@event4u/agent-config 1.41.2 → 2.1.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 (48) hide show
  1. package/.agent-src/commands/fix/{pr-bots.md → pr-bot-comments.md} +3 -3
  2. package/.agent-src/commands/fix/{pr.md → pr-comments.md} +6 -6
  3. package/.agent-src/commands/fix/{pr-developers.md → pr-developer-comments.md} +3 -3
  4. package/.agent-src/commands/fix.md +6 -6
  5. package/.agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +2 -2
  6. package/.agent-src/templates/agents/agent-project-settings.example.yml +14 -0
  7. package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +120 -11
  8. package/.claude-plugin/marketplace.json +4 -4
  9. package/CHANGELOG.md +54 -0
  10. package/README.md +39 -31
  11. package/config/agent-settings.template.yml +25 -0
  12. package/docs/architecture.md +47 -1
  13. package/docs/catalog.md +3 -3
  14. package/docs/contracts/command-clusters.md +3 -3
  15. package/docs/contracts/file-ownership-matrix.json +9 -9
  16. package/docs/customization.md +125 -9
  17. package/docs/getting-started.md +16 -25
  18. package/docs/installation.md +66 -82
  19. package/docs/migration/v1-to-v2.md +98 -0
  20. package/docs/migrations/commands-1.15.0.md +3 -3
  21. package/docs/setup/per-ide/claude-code.md +0 -17
  22. package/docs/setup/per-ide/claude-desktop.md +35 -48
  23. package/docs/setup/per-ide/windsurf.md +0 -11
  24. package/docs/skills-catalog.md +23 -2
  25. package/docs/troubleshooting.md +20 -32
  26. package/llms.txt +22 -1
  27. package/package.json +1 -6
  28. package/scripts/_cli/__init__.py +0 -0
  29. package/scripts/_cli/cmd_migrate.py +270 -0
  30. package/scripts/_cli/cmd_update.py +226 -0
  31. package/scripts/_lib/agent_settings.py +120 -11
  32. package/scripts/_lib/agents_overlay.py +109 -0
  33. package/scripts/_lib/pin_resolver.py +152 -0
  34. package/scripts/_lib/update_check.py +183 -0
  35. package/scripts/agent-config +73 -1
  36. package/scripts/check_overlay_cascade_subdirs.py +125 -0
  37. package/scripts/check_template_pin_drift.py +112 -0
  38. package/scripts/check_update_banner.py +86 -0
  39. package/scripts/install +27 -40
  40. package/scripts/install.py +17 -228
  41. package/scripts/install.sh +6 -11
  42. package/templates/agent-config-wrapper.sh +40 -25
  43. package/templates/consumer-settings/README.md +2 -2
  44. package/bin/install.php +0 -45
  45. package/composer.json +0 -33
  46. package/scripts/postinstall.sh +0 -76
  47. package/scripts/setup.sh +0 -230
  48. package/templates/global-install-manifest.yml +0 -91
@@ -1,7 +1,7 @@
1
1
  ---
2
- name: fix:pr-bots
2
+ name: fix:pr-bot-comments
3
3
  cluster: fix
4
- sub: pr-bots
4
+ sub: pr-bot-comments
5
5
  skills: [php-coder, quality-tools]
6
6
  description: Fix and reply to bot review comments (Copilot, Augment, Greptile, etc.) on a GitHub PR
7
7
  disable-model-invocation: true
@@ -11,7 +11,7 @@ suggestion:
11
11
  trigger_context: "open PR with bot review comments unresolved"
12
12
  ---
13
13
 
14
- # /fix pr-bots
14
+ # /fix pr-bot-comments
15
15
  ## Input
16
16
 
17
17
  The user may or may not provide a PR URL.
@@ -1,7 +1,7 @@
1
1
  ---
2
- name: fix:pr
2
+ name: fix:pr-comments
3
3
  cluster: fix
4
- sub: pr
4
+ sub: pr-comments
5
5
  skills: [php-coder]
6
6
  description: Fix and reply to all open review comments (bots + human reviewers) on a GitHub PR
7
7
  disable-model-invocation: true
@@ -11,8 +11,8 @@ suggestion:
11
11
  trigger_context: "open PR with unresolved comments (bot + human)"
12
12
  ---
13
13
 
14
- # /fix pr
15
- This command runs `/fix pr-bots` and `/fix pr-developers` in sequence on the same PR.
14
+ # /fix pr-comments
15
+ This command runs `/fix pr-bot-comments` and `/fix pr-developer-comments` in sequence on the same PR.
16
16
 
17
17
  ## Input
18
18
 
@@ -45,14 +45,14 @@ The chosen mode applies to **both** phases.
45
45
 
46
46
  ### Phase 1: Bot comments
47
47
 
48
- Follow the full `/fix pr-bots` instructions (see `commands/fix/pr-bots.md`).
48
+ Follow the full `/fix pr-bot-comments` instructions (see `commands/fix/pr-bot-comments.md`).
49
49
  Use the already-confirmed PR and mode — do not ask again.
