@khoavu882/doflow 2.0.0-beta.5 → 2.0.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 (471) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  3. package/core/.antigravity-plugin/plugin.json +1 -2
  4. package/core/.claude-plugin/plugin.json +1 -1
  5. package/core/.codex-plugin/plugin.json +1 -1
  6. package/core/.plugin/plugin.json +1 -1
  7. package/core/harnesses/claude/hooks/lib.sh +43 -24
  8. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  9. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  10. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  11. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  12. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  13. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  14. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  15. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  16. package/core/harnesses/claude/settings/settings.json +18 -0
  17. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  18. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  19. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  20. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  21. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  22. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  23. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  24. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  25. package/core/harnesses/codex/hooks/lib.sh +44 -25
  26. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  27. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  28. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  29. package/core/harnesses/codex/hooks/subagent-audit.sh +1 -0
  30. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  31. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  32. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  33. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  34. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  35. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  36. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  37. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  38. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  39. package/core/harnesses/kiro/agents/doflow.json +1 -1
  40. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  41. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +1 -0
  42. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +1 -0
  43. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +1 -0
  44. package/core/harnesses/kiro/hooks/session-start.sh +1 -0
  45. package/core/harnesses/kiro/hooks/stop-check.sh +1 -0
  46. package/core/harnesses/pi/extensions/doflow-guard.js +8 -0
  47. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +0 -1
  48. package/core/harnesses/shared/hooks/bridge/bridge.sh +102 -9
  49. package/core/harnesses/shared/hooks/bridge/envelope.jq +87 -18
  50. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  51. package/core/harnesses/shared/hooks/bridge/respond.sh +10 -2
  52. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  53. package/core/harnesses/shared/hooks/policies/capture-failure.sh +48 -15
  54. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  55. package/core/harnesses/shared/hooks/policies/contract.sh +3 -0
  56. package/core/harnesses/shared/hooks/policies/deny-json.sh +2 -11
  57. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  58. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  59. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  60. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  61. package/core/harnesses/shared/hooks/policies/lib.sh +63 -40
  62. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +3 -2
  63. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +213 -12
  64. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +114 -38
  65. package/core/harnesses/shared/hooks/policies/session-context.sh +30 -1
  66. package/core/harnesses/shared/hooks/policies/stop-check.sh +20 -9
  67. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +5 -2
  68. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  69. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +60 -155
  70. package/core/harnesses/shared/hooks/stream-hook-runner.js +47 -8
  71. package/core/harnesses/shared/locator/doflow-run +2 -3
  72. package/core/registry/advice.json +3 -3
  73. package/core/registry/assets.json +55 -82
  74. package/core/registry/capabilities.json +12 -0
  75. package/core/registry/contracts.json +58 -31
  76. package/core/registry/contribution-points.json +32 -0
  77. package/core/registry/gates.json +32 -0
  78. package/core/registry/guidance-caps.json +40 -0
  79. package/core/registry/harnesses.json +1442 -363
  80. package/core/registry/lifecycle.json +485 -304
  81. package/core/registry/mcp.json +5 -1
  82. package/core/registry/models.json +7 -1
  83. package/core/registry/package-templates/README.md +19 -0
  84. package/core/registry/package-templates/agent/files/agent.md +9 -0
  85. package/core/registry/package-templates/agent/template.json +4 -0
  86. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  87. package/core/registry/package-templates/capability-provider/template.json +11 -0
  88. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  89. package/core/registry/package-templates/debate-preset/template.json +4 -0
  90. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  91. package/core/registry/package-templates/review-preset/template.json +4 -0
  92. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  93. package/core/registry/package-templates/skill/template.json +4 -0
  94. package/core/registry/package-templates/worker/files/worker.json +92 -0
  95. package/core/registry/package-templates/worker/template.json +11 -0
  96. package/core/registry/packages/doflow/doflow-package.json +15 -0
  97. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  98. package/core/registry/protocols.json +61 -0
  99. package/core/registry/routes.json +17 -0
  100. package/core/registry/rules.json +431 -0
  101. package/core/registry/settings.json +276 -0
  102. package/core/registry/storage.json +679 -31
  103. package/core/registry/telemetry.json +236 -0
  104. package/core/registry/transcripts.json +142 -0
  105. package/core/registry/verification.json +76 -1
  106. package/core/registry/workflows.json +55 -0
  107. package/core/shared/agent-specs/core-implementer.md +3 -0
  108. package/core/shared/agent-specs/delivery-lead.md +68 -0
  109. package/core/shared/agent-specs/quality-guardian.md +5 -1
  110. package/core/shared/agent-specs/research-writer.md +10 -3
  111. package/core/shared/agent-specs/reviewer.md +53 -0
  112. package/core/shared/agent-specs/spec-analyst.md +5 -6
  113. package/core/shared/agent-specs/system-architect.md +5 -1
  114. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  115. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  116. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  117. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  118. package/core/shared/guidance/pointers/codex.md +1 -4
  119. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  120. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  121. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  122. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  123. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  124. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  125. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  126. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  127. package/core/shared/guidance/rules/RULES.md +45 -0
  128. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  129. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  130. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  131. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  132. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  133. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  134. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  135. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  136. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  137. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  138. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  139. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  140. package/core/shared/scripts/doflow/bin/doflow-run +149 -34
  141. package/core/shared/skills/do/SKILL.md +12 -10
  142. package/core/shared/skills/do/references/advice_calls.md +26 -0
  143. package/core/shared/skills/do/references/pm_routing.md +1 -2
  144. package/core/shared/skills/do/references/program_mode.md +31 -0
  145. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  146. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  147. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  148. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  149. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  150. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  151. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  152. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  153. package/core/shared/skills/do-design/SKILL.md +18 -17
  154. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  155. package/core/shared/skills/do-document/SKILL.md +11 -1
  156. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  157. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  158. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  159. package/core/shared/skills/do-execute-plan/SKILL.md +15 -58
  160. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  161. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  162. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +26 -1
  163. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  164. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  165. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  166. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  167. package/core/shared/skills/do-flow/SKILL.md +8 -9
  168. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  169. package/core/shared/skills/do-git/SKILL.md +4 -0
  170. package/core/shared/skills/do-implement/SKILL.md +4 -7
  171. package/core/shared/skills/do-plan/SKILL.md +26 -15
  172. package/core/shared/skills/do-test/SKILL.md +7 -4
  173. package/core/shared/templates/doflow/constitution-template.md +9 -3
  174. package/core/shared/templates/doflow/data-model-template.md +1 -1
  175. package/core/shared/templates/doflow/design-template.md +113 -16
  176. package/core/shared/templates/doflow/plan-template.md +11 -10
  177. package/core/shared/templates/doflow/question-log-template.md +14 -2
  178. package/core/shared/templates/doflow/requirement-template.md +1 -1
  179. package/core/worker-evidence/antigravity/checks.json +14 -0
  180. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  181. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  182. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  183. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  184. package/core/worker-evidence/codex/checks.json +38 -0
  185. package/package.json +10 -6
  186. package/src/adapters/antigravity/index.js +143 -66
  187. package/src/adapters/claude/index.js +24 -4
  188. package/src/adapters/codex/agents.js +25 -15
  189. package/src/adapters/codex/index.js +48 -13
  190. package/src/adapters/codex/native-projection.js +6 -2
  191. package/src/adapters/copilot/index.js +58 -23
  192. package/src/adapters/copy-tree.js +290 -44
  193. package/src/adapters/guidance-manifest.js +71 -0
  194. package/src/adapters/guidance-pointer.js +19 -0
  195. package/src/adapters/hook-commands.js +6 -10
  196. package/src/adapters/index.js +1 -0
  197. package/src/adapters/kiro/index.js +23 -12
  198. package/src/adapters/opencode/index.js +8 -8
  199. package/src/adapters/pi/hooks.js +2 -1
  200. package/src/adapters/pi/index.js +14 -7
  201. package/src/adapters/resolve-source.js +26 -2
  202. package/src/cli/commands/install.js +2 -1
  203. package/src/cli/commands/reconcile.js +53 -9
  204. package/src/cli/commands/remove.js +2 -2
  205. package/src/cli/commands/rollback.js +6 -3
  206. package/src/cli/commands/self-update.js +18 -9
  207. package/src/cli/commands/status.js +21 -2
  208. package/src/cli/commands/ui.js +99 -0
  209. package/src/cli/commands/update.js +2 -1
  210. package/src/cli/index.js +322 -29
  211. package/src/cli/runtime-commands.js +209 -57
  212. package/src/cli/shared.js +0 -2
  213. package/src/helper/git.js +1 -1
  214. package/src/helper/guardrails.js +1 -1
  215. package/src/helper/marker-merge.js +31 -13
  216. package/src/helper/package-ids.js +37 -0
  217. package/src/helper/semver.js +94 -0
  218. package/src/install/backup.js +105 -15
  219. package/src/install/context.js +1 -1
  220. package/src/install/targets.js +31 -16
  221. package/src/lifecycle/coverage.js +20 -3
  222. package/src/lifecycle/hook-tier.js +160 -0
  223. package/src/lifecycle/index.js +412 -78
  224. package/src/lifecycle/retired-harnesses.js +318 -0
  225. package/src/lifecycle/view.js +35 -15
  226. package/src/registry/index.js +551 -26
  227. package/src/registry/worker-ids.js +45 -0
  228. package/src/release/build-package.js +0 -3
  229. package/src/release/docs-blocks.js +492 -0
  230. package/src/release/preflight.js +425 -0
  231. package/src/release/rehearse.js +401 -0
  232. package/src/release/release-workflow.js +733 -0
  233. package/src/release/sync-plugin-versions.js +43 -7
  234. package/src/runtime/advice/bench-gate.js +25 -0
  235. package/src/runtime/advice/cli.js +59 -16
  236. package/src/runtime/advice/client.js +32 -9
  237. package/src/runtime/advice/config.js +98 -133
  238. package/src/runtime/advice/doctor.js +1 -1
  239. package/src/runtime/advice/elevation.js +97 -0
  240. package/src/runtime/advice/endpoint-guard.js +9 -3
  241. package/src/runtime/advice/mode.js +37 -0
  242. package/src/runtime/advice/record.js +18 -5
  243. package/src/runtime/advice/registry.js +4 -1
  244. package/src/runtime/advice/shadow-config.js +229 -0
  245. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  246. package/src/runtime/brief-rules.js +81 -0
  247. package/src/runtime/brief-tools.js +111 -34
  248. package/src/runtime/candidate.js +20 -11
  249. package/src/runtime/capabilities/executor.js +450 -0
  250. package/src/runtime/capabilities/loopback.js +41 -0
  251. package/src/runtime/capabilities/sanitizer.js +88 -0
  252. package/src/runtime/capability-router.js +135 -3
  253. package/src/runtime/checkouts.js +73 -11
  254. package/src/runtime/claims.js +13 -7
  255. package/src/runtime/cli.js +196 -19
  256. package/src/runtime/config-home.js +42 -0
  257. package/src/runtime/context/arbitrate.js +767 -0
  258. package/src/runtime/context/delivery-store.js +4 -6
  259. package/src/runtime/context/emission-rules.js +118 -0
  260. package/src/runtime/context/identity.js +227 -0
  261. package/src/runtime/context/primary-command.js +117 -0
  262. package/src/runtime/context/primary.js +344 -0
  263. package/src/runtime/context/summary-store.js +655 -0
  264. package/src/runtime/context-pack.js +154 -78
  265. package/src/runtime/decision-register.js +13 -4
  266. package/src/runtime/dispatch/admission.js +392 -0
  267. package/src/runtime/dispatch/attempt-end.js +274 -0
  268. package/src/runtime/dispatch/command.js +628 -0
  269. package/src/runtime/dispatch/controls.js +904 -0
  270. package/src/runtime/dispatch/envelope.js +276 -0
  271. package/src/runtime/dispatch/grants.js +310 -0
  272. package/src/runtime/dispatch/integrate.js +617 -0
  273. package/src/runtime/dispatch/loop.js +1835 -0
  274. package/src/runtime/dispatch/store.js +352 -0
  275. package/src/runtime/dispatch/verify-run.js +201 -0
  276. package/src/runtime/evidence-ledger.js +34 -7
  277. package/src/runtime/failure/capture.js +3 -1
  278. package/src/runtime/failure/cli.js +25 -9
  279. package/src/runtime/failure/home.js +57 -30
  280. package/src/runtime/failure/store.js +7 -2
  281. package/src/runtime/feature-pointer.js +174 -0
  282. package/src/runtime/feature-resolve.js +13 -2
  283. package/src/runtime/fleet/command.js +77 -0
  284. package/src/runtime/fleet/projects.js +178 -0
  285. package/src/runtime/fleet/tree.js +383 -0
  286. package/src/runtime/freshness.js +33 -3
  287. package/src/runtime/git-memo.js +46 -0
  288. package/src/runtime/guidance/ablation.js +427 -0
  289. package/src/runtime/health.js +565 -17
  290. package/src/runtime/history-compactor.js +13 -3
  291. package/src/runtime/implementation-gate.js +277 -22
  292. package/src/runtime/inventory/coverage.js +1 -1
  293. package/src/runtime/inventory/index.js +1 -1
  294. package/src/runtime/inventory/precedence.js +2 -2
  295. package/src/runtime/inventory/siblings.js +6 -4
  296. package/src/runtime/knowledge/code-corpus.js +277 -0
  297. package/src/runtime/knowledge/code-lexical.js +130 -0
  298. package/src/runtime/knowledge/code-retrieval.js +307 -0
  299. package/src/runtime/knowledge/code-validation.js +106 -0
  300. package/src/runtime/knowledge/gp3-gate.js +74 -0
  301. package/src/runtime/knowledge/graph-adapter.js +288 -0
  302. package/src/runtime/knowledge/graph-fallback.js +394 -0
  303. package/src/runtime/knowledge/hybrid.js +136 -8
  304. package/src/runtime/knowledge/retrieval.js +34 -1
  305. package/src/runtime/knowledge/rtk-compress.js +77 -0
  306. package/src/runtime/knowledge/semble-bridge.py +106 -0
  307. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  308. package/src/runtime/knowledge/semble-provider.js +365 -0
  309. package/src/runtime/lifecycle/cli.js +16 -6
  310. package/src/runtime/lifecycle/event-store.js +8 -6
  311. package/src/runtime/lifecycle/followup.js +6 -1
  312. package/src/runtime/lifecycle/overview.js +24 -1
  313. package/src/runtime/lifecycle/report-store.js +8 -10
  314. package/src/runtime/lifecycle/retention.js +95 -31
  315. package/src/runtime/lifecycle/root.js +9 -1
  316. package/src/runtime/lifecycle/status.js +34 -17
  317. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  318. package/src/runtime/mask.js +134 -7
  319. package/src/runtime/mcp-consultations.js +40 -6
  320. package/src/runtime/model-router.js +79 -7
  321. package/src/runtime/models/catalogue.js +191 -0
  322. package/src/runtime/models/command.js +153 -0
  323. package/src/runtime/off-words.js +12 -0
  324. package/src/runtime/outcome.js +2 -2
  325. package/src/runtime/packages/command.js +1009 -0
  326. package/src/runtime/packages/contributions.js +116 -0
  327. package/src/runtime/packages/digest.js +132 -0
  328. package/src/runtime/packages/fetch.js +182 -0
  329. package/src/runtime/packages/grants.js +192 -0
  330. package/src/runtime/packages/index-file.js +134 -0
  331. package/src/runtime/packages/instruction.js +90 -0
  332. package/src/runtime/packages/manifest.js +331 -0
  333. package/src/runtime/packages/points.js +477 -0
  334. package/src/runtime/packages/programs.js +216 -0
  335. package/src/runtime/packages/scaffold.js +277 -0
  336. package/src/runtime/packages/source.js +90 -0
  337. package/src/runtime/packages/state.js +164 -0
  338. package/src/runtime/packages/store.js +449 -0
  339. package/src/runtime/packages/tar.js +106 -0
  340. package/src/runtime/packages/view.js +406 -0
  341. package/src/runtime/plan-check.js +59 -0
  342. package/src/runtime/plan-content.js +324 -0
  343. package/src/runtime/policy-init.js +118 -0
  344. package/src/runtime/profiles/doctor.js +96 -0
  345. package/src/runtime/profiles/resolve.js +244 -0
  346. package/src/runtime/profiles/rollback.js +254 -0
  347. package/src/runtime/profiles/sampler.js +41 -0
  348. package/src/runtime/readiness-record.js +16 -11
  349. package/src/runtime/readiness.js +46 -5
  350. package/src/runtime/research-request.js +50 -25
  351. package/src/runtime/retrieval-plan.js +10 -30
  352. package/src/runtime/retrieval-record.js +75 -5
  353. package/src/runtime/review/command.js +246 -0
  354. package/src/runtime/review/dominance.js +68 -0
  355. package/src/runtime/review/findings.js +434 -0
  356. package/src/runtime/review/identity.js +255 -0
  357. package/src/runtime/review/protocol-command.js +109 -0
  358. package/src/runtime/review/protocols.js +405 -0
  359. package/src/runtime/review/resolve-protocol.js +302 -0
  360. package/src/runtime/review/start.js +530 -0
  361. package/src/runtime/roadmap/facts.js +479 -0
  362. package/src/runtime/roadmap/gates.js +270 -0
  363. package/src/runtime/roadmap/loop.js +1636 -0
  364. package/src/runtime/roadmap/merge.js +381 -0
  365. package/src/runtime/roadmap/rows.js +1113 -0
  366. package/src/runtime/roadmap/seed.js +951 -0
  367. package/src/runtime/rules-report.js +336 -0
  368. package/src/runtime/scaffold/artifacts.js +60 -9
  369. package/src/runtime/scaffold/generate.js +21 -9
  370. package/src/runtime/settings/autopilot.js +106 -0
  371. package/src/runtime/settings/cli.js +280 -0
  372. package/src/runtime/settings/config-write.js +314 -0
  373. package/src/runtime/settings/files.js +271 -0
  374. package/src/runtime/settings/legacy.js +154 -0
  375. package/src/runtime/settings/lexical.js +56 -0
  376. package/src/runtime/settings/prepared-run.js +269 -0
  377. package/src/runtime/settings/project-layers.js +118 -0
  378. package/src/runtime/settings/refs.js +288 -0
  379. package/src/runtime/settings/registry.js +553 -0
  380. package/src/runtime/settings/resolve.js +713 -0
  381. package/src/runtime/settings/shared.js +37 -0
  382. package/src/runtime/settings/worker-billing.js +107 -0
  383. package/src/runtime/settings/write.js +269 -0
  384. package/src/runtime/slot-command.js +78 -0
  385. package/src/runtime/slots.js +671 -0
  386. package/src/runtime/source-version.js +1 -0
  387. package/src/runtime/state-root.js +217 -0
  388. package/src/runtime/storage/cli.js +12 -5
  389. package/src/runtime/storage/engine.js +9 -2
  390. package/src/runtime/storage/registry.js +14 -1
  391. package/src/runtime/storage/roots.js +66 -16
  392. package/src/runtime/storage/rules.js +82 -10
  393. package/src/runtime/storage/upkeep.js +10 -2
  394. package/src/runtime/storage/work-status.js +245 -26
  395. package/src/runtime/task-attempts.js +589 -69
  396. package/src/runtime/task-classifier.js +47 -11
  397. package/src/runtime/task-graph.js +373 -0
  398. package/src/runtime/task-run.js +778 -0
  399. package/src/runtime/task-scope.js +176 -55
  400. package/src/runtime/task-sources.js +147 -0
  401. package/src/runtime/task-state.js +374 -64
  402. package/src/runtime/team/admission.js +301 -0
  403. package/src/runtime/team/envelope.js +324 -0
  404. package/src/runtime/team/review-guard.js +156 -0
  405. package/src/runtime/trace/analyze.js +427 -0
  406. package/src/runtime/trace/baseline.js +770 -0
  407. package/src/runtime/trace/ledger.js +63 -140
  408. package/src/runtime/trace/otlp-export.js +568 -0
  409. package/src/runtime/trace/otlp-map.js +481 -0
  410. package/src/runtime/trace/spans.js +745 -0
  411. package/src/runtime/trace/telemetry.js +225 -0
  412. package/src/runtime/trace/views.js +1 -0
  413. package/src/runtime/transcripts/command.js +98 -0
  414. package/src/runtime/transcripts/cursor.js +326 -0
  415. package/src/runtime/transcripts/read.js +126 -0
  416. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  417. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  418. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  419. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  420. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  421. package/src/runtime/transcripts/registry.js +161 -0
  422. package/src/runtime/transcripts/stats.js +161 -0
  423. package/src/runtime/verification/check-key.js +628 -0
  424. package/src/runtime/verification/contract-runner.js +546 -11
  425. package/src/runtime/verification/engine.js +499 -9
  426. package/src/runtime/verification/impact.js +617 -0
  427. package/src/runtime/verification/inflight.js +205 -0
  428. package/src/runtime/verification/registry.js +176 -0
  429. package/src/runtime/verification/reuse.js +184 -0
  430. package/src/runtime/verification/telemetry-emit.js +254 -0
  431. package/src/runtime/verification/test-selection.js +67 -7
  432. package/src/runtime/worker/active.js +90 -0
  433. package/src/runtime/worker/cancel.js +222 -0
  434. package/src/runtime/worker/catalogue.js +122 -0
  435. package/src/runtime/worker/command.js +677 -0
  436. package/src/runtime/worker/evidence.js +288 -0
  437. package/src/runtime/worker/launch.js +288 -0
  438. package/src/runtime/worker/models.js +137 -0
  439. package/src/runtime/worker/parsers.js +218 -0
  440. package/src/runtime/worker/probes/index.js +706 -0
  441. package/src/runtime/worker/process-tree.js +415 -0
  442. package/src/runtime/worker/quota.js +43 -0
  443. package/src/runtime/worker/readiness.js +713 -0
  444. package/src/runtime/worker/run-store.js +166 -0
  445. package/src/runtime/worker/supervisor.js +541 -0
  446. package/src/runtime/worker/worktree-check.js +252 -0
  447. package/src/runtime/workflow-engine.js +5 -1
  448. package/src/runtime/workflow-orchestrator.js +578 -63
  449. package/src/runtime/worktree.js +149 -22
  450. package/src/state/index.js +1 -1
  451. package/src/state/lockfile.js +64 -10
  452. package/src/state/run-lock.js +1 -1
  453. package/types/node-commonjs.d.ts +106 -7
  454. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  455. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  456. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -10
  457. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  458. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -10
  459. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  460. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -10
  461. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  462. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  463. package/core/harnesses/gemini/hooks/session-start.sh +0 -7
  464. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  465. package/core/shared/guidance/FLAGS.md +0 -25
  466. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  467. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  468. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  469. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  470. package/src/adapters/gemini/hooks.js +0 -251
  471. package/src/adapters/gemini/index.js +0 -429
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * The roadmap autopilot kill switch (feature 108 IC-011, FR-016; decisions C9, C4, C20). It lives
5
+ * with the settings it reads, so the orchestrator and the roadmap loop share one reader without the
6
+ * orchestrator importing the loop.
7
+ */
8
+
9
+ const fs = require('node:fs');
10
+ const path = require('node:path');
11
+
12
+
13
+
14
+ /** `<config home>/autopilot/off`, or null with no config home (which already reads as off). */
15
+ function sentinelFile(env ) {
16
+ const { configHome } = require('../config-home.js');
17
+ const home = configHome(env).dir;
18
+ return home ? path.join(home, 'autopilot', 'off') : null;
19
+ }
20
+
21
+ /**
22
+ * Read fresh on every call (never memoised: a copied env defeats the resolver cache), so a switch
23
+ * set between two boundaries stops the next one. Any layer saying off wins and is named, in the
24
+ * order env (DOFLOW_AUTOPILOT_ENABLED), the `autopilot/off` sentinel, the settings file. The
25
+ * sentinel is stat'ed here: any error but ENOENT (EACCES, ENOTDIR) reads as present, because the
26
+ * resolver reads every stat error as absent. Absent, invalid or unreadable settings read as off.
27
+ */
28
+ function readKillSwitch(env = process.env, fsImpl = fs) {
29
+ const off = (layer ) => ({ enabled: false, switch: layer });
30
+ try {
31
+ const { loadSettings } = require('./resolve.js');
32
+ const resolution = loadSettings({ global: true, env: { ...env } }).get('autopilot.enabled', 'global');
33
+ if (resolution.candidates.some((c ) => c.layer === 'env' && c.value === 'off')) return off('env');
34
+ const file = sentinelFile(env);
35
+ if (file) {
36
+ try { fsImpl.statSync(file); return off('sentinel'); }
37
+ catch (error ) { if (error?.code !== 'ENOENT') return off('sentinel'); }
38
+ }
39
+ if (resolution.candidates.some((c ) => c.legacy && c.value === 'off')) return off('sentinel');
40
+ return resolution.value === 'on' ? { enabled: true, switch: null } : off('setting');
41
+ } catch {
42
+ return off('setting');
43
+ }
44
+ }
45
+
46
+ /** Seed writes require an independently verified durable off, so uncertainty refuses the write. */
47
+ function readSeedSwitch(env = process.env, fsImpl = fs) {
48
+ const refuse = () => ({ enabled: true, switch: null });
49
+ const off = (layer ) => ({ enabled: false, switch: layer });
50
+ try {
51
+ const { configHome } = require('../config-home.js');
52
+ const home = configHome(env).dir;
53
+ if (!home) return refuse();
54
+
55
+ const settingsEnv = { ...env };
56
+ delete settingsEnv.DOFLOW_AUTOPILOT_ENABLED;
57
+ const { loadSettings } = require('./resolve.js');
58
+ const settings = loadSettings({ global: true, env: settingsEnv, fsImpl });
59
+ const resolution = settings.get('autopilot.enabled', 'global');
60
+ if (resolution.state === 'invalid' || resolution.candidates.some((candidate ) => candidate.status === 'invalid')) {
61
+ return refuse();
62
+ }
63
+ if (settings.errors.some((entry ) => entry.key === 'autopilot.enabled' || entry.key === null)) {
64
+ return refuse();
65
+ }
66
+
67
+ const file = path.join(home, 'autopilot', 'off');
68
+ try {
69
+ fsImpl.statSync(file);
70
+ return off('sentinel');
71
+ } catch (error ) {
72
+ if (error?.code !== 'ENOENT') return off('sentinel');
73
+ }
74
+
75
+ const legacyOff = resolution.candidates.some((candidate ) => candidate.legacy && candidate.value === 'off');
76
+ if (resolution.value === 'off' || legacyOff) return off('setting');
77
+ return refuse();
78
+ } catch {
79
+ return refuse();
80
+ }
81
+ }
82
+
83
+ /**
84
+ * maint-thin: whether a review is unattended, so the class seat floor binds. Fail closed: only a verifiably off
85
+ * switch (the seed reader: a resolved config home whose setting or sentinel says off) reads as attended. An uncertain
86
+ * switch, unreadable settings or no config home count as unattended. The one other attended case is an explicit,
87
+ * process-local `DOFLOW_AUTOPILOT_ENABLED=off`: a caller can always lower its own run that way, and that costs nothing,
88
+ * because roadmap gate-b judges the recorded seats against the class floor itself and denies too few.
89
+ */
90
+ function reviewUnattended(env = process.env, fsImpl = fs) {
91
+ if (env?.DOFLOW_AUTOPILOT_ENABLED === 'off') return false;
92
+ return readSeedSwitch(env, fsImpl).enabled !== false;
93
+ }
94
+
95
+ /** Tripwire (narrowing only): writes the kill-switch sentinel; only a person removes it. */
96
+ function tripSentinel(env , line , fsImpl = fs) {
97
+ const file = sentinelFile(env);
98
+ // No config home already reads as off (needsConfigHome), so there is nothing to narrow.
99
+ if (!file) return false;
100
+ fsImpl.mkdirSync(path.dirname(file), { recursive: true });
101
+ try { fsImpl.writeFileSync(file, `${line}\n`, { flag: 'wx', mode: 0o600 }); }
102
+ catch (error ) { if (error.code !== 'EEXIST') throw error; }
103
+ return true;
104
+ }
105
+
106
+ module.exports = { readKillSwitch, readSeedSwitch, reviewUnattended, tripSentinel };
@@ -0,0 +1,280 @@
1
+ 'use strict';
2
+
3
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
4
+
5
+ const path = require('node:path');
6
+ const fs = require('node:fs');
7
+ const { configHome } = require('../config-home.js');
8
+ const { finishRuntime, usageError } = require('../cli-result.js');
9
+ const { REPO_ROOT } = require('../../helper/repo-root.js');
10
+ const { loadSettingsRegistry, REGISTRY_FILE } = require('./registry.js');
11
+ const { loadSettings } = require('./resolve.js');
12
+ const { maskUrl } = require('./shared.js');
13
+
14
+ function safeValue(value , meta ) {
15
+ return meta?.type === 'url' && typeof value === 'string' ? maskUrl(value) : value;
16
+ }
17
+
18
+ function safeResolution(resolution ) {
19
+ const meta = resolution?.meta || {};
20
+ return {
21
+ ...resolution,
22
+ value: safeValue(resolution.value, meta),
23
+ origin: resolution.origin ? { ...resolution.origin } : resolution.origin,
24
+ candidates: (resolution.candidates || []).map((candidate ) => ({
25
+ ...candidate,
26
+ value: safeValue(candidate.value, meta),
27
+ display: meta.type === 'url' && typeof candidate.display === 'string'
28
+ ? maskUrl(candidate.display) : candidate.display,
29
+ })),
30
+ meta: { ...meta, default: safeValue(meta.default, meta) },
31
+ };
32
+ }
33
+
34
+ function safeReport(report ) {
35
+ const keys = {};
36
+ for (const [key, value] of Object.entries(report.keys || {})) {
37
+ if (value && typeof value === 'object' && !('key' in value)
38
+ && 'project' in value && 'global' in value) {
39
+ keys[key] = { project: safeResolution((value ).project), global: safeResolution((value ).global) };
40
+ } else {
41
+ keys[key] = safeResolution(value);
42
+ }
43
+ }
44
+ return { ...report, keys };
45
+ }
46
+
47
+ /** The settings-only part of doctor output; values are omitted, while present files and faults remain. */
48
+ function settingsReport(view ) {
49
+ const report = view.report();
50
+ return {
51
+ schema: 1,
52
+ scope: report.scope,
53
+ configHome: report.configHome,
54
+ project: report.project,
55
+ files: report.files,
56
+ errors: report.errors,
57
+ notes: report.notes,
58
+ };
59
+ }
60
+
61
+ function buildSettingsReport({ repoRoot = REPO_ROOT, projectRoot = process.cwd(), global = false,
62
+ env = process.env, fsImpl = fs } = {}) {
63
+ const loaded = loadSettingsRegistry({ repoRoot, fsImpl });
64
+ if (!loaded.ok) {
65
+ const home = configHome(env);
66
+ return {
67
+ schema: 1,
68
+ scope: global ? 'global' : 'project',
69
+ configHome: { dir: home.dir, ignored: [...home.ignored] },
70
+ project: { root: global ? null : path.resolve(projectRoot), layersFrom: null, checkout: null },
71
+ files: [],
72
+ errors: [{ key: null, layer: 'default', source: path.join(repoRoot, REGISTRY_FILE), legacy: false,
73
+ code: 'settings-registry-invalid', reason: loaded.detail, offset: null }],
74
+ notes: [],
75
+ };
76
+ }
77
+ try {
78
+ const view = loadSettings({ projectRoot, global, env, fsImpl, registry: loaded.registry });
79
+ return settingsReport(view);
80
+ } catch (error ) {
81
+ const home = configHome(env);
82
+ return {
83
+ schema: 1,
84
+ scope: global ? 'global' : 'project',
85
+ configHome: { dir: home.dir, ignored: [...home.ignored] },
86
+ project: { root: global ? null : path.resolve(projectRoot), layersFrom: null, checkout: null },
87
+ files: [],
88
+ errors: [{ key: null, layer: 'default', source: path.join(repoRoot, REGISTRY_FILE), legacy: false,
89
+ code: 'settings-unavailable', reason: error?.message || String(error), offset: null }],
90
+ notes: [],
91
+ };
92
+ }
93
+ }
94
+
95
+ function settingValue(value , meta ) {
96
+ const safe = safeValue(value, meta);
97
+ if (safe === null || safe === undefined) return '(none)';
98
+ if (typeof safe === 'string') return JSON.stringify(safe);
99
+ return JSON.stringify(safe);
100
+ }
101
+
102
+ function originLabel(resolution ) {
103
+ const { origin } = resolution;
104
+ const source = origin.source || (origin.via === 'no-config-home' ? 'no config home' : REGISTRY_FILE);
105
+ return `${origin.layer}: ${source}`;
106
+ }
107
+
108
+ function printResolution(key , resolution , showOrigin , suffix = '') {
109
+ if (resolution.meta?.needsConfigHome && resolution.origin?.via === 'no-config-home') {
110
+ console.log(`${key}${suffix} = ${settingValue(resolution.value, resolution.meta)} (no config home: capture skipped)`);
111
+ } else {
112
+ const origin = showOrigin ? ` (${originLabel(resolution)})` : '';
113
+ console.log(`${key}${suffix} = ${settingValue(resolution.value, resolution.meta)}${origin}`);
114
+ }
115
+ if (!showOrigin) return;
116
+ for (const candidate of resolution.candidates || []) {
117
+ const display = typeof candidate.display === 'string' && candidate.display !== '' ? candidate.display : '(none)';
118
+ const reason = candidate.reason ? `: ${candidate.reason}` : '';
119
+ console.log(` ${candidate.layer} ${candidate.source}: ${display} — ${candidate.status}${reason}`);
120
+ }
121
+ }
122
+
123
+ function printSettingsList(report , showOrigin ) {
124
+ const home = report.configHome;
125
+ const ignored = home.ignored || [];
126
+ const homeLabel = home.dir
127
+ ? `${home.dir}${ignored.length ? ` | ${ignored.join(', ')} ignored` : ''}`
128
+ : `none${ignored.length ? ` (${ignored.join(', ')} ignored)` : ''}`;
129
+ console.log(`config home: ${homeLabel}`);
130
+ for (const name of ignored) console.log(`note: ignored relative ${name}`);
131
+ const project = report.project;
132
+ console.log(`project: ${project.root || '(none)'}${project.checkout ? ` (${project.checkout})` : ''}`);
133
+
134
+ for (const [key, value] of Object.entries(report.keys || {})) {
135
+ const dualView = value && typeof value === 'object' && !('key' in (value ))
136
+ && 'project' in (value ) && 'global' in (value )
137
+ && Array.isArray((value ).project?.meta?.views) && (value ).project.meta.views.includes('global');
138
+ if (dualView) {
139
+ printResolution(key, (value ).project, showOrigin, ' [project roots]');
140
+ printResolution(key, (value ).global, showOrigin, ' [user roots]');
141
+ } else {
142
+ const views = (value )?.meta?.views;
143
+ const suffix = Array.isArray(views) && views.includes('global')
144
+ ? ((value ).view === 'global' ? ' [user roots]' : ' [project roots]')
145
+ : '';
146
+ printResolution(key, value, showOrigin, suffix);
147
+ }
148
+ }
149
+ for (const error of report.errors || []) {
150
+ console.log(`error: ${error.key || 'settings'} (${error.layer}: ${error.source}): ${error.reason}`);
151
+ }
152
+ for (const note of report.notes || []) console.log(`note: ${note.text}`);
153
+ }
154
+
155
+ function securityFault(report ) {
156
+ const check = (resolution ) => {
157
+ if (resolution && resolution.meta?.securityRelevant
158
+ && ['fail-safe', 'cross-key'].includes(resolution.origin?.via)) return true;
159
+ if (resolution && typeof resolution === 'object' && 'project' in resolution && 'global' in resolution) {
160
+ return check(resolution.project) || check(resolution.global);
161
+ }
162
+ return false;
163
+ };
164
+ return Object.values(report.keys || {}).some(check);
165
+ }
166
+
167
+ const CONFIG_ACTIONS = ['list', 'schema', 'validate', 'set', 'unset'];
168
+ const CONFIG_LAYERS = ['user', 'project', 'local'];
169
+ /** Positional words after the action: the key and, for validate and set, a JSON value. */
170
+ const CONFIG_OPERANDS = { schema: 0, validate: 2, set: 2, unset: 1 };
171
+
172
+
173
+
174
+ /** Splits `config [list] [path] | schema | validate <key> <value> | set <key> <value> | unset <key>` and its flags. */
175
+ function configArguments(positional , { layer, global, showOrigin, preparedRun } ) {
176
+ const args = Array.isArray(positional) ? [...positional] : [];
177
+ const fail = (error ) => ({ action: 'list', project: null, key: null, valueText: null, error });
178
+ let action = 'list';
179
+ if (CONFIG_ACTIONS.includes(args[0])) action = args.shift();
180
+ else if (args.length === 1 && !args[0].includes(path.sep) && !fs.existsSync(args[0])) {
181
+ return fail(`unknown action '${args[0]}'; expected ${CONFIG_ACTIONS.join(', ')}`);
182
+ }
183
+ if (layer !== undefined && !CONFIG_LAYERS.includes(layer)) return fail(`--layer must be one of ${CONFIG_LAYERS.join(', ')}`);
184
+ if (action === 'list') {
185
+ if (args.length > 1) return fail('expected config [list] [project path]');
186
+ if (layer !== undefined) return fail('--layer is only for validate, set and unset');
187
+ if (preparedRun !== undefined) return fail('--prepared-run is only for config validate');
188
+ return { action, project: args[0] || null, key: null, valueText: null, error: null };
189
+ }
190
+ if (showOrigin) return fail('--show-origin is only for config list');
191
+ if (global) return fail(`-g is not for config ${action}`);
192
+ if (action === 'schema' && layer !== undefined) return fail('--layer is only for validate, set and unset');
193
+ if (preparedRun !== undefined) {
194
+ if (action !== 'validate') return fail('--prepared-run is only for config validate');
195
+ if (args.length) return fail('config validate --prepared-run <file> takes no key or value');
196
+ if (layer !== undefined) return fail('--layer is not for config validate --prepared-run (its settings are judged at the project layer)');
197
+ return { action, project: null, key: null, valueText: null, error: null };
198
+ }
199
+ const want = CONFIG_OPERANDS[action];
200
+ if (args.length !== want) {
201
+ const usage = { schema: 'config schema', validate: 'config validate <key> <json-value> [--layer user|project|local] | config validate --prepared-run <file>',
202
+ set: 'config set <key> <json-value> --layer user|project|local', unset: 'config unset <key> --layer user|project|local' }[action];
203
+ return fail(`expected ${usage}`);
204
+ }
205
+ if ((action === 'set' || action === 'unset') && layer === undefined) return fail(`config ${action} needs --layer user|project|local`);
206
+ return { action, project: null, key: args[0] ?? null, valueText: args[1] ?? null, error: null };
207
+ }
208
+
209
+ function handleConfigCommand({ json = false, global = false, showOrigin = false, positional = [], layer, preparedRun,
210
+ projectRoot, repoRoot = REPO_ROOT, env = process.env, fsImpl = fs } = {}) {
211
+ const args = configArguments(positional, { layer, global, showOrigin, preparedRun });
212
+ if (args.error) return usageError('config', args.error, json);
213
+ const loaded = loadSettingsRegistry({ repoRoot, fsImpl });
214
+ if (!loaded.ok) {
215
+ const detail = loaded.detail || 'settings registry is invalid';
216
+ if (json) console.log(JSON.stringify({ ok: false, status: 'ERROR', exitCode: 2,
217
+ error: 'settings-registry-invalid', detail }, null, 2));
218
+ else console.error(`doflow config: settings registry unavailable: ${detail}`);
219
+ return finishRuntime(2);
220
+ }
221
+
222
+ if (preparedRun !== undefined) {
223
+ return require('./prepared-run.js').handlePreparedRun({
224
+ file: preparedRun, json, registry: loaded.registry, repoRoot, projectRoot: projectRoot || process.cwd(), env, fsImpl,
225
+ });
226
+ }
227
+
228
+ if (args.action !== 'list') {
229
+ // loaded on demand: the writer and the protocol registry stay off the read-only list path
230
+ return require('./config-write.js').handleConfigAction({
231
+ action: args.action, key: args.key, valueText: args.valueText, layer, json, registry: loaded.registry,
232
+ repoRoot, projectRoot: projectRoot || process.cwd(), env, fsImpl,
233
+ });
234
+ }
235
+
236
+ try {
237
+ const root = global ? null : path.resolve(args.project || projectRoot || process.cwd());
238
+ const view = loadSettings({ projectRoot: root, global, env, fsImpl, registry: loaded.registry });
239
+ const report = safeReport(view.report());
240
+ if (json) console.log(JSON.stringify(report, null, 2));
241
+ else printSettingsList(report, showOrigin);
242
+ return finishRuntime(securityFault(report) ? 1 : 0);
243
+ } catch (error ) {
244
+ const detail = error?.message || String(error);
245
+ if (json) console.log(JSON.stringify({ ok: false, status: 'ERROR', exitCode: 2,
246
+ error: 'settings-registry-invalid', detail }, null, 2));
247
+ else console.error(`doflow config: settings registry unavailable: ${detail}`);
248
+ return finishRuntime(2);
249
+ }
250
+ }
251
+
252
+ function printSettingsReport(report ) {
253
+ console.log('\n[Settings]');
254
+ console.log(` config home: ${report.configHome.dir || 'none'}`);
255
+ for (const name of report.configHome.ignored || []) {
256
+ console.log(` ignored relative ${name} (ignored)`);
257
+ }
258
+ if (report.project.root) {
259
+ console.log(` project: ${report.project.root}${report.project.checkout ? ` (${report.project.checkout})` : ''}`);
260
+ }
261
+ const present = (report.files || []).filter((file ) => file.status !== 'absent');
262
+ if (!present.length) console.log(' files: none');
263
+ for (const file of present) {
264
+ const deprecated = file.kind === 'legacy' ? ' (deprecated)' : '';
265
+ console.log(` ${file.layer} ${file.path}: ${file.status}${deprecated}`);
266
+ }
267
+ for (const note of report.notes || []) console.log(` note: ${note.text}`);
268
+ for (const error of report.errors || []) {
269
+ console.log(` error: ${error.key || 'settings'} (${error.layer}: ${error.source}): ${error.reason}`);
270
+ }
271
+ }
272
+
273
+ module.exports = {
274
+ maskUrl,
275
+ safeReport,
276
+ settingsReport,
277
+ buildSettingsReport,
278
+ printSettingsReport,
279
+ handleConfigCommand,
280
+ };