@event4u/agent-config 10.3.0 → 10.4.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 +1 -1
- package/CHANGELOG.md +78 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze.md +2 -1
- package/dist/agent-src/commands/design-system/capture.md +44 -0
- package/dist/agent-src/commands/design-system/generate.md +53 -0
- package/dist/agent-src/commands/design-system/import.md +63 -0
- package/dist/agent-src/commands/design-system.md +66 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +9 -0
- package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +70 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
- package/dist/cli-delegate/chunk-RLN73PR5.js +157 -0
- package/dist/cli-delegate/{chunk-I5EAFRII.js → chunk-ZPSXJTLI.js} +2 -154
- package/dist/cli-delegate/cmd_conformance.js +671 -213
- package/dist/cli-delegate/cmd_handoff.js +8 -6
- package/dist/cli-delegate/cmd_session_recycle.js +5 -3
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +116 -11
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +9 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +8 -4
- package/dist/hooks/dispatch.js +940 -387
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1102 -592
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +4 -1
- package/src/config/gate-coverage.yml +23 -2
- package/src/config/gate-violation-baselines.json +2 -2
- package/src/scripts/_lib/design_system_import.ts +987 -0
- package/src/scripts/design_system_import.ts +264 -0
- package/src/scripts/hook_manifest.yaml +71 -2
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/dispatch_hook.ts +10 -0
- package/src/scripts/hooks/host_semantics.ts +2 -0
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +212 -0
- package/src/scripts/hooks/subagent_ledger_hook.ts +723 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +39 -2
- package/src/scripts/lint_hook_manifest.ts +2 -0
- package/src/scripts/lint_rule_skill_pack_reach.ts +194 -13
- package/tests/fixtures/hooks/subagent_start.json +7 -0
- package/tests/fixtures/hooks/subagent_stop.json +8 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
|
|
9
|
-
"version": "10.
|
|
9
|
+
"version": "10.4.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"agent-config",
|
|
12
12
|
"skills",
|
package/CHANGELOG.md
CHANGED
|
@@ -348,6 +348,84 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
|
|
|
348
348
|
> that forces a new era split (`# Era: 10.4.x`, etc.) — see
|
|
349
349
|
> [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
|
|
350
350
|
|
|
351
|
+
## [10.4.0](https://github.com/event4u-app/agent-config/compare/10.3.0...10.4.0) (2026-08-13)
|
|
352
|
+
|
|
353
|
+
### Release highlights
|
|
354
|
+
|
|
355
|
+
<!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
|
|
356
|
+
- **Behaviour changes:** _none_
|
|
357
|
+
- **Default changes + migration:** _none_
|
|
358
|
+
- **Security and correctness:** _none_
|
|
359
|
+
- **Honest nulls:** _auto-derived, rewrite before merge:_ commits carrying an honest-null marker in 5a9f530.
|
|
360
|
+
- **Known limitations:** _none_
|
|
361
|
+
|
|
362
|
+
### Features
|
|
363
|
+
|
|
364
|
+
* **commands:** /design-system cluster — three doors onto machinery that already ships ([e56eaf4](https://github.com/event4u-app/agent-config/commit/e56eaf4a5496bed575e421df997ad60bd2cfac08))
|
|
365
|
+
* **scripts:** three-lane adapter into the design-system.json contract ([d1dd006](https://github.com/event4u-app/agent-config/commit/d1dd00610d4c2c97aa5adf0fa7baa120167b6aa2))
|
|
366
|
+
* **hooks:** an open subagent dispatch is an explicit turn-end allow ([39daf4e](https://github.com/event4u-app/agent-config/commit/39daf4e2c3ba70fa4e43b57fc82bc1bf9eb5b613))
|
|
367
|
+
* **hooks:** ship Phase 3 runaway containment in shadow posture ([b9efa4e](https://github.com/event4u-app/agent-config/commit/b9efa4ec618b3f26c1c07a8eb335866545c4274c))
|
|
368
|
+
* **hooks:** register subagent lifecycle events and bind the ledger ([a6a4023](https://github.com/event4u-app/agent-config/commit/a6a4023529074069f03f8542d0513ee77f3adfde))
|
|
369
|
+
* **hooks:** add the capture-only subagent-ledger concern ([f393ec4](https://github.com/event4u-app/agent-config/commit/f393ec4686422d247bc5862cf13e04459d64ace5))
|
|
370
|
+
* **gates:** adopt the self-test harness in lint_rule_skill_pack_reach ([a758153](https://github.com/event4u-app/agent-config/commit/a7581533b8d5ed8672f985337dc87d21508fa451))
|
|
371
|
+
|
|
372
|
+
### Bug Fixes
|
|
373
|
+
|
|
374
|
+
* **design-system:** drop maintainer-only invocations from shipped surfaces ([122760a](https://github.com/event4u-app/agent-config/commit/122760aad5f2a6f4a19c7571da5fcfb732e5e1a8))
|
|
375
|
+
* **scripts:** close nine silent-loss paths in the design-system import adapter ([ed4c7e3](https://github.com/event4u-app/agent-config/commit/ed4c7e39ad3bd732b034c24952460332bb7cb503))
|
|
376
|
+
* **docs:** regenerate proof.md after the command-count change ([c5cb075](https://github.com/event4u-app/agent-config/commit/c5cb07529d8e1903ad15bbf300ce4156fb5a11b2))
|
|
377
|
+
* **ci:** wire check_gate_coverage locally too, and correct three numbers ([a62745c](https://github.com/event4u-app/agent-config/commit/a62745cea249ace8e89a453e9f5950e7179721ce))
|
|
378
|
+
* **ci:** wire the two meta-gates, re-anchor the parity floor ([ea13fc7](https://github.com/event4u-app/agent-config/commit/ea13fc77f2cceecc127933b7f56a5fbcc5a07709))
|
|
379
|
+
* **commands:** register analyze:conformance in the table it already belonged in ([2c307f3](https://github.com/event4u-app/agent-config/commit/2c307f392061eb4ff24a15b1c29b7ddc5c162b71))
|
|
380
|
+
* **hooks:** close the round-2 completion-review findings ([a3de33b](https://github.com/event4u-app/agent-config/commit/a3de33beacff72725b48e4ebdd0bb58b4258bee1))
|
|
381
|
+
* **contracts:** drop the roadmap link from the activation policy ([4d49029](https://github.com/event4u-app/agent-config/commit/4d49029266a04d8d025e110be0a574553634acea))
|
|
382
|
+
* **roadmap:** sync the Phase 2 record with the shipped floors, and own the red ([f98d9d5](https://github.com/event4u-app/agent-config/commit/f98d9d52998c016ad865334ffdf3964b4e01a8e3))
|
|
383
|
+
* **hooks:** close the twelve R2 completion-review findings in the subagent ledger ([4415ff5](https://github.com/event4u-app/agent-config/commit/4415ff54c2e8f47375aeeada5e5d9776eccefa86))
|
|
384
|
+
* **gates:** emit a parseable scan line, and refuse a valueless --root ([8ec2334](https://github.com/event4u-app/agent-config/commit/8ec2334a526572dd549b571f40bf9a24928dbd35))
|
|
385
|
+
* **refs:** re-point the archived roadmap and record a two-gate contradiction ([9671002](https://github.com/event4u-app/agent-config/commit/9671002114d27fcbd112d3f77d79dfaacc94c821))
|
|
386
|
+
* **roadmap:** tag the corpus-scoping roadmap lightweight, not standard ([b6676b0](https://github.com/event4u-app/agent-config/commit/b6676b09f87c48aa083feb98f2ff7343c837bd18))
|
|
387
|
+
|
|
388
|
+
### Documentation
|
|
389
|
+
|
|
390
|
+
* **review:** re-bind the findings artefact after the consumer-path fix ([fcb8ab4](https://github.com/event4u-app/agent-config/commit/fcb8ab408c9b2fbfd51d98e261ead5c572e5cf7a))
|
|
391
|
+
* **review:** re-bind the findings artefact after the second main merge ([cfd2695](https://github.com/event4u-app/agent-config/commit/cfd2695162708c3db80b699667dbc7108c9e057c))
|
|
392
|
+
* **review:** re-bind the findings artefact to the post-fix scope ([2674827](https://github.com/event4u-app/agent-config/commit/267482700c5d00db465722005888f823d50acc4c))
|
|
393
|
+
* **review:** re-bind the skip declaration to the merged scope ([6518a6a](https://github.com/event4u-app/agent-config/commit/6518a6a12a69bc640c70febcf36d176ae05b8992))
|
|
394
|
+
* **design-system:** correct two claims the review showed were too broad ([49b6e47](https://github.com/event4u-app/agent-config/commit/49b6e4741aa21a18c72c3f51f9775981f980bb1f))
|
|
395
|
+
* **review:** bind the R2 completion-review findings for feat-design-system-onramp ([3be0b77](https://github.com/event4u-app/agent-config/commit/3be0b771bf99816ab4b0a7d9d69c51ea8e41a848))
|
|
396
|
+
* **roadmap:** close road-to-local-only-gate-reds and archive it ([cfeeacc](https://github.com/event4u-app/agent-config/commit/cfeeacc81c2b09f18d7e5fcfd7a312b05dd0b209))
|
|
397
|
+
* **roadmap:** archive road-to-august-program on its own falsifier ([3fd5a77](https://github.com/event4u-app/agent-config/commit/3fd5a776750447e6967137be31ee76a6e1c7b4b4))
|
|
398
|
+
* **roadmap:** resolve the three release-integrity blockers and archive it ([9d66d73](https://github.com/event4u-app/agent-config/commit/9d66d73f45b28ed8c17b842ca0f730cf11ca614d))
|
|
399
|
+
* **contract:** publish the curated-head recurrence rate, (b) stands ([310b49b](https://github.com/event4u-app/agent-config/commit/310b49b1d4b5f8fe7a12d6199c84429257cc4e0c))
|
|
400
|
+
* **adr:** ADR-228 — the global install does not emit paths: ([d9bcbf5](https://github.com/event4u-app/agent-config/commit/d9bcbf5c46e7d4c100f1bceabe429c0df6b42990))
|
|
401
|
+
* **adr:** accept ADR-221, the host-native-first ladder ([a55a37f](https://github.com/event4u-app/agent-config/commit/a55a37f6f88eb08326d56a0562c22324fa1746dc))
|
|
402
|
+
* **review:** re-bind the round-2 findings after the fix pass ([f1403f1](https://github.com/event4u-app/agent-config/commit/f1403f1896b4570b6eb83c9ac0f1c28b1d504914))
|
|
403
|
+
* **review:** bind round 2 of the completion review, and keep round 1 ([7914694](https://github.com/event4u-app/agent-config/commit/7914694b9055c4b47caf5c01c49699cb1aa77f01))
|
|
404
|
+
* **design-system:** name the supply path where the contract is refused ([0bef92d](https://github.com/event4u-app/agent-config/commit/0bef92d6314c82978bce578effaff7e43e24ea6c))
|
|
405
|
+
* **roadmap:** record the Phase 3 council pass and flip its three steps ([e1c99ad](https://github.com/event4u-app/agent-config/commit/e1c99ad25ece149cd80c0879957b01702148cc00))
|
|
406
|
+
* **contracts:** write the concern activation policy three roadmaps cited and none wrote ([130a9d9](https://github.com/event4u-app/agent-config/commit/130a9d98ad691888a3d41bec71f170e8e6d853c3))
|
|
407
|
+
* **review:** re-bind the round-2 artefact to the fixed scope ([1cba2b1](https://github.com/event4u-app/agent-config/commit/1cba2b111a3759d565ec0071ee1607c7c0d6bbec))
|
|
408
|
+
* **review:** round 2 of the completion review, over the merged scope ([57e4fc5](https://github.com/event4u-app/agent-config/commit/57e4fc58491b80ce70f994963fbcaa6fbe972be4))
|
|
409
|
+
* **review:** re-bind the findings artefact after the fix pass ([b58fcd5](https://github.com/event4u-app/agent-config/commit/b58fcd59ea10b899d6feaa1b7afa632c437f3d77))
|
|
410
|
+
* **review:** bind the R2 completion-review findings for feat-subagent-lifecycle-integrity ([79b7c8e](https://github.com/event4u-app/agent-config/commit/79b7c8eb27f114ae6d40d6c168fa5c992be1b650))
|
|
411
|
+
* **review:** re-bind the completion-review artefact to the fixed scope ([c714668](https://github.com/event4u-app/agent-config/commit/c71466897e1053bc28387d3da1240a3773534a0b))
|
|
412
|
+
* **review:** R2 completion review for feat-local-only-gate-reds ([3c87378](https://github.com/event4u-app/agent-config/commit/3c87378c83b36da10a82af729ffa224d506716a8))
|
|
413
|
+
* **roadmap:** record the Phase 0/1/5 findings and the Phase 3 stop ([3fc4332](https://github.com/event4u-app/agent-config/commit/3fc433269cc36520bb10e5f08f302cdfdffc5d5a))
|
|
414
|
+
* **review:** declare the completion-review skip for a zero-code-path branch ([ac92f16](https://github.com/event4u-app/agent-config/commit/ac92f1686a44ca8d52cf652fb3c35ec71224d800))
|
|
415
|
+
* **adr:** record that paths scoping is saturated, not a corpus lever ([6c062d9](https://github.com/event4u-app/agent-config/commit/6c062d9d57e290a50b0eb544448e83b8ec03c396))
|
|
416
|
+
* **roadmap:** record the four closed steps, and a fifth red the repair left ([637c009](https://github.com/event4u-app/agent-config/commit/637c00913b9936d5ceb8fe5cdffa8eddd610ef47))
|
|
417
|
+
|
|
418
|
+
### Chores
|
|
419
|
+
|
|
420
|
+
* **dist:** re-project the design-system doc and halt-text changes ([070f4ce](https://github.com/event4u-app/agent-config/commit/070f4ce7b48ca0f206b6fae413a8f529d3f5bf0b))
|
|
421
|
+
* **roadmap:** regenerate the dashboard after the main merge ([54250e3](https://github.com/event4u-app/agent-config/commit/54250e3f6de110ba8881386e6e8c95be38b9b8d4))
|
|
422
|
+
* **roadmap:** close design-system-onramp Phases 1, 2 and 4; file two blockers ([80573dd](https://github.com/event4u-app/agent-config/commit/80573dd7d75ab27d026138e54ef06119daec59e8))
|
|
423
|
+
* **roadmaps:** regenerate the dashboard after the main merge ([d54aba9](https://github.com/event4u-app/agent-config/commit/d54aba956229302c3bc7323ddf8cafd7bd4ccb3c))
|
|
424
|
+
* **roadmap:** regenerate the dashboard after the second main merge ([b1a283b](https://github.com/event4u-app/agent-config/commit/b1a283bb04d9a881aa13495c28f0779557792670))
|
|
425
|
+
* **roadmap:** close always-loaded-corpus-scoping on its honest null ([5a9f530](https://github.com/event4u-app/agent-config/commit/5a9f53009a920ff16b9cc92e39167497a51d92ab))
|
|
426
|
+
|
|
427
|
+
Tests: 13768 (+89 since 10.3.0)
|
|
428
|
+
|
|
351
429
|
## [10.3.0](https://github.com/event4u-app/agent-config/compare/10.2.0...10.3.0) (2026-08-13)
|
|
352
430
|
|
|
353
431
|
### Release highlights
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [](https://www.npmjs.com/package/@event4u/agent-config) [](https://glama.ai/mcp/servers/event4u-app/agent-config) [](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
|
|
6
6
|
|
|
7
|
-
[](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/commands/) [](docs/guidelines/) [](dist/agent-src/personas/) [](dist/agent-src/personas/advisors/)
|
|
8
8
|
|
|
9
9
|
**Try it in 30 seconds** — drop one read-only subagent into any repo and watch it gate "done": `@production-validator check this branch is actually done`. No wizard, no lock-in, nothing else installed — the [30-second wedge ↓](#quickstart) is the whole first step. Start at the proof, not the catalog: **[event4u-app.github.io/agent-config/proof/](https://event4u-app.github.io/agent-config/proof/)**.
|
|
10
10
|
|
|
@@ -5,7 +5,7 @@ disable-model-invocation: true
|
|
|
5
5
|
argument-hint: "[postmortem|premortem|decision|near-miss|incident|reference-repo|inbox] [subject]"
|
|
6
6
|
pack: analysis-workbench
|
|
7
7
|
intent: "Analysis dispatcher — classify input by keywords, propose a weighted framework path, let the user pick"
|
|
8
|
-
routes_to: [analyze-postmortem, analyze-premortem, analyze-decision, analyze-near-miss, analyze-incident, analyze-reference-repo, analyze-inbox]
|
|
8
|
+
routes_to: [analyze-postmortem, analyze-premortem, analyze-decision, analyze-near-miss, analyze-incident, analyze-reference-repo, analyze-inbox, analyze-conformance]
|
|
9
9
|
replaces: []
|
|
10
10
|
tier: 1
|
|
11
11
|
visibility: advanced
|
|
@@ -40,6 +40,7 @@ to the chosen sub-command. Never auto-selects silently.
|
|
|
40
40
|
| `/analyze:incident` | `analyze/incident/command.md` | Full incident flow: commander → RCA → post-mortem → memory candidate |
|
|
41
41
|
| `/analyze:reference-repo` | `analyze/reference-repo/command.md` | Deep-dive an external reference repo (competitor, inspiration, peer) → structured comparison + adoption plan |
|
|
42
42
|
| `/analyze:inbox` | `analyze/inbox/command.md` | Deep-dive a LOCAL artifact dropped in `agents/tmp/` (review, prompt, spec, transcript) → claim verification against the current tree + artefact mapping + roadmap |
|
|
43
|
+
| `/analyze:conformance` | `analyze/conformance/command.md` | Audit recent local sessions for rule violations → deterministic scan + subagent passes, root-caused per class, and a roadmap for what is mechanisable |
|
|
43
44
|
|
|
44
45
|
## Dispatch
|
|
45
46
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: medium
|
|
3
|
+
name: design-system-capture
|
|
4
|
+
pack: engineering-base
|
|
5
|
+
tier: 2
|
|
6
|
+
visibility: internal
|
|
7
|
+
cluster: design-system
|
|
8
|
+
sub: capture
|
|
9
|
+
skills: [existing-ui-audit, design-system-capture]
|
|
10
|
+
description: Inventory this repo's own components and tokens and emit them in the design-system.json shape, so the import path is identical to an external extraction.
|
|
11
|
+
argument-hint: "[path]"
|
|
12
|
+
suggestion:
|
|
13
|
+
eligible: false
|
|
14
|
+
rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
|
|
15
|
+
workspaces:
|
|
16
|
+
- engineering
|
|
17
|
+
packs:
|
|
18
|
+
- frontend-design
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# /design-system:capture
|
|
22
|
+
|
|
23
|
+
Run [`existing-ui-audit`](../../skills/existing-ui-audit/SKILL.md) over the
|
|
24
|
+
current repo and emit its inventory as a `design-system.json` artifact — the
|
|
25
|
+
same shape an external extraction tool produces, so the import path is identical
|
|
26
|
+
either way. Args: optional `[path]` to narrow the scan.
|
|
27
|
+
|
|
28
|
+
Two sources, one shape: use this for **this** repo, and
|
|
29
|
+
[`/design-system:import`](../import/command.md) for a site or repo you do not
|
|
30
|
+
own.
|
|
31
|
+
|
|
32
|
+
## Then hand it over
|
|
33
|
+
|
|
34
|
+
Pass the emitted artifact to [`design-system-capture`](../../skills/design-system-capture/SKILL.md)'s
|
|
35
|
+
import step, which confirms it per field into `DESIGN.md`.
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
- **Set `source` honestly** — `kind: dir`, `ref` = the scanned path,
|
|
40
|
+
`captured_at` = now. An artifact with no provenance is rejected downstream.
|
|
41
|
+
- **Observation is not a token.** Anything the audit *noticed* rather than
|
|
42
|
+
*decided* belongs under `_meta`, per the contract's field rules.
|
|
43
|
+
- **The audit's own grouping is not the contract's shape.** Map it deliberately;
|
|
44
|
+
do not rename the audit's output keys and call it done.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: high
|
|
3
|
+
name: design-system-generate
|
|
4
|
+
pack: engineering-base
|
|
5
|
+
tier: 2
|
|
6
|
+
visibility: internal
|
|
7
|
+
cluster: design-system
|
|
8
|
+
sub: generate
|
|
9
|
+
skills: [corpus-grounding, design-intelligence, design-system-capture]
|
|
10
|
+
description: Ground a design system in the curated design corpus from a product or industry brief, then optionally persist it as MASTER.md or seed DESIGN.md.
|
|
11
|
+
argument-hint: "<product / industry / keywords>"
|
|
12
|
+
suggestion:
|
|
13
|
+
eligible: false
|
|
14
|
+
rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
|
|
15
|
+
workspaces:
|
|
16
|
+
- engineering
|
|
17
|
+
packs:
|
|
18
|
+
- frontend-design
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# /design-system:generate
|
|
22
|
+
|
|
23
|
+
Run the grounded one-shot over the curated corpus and print the full
|
|
24
|
+
recommendation. Args: `"<product / industry / keywords>"`.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx tsx node_modules/@event4u/agent-config/src/skills/corpus-grounding/scripts/ground.ts \
|
|
28
|
+
ground "<query>" \
|
|
29
|
+
--manifest node_modules/@event4u/agent-config/src/skills/design-intelligence/data/manifest.json
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Add `--persist <dir> --project-name <name>` to write
|
|
33
|
+
`design-system/<slug>/MASTER.md`, and `--page <name>` for a page-override stub
|
|
34
|
+
alongside it. The engine is read-only without `--persist`.
|
|
35
|
+
|
|
36
|
+
## After the recommendation
|
|
37
|
+
|
|
38
|
+
Offer both destinations, and let the human pick — they are different artifacts,
|
|
39
|
+
not two spellings of one:
|
|
40
|
+
|
|
41
|
+
- **`MASTER.md` + page overrides** (`--persist`) — the interchange format, good
|
|
42
|
+
for handing a system to another tool or to a designer.
|
|
43
|
+
- **`DESIGN.md`** via [`design-system-capture`](../../skills/design-system-capture/SKILL.md)
|
|
44
|
+
— this package's canonical design memory, the file every later design task
|
|
45
|
+
reads. Seed it when the system is for *this* repo's own work.
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
- **Generated output is a proposal.** A provided artifact, registered brand
|
|
50
|
+
tokens, and a confirmed `DESIGN.md` outrank it — never overwrite a confirmed
|
|
51
|
+
decision with a generated default.
|
|
52
|
+
- **Never persist silently.** `--persist` is the human's choice, and `DESIGN.md`
|
|
53
|
+
is seeded per field, not written wholesale.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: medium
|
|
3
|
+
name: design-system-import
|
|
4
|
+
pack: engineering-base
|
|
5
|
+
tier: 2
|
|
6
|
+
visibility: internal
|
|
7
|
+
cluster: design-system
|
|
8
|
+
sub: import
|
|
9
|
+
skills: [design-system-capture]
|
|
10
|
+
description: Run an extraction tool's output through the three-lane adapter into the design-system.json contract, then hand it to the per-field confirmation import.
|
|
11
|
+
argument-hint: "<file>"
|
|
12
|
+
suggestion:
|
|
13
|
+
eligible: false
|
|
14
|
+
rationale: "Cluster sub-command — reached via its cluster head's routing or its explicit /cluster:sub name; not independently suggested (surface-consolidation)."
|
|
15
|
+
workspaces:
|
|
16
|
+
- engineering
|
|
17
|
+
packs:
|
|
18
|
+
- frontend-design
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# /design-system:import
|
|
22
|
+
|
|
23
|
+
Transform an extracted design system into the `design-system.json` contract,
|
|
24
|
+
then import it per field. Args: `<file>`.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx tsx node_modules/@event4u/agent-config/src/scripts/design_system_import.ts <file> \
|
|
28
|
+
[--lane native|dtcg|dembrandt] \
|
|
29
|
+
[--source-kind url|repo|dir --source-ref <ref>] [--captured-at <ISO>] \
|
|
30
|
+
[--format json|summary]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The lane is detected from the file's own shape; `--lane` only forces which
|
|
34
|
+
mapper runs and never reshapes the input. Lane behaviour, the documented
|
|
35
|
+
producers, and the never-force-a-lane degradation are specified in
|
|
36
|
+
[`design-system-json.md`](../../skills/design-system-capture/references/design-system-json.md)
|
|
37
|
+
§ Extractor compatibility.
|
|
38
|
+
|
|
39
|
+
## The easy path, in two lines
|
|
40
|
+
|
|
41
|
+
1. Connect an extractor once — e.g.
|
|
42
|
+
`claude mcp add --transport stdio dembrandt -- npx -y --package dembrandt dembrandt-mcp`.
|
|
43
|
+
2. Run `/design-system:import` over its output.
|
|
44
|
+
|
|
45
|
+
No extractor available? Skip step 1 and use
|
|
46
|
+
[`/design-system:generate`](../generate/command.md) from the corpus instead, or
|
|
47
|
+
[`/design-system:capture`](../capture/command.md) for this repo.
|
|
48
|
+
|
|
49
|
+
## Then hand it over
|
|
50
|
+
|
|
51
|
+
Pass the result to [`design-system-capture`](../../skills/design-system-capture/SKILL.md)'s
|
|
52
|
+
import step. Do not write `DESIGN.md` from here.
|
|
53
|
+
|
|
54
|
+
## Rules
|
|
55
|
+
|
|
56
|
+
- **Provenance is mandatory.** A file with no `source` and no `--source-ref` is
|
|
57
|
+
rejected — you cannot confirm what you cannot trace. Supplying it by flag is
|
|
58
|
+
recorded as caller-asserted, not extracted.
|
|
59
|
+
- **The artifact is observed, not authoritative.** Every field is confirmed by
|
|
60
|
+
the human; a value conflicting with a registered brand token is flagged, never
|
|
61
|
+
auto-applied.
|
|
62
|
+
- **The adapter is offline.** It reads a file and writes the contract shape — it
|
|
63
|
+
never fetches, crawls, or launches a browser.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
model_tier: inherit
|
|
3
|
+
name: design-system
|
|
4
|
+
pack: engineering-base
|
|
5
|
+
tier: 2
|
|
6
|
+
visibility: internal
|
|
7
|
+
cluster: design-system
|
|
8
|
+
type: orchestrator
|
|
9
|
+
description: Design-system onramp — generate one from the corpus, import an extractor's output, or capture the current repo's. Three doors onto machinery that already ships.
|
|
10
|
+
argument-hint: "[generate|import|capture] [args]"
|
|
11
|
+
suggestion:
|
|
12
|
+
eligible: true
|
|
13
|
+
trigger_description: "generate a design system, import extracted design tokens, capture this repo's design system, seed DESIGN.md from a site"
|
|
14
|
+
trigger_context: "user explicitly wants a design system produced, imported, or captured — never suggested for ordinary UI work"
|
|
15
|
+
workspaces:
|
|
16
|
+
- engineering
|
|
17
|
+
packs:
|
|
18
|
+
- frontend-design
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# /design-system
|
|
22
|
+
|
|
23
|
+
Three doors onto machinery this package already ships and nothing could reach.
|
|
24
|
+
The grounded generator, its `MASTER.md` persistence, the `design-system.json`
|
|
25
|
+
import contract, and the current-repo inventory all existed before this cluster;
|
|
26
|
+
what was missing was a way in. So every sub-command below is an entry point, not
|
|
27
|
+
a new subsystem.
|
|
28
|
+
|
|
29
|
+
**Optional means invoked or not invoked.** This cluster adds no settings key, no
|
|
30
|
+
always-on rule, and no auto-trigger. It is suggestion-eligible only when a
|
|
31
|
+
design-system question is explicit, and otherwise silent.
|
|
32
|
+
|
|
33
|
+
## Sub-commands
|
|
34
|
+
|
|
35
|
+
| Sub-command | Routes to | Purpose |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `/design-system:generate "<product / industry / keywords>"` | `commands/design-system/generate.md` | Ground a design system in the curated corpus; optionally persist `MASTER.md` + page overrides, or seed `DESIGN.md` |
|
|
38
|
+
| `/design-system:import <file>` | `commands/design-system/import.md` | Run an extractor's output through the three-lane adapter, then the per-field confirmation import |
|
|
39
|
+
| `/design-system:capture` | `commands/design-system/capture.md` | Inventory *this* repo's components and tokens and emit the same `design-system.json` shape |
|
|
40
|
+
|
|
41
|
+
## Dispatch
|
|
42
|
+
|
|
43
|
+
1. Parse `/design-system <sub-command> [args]`. Sub-command = first token; match
|
|
44
|
+
against the table's exact names only.
|
|
45
|
+
2. Look up the sub-command and execute its file verbatim with the remaining args.
|
|
46
|
+
3. Unknown / missing sub-command → print the table and ask which door to take.
|
|
47
|
+
|
|
48
|
+
## Rules
|
|
49
|
+
|
|
50
|
+
- **Do NOT commit, push, or open a PR** — subcommands never do this.
|
|
51
|
+
- **Do NOT chain subcommands.** One `/design-system <sub>` per turn.
|
|
52
|
+
- **Generated and imported output is a proposal.** A provided artifact,
|
|
53
|
+
registered brand tokens, and a confirmed `DESIGN.md` all outrank it; a value
|
|
54
|
+
that conflicts with a registered brand token is flagged, never auto-applied
|
|
55
|
+
(per [`brand-source-of-truth`](../rules/brand-source-of-truth.md)).
|
|
56
|
+
- **No crawler, browser runtime, or font-bundler is shipped.** Extraction tools
|
|
57
|
+
are user-installed and user-connected; this package's share is the adapter,
|
|
58
|
+
the instructions, and the validation.
|
|
59
|
+
- **Edit `src/` only.** Generated mirrors regenerate.
|
|
60
|
+
|
|
61
|
+
## See also
|
|
62
|
+
|
|
63
|
+
- [`design-system-capture`](../../skills/design-system-capture/SKILL.md) — owns `DESIGN.md` and the per-field-confirmation import.
|
|
64
|
+
- [`corpus-grounding`](../../skills/corpus-grounding/SKILL.md) · [`design-intelligence`](../../skills/design-intelligence/SKILL.md) — the grounded generator behind `:generate`.
|
|
65
|
+
- [`existing-ui-audit`](../../skills/existing-ui-audit/SKILL.md) — the current-repo inventory behind `:capture`.
|
|
66
|
+
- [`docs/contracts/command-clusters.md`](../docs/contracts/command-clusters.md) — `design-system` cluster registration.
|
|
@@ -202,6 +202,15 @@ auto-installer (out of scope). Full schema is lazy-loaded from
|
|
|
202
202
|
[`references/design-system-json.md`](references/design-system-json.md) — read it
|
|
203
203
|
only when an import is requested.
|
|
204
204
|
|
|
205
|
+
**The supply path is real, and it is one command.** Where an extractor's output
|
|
206
|
+
is not already in this shape, run it through the three-lane adapter first —
|
|
207
|
+
`/design-system:import <file>`, which accepts a native artifact, a DTCG token
|
|
208
|
+
file, or an extraction tool's raw JSON and emits the contract. Lanes and
|
|
209
|
+
documented producers:
|
|
210
|
+
[`references/design-system-json.md`](references/design-system-json.md)
|
|
211
|
+
§ Extractor compatibility. The adapter is offline and pure — it does not change
|
|
212
|
+
what this skill owns.
|
|
213
|
+
|
|
205
214
|
**Import procedure:**
|
|
206
215
|
|
|
207
216
|
1. Read `design-system.json`; reject it if `source` (kind + ref + captured_at)
|
|
@@ -71,3 +71,73 @@ brand wins). Precedence on import: registered brand tokens > confirmed
|
|
|
71
71
|
|
|
72
72
|
The package **owns this contract**; it does **not** ship the crawler, the
|
|
73
73
|
Playwright runtime, or a font-bundler.
|
|
74
|
+
|
|
75
|
+
## Extractor compatibility — which crawler, and how its output gets here
|
|
76
|
+
|
|
77
|
+
The contract above says what this skill reads. This section says how a real
|
|
78
|
+
tool's output becomes that shape, so the answer to *"which crawler?"* lives in
|
|
79
|
+
the contract rather than in somebody's memory.
|
|
80
|
+
|
|
81
|
+
`src/scripts/design_system_import.ts` is a **pure, offline file transform** with
|
|
82
|
+
three input lanes. It reads a file and writes the contract shape to stdout — no
|
|
83
|
+
network, no browser, no crawl. That is the lock restated as code: a transform
|
|
84
|
+
that fetched would quietly become the crawler this package does not ship.
|
|
85
|
+
|
|
86
|
+
| Lane | Input | What it does |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `native` | an existing `design-system.json` | Validates `source`, carries every other key verbatim. Past provenance the validation is **report-only** — a key whose shape contradicts the contract is flagged and kept, never dropped, because the import is a proposal a human reads. |
|
|
89
|
+
| `dtcg` | a W3C DTCG token file (`{$value, $type}` leaves) | Buckets by `$type`, so it works on any authoring tool's layering — **with two stated path exceptions**: `dimension` / `number` is genuinely ambiguous in DTCG (spacing, radius and font size share it), so the path breaks that tie, and a path segment named `dark` files a colour under the dark theme. Both are inferences and both are reported in the notes. Resolves `{alias.references}` to their values. Tokens with no contract bucket land in `_meta.unmapped` — which is why `component.button.paddingX` lands there rather than under spacing. |
|
|
90
|
+
| `dembrandt` | an extraction tool's raw JSON | Matches the documented top-level key names and accepts a small set of shapes per bucket. Motion durations/easings become the `motion` block; per-context profiles, hover deltas, WCAG results and breakpoints are **observation** and land in `_meta`. |
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# The command is the supported entry point:
|
|
94
|
+
/design-system:import <file>
|
|
95
|
+
|
|
96
|
+
# Or call the transform directly, from an installed package:
|
|
97
|
+
npx tsx node_modules/@event4u/agent-config/src/scripts/design_system_import.ts <file> \
|
|
98
|
+
[--lane native|dtcg|dembrandt] \
|
|
99
|
+
[--source-kind url|repo|dir --source-ref <ref>] [--captured-at <ISO>] \
|
|
100
|
+
[--format json|summary]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Documented producers.** Two extraction tools are known to emit input this
|
|
104
|
+
adapter consumes, and both are **user-installed and user-connected** — the
|
|
105
|
+
package ships the adapter, the instructions, and the validation, never the tool:
|
|
106
|
+
|
|
107
|
+
- **dembrandt** (MIT, npm) — the richest single source: computed-DOM tokens,
|
|
108
|
+
automatic motion extraction (duration scale, easing curves), component
|
|
109
|
+
observations, WCAG pairs, and a stdio MCP server. Feeds the `dembrandt` lane
|
|
110
|
+
directly, or the `dtcg` lane via its `--dtcg` export.
|
|
111
|
+
- **designlang** (MIT) — DTCG in primitive/semantic/composite layers plus
|
|
112
|
+
interaction states. Feeds the `dtcg` lane. Its own repo-writing feature is not
|
|
113
|
+
invoked; this package owns its projection.
|
|
114
|
+
|
|
115
|
+
A third, **extract-design-system**, emits plain W3C `tokens.json` and feeds the
|
|
116
|
+
same `dtcg` lane. Any other tool that can export DTCG works without a new lane.
|
|
117
|
+
|
|
118
|
+
**Provenance is mandatory on every lane, and its origin is recorded.** DTCG
|
|
119
|
+
carries no `source` block by construction, so the caller supplies one; the
|
|
120
|
+
result then carries `source._meta.provenance_origin: "caller"` rather than
|
|
121
|
+
`"input"`, so a reader can always tell an extracted provenance from an asserted
|
|
122
|
+
one. Neither one present is a rejection, not a default — you cannot confirm what
|
|
123
|
+
you cannot trace.
|
|
124
|
+
|
|
125
|
+
**A lane is never forced.** Where a real sample cannot be mapped without
|
|
126
|
+
inventing values, the adapter emits it as `_meta` observation and says so in a
|
|
127
|
+
note. An import that lands mostly under `_meta` is the designed degradation, not
|
|
128
|
+
a failure — it means the tool's shape moved, and the values are still in front
|
|
129
|
+
of the human instead of silently coerced into tokens.
|
|
130
|
+
|
|
131
|
+
**Parked, not adopted — runtime drift detection.** One documented producer also
|
|
132
|
+
ships a drift gate: `--compare <baseline>` against a captured baseline, with
|
|
133
|
+
distinct exit codes (0 clean · 1 drift · 2 usage · 67 threshold) and a
|
|
134
|
+
machine-readable `drift` key carrying per-token `changes[]`. That is a
|
|
135
|
+
*design-quality CI* capability, not an import one, and nothing in this package
|
|
136
|
+
asks for it today — recorded here as a candidate so the next reader finds it
|
|
137
|
+
already assessed, and taken up only if a design-quality roadmap asks for runtime
|
|
138
|
+
drift detection.
|
|
139
|
+
|
|
140
|
+
The compatibility matrix is committed as tests, not prose:
|
|
141
|
+
`tests/scripts/fixtures/design-system-import/` holds one input/expected pair per
|
|
142
|
+
lane, and that directory's README states which sample is a real capture and
|
|
143
|
+
which is derived from a tool's published output surface.
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "10.
|
|
42
|
+
agent_config_version: "10.4.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -345,7 +345,10 @@ function _halt_provided_without_contract(
|
|
|
345
345
|
'> 1. Proceed — port it with those five losses on the record; `apply` ' +
|
|
346
346
|
'still has to report what it honoured, translated, and flagged',
|
|
347
347
|
'> 2. Supply a `design-system.json` — its token values are then ' +
|
|
348
|
-
'honoured verbatim instead of re-derived'
|
|
348
|
+
'honoured verbatim instead of re-derived. Already have an ' +
|
|
349
|
+
"extractor's output in another shape? `/design-system:import " +
|
|
350
|
+
'<file>` maps a DTCG token file or an extraction tool\'s raw JSON ' +
|
|
351
|
+
'into this contract offline.',
|
|
349
352
|
'> 3. Abort — drop this UI request',
|
|
350
353
|
'',
|
|
351
354
|
'**Recommendation: 2 — Supply the contract** — it is the only option ' +
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
git_common_dir
|
|
4
|
+
} from "./chunk-PZWRPRWP.js";
|
|
5
|
+
|
|
6
|
+
// src/scripts/_lib/envelope_grounding.ts
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as path from "node:path";
|
|
10
|
+
|
|
11
|
+
// src/scripts/_lib/git_env.ts
|
|
12
|
+
var GIT_DISCOVERY_VARS = [
|
|
13
|
+
"GIT_DIR",
|
|
14
|
+
"GIT_WORK_TREE",
|
|
15
|
+
"GIT_INDEX_FILE",
|
|
16
|
+
"GIT_OBJECT_DIRECTORY",
|
|
17
|
+
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
18
|
+
"GIT_COMMON_DIR",
|
|
19
|
+
"GIT_NAMESPACE",
|
|
20
|
+
"GIT_PREFIX"
|
|
21
|
+
];
|
|
22
|
+
function gitEnv(base = process.env) {
|
|
23
|
+
const env = { ...base };
|
|
24
|
+
for (const key of GIT_DISCOVERY_VARS) {
|
|
25
|
+
delete env[key];
|
|
26
|
+
}
|
|
27
|
+
return env;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/scripts/_lib/envelope_grounding.ts
|
|
31
|
+
var MAX_FIELD_CHARS = 200;
|
|
32
|
+
var MAX_PATHS = 40;
|
|
33
|
+
function git(root, args) {
|
|
34
|
+
try {
|
|
35
|
+
return execFileSync("git", args, {
|
|
36
|
+
cwd: root,
|
|
37
|
+
env: gitEnv(),
|
|
38
|
+
encoding: "utf-8",
|
|
39
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
40
|
+
}).trim();
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function canonicalizeRepoIdentity(raw) {
|
|
46
|
+
let s = raw.trim();
|
|
47
|
+
s = s.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
|
|
48
|
+
s = s.replace(/^[^/@]+@/, "");
|
|
49
|
+
s = s.replace(/^([^/:]+):(?!\/)/, "$1/");
|
|
50
|
+
s = s.replace(/\/+$/, "");
|
|
51
|
+
s = s.replace(/\.git$/i, "");
|
|
52
|
+
const slash = s.indexOf("/");
|
|
53
|
+
if (slash > 0) {
|
|
54
|
+
s = s.slice(0, slash).toLowerCase() + s.slice(slash);
|
|
55
|
+
} else {
|
|
56
|
+
s = s.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
return s;
|
|
59
|
+
}
|
|
60
|
+
function collectRepoAnchor(root) {
|
|
61
|
+
const remote = git(root, ["config", "--get", "remote.origin.url"]);
|
|
62
|
+
let identity = null;
|
|
63
|
+
if (remote) {
|
|
64
|
+
identity = canonicalizeRepoIdentity(remote);
|
|
65
|
+
} else {
|
|
66
|
+
const common = git_common_dir(root);
|
|
67
|
+
if (common !== null) {
|
|
68
|
+
try {
|
|
69
|
+
identity = fs.realpathSync(common);
|
|
70
|
+
} catch {
|
|
71
|
+
identity = common;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
repo_identity: identity ? identity.slice(0, MAX_FIELD_CHARS) : null,
|
|
77
|
+
branch: git(root, ["rev-parse", "--abbrev-ref", "HEAD"]),
|
|
78
|
+
head: git(root, ["rev-parse", "HEAD"])
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
var VERIFY_STATE_REL = path.join("agents", "runtime", "state", "verify-before-complete.json");
|
|
82
|
+
function readLastVerify(root) {
|
|
83
|
+
try {
|
|
84
|
+
const raw = fs.readFileSync(path.join(root, VERIFY_STATE_REL), "utf-8");
|
|
85
|
+
const state = JSON.parse(raw);
|
|
86
|
+
const lv = state["last_verification"];
|
|
87
|
+
if (typeof lv !== "object" || lv === null || Array.isArray(lv)) return null;
|
|
88
|
+
const rec = lv;
|
|
89
|
+
const command = typeof rec["command"] === "string" ? rec["command"] : null;
|
|
90
|
+
if (!command) return null;
|
|
91
|
+
const at = typeof rec["at"] === "string" ? rec["at"] : "unknown time";
|
|
92
|
+
return `${command} @ ${at} (no exit status is recorded anywhere)`.slice(0, MAX_FIELD_CHARS);
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function collectGrounding(root) {
|
|
98
|
+
const anchor = collectRepoAnchor(root);
|
|
99
|
+
const porcelain = git(root, ["status", "--porcelain"]);
|
|
100
|
+
if (porcelain === null) {
|
|
101
|
+
return { ...anchor, uncommitted_paths: [], status_summary: null, last_verify: readLastVerify(root) };
|
|
102
|
+
}
|
|
103
|
+
const lines = porcelain.split("\n").filter((l) => l.trim().length > 0);
|
|
104
|
+
const paths = lines.map((l) => l.slice(3).trim()).filter((p) => p.length > 0 && p.length <= MAX_FIELD_CHARS).slice(0, MAX_PATHS);
|
|
105
|
+
return {
|
|
106
|
+
...anchor,
|
|
107
|
+
uncommitted_paths: paths,
|
|
108
|
+
status_summary: lines.length === 0 ? "clean working tree" : `${lines.length} uncommitted path(s)${lines.length > MAX_PATHS ? `, first ${MAX_PATHS} listed` : ""}`,
|
|
109
|
+
last_verify: readLastVerify(root)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function describeDrift(envelope, actual) {
|
|
113
|
+
if (typeof envelope !== "object" || envelope === null || Array.isArray(envelope)) return [];
|
|
114
|
+
const e = envelope;
|
|
115
|
+
const drift = [];
|
|
116
|
+
const recordedIdentity = typeof e["repo_identity"] === "string" ? e["repo_identity"] : null;
|
|
117
|
+
if (recordedIdentity && actual.repo_identity && recordedIdentity !== actual.repo_identity) {
|
|
118
|
+
drift.push(
|
|
119
|
+
`IDENTITY DRIFT: this envelope was written in "${recordedIdentity}", you are in "${actual.repo_identity}". Re-verify every path before acting \u2014 same branch name does not mean same working tree.`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
const recordedBranch = typeof e["branch"] === "string" ? e["branch"] : null;
|
|
123
|
+
if (recordedBranch && actual.branch && recordedBranch !== actual.branch) {
|
|
124
|
+
drift.push(
|
|
125
|
+
`BRANCH DRIFT: envelope written on "${recordedBranch}", checkout is on "${actual.branch}".`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
const recordedHead = typeof e["head"] === "string" ? e["head"] : null;
|
|
129
|
+
if (recordedHead && actual.head && recordedHead !== actual.head) {
|
|
130
|
+
drift.push(
|
|
131
|
+
`COMMIT DRIFT: envelope written at ${recordedHead.slice(0, 12)}, HEAD is now ${actual.head.slice(0, 12)} \u2014 re-read anything the envelope quotes.`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return drift;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/scripts/_lib/recycle_envelope_paths.ts
|
|
138
|
+
import * as path2 from "node:path";
|
|
139
|
+
var RECYCLE_ENVELOPE_REL = path2.join("agents", "runtime", "state", "recycle-envelope.json");
|
|
140
|
+
var RECYCLE_CONSUMED_REL = path2.join(
|
|
141
|
+
"agents",
|
|
142
|
+
"runtime",
|
|
143
|
+
"state",
|
|
144
|
+
"recycle-envelope.consumed.json"
|
|
145
|
+
);
|
|
146
|
+
var RECYCLE_MAX_AGE_HOURS = 48;
|
|
147
|
+
var RECYCLE_ENVELOPE_MAX_BYTES = 6144;
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
collectRepoAnchor,
|
|
151
|
+
collectGrounding,
|
|
152
|
+
describeDrift,
|
|
153
|
+
RECYCLE_ENVELOPE_REL,
|
|
154
|
+
RECYCLE_CONSUMED_REL,
|
|
155
|
+
RECYCLE_MAX_AGE_HOURS,
|
|
156
|
+
RECYCLE_ENVELOPE_MAX_BYTES
|
|
157
|
+
};
|