@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
@@ -1,8 +1,9 @@
1
1
  # Agent Settings
2
2
  # This file is generated by scripts/install.py from
3
3
  # config/agent-settings.template.yml. It holds personal and project-wide
4
- # preferences. Run /config-agent-settings to re-sync it against the
5
- # template at .augment/templates/agent-settings.md.
4
+ # preferences. Run /onboard for first-run setup; for later edits, change
5
+ # values here directly or ask the agent (it follows the merge rules in
6
+ # .augment/guidelines/agent-infra/layered-settings.md).
6
7
 
7
8
  # --- Cost profile ---
8
9
  #
@@ -41,11 +42,12 @@ personal:
41
42
  # false = silently investigate, only report the conclusion
42
43
  play_by_play: false
43
44
 
44
- # --- Project / team preferences ---
45
- project:
46
45
  # Prefix PR comment replies with a bot icon 🤖 (true, false)
46
+ # Personal preference — each developer decides for themselves.
47
47
  pr_comment_bot_icon: false
48
48
 
49
+ # --- Project / team preferences ---
50
+ project:
49
51
  # Path to the PR template file (relative to project root)
50
52
  pr_template: .github/pull_request_template.md
51
53
 
@@ -71,12 +73,37 @@ eloquent:
71
73
  # magic_properties = use $model->column_name (Laravel default)
72
74
  access_style: getters_setters
73
75
 
76
+ # --- Chat history (crash recovery) ---
77
+ #
78
+ # Persistent JSONL log at .agent-chat-history (project root, git-ignored).
79
+ # Keeps a durable record of the conversation so a crashed or switched
80
+ # agent session can be resumed. See scripts/chat_history.py for the API.
81
+ chat_history:
82
+ # Log chat events to disk (true, false)
83
+ enabled: true
84
+
85
+ # Logging granularity
86
+ # per_turn = one entry per user↔agent turn (lightest)
87
+ # per_phase = one entry per workflow phase
88
+ # per_tool = one entry per tool call (most verbose)
89
+ frequency: __CHAT_HISTORY_FREQUENCY__
90
+
91
+ # Max file size in KB before overflow handling kicks in (integer)
92
+ max_size_kb: __CHAT_HISTORY_MAX_SIZE_KB__
93
+
94
+ # Overflow behavior
95
+ # rotate = drop oldest entries to stay under max_size_kb
96
+ # compress = mark for summarization on the next agent turn
97
+ on_overflow: __CHAT_HISTORY_ON_OVERFLOW__
98
+
74
99
  # --- Optional pipelines ---
75
100
  pipelines:
76
101
  # Skill improvement pipeline (true, false)
77
- # true = after meaningful tasks, propose learning capture and improvements
102
+ # true = after meaningful tasks, propose learning capture and improvements (default)
78
103
  # false = silent, no post-task analysis
79
- skill_improvement: false
104
+ # Included by every cost_profile except `custom`. Flip to false here if you
105
+ # want a silent agent; `custom` profile ignores this default entirely.
106
+ skill_improvement: true
80
107
 
81
108
  # --- Subagent orchestration ---
82
109
  #
@@ -94,3 +121,15 @@ subagents:
94
121
  # Maximum number of parallel subagent invocations
95
122
  # Integer, default 3. Set to 1 to serialize. Hard cap enforced by runtime.
96
123
  max_parallel: 3
124
+
125
+ # --- Onboarding ---
126
+ #
127
+ # Tracks whether the initial setup flow (/onboard) has been completed
128
+ # for this developer on this project. When false, the onboarding-gate
129
+ # rule prompts the user to run /onboard before starting normal work.
130
+ # Missing entirely = legacy project (treated as onboarded).
131
+ onboarding:
132
+ # Has the developer completed /onboard? (true, false)
133
+ # Set to true automatically by /onboard at the end. Flip to false if
134
+ # you want to re-run the flow.
135
+ onboarded: false
@@ -0,0 +1,24 @@
1
+ # Agent config — symlinked from vendor (auto-managed)
2
+ .augment/skills/
3
+ .augment/commands/
4
+ .augment/guidelines/
5
+ .augment/templates/
6
+ .augment/contexts/
7
+ .augment/scripts/
8
+ .augment/README.md
9
+
10
+ # Agent config — NOT ignored (real copies, may contain project overrides)
11
+ # .augment/rules/
12
+
13
+ # Agent config — CLI wrapper (auto-generated on every install)
14
+ /agent-config
15
+
16
+ # Agent config — personal settings (written by the installer)
17
+ .agent-settings.yml
18
+ .agent-settings
19
+ .agent-settings.backup.key-value
20
+
21
+ # Agent config — persistent chat history (crash recovery, never commit)
22
+ .agent-chat-history
23
+ .agent-chat-history.bak
24
+ .agent-chat-history.*.bak
@@ -8,3 +8,8 @@
8
8
  ; See docs/customization.md for the full profile description.
