[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M698RHSYB7DD8V33S6NSARFJ":3,"skill-same:01M698RHSYB7DD8V33S6NSARFJ":74},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":48,"repositoryHtmlUrl":49,"repositoryHomepageUrl":50,"ownerHtmlUrl":51,"ownerBlogUrl":50,"ownerDescription":52,"updatedAt":53,"install":54,"resources":67},"01M698RHSYB7DD8V33S6NSARFJ","openclaw-test-performance",null,"Benchmark, diagnose, and optimize OpenClaw test and plugin-suite runtime, import hotspots, CPU\u002FRSS, heap growth, and slow coverage paths.","openclaw\u002Fopenclaw","openclaw","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F252820863?v=4","01M698P3FSAZ6B4R928ZF19KPT","01M698PDMDRVH56MV30D253NFP",394352,"MIT","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fopenclaw-test-performance\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[23,24,25,26,9,27,28,29,30,31,32,33,34,35,36,37,38,39],"openclaw test performance","test performance","test","performance","diagnose","plugin","benchmark","rss","coverage","growth","optimize","runtime","import","paths","CPU","heap","suite","2026-11-10 10:12:30",false,"---\nname: openclaw-test-performance\ndescription: Benchmark, diagnose, and optimize OpenClaw test and plugin-suite runtime, import hotspots, CPU\u002FRSS, heap growth, and slow coverage paths.\n---\n\n# OpenClaw Test Performance\n\nUse evidence first. The goal is real `pnpm test`, plugin-suite, and\nplugin-inspector speed\u002FRSS improvement with coverage intact, not runner tuning by\nguesswork.\n\n## Workflow\n\n1. Read the relevant local `AGENTS.md` files before editing:\n   - `src\u002Fagents\u002FAGENTS.md` for agent\u002Fimport hotspots.\n   - `src\u002Fchannels\u002FAGENTS.md` and `src\u002Fplugins\u002FAGENTS.md` for plugin\u002Fchannel\n     laziness.\n   - `src\u002Fgateway\u002FAGENTS.md` for server lifecycle tests.\n   - `test\u002Fhelpers\u002FAGENTS.md` and\n     `src\u002Fchannels\u002Fplugins\u002Fcontracts\u002Ftest-helpers\u002FAGENTS.md` for shared contract\n     helpers.\n   - `src\u002Finfra\u002Foutbound\u002FAGENTS.md` for outbound\u002Fmedia\u002Faction tests.\n2. Establish a baseline before changing code:\n   - Prefer `pnpm test:perf:groups --full-suite --allow-failures --output \u003Cfile>`\n     for full-suite ranking.\n   - For bundled plugin breadth, run the smallest relevant `pnpm\n     test:extensions:batch \u003Cplugin[,plugin...]>` or plugin-inspector command\n     before jumping to the full extension sweep.\n   - For a scoped hotspot use:\n     `\u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile-or-files> --maxWorkers=1 --reporter=verbose`\n   - For import-heavy suspicion add:\n     `OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1`.\n3. Separate wall\u002Frunner noise from real file cost:\n   - Compare Vitest duration, test body timing, import breakdown, wall time, and\n     max RSS.\n   - Re-run single files when grouped\u002Ffull-suite numbers look stale or noisy.\n   - If a full-suite grouped run reports a lane failure but JSON says tests\n     passed, capture that as harness\u002Fnoise and verify the suspect file directly.\n4. Pick the next attack by return and risk:\n   - High return: one file\u002Ftest dominates seconds or RSS and has a clear root.\n   - High leverage: one plugin or SDK barrel causes every plugin-inspector or\n     extension-batch run to load broad runtime.\n   - Lower risk: static descriptors, target parsing, routing, auth bypass,\n     setup hints, registry fixtures, or test server lifecycle.\n   - Higher risk: real memory\u002Fruntime behavior, live providers, protocol\n     contracts, or broad production refactors.\n5. Fix the root cause, not the symptom:\n   - Move static metadata\u002Fparsing into narrow helpers or lightweight artifacts\n     reused by full runtime and fast paths.\n   - Prefer dependency injection, loaded-plugin-only lookup, explicit fixtures,\n     and pure helpers over broad mocks.\n   - Reuse suite-level servers\u002Fclients when a fresh handshake is irrelevant.\n   - Keep schedulers\u002Fbackground loops off unless the test proves scheduling.\n   - In plugin paths, move static metadata into manifest\u002Flightweight artifacts\n     and keep runtime plugin loads behind explicit execution boundaries.\n6. Preserve coverage shape:\n   - Do not delete a slow integration proof unless the exact production\n     composition is extracted into a named helper and tested.\n   - Keep one cheap integration smoke when cross-component wiring matters.\n   - State explicitly what incidental coverage was removed, if any.\n7. Re-benchmark the same command after the change and compute seconds plus\n   percent gain.\n8. Update the running report when requested or when this thread is tracking one.\n   Include before\u002Fafter commands, artifacts, coverage notes, verification, and\n   next attack order.\n9. Stage the intended paths, commit with standard Git, and push when the\n   user asked for commits\u002Fpushes. Stage only files touched for this attack.\n\n## Plugin-Suite Workflow\n\nUse this section when perf work involves bundled plugins, plugin-inspector, SDK\nbarrels, package-boundary tests, or extension suites.\n\n1. Map the suite shape first:\n   - source tests: `pnpm test extensions\u002F\u003Cid>` or `pnpm test:extensions:batch \u003Cid>`\n   - package boundaries: `pnpm run test:extensions:package-boundary:canary` and\n     `pnpm run test:extensions:package-boundary:compile`\n   - all bundled source tests: `pnpm test:extensions`\n   - plugin import memory: `pnpm test:extensions:memory -- --json .artifacts\u002Ftest-perf\u002Fextensions-memory.json`\n   - plugin-inspector\u002Freport work: keep report primitives in `plugin-inspector`;\n     keep wrappers thin and collect peak RSS when the command supports it.\n2. Start narrow, then widen:\n   - one plugin changed: run that plugin's tests and plugin-inspector slice.\n   - SDK\u002Fpublic barrel changed: add representative provider, channel, memory,\n     and feature plugins.\n   - loader\u002Fruntime mirror changed: add package-boundary checks and build\u002Fpackage\n     proof as needed.\n   - unknown shared plugin behavior: run `test:extensions:batch` groups before\n     `pnpm test:extensions`.\n3. Treat plugin-inspector failures as product signals:\n   - JSON must parse.\n   - warnings\u002Ferrors must be classified, not hidden.\n   - runtime capture should be quiet and config-tolerant.\n   - command output should include wall time, exit code, and peak RSS when\n     available.\n4. Follow `$openclaw-testing` for host selection. Trusted source benchmarks\n   can run locally with comparable machine\u002Fload conditions. Use `$crabbox` when\n   clean packaging, Linux\u002Fplatform behavior, isolation, or an explicit remote\n   request is part of the proof; reuse and clean up only the owned lease.\n5. If plugin performance is package-artifact sensitive, switch to\n   `release-openclaw-plugin-testing` and Package Acceptance rather than\n   trusting source-only timing.\n\n## Metric Collection\n\nCollect at least one stable metric before and after. Prefer the same machine and\nsame command. For Testbox comparisons, use the same `tbx_...` id when possible.\n\n| Metric          | Use for                            | Preferred source                                                            |\n| --------------- | ---------------------------------- | --------------------------------------------------------------------------- |\n| wall time       | user-visible suite cost            | `\u002Fusr\u002Fbin\u002Ftime -l`, test wrapper duration, Testbox run time                 |\n| Vitest duration | test body\u002Fimport cost              | Vitest output per file\u002Fshard                                                |\n| import duration | broad barrel\u002Fruntime loads         | `OPENCLAW_VITEST_IMPORT_DURATIONS=1`                                        |\n| max RSS         | memory pressure and OOM risk       | `\u002Fusr\u002Fbin\u002Ftime -l`, `pnpm test:extensions:memory`, wrapper memory summaries |\n| CPU\u002Fuser\u002Fsys    | CPU-bound vs wait-bound split      | `\u002Fusr\u002Fbin\u002Ftime -l` locally, Testbox job timing when local CPU is noisy      |\n| heap evidence   | real leak vs retained module graph | `openclaw-test-heap-leaks` workflow                                         |\n\nLocal scoped command with CPU\u002FRSS:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nPlugin import memory profile:\n\n```bash\npnpm build\npnpm test:extensions:memory -- --top 20 --json .artifacts\u002Ftest-perf\u002Fextensions-memory.json\n```\n\nTargeted plugin import memory:\n\n```bash\npnpm test:extensions:memory -- --extension discord --extension telegram --skip-combined\n```\n\nHeap\u002FRSS escalation:\n\n```bash\npnpm test:perf:groups \\\n  --config test\u002Fvitest\u002Fvitest.unit-fast.config.ts \\\n  --allow-failures \\\n  --output .artifacts\u002Ftest-perf\u002Funit-fast-memory.json\npnpm test:perf:profile:runner -- \\\n  --output-dir .artifacts\u002Ftest-perf\u002Fvitest-runner-profile -- \u003Cfile>\n```\n\nUse `openclaw-test-heap-leaks` when RSS keeps growing across intervals, workers\nOOM, or the suspect command has app-object retention. Do not call RSS growth a\nleak until snapshots or retainers support it.\n\n## Common Root Causes\n\n- Full bundled channel\u002Fplugin runtime loaded for static data.\n- `getChannelPlugin()` fallback used when an already-loaded fixture or pure\n  parser would suffice.\n- Broad `api.ts`, `runtime-api.ts`, `test-api.ts`, or plugin-sdk barrels pulled\n  into hot tests.\n- SDK root aliases or package barrels pulling focused subpaths back into a broad\n  plugin graph.\n- Plugin-inspector loading runtime code just to render metadata, reports, or CI\n  policy scores.\n- Bundled plugin capture reusing real config\u002Fhome state instead of synthetic,\n  redacted, isolated state.\n- Partial-real mocks using `importActual()` around broad modules.\n- `vi.resetModules()` plus fresh imports in per-test loops.\n- Test plugin registry seeded in `beforeAll` while runtime state resets in\n  `afterEach`.\n- Per-test gateway\u002Fserver\u002Fclient startup when state reset would suffice.\n- Runtime\u002Fdefault model\u002Fauth selection paid by idle snapshots or fixtures.\n- Plugin-owned media\u002Faction discovery triggered before checking whether args\n  contain plugin-owned fields.\n- Parallel Vitest runs sharing `node_modules\u002F.experimental-vitest-cache` without\n  distinct `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH` values.\n\n## Benchmark Commands\n\nScoped file:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nScoped file with import breakdown:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l env \\\n  OPENCLAW_VITEST_IMPORT_DURATIONS=1 \\\n  OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 \\\n  pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nGrouped suite:\n\n```bash\npnpm test:perf:groups --full-suite --allow-failures \\\n  --output .artifacts\u002Ftest-perf\u002F\u003Cname>.json\n```\n\nExtension batch:\n\n```bash\npnpm test:extensions:batch \u003Cplugin[,plugin...]> -- --reporter=verbose\n```\n\nAll extension tests:\n\n```bash\npnpm test:extensions\n```\n\nPackage-boundary plugin checks:\n\n```bash\npnpm run test:extensions:package-boundary:canary\npnpm run test:extensions:package-boundary:compile\n```\n\nReuse an existing Vitest JSON report:\n\n```bash\npnpm test:perf:groups --report \u003Cvitest-json> \\\n  --output .artifacts\u002Ftest-perf\u002F\u003Cname>.json\n```\n\n## Verification\n\n- Always run the targeted test surface that proves the change.\n- Follow [OpenClaw testing](..\u002Fopenclaw-testing\u002FSKILL.md) for focused tests,\n  required builds, proof routing, and publication timing.\n- For test-only changes, run the exact edited tests through that owner's supported command.\n- For plugin SDK\u002Fbarrel\u002Fruntime changes, compare exact commits with\n  `pnpm plugin-sdk:api:diff -- --base \u003Cbase-sha> --head \u003Chead-sha>` when the\n  public API surface may drift. For PR-local proof, use the branch merge base\n  as `\u003Cbase-sha>` and the exact tested head commit as `\u003Chead-sha>`.\n- For plugin-suite perf fixes, verify at least one representative plugin batch\n  plus the changed gate; use Package Acceptance if the bug only exists in a\n  packed artifact.\n- For missing or stale dependencies, follow [Source dependencies](..\u002F..\u002F..\u002FCONTRIBUTING.md#source-dependencies)\n  and the current worktree's owner instructions. Use a qualified proof route.\n- Use the report format:\n\n```markdown\n| Metric         | Before |  After |          Gain |\n| -------------- | -----: | -----: | ------------: |\n| File wall time |   `Xs` |   `Ys` |  `-Zs` (`P%`) |\n| Max RSS        |  `XMB` |  `YMB` | `-ZMB` (`P%`) |\n| CPU user\u002Fsys   | `X\u002FYs` | `A\u002FBs` |       explain |\n```\n\n## Handoff\n\nKeep the final concise:\n\n- Root cause.\n- Suite\u002Fplugin scope.\n- Files changed.\n- Before\u002Fafter wall, Vitest\u002Fimport, CPU, and RSS numbers where available.\n- Leak classification if memory was involved: real leak, retained module graph,\n  or inconclusive.\n- Coverage retained.\n- Verification commands.\n- Testbox ID or workflow URL for remote proof.\n- Commit hash and push status.\n","# OpenClaw Test Performance\n\nUse evidence first. The goal is real `pnpm test`, plugin-suite, and\nplugin-inspector speed\u002FRSS improvement with coverage intact, not runner tuning by\nguesswork.\n\n## Workflow\n\n1. Read the relevant local `AGENTS.md` files before editing:\n   - `src\u002Fagents\u002FAGENTS.md` for agent\u002Fimport hotspots.\n   - `src\u002Fchannels\u002FAGENTS.md` and `src\u002Fplugins\u002FAGENTS.md` for plugin\u002Fchannel\n     laziness.\n   - `src\u002Fgateway\u002FAGENTS.md` for server lifecycle tests.\n   - `test\u002Fhelpers\u002FAGENTS.md` and\n     `src\u002Fchannels\u002Fplugins\u002Fcontracts\u002Ftest-helpers\u002FAGENTS.md` for shared contract\n     helpers.\n   - `src\u002Finfra\u002Foutbound\u002FAGENTS.md` for outbound\u002Fmedia\u002Faction tests.\n2. Establish a baseline before changing code:\n   - Prefer `pnpm test:perf:groups --full-suite --allow-failures --output \u003Cfile>`\n     for full-suite ranking.\n   - For bundled plugin breadth, run the smallest relevant `pnpm\n     test:extensions:batch \u003Cplugin[,plugin...]>` or plugin-inspector command\n     before jumping to the full extension sweep.\n   - For a scoped hotspot use:\n     `\u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile-or-files> --maxWorkers=1 --reporter=verbose`\n   - For import-heavy suspicion add:\n     `OPENCLAW_VITEST_IMPORT_DURATIONS=1 OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1`.\n3. Separate wall\u002Frunner noise from real file cost:\n   - Compare Vitest duration, test body timing, import breakdown, wall time, and\n     max RSS.\n   - Re-run single files when grouped\u002Ffull-suite numbers look stale or noisy.\n   - If a full-suite grouped run reports a lane failure but JSON says tests\n     passed, capture that as harness\u002Fnoise and verify the suspect file directly.\n4. Pick the next attack by return and risk:\n   - High return: one file\u002Ftest dominates seconds or RSS and has a clear root.\n   - High leverage: one plugin or SDK barrel causes every plugin-inspector or\n     extension-batch run to load broad runtime.\n   - Lower risk: static descriptors, target parsing, routing, auth bypass,\n     setup hints, registry fixtures, or test server lifecycle.\n   - Higher risk: real memory\u002Fruntime behavior, live providers, protocol\n     contracts, or broad production refactors.\n5. Fix the root cause, not the symptom:\n   - Move static metadata\u002Fparsing into narrow helpers or lightweight artifacts\n     reused by full runtime and fast paths.\n   - Prefer dependency injection, loaded-plugin-only lookup, explicit fixtures,\n     and pure helpers over broad mocks.\n   - Reuse suite-level servers\u002Fclients when a fresh handshake is irrelevant.\n   - Keep schedulers\u002Fbackground loops off unless the test proves scheduling.\n   - In plugin paths, move static metadata into manifest\u002Flightweight artifacts\n     and keep runtime plugin loads behind explicit execution boundaries.\n6. Preserve coverage shape:\n   - Do not delete a slow integration proof unless the exact production\n     composition is extracted into a named helper and tested.\n   - Keep one cheap integration smoke when cross-component wiring matters.\n   - State explicitly what incidental coverage was removed, if any.\n7. Re-benchmark the same command after the change and compute seconds plus\n   percent gain.\n8. Update the running report when requested or when this thread is tracking one.\n   Include before\u002Fafter commands, artifacts, coverage notes, verification, and\n   next attack order.\n9. Stage the intended paths, commit with standard Git, and push when the\n   user asked for commits\u002Fpushes. Stage only files touched for this attack.\n\n## Plugin-Suite Workflow\n\nUse this section when perf work involves bundled plugins, plugin-inspector, SDK\nbarrels, package-boundary tests, or extension suites.\n\n1. Map the suite shape first:\n   - source tests: `pnpm test extensions\u002F\u003Cid>` or `pnpm test:extensions:batch \u003Cid>`\n   - package boundaries: `pnpm run test:extensions:package-boundary:canary` and\n     `pnpm run test:extensions:package-boundary:compile`\n   - all bundled source tests: `pnpm test:extensions`\n   - plugin import memory: `pnpm test:extensions:memory -- --json .artifacts\u002Ftest-perf\u002Fextensions-memory.json`\n   - plugin-inspector\u002Freport work: keep report primitives in `plugin-inspector`;\n     keep wrappers thin and collect peak RSS when the command supports it.\n2. Start narrow, then widen:\n   - one plugin changed: run that plugin's tests and plugin-inspector slice.\n   - SDK\u002Fpublic barrel changed: add representative provider, channel, memory,\n     and feature plugins.\n   - loader\u002Fruntime mirror changed: add package-boundary checks and build\u002Fpackage\n     proof as needed.\n   - unknown shared plugin behavior: run `test:extensions:batch` groups before\n     `pnpm test:extensions`.\n3. Treat plugin-inspector failures as product signals:\n   - JSON must parse.\n   - warnings\u002Ferrors must be classified, not hidden.\n   - runtime capture should be quiet and config-tolerant.\n   - command output should include wall time, exit code, and peak RSS when\n     available.\n4. Follow `$openclaw-testing` for host selection. Trusted source benchmarks\n   can run locally with comparable machine\u002Fload conditions. Use `$crabbox` when\n   clean packaging, Linux\u002Fplatform behavior, isolation, or an explicit remote\n   request is part of the proof; reuse and clean up only the owned lease.\n5. If plugin performance is package-artifact sensitive, switch to\n   `release-openclaw-plugin-testing` and Package Acceptance rather than\n   trusting source-only timing.\n\n## Metric Collection\n\nCollect at least one stable metric before and after. Prefer the same machine and\nsame command. For Testbox comparisons, use the same `tbx_...` id when possible.\n\n| Metric          | Use for                            | Preferred source                                                            |\n| --------------- | ---------------------------------- | --------------------------------------------------------------------------- |\n| wall time       | user-visible suite cost            | `\u002Fusr\u002Fbin\u002Ftime -l`, test wrapper duration, Testbox run time                 |\n| Vitest duration | test body\u002Fimport cost              | Vitest output per file\u002Fshard                                                |\n| import duration | broad barrel\u002Fruntime loads         | `OPENCLAW_VITEST_IMPORT_DURATIONS=1`                                        |\n| max RSS         | memory pressure and OOM risk       | `\u002Fusr\u002Fbin\u002Ftime -l`, `pnpm test:extensions:memory`, wrapper memory summaries |\n| CPU\u002Fuser\u002Fsys    | CPU-bound vs wait-bound split      | `\u002Fusr\u002Fbin\u002Ftime -l` locally, Testbox job timing when local CPU is noisy      |\n| heap evidence   | real leak vs retained module graph | `openclaw-test-heap-leaks` workflow                                         |\n\nLocal scoped command with CPU\u002FRSS:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nPlugin import memory profile:\n\n```bash\npnpm build\npnpm test:extensions:memory -- --top 20 --json .artifacts\u002Ftest-perf\u002Fextensions-memory.json\n```\n\nTargeted plugin import memory:\n\n```bash\npnpm test:extensions:memory -- --extension discord --extension telegram --skip-combined\n```\n\nHeap\u002FRSS escalation:\n\n```bash\npnpm test:perf:groups \\\n  --config test\u002Fvitest\u002Fvitest.unit-fast.config.ts \\\n  --allow-failures \\\n  --output .artifacts\u002Ftest-perf\u002Funit-fast-memory.json\npnpm test:perf:profile:runner -- \\\n  --output-dir .artifacts\u002Ftest-perf\u002Fvitest-runner-profile -- \u003Cfile>\n```\n\nUse `openclaw-test-heap-leaks` when RSS keeps growing across intervals, workers\nOOM, or the suspect command has app-object retention. Do not call RSS growth a\nleak until snapshots or retainers support it.\n\n## Common Root Causes\n\n- Full bundled channel\u002Fplugin runtime loaded for static data.\n- `getChannelPlugin()` fallback used when an already-loaded fixture or pure\n  parser would suffice.\n- Broad `api.ts`, `runtime-api.ts`, `test-api.ts`, or plugin-sdk barrels pulled\n  into hot tests.\n- SDK root aliases or package barrels pulling focused subpaths back into a broad\n  plugin graph.\n- Plugin-inspector loading runtime code just to render metadata, reports, or CI\n  policy scores.\n- Bundled plugin capture reusing real config\u002Fhome state instead of synthetic,\n  redacted, isolated state.\n- Partial-real mocks using `importActual()` around broad modules.\n- `vi.resetModules()` plus fresh imports in per-test loops.\n- Test plugin registry seeded in `beforeAll` while runtime state resets in\n  `afterEach`.\n- Per-test gateway\u002Fserver\u002Fclient startup when state reset would suffice.\n- Runtime\u002Fdefault model\u002Fauth selection paid by idle snapshots or fixtures.\n- Plugin-owned media\u002Faction discovery triggered before checking whether args\n  contain plugin-owned fields.\n- Parallel Vitest runs sharing `node_modules\u002F.experimental-vitest-cache` without\n  distinct `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH` values.\n\n## Benchmark Commands\n\nScoped file:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nScoped file with import breakdown:\n\n```bash\ntimeout 240 \u002Fusr\u002Fbin\u002Ftime -l env \\\n  OPENCLAW_VITEST_IMPORT_DURATIONS=1 \\\n  OPENCLAW_VITEST_PRINT_IMPORT_BREAKDOWN=1 \\\n  pnpm test \u003Cfile> --maxWorkers=1 --reporter=verbose\n```\n\nGrouped suite:\n\n```bash\npnpm test:perf:groups --full-suite --allow-failures \\\n  --output .artifacts\u002Ftest-perf\u002F\u003Cname>.json\n```\n\nExtension batch:\n\n```bash\npnpm test:extensions:batch \u003Cplugin[,plugin...]> -- --reporter=verbose\n```\n\nAll extension tests:\n\n```bash\npnpm test:extensions\n```\n\nPackage-boundary plugin checks:\n\n```bash\npnpm run test:extensions:package-boundary:canary\npnpm run test:extensions:package-boundary:compile\n```\n\nReuse an existing Vitest JSON report:\n\n```bash\npnpm test:perf:groups --report \u003Cvitest-json> \\\n  --output .artifacts\u002Ftest-perf\u002F\u003Cname>.json\n```\n\n## Verification\n\n- Always run the targeted test surface that proves the change.\n- Follow [OpenClaw testing](..\u002Fopenclaw-testing\u002FSKILL.md) for focused tests,\n  required builds, proof routing, and publication timing.\n- For test-only changes, run the exact edited tests through that owner's supported command.\n- For plugin SDK\u002Fbarrel\u002Fruntime changes, compare exact commits with\n  `pnpm plugin-sdk:api:diff -- --base \u003Cbase-sha> --head \u003Chead-sha>` when the\n  public API surface may drift. For PR-local proof, use the branch merge base\n  as `\u003Cbase-sha>` and the exact tested head commit as `\u003Chead-sha>`.\n- For plugin-suite perf fixes, verify at least one representative plugin batch\n  plus the changed gate; use Package Acceptance if the bug only exists in a\n  packed artifact.\n- For missing or stale dependencies, follow [Source dependencies](..\u002F..\u002F..\u002FCONTRIBUTING.md#source-dependencies)\n  and the current worktree's owner instructions. Use a qualified proof route.\n- Use the report format:\n\n```markdown\n| Metric         | Before |  After |          Gain |\n| -------------- | -----: | -----: | ------------: |\n| File wall time |   `Xs` |   `Ys` |  `-Zs` (`P%`) |\n| Max RSS        |  `XMB` |  `YMB` | `-ZMB` (`P%`) |\n| CPU user\u002Fsys   | `X\u002FYs` | `A\u002FBs` |       explain |\n```\n\n## Handoff\n\nKeep the final concise:\n\n- Root cause.\n- Suite\u002Fplugin scope.\n- Files changed.\n- Before\u002Fafter wall, Vitest\u002Fimport, CPU, and RSS numbers where available.\n- Leak classification if memory was involved: real leak, retained module graph,\n  or inconclusive.\n- Coverage retained.\n- Verification commands.\n- Testbox ID or workflow URL for remote proof.\n- Commit hash and push status.\n",{"name":5,"description":7},"main","df9d3240e52a533ea176e98cf047ed6b40cf37d6",".agents\u002Fskills\u002Fopenclaw-test-performance",82861,"https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw","https:\u002F\u002Fopenclaw.ai","https:\u002F\u002Fgithub.com\u002Fopenclaw","Your personal, open source AI assistant.","2026-11-12 03:01:25",{"source":8,"skillName":5,"commands":55,"prompt":65,"zipAvailable":66},[56,59,62],{"tool":57,"command":58},"npx","npx skills add openclaw\u002Fopenclaw --skill openclaw-test-performance",{"tool":60,"command":61},"bunx","bunx skills add openclaw\u002Fopenclaw --skill openclaw-test-performance",{"tool":63,"command":64},"pnpm","pnpm dlx skills add openclaw\u002Fopenclaw --skill openclaw-test-performance","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fopenclaw-test-performance\u002FSKILL.md",true,[68],{"path":69,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":72,"sourceHtmlUrl":73},"agents\u002Fopenai.yaml","REFERENCE","参考文档",459,"https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fopenclaw-test-performance\u002Fagents\u002Fopenai.yaml",[75,81,104,122,144,166],{"skillNo":76,"name":77,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":40},"01M698VP84FNM6G9MR1HPX7MF7","lobster","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fextensions\u002Flobster\u002FSKILL.md",[],[77],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":40},"01M698YY8QGQ7S8TJNKJG6VTPH","xurl","xurl CLI for authenticated X posts, replies, reads\u002Fsearch, DMs, media upload, followers, auth status, or raw v2 API calls.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fxurl\u002FSKILL.md",[],[83,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103],"for","api","calls","replies","posts","upload","tap","install","brew","node","Media","search","npm","status","auth","cli",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":40},"01M698YWT1CJ0WK88WB909R9RT","weather","Current weather and forecasts with web_fetch, falling back to wttr.in curl for locations, rain, temperature, travel planning.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fweather\u002FSKILL.md",[],[106,111,112,95,113,96,114,115,116,117,118,119,88,120,121],"travel planning","travel","fetch","curl","https","help","planning","web","back","temperature","with",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":133,"publishedAt":40},"01M698YV2Q0R0JJKAWGFS21K0N","visualize","Create inline visuals for code and explanations, or author persistent OpenClaw dashboard widgets with show_widget.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Fvisualize\u002FSKILL.md",[128],{"categoryNo":129,"categoryName":130,"taxonomyType":131,"taxonomyTypeDesc":132},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[124,134,135,136,137,88,121,138,139,140,141,142,9,143],"widgets","openclaw dashboard","author","inline","show","code","create","visuals","dashboard","widget",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":156,"publishedAt":40},"01M698YS2TRJH9ENG28HD9CD87","trello","Manage Trello boards, lists, and cards via the Trello REST API.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Ftrello\u002FSKILL.md",[150,153],{"categoryNo":151,"categoryName":152,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":154,"categoryName":155,"taxonomyType":131,"taxonomyTypeDesc":132},"01JBSEEDCAT000000000000030","开发工程师",[146,115,157,158,159,160,161,162,95,96,163,114,89,164,165],"cloud","manage","via","rest api","token","atlassian","jq","REST","developer",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":40},"01M698YQ9Q3M4W78EWV2KSCSVW","tmux","Control tmux sessions\u002Fpanes for interactive CLIs: list, capture output, send keys, paste text, monitor prompts.","https:\u002F\u002Fgithub.com\u002Fopenclaw\u002Fopenclaw\u002Fblob\u002Fmain\u002Fskills\u002Ftmux\u002FSKILL.md",[],[168,95,173,174,88,175,176,177,178,179,180,181,96,182,183,184,185,186,187],"send","darwin","keys","paste","output","control","prompts","interactive","list","capture","panes","text","monitor","sessions","linux"]