@event4u/agent-config 2.6.0 → 2.7.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 (132) hide show
  1. package/.agent-src/commands/agent-handoff.md +1 -0
  2. package/.agent-src/commands/agent-status.md +1 -0
  3. package/.agent-src/commands/agents/audit.md +1 -0
  4. package/.agent-src/commands/agents/init.md +1 -0
  5. package/.agent-src/commands/agents/optimize.md +1 -0
  6. package/.agent-src/commands/agents.md +1 -0
  7. package/.agent-src/commands/analyze-reference-repo.md +1 -0
  8. package/.agent-src/commands/bug-fix.md +1 -0
  9. package/.agent-src/commands/bug-investigate.md +1 -0
  10. package/.agent-src/commands/challenge-me/vision.md +1 -0
  11. package/.agent-src/commands/challenge-me/with-docs.md +1 -0
  12. package/.agent-src/commands/challenge-me.md +1 -0
  13. package/.agent-src/commands/chat-history/import.md +1 -0
  14. package/.agent-src/commands/chat-history/learn.md +1 -0
  15. package/.agent-src/commands/chat-history/show.md +1 -0
  16. package/.agent-src/commands/chat-history.md +1 -0
  17. package/.agent-src/commands/check-current-md.md +1 -0
  18. package/.agent-src/commands/commit/in-chunks.md +1 -0
  19. package/.agent-src/commands/commit.md +1 -0
  20. package/.agent-src/commands/compress.md +1 -0
  21. package/.agent-src/commands/context/create.md +1 -0
  22. package/.agent-src/commands/context/refactor.md +1 -0
  23. package/.agent-src/commands/context.md +1 -0
  24. package/.agent-src/commands/cost-report.md +1 -0
  25. package/.agent-src/commands/council/default.md +1 -0
  26. package/.agent-src/commands/council/design.md +1 -0
  27. package/.agent-src/commands/council/optimize.md +1 -0
  28. package/.agent-src/commands/council/pr.md +1 -0
  29. package/.agent-src/commands/council.md +1 -0
  30. package/.agent-src/commands/create-pr/description-only.md +1 -0
  31. package/.agent-src/commands/create-pr.md +1 -0
  32. package/.agent-src/commands/e2e-heal.md +1 -0
  33. package/.agent-src/commands/e2e-plan.md +1 -0
  34. package/.agent-src/commands/estimate-ticket.md +1 -0
  35. package/.agent-src/commands/feature/dev.md +1 -0
  36. package/.agent-src/commands/feature/explore.md +1 -0
  37. package/.agent-src/commands/feature/plan.md +1 -0
  38. package/.agent-src/commands/feature/refactor.md +1 -0
  39. package/.agent-src/commands/feature/roadmap.md +1 -0
  40. package/.agent-src/commands/feature.md +1 -0
  41. package/.agent-src/commands/fix/ci.md +1 -0
  42. package/.agent-src/commands/fix/portability.md +1 -0
  43. package/.agent-src/commands/fix/pr-bot-comments.md +1 -0
  44. package/.agent-src/commands/fix/pr-comments.md +1 -0
  45. package/.agent-src/commands/fix/pr-developer-comments.md +1 -0
  46. package/.agent-src/commands/fix/refs.md +1 -0
  47. package/.agent-src/commands/fix/seeder.md +1 -0
  48. package/.agent-src/commands/fix.md +1 -0
  49. package/.agent-src/commands/grill-me.md +1 -0
  50. package/.agent-src/commands/implement-ticket.md +1 -0
  51. package/.agent-src/commands/jira-ticket.md +1 -0
  52. package/.agent-src/commands/judge/on-diff.md +1 -0
  53. package/.agent-src/commands/judge/solo.md +1 -0
  54. package/.agent-src/commands/judge/steps.md +1 -0
  55. package/.agent-src/commands/judge.md +1 -0
  56. package/.agent-src/commands/memory/add.md +1 -0
  57. package/.agent-src/commands/memory/load.md +1 -0
  58. package/.agent-src/commands/memory/mine-session.md +1 -0
  59. package/.agent-src/commands/memory/promote.md +1 -0
  60. package/.agent-src/commands/memory/propose.md +1 -0
  61. package/.agent-src/commands/memory.md +1 -0
  62. package/.agent-src/commands/mode.md +1 -0
  63. package/.agent-src/commands/module/create.md +1 -0
  64. package/.agent-src/commands/module/explore.md +1 -0
  65. package/.agent-src/commands/module.md +1 -0
  66. package/.agent-src/commands/onboard.md +1 -0
  67. package/.agent-src/commands/optimize/agents-dir.md +1 -0
  68. package/.agent-src/commands/optimize/augmentignore.md +1 -0
  69. package/.agent-src/commands/optimize/rtk.md +1 -0
  70. package/.agent-src/commands/optimize/skills.md +1 -0
  71. package/.agent-src/commands/optimize-prompt.md +1 -0
  72. package/.agent-src/commands/optimize.md +1 -0
  73. package/.agent-src/commands/orchestrate.md +1 -0
  74. package/.agent-src/commands/override/create.md +1 -0
  75. package/.agent-src/commands/override/manage.md +1 -0
  76. package/.agent-src/commands/override.md +1 -0
  77. package/.agent-src/commands/package-reset.md +1 -0
  78. package/.agent-src/commands/package-test.md +1 -0
  79. package/.agent-src/commands/prepare-for-review.md +1 -0
  80. package/.agent-src/commands/project-analyze.md +1 -0
  81. package/.agent-src/commands/project-health.md +1 -0
  82. package/.agent-src/commands/quality-fix.md +1 -0
  83. package/.agent-src/commands/refine-ticket.md +1 -0
  84. package/.agent-src/commands/research/deep.md +1 -0
  85. package/.agent-src/commands/research/report.md +1 -0
  86. package/.agent-src/commands/research.md +1 -0
  87. package/.agent-src/commands/review-changes.md +1 -0
  88. package/.agent-src/commands/review-routing.md +1 -0
  89. package/.agent-src/commands/roadmap/ai-council.md +1 -0
  90. package/.agent-src/commands/roadmap/create.md +1 -0
  91. package/.agent-src/commands/roadmap/process-full.md +1 -0
  92. package/.agent-src/commands/roadmap/process-phase.md +1 -0
  93. package/.agent-src/commands/roadmap/process-step.md +1 -0
  94. package/.agent-src/commands/roadmap.md +1 -0
  95. package/.agent-src/commands/rule-compliance-audit.md +1 -0
  96. package/.agent-src/commands/set-cost-profile.md +1 -0
  97. package/.agent-src/commands/sync-agent-settings.md +1 -0
  98. package/.agent-src/commands/sync-gitignore/fix.md +1 -0
  99. package/.agent-src/commands/sync-gitignore.md +1 -0
  100. package/.agent-src/commands/tests/create.md +1 -0
  101. package/.agent-src/commands/tests/execute.md +1 -0
  102. package/.agent-src/commands/tests.md +1 -0
  103. package/.agent-src/commands/threat-model.md +1 -0
  104. package/.agent-src/commands/update-form-request-messages.md +1 -0
  105. package/.agent-src/commands/upstream-contribute.md +1 -0
  106. package/.agent-src/commands/work.md +1 -0
  107. package/.claude-plugin/marketplace.json +1 -1
  108. package/AGENTS.md +4 -4
  109. package/CHANGELOG.md +56 -2121
  110. package/README.md +58 -32
  111. package/config/gitignore-block.txt +5 -0
  112. package/docs/architecture/augment-projection.md +70 -0
  113. package/docs/architecture/claude-bundle.md +77 -0
  114. package/docs/architecture/compression.md +67 -0
  115. package/docs/architecture/multi-tool-projection.md +72 -0
  116. package/docs/architecture.md +30 -53
  117. package/docs/archive/CHANGELOG-pre-2.2.0.md +2138 -0
  118. package/docs/contracts/CHANGELOG-conventions.md +121 -0
  119. package/docs/contracts/command-surface-tiers.md +140 -0
  120. package/docs/contracts/mcp-cloud-scope.md +193 -21
  121. package/docs/contracts/mcp-phase-1-scope.md +1 -0
  122. package/docs/decisions/ADR-007-agent-discovery-scopes.md +67 -0
  123. package/docs/setup/enterprise-and-offline.md +201 -0
  124. package/docs/setup/per-ide/augment.md +37 -25
  125. package/package.json +1 -1
  126. package/scripts/_bootstrap_tier_frontmatter.py +151 -0
  127. package/scripts/agent-config +146 -83
  128. package/scripts/hermetic-install.sh +235 -0
  129. package/scripts/install.py +8 -1
  130. package/scripts/lint_command_tiers.py +115 -0
  131. package/scripts/mcp_server/__init__.py +5 -0
  132. package/scripts/schemas/command.schema.json +5 -0