9
9
 
10
10
  cost_profile=balanced
11
+
12
+ ; Chat history (crash recovery) — balanced = phase-level traceability
13
+ chat_history_frequency=per_phase
14
+ chat_history_max_size_kb=256
15
+ chat_history_on_overflow=rotate
@@ -8,3 +8,8 @@
8
8
  ; profile description.
9
9
 
10
10
  cost_profile=full
11
+
12
+ ; Chat history (crash recovery) — full = tool-level traceability + summarize on overflow
13
+ chat_history_frequency=per_tool
14
+ chat_history_max_size_kb=512
15
+ chat_history_on_overflow=compress
@@ -8,3 +8,8 @@
8
8
  ; config/agent-settings.template.ini to produce the user's .agent-settings.
9
9
 
10
10
  cost_profile=minimal
11
+
12
+ ; Chat history (crash recovery) — minimal = lightest footprint
13
+ chat_history_frequency=per_turn
14
+ chat_history_max_size_kb=128
15
+ chat_history_on_overflow=rotate
@@ -52,20 +52,46 @@ those sections.
52
52
  | `personal.play_by_play` | `false` | Share intermediate findings during analysis |
53
53
  | `personal.open_edited_files` | `false` | Open edited files in IDE |
54
54
  | `personal.ide` | *(empty)* | IDE for file opening (`cursor`, `code`, `phpstorm`) |
55
- | `pipelines.skill_improvement` | `false` | Enable post-task learning capture |
55
+ | `pipelines.skill_improvement` | `true` | Post-task learning capture. Included in every profile except `custom`. |
56
+ | `chat_history.enabled` | `true` | Persistent JSONL log at `.agent-chat-history` for crash recovery. |
57
+ | `chat_history.frequency` | per profile | Logging granularity: `per_turn`, `per_phase`, or `per_tool` (see matrix below). |
58
+ | `chat_history.max_size_kb` | per profile | Max file size before overflow handling (see matrix below). |
59
+ | `chat_history.on_overflow` | per profile | `rotate` drops oldest, `compress` marks for summarization (see matrix below). |
60
+ | `onboarding.onboarded` | `false` | Whether `/onboard` has run. The `onboarding-gate` rule prompts for `/onboard` while this is `false`. |
56
61
 
57
62
  ### Cost profiles
58
63
 
59
64
  | Profile | Description |
60
65
  |---|---|
61
- | `minimal` | Zero extra surface. Rules, skills, and commands only. |
62
- | `balanced` | + Runtime dispatcher for skills that declare a shell command. |
63
- | `full` | + Tool adapters (GitHub / Jira, read-only, opt-in). |
66
+ | `minimal` | Rules, skills, and commands only. **Includes the learning loop.** Default. |
67
+ | `balanced` | `minimal` + Runtime dispatcher for skills that declare a shell command. |
68
+ | `full` | `balanced` + Tool adapters (GitHub / Jira, read-only, opt-in). |
64
69
  | `custom` | Ignore profile — every matrix value must be set explicitly. |
65
70
 
71
+ All profiles except `custom` ship with `pipelines.skill_improvement: true`,
72
+ so the agent captures learnings after meaningful tasks by default. Set it
73
+ to `false` in `.agent-settings.yml` to silence post-task analysis without
74
+ changing the profile.
75
+
66
76
  The authoritative matrix of all matrix-controlled settings lives in
67
77
  [`.agent-src.uncompressed/templates/agent-settings.md`](../.agent-src.uncompressed/templates/agent-settings.md).
68
78
 
