@khoavu882/doflow 2.0.0-beta.4 → 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 (497) hide show
  1. package/README.md +12 -11
  2. package/bin/doflow.js +21 -11
  3. package/core/.antigravity-plugin/plugin.json +1 -3
  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/mcp-tool-guard.sh +7 -17
  9. package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
  10. package/core/harnesses/claude/hooks/post-compact.sh +35 -32
  11. package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
  12. package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
  13. package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
  14. package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
  15. package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
  16. package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
  17. package/core/harnesses/claude/hooks/session-end.sh +23 -10
  18. package/core/harnesses/claude/hooks/session-start.sh +5 -3
  19. package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
  20. package/core/harnesses/claude/hooks/stop-check.sh +5 -3
  21. package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
  22. package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
  23. package/core/harnesses/claude/settings/settings.json +18 -0
  24. package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
  25. package/core/harnesses/codex/agents/core-implementer.toml +1 -0
  26. package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
  27. package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
  28. package/core/harnesses/codex/agents/research-writer.toml +1 -1
  29. package/core/harnesses/codex/agents/reviewer.toml +10 -0
  30. package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
  31. package/core/harnesses/codex/agents/system-architect.toml +1 -1
  32. package/core/harnesses/codex/hooks/lib.sh +44 -25
  33. package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
  34. package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
  35. package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
  36. package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
  37. package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
  38. package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
  39. package/core/harnesses/codex/hooks/session-start.sh +5 -3
  40. package/core/harnesses/codex/hooks/stop-check.sh +6 -5
  41. package/core/harnesses/codex/hooks/subagent-audit.sh +18 -6
  42. package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
  43. package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
  44. package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
  45. package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
  46. package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
  47. package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
  48. package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
  49. package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
  50. package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
  51. package/core/harnesses/copilot/hooks/doflow.json +57 -0
  52. package/core/harnesses/kiro/agents/doflow.json +1 -1
  53. package/core/harnesses/kiro/hooks/lib.sh +26 -6
  54. package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +21 -5
  55. package/core/harnesses/kiro/hooks/pre-bash-guard.sh +21 -5
  56. package/core/harnesses/kiro/hooks/pre-implement-gate.sh +21 -5
  57. package/core/harnesses/kiro/hooks/session-start.sh +12 -5
  58. package/core/harnesses/kiro/hooks/stop-check.sh +22 -30
  59. package/core/harnesses/pi/extensions/doflow-guard.js +167 -0
  60. package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -12
  61. package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
  62. package/core/harnesses/shared/hooks/bridge/bridge.sh +277 -0
  63. package/core/harnesses/shared/hooks/bridge/envelope.jq +129 -0
  64. package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
  65. package/core/harnesses/shared/hooks/bridge/respond.sh +70 -0
  66. package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
  67. package/core/harnesses/shared/hooks/policies/capture-failure.sh +51 -16
  68. package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
  69. package/core/harnesses/shared/hooks/policies/contract.sh +78 -0
  70. package/core/harnesses/shared/hooks/policies/deny-json.sh +35 -9
  71. package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
  72. package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
  73. package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
  74. package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
  75. package/core/harnesses/shared/hooks/policies/lib.sh +65 -40
  76. package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +48 -35
  77. package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +284 -33
  78. package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +180 -110
  79. package/core/harnesses/shared/hooks/policies/session-context.sh +66 -7
  80. package/core/harnesses/shared/hooks/policies/stop-check.sh +61 -23
  81. package/core/harnesses/shared/hooks/policies/subagent-audit.sh +39 -6
  82. package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
  83. package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +97 -159
  84. package/core/harnesses/shared/hooks/stream-hook-runner.js +114 -187
  85. package/core/harnesses/shared/locator/doflow-run +2 -3
  86. package/core/registry/advice.json +3 -3
  87. package/core/registry/assets.json +72 -80
  88. package/core/registry/capabilities.json +12 -0
  89. package/core/registry/contracts.json +60 -33
  90. package/core/registry/contribution-points.json +32 -0
  91. package/core/registry/gates.json +32 -0
  92. package/core/registry/guidance-caps.json +40 -0
  93. package/core/registry/harnesses.json +1542 -277
  94. package/core/registry/lifecycle.json +2837 -37
  95. package/core/registry/mcp.json +5 -1
  96. package/core/registry/models.json +7 -1
  97. package/core/registry/package-templates/README.md +19 -0
  98. package/core/registry/package-templates/agent/files/agent.md +9 -0
  99. package/core/registry/package-templates/agent/template.json +4 -0
  100. package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
  101. package/core/registry/package-templates/capability-provider/template.json +11 -0
  102. package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
  103. package/core/registry/package-templates/debate-preset/template.json +4 -0
  104. package/core/registry/package-templates/review-preset/files/preset.json +30 -0
  105. package/core/registry/package-templates/review-preset/template.json +4 -0
  106. package/core/registry/package-templates/skill/files/SKILL.md +8 -0
  107. package/core/registry/package-templates/skill/template.json +4 -0
  108. package/core/registry/package-templates/worker/files/worker.json +92 -0
  109. package/core/registry/package-templates/worker/template.json +11 -0
  110. package/core/registry/packages/doflow/doflow-package.json +15 -0
  111. package/core/registry/packages/doflow/presets/debate-3.json +26 -0
  112. package/core/registry/protocols.json +61 -0
  113. package/core/registry/routes.json +17 -0
  114. package/core/registry/rules.json +431 -0
  115. package/core/registry/settings.json +276 -0
  116. package/core/registry/storage.json +701 -30
  117. package/core/registry/telemetry.json +236 -0
  118. package/core/registry/transcripts.json +142 -0
  119. package/core/registry/verification.json +76 -1
  120. package/core/registry/workflows.json +55 -0
  121. package/core/shared/agent-specs/core-implementer.md +3 -0
  122. package/core/shared/agent-specs/delivery-lead.md +68 -0
  123. package/core/shared/agent-specs/quality-guardian.md +5 -1
  124. package/core/shared/agent-specs/research-writer.md +10 -3
  125. package/core/shared/agent-specs/reviewer.md +53 -0
  126. package/core/shared/agent-specs/spec-analyst.md +5 -6
  127. package/core/shared/agent-specs/system-architect.md +5 -1
  128. package/core/shared/guidance/DOFLOW_CORE.md +1 -5
  129. package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
  130. package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
  131. package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
  132. package/core/shared/guidance/pointers/codex.md +1 -4
  133. package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
  134. package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
  135. package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
  136. package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
  137. package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
  138. package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
  139. package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
  140. package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
  141. package/core/shared/guidance/rules/RULES.md +45 -0
  142. package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
  143. package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
  144. package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
  145. package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
  146. package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
  147. package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
  148. package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
  149. package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
  150. package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
  151. package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
  152. package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
  153. package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
  154. package/core/shared/scripts/doflow/bin/doflow-run +154 -35
  155. package/core/shared/skills/do/SKILL.md +12 -10
  156. package/core/shared/skills/do/references/advice_calls.md +26 -0
  157. package/core/shared/skills/do/references/pm_routing.md +1 -2
  158. package/core/shared/skills/do/references/program_mode.md +31 -0
  159. package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
  160. package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
  161. package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
  162. package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
  163. package/core/shared/skills/do-code-review/SKILL.md +41 -144
  164. package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
  165. package/core/shared/skills/do-code-review/references/tools.md +90 -0
  166. package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
  167. package/core/shared/skills/do-design/SKILL.md +24 -23
  168. package/core/shared/skills/do-diagnose/SKILL.md +14 -4
  169. package/core/shared/skills/do-document/SKILL.md +11 -1
  170. package/core/shared/skills/do-document/references/deep_research.md +1 -2
  171. package/core/shared/skills/do-document/references/embedded-research.md +18 -6
  172. package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
  173. package/core/shared/skills/do-execute-plan/SKILL.md +17 -59
  174. package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
  175. package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
  176. package/core/shared/skills/do-execute-plan/references/readiness_gate.md +28 -1
  177. package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
  178. package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
  179. package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
  180. package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
  181. package/core/shared/skills/do-flow/SKILL.md +8 -9
  182. package/core/shared/skills/do-flow/references/task_classes.md +2 -2
  183. package/core/shared/skills/do-git/SKILL.md +4 -0
  184. package/core/shared/skills/do-implement/SKILL.md +7 -9
  185. package/core/shared/skills/do-plan/SKILL.md +29 -19
  186. package/core/shared/skills/do-test/SKILL.md +7 -4
  187. package/core/shared/templates/doflow/constitution-template.md +9 -3
  188. package/core/shared/templates/doflow/data-model-template.md +1 -1
  189. package/core/shared/templates/doflow/design-template.md +113 -16
  190. package/core/shared/templates/doflow/plan-template.md +11 -10
  191. package/core/shared/templates/doflow/question-log-template.md +14 -2
  192. package/core/shared/templates/doflow/requirement-template.md +1 -1
  193. package/core/worker-evidence/antigravity/checks.json +14 -0
  194. package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
  195. package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
  196. package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
  197. package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
  198. package/core/worker-evidence/codex/checks.json +38 -0
  199. package/package.json +10 -6
  200. package/src/adapters/antigravity/index.js +226 -113
  201. package/src/adapters/claude/index.js +39 -5
  202. package/src/adapters/codex/agents.js +25 -15
  203. package/src/adapters/codex/hooks.js +40 -5
  204. package/src/adapters/codex/index.js +100 -22
  205. package/src/adapters/codex/native-projection.js +6 -2
  206. package/src/adapters/copilot/index.js +58 -23
  207. package/src/adapters/copy-tree.js +294 -48
  208. package/src/adapters/guidance-manifest.js +71 -0
  209. package/src/adapters/guidance-pointer.js +19 -0
  210. package/src/adapters/hook-commands.js +6 -10
  211. package/src/adapters/index.js +1 -0
  212. package/src/adapters/kiro/index.js +38 -13
  213. package/src/adapters/opencode/index.js +8 -8
  214. package/src/adapters/pi/hooks.js +120 -0
  215. package/src/adapters/pi/index.js +48 -16
  216. package/src/adapters/resolve-source.js +26 -2
  217. package/src/cli/commands/install.js +3 -2
  218. package/src/cli/commands/reconcile.js +53 -9
  219. package/src/cli/commands/remove.js +2 -2
  220. package/src/cli/commands/rollback.js +6 -3
  221. package/src/cli/commands/self-update.js +18 -9
  222. package/src/cli/commands/status.js +21 -2
  223. package/src/cli/commands/ui.js +99 -0
  224. package/src/cli/commands/update.js +3 -2
  225. package/src/cli/index.js +338 -33
  226. package/src/cli/runtime-commands.js +243 -52
  227. package/src/cli/shared.js +0 -2
  228. package/src/helper/git.js +1 -1
  229. package/src/helper/guardrails.js +1 -1
  230. package/src/helper/marker-merge.js +31 -13
  231. package/src/helper/package-ids.js +37 -0
  232. package/src/helper/semver.js +94 -0
  233. package/src/install/backup.js +105 -15
  234. package/src/install/context.js +1 -1
  235. package/src/install/targets.js +31 -16
  236. package/src/lifecycle/coverage.js +74 -0
  237. package/src/lifecycle/hook-step.js +61 -0
  238. package/src/lifecycle/hook-tier.js +160 -0
  239. package/src/lifecycle/index.js +434 -86
  240. package/src/lifecycle/retired-harnesses.js +318 -0
  241. package/src/lifecycle/view.js +35 -15
  242. package/src/registry/index.js +686 -32
  243. package/src/registry/worker-ids.js +45 -0
  244. package/src/release/build-package.js +0 -3
  245. package/src/release/docs-blocks.js +492 -0
  246. package/src/release/preflight.js +425 -0
  247. package/src/release/rehearse.js +401 -0
  248. package/src/release/release-workflow.js +733 -0
  249. package/src/release/sync-plugin-versions.js +43 -7
  250. package/src/runtime/advice/bench-gate.js +25 -0
  251. package/src/runtime/advice/cli.js +59 -16
  252. package/src/runtime/advice/client.js +32 -9
  253. package/src/runtime/advice/config.js +98 -133
  254. package/src/runtime/advice/doctor.js +1 -1
  255. package/src/runtime/advice/elevation.js +97 -0
  256. package/src/runtime/advice/endpoint-guard.js +9 -3
  257. package/src/runtime/advice/mode.js +37 -0
  258. package/src/runtime/advice/record.js +18 -5
  259. package/src/runtime/advice/registry.js +4 -1
  260. package/src/runtime/advice/shadow-config.js +229 -0
  261. package/src/runtime/advice/shadow-dispatcher.js +276 -0
  262. package/src/runtime/brief-rules.js +81 -0
  263. package/src/runtime/brief-tools.js +111 -34
  264. package/src/runtime/candidate.js +514 -0
  265. package/src/runtime/capabilities/executor.js +450 -0
  266. package/src/runtime/capabilities/loopback.js +41 -0
  267. package/src/runtime/capabilities/sanitizer.js +88 -0
  268. package/src/runtime/capability-router.js +135 -3
  269. package/src/runtime/checkouts.js +73 -11
  270. package/src/runtime/claims.js +27 -12
  271. package/src/runtime/cli-result.js +11 -4
  272. package/src/runtime/cli.js +221 -277
  273. package/src/runtime/config-home.js +42 -0
  274. package/src/runtime/context/arbitrate.js +767 -0
  275. package/src/runtime/context/budget.js +203 -0
  276. package/src/runtime/context/compose.js +1367 -0
  277. package/src/runtime/context/delivery-store.js +100 -0
  278. package/src/runtime/context/emission-rules.js +118 -0
  279. package/src/runtime/context/identity.js +227 -0
  280. package/src/runtime/context/mandatory.js +594 -0
  281. package/src/runtime/context/pointer.js +142 -0
  282. package/src/runtime/context/primary-command.js +117 -0
  283. package/src/runtime/context/primary.js +344 -0
  284. package/src/runtime/context/summary-store.js +655 -0
  285. package/src/runtime/context-pack.js +1106 -245
  286. package/src/runtime/decision-register.js +13 -4
  287. package/src/runtime/dispatch/admission.js +392 -0
  288. package/src/runtime/dispatch/attempt-end.js +274 -0
  289. package/src/runtime/dispatch/command.js +628 -0
  290. package/src/runtime/dispatch/controls.js +904 -0
  291. package/src/runtime/dispatch/envelope.js +276 -0
  292. package/src/runtime/dispatch/grants.js +310 -0
  293. package/src/runtime/dispatch/integrate.js +617 -0
  294. package/src/runtime/dispatch/loop.js +1835 -0
  295. package/src/runtime/dispatch/store.js +352 -0
  296. package/src/runtime/dispatch/verify-run.js +201 -0
  297. package/src/runtime/evidence-fields.js +39 -0
  298. package/src/runtime/evidence-ledger.js +41 -7
  299. package/src/runtime/failure/capture.js +3 -1
  300. package/src/runtime/failure/cli.js +25 -9
  301. package/src/runtime/failure/home.js +57 -30
  302. package/src/runtime/failure/store.js +7 -2
  303. package/src/runtime/feature-pointer.js +174 -0
  304. package/src/runtime/feature-resolve.js +13 -2
  305. package/src/runtime/fleet/command.js +77 -0
  306. package/src/runtime/fleet/projects.js +178 -0
  307. package/src/runtime/fleet/tree.js +383 -0
  308. package/src/runtime/freshness.js +77 -10
  309. package/src/runtime/git-memo.js +46 -0
  310. package/src/runtime/guidance/ablation.js +427 -0
  311. package/src/runtime/health.js +565 -17
  312. package/src/runtime/history-compactor.js +13 -3
  313. package/src/runtime/implementation-gate.js +277 -22
  314. package/src/runtime/inventory/coverage.js +1 -1
  315. package/src/runtime/inventory/index.js +1 -1
  316. package/src/runtime/inventory/precedence.js +2 -2
  317. package/src/runtime/inventory/siblings.js +6 -4
  318. package/src/runtime/knowledge/code-corpus.js +277 -0
  319. package/src/runtime/knowledge/code-lexical.js +130 -0
  320. package/src/runtime/knowledge/code-retrieval.js +307 -0
  321. package/src/runtime/knowledge/code-validation.js +106 -0
  322. package/src/runtime/knowledge/gp3-gate.js +74 -0
  323. package/src/runtime/knowledge/graph-adapter.js +288 -0
  324. package/src/runtime/knowledge/graph-fallback.js +394 -0
  325. package/src/runtime/knowledge/hybrid.js +136 -8
  326. package/src/runtime/knowledge/retrieval.js +34 -1
  327. package/src/runtime/knowledge/rtk-compress.js +77 -0
  328. package/src/runtime/knowledge/semble-bridge.py +106 -0
  329. package/src/runtime/knowledge/semble-lifecycle.js +114 -0
  330. package/src/runtime/knowledge/semble-provider.js +365 -0
  331. package/src/runtime/lifecycle/cli.js +16 -6
  332. package/src/runtime/lifecycle/event-store.js +8 -6
  333. package/src/runtime/lifecycle/followup.js +6 -1
  334. package/src/runtime/lifecycle/overview.js +24 -1
  335. package/src/runtime/lifecycle/report-store.js +8 -10
  336. package/src/runtime/lifecycle/retention.js +95 -31
  337. package/src/runtime/lifecycle/root.js +9 -1
  338. package/src/runtime/lifecycle/status.js +34 -17
  339. package/src/runtime/lifecycle/store-upkeep.js +56 -7
  340. package/src/runtime/mask.js +134 -7
  341. package/src/runtime/mcp-consultations.js +40 -6
  342. package/src/runtime/model-router.js +79 -7
  343. package/src/runtime/models/catalogue.js +191 -0
  344. package/src/runtime/models/command.js +153 -0
  345. package/src/runtime/off-words.js +12 -0
  346. package/src/runtime/outcome.js +3 -3
  347. package/src/runtime/packages/command.js +1009 -0
  348. package/src/runtime/packages/contributions.js +116 -0
  349. package/src/runtime/packages/digest.js +132 -0
  350. package/src/runtime/packages/fetch.js +182 -0
  351. package/src/runtime/packages/grants.js +192 -0
  352. package/src/runtime/packages/index-file.js +134 -0
  353. package/src/runtime/packages/instruction.js +90 -0
  354. package/src/runtime/packages/manifest.js +331 -0
  355. package/src/runtime/packages/points.js +477 -0
  356. package/src/runtime/packages/programs.js +216 -0
  357. package/src/runtime/packages/scaffold.js +277 -0
  358. package/src/runtime/packages/source.js +90 -0
  359. package/src/runtime/packages/state.js +164 -0
  360. package/src/runtime/packages/store.js +449 -0
  361. package/src/runtime/packages/tar.js +106 -0
  362. package/src/runtime/packages/view.js +406 -0
  363. package/src/runtime/plan-check.js +59 -0
  364. package/src/runtime/plan-content.js +324 -0
  365. package/src/runtime/policy-init.js +118 -0
  366. package/src/runtime/profiles/doctor.js +96 -0
  367. package/src/runtime/profiles/resolve.js +244 -0
  368. package/src/runtime/profiles/rollback.js +254 -0
  369. package/src/runtime/profiles/sampler.js +41 -0
  370. package/src/runtime/readiness-record.js +16 -11
  371. package/src/runtime/readiness.js +127 -16
  372. package/src/runtime/research-request.js +50 -25
  373. package/src/runtime/retrieval-plan.js +402 -73
  374. package/src/runtime/retrieval-record.js +293 -0
  375. package/src/runtime/review/command.js +246 -0
  376. package/src/runtime/review/dominance.js +68 -0
  377. package/src/runtime/review/findings.js +434 -0
  378. package/src/runtime/review/identity.js +255 -0
  379. package/src/runtime/review/protocol-command.js +109 -0
  380. package/src/runtime/review/protocols.js +405 -0
  381. package/src/runtime/review/resolve-protocol.js +302 -0
  382. package/src/runtime/review/start.js +530 -0
  383. package/src/runtime/roadmap/facts.js +479 -0
  384. package/src/runtime/roadmap/gates.js +270 -0
  385. package/src/runtime/roadmap/loop.js +1636 -0
  386. package/src/runtime/roadmap/merge.js +381 -0
  387. package/src/runtime/roadmap/rows.js +1113 -0
  388. package/src/runtime/roadmap/seed.js +951 -0
  389. package/src/runtime/rules-report.js +336 -0
  390. package/src/runtime/scaffold/artifacts.js +63 -9
  391. package/src/runtime/scaffold/generate.js +21 -9
  392. package/src/runtime/settings/autopilot.js +106 -0
  393. package/src/runtime/settings/cli.js +280 -0
  394. package/src/runtime/settings/config-write.js +314 -0
  395. package/src/runtime/settings/files.js +271 -0
  396. package/src/runtime/settings/legacy.js +154 -0
  397. package/src/runtime/settings/lexical.js +56 -0
  398. package/src/runtime/settings/prepared-run.js +269 -0
  399. package/src/runtime/settings/project-layers.js +118 -0
  400. package/src/runtime/settings/refs.js +288 -0
  401. package/src/runtime/settings/registry.js +553 -0
  402. package/src/runtime/settings/resolve.js +713 -0
  403. package/src/runtime/settings/shared.js +37 -0
  404. package/src/runtime/settings/worker-billing.js +107 -0
  405. package/src/runtime/settings/write.js +269 -0
  406. package/src/runtime/slot-command.js +78 -0
  407. package/src/runtime/slots.js +671 -0
  408. package/src/runtime/source-version.js +290 -0
  409. package/src/runtime/state-root.js +217 -0
  410. package/src/runtime/storage/cli.js +12 -5
  411. package/src/runtime/storage/engine.js +9 -2
  412. package/src/runtime/storage/registry.js +14 -1
  413. package/src/runtime/storage/roots.js +66 -16
  414. package/src/runtime/storage/rules.js +82 -10
  415. package/src/runtime/storage/upkeep.js +10 -2
  416. package/src/runtime/storage/work-status.js +245 -26
  417. package/src/runtime/task-attempts.js +589 -69
  418. package/src/runtime/task-classifier.js +47 -11
  419. package/src/runtime/task-graph.js +373 -0
  420. package/src/runtime/task-run.js +778 -0
  421. package/src/runtime/task-scope.js +202 -56
  422. package/src/runtime/task-sources.js +147 -0
  423. package/src/runtime/task-state.js +440 -65
  424. package/src/runtime/team/admission.js +301 -0
  425. package/src/runtime/team/envelope.js +324 -0
  426. package/src/runtime/team/review-guard.js +156 -0
  427. package/src/runtime/trace/analyze.js +427 -0
  428. package/src/runtime/trace/baseline.js +770 -0
  429. package/src/runtime/trace/ledger.js +63 -140
  430. package/src/runtime/trace/otlp-export.js +568 -0
  431. package/src/runtime/trace/otlp-map.js +481 -0
  432. package/src/runtime/trace/spans.js +745 -0
  433. package/src/runtime/trace/telemetry.js +225 -0
  434. package/src/runtime/trace/views.js +1 -0
  435. package/src/runtime/transcripts/command.js +98 -0
  436. package/src/runtime/transcripts/cursor.js +326 -0
  437. package/src/runtime/transcripts/read.js +126 -0
  438. package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
  439. package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
  440. package/src/runtime/transcripts/readers/copilot-events.js +90 -0
  441. package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
  442. package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
  443. package/src/runtime/transcripts/registry.js +161 -0
  444. package/src/runtime/transcripts/stats.js +161 -0
  445. package/src/runtime/verification/check-key.js +628 -0
  446. package/src/runtime/verification/contract-runner.js +546 -11
  447. package/src/runtime/verification/engine.js +499 -9
  448. package/src/runtime/verification/impact.js +617 -0
  449. package/src/runtime/verification/inflight.js +205 -0
  450. package/src/runtime/verification/registry.js +176 -0
  451. package/src/runtime/verification/reuse.js +184 -0
  452. package/src/runtime/verification/telemetry-emit.js +254 -0
  453. package/src/runtime/verification/test-selection.js +67 -7
  454. package/src/runtime/worker/active.js +90 -0
  455. package/src/runtime/worker/cancel.js +222 -0
  456. package/src/runtime/worker/catalogue.js +122 -0
  457. package/src/runtime/worker/command.js +677 -0
  458. package/src/runtime/worker/evidence.js +288 -0
  459. package/src/runtime/worker/launch.js +288 -0
  460. package/src/runtime/worker/models.js +137 -0
  461. package/src/runtime/worker/parsers.js +218 -0
  462. package/src/runtime/worker/probes/index.js +706 -0
  463. package/src/runtime/worker/process-tree.js +415 -0
  464. package/src/runtime/worker/quota.js +43 -0
  465. package/src/runtime/worker/readiness.js +713 -0
  466. package/src/runtime/worker/run-store.js +166 -0
  467. package/src/runtime/worker/supervisor.js +541 -0
  468. package/src/runtime/worker/worktree-check.js +252 -0
  469. package/src/runtime/workflow-engine.js +5 -1
  470. package/src/runtime/workflow-orchestrator.js +578 -63
  471. package/src/runtime/worktree.js +149 -22
  472. package/src/state/index.js +1 -1
  473. package/src/state/lockfile.js +64 -10
  474. package/src/state/run-lock.js +1 -1
  475. package/types/node-commonjs.d.ts +106 -7
  476. package/core/.antigravity-plugin/hooks.json +0 -39
  477. package/core/harnesses/gemini/hooks/hooks.json +0 -77
  478. package/core/harnesses/gemini/hooks/lib.sh +0 -302
  479. package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -21
  480. package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
  481. package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -21
  482. package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
  483. package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -22
  484. package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
  485. package/core/harnesses/gemini/hooks/session-end.sh +0 -5
  486. package/core/harnesses/gemini/hooks/session-start.sh +0 -5
  487. package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
  488. package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
  489. package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
  490. package/core/harnesses/shared/hooks/hooks.json +0 -47
  491. package/core/shared/guidance/FLAGS.md +0 -25
  492. package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
  493. package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
  494. package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
  495. package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
  496. package/src/adapters/gemini/hooks.js +0 -210
  497. package/src/adapters/gemini/index.js +0 -390
