@ikon85/agent-workflow-kit 0.43.0 → 0.44.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 (126) hide show
  1. package/.agents/skills/grill-me/SKILL.md +3 -1
  2. package/.agents/skills/grill-with-docs/SKILL.md +3 -1
  3. package/.agents/skills/kit-update/SKILL.md +9 -11
  4. package/.agents/skills/orchestrate-wave/SKILL.md +8 -8
  5. package/.agents/skills/setup-workflow/SKILL.md +20 -18
  6. package/.agents/skills/setup-workflow/board-sync.md +4 -1
  7. package/.agents/skills/setup-workflow/workflow-advisories.md +3 -2
  8. package/.agents/skills/setup-workflow/worktree-lifecycle.md +36 -31
  9. package/.agents/skills/to-issues/SKILL.md +43 -0
  10. package/.agents/skills/wrapup/SKILL.md +98 -54
  11. package/.claude/skills/grill-me/SKILL.md +3 -1
  12. package/.claude/skills/grill-me-codex/SKILL.md +3 -1
  13. package/.claude/skills/grill-with-docs/SKILL.md +3 -1
  14. package/.claude/skills/grill-with-docs-codex/SKILL.md +3 -1
  15. package/.claude/skills/kit-update/SKILL.md +9 -11
  16. package/.claude/skills/orchestrate-wave/SKILL.md +8 -8
  17. package/.claude/skills/setup-workflow/SKILL.md +20 -18
  18. package/.claude/skills/setup-workflow/board-sync.md +4 -1
  19. package/.claude/skills/setup-workflow/workflow-advisories.md +3 -2
  20. package/.claude/skills/setup-workflow/worktree-lifecycle.md +36 -31
  21. package/.claude/skills/to-issues/SKILL.md +43 -0
  22. package/.claude/skills/wrapup/SKILL.md +98 -54
  23. package/README.md +249 -7
  24. package/agent-workflow-kit.package.json +42 -42
  25. package/package.json +16 -12
  26. package/scripts/marker_lib.py +3 -0
  27. package/scripts/profile_globs.py +26 -45
  28. package/scripts/release-delta-guard.mjs +26 -9
  29. package/scripts/worktree-lifecycle/README.md +57 -160
  30. package/scripts/worktree-lifecycle/capabilities.json +2 -3
  31. package/scripts/worktree-lifecycle/classify.py +480 -0
  32. package/scripts/worktree-lifecycle/cleanup.py +9 -29
  33. package/scripts/worktree-lifecycle/core.py +68 -1429
  34. package/scripts/worktree-lifecycle/ignore_seed.py +1 -1
  35. package/scripts/worktree-lifecycle/profile.py +46 -29
  36. package/scripts/worktree-lifecycle/setup.py +7 -19
  37. package/scripts/wrapup-land.py +1292 -545
  38. package/src/consumer-migrations.json +1 -16
  39. package/src/lib/bundle.mjs +31 -1
  40. package/docs/adr/0001-consumer-divergence-policy.md +0 -53
  41. package/docs/adr/0002-capability-gated-orchestration.md +0 -70
  42. package/docs/adr/0003-kit-core-and-project-extension-lifecycle.md +0 -63
  43. package/docs/adr/0004-release-intent-is-a-version-tag.md +0 -64
  44. package/docs/adr/0005-to-issues-is-the-planning-facade.md +0 -42
  45. package/docs/adr/0006-routing-knowledge-access-and-policy-are-separate.md +0 -95
  46. package/docs/adr/0007-session-teardown-requires-provenance-bound-ownership.md +0 -88
  47. package/docs/adr/0008-planning-ignore-rules-are-offered-never-installed.md +0 -84
  48. package/docs/adr/0009-teardown-authority-is-stateless-repository-classification.md +0 -101
  49. package/docs/adr/0010-model-roster-replaces-the-optimization-dial.md +0 -87
  50. package/docs/agents/board-sync.md +0 -74
  51. package/docs/agents/code-review.md +0 -14
  52. package/docs/agents/workflow-capabilities.json +0 -28
  53. package/docs/research/agent-task-taxonomy-benchmark-coverage.md +0 -451
  54. package/docs/research/benchlm-routing-source.md +0 -198
  55. package/docs/research/consumer-owned-protocol-files.md +0 -238
  56. package/docs/research/frontend-agent-benchmarks.md +0 -282
  57. package/docs/research/model-effort-routing-benchmarks.md +0 -261
  58. package/docs/research/provider-neutral-agent-routing.md +0 -207
  59. package/docs/research/wave-152-consumer-acceptance.md +0 -98
  60. package/docs/research/wave-43-script-hook-census.md +0 -128
  61. package/scripts/build-kit.mjs +0 -117
  62. package/scripts/build-kit.test.mjs +0 -207
  63. package/scripts/census/census.test.mjs +0 -252
  64. package/scripts/census/state.test.mjs +0 -15
  65. package/scripts/census/transaction.test.mjs +0 -103
  66. package/scripts/census-contract.test.mjs +0 -227
  67. package/scripts/check-kit-staleness.mjs +0 -45
  68. package/scripts/check-kit-staleness.test.mjs +0 -19
  69. package/scripts/codex-exec-scenarios/fake-codex.mjs +0 -165
  70. package/scripts/codex-exec.test.mjs +0 -871
  71. package/scripts/grill-census-wiring-guard.mjs +0 -87
  72. package/scripts/grill-census-wiring-guard.test.mjs +0 -107
  73. package/scripts/kit-release.test.mjs +0 -273
  74. package/scripts/kit-update-pr.test.mjs +0 -151
  75. package/scripts/lib/audit-refs.mjs +0 -146
  76. package/scripts/lib/scrub.mjs +0 -113
  77. package/scripts/lib/scrub.test.mjs +0 -187
  78. package/scripts/memory-lifecycle/memory-lifecycle.test.mjs +0 -170
  79. package/scripts/portability_profile_scan.py +0 -53
  80. package/scripts/release-delta-guard.test.mjs +0 -174
  81. package/scripts/release-parity.test.mjs +0 -90
  82. package/scripts/release-state.test.mjs +0 -360
  83. package/scripts/test_anchor_table.py +0 -69
  84. package/scripts/test_board_bootstrap.py +0 -348
  85. package/scripts/test_board_sync.py +0 -208
  86. package/scripts/test_board_sync_create_idempotency.py +0 -117
  87. package/scripts/test_board_sync_wave_title.py +0 -120
  88. package/scripts/test_census_backstop.py +0 -712
  89. package/scripts/test_census_forward_contract.py +0 -91
  90. package/scripts/test_census_update_contract.test.mjs +0 -454
  91. package/scripts/test_codex_adapter_sync_contract.py +0 -169
  92. package/scripts/test_dist_kit_smoke.py +0 -220
  93. package/scripts/test_drift_guard_diagnostics.py +0 -295
  94. package/scripts/test_issue_claim_contract.py +0 -169
  95. package/scripts/test_kit_docs_language_census.py +0 -178
  96. package/scripts/test_marker_lib.py +0 -162
  97. package/scripts/test_orchestrate_wave_contract.py +0 -381
  98. package/scripts/test_pr_body_check.py +0 -264
  99. package/scripts/test_profile_globs.py +0 -280
  100. package/scripts/test_program_planning_contract.py +0 -133
  101. package/scripts/test_release_authorization_contract.py +0 -101
  102. package/scripts/test_render_anchor.py +0 -267
  103. package/scripts/test_retro_wrapup_contract.py +0 -153
  104. package/scripts/test_skill_code_review_seed.py +0 -89
  105. package/scripts/test_skill_codex_exec_lifecycle.py +0 -123
  106. package/scripts/test_skill_frontmatter_lint.py +0 -234
  107. package/scripts/test_skill_gh_lint.py +0 -124
  108. package/scripts/test_skill_language_census.py +0 -254
  109. package/scripts/test_skill_optional_readiness.py +0 -171
  110. package/scripts/test_skill_portability_lint.py +0 -866
  111. package/scripts/test_skill_precommit_template.py +0 -30
  112. package/scripts/test_skill_publish_audit.py +0 -358
  113. package/scripts/test_skill_readiness_contract.py +0 -264
  114. package/scripts/test_skill_readiness_preflight.py +0 -180
  115. package/scripts/test_skill_required_readiness.py +0 -233
  116. package/scripts/test_skill_selfcontainment_lint.py +0 -255
  117. package/scripts/test_skill_setup_workflow_seeds.py +0 -691
  118. package/scripts/test_skill_stale_name_lint.py +0 -126
  119. package/scripts/test_skill_surface_refs.py +0 -300
  120. package/scripts/test_skill_trailing_artifact_lint.py +0 -71
  121. package/scripts/test_tdd_contract.py +0 -78
  122. package/scripts/test_worktree_ignore_seed.py +0 -320
  123. package/scripts/test_worktree_setup_base_guard.py +0 -140
  124. package/scripts/test_worktree_wrapup_contract.py +0 -1737
  125. package/scripts/test_wrapup_land.py +0 -428
  126. package/scripts/worktree-lifecycle/session.py +0 -1857