50
50
 
51
51
  Report when done: "Bot comments done. Continuing with reviewer comments..."
52
52
 
53
53
  ### Phase 2: Developer comments
54
54
 
55
- Follow the full `/fix pr-developers` instructions (see `commands/fix/pr-developers.md`).
55
+ Follow the full `/fix pr-developer-comments` instructions (see `commands/fix/pr-developer-comments.md`).
56
56
  Use the same PR and mode.
57
57
 
58
58
  ### After both phases
@@ -1,7 +1,7 @@
1
1
  ---
2
- name: fix:pr-developers
2
+ name: fix:pr-developer-comments
3
3
  cluster: fix
4
- sub: pr-developers
4
+ sub: pr-developer-comments
5
5
  skills: [php-coder]
6
6
  description: Fix and reply to human reviewer comments on a GitHub PR
7
7
  disable-model-invocation: true
@@ -11,7 +11,7 @@ suggestion:
11
11
  trigger_context: "open PR with unresolved human-reviewer comments"
12
12
  ---
13
13
 
14
- # /fix pr-developers
14
+ # /fix pr-developer-comments
15
15
  ## Input
16
16
 
17
17
  The user may or may not provide a PR URL.
@@ -22,9 +22,9 @@ with a single entry point + sub-command dispatch.
22
22
  | `/fix refs` | `commands/fix/refs.md` | Find and fix broken cross-references in `.augment/` and `agents/` |
23
23
  | `/fix portability` | `commands/fix/portability.md` | Find and fix project-specific references in shared `.augment/` files |
24
24
  | `/fix seeder` | `commands/fix/seeder.md` | Scan seeder data files for broken FK references |
25
- | `/fix pr` | `commands/fix/pr.md` | Fix and reply to **all** open review comments (bots + humans) |
26
- | `/fix pr-bots` | `commands/fix/pr-bots.md` | Fix and reply to **bot** review comments only |
27
- | `/fix pr-developers` | `commands/fix/pr-developers.md` | Fix and reply to **human** reviewer comments only |
25
+ | `/fix pr-comments` | `commands/fix/pr-comments.md` | Fix and reply to **all** open review comments (bots + humans) |
26
+ | `/fix pr-bot-comments` | `commands/fix/pr-bot-comments.md` | Fix and reply to **bot** review comments only |
27
+ | `/fix pr-developer-comments` | `commands/fix/pr-developer-comments.md` | Fix and reply to **human** reviewer comments only |
28
28
 
29
29
  Sub-command names match the locked contract in
30
30
  [`docs/contracts/command-clusters.md`](../docs/contracts/command-clusters.md).
@@ -41,9 +41,9 @@ Sub-command names match the locked contract in
41
41
  > 2. refs — fix broken cross-refs in agent docs
42
42
  > 3. portability — purge project-specific refs from shared package
43
43
  > 4. seeder — scan seeders for broken FK references
44
- > 5. pr — address all open review comments
45
- > 6. pr-bots — address bot reviewer comments only
46
- > 7. pr-developers — address human reviewer comments only
44
+ > 5. pr-comments — address all open review comments
45
+ > 6. pr-bot-comments — address bot reviewer comments only
46
+ > 7. pr-developer-comments — address human reviewer comments only
47
47
 
48
48
  ## Rules
49
49
 
@@ -4,7 +4,7 @@ Lookup table for the `slash-command-routing-policy` rule. Lists the
4
4
  locked clusters and their sub-commands so the rule itself can stay at
5
5
  its current LOC while still reflecting the full surface. Source of
6
6
  truth for the cluster names is
7
- [`docs/contracts/command-clusters.md`](../../../../../../docs/contracts/command-clusters.md);
7
+ [`docs/contracts/command-clusters.md`](../../../../../docs/contracts/command-clusters.md);
8
8
  this file mirrors that contract for runtime lookup. Linter:
9
9
  `scripts/check_cluster_patterns.py` (verifies dispatcher shape).
10
10
 
@@ -12,7 +12,7 @@ this file mirrors that contract for runtime lookup. Linter:
12
12
 
13
13
  | Cluster | Phase | Sub-commands | Replaces |
14
14
  |---|:-:|---|-------------------------------------------------------------------------------------------------------------------------------------------------|
15
- | `/fix` | 1 | `ci` · `pr` · `pr-bots` · `pr-developers` · `portability` · `refs` · `seeder` | `/fix-ci` · `/fix-pr-comments` · `/fix-pr-bot-comments` · `/fix-pr-developer-comments` · `/fix-portability` · `/fix-references` · `/fix-seeder` |
15
+ | `/fix` | 1 | `ci` · `pr-comments` · `pr-bot-comments` · `pr-developer-comments` · `portability` · `refs` · `seeder` | `/fix-ci` · `/fix-pr-comments` · `/fix-pr-bot-comments` · `/fix-pr-developer-comments` · `/fix-portability` · `/fix-references` · `/fix-seeder` |
16
16
  | `/optimize` | 1 | `agents` · `augmentignore` · `rtk` · `skills` | `/optimize-agents` · `/optimize-augmentignore` · `/optimize-rtk-filters` · `/optimize-skills` |
