@event4u/agent-config 1.9.1 → 1.13.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 (85) hide show
  1. package/.agent-src/commands/agent-handoff.md +15 -0
  2. package/.agent-src/commands/chat-history-clear.md +98 -0
  3. package/.agent-src/commands/chat-history-resume.md +178 -0
  4. package/.agent-src/commands/chat-history.md +102 -0
  5. package/.agent-src/commands/compress.md +9 -9
  6. package/.agent-src/commands/copilot-agents-init.md +1 -1
  7. package/.agent-src/commands/fix-portability.md +2 -2
  8. package/.agent-src/commands/fix-pr-bot-comments.md +1 -1
  9. package/.agent-src/commands/fix-pr-developer-comments.md +1 -1
  10. package/.agent-src/commands/fix-references.md +2 -2
  11. package/.agent-src/commands/mode.md +5 -5
  12. package/.agent-src/commands/onboard.md +171 -0
  13. package/.agent-src/commands/roadmap-create.md +7 -2
  14. package/.agent-src/commands/roadmap-execute.md +2 -2
  15. package/.agent-src/commands/set-cost-profile.md +101 -0
  16. package/.agent-src/commands/sync-agent-settings.md +122 -0
  17. package/.agent-src/commands/sync-gitignore.md +104 -0
  18. package/.agent-src/commands/tests-execute.md +6 -6
  19. package/.agent-src/commands/upstream-contribute.md +5 -4
  20. package/.agent-src/contexts/augment-infrastructure.md +2 -2
  21. package/.agent-src/contexts/override-system.md +1 -1
  22. package/.agent-src/contexts/subagent-configuration.md +3 -3
  23. package/.agent-src/guidelines/agent-infra/layered-settings.md +48 -5
  24. package/.agent-src/rules/ask-when-uncertain.md +56 -3
  25. package/.agent-src/rules/augment-portability.md +52 -1
  26. package/.agent-src/rules/augment-source-of-truth.md +10 -10
  27. package/.agent-src/rules/chat-history.md +171 -0
  28. package/.agent-src/rules/docker-commands.md +5 -7
  29. package/.agent-src/rules/docs-sync.md +13 -9
  30. package/.agent-src/rules/improve-before-implement.md +2 -0
  31. package/.agent-src/rules/onboarding-gate.md +94 -0
  32. package/.agent-src/rules/package-ci-checks.md +6 -5
  33. package/.agent-src/rules/roadmap-progress-sync.md +24 -13
  34. package/.agent-src/rules/size-enforcement.md +1 -1
  35. package/.agent-src/rules/skill-quality.md +1 -1
  36. package/.agent-src/rules/think-before-action.md +1 -0
  37. package/.agent-src/rules/user-interaction.md +53 -7
  38. package/.agent-src/scripts/update_roadmap_progress.py +57 -10
  39. package/.agent-src/skills/check-refs/SKILL.md +1 -1
  40. package/.agent-src/skills/command-routing/SKILL.md +1 -1
  41. package/.agent-src/skills/command-writing/SKILL.md +4 -3
  42. package/.agent-src/skills/file-editor/SKILL.md +2 -2
  43. package/.agent-src/skills/guideline-writing/SKILL.md +4 -3
  44. package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +2 -2
  45. package/.agent-src/skills/lint-skills/SKILL.md +1 -1
  46. package/.agent-src/skills/roadmap-management/SKILL.md +13 -10
  47. package/.agent-src/skills/rtk-output-filtering/SKILL.md +20 -30
  48. package/.agent-src/skills/rule-writing/SKILL.md +5 -5
  49. package/.agent-src/skills/terragrunt/SKILL.md +0 -8
  50. package/.agent-src/skills/upstream-contribute/SKILL.md +5 -4
  51. package/.agent-src/templates/agent-settings.md +86 -34
  52. package/.agent-src/templates/github-workflows/roadmap-progress-check.yml +63 -0
  53. package/.agent-src/templates/hooks/pre-commit-roadmap-progress +60 -0
  54. package/.agent-src/templates/scripts/memory_lookup.py +382 -21
  55. package/.agent-src/templates/scripts/memory_status.py +110 -9
  56. package/.claude-plugin/marketplace.json +1 -1
  57. package/AGENTS.md +2 -2
  58. package/CHANGELOG.md +320 -0
  59. package/CONTRIBUTING.md +89 -40
  60. package/README.md +24 -3
  61. package/composer.json +5 -1
  62. package/config/agent-settings.template.yml +45 -6
  63. package/config/gitignore-block.txt +24 -0
  64. package/config/profiles/balanced.ini +5 -0
  65. package/config/profiles/full.ini +5 -0
  66. package/config/profiles/minimal.ini +5 -0
  67. package/docs/customization.md +30 -4
  68. package/docs/getting-started.md +53 -3
  69. package/docs/mcp.md +15 -4
  70. package/package.json +21 -2
  71. package/scripts/agent-config +230 -0
  72. package/scripts/chat_history.py +519 -0
  73. package/scripts/check_portability.py +151 -1
  74. package/scripts/install.py +55 -3
  75. package/scripts/install.sh +50 -21
  76. package/scripts/mcp_render.py +30 -16
  77. package/scripts/memory_lookup.py +143 -7
  78. package/scripts/memory_status.py +76 -14
  79. package/scripts/postinstall.sh +16 -0
  80. package/scripts/release.py +588 -0
  81. package/scripts/sync_agent_settings.py +211 -0
  82. package/scripts/sync_gitignore.py +226 -0
  83. package/templates/agent-config-wrapper.sh +47 -0
  84. package/.agent-src/commands/config-agent-settings.md +0 -126
  85. package/.agent-src/skills/eloquent/evals/last-run.json +0 -99