@@ -0,0 +1,201 @@
1
+ # Enterprise & offline installation
2
+
3
+ > **Status:** experimental · contract-shaped output of
4
+ > `agents/roadmaps/road-to-distribution-maturity.md` Phase 2. Four
5
+ > documented happy-paths for environments where the public npm
6
+ > registry is not freely reachable from the developer's machine, plus
7
+ > a "no-internet developer" runbook.
8
+
9
+ ## Why no Composer fallback
10
+
11
+ Re-introducing a Composer-published distribution was evaluated in the
12
+ Phase 0 council session
13
+ (`agents/council-questions/composer-fallback-feasibility.md`) and
14
+ **rejected** on three grounds:
15
+
16
+ 1. **Lock-shape mismatch.** `installed.lock` is npm-shaped (flat dep
17
+ model + npm pin in `.agent-settings.yml`). A Composer fallback
18
+ would need either a parallel manifest (breaks the "lock is
19
+ canonical" invariant) or a translation layer (defeats the
20
+ "minimal" claim).
21
+ 2. **Dual-distribution attack surface.** Two pipelines means two
22
+ SBOMs, two CVE response surfaces, two signing roots. Supply-chain
23
+ risk doubles for a fallback most operators will never use.
24
+ 3. **"Minimal fallback" is an oxymoron.** Partial functionality
25
+ shipped on a parallel pipeline confuses operators more than it
26
+ helps — the failure mode of a half-working Composer install is
27
+ worse than a documented npm-only path.
28
+
29
+ The supported alternative is the **four-path enterprise/offline
30
+ matrix** below, all of which keep npm as the single distribution
31
+ channel.
32
+
33
+ ## Path A — pinned-npx via internal registry
34
+
35
+ For environments where the public registry is unreachable but an
36
+ internal mirror (Verdaccio, Nexus, JFrog, Sonatype) is configured:
37
+
38
+ ```bash
39
+ # .npmrc at repo root or ~/.npmrc
40
+ registry=https://npm.internal.example.com/
41
+ @event4u:registry=https://npm.internal.example.com/
42
+ always-auth=true
43
+ ```
44
+
45
+ Pin the consumed version in the consumer project's
46
+ `.agent-settings.yml`:
47
+
48
+ ```yaml
49
+ # .agent-settings.yml
50
+ agent_config_version: "2.6.1" # matches the version your mirror has indexed
51
+ ```
52
+
53
+ `scripts/install.py` reads `agent_config_version` at install time and
54
+ records it in `~/.event4u/agent-config/installed.lock` per ADR-007.
55
+ The registry-mirror caveat: your mirror **must** index the
56
+ `@event4u/agent-config` scope before the first `npx` call — `npx`
57
+ does not transparently fall back from a private mirror to the public
58
+ registry.
59
+
60
+ > **Consumer npm-pinning ≠ release-shape pinning.** This path pins
61
+ > what the consumer's `npx` resolves to. The package's own release
62
+ > cadence (semver, tags, deprecation windows) is not pinned here per
63
+ > `.augment/rules/scope-control.md` § "no version pinning in
64
+ > roadmaps". The `agent_config_version` field is a consumer choice.
65
+
66
+ ## Path B — offline cache strategy
67
+
68
+ For environments where the developer's machine has no network egress
69
+ at all but a pre-staged npm cache is delivered out-of-band:
70
+
71
+ ```bash
72
+ # On a machine with internet access:
73
+ npm cache add @event4u/agent-config@2.6.1
74
+ tar -czf agent-config-npm-cache.tgz ~/.npm/_cacache
75
+
76
+ # On the offline machine:
77
+ tar -xzf agent-config-npm-cache.tgz -C ~/
78
+ npx --prefer-offline @event4u/agent-config init
79
+ ```
80
+
81
+ Corepack-pinning the npm version makes the cache reproducible across
82
+ developers:
83
+
84
+ ```bash
85
+ corepack enable
86
+ corepack prepare npm@10.5.0 --activate # whatever version your cache was built with
87
+ ```
88
+
89
+ `agent_config_version` in `.agent-settings.yml` must match the cached
90
+ version exactly — otherwise `npx` will try (and fail) to resolve a
91
+ different version from the registry.
92
+
93
+ ## Path C — CI-safe install pattern
94
+
95
+ CI agents (GitHub Actions runners, GitLab runners, Jenkins agents
96
+ behind a corporate proxy) get a narrower happy-path:
97
+
98
+ - **Cached tarball** in the runner's artifact store
99
+ (`actions/cache@v4` or equivalent), keyed on
100
+ `agent_config_version`.
101
+ - **`npm install --offline`** against the cache so the runner never
102
+ hits the registry.
103
+ - **`scripts/install.py validate`** instead of `init` — `validate`
104
+ re-reads `installed.lock` and checks the worktree matches; `init`
105
+ scaffolds tool directories which a CI agent typically does not
106
+ need.
107
+ - **No global writes.** CI runners are ephemeral; the
108
+ `~/.event4u/agent-config/installed.lock` write is harmless but the
109
+ CI job should not rely on it persisting between runs.
110
+
111
+ ## Path D — verified-offline install (`scripts/hermetic-install.sh`)
112
+
113
+ > **Naming note.** The file name is `scripts/hermetic-install.sh` for
114
+ > roadmap continuity (Phase 2 Step 5). The **semantic** per the
115
+ > Anthropic council verdict is **verified-offline install** — the
116
+ > checksum manifest is delivered via a separate channel (not bundled
117
+ > in the tarball), so the trust model is not circular. "Hermetic" is
118
+ > used in the colloquial sense (reproducible + verifiable), not the
119
+ > Bazel-strict sense.
120
+
121
+ For air-gapped or strict-supply-chain environments where (a) network
122
+ egress is fully blocked, (b) tarball integrity must be verifiable
123
+ against an external manifest, and (c) installation must be auditable
124
+ end-to-end:
125
+
126
+ ```bash
127
+ # 1. Out-of-band: operator obtains
128
+ # - agent-config-2.6.1.tgz (from a separate channel)
129
+ # - agent-config-2.6.1.sha256 (separate-channel manifest, GPG-signed)
130
+ # - public.gpg (operator-supplied trust root)
131
+
132
+ # 2. On the target machine:
133
+ bash scripts/hermetic-install.sh \
134
+ --tarball ./agent-config-2.6.1.tgz \
135
+ --manifest ./agent-config-2.6.1.sha256 \
136
+ --gpg-key ./public.gpg
137
+ ```
138
+
139
+ Outcomes recorded in `~/.event4u/agent-config/installed.lock`:
140
+
141
+ ```yaml
142
+ schema_version: 1
143
+ agent_config_version: "2.6.1"
144
+ installation_mode: "hermetic" # additive field (schema_v1 + extension)
145
+ package_checksum: "sha256:<hex>" # sha256 of the verified tarball
146
+ signature_verified: true # GPG verification result
147
+ installed_at: "2026-05-13T09:42:00Z"
148
+ tools:
149
+ - claude
150
+ ```
151
+
152
+ > **Platform support.** Unix-only (macOS + Linux). The script depends
153
+ > on `bash`, `sha256sum`/`shasum`, and `gpg`. Windows support is
154
+ > future scope per the Phase 2 council session (o1 verdict). Windows
155
+ > users go through Path B (offline cache) on WSL.
156
+
157
+ > **Schema cadence.** The three additional fields are written under
158
+ > `schema_version: 1` as additive keys. The bump to
159
+ > `schema_version: 2` is captured as a deferred ADR candidate in
160
+ > `agents/roadmaps/road-to-distribution-maturity.md` Notes § "Phase 2
161
+ > lock-schema extension — ADR candidate" — not opened this PR.
162
+
163
+ ## No-internet developer runbook
164
+
165
+ A developer arrives on Monday with no network and finds a broken
166
+ `npx` cache (corrupted, stale, or never staged). Recovery:
167
+
168
+ 1. **Confirm no-network.** `curl -m 5 https://registry.npmjs.org/ ||
169
+ echo "offline as expected"`.
170
+ 2. **Inventory what is local.**
171
+ - `ls ~/.npm/_cacache/` — is the offline cache present?
172
+ - `cat ~/.event4u/agent-config/installed.lock` — was a prior
173
+ install successful?
174
+ 3. **Pick a path:**
175
+ - Cache present + lock present → **Path B**, `npx --prefer-offline`.
176
+ - Cache present + lock missing → **Path B**, then `validate`.
177
+ - Cache missing + tarball + manifest present → **Path D**.
178
+ - Cache missing + nothing else → ask the IT contact to deliver
179
+ either a fresh tarball (for Path D) or a fresh cache archive
180
+ (for Path B). Do not attempt to bridge to the registry.
181
+ 4. **Verify.** After whichever path, run `npx --prefer-offline
182
+ @event4u/agent-config validate` and confirm exit code zero. If
183
+ `validate` fails on a checksum or version mismatch, the cache
184
+ or tarball is stale — re-acquire, do not edit `installed.lock`
185
+ by hand.
186
+
187
+ > No code recovery path goes through editing `installed.lock`
188
+ > manually. The file is atomic (`os.replace`) by design — hand-edits
189
+ > bypass the schema invariant and will be overwritten on the next
190
+ > `init`/`update`.
191
+
192
+ ## See also
193
+
194
+ - `agents/roadmaps/road-to-distribution-maturity.md` § Phase 2 — the
195
+ roadmap entry that produced this document.
196
+ - `agents/council-questions/composer-fallback-feasibility.md` — the
197
+ question that rejected the Composer path.
198
+ - `agents/council-questions/hermetic-install-scaffolding.md` — the
199
+ question that shaped Path D.
200
+ - `docs/decisions/ADR-007-agent-discovery-scopes.md` — the lock
201
+ manifest contract that Phase 2 extends additively.
@@ -1,10 +1,18 @@
1
1
  # Augment Code Setup
