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

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 (407) 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 +1057 -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 +46 -4
  250. package/src/adapters/antigravity/index.ts +631 -0
  251. package/src/adapters/claude/index.ts +548 -0
  252. package/src/adapters/claude/mcp.ts +94 -0
  253. package/src/adapters/codex/agents.ts +208 -0
  254. package/src/adapters/codex/config.ts +272 -0
  255. package/src/adapters/codex/hooks.ts +203 -0
  256. package/src/adapters/codex/index.ts +707 -0
  257. package/src/adapters/codex/mcp.ts +271 -0
  258. package/src/adapters/codex/native-projection.ts +34 -0
  259. package/src/adapters/copilot/index.ts +413 -0
  260. package/src/adapters/copy-tree.ts +620 -0
  261. package/src/adapters/gemini/hooks.ts +210 -0
  262. package/src/adapters/gemini/index.ts +390 -0
  263. package/src/adapters/hook-commands.ts +60 -0
  264. package/src/adapters/index.ts +106 -0
  265. package/src/adapters/kiro/index.ts +310 -0
  266. package/src/adapters/mcp-entries.ts +331 -0
  267. package/src/adapters/opencode/index.ts +466 -0
  268. package/src/adapters/pi/index.ts +279 -0
  269. package/src/adapters/pi/json-members.ts +185 -0
  270. package/src/adapters/pi/mcp.ts +373 -0
  271. package/src/adapters/resolve-source.ts +19 -0
  272. package/src/cli/commands/install.ts +218 -0
  273. package/src/cli/commands/list-backups.ts +21 -0
  274. package/src/cli/commands/reconcile.ts +120 -0
  275. package/src/cli/commands/remove.ts +82 -0
  276. package/src/cli/commands/rollback.ts +172 -0
  277. package/src/cli/commands/self-update.ts +33 -0
  278. package/src/cli/commands/status.ts +138 -0
  279. package/src/cli/commands/tools.ts +92 -0
  280. package/src/cli/commands/update.ts +162 -0
  281. package/src/cli/index.ts +568 -0
  282. package/src/cli/runtime-commands.ts +281 -0
  283. package/src/cli/shared.ts +218 -0
  284. package/src/helper/bash-helper.ts +34 -0
  285. package/src/helper/git.ts +24 -0
  286. package/src/helper/guardrails.ts +49 -0
  287. package/src/helper/harness-paths.ts +140 -0
  288. package/src/helper/marker-merge.ts +116 -0
  289. package/src/helper/prompt.ts +61 -0
  290. package/src/helper/repo-root.ts +29 -0
  291. package/src/helper/settings-merge.ts +151 -0
  292. package/src/helper/settings-scope.ts +33 -0
  293. package/src/helper/toml.ts +244 -0
  294. package/src/install/backup-set.ts +149 -0
  295. package/src/install/backup.ts +724 -0
  296. package/src/install/context.ts +58 -0
  297. package/src/install/manifest.ts +145 -0
  298. package/src/install/mcp.ts +254 -0
  299. package/src/install/paths.ts +84 -0
  300. package/src/install/targets.ts +90 -0
  301. package/src/install/tool-lifecycle.ts +151 -0
  302. package/src/lifecycle/bash-availability.ts +25 -0
  303. package/src/lifecycle/index.ts +812 -0
  304. package/src/lifecycle/mcp-index.ts +28 -0
  305. package/src/lifecycle/policies.ts +73 -0
  306. package/src/lifecycle/view.ts +175 -0
  307. package/src/registry/index.ts +611 -0
  308. package/src/release/sync-plugin-versions.ts +66 -0
  309. package/src/runtime/advice/cli.ts +283 -0
  310. package/src/runtime/advice/client.ts +324 -0
  311. package/src/runtime/advice/config.ts +189 -0
  312. package/src/runtime/advice/doctor.ts +169 -0
  313. package/src/runtime/advice/endpoint-guard.ts +134 -0
  314. package/src/runtime/advice/kinds.ts +154 -0
  315. package/src/runtime/advice/providers/ollama-systemone.ts +209 -0
  316. package/src/runtime/advice/record.ts +166 -0
  317. package/src/runtime/advice/registry.ts +170 -0
  318. package/src/runtime/advice/strength.ts +66 -0
  319. package/src/runtime/brief-tools.ts +342 -0
  320. package/src/runtime/c4-project.ts +371 -0
  321. package/src/runtime/capability-router.ts +484 -0
  322. package/src/runtime/checkouts.ts +170 -0
  323. package/src/runtime/claims.ts +468 -0
  324. package/src/runtime/cli-result.ts +55 -0
  325. package/src/runtime/cli.ts +678 -0
  326. package/src/runtime/command-detect.ts +516 -0
  327. package/src/runtime/context-pack.ts +492 -0
  328. package/src/runtime/decision-register.ts +493 -0
  329. package/src/runtime/evidence-ledger.ts +338 -0
  330. package/src/runtime/failure/capture.ts +272 -0
  331. package/src/runtime/failure/classifier.ts +68 -0
  332. package/src/runtime/failure/cli.ts +178 -0
  333. package/src/runtime/failure/home.ts +64 -0
  334. package/src/runtime/failure/store.ts +226 -0
  335. package/src/runtime/feature-resolve.ts +79 -0
  336. package/src/runtime/freshness.ts +177 -0
  337. package/src/runtime/health.ts +863 -0
  338. package/src/runtime/history-compactor.ts +237 -0
  339. package/src/runtime/implementation-gate.ts +321 -0
  340. package/src/runtime/inventory/coverage.ts +218 -0
  341. package/src/runtime/inventory/identity.ts +65 -0
  342. package/src/runtime/inventory/index.ts +705 -0
  343. package/src/runtime/inventory/precedence.ts +134 -0
  344. package/src/runtime/inventory/read-scopes.ts +131 -0
  345. package/src/runtime/inventory/siblings.ts +192 -0
  346. package/src/runtime/knowledge/chunker.ts +124 -0
  347. package/src/runtime/knowledge/hybrid.ts +149 -0
  348. package/src/runtime/knowledge/index-store.ts +145 -0
  349. package/src/runtime/knowledge/retrieval.ts +194 -0
  350. package/src/runtime/leak-scan.ts +185 -0
  351. package/src/runtime/lifecycle/cli.ts +276 -0
  352. package/src/runtime/lifecycle/event-store.ts +340 -0
  353. package/src/runtime/lifecycle/fold.ts +353 -0
  354. package/src/runtime/lifecycle/followup.ts +432 -0
  355. package/src/runtime/lifecycle/goal.ts +249 -0
  356. package/src/runtime/lifecycle/intent-writer.ts +86 -0
  357. package/src/runtime/lifecycle/overview.ts +292 -0
  358. package/src/runtime/lifecycle/release.ts +241 -0
  359. package/src/runtime/lifecycle/report-store.ts +221 -0
  360. package/src/runtime/lifecycle/retention.ts +212 -0
  361. package/src/runtime/lifecycle/root.ts +71 -0
  362. package/src/runtime/lifecycle/status.ts +353 -0
  363. package/src/runtime/lifecycle/store-upkeep.ts +393 -0
  364. package/src/runtime/locator-resolve.ts +158 -0
  365. package/src/runtime/mask.ts +210 -0
  366. package/src/runtime/mcp-consultations.ts +412 -0
  367. package/src/runtime/mcp-reach.ts +157 -0
  368. package/src/runtime/model-router.ts +153 -0
  369. package/src/runtime/outcome.ts +467 -0
  370. package/src/runtime/reach.ts +148 -0
  371. package/src/runtime/readiness-record.ts +150 -0
  372. package/src/runtime/readiness.ts +435 -0
  373. package/src/runtime/recovery.ts +282 -0
  374. package/src/runtime/research-request.ts +231 -0
  375. package/src/runtime/retrieval-plan.ts +578 -0
  376. package/src/runtime/scaffold/artifacts.ts +217 -0
  377. package/src/runtime/scaffold/fingerprint.ts +56 -0
  378. package/src/runtime/scaffold/generate.ts +911 -0
  379. package/src/runtime/scaffold/languages.ts +245 -0
  380. package/src/runtime/storage/cli.ts +64 -0
  381. package/src/runtime/storage/engine.ts +249 -0
  382. package/src/runtime/storage/registry.ts +130 -0
  383. package/src/runtime/storage/roots.ts +63 -0
  384. package/src/runtime/storage/rules.ts +282 -0
  385. package/src/runtime/storage/upkeep.ts +243 -0
  386. package/src/runtime/storage/work-status.ts +326 -0
  387. package/src/runtime/task-attempts.ts +415 -0
  388. package/src/runtime/task-classifier.ts +550 -0
  389. package/src/runtime/task-scope.ts +130 -0
  390. package/src/runtime/task-state.ts +176 -0
  391. package/src/runtime/trace/indicators.ts +235 -0
  392. package/src/runtime/trace/ledger.ts +626 -0
  393. package/src/runtime/trace/render.ts +76 -0
  394. package/src/runtime/trace/views.ts +459 -0
  395. package/src/runtime/verification/contract-runner.ts +341 -0
  396. package/src/runtime/verification/engine.ts +1461 -0
  397. package/src/runtime/verification/registry.ts +130 -0
  398. package/src/runtime/verification/scope-bound.ts +418 -0
  399. package/src/runtime/verification/test-selection.ts +172 -0
  400. package/src/runtime/workflow-engine.ts +588 -0
  401. package/src/runtime/workflow-orchestrator.ts +953 -0
  402. package/src/runtime/worktree.ts +340 -0
  403. package/src/state/index.ts +193 -0
  404. package/src/state/lockfile.ts +136 -0
  405. package/src/state/run-lock.ts +408 -0
  406. package/types/node-commonjs.d.ts +68 -0
  407. package/types/runtime.d.ts +91 -0
