@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
@@ -0,0 +1,638 @@
1
+ #!/usr/bin/env tsx
2
+ import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
3
+ import {
4
+ execute
5
+ } from "./chunk-LTYVIY76.js";
6
+ import {
7
+ blocker_class,
8
+ blocker_needs_user,
9
+ collect
10
+ } from "./chunk-QAJS5YWY.js";
11
+ import "./chunk-ULET4BYS.js";
12
+ import {
13
+ isCliEntry
14
+ } from "./chunk-5EK5WQN6.js";
15
+ import "./chunk-YWVXLR44.js";
16
+ import "./chunk-7XGD2OEU.js";
17
+ import "./chunk-DBH4AHDK.js";
18
+ import "./chunk-YDQSHTD7.js";
19
+ import {
20
+ probeLater
21
+ } from "./chunk-ZZQBUHFK.js";
22
+ import "./chunk-JO25G5H7.js";
23
+
24
+ // src/agent-src/scripts/roadmap_gates.ts
25
+ import * as path2 from "node:path";
26
+ import { fileURLToPath } from "node:url";
27
+ import * as fs2 from "node:fs";
28
+ import { spawnSync } from "node:child_process";
29
+
30
+ // src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts
31
+ import * as fs from "node:fs";
32
+ import * as path from "node:path";
33
+
34
+ // src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation.ts
35
+ var STAGE_TTL_MS = 15 * 60 * 1e3;
36
+ function stageStatus(stage, now) {
37
+ if (stage.state === "pending" && Date.parse(stage.expires_at) <= now) {
38
+ return "expired";
39
+ }
40
+ return stage.state;
41
+ }
42
+
43
+ // src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts
44
+ var STORE_REL = path.join("agents", "runtime", "staged-confirmations");
45
+ function storeDir(root) {
46
+ return path.join(root, STORE_REL);
47
+ }
48
+ function pendingDir(root) {
49
+ return path.join(storeDir(root), "pending");
50
+ }
51
+ var _TOKEN_RE = /^[0-9a-f]{8,64}$/;
52
+ function isSafeToken(token) {
53
+ return _TOKEN_RE.test(token);
54
+ }
55
+ function isStage(v) {
56
+ if (typeof v !== "object" || v === null) {
57
+ return false;
58
+ }
59
+ const s = v;
60
+ return typeof s.token === "string" && isSafeToken(s.token) && typeof s.action === "string" && typeof s.object === "string" && typeof s.staged_at === "string" && typeof s.expires_at === "string";
61
+ }
62
+ function readStageFile(file) {
63
+ try {
64
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
65
+ return isStage(parsed) ? parsed : null;
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
70
+ function listPending(root, now) {
71
+ let names;
72
+ try {
73
+ names = fs.readdirSync(pendingDir(root));
74
+ } catch {
75
+ return [];
76
+ }
77
+ const out = [];
78
+ for (const n of names.sort()) {
79
+ if (!n.endsWith(".json")) {
80
+ continue;
81
+ }
82
+ const stage = readStageFile(path.join(pendingDir(root), n));
83
+ if (stage !== null) {
84
+ out.push({ stage, status: stageStatus(stage, now) });
85
+ }
86
+ }
87
+ out.sort(
88
+ (a, b) => a.stage.staged_at.localeCompare(b.stage.staged_at) || a.stage.token.localeCompare(b.stage.token)
89
+ );
90
+ return out;
91
+ }
92
+
93
+ // src/agent-src/scripts/roadmap_gates.ts
94
+ var _HERE = fileURLToPath(import.meta.url);
95
+ var WIDTH = 78;
96
+ function regroupTodo(todo) {
97
+ const steps = [];
98
+ for (const line of todo) {
99
+ const startsStep = /^(\d+[.)]|[-*+])\s/.test(line);
100
+ if (startsStep || steps.length === 0) {
101
+ steps.push(line);
102
+ } else {
103
+ steps[steps.length - 1] = `${steps[steps.length - 1]} ${line}`;
104
+ }
105
+ }
106
+ return steps;
107
+ }
108
+ function wrap(text, width, indent) {
109
+ const words = text.split(/\s+/).filter(Boolean);
110
+ if (words.length === 0) {
111
+ return [];
112
+ }
113
+ const lines = [];
114
+ let cur = "";
115
+ for (const w of words) {
116
+ const candidate = cur === "" ? w : `${cur} ${w}`;
117
+ if (candidate.length > width && cur !== "") {
118
+ lines.push(cur);
119
+ cur = w;
120
+ } else {
121
+ cur = candidate;
122
+ }
123
+ }
124
+ if (cur !== "") {
125
+ lines.push(cur);
126
+ }
127
+ return lines.map((l, i) => i === 0 ? l : indent + l);
128
+ }
129
+ var LABEL_W = 19;
130
+ function field(label, value) {
131
+ const pad = " " + label.padEnd(LABEL_W);
132
+ const indent = " ".repeat(pad.length);
133
+ const lines = wrap(value, WIDTH - pad.length, indent);
134
+ if (lines.length === 0) {
135
+ return [];
136
+ }
137
+ return [pad + lines[0], ...lines.slice(1)];
138
+ }
139
+ function collectEntries(roadmapRoot) {
140
+ const entries = [];
141
+ for (const r of collect(roadmapRoot)) {
142
+ for (const b of r.open_blockers) {
143
+ entries.push({ blocker: b, roadmapRel: r.rel, openSteps: r.open_ });
144
+ }
145
+ }
146
+ entries.sort(
147
+ (a, b) => b.openSteps - a.openSteps || a.roadmapRel.localeCompare(b.roadmapRel) || a.blocker.id.localeCompare(b.blocker.id)
148
+ );
149
+ return entries;
150
+ }
151
+ function isLegacy(b) {
152
+ return b.id === "legacy";
153
+ }
154
+ function renderEntry(e, index) {
155
+ const head = `${index} \xB7 ${isLegacy(e.blocker) ? "blocked-until note" : e.blocker.id}`;
156
+ const tail = e.openSteps > 0 ? `unblocks: ${e.openSteps} step${e.openSteps !== 1 ? "s" : ""}` : "";
157
+ const dashes = Math.max(3, WIDTH - head.length - tail.length - 6);
158
+ const out = [
159
+ "",
160
+ `\u2500\u2500 ${head} ${"\u2500".repeat(dashes)} ${tail}`.trimEnd(),
161
+ ...field("Roadmap:", e.roadmapRel),
162
+ ...field("Blocks:", e.blocker.blocks)
163
+ ];
164
+ if (e.blocker.question) {
165
+ out.push(...field("The question:", e.blocker.question));
166
+ }
167
+ out.push(
168
+ ...field(
169
+ "Recommendation:",
170
+ e.blocker.recommendation || "(none recorded \u2014 this entry predates the field; ask for one before deciding)"
171
+ )
172
+ );
173
+ const doLabel = isLegacy(e.blocker) ? "Blocked until:" : "Do this:";
174
+ const steps = regroupTodo(e.blocker.todo);
175
+ if (steps.length === 0) {
176
+ out.push(
177
+ ...field(
178
+ doLabel,
179
+ "(no steps recorded \u2014 the blocker entry in the roadmap needs a **What to do:** list)"
180
+ )
181
+ );
182
+ } else {
183
+ out.push(...field(doLabel, steps[0]));
184
+ for (const s of steps.slice(1)) {
185
+ const indent = " ".repeat(LABEL_W + 2);
186
+ const lines = wrap(s, WIDTH - LABEL_W - 2, indent);
187
+ out.push(...lines.map((l, i) => i === 0 ? indent + l : l));
188
+ }
189
+ }
190
+ if (e.blocker.ifNothing) {
191
+ out.push(...field("If you do nothing:", e.blocker.ifNothing));
192
+ }
193
+ out.push(...field("Done when:", e.blocker.resolvedWhen));
194
+ return out;
195
+ }
196
+ function renderResumed(findings) {
197
+ const fired = findings.filter((f) => f.verdict === "fired");
198
+ const undecidable = findings.filter((f) => f.verdict === "undecidable").length;
199
+ if (findings.length === 0) {
200
+ return [];
201
+ }
202
+ const out = [];
203
+ if (fired.length > 0) {
204
+ out.push("");
205
+ const head = `FIRED \xB7 ${fired.length} parked roadmap${fired.length !== 1 ? "s" : ""} can resume`;
206
+ out.push(`\u2500\u2500 ${head} ${"\u2500".repeat(Math.max(3, WIDTH - head.length - 4))}`);
207
+ for (const f of fired) {
208
+ out.push(...field("Roadmap:", f.file));
209
+ out.push(...field("Condition:", f.condition));
210
+ out.push(...field("Fired because:", f.why));
211
+ }
212
+ out.push("");
213
+ out.push("Resume one with: `git mv agents/roadmaps/later/<file> agents/roadmaps/`");
214
+ out.push("then `agent-config roadmap:progress`.");
215
+ }
216
+ out.push("");
217
+ out.push(
218
+ `Resume-probe coverage: ${findings.length - undecidable} of ${findings.length} park note${findings.length !== 1 ? "s" : ""} carry a machine-decidable condition` + (undecidable > 0 ? ` \xB7 ${undecidable} undecidable` : "")
219
+ );
220
+ return out;
221
+ }
222
+ function render(entries, all, resumed = []) {
223
+ const mine = entries.filter((e) => blocker_needs_user(e.blocker.owner));
224
+ const others = entries.filter((e) => !blocker_needs_user(e.blocker.owner));
225
+ const shown = all ? entries : mine;
226
+ const lines = [];
227
+ if (mine.length === 0) {
228
+ lines.push(
229
+ others.length === 0 ? "No open blockers at all." : `Nothing is waiting on you. ${others.length} open blocker${others.length !== 1 ? "s" : ""} sit with maintainer/external${all ? "" : " \u2014 see --all"}.`
230
+ );
231
+ } else {
232
+ const head = `${mine.length} decision${mine.length !== 1 ? "s" : ""} need${mine.length === 1 ? "s" : ""} you`;
233
+ const rest = others.length > 0 ? ` \xB7 ${others.length} more with maintainer/external${all ? "" : " (--all)"}` : "";
234
+ lines.push(head + rest);
235
+ }
236
+ let n = 0;
237
+ for (const e of shown) {
238
+ n += 1;
239
+ lines.push(...renderEntry(e, n));
240
+ }
241
+ if (shown.length > 0) {
242
+ lines.push("");
243
+ lines.push("Not sure about one of these? Ask your agent:");
244
+ lines.push(' "guide me through <id>" \u2014 one decision, step by step');
245
+ lines.push("");
246
+ }
247
+ lines.push(...renderResumed(resumed));
248
+ return lines.join("\n") + "\n";
249
+ }
250
+ function isAgentDrafted(recommendation) {
251
+ return /\(agent-drafted\b/i.test(recommendation);
252
+ }
253
+ function sheetLabel(b) {
254
+ return isLegacy(b) ? "blocked-until note" : `\`${b.id}\``;
255
+ }
256
+ function firstSentence(text) {
257
+ const trimmed = text.trim();
258
+ if (trimmed === "") {
259
+ return "";
260
+ }
261
+ const m = /^(.+?[.!?])(\s|$)/.exec(trimmed.replace(/\s+/g, " "));
262
+ return m === null ? trimmed.replace(/\s+/g, " ") : m[1];
263
+ }
264
+ function sheetQuestion(b) {
265
+ if (b.question.trim() !== "") {
266
+ return { text: firstSentence(b.question), source: "question" };
267
+ }
268
+ const steps = regroupTodo(b.todo);
269
+ if (steps.length > 0 && steps[0].trim() !== "") {
270
+ return { text: firstSentence(steps[0]), source: "todo" };
271
+ }
272
+ return { text: firstSentence(b.blocks), source: "blocks" };
273
+ }
274
+ var SHEET_ANSWER_REL = path2.join("agents", "decisions", "consolidated-decision-sheet-answer.md");
275
+ var SHEET_ANSWER_RE = /<!--\s*sheet-answer:\s*(.+?)\s*\|\s*answered:\s*(\d{4}-\d{2}-\d{2})\s*\|\s*authority:\s*(\S+)\s*-->/;
276
+ function readSheetAnswer(repoRoot) {
277
+ const file = path2.join(repoRoot, SHEET_ANSWER_REL);
278
+ let text;
279
+ try {
280
+ text = fs2.readFileSync(file, "utf8");
281
+ } catch {
282
+ return null;
283
+ }
284
+ const m = SHEET_ANSWER_RE.exec(text);
285
+ if (m === null) {
286
+ return null;
287
+ }
288
+ return {
289
+ option: m[1].trim(),
290
+ answered: m[2].trim(),
291
+ authority: m[3].trim()
292
+ };
293
+ }
294
+ function answerBanner(answer) {
295
+ if (answer === null) {
296
+ return [];
297
+ }
298
+ return [
299
+ ">",
300
+ `> **ANSWERED ${answer.answered} \u2014 ${answer.option}.**`,
301
+ `> Recorded in \`${SHEET_ANSWER_REL}\` (not derived);`,
302
+ `> authority \`${answer.authority}\`.`,
303
+ "> The rows below are the ones still OPEN: an answered",
304
+ "> row stays here until the work its own entry names is done, so this is a work",
305
+ "> queue and not a count of unanswered questions."
306
+ ];
307
+ }
308
+ function renderSheet(entries, now, answer = null) {
309
+ const mine = entries.filter((e) => blocker_needs_user(e.blocker.owner));
310
+ const stamp = now.toISOString().slice(0, 10);
311
+ if (mine.length === 0) {
312
+ const banner = answerBanner(answer);
313
+ return `# Consolidated decision sheet \u2014 nothing owned by you (${stamp})
314
+
315
+ No open blocker in the active roadmap tree carries \`Owner: user\`. Nothing to answer.
316
+ ` + (banner.length === 0 ? "" : "\n" + banner.slice(1).join("\n") + "\n");
317
+ }
318
+ const noRec = mine.filter((e) => e.blocker.recommendation.trim() === "");
319
+ const legacyNotes = noRec.filter((e) => isLegacy(e.blocker)).length;
320
+ const missing = noRec.length - legacyNotes;
321
+ const drafted = mine.filter((e) => isAgentDrafted(e.blocker.recommendation)).length;
322
+ const maintainerRecorded = mine.length - noRec.length - drafted;
323
+ const out = [
324
+ `# Consolidated decision sheet \u2014 ${String(mine.length)} decisions owned by you`,
325
+ "",
326
+ `> Generated ${stamp} by \`agent-config gates --sheet\` over \`agents/roadmaps/\`.`,
327
+ "> Sorted by unblock count, descending. **Accept-all-defaults is a valid answer**",
328
+ "> (`road-to-estate-drawdown` blocker `b-consolidated-decision-sheet`, option (a));",
329
+ "> answering only the two largest-unblock items and deferring the rest is option (c),",
330
+ "> which the roadmap itself recommends. Whichever you pick, the agent writes the answers",
331
+ "> back into each roadmap at its own blocker \u2014 that is not your work.",
332
+ ">",
333
+ `> **Provenance of the ${String(mine.length)} defaults: ${String(maintainerRecorded)} maintainer-recorded \xB7`,
334
+ `> ${String(drafted)} \`agent-drafted\` \xB7 ${String(missing)} with no recommendation at all \xB7`,
335
+ `> ${String(legacyNotes)} legacy \`> Blocked until \u2026\` note(s) that have no field to carry one.**`,
336
+ "> The distinction is in every row on purpose: an agent-drafted default is the",
337
+ "> least-examined thing on this sheet, and accept-all-defaults would accept those too.",
338
+ ">",
339
+ "> This file is DERIVED \u2014 every line above and below comes from the roadmaps themselves,",
340
+ "> so regenerating is deterministic and an answer written into this file would be lost.",
341
+ "> Answers go back into each roadmap at its own blocker; the agent does that.",
342
+ ...answerBanner(answer),
343
+ "",
344
+ "| # | Decision | Roadmap | Unblocks | Default source |",
345
+ "|---:|---|---|---:|---|"
346
+ ];
347
+ mine.forEach((e, i) => {
348
+ const source = e.blocker.recommendation.trim() !== "" ? isAgentDrafted(e.blocker.recommendation) ? "`agent-drafted`" : "maintainer-recorded" : isLegacy(e.blocker) ? "none \u2014 legacy note" : "none recorded";
349
+ out.push(
350
+ `| ${String(i + 1)} | ${sheetLabel(e.blocker)} | ${e.roadmapRel} | ${String(e.openSteps)} | ${source} |`
351
+ );
352
+ });
353
+ mine.forEach((e, i) => {
354
+ const q = sheetQuestion(e.blocker);
355
+ const qLabel = q.source === "question" ? "recorded `Question:`" : q.source === "todo" ? "derived from the first `What to do:` step" : "derived from `Blocks:`";
356
+ const recorded = e.blocker.recommendation.trim();
357
+ out.push(
358
+ "",
359
+ `## ${String(i + 1)} \xB7 ${sheetLabel(e.blocker)}`,
360
+ "",
361
+ `- **Roadmap:** ${e.roadmapRel}`,
362
+ `- **Unblocks:** ${String(e.openSteps)} open step(s) \u2014 ${e.blocker.blocks || "(not recorded)"}`,
363
+ `- **Question** (${qLabel})**:** ${q.text || "(the blocker records no question, no steps and no Blocks: field)"}`
364
+ );
365
+ if (recorded === "" && isLegacy(e.blocker)) {
366
+ out.push(
367
+ "- **Default:** _this is a legacy `> Blocked until \u2026` note, not a `### blocker:` entry, so it has no `Recommendation:` field to read. Converting it into a real blocker entry is what gives it a default._",
368
+ "- **Default source:** none \u2014 legacy note"
369
+ );
370
+ } else if (recorded === "") {
371
+ out.push(
372
+ "- **Default:** _none recorded \u2014 needs an agent-drafted default before this row can be answered by accepting it._",
373
+ "- **Default source:** `agent-drafted` (to be written in below, and marked as such)"
374
+ );
375
+ } else {
376
+ const drafted2 = isAgentDrafted(recorded);
377
+ out.push(
378
+ `- **Default:** ${firstSentence(recorded)}`,
379
+ drafted2 ? "- **Default source:** `agent-drafted` \u2014 written into the roadmap\u2019s `Recommendation:` field and marked there, NOT a maintainer decision" : "- **Default source:** maintainer-recorded `Recommendation:` in the roadmap",
380
+ `- **Recommendation (full):** ${recorded.replace(/\s+/g, " ")}`
381
+ );
382
+ }
383
+ if (e.blocker.ifNothing.trim() !== "") {
384
+ out.push(`- **If you do nothing:** ${e.blocker.ifNothing.replace(/\s+/g, " ")}`);
385
+ }
386
+ out.push(
387
+ `- **Done when:** ${e.blocker.resolvedWhen.replace(/\s+/g, " ") || "(not recorded)"}`,
388
+ "- **Your answer:** _(accept default \xB7 override \xB7 defer)_"
389
+ );
390
+ });
391
+ out.push("");
392
+ return out.join("\n");
393
+ }
394
+ function renderReply(entries) {
395
+ const mine = entries.filter((e) => blocker_needs_user(e.blocker.owner));
396
+ if (mine.length === 0) {
397
+ return "";
398
+ }
399
+ const lead = mine[0];
400
+ const rest = mine.slice(1);
401
+ const lines = [];
402
+ lines.push(`Blocked: ${lead.blocker.blocks} \u2014 ${lead.roadmapRel}`);
403
+ const steps = regroupTodo(lead.blocker.todo);
404
+ const doLabel = isLegacy(lead.blocker) ? "Blocked until:" : "Do:";
405
+ if (steps.length === 0) {
406
+ lines.push(
407
+ `${doLabel} (no steps recorded \u2014 the blocker entry needs a **What to do:** list)`
408
+ );
409
+ } else if (steps.length === 1) {
410
+ lines.push(...wrap(`${doLabel} ${steps[0]}`, WIDTH, " "));
411
+ } else {
412
+ lines.push(`${doLabel}`);
413
+ for (const s of steps) {
414
+ lines.push(...wrap(` ${s}`, WIDTH, " "));
415
+ }
416
+ }
417
+ lines.push(...wrap(`Done when: ${lead.blocker.resolvedWhen}`, WIDTH, " "));
418
+ if (rest.length > 0) {
419
+ lines.push("");
420
+ lines.push(
421
+ ...wrap(
422
+ `${rest.length} other decision${rest.length !== 1 ? "s" : ""} also wait${rest.length === 1 ? "s" : ""} on you, none blocking this \u2014 \`agent-config gates\`.`,
423
+ WIDTH,
424
+ " "
425
+ )
426
+ );
427
+ }
428
+ return lines.join("\n") + "\n";
429
+ }
430
+ function renderJson(entries, all, resumed = []) {
431
+ const pick = all ? entries : entries.filter((e) => blocker_needs_user(e.blocker.owner));
432
+ return JSON.stringify(
433
+ {
434
+ needsYou: entries.filter((e) => blocker_needs_user(e.blocker.owner)).length,
435
+ other: entries.filter((e) => !blocker_needs_user(e.blocker.owner)).length,
436
+ resumeFired: resumed.filter((f) => f.verdict === "fired").length,
437
+ resumeUndecidable: resumed.filter((f) => f.verdict === "undecidable").length,
438
+ resumed: resumed.filter((f) => f.verdict === "fired"),
439
+ blockers: pick.map((e) => ({
440
+ id: e.blocker.id,
441
+ roadmap: e.roadmapRel,
442
+ owner: e.blocker.owner,
443
+ needsYou: blocker_needs_user(e.blocker.owner),
444
+ // Resolved through the same absent-field default every
445
+ // other consumer applies, so a synthesised `legacy` note
446
+ // reads as class 3 rather than as a hole. `class` ships and
447
+ // the sibling `run` does not, and the asymmetry is the
448
+ // roadmap's, not a preference: `road-to-gate-autonomy` step
449
+ // 1.3 names this field as its acceptance condition, while
450
+ // nothing asks for the command here — `--execute` reads it
451
+ // off the entry via `locate()`. Emitting `run` would also
452
+ // need a call on the authored-vs-`commandOf()`-stripped
453
+ // form, which no consumer exists to settle.
454
+ class: blocker_class(e.blocker),
455
+ blocks: e.blocker.blocks,
456
+ unblocksSteps: e.openSteps,
457
+ todo: regroupTodo(e.blocker.todo),
458
+ resolvedWhen: e.blocker.resolvedWhen
459
+ }))
460
+ },
461
+ null,
462
+ 2
463
+ ) + "\n";
464
+ }
465
+ function renderPending(root, now) {
466
+ const rows = listPending(root, now);
467
+ const live = rows.filter((r) => r.status === "pending");
468
+ const expired = rows.filter((r) => r.status === "expired");
469
+ const lines = [];
470
+ if (live.length === 0) {
471
+ lines.push(
472
+ expired.length === 0 ? "No staged actions awaiting confirmation." : `Nothing awaits your confirmation. ${expired.length} stage${expired.length !== 1 ? "s" : ""} expired unconfirmed \u2014 the action never fired.`
473
+ );
474
+ return lines.join("\n") + "\n";
475
+ }
476
+ lines.push(
477
+ `${live.length} staged action${live.length !== 1 ? "s" : ""} await${live.length === 1 ? "s" : ""} your confirmation` + (expired.length > 0 ? ` \xB7 ${expired.length} expired unconfirmed` : "")
478
+ );
479
+ let n = 0;
480
+ for (const { stage } of live) {
481
+ n += 1;
482
+ lines.push(...renderStage(stage, n));
483
+ }
484
+ lines.push("");
485
+ return lines.join("\n") + "\n";
486
+ }
487
+ function renderStage(stage, index) {
488
+ const head = `${index} \xB7 ${stage.action}`;
489
+ const tail = `token: ${stage.token}`;
490
+ const dashes = Math.max(3, WIDTH - head.length - tail.length - 6);
491
+ return [
492
+ "",
493
+ `\u2500\u2500 ${head} ${"\u2500".repeat(dashes)} ${tail}`.trimEnd(),
494
+ // The object is the first field on purpose: an approval that does not
495
+ // name the exact object is the thing non-destructive-by-default forbids,
496
+ // so it is what the reader must see before anything else.
497
+ ...field("Object:", stage.object),
498
+ ...field("Staged by:", stage.source),
499
+ ...field("Expires:", stage.expires_at)
500
+ ];
501
+ }
502
+ function renderPendingJson(root, now) {
503
+ const rows = listPending(root, now);
504
+ return JSON.stringify(
505
+ {
506
+ awaitingYou: rows.filter((r) => r.status === "pending").length,
507
+ expired: rows.filter((r) => r.status === "expired").length,
508
+ staged: rows.map(({ stage, status }) => ({
509
+ token: stage.token,
510
+ action: stage.action,
511
+ object: stage.object,
512
+ source: stage.source,
513
+ stagedAt: stage.staged_at,
514
+ expiresAt: stage.expires_at,
515
+ status
516
+ }))
517
+ },
518
+ null,
519
+ 2
520
+ ) + "\n";
521
+ }
522
+ function _isDir(p) {
523
+ try {
524
+ return fs2.statSync(p).isDirectory();
525
+ } catch {
526
+ return false;
527
+ }
528
+ }
529
+ function _resolveRepoRoot(start, marker = path2.join("agents", "roadmaps")) {
530
+ if (_isDir(path2.join(start, marker))) {
531
+ return start;
532
+ }
533
+ try {
534
+ const r = spawnSync("git", ["rev-parse", "--show-toplevel"], {
535
+ cwd: start,
536
+ encoding: "utf-8",
537
+ timeout: 1e4
538
+ });
539
+ const top = (r.stdout || "").trim();
540
+ if (r.status === 0 && top !== "" && _isDir(path2.join(top, marker))) {
541
+ return top;
542
+ }
543
+ } catch {
544
+ }
545
+ return start;
546
+ }
547
+ function main(argv) {
548
+ const args = argv ?? process.argv.slice(2);
549
+ const all = args.includes("--all");
550
+ const json = args.includes("--json");
551
+ const reply = args.includes("--reply");
552
+ const pending = args.includes("--pending");
553
+ const sheet = args.includes("--sheet");
554
+ const execIdx = args.indexOf("--execute");
555
+ if (execIdx !== -1) {
556
+ const id = args[execIdx + 1];
557
+ if (id === void 0 || id.startsWith("--")) {
558
+ process.stderr.write(
559
+ "usage: gates --execute <blocker-id> [--confirm]\n Without --confirm the command is echoed and nothing runs.\n"
560
+ );
561
+ return 1;
562
+ }
563
+ if (pending) {
564
+ process.stderr.write("gates: --execute and --pending are different sources; pick one.\n");
565
+ return 1;
566
+ }
567
+ if (json) {
568
+ process.stderr.write("gates --execute has no JSON form; its output is a report.\n");
569
+ return 1;
570
+ }
571
+ const root = _resolveRepoRoot(process.cwd());
572
+ const dir = path2.join(root, "agents", "roadmaps");
573
+ if (!_isDir(dir)) {
574
+ process.stderr.write("No roadmaps directory \u2014 nothing to execute.\n");
575
+ return 1;
576
+ }
577
+ const r = execute(dir, id, /* @__PURE__ */ new Date(), { confirm: args.includes("--confirm") });
578
+ process.stdout.write(r.report);
579
+ return r.code;
580
+ }
581
+ if (pending) {
582
+ const root = _resolveRepoRoot(process.cwd(), path2.join("agents", "runtime"));
583
+ const now = Date.now();
584
+ process.stdout.write(json ? renderPendingJson(root, now) : renderPending(root, now));
585
+ return 0;
586
+ }
587
+ const repoRoot = _resolveRepoRoot(process.cwd());
588
+ const roadmapRoot = path2.join(repoRoot, "agents", "roadmaps");
589
+ if (!_isDir(roadmapRoot)) {
590
+ process.stdout.write(
591
+ reply ? "" : json ? (
592
+ // Every key `renderJson` emits, so a consumer reading the
593
+ // resume fields gets 0 rather than `undefined` on the
594
+ // branch where there is no roadmap tree to probe.
595
+ JSON.stringify(
596
+ {
597
+ needsYou: 0,
598
+ other: 0,
599
+ resumeFired: 0,
600
+ resumeUndecidable: 0,
601
+ resumed: [],
602
+ blockers: []
603
+ },
604
+ null,
605
+ 2
606
+ ) + "\n"
607
+ ) : "No roadmaps directory \u2014 nothing to report.\n"
608
+ );
609
+ return 0;
610
+ }
611
+ const entries = collectEntries(roadmapRoot);
612
+ const resumed = reply || sheet ? [] : probeLater(roadmapRoot, repoRoot);
613
+ process.stdout.write(
614
+ sheet ? renderSheet(entries, /* @__PURE__ */ new Date(), readSheetAnswer(repoRoot)) : reply ? renderReply(entries) : json ? renderJson(entries, all, resumed) : render(entries, all, resumed)
615
+ );
616
+ return 0;
617
+ }
618
+ if (isCliEntry(import.meta.url, "roadmap_gates")) {
619
+ process.exitCode = main();
620
+ }
621
+ export {
622
+ collectEntries,
623
+ isAgentDrafted,
624
+ main,
625
+ blocker_needs_user as needsUser,
626
+ readSheetAnswer,
627
+ regroupTodo,
628
+ render,
629
+ renderJson,
630
+ renderPending,
631
+ renderPendingJson,
632
+ renderReply,
633
+ renderResumed,
634
+ renderSheet,
635
+ sheetLabel,
636
+ sheetQuestion,
637
+ wrap
638
+ };