@event4u/agent-config 14.21.0 → 14.23.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 (235) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +164 -187
  5. package/CREDITS.md +37 -0
  6. package/README.md +1 -1
  7. package/dist/agent-src/commands/analyze/inbox.md +380 -5
  8. package/dist/agent-src/commands/analyze/repo.md +4 -2
  9. package/dist/agent-src/commands/pr/merge.md +47 -38
  10. package/dist/agent-src/commands/roadmap/next.md +8 -0
  11. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +69 -0
  12. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -5
  13. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +12 -0
  14. package/dist/agent-src/rules/external-code-graph-interop.md +19 -14
  15. package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
  16. package/dist/agent-src/rules/token-efficiency.md +26 -3
  17. package/dist/agent-src/scripts/_cli_entry.ts +51 -0
  18. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +120 -27
  19. package/dist/agent-src/scripts/roadmap_gates.ts +4 -20
  20. package/dist/agent-src/scripts/roadmap_set_step.ts +5 -2
  21. package/dist/agent-src/scripts/stubs_due.ts +4 -18
  22. package/dist/agent-src/scripts/update_roadmap_progress.ts +7 -24
  23. package/dist/agent-src/skills/code-intelligence/SKILL.md +82 -1
  24. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
  25. package/dist/agent-src/skills/roadmap-writing/SKILL.md +17 -0
  26. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +52 -2
  27. package/dist/agent-src/templates/agent-settings.md +0 -1
  28. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  29. package/dist/cli/registry.js +1 -1
  30. package/dist/cli-delegate/_cli_entry.js +8 -0
  31. package/dist/cli-delegate/_lib/pin_resolver.js +170 -0
  32. package/dist/cli-delegate/archival_sweep.js +8 -0
  33. package/dist/cli-delegate/archive_completed_roadmaps.js +542 -0
  34. package/dist/cli-delegate/check_update_banner.js +923 -0
  35. package/dist/cli-delegate/{chunk-ZVBOHSVF.js → chunk-2KKXJW25.js} +23 -9
  36. package/dist/cli-delegate/chunk-5EK5WQN6.js +28 -0
  37. package/dist/cli-delegate/chunk-7XGD2OEU.js +96 -0
  38. package/dist/cli-delegate/chunk-DBH4AHDK.js +155 -0
  39. package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-IAI3XL43.js} +15 -3
  40. package/dist/cli-delegate/chunk-JO25G5H7.js +20 -0
  41. package/dist/cli-delegate/{chunk-643Z7FIC.js → chunk-KCNTUSPI.js} +7 -1
  42. package/dist/cli-delegate/chunk-LTYVIY76.js +7961 -0
  43. package/dist/cli-delegate/chunk-QAJS5YWY.js +999 -0
  44. package/dist/cli-delegate/{chunk-YS6XTLEK.js → chunk-TYSY33MD.js} +56 -6
  45. package/dist/cli-delegate/chunk-ULET4BYS.js +328 -0
  46. package/dist/cli-delegate/chunk-YDQSHTD7.js +187 -0
  47. package/dist/cli-delegate/chunk-YWVXLR44.js +48 -0
  48. package/dist/cli-delegate/chunk-ZZQBUHFK.js +273 -0
  49. package/dist/cli-delegate/cmd_conformance.js +2 -2
  50. package/dist/cli-delegate/cmd_export.js +2 -2
  51. package/dist/cli-delegate/cmd_handoff.js +45 -13
  52. package/dist/cli-delegate/cmd_prune.js +2 -2
  53. package/dist/cli-delegate/cmd_session_recycle.js +4 -14
  54. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  55. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  56. package/dist/cli-delegate/cmd_sync.js +2 -2
  57. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  58. package/dist/cli-delegate/cmd_validate.js +2 -2
  59. package/dist/cli-delegate/dashboard_mode.js +16 -0
  60. package/dist/cli-delegate/gate_budget.js +24 -0
  61. package/dist/cli-delegate/gate_execute.js +25 -0
  62. package/dist/cli-delegate/guarded_baseline.js +18 -0
  63. package/dist/cli-delegate/resume_probe.js +22 -0
  64. package/dist/cli-delegate/roadmap_gates.js +638 -0
  65. package/dist/cli-delegate/roadmap_set_step.js +173 -0
  66. package/dist/cli-delegate/stub_queue.js +47 -0
  67. package/dist/cli-delegate/stubs_due.js +38 -0
  68. package/dist/cli-delegate/ticket_bundles.js +59 -0
  69. package/dist/cli-delegate/update_roadmap_progress.js +60 -0
  70. package/dist/discovery/deprecation-report.md +1 -1
  71. package/dist/discovery/discovery-manifest.json +13 -13
  72. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  73. package/dist/discovery/discovery-manifest.summary.md +1 -1
  74. package/dist/discovery/dormancy-report.md +1 -1
  75. package/dist/discovery/orphan-report.md +1 -1
  76. package/dist/discovery/packs.json +2 -2
  77. package/dist/discovery/trust-report.md +1 -1
  78. package/dist/discovery/workspaces.json +2 -2
  79. package/dist/hooks/dispatch.js +1813 -946
  80. package/dist/install/claudeLayerCarriage.js +237 -0
  81. package/dist/install/claudePathsPlan.js +79 -0
  82. package/dist/install/hostLayerFingerprint.js +1 -1
  83. package/dist/install/install.mjs +21 -3
  84. package/dist/install/partitionEligibility.js +231 -117
  85. package/dist/install/ruleLayerPartition.js +10 -7
  86. package/dist/mcp/registry-manifest.json +2 -2
  87. package/dist/mcp/server.json +2 -2
  88. package/dist/mcp/server.mjs +10870 -7641
  89. package/dist/scripts/_lib/lean_projection_mode.js +108 -0
  90. package/dist/scripts/_lib/router_match.js +243 -0
  91. package/dist/scripts/_lib/rule_injection.js +216 -0
  92. package/dist/scripts/condense.js +52 -45
  93. package/dist/scripts/project_thin_rules.js +139 -19
  94. package/dist/server/schemas/settings.js +16 -3
  95. package/docs/MIGRATION.md +105 -1
  96. package/docs/contracts/settings-classes.md +40 -8
  97. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +73 -0
  98. package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  99. package/llms.txt +1 -1
  100. package/package.json +7 -4
  101. package/src/agent-src/scripts/_cli_entry.ts +51 -0
  102. package/src/agent-src/scripts/archive_completed_roadmaps.ts +120 -27
  103. package/src/agent-src/scripts/roadmap_gates.ts +4 -20
  104. package/src/agent-src/scripts/roadmap_set_step.ts +5 -2
  105. package/src/agent-src/scripts/stubs_due.ts +4 -18
  106. package/src/agent-src/scripts/update_roadmap_progress.ts +7 -24
  107. package/src/config/agent-settings.template.yml +47 -1
  108. package/src/config/continuity-surface.json +516 -0
  109. package/src/config/estate-count-budget.json +1 -1
  110. package/src/config/evaluator-budgets.json +4 -4
  111. package/src/config/gate-coverage.yml +29 -8
  112. package/src/config/gate-violation-baselines.json +8 -8
  113. package/src/config/gitignore-block.txt +19 -0
  114. package/src/config/hook-token-budget.json +7 -6
  115. package/src/config/host-injection-effect.json +73 -0
  116. package/src/config/packed-binary-manifest.json +33 -0
  117. package/src/config/preamble-payload-budget.json +112 -105
  118. package/src/config/publish-surface.json +4 -2
  119. package/src/config/routing-coverage-seed.json +9 -2
  120. package/src/install/claudeLayerCarriage.ts +273 -0
  121. package/src/install/claudePathsPlan.ts +76 -0
  122. package/src/install/hostLayerFingerprint.ts +1 -1
  123. package/src/install/partitionEligibility.ts +261 -127
  124. package/src/install/ruleLayerPartition.ts +19 -23
  125. package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
  126. package/src/scripts/_cli/handoff_sessions.ts +14 -44
  127. package/src/scripts/_dispatch.bash +77 -27
  128. package/src/scripts/_lib/auto_dispatch.ts +2 -2
  129. package/src/scripts/_lib/catalogue_layer_parity.ts +146 -0
  130. package/src/scripts/_lib/continuity_slot.ts +295 -0
  131. package/src/scripts/_lib/continuity_surface.ts +296 -0
  132. package/src/scripts/_lib/continuity_writer.ts +253 -0
  133. package/src/scripts/_lib/corpus_manifest.ts +26 -9
  134. package/src/scripts/_lib/hook_settings.ts +86 -1
  135. package/src/scripts/_lib/injection_effect.ts +151 -0
  136. package/src/scripts/_lib/layer_overlap_notice.ts +50 -6
  137. package/src/scripts/_lib/lean_projection_mode.ts +127 -0
  138. package/src/scripts/_lib/packed_binary_predicate.ts +262 -0
  139. package/src/scripts/_lib/pin_resolver.ts +13 -0
  140. package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
  141. package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
  142. package/src/scripts/_lib/retired_status.ts +74 -0
  143. package/src/scripts/_lib/session_eol.ts +44 -0
  144. package/src/scripts/_lib/session_index_trust.ts +346 -0
  145. package/src/scripts/_lib/skill_catalogue.ts +156 -21
  146. package/src/scripts/_lib/standing_bound_ratchet.ts +154 -0
  147. package/src/scripts/_lib/subagent_capsule.ts +117 -8
  148. package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
  149. package/src/scripts/ai_council/api_transport.ts +5 -0
  150. package/src/scripts/ai_council/deliberation_metrics.ts +353 -0
  151. package/src/scripts/ai_council/prompts.ts +9 -0
  152. package/src/scripts/ai_council/synthesis_disagreement.ts +206 -0
  153. package/src/scripts/audit_mcp_tools.ts +69 -25
  154. package/src/scripts/build_mcp_catalog.ts +24 -1
  155. package/src/scripts/capture_skill_catalogue.ts +24 -11
  156. package/src/scripts/check_candidate_lines.ts +499 -0
  157. package/src/scripts/check_continuity_surface.ts +475 -0
  158. package/src/scripts/check_dependency_floors.ts +13 -6
  159. package/src/scripts/check_estate_count.ts +40 -79
  160. package/src/scripts/check_host_tree_parity.ts +291 -0
  161. package/src/scripts/check_pack_size.ts +262 -23
  162. package/src/scripts/check_preamble_payload_budget.ts +136 -7
  163. package/src/scripts/check_roadmap_trackable.ts +19 -16
  164. package/src/scripts/check_rule_layer_partition.ts +54 -34
  165. package/src/scripts/check_rule_projection_integrity.ts +102 -2
  166. package/src/scripts/check_single_delivery.ts +97 -31
  167. package/src/scripts/check_update_banner.ts +13 -0
  168. package/src/scripts/ci_settle.ts +205 -5
  169. package/src/scripts/code_graph/build.ts +217 -15
  170. package/src/scripts/code_graph/cli.ts +334 -15
  171. package/src/scripts/code_graph/detect.ts +38 -0
  172. package/src/scripts/code_graph/extract.ts +11 -0
  173. package/src/scripts/code_graph/grammar_probe.ts +43 -0
  174. package/src/scripts/code_graph/loader.ts +88 -14
  175. package/src/scripts/code_graph/query.ts +144 -11
  176. package/src/scripts/code_graph/resolution_tiers.ts +238 -0
  177. package/src/scripts/code_graph/sqlite_store.ts +262 -6
  178. package/src/scripts/code_graph/types.ts +117 -3
  179. package/src/scripts/code_graph/validate.ts +26 -1
  180. package/src/scripts/code_graph/verbs.ts +590 -0
  181. package/src/scripts/condense.ts +54 -42
  182. package/src/scripts/corpus_manifest.ts +5 -5
  183. package/src/scripts/council_cli.ts +11 -12
  184. package/src/scripts/count_intent_disagreement.ts +426 -0
  185. package/src/scripts/handoff_context_hook.ts +118 -1
  186. package/src/scripts/hook_effect_doctor.ts +82 -1
  187. package/src/scripts/hook_manifest.json +1 -1
  188. package/src/scripts/hook_manifest.yaml +87 -12
  189. package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
  190. package/src/scripts/hooks/chain_nudge_hook.ts +282 -0
  191. package/src/scripts/hooks/code_graph_context_hook.ts +201 -0
  192. package/src/scripts/hooks/concern_registry.ts +4 -2
  193. package/src/scripts/hooks/host_semantics.ts +1 -1
  194. package/src/scripts/hooks/orchestration_record_hook.ts +2 -2
  195. package/src/scripts/hooks/push_settle_hook.ts +3 -2
  196. package/src/scripts/hooks/rule_inject_hook.ts +108 -21
  197. package/src/scripts/hooks/session_eol_hook.ts +120 -2
  198. package/src/scripts/hooks/skill_route_hook.ts +11 -4
  199. package/src/scripts/hot_context_hook.ts +62 -7
  200. package/src/scripts/inbox_source_census.ts +322 -0
  201. package/src/scripts/install-hooks.sh +82 -0
  202. package/src/scripts/{lint_carrier_integrity.ts → lint_deferral_integrity.ts} +60 -214
  203. package/src/scripts/lint_plan_risk_register.ts +13 -17
  204. package/src/scripts/lint_roadmap_blockers.ts +164 -1
  205. package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
  206. package/src/scripts/mcp_server/graph_tools.ts +294 -0
  207. package/src/scripts/mcp_server/path_util.ts +31 -0
  208. package/src/scripts/mcp_server/suggest_skill.ts +72 -0
  209. package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
  210. package/src/scripts/mcp_server/tools.ts +5 -69
  211. package/src/scripts/media/lib/adapter-contract.md +7 -2
  212. package/src/scripts/media/lib/fixtures/flux/asset-0001.png +0 -0
  213. package/src/scripts/media/lib/fixtures/gemini-image/asset-0001.png +0 -0
  214. package/src/scripts/media/lib/fixtures/ideogram/asset-0001.png +0 -0
  215. package/src/scripts/model_rule_injection.ts +61 -4
  216. package/src/scripts/project_thin_rules.ts +149 -16
  217. package/src/scripts/rdp_candidates_delta.ts +276 -0
  218. package/src/scripts/rdp_quality_eval.ts +217 -19
  219. package/src/scripts/release_mix_taxonomy.json +3 -2
  220. package/src/scripts/report_host_injection_effect.ts +189 -0
  221. package/src/scripts/report_layer_overlap.ts +41 -0
  222. package/src/scripts/report_skill_menu_census.ts +341 -0
  223. package/src/scripts/report_standing_payload_by_host.ts +650 -0
  224. package/src/scripts/schemas/agent-settings.schema.json +7 -1
  225. package/src/scripts/session_memory_index.ts +81 -8
  226. package/src/scripts/skill_tools/score_skill_relevance.ts +70 -6
  227. package/src/scripts/skill_tools/suggest_skill_for_task.ts +37 -3
  228. package/src/server/schemas/settings.ts +23 -4
  229. package/src/vendor/grammars/README.md +86 -0
  230. package/src/vendor/grammars/tree-sitter-javascript.wasm +0 -0
  231. package/src/vendor/grammars/tree-sitter-php.wasm +0 -0
  232. package/src/vendor/grammars/tree-sitter-typescript.wasm +0 -0
  233. package/src/scripts/_lib/carrier_status.ts +0 -118
  234. package/src/scripts/_lib/estate_carrier_cases.ts +0 -72
  235. package/src/scripts/hooks/code_graph_nudge_hook.ts +0 -191