17
17
  | `/feature` | 1 | `explore` · `plan` · `refactor` · `roadmap` | `/feature-explore` · `/feature-plan` · `/feature-refactor` · `/feature-roadmap` |
18
18
  | `/chat-history` | 2 | `show` | `/chat-history` (legacy status) — `resume` / `clear` / `checkpoint` removed in `road-to-chat-history-hook-only` |
@@ -26,6 +26,20 @@
26
26
 
27
27
  schema_version: 1
28
28
 
29
+ # --- Agent config version pin (project-shared) ---
30
+ #
31
+ # Exact semver of @event4u/agent-config this project commits to. The
32
+ # `npx @event4u/agent-config` dispatcher re-execs at this version when
33
+ # the developer's locally-resolved version differs — so every
34
+ # contributor runs the same agent surface regardless of their npm
35
+ # cache state. Bump this together with a tested upgrade. Empty string
36
+ # disables the pin (resolver picks the latest release; only safe for
37
+ # greenfield projects). Ranges (^, ~, >=) are NOT supported.
38
+ # CI guard: a release bump of `package.json` must update this value
39
+ # in lockstep — see scripts/check_template_pin_drift.py (road-to-
40
+ # portable-runtime-and-update-check P3.3).
41
+ agent_config_version: "1.41.2"
42
+
29
43
  # --- Project identity ---
30
44
  project:
31
45
  # Short slug used in agent output, prompts, and PR metadata. Keep it
@@ -3,17 +3,24 @@
3
3
  Phase 1 of road-to-portable-dev-preferences. Single source of truth for
4
4
  how scripts read agent settings — replaces ~15 ad-hoc loaders in P3.
5
5
 
6
- Resolution order (project wins, user-global fills gaps for whitelisted
7
- keys only):
6
+ Resolution order (deepest wins; user-global is whitelist-filtered only):
8
7
 
9
- 1. Project ``./.agent-settings.yml`` (full file, all keys)
10
- 2. ``~/.config/agent-config/agent-settings.yml`` (whitelist only)
11
- 3. Built-in defaults (currently empty)
8
+ N. ``~/.config/agent-config/agent-settings.yml`` (user-global; whitelist only)
9
+ N-1. ``<repo-root>/.agent-settings.yml`` (project-wide; all keys)
10
+ N-2. ``<intermediate-dir>/.agent-settings.yml`` (subsystem-scoped; all keys)
11
+ 1. ``<CWD>/.agent-settings.yml`` (deepest, wins; all keys)
12
+
13
+ ``<repo-root>`` is the nearest ancestor that contains ``.git`` (directory
14
+ **or** file — submodule support). The walk stops there — it never drifts
15
+ into a parent repo or ``$HOME``. When ``cwd`` is ``None`` (default), the
16
+ loader behaves identically to the pre-cascade contract: project file +
17
+ user-global only, no ancestor walk. Back-compat is hard.
12
18
 
13
19
  Whitelisted keys (``MERGEABLE_KEYS``) are exact dotted paths. A
14
20
  non-whitelisted key in the user-global file is silently ignored — the
15
21
  ``verbose=True`` flag surfaces ignored paths via ``logging.info`` for
16
- debugging.
22
+ debugging. Non-root in-project layers (intermediate + CWD) are **not**
23
+ whitelist-filtered — they live inside the project boundary.
17
24
 
18
25
  Contract — pure, read-only, tolerant:
19
26
 
@@ -28,7 +35,7 @@ from __future__ import annotations
28
35
 
29
36
  import logging
30
37
  from pathlib import Path
31
- from typing import Any
38
+ from typing import Any, Iterator
32
39
 
33
40
  logger = logging.getLogger(__name__)
34
41
 
