@webpresso/agent-kit 0.21.5 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +87 -124
  4. package/bin/_run.js +143 -1
  5. package/bin/runtime-manifest.json +40 -0
  6. package/catalog/AGENTS.md.tpl +7 -6
  7. package/catalog/agent/commands/plan-refine.md +3 -3
  8. package/catalog/agent/commands/pll.md +2 -0
  9. package/catalog/agent/guides/parallel-execution.md +2 -0
  10. package/catalog/agent/rules/extraction-parity.md +27 -1
  11. package/catalog/agent/rules/public-package-safety.md +24 -1
  12. package/catalog/agent/skills/pll/SKILL.md +1 -0
  13. package/catalog/base-kit/.github/workflows/ci.webpresso.yml.tmpl +33 -0
  14. package/catalog/base-kit/stryker.config.ts.tmpl +2 -2
  15. package/catalog/docs/templates/blueprint.md +1 -0
  16. package/catalog/docs/templates/blueprint.yaml +10 -12
  17. package/commands/blueprint.md +8 -43
  18. package/dist/esm/audit/blueprint-db-consistency.d.ts +1 -1
  19. package/dist/esm/audit/blueprint-db-consistency.js +6 -8
  20. package/dist/esm/audit/blueprint-lifecycle-sql.js +10 -3
  21. package/dist/esm/audit/cloudflare-deploy-contract.d.ts +3 -0
  22. package/dist/esm/audit/cloudflare-deploy-contract.js +64 -0
  23. package/dist/esm/audit/no-legacy-cli-bin.d.ts +3 -0
  24. package/dist/esm/audit/no-legacy-cli-bin.js +100 -0
  25. package/dist/esm/audit/package-surface.js +14 -1
  26. package/dist/esm/audit/repo-guardrails.js +40 -13
  27. package/dist/esm/audit/roadmap-links.js +23 -10
  28. package/dist/esm/blueprint/core/schema.d.ts +8 -8
  29. package/dist/esm/blueprint/core/schema.js +2 -2
  30. package/dist/esm/blueprint/db/enums.d.ts +1 -1
  31. package/dist/esm/blueprint/db/ingester.js +18 -10
  32. package/dist/esm/blueprint/lifecycle/audit.js +9 -2
  33. package/dist/esm/blueprint/lifecycle/local.js +15 -4
  34. package/dist/esm/blueprint/service/BlueprintCreationService.js +11 -6
  35. package/dist/esm/blueprint/service/BlueprintService.js +37 -19
  36. package/dist/esm/blueprint/service/scanner.js +73 -9
  37. package/dist/esm/blueprint/tracked-document/schema.d.ts +2 -2
  38. package/dist/esm/blueprint/utils/document-paths.d.ts +23 -0
  39. package/dist/esm/blueprint/utils/document-paths.js +91 -0
  40. package/dist/esm/build/package-manifest.js +7 -0
  41. package/dist/esm/build/release-policy.d.ts +27 -0
  42. package/dist/esm/build/release-policy.js +29 -0
  43. package/dist/esm/build/runtime-targets.d.ts +13 -0
  44. package/dist/esm/build/runtime-targets.js +48 -0
  45. package/dist/esm/cli/auto-update/detect-pm.d.ts +15 -0
  46. package/dist/esm/cli/auto-update/detect-pm.js +24 -9
  47. package/dist/esm/cli/auto-update/skip.js +9 -1
  48. package/dist/esm/cli/bundle/agent-command-inventory.d.ts +120 -0
  49. package/dist/esm/cli/bundle/agent-command-inventory.js +100 -0
  50. package/dist/esm/cli/bundle/index.d.ts +17 -0
  51. package/dist/esm/cli/bundle/index.js +15 -0
  52. package/dist/esm/cli/cli.d.ts +1 -1
  53. package/dist/esm/cli/cli.js +49 -5
  54. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  55. package/dist/esm/cli/commands/audit.js +2 -0
  56. package/dist/esm/cli/commands/blueprint/router.js +11 -8
  57. package/dist/esm/cli/commands/hook.d.ts +8 -0
  58. package/dist/esm/cli/commands/hook.js +47 -0
  59. package/dist/esm/cli/commands/init/index.js +35 -1
  60. package/dist/esm/cli/commands/init/scaffold-base-kit.js +1 -1
  61. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/codex-ownership.js +9 -1
  62. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +130 -20
  63. package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +65 -0
  64. package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +64 -0
  65. package/dist/esm/cli/commands/package-manager.d.ts +15 -0
  66. package/dist/esm/cli/commands/package-manager.js +42 -0
  67. package/dist/esm/cli/commands/test.d.ts +1 -0
  68. package/dist/esm/cli/commands/test.js +2 -1
  69. package/dist/esm/cli/commands/typecheck.js +5 -20
  70. package/dist/esm/cli/package-scripts.d.ts +12 -0
  71. package/dist/esm/cli/package-scripts.js +59 -0
  72. package/dist/esm/cli/utils.js +3 -22
  73. package/dist/esm/cli/wp-extensions.d.ts +14 -0
  74. package/dist/esm/cli/wp-extensions.js +34 -0
  75. package/dist/esm/config/docs-lint/schemas/common.d.ts +1 -1
  76. package/dist/esm/config/docs-lint/schemas/implementation-plan.d.ts +2 -2
  77. package/dist/esm/config/docs-lint/schemas/parent-roadmap.d.ts +1 -1
  78. package/dist/esm/config/stryker/index.d.ts +85 -0
  79. package/dist/esm/config/stryker/index.js +31 -0
  80. package/dist/esm/e2e/command-builder.js +11 -2
  81. package/dist/esm/e2e/config.d.ts +56 -0
  82. package/dist/esm/e2e/config.js +114 -0
  83. package/dist/esm/e2e/execution.js +4 -0
  84. package/dist/esm/e2e/run-planner.js +1 -0
  85. package/dist/esm/e2e/types.d.ts +2 -0
  86. package/dist/esm/format/index.js +1 -3
  87. package/dist/esm/hooks/guard-switch/index.d.ts +1 -1
  88. package/dist/esm/hooks/guard-switch/index.js +22 -14
  89. package/dist/esm/hooks/post-tool/lint-after-edit.d.ts +1 -0
  90. package/dist/esm/hooks/post-tool/lint-after-edit.js +5 -2
  91. package/dist/esm/hooks/pretool-guard/validators/file-conventions.js +1 -1
  92. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.d.ts +6 -0
  93. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +27 -2
  94. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +2 -1
  95. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +59 -34
  96. package/dist/esm/hooks/pretool-guard/validators/plan-frontmatter.js +3 -3
  97. package/dist/esm/hooks/shared/routing-block.js +18 -4
  98. package/dist/esm/hooks/shared/validators/blueprint.js +3 -0
  99. package/dist/esm/hooks/stop/qa-changed-files.d.ts +1 -0
  100. package/dist/esm/hooks/stop/qa-changed-files.js +5 -2
  101. package/dist/esm/lint/index.js +1 -1
  102. package/dist/esm/mcp/auto-discover.d.ts +2 -0
  103. package/dist/esm/mcp/auto-discover.js +14 -6
  104. package/dist/esm/mcp/blueprint-server.js +30 -26
  105. package/dist/esm/mcp/cli.js +21 -0
  106. package/dist/esm/mcp/runners/test.js +15 -0
  107. package/dist/esm/mcp/server.d.ts +7 -0
  108. package/dist/esm/mcp/server.js +16 -27
  109. package/dist/esm/mcp/tools/_registry.d.ts +3 -0
  110. package/dist/esm/mcp/tools/_registry.js +21 -0
  111. package/dist/esm/mcp/tools/audit.d.ts +1 -0
  112. package/dist/esm/mcp/tools/audit.js +11 -0
  113. package/dist/esm/mcp/tools/e2e.d.ts +1 -1
  114. package/dist/esm/mcp/tools/typecheck.js +4 -2
  115. package/dist/esm/mutation/affected.d.ts +9 -0
  116. package/dist/esm/mutation/affected.js +36 -0
  117. package/dist/esm/package.json +5 -0
  118. package/dist/esm/runtime/package-version.d.ts +2 -0
  119. package/dist/esm/runtime/package-version.js +43 -0
  120. package/dist/esm/test/command-builder.d.ts +3 -0
  121. package/dist/esm/test/command-builder.js +22 -3
  122. package/dist/esm/tool-runtime/index.d.ts +2 -2
  123. package/dist/esm/tool-runtime/index.js +2 -1
  124. package/dist/esm/tool-runtime/resolve-runner.d.ts +3 -0
  125. package/dist/esm/tool-runtime/resolve-runner.js +7 -5
  126. package/dist/esm/typecheck/index.js +4 -2
  127. package/dist/esm/wp-extension/index.d.ts +50 -0
  128. package/dist/esm/wp-extension/index.js +268 -0
  129. package/package.json +67 -31
  130. package/skills/pll/SKILL.md +1 -0
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Webpresso agent-kit Claude Code plugin: blueprints, skills, hooks, MCP server",
9
- "version": "0.21.5"
9
+ "version": "0.23.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -23,5 +23,5 @@
23
23
  ]
