@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +87 -124
- package/bin/_run.js +143 -1
- package/bin/runtime-manifest.json +40 -0
- package/catalog/AGENTS.md.tpl +7 -6
- package/catalog/agent/commands/plan-refine.md +3 -3
- package/catalog/agent/commands/pll.md +2 -0
- package/catalog/agent/guides/parallel-execution.md +2 -0
- package/catalog/agent/rules/extraction-parity.md +27 -1
- package/catalog/agent/rules/public-package-safety.md +24 -1
- package/catalog/agent/skills/pll/SKILL.md +1 -0
- package/catalog/base-kit/.github/workflows/ci.webpresso.yml.tmpl +33 -0
- package/catalog/base-kit/stryker.config.ts.tmpl +2 -2
- package/catalog/docs/templates/blueprint.md +1 -0
- package/catalog/docs/templates/blueprint.yaml +10 -12
- package/commands/blueprint.md +8 -43
- package/dist/esm/audit/blueprint-db-consistency.d.ts +1 -1
- package/dist/esm/audit/blueprint-db-consistency.js +6 -8
- package/dist/esm/audit/blueprint-lifecycle-sql.js +10 -3
- package/dist/esm/audit/cloudflare-deploy-contract.d.ts +3 -0
- package/dist/esm/audit/cloudflare-deploy-contract.js +64 -0
- package/dist/esm/audit/no-legacy-cli-bin.d.ts +3 -0
- package/dist/esm/audit/no-legacy-cli-bin.js +100 -0
- package/dist/esm/audit/package-surface.js +14 -1
- package/dist/esm/audit/repo-guardrails.js +40 -13
- package/dist/esm/audit/roadmap-links.js +23 -10
- package/dist/esm/blueprint/core/schema.d.ts +8 -8
- package/dist/esm/blueprint/core/schema.js +2 -2
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/db/ingester.js +18 -10
- package/dist/esm/blueprint/lifecycle/audit.js +9 -2
- package/dist/esm/blueprint/lifecycle/local.js +15 -4
- package/dist/esm/blueprint/service/BlueprintCreationService.js +11 -6
- package/dist/esm/blueprint/service/BlueprintService.js +37 -19
- package/dist/esm/blueprint/service/scanner.js +73 -9
- package/dist/esm/blueprint/tracked-document/schema.d.ts +2 -2
- package/dist/esm/blueprint/utils/document-paths.d.ts +23 -0
- package/dist/esm/blueprint/utils/document-paths.js +91 -0
- package/dist/esm/build/package-manifest.js +7 -0
- package/dist/esm/build/release-policy.d.ts +27 -0
- package/dist/esm/build/release-policy.js +29 -0
- package/dist/esm/build/runtime-targets.d.ts +13 -0
- package/dist/esm/build/runtime-targets.js +48 -0
- package/dist/esm/cli/auto-update/detect-pm.d.ts +15 -0
- package/dist/esm/cli/auto-update/detect-pm.js +24 -9
- package/dist/esm/cli/auto-update/skip.js +9 -1
- package/dist/esm/cli/bundle/agent-command-inventory.d.ts +120 -0
- package/dist/esm/cli/bundle/agent-command-inventory.js +100 -0
- package/dist/esm/cli/bundle/index.d.ts +17 -0
- package/dist/esm/cli/bundle/index.js +15 -0
- package/dist/esm/cli/cli.d.ts +1 -1
- package/dist/esm/cli/cli.js +49 -5
- package/dist/esm/cli/commands/audit-core.d.ts +1 -1
- package/dist/esm/cli/commands/audit.js +2 -0
- package/dist/esm/cli/commands/blueprint/router.js +11 -8
- package/dist/esm/cli/commands/hook.d.ts +8 -0
- package/dist/esm/cli/commands/hook.js +47 -0
- package/dist/esm/cli/commands/init/index.js +35 -1
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +1 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/codex-ownership.js +9 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +130 -20
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +65 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +64 -0
- package/dist/esm/cli/commands/package-manager.d.ts +15 -0
- package/dist/esm/cli/commands/package-manager.js +42 -0
- package/dist/esm/cli/commands/test.d.ts +1 -0
- package/dist/esm/cli/commands/test.js +2 -1
- package/dist/esm/cli/commands/typecheck.js +5 -20
- package/dist/esm/cli/package-scripts.d.ts +12 -0
- package/dist/esm/cli/package-scripts.js +59 -0
- package/dist/esm/cli/utils.js +3 -22
- package/dist/esm/cli/wp-extensions.d.ts +14 -0
- package/dist/esm/cli/wp-extensions.js +34 -0
- package/dist/esm/config/docs-lint/schemas/common.d.ts +1 -1
- package/dist/esm/config/docs-lint/schemas/implementation-plan.d.ts +2 -2
- package/dist/esm/config/docs-lint/schemas/parent-roadmap.d.ts +1 -1
- package/dist/esm/config/stryker/index.d.ts +85 -0
- package/dist/esm/config/stryker/index.js +31 -0
- package/dist/esm/e2e/command-builder.js +11 -2
- package/dist/esm/e2e/config.d.ts +56 -0
- package/dist/esm/e2e/config.js +114 -0
- package/dist/esm/e2e/execution.js +4 -0
- package/dist/esm/e2e/run-planner.js +1 -0
- package/dist/esm/e2e/types.d.ts +2 -0
- package/dist/esm/format/index.js +1 -3
- package/dist/esm/hooks/guard-switch/index.d.ts +1 -1
- package/dist/esm/hooks/guard-switch/index.js +22 -14
- package/dist/esm/hooks/post-tool/lint-after-edit.d.ts +1 -0
- package/dist/esm/hooks/post-tool/lint-after-edit.js +5 -2
- package/dist/esm/hooks/pretool-guard/validators/file-conventions.js +1 -1
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.d.ts +6 -0
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +27 -2
- package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +2 -1
- package/dist/esm/hooks/pretool-guard/validators/path-contract.js +59 -34
- package/dist/esm/hooks/pretool-guard/validators/plan-frontmatter.js +3 -3
- package/dist/esm/hooks/shared/routing-block.js +18 -4
- package/dist/esm/hooks/shared/validators/blueprint.js +3 -0
- package/dist/esm/hooks/stop/qa-changed-files.d.ts +1 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +5 -2
- package/dist/esm/lint/index.js +1 -1
- package/dist/esm/mcp/auto-discover.d.ts +2 -0
- package/dist/esm/mcp/auto-discover.js +14 -6
- package/dist/esm/mcp/blueprint-server.js +30 -26
- package/dist/esm/mcp/cli.js +21 -0
- package/dist/esm/mcp/runners/test.js +15 -0
- package/dist/esm/mcp/server.d.ts +7 -0
- package/dist/esm/mcp/server.js +16 -27
- package/dist/esm/mcp/tools/_registry.d.ts +3 -0
- package/dist/esm/mcp/tools/_registry.js +21 -0
- package/dist/esm/mcp/tools/audit.d.ts +1 -0
- package/dist/esm/mcp/tools/audit.js +11 -0
- package/dist/esm/mcp/tools/e2e.d.ts +1 -1
- package/dist/esm/mcp/tools/typecheck.js +4 -2
- package/dist/esm/mutation/affected.d.ts +9 -0
- package/dist/esm/mutation/affected.js +36 -0
- package/dist/esm/package.json +5 -0
- package/dist/esm/runtime/package-version.d.ts +2 -0
- package/dist/esm/runtime/package-version.js +43 -0
- package/dist/esm/test/command-builder.d.ts +3 -0
- package/dist/esm/test/command-builder.js +22 -3
- package/dist/esm/tool-runtime/index.d.ts +2 -2
- package/dist/esm/tool-runtime/index.js +2 -1
- package/dist/esm/tool-runtime/resolve-runner.d.ts +3 -0
- package/dist/esm/tool-runtime/resolve-runner.js +7 -5
- package/dist/esm/typecheck/index.js +4 -2
- package/dist/esm/wp-extension/index.d.ts +50 -0
- package/dist/esm/wp-extension/index.js +268 -0
- package/package.json +67 -31
- 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.
|
|
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.
|
|
26
|
+
"version": "0.23.0"
|
|
27
27
|
}
|
package/README.md
CHANGED
|
@@ -1,164 +1,127 @@
|
|
|
1
1
|
# @webpresso/agent-kit
|
|
2
2
|
|
|
3
|
+
[](./LICENSE)
|
|
4
|
+
[](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
|
-
##
|
|
11
|
+
## What it is
|
|
9
12
|
|
|
10
|
-
|
|
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
|
-
|
|
17
|
+
## Why use it
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
28
|
+
Requires Node.js 24 or newer. No private registry setup is required.
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g @webpresso/agent-kit && wp setup
|
|
32
|
+
```
|
|
22
33
|
|
|
23
|
-
|
|
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`
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
Verify install claims against the packed artifact:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
vp run public:consumer-smoke -- --setup-only
|
|
58
|
+
```
|
|
42
59
|
|
|
43
|
-
|
|
60
|
+
## Features
|
|
44
61
|
|
|
45
|
-
|
|
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
|
-
|
|
48
|
-
- e2e
|
|
49
|
-
- lint
|
|
50
|
-
- format
|
|
51
|
-
- typecheck
|
|
75
|
+
## Architecture
|
|
52
76
|
|
|
53
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
63
|
-
accidentally strip authoring-time dependencies just because `wp` can execute
|
|
64
|
-
the tool.
|
|
96
|
+
## Verify
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
**Fast contributor check** — narrowest scope that proves a change:
|
|
67
99
|
|
|
68
100
|
```bash
|
|
69
|
-
vp run
|
|
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
|
-
|
|
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
|
-
|
|
109
|
+
vp run qa # build + typecheck + lint + format:check + test + lint:pkg + audits:check
|
|
142
110
|
```
|
|
143
111
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
##
|
|
116
|
+
## Contribute / Security / License
|
|
155
117
|
|
|
156
|
-
- [
|
|
157
|
-
|
|
158
|
-
- [
|
|
159
|
-
- [
|
|
160
|
-
- [
|
|
161
|
-
- [
|
|
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, {
|
|
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
|
+
}
|
package/catalog/AGENTS.md.tpl
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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/`)
|
|
149
|
-
|
|
150
|
-
|
|
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 -
|
|
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
|
|
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-
|
|
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`
|