@@ -53,10 +60,70 @@ MERGEABLE_KEYS: tuple[str, ...] = (
53
60
  _DEFAULTS: dict[str, Any] = {}
54
61
 
55
62
 
63
+ def find_project_root(start: Path) -> Path | None:
64
+ """Walk up from ``start`` looking for ``.git`` (file or directory).
65
+
66
+ Returns the first ancestor that contains ``.git`` as a file (submodule
67
+ pointer) or directory (regular checkout), or ``None`` if the walk
68
+ reaches the filesystem root without finding one. The walk stops at
69
+ the project boundary — it never drifts into a parent repo or
70
+ ``$HOME``.
71
+
72
+ Pure read-only; never touches the filesystem beyond ``exists()``
73
+ probes on the ``.git`` entry.
74
+ """
75
+ current = start.resolve() if start.exists() else start
76
+ # ``Path.parents`` excludes ``current`` itself, so probe it first.
77
+ for candidate in [current, *current.parents]:
78
+ git_marker = candidate / ".git"
79
+ if git_marker.exists():
80
+ return candidate
81
+ return None
82
+
83
+
84
+ def _resolve_cascade_paths(
85
+ cwd: Path | None,
86
+ project_path: Path | str | None,
87
+ ) -> list[Path]:
88
+ """Return the ordered cascade of in-project settings files (shallow → deep).
89
+
90
+ When ``cwd`` is provided and ``find_project_root(cwd)`` succeeds, the
91
+ list contains every ``<dir>/.agent-settings.yml`` from the repo root
92
+ down to ``cwd`` (inclusive on both ends), shallowest first. When
93
+ ``cwd`` is ``None`` or no ``.git`` is reached, falls back to the
94
+ single legacy project path — back-compat with the pre-cascade
95
+ loader.
96
+ """
97
+ if cwd is None:
98
+ legacy = Path(project_path) if project_path else Path(DEFAULT_PROJECT_FILE)
99
+ return [legacy]
100
+
101
+ root = find_project_root(cwd)
102
+ if root is None:
103
+ legacy = Path(project_path) if project_path else Path(DEFAULT_PROJECT_FILE)
104
+ return [legacy]
105
+
106
+ cwd_resolved = cwd.resolve()
107
+ # Build the chain root → … → cwd (shallowest first, deepest last).
108
+ chain: list[Path] = []
109
+ cursor = cwd_resolved
110
+ while True:
111
+ chain.append(cursor)
112
+ if cursor == root:
113
+ break
114
+ parent = cursor.parent
115
+ if parent == cursor:
116
+ break
117
+ cursor = parent
118
+ chain.reverse()
119
+ return [d / DEFAULT_PROJECT_FILE for d in chain]
120
+
121
+
56
122
  def load_agent_settings(
57
123
  project_path: Path | str | None = None,
58
124
  user_global_path: Path | str | None = None,
59
125
  verbose: bool = False,
126
+ cwd: Path | None = None,
60
127
  ) -> dict[str, Any]:
61
128
  """Return the merged settings dict.
62
129
 
@@ -65,10 +132,16 @@ def load_agent_settings(
65
132
  ``~/.config/agent-config/agent-settings.yml``. Both arguments accept
66
133
  ``Path`` or ``str``. Pass ``verbose=True`` to log keys present in
67
134
  user-global that are not on the whitelist.
135
+
136
+ ``cwd`` enables the in-project cascade: when provided **and**
137
+ ``find_project_root(cwd)`` reaches a ``.git`` ancestor, the loader
138
+ walks every ``.agent-settings.yml`` from the repo root down to
139
+ ``cwd`` and merges them shallowest → deepest (deepest wins).
140
+ Non-root layers are **not** whitelist-filtered (they live inside the
141
+ project boundary). When ``cwd`` is ``None`` (default), the loader
142
+ falls back to the single ``project_path`` behaviour — back-compat
143
+ with pre-cascade callers.
68
144
  """
69
- project = _read_yaml(
70
- Path(project_path) if project_path else Path(DEFAULT_PROJECT_FILE),
71
- ) or {}
72
145
  user_global_raw = _read_yaml(
73
146
  Path(user_global_path) if user_global_path else DEFAULT_USER_GLOBAL_FILE,
74
147
  ) or {}
@@ -82,12 +155,48 @@ def load_agent_settings(
82
155
  sorted(ignored),
83
156
  )
84
157
 
158
+ cascade = _resolve_cascade_paths(cwd, project_path)
159
+
85
160
  merged: dict[str, Any] = _deep_copy_defaults(_DEFAULTS)
86
161
  _deep_merge(merged, user_global_filtered)
87
- _deep_merge(merged, project)
162
+ for path in cascade:
163
+ layer = _read_yaml(path) or {}
164
+ if layer:
165
+ _deep_merge(merged, layer)
88
166
  return merged
89
167
 
90
168
 
169
+ def iter_setting_overrides(
170
+ project_path: Path | str | None = None,
171
+ user_global_path: Path | str | None = None,
172
+ cwd: Path | None = None,
173
+ ) -> Iterator[tuple[str, Any, Path]]:
174
+ """Yield ``(dotted_key, value, source_path)`` for every leaf setting.
175
+
176
+ Walks the same cascade as :func:`load_agent_settings` and emits one
177
+ tuple per leaf observed at each layer (user-global → repo-root →
178
+ intermediates → CWD). Callers can detect overrides by grouping
179
+ tuples on ``dotted_key`` — the deepest tuple per group wins. Useful
180
+ for ``task settings:trace`` and other banner-only diagnostics.
181
+ Never blocks, never raises on missing files.
182
+ """
183
+ user_global_path_resolved = (
184
+ Path(user_global_path) if user_global_path else DEFAULT_USER_GLOBAL_FILE
185
+ )
186
+ user_global_raw = _read_yaml(user_global_path_resolved) or {}
187
+ user_global_filtered, _ = _filter_whitelist(user_global_raw, MERGEABLE_KEYS)
188
+ if user_global_filtered:
189
+ for key in _leaf_paths(user_global_filtered):
190
+ yield key, _get_dotted(user_global_filtered, key), user_global_path_resolved
191
+
192
+ for path in _resolve_cascade_paths(cwd, project_path):
193
+ layer = _read_yaml(path)
194
+ if not layer:
195
+ continue
196
+ for key in _leaf_paths(layer):
197
+ yield key, _get_dotted(layer, key), path
198
+
199
+
91
200
  def _read_yaml(path: Path) -> dict[str, Any] | None:
92
201
  """Best-effort YAML read; never raises. Returns ``None`` on any failure."""
93
202
  if not path.is_file():
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Shared agent configuration \u2014 skills for AI coding tools (Claude Code, Augment, Cursor, Cline, Windsurf, Gemini CLI).",
9
- "version": "1.41.2"
9
+ "version": "2.1.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -112,9 +112,9 @@
112
112
  "./.claude/skills/fix",
113
113
  "./.claude/skills/fix-ci",
114
114
  "./.claude/skills/fix-portability",
115
- "./.claude/skills/fix-pr",
116
- "./.claude/skills/fix-pr-bots",
117
- "./.claude/skills/fix-pr-developers",
115
+ "./.claude/skills/fix-pr-bot-comments",
116
+ "./.claude/skills/fix-pr-comments",
117
+ "./.claude/skills/fix-pr-developer-comments",
118
118
  "./.claude/skills/fix-refs",
119
119
  "./.claude/skills/fix-seeder",
120
120
  "./.claude/skills/flux",
package/CHANGELOG.md CHANGED
@@ -318,6 +318,60 @@ our recommendation order, not its support status.
318
318
  users" tension without removing any path that an existing user
319
319
  might rely on.
320
320
 
321
+ ## [2.1.0](https://github.com/event4u-app/agent-config/compare/2.0.0...2.1.0) (2026-05-12)
322
+
323
+ ### Features
324
+
325
+ * **wrapper:** add npx fallback and sanitize wrapper error test ([9f4326b](https://github.com/event4u-app/agent-config/commit/9f4326bffc59d79e4421b0cd8966c99348afe1e6))
326
+ * **installer:** add source-repo guard and drop composer/global paths ([5388de2](https://github.com/event4u-app/agent-config/commit/5388de2598ea668a8671f49bd7bacd4866ed1c33))
327
+
328
+ ### Documentation
329
+
330
+ * **installation:** add Upgrading from v1 section ([f35df4b](https://github.com/event4u-app/agent-config/commit/f35df4b9667eb848ce2ec47f4a7c550b1bba4054))
331
+ * align install guides with v2 npx-only flow ([e841a14](https://github.com/event4u-app/agent-config/commit/e841a14cdbb6691433976c57ff9b28b3ec4992ad))
332
+ * **readme:** collapse plugin-install table to one-liner ([b3407bb](https://github.com/event4u-app/agent-config/commit/b3407bb2fda39a8a57c0e2f72c8b430bed4fd012))
333
+
334
+ ### Refactoring
335
+
336
+ * **cli:** rename fix:pr sub-commands for clarity ([fbdf636](https://github.com/event4u-app/agent-config/commit/fbdf636a50a06f3b35fe5c3d5fb108e9c15e6266))
337
+
338
+ ### Tests
339
+
340
+ * **install:** drop composer-detection tests retired in v2 ([e37ad99](https://github.com/event4u-app/agent-config/commit/e37ad99beaebbb5f6a98b41e02ecefd6b0d39453))
341
+
342
+ ### Build
343
+
344
+ * **tasks:** add npm:login + npm:publish-installer ([22639f8](https://github.com/event4u-app/agent-config/commit/22639f877feee33a3cbadb9147941cfb32fb6c9e))
345
+
346
+ ### Chores
347
+
348
+ * remove retired setup.sh and global-install test surface ([3eebcf7](https://github.com/event4u-app/agent-config/commit/3eebcf72bcc45af168df4fd4b172a2484901a793))
349
+
350
+ Tests: 3253 (-4 since 2.0.0)
351
+
352
+ ## [2.0.0](https://github.com/event4u-app/agent-config/compare/1.41.2...2.0.0) (2026-05-12)
353
+
354
+ ### BREAKING CHANGES
355
+
356
+ * **install:** drop composer + npm postinstall, go npx-only ([6bc6c99](https://github.com/event4u-app/agent-config/commit/6bc6c99f57d2a2bcdab03bfacab429ce146dd9b9))
357
+
358
+ ### Features
359
+
360
+ * **cli:** add update + migrate commands, version-pin resolver, CI drift guard ([b1e34fc](https://github.com/event4u-app/agent-config/commit/b1e34fcd7a03d38266e40dd053414fc9d20c9024))
361
+ * **update-check:** add daily npm-registry version probe + banner ([2c4d752](https://github.com/event4u-app/agent-config/commit/2c4d752d5eb28f1c460470668704f5cf403c4046))
362
+ * **settings:** add hierarchical project-settings cascade + agents overlay ([3296885](https://github.com/event4u-app/agent-config/commit/32968855ca17210b1594cea2e79778acb0476f0a))
363
+
364
+ ### Tests
365
+
366
+ * **install:** drop postinstall.sh test cases removed in P0 ([d4e7750](https://github.com/event4u-app/agent-config/commit/d4e7750bcd13b021caa4ccaccff821dc0ae8e537))
367
+
368
+ ### Chores
369
+
370
+ * **template:** mirror agent_settings cascade into work_engine template ([92f4716](https://github.com/event4u-app/agent-config/commit/92f471662c463efec0df591099a3507919396d77))
371
+ * **roadmap:** archive completed portable-runtime-and-update-check ([91e2e4e](https://github.com/event4u-app/agent-config/commit/91e2e4ef75042d2d19a528874ebcac4b94c4046a))
372
+
373
+ Tests: 3257 (+84 since 1.41.2)
374
+
321
375
  ## [1.41.2](https://github.com/event4u-app/agent-config/compare/1.41.1...1.41.2) (2026-05-12)
322
376
 
323
377
  ### Documentation
package/README.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Agent Config — Governed Agent System
2
2
 
3
+ > ⚠️ **Breaking change in vX.0** — `agent-config` now ships as an
4
+ > **npx-only runtime**. `composer require` / `npm install --save-dev`
5
+ > are gone, the `--global` symlink scheme is retired. Existing
6
+ > consumers: run `npx @event4u/agent-config migrate`
7
+ > ([guide](docs/migration/v1-to-v2.md)). New consumers: jump to
8
+ > [Quickstart](#quickstart).
9
+
3
10
  > **agent-config is not a runtime, but it ships a deterministic orchestration contract / state machine for host agents.**
4
11
 
5
12
  Give your AI agents an audit-disciplined orchestration contract — testing, Git, CI, code review, and **120+ stack-aware skills** — with quality guardrails built in.
@@ -26,39 +33,40 @@ If none of those apply yet — start with the [Quickstart](#quickstart) and pick
26
33
 
27
34
  ## Quickstart
28
35
 
29
- Two minutes from `composer require` to a better-behaved agent.
36
+ Two minutes from `npx` to a better-behaved agent — no install, no
37
+ vendored package, no postinstall hook.
30
38
 
31
39
  ### For teams (recommended)
32
40
 
33
- Install once in the project — available to everyone who works on it:
41
+ Run once in the project root `npx` resolves the runtime against the
42
+ npm registry on every invocation, and the version pin in
43
+ `.agent-settings.yml` keeps it reproducible:
34
44
 
35
45
  ```bash
36
- # PHP
37
- composer require --dev event4u/agent-config
46
+ # Bootstrap (writes .agent-settings.yml, .augment/, .claude/, …):
47
+ npx @event4u/agent-config init
38
48
 
39
- # JavaScript/TypeScript
40
- npm install --save-dev @event4u/agent-config
49
+ # Any subsequent command:
50
+ npx @event4u/agent-config <command>
41
51
  ```
42
52
 
43
- After installing the package, run the installer to sync the payload and
44
- create `.agent-settings.yml`, `.vscode/settings.json`, `.augment/settings.json`,
45
- and the tool-specific glue:
53
+ The init writes:
46
54
 
47
- ```bash
48
- # PHP / Composer projects — explicit step (Composer does not auto-run it):
49
- php vendor/bin/install.php
50
- # or directly (any environment):
51
- bash vendor/event4u/agent-config/scripts/install
52
-
53
- # npm projects run the installer automatically via postinstall.
54
- # To re-run or override the default profile:
55
- bash node_modules/@event4u/agent-config/scripts/install --profile=balanced
56
- ```
55
+ - `.agent-settings.yml` (including the `agent_config_version` pin)
56
+ - `.vscode/settings.json`, `.augment/settings.json`
57
+ - per-tool glue: `.claude/`, `.cursor/`, `.clinerules/`,
58
+ `.windsurfrules`, `GEMINI.md`, `.github/copilot-instructions.md`
59
+
60
+ → Migrating from a pre-vX.0 install? See
61
+ [`docs/migration/v1-to-v2.md`](docs/migration/v1-to-v2.md). The one-shot
62
+ `npx @event4u/agent-config migrate` removes the legacy
63
+ `composer.json` entry / `node_modules/@event4u/agent-config`,
64
+ deletes the retired `~/.claude/{rules,skills}/event4u/` namespace if
65
+ present, and writes the new `.agent-settings.yml` shape.
57
66
 
58
- **To install:** no Task / Make / build tools`scripts/install` runs a
59
- bash payload sync plus a Python 3 bridge generator (stdlib only, default
60
- on macOS 12.3+ / major Linux distros). Python missing → orchestrator
61
- warns and continues payload-only. Task is needed only for *contributors*
67
+ **To run:** Node 18 and Python 3 (stdlib only default on macOS
68
+ 12.3+ / major Linux distros). Python missing orchestrator warns and
69
+ continues payload-only. Task is needed only for *contributors*
62
70
  rebuilding compressed content — see [CONTRIBUTING.md](CONTRIBUTING.md).
63
71
 
64
72
  **Verify hook coverage** after installing — every supported platform
@@ -71,13 +79,12 @@ dispatcher per bridge as a post-install smoke test (skip: `--no-smoke`).
71
79
 
72
80
  ### For individual use (optional)
73
81
 
74
- Install directly in your agent for global, cross-project use:
82
+ Skills-only, global across projects installs into the agent itself,
83
+ no per-repo `init`:
75
84
 
76
- | Tool | Install |
77
- |---|---|
78
- | **Augment CLI** | `auggie plugin install agent-config@event4u-agent-config` |
79
- | **Claude Code** | `claude plugin install agent-config@event4u-agent-config` |
80
- | **Copilot CLI** | `copilot plugin install agent-config@event4u-agent-config` |
85
+ ```bash
86
+ <auggie|claude|copilot> plugin install agent-config@event4u-agent-config
87
+ ```
81
88
 
82
89
  → [All install options & project bridge setup](docs/installation.md)
83
90
 
@@ -410,9 +417,10 @@ kernel set: [`docs/contracts/kernel-membership.md`](docs/contracts/kernel-member
410
417
 
411
418
  ## Supported Tools
412
419
 
413
- ### Project-installed (Composer / npm)
420
+ ### Project-installed (`npx`)
414
421
 
415
- Every developer gets the same behavior. No per-user setup needed.
422
+ Every developer gets the same behavior. No per-user setup needed
423
+ `npx @event4u/agent-config init` writes the per-tool glue listed below.
416
424
 
417
425
  | Tool | Rules | Skills | Commands | How it works |
418
426
  |---|---|---|---|---|
@@ -5,6 +5,18 @@
5
5
  # values here directly or ask the agent (it follows the merge rules in
6
6
  # .augment/guidelines/agent-infra/layered-settings.md).
7
7
 
8
+ # --- Agent config version pin ---
9
+ #
10
+ # Exact semver of the @event4u/agent-config release this project is
11
+ # pinned to. Used by `npx @event4u/agent-config <cmd>` to re-exec at
12
+ # the pinned version when the developer's local resolution differs.
13
+ # Empty string = unpinned (resolver picks the latest release; only safe
14
+ # for greenfield projects). Ranges (^, ~, >=) are NOT supported — the
15
+ # pin replaces lockfile determinism, so it must be exact.
16
+ # See docs/customization.md § "Agent config version pin" and
17
+ # docs/architecture.md § "npx-only distribution + version-pin governance".
18
+ agent_config_version: ""
19
+
8
20
  # --- Cost profile ---
9
21
  #
10
22
  # Master switch that controls which rule tiers load each session.
@@ -376,3 +388,16 @@ memory:
376
388
  # or paths outside the repo root that must not land in intake JSONL.
377
389
  # Example: ["api[_-]?key", "/Users/[a-z]+/Library"]
378
390
  redact_patterns: []
391
+
392
+ # --- Update check ---
393
+ #
394
+ # Daily background check against the npm registry for a newer
395
+ # @event4u/agent-config release. When enabled the dispatcher writes a
396
+ # two-line banner to stderr **after** the subcommand finishes; CI,
397
+ # non-TTY stdout, and `AGENT_CONFIG_NO_UPDATE_CHECK=1` always suppress
398
+ # it regardless of this flag. State is persisted at
399
+ # `~/.config/agent-config/update-check.json` (mode 0600) with a 24 h
400
+ # cadence. See docs/customization.md § "Update check" for the suppression
401
+ # matrix and the road-to-portable-runtime-and-update-check roadmap (P2).
402
+ update_check:
403
+ enabled: true
@@ -54,7 +54,7 @@ tree where:
54
54
  `.agent-src/<subdir>/`. Reading a context follows the symlink to
55
55
  the package payload.
56
56
  - `.augment/docs/guidelines/` — **symlink** into the package's
57
- `docs/guidelines/` (consumer side: `vendor/event4u/agent-config/docs/guidelines/`;
57
+ `docs/guidelines/` (consumer side: `node_modules/@event4u/agent-config/docs/guidelines/`;
58
58
  package self-projection: `../docs/guidelines/`). This is the only
59
59
  `docs/` subdirectory exposed in `.augment/`; `docs/contracts/` and
60
60
  `docs/decisions/` are package-internal — rules that reference
@@ -70,6 +70,52 @@ them to the relative form when writing into `.agent-src/`. Hardcoding
70
70
  `.agent-src.uncompressed/` in source frontmatter or body links is
71
71
  forbidden and caught by `scripts/check_compressed_paths.py`.
72
72
 
73
+ ### Distribution model — npx-only + version-pin governance
74
+
75
+ Starting with the road-to-portable-runtime cutover, the package ships
76
+ exclusively as a **runtime resolved by `npx @event4u/agent-config`**.
77
+ There is no Composer dependency, no `npm install` step, no `--global`
78
+ symlink scheme. Consumers run:
79
+
80
+ ```bash
81
+ npx @event4u/agent-config init # bootstrap a project
82
+ npx @event4u/agent-config <cmd> # any subsequent command
83
+ ```
84
+
85
+ **Why local installs are gone.** Vendoring the package into every
86
+ consumer's `vendor/` or `node_modules/` created three problems: stale
87
+ runtimes diverging from the published version, build-system coupling
88
+ (Composer post-install hooks, npm postinstall scripts), and a parallel
89
+ "global install" scheme that copied curated skills into `~/.claude/`,
90
+ `~/.cursor/`, `~/.codeium/windsurf/` under an `event4u/` namespace.
91
+ Maintenance cost was high, the abstractions leaked across surfaces, and
92
+ debugging "which version is loaded" was non-trivial. `npx` resolves the
93
+ runtime per invocation against a single npm registry source, which
94
+ collapses all three failure modes.
95
+
96
+ **How the pin replaces lockfile determinism.** A consumer-managed
97
+ `composer.lock` / `package-lock.json` previously froze the runtime
98
+ version per repo. Under npx-only, the equivalent role is played by the
99
+ `agent_config_version` field in the consumer's `.agent-settings.yml`
100
+ (see `config/agent-settings.template.yml`). The dispatcher reads the
101
+ pin on every invocation and re-execs `npx @event4u/agent-config@<pin>`
102
+ if the resolved version diverges (P3.2 pin-resolver). The pin lives in
103
+ the consumer's repo, is reviewed in PRs, and survives `npx`'s own
104
+ cache eviction.
105
+
106
+ **Q1 council rejection + override + pin as substitute.** During Q1
107
+ planning, the architecture council rejected the npx-only proposal on
108
+ the grounds that `npx` resolution introduces a "09:00 vs 09:15
109
+ release skew" window where two developers running the same command
110
+ minutes apart could see different runtimes. The user overrode the
111
+ rejection on the condition that an explicit version pin replaces
112
+ lockfile determinism — the council's concern is real, but the pin
113
+ collapses the skew window to whatever the project's PR cadence is.
114
+ Pin drift across developers becomes a reviewable config change in
115
+ `.agent-settings.yml` rather than an invisible registry-resolution
116
+ race. ADR-pending entry will record the trade-off in full once P3 is
117
+ green.
118
+
73
119
  ### Cloud-bundle pipeline
74
120
 
75
121
  `task build-cloud-bundles-all` produces one ZIP per skill at
package/docs/catalog.md CHANGED
@@ -294,9 +294,9 @@ are excluded.
294
294
  | command | [`feature`](../.agent-src/commands/feature.md) | cluster: feature | Feature orchestrator — routes to explore, plan, refactor, roadmap, dev |
295
295
  | command | [`fix:ci`](../.agent-src/commands/fix/ci.md) | cluster: fix | Fetch CI errors from GitHub Actions and fix them |
296
296
  | command | [`fix:portability`](../.agent-src/commands/fix/portability.md) | cluster: fix | Find and fix project-specific references in shared .augment/ package files |
297
- | command | [`fix:pr-bots`](../.agent-src/commands/fix/pr-bots.md) | cluster: fix | Fix and reply to bot review comments (Copilot, Augment, Greptile, etc.) on a GitHub PR |
298
- | command | [`fix:pr-developers`](../.agent-src/commands/fix/pr-developers.md) | cluster: fix | Fix and reply to human reviewer comments on a GitHub PR |
299
- | command | [`fix:pr`](../.agent-src/commands/fix/pr.md) | cluster: fix | Fix and reply to all open review comments (bots + human reviewers) on a GitHub PR |
297
+ | command | [`fix:pr-bot-comments`](../.agent-src/commands/fix/pr-bot-comments.md) | cluster: fix | Fix and reply to bot review comments (Copilot, Augment, Greptile, etc.) on a GitHub PR |
298
+ | command | [`fix:pr-comments`](../.agent-src/commands/fix/pr-comments.md) | cluster: fix | Fix and reply to all open review comments (bots + human reviewers) on a GitHub PR |
299
+ | command | [`fix:pr-developer-comments`](../.agent-src/commands/fix/pr-developer-comments.md) | cluster: fix | Fix and reply to human reviewer comments on a GitHub PR |
300
300
  | command | [`fix:refs`](../.agent-src/commands/fix/refs.md) | cluster: fix | Find and fix broken cross-references in .augment/ and agents/ files |
301
301
  | command | [`fix:seeder`](../.agent-src/commands/fix/seeder.md) | cluster: fix | Scan seeder data files for broken foreign key references — find constants used without getReference() and fix them |
302
302
  | command | [`fix`](../.agent-src/commands/fix.md) | cluster: fix | Fix orchestrator — routes to ci, references, portability, seeder, pr-comments, pr-bot-comments, pr-developer-comments |