@@ -0,0 +1,568 @@
1
+ 'use strict';
2
+
3
+ // TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
4
+
5
+ /**
6
+ * `trace export --otlp-http` (091 IC-006, IC-007, IC-009): resolves OTLP environment,
7
+ * maps spans through `otlp-map.ts`, and POSTs OTLP/HTTP JSON requests bounded to 20 requests.
8
+ *
9
+ * Privacy and secrecy: never prints, logs, or stores endpoints, headers, or response bodies.
10
+ * Errors name variables and HTTP status codes only.
11
+ */
12
+
13
+ const nodeFs = require('node:fs');
14
+ const { TextEncoder, TextDecoder } = require('node:util');
15
+ const path = require('node:path');
16
+ const { projectSpans } = require('./spans.js');
17
+ const otlpMap = require('./otlp-map.js');
18
+ const { finish } = require('./render.js');
19
+ const { REPO_ROOT } = require('../../helper/repo-root.js');
20
+
21
+ const RUN_ARG = /^[A-Za-z0-9][A-Za-z0-9._:-]*(?:\/[A-Za-z0-9._:-]+){0,2}$/;
22
+ const cmp = (a , b ) => (a < b ? -1 : a > b ? 1 : 0);
23
+
24
+ /** Object keys sorted at every level, ensuring deterministic JSON output. */
25
+ function sorted(value ) {
26
+ if (Array.isArray(value)) return value.map(sorted);
27
+ if (value && typeof value === 'object') {
28
+ return Object.fromEntries(
29
+ Object.keys(value)
30
+ .sort(cmp)
31
+ .map((k) => [k, sorted(value[k])])
32
+ );
33
+ }
34
+ return value;
35
+ }
36
+
37
+ /**
38
+ * Resolves OTLP environment variables per IC-006:
39
+ * - empty values after trimming count as unset; non-empty TRACES_* values override base values
40
+ * - endpoint: traces endpoint as-is (fragments rejected), else base endpoint with /v1/traces
41
+ * appended to its pathname while preserving its query; fragments are rejected
42
+ * - headers: comma-separated k=v pairs, percent-decoded; empty members are skipped and names
43
+ * and decoded values are validated
44
+ * - timeout: integer ms, default 10000 and max 30000
45
+ *
46
+ * Errors name the variable only, never echoing the value.
47
+ */
48
+ function resolveOtlpEnv(env = process.env)
49
+
50
+
51
+
52
+ {
53
+ const tracesEndpoint = env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
54
+ const baseEndpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT;
55
+
56
+ let endpoint = '';
57
+
58
+ if (tracesEndpoint !== undefined && tracesEndpoint.trim() !== '') {
59
+ const endpointVar = 'OTEL_EXPORTER_OTLP_TRACES_ENDPOINT';
60
+ const raw = tracesEndpoint.trim();
61
+ let u ;
62
+ try {
63
+ u = new URL(raw);
64
+ } catch {
65
+ throw new Error(`${endpointVar} is invalid URL`);
66
+ }
67
+ if (u.protocol !== 'http:' && u.protocol !== 'https:') {
68
+ throw new Error(`${endpointVar} must use http or https scheme`);
69
+ }
70
+ if (u.username || u.password) {
71
+ throw new Error(`${endpointVar} must not contain user info`);
72
+ }
73
+ if (u.hash !== '' || raw.includes('#')) {
74
+ throw new Error(`${endpointVar} must not contain a fragment`);
75
+ }
76
+ endpoint = u.href;
77
+ } else if (baseEndpoint !== undefined && baseEndpoint.trim() !== '') {
78
+ const endpointVar = 'OTEL_EXPORTER_OTLP_ENDPOINT';
79
+ const raw = baseEndpoint.trim();
80
+ let u ;
81
+ try {
82
+ u = new URL(raw);
83
+ } catch {
84
+ throw new Error(`${endpointVar} is invalid URL`);
85
+ }
86
+ if (u.protocol !== 'http:' && u.protocol !== 'https:') {
87
+ throw new Error(`${endpointVar} must use http or https scheme`);
88
+ }
89
+ if (u.username || u.password) {
90
+ throw new Error(`${endpointVar} must not contain user info`);
91
+ }
92
+ if (u.hash !== '' || raw.includes('#')) {
93
+ throw new Error(`${endpointVar} must not contain a fragment`);
94
+ }
95
+ u.pathname = u.pathname.replace(/\/+$/, '') + '/v1/traces';
96
+ endpoint = u.href;
97
+ } else {
98
+ throw new Error('missing endpoint: set OTEL_EXPORTER_OTLP_TRACES_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT');
99
+ }
100
+
101
+ const tracesHeaders = env.OTEL_EXPORTER_OTLP_TRACES_HEADERS;
102
+ const baseHeaders = env.OTEL_EXPORTER_OTLP_HEADERS;
103
+ const headers = {};
104
+ const useTracesHeaders = tracesHeaders !== undefined && tracesHeaders.trim() !== '';
105
+ const useBaseHeaders = baseHeaders !== undefined && baseHeaders.trim() !== '';
106
+
107
+ if (useTracesHeaders || useBaseHeaders) {
108
+ const isTraces = useTracesHeaders;
109
+ const headerVar = isTraces ? 'OTEL_EXPORTER_OTLP_TRACES_HEADERS' : 'OTEL_EXPORTER_OTLP_HEADERS';
110
+ const raw = (isTraces ? tracesHeaders : baseHeaders) ?? '';
111
+ const pairs = raw.split(',');
112
+ for (const pair of pairs) {
113
+ if (pair.trim() === '') continue;
114
+ const eqIdx = pair.indexOf('=');
115
+ if (eqIdx === -1) {
116
+ throw new Error(`${headerVar} missing '='`);
117
+ }
118
+ const key = pair.slice(0, eqIdx).trim();
119
+ const val = pair.slice(eqIdx + 1).trim();
120
+ if (!key) {
121
+ throw new Error(`${headerVar} has empty key`);
122
+ }
123
+ if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(key)) {
124
+ throw new Error(`${headerVar} has invalid header name`);
125
+ }
126
+ let decoded ;
127
+ try {
128
+ decoded = decodeURIComponent(val);
129
+ } catch {
130
+ throw new Error(`${headerVar} has bad escape sequence`);
131
+ }
132
+ if (/[\r\n\0]/.test(decoded)) {
133
+ throw new Error(`${headerVar} has invalid header value`);
134
+ }
135
+ headers[key] = decoded;
136
+ }
137
+ }
138
+
139
+ const tracesTimeout = env.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT;
140
+ const baseTimeout = env.OTEL_EXPORTER_OTLP_TIMEOUT;
141
+ let timeoutMs = 10000;
142
+ const useTracesTimeout = tracesTimeout !== undefined && tracesTimeout.trim() !== '';
143
+ const useBaseTimeout = baseTimeout !== undefined && baseTimeout.trim() !== '';
144
+
145
+ if (useTracesTimeout || useBaseTimeout) {
146
+ const isTraces = useTracesTimeout;
147
+ const timeoutVar = isTraces ? 'OTEL_EXPORTER_OTLP_TRACES_TIMEOUT' : 'OTEL_EXPORTER_OTLP_TIMEOUT';
148
+ const raw = String(isTraces ? tracesTimeout : baseTimeout).trim();
149
+ if (!/^\d+$/.test(raw)) {
150
+ throw new Error(`${timeoutVar} must be a positive integer`);
151
+ }
152
+ const ms = Number(raw);
153
+ if (!Number.isSafeInteger(ms) || ms < 1) {
154
+ throw new Error(`${timeoutVar} must be a positive integer`);
155
+ }
156
+ timeoutMs = ms > 30000 ? 30000 : ms;
157
+ }
158
+
159
+ return { endpoint, headers, timeoutMs };
160
+ }
161
+
162
+ const MAX_RESPONSE_BODY_BYTES = 65536;
163
+ const RESPONSE_BODY_TOO_LARGE = 'OTLP_RESPONSE_BODY_TOO_LARGE';
164
+
165
+ /** Reads only a bounded response body, never retaining data over the limit. */
166
+ async function readResponseText(res ) {
167
+ const encoder = new TextEncoder();
168
+ if (res.body !== undefined && res.body !== null) {
169
+ const reader = res.body.getReader();
170
+ const chunks = [];
171
+ let totalBytes = 0;
172
+ while (true) {
173
+ const { done, value } = await reader.read();
174
+ if (done) break;
175
+ const chunk = typeof value === 'string' ? encoder.encode(value) : value;
176
+ totalBytes += chunk.byteLength;
177
+ if (totalBytes > MAX_RESPONSE_BODY_BYTES) {
178
+ try {
179
+ await reader.cancel();
180
+ } catch {
181
+ // The body is already known to exceed the cap.
182
+ }
183
+ const err = new Error();
184
+ err.code = RESPONSE_BODY_TOO_LARGE;
185
+ throw err;
186
+ }
187
+ chunks.push(chunk);
188
+ }
189
+
190
+ const bytes = new Uint8Array(totalBytes);
191
+ let offset = 0;
192
+ for (const chunk of chunks) {
193
+ bytes.set(chunk, offset);
194
+ offset += chunk.byteLength;
195
+ }
196
+ return new TextDecoder().decode(bytes);
197
+ }
198
+
199
+ const text = await res.text();
200
+ const bytes = encoder.encode(text);
201
+ if (bytes.byteLength > MAX_RESPONSE_BODY_BYTES) {
202
+ const err = new Error();
203
+ err.code = RESPONSE_BODY_TOO_LARGE;
204
+ throw err;
205
+ }
206
+ return new TextDecoder().decode(bytes);
207
+ }
208
+
209
+ /**
210
+ * The rejected-span count of a parsed 2xx body: 0 when there is no `partialSuccess` or no
211
+ * `rejectedSpans`; null (malformed) for the snake_case `partial_success` form, a non-object
212
+ * `partialSuccess`, or a count that is not a non-negative safe integer (a JSON number, or the
213
+ * proto3 JSON int64 decimal string).
214
+ */
215
+ function partialRejected(body ) {
216
+ if (!body || typeof body !== 'object' || Array.isArray(body)) return 0;
217
+ if (Object.prototype.hasOwnProperty.call(body, 'partial_success')) return null;
218
+ const ps = body.partialSuccess;
219
+ if (ps === undefined || ps === null) return 0;
220
+ if (typeof ps !== 'object' || Array.isArray(ps)) return null;
221
+ const raw = ps.rejectedSpans;
222
+ if (raw === undefined || raw === null) return 0;
223
+ let n ;
224
+ if (typeof raw === 'number') n = raw;
225
+ else if (typeof raw === 'string' && /^(0|[1-9][0-9]*)$/.test(raw)) n = Number(raw);
226
+ else return null;
227
+ return Number.isSafeInteger(n) && n >= 0 ? n : null;
228
+ }
229
+
230
+ function responseReadFailureReason(err ) {
231
+ const chain = [];
232
+ let current = err;
233
+ for (let depth = 0; current && depth < 8; depth++) {
234
+ chain.push(current);
235
+ current = current.cause;
236
+ }
237
+ if (chain.some((item) => item.code === RESPONSE_BODY_TOO_LARGE)) return 'bad-response';
238
+ if (chain.some((item) => item.name === 'TimeoutError' || item.name === 'AbortError')) return 'timeout';
239
+ if (chain.some((item) => typeof item.message === 'string' && /timeout|timed out|aborted/i.test(item.message))) {
240
+ return 'timeout';
241
+ }
242
+ // A rejected response-body read means the response was not received in full.
243
+ return 'connection';
244
+ }
245
+
246
+ /**
247
+ * Posts OTLP requests in order using global fetch (or fetchImpl).
248
+ * Stops at first failure (timeout, connection, bad response, redirect, non-2xx),
249
+ * caps each 2xx response body at 65536 bytes, and reads partialSuccess.rejectedSpans.
250
+ */
251
+ async function sendRequests(
252
+ requests ,
253
+ {
254
+ endpoint,
255
+ headers = {},
256
+ timeoutMs = 10000,
257
+ fetchImpl = (globalThis ).fetch,
258
+ }
259
+
260
+
261
+
262
+
263
+
264
+ )
265
+
266
+
267
+
268
+
269
+
270
+
271
+ {
272
+ if (requests.length === 0) {
273
+ return {
274
+ requests: 0,
275
+ sent: 0,
276
+ rejected: 0,
277
+ status: 'ok',
278
+ httpStatus: null,
279
+ reason: null,
280
+ };
281
+ }
282
+
283
+ const reqHeaders = {};
284
+ for (const [k, v] of Object.entries(headers)) {
285
+ if (k.toLowerCase() !== 'content-type') {
286
+ reqHeaders[k] = v;
287
+ }
288
+ }
289
+ reqHeaders['Content-Type'] = 'application/json';
290
+
291
+ let sent = 0;
292
+ let rejected = 0;
293
+ let hasPartial = false;
294
+ let lastHttpStatus = null;
295
+ const abortSignal = (globalThis ).AbortSignal;
296
+
297
+ for (let i = 0; i < requests.length; i++) {
298
+ const req = requests[i];
299
+ let res ;
300
+ try {
301
+ res = await fetchImpl(endpoint, {
302
+ method: 'POST',
303
+ headers: reqHeaders,
304
+ body: JSON.stringify(req),
305
+ redirect: 'error',
306
+ signal: abortSignal ? abortSignal.timeout(timeoutMs) : undefined,
307
+ });
308
+ } catch (err ) {
309
+ const isTimeout =
310
+ err?.name === 'TimeoutError' ||
311
+ err?.name === 'AbortError' ||
312
+ err?.cause?.name === 'TimeoutError' ||
313
+ (typeof err?.message === 'string' && /timeout/i.test(err.message)) ||
314
+ (typeof err?.cause?.message === 'string' && /timeout/i.test(err.cause.message));
315
+ if (isTimeout) {
316
+ return {
317
+ requests: requests.length,
318
+ sent,
319
+ rejected,
320
+ status: 'failed',
321
+ httpStatus: null,
322
+ reason: 'timeout',
323
+ };
324
+ }
325
+
326
+ const isRedirect =
327
+ (typeof err?.message === 'string' && /redirect/i.test(err.message)) ||
328
+ (typeof err?.cause?.message === 'string' && /redirect/i.test(err.cause.message));
329
+ if (isRedirect) {
330
+ return {
331
+ requests: requests.length,
332
+ sent,
333
+ rejected,
334
+ status: 'failed',
335
+ httpStatus: null,
336
+ reason: 'redirect',
337
+ };
338
+ }
339
+
340
+ const code = err?.code || err?.cause?.code;
341
+ const isConnection =
342
+ code === 'ECONNREFUSED' ||
343
+ code === 'ENOTFOUND' ||
344
+ code === 'ECONNRESET' ||
345
+ code === 'EHOSTUNREACH' ||
346
+ code === 'EPIPE' ||
347
+ code === 'UND_ERR_CONNECT_TIMEOUT' ||
348
+ (typeof err?.message === 'string' && /connect|fetch failed|network|econnrefused/i.test(err.message) && !isTimeout && !isRedirect);
349
+
350
+ return {
351
+ requests: requests.length,
352
+ sent,
353
+ rejected,
354
+ status: 'failed',
355
+ httpStatus: null,
356
+ reason: isConnection ? 'connection' : 'bad-response',
357
+ };
358
+ }
359
+
360
+ if (res.status >= 300 && res.status < 400) {
361
+ return {
362
+ requests: requests.length,
363
+ sent,
364
+ rejected,
365
+ status: 'failed',
366
+ httpStatus: res.status,
367
+ reason: 'redirect',
368
+ };
369
+ }
370
+
371
+ if (res.status < 200 || res.status >= 300) {
372
+ return {
373
+ requests: requests.length,
374
+ sent,
375
+ rejected,
376
+ status: 'failed',
377
+ httpStatus: res.status,
378
+ reason: 'http-status',
379
+ };
380
+ }
381
+
382
+ lastHttpStatus = res.status;
383
+ sent += 1;
384
+
385
+ try {
386
+ const text = await readResponseText(res);
387
+ if (text) {
388
+ try {
389
+ const body = JSON.parse(text);
390
+ const rejectedSpans = partialRejected(body);
391
+ if (rejectedSpans === null) {
392
+ return { requests: requests.length, sent, rejected, status: 'failed', httpStatus: res.status, reason: 'bad-response' };
393
+ }
394
+ if (rejectedSpans > 0) {
395
+ rejected += rejectedSpans;
396
+ hasPartial = true;
397
+ }
398
+ } catch {
399
+ // unparseable body counts as accepted
400
+ }
401
+ }
402
+ } catch (err ) {
403
+ return {
404
+ requests: requests.length,
405
+ sent,
406
+ rejected,
407
+ status: 'failed',
408
+ httpStatus: res.status,
409
+ reason: responseReadFailureReason(err),
410
+ };
411
+ }
412
+ }
413
+
414
+ return {
415
+ requests: requests.length,
416
+ sent,
417
+ rejected,
418
+ status: hasPartial || rejected > 0 ? 'partial' : 'ok',
419
+ httpStatus: lastHttpStatus,
420
+ reason: null,
421
+ };
422
+ }
423
+
424
+ /**
425
+ * Handler for `doflow trace export --otlp-http [--run <key|id>] [--json] [--dry-run] [-g] [<project>]`.
426
+ * Exit 0 all accepted and zero rejected, 1 any failure or rejection, 2 usage.
427
+ */
428
+ async function handleTraceExport({
429
+ positional = [],
430
+ run,
431
+ json = false,
432
+ global = false,
433
+ dryRun = false,
434
+ otlpHttp = false,
435
+ env = process.env,
436
+ fetchImpl = (globalThis ).fetch,
437
+ stdout,
438
+ stderr,
439
+ fsImpl = nodeFs,
440
+ homeDir,
441
+ registry: registryOption,
442
+ } = {}) {
443
+ const writeOut = (str ) => {
444
+ if (stdout) {
445
+ if (typeof stdout.write === 'function') {
446
+ stdout.write(str.endsWith('\n') ? str : str + '\n');
447
+ } else if (typeof stdout === 'function') {
448
+ stdout(str);
449
+ } else if (Array.isArray(stdout)) {
450
+ stdout.push(str);
451
+ }
452
+ } else {
453
+ console.log(str);
454
+ }
455
+ };
456
+
457
+ const writeErr = (str ) => {
458
+ if (stderr) {
459
+ if (typeof stderr.write === 'function') {
460
+ stderr.write(str.endsWith('\n') ? str : str + '\n');
461
+ } else if (typeof stderr === 'function') {
462
+ stderr(str);
463
+ } else if (Array.isArray(stderr)) {
464
+ stderr.push(str);
465
+ }
466
+ } else {
467
+ console.error(str);
468
+ }
469
+ };
470
+
471
+ const usage = (detail ) => {
472
+ if (json) writeOut(JSON.stringify({ error: 'usage', detail }));
473
+ else writeErr(`doflow trace export: ${detail}`);
474
+ return finish(2);
475
+ };
476
+
477
+ if (!otlpHttp) return usage('usage: trace export requires --otlp-http');
478
+ if (positional.length > 1) return usage('usage: trace export --otlp-http [--run <runKey|run>] [--json] [--dry-run] [-g] [<project>]');
479
+ if (run !== undefined && run !== null && (typeof run !== 'string' || !RUN_ARG.test(run))) {
480
+ return usage('--run expects a run key (<hash>/<run>/<lineage>) or a run id');
481
+ }
482
+
483
+ let envConfig = null;
484
+ if (!dryRun) {
485
+ try {
486
+ envConfig = resolveOtlpEnv(env);
487
+ } catch (err ) {
488
+ return usage(err.message);
489
+ }
490
+
491
+ const tracesProtocol = typeof env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL === 'string'
492
+ ? env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL.trim()
493
+ : '';
494
+ const baseProtocol = typeof env.OTEL_EXPORTER_OTLP_PROTOCOL === 'string'
495
+ ? env.OTEL_EXPORTER_OTLP_PROTOCOL.trim()
496
+ : '';
497
+ const protocolVar = tracesProtocol !== ''
498
+ ? 'OTEL_EXPORTER_OTLP_TRACES_PROTOCOL'
499
+ : baseProtocol !== ''
500
+ ? 'OTEL_EXPORTER_OTLP_PROTOCOL'
501
+ : null;
502
+ const protocol = tracesProtocol !== '' ? tracesProtocol : baseProtocol;
503
+ if (protocolVar && protocol.toLowerCase() !== 'http/json') {
504
+ writeErr(`doflow trace export: ${protocolVar} is not read: --otlp-http sends HTTP/JSON`);
505
+ }
506
+ }
507
+
508
+ const projectRoot = global ? undefined : path.resolve(positional[0] || '.');
509
+ const view = projectSpans({ projectRoot, run: run ?? null, global, env, fsImpl, ...(homeDir ? { homeDir } : {}) });
510
+
511
+ let registry = registryOption;
512
+ if (!registry) {
513
+ try {
514
+ registry = JSON.parse(nodeFs.readFileSync(path.join(REPO_ROOT, 'core', 'registry', 'telemetry.json'), 'utf8'));
515
+ } catch {
516
+ registry = {};
517
+ }
518
+ }
519
+
520
+ const lists = otlpMap.ownedLists();
521
+ const { requests, skipped } = otlpMap.buildOtlpRequests(view, registry, { lists });
522
+
523
+ if (requests.length > 20) {
524
+ return usage('export exceeds limit of 20 requests (use --run to export a single run)');
525
+ }
526
+
527
+ if (dryRun) {
528
+ writeOut(JSON.stringify(sorted(requests), null, 2));
529
+ writeErr(`doflow trace export: dry run: ${requests.length} request(s), skipped: ${skipped.ungrouped} ungrouped, ${skipped.noStart} no-start`);
530
+ return finish(0);
531
+ }
532
+
533
+ const sendResult = await sendRequests(requests, {
534
+ endpoint: envConfig .endpoint,
535
+ headers: envConfig .headers,
536
+ timeoutMs: envConfig .timeoutMs,
537
+ fetchImpl,
538
+ });
539
+
540
+ const output = {
541
+ requests: sendResult.requests,
542
+ sent: sendResult.sent,
543
+ rejected: sendResult.rejected,
544
+ skipped: {
545
+ ungrouped: skipped.ungrouped,
546
+ noStart: skipped.noStart,
547
+ },
548
+ status: sendResult.status,
549
+ httpStatus: sendResult.httpStatus,
550
+ reason: sendResult.reason,
551
+ };
552
+
553
+ if (json) {
554
+ writeOut(JSON.stringify(sorted(output), null, 2));
555
+ } else {
556
+ writeOut(
557
+ `doflow trace export: ${output.status} (${output.sent}/${output.requests} requests sent, ${output.rejected} rejected, skipped: ${output.skipped.ungrouped} ungrouped, ${output.skipped.noStart} no-start${output.reason ? `, reason: ${output.reason}` : ''}${output.httpStatus !== null ? `, HTTP ${output.httpStatus}` : ''})`
558
+ );
559
+ }
560
+
561
+ return finish(output.status === 'ok' && output.rejected === 0 ? 0 : 1);
562
+ }
563
+
564
+ module.exports = {
565
+ resolveOtlpEnv,
566
+ sendRequests,
567
+ handleTraceExport,
568
+ };