@@ -0,0 +1,331 @@
1
+ 'use strict';
2
+
3
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
4
+
5
+ // MCP entry ownership for the adapters that keep DoFlow's servers as members of a JSON map in a
6
+ // file the harness shares with its user. Ownership is one ledger row per harness, file and server,
7
+ // whose fingerprint is the entry value DoFlow last verified there. A same-named entry no row claims
8
+ // is the user's and is never touched; an owned entry whose value no longer matches its row was
9
+ // edited outside DoFlow and is released, never overwritten or removed. While a harness holds no MCP
10
+ // row at all, an entry equal to DoFlow's own rendering of a server it may adopt is DoFlow's.
11
+ //
12
+ // Plan changes carry DoFlow's own entry and a fingerprint of the value plan saw, never file text:
13
+ // the lifecycle copies every change into the recovery record, and an MCP file may hold secrets. For
14
+ // the same reason a file DoFlow cannot read is described by a fixed reason, never parser output.
15
+ const fs = require('node:fs');
16
+ const path = require('node:path');
17
+ const { fingerprint } = require('./copy-tree.ts');
18
+
19
+ const REASONS = Object.freeze({
20
+ json: 'invalid JSON',
21
+ root: 'top-level value is not an object',
22
+ container: 'server container is not an object',
23
+ });
24
+
25
+ function isObject(value: any): boolean { return Boolean(value) && typeof value === 'object' && !Array.isArray(value); }
26
+
27
+ function entryFingerprint(value: any): string { return fingerprint(value); }
28
+
29
+ function fingerprintOrNull(value: any): string | null { return value === undefined ? null : entryFingerprint(value); }
30
+
31
+ /** Deep equality that ignores key order, so a reformatted entry still equals DoFlow's rendering. */
32
+ function sameValue(a: any, b: any): boolean { return a !== undefined && b !== undefined && entryFingerprint(a) === entryFingerprint(b); }
33
+
34
+ function shortId(id: any): string { const text = String(id); return text.length > 40 ? `${text.slice(0, 37)}...` : text; }
35
+
36
+ function shortPath(file: string): string { return file.length > 80 ? `...${file.slice(-77)}` : file; }
37
+
38
+ const NOTICES = Object.freeze({
39
+ collision: (id: any, file: string) => `MCP: kept your own entry '${shortId(id)}' in ${path.basename(file)} and did not register DoFlow's; rename or remove yours to let DoFlow manage it.`,
40
+ released: (id: any, file: string) => `MCP: entry '${shortId(id)}' in ${path.basename(file)} was changed outside DoFlow; it is yours now and DoFlow no longer updates or removes it.`,
41
+ untouched: (file: string) => `MCP: left ${shortPath(file)} untouched because it cannot be edited safely; DoFlow no longer manages the entries in it.`,
42
+ });
43
+
44
+ function refusal(label: string, file: string, reason: string): string { return `${label}: ${file}: ${reason}; DoFlow did not change the file`; }
45
+
46
+ /** Read one MCP file as a JSON object. `servers` is null when the file or its container is absent. */
47
+ function readMcpFile(file: string, container: string, { fsImpl = fs }: { fsImpl?: any } = {}): any {
48
+ if (!fsImpl.existsSync(file)) return { ok: true, doc: null, servers: null };
49
+ let doc;
50
+ try { doc = JSON.parse(fsImpl.readFileSync(file, 'utf8')); } catch { return { ok: false, reason: REASONS.json }; }
51
+ if (!isObject(doc)) return { ok: false, reason: REASONS.root };
52
+ if (doc[container] === undefined) return { ok: true, doc, servers: null };
53
+ if (!isObject(doc[container])) return { ok: false, reason: REASONS.container };
54
+ return { ok: true, doc, servers: doc[container] };
55
+ }
56
+
57
+ /** The `files` map plan and verify take: the scope's MCP file and every file an own row names. */
58
+ function readMcpFiles({ file, ownRows = [], container, fsImpl = fs }: any): any {
59
+ const targets = new Set([file, ...ownRows.map((row: any) => row.target)]);
60
+ return Object.fromEntries([...targets].map((target) => {
61
+ const read = readMcpFile(target, container, { fsImpl });
62
+ return [target, read.ok ? { ok: true, servers: read.servers } : read];
63
+ }));
64
+ }
65
+
66
+ function renderedById(selected: any[], adoptable: any[]): Map<string, any> {
67
+ const rendered = new Map<string, any>();
68
+ for (const { id, entry } of [...selected, ...adoptable]) if (!rendered.has(id)) rendered.set(id, entry);
69
+ return rendered;
70
+ }
71
+
72
+ /** Shared by plan, verify and ownedMcpIds, so the three read one entry the same way. */
73
+ function ownershipView({ file, files, selected = [], adoptable = [], ownRows = [], foreignRows = [] }: any): any {
74
+ const rendered = renderedById(selected, adoptable);
75
+ const valueOf = (target: string, id: string) => (files[target]?.ok ? files[target].servers?.[id] : undefined);
76
+ const matches = (row: any, value: any) => {
77
+ if (value === undefined) return false;
78
+ const recorded = row.fingerprint ?? null;
79
+ return recorded !== null ? entryFingerprint(value) === recorded : sameValue(value, rendered.get(row.identity));
80
+ };
81
+ const rowsFor = (id: string) => ownRows.filter((row: any) => row.identity === id && row.target === file);
82
+ // A legacy row is consumed alongside the current one, but never preferred over it.
83
+ const rowFor = (id: string) => { const rows = rowsFor(id); return rows.find((row: any) => !row.legacy) ?? rows[0] ?? null; };
84
+ const adoptionOpen = ownRows.length === 0;
85
+ const adoptableIds = new Set(adoptable.map((server: any) => server.id));
86
+ const selectedIds = new Set(selected.map((server: any) => server.id));
87
+ /** An equal entry no own row claims is DoFlow's when another harness's row claims it, or when it
88
+ * may be adopted. */
89
+ const claimable = (id: string, entry: any) => {
90
+ const value = valueOf(file, id);
91
+ return sameValue(value, entry) && (foreignRows.some((row: any) => row.identity === id && row.target === file)
92
+ || (adoptionOpen && adoptableIds.has(id)));
93
+ };
94
+ /** Adoptable entries DoFlow takes out because nothing selects them any more. */
95
+ const adoptedRemovals = () => (adoptionOpen && files[file]?.ok
96
+ ? adoptable.filter(({ id, entry }: any) => !selectedIds.has(id) && sameValue(valueOf(file, id), entry)) : []);
97
+ return { rendered, valueOf, matches, rowsFor, rowFor, claimable, adoptedRemovals };
98
+ }
99
+
100
+ function orderOf(selected: any[], adoptable: any[]): (a: any, b: any) => number {
101
+ const ids = [...renderedById(selected, adoptable).keys()];
102
+ const rank = (id: string) => { const index = ids.indexOf(id); return index < 0 ? ids.length : index; };
103
+ return (a: any, b: any) => (a.target < b.target ? -1 : a.target > b.target ? 1
104
+ : rank(a.identity) - rank(b.identity) || (a.identity < b.identity ? -1 : a.identity > b.identity ? 1 : 0));
105
+ }
106
+
107
+ /**
108
+ * Decide every MCP entry change for one harness at one scope. `selected` and `adoptable` are the
109
+ * adapter's rendered entries `[{ id, entry }]`; `ownRows` its rows (legacy ones flagged `legacy`);
110
+ * `foreignRows` other harnesses' rows; `identityFor` composes the adapter's ownership identity.
111
+ */
112
+ function planMcpEntries({ file, files, selected = [], adoptable = [], ownRows = [], foreignRows = [], removing = false,
113
+ identityFor, assetId, renderer, label }: any): any {
114
+ const view = ownershipView({ file, files, selected, adoptable, ownRows, foreignRows });
115
+ const changes: any[] = [];
116
+ const conflicts: string[] = [];
117
+ const notices: string[] = [];
118
+ const base = (fields: any) => ({ assetId, kind: 'mcp-server', sourceVersion: 'registry-v1', projection: { renderer }, ...fields });
119
+ const write = (operation: string, id: string, entry: any) => base({
120
+ target: file, operation, identity: id, ownershipIdentity: identityFor(id),
121
+ before: fingerprintOrNull(view.valueOf(file, id)), entry, fingerprint: entryFingerprint(entry), afterFingerprint: entryFingerprint(entry),
122
+ });
123
+ const drop = (row: any, release: boolean) => base({
124
+ target: row.target, operation: 'remove', identity: row.identity, ownershipIdentity: row.ownershipIdentity,
125
+ before: fingerprintOrNull(view.valueOf(row.target, row.identity)), fingerprint: row.fingerprint ?? null,
126
+ ...(release ? { release: true } : {}),
127
+ });
128
+
129
+ const broken = Object.keys(files).filter((target) => !files[target].ok).sort();
130
+ for (const target of broken) {
131
+ if (removing) notices.push(NOTICES.untouched(target));
132
+ else conflicts.push(refusal(label, target, files[target].reason));
133
+ }
134
+
135
+ const consumed = new Set<any>();
136
+ if (!removing && files[file]?.ok) {
137
+ for (const { id, entry } of selected) {
138
+ const rows = view.rowsFor(id);
139
+ for (const row of rows) consumed.add(row);
140
+ const row = view.rowFor(id);
141
+ const value = view.valueOf(file, id);
142
+ if (row && value !== undefined && !view.matches(row, value)) {
143
+ for (const item of rows) changes.push(drop(item, true));
144
+ notices.push(NOTICES.released(id, file));
145
+ continue;
146
+ }
147
+ if (row || value === undefined) {
148
+ if (value === undefined) changes.push(write('create', id, entry));
149
+ else if (!sameValue(value, entry)) changes.push(write('update', id, entry));
150
+ // The row verify records under the adapter's identity replaces the legacy one in this run.
151
+ for (const item of rows) if (item.legacy) changes.push(drop(item, true));
152
+ } else if (!view.claimable(id, entry)) {
153
+ notices.push(NOTICES.collision(id, file));
154
+ }
155
+ }
156
+ }
157
+
158
+ for (const row of ownRows) {
159
+ if (consumed.has(row)) continue;
160
+ if (!files[row.target]?.ok) {
161
+ if (removing) changes.push(drop(row, true));
162
+ continue;
163
+ }
164
+ const value = view.valueOf(row.target, row.identity);
165
+ if (value === undefined) changes.push(drop(row, true));
166
+ else if (view.matches(row, value)) changes.push(drop(row, false));
167
+ else {
168
+ changes.push(drop(row, true));
169
+ notices.push(NOTICES.released(row.identity, row.target));
170
+ }
171
+ }
172
+
173
+ for (const { id } of view.adoptedRemovals()) {
174
+ const value = view.valueOf(file, id);
175
+ changes.push(base({
176
+ target: file, operation: 'remove', identity: id, ownershipIdentity: identityFor(id),
177
+ before: entryFingerprint(value), fingerprint: entryFingerprint(value),
178
+ }));
179
+ }
180
+
181
+ return { changes: changes.sort(orderOf(selected, adoptable)), conflicts, notices };
182
+ }
183
+
184
+ /** Apply one file's planned changes to the server map read now. Each change goes ahead only while
185
+ * its entry still holds what plan saw, or already holds the change's end state, which makes two
186
+ * harnesses' changes to one shared entry in one run idempotent. Release changes touch nothing. */
187
+ function applyMcpEntries(servers: any, changes: any[]): any {
188
+ const next = { ...(servers || {}) };
189
+ for (const change of changes) {
190
+ if (change.release) continue;
191
+ const current = next[change.identity];
192
+ const settled = change.operation === 'remove' ? current === undefined : sameValue(current, change.entry);
193
+ if (!settled && fingerprintOrNull(current) !== (change.before ?? null)) {
194
+ throw new Error(`MCP: ${change.target} changed after planning; nothing was written, re-run the command`);
195
+ }
196
+ if (change.operation === 'remove') delete next[change.identity];
197
+ else next[change.identity] = change.entry;
198
+ }
199
+ return next;
200
+ }
201
+
202
+ /**
203
+ * Statuses and ledger resources for one harness's MCP entries. `files` is read after apply,
204
+ * `snapshot` is what plan read: an entry plan found holding the user's value stays the user's,
205
+ * whatever it holds now.
206
+ */
207
+ function verifyMcpEntries({ file, files, snapshot, selected = [], adoptable = [], ownRows = [], foreignRows = [], removing = false,
208
+ identityFor, assetId, renderer, label, harness, sourceVersion = 'unknown' }: any): any {
209
+ const now = ownershipView({ file, files, selected, adoptable, ownRows, foreignRows });
210
+ const then = ownershipView({ file, files: snapshot, selected, adoptable, ownRows, foreignRows });
211
+ const statuses: any[] = [];
212
+ const resources: any[] = [];
213
+ const conflicts: string[] = [];
214
+ const report = (id: string, target: string, ownershipIdentity: any, status: string) => statuses.push({
215
+ harness, assetId, capability: 'mcp', identity: id, target, ownershipIdentity, status,
216
+ });
217
+
218
+ if (!removing) {
219
+ for (const target of Object.keys(files).filter((item) => !files[item].ok).sort()) conflicts.push(refusal(label, target, files[target].reason));
220
+ }
221
+
222
+ const consumed = new Set<any>();
223
+ if (!removing) {
224
+ for (const { id, entry } of selected) {
225
+ for (const row of now.rowsFor(id)) consumed.add(row);
226
+ if (!files[file]?.ok) continue;
227
+ const before = then.valueOf(file, id);
228
+ const row = then.rowFor(id);
229
+ const usersBefore = before !== undefined && (row ? !then.matches(row, before) : !then.claimable(id, entry));
230
+ const value = now.valueOf(file, id);
231
+ if (usersBefore) report(id, file, identityFor(id), 'not-managed');
232
+ else if (sameValue(value, entry)) {
233
+ report(id, file, identityFor(id), 'managed');
234
+ resources.push({
235
+ assetId, target: file, ownershipIdentity: identityFor(id), kind: 'mcp-server', identity: id,
236
+ fingerprint: entryFingerprint(value), sourceVersion, projection: { renderer },
237
+ });
238
+ } else report(id, file, identityFor(id), 'missing');
239
+ }
240
+ }
241
+
242
+ const leftover = (value: any, matching: boolean, target: string) => {
243
+ if (!files[target]?.ok) return 'not-managed';
244
+ if (value === undefined) return 'absent';
245
+ return matching ? 'retained' : 'not-managed';
246
+ };
247
+ for (const row of ownRows) {
248
+ if (consumed.has(row)) continue;
249
+ const value = now.valueOf(row.target, row.identity);
250
+ report(row.identity, row.target, row.ownershipIdentity, leftover(value, now.matches(row, value), row.target));
251
+ }
252
+ if (removing) {
253
+ for (const { id, entry } of then.adoptedRemovals()) {
254
+ const value = now.valueOf(file, id);
255
+ report(id, file, identityFor(id), leftover(value, sameValue(value, entry), file));
256
+ }
257
+ }
258
+ return { statuses, resources, conflicts };
259
+ }
260
+
261
+ /** The ids DoFlow owns in this harness's MCP file now, in rendering order: those an own row matches,
262
+ * and, while the harness holds no row, adoptable entries equal to DoFlow's rendering. A file that
263
+ * cannot be read contributes none. */
264
+ function ownedMcpIds({ file, files, selected = [], adoptable = [], ownRows = [] }: any): string[] {
265
+ const view = ownershipView({ file, files, selected, adoptable, ownRows });
266
+ const owned = new Set<string>(ownRows.filter((row: any) => view.matches(row, view.valueOf(row.target, row.identity))).map((row: any) => row.identity));
267
+ if (!ownRows.length) {
268
+ for (const { id, entry } of adoptable) if (sameValue(view.valueOf(file, id), entry)) owned.add(id);
269
+ }
270
+ const order: string[] = [...view.rendered.keys()];
271
+ return [...order.filter((id) => owned.has(id)), ...[...owned].filter((id) => !order.includes(id)).sort()];
272
+ }
273
+
274
+ function isSymlink(file: string, fsImpl: any): boolean {
275
+ try { return fsImpl.lstatSync(file).isSymbolicLink(); } catch { return false; }
276
+ }
277
+
278
+ /** A symlinked MCP file is written through to the file it points at, so the link stays a link. */
279
+ function writePath(file: string, fsImpl: any): string {
280
+ if (!isSymlink(file, fsImpl)) return file;
281
+ try { return fsImpl.realpathSync(file); } catch { return path.resolve(path.dirname(file), fsImpl.readlinkSync(file)); }
282
+ }
283
+
284
+ /** Write a JSON document atomically, keeping the existing file's permission bits: an MCP file kept
285
+ * private for its tokens stays so. Creates missing directories; never deletes a file. */
286
+ function writeMcpJson(file: string, doc: any, { fsImpl = fs }: { fsImpl?: any } = {}): string {
287
+ const dest = writePath(file, fsImpl);
288
+ fsImpl.mkdirSync(path.dirname(dest), { recursive: true });
289
+ const mode = fsImpl.existsSync(dest) ? fsImpl.statSync(dest).mode & 0o7777 : null;
290
+ const temp = path.join(path.dirname(dest), `.${path.basename(dest)}.${process.pid}.${Date.now()}.tmp`);
291
+ try {
292
+ fsImpl.writeFileSync(temp, `${JSON.stringify(doc, null, 2)}\n`, { encoding: 'utf8', flag: 'wx', ...(mode === null ? {} : { mode }) });
293
+ if (mode !== null) fsImpl.chmodSync(temp, mode);
294
+ fsImpl.renameSync(temp, dest);
295
+ } finally {
296
+ if (fsImpl.existsSync(temp)) fsImpl.rmSync(temp, { force: true });
297
+ }
298
+ return dest;
299
+ }
300
+
301
+ /**
302
+ * Carry out an adapter's `kind: 'mcp-server'` changes: one fresh read and one write per file, with
303
+ * every file's next document computed before the first write. An emptied container is kept as `{}`
304
+ * or its member deleted, as the harness expects. Returns the number of files written.
305
+ */
306
+ function writeMcpEntries(changes: any[], { container, keepEmptyContainer = false, fsImpl = fs }: { container?: any, keepEmptyContainer?: boolean, fsImpl?: any } = {}): number {
307
+ const byFile = new Map<string, any[]>();
308
+ for (const change of changes) {
309
+ if (change.kind !== 'mcp-server' || change.release) continue;
310
+ if (!byFile.has(change.target)) byFile.set(change.target, []);
311
+ byFile.get(change.target)!.push(change);
312
+ }
313
+ const writes: [string, any][] = [];
314
+ for (const [file, group] of byFile) {
315
+ const read = readMcpFile(file, container, { fsImpl });
316
+ if (!read.ok) throw new Error(`MCP: ${file} changed after planning; nothing was written, re-run the command`);
317
+ const servers = applyMcpEntries(read.servers, group);
318
+ if (entryFingerprint(servers) === entryFingerprint(read.servers ?? {})) continue;
319
+ const doc = { ...(read.doc ?? {}) };
320
+ if (Object.keys(servers).length || keepEmptyContainer) doc[container] = servers;
321
+ else delete doc[container];
322
+ writes.push([file, doc]);
323
+ }
324
+ for (const [file, doc] of writes) writeMcpJson(file, doc, { fsImpl });
325
+ return writes.length;
326
+ }
327
+
328
+ module.exports = {
329
+ NOTICES, entryFingerprint, readMcpFiles, planMcpEntries, applyMcpEntries, verifyMcpEntries, ownedMcpIds,
330
+ writeMcpJson, writeMcpEntries,
331
+ };