2
2
 
3
- Augment Code is the **substrate** for this package — every other tool
4
- mirrors content from the canonical `.augment/` tree. The Augment
5
- extension (VS Code, JetBrains) reads `.augment/rules/`,
6
- `.augment/skills/`, `.augment/commands/`, `.augment/personas/`, and
7
- `.augment/contexts/` directly.
3
+ Augment Code is **global-only** in this package — content ships from a
4
+ single user-scope tree at `~/.augment/` and the Augment extension
5
+ (VS Code, JetBrains) reads it on every workspace. Per-project
6
+ `.augment/` content is not installed; project `init` writes only the
7
+ `.augment/settings.json` marker that authorizes the plugin for the
8
+ workspace.
9
+
10
+ > **Why global-only?** Augment counts the full body of every file in
11
+ > `.augment/rules/` against its 49,512-char workspace-guidelines limit.
12
+ > The package-wide rule set exceeds that limit on every workspace, so
13
+ > a single user-scope install is the canonical surface and the
14
+ > overflow is a known, accepted trade-off. See
15
+ > [`ADR-007 § Amendment 2026-05-13 — global-only`](../../decisions/ADR-007-agent-discovery-scopes.md#amendment-2026-05-13--augment-global-only).
8
16
 
9
17
  ## Prerequisites
10
18
 
@@ -13,28 +21,31 @@ extension (VS Code, JetBrains) reads `.augment/rules/`,
13
21
 
14
22
  ## Install
15
23
 
16
- Project scope (default):
24
+ Global scope (the only supported path — deploys the full bundle to
25
+ `~/.augment/`):
17
26
 
18
27
  ```bash
19
- npx @event4u/agent-config init --tools=augment
28
+ npx @event4u/agent-config init --tools=augment --global
20
29
  ```
21
30
 
22
- Global scope (cross-project, deploys the full bundle to `~/.augment/`):
31
+ `--tools=augment` without `--global` is rejected with a directive
32
+ error; `--tools=all` (project scope) silently filters `augment` out.
23
33
 
24
- ```bash
25
- npx @event4u/agent-config init --tools=augment --global
26
- ```
34
+ Populates (`~/.augment/`):
35
+
36
+ - `~/.augment/rules/` — kernel (9 Iron-Law rules) + tier-1/2 routed rules
37
+ - `~/.augment/skills/` — domain skills
38
+ - `~/.augment/commands/` — slash commands
39
+ - `~/.augment/personas/` — review-lens personas
40
+ - `~/.augment/contexts/` — knowledge-layer contexts
41
+ - `~/.augment/templates/` — scaffolds for AGENTS.md, copilot-instructions, etc.
27
42
 
28
- Populates (project):
43
+ A project-scope `init` (any `--tools=…` selection except `augment`)
44
+ still writes:
29
45
 
30
- - `.augment/rules/` kernel (9 Iron-Law rules) + tier-1/2 routed rules
31
- - `.augment/skills/` domain skills
32
- - `.augment/commands/` slash commands
33
- - `.augment/personas/` — review-lens personas
34
- - `.augment/contexts/` — knowledge-layer contexts
35
- - `.augment/templates/` — scaffolds for AGENTS.md, copilot-instructions, etc.
36
- - `AGENTS.md` — canonical agent self-orientation
37
- - `.agent-settings.yml` — per-project knobs
46
+ - `.augment/settings.json` plugin activation marker for the workspace
47
+ - `AGENTS.md` canonical agent self-orientation
48
+ - `.agent-settings.yml` per-project knobs
38
49
 
39
50
  ## How to use
40
51
 
@@ -53,9 +64,9 @@ Populates (project):
53
64
  ## Verification
54
65
 
55
66
  ```bash
56
- test -d .augment/rules
57
- test -d .augment/skills
58
- test -d .augment/commands
67
+ test -d ~/.augment/rules
68
+ test -d ~/.augment/skills
69
+ test -d ~/.augment/commands
59
70
  test -f AGENTS.md
60
71
  ```
61
72
 
@@ -67,8 +78,9 @@ should cite the AGENTS.md emergency triage block.
67
78
  | Symptom | Fix |
68
79
  |---|---|
69
80
  | Skills not surfaced | Reload the Augment workspace; skills are indexed on session start. |
70
- | Symlinked sub-dirs missing | `.augment/skills` is a symlink to `.agent-src/skills`; run `task sync` to rebuild. |
71
- | Iron Laws not firing | Confirm `.augment/rules/` contains 9 kernel files (`task ci` validates the kernel count). |
81
+ | `~/.augment/rules/` missing | Re-run `npx @event4u/agent-config init --tools=augment --global`. |
82
+ | Workspace-guidelines overflow warning | Expected the package rule set exceeds Augment's 49,512-char budget. See [`ADR-007 § Amendment 2026-05-13`](../../decisions/ADR-007-agent-discovery-scopes.md#amendment-2026-05-13--augment-global-only). |
83
+ | Iron Laws not firing | Confirm `~/.augment/rules/` contains 9 kernel files. |
72
84
 
73
85
  ## Cross-references
74
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Shared agent configuration \u2014 skills, rules, commands, guidelines, and templates for AI coding tools",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python3
2
+ """One-shot bootstrap — inject `tier: N` frontmatter into every slash command.
3
+
4
+ Per Phase 4 Step 3 of `agents/roadmaps/road-to-distribution-maturity.md`.
5
+
6
+ Walks `.agent-src.uncompressed/commands/**.md`. For each file:
7
+
8
+ - Tier-0 promotions match TIER_0 below — typed by hand.
9
+ - Tier-1 promotions match TIER_1 below — typed by hand.
10
+ - Everything else defaults to **Tier-2** (per the contract).
11
+
12
+ Idempotent — re-running is a no-op once tiers are tagged. The lint
13
+ script `scripts/lint_command_tiers.py` enforces drift from here on.
14
+
15
+ Run from repo root: `python3 scripts/_bootstrap_tier_frontmatter.py`.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import re
20
+ from pathlib import Path
21
+
22
+ REPO_ROOT = Path(__file__).resolve().parent.parent
23
+ COMMANDS_DIRS = (
24
+ REPO_ROOT / ".agent-src.uncompressed" / "commands",
25
+ REPO_ROOT / ".agent-src" / "commands",
26
+ )
27
+
28
+ # Tier-0 — daily-driver slash commands (per docs/contracts/command-surface-tiers.md).
29
+ # Paths are relative to COMMANDS_DIR.
30
+ TIER_0 = {
31
+ "onboard.md",
32
+ "commit.md",
33
+ "work.md",
34
+ "implement-ticket.md",
35
+ "agent-status.md",
36
+ "agent-handoff.md",
37
+ }
38
+
39
+ # Tier-1 — power-user / maintainer / orchestrator slash commands.
40
+ TIER_1 = {
41
+ "create-pr.md",
42
+ "review-changes.md",
43
+ "optimize.md",
44
+ "roadmap.md",
45
+ "feature.md",
46
+ "fix.md",
47
+ "judge.md",
48
+ "memory.md",
49
+ "council.md",
50
+ "agents.md",
51
+ "commit/in-chunks.md",
52
+ "create-pr/description-only.md",
53
+ "quality-fix.md",
54
+ "prepare-for-review.md",
55
+ "estimate-ticket.md",
56
+ "refine-ticket.md",
57
+ "bug-fix.md",
58
+ "bug-investigate.md",
59
+ "jira-ticket.md",
60
+ "compress.md",
61
+ "mode.md",
62
+ "project-analyze.md",
63
+ "project-health.md",
64
+ "rule-compliance-audit.md",
65
+ "threat-model.md",
66
+ "set-cost-profile.md",
67
+ "sync-agent-settings.md",
68
+ "sync-gitignore.md",
69
+ "upstream-contribute.md",
70
+ }
71
+
72
+ FRONTMATTER_RE = re.compile(r"^---\n(.*?)\n---\n", re.DOTALL)
73
+
74
+
75
+ def classify(rel_path: str) -> int:
76
+ if rel_path in TIER_0:
77
+ return 0
78
+ if rel_path in TIER_1:
79
+ return 1
80
+ return 2
81
+
82
+
83
+ def inject_tier(text: str, tier: int) -> tuple[str, bool]:
84
+ """Inject `tier: N` into the frontmatter block. Returns (new_text, changed).
85
+
86
+ If frontmatter already contains `tier:`, the existing value wins
87
+ (idempotent — bootstrap never overrides a manual tag).
88
+ """
89
+ m = FRONTMATTER_RE.match(text)
90
+ if not m:
91
+ return text, False
92
+ block = m.group(1)
93
+ if re.search(r"^tier:\s*[012]\s*$", block, re.MULTILINE):
94
+ return text, False
95
+ # Insert `tier: N` right after the `name:` line if present, else at
96
+ # the top of the block.
97
+ name_match = re.search(r"^(name:\s*\S+)$", block, re.MULTILINE)
98
+ if name_match:
99
+ new_block = (
100
+ block[: name_match.end()]
101
+ + f"\ntier: {tier}"
102
+ + block[name_match.end() :]
103
+ )
104
+ else:
105
+ new_block = f"tier: {tier}\n{block}"
106
+ new_fm = f"---\n{new_block}\n---\n"
107
+ return new_fm + text[m.end() :], True
108
+
109
+
110
+ def main() -> int:
111
+ overall_tagged = 0
112
+ overall_skipped = 0
113
+ for commands_dir in COMMANDS_DIRS:
114
+ if not commands_dir.is_dir():
115
+ print(f"[bootstrap-tier] no commands dir: {commands_dir}")
116
+ continue
117
+ files = sorted(commands_dir.rglob("*.md"))
118
+ tagged = 0
119
+ skipped = 0
120
+ by_tier = {0: 0, 1: 0, 2: 0}
121
+ for path in files:
122
+ rel = path.relative_to(commands_dir).as_posix()
123
+ # Sub-AGENTS.md files are not slash commands.
124
+ if rel.endswith("AGENTS.md"):
125
+ continue
126
+ tier = classify(rel)
127
+ by_tier[tier] += 1
128
+ text = path.read_text(encoding="utf-8")
129
+ new_text, changed = inject_tier(text, tier)
130
+ if changed:
131
+ path.write_text(new_text, encoding="utf-8")
132
+ tagged += 1
133
+ else:
134
+ skipped += 1
135
+ overall_tagged += tagged
136
+ overall_skipped += skipped
137
+ rel_label = commands_dir.relative_to(REPO_ROOT)
138
+ print(
139
+ f"[bootstrap-tier] dir={rel_label} tagged={tagged} "
140
+ f"skipped={skipped} tier-0={by_tier[0]} "
141
+ f"tier-1={by_tier[1]} tier-2={by_tier[2]}"
142
+ )
143
+ print(
144
+ f"[bootstrap-tier] total: tagged={overall_tagged} "
145
+ f"skipped={overall_skipped}"
146
+ )
147
+ return 0
148
+
149
+
150
+ if __name__ == "__main__":
151
+ raise SystemExit(main())