@khoavu882/doflow 0.0.0-stage → 2.0.0-beta.4

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 (409) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -2
  3. package/bin/doflow.js +44 -0
  4. package/core/.antigravity-plugin/hooks.json +39 -0
  5. package/core/.antigravity-plugin/mcp_config.json +18 -0
  6. package/core/.antigravity-plugin/plugin.json +31 -0
  7. package/core/.claude-plugin/marketplace.json +20 -0
  8. package/core/.claude-plugin/plugin.json +21 -0
  9. package/core/.codex-plugin/marketplace.json +20 -0
  10. package/core/.codex-plugin/plugin.json +35 -0
  11. package/core/.plugin/plugin.json +19 -0
  12. package/core/harnesses/antigravity/hooks/pre-implementation-gate.sh +9 -0
  13. package/core/harnesses/antigravity/hooks/stop-check.sh +10 -0
  14. package/core/harnesses/claude/hooks/lib.sh +304 -0
  15. package/core/harnesses/claude/hooks/mcp-tool-guard.sh +20 -0
  16. package/core/harnesses/claude/hooks/permission-audit.sh +47 -0
  17. package/core/harnesses/claude/hooks/post-compact.sh +74 -0
  18. package/core/harnesses/claude/hooks/post-edit-lint.sh +36 -0
  19. package/core/harnesses/claude/hooks/post-tool-failure.sh +47 -0
  20. package/core/harnesses/claude/hooks/pre-bash-guard.sh +20 -0
  21. package/core/harnesses/claude/hooks/pre-compact.sh +43 -0
  22. package/core/harnesses/claude/hooks/pre-implement-gate.sh +21 -0
  23. package/core/harnesses/claude/hooks/session-end.sh +89 -0
  24. package/core/harnesses/claude/hooks/session-start.sh +5 -0
  25. package/core/harnesses/claude/hooks/skill-config-audit.sh +39 -0
  26. package/core/harnesses/claude/hooks/stop-check.sh +5 -0
  27. package/core/harnesses/claude/hooks/subagent-audit.sh +7 -0
  28. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -0
  29. package/core/harnesses/claude/settings/keybindings.json +20 -0
  30. package/core/harnesses/claude/settings/settings.json +201 -0
  31. package/core/harnesses/claude/statusline/doflow-statusline.sh +49 -0
  32. package/core/harnesses/codex/agents/core-implementer.toml +7 -0
  33. package/core/harnesses/codex/agents/quality-guardian.toml +8 -0
  34. package/core/harnesses/codex/agents/research-writer.toml +8 -0
  35. package/core/harnesses/codex/agents/spec-analyst.toml +8 -0
  36. package/core/harnesses/codex/agents/system-architect.toml +9 -0
  37. package/core/harnesses/codex/config/config.toml +10 -0
  38. package/core/harnesses/codex/hooks/hooks.json +122 -0
  39. package/core/harnesses/codex/hooks/lib.sh +335 -0
  40. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +18 -0
  41. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +52 -0
  42. package/core/harnesses/codex/hooks/post-edit-lint.sh +6 -0
  43. package/core/harnesses/codex/hooks/pre-bash-guard.sh +18 -0
  44. package/core/harnesses/codex/hooks/pre-compact.impl.sh +46 -0
  45. package/core/harnesses/codex/hooks/pre-compact.sh +9 -0
  46. package/core/harnesses/codex/hooks/pre-implement-gate.sh +19 -0
  47. package/core/harnesses/codex/hooks/session-end.impl.sh +92 -0
  48. package/core/harnesses/codex/hooks/session-end.sh +5 -0
  49. package/core/harnesses/codex/hooks/session-start.sh +5 -0
  50. package/core/harnesses/codex/hooks/stop-check.sh +8 -0
  51. package/core/harnesses/codex/hooks/subagent-audit.sh +8 -0
  52. package/core/harnesses/codex/hooks/user-prompt-submit.sh +6 -0
  53. package/core/harnesses/gemini/hooks/hooks.json +77 -0
  54. package/core/harnesses/gemini/hooks/lib.sh +302 -0
  55. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +21 -0
  56. package/core/harnesses/gemini/hooks/post-edit-lint.sh +39 -0
  57. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +21 -0
  58. package/core/harnesses/gemini/hooks/pre-compact.sh +38 -0
  59. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +22 -0
  60. package/core/harnesses/gemini/hooks/session-end.impl.sh +89 -0
  61. package/core/harnesses/gemini/hooks/session-end.sh +5 -0
  62. package/core/harnesses/gemini/hooks/session-start.sh +5 -0
  63. package/core/harnesses/gemini/settings/adapter-defaults.json +4 -0
  64. package/core/harnesses/kiro/agents/doflow.json +58 -0
  65. package/core/harnesses/kiro/hooks/doflow.json +53 -0
  66. package/core/harnesses/kiro/hooks/lib.sh +324 -0
  67. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +9 -0
  68. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +9 -0
  69. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +9 -0
  70. package/core/harnesses/kiro/hooks/session-start.sh +9 -0
  71. package/core/harnesses/kiro/hooks/stop-check.sh +43 -0
  72. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +39 -0
  73. package/core/harnesses/shared/hooks/adapters/antigravity.js +111 -0
  74. package/core/harnesses/shared/hooks/adapters/arg-fields.js +19 -0
  75. package/core/harnesses/shared/hooks/adapters/gemini.js +114 -0
  76. package/core/harnesses/shared/hooks/hooks.json +47 -0
  77. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +91 -0
  78. package/core/harnesses/shared/hooks/policies/capture-failure.sh +97 -0
  79. package/core/harnesses/shared/hooks/policies/deny-json.sh +29 -0
  80. package/core/harnesses/shared/hooks/policies/lib.sh +501 -0
  81. package/core/harnesses/shared/hooks/policies/mcp-policy.conf +21 -0
  82. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +91 -0
  83. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +328 -0
  84. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +496 -0
  85. package/core/harnesses/shared/hooks/policies/prompt-nudge.jq +131 -0
  86. package/core/harnesses/shared/hooks/policies/session-context.sh +141 -0
  87. package/core/harnesses/shared/hooks/policies/stop-check.sh +264 -0
  88. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +46 -0
  89. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +235 -0
  90. package/core/harnesses/shared/hooks/stream-hook-runner.js +590 -0
  91. package/core/harnesses/shared/locator/doflow-run +87 -0
  92. package/core/registry/advice.json +101 -0
  93. package/core/registry/assets.json +792 -0
  94. package/core/registry/capabilities.json +120 -0
  95. package/core/registry/contracts.json +189 -0
  96. package/core/registry/external-tools.json +191 -0
  97. package/core/registry/harnesses.json +2062 -0
  98. package/core/registry/lifecycle.json +231 -0
  99. package/core/registry/mcp.json +18 -0
  100. package/core/registry/models.json +79 -0
  101. package/core/registry/readiness-templates.json +118 -0
  102. package/core/registry/routes.json +47 -0
  103. package/core/registry/storage.json +1061 -0
  104. package/core/registry/verification.json +258 -0
  105. package/core/registry/workflows.json +790 -0
  106. package/core/shared/agent-specs/core-implementer.md +73 -0
  107. package/core/shared/agent-specs/quality-guardian.md +28 -0
  108. package/core/shared/agent-specs/research-writer.md +31 -0
  109. package/core/shared/agent-specs/spec-analyst.md +33 -0
  110. package/core/shared/agent-specs/system-architect.md +29 -0
  111. package/core/shared/guidance/DOFLOW_CORE.md +8 -0
  112. package/core/shared/guidance/FLAGS.md +25 -0
  113. package/core/shared/guidance/PRINCIPLES.md +61 -0
  114. package/core/shared/guidance/VERSION +1 -0
  115. package/core/shared/guidance/mcp/MCP_Context7.md +18 -0
  116. package/core/shared/guidance/mcp/MCP_Sequential.md +17 -0
  117. package/core/shared/guidance/modes/MODE_Brainstorming.md +46 -0
  118. package/core/shared/guidance/modes/MODE_DeepResearch.md +69 -0
  119. package/core/shared/guidance/modes/MODE_Introspection.md +33 -0
  120. package/core/shared/guidance/modes/MODE_Orchestration.md +57 -0
  121. package/core/shared/guidance/modes/MODE_Task_Management.md +74 -0
  122. package/core/shared/guidance/pointers/claude-gemini.md +2 -0
  123. package/core/shared/guidance/pointers/codex.md +6 -0
  124. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +373 -0
  125. package/core/shared/guidance/references/ARTIFACT_VOICE.md +104 -0
  126. package/core/shared/guidance/references/CONSTITUTION_BASE.md +47 -0
  127. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +161 -0
  128. package/core/shared/guidance/references/DOFLOW_CHAIN.md +87 -0
  129. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +93 -0
  130. package/core/shared/guidance/references/MODEL_SELECTION.md +74 -0
  131. package/core/shared/guidance/references/ORCHESTRATION.md +36 -0
  132. package/core/shared/guidance/references/RESEARCH_CONFIG.md +21 -0
  133. package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +81 -0
  134. package/core/shared/guidance/rules/RULE_01_SAFETY.md +25 -0
  135. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +23 -0
  136. package/core/shared/guidance/rules/RULE_03_QUALITY.md +14 -0
  137. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +46 -0
  138. package/core/shared/scripts/doflow/assets/mermaid-theme.json +46 -0
  139. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +167 -0
  140. package/core/shared/scripts/doflow/bash/do-git-state.sh +546 -0
  141. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +208 -0
  142. package/core/shared/scripts/doflow/bash/do-paths.sh +347 -0
  143. package/core/shared/scripts/doflow/bash/do-prereqs.sh +66 -0
  144. package/core/shared/scripts/doflow/bash/do-review-package.sh +127 -0
  145. package/core/shared/scripts/doflow/bash/do-task-brief.sh +698 -0
  146. package/core/shared/scripts/doflow/bash/render-audit.sh +224 -0
  147. package/core/shared/scripts/doflow/bash/render-diagrams.sh +177 -0
  148. package/core/shared/scripts/doflow/bash/render-puml.sh +223 -0
  149. package/core/shared/scripts/doflow/bash/sync-context.sh +66 -0
  150. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +526 -0
  151. package/core/shared/scripts/doflow/bin/doflow-run +592 -0
  152. package/core/shared/skills/do/SKILL.md +128 -0
  153. package/core/shared/skills/do/references/estimation.md +13 -0
  154. package/core/shared/skills/do/references/pm_routing.md +25 -0
  155. package/core/shared/skills/do/references/tool_matrix.md +52 -0
  156. package/core/shared/skills/do-brainstorm/SKILL.md +252 -0
  157. package/core/shared/skills/do-code-review/README.md +49 -0
  158. package/core/shared/skills/do-code-review/SKILL.md +333 -0
  159. package/core/shared/skills/do-code-review/assets/sample_c_clean.c +71 -0
  160. package/core/shared/skills/do-code-review/assets/sample_c_smells.c +66 -0
  161. package/core/shared/skills/do-code-review/assets/sample_cpp_shift.cpp +19 -0
  162. package/core/shared/skills/do-code-review/assets/sample_csharp_clean.cs +100 -0
  163. package/core/shared/skills/do-code-review/assets/sample_csharp_smells.cs +78 -0
  164. package/core/shared/skills/do-code-review/assets/sample_java_clean.java +55 -0
  165. package/core/shared/skills/do-code-review/assets/sample_java_smells.java +56 -0
  166. package/core/shared/skills/do-code-review/assets/sample_json_clean.json +7 -0
  167. package/core/shared/skills/do-code-review/assets/sample_markdown_clean.md +30 -0
  168. package/core/shared/skills/do-code-review/assets/sample_markdown_smells.md +29 -0
  169. package/core/shared/skills/do-code-review/assets/sample_shell_heredoc.sh +38 -0
  170. package/core/shared/skills/do-code-review/assets/sample_shell_smells.sh +15 -0
  171. package/core/shared/skills/do-code-review/assets/sample_typescript_strings.ts +36 -0
  172. package/core/shared/skills/do-code-review/assets/sample_yaml_smells.yaml +6 -0
  173. package/core/shared/skills/do-code-review/content-types/config.md +83 -0
  174. package/core/shared/skills/do-code-review/content-types/markdown.md +132 -0
  175. package/core/shared/skills/do-code-review/expected_outputs/sample_c_clean_quality.json +79 -0
  176. package/core/shared/skills/do-code-review/expected_outputs/sample_c_smells_quality.json +169 -0
  177. package/core/shared/skills/do-code-review/expected_outputs/sample_cpp_shift_quality.json +49 -0
  178. package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_clean_quality.json +149 -0
  179. package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_smells_quality.json +157 -0
  180. package/core/shared/skills/do-code-review/expected_outputs/sample_java_clean_quality.json +67 -0
  181. package/core/shared/skills/do-code-review/expected_outputs/sample_java_smells_quality.json +97 -0
  182. package/core/shared/skills/do-code-review/expected_outputs/sample_json_clean_quality.json +33 -0
  183. package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_clean_quality.json +1 -0
  184. package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_smells_quality.json +16 -0
  185. package/core/shared/skills/do-code-review/expected_outputs/sample_shell_heredoc_quality.json +54 -0
  186. package/core/shared/skills/do-code-review/expected_outputs/sample_shell_smells_quality.json +91 -0
  187. package/core/shared/skills/do-code-review/expected_outputs/sample_typescript_strings_quality.json +60 -0
  188. package/core/shared/skills/do-code-review/expected_outputs/sample_yaml_smells_quality.json +46 -0
  189. package/core/shared/skills/do-code-review/languages/c.md +103 -0
  190. package/core/shared/skills/do-code-review/languages/cpp.md +103 -0
  191. package/core/shared/skills/do-code-review/languages/csharp.md +97 -0
  192. package/core/shared/skills/do-code-review/languages/dart.md +108 -0
  193. package/core/shared/skills/do-code-review/languages/go.md +92 -0
  194. package/core/shared/skills/do-code-review/languages/java.md +103 -0
  195. package/core/shared/skills/do-code-review/languages/kotlin.md +88 -0
  196. package/core/shared/skills/do-code-review/languages/php.md +109 -0
  197. package/core/shared/skills/do-code-review/languages/python.md +94 -0
  198. package/core/shared/skills/do-code-review/languages/ruby.md +105 -0
  199. package/core/shared/skills/do-code-review/languages/rust.md +99 -0
  200. package/core/shared/skills/do-code-review/languages/shell.md +90 -0
  201. package/core/shared/skills/do-code-review/languages/swift.md +88 -0
  202. package/core/shared/skills/do-code-review/languages/typescript.md +97 -0
  203. package/core/shared/skills/do-code-review/review-policy.json +47 -0
  204. package/core/shared/skills/do-code-review/rules/universal.md +49 -0
  205. package/core/shared/skills/do-code-review/scripts/code_quality_checker.py +1696 -0
  206. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +532 -0
  207. package/core/shared/skills/do-code-review/scripts/pr_analyzer.py +620 -0
  208. package/core/shared/skills/do-code-review/scripts/review_report_generator.py +505 -0
  209. package/core/shared/skills/do-constitution/SKILL.md +72 -0
  210. package/core/shared/skills/do-design/SKILL.md +212 -0
  211. package/core/shared/skills/do-diagnose/SKILL.md +156 -0
  212. package/core/shared/skills/do-diagnose/references/code_audit.md +15 -0
  213. package/core/shared/skills/do-diagnose/references/refactoring.md +12 -0
  214. package/core/shared/skills/do-diagnose/references/root_cause.md +17 -0
  215. package/core/shared/skills/do-document/SKILL.md +81 -0
  216. package/core/shared/skills/do-document/references/api-reference.md +42 -0
  217. package/core/shared/skills/do-document/references/deep_research.md +18 -0
  218. package/core/shared/skills/do-document/references/embedded-research.md +11 -0
  219. package/core/shared/skills/do-document/references/implementation-flow.md +105 -0
  220. package/core/shared/skills/do-document/references/index_generator.md +9 -0
  221. package/core/shared/skills/do-document/references/user-guide.md +22 -0
  222. package/core/shared/skills/do-execute-plan/SKILL.md +261 -0
  223. package/core/shared/skills/do-execute-plan/references/handoff_record.md +57 -0
  224. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +92 -0
  225. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +155 -0
  226. package/core/shared/skills/do-execute-plan/references/run_position.md +63 -0
  227. package/core/shared/skills/do-execute-plan/references/scaffold.md +441 -0
  228. package/core/shared/skills/do-execute-plan/references/task_attempts.md +41 -0
  229. package/core/shared/skills/do-flow/SKILL.md +186 -0
  230. package/core/shared/skills/do-flow/references/task_classes.md +134 -0
  231. package/core/shared/skills/do-git/SKILL.md +115 -0
  232. package/core/shared/skills/do-git/references/hotfix-ritual.md +44 -0
  233. package/core/shared/skills/do-git/references/lifecycle-policy.md +54 -0
  234. package/core/shared/skills/do-git/references/release-ritual.md +64 -0
  235. package/core/shared/skills/do-implement/SKILL.md +222 -0
  236. package/core/shared/skills/do-plan/SKILL.md +219 -0
  237. package/core/shared/skills/do-test/SKILL.md +113 -0
  238. package/core/shared/templates/doflow/constitution-template.md +28 -0
  239. package/core/shared/templates/doflow/data-model-template.md +169 -0
  240. package/core/shared/templates/doflow/design-template.md +193 -0
  241. package/core/shared/templates/doflow/external-contract-template.md +35 -0
  242. package/core/shared/templates/doflow/intent-template.md +45 -0
  243. package/core/shared/templates/doflow/plan-template.md +151 -0
  244. package/core/shared/templates/doflow/question-log-template.md +51 -0
  245. package/core/shared/templates/doflow/requirement-template.md +126 -0
  246. package/core/shared/templates/doflow/specs-template.md +55 -0
  247. package/core/shared/templates/doflow/state-template.md +59 -0
  248. package/core/shared/workflows/do-flow-chain.md +17 -0
  249. package/package.json +48 -4
  250. package/src/adapters/antigravity/index.js +631 -0
  251. package/src/adapters/claude/index.js +548 -0
  252. package/src/adapters/claude/mcp.js +94 -0
  253. package/src/adapters/codex/agents.js +208 -0
  254. package/src/adapters/codex/config.js +272 -0
  255. package/src/adapters/codex/hooks.js +203 -0
  256. package/src/adapters/codex/index.js +707 -0
  257. package/src/adapters/codex/mcp.js +271 -0
  258. package/src/adapters/codex/native-projection.js +34 -0
  259. package/src/adapters/copilot/index.js +413 -0
  260. package/src/adapters/copy-tree.js +620 -0
  261. package/src/adapters/gemini/hooks.js +210 -0
  262. package/src/adapters/gemini/index.js +390 -0
  263. package/src/adapters/hook-commands.js +60 -0
  264. package/src/adapters/index.js +106 -0
  265. package/src/adapters/kiro/index.js +310 -0
  266. package/src/adapters/mcp-entries.js +331 -0
  267. package/src/adapters/opencode/index.js +466 -0
  268. package/src/adapters/pi/index.js +279 -0
  269. package/src/adapters/pi/json-members.js +185 -0
  270. package/src/adapters/pi/mcp.js +373 -0
  271. package/src/adapters/resolve-source.js +19 -0
  272. package/src/cli/commands/install.js +218 -0
  273. package/src/cli/commands/list-backups.js +21 -0
  274. package/src/cli/commands/reconcile.js +120 -0
  275. package/src/cli/commands/remove.js +82 -0
  276. package/src/cli/commands/rollback.js +172 -0
  277. package/src/cli/commands/self-update.js +33 -0
  278. package/src/cli/commands/status.js +138 -0
  279. package/src/cli/commands/tools.js +92 -0
  280. package/src/cli/commands/update.js +162 -0
  281. package/src/cli/index.js +568 -0
  282. package/src/cli/runtime-commands.js +281 -0
  283. package/src/cli/shared.js +218 -0
  284. package/src/helper/bash-helper.js +34 -0
  285. package/src/helper/git.js +24 -0
  286. package/src/helper/guardrails.js +49 -0
  287. package/src/helper/harness-paths.js +140 -0
  288. package/src/helper/marker-merge.js +116 -0
  289. package/src/helper/prompt.js +61 -0
  290. package/src/helper/repo-root.js +29 -0
  291. package/src/helper/settings-merge.js +151 -0
  292. package/src/helper/settings-scope.js +33 -0
  293. package/src/helper/toml.js +244 -0
  294. package/src/install/backup-set.js +149 -0
  295. package/src/install/backup.js +724 -0
  296. package/src/install/context.js +58 -0
  297. package/src/install/manifest.js +145 -0
  298. package/src/install/mcp.js +254 -0
  299. package/src/install/paths.js +84 -0
  300. package/src/install/targets.js +90 -0
  301. package/src/install/tool-lifecycle.js +151 -0
  302. package/src/lifecycle/bash-availability.js +25 -0
  303. package/src/lifecycle/index.js +812 -0
  304. package/src/lifecycle/mcp-index.js +28 -0
  305. package/src/lifecycle/policies.js +73 -0
  306. package/src/lifecycle/view.js +175 -0
  307. package/src/registry/index.js +611 -0
  308. package/src/release/build-package.js +91 -0
  309. package/src/release/changelog-section.js +70 -0
  310. package/src/release/sync-plugin-versions.js +66 -0
  311. package/src/runtime/advice/cli.js +283 -0
  312. package/src/runtime/advice/client.js +324 -0
  313. package/src/runtime/advice/config.js +189 -0
  314. package/src/runtime/advice/doctor.js +169 -0
  315. package/src/runtime/advice/endpoint-guard.js +134 -0
  316. package/src/runtime/advice/kinds.js +154 -0
  317. package/src/runtime/advice/providers/ollama-systemone.js +209 -0
  318. package/src/runtime/advice/record.js +166 -0
  319. package/src/runtime/advice/registry.js +170 -0
  320. package/src/runtime/advice/strength.js +66 -0
  321. package/src/runtime/brief-tools.js +342 -0
  322. package/src/runtime/c4-project.js +371 -0
  323. package/src/runtime/capability-router.js +484 -0
  324. package/src/runtime/checkouts.js +170 -0
  325. package/src/runtime/claims.js +468 -0
  326. package/src/runtime/cli-result.js +55 -0
  327. package/src/runtime/cli.js +678 -0
  328. package/src/runtime/command-detect.js +516 -0
  329. package/src/runtime/context-pack.js +492 -0
  330. package/src/runtime/decision-register.js +493 -0
  331. package/src/runtime/evidence-ledger.js +338 -0
  332. package/src/runtime/failure/capture.js +272 -0
  333. package/src/runtime/failure/classifier.js +68 -0
  334. package/src/runtime/failure/cli.js +178 -0
  335. package/src/runtime/failure/home.js +64 -0
  336. package/src/runtime/failure/store.js +226 -0
  337. package/src/runtime/feature-resolve.js +79 -0
  338. package/src/runtime/freshness.js +177 -0
  339. package/src/runtime/health.js +863 -0
  340. package/src/runtime/history-compactor.js +237 -0
  341. package/src/runtime/implementation-gate.js +321 -0
  342. package/src/runtime/inventory/coverage.js +218 -0
  343. package/src/runtime/inventory/identity.js +65 -0
  344. package/src/runtime/inventory/index.js +705 -0
  345. package/src/runtime/inventory/precedence.js +134 -0
  346. package/src/runtime/inventory/read-scopes.js +131 -0
  347. package/src/runtime/inventory/siblings.js +192 -0
  348. package/src/runtime/knowledge/chunker.js +124 -0
  349. package/src/runtime/knowledge/hybrid.js +149 -0
  350. package/src/runtime/knowledge/index-store.js +145 -0
  351. package/src/runtime/knowledge/retrieval.js +194 -0
  352. package/src/runtime/leak-scan.js +185 -0
  353. package/src/runtime/lifecycle/cli.js +276 -0
  354. package/src/runtime/lifecycle/event-store.js +340 -0
  355. package/src/runtime/lifecycle/fold.js +353 -0
  356. package/src/runtime/lifecycle/followup.js +432 -0
  357. package/src/runtime/lifecycle/goal.js +249 -0
  358. package/src/runtime/lifecycle/intent-writer.js +86 -0
  359. package/src/runtime/lifecycle/overview.js +292 -0
  360. package/src/runtime/lifecycle/release.js +241 -0
  361. package/src/runtime/lifecycle/report-store.js +221 -0
  362. package/src/runtime/lifecycle/retention.js +212 -0
  363. package/src/runtime/lifecycle/root.js +71 -0
  364. package/src/runtime/lifecycle/status.js +353 -0
  365. package/src/runtime/lifecycle/store-upkeep.js +393 -0
  366. package/src/runtime/locator-resolve.js +158 -0
  367. package/src/runtime/mask.js +210 -0
  368. package/src/runtime/mcp-consultations.js +412 -0
  369. package/src/runtime/mcp-reach.js +157 -0
  370. package/src/runtime/model-router.js +153 -0
  371. package/src/runtime/outcome.js +467 -0
  372. package/src/runtime/reach.js +148 -0
  373. package/src/runtime/readiness-record.js +150 -0
  374. package/src/runtime/readiness.js +435 -0
  375. package/src/runtime/recovery.js +282 -0
  376. package/src/runtime/research-request.js +231 -0
  377. package/src/runtime/retrieval-plan.js +578 -0
  378. package/src/runtime/scaffold/artifacts.js +217 -0
  379. package/src/runtime/scaffold/fingerprint.js +56 -0
  380. package/src/runtime/scaffold/generate.js +911 -0
  381. package/src/runtime/scaffold/languages.js +245 -0
  382. package/src/runtime/storage/cli.js +64 -0
  383. package/src/runtime/storage/engine.js +249 -0
  384. package/src/runtime/storage/registry.js +130 -0
  385. package/src/runtime/storage/roots.js +63 -0
  386. package/src/runtime/storage/rules.js +282 -0
  387. package/src/runtime/storage/upkeep.js +243 -0
  388. package/src/runtime/storage/work-status.js +326 -0
  389. package/src/runtime/task-attempts.js +415 -0
  390. package/src/runtime/task-classifier.js +550 -0
  391. package/src/runtime/task-scope.js +130 -0
  392. package/src/runtime/task-state.js +176 -0
  393. package/src/runtime/trace/indicators.js +235 -0
  394. package/src/runtime/trace/ledger.js +626 -0
  395. package/src/runtime/trace/render.js +76 -0
  396. package/src/runtime/trace/views.js +459 -0
  397. package/src/runtime/verification/contract-runner.js +341 -0
  398. package/src/runtime/verification/engine.js +1461 -0
  399. package/src/runtime/verification/registry.js +130 -0
  400. package/src/runtime/verification/scope-bound.js +418 -0
  401. package/src/runtime/verification/test-selection.js +172 -0
  402. package/src/runtime/workflow-engine.js +588 -0
  403. package/src/runtime/workflow-orchestrator.js +953 -0
  404. package/src/runtime/worktree.js +340 -0
  405. package/src/state/index.js +193 -0
  406. package/src/state/lockfile.js +136 -0
  407. package/src/state/run-lock.js +408 -0
  408. package/types/node-commonjs.d.ts +68 -0
  409. package/types/runtime.d.ts +91 -0