@@ -1,72 +0,0 @@
1
- /**
2
- * The three `check_estate_count` self-test cases that exercise `status: carrier`.
3
- *
4
- * They live outside that gate because it sits at the 1,500-line source ceiling
5
- * `check_source_size_budget` enforces, and because the doctrine that gate states
6
- * for an oversized file is a split rather than a raised baseline. The reasoning
7
- * behind the fixture shapes is in `carrier_status.ts` § Fixture design.
8
- */
9
-
10
- import type { SelfTestCase } from './gate_self_test.js';
11
-
12
- /** What the caller must supply: its own fixture harness and roadmap bodies. */
13
- export interface EstateCaseDeps {
14
- fixture: (opts: {
15
- roadmaps: number;
16
- base?: string;
17
- before?: (dir: string) => void;
18
- after: (dir: string) => void;
19
- }) => number;
20
- write: (dir: string, rel: string, body: string) => void;
21
- remove: (dir: string, rel: string) => void;
22
- roadmap: (name: string, extra?: string) => string;
23
- CARRIER: string;
24
- DRAFT: string;
25
- }
26
-
27
- export function carrierEstateCases(d: EstateCaseDeps): SelfTestCase[] {
28
- const { fixture, write, remove, roadmap, CARRIER, DRAFT } = d;
29
- return [
30
- {
31
- name: 'deleting a carrier does not offset a new draft → reject',
32
- expect: 'reject',
33
- run: () =>
34
- fixture({
35
- roadmaps: 3,
36
- base: 'main',
37
- before: (dir) => write(dir, 'agents/roadmaps/road-to-carrier.md', CARRIER),
38
- after: (dir) => {
39
- remove(dir, 'agents/roadmaps/road-to-carrier.md');
40
- write(dir, 'agents/roadmaps/road-to-new.md', DRAFT);
41
- },
42
- }),
43
- },
44
- {
45
- // The control that proves the case above tests the STATUS rather
46
- // than the deletion: only the removed file's status differs.
47
- name: 'deleting an ordinary roadmap still offsets a new draft → accept',
48
- expect: 'accept',
49
- run: () =>
50
- fixture({
51
- roadmaps: 3,
52
- base: 'main',
53
- before: (dir) => write(dir, 'agents/roadmaps/road-to-spare.md', roadmap('S')),
54
- after: (dir) => {
55
- remove(dir, 'agents/roadmaps/road-to-spare.md');
56
- write(dir, 'agents/roadmaps/road-to-new.md', DRAFT);
57
- },
58
- }),
59
- },
60
- {
61
- name: 'flipping a carrier back to an ordinary roadmap costs nothing → accept',
62
- expect: 'accept',
63
- run: () =>
64
- fixture({
65
- roadmaps: 3,
66
- base: 'main',
67
- before: (dir) => write(dir, 'agents/roadmaps/road-to-2.md', CARRIER),
68
- after: (dir) => write(dir, 'agents/roadmaps/road-to-2.md', roadmap('R2')),
69
- }),
70
- },
71
- ];
72
- }
@@ -1,191 +0,0 @@
1
- #!/usr/bin/env tsx
2
- /**
3
- * PreToolUse code-graph nudge (ADR-124 Phase 4) — deterministic, warn-only.
4
- *
5
- * When a code-graph source is available and the agent is about to search or
6
- * read source files, surface a one-line reminder to query the graph first.
7
- * NEVER blocks (dispatcher contract: 0 allow · 2 warn) — Source G's strict
8
- * block-the-first-read mode is deliberately NOT ported (blocking reads on a
9
- * possibly-stale index violates the minimal-safe-diff posture). Once per
10
- * session (a latch keyed by session id), so it cannot nag.
11
- *
12
- * Default-OFF. Fires only when `hooks.code_graph.enabled: true`. Disabled /
13
- * missing / already-latched → no-op exit 0. fail_closed: false — any error
14
- * returns allow; a token optimisation must never break a tool call.
15
- *
16
- * Branches (first eligible search/read this session):
17
- * present + fresh → "query the graph first"
18
- * present + stale → "index N commits behind — rebuild"
19
- * absent → "no graph — build one?"
20
- */
21
- import fs from 'node:fs';
22
- import path from 'node:path';
23
- import { fileURLToPath, pathToFileURL } from 'node:url';
24
-
25
- import { detectSources, pickSource } from '../code_graph/detect.js';
26
- import { readHookStdin } from './hook_stdin.js';
27
-
28
- const SETTINGS_FILE = '.agent-settings.yml';
29
- const EXIT_ALLOW = 0;
30
- const EXIT_WARN = 2;
31
- const CODE_EXT = /\.(php|ts|tsx|mts|cts|js|jsx|mjs|cjs)$/i;
32
-
33
- type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
34
- type JsonObject = { [k: string]: JsonValue };
35
-
36
- function isObject(v: unknown): v is JsonObject {
37
- return typeof v === 'object' && v !== null && !Array.isArray(v);
38
- }
39
-
40
- /** `hooks.code_graph.enabled: true` mini-parser (mirrors rtk_wrap_hook). */
41
- export function enabled(root: string): boolean {
42
- const f = path.join(root, SETTINGS_FILE);
43
- let text: string;
44
- try {
45
- if (!fs.statSync(f).isFile()) return false;
46
- text = fs.readFileSync(f, 'utf-8');
47
- } catch {
48
- return false;
49
- }
50
- let inHooks = false;
51
- let inCg = false;
52
- for (const raw of text.split(/\r\n|\r|\n/)) {
53
- const line = raw.replace(/\s+$/, '');
54
- if (!line || line.replace(/^\s+/, '').startsWith('#')) continue;
55
- if (!(line.startsWith(' ') || line.startsWith('\t'))) {
56
- inHooks = /^hooks\s*:\s*$/.test(line);
57
- inCg = false;
58
- continue;
59
- }
60
- if (inHooks) {
61
- if (/^\s+code_graph\s*:\s*$/.test(line)) {
62
- inCg = true;
63
- continue;
64
- }
65
- if (inCg && /^\s{0,3}\S/.test(line)) inCg = false;
66
- }
67
- if (inCg && /^\s+enabled\s*:\s*true\b/.test(line)) return true;
68
- }
69
- return false;
70
- }
71
-
72
- interface ToolIntent {
73
- isSearch: boolean;
74
- isCodeRead: boolean;
75
- }
76
-
77
- /** Best-effort read of the intercepted tool + its target from the envelope. */
78
- export function classifyTool(envelope: JsonObject): ToolIntent {
79
- const payload = isObject(envelope['payload']) ? envelope['payload'] : envelope;
80
- const nameVal =
81
- payload['tool_name'] ?? payload['toolName'] ?? payload['tool'] ?? envelope['tool_name'] ?? envelope['tool'];
82
- const name = typeof nameVal === 'string' ? nameVal : '';
83
- const ti = (isObject(payload['tool_input']) ? payload['tool_input'] : envelope['tool_input']) as
84
- | JsonObject
85
- | undefined;
86
- const isSearch = name === 'Grep' || name === 'Glob';
87
- let isCodeRead = false;
88
- if (name === 'Read' && isObject(ti)) {
89
- const fp = ti['file_path'] ?? ti['path'];
90
- if (typeof fp === 'string') isCodeRead = CODE_EXT.test(fp);
91
- }
92
- return { isSearch, isCodeRead };
93
- }
94
-
95
- function sessionId(envelope: JsonObject): string {
96
- const s = envelope['session_id'] ?? envelope['sessionId'];
97
- return typeof s === 'string' && s ? s : 'default';
98
- }
99
-
100
- function latchFile(root: string): string {
101
- return path.join(root, 'agents', 'runtime', 'state', 'code-graph-nudge.json');
102
- }
103
- function alreadyNudged(root: string, session: string): boolean {
104
- try {
105
- const state = JSON.parse(fs.readFileSync(latchFile(root), 'utf-8')) as Record<string, boolean>;
106
- return state[session] === true;
107
- } catch {
108
- return false;
109
- }
110
- }
111
- function latch(root: string, session: string): void {
112
- try {
113
- const p = latchFile(root);
114
- let state: Record<string, boolean> = {};
115
- try {
116
- state = JSON.parse(fs.readFileSync(p, 'utf-8')) as Record<string, boolean>;
117
- } catch {
118
- /* fresh */
119
- }
120
- state[session] = true;
121
- fs.mkdirSync(path.dirname(p), { recursive: true });
122
- fs.writeFileSync(p, JSON.stringify(state));
123
- } catch {
124
- /* fail-open: a persistence failure must not break the tool call */
125
- }
126
- }
127
-
128
- const NATIVE_CACHE = path.join('agents', 'runtime', 'state', 'code-graph-v1.json');
129
-
130
- /** The nudge line for the current source state (≤40 tokens, one line). */
131
- export function nudgeReason(root: string): string {
132
- const verdicts = detectSources(root, path.join(root, NATIVE_CACHE));
133
- const picked = pickSource(verdicts);
134
- if (!picked) {
135
- return 'No code-graph found. For "who calls / where used / impact" run `agent-config code-graph refresh` once, then `agent-config code-graph query <symbol>` instead of grepping blind.';
136
- }
137
- if (picked.stale) {
138
- return `code-graph is ${picked.commits_behind ?? 'N'} commit(s) behind — rebuild with \`agent-config code-graph refresh\` before trusting relationship answers.`;
139
- }
140
- return 'A fresh code-graph is present — for structure questions run `agent-config code-graph query|affected <symbol>` first; grep is the fallback (say which answered).';
141
- }
142
-
143
- export function main(): number {
144
- let envelope: JsonValue;
145
- try {
146
- const raw = readHookStdin();
147
- envelope = raw.trim() ? (JSON.parse(raw) as JsonValue) : {};
148
- } catch {
149
- return EXIT_ALLOW;
150
- }
151
- if (!isObject(envelope)) return EXIT_ALLOW;
152
-
153
- const cwd = envelope['cwd'];
154
- const pr = envelope['workspace_root'] ?? envelope['project_root'];
155
- const root = typeof cwd === 'string' && cwd ? cwd : typeof pr === 'string' && pr ? pr : '.';
156
- if (!enabled(root)) return EXIT_ALLOW;
157
-
158
- const { isSearch, isCodeRead } = classifyTool(envelope);
159
- if (!isSearch && !isCodeRead) return EXIT_ALLOW;
160
-
161
- const session = sessionId(envelope);
162
- if (alreadyNudged(root, session)) return EXIT_ALLOW; // once per session
163
-
164
- let reason: string;
165
- try {
166
- reason = nudgeReason(root);
167
- } catch {
168
- return EXIT_ALLOW;
169
- }
170
- latch(root, session);
171
- process.stdout.write(`${JSON.stringify({ decision: 'warn', reason })}\n`);
172
- return EXIT_WARN;
173
- }
174
-
175
- // Bundle-safety: never auto-run when inlined into an esbuild bundle, where
176
- // every module shares the bundle's `import.meta.url` (see cmd_migrate.ts).
177
- declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
178
- function isCliEntry(): boolean {
179
- if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) {
180
- return false;
181
- }
182
- if (process.argv[1] === undefined) return false;
183
- const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
184
- if (import.meta.url === argvUrl) return true;
185
- try {
186
- return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
187
- } catch {
188
- return false;
189
- }
190
- }
191
- if (isCliEntry()) process.exit(main());