24
24
  }
25
25
  ],
26
- "version": "0.21.5"
26
+ "version": "0.23.0"
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpresso",
3
- "version": "0.21.3",
3
+ "version": "0.23.0",
4
4
  "description": "Webpresso agent-kit: blueprints, skills, lore commit protocol, tech-debt lifecycle",
5
5
  "skills": "./skills",
6
6
  "commands": "./commands",
package/README.md CHANGED
@@ -1,164 +1,127 @@
1
1
  # @webpresso/agent-kit
2
2
 
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
4
+ [![CI](https://github.com/webpresso/agent-kit/actions/workflows/ci.webpresso.yml/badge.svg)](https://github.com/webpresso/agent-kit/actions/workflows/ci.webpresso.yml)
5
+
3
6
  > TypeScript infrastructure for AI-agent-driven development. One `wp` runtime
4
7
  > gives agents planning, tests, mutation, e2e, CI, docs, and debt tracking —
5
8
  > all summary-first so they keep context, and enforced as contracts so docs,
6
9
  > intent, and code can't drift. MIT. Experimental v0.x.
7
10
 
8
- ## Install
11
+ ## What it is
9
12
 
10
- Requires Node.js 24 or newer.
13
+ `@webpresso/agent-kit` is a TypeScript toolkit — the `wp` CLI plus an MCP
14
+ server — that gives AI coding agents a summary-first, contract-enforced way to
15
+ plan, test, and keep a repo correct.
11
16
 
12
- Install from the public npm registry:
17
+ ## Why use it
13
18
 
14
- ```bash
15
- npm install -g @webpresso/agent-kit
16
- wp setup
17
- ```
19
+ - **Agents keep context.** The `wp_*` MCP tools return summary-first JSON
20
+ (failures + `bytes` + `tokensSaved`), not thousand-line logs.
21
+ - **Docs, plans, and code can't silently diverge.** Every audit runs as both an
22
+ MCP tool and a pre-commit/CI gate.
23
+ - **Zero hand-wiring onboarding.** `wp setup` scaffolds the quality config and
24
+ keeps `AGENTS.md` / `CLAUDE.md` plus per-agent surfaces in sync.
25
+
26
+ ## Quick start
18
27
 
19
- That's the product.
28
+ Requires Node.js 24 or newer. No private registry setup is required.
20
29
 
21
- No private registry setup is required.
30
+ ```bash
31
+ npm install -g @webpresso/agent-kit && wp setup
32
+ ```
22
33
 
23
- If you do not want a global install, run it one-shot instead:
34
+ Prefer not to install globally? Run it one-shot:
24
35
 
25
36
  ```bash
26
37
  npm exec --yes --package @webpresso/agent-kit@latest -- wp setup
27
38
  ```
28
39
 
29
- `wp setup` is safe to run again. It refreshes the webpresso-owned pieces,
30
- creates the default `base-kit` quality scaffold when files are absent, and
31
- preserves consumer-owned files.
40
+ **Success signal:** `wp setup` completes and is idempotent. On a fresh repo it
41
+ scaffolds the `base-kit` quality assets (`tsconfig`, Vitest, Oxlint, Stryker,
42
+ Playwright, unit-test and file-based e2e smoke assets), wires `AGENTS.md` /
43
+ `CLAUDE.md` plus per-agent command/skill/hook surfaces, and prints
44
+ execution-owned vs authoring-owned dependency migration guidance. Re-running
45
+ refreshes the webpresso-owned pieces and preserves consumer-owned files.
32
46
 
33
- The guarantee is **zero hand-wiring**, not zero local dependencies. Fresh repos
34
- get starter `tsconfig`, Vitest, Oxlint, Stryker, Playwright, unit-test, and
35
- file-based e2e smoke assets. Repos still keep authoring-time dependencies that
36
- their configs and tests import directly.
47
+ `wp` owns **execution** for the generic tool lanes it manages (test / mutation /
48
+ e2e / lint / format / typecheck). That does **not** mean every local
49
+ devDependency disappears keep dependencies your repo imports directly (e.g.
50
+ `vitest`, `@playwright/test`, `typescript`); review execution-only binaries
51
+ (e.g. `oxlint`, `oxfmt`) for removal only when nothing imports them. See
52
+ [`docs/getting-started.md`](docs/getting-started.md).
37
53
 
38
- Default workstation presets are separate from repo bootstrap. `omx`, `omc`,
39
- `gstack`, `vision`, `rtk`, and `context-mode` are requested by default and
40
- degrade with explicit skipped/warning output when the matching host or auth is
41
- unavailable. The repo bootstrap is `base-kit`.
54
+ Verify install claims against the packed artifact:
55
+
56
+ ```bash
57
+ vp run public:consumer-smoke -- --setup-only
58
+ ```
42
59
 
43
- ### Execution-owned vs authoring-owned dependencies
60
+ ## Features
44
61
 
45
- `wp` now owns **execution** for the generic tool lanes it manages:
62
+ | Capability | What it does | Proof |
63
+ | --- | --- | --- |
64
+ | **`wp setup` onboarding** | Idempotent scaffolder for the base-kit quality config + `AGENTS.md` / `CLAUDE.md` wiring | [`src/cli/commands/init/`](src/cli/commands/init/), verified by [`scripts/public-consumer-smoke.ts`](scripts/public-consumer-smoke.ts) |
65
+ | **Summary-first `wp_*` MCP tools** | `wp_test` / `wp_typecheck` / `wp_lint` / `wp_qa` / `wp_e2e` / `wp_format` / `wp_ci_act` / `wp_audit` return JSON with `bytes` / `tokensSaved` budget metadata | [`src/mcp/tools/`](src/mcp/tools/) (each with co-located `.test.ts`), [`src/mcp/server.integration.test.ts`](src/mcp/server.integration.test.ts) |
66
+ | **MCP server + CLI surface** | Registers the tool set and exposes it to agents | [`src/mcp/server.ts`](src/mcp/server.ts), [`src/mcp/cli.ts`](src/mcp/cli.ts), [`src/mcp/cli.integration.test.ts`](src/mcp/cli.integration.test.ts) |
67
+ | **Blueprint runtime** | Lifecycle states, dependency-aware task graph, structured authoring control plane (`wp_blueprint_depgraph` / `put` / `transition`) | [`src/mcp/blueprint-server.ts`](src/mcp/blueprint-server.ts), [`docs/lifecycle.md`](docs/lifecycle.md), [`docs/blueprint-format.md`](docs/blueprint-format.md) |
68
+ | **Audit contract family** | `blueprint-lifecycle`, `docs-frontmatter`, `catalog-drift`, `vision`, `architecture-drift`, `bundle-budget`, `commit-message` (Lore), `tech-debt`, `absolute-path-policy`, `open-source-licenses`, … — each runs as a `wp_audit` MCP tool **and** a pre-commit/CI gate | [`src/audit/`](src/audit/), [`src/mcp/tools/audit.ts`](src/mcp/tools/audit.ts), [`.github/workflows/ci.webpresso.yml`](.github/workflows/ci.webpresso.yml) |
69
+ | **Symlinker** | Syncs canonical `.agent/` to per-IDE surfaces (Codex/Amp skills, Gemini TOML commands) via rulesync | [`src/symlinker/index.ts`](src/symlinker/index.ts), [`src/symlinker/symlinker.integration.test.ts`](src/symlinker/symlinker.integration.test.ts), [`docs/symlinker.md`](docs/symlinker.md) |
70
+ | **Mutation testing** | `wp audit mutation` (Stryker) catches tests that pass without asserting | [`src/config/stryker/`](src/config/stryker/), `./stryker` + `./mutation` exports |
71
+ | **Tech-debt lifecycle** | `accepted → needs-remediation → monitoring → resolved`, auto-filed from failing audits | [`src/blueprint/tech-debt/`](src/blueprint/tech-debt/), [`src/cli/commands/tech-debt/`](src/cli/commands/tech-debt/) |
72
+ | **Shared config subpaths** | `tsconfig/*`, `vitest/*`, `oxlint/*`, `workers-test`, `test-preset`, `e2e-preset`, `docs-lint`, `launch` | [`package.json` exports](package.json), [`src/config/`](src/config/) |
73
+ | **Claude Code plugin** | Ships as a plugin; `vp run lint:pkg` runs `claude plugin validate .` | `.claude-plugin/` (in `package.json#files`) |
46
74
 
47
- - test / mutation
48
- - e2e
49
- - lint
50
- - format
51
- - typecheck
75
+ ## Architecture
52
76
 
53
- That does **not** mean every local devDependency should disappear.
77
+ ```
78
+ ┌──────────────────────────────────────────┐
79
+ AI agent ───▶ │ MCP server (summary-first wp_* tools) │
80
+ (Claude / │ test · typecheck · lint · qa · e2e · │
81
+ Codex) │ format · ci-act · audit · blueprint_* │
82
+ └───────────────┬──────────────────────────┘
83
+ human ───▶ wp CLI ──────┤ (same logic, shell surface)
84
+
85
+ ┌────────────┬───────────────┬───────────────┬─────────────┐
86
+ │ Blueprints │ Audit family │ Symlinker │ base-kit │
87
+ │ lifecycle │ MCP + CI gate │ .agent/ → IDEs │ scaffold │
88
+ └────────────┴───────────────┴───────────────┴─────────────┘
89
+ ```
54
90
 
55
- - Keep local dependencies that your repo **imports directly** from tests,
56
- config files, or tsconfig types for example `vitest`,
57
- `@playwright/test`, `@testing-library/jest-dom`, or `typescript`.
58
- - Review execution-only binaries for removal **only if** they were installed
59
- just to invoke them locally and nothing imports them directly — for example
60
- `oxlint`, `oxfmt`, or `markdownlint-cli2`.
91
+ Two properties make it *agent-grade*: output is **summary-first** (agents keep
92
+ context) and tooling is **enforced** (pre-commit + CI gates, not just
93
+ available). See [`docs/qa-output.md`](docs/qa-output.md) and
94
+ [`VISION.md`](./VISION.md).
61
95
 
62
- `wp setup` prints this migration guidance after scaffolding so consumers do not
63
- accidentally strip authoring-time dependencies just because `wp` can execute
64
- the tool.
96
+ ## Verify
65
97
 
66
- Public install claims are checked against the packed artifact with:
98
+ **Fast contributor check** narrowest scope that proves a change:
67
99
 
68
100
  ```bash
69
- vp run public:consumer-smoke -- --setup-only
101
+ vp run typecheck # wp typecheck — no TS errors
102
+ vp run lint # wp lint (oxlint) — no violations
103
+ vp run test # unit then integration vitest suites — all green
70
104
  ```
71
105
 
72
- Use the full smoke without `--setup-only` when you want to install the generated
73
- starter dependencies and run the generated quality commands.
74
-
75
- ## What it does
76
-
77
- `wp` is the toolkit agents use to do real work in a repo. Every piece is built
78
- on two properties that make it *agent-grade* rather than yet-another-bundle:
79
- its output is **summary-first** (agents keep context) and it is **enforced**
80
- (pre-commit + CI gates, not just available).
81
-
82
- ### The toolkit
83
-
84
- - **Planning** — blueprints: markdown plans with a lifecycle
85
- (`wp audit blueprint-lifecycle`) and a dependency-aware task graph.
86
- `wp_blueprint_depgraph` returns its dependency graph (nodes + edges), and
87
- optional runtime adapters (OMX `/pll`) use those dependencies to run
88
- independent tasks in parallel.
89
- Authoring now has a structured control plane: `wp_blueprint_put` writes the
90
- blueprint from typed input and `wp_blueprint_transition` advances lifecycle
91
- state with revision-aware optimistic concurrency. A future MCP Apps editor is
92
- explicitly a follow-on enhancement layered on top of those tools, not a
93
- separate required write surface. See [`docs/lifecycle.md`](docs/lifecycle.md).
94
- - **Tests, types, lint** — `wp_test`, `wp_typecheck`, `wp_lint` over your
95
- vitest/oxlint setup.
96
- - **Mutation testing** — `wp audit mutation` (Stryker) catches tests that pass
97
- without actually asserting.
98
- - **End-to-end** — `wp_e2e` runs suite-aware Playwright flows.
99
- - **CI, locally** — `wp_ci_act` runs your GitHub Actions through `act` behind
100
- the repo secret contract.
101
- - **Docs** — `wp docs lint` and `wp audit docs-frontmatter` keep docs
102
- structured and current.
103
- - **Tech-debt** — `wp tech-debt` tracks debt through a status lifecycle
104
- (accepted → needs-remediation → monitoring → resolved), auto-filed from
105
- failing audits.
106
-
107
- ### What makes it agent-grade
108
-
109
- - **Summary-first output** — the `wp_*` MCP wrappers return summary-first JSON
110
- with clipped raw output and budget metadata (`bytes`, `tokensSaved`), and
111
- `wp setup` wires the `rtk` and `context-mode` output-filtering lanes by
112
- default (skipped in CI and via `WP_SKIP_RTK=1` / `WP_SKIP_CONTEXT_MODE=1`;
113
- never bundled in the package). Agents reason over the failure set, not the
114
- thousand-line log. See [`docs/qa-output.md`](docs/qa-output.md).
115
- - **Enforced as contracts** — `wp audit vision` keeps `VISION.md` current,
116
- `wp audit architecture-drift` keeps architecture docs aligned with the
117
- implementation they describe, `wp audit bundle-budget` caps client output,
118
- and the Lore commit protocol (`wp audit commit-message --require-lore`)
119
- records the *why* behind each change. Every audit runs as a `wp_audit` MCP
120
- tool **and** as a pre-commit and CI gate — so intent, docs, and code can't
121
- silently diverge.
122
- - **One operating contract, managed for you** — `wp` generates and keeps your
123
- `AGENTS.md`, `CLAUDE.md`, and each agent's command, skill, and hook surfaces
124
- in sync, emitted through rulesync across every supported runtime (see
125
- [`catalog/agent/rules/supported-agent-clis.md`](catalog/agent/rules/supported-agent-clis.md)).
126
- `AGENTS.md` is the standard; `wp` keeps everything around it coherent.
127
-
128
- ## Why it exists
129
-
130
- Sharing instructions across agents is largely solved: `AGENTS.md` is the
131
- standard, and emitters like rulesync fan one source out to every runtime. `wp`
132
- manages that layer for you — but the hard part of agent-driven development isn't
133
- a missing instruction file. It is keeping agents **effective** (they burn the
134
- context window on verbose tool output) and keeping the repo **correct** (docs,
135
- plans, and code drift apart as agents move fast).
136
-
137
- `wp` is the TypeScript layer for both: summary-first tooling so the window goes
138
- to code, and enforced contracts so the work stays coherent.
106
+ **Full maintainer check** (bookend run once at start, once at end):
139
107
 
140
108
  ```bash
141
- wp setup
109
+ vp run qa # build + typecheck + lint + format:check + test + lint:pkg + audits:check
142
110
  ```
143
111
 
144
- ## Add-ons
145
-
146
- Most repos should start with the default setup. Extra integrations and their
147
- default/opt-in behavior are documented in [`docs/add-ons.md`](docs/add-ons.md).
148
-
149
- ## Package references
150
-
151
- If you need config subpaths or dependency references, use the appendix:
152
- [`docs/markdown-fact-check.md`](docs/markdown-fact-check.md).
112
+ `vp run qa` exits 0 when every stage passes. The package-surface gate runs
113
+ separately as `vp run lint:pkg` (publint + attw `--pack`, plus `claude plugin
114
+ validate` when `claude` is present).
153
115
 
154
- ## Docs
116
+ ## Contribute / Security / License
155
117
 
156
- - [Getting started](docs/getting-started.md)
157
- - [Is webpresso for me?](docs/is-agent-kit-for-me.md)
158
- - [Blueprint lifecycle](docs/lifecycle.md)
159
- - [Add-ons](docs/add-ons.md)
160
- - [Blueprint format](docs/blueprint-format.md)
161
- - [Skills catalog](docs/skills-catalog.md)
118
+ - [CONTRIBUTING.md](./CONTRIBUTING.md) — setup, verify commands, Lore Commit
119
+ Protocol, and the Changesets release flow.
120
+ - [SECURITY.md](./SECURITY.md) — private vulnerability reporting.
121
+ - [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) — Contributor Covenant.
122
+ - [CHANGELOG.md](./CHANGELOG.md) — release history (Changesets-managed).
123
+ - [VISION.md](./VISION.md) — why this exists and where it's going.
124
+ - [docs/markdown-fact-check.md](./docs/markdown-fact-check.md) — appendix: fact-check of current-state documentation claims and package references.
162
125
 
163
126
  ## Status
164
127
 
package/bin/_run.js CHANGED
@@ -22,6 +22,25 @@ export const BIN_ENTRYPOINTS = {
22
22
  'docs-migrate': 'src/config/docs-lint/cli/migrate.ts',
23
23
  }
24
24
 
25
+ const LATENCY_SENSITIVE_BUILT_BINS = new Set([
26
+ 'wp-pretool-guard',
27
+ 'wp-post-tool',
28
+ 'wp-stop-qa',
29
+ 'wp-guard-switch',
30
+ 'wp-test-quality-check',
31
+ 'wp-sessionstart-routing',
32
+ 'wp-check-dev-link',
33
+ ])
34
+
35
+ const RUNTIME_BIN_ARGS = {
36
+ wp: [],
37
+ 'wp-pretool-guard': ['hook', 'pretool-guard'],
38
+ 'wp-post-tool': ['hook', 'post-tool'],
39
+ 'wp-stop-qa': ['hook', 'stop-qa'],
40
+ 'wp-guard-switch': ['hook', 'guard-switch'],
41
+ 'wp-sessionstart-routing': ['hook', 'sessionstart-routing'],
42
+ }
43
+
25
44
  function resolvePackageRoot() {
26
45
  return join(dirname(fileURLToPath(import.meta.url)), '..')
27
46
  }
@@ -38,6 +57,46 @@ function readTextIfExists(path) {
38
57
  return existsSync(path) ? readFileSync(path, 'utf8').trim() : null
39
58
  }
40
59
 
60
+ function readRuntimeManifest(repoRoot) {
61
+ const manifestPath = join(repoRoot, 'bin', 'runtime-manifest.json')
62
+ if (!existsSync(manifestPath)) return null
63
+
64
+ try {
65
+ return JSON.parse(readFileSync(manifestPath, 'utf8'))
66
+ } catch (error) {
67
+ throw new Error(
68
+ `Unable to read compiled runtime manifest at ${manifestPath}: ${
69
+ error instanceof Error ? error.message : String(error)
70
+ }`,
71
+ )
72
+ }
73
+ }
74
+
75
+ function resolveRuntimeTarget(manifest, platform, arch) {
76
+ const targets = Array.isArray(manifest?.targets) ? manifest.targets : []
77
+ return targets.find((target) => target?.os === platform && target?.cpu === arch) ?? null
78
+ }
79
+
80
+ function runtimeBinaryFilename(manifest, target) {
81
+ const binaryName = typeof manifest?.binaryName === 'string' ? manifest.binaryName : 'wp'
82
+ return target?.os === 'win32' ? `${binaryName}.exe` : binaryName
83
+ }
84
+
85
+ function runtimePackageDirName(packageName) {
86
+ return String(packageName).split('/').at(-1)
87
+ }
88
+
89
+ function resolveRuntimeBinaryCandidates(repoRoot, manifest, target) {
90
+ const filename = runtimeBinaryFilename(manifest, target)
91
+ const packageDir = runtimePackageDirName(target.packageName)
92
+ return [
93
+ join(repoRoot, 'bin', 'runtime', target.id, filename),
94
+ join(repoRoot, 'dist', 'runtime', target.id, filename),
95
+ join(repoRoot, '..', packageDir, 'bin', filename),
96
+ join(repoRoot, 'node_modules', '@webpresso', packageDir, 'bin', filename),
97
+ ]
98
+ }
99
+
41
100
  export function resolvePinnedNodeVersion(repoRoot = resolvePackageRoot()) {
42
101
  const nodeVersionFile = readTextIfExists(join(repoRoot, '.node-version'))
43
102
  if (nodeVersionFile && isExactNodeVersion(nodeVersionFile)) return nodeVersionFile
@@ -82,6 +141,66 @@ function buildSourceLaunchPlan(sourceEntrypoint, forwardedArgs) {
82
141
  }
83
142
  }
84
143
 
144
+ function shouldPreferBuiltDist(binName) {
145
+ return LATENCY_SENSITIVE_BUILT_BINS.has(binName)
146
+ }
147
+
148
+ function buildRuntimeLaunchPlan({
149
+ binName,
150
+ repoRoot,
151
+ forwardedArgs,
152
+ platform,
153
+ arch,
154
+ runtimeManifest,
155
+ runtimeBinaryExists,
156
+ runtimeBinaryPath,
157
+ forceCompiledRuntime,
158
+ }) {
159
+ const selectorArgs = RUNTIME_BIN_ARGS[binName]
160
+ if (!selectorArgs) return null
161
+
162
+ const manifest = runtimeManifest ?? readRuntimeManifest(repoRoot)
163
+ if (!manifest) return null
164
+
165
+ const target = resolveRuntimeTarget(manifest, platform, arch)
166
+ if (!target) {
167
+ if (!forceCompiledRuntime) return null
168
+ throw new Error(
169
+ `Unable to launch ${binName}: no compiled runtime target for ${platform}/${arch}.`,
170
+ )
171
+ }
172
+
173
+ const candidates = runtimeBinaryPath
174
+ ? [runtimeBinaryPath]
175
+ : resolveRuntimeBinaryCandidates(repoRoot, manifest, target)
176
+ const binaryPath = candidates.find((candidate) =>
177
+ runtimeBinaryExists ? runtimeBinaryExists(candidate) : existsSync(candidate),
178
+ )
179
+
180
+ if (!binaryPath) {
181
+ if (!forceCompiledRuntime) return null
182
+ throw new Error(
183
+ [
184
+ `Unable to launch ${binName}: compiled runtime target ${target.id} is missing.`,
185
+ `Looked for ${candidates.join(', ')}.`,
186
+ 'Run `wp hooks doctor` to diagnose the install, or rebuild/reinstall the runtime package.',
187
+ ].join(' '),
188
+ )
189
+ }
190
+
191
+ return {
192
+ mode: 'runtime',
193
+ runtime: binaryPath,
194
+ entrypoint: binaryPath,
195
+ args: [...selectorArgs, ...forwardedArgs],
196
+ env: {
197
+ ...process.env,
198
+ WP_COMPILED_RUNTIME: '1',
199
+ WP_MCP_TOOL_MODE: 'registry',
200
+ },
201
+ }
202
+ }
203
+
85
204
  export function resolveInvokedBinName(argv = process.argv.slice(1)) {
86
205
  const invoked = argv[0]
87
206
  if (typeof invoked !== 'string' || invoked.length === 0) {
@@ -94,8 +213,14 @@ export function buildLaunchPlan({
94
213
  binName,
95
214
  repoRoot = resolvePackageRoot(),
96
215
  forwardedArgs = process.argv.slice(2),
216
+ platform = process.platform,
217
+ arch = process.arch,
97
218
  builtExists,
98
219
  sourceExists,
220
+ runtimeBinaryExists,
221
+ runtimeBinaryPath,
222
+ runtimeManifest,
223
+ forceCompiledRuntime = process.env.WP_FORCE_COMPILED_RUNTIME === '1',
99
224
  nodeExecPath = process.execPath,
100
225
  currentNodeVersion = process.version,
101
226
  pinnedNodeVersion = resolvePinnedNodeVersion(repoRoot),
@@ -108,6 +233,19 @@ export function buildLaunchPlan({
108
233
  throw new Error(`Unknown webpresso bin: ${binName}`)
109
234
  }
110
235
 
236
+ const runtimePlan = buildRuntimeLaunchPlan({
237
+ binName,
238
+ repoRoot,
239
+ forwardedArgs,
240
+ platform,
241
+ arch,
242
+ runtimeManifest,
243
+ runtimeBinaryExists,
244
+ runtimeBinaryPath,
245
+ forceCompiledRuntime,
246
+ })
247
+ if (runtimePlan) return runtimePlan
248
+
111
249
  const builtRelativePath = sourceToBuiltRelativePath(sourceRelativePath)
112
250
  const builtEntrypoint = join(repoRoot, builtRelativePath)
113
251
  const sourceEntrypoint = join(repoRoot, sourceRelativePath)
@@ -121,6 +259,7 @@ export function buildLaunchPlan({
121
259
  sourceMtimeMs ??
122
260
  (sourceExists === undefined && hasSource ? statSync(sourceEntrypoint).mtimeMs : null)
123
261
  const shouldPreferSource =
262
+ !shouldPreferBuiltDist(binName) &&
124
263
  hasSource &&
125
264
  typeof resolvedBuiltMtimeMs === 'number' &&
126
265
  typeof resolvedSourceMtimeMs === 'number' &&
@@ -183,7 +322,10 @@ export function buildLaunchPlan({
183
322
 
184
323
  export function runNamedBin(binName, argv = process.argv.slice(2)) {
185
324
  const plan = buildLaunchPlan({ binName, forwardedArgs: argv })
186
- const child = spawnSync(plan.runtime, plan.args, { stdio: 'inherit' })
325
+ const child = spawnSync(plan.runtime, plan.args, {
326
+ stdio: 'inherit',
327
+ env: plan.env ?? process.env,
328
+ })
187
329
 
188
330
  if (child.error) {
189
331
  const detail =
@@ -0,0 +1,40 @@
1
+ {
2
+ "binaryName": "wp",
3
+ "targets": [
4
+ {
5
+ "id": "darwin-arm64",
6
+ "bunTarget": "bun-darwin-arm64",
7
+ "os": "darwin",
8
+ "cpu": "arm64",
9
+ "packageName": "@webpresso/agent-kit-runtime-darwin-arm64"
10
+ },
11
+ {
12
+ "id": "darwin-x64",
13
+ "bunTarget": "bun-darwin-x64",
14
+ "os": "darwin",
15
+ "cpu": "x64",
16
+ "packageName": "@webpresso/agent-kit-runtime-darwin-x64"
17
+ },
18
+ {
19
+ "id": "linux-x64",
20
+ "bunTarget": "bun-linux-x64",
21
+ "os": "linux",
22
+ "cpu": "x64",
23
+ "packageName": "@webpresso/agent-kit-runtime-linux-x64"
24
+ },
25
+ {
26
+ "id": "linux-arm64",
27
+ "bunTarget": "bun-linux-arm64",
28
+ "os": "linux",
29
+ "cpu": "arm64",
30
+ "packageName": "@webpresso/agent-kit-runtime-linux-arm64"
31
+ },
32
+ {
33
+ "id": "windows-x64",
34
+ "bunTarget": "bun-windows-x64",
35
+ "os": "win32",
36
+ "cpu": "x64",
37
+ "packageName": "@webpresso/agent-kit-runtime-windows-x64"
38
+ }
39
+ ]
40
+ }
@@ -34,7 +34,7 @@ vp install && vp run setup:agent # setup:agent runs wp setup, which scaffolds .
34
34
  ```
35
35
 
36
36
  agent-kit's catalog is the single source of truth for generated agent surfaces.
37
- `wp` is the canonical public CLI surface for setup, sync, and repo automation.
37
+ Agent-kit owns the generated agent surfaces in this file; the Webpresso CLI host owns the end-user command surface.
38
38
  To customize skills, commands, or workflows, edit them in agent-kit's catalog
39
39
  and publish — not in individual repos. The default `omx` preset chains
40
40
  `omx setup --yes --scope user` and installs missing OMX through
@@ -52,7 +52,7 @@ Tracked vs ignored rule of thumb:
52
52
  `.agents/`, generated `.claude/rules/`, `.claude/skills/`,
53
53
  `.claude/worktrees/`, editor-local state, and other runtime projections).
54
54
 
55
- `wp setup` / `wp sync` are the canonical bootstrap commands.
55
+ Current-state bootstrap commands remain `wp setup` / `wp sync`; future unified CLI replacements are `webpresso agent setup` / `webpresso agent sync`.
56
56
 
57
57
  ## Plan
58
58
 
@@ -96,7 +96,7 @@ behavior and any broader checks this repo requires. Typical gates are:
96
96
  - repo policy checks such as `verify:paths` / `verify:secrets` when setup
97
97
  scaffolded them
98
98
  - docs or blueprint validation when docs/plans changed
99
- - `wp sync --check` after `wp setup` to verify surfaces are in sync
99
+ - `wp sync --check` after `wp setup` to verify surfaces are in sync today; treat `webpresso agent setup` / `webpresso agent sync` as the future cutover replacements
100
100
 
101
101
  If a gate fails, fix the root cause or record the blocker with evidence.
102
102
 
@@ -145,9 +145,10 @@ this block is preserved verbatim across `wp sync` runs.
145
145
  ## Durable planning surface
146
146
 
147
147
  - Materialized by setup: blueprint lifecycle directories under
148
- `{{BLUEPRINTS_DIR}}/` (`planned/`, `in-progress/`, `completed/`) and durable
149
- plan files under `{{DURABLE_PLANNING_ROOT}}plans/` when PRDs or test specs
150
- are generated.
148
+ `{{BLUEPRINTS_DIR}}/` (`planned/`, `in-progress/`, `completed/`).
149
+ - PRDs, test specs, and other blueprint-owned planning artifacts should live
150
+ under the configured blueprint root (`{{BLUEPRINTS_DIR}}/`), colocated with
151
+ the blueprint they refine, rather than under the durable planning root.
151
152
  - Generated on demand (not created by setup): boundary contracts at
152
153
  `{{DURABLE_PLANNING_ROOT}}contracts/`, lifecycle state at
153
154
  `{{DURABLE_PLANNING_ROOT}}state/`, session notes at
@@ -20,7 +20,7 @@ Refine a blueprint by applying the canonical plan-refine methodology to the actu
20
20
 
21
21
  ## What This Command Does
22
22
 
23
- Edits `blueprints/*/<slug>/_overview.md` so the blueprint is:
23
+ Edits the canonical blueprint markdown (`blueprints/*/<slug>.md` by default, or `blueprints/*/<slug>/_overview.md` for folder-shaped plans) so the blueprint is:
24
24
 
25
25
  - fact-checked against current docs and repo reality
26
26
  - aligned with planning and testing rules
@@ -32,7 +32,7 @@ Edits `blueprints/*/<slug>/_overview.md` so the blueprint is:
32
32
  ### Step 1: Locate the blueprint
33
33
 
34
34
  ```bash
35
- find blueprints -name "_overview.md" -path "*/$SLUG/*"
35
+ find blueprints \\( -path "*/$SLUG.md" -o -path "*/$SLUG/_overview.md" \\)
36
36
  ```
37
37
 
38
38
  If no matching blueprint exists, stop and report that.
@@ -83,7 +83,7 @@ Run the blueprint parser check:
83
83
  wp blueprint show <slug>
84
84
  ```
85
85
 
86
- If the refinement changes markdown structure enough to warrant a lint pass, also run your repo's markdown linter against `blueprints/*/<slug>/_overview.md` (for example, `just lint-md` with webpresso's just recipes).
86
+ If the refinement changes markdown structure enough to warrant a lint pass, also run your repo's markdown linter against the canonical blueprint markdown for that slug (for example, `just lint-md` with webpresso's just recipes).
87
87
 
88
88
  ### Step 6: Report the outcome
89
89
 
@@ -41,6 +41,7 @@ It does three things:
41
41
 
42
42
  ```text
43
43
  /pll tasks.md
44
+ /pll blueprints/in-progress/my-blueprint.md
44
45
  /pll blueprints/in-progress/my-blueprint/_overview.md
45
46
  ```
46
47
 
@@ -162,6 +163,7 @@ If the model would diverge between the two surfaces, fix the contract instead of
162
163
  ```text
163
164
  /pll "lint auth, lint utils, typecheck auth [depends: 1], test auth [depends: 3]"
164
165
 
166
+ /pll blueprints/in-progress/converge-omx-and-blueprint-planning-surfaces.md
165
167
  /pll blueprints/in-progress/converge-omx-and-blueprint-planning-surfaces/_overview.md
166
168
 
167
169
  /pll
@@ -22,6 +22,8 @@ wp blueprint start <slug>
22
22
  wp blueprint show <slug>
23
23
 
24
24
  # 3. Execute via the parallel orchestration surface
25
+ /pll blueprints/in-progress/<slug>.md
26
+ # or, for folder-shaped blueprints:
25
27
  /pll blueprints/in-progress/<slug>/_overview.md
26
28
 
27
29
  # 4. Monitor and complete
@@ -7,7 +7,7 @@ scope: repo
7
7
  applies_to: [agents, humans]
8
8
  related: [blueprint-scoping]
9
9
  created: '2026-05-11'
10
- last_reviewed: '2026-05-11'
10
+ last_reviewed: '2026-05-31'
11
11
  ---
12
12
 
13
13
  # Extraction parity — byte-identity + mutation-score verification
@@ -144,6 +144,32 @@ Reference in the blueprint overview:
144
144
 
145
145
  ---
146
146
 
147
+ ## 5. Deploy-contract relocation parity
148
+
149
+ If the relocation touches shared deploy-contract material (workflow templates,
150
+ policy docs, fixtures, or verifier handoff docs), parity evidence must also
151
+ state that these semantics remained unchanged:
152
+
153
+ - internal lane IDs stay internal and remain exactly `dev`, `preview_main`,
154
+ `preview_pr_<n>`, and `prd`;
155
+ - cloud/provider-facing environment names are derived separately and must be
156
+ dash-safe rather than reusing the internal lane IDs as public contract;
157
+ - Durable Object-backed previews do **not** rely on provider Preview URLs;
158
+ custom-domain environment previews are the default and `workers_dev_env` is
159
+ exception-only;
160
+ - production release metadata stays anchored at
161
+ `infra/release-metadata.production.json`;
162
+ - migration-bearing Durable Object releases fail closed in the consuming
163
+ repo's deploy verifier/workflow;
164
+ - provider-specific deployment plumbing does not move into shared
165
+ `@webpresso/agent-kit` surfaces during the extraction.
166
+
167
+ When any of the above changes intentionally, the move is no longer "pure
168
+ relocation" and the blueprint must document the contract delta explicitly
169
+ instead of claiming parity.
170
+
171
+ ---
172
+
147
173
  ## Why this rule exists
148
174
 
149
175
  Task 1.4 of the `fold-webpresso-quality-engine-into-webpresso`