@@ -12,8 +12,9 @@ grouped sections (`personal`, `project`, `github`, `eloquent`, `pipelines`,
12
12
 
13
13
  Keep the format regular — 2-space indent, no tabs, no lists, one nesting
14
14
  level only. The installer's YAML handler is a restricted stdlib parser, not
15
- a full YAML engine. Run `/config-agent-settings` to normalize after manual
16
- edits.
15
+ a full YAML engine. Ask the agent to normalize after manual edits — it
16
+ follows the merge rules in
17
+ [`layered-settings`](../guidelines/agent-infra/layered-settings.md#section-aware-merge-rules).
17
18
 
18
19
  ### Migration from the legacy `.agent-settings` (key=value)
19
20
 
@@ -32,13 +33,15 @@ exists and is the source of truth.
32
33
  ## Template
33
34
 
34
35
  This block defines the personal and project-level settings that
35
- `/config-agent-settings` (and `bin/install.php` via
36
- `config/agent-settings.template.yml`) writes to `.agent-settings.yml`.
36
+ `scripts/install.py` (via `config/agent-settings.template.yml`)
37
+ writes to `.agent-settings.yml` on first install. Subsequent edits are
38
+ made by the user directly or by the agent on request, following the
39
+ [section-aware merge rules](../guidelines/agent-infra/layered-settings.md#section-aware-merge-rules).
37
40
 
38
41
  ```yaml
39
42
  # Agent Settings
40
43
  # This file is git-ignored. Each developer has their own settings.
41
- # Run /config-agent-settings to create or update this file.
44
+ # Run scripts/install to create this file, then /onboard for first-run setup.
42
45
 
43
46
  # --- Cost profile ---
44
47
  #
@@ -60,10 +63,11 @@ personal:
60
63
  open_edited_files: false
61
64
 
62
65
  # User's first name — used to address the user personally
66
+ # Captured by /onboard on first run.
63
67
  user_name: ""
64
68
 
65
69
  # rtk (Rust Token Killer) installed for output filtering (true, false)
66
- # Agent will auto-detect and ask once, then store the result
70
+ # Detected and set by /onboard on first run.
67
71
  rtk_installed: false
68
72
 
69
73
  # Minimal output mode (true, false)
@@ -76,11 +80,12 @@ personal:
76
80
  # false = silently investigate, only report the conclusion
77
81
  play_by_play: false
78
82
 
79
- # --- Project / team preferences ---
80
- project:
81
83
  # Prefix PR comment replies with a bot icon 🤖 (true, false)
84
+ # Personal preference — each developer decides for themselves.
82
85
  pr_comment_bot_icon: false
83
86
 
87
+ # --- Project / team preferences ---
88
+ project:
84
89
  # Path to the PR template file (relative to project root)
85
90
  pr_template: .github/pull_request_template.md
86
91
 
@@ -106,12 +111,34 @@ eloquent:
106
111
  # magic_properties = use $model->column_name (Laravel default)
107
112
  access_style: getters_setters
108
113
 
114
+ # --- Chat history (crash recovery) ---
115
+ #
116
+ # Persistent JSONL log at .agent-chat-history (project root, git-ignored).
117
+ # Keeps a durable record of the conversation so a crashed or switched
118
+ # agent session can be resumed. See scripts/chat_history.py for the API.
119
+ #
120
+ # Defaults below are placeholders — scripts/install.py substitutes them
121
+ # per cost_profile (see config/profiles/*.ini).
122
+ chat_history:
123
+ # Log chat events to disk (true, false)
124
+ enabled: true
125
+
126
+ # Logging granularity: per_turn | per_phase | per_tool
127
+ frequency: per_phase
128
+
129
+ # Max file size in KB before overflow handling kicks in
130
+ max_size_kb: 256
131
+
132
+ # Overflow behavior: rotate (drop oldest) | compress (summarize)
133
+ on_overflow: rotate
134
+
109
135
  # --- Optional pipelines ---
110
136
  pipelines:
111
137
  # Skill improvement pipeline (true, false)
112
- # true = after meaningful tasks, propose learning capture and improvements
138
+ # true = after meaningful tasks, propose learning capture and improvements (default)
113
139
  # false = silent, no post-task analysis
114
- skill_improvement: false
140
+ # Included by every cost_profile except `custom`.
141
+ skill_improvement: true
115
142
 
116
143
  # --- Subagent orchestration ---
117
144
  subagents:
@@ -154,30 +181,48 @@ personas:
154
181
  # the whole list. Ignored personas stay invokable explicitly via
155
182
  # `--personas=<id>`. Mirrors `.augmentignore` semantics.
156
183
  ignore: []
184
+
185
+ # --- Onboarding ---
186
+ #
187
+ # Tracks whether the initial setup flow (/onboard) has been completed
188
+ # for this developer on this project. When false, the onboarding-gate
189
+ # rule prompts the user to run /onboard before starting normal work.
190
+ # Missing entirely = legacy project (treated as onboarded).
191
+ onboarding:
192
+ # Has the developer completed /onboard? (true, false)
193
+ # Set to true automatically by /onboard at the end. Flip to false
194
+ # if you want to re-run the flow.
195
+ onboarded: false
157
196
  ```
158
197
 
159
198
  ## Settings Reference
160
199
 
161
- Personal and project-level settings (written by `/config-agent-settings` and
162
- `bin/install.php`). **Key paths use dot-notation** to denote nesting:
163
- `personal.user_name` lives under `personal:` in YAML.
200
+ Personal and project-level settings (initial file written by
201
+ `scripts/install.py`, edits follow the merge rules in
202
+ [`layered-settings`](../guidelines/agent-infra/layered-settings.md#section-aware-merge-rules)).
203
+ **Key paths use dot-notation** to denote nesting: `personal.user_name`
204
+ lives under `personal:` in YAML.
164
205
 
165
206
  | Key path | Values | Default | Description |
166
207
  |---|---|---|---|
167
208
  | `cost_profile` | `minimal`, `balanced`, `full`, `custom` | `minimal` | Selects which agent surfaces are active. See [Cost profiles](#cost-profiles). |
168
209
  | `personal.ide` | `code`, `phpstorm`, `cursor` | _(empty)_ | CLI command to open files in the IDE |
169
210
  | `personal.open_edited_files` | `true`, `false` | `false` | Auto-open edited files in the IDE after edits |
170
- | `personal.user_name` | first name | _(empty)_ | User's first name. Agent asks on first interaction if empty, then addresses user by name. |
171
- | `personal.rtk_installed` | `true`, `false` | `false` | Whether rtk (Rust Token Killer) is installed. Agent auto-detects once and stores the result. |
211
+ | `personal.user_name` | first name | _(empty)_ | User's first name, used to address the user personally. Captured by `/onboard`. |
212
+ | `personal.rtk_installed` | `true`, `false` | `false` | Whether rtk (Rust Token Killer) is installed. Detected and set by `/onboard`. |
172
213
  | `personal.minimal_output` | `true`, `false` | `true` | When `true`: short bullet points during work, concise summary at end. When `false`: verbose explanations. |
173
214
  | `personal.play_by_play` | `true`, `false` | `false` | When `true`: share intermediate findings during investigation. When `false`: work silently, report only the conclusion. |
174
- | `project.pr_comment_bot_icon` | `true`, `false` | `false` | Prefix PR comment replies with 🤖 to indicate bot-authored replies |
215
+ | `personal.pr_comment_bot_icon` | `true`, `false` | `false` | Prefix PR comment replies with 🤖 to indicate bot-authored replies. Personal preference — each developer decides. |
175
216
  | `project.pr_template` | file path | `.github/pull_request_template.md` | Path to PR template file. Read this instead of searching for it. |
176
217
  | `project.upstream_repo` | `org/repo` | _(empty)_ | Target repository for universal improvement PRs (e.g., `org/agent-config`). |
177
218
  | `project.improvement_pr_branch_prefix` | string | `improve/agent-` | Branch prefix for agent improvement PRs. |
178
219
  | `github.pr_reply_method` | `replies_endpoint`, `create_review_comment`, `auto` | `create_review_comment` | GitHub API method for replying to PR review comments. `auto` detects on first use. |
179
220
  | `eloquent.access_style` | `getters_setters`, `get_attribute`, `magic_properties` | `getters_setters` | How to access Eloquent model attributes. See `eloquent` skill for details. |
180
- | `pipelines.skill_improvement` | `true`, `false` | `false` | When `true`: propose learning capture after meaningful tasks. When `false`: silent. |
221
+ | `chat_history.enabled` | `true`, `false` | `true` | Persist chat events to `.agent-chat-history` (JSONL) for crash recovery. |
222
+ | `chat_history.frequency` | `per_turn`, `per_phase`, `per_tool` | per profile | Logging granularity. Defaults: `minimal`→`per_turn`, `balanced`→`per_phase`, `full`→`per_tool`. |
223
+ | `chat_history.max_size_kb` | integer | per profile | Max file size before overflow handling. Defaults: `minimal`→`128`, `balanced`→`256`, `full`→`512`. |
224
+ | `chat_history.on_overflow` | `rotate`, `compress` | per profile | On overflow: `rotate` drops oldest entries; `compress` marks the file for summarization on the next turn. Defaults: `minimal`/`balanced`→`rotate`, `full`→`compress`. |
225
+ | `pipelines.skill_improvement` | `true`, `false` | `true` | When `true`: propose learning capture after meaningful tasks. When `false`: silent. Included in every profile except `custom`. |
181
226
  | `subagents.implementer_model` | model alias or empty | _(empty)_ | Model for implementer subagents. Empty = same tier as session model. See [subagent-configuration](../contexts/subagent-configuration.md). |
182
227
  | `subagents.judge_model` | model alias or empty | _(empty)_ | Model for judge subagents. Empty = one tier above implementer (opus if sonnet, sonnet if haiku). |
183
228
  | `subagents.max_parallel` | integer | `3` | Maximum parallel subagent invocations. `1` serializes. |
@@ -185,6 +230,7 @@ Personal and project-level settings (written by `/config-agent-settings` and
185
230
  | `roles.active_role` | same as `default_role` | _(empty)_ | Role currently active; set by `/mode <name>`, cleared by `/mode none`. Enables the `role-mode-adherence` rule. |
186
231
  | `personas.override` | list of persona ids | `[]` | Developer-local override of the team default lens cast. Empty = inherit `personas.default` from `.agent-project-settings.yml`. See [`layered-settings`](../guidelines/agent-infra/layered-settings.md). |
187
232
  | `personas.ignore` | list of persona ids | `[]` | Persona ids dropped from the default cast locally. Ignored personas stay invokable via `--personas=<id>`. |
233
+ | `onboarding.onboarded` | `true`, `false` | `false` | Whether `/onboard` has run on this project. The `onboarding-gate` rule prompts for `/onboard` when this is `false`. Missing entirely = legacy project, treated as onboarded. |
188
234
 
189
235
  ### Rename-Map (migration)
190
236
 
@@ -200,7 +246,7 @@ Applied automatically when `scripts/install` finds a legacy `.agent-settings`
200
246
  | `rtk_installed` | `personal.rtk_installed` |
201
247
  | `minimal_output` | `personal.minimal_output` |
202
248
  | `play_by_play` | `personal.play_by_play` |
203
- | `pr_comment_bot_icon` | `project.pr_comment_bot_icon` |
249
+ | `pr_comment_bot_icon` | `personal.pr_comment_bot_icon` |
204
250
  | `pr_template` | `project.pr_template` |
205
251
  | `upstream_repo` | `project.upstream_repo` |
206
252
  | `improvement_pr_branch_prefix` | `project.improvement_pr_branch_prefix` |
@@ -221,28 +267,34 @@ The `cost_profile` setting selects which agent surfaces are active. See
221
267
 
222
268
  | Profile | Description |
223
269
  |---|---|
224
- | `minimal` | Rules, skills, and commands only. Zero extra surface. Default. |
225
- | `balanced` | + Runtime dispatcher for skills that declare a shell command. |
226
- | `full` | + Tool adapters (GitHub / Jira, read-only, opt-in). |
270
+ | `minimal` | Rules, skills, and commands only. **Includes the learning loop.** Default. |
271
+ | `balanced` | `minimal` + Runtime dispatcher for skills that declare a shell command. |
272
+ | `full` | `balanced` + Tool adapters (GitHub / Jira, read-only, opt-in). |
227
273
  | `custom` | Ignore profile — every matrix value must be set explicitly. |
228
274
 
229
- The only cross-profile toggle written to `.agent-settings.yml` today is
230
- `pipelines.skill_improvement`. Other per-feature toggles may be added in
231
- future releases; when they land, they ship with a live consumer in code
232
- and get documented here, not before.
275
+ **Learning loop:** `pipelines.skill_improvement` is `true` by default and is
276
+ included in every profile except `custom`. It triggers post-task learning
277
+ capture via the `skill-improvement-trigger` rule. Flip to `false` in the
278
+ settings file if you want a silent agent without touching the profile.
279
+
280
+ Other per-feature toggles may be added in future releases; when they land,
281
+ they ship with a live consumer in code and get documented here, not before.
233
282
 
234
283
  ## Sync rules
235
284
 
236
- When new settings are added to this template:
285
+ When new settings are added to this template, the
286
+ [section-aware merge rules](../guidelines/agent-infra/layered-settings.md#section-aware-merge-rules)
287
+ govern the update:
237
288
 
238
- 1. The `/config-agent-settings` command detects missing keys (dot-paths) in
239
- the user's `.agent-settings.yml`.
240
- 2. Missing keys are added with their **default value** from this template,
289
+ 1. Missing keys are added with their **default value** from this template,
241
290
  inside the correct section.
242
- 3. Existing keys keep their **current value** — never overwritten.
243
- 4. The **order** of keys follows this template — existing values are
291
+ 2. Existing keys keep their **current value** — never overwritten.
292
+ 3. The **order** of keys follows this template — existing values are
244
293
  reordered to match.
245
- 5. Comments from the template are preserved in the output.
294
+ 4. Comments from the template are preserved in the output.
295
+
296
+ Re-run `scripts/install` to pull in template drift, or ask the agent to
297
+ update a specific key — it walks the same rules.
246
298
 
247
299
  ## Adding new settings
248
300
 
@@ -252,5 +304,5 @@ When adding a new setting:
252
304
  the right section (or create a new section if it is a new domain).
253
305
  2. Add a row to the Settings Reference table using the full dot-path.
254
306
  3. Update the relevant skill or command that reads this setting.
255
- 4. The next time `/config-agent-settings` runs, it will add the new key
256
- automatically.
307
+ 4. Re-run `scripts/install` (or ask the agent to sync) to pull the new
308
+ key into the user's file.
@@ -0,0 +1,63 @@
1
+ # Roadmap Progress Check — template shipped by agent-config
2
+ #
3
+ # Copy this file to `.github/workflows/roadmap-progress-check.yml` in the
4
+ # consumer project. It fails CI when `agents/roadmaps-progress.md` is
5
+ # stale relative to the source roadmaps under `agents/roadmaps/`.
6
+ #
7
+ # This is the last-line defence behind the `roadmap-progress-sync` rule
8
+ # and the optional pre-commit hook (see `./agent-config hooks:install`).
9
+ # A green check here proves the dashboard reflects reality on every PR
10
+ # that touches roadmaps.
11
+ #
12
+ # Prerequisites:
13
+ # - `.augment/scripts/update_roadmap_progress.py` installed by
14
+ # `task install` (or `./agent-config install`).
15
+ # - At least one file exists under `agents/roadmaps/` — absence
16
+ # short-circuits the check with a passing exit (consumer projects
17
+ # that haven't adopted roadmaps stay green).
18
+ #
19
+ # This workflow is intentionally narrow: it only runs when relevant
20
+ # files change, so it adds zero overhead to unrelated PRs.
21
+
22
+ name: Roadmap Progress Check
23
+
24
+ on:
25
+ push:
26
+ branches: [main]
27
+ paths:
28
+ - "agents/roadmaps/**"
29
+ - "agents/roadmaps-progress.md"
30
+ - ".augment/scripts/update_roadmap_progress.py"
31
+ pull_request:
32
+ paths:
33
+ - "agents/roadmaps/**"
34
+ - "agents/roadmaps-progress.md"
35
+ - ".augment/scripts/update_roadmap_progress.py"
36
+ workflow_dispatch: {}
37
+
38
+ permissions:
39
+ contents: read
40
+
41
+ jobs:
42
+ check:
43
+ name: Verify roadmaps-progress.md is fresh
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+
48
+ - uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.11"
51
+
52
+ - name: Run roadmap progress check
53
+ run: python3 .augment/scripts/update_roadmap_progress.py --check
54
+
55
+ - name: Remediation hint on failure
56
+ if: failure()
57
+ run: |
58
+ echo "::error::roadmaps-progress.md is stale."
59
+ echo "Regenerate locally with one of:"
60
+ echo " ./agent-config roadmap:progress"
61
+ echo " task roadmap-progress"
62
+ echo " python3 .augment/scripts/update_roadmap_progress.py"
63
+ echo "Then commit and push the updated agents/roadmaps-progress.md."
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env bash
2
+ # Pre-commit hook: roadmap progress dashboard sync (event4u/agent-config)
3
+ #
4
+ # Installed by `./agent-config hooks:install`. Aborts the commit if
5
+ # `agents/roadmaps-progress.md` is out of date relative to staged
6
+ # changes under `agents/roadmaps/`. Exits silently when no roadmap
7
+ # files are staged — zero overhead on unrelated commits.
8
+ #
9
+ # To run manually:
10
+ # ./agent-config roadmap:progress-check
11
+ #
12
+ # To uninstall:
13
+ # rm .git/hooks/pre-commit
14
+ set -e
15
+
16
+ # Only act on commits that touch roadmap content.
17
+ staged="$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null || true)"
18
+ case "$staged" in
19
+ *agents/roadmaps/*.md*|*agents/roadmaps-progress.md*|*.augment/scripts/update_roadmap_progress.py*)
20
+ : ;;
21
+ *)
22
+ exit 0 ;;
23
+ esac
24
+
25
+ # Resolve the script — prefer the consumer-shipped path, fall back to
26
+ # the source-of-truth copy when run from inside the package itself.
27
+ script=""
28
+ for cand in \
29
+ ".augment/scripts/update_roadmap_progress.py" \
30
+ ".agent-src/scripts/update_roadmap_progress.py" \
31
+ ".agent-src.uncompressed/scripts/update_roadmap_progress.py"; do
32
+ if [ -f "$cand" ]; then
33
+ script="$cand"
34
+ break
35
+ fi
36
+ done
37
+
38
+ if [ -z "$script" ]; then
39
+ echo "⚠️ pre-commit-roadmap-progress: update_roadmap_progress.py not found." >&2
40
+ echo " Run \`task install\` (or \`./agent-config install\`) and retry." >&2
41
+ echo " Skipping check — letting commit through." >&2
42
+ exit 0
43
+ fi
44
+
45
+ if ! python3 "$script" --check >/dev/null 2>&1; then
46
+ echo "❌ agents/roadmaps-progress.md is stale relative to your staged changes." >&2
47
+ echo "" >&2
48
+ echo " Regenerate the dashboard with one of:" >&2
49
+ echo " ./agent-config roadmap:progress" >&2
50
+ echo " task roadmap-progress" >&2
51
+ echo " python3 $script" >&2
52
+ echo "" >&2
53
+ echo " Then \`git add agents/roadmaps-progress.md\` and retry the commit." >&2
54
+ echo "" >&2
55
+ echo " To bypass once (NOT recommended):" >&2
56
+ echo " git commit --no-verify" >&2
57
+ exit 1
58
+ fi
59
+
60
+ exit 0