@@ -0,0 +1,244 @@
1
+ 'use strict';
2
+
3
+ // A deliberately generic, restricted TOML parser. It has no knowledge of Codex, or of any other
4
+ // harness — it only understands the TOML subset needed to safely locate scalar keys and table
5
+ // headers for a surgical, comment-preserving rewrite. It was extracted out of codex-config.js
6
+ // (which is Codex-specific and is moving under src/adapters/codex/) so that non-Codex code, such
7
+ // as the lifecycle layer, can parse TOML without depending on a harness-specific module.
8
+ //
9
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
10
+ // native type-stripping — no build step, no runtime dependency. Body stays CommonJS so a `.js`
11
+ // caller's `require('../helper/toml.js')` keeps working while the rest of the tree is still `.js`.
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+ function stripComment(line ) {
41
+ let quote = null;
42
+ let escape = false;
43
+ for (let i = 0; i < line.length; i++) {
44
+ const char = line[i];
45
+ if (quote) {
46
+ if (escape) escape = false;
47
+ else if (char === '\\') escape = true;
48
+ else if (char === quote) quote = null;
49
+ } else if (char === '"' || char === "'") quote = char;
50
+ else if (char === '#') return line.slice(0, i);
51
+ }
52
+ return line;
53
+ }
54
+
55
+ function splitAssignment(line ) {
56
+ let quote = null;
57
+ let escape = false;
58
+ let depth = 0;
59
+ for (let i = 0; i < line.length; i++) {
60
+ const char = line[i];
61
+ if (quote) {
62
+ if (escape) escape = false;
63
+ else if (char === '\\') escape = true;
64
+ else if (char === quote) quote = null;
65
+ continue;
66
+ }
67
+ if (char === '"' || char === "'") quote = char;
68
+ else if (char === '[' || char === '{') depth++;
69
+ else if (char === ']' || char === '}') depth--;
70
+ else if (char === '=' && depth === 0) return [line.slice(0, i), line.slice(i + 1)];
71
+ }
72
+ return null;
73
+ }
74
+
75
+ function balanced(value ) {
76
+ let quote = null;
77
+ let escape = false;
78
+ let depth = 0;
79
+ for (const char of value) {
80
+ if (quote) {
81
+ if (escape) escape = false;
82
+ else if (char === '\\') escape = true;
83
+ else if (char === quote) quote = null;
84
+ } else if (char === '"' || char === "'") quote = char;
85
+ else if (char === '[' || char === '{') depth++;
86
+ else if (char === ']' || char === '}') {
87
+ depth--;
88
+ if (depth < 0) return false;
89
+ }
90
+ }
91
+ return !quote && depth === 0;
92
+ }
93
+
94
+ function parseValue(raw ) {
95
+ const value = raw.trim();
96
+ if (!value || !balanced(value)) throw new Error('invalid TOML value');
97
+ if (value === 'true') return true;
98
+ if (value === 'false') return false;
99
+ if (/^[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(value)) return Number(value);
100
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
101
+ if (value[0] === '"') return JSON.parse(value);
102
+ return value.slice(1, -1);
103
+ }
104
+ // Valid TOML arrays/inline tables/datetime values do not need interpretation when unmanaged.
105
+ if (value.startsWith('[') || value.startsWith('{') || /^\d{4}-\d\d-\d\d(?:[Tt ].*)?$/.test(value)) return value;
106
+ throw new Error('unsupported or invalid TOML value');
107
+ }
108
+
109
+ const BARE_KEY = /^[A-Za-z0-9_-]+$/;
110
+
111
+ /** Splits a TOML key path (`a.b`, `mcp_servers."my-server"`, `'lit'.x`) into its segments.
112
+ * Quoted segments are ordinary TOML — a table header like `[mcp_servers."timo-document-hub"]` is
113
+ * spec-valid — but this scanner previously matched bare keys only and rejected the whole file,
114
+ * making any config that used one unreadable. Returns null for anything it cannot represent
115
+ * faithfully, so every caller keeps failing closed rather than guessing at a rewrite.
116
+ *
117
+ * A dot *inside* a quoted segment is legal TOML (`"gpt-5.5" = 4`) and is preserved — see
118
+ * flattenKeyPath for how it is kept from colliding with a genuine path separator. */
119
+ function parseKeyPath(raw ) {
120
+ const segments = [];
121
+ let i = 0;
122
+ const skipSpace = () => { while (i < raw.length && (raw[i] === ' ' || raw[i] === '\t')) i += 1; };
123
+ skipSpace();
124
+ if (i >= raw.length) return null;
125
+ while (i < raw.length) {
126
+ let segment ;
127
+ const quote = raw[i];
128
+ if (quote === '"' || quote === "'") {
129
+ i += 1;
130
+ let body = '';
131
+ while (i < raw.length && raw[i] !== quote) {
132
+ if (quote === '"' && raw[i] === '\\') { body += raw.slice(i, i + 2); i += 2; continue; }
133
+ body += raw[i]; i += 1;
134
+ }
135
+ if (raw[i] !== quote) return null; // unterminated
136
+ i += 1;
137
+ try { segment = quote === '"' ? JSON.parse(`"${body}"`) : body; } catch { return null; }
138
+ } else {
139
+ const start = i;
140
+ while (i < raw.length && raw[i] !== '.' && raw[i] !== ' ' && raw[i] !== '\t') i += 1;
141
+ segment = raw.slice(start, i);
142
+ if (!BARE_KEY.test(segment)) return null;
143
+ }
144
+ if (!segment) return null;
145
+ segments.push(segment);
146
+ skipSpace();
147
+ if (i >= raw.length) break;
148
+ if (raw[i] !== '.') return null;
149
+ i += 1;
150
+ skipSpace();
151
+ if (i >= raw.length) return null; // trailing dot
152
+ }
153
+ return segments.length ? segments : null;
154
+ }
155
+
156
+ /** Flattens key-path segments into the dotted string `entries` is keyed by, escaping any dot that
157
+ * lives *inside* a segment so it cannot be mistaken for a path separator — without this,
158
+ * `["a.b"]` and `[a.b]` collide and a surgical edit could rewrite the wrong line. Managed
159
+ * identities (normaliseDesired) are bare-key-only, so their flattened form is unchanged and
160
+ * lookups against them still match. */
161
+ function flattenKeyPath(segments ) {
162
+ return segments.map((segment) => segment.replace(/\\/g, '\\\\').replace(/\./g, '\\.')).join('.');
163
+ }
164
+
165
+ /** A conservative TOML scanner. It validates the subset needed to safely locate scalar keys;
166
+ * unsupported multi-line syntax fails closed rather than risking a destructive rewrite. `headers`
167
+ * lists each table header line in file order, so a caller never re-detects headers itself. */
168
+ function parseToml(text ) {
169
+ const lines = text.split(/\r?\n/);
170
+ let table = [];
171
+ const entries = new Map ();
172
+ const headers = [];
173
+ for (let index = 0; index < lines.length; index++) {
174
+ const clean = stripComment(lines[index]).trim();
175
+ if (!clean) continue;
176
+ // `[[array.of.tables]]` still fails closed: the inner capture starts with '[', which
177
+ // parseKeyPath rejects, so array-of-tables remains unsupported exactly as before.
178
+ const tableMatch = clean.match(/^\[(.+)\]$/);
179
+ if (tableMatch) {
180
+ const tablePath = parseKeyPath(tableMatch[1].trim());
181
+ if (!tablePath) throw new Error(`Malformed or unsupported TOML table on line ${index + 1}`);
182
+ table = tablePath;
183
+ headers.push({ line: index, table: flattenKeyPath(table) });
184
+ continue;
185
+ }
186
+ if (clean.startsWith('[')) throw new Error(`Malformed or unsupported TOML table on line ${index + 1}`);
187
+ const assignment = splitAssignment(clean);
188
+ if (!assignment) throw new Error(`Malformed TOML assignment on line ${index + 1}`);
189
+ const keyPath = parseKeyPath(assignment[0].trim());
190
+ if (!keyPath) throw new Error(`Unsupported TOML key on line ${index + 1}`);
191
+ let value ;
192
+ try { value = parseValue(assignment[1]); } catch { throw new Error(`Malformed TOML value on line ${index + 1}`); }
193
+ const fullKey = flattenKeyPath([...table, ...keyPath]);
194
+ if (entries.has(fullKey)) throw new Error(`Duplicate TOML key '${fullKey}'`);
195
+ entries.set(fullKey, { value, line: index, table: flattenKeyPath(table) });
196
+ }
197
+ return { lines, entries, headers };
198
+ }
199
+
200
+ /** The table rules of TOML 1.0 that parseToml does not enforce, as found in `text`:
201
+ * `duplicate-table` when a table is opened by a second `[header]`, or by a `[header]` after dotted
202
+ * keys already defined it; `table-and-value` when one path is both a key's value and a table (by a
203
+ * header, or implied by a longer dotted key). `line` is the 1-based line of the second definition.
204
+ * Throws what parseToml throws. */
205
+ function tableViolations(text ) {
206
+ parseToml(text);
207
+ const lines = text.split(/\r?\n/);
208
+ const violations = [];
209
+ const opened = new Set ();
210
+ const dotted = new Set ();
211
+ const tables = new Set ();
212
+ const values = new Set ();
213
+ const asTable = (segments , line ) => {
214
+ const flat = flattenKeyPath(segments);
215
+ if (values.has(flat)) violations.push({ kind: 'table-and-value', table: flat, line });
216
+ tables.add(flat);
217
+ };
218
+ let table = [];
219
+ for (let index = 0; index < lines.length; index++) {
220
+ const clean = stripComment(lines[index]).trim();
221
+ if (!clean) continue;
222
+ const tableMatch = clean.match(/^\[(.+)\]$/);
223
+ if (tableMatch) {
224
+ table = parseKeyPath(tableMatch[1].trim()) ;
225
+ const flat = flattenKeyPath(table);
226
+ if (opened.has(flat) || dotted.has(flat)) violations.push({ kind: 'duplicate-table', table: flat, line: index + 1 });
227
+ opened.add(flat);
228
+ for (let length = 1; length <= table.length; length++) asTable(table.slice(0, length), index + 1);
229
+ continue;
230
+ }
231
+ const keyPath = parseKeyPath(splitAssignment(clean) [0].trim()) ;
232
+ for (let length = 1; length < keyPath.length; length++) {
233
+ const segments = [...table, ...keyPath.slice(0, length)];
234
+ dotted.add(flattenKeyPath(segments));
235
+ asTable(segments, index + 1);
236
+ }
237
+ const full = flattenKeyPath([...table, ...keyPath]);
238
+ if (tables.has(full)) violations.push({ kind: 'table-and-value', table: full, line: index + 1 });
239
+ values.add(full);
240
+ }
241
+ return violations;
242
+ }
243
+
244
+ module.exports = { parseToml, stripComment, tableViolations };
@@ -0,0 +1,149 @@
1
+ 'use strict';
2
+ // backup-set.js — the files a run backs up: every file its lifecycle plan is about to write or
3
+ // delete, the scripts an adapter copies beside a change's target, the old copy a moved resource
4
+ // leaves behind, and files a pending tombstone will sweep. Files holding only MCP entries stay out:
5
+ // their ledger row, not a file copy, is how an entry is recovered, and the same file can hold the
6
+ // harness's own state, which a rollback must never restore over. DoFlow's own records stay out too,
7
+ // except the ones named in `records`: the ownership ledger rides along with the files, because a
8
+ // rollback that restores files without the rows describing them leaves every later update and
9
+ // remove refusing those files as modified outside DoFlow.
10
+ // Reads only: it stats files and creates nothing.
11
+ //
12
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): authored as `.ts`, run directly by Node
13
+ // native type-stripping — no build step, no runtime dependency. Body stays CommonJS so a `.js`
14
+ // caller's `require('../install/backup-set.js')` keeps working while the tree is still `.js`. The
15
+ // `./backup` require carries `.ts` because backup migrated in the same slice.
16
+ const fs = require('node:fs');
17
+ const path = require('node:path');
18
+ const { BackupError, scopeRelative } = require('./backup.js');
19
+
20
+ const REASON_ORDER = ['change', 'companion', 'relocated-from', 'tombstone', 'snapshot', 'record'];
21
+
22
+ function byCodePoint(a , b ) {
23
+ if (a === b) return 0;
24
+ return a < b ? -1 : 1;
25
+ }
26
+
27
+ /** What a set entry is on disk now, following links. */
28
+ function statEntry(file , fsImpl ) {
29
+ let stat;
30
+ try {
31
+ stat = fsImpl.statSync(file);
32
+ } catch (err ) {
33
+ if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return { kind: 'absent', size: null, mode: null };
34
+ throw new BackupError(`could not read ${file}: ${err.code || err.message}`);
35
+ }
36
+ if (stat.isFile()) return { kind: 'file', size: stat.size, mode: stat.mode & 0o7777 };
37
+ return { kind: 'other', size: null, mode: null };
38
+ }
39
+
40
+ function isAtOrUnder(file , root ) {
41
+ const resolved = path.resolve(root);
42
+ return file === resolved || file.startsWith(resolved.endsWith(path.sep) ? resolved : resolved + path.sep);
43
+ }
44
+
45
+ /** Candidates (absolute path -> harnesses and reasons) into a BackupSet, after the exclusions.
46
+ * A path in `records` is kept even under an excluded root. */
47
+ function toBackupSet(candidates , { scope, scopeRoot, exclude, excluded, records = [], fsImpl } ) {
48
+ const root = path.resolve(scopeRoot);
49
+ const kept = new Set(records.map((file ) => path.resolve(file)));
50
+ const entries = [];
51
+ for (const file of [...candidates.keys()].sort(byCodePoint)) {
52
+ if (!kept.has(file) && exclude.some((x ) => isAtOrUnder(file, x))) {
53
+ excluded.push({ path: file, reason: 'doflow-state' });
54
+ continue;
55
+ }
56
+ const { harnesses, reasons } = candidates.get(file);
57
+ entries.push({
58
+ path: file,
59
+ rel: scopeRelative(root, file),
60
+ harnesses: [...harnesses].sort(byCodePoint),
61
+ reasons: REASON_ORDER.filter((reason) => reasons.has(reason)),
62
+ ...statEntry(file, fsImpl),
63
+ });
64
+ }
65
+ const files = entries.filter((e) => e.kind === 'file');
66
+ return {
67
+ scope,
68
+ scopeRoot: root,
69
+ entries,
70
+ excluded: excluded.sort((a , b ) => byCodePoint(a.path, b.path)),
71
+ count: entries.length,
72
+ existing: files.length,
73
+ absent: entries.filter((e) => e.kind === 'absent').length,
74
+ bytes: files.reduce((sum, e) => sum + (e.size ), 0),
75
+ };
76
+ }
77
+
78
+ function addCandidate(candidates , file , harness , reason ) {
79
+ const key = path.resolve(file);
80
+ if (!candidates.has(key)) candidates.set(key, { harnesses: new Set(), reasons: new Set() });
81
+ const item = candidates.get(key);
82
+ if (harness) item.harnesses.add(harness);
83
+ item.reasons.add(reason);
84
+ }
85
+
86
+ /**
87
+ * The files a lifecycle plan's apply can overwrite or delete, as a BackupSet.
88
+ * `exclude` lists DoFlow's own paths (the backup root, the state root, the install manifest, the
89
+ * lock); an entry at or under one of them is reported in `excluded`, not backed up.
90
+ * `records` lists DoFlow record files backed up beside those files although an `exclude` root holds
91
+ * them (the ownership ledger), with no harness; a rollback restores only the ledger rows of the files
92
+ * it writes back (backup.ts mergeRestoredLedger). They join only a set that holds some file already,
93
+ * so a run that backs up nothing still backs up nothing.
94
+ */
95
+ function backupSetFromPlan({ plan, scope, scopeRoot, exclude = [], records = [], fsImpl = fs } ) {
96
+ const candidates = new Map();
97
+ const mcpOnly = new Map();
98
+ const resources = plan.ledger?.resources ?? [];
99
+ const tombstones = plan.ledger?.tombstones ?? [];
100
+ // A retained or released change gives up a ledger row and touches no file.
101
+ const changes = plan.changes.filter((change ) => change.retained !== true && change.release !== true);
102
+
103
+ for (const change of changes) {
104
+ const target = path.resolve(change.target);
105
+ if (change.kind === 'mcp-server') {
106
+ if (!mcpOnly.has(target)) mcpOnly.set(target, true);
107
+ continue;
108
+ }
109
+ mcpOnly.set(target, false);
110
+ addCandidate(candidates, target, change.harness, 'change');
111
+ for (const companion of change.companionTargets ?? []) {
112
+ if (typeof companion === 'string') addCandidate(candidates, companion, change.harness, 'companion');
113
+ }
114
+ if ((change.operation === 'create' || change.operation === 'update') && typeof change.identity === 'string') {
115
+ for (const resource of resources) {
116
+ if (resource.harness !== change.harness || resource.assetId !== change.assetId || resource.identity !== change.identity) continue;
117
+ if (resource.kind === 'mcp-server' || typeof resource.target !== 'string') continue;
118
+ if (path.resolve(resource.target) === target || !fsImpl.existsSync(resource.target)) continue;
119
+ addCandidate(candidates, resource.target, resource.harness, 'relocated-from');
120
+ }
121
+ }
122
+ }
123
+
124
+ const owned = new Set(resources.filter((r ) => typeof r.target === 'string').map((r ) => path.resolve(r.target)));
125
+ for (const tombstone of tombstones) {
126
+ if (tombstone.sweptAt || typeof tombstone.fromTarget !== 'string') continue;
127
+ if (owned.has(path.resolve(tombstone.fromTarget)) || !fsImpl.existsSync(tombstone.fromTarget)) continue;
128
+ addCandidate(candidates, tombstone.fromTarget, tombstone.harness, 'tombstone');
129
+ }
130
+
131
+ const excluded = [...mcpOnly]
132
+ .filter(([target, onlyMcp]) => onlyMcp && !candidates.has(target))
133
+ .map(([target]) => ({ path: target, reason: 'mcp-entries-only' }));
134
+ if (candidates.size) for (const file of records) addCandidate(candidates, file, null, 'record');
135
+ return toBackupSet(candidates, { scope, scopeRoot, exclude, excluded, records, fsImpl });
136
+ }
137
+
138
+ /** A BackupSet of the given absolute paths, for the pre-rollback snapshot. `records` as for
139
+ * backupSetFromPlan: a restored ledger is snapshotted too, so the snapshot rolls back as a whole. */
140
+ function backupSetFromPaths({ items, scope, scopeRoot, exclude = [], records = [], fsImpl = fs } ) {
141
+ const candidates = new Map();
142
+ for (const item of items) {
143
+ if (item.harnesses.length === 0) addCandidate(candidates, item.path, null, 'snapshot');
144
+ for (const harness of item.harnesses) addCandidate(candidates, item.path, harness, 'snapshot');
145
+ }
146
+ return toBackupSet(candidates, { scope, scopeRoot, exclude, excluded: [], records, fsImpl });
147
+ }
148
+
149
+ module.exports = { backupSetFromPlan, backupSetFromPaths };