79
+ ### Chat-history defaults per profile
80
+
81
+ `scripts/install.py` fills these placeholders from
82
+ [`config/profiles/*.ini`](../config/profiles) when it writes
83
+ `.agent-settings.yml`. Edit the values afterwards if you want different
84
+ behavior — the per-profile table is just the initial default.
85
+
86
+ | Setting | `minimal` | `balanced` | `full` |
87
+ |---|---|---|---|
88
+ | `chat_history.enabled` | `true` | `true` | `true` |
89
+ | `chat_history.frequency` | `per_turn` | `per_phase` | `per_tool` |
90
+ | `chat_history.max_size_kb` | `128` | `256` | `512` |
91
+ | `chat_history.on_overflow` | `rotate` | `rotate` | `compress` |
92
+
93
+ `custom` ignores these defaults — set every value explicitly.
94
+
69
95
  ---
70
96
 
71
97
  ## Project documentation
@@ -19,11 +19,29 @@ runs a bash payload sync and a Python bridge generator (Python 3 is
19
19
  recommended; without it the payload sync still runs). No Task or Make
20
20
  required for end users.
21
21
 
22
+ ## Project CLI — `./agent-config`
23
+
24
+ The installer writes `./agent-config` into your project root (gitignored)
25
+ so you can run a few package scripts without installing `go-task`,
26
+ `make`, or other build tools:
27
+
28
+ ```bash
29
+ ./agent-config mcp:render # sync MCP server config into .cursor/ and .windsurf/
30
+ ./agent-config roadmap:progress # regenerate agents/roadmaps-progress.md
31
+ ./agent-config hooks:install # install pre-commit roadmap-progress hook (opt-in)
32
+ ./agent-config first-run # guided setup
33
+ ./agent-config help # full command list
34
+ ```
35
+
36
+ The wrapper is regenerated on every `npm install` / `composer install`
37
+ and delegates to the copy under `node_modules/@event4u/agent-config/`
38
+ or `vendor/event4u/agent-config/`.
39
+
22
40
  ## First Run
23
41
 
24
42
  Open your agent and try the 3 tests below. That's it — no additional tools needed.
25
43
 