@@ -1,207 +0,0 @@
1
- # Provider-neutral agent routing for shared work items
2
-
3
- **Researched:** 2026-07-22
4
- **Question:** How should shared agent-workflow issues express model-routing intent across Claude Code and OpenAI Codex without embedding short-lived provider model names?
5
-
6
- ## Recommendation
7
-
8
- Persist **task intent, not a model selection**, in shared issues. Use two small,
9
- provider-neutral fields:
10
-
11
- ```yaml
12
- routing-intent: judgment | development | mechanical
13
- reasoning-intent: deep | balanced | light
14
- ```
15
-
16
- The exact vocabulary is a Kit domain decision; the important constraint is that
17
- the values describe the work and desired trade-off, not Anthropic or OpenAI
18
- products. A surface-local resolver maps those values at dispatch time:
19
-
20
- ```text
21
- shared issue intent
22
- |
23
- +-- Claude resolver -> current Claude alias/model + session effort
24
- |
25
- `-- Codex resolver -> current Codex model + model_reasoning_effort
26
- ```
27
-
28
- The default resolution must be `inherit` when no local policy exists or when a
29
- configured target cannot be proven usable. The orchestrator should report the
30
- effective resolution at session start, but it should not write that volatile
31
- result back into the issue.
32
-
33
- This separates three ownership layers:
34
-
35
- 1. **Kit-owned schema and validation:** allowed intent values, inheritance,
36
- diagnostics, and dispatch contract.
37
- 2. **User/organization-owned surface policy:** how intent maps to models and
38
- effort for that account, budget, provider, and current catalog.
39
- 3. **Project-owned constraints, only when genuinely shared:** for example, a
40
- prohibition on a model or a minimum capability required by every
41
- collaborator. A project should not carry one maintainer's preferred model
42
- mapping.
43
-
44
- ## Verified platform facts
45
-
46
- ### Claude Code
47
-
48
- Claude Code has Managed, User, Project, and Local scopes. For ordinary scalar
49
- settings, precedence is Managed, command-line, Local, Project, then User. A
50
- committed `.claude/settings.json` therefore affects all collaborators and
51
- overrides their user settings, while `.claude/settings.local.json` is personal
52
- and repository-specific ([Claude Code settings: scopes and precedence](https://code.claude.com/docs/en/settings#configuration-scopes)).
53
-
54
- Claude accepts provider aliases as well as full model IDs. Aliases such as
55
- `fable` and `sonnet` resolve to current models, while `default` returns to the
56
- runtime default for the account or organization. Aliases reduce version churn,
57
- but remain Claude-specific and do not encode a cross-provider task class
58
- ([Claude Code model aliases](https://code.claude.com/docs/en/model-config#model-aliases)).
59
-
60
- The main-session model can be changed for a session with `/model` or at launch
61
- with `--model`; `ANTHROPIC_MODEL` and the persistent `model` setting are also
62
- supported. Organization restrictions and managed settings can replace or
63
- reject a requested selection, so a repository cannot assume that a named model
64
- is usable for every collaborator ([Claude Code model selection](https://code.claude.com/docs/en/model-config#setting-your-model),
65
- [Claude Code model restrictions](https://code.claude.com/docs/en/model-config#restrict-model-selection)).
66
-
67
- Claude subagent definitions support an alias, a full ID, or `inherit`; omission
68
- means `inherit`. Resolution currently considers
69
- `CLAUDE_CODE_SUBAGENT_MODEL`, a per-invocation value, subagent frontmatter, and
70
- finally the main conversation model. Excluded selections fall back to the
71
- inherited model. Extended-thinking configuration is inherited from the main
72
- conversation and has no per-subagent setting
73
- ([Claude Code subagent model resolution](https://code.claude.com/docs/en/sub-agents#choose-a-model)).
74
-
75
- Claude effort levels are model-dependent. Unsupported levels are reduced to a
76
- supported level, organization policy can cap them, and some effort choices are
77
- session-only. Skill and subagent frontmatter can override the inherited session
78
- effort, subject to higher-precedence environment and organization constraints.
79
- Therefore a provider-neutral reasoning intent can be resolved on Claude, but a
80
- shared issue must not claim that one literal effort value has identical
81
- enforcement everywhere
82
- ([Claude Code effort levels](https://code.claude.com/docs/en/model-config#adjust-effort-level),
83
- [Claude Code subagent effort](https://code.claude.com/docs/en/sub-agents#supported-frontmatter-fields)).
84
-
85
- Anthropic exposes `GET /v1/models`, whose result describes models available to
86
- that API credential ([Anthropic Models API](https://platform.claude.com/docs/en/api/models/list)).
87
- That is not a universal Claude Code discovery contract: Claude Code may run
88
- through a Claude subscription, Bedrock, Vertex, Foundry, or a gateway. Gateway
89
- discovery is optional, limited to compatible `/v1/models` gateways, cached,
90
- and falls back to built-in entries if discovery fails
91
- ([Claude Code gateway model discovery](https://code.claude.com/docs/en/llm-gateway#model-selection)).
92
-
93
- ### OpenAI Codex
94
-
95
- Codex reads personal defaults from `~/.codex/config.toml` and project overrides
96
- from trusted `.codex/config.toml` files. Its documented precedence is CLI,
97
- project config, selected user profile, user config, system config, then built-in
98
- defaults. Consequently, a committed project routing table can override a
99
- collaborator's personal defaults; untrusted projects skip project-local layers
100
- entirely ([Codex configuration precedence](https://learn.chatgpt.com/docs/config-file/config-basic#configuration-precedence)).
101
-
102
- Codex exposes `model` and `model_reasoning_effort` as separate configuration
103
- values ([Codex common configuration options](https://learn.chatgpt.com/docs/config-file/config-basic#common-configuration-options)).
104
- For custom subagents, a custom-agent file may override both. Otherwise each is
105
- resolved independently from an explicit spawn value, the `[agents]` default,
106
- and the parent session. Omitting a setting inherits it; changing the model
107
- without an explicit effort uses the selected model's default effort
108
- ([Codex custom-agent resolution](https://learn.chatgpt.com/docs/agent-configuration/subagents#custom-agents)).
109
-
110
- Official Codex guidance explicitly allows leaving both values unpinned so the
111
- runtime can balance capability, speed, and price. It also documents that
112
- available reasoning levels depend on the selected model
113
- ([Codex choosing models and reasoning](https://learn.chatgpt.com/docs/agent-configuration/subagents#choosing-models-and-reasoning)).
114
-
115
- OpenAI exposes `GET /v1/models` for models available to an API key
116
- ([OpenAI Models API](https://platform.openai.com/docs/api-reference/models/list)).
117
- The Codex documentation does not provide a stable, public model-discovery API
118
- for the effective catalog of every Codex/ChatGPT account and local client.
119
- An API-key catalog therefore cannot safely populate routing for users whose
120
- Codex authentication, plan, organization policy, or client surface differs.
121
-
122
- ## Options compared
123
-
124
- | Option | Survives catalog changes | Works across Claude and Codex | Multi-user behavior | Offline/update behavior | Verdict |
125
- |---|---:|---:|---|---|---|
126
- | Concrete model names in issues | No. Every rename, replacement, or access change makes existing issues stale. | No. Names and effort controls are provider-specific. | Assumes every collaborator has the same entitlement and budget. | Old issues remain wrong until rewritten. | Reject. Suitable only for an explicit reproducibility pin in a provider-specific experiment. |
127
- | Stable task intent resolved by user/org surface policy | Yes. Existing issues survive mapping changes. | Yes. Each surface resolves independently or inherits. | Preserves personal and organization choices. | Cached/local policy continues to work; unknown targets can inherit and warn. | **Adopt.** |
128
- | Project-local concrete routing table | Partly. One table can be updated, but every checkout still receives volatile provider data. | Only by maintaining multiple provider sections. | Project config outranks user config on both surfaces, so the maintainer's preferences can override collaborators. | Fresh clones can start stale; offline discovery cannot repair it. | Reject as the default. Permit only explicit team policy/constraints. |
129
-
130
- ## Setup and update implications
131
-
132
- ### `setup-workflow`
133
-
134
- `setup-workflow` should install or reconcile only the Kit-owned intent schema,
135
- templates, validation, and a documented inheritance fallback. It may **offer**
136
- to create a user-local routing policy for the detected surface, but only with
137
- explicit consent and never as a committed project default.
138
-
139
- Setup must not attempt to infer a complete routing table from `/v1/models`:
140
-
141
- - API discovery requires credentials and network access.
142
- - API availability is not equivalent to Claude Code or Codex subscription
143
- availability across all supported providers and account types.
144
- - A discovered model ID says nothing about the user's desired cost/capability
145
- trade-off.
146
-
147
- An interactive setup may validate explicitly selected targets using the active
148
- surface and show a preview. Failure or absence of discovery should leave the
149
- policy at `inherit`, not install guessed names.
150
-
151
- ### `kit-update`
152
-
153
- `kit-update` should update the Kit-owned schema, resolver implementation, and
154
- provider adapter capabilities transactionally. It must preserve user-owned
155
- mappings and project-owned constraints. If the schema changes, migration must
156
- be semantic (for example, rename an intent key), previewed, and reversible;
157
- ordinary updates must not rewrite historical issues or replace personal model
158
- choices.
159
-
160
- At dispatch, the resolver should:
161
-
162
- 1. read the issue's stable intent;
163
- 2. apply organization/user policy and explicit session overrides according to
164
- the active surface;
165
- 3. resolve or inherit without network-dependent mutation;
166
- 4. reject a malformed intent, but fall back to `inherit` with a visible warning
167
- when a volatile target is unavailable;
168
- 5. record the effective model and effort in run evidence, not in the durable
169
- issue contract.
170
-
171
- This lets a later Kit release improve mappings for users who accept Kit
172
- defaults while allowing a maintainer's user-local policy to evolve independently.
173
-
174
- ## Implication for #213
175
-
176
- #213 should not hardcode `sol`, `terra`, `luna`, Claude aliases, or full model
177
- IDs into the issue template or validator. It should instead establish the
178
- provider-neutral intent schema and make `to-issues` emit that schema. The
179
- execute-ready check should reject concrete provider model recommendations in
180
- shared handoffs, while orchestration resolves the intent on the active surface.
181
-
182
- The existing free-text `Recommended model: <Model [Effort]>` field conflates a
183
- durable work classification with a volatile local decision. Replace it with
184
- machine-readable intent and render the effective local recommendation only
185
- when a session is actually dispatched.
186
-
187
- ## Open risks and decisions
188
-
189
- 1. **Vocabulary quality:** `judgment/development/mechanical` and
190
- `deep/balanced/light` need task-based definitions and contract tests so they
191
- do not become disguised provider tiers.
192
- 2. **Enforcement asymmetry:** Both surfaces can override model and effort for
193
- subagents, but their precedence, supported values, organization controls,
194
- and fallback behavior differ. The Kit must promise intent resolution, not
195
- identical low-level enforcement.
196
- 3. **Unavailable targets:** silent substitution hides policy drift. Inheritance
197
- should be visible in run evidence, and strict team policies may choose to
198
- fail instead.
199
- 4. **Organization policy:** managed restrictions outrank personal/project
200
- wishes. The resolver must treat the surface's effective selection as
201
- authoritative.
202
- 5. **Reproducibility exception:** a benchmark or regression reproduction may
203
- legitimately pin a provider/model snapshot. That is a distinct,
204
- provider-specific execution constraint, not the normal issue-routing field.
205
- 6. **No universal discovery source:** model catalogs are useful validation
206
- inputs where available, but cannot be the SSOT for setup or updates across
207
- all supported account types and providers.
@@ -1,98 +0,0 @@
1
- # Wave 152 consumer acceptance and release checklist
2
-
3
- Verified on 2026-07-19 for candidate `52ea49856a03f6e4bb13f24913990769126f81a8`.
4
-
5
- ## Candidate
6
-
7
- - Source repository: `iKon85/agent-workflow-kit`
8
- - Candidate tarball: `/tmp/wave152-final-candidate.8CRnlP/ikon85-agent-workflow-kit-0.28.0.tgz`
9
- - Extracted kit: `/tmp/wave152-final-package.QQTOvE/package/dist-kit`
10
- - Disposable consumer checkout: `/tmp/wave152-testreporter.ZZg8zY/checkout`
11
- - Consumer base: `iKon85/Testreporter` `origin/main` at
12
- `76bcaa91`
13
-
14
- The temporary paths record the exact acceptance input. They are not release
15
- artifacts; a repeat run creates fresh temporary directories and a fresh
16
- test-only marker identity.
17
-
18
- ## Repeatable procedure
19
-
20
- 1. Build the kit from the candidate commit, create an npm tarball, extract it,
21
- and run its `kit:build`. Install that built kit into a disposable checkout
22
- of the consumer's current `origin/main`.
23
- 2. Run `scripts/codex-exec.sh new` with the `review` profile and `read-only`
24
- mode. Capture the opaque run ID, resume it for round 2, verify both rounds
25
- return `OK`, then finalize and verify that the run state is deleted.
26
- 3. Run `scripts/codex-exec.sh new` with the `build` profile and
27
- `workspace-write` mode. Ask it to create only an allowlisted ignored scratch
28
- file containing a fixed sentinel, verify the sentinel, finalize the run,
29
- and remove the scratch file.
30
- 4. Create a disposable consumer issue through `scripts/board-sync.py` with a
31
- unique `wave-stub-source` marker. Resolve it through
32
- `scripts/find-by-marker.py`, verify one exact match, move its board status to
33
- Done, close it, and repeat the lookup. The terminal lookup must report the
34
- closed/user-decision branch and an all-open scan must find zero disposable
35
- issues.
36
-
37
- ## Acceptance evidence
38
-
39
- | Smoke | Evidence | Result |
40
- |---|---|---|
41
- | `codex-review` read-only | Real new round returned `OK` with a thread; resume round 2 returned `OK`; finalize deleted run state. | PASS |
42
- | `codex-build` workspace-write | Created only ignored `_ai_temp/wave152-build-smoke.txt` with `WAVE152_BUILD_SMOKE_OK`; finalize succeeded; scratch file removed. | PASS |
43
- | Marker roundtrip | Identity `wave-stub-source=awkit-wave152-20260719-acceptance-52ea498` created Testreporter issue #2168 through board-sync; exact lookup was unique; board status became Done; issue was closed; final lookup selected closed/user-decision; `openDisposable=0`. | PASS |
44
-
45
- No open disposable issue or scratch file remained after acceptance. The closed
46
- issue remains deliberate cleanup evidence and is excluded from open productive
47
- work by the all-state lookup's closed/user-decision result.
48
-
49
- ## Counted surface census: 31 of 31
50
-
51
- The denominator is re-derived from the current skill manifest and the delivery
52
- surfaces, not from the changed-file list.
53
-
54
- | Surface class | Derivation | Covered |
55
- |---|---|---:|
56
- | Skill surfaces | Nine records from `.claude/skills/skill-manifest.json`: four Claude-only Codex skills (4), three dual-surface marker callers (6), dual-surface `to-issues` (2), and dual-surface `wrapup` (2). The four Codex skills intentionally have no invented `.agents` mirrors. | 14/14 |
57
- | Bundle registrations | The five Wave helpers in `HELPER_FILES`, with their declared kind and mode. | 5/5 |
58
- | Checked manifest entries | The same five helpers in the freshly built and checked `agent-workflow-kit.package.json`. | 5/5 |
59
- | Test surfaces | Harness scenarios, thin-skill lifecycle, marker library/CLI, anchor renderer/promotion, wrapup contradiction absence, and bundle/manifest/tarball modes. | 6/6 |
60
- | Shared board callsite | `scripts/board-sync.py` imports and uses the shared marker parser instead of retaining a second grammar. | 1/1 |
61
- | **Total** | **No unexplained gap.** | **31/31** |
62
-
63
- The exact manifest-derived skill set is:
64
-
65
- - Claude-only: `codex-review`, `codex-build`, `grill-me-codex`,
66
- `grill-with-docs-codex`.
67
- - Dual-surface: `to-prd`, `to-waves`, `board-to-waves`, `to-issues`, `wrapup`.
68
-
69
- The five helper modes are:
70
-
71
- - `scripts/marker_lib.py` — `0644`
72
- - `scripts/find-by-marker.py` — `0755`
73
- - `scripts/codex-exec.sh` — `0755`
74
- - `scripts/codex_proc.py` — `0644`
75
- - `scripts/render-anchor.py` — `0755`
76
-
77
- ## Release checklist
78
-
79
- - [x] K1-K5 integrated into one candidate.
80
- - [x] K1, K2, and K4 passed independent Standards and Spec reviews.
81
- - [x] Candidate tarball passed all three real consumer smokes.
82
- - [x] Disposable consumer issue and scratch file cleaned up; no open disposable
83
- issue remains.
84
- - [x] Bundle, built-manifest, and npm-tarball mode assertions cover all five
85
- helpers.
86
- - [x] Surface census is 31 of 31 with zero unexplained gaps.
87
- - [x] Prepared the user-authorized single minor bump from 0.28.0 to 0.29.0 and
88
- refresh checked release state.
89
- - [x] `release:prepare -- --version 0.29.0` completed its release guard, full
90
- test suite, manifest rebuild, and dry-run npm pack.
91
- - [x] Re-ran the full suite (354 Node tests and 277 Python tests),
92
- `kit:staleness` (`OK`), and `release:guard` (`OK (minor)`).
93
- - [x] Created and extracted the final `0.29.0` npm tarball (380 package
94
- entries); all five helper modes matched both pack metadata and extracted
95
- filesystem modes.
96
- - [ ] After merge, let the trusted release workflow publish and verify
97
- `npm run release:status` reports `released` before declaring the release
98
- complete.
@@ -1,128 +0,0 @@
1
- # Wave 43 script and hook census
2
-
3
- Verified on 2026-07-15 against `agent-workflow-kit` commit
4
- `2d47dce23d9204b44951334c3c370bdb997c0943` and Testreporter commit
5
- [`458747ebe8d67f66840cb3c1e75284cf2be7fb20`](https://github.com/iKon85/Testreporter/tree/458747ebe8d67f66840cb3c1e75284cf2be7fb20).
6
- This is the research input for issue #59. It records facts only; it does not make
7
- ship, opt-in, profile-seam, or maintenance decisions.
8
-
9
- ## Method and reconciliation
10
-
11
- The public-repository denominator is every tracked file below `scripts/**` and
12
- `.claude/hooks/**`, excluding `test_*.py`, `*.test.mjs`, and the metadata file
13
- `scripts/.npmignore`. The recount is:
14
-
15
- ```text
16
- 68 tracked entries
17
- - 31 tests
18
- - 1 metadata file
19
- = 36 current script/hook entries
20
- = 32 scripts + 4 hooks
21
- = 30 shipped helpers + 6 maintainer-only helpers
22
- ```
23
-
24
- The shipped/helper split is derived from
25
- [`src/lib/bundle.mjs`](../../src/lib/bundle.mjs), whose `HELPER_FILES` list is
26
- the public distribution authority. The historical input is the 26-candidate
27
- list in [Testreporter #1976](https://github.com/iKon85/Testreporter/issues/1976),
28
- originally reconciled as 11 portable plus 15 generalize-first candidates in
29
- [Testreporter #1964](https://github.com/iKon85/Testreporter/issues/1964).
30
-
31
- Fresh exact-path comparison:
32
-
33
- ```text
34
- Historical candidates: 26/26 accounted for
35
- Still present at the exact Testreporter path: 26/26
36
- Present at the exact public-repo path: 0/26
37
- Proven exact rename in the public repo: 0/26
38
- Explicitly retired by a locked decision: 0/26
39
- ```
40
-
41
- Therefore every historical row is classified as **present in the current
42
- consumer and absent from the current public denominator**. Related public
43
- primitives are called out only as inputs to the later grill; similarity is not
44
- treated as proof of a rename or as a ship decision.
45
-
46
- ## Fresh public denominator: 36 of 36
47
-
48
- | Current path | Distribution status |
49
- |---|---|
50
- | `.claude/hooks/_hook_utils.py` | shipped helper |
51
- | `.claude/hooks/drift-guard.py` | shipped helper |
52
- | `.claude/hooks/skill-drift-hint.py` | shipped helper |
53
- | `.claude/hooks/sync-board-status.py` | shipped helper |
54
- | `scripts/anchor_table.py` | shipped helper |
55
- | `scripts/board-sync.py` | shipped helper |
56
- | `scripts/board_config.py` | shipped helper |
57
- | `scripts/board_fields.py` | shipped helper |
58
- | `scripts/build-kit.mjs` | maintainer-only |
59
- | `scripts/census/delta.mjs` | shipped helper |
60
- | `scripts/census/fingerprint.mjs` | shipped helper |
61
- | `scripts/census/index.mjs` | shipped helper |
62
- | `scripts/census/scan.mjs` | shipped helper |
63
- | `scripts/census/state.mjs` | shipped helper |
64
- | `scripts/census/transaction.mjs` | shipped helper |
65
- | `scripts/check-kit-staleness.mjs` | maintainer-only |
66
- | `scripts/execute-ready-check.py` | shipped helper |
67
- | `scripts/grill-census-wiring-guard.mjs` | maintainer-only |
68
- | `scripts/issue_deps.py` | shipped helper |
69
- | `scripts/kit-release.mjs` | shipped helper |
70
- | `scripts/kit-update-pr.mjs` | shipped helper |
71
- | `scripts/lib/audit-refs.mjs` | maintainer-only |
72
- | `scripts/lib/scrub.mjs` | maintainer-only |
73
- | `scripts/loc_offender_core.py` | shipped helper |
74
- | `scripts/loc_offender_gate.py` | shipped helper |
75
- | `scripts/node_kind.py` | shipped helper |
76
- | `scripts/portability_profile_scan.py` | maintainer-only |
77
- | `scripts/pr-body-check.py` | shipped helper |
78
- | `scripts/program_graph.py` | shipped helper |
79
- | `scripts/program_graph_parse.py` | shipped helper |
80
- | `scripts/program_graph_validate.py` | shipped helper |
81
- | `scripts/program_sync.py` | shipped helper |
82
- | `scripts/release-delta-guard.mjs` | shipped helper |
83
- | `scripts/release-parity.mjs` | shipped helper |
84
- | `scripts/release-state.mjs` | shipped helper |
85
- | `scripts/wrapup-land.py` | shipped helper |
86
-
87
- ## Historical candidate crosswalk: 26 of 26
88
-
89
- All Testreporter links below are pinned to the verified consumer commit. “No
90
- dedicated tracked test found” means the fresh tracked-tree search found no test
91
- named for that candidate; it is not a statement about runtime correctness.
92
-
93
- | Historical candidate | Current public status and adjacent evidence | Current consumer dependency | Existing consumer test evidence |
94
- |---|---|---|---|
95
- | `scripts/audit_gate.py` | Exact path absent. | [`package.json#L44`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L44) and `.githooks/pre-push` invoke it. | [`scripts/test_audit_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_audit_gate.py), [`scripts/test_pre_push_audit_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_pre_push_audit_gate.py) |
96
- | `scripts/cleanup-worktrees.sh` | Exact path absent. Public `scripts/wrapup-land.py` has adjacent worktree-cleanup behavior, not a proven rename. | No separate tracked consumer found beyond direct/manual use. | No dedicated tracked test found. |
97
- | `scripts/install-git-hooks.sh` | Exact path absent. | [`package.json#L45`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L45) invokes it during postinstall. | [`scripts/test_install_git_hooks.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_install_git_hooks.py) |
98
- | `scripts/ensure-gitleaks.sh` | Exact path absent. | [`package.json#L45`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/package.json#L45) invokes it during postinstall; `docs/security/secret-scan.md` documents it. | No dedicated tracked test found. |
99
- | `.claude/hooks/block-bg-double-background.py` | Exact path absent. | [`.claude/settings.json#L85`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L85) wires it. | [`.claude/hooks/test_block_bg_double_background.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_bg_double_background.py) |
100
- | `.claude/hooks/block-npm-install-in-pnpm.py` | Exact path absent. | [`.claude/settings.json#L75`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L75) wires it. | [`.claude/hooks/test_block_npm_install_in_pnpm.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_npm_install_in_pnpm.py) |
101
- | `.claude/hooks/block-secrets.py` | Exact path absent. | [`.claude/settings.json#L56-L65`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L56-L65) wires it at two hook events. | [`.claude/hooks/test_block_secrets_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_block_secrets_smoke.py) |
102
- | `.claude/hooks/branch-watch.py` | Exact path absent. | [`.claude/settings.json#L161`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L161) wires it. | [`.claude/hooks/test_branch_watch_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_branch_watch_smoke.py) |
103
- | `.claude/hooks/grep-shim-guard.py` | Exact path absent. | [`.claude/settings.json#L80`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L80) wires it. | [`.claude/hooks/test_grep_shim_guard.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_grep_shim_guard.py) |
104
- | `.claude/hooks/recon-size-hint.py` | Exact path absent. | [`.claude/settings.json#L134`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L134) wires it. | [`.claude/hooks/test_recon_size_hint.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_recon_size_hint.py) |
105
- | `.claude/hooks/loc-offender-forewarn.py` | Exact path absent. Public `scripts/loc_offender_core.py` and `scripts/loc_offender_gate.py` are related shipped primitives, not a proven rename. | [`.claude/settings.json#L18`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L18) wires it. | [`scripts/test_loc_offender_forewarn.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_loc_offender_forewarn.py) |
106
- | `scripts/bump-version.sh` | Exact path absent. Public `scripts/kit-release.mjs` contains tested SemVer and metadata-update behavior, not a proven rename. | No separate consumer wiring found; the script is directly invoked. | No dedicated tracked test found for the historical script. |
107
- | `scripts/consolidate-memories.sh` | Exact path absent. | The two historical memory templates name it as their consolidator. | No dedicated tracked test found. |
108
- | `scripts/memory-templates/meta_decision_layer_choice.md` | Exact path absent. | Input consumed by `scripts/consolidate-memories.sh`. | No dedicated tracked test found. |
109
- | `scripts/memory-templates/meta_memory_lifecycle.md` | Exact path absent. | Input consumed by `scripts/consolidate-memories.sh`. | No dedicated tracked test found. |
110
- | `scripts/setup-worktree.sh` | Exact path absent. Public workflow prose allows a project helper or plain `git worktree add`; that is not a rename. | Central Testreporter worktree, port, and local-env setup primitive referenced by workflow documentation. | [`scripts/setup-worktree.test.mjs`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/setup-worktree.test.mjs), [`scripts/test_pre_push_loc_gate.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/scripts/test_pre_push_loc_gate.py) |
111
- | `.claude/hooks/baseline-capture-hint.py` | Exact path absent. | [`.claude/settings.json#L114`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L114) wires it. | [`.claude/hooks/test_baseline_capture_hint_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_baseline_capture_hint_smoke.py) |
112
- | `.claude/hooks/branch-context.py` | Exact path absent. | [`.claude/settings.json#L13`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L13) wires it. | [`.claude/hooks/test_branch_context_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_branch_context_smoke.py) |
113
- | `.claude/hooks/convention-drift-hint.py` | Exact path absent. Public `.claude/hooks/skill-drift-hint.py` and `drift-guard.py` are narrower adjacent mechanisms, not proven renames. | [`.claude/settings.json#L33`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L33) and rule `SOURCES.txt` files refer to it. | No dedicated tracked test found. |
114
- | `.claude/hooks/enforce-worktree.py` | Exact path absent. | [`.claude/settings.json#L109`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L109) wires it. | [`.claude/hooks/test_enforce_worktree.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree.py) |
115
- | `.claude/hooks/enforce-worktree-cwd.py` | Exact path absent. | [`.claude/settings.json#L95`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L95) wires it. | [`.claude/hooks/test_enforce_worktree_cwd_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree_cwd_smoke.py) |
116
- | `.claude/hooks/enforce-worktree-discipline.py` | Exact path absent. | [`.claude/settings.json#L70`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L70) wires it. | [`.claude/hooks/test_enforce_worktree_discipline_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_enforce_worktree_discipline_smoke.py) |
117
- | `.claude/hooks/migration-snapshot-reminder.py` | Exact path absent. | [`.claude/settings.json#L166`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L166) wires it. | [`.claude/hooks/test_migration_snapshot_reminder_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_migration_snapshot_reminder_smoke.py) |
118
- | `.claude/hooks/pre-refactor-sweep.py` | Exact path absent. | [`.claude/settings.json#L23`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L23) wires it. | [`.claude/hooks/test_pre_refactor_sweep.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_pre_refactor_sweep.py) |
119
- | `.claude/hooks/typecheck-on-stop.sh` | Exact path absent. | [`.claude/settings.json#L145`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L145) wires it. | No dedicated tracked test found. |
120
- | `.claude/hooks/slice-handoff-hint.py` | Exact path absent. | [`.claude/settings.json#L44`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/settings.json#L44) wires it. | [`.claude/hooks/test_slice_handoff_hint_smoke.py`](https://github.com/iKon85/Testreporter/blob/458747ebe8d67f66840cb3c1e75284cf2be7fb20/.claude/hooks/test_slice_handoff_hint_smoke.py) |
121
-
122
- ## Inputs for the decision grill
123
-
124
- The crosswalk establishes the decision set but intentionally leaves its verdict
125
- columns blank. Issue #59 must decide, with the user, each row’s outcome, opt-in,
126
- profile seam, security and maintenance cost, and ship verdict. In particular,
127
- the adjacent public primitives identified above must be compared behaviorally
128
- before any row is called replaced, redundant, or already shipped.
@@ -1,117 +0,0 @@
1
- /** Build the distributable kit from this public repository's current SSOT. */
2
- import { chmod, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises';
3
- import { dirname, join, relative } from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { collectBundle } from '../src/lib/bundle.mjs';
6
- import { sha256 } from '../src/lib/hash.mjs';
7
- import { scrub } from './lib/scrub.mjs';
8
- import { auditExecRefs, auditModuleImports, auditSkillNameRefs } from './lib/audit-refs.mjs';
9
-
10
- const ROOT_FILES = ['LICENSE', 'README.md', 'PROVENANCE.md'];
11
- const DOC_ASSETS = ['index.html', 'methodology.html', 'methodology.svg', 'workflow.png'];
12
-
13
- const isBinary = (buf) => buf.includes(0);
14
-
15
- async function walk(dir) {
16
- const files = [];
17
- let entries;
18
- try { entries = await readdir(dir, { withFileTypes: true }); }
19
- catch (error) { if (error.code === 'ENOENT') return files; throw error; }
20
- for (const entry of entries) {
21
- const path = join(dir, entry.name);
22
- if (entry.isDirectory()) files.push(...await walk(path));
23
- else if (entry.isFile()) files.push(path);
24
- }
25
- return files.sort();
26
- }
27
-
28
- async function writeOut(path, content, mode = 0o644) {
29
- await mkdir(dirname(path), { recursive: true });
30
- await writeFile(path, content);
31
- await chmod(path, mode);
32
- }
33
-
34
- async function copySource(repoRoot, distDir, source, destination, mode = 0o644, shouldScrub = true) {
35
- const raw = await readFile(join(repoRoot, source));
36
- const content = shouldScrub && !isBinary(raw)
37
- ? Buffer.from(scrub(raw.toString('utf8')), 'utf8') : raw;
38
- await writeOut(join(distDir, destination), content, mode);
39
- return content;
40
- }
41
-
42
- async function shipBundle(repoRoot, distDir, bundleFiles) {
43
- const entries = [];
44
- for (const file of bundleFiles) {
45
- const content = await copySource(repoRoot, distDir, file.src, file.dest, file.mode);
46
- entries.push({
47
- path: file.dest, kind: file.kind, ownerSkill: file.ownerSkill,
48
- surface: file.surface, installRole: file.installRole,
49
- sha256: sha256(content), mode: file.mode, origin: 'kit',
50
- });
51
- }
52
- return entries.sort((a, b) => a.path.localeCompare(b.path));
53
- }
54
-
55
- async function shipRepositoryFiles(repoRoot, distDir, packageJson) {
56
- for (const file of ROOT_FILES) await copySource(repoRoot, distDir, file, file, 0o644, false);
57
- for (const file of DOC_ASSETS) {
58
- await copySource(repoRoot, distDir, `docs/${file}`, `docs/${file}`);
59
- }
60
- for (const absolute of await walk(join(repoRoot, 'src'))) {
61
- const path = `src/${relative(join(repoRoot, 'src'), absolute)}`;
62
- await copySource(repoRoot, distDir, path, path);
63
- }
64
- const distributable = {
65
- ...packageJson,
66
- repository: {
67
- type: 'git', url: 'git+https://github.com/iKon85/agent-workflow-kit.git',
68
- },
69
- };
70
- await writeOut(join(distDir, 'package.json'), Buffer.from(`${JSON.stringify(distributable, null, 2)}\n`));
71
- }
72
-
73
- async function auditBuild(repoRoot, distDir, manifest, entries) {
74
- const bodies = new Map();
75
- for (const entry of entries) {
76
- if (entry.path.endsWith('.md') || entry.path.endsWith('.py')) {
77
- bodies.set(entry.path, await readFile(join(distDir, entry.path), 'utf8'));
78
- }
79
- }
80
- const localModules = (await Promise.all(
81
- ['scripts', '.claude/hooks'].map(async (dir) => {
82
- try { return await readdir(join(repoRoot, dir)); } catch { return []; }
83
- }),
84
- )).flat().filter((name) => name.endsWith('.py')).map((name) => name.slice(0, -3));
85
- const known = Object.keys(manifest.skills);
86
- const published = known.filter((name) => manifest.skills[name].publish);
87
- const read = (path) => bodies.get(path) ?? null;
88
- const failures = [
89
- ...auditExecRefs(entries, read).map((v) => `${v.file} -> ${v.ref}`),
90
- ...auditModuleImports(entries, read, localModules).map((v) => `${v.file} -> ${v.module}`),
91
- ...auditSkillNameRefs(entries, read, { known, published }).map((v) => `${v.file} -> ${v.skill}`),
92
- ];
93
- if (failures.length) throw new Error(`build-kit: dangling dependencies:\n${failures.join('\n')}`);
94
- }
95
-
96
- export async function buildKit({ repoRoot, distDir } = {}) {
97
- repoRoot ??= join(dirname(fileURLToPath(import.meta.url)), '..');
98
- distDir ??= join(repoRoot, 'dist-kit');
99
- const manifest = JSON.parse(await readFile(join(repoRoot, '.claude/skills/skill-manifest.json'), 'utf8'));
100
- const packageJson = JSON.parse(await readFile(join(repoRoot, 'package.json'), 'utf8'));
101
- await rm(distDir, { recursive: true, force: true });
102
- await mkdir(distDir, { recursive: true });
103
- const { files } = await collectBundle(repoRoot, manifest);
104
- const entries = await shipBundle(repoRoot, distDir, files);
105
- await shipRepositoryFiles(repoRoot, distDir, packageJson);
106
- await writeOut(join(distDir, 'agent-workflow-kit.package.json'), Buffer.from(
107
- `${JSON.stringify({ kitVersion: packageJson.version, files: entries }, null, 2)}\n`,
108
- ));
109
- await auditBuild(repoRoot, distDir, manifest, entries);
110
- return { distDir, kitVersion: packageJson.version, fileCount: entries.length };
111
- }
112
-
113
- if (import.meta.url === `file://${process.argv[1]}`) {
114
- buildKit().then(({ distDir, kitVersion, fileCount }) => {
115
- console.log(`built ${distDir} · kitVersion ${kitVersion} · ${fileCount} files`);
116
- }).catch((error) => { console.error(error.message); process.exitCode = 1; });
117
- }