@event4u/agent-config 2.6.1 → 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.
- package/.agent-src/commands/agent-handoff.md +1 -0
- package/.agent-src/commands/agent-status.md +1 -0
- package/.agent-src/commands/agents/audit.md +1 -0
- package/.agent-src/commands/agents/init.md +1 -0
- package/.agent-src/commands/agents/optimize.md +1 -0
- package/.agent-src/commands/agents.md +1 -0
- package/.agent-src/commands/analyze-reference-repo.md +1 -0
- package/.agent-src/commands/bug-fix.md +1 -0
- package/.agent-src/commands/bug-investigate.md +1 -0
- package/.agent-src/commands/challenge-me/vision.md +1 -0
- package/.agent-src/commands/challenge-me/with-docs.md +1 -0
- package/.agent-src/commands/challenge-me.md +1 -0
- package/.agent-src/commands/chat-history/import.md +1 -0
- package/.agent-src/commands/chat-history/learn.md +1 -0
- package/.agent-src/commands/chat-history/show.md +1 -0
- package/.agent-src/commands/chat-history.md +1 -0
- package/.agent-src/commands/check-current-md.md +1 -0
- package/.agent-src/commands/commit/in-chunks.md +1 -0
- package/.agent-src/commands/commit.md +1 -0
- package/.agent-src/commands/compress.md +1 -0
- package/.agent-src/commands/context/create.md +1 -0
- package/.agent-src/commands/context/refactor.md +1 -0
- package/.agent-src/commands/context.md +1 -0
- package/.agent-src/commands/cost-report.md +1 -0
- package/.agent-src/commands/council/default.md +1 -0
- package/.agent-src/commands/council/design.md +1 -0
- package/.agent-src/commands/council/optimize.md +1 -0
- package/.agent-src/commands/council/pr.md +1 -0
- package/.agent-src/commands/council.md +1 -0
- package/.agent-src/commands/create-pr/description-only.md +1 -0
- package/.agent-src/commands/create-pr.md +1 -0
- package/.agent-src/commands/e2e-heal.md +1 -0
- package/.agent-src/commands/e2e-plan.md +1 -0
- package/.agent-src/commands/estimate-ticket.md +1 -0
- package/.agent-src/commands/feature/dev.md +1 -0
- package/.agent-src/commands/feature/explore.md +1 -0
- package/.agent-src/commands/feature/plan.md +1 -0
- package/.agent-src/commands/feature/refactor.md +1 -0
- package/.agent-src/commands/feature/roadmap.md +1 -0
- package/.agent-src/commands/feature.md +1 -0
- package/.agent-src/commands/fix/ci.md +1 -0
- package/.agent-src/commands/fix/portability.md +1 -0
- package/.agent-src/commands/fix/pr-bot-comments.md +1 -0
- package/.agent-src/commands/fix/pr-comments.md +1 -0
- package/.agent-src/commands/fix/pr-developer-comments.md +1 -0
- package/.agent-src/commands/fix/refs.md +1 -0
- package/.agent-src/commands/fix/seeder.md +1 -0
- package/.agent-src/commands/fix.md +1 -0
- package/.agent-src/commands/grill-me.md +1 -0
- package/.agent-src/commands/implement-ticket.md +1 -0
- package/.agent-src/commands/jira-ticket.md +1 -0
- package/.agent-src/commands/judge/on-diff.md +1 -0
- package/.agent-src/commands/judge/solo.md +1 -0
- package/.agent-src/commands/judge/steps.md +1 -0
- package/.agent-src/commands/judge.md +1 -0
- package/.agent-src/commands/memory/add.md +1 -0
- package/.agent-src/commands/memory/load.md +1 -0
- package/.agent-src/commands/memory/mine-session.md +1 -0
- package/.agent-src/commands/memory/promote.md +1 -0
- package/.agent-src/commands/memory/propose.md +1 -0
- package/.agent-src/commands/memory.md +1 -0
- package/.agent-src/commands/mode.md +1 -0
- package/.agent-src/commands/module/create.md +1 -0
- package/.agent-src/commands/module/explore.md +1 -0
- package/.agent-src/commands/module.md +1 -0
- package/.agent-src/commands/onboard.md +1 -0
- package/.agent-src/commands/optimize/agents-dir.md +1 -0
- package/.agent-src/commands/optimize/augmentignore.md +1 -0
- package/.agent-src/commands/optimize/rtk.md +1 -0
- package/.agent-src/commands/optimize/skills.md +1 -0
- package/.agent-src/commands/optimize-prompt.md +1 -0
- package/.agent-src/commands/optimize.md +1 -0
- package/.agent-src/commands/orchestrate.md +1 -0
- package/.agent-src/commands/override/create.md +1 -0
- package/.agent-src/commands/override/manage.md +1 -0
- package/.agent-src/commands/override.md +1 -0
- package/.agent-src/commands/package-reset.md +1 -0
- package/.agent-src/commands/package-test.md +1 -0
- package/.agent-src/commands/prepare-for-review.md +1 -0
- package/.agent-src/commands/project-analyze.md +1 -0
- package/.agent-src/commands/project-health.md +1 -0
- package/.agent-src/commands/quality-fix.md +1 -0
- package/.agent-src/commands/refine-ticket.md +1 -0
- package/.agent-src/commands/research/deep.md +1 -0
- package/.agent-src/commands/research/report.md +1 -0
- package/.agent-src/commands/research.md +1 -0
- package/.agent-src/commands/review-changes.md +1 -0
- package/.agent-src/commands/review-routing.md +1 -0
- package/.agent-src/commands/roadmap/ai-council.md +1 -0
- package/.agent-src/commands/roadmap/create.md +1 -0
- package/.agent-src/commands/roadmap/process-full.md +1 -0
- package/.agent-src/commands/roadmap/process-phase.md +1 -0
- package/.agent-src/commands/roadmap/process-step.md +1 -0
- package/.agent-src/commands/roadmap.md +1 -0
- package/.agent-src/commands/rule-compliance-audit.md +1 -0
- package/.agent-src/commands/set-cost-profile.md +1 -0
- package/.agent-src/commands/sync-agent-settings.md +1 -0
- package/.agent-src/commands/sync-gitignore/fix.md +1 -0
- package/.agent-src/commands/sync-gitignore.md +1 -0
- package/.agent-src/commands/tests/create.md +1 -0
- package/.agent-src/commands/tests/execute.md +1 -0
- package/.agent-src/commands/tests.md +1 -0
- package/.agent-src/commands/threat-model.md +1 -0
- package/.agent-src/commands/update-form-request-messages.md +1 -0
- package/.agent-src/commands/upstream-contribute.md +1 -0
- package/.agent-src/commands/work.md +1 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +48 -2121
- package/README.md +58 -32
- package/docs/architecture/augment-projection.md +70 -0
- package/docs/architecture/claude-bundle.md +77 -0
- package/docs/architecture/compression.md +67 -0
- package/docs/architecture/multi-tool-projection.md +72 -0
- package/docs/architecture.md +30 -53
- package/docs/archive/CHANGELOG-pre-2.2.0.md +2138 -0
- package/docs/contracts/CHANGELOG-conventions.md +121 -0
- package/docs/contracts/command-surface-tiers.md +140 -0
- package/docs/contracts/mcp-cloud-scope.md +193 -21
- package/docs/contracts/mcp-phase-1-scope.md +1 -0
- package/docs/decisions/ADR-007-agent-discovery-scopes.md +67 -0
- package/docs/setup/enterprise-and-offline.md +201 -0
- package/docs/setup/per-ide/augment.md +37 -25
- package/package.json +1 -1
- package/scripts/_bootstrap_tier_frontmatter.py +151 -0
- package/scripts/agent-config +146 -83
- package/scripts/hermetic-install.sh +235 -0
- package/scripts/install.py +8 -1
- package/scripts/lint_command_tiers.py +115 -0
- package/scripts/mcp_server/__init__.py +5 -0
- package/scripts/schemas/command.schema.json +5 -0
package/scripts/agent-config
CHANGED
|
@@ -34,13 +34,89 @@ CONSUMER_ROOT="$(pwd)"
|
|
|
34
34
|
VERSION_FILE="$PACKAGE_ROOT/package.json"
|
|
35
35
|
|
|
36
36
|
usage() {
|
|
37
|
+
# Tier filter — see docs/contracts/command-surface-tiers.md.
|
|
38
|
+
# Default prints Tier-0 only; --tier=1 adds Tier-1; --tier=all adds Tier-2.
|
|
39
|
+
local tier="${1:-0}"
|
|
40
|
+
|
|
37
41
|
cat <<'EOF'
|
|
38
42
|
agent-config — event4u/agent-config CLI
|
|
39
43
|
|
|
40
44
|
Usage:
|
|
41
45
|
./agent-config <command> [options]
|
|
46
|
+
./agent-config --help [--tier=0|1|all]
|
|
47
|
+
EOF
|
|
48
|
+
|
|
49
|
+
cat <<'EOF'
|
|
50
|
+
|
|
51
|
+
Tier 0 — daily-driver (init → sync → validate → work):
|
|
52
|
+
init One-shot project install. Forwards to `scripts/install`
|
|
53
|
+
with all args. Entry point for `npx @event4u/agent-config init`.
|
|
54
|
+
Flags: --tools=<list> | --ai=<list> | --yes | --force
|
|
55
|
+
sync Replay agents/installed-tools.lock — re-installs any
|
|
56
|
+
tool whose bridge marker is missing locally (ADR-008).
|
|
57
|
+
Flags: --dry-run | --force | --project=<path>
|
|
58
|
+
validate Read-only drift detection on the manifest
|
|
59
|
+
(marker missing, scope divergence, version drift).
|
|
60
|
+
Exits 1 on drift. Flags: --quiet | --skip-version-check
|
|
61
|
+
work Drive the work_engine Python engine on a free-form prompt
|
|
62
|
+
(Option-A loop; called by the /work command)
|
|
63
|
+
implement-ticket Drive the work_engine Python engine on a ticket envelope
|
|
64
|
+
(Option-A loop; called by the /implement-ticket command)
|
|
65
|
+
first-run Guided first-run setup — cost profile, settings, tooling
|
|
66
|
+
keys:install-anthropic Install the Anthropic API key for the AI Council
|
|
67
|
+
(interactive, /dev/tty only, writes ~/.config/agent-config/anthropic.key 0600)
|
|
68
|
+
keys:install-openai Install the OpenAI API key for the AI Council
|
|
69
|
+
(interactive, /dev/tty only, writes ~/.config/agent-config/openai.key 0600)
|
|
70
|
+
council:estimate Pre-call council cost preview (no API call, no spend)
|
|
71
|
+
Usage: council:estimate <question> [--input-mode prompt|roadmap]
|
|
72
|
+
council:run Run the council. Requires --confirm to spend.
|
|
73
|
+
Usage: council:run <question> --output <path> --confirm
|
|
74
|
+
council:render Re-render a saved council responses JSON to markdown
|
|
75
|
+
Usage: council:render <responses.json>
|
|
76
|
+
help Show this help (default Tier-0; --tier=1|all expands)
|
|
77
|
+
--version, -V Print package version
|
|
78
|
+
EOF
|
|
79
|
+
|
|
80
|
+
if [[ "$tier" == "1" || "$tier" == "all" ]]; then
|
|
81
|
+
cat <<'EOF'
|
|
82
|
+
|
|
83
|
+
Tier 1 — power-user (release shape, audit, migration):
|
|
84
|
+
update Update the agent_config_version pin in .agent-settings.yml
|
|
85
|
+
Flags: --check (read-only) | --to <version> (explicit pin)
|
|
86
|
+
versions List available @event4u/agent-config versions
|
|
87
|
+
on npm. Marks the current pin and latest.
|
|
88
|
+
Flags: --offline | --limit=N | --json
|
|
89
|
+
global Install to user-scope paths (~/.claude/, ~/.cursor/, …)
|
|
90
|
+
Forwards to `scripts/install --global` (ADR-007).
|
|
91
|
+
Flags: --tools=<list> | --ai=<list> | --yes | --force
|
|
92
|
+
export Eject a tool's canonical content into a chosen path
|
|
93
|
+
(real file, no symlink). Idempotent; --force overrides
|
|
94
|
+
content drift. See `./agent-config export --list`.
|
|
95
|
+
Flags: --tool=<id> | --output=<path> | --force | --list
|
|
96
|
+
uninstall Remove bridge markers (project) or lockfile
|
|
97
|
+
entries (global). Idempotent. User-deployed
|
|
98
|
+
content under ~/.<tool>/ is preserved unless
|
|
99
|
+
--purge is passed (destructive).
|
|
100
|
+
Flags: --global | --tools=<list> | --dry-run
|
|
101
|
+
| --purge | --force | --project=<path>
|
|
102
|
+
prune Remove project bridge markers not declared in
|
|
103
|
+
agents/installed-tools.lock (npm-prune style).
|
|
104
|
+
Hard-floors when lockfile is absent.
|
|
105
|
+
Flags: --dry-run | --json | --project=<path>
|
|
106
|
+
| --all-missing-lock
|
|
107
|
+
doctor Read-only drift report: manifest ↔ filesystem.
|
|
108
|
+
Lists missing, modified, and foreign files.
|
|
109
|
+
Exits 1 on drift, 2 on missing lockfile.
|
|
110
|
+
Flags: --json | --project=<path>
|
|
111
|
+
migrate One-shot migration off legacy composer / npm install paths
|
|
112
|
+
Flags: --dry-run (detect only)
|
|
113
|
+
EOF
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
if [[ "$tier" == "all" ]]; then
|
|
117
|
+
cat <<'EOF'
|
|
42
118
|
|
|
43
|
-
|
|
119
|
+
Tier 2 — maintenance / internal (hooks, MCP, memory, telemetry):
|
|
44
120
|
mcp:render Render mcp.json → .cursor/mcp.json, .windsurf/mcp.json
|
|
45
121
|
(pass --claude-desktop to also write user-scope config)
|
|
46
122
|
mcp:check Dry-run mcp:render; exit non-zero if targets are stale
|
|
@@ -52,15 +128,8 @@ Commands:
|
|
|
52
128
|
roadmap:progress-check Fail if agents/roadmaps-progress.md is stale (for CI)
|
|
53
129
|
hooks:install Install the pre-commit roadmap-progress hook
|
|
54
130
|
(use --print to dump it, --force to overwrite an existing hook)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
keys:install-openai Install the OpenAI API key for the AI Council
|
|
58
|
-
(interactive, /dev/tty only, writes ~/.config/agent-config/openai.key 0600)
|
|
59
|
-
first-run Guided first-run setup — cost profile, settings, tooling
|
|
60
|
-
implement-ticket Drive the work_engine Python engine on a ticket envelope
|
|
61
|
-
(Option-A loop; called by the /implement-ticket command)
|
|
62
|
-
work Drive the work_engine Python engine on a free-form prompt
|
|
63
|
-
(Option-A loop; called by the /work command)
|
|
131
|
+
hooks:status Print the runtime hook matrix (per-platform install + bindings)
|
|
132
|
+
Flags: --format json|table, --strict (CI), --project-root <path>
|
|
64
133
|
migrate-state Migrate a legacy .implement-ticket-state.json file
|
|
65
134
|
to the v1 .work-state.json schema (preserves .bak)
|
|
66
135
|
memory:lookup Retrieve memory entries (text or JSON envelope)
|
|
@@ -83,92 +152,46 @@ Commands:
|
|
|
83
152
|
dispatch:hook Universal hook dispatcher (Phase 7, hook-architecture-v1.md)
|
|
84
153
|
Usage: dispatch:hook --platform <name> --event <event> [--native-event <native>]
|
|
85
154
|
Reads scripts/hook_manifest.yaml and runs the resolved concern chain.
|
|
86
|
-
hooks:status Print the runtime hook matrix (per-platform install + bindings)
|
|
87
|
-
Flags: --format json|table, --strict (CI), --project-root <path>
|
|
88
155
|
telemetry:record Append one artefact-engagement event (default-off)
|
|
89
156
|
telemetry:status Print artefact-engagement telemetry status (read-only)
|
|
90
157
|
telemetry:report Aggregate the engagement log into a quartile report
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
council:run Run the council. Requires --confirm to spend.
|
|
94
|
-
Usage: council:run <question> --output <path> --confirm
|
|
95
|
-
council:render Re-render a saved council responses JSON to markdown
|
|
96
|
-
Usage: council:render <responses.json>
|
|
97
|
-
update Update the agent_config_version pin in .agent-settings.yml
|
|
98
|
-
Flags: --check (read-only) | --to <version> (explicit pin)
|
|
99
|
-
migrate One-shot migration off legacy composer / npm install paths
|
|
100
|
-
Flags: --dry-run (detect only)
|
|
101
|
-
init One-shot project install. Forwards to `scripts/install`
|
|
102
|
-
with all args. Entry point for `npx @event4u/agent-config init`.
|
|
103
|
-
Flags: --tools=<list> | --ai=<list> | --yes | --force
|
|
104
|
-
global Install to user-scope paths (~/.claude/, ~/.cursor/, …)
|
|
105
|
-
Forwards to `scripts/install --global` (ADR-007).
|
|
106
|
-
Flags: --tools=<list> | --ai=<list> | --yes | --force
|
|
107
|
-
export Eject a tool's canonical content into a chosen path
|
|
108
|
-
(real file, no symlink). Idempotent; --force overrides
|
|
109
|
-
content drift. See `./agent-config export --list`.
|
|
110
|
-
Flags: --tool=<id> | --output=<path> | --force | --list
|
|
111
|
-
sync Replay agents/installed-tools.lock — re-installs any
|
|
112
|
-
tool whose bridge marker is missing locally (ADR-008).
|
|
113
|
-
Flags: --dry-run | --force | --project=<path>
|
|
114
|
-
validate Read-only drift detection on the manifest
|
|
115
|
-
(marker missing, scope divergence, version drift).
|
|
116
|
-
Exits 1 on drift. Flags: --quiet | --skip-version-check
|
|
117
|
-
uninstall Remove bridge markers (project) or lockfile
|
|
118
|
-
entries (global). Idempotent. User-deployed
|
|
119
|
-
content under ~/.<tool>/ is preserved unless
|
|
120
|
-
--purge is passed (destructive).
|
|
121
|
-
Flags: --global | --tools=<list> | --dry-run
|
|
122
|
-
| --purge | --force | --project=<path>
|
|
123
|
-
prune Remove project bridge markers not declared in
|
|
124
|
-
agents/installed-tools.lock (npm-prune style).
|
|
125
|
-
Hard-floors when lockfile is absent.
|
|
126
|
-
Flags: --dry-run | --json | --project=<path>
|
|
127
|
-
| --all-missing-lock
|
|
128
|
-
doctor Read-only drift report: manifest ↔ filesystem.
|
|
129
|
-
Lists missing, modified, and foreign files.
|
|
130
|
-
Exits 1 on drift, 2 on missing lockfile.
|
|
131
|
-
Flags: --json | --project=<path>
|
|
132
|
-
versions List available @event4u/agent-config versions
|
|
133
|
-
on npm. Marks the current pin and latest.
|
|
134
|
-
Flags: --offline | --limit=N | --json
|
|
135
|
-
help Show this help
|
|
136
|
-
--version, -V Print package version
|
|
158
|
+
EOF
|
|
159
|
+
fi
|
|
137
160
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
161
|
+
if [[ "$tier" == "0" ]]; then
|
|
162
|
+
cat <<'EOF'
|
|
163
|
+
|
|
164
|
+
(Hidden: 9 Tier-1 + 26 Tier-2 commands. Run `./agent-config --help --tier=1`
|
|
165
|
+
or `--tier=all` to see them. Tier criteria: docs/contracts/command-surface-tiers.md.)
|
|
166
|
+
EOF
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
cat <<'EOF'
|
|
170
|
+
|
|
171
|
+
Examples (Tier 0):
|
|
172
|
+
./agent-config init --tools=claude-code,cursor --yes
|
|
173
|
+
./agent-config sync --dry-run
|
|
174
|
+
./agent-config sync
|
|
175
|
+
./agent-config validate
|
|
148
176
|
./agent-config first-run
|
|
149
|
-
./agent-config implement-ticket --state-file .work-state.json
|
|
150
177
|
./agent-config work --state-file .work-state.json --prompt-file prompt.txt
|
|
151
|
-
./agent-config
|
|
152
|
-
./agent-config
|
|
153
|
-
./agent-config
|
|
154
|
-
./agent-config memory:check --path agents/memory
|
|
155
|
-
./agent-config refine-ticket:detect ticket-body.txt
|
|
156
|
-
./agent-config telemetry:status
|
|
157
|
-
./agent-config telemetry:status --format json
|
|
158
|
-
./agent-config telemetry:report --since 30d --top 20
|
|
159
|
-
./agent-config telemetry:report --since 7d --format json --top 0
|
|
178
|
+
./agent-config implement-ticket --state-file .work-state.json
|
|
179
|
+
./agent-config keys:install-anthropic
|
|
180
|
+
./agent-config keys:install-openai
|
|
160
181
|
./agent-config council:estimate prompt.txt
|
|
161
182
|
./agent-config council:run prompt.txt --output agents/council-sessions/out.json --confirm
|
|
162
183
|
./agent-config council:render agents/council-sessions/out.json
|
|
163
|
-
|
|
184
|
+
EOF
|
|
185
|
+
|
|
186
|
+
if [[ "$tier" == "1" || "$tier" == "all" ]]; then
|
|
187
|
+
cat <<'EOF'
|
|
188
|
+
|
|
189
|
+
Examples (Tier 1):
|
|
164
190
|
./agent-config global --tools=claude-code --yes
|
|
165
191
|
./agent-config global --ai=cursor,windsurf
|
|
166
192
|
./agent-config export --list
|
|
167
193
|
./agent-config export --tool=agents-md --output=AGENTS.md
|
|
168
194
|
./agent-config export --tool=copilot-instructions --output=.github/copilot-instructions.md
|
|
169
|
-
./agent-config sync --dry-run
|
|
170
|
-
./agent-config sync
|
|
171
|
-
./agent-config validate
|
|
172
195
|
./agent-config uninstall --tools=cursor --dry-run
|
|
173
196
|
./agent-config uninstall --global --tools=windsurf --purge
|
|
174
197
|
./agent-config prune --dry-run
|
|
@@ -180,6 +203,33 @@ Examples:
|
|
|
180
203
|
./agent-config versions --json
|
|
181
204
|
./agent-config init --offline --tools=claude-code,cursor --yes
|
|
182
205
|
./agent-config update --offline --to=2.2.0
|
|
206
|
+
EOF
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
if [[ "$tier" == "all" ]]; then
|
|
210
|
+
cat <<'EOF'
|
|
211
|
+
|
|
212
|
+
Examples (Tier 2):
|
|
213
|
+
./agent-config mcp:render
|
|
214
|
+
./agent-config mcp:render --claude-desktop
|
|
215
|
+
./agent-config mcp:check
|
|
216
|
+
./agent-config mcp:setup
|
|
217
|
+
./agent-config mcp:run
|
|
218
|
+
./agent-config roadmap:progress
|
|
219
|
+
./agent-config hooks:install
|
|
220
|
+
./agent-config migrate-state
|
|
221
|
+
./agent-config memory:lookup --types domain-invariants --key billing
|
|
222
|
+
./agent-config memory:signal --type architecture-decision --path src/Foo.php --body "…"
|
|
223
|
+
./agent-config memory:check --path agents/memory
|
|
224
|
+
./agent-config refine-ticket:detect ticket-body.txt
|
|
225
|
+
./agent-config telemetry:status
|
|
226
|
+
./agent-config telemetry:status --format json
|
|
227
|
+
./agent-config telemetry:report --since 30d --top 20
|
|
228
|
+
./agent-config telemetry:report --since 7d --format json --top 0
|
|
229
|
+
EOF
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
cat <<'EOF'
|
|
183
233
|
|
|
184
234
|
All commands operate on the CURRENT DIRECTORY (your project root).
|
|
185
235
|
The CLI is strictly consumer-facing. Maintainer tasks live in Taskfile.yml.
|
|
@@ -710,7 +760,20 @@ main() {
|
|
|
710
760
|
prune) cmd_prune "$@" ;;
|
|
711
761
|
doctor) cmd_doctor "$@" ;;
|
|
712
762
|
versions) cmd_versions "$@" ;;
|
|
713
|
-
help|--help|-h|"")
|
|
763
|
+
help|--help|-h|"")
|
|
764
|
+
# Optional `--tier=0|1|all` filter (default 0).
|
|
765
|
+
local tier_arg="0"
|
|
766
|
+
for arg in "$@"; do
|
|
767
|
+
case "$arg" in
|
|
768
|
+
--tier=0|--tier=1|--tier=all) tier_arg="${arg#--tier=}" ;;
|
|
769
|
+
--tier|-t) ;; # next arg
|
|
770
|
+
0|1|all)
|
|
771
|
+
# Positional after --tier/-t.
|
|
772
|
+
tier_arg="$arg" ;;
|
|
773
|
+
--all) tier_arg="all" ;;
|
|
774
|
+
esac
|
|
775
|
+
done
|
|
776
|
+
usage "$tier_arg" ;;
|
|
714
777
|
--version|-V) print_version ;;
|
|
715
778
|
*)
|
|
716
779
|
echo "❌ agent-config: unknown command: $cmd" >&2
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/hermetic-install.sh — verified-offline install entrypoint.
|
|
3
|
+
#
|
|
4
|
+
# Phase 2 Step 5 of agents/roadmaps/road-to-distribution-maturity.md.
|
|
5
|
+
# Council-revised semantic: this is a **verified-offline install**.
|
|
6
|
+
# The script name keeps "hermetic" for roadmap continuity; the
|
|
7
|
+
# Anthropic Phase 2 verdict requires the checksum manifest to be
|
|
8
|
+
# delivered through a separate channel (not bundled in the tarball)
|
|
9
|
+
# so the trust model is not circular.
|
|
10
|
+
#
|
|
11
|
+
# Operator brings the trust root (--gpg-key). No embedded key.
|
|
12
|
+
# Unix-only (macOS + Linux). Windows is future scope per o1 verdict.
|
|
13
|
+
#
|
|
14
|
+
# Sub-criteria from the roadmap:
|
|
15
|
+
# (a) stages a tarball from `npm pack` or operator-supplied .tgz
|
|
16
|
+
# (b) verifies sha256sum against a separate-channel manifest +
|
|
17
|
+
# operator GPG key
|
|
18
|
+
# (c) invokes `scripts/install.py --offline --package-dir=<staging>`
|
|
19
|
+
# (d) writes additive lockfile fields under schema_version: 1
|
|
20
|
+
# (installation_mode, package_checksum, signature_verified)
|
|
21
|
+
#
|
|
22
|
+
# Exit codes:
|
|
23
|
+
# 0 — install + verification succeeded
|
|
24
|
+
# 1 — argument error
|
|
25
|
+
# 2 — checksum mismatch
|
|
26
|
+
# 3 — GPG verification failed
|
|
27
|
+
# 4 — install.py invocation failed
|
|
28
|
+
# 5 — required dependency missing
|
|
29
|
+
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
|
|
32
|
+
# ---------------------------------------------------------------- usage
|
|
33
|
+
|
|
34
|
+
usage() {
|
|
35
|
+
cat <<'USAGE'
|
|
36
|
+
Usage:
|
|
37
|
+
hermetic-install.sh --tarball <file.tgz> --manifest <file.sha256>
|
|
38
|
+
--gpg-key <pubkey.gpg> [--package-dir <staging>]
|
|
39
|
+
[--package-version <semver>] [--dry-run]
|
|
40
|
+
|
|
41
|
+
Required:
|
|
42
|
+
--tarball Path to the agent-config-<version>.tgz produced
|
|
43
|
+
by `npm pack @event4u/agent-config@<version>`.
|
|
44
|
+
--manifest Path to the separate-channel sha256 manifest.
|
|
45
|
+
Manifest must be detached-signed by the operator
|
|
46
|
+
key; the script verifies the signature before
|
|
47
|
+
using the manifest for checksum comparison.
|
|
48
|
+
--gpg-key Path to the operator-supplied GPG public key
|
|
49
|
+
(ASCII-armored or binary). No embedded trust root.
|
|
50
|
+
|
|
51
|
+
Optional:
|
|
52
|
+
--package-dir Staging dir for the extracted tarball
|
|
53
|
+
(default: $(mktemp -d)).
|
|
54
|
+
--package-version Override the semver written to installed.lock
|
|
55
|
+
(default: parse package.json after extraction).
|
|
56
|
+
--dry-run Verify everything but skip install.py invocation.
|
|
57
|
+
|
|
58
|
+
Exit codes: 0 ok · 1 args · 2 checksum · 3 gpg · 4 install · 5 dep
|
|
59
|
+
USAGE
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ---------------------------------------------------------------- deps
|
|
63
|
+
|
|
64
|
+
require() {
|
|
65
|
+
command -v "$1" >/dev/null 2>&1 || {
|
|
66
|
+
echo "❌ missing required command: $1" >&2
|
|
67
|
+
exit 5
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
require bash
|
|
72
|
+
require tar
|
|
73
|
+
require gpg
|
|
74
|
+
|
|
75
|
+
# Prefer sha256sum (Linux); fall back to shasum -a 256 (macOS).
|
|
76
|
+
SHA256_CMD=""
|
|
77
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
78
|
+
SHA256_CMD="sha256sum"
|
|
79
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
80
|
+
SHA256_CMD="shasum -a 256"
|
|
81
|
+
else
|
|
82
|
+
echo "❌ missing sha256sum / shasum" >&2
|
|
83
|
+
exit 5
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------- args
|
|
87
|
+
|
|
88
|
+
TARBALL=""
|
|
89
|
+
MANIFEST=""
|
|
90
|
+
GPG_KEY=""
|
|
91
|
+
PACKAGE_DIR=""
|
|
92
|
+
PACKAGE_VERSION=""
|
|
93
|
+
DRY_RUN=0
|
|
94
|
+
|
|
95
|
+
while [[ $# -gt 0 ]]; do
|
|
96
|
+
case "$1" in
|
|
97
|
+
--tarball) TARBALL="$2"; shift 2 ;;
|
|
98
|
+
--manifest) MANIFEST="$2"; shift 2 ;;
|
|
99
|
+
--gpg-key) GPG_KEY="$2"; shift 2 ;;
|
|
100
|
+
--package-dir) PACKAGE_DIR="$2"; shift 2 ;;
|
|
101
|
+
--package-version) PACKAGE_VERSION="$2"; shift 2 ;;
|
|
102
|
+
--dry-run) DRY_RUN=1; shift ;;
|
|
103
|
+
-h|--help) usage; exit 0 ;;
|
|
104
|
+
*) echo "❌ unknown arg: $1" >&2; usage; exit 1 ;;
|
|
105
|
+
esac
|
|
106
|
+
done
|
|
107
|
+
|
|
108
|
+
if [[ -z "$TARBALL" || -z "$MANIFEST" || -z "$GPG_KEY" ]]; then
|
|
109
|
+
echo "❌ --tarball, --manifest, --gpg-key are required" >&2
|
|
110
|
+
usage
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
for f in "$TARBALL" "$MANIFEST" "$GPG_KEY"; do
|
|
115
|
+
[[ -f "$f" ]] || { echo "❌ file not found: $f" >&2; exit 1; }
|
|
116
|
+
done
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------- gpg
|
|
119
|
+
|
|
120
|
+
# Use a throwaway GPG home so we never touch the operator's
|
|
121
|
+
# real keyring. Cleanup on exit.
|
|
122
|
+
GPGHOME="$(mktemp -d)"
|
|
123
|
+
trap 'rm -rf "$GPGHOME"' EXIT
|
|
124
|
+
export GNUPGHOME="$GPGHOME"
|
|
125
|
+
|
|
126
|
+
echo "🔐 importing operator GPG key from $GPG_KEY"
|
|
127
|
+
gpg --batch --quiet --import "$GPG_KEY"
|
|
128
|
+
|
|
129
|
+
# Verify the manifest signature. Expect detached signature at
|
|
130
|
+
# <manifest>.asc OR inline-signed manifest. Try both.
|
|
131
|
+
if [[ -f "${MANIFEST}.asc" ]]; then
|
|
132
|
+
echo "🔐 verifying detached signature: ${MANIFEST}.asc"
|
|
133
|
+
gpg --batch --quiet --verify "${MANIFEST}.asc" "$MANIFEST" || {
|
|
134
|
+
echo "❌ GPG verification failed (detached)" >&2
|
|
135
|
+
exit 3
|
|
136
|
+
}
|
|
137
|
+
else
|
|
138
|
+
echo "🔐 verifying inline signature on $MANIFEST"
|
|
139
|
+
gpg --batch --quiet --verify "$MANIFEST" || {
|
|
140
|
+
echo "❌ GPG verification failed (inline)" >&2
|
|
141
|
+
echo " hint: provide ${MANIFEST}.asc as a detached signature" >&2
|
|
142
|
+
exit 3
|
|
143
|
+
}
|
|
144
|
+
fi
|
|
145
|
+
SIGNATURE_VERIFIED=true
|
|
146
|
+
|
|
147
|
+
# ---------------------------------------------------------------- sha
|
|
148
|
+
|
|
149
|
+
echo "🔍 computing tarball checksum"
|
|
150
|
+
ACTUAL_SHA="$($SHA256_CMD "$TARBALL" | awk '{print $1}')"
|
|
151
|
+
|
|
152
|
+
# Manifest format: lines of "<sha256> <relative-tarball-path>".
|
|
153
|
+
# Match by basename to avoid path-prefix surprises.
|
|
154
|
+
TARBALL_BASE="$(basename "$TARBALL")"
|
|
155
|
+
EXPECTED_SHA="$(awk -v base="$TARBALL_BASE" '
|
|
156
|
+
$2 == base || $2 == "*"base || $2 ~ "/"base"$" {print $1; exit}
|
|
157
|
+
' "$MANIFEST")"
|
|
158
|
+
|
|
159
|
+
if [[ -z "$EXPECTED_SHA" ]]; then
|
|
160
|
+
echo "❌ no checksum entry for $TARBALL_BASE in manifest" >&2
|
|
161
|
+
exit 2
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
if [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then
|
|
165
|
+
echo "❌ checksum mismatch" >&2
|
|
166
|
+
echo " expected: $EXPECTED_SHA" >&2
|
|
167
|
+
echo " actual: $ACTUAL_SHA" >&2
|
|
168
|
+
exit 2
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
PACKAGE_CHECKSUM="sha256:${ACTUAL_SHA}"
|
|
172
|
+
echo "✅ checksum verified: $PACKAGE_CHECKSUM"
|
|
173
|
+
|
|
174
|
+
# ---------------------------------------------------------------- stage
|
|
175
|
+
|
|
176
|
+
if [[ -z "$PACKAGE_DIR" ]]; then
|
|
177
|
+
PACKAGE_DIR="$(mktemp -d -t agent-config-hermetic-XXXXXX)"
|
|
178
|
+
fi
|
|
179
|
+
mkdir -p "$PACKAGE_DIR"
|
|
180
|
+
echo "📦 staging tarball into $PACKAGE_DIR"
|
|
181
|
+
tar -xzf "$TARBALL" -C "$PACKAGE_DIR"
|
|
182
|
+
|
|
183
|
+
# npm pack produces a top-level `package/` directory.
|
|
184
|
+
STAGED="$PACKAGE_DIR/package"
|
|
185
|
+
[[ -d "$STAGED" ]] || {
|
|
186
|
+
echo "❌ staged dir missing expected 'package/' subdir: $STAGED" >&2
|
|
187
|
+
exit 4
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if [[ -z "$PACKAGE_VERSION" ]] && [[ -f "$STAGED/package.json" ]]; then
|
|
191
|
+
# Pull the literal value bound to the "version" key, not the next
|
|
192
|
+
# quoted token on the same line (which is the package name when
|
|
193
|
+
# package.json is single-line).
|
|
194
|
+
PACKAGE_VERSION="$(
|
|
195
|
+
sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
|
|
196
|
+
"$STAGED/package.json" | head -n 1
|
|
197
|
+
)"
|
|
198
|
+
fi
|
|
199
|
+
[[ -n "$PACKAGE_VERSION" ]] || {
|
|
200
|
+
echo "❌ could not determine package version" >&2
|
|
201
|
+
exit 4
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# ---------------------------------------------------------------- install.py
|
|
205
|
+
|
|
206
|
+
if [[ "$DRY_RUN" -eq 1 ]]; then
|
|
207
|
+
echo "🟡 --dry-run: skipping install.py invocation"
|
|
208
|
+
echo " would invoke: scripts/install.py --offline --package-dir=$STAGED"
|
|
209
|
+
echo " installation_mode=hermetic"
|
|
210
|
+
echo " package_checksum=$PACKAGE_CHECKSUM"
|
|
211
|
+
echo " signature_verified=$SIGNATURE_VERIFIED"
|
|
212
|
+
exit 0
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
# install.py is shipped inside the staged package — invoke that
|
|
216
|
+
# copy, not whatever happens to be in $PWD.
|
|
217
|
+
INSTALL_PY="$STAGED/scripts/install.py"
|
|
218
|
+
[[ -f "$INSTALL_PY" ]] || {
|
|
219
|
+
echo "❌ install.py not found in staged package: $INSTALL_PY" >&2
|
|
220
|
+
exit 4
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
echo "🚀 invoking install.py --offline --package-dir=$STAGED"
|
|
224
|
+
# Pass the hermetic metadata via environment so install.py can record
|
|
225
|
+
# the additive lockfile fields without changing its CLI surface.
|
|
226
|
+
AGENT_CONFIG_INSTALLATION_MODE="hermetic" \
|
|
227
|
+
AGENT_CONFIG_PACKAGE_CHECKSUM="$PACKAGE_CHECKSUM" \
|
|
228
|
+
AGENT_CONFIG_SIGNATURE_VERIFIED="$SIGNATURE_VERIFIED" \
|
|
229
|
+
AGENT_CONFIG_PACKAGE_VERSION="$PACKAGE_VERSION" \
|
|
230
|
+
python3 "$INSTALL_PY" --offline --package-dir="$STAGED" || {
|
|
231
|
+
echo "❌ install.py exited non-zero" >&2
|
|
232
|
+
exit 4
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
echo "✅ verified-offline install complete (version $PACKAGE_VERSION)"
|
package/scripts/install.py
CHANGED
|
@@ -2023,7 +2023,14 @@ SCOPE_SUPPORT = {
|
|
|
2023
2023
|
"cline": "both",
|
|
2024
2024
|
"gemini-cli": "both",
|
|
2025
2025
|
"copilot": "both",
|
|
2026
|
-
|
|
2026
|
+
# `augment` is global-only by design: a single user-scope deploy to
|
|
2027
|
+
# `~/.augment/` is the canonical surface. The package owner accepts
|
|
2028
|
+
# that the full rule set exceeds Augment's 49,512-char workspace-
|
|
2029
|
+
# guidelines limit — the overflow is a known, surfaced trade-off
|
|
2030
|
+
# (see ADR-007 § Amendment 2026-05-13 — global-only). Project-scope
|
|
2031
|
+
# installs are rejected so the per-repo `.augment/` surface stays
|
|
2032
|
+
# out of the install matrix entirely.
|
|
2033
|
+
"augment": "global",
|
|
2027
2034
|
"aider": "both",
|
|
2028
2035
|
"codex": "both",
|
|
2029
2036
|
# Phase 2.4: roocode / kilocode lifted to "both" — global deploys
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Lint slash-command frontmatter for the `tier:` key.
|
|
3
|
+
|
|
4
|
+
Hard-fails CI if any command under .agent-src.uncompressed/commands/
|
|
5
|
+
lacks a `tier:` declaration or uses an unknown tier value. The valid
|
|
6
|
+
tier set is locked by docs/contracts/command-surface-tiers.md.
|
|
7
|
+
|
|
8
|
+
Hooked into `task ci` after `task lint-rule-tiers`.
|
|
9
|
+
|
|
10
|
+
Exit codes:
|
|
11
|
+
0 every command declares a valid tier
|
|
12
|
+
1 one or more commands missing or using an invalid tier
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
QUIET = "--quiet" in sys.argv
|
|
20
|
+
|
|
21
|
+
REPO = Path(__file__).resolve().parents[1]
|
|
22
|
+
COMMANDS_DIR = REPO / ".agent-src.uncompressed" / "commands"
|
|
23
|
+
# Consumer-facing projection — must also carry tier so .augment/commands/
|
|
24
|
+
# (which symlinks to .agent-src/commands/) renders the tier filter.
|
|
25
|
+
COMMANDS_DIR_COMPRESSED = REPO / ".agent-src" / "commands"
|
|
26
|
+
|
|
27
|
+
VALID_TIERS = frozenset({"0", "1", "2"})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def parse_tier(text: str) -> str | None:
|
|
31
|
+
if not text.startswith("---\n"):
|
|
32
|
+
return None
|
|
33
|
+
end = text.find("\n---\n", 4)
|
|
34
|
+
if end == -1:
|
|
35
|
+
return None
|
|
36
|
+
for line in text[4:end].splitlines():
|
|
37
|
+
if ":" not in line:
|
|
38
|
+
continue
|
|
39
|
+
k, _, v = line.partition(":")
|
|
40
|
+
if k.strip() == "tier":
|
|
41
|
+
return v.strip().strip('"').strip("'")
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def lint(commands_dir: Path, *, quiet: bool = False) -> int:
|
|
46
|
+
"""Lint a commands directory. Returns 0 on success, 1 on failure."""
|
|
47
|
+
if not commands_dir.is_dir():
|
|
48
|
+
print(
|
|
49
|
+
f"lint_command_tiers: no commands dir at {commands_dir}",
|
|
50
|
+
file=sys.stderr,
|
|
51
|
+
)
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
files = sorted(commands_dir.rglob("*.md"))
|
|
55
|
+
# Sub-AGENTS.md companions are not slash commands.
|
|
56
|
+
commands = [p for p in files if p.name != "AGENTS.md"]
|
|
57
|
+
|
|
58
|
+
if not commands:
|
|
59
|
+
print(
|
|
60
|
+
f"lint_command_tiers: no commands found under {commands_dir}",
|
|
61
|
+
file=sys.stderr,
|
|
62
|
+
)
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
missing: list[str] = []
|
|
66
|
+
invalid: list[tuple[str, str]] = []
|
|
67
|
+
|
|
68
|
+
for cmd in commands:
|
|
69
|
+
rel = cmd.relative_to(commands_dir).as_posix()
|
|
70
|
+
tier = parse_tier(cmd.read_text(encoding="utf-8"))
|
|
71
|
+
if tier is None:
|
|
72
|
+
missing.append(rel)
|
|
73
|
+
elif tier not in VALID_TIERS:
|
|
74
|
+
invalid.append((rel, tier))
|
|
75
|
+
|
|
76
|
+
if missing or invalid:
|
|
77
|
+
print(
|
|
78
|
+
f"❌ lint_command_tiers: {len(missing)} missing, "
|
|
79
|
+
f"{len(invalid)} invalid (of {len(commands)} commands)",
|
|
80
|
+
file=sys.stderr,
|
|
81
|
+
)
|
|
82
|
+
for name in missing:
|
|
83
|
+
print(f" missing tier: {name}", file=sys.stderr)
|
|
84
|
+
for name, tier in invalid:
|
|
85
|
+
print(f" invalid tier '{tier}': {name}", file=sys.stderr)
|
|
86
|
+
print(
|
|
87
|
+
f" valid tiers: {sorted(VALID_TIERS)}",
|
|
88
|
+
file=sys.stderr,
|
|
89
|
+
)
|
|
90
|
+
print(
|
|
91
|
+
" contract: docs/contracts/command-surface-tiers.md",
|
|
92
|
+
file=sys.stderr,
|
|
93
|
+
)
|
|
94
|
+
return 1
|
|
95
|
+
|
|
96
|
+
if not quiet:
|
|
97
|
+
print(
|
|
98
|
+
f"✅ lint_command_tiers: {len(commands)} commands, "
|
|
99
|
+
f"all tier values valid"
|
|
100
|
+
)
|
|
101
|
+
return 0
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def main() -> int:
|
|
105
|
+
rc = lint(COMMANDS_DIR, quiet=QUIET)
|
|
106
|
+
# The compressed projection is the consumer-facing tree (via the
|
|
107
|
+
# .augment/commands → .agent-src/commands symlink). It must also
|
|
108
|
+
# carry tier so the surface stays uniform.
|
|
109
|
+
if COMMANDS_DIR_COMPRESSED.is_dir():
|
|
110
|
+
rc |= lint(COMMANDS_DIR_COMPRESSED, quiet=QUIET)
|
|
111
|
+
return rc
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
raise SystemExit(main())
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
"""MCP server for agent-config — Phase 1 MVP.
|
|
2
2
|
|
|
3
|
+
mcp_scope: full — local stdio access can be extended to tool execution
|
|
4
|
+
under the Phase 7 wake-up triggers in `docs/contracts/mcp-cloud-scope.md`.
|
|
5
|
+
The hosted Worker (`workers/mcp/`) is `mcp_scope: lite` and is
|
|
6
|
+
intentionally narrower.
|
|
7
|
+
|
|
3
8
|
Exposes a hand-picked subset of `.agent-src/skills/` as MCP `prompts`
|
|
4
9
|
over stdio. Read-only and instructional per the A0 execution-safety
|
|
5
10
|
boundary in `agents/roadmaps/road-to-mcp-server.md`. No `tools`
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"pattern": "^[a-z][a-z0-9-]*(:[a-z][a-z0-9-]*)?$",
|
|
13
13
|
"$comment": "Top-level commands use the bare slug (`commit`). Nested cluster commands under `commands/<cluster>/<sub>.md` use the colon form (`council:default`) to mirror Claude Code's `/cluster:sub` rendering. Directory slug for `.claude/skills/` is the hyphenated form (`council-default`), generated by compress.py."
|
|
14
14
|
},
|
|
15
|
+
"tier": {
|
|
16
|
+
"type": "integer",
|
|
17
|
+
"enum": [0, 1, 2],
|
|
18
|
+
"description": "Command-surface tier per docs/contracts/command-surface-tiers.md. 0 = daily-driver (rendered in default `./agent-config --help`), 1 = power-user (rendered with `--tier=1`), 2 = maintenance/internal (rendered only with `--tier=all`). Default for new commands is 2 — promotion is gated by ADR criteria, never by author preference."
|
|
19
|
+
},
|
|
15
20
|
"description": {
|
|
16
21
|
"type": "string",
|
|
17
22
|
"minLength": 1,
|