26
- **Optional:** For a guided walkthrough, run `task first-run` (requires [Task](https://taskfile.dev/)).
44
+ **Optional:** For a guided walkthrough, run `./agent-config first-run`.
27
45
 
28
46
  ---
29
47
 
@@ -81,7 +99,7 @@ Your agent is now:
81
99
  - **Respecting your codebase** — no conflicting patterns
82
100
  - **Following standards** — consistent code quality
83
101
 
84
- This is enforced automatically by 44 rules. No configuration needed.
102
+ This is enforced automatically by 46 rules. No configuration needed.
85
103
 
86
104
  ---
87
105
 
@@ -115,8 +133,40 @@ Your agent now understands slash commands:
115
133
  | `/create-pr` | Create PR with Jira-linked description |
116
134
  | `/fix-ci` | Fetch and fix GitHub Actions failures |
117
135
  | `/quality-fix` | Run and fix all quality checks |
136
+ | `/chat-history` | Inspect the persistent chat-history log |
137
+ | `/chat-history-resume` | Recover context after a crashed or switched session |
138
+ | `/chat-history-clear` | Wipe the chat-history log (with confirmation) |
139
+
140
+ → [Browse all 73 commands](../.agent-src/commands/)
141
+
142
+ ---
143
+
144
+ ## Crash recovery — `.agent-chat-history`
145
+
146
+ When `chat_history.enabled: true` in `.agent-settings.yml` (on by default
147
+ for every profile), the agent keeps a JSONL log of your conversation in
148
+ `.agent-chat-history` at the project root. The file is git-ignored and
149
+ rotates at the size configured in the profile (`128 KB` on `minimal`,
150
+ `256 KB` on `balanced`, `512 KB` on `full`).
151
+
152
+ When a chat opens and finds an existing log, the agent runs a
153
+ 4-state ownership check and chooses the right flow:
154
+
155
+ - **match** — this chat already owns the file. Append silently.
156
+ - **foreign** — a different session's file. You get 3 options:
157
+ Resume (adopt), New start (archive + init), Ignore (skip logging).
158
+ - **returning** — this chat once owned the file, but another session
159
+ took over in between. You get 3 options: Merge (your history in front
160
+ of the foreign entries), Replace (wipe foreign entries, keep yours
161
+ only), Continue (just leave the file and append from now on).
162
+ - **missing** — no file yet. Init and proceed.
163
+
164
+ Run `/chat-history-resume` to walk through the prompts explicitly, or
165
+ let the agent ask on the first turn of a new chat. All merge/replace/
166
+ resume paths read the on-disk entries into context before any write.
118
167
 
119
- [Browse all 67 commands](../.agent-src/commands/)
168
+ See the [`chat-history` rule](../.agent-src/rules/chat-history.md) and
169
+ [`scripts/chat_history.py`](../scripts/chat_history.py) for the mechanics.
120
170
 
121
171
  ---
122
172
 
package/docs/mcp.md CHANGED
@@ -48,13 +48,24 @@ values literal, or resolve them from the environment.
48
48
 
49
49
  ## Usage
50
50
 
51
+ **Consumer projects** — use the `./agent-config` CLI installed into the
52
+ project root:
53
+
54
+ ```bash
55
+ ./agent-config mcp:render # write in-project targets
56
+ ./agent-config mcp:render --claude-desktop # also write user-scope Claude Desktop
57
+ ./agent-config mcp:check # dry-run; exit 1 if targets are stale
58
+ ```
59
+
60
+ **Package maintainers** — the same commands are available through Taskfile:
61
+
51
62
  ```bash
52
- task mcp:render # write in-project targets
53
- task mcp:render -- --claude-desktop # also write user-scope Claude Desktop
54
- task mcp:check # dry-run; exit 1 if targets are stale
63
+ task mcp:render
64
+ task mcp:render -- --claude-desktop
65
+ task mcp:check
55
66
  ```
56
67
 
57
- Or invoke the script directly:
68
+ Or invoke the script directly (maintainer workflow, inside the package repo):
58
69
 
59
70
  ```bash
60
71
  python3 scripts/mcp_render.py [--source PATH] [--claude-desktop] [--check]
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "1.9.1",
4
- "description": "Shared agent configuration skills, rules, commands, guidelines, and templates for AI coding tools",
3
+ "version": "1.13.0",
4
+ "description": "Shared agent configuration \u2014 skills, rules, commands, guidelines, and templates for AI coding tools",
5
5
  "license": "MIT",
6
6
  "private": false,
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/event4u-app/agent-config.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/event4u-app/agent-config/issues"
13
+ },
14
+ "homepage": "https://github.com/event4u-app/agent-config#readme",
7
15
  "files": [
8
16
  ".agent-src/",
9
17
  ".augment-plugin/",
@@ -21,11 +29,22 @@
21
29
  "composer.json",
22
30
  "llms.txt"
23
31
  ],
32
+ "bin": {
33
+ "agent-config": "scripts/agent-config"
34
+ },
24
35
  "scripts": {
25
36
  "postinstall": "bash scripts/postinstall.sh"
26
37
  },
27
38
  "publishConfig": {
28
39
  "access": "public",
29
40
  "provenance": true
41
+ },
42
+ "peerDependencies": {
43
+ "@event4u/agent-memory": "^1.1.0"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "@event4u/agent-memory": {
47
+ "optional": true
48
+ }
30
49
  }
31
50
  }
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env bash
2
+ # agent-config — consumer-facing CLI for the event4u/agent-config package.
3
+ #
4
+ # This is the MASTER entrypoint shipped inside the package
5
+ # (node_modules/@event4u/agent-config/scripts/agent-config or
6
+ # vendor/event4u/agent-config/scripts/agent-config). A thin wrapper at
7
+ # the consumer's repo root (`./agent-config`) delegates here.
8
+ #
9
+ # Commands are strictly consumer-facing. Maintainer workflows stay in
10
+ # Taskfile.yml and are NOT exposed here.
11
+ #
12
+ # Invariants:
13
+ # * CWD on entry is the consumer's repo root — we keep it that way
14
+ # so underlying scripts resolve paths correctly.
15
+ # * PACKAGE_ROOT is derived from this script's location, used only to
16
+ # locate the package-internal Python scripts (mcp_render.py, …).
17
+ # * Unknown arguments are forwarded verbatim to the underlying script.
18
+
19
+ set -euo pipefail
20
+
21
+ # Resolve symlinks in BASH_SOURCE so PACKAGE_ROOT points at the real
22
+ # package directory even when invoked via a symlink (global npm install,
23
+ # vendor/bin symlink, user-placed symlink on PATH, …).
24
+ SOURCE="${BASH_SOURCE[0]}"
25
+ while [ -L "$SOURCE" ]; do
26
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
27
+ SOURCE="$(readlink "$SOURCE")"
28
+ [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
29
+ done
30
+ SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
31
+ PACKAGE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
32
+ CONSUMER_ROOT="$(pwd)"
33
+
34
+ VERSION_FILE="$PACKAGE_ROOT/package.json"
35
+
36
+ usage() {
37
+ cat <<'EOF'
38
+ agent-config — event4u/agent-config CLI
39
+
40
+ Usage:
41
+ ./agent-config <command> [options]
42
+
43
+ Commands:
44
+ mcp:render Render mcp.json → .cursor/mcp.json, .windsurf/mcp.json
45
+ (pass --claude-desktop to also write user-scope config)
46
+ mcp:check Dry-run mcp:render; exit non-zero if targets are stale
47
+ roadmap:progress Regenerate agents/roadmaps-progress.md from open roadmaps
48
+ roadmap:progress-check Fail if agents/roadmaps-progress.md is stale (for CI)
49
+ hooks:install Install the pre-commit roadmap-progress hook
50
+ (use --print to dump it, --force to overwrite an existing hook)
51
+ first-run Guided first-run setup — cost profile, settings, tooling
52
+ help Show this help
53
+ --version, -V Print package version
54
+
55
+ Examples:
56
+ ./agent-config mcp:render
57
+ ./agent-config mcp:render --claude-desktop
58
+ ./agent-config mcp:check
59
+ ./agent-config roadmap:progress
60
+ ./agent-config hooks:install
61
+ ./agent-config first-run
62
+
63
+ All commands operate on the CURRENT DIRECTORY (your project root).
64
+ The CLI is strictly consumer-facing. Maintainer tasks live in Taskfile.yml.
65
+ EOF
66
+ }
67
+
68
+ print_version() {
69
+ if [[ -f "$VERSION_FILE" ]] && command -v python3 >/dev/null 2>&1; then
70
+ python3 -c "import json; print(json.load(open('$VERSION_FILE'))['version'])"
71
+ else
72
+ echo "unknown"
73
+ fi
74
+ }
75
+
76
+ require_python3() {
77
+ if ! command -v python3 >/dev/null 2>&1; then
78
+ echo "❌ agent-config: python3 not found on PATH" >&2
79
+ echo " Install Python 3.10+ and retry." >&2
80
+ exit 127
81
+ fi
82
+ }
83
+
84
+ # Locate a script. First argument is relative to PACKAGE_ROOT, second is
85
+ # an optional fallback relative to CONSUMER_ROOT (for scripts that ship
86
+ # to the consumer via .augment/, e.g. update_roadmap_progress.py).
87
+ resolve_script() {
88
+ local pkg_rel="$1"
89
+ local consumer_rel="${2-}"
90
+ local pkg_abs="$PACKAGE_ROOT/$pkg_rel"
91
+ if [[ -f "$pkg_abs" ]]; then
92
+ printf '%s' "$pkg_abs"
93
+ return 0
94
+ fi
95
+ if [[ -n "$consumer_rel" && -f "$CONSUMER_ROOT/$consumer_rel" ]]; then
96
+ printf '%s' "$CONSUMER_ROOT/$consumer_rel"
97
+ return 0
98
+ fi
99
+ echo "❌ agent-config: script not found: $pkg_rel" >&2
100
+ [[ -n "$consumer_rel" ]] && echo " (also tried: $consumer_rel in $CONSUMER_ROOT)" >&2
101
+ return 1
102
+ }
103
+
104
+ cmd_mcp_render() {
105
+ require_python3
106
+ local script
107
+ script="$(resolve_script "scripts/mcp_render.py")"
108
+ exec python3 "$script" "$@"
109
+ }
110
+
111
+ cmd_mcp_check() {
112
+ require_python3
113
+ local script
114
+ script="$(resolve_script "scripts/mcp_render.py")"
115
+ exec python3 "$script" --check "$@"
116
+ }
117
+
118
+ cmd_roadmap_progress() {
119
+ require_python3
120
+ local script
121
+ script="$(resolve_script ".agent-src/scripts/update_roadmap_progress.py" ".augment/scripts/update_roadmap_progress.py")"
122
+ exec python3 "$script" "$@"
123
+ }
124
+
125
+ cmd_roadmap_progress_check() {
126
+ require_python3
127
+ local script
128
+ script="$(resolve_script ".agent-src/scripts/update_roadmap_progress.py" ".augment/scripts/update_roadmap_progress.py")"
129
+ exec python3 "$script" --check "$@"
130
+ }
131
+
132
+ cmd_first_run() {
133
+ local script
134
+ script="$(resolve_script "scripts/first-run.sh")"
135
+ exec bash "$script" "$@"
136
+ }
137
+
138
+ cmd_hooks_install() {
139
+ local force=false
140
+ local print_only=false
141
+ for arg in "$@"; do
142
+ case "$arg" in
143
+ --force) force=true ;;
144
+ --print) print_only=true ;;
145
+ -h|--help)
146
+ cat <<'HELP'
147
+ agent-config hooks:install — install the pre-commit roadmap-progress hook.
148
+
149
+ Usage:
150
+ ./agent-config hooks:install [--force] [--print]
151
+
152
+ Without flags: copies the hook to .git/hooks/pre-commit. Refuses to
153
+ overwrite an existing pre-commit hook unless --force is given (the
154
+ existing hook may already chain other tooling).
155
+
156
+ --print dump the hook script to stdout (for manual chaining into an
157
+ existing pre-commit script, husky, lefthook, etc.)
158
+ --force overwrite an existing .git/hooks/pre-commit (DESTRUCTIVE)
159
+ HELP
160
+ return 0 ;;
161
+ *)
162
+ echo "❌ hooks:install: unknown argument: $arg" >&2
163
+ echo " Run \`./agent-config hooks:install --help\` for usage." >&2
164
+ return 2 ;;
165
+ esac
166
+ done
167
+
168
+ local hook_src
169
+ hook_src="$(resolve_script ".agent-src/templates/hooks/pre-commit-roadmap-progress" ".augment/templates/hooks/pre-commit-roadmap-progress")" || return 1
170
+
171
+ if $print_only; then
172
+ cat "$hook_src"
173
+ return 0
174
+ fi
175
+
176
+ local git_dir
177
+ git_dir="$(git -C "$CONSUMER_ROOT" rev-parse --git-dir 2>/dev/null || true)"
178
+ if [[ -z "$git_dir" ]]; then
179
+ echo "❌ hooks:install: $CONSUMER_ROOT is not a git repository." >&2
180
+ return 1
181
+ fi
182
+ # Resolve relative git-dir paths (worktrees, submodules) against CONSUMER_ROOT.
183
+ [[ "$git_dir" != /* ]] && git_dir="$CONSUMER_ROOT/$git_dir"
184
+
185
+ local hook_dir="$git_dir/hooks"
186
+ local target="$hook_dir/pre-commit"
187
+ mkdir -p "$hook_dir"
188
+
189
+ if [[ -f "$target" ]] && ! $force; then
190
+ if grep -q "pre-commit-roadmap-progress" "$target" 2>/dev/null; then
191
+ echo "✅ hooks:install: already installed at $target"
192
+ return 0
193
+ fi
194
+ echo "⚠️ hooks:install: $target already exists and looks unrelated." >&2
195
+ echo " Options:" >&2
196
+ echo " 1. Inspect it and append the snippet manually:" >&2
197
+ echo " ./agent-config hooks:install --print >> $target" >&2
198
+ echo " 2. Replace it (destructive):" >&2
199
+ echo " ./agent-config hooks:install --force" >&2
200
+ return 1
201
+ fi
202
+
203
+ cp "$hook_src" "$target"
204
+ chmod +x "$target"
205
+ echo "✅ hooks:install: pre-commit hook installed at $target"
206
+ echo " To uninstall: rm $target"
207
+ }
208
+
209
+ main() {
210
+ local cmd="${1-}"
211
+ [[ $# -gt 0 ]] && shift || true
212
+
213
+ case "$cmd" in
214
+ mcp:render) cmd_mcp_render "$@" ;;
215
+ mcp:check) cmd_mcp_check "$@" ;;
216
+ roadmap:progress) cmd_roadmap_progress "$@" ;;
217
+ roadmap:progress-check) cmd_roadmap_progress_check "$@" ;;
218
+ hooks:install) cmd_hooks_install "$@" ;;
219
+ first-run) cmd_first_run "$@" ;;
220
+ help|--help|-h|"") usage ;;
221
+ --version|-V) print_version ;;
222
+ *)
223
+ echo "❌ agent-config: unknown command: $cmd" >&2
224
+ echo " Run \`./agent-config help\` for the command list." >&2
225
+ exit 2
226
+ ;;
227
+ esac
228
+ }
229
+
230
+ main "$@"