@ai-is-gonna/get-tasks-done 0.2.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 (1517) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/agents/gtd-advisor-researcher.md +127 -0
  4. package/agents/gtd-ai-researcher.md +133 -0
  5. package/agents/gtd-assumptions-analyzer.md +105 -0
  6. package/agents/gtd-code-fixer.md +668 -0
  7. package/agents/gtd-code-reviewer.md +387 -0
  8. package/agents/gtd-codebase-mapper.md +853 -0
  9. package/agents/gtd-debug-session-manager.md +314 -0
  10. package/agents/gtd-debugger.md +1452 -0
  11. package/agents/gtd-doc-classifier.md +168 -0
  12. package/agents/gtd-doc-synthesizer.md +204 -0
  13. package/agents/gtd-doc-verifier.md +217 -0
  14. package/agents/gtd-doc-writer.md +615 -0
  15. package/agents/gtd-domain-researcher.md +153 -0
  16. package/agents/gtd-eval-auditor.md +191 -0
  17. package/agents/gtd-eval-planner.md +154 -0
  18. package/agents/gtd-framework-selector.md +160 -0
  19. package/agents/gtd-integration-checker.md +470 -0
  20. package/agents/gtd-intel-updater.md +342 -0
  21. package/agents/gtd-nyquist-auditor.md +203 -0
  22. package/agents/gtd-pattern-mapper.md +335 -0
  23. package/agents/gtd-phase-researcher.md +928 -0
  24. package/agents/gtd-plan-checker.md +1000 -0
  25. package/agents/gtd-planner.md +926 -0
  26. package/agents/gtd-project-researcher.md +677 -0
  27. package/agents/gtd-research-synthesizer.md +247 -0
  28. package/agents/gtd-roadmapper.md +688 -0
  29. package/agents/gtd-security-auditor.md +155 -0
  30. package/agents/gtd-task-executor.md +166 -0
  31. package/agents/gtd-ui-auditor.md +495 -0
  32. package/agents/gtd-ui-checker.md +309 -0
  33. package/agents/gtd-ui-researcher.md +380 -0
  34. package/agents/gtd-user-profiler.md +171 -0
  35. package/agents/gtd-verifier.md +917 -0
  36. package/bin/gtd-sdk.js +37 -0
  37. package/bin/install.js +11358 -0
  38. package/commands/gtd/add-tests.md +42 -0
  39. package/commands/gtd/ai-integration-phase.md +37 -0
  40. package/commands/gtd/audit-fix.md +34 -0
  41. package/commands/gtd/audit-milestone.md +37 -0
  42. package/commands/gtd/audit-uat.md +24 -0
  43. package/commands/gtd/autonomous.md +46 -0
  44. package/commands/gtd/capture.md +62 -0
  45. package/commands/gtd/cleanup.md +24 -0
  46. package/commands/gtd/code-review.md +59 -0
  47. package/commands/gtd/complete-milestone.md +143 -0
  48. package/commands/gtd/config.md +58 -0
  49. package/commands/gtd/debug.md +52 -0
  50. package/commands/gtd/discuss-phase.md +76 -0
  51. package/commands/gtd/docs-update.md +49 -0
  52. package/commands/gtd/eval-review.md +33 -0
  53. package/commands/gtd/explore.md +27 -0
  54. package/commands/gtd/export-phase-issues.md +43 -0
  55. package/commands/gtd/extract-learnings.md +23 -0
  56. package/commands/gtd/fast.md +31 -0
  57. package/commands/gtd/forensics.md +57 -0
  58. package/commands/gtd/graphify.md +199 -0
  59. package/commands/gtd/health.md +31 -0
  60. package/commands/gtd/help.md +28 -0
  61. package/commands/gtd/import.md +35 -0
  62. package/commands/gtd/inbox.md +39 -0
  63. package/commands/gtd/ingest-docs.md +42 -0
  64. package/commands/gtd/manager.md +45 -0
  65. package/commands/gtd/map-codebase.md +83 -0
  66. package/commands/gtd/milestone-summary.md +51 -0
  67. package/commands/gtd/mvp-phase.md +45 -0
  68. package/commands/gtd/new-milestone.md +45 -0
  69. package/commands/gtd/new-project.md +47 -0
  70. package/commands/gtd/ns-context.md +23 -0
  71. package/commands/gtd/ns-ideate.md +24 -0
  72. package/commands/gtd/ns-manage.md +28 -0
  73. package/commands/gtd/ns-project.md +22 -0
  74. package/commands/gtd/ns-review.md +26 -0
  75. package/commands/gtd/ns-workflow.md +30 -0
  76. package/commands/gtd/orchestrate-tasks.md +83 -0
  77. package/commands/gtd/pause-work.md +43 -0
  78. package/commands/gtd/phase.md +56 -0
  79. package/commands/gtd/plan-phase.md +62 -0
  80. package/commands/gtd/plan-review-convergence.md +59 -0
  81. package/commands/gtd/pr-branch.md +26 -0
  82. package/commands/gtd/profile-user.md +46 -0
  83. package/commands/gtd/progress.md +46 -0
  84. package/commands/gtd/quick.md +174 -0
  85. package/commands/gtd/resume-work.md +30 -0
  86. package/commands/gtd/review-backlog.md +63 -0
  87. package/commands/gtd/review.md +41 -0
  88. package/commands/gtd/secure-phase.md +36 -0
  89. package/commands/gtd/settings.md +29 -0
  90. package/commands/gtd/sketch.md +60 -0
  91. package/commands/gtd/spec-phase.md +63 -0
  92. package/commands/gtd/spike.md +57 -0
  93. package/commands/gtd/stats.md +19 -0
  94. package/commands/gtd/surface.md +130 -0
  95. package/commands/gtd/thread.md +24 -0
  96. package/commands/gtd/ui-phase.md +35 -0
  97. package/commands/gtd/ui-review.md +33 -0
  98. package/commands/gtd/ultraplan-phase.md +34 -0
  99. package/commands/gtd/undo.md +35 -0
  100. package/commands/gtd/update.md +48 -0
  101. package/commands/gtd/validate-phase.md +36 -0
  102. package/commands/gtd/verify-work.md +39 -0
  103. package/commands/gtd/work-task-issue.md +45 -0
  104. package/commands/gtd/workspace.md +52 -0
  105. package/commands/gtd/workstreams.md +70 -0
  106. package/get-tasks-done/bin/check-latest-version.cjs +104 -0
  107. package/get-tasks-done/bin/gtd-tools.cjs +1264 -0
  108. package/get-tasks-done/bin/lib/active-workstream-store.cjs +85 -0
  109. package/get-tasks-done/bin/lib/adr-parser.cjs +394 -0
  110. package/get-tasks-done/bin/lib/artifacts.cjs +53 -0
  111. package/get-tasks-done/bin/lib/audit.cjs +755 -0
  112. package/get-tasks-done/bin/lib/cjs-command-router-adapter.cjs +39 -0
  113. package/get-tasks-done/bin/lib/clusters.cjs +147 -0
  114. package/get-tasks-done/bin/lib/command-aliases.generated.cjs +830 -0
  115. package/get-tasks-done/bin/lib/commands.cjs +1031 -0
  116. package/get-tasks-done/bin/lib/config-schema.cjs +31 -0
  117. package/get-tasks-done/bin/lib/config.cjs +621 -0
  118. package/get-tasks-done/bin/lib/configuration.generated.cjs +253 -0
  119. package/get-tasks-done/bin/lib/context-utilization.cjs +47 -0
  120. package/get-tasks-done/bin/lib/core.cjs +1921 -0
  121. package/get-tasks-done/bin/lib/decisions.cjs +48 -0
  122. package/get-tasks-done/bin/lib/docs.cjs +270 -0
  123. package/get-tasks-done/bin/lib/drift.cjs +388 -0
  124. package/get-tasks-done/bin/lib/export-phase-issues.cjs +1862 -0
  125. package/get-tasks-done/bin/lib/fallow-runner.cjs +109 -0
  126. package/get-tasks-done/bin/lib/frontmatter.cjs +389 -0
  127. package/get-tasks-done/bin/lib/gap-checker.cjs +197 -0
  128. package/get-tasks-done/bin/lib/github-api-client.cjs +97 -0
  129. package/get-tasks-done/bin/lib/github-repo.cjs +154 -0
  130. package/get-tasks-done/bin/lib/graphify.cjs +592 -0
  131. package/get-tasks-done/bin/lib/gtd2-import.cjs +514 -0
  132. package/get-tasks-done/bin/lib/init-command-router.cjs +65 -0
  133. package/get-tasks-done/bin/lib/init.cjs +1898 -0
  134. package/get-tasks-done/bin/lib/install-profiles.cjs +589 -0
  135. package/get-tasks-done/bin/lib/installer-migration-authoring.cjs +117 -0
  136. package/get-tasks-done/bin/lib/installer-migration-report.cjs +354 -0
  137. package/get-tasks-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +220 -0
  138. package/get-tasks-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +41 -0
  139. package/get-tasks-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +80 -0
  140. package/get-tasks-done/bin/lib/installer-migrations/003-legacy-acronym-install-cleanup.cjs +135 -0
  141. package/get-tasks-done/bin/lib/installer-migrations.cjs +703 -0
  142. package/get-tasks-done/bin/lib/intel.cjs +643 -0
  143. package/get-tasks-done/bin/lib/learnings.cjs +379 -0
  144. package/get-tasks-done/bin/lib/milestone.cjs +314 -0
  145. package/get-tasks-done/bin/lib/model-catalog.cjs +143 -0
  146. package/get-tasks-done/bin/lib/model-profiles.cjs +27 -0
  147. package/get-tasks-done/bin/lib/orchestrate-tasks.cjs +2166 -0
  148. package/get-tasks-done/bin/lib/phase-command-router.cjs +96 -0
  149. package/get-tasks-done/bin/lib/phase.cjs +1422 -0
  150. package/get-tasks-done/bin/lib/phases-command-router.cjs +39 -0
  151. package/get-tasks-done/bin/lib/plan-scan.cjs +138 -0
  152. package/get-tasks-done/bin/lib/planning-workspace.cjs +361 -0
  153. package/get-tasks-done/bin/lib/profile-output.cjs +1132 -0
  154. package/get-tasks-done/bin/lib/profile-pipeline.cjs +539 -0
  155. package/get-tasks-done/bin/lib/project-root.generated.cjs +117 -0
  156. package/get-tasks-done/bin/lib/review-reviewer-selection.cjs +125 -0
  157. package/get-tasks-done/bin/lib/roadmap-command-router.cjs +23 -0
  158. package/get-tasks-done/bin/lib/roadmap.cjs +621 -0
  159. package/get-tasks-done/bin/lib/runtime-homes.cjs +178 -0
  160. package/get-tasks-done/bin/lib/runtime-slash.cjs +109 -0
  161. package/get-tasks-done/bin/lib/schema-detect.cjs +238 -0
  162. package/get-tasks-done/bin/lib/secrets.cjs +33 -0
  163. package/get-tasks-done/bin/lib/security.cjs +504 -0
  164. package/get-tasks-done/bin/lib/shell-command-projection.cjs +548 -0
  165. package/get-tasks-done/bin/lib/state-command-router.cjs +318 -0
  166. package/get-tasks-done/bin/lib/state-document.cjs +12 -0
  167. package/get-tasks-done/bin/lib/state-document.generated.cjs +127 -0
  168. package/get-tasks-done/bin/lib/state.cjs +1917 -0
  169. package/get-tasks-done/bin/lib/surface.cjs +398 -0
  170. package/get-tasks-done/bin/lib/task-issue-shared.cjs +64 -0
  171. package/get-tasks-done/bin/lib/template.cjs +228 -0
  172. package/get-tasks-done/bin/lib/uat.cjs +289 -0
  173. package/get-tasks-done/bin/lib/validate-command-router.cjs +57 -0
  174. package/get-tasks-done/bin/lib/verify-command-router.cjs +34 -0
  175. package/get-tasks-done/bin/lib/verify.cjs +1557 -0
  176. package/get-tasks-done/bin/lib/work-task-issue.cjs +3429 -0
  177. package/get-tasks-done/bin/lib/workstream-inventory-builder.generated.cjs +79 -0
  178. package/get-tasks-done/bin/lib/workstream-inventory.cjs +132 -0
  179. package/get-tasks-done/bin/lib/workstream-name-policy.cjs +33 -0
  180. package/get-tasks-done/bin/lib/workstream.cjs +374 -0
  181. package/get-tasks-done/bin/lib/worktree-safety.cjs +563 -0
  182. package/get-tasks-done/bin/verify-reapply-patches.cjs +247 -0
  183. package/get-tasks-done/contexts/dev.md +21 -0
  184. package/get-tasks-done/contexts/research.md +22 -0
  185. package/get-tasks-done/contexts/review.md +23 -0
  186. package/get-tasks-done/references/agent-contracts.md +79 -0
  187. package/get-tasks-done/references/ai-evals.md +156 -0
  188. package/get-tasks-done/references/ai-frameworks.md +186 -0
  189. package/get-tasks-done/references/artifact-types.md +131 -0
  190. package/get-tasks-done/references/autonomous-smart-discuss.md +277 -0
  191. package/get-tasks-done/references/checkpoints.md +814 -0
  192. package/get-tasks-done/references/common-bug-patterns.md +114 -0
  193. package/get-tasks-done/references/context-budget.md +85 -0
  194. package/get-tasks-done/references/continuation-format.md +253 -0
  195. package/get-tasks-done/references/debugger-philosophy.md +76 -0
  196. package/get-tasks-done/references/decimal-phase-calculation.md +64 -0
  197. package/get-tasks-done/references/doc-conflict-engine.md +91 -0
  198. package/get-tasks-done/references/domain-probes.md +125 -0
  199. package/get-tasks-done/references/execute-mvp-tdd.md +81 -0
  200. package/get-tasks-done/references/executor-examples.md +110 -0
  201. package/get-tasks-done/references/few-shot-examples/plan-checker.md +73 -0
  202. package/get-tasks-done/references/few-shot-examples/verifier.md +109 -0
  203. package/get-tasks-done/references/gate-prompts.md +100 -0
  204. package/get-tasks-done/references/gates.md +70 -0
  205. package/get-tasks-done/references/git-integration.md +298 -0
  206. package/get-tasks-done/references/git-planning-commit.md +40 -0
  207. package/get-tasks-done/references/ios-scaffold.md +123 -0
  208. package/get-tasks-done/references/mandatory-initial-read.md +2 -0
  209. package/get-tasks-done/references/model-profile-resolution.md +38 -0
  210. package/get-tasks-done/references/model-profiles.md +245 -0
  211. package/get-tasks-done/references/mvp-concepts.md +49 -0
  212. package/get-tasks-done/references/phase-argument-parsing.md +61 -0
  213. package/get-tasks-done/references/plan-checker-task-atomicity.md +73 -0
  214. package/get-tasks-done/references/planner-antipatterns.md +89 -0
  215. package/get-tasks-done/references/planner-chunked.md +49 -0
  216. package/get-tasks-done/references/planner-execution-flow.md +85 -0
  217. package/get-tasks-done/references/planner-gap-closure.md +71 -0
  218. package/get-tasks-done/references/planner-graphify-auto-update.md +67 -0
  219. package/get-tasks-done/references/planner-human-verify-mode.md +57 -0
  220. package/get-tasks-done/references/planner-mvp-mode.md +53 -0
  221. package/get-tasks-done/references/planner-reviews.md +39 -0
  222. package/get-tasks-done/references/planner-revision.md +87 -0
  223. package/get-tasks-done/references/planner-source-audit.md +73 -0
  224. package/get-tasks-done/references/planning-config.md +463 -0
  225. package/get-tasks-done/references/project-skills-discovery.md +19 -0
  226. package/get-tasks-done/references/questioning.md +162 -0
  227. package/get-tasks-done/references/revision-loop.md +97 -0
  228. package/get-tasks-done/references/scout-codebase.md +51 -0
  229. package/get-tasks-done/references/skeleton-template.md +48 -0
  230. package/get-tasks-done/references/sketch-interactivity.md +41 -0
  231. package/get-tasks-done/references/sketch-theme-system.md +94 -0
  232. package/get-tasks-done/references/sketch-tooling.md +45 -0
  233. package/get-tasks-done/references/sketch-variant-patterns.md +81 -0
  234. package/get-tasks-done/references/spidr-splitting.md +69 -0
  235. package/get-tasks-done/references/tdd.md +330 -0
  236. package/get-tasks-done/references/thinking-models-debug.md +44 -0
  237. package/get-tasks-done/references/thinking-models-execution.md +50 -0
  238. package/get-tasks-done/references/thinking-models-planning.md +62 -0
  239. package/get-tasks-done/references/thinking-models-research.md +50 -0
  240. package/get-tasks-done/references/thinking-models-verification.md +55 -0
  241. package/get-tasks-done/references/thinking-partner.md +96 -0
  242. package/get-tasks-done/references/ui-brand.md +160 -0
  243. package/get-tasks-done/references/universal-anti-patterns.md +63 -0
  244. package/get-tasks-done/references/user-profiling.md +681 -0
  245. package/get-tasks-done/references/user-story-template.md +58 -0
  246. package/get-tasks-done/references/verification-overrides.md +227 -0
  247. package/get-tasks-done/references/verification-patterns.md +612 -0
  248. package/get-tasks-done/references/verify-mvp-mode.md +85 -0
  249. package/get-tasks-done/references/workstream-flag.md +111 -0
  250. package/get-tasks-done/references/worktree-path-safety.md +89 -0
  251. package/get-tasks-done/templates/AI-SPEC.md +246 -0
  252. package/get-tasks-done/templates/DEBUG.md +169 -0
  253. package/get-tasks-done/templates/README.md +77 -0
  254. package/get-tasks-done/templates/SECURITY.md +61 -0
  255. package/get-tasks-done/templates/UAT.md +265 -0
  256. package/get-tasks-done/templates/UI-SPEC.md +100 -0
  257. package/get-tasks-done/templates/VALIDATION.md +76 -0
  258. package/get-tasks-done/templates/claude-md.md +147 -0
  259. package/get-tasks-done/templates/codebase/architecture.md +255 -0
  260. package/get-tasks-done/templates/codebase/concerns.md +310 -0
  261. package/get-tasks-done/templates/codebase/conventions.md +307 -0
  262. package/get-tasks-done/templates/codebase/integrations.md +280 -0
  263. package/get-tasks-done/templates/codebase/stack.md +186 -0
  264. package/get-tasks-done/templates/codebase/structure.md +285 -0
  265. package/get-tasks-done/templates/codebase/testing.md +480 -0
  266. package/get-tasks-done/templates/config.json +55 -0
  267. package/get-tasks-done/templates/context.md +352 -0
  268. package/get-tasks-done/templates/continue-here.md +78 -0
  269. package/get-tasks-done/templates/copilot-instructions.md +8 -0
  270. package/get-tasks-done/templates/debug-subagent-prompt.md +91 -0
  271. package/get-tasks-done/templates/dev-preferences.md +21 -0
  272. package/get-tasks-done/templates/discovery.md +146 -0
  273. package/get-tasks-done/templates/discussion-log.md +63 -0
  274. package/get-tasks-done/templates/milestone-archive.md +123 -0
  275. package/get-tasks-done/templates/milestone.md +115 -0
  276. package/get-tasks-done/templates/phase-prompt.md +616 -0
  277. package/get-tasks-done/templates/planner-subagent-prompt.md +118 -0
  278. package/get-tasks-done/templates/project.md +186 -0
  279. package/get-tasks-done/templates/requirements.md +231 -0
  280. package/get-tasks-done/templates/research-project/ARCHITECTURE.md +204 -0
  281. package/get-tasks-done/templates/research-project/FEATURES.md +147 -0
  282. package/get-tasks-done/templates/research-project/PITFALLS.md +200 -0
  283. package/get-tasks-done/templates/research-project/STACK.md +120 -0
  284. package/get-tasks-done/templates/research-project/SUMMARY.md +170 -0
  285. package/get-tasks-done/templates/research.md +592 -0
  286. package/get-tasks-done/templates/retrospective.md +54 -0
  287. package/get-tasks-done/templates/roadmap.md +202 -0
  288. package/get-tasks-done/templates/spec.md +307 -0
  289. package/get-tasks-done/templates/state.md +184 -0
  290. package/get-tasks-done/templates/summary-complex.md +59 -0
  291. package/get-tasks-done/templates/summary-minimal.md +41 -0
  292. package/get-tasks-done/templates/summary-standard.md +48 -0
  293. package/get-tasks-done/templates/summary.md +248 -0
  294. package/get-tasks-done/templates/user-profile.md +146 -0
  295. package/get-tasks-done/templates/user-setup.md +311 -0
  296. package/get-tasks-done/templates/verification-report.md +322 -0
  297. package/get-tasks-done/workflows/add-backlog.md +90 -0
  298. package/get-tasks-done/workflows/add-phase.md +112 -0
  299. package/get-tasks-done/workflows/add-tests.md +354 -0
  300. package/get-tasks-done/workflows/add-todo.md +160 -0
  301. package/get-tasks-done/workflows/ai-integration-phase.md +294 -0
  302. package/get-tasks-done/workflows/analyze-dependencies.md +96 -0
  303. package/get-tasks-done/workflows/audit-fix.md +177 -0
  304. package/get-tasks-done/workflows/audit-milestone.md +357 -0
  305. package/get-tasks-done/workflows/audit-uat.md +109 -0
  306. package/get-tasks-done/workflows/autonomous.md +790 -0
  307. package/get-tasks-done/workflows/check-todos.md +179 -0
  308. package/get-tasks-done/workflows/cleanup.md +154 -0
  309. package/get-tasks-done/workflows/code-review-fix.md +501 -0
  310. package/get-tasks-done/workflows/code-review.md +613 -0
  311. package/get-tasks-done/workflows/complete-milestone.md +854 -0
  312. package/get-tasks-done/workflows/debug.md +231 -0
  313. package/get-tasks-done/workflows/diagnose-issues.md +240 -0
  314. package/get-tasks-done/workflows/discovery-phase.md +291 -0
  315. package/get-tasks-done/workflows/discuss-phase/modes/advisor.md +175 -0
  316. package/get-tasks-done/workflows/discuss-phase/modes/all.md +28 -0
  317. package/get-tasks-done/workflows/discuss-phase/modes/analyze.md +44 -0
  318. package/get-tasks-done/workflows/discuss-phase/modes/auto.md +56 -0
  319. package/get-tasks-done/workflows/discuss-phase/modes/batch.md +52 -0
  320. package/get-tasks-done/workflows/discuss-phase/modes/chain.md +97 -0
  321. package/get-tasks-done/workflows/discuss-phase/modes/default.md +141 -0
  322. package/get-tasks-done/workflows/discuss-phase/modes/power.md +44 -0
  323. package/get-tasks-done/workflows/discuss-phase/modes/text.md +55 -0
  324. package/get-tasks-done/workflows/discuss-phase/templates/checkpoint.json +18 -0
  325. package/get-tasks-done/workflows/discuss-phase/templates/context.md +136 -0
  326. package/get-tasks-done/workflows/discuss-phase/templates/discussion-log.md +50 -0
  327. package/get-tasks-done/workflows/discuss-phase-assumptions.md +674 -0
  328. package/get-tasks-done/workflows/discuss-phase-power.md +291 -0
  329. package/get-tasks-done/workflows/discuss-phase.md +499 -0
  330. package/get-tasks-done/workflows/do.md +110 -0
  331. package/get-tasks-done/workflows/docs-update.md +1161 -0
  332. package/get-tasks-done/workflows/edit-phase.md +294 -0
  333. package/get-tasks-done/workflows/eval-review.md +155 -0
  334. package/get-tasks-done/workflows/explore.md +143 -0
  335. package/get-tasks-done/workflows/export-phase-issues.md +74 -0
  336. package/get-tasks-done/workflows/extract-learnings.md +242 -0
  337. package/get-tasks-done/workflows/fast.md +105 -0
  338. package/get-tasks-done/workflows/forensics.md +278 -0
  339. package/get-tasks-done/workflows/graduation.md +195 -0
  340. package/get-tasks-done/workflows/health.md +223 -0
  341. package/get-tasks-done/workflows/help/modes/brief.md +24 -0
  342. package/get-tasks-done/workflows/help/modes/default.md +52 -0
  343. package/get-tasks-done/workflows/help/modes/full.md +813 -0
  344. package/get-tasks-done/workflows/help/modes/topic.md +74 -0
  345. package/get-tasks-done/workflows/help.md +24 -0
  346. package/get-tasks-done/workflows/import.md +253 -0
  347. package/get-tasks-done/workflows/inbox.md +87 -0
  348. package/get-tasks-done/workflows/ingest-docs.md +339 -0
  349. package/get-tasks-done/workflows/insert-phase.md +151 -0
  350. package/get-tasks-done/workflows/list-phase-assumptions.md +178 -0
  351. package/get-tasks-done/workflows/list-workspaces.md +56 -0
  352. package/get-tasks-done/workflows/manager.md +393 -0
  353. package/get-tasks-done/workflows/map-codebase.md +443 -0
  354. package/get-tasks-done/workflows/milestone-summary.md +223 -0
  355. package/get-tasks-done/workflows/mvp-phase.md +221 -0
  356. package/get-tasks-done/workflows/new-milestone.md +634 -0
  357. package/get-tasks-done/workflows/new-project.md +1443 -0
  358. package/get-tasks-done/workflows/new-workspace.md +239 -0
  359. package/get-tasks-done/workflows/next.md +220 -0
  360. package/get-tasks-done/workflows/node-repair.md +92 -0
  361. package/get-tasks-done/workflows/note.md +158 -0
  362. package/get-tasks-done/workflows/orchestrate-tasks.md +209 -0
  363. package/get-tasks-done/workflows/pause-work.md +243 -0
  364. package/get-tasks-done/workflows/plan-milestone-gaps.md +280 -0
  365. package/get-tasks-done/workflows/plan-phase.md +1756 -0
  366. package/get-tasks-done/workflows/plan-review-convergence.md +329 -0
  367. package/get-tasks-done/workflows/plant-seed.md +229 -0
  368. package/get-tasks-done/workflows/pr-branch.md +156 -0
  369. package/get-tasks-done/workflows/profile-user.md +452 -0
  370. package/get-tasks-done/workflows/progress.md +668 -0
  371. package/get-tasks-done/workflows/quick.md +1169 -0
  372. package/get-tasks-done/workflows/reapply-patches.md +390 -0
  373. package/get-tasks-done/workflows/remove-phase.md +155 -0
  374. package/get-tasks-done/workflows/remove-workspace.md +107 -0
  375. package/get-tasks-done/workflows/resume-project.md +329 -0
  376. package/get-tasks-done/workflows/review.md +459 -0
  377. package/get-tasks-done/workflows/scan.md +104 -0
  378. package/get-tasks-done/workflows/secure-phase.md +179 -0
  379. package/get-tasks-done/workflows/session-report.md +146 -0
  380. package/get-tasks-done/workflows/settings-advanced.md +532 -0
  381. package/get-tasks-done/workflows/settings-integrations.md +281 -0
  382. package/get-tasks-done/workflows/settings.md +502 -0
  383. package/get-tasks-done/workflows/sketch-wrap-up.md +285 -0
  384. package/get-tasks-done/workflows/sketch.md +360 -0
  385. package/get-tasks-done/workflows/spec-phase.md +262 -0
  386. package/get-tasks-done/workflows/spike-wrap-up.md +306 -0
  387. package/get-tasks-done/workflows/spike.md +452 -0
  388. package/get-tasks-done/workflows/stats.md +79 -0
  389. package/get-tasks-done/workflows/sync-skills.md +182 -0
  390. package/get-tasks-done/workflows/thread.md +221 -0
  391. package/get-tasks-done/workflows/transition.md +693 -0
  392. package/get-tasks-done/workflows/ui-phase.md +327 -0
  393. package/get-tasks-done/workflows/ui-review.md +192 -0
  394. package/get-tasks-done/workflows/ultraplan-phase.md +198 -0
  395. package/get-tasks-done/workflows/undo.md +314 -0
  396. package/get-tasks-done/workflows/update.md +644 -0
  397. package/get-tasks-done/workflows/validate-phase.md +178 -0
  398. package/get-tasks-done/workflows/verify-phase.md +543 -0
  399. package/get-tasks-done/workflows/verify-work.md +797 -0
  400. package/get-tasks-done/workflows/work-task-issue.md +249 -0
  401. package/hooks/dist/gtd-check-update-worker.js +117 -0
  402. package/hooks/dist/gtd-check-update.js +64 -0
  403. package/hooks/dist/gtd-context-monitor.js +192 -0
  404. package/hooks/dist/gtd-phase-boundary.sh +47 -0
  405. package/hooks/dist/gtd-prompt-guard.js +97 -0
  406. package/hooks/dist/gtd-read-guard.js +101 -0
  407. package/hooks/dist/gtd-read-injection-scanner.js +152 -0
  408. package/hooks/dist/gtd-session-state.sh +59 -0
  409. package/hooks/dist/gtd-statusline.js +537 -0
  410. package/hooks/dist/gtd-update-banner.js +134 -0
  411. package/hooks/dist/gtd-validate-commit.sh +57 -0
  412. package/hooks/dist/gtd-workflow-guard.js +94 -0
  413. package/hooks/gtd-check-update-worker.js +117 -0
  414. package/hooks/gtd-check-update.js +64 -0
  415. package/hooks/gtd-context-monitor.js +192 -0
  416. package/hooks/gtd-graphify-update.sh +152 -0
  417. package/hooks/gtd-phase-boundary.sh +47 -0
  418. package/hooks/gtd-prompt-guard.js +97 -0
  419. package/hooks/gtd-read-guard.js +101 -0
  420. package/hooks/gtd-read-injection-scanner.js +152 -0
  421. package/hooks/gtd-session-state.sh +59 -0
  422. package/hooks/gtd-statusline.js +537 -0
  423. package/hooks/gtd-update-banner.js +134 -0
  424. package/hooks/gtd-validate-commit.sh +57 -0
  425. package/hooks/gtd-workflow-guard.js +94 -0
  426. package/hooks/lib/git-cmd.js +150 -0
  427. package/hooks/lib/gtd-graphify-rebuild.sh +65 -0
  428. package/package.json +85 -0
  429. package/scripts/audit-workflow-script-paths.cjs +73 -0
  430. package/scripts/base64-scan.sh +262 -0
  431. package/scripts/build-hooks.js +187 -0
  432. package/scripts/command-contract-helpers.cjs +61 -0
  433. package/scripts/fix-slash-commands.cjs +106 -0
  434. package/scripts/lint-command-contract.cjs +108 -0
  435. package/scripts/lint-descriptions.cjs +83 -0
  436. package/scripts/lint-no-source-grep-extras.cjs +81 -0
  437. package/scripts/lint-no-source-grep.cjs +174 -0
  438. package/scripts/lint-pr-check-project-dir.cjs +94 -0
  439. package/scripts/lint-shell-command-projection-drift.cjs +57 -0
  440. package/scripts/lint-skill-deps.cjs +180 -0
  441. package/scripts/prompt-injection-scan.sh +201 -0
  442. package/scripts/run-tests.cjs +33 -0
  443. package/scripts/secret-scan.sh +227 -0
  444. package/scripts/strip-prose-atrefs.cjs +106 -0
  445. package/scripts/verify-tarball-sdk-dist.sh +69 -0
  446. package/sdk/dist/cli-transport.d.ts +19 -0
  447. package/sdk/dist/cli-transport.d.ts.map +1 -0
  448. package/sdk/dist/cli-transport.js +104 -0
  449. package/sdk/dist/cli-transport.js.map +1 -0
  450. package/sdk/dist/cli.d.ts +46 -0
  451. package/sdk/dist/cli.d.ts.map +1 -0
  452. package/sdk/dist/cli.js +511 -0
  453. package/sdk/dist/cli.js.map +1 -0
  454. package/sdk/dist/config.d.ts +107 -0
  455. package/sdk/dist/config.d.ts.map +1 -0
  456. package/sdk/dist/config.js +115 -0
  457. package/sdk/dist/config.js.map +1 -0
  458. package/sdk/dist/configuration/index.d.ts +85 -0
  459. package/sdk/dist/configuration/index.d.ts.map +1 -0
  460. package/sdk/dist/configuration/index.js +257 -0
  461. package/sdk/dist/configuration/index.js.map +1 -0
  462. package/sdk/dist/context-engine.d.ts +49 -0
  463. package/sdk/dist/context-engine.d.ts.map +1 -0
  464. package/sdk/dist/context-engine.js +142 -0
  465. package/sdk/dist/context-engine.js.map +1 -0
  466. package/sdk/dist/context-truncation.d.ts +33 -0
  467. package/sdk/dist/context-truncation.d.ts.map +1 -0
  468. package/sdk/dist/context-truncation.js +197 -0
  469. package/sdk/dist/context-truncation.js.map +1 -0
  470. package/sdk/dist/errors.d.ts +46 -0
  471. package/sdk/dist/errors.d.ts.map +1 -0
  472. package/sdk/dist/errors.js +64 -0
  473. package/sdk/dist/errors.js.map +1 -0
  474. package/sdk/dist/event-stream.d.ts +53 -0
  475. package/sdk/dist/event-stream.d.ts.map +1 -0
  476. package/sdk/dist/event-stream.js +321 -0
  477. package/sdk/dist/event-stream.js.map +1 -0
  478. package/sdk/dist/golden/capture.d.ts +15 -0
  479. package/sdk/dist/golden/capture.d.ts.map +1 -0
  480. package/sdk/dist/golden/capture.js +67 -0
  481. package/sdk/dist/golden/capture.js.map +1 -0
  482. package/sdk/dist/golden/golden-integration-covered.d.ts +6 -0
  483. package/sdk/dist/golden/golden-integration-covered.d.ts.map +1 -0
  484. package/sdk/dist/golden/golden-integration-covered.js +30 -0
  485. package/sdk/dist/golden/golden-integration-covered.js.map +1 -0
  486. package/sdk/dist/golden/golden-mutation-covered.d.ts +7 -0
  487. package/sdk/dist/golden/golden-mutation-covered.d.ts.map +1 -0
  488. package/sdk/dist/golden/golden-mutation-covered.js +17 -0
  489. package/sdk/dist/golden/golden-mutation-covered.js.map +1 -0
  490. package/sdk/dist/golden/golden-policy.d.ts +10 -0
  491. package/sdk/dist/golden/golden-policy.d.ts.map +1 -0
  492. package/sdk/dist/golden/golden-policy.js +97 -0
  493. package/sdk/dist/golden/golden-policy.js.map +1 -0
  494. package/sdk/dist/golden/init-golden-normalize.d.ts +8 -0
  495. package/sdk/dist/golden/init-golden-normalize.d.ts.map +1 -0
  496. package/sdk/dist/golden/init-golden-normalize.js +14 -0
  497. package/sdk/dist/golden/init-golden-normalize.js.map +1 -0
  498. package/sdk/dist/golden/read-only-golden-rows.d.ts +20 -0
  499. package/sdk/dist/golden/read-only-golden-rows.d.ts.map +1 -0
  500. package/sdk/dist/golden/read-only-golden-rows.js +67 -0
  501. package/sdk/dist/golden/read-only-golden-rows.js.map +1 -0
  502. package/sdk/dist/golden/registry-canonical-commands.d.ts +6 -0
  503. package/sdk/dist/golden/registry-canonical-commands.d.ts.map +1 -0
  504. package/sdk/dist/golden/registry-canonical-commands.js +30 -0
  505. package/sdk/dist/golden/registry-canonical-commands.js.map +1 -0
  506. package/sdk/dist/gtd-tools-error.d.ts +23 -0
  507. package/sdk/dist/gtd-tools-error.d.ts.map +1 -0
  508. package/sdk/dist/gtd-tools-error.js +29 -0
  509. package/sdk/dist/gtd-tools-error.js.map +1 -0
  510. package/sdk/dist/gtd-tools.d.ts +102 -0
  511. package/sdk/dist/gtd-tools.d.ts.map +1 -0
  512. package/sdk/dist/gtd-tools.js +222 -0
  513. package/sdk/dist/gtd-tools.js.map +1 -0
  514. package/sdk/dist/gtd-transport-policy.d.ts +10 -0
  515. package/sdk/dist/gtd-transport-policy.d.ts.map +1 -0
  516. package/sdk/dist/gtd-transport-policy.js +32 -0
  517. package/sdk/dist/gtd-transport-policy.js.map +1 -0
  518. package/sdk/dist/gtd-transport.d.ts +39 -0
  519. package/sdk/dist/gtd-transport.d.ts.map +1 -0
  520. package/sdk/dist/gtd-transport.js +78 -0
  521. package/sdk/dist/gtd-transport.js.map +1 -0
  522. package/sdk/dist/index.d.ts +127 -0
  523. package/sdk/dist/index.d.ts.map +1 -0
  524. package/sdk/dist/index.js +298 -0
  525. package/sdk/dist/index.js.map +1 -0
  526. package/sdk/dist/init-runner.d.ts +90 -0
  527. package/sdk/dist/init-runner.d.ts.map +1 -0
  528. package/sdk/dist/init-runner.js +613 -0
  529. package/sdk/dist/init-runner.js.map +1 -0
  530. package/sdk/dist/logger.d.ts +50 -0
  531. package/sdk/dist/logger.d.ts.map +1 -0
  532. package/sdk/dist/logger.js +70 -0
  533. package/sdk/dist/logger.js.map +1 -0
  534. package/sdk/dist/model-catalog.d.ts +33 -0
  535. package/sdk/dist/model-catalog.d.ts.map +1 -0
  536. package/sdk/dist/model-catalog.js +34 -0
  537. package/sdk/dist/model-catalog.js.map +1 -0
  538. package/sdk/dist/phase-prompt.d.ts +71 -0
  539. package/sdk/dist/phase-prompt.d.ts.map +1 -0
  540. package/sdk/dist/phase-prompt.js +208 -0
  541. package/sdk/dist/phase-prompt.js.map +1 -0
  542. package/sdk/dist/phase-runner.d.ts +145 -0
  543. package/sdk/dist/phase-runner.d.ts.map +1 -0
  544. package/sdk/dist/phase-runner.js +1206 -0
  545. package/sdk/dist/phase-runner.js.map +1 -0
  546. package/sdk/dist/plan-atomicity.d.ts +26 -0
  547. package/sdk/dist/plan-atomicity.d.ts.map +1 -0
  548. package/sdk/dist/plan-atomicity.js +116 -0
  549. package/sdk/dist/plan-atomicity.js.map +1 -0
  550. package/sdk/dist/plan-parser.d.ts +55 -0
  551. package/sdk/dist/plan-parser.d.ts.map +1 -0
  552. package/sdk/dist/plan-parser.js +391 -0
  553. package/sdk/dist/plan-parser.js.map +1 -0
  554. package/sdk/dist/planning-journal.d.ts +64 -0
  555. package/sdk/dist/planning-journal.d.ts.map +1 -0
  556. package/sdk/dist/planning-journal.js +88 -0
  557. package/sdk/dist/planning-journal.js.map +1 -0
  558. package/sdk/dist/planning-runtime.d.ts +67 -0
  559. package/sdk/dist/planning-runtime.d.ts.map +1 -0
  560. package/sdk/dist/planning-runtime.js +58 -0
  561. package/sdk/dist/planning-runtime.js.map +1 -0
  562. package/sdk/dist/project-root/index.d.ts +46 -0
  563. package/sdk/dist/project-root/index.d.ts.map +1 -0
  564. package/sdk/dist/project-root/index.js +138 -0
  565. package/sdk/dist/project-root/index.js.map +1 -0
  566. package/sdk/dist/prompt-builder.d.ts +44 -0
  567. package/sdk/dist/prompt-builder.d.ts.map +1 -0
  568. package/sdk/dist/prompt-builder.js +180 -0
  569. package/sdk/dist/prompt-builder.js.map +1 -0
  570. package/sdk/dist/prompt-sanitizer.d.ts +35 -0
  571. package/sdk/dist/prompt-sanitizer.d.ts.map +1 -0
  572. package/sdk/dist/prompt-sanitizer.js +101 -0
  573. package/sdk/dist/prompt-sanitizer.js.map +1 -0
  574. package/sdk/dist/query/active-workstream-store.d.ts +7 -0
  575. package/sdk/dist/query/active-workstream-store.d.ts.map +1 -0
  576. package/sdk/dist/query/active-workstream-store.js +56 -0
  577. package/sdk/dist/query/active-workstream-store.js.map +1 -0
  578. package/sdk/dist/query/agent-failure-classifier.d.ts +37 -0
  579. package/sdk/dist/query/agent-failure-classifier.d.ts.map +1 -0
  580. package/sdk/dist/query/agent-failure-classifier.js +82 -0
  581. package/sdk/dist/query/agent-failure-classifier.js.map +1 -0
  582. package/sdk/dist/query/audit-open.d.ts +46 -0
  583. package/sdk/dist/query/audit-open.d.ts.map +1 -0
  584. package/sdk/dist/query/audit-open.js +662 -0
  585. package/sdk/dist/query/audit-open.js.map +1 -0
  586. package/sdk/dist/query/check-auto-mode.d.ts +13 -0
  587. package/sdk/dist/query/check-auto-mode.d.ts.map +1 -0
  588. package/sdk/dist/query/check-auto-mode.js +40 -0
  589. package/sdk/dist/query/check-auto-mode.js.map +1 -0
  590. package/sdk/dist/query/check-completion.d.ts +10 -0
  591. package/sdk/dist/query/check-completion.d.ts.map +1 -0
  592. package/sdk/dist/query/check-completion.js +157 -0
  593. package/sdk/dist/query/check-completion.js.map +1 -0
  594. package/sdk/dist/query/check-decision-coverage.d.ts +33 -0
  595. package/sdk/dist/query/check-decision-coverage.d.ts.map +1 -0
  596. package/sdk/dist/query/check-decision-coverage.js +472 -0
  597. package/sdk/dist/query/check-decision-coverage.js.map +1 -0
  598. package/sdk/dist/query/check-gates.d.ts +10 -0
  599. package/sdk/dist/query/check-gates.d.ts.map +1 -0
  600. package/sdk/dist/query/check-gates.js +89 -0
  601. package/sdk/dist/query/check-gates.js.map +1 -0
  602. package/sdk/dist/query/check-verification-status.d.ts +10 -0
  603. package/sdk/dist/query/check-verification-status.d.ts.map +1 -0
  604. package/sdk/dist/query/check-verification-status.js +142 -0
  605. package/sdk/dist/query/check-verification-status.js.map +1 -0
  606. package/sdk/dist/query/command-aliases.generated.d.ts +31 -0
  607. package/sdk/dist/query/command-aliases.generated.d.ts.map +1 -0
  608. package/sdk/dist/query/command-aliases.generated.js +134 -0
  609. package/sdk/dist/query/command-aliases.generated.js.map +1 -0
  610. package/sdk/dist/query/command-catalog.d.ts +9 -0
  611. package/sdk/dist/query/command-catalog.d.ts.map +1 -0
  612. package/sdk/dist/query/command-catalog.js +17 -0
  613. package/sdk/dist/query/command-catalog.js.map +1 -0
  614. package/sdk/dist/query/command-definition.d.ts +19 -0
  615. package/sdk/dist/query/command-definition.d.ts.map +1 -0
  616. package/sdk/dist/query/command-definition.js +44 -0
  617. package/sdk/dist/query/command-definition.js.map +1 -0
  618. package/sdk/dist/query/command-family-handlers.d.ts +3 -0
  619. package/sdk/dist/query/command-family-handlers.d.ts.map +1 -0
  620. package/sdk/dist/query/command-family-handlers.js +93 -0
  621. package/sdk/dist/query/command-family-handlers.js.map +1 -0
  622. package/sdk/dist/query/command-manifest.d.ts +2 -0
  623. package/sdk/dist/query/command-manifest.d.ts.map +1 -0
  624. package/sdk/dist/query/command-manifest.init.d.ts +6 -0
  625. package/sdk/dist/query/command-manifest.init.d.ts.map +1 -0
  626. package/sdk/dist/query/command-manifest.init.js +22 -0
  627. package/sdk/dist/query/command-manifest.init.js.map +1 -0
  628. package/sdk/dist/query/command-manifest.js +17 -0
  629. package/sdk/dist/query/command-manifest.js.map +1 -0
  630. package/sdk/dist/query/command-manifest.non-family.d.ts +9 -0
  631. package/sdk/dist/query/command-manifest.non-family.d.ts.map +1 -0
  632. package/sdk/dist/query/command-manifest.non-family.js +62 -0
  633. package/sdk/dist/query/command-manifest.non-family.js.map +1 -0
  634. package/sdk/dist/query/command-manifest.phase.d.ts +6 -0
  635. package/sdk/dist/query/command-manifest.phase.d.ts.map +1 -0
  636. package/sdk/dist/query/command-manifest.phase.js +15 -0
  637. package/sdk/dist/query/command-manifest.phase.js.map +1 -0
  638. package/sdk/dist/query/command-manifest.phases.d.ts +7 -0
  639. package/sdk/dist/query/command-manifest.phases.d.ts.map +1 -0
  640. package/sdk/dist/query/command-manifest.phases.js +10 -0
  641. package/sdk/dist/query/command-manifest.phases.js.map +1 -0
  642. package/sdk/dist/query/command-manifest.roadmap.d.ts +6 -0
  643. package/sdk/dist/query/command-manifest.roadmap.d.ts.map +1 -0
  644. package/sdk/dist/query/command-manifest.roadmap.js +10 -0
  645. package/sdk/dist/query/command-manifest.roadmap.js.map +1 -0
  646. package/sdk/dist/query/command-manifest.state.d.ts +9 -0
  647. package/sdk/dist/query/command-manifest.state.d.ts.map +1 -0
  648. package/sdk/dist/query/command-manifest.state.js +30 -0
  649. package/sdk/dist/query/command-manifest.state.js.map +1 -0
  650. package/sdk/dist/query/command-manifest.types.d.ts +12 -0
  651. package/sdk/dist/query/command-manifest.types.d.ts.map +1 -0
  652. package/sdk/dist/query/command-manifest.types.js +2 -0
  653. package/sdk/dist/query/command-manifest.types.js.map +1 -0
  654. package/sdk/dist/query/command-manifest.validate.d.ts +6 -0
  655. package/sdk/dist/query/command-manifest.validate.d.ts.map +1 -0
  656. package/sdk/dist/query/command-manifest.validate.js +10 -0
  657. package/sdk/dist/query/command-manifest.validate.js.map +1 -0
  658. package/sdk/dist/query/command-manifest.verify.d.ts +6 -0
  659. package/sdk/dist/query/command-manifest.verify.d.ts.map +1 -0
  660. package/sdk/dist/query/command-manifest.verify.js +14 -0
  661. package/sdk/dist/query/command-manifest.verify.js.map +1 -0
  662. package/sdk/dist/query/command-static-catalog-domain.d.ts +3 -0
  663. package/sdk/dist/query/command-static-catalog-domain.d.ts.map +1 -0
  664. package/sdk/dist/query/command-static-catalog-domain.js +120 -0
  665. package/sdk/dist/query/command-static-catalog-domain.js.map +1 -0
  666. package/sdk/dist/query/command-static-catalog-foundation.d.ts +7 -0
  667. package/sdk/dist/query/command-static-catalog-foundation.d.ts.map +1 -0
  668. package/sdk/dist/query/command-static-catalog-foundation.js +95 -0
  669. package/sdk/dist/query/command-static-catalog-foundation.js.map +1 -0
  670. package/sdk/dist/query/command-topology.d.ts +32 -0
  671. package/sdk/dist/query/command-topology.d.ts.map +1 -0
  672. package/sdk/dist/query/command-topology.js +66 -0
  673. package/sdk/dist/query/command-topology.js.map +1 -0
  674. package/sdk/dist/query/commands-list.d.ts +14 -0
  675. package/sdk/dist/query/commands-list.d.ts.map +1 -0
  676. package/sdk/dist/query/commands-list.js +18 -0
  677. package/sdk/dist/query/commands-list.js.map +1 -0
  678. package/sdk/dist/query/commit.d.ts +79 -0
  679. package/sdk/dist/query/commit.d.ts.map +1 -0
  680. package/sdk/dist/query/commit.js +340 -0
  681. package/sdk/dist/query/commit.js.map +1 -0
  682. package/sdk/dist/query/config-gates.d.ts +12 -0
  683. package/sdk/dist/query/config-gates.d.ts.map +1 -0
  684. package/sdk/dist/query/config-gates.js +66 -0
  685. package/sdk/dist/query/config-gates.js.map +1 -0
  686. package/sdk/dist/query/config-mutation.d.ts +86 -0
  687. package/sdk/dist/query/config-mutation.d.ts.map +1 -0
  688. package/sdk/dist/query/config-mutation.js +445 -0
  689. package/sdk/dist/query/config-mutation.js.map +1 -0
  690. package/sdk/dist/query/config-query.d.ts +57 -0
  691. package/sdk/dist/query/config-query.d.ts.map +1 -0
  692. package/sdk/dist/query/config-query.js +208 -0
  693. package/sdk/dist/query/config-query.js.map +1 -0
  694. package/sdk/dist/query/config-schema.d.ts +19 -0
  695. package/sdk/dist/query/config-schema.d.ts.map +1 -0
  696. package/sdk/dist/query/config-schema.js +26 -0
  697. package/sdk/dist/query/config-schema.js.map +1 -0
  698. package/sdk/dist/query/decisions.d.ts +58 -0
  699. package/sdk/dist/query/decisions.d.ts.map +1 -0
  700. package/sdk/dist/query/decisions.js +161 -0
  701. package/sdk/dist/query/decisions.js.map +1 -0
  702. package/sdk/dist/query/detect-custom-files.d.ts +11 -0
  703. package/sdk/dist/query/detect-custom-files.d.ts.map +1 -0
  704. package/sdk/dist/query/detect-custom-files.js +89 -0
  705. package/sdk/dist/query/detect-custom-files.js.map +1 -0
  706. package/sdk/dist/query/detect-phase-type.d.ts +9 -0
  707. package/sdk/dist/query/detect-phase-type.d.ts.map +1 -0
  708. package/sdk/dist/query/detect-phase-type.js +124 -0
  709. package/sdk/dist/query/detect-phase-type.js.map +1 -0
  710. package/sdk/dist/query/docs-init.d.ts +26 -0
  711. package/sdk/dist/query/docs-init.d.ts.map +1 -0
  712. package/sdk/dist/query/docs-init.js +231 -0
  713. package/sdk/dist/query/docs-init.js.map +1 -0
  714. package/sdk/dist/query/fallow-audit.d.ts +44 -0
  715. package/sdk/dist/query/fallow-audit.d.ts.map +1 -0
  716. package/sdk/dist/query/fallow-audit.js +44 -0
  717. package/sdk/dist/query/fallow-audit.js.map +1 -0
  718. package/sdk/dist/query/frontmatter-mutation.d.ts +77 -0
  719. package/sdk/dist/query/frontmatter-mutation.d.ts.map +1 -0
  720. package/sdk/dist/query/frontmatter-mutation.js +317 -0
  721. package/sdk/dist/query/frontmatter-mutation.js.map +1 -0
  722. package/sdk/dist/query/frontmatter.d.ts +93 -0
  723. package/sdk/dist/query/frontmatter.d.ts.map +1 -0
  724. package/sdk/dist/query/frontmatter.js +365 -0
  725. package/sdk/dist/query/frontmatter.js.map +1 -0
  726. package/sdk/dist/query/helpers.d.ts +167 -0
  727. package/sdk/dist/query/helpers.d.ts.map +1 -0
  728. package/sdk/dist/query/helpers.js +495 -0
  729. package/sdk/dist/query/helpers.js.map +1 -0
  730. package/sdk/dist/query/index.d.ts +8 -0
  731. package/sdk/dist/query/index.d.ts.map +1 -0
  732. package/sdk/dist/query/index.js +6 -0
  733. package/sdk/dist/query/index.js.map +1 -0
  734. package/sdk/dist/query/init-complex.d.ts +47 -0
  735. package/sdk/dist/query/init-complex.d.ts.map +1 -0
  736. package/sdk/dist/query/init-complex.js +723 -0
  737. package/sdk/dist/query/init-complex.js.map +1 -0
  738. package/sdk/dist/query/init.d.ts +98 -0
  739. package/sdk/dist/query/init.d.ts.map +1 -0
  740. package/sdk/dist/query/init.js +1074 -0
  741. package/sdk/dist/query/init.js.map +1 -0
  742. package/sdk/dist/query/intel.d.ts +43 -0
  743. package/sdk/dist/query/intel.d.ts.map +1 -0
  744. package/sdk/dist/query/intel.js +416 -0
  745. package/sdk/dist/query/intel.js.map +1 -0
  746. package/sdk/dist/query/mutation-event-decorator.d.ts +5 -0
  747. package/sdk/dist/query/mutation-event-decorator.d.ts.map +1 -0
  748. package/sdk/dist/query/mutation-event-decorator.js +28 -0
  749. package/sdk/dist/query/mutation-event-decorator.js.map +1 -0
  750. package/sdk/dist/query/mutation-event-mapper.d.ts +4 -0
  751. package/sdk/dist/query/mutation-event-mapper.d.ts.map +1 -0
  752. package/sdk/dist/query/mutation-event-mapper.js +70 -0
  753. package/sdk/dist/query/mutation-event-mapper.js.map +1 -0
  754. package/sdk/dist/query/mvp.d.ts +113 -0
  755. package/sdk/dist/query/mvp.d.ts.map +1 -0
  756. package/sdk/dist/query/mvp.js +225 -0
  757. package/sdk/dist/query/mvp.js.map +1 -0
  758. package/sdk/dist/query/phase-filesystem-adapter.d.ts +4 -0
  759. package/sdk/dist/query/phase-filesystem-adapter.d.ts.map +1 -0
  760. package/sdk/dist/query/phase-filesystem-adapter.js +33 -0
  761. package/sdk/dist/query/phase-filesystem-adapter.js.map +1 -0
  762. package/sdk/dist/query/phase-lifecycle-policy.d.ts +34 -0
  763. package/sdk/dist/query/phase-lifecycle-policy.d.ts.map +1 -0
  764. package/sdk/dist/query/phase-lifecycle-policy.js +138 -0
  765. package/sdk/dist/query/phase-lifecycle-policy.js.map +1 -0
  766. package/sdk/dist/query/phase-lifecycle.d.ts +116 -0
  767. package/sdk/dist/query/phase-lifecycle.d.ts.map +1 -0
  768. package/sdk/dist/query/phase-lifecycle.js +1486 -0
  769. package/sdk/dist/query/phase-lifecycle.js.map +1 -0
  770. package/sdk/dist/query/phase-list-queries.d.ts +18 -0
  771. package/sdk/dist/query/phase-list-queries.d.ts.map +1 -0
  772. package/sdk/dist/query/phase-list-queries.js +129 -0
  773. package/sdk/dist/query/phase-list-queries.js.map +1 -0
  774. package/sdk/dist/query/phase-ready.d.ts +9 -0
  775. package/sdk/dist/query/phase-ready.d.ts.map +1 -0
  776. package/sdk/dist/query/phase-ready.js +132 -0
  777. package/sdk/dist/query/phase-ready.js.map +1 -0
  778. package/sdk/dist/query/phase-roadmap-mutation.d.ts +13 -0
  779. package/sdk/dist/query/phase-roadmap-mutation.d.ts.map +1 -0
  780. package/sdk/dist/query/phase-roadmap-mutation.js +65 -0
  781. package/sdk/dist/query/phase-roadmap-mutation.js.map +1 -0
  782. package/sdk/dist/query/phase.d.ts +48 -0
  783. package/sdk/dist/query/phase.d.ts.map +1 -0
  784. package/sdk/dist/query/phase.js +451 -0
  785. package/sdk/dist/query/phase.js.map +1 -0
  786. package/sdk/dist/query/pipeline.d.ts +53 -0
  787. package/sdk/dist/query/pipeline.d.ts.map +1 -0
  788. package/sdk/dist/query/pipeline.js +198 -0
  789. package/sdk/dist/query/pipeline.js.map +1 -0
  790. package/sdk/dist/query/plan-scan.d.ts +14 -0
  791. package/sdk/dist/query/plan-scan.d.ts.map +1 -0
  792. package/sdk/dist/query/plan-scan.js +70 -0
  793. package/sdk/dist/query/plan-scan.js.map +1 -0
  794. package/sdk/dist/query/plan-task-structure.d.ts +9 -0
  795. package/sdk/dist/query/plan-task-structure.d.ts.map +1 -0
  796. package/sdk/dist/query/plan-task-structure.js +59 -0
  797. package/sdk/dist/query/plan-task-structure.js.map +1 -0
  798. package/sdk/dist/query/profile-extract-messages.d.ts +40 -0
  799. package/sdk/dist/query/profile-extract-messages.d.ts.map +1 -0
  800. package/sdk/dist/query/profile-extract-messages.js +195 -0
  801. package/sdk/dist/query/profile-extract-messages.js.map +1 -0
  802. package/sdk/dist/query/profile-output.d.ts +11 -0
  803. package/sdk/dist/query/profile-output.d.ts.map +1 -0
  804. package/sdk/dist/query/profile-output.js +873 -0
  805. package/sdk/dist/query/profile-output.js.map +1 -0
  806. package/sdk/dist/query/profile-questionnaire-data.d.ts +21 -0
  807. package/sdk/dist/query/profile-questionnaire-data.d.ts.map +1 -0
  808. package/sdk/dist/query/profile-questionnaire-data.js +171 -0
  809. package/sdk/dist/query/profile-questionnaire-data.js.map +1 -0
  810. package/sdk/dist/query/profile-sample.d.ts +22 -0
  811. package/sdk/dist/query/profile-sample.d.ts.map +1 -0
  812. package/sdk/dist/query/profile-sample.js +136 -0
  813. package/sdk/dist/query/profile-sample.js.map +1 -0
  814. package/sdk/dist/query/profile-scan-sessions.d.ts +49 -0
  815. package/sdk/dist/query/profile-scan-sessions.d.ts.map +1 -0
  816. package/sdk/dist/query/profile-scan-sessions.js +137 -0
  817. package/sdk/dist/query/profile-scan-sessions.js.map +1 -0
  818. package/sdk/dist/query/profile.d.ts +61 -0
  819. package/sdk/dist/query/profile.d.ts.map +1 -0
  820. package/sdk/dist/query/profile.js +307 -0
  821. package/sdk/dist/query/profile.js.map +1 -0
  822. package/sdk/dist/query/progress.d.ts +77 -0
  823. package/sdk/dist/query/progress.d.ts.map +1 -0
  824. package/sdk/dist/query/progress.js +481 -0
  825. package/sdk/dist/query/progress.js.map +1 -0
  826. package/sdk/dist/query/query-cli-adapter.d.ts +8 -0
  827. package/sdk/dist/query/query-cli-adapter.d.ts.map +1 -0
  828. package/sdk/dist/query/query-cli-adapter.js +32 -0
  829. package/sdk/dist/query/query-cli-adapter.js.map +1 -0
  830. package/sdk/dist/query/query-cli-output.d.ts +9 -0
  831. package/sdk/dist/query/query-cli-output.d.ts.map +1 -0
  832. package/sdk/dist/query/query-cli-output.js +54 -0
  833. package/sdk/dist/query/query-cli-output.js.map +1 -0
  834. package/sdk/dist/query/query-command-diagnosis.d.ts +6 -0
  835. package/sdk/dist/query/query-command-diagnosis.d.ts.map +1 -0
  836. package/sdk/dist/query/query-command-diagnosis.js +6 -0
  837. package/sdk/dist/query/query-command-diagnosis.js.map +1 -0
  838. package/sdk/dist/query/query-command-resolution-strategy.d.ts +29 -0
  839. package/sdk/dist/query/query-command-resolution-strategy.d.ts.map +1 -0
  840. package/sdk/dist/query/query-command-resolution-strategy.js +103 -0
  841. package/sdk/dist/query/query-command-resolution-strategy.js.map +1 -0
  842. package/sdk/dist/query/query-command-semantics.d.ts +7 -0
  843. package/sdk/dist/query/query-command-semantics.d.ts.map +1 -0
  844. package/sdk/dist/query/query-command-semantics.js +7 -0
  845. package/sdk/dist/query/query-command-semantics.js.map +1 -0
  846. package/sdk/dist/query/query-dispatch-contract.d.ts +21 -0
  847. package/sdk/dist/query/query-dispatch-contract.d.ts.map +1 -0
  848. package/sdk/dist/query/query-dispatch-contract.js +2 -0
  849. package/sdk/dist/query/query-dispatch-contract.js.map +1 -0
  850. package/sdk/dist/query/query-dispatch-error-mapper.d.ts +6 -0
  851. package/sdk/dist/query/query-dispatch-error-mapper.d.ts.map +1 -0
  852. package/sdk/dist/query/query-dispatch-error-mapper.js +6 -0
  853. package/sdk/dist/query/query-dispatch-error-mapper.js.map +1 -0
  854. package/sdk/dist/query/query-dispatch-formatting.d.ts +6 -0
  855. package/sdk/dist/query/query-dispatch-formatting.d.ts.map +1 -0
  856. package/sdk/dist/query/query-dispatch-formatting.js +6 -0
  857. package/sdk/dist/query/query-dispatch-formatting.js.map +1 -0
  858. package/sdk/dist/query/query-dispatch-input-validation.d.ts +6 -0
  859. package/sdk/dist/query/query-dispatch-input-validation.d.ts.map +1 -0
  860. package/sdk/dist/query/query-dispatch-input-validation.js +6 -0
  861. package/sdk/dist/query/query-dispatch-input-validation.js.map +1 -0
  862. package/sdk/dist/query/query-dispatch-observability.d.ts +2 -0
  863. package/sdk/dist/query/query-dispatch-observability.d.ts.map +1 -0
  864. package/sdk/dist/query/query-dispatch-observability.js +7 -0
  865. package/sdk/dist/query/query-dispatch-observability.js.map +1 -0
  866. package/sdk/dist/query/query-dispatch-plan.d.ts +6 -0
  867. package/sdk/dist/query/query-dispatch-plan.d.ts.map +1 -0
  868. package/sdk/dist/query/query-dispatch-plan.js +6 -0
  869. package/sdk/dist/query/query-dispatch-plan.js.map +1 -0
  870. package/sdk/dist/query/query-dispatch-result-builder.d.ts +6 -0
  871. package/sdk/dist/query/query-dispatch-result-builder.d.ts.map +1 -0
  872. package/sdk/dist/query/query-dispatch-result-builder.js +6 -0
  873. package/sdk/dist/query/query-dispatch-result-builder.js.map +1 -0
  874. package/sdk/dist/query/query-dispatch.d.ts +48 -0
  875. package/sdk/dist/query/query-dispatch.d.ts.map +1 -0
  876. package/sdk/dist/query/query-dispatch.js +205 -0
  877. package/sdk/dist/query/query-dispatch.js.map +1 -0
  878. package/sdk/dist/query/query-error-details-schema.d.ts +19 -0
  879. package/sdk/dist/query/query-error-details-schema.d.ts.map +1 -0
  880. package/sdk/dist/query/query-error-details-schema.js +10 -0
  881. package/sdk/dist/query/query-error-details-schema.js.map +1 -0
  882. package/sdk/dist/query/query-error-taxonomy.d.ts +38 -0
  883. package/sdk/dist/query/query-error-taxonomy.d.ts.map +1 -0
  884. package/sdk/dist/query/query-error-taxonomy.js +74 -0
  885. package/sdk/dist/query/query-error-taxonomy.js.map +1 -0
  886. package/sdk/dist/query/query-fallback-bridge-adapter.d.ts +14 -0
  887. package/sdk/dist/query/query-fallback-bridge-adapter.d.ts.map +1 -0
  888. package/sdk/dist/query/query-fallback-bridge-adapter.js +33 -0
  889. package/sdk/dist/query/query-fallback-bridge-adapter.js.map +1 -0
  890. package/sdk/dist/query/query-fallback-executor.d.ts +11 -0
  891. package/sdk/dist/query/query-fallback-executor.d.ts.map +1 -0
  892. package/sdk/dist/query/query-fallback-executor.js +31 -0
  893. package/sdk/dist/query/query-fallback-executor.js.map +1 -0
  894. package/sdk/dist/query/query-fallback-output-classifier.d.ts +6 -0
  895. package/sdk/dist/query/query-fallback-output-classifier.d.ts.map +1 -0
  896. package/sdk/dist/query/query-fallback-output-classifier.js +27 -0
  897. package/sdk/dist/query/query-fallback-output-classifier.js.map +1 -0
  898. package/sdk/dist/query/query-fallback-policy.d.ts +6 -0
  899. package/sdk/dist/query/query-fallback-policy.d.ts.map +1 -0
  900. package/sdk/dist/query/query-fallback-policy.js +7 -0
  901. package/sdk/dist/query/query-fallback-policy.js.map +1 -0
  902. package/sdk/dist/query/query-native-dispatch-adapter.d.ts +7 -0
  903. package/sdk/dist/query/query-native-dispatch-adapter.d.ts.map +1 -0
  904. package/sdk/dist/query/query-native-dispatch-adapter.js +6 -0
  905. package/sdk/dist/query/query-native-dispatch-adapter.js.map +1 -0
  906. package/sdk/dist/query/query-policy-capability.d.ts +10 -0
  907. package/sdk/dist/query/query-policy-capability.d.ts.map +1 -0
  908. package/sdk/dist/query/query-policy-capability.js +17 -0
  909. package/sdk/dist/query/query-policy-capability.js.map +1 -0
  910. package/sdk/dist/query/query-runtime-context.d.ts +19 -0
  911. package/sdk/dist/query/query-runtime-context.d.ts.map +1 -0
  912. package/sdk/dist/query/query-runtime-context.js +31 -0
  913. package/sdk/dist/query/query-runtime-context.js.map +1 -0
  914. package/sdk/dist/query/query-unknown-command-hints.d.ts +2 -0
  915. package/sdk/dist/query/query-unknown-command-hints.d.ts.map +1 -0
  916. package/sdk/dist/query/query-unknown-command-hints.js +6 -0
  917. package/sdk/dist/query/query-unknown-command-hints.js.map +1 -0
  918. package/sdk/dist/query/registry-assembly-descriptor.d.ts +12 -0
  919. package/sdk/dist/query/registry-assembly-descriptor.d.ts.map +1 -0
  920. package/sdk/dist/query/registry-assembly-descriptor.js +61 -0
  921. package/sdk/dist/query/registry-assembly-descriptor.js.map +1 -0
  922. package/sdk/dist/query/registry-assembly-invariants.d.ts +30 -0
  923. package/sdk/dist/query/registry-assembly-invariants.d.ts.map +1 -0
  924. package/sdk/dist/query/registry-assembly-invariants.js +77 -0
  925. package/sdk/dist/query/registry-assembly-invariants.js.map +1 -0
  926. package/sdk/dist/query/registry-assembly.d.ts +10 -0
  927. package/sdk/dist/query/registry-assembly.d.ts.map +1 -0
  928. package/sdk/dist/query/registry-assembly.js +53 -0
  929. package/sdk/dist/query/registry-assembly.js.map +1 -0
  930. package/sdk/dist/query/registry.d.ts +90 -0
  931. package/sdk/dist/query/registry.d.ts.map +1 -0
  932. package/sdk/dist/query/registry.js +129 -0
  933. package/sdk/dist/query/registry.js.map +1 -0
  934. package/sdk/dist/query/requirements-extract-from-plans.d.ts +9 -0
  935. package/sdk/dist/query/requirements-extract-from-plans.d.ts.map +1 -0
  936. package/sdk/dist/query/requirements-extract-from-plans.js +76 -0
  937. package/sdk/dist/query/requirements-extract-from-plans.js.map +1 -0
  938. package/sdk/dist/query/roadmap-update-plan-progress.d.ts +11 -0
  939. package/sdk/dist/query/roadmap-update-plan-progress.d.ts.map +1 -0
  940. package/sdk/dist/query/roadmap-update-plan-progress.js +124 -0
  941. package/sdk/dist/query/roadmap-update-plan-progress.js.map +1 -0
  942. package/sdk/dist/query/roadmap.d.ts +137 -0
  943. package/sdk/dist/query/roadmap.d.ts.map +1 -0
  944. package/sdk/dist/query/roadmap.js +753 -0
  945. package/sdk/dist/query/roadmap.js.map +1 -0
  946. package/sdk/dist/query/route-next-action.d.ts +9 -0
  947. package/sdk/dist/query/route-next-action.d.ts.map +1 -0
  948. package/sdk/dist/query/route-next-action.js +342 -0
  949. package/sdk/dist/query/route-next-action.js.map +1 -0
  950. package/sdk/dist/query/schema-detect.d.ts +21 -0
  951. package/sdk/dist/query/schema-detect.d.ts.map +1 -0
  952. package/sdk/dist/query/schema-detect.js +146 -0
  953. package/sdk/dist/query/schema-detect.js.map +1 -0
  954. package/sdk/dist/query/secrets.d.ts +27 -0
  955. package/sdk/dist/query/secrets.d.ts.map +1 -0
  956. package/sdk/dist/query/secrets.js +42 -0
  957. package/sdk/dist/query/secrets.js.map +1 -0
  958. package/sdk/dist/query/skill-manifest.d.ts +50 -0
  959. package/sdk/dist/query/skill-manifest.d.ts.map +1 -0
  960. package/sdk/dist/query/skill-manifest.js +171 -0
  961. package/sdk/dist/query/skill-manifest.js.map +1 -0
  962. package/sdk/dist/query/skills.d.ts +27 -0
  963. package/sdk/dist/query/skills.d.ts.map +1 -0
  964. package/sdk/dist/query/skills.js +137 -0
  965. package/sdk/dist/query/skills.js.map +1 -0
  966. package/sdk/dist/query/state-document.d.ts +14 -0
  967. package/sdk/dist/query/state-document.d.ts.map +1 -0
  968. package/sdk/dist/query/state-document.js +110 -0
  969. package/sdk/dist/query/state-document.js.map +1 -0
  970. package/sdk/dist/query/state-mutation.d.ts +224 -0
  971. package/sdk/dist/query/state-mutation.d.ts.map +1 -0
  972. package/sdk/dist/query/state-mutation.js +1539 -0
  973. package/sdk/dist/query/state-mutation.js.map +1 -0
  974. package/sdk/dist/query/state-project-load.d.ts +23 -0
  975. package/sdk/dist/query/state-project-load.d.ts.map +1 -0
  976. package/sdk/dist/query/state-project-load.js +75 -0
  977. package/sdk/dist/query/state-project-load.js.map +1 -0
  978. package/sdk/dist/query/state.d.ts +78 -0
  979. package/sdk/dist/query/state.d.ts.map +1 -0
  980. package/sdk/dist/query/state.js +430 -0
  981. package/sdk/dist/query/state.js.map +1 -0
  982. package/sdk/dist/query/summary.d.ts +18 -0
  983. package/sdk/dist/query/summary.d.ts.map +1 -0
  984. package/sdk/dist/query/summary.js +249 -0
  985. package/sdk/dist/query/summary.js.map +1 -0
  986. package/sdk/dist/query/task-issues.d.ts +5 -0
  987. package/sdk/dist/query/task-issues.d.ts.map +1 -0
  988. package/sdk/dist/query/task-issues.js +72 -0
  989. package/sdk/dist/query/task-issues.js.map +1 -0
  990. package/sdk/dist/query/template.d.ts +46 -0
  991. package/sdk/dist/query/template.d.ts.map +1 -0
  992. package/sdk/dist/query/template.js +210 -0
  993. package/sdk/dist/query/template.js.map +1 -0
  994. package/sdk/dist/query/uat.d.ts +34 -0
  995. package/sdk/dist/query/uat.d.ts.map +1 -0
  996. package/sdk/dist/query/uat.js +339 -0
  997. package/sdk/dist/query/uat.js.map +1 -0
  998. package/sdk/dist/query/utils.d.ts +59 -0
  999. package/sdk/dist/query/utils.d.ts.map +1 -0
  1000. package/sdk/dist/query/utils.js +74 -0
  1001. package/sdk/dist/query/utils.js.map +1 -0
  1002. package/sdk/dist/query/validate.d.ts +67 -0
  1003. package/sdk/dist/query/validate.d.ts.map +1 -0
  1004. package/sdk/dist/query/validate.js +908 -0
  1005. package/sdk/dist/query/validate.js.map +1 -0
  1006. package/sdk/dist/query/verify.d.ts +110 -0
  1007. package/sdk/dist/query/verify.d.ts.map +1 -0
  1008. package/sdk/dist/query/verify.js +647 -0
  1009. package/sdk/dist/query/verify.js.map +1 -0
  1010. package/sdk/dist/query/websearch.d.ts +24 -0
  1011. package/sdk/dist/query/websearch.d.ts.map +1 -0
  1012. package/sdk/dist/query/websearch.js +68 -0
  1013. package/sdk/dist/query/websearch.js.map +1 -0
  1014. package/sdk/dist/query/workspace.d.ts +62 -0
  1015. package/sdk/dist/query/workspace.d.ts.map +1 -0
  1016. package/sdk/dist/query/workspace.js +104 -0
  1017. package/sdk/dist/query/workspace.js.map +1 -0
  1018. package/sdk/dist/query/workstream-inventory.d.ts +24 -0
  1019. package/sdk/dist/query/workstream-inventory.d.ts.map +1 -0
  1020. package/sdk/dist/query/workstream-inventory.js +120 -0
  1021. package/sdk/dist/query/workstream-inventory.js.map +1 -0
  1022. package/sdk/dist/query/workstream.d.ts +35 -0
  1023. package/sdk/dist/query/workstream.d.ts.map +1 -0
  1024. package/sdk/dist/query/workstream.js +298 -0
  1025. package/sdk/dist/query/workstream.js.map +1 -0
  1026. package/sdk/dist/query/worktree.d.ts +3 -0
  1027. package/sdk/dist/query/worktree.d.ts.map +1 -0
  1028. package/sdk/dist/query/worktree.js +36 -0
  1029. package/sdk/dist/query/worktree.js.map +1 -0
  1030. package/sdk/dist/query-command-executor.d.ts +22 -0
  1031. package/sdk/dist/query-command-executor.d.ts.map +1 -0
  1032. package/sdk/dist/query-command-executor.js +22 -0
  1033. package/sdk/dist/query-command-executor.js.map +1 -0
  1034. package/sdk/dist/query-execution-policy.d.ts +24 -0
  1035. package/sdk/dist/query-execution-policy.d.ts.map +1 -0
  1036. package/sdk/dist/query-execution-policy.js +27 -0
  1037. package/sdk/dist/query-execution-policy.js.map +1 -0
  1038. package/sdk/dist/query-failure-classification.d.ts +9 -0
  1039. package/sdk/dist/query-failure-classification.d.ts.map +1 -0
  1040. package/sdk/dist/query-failure-classification.js +32 -0
  1041. package/sdk/dist/query-failure-classification.js.map +1 -0
  1042. package/sdk/dist/query-gtd-tools-path.d.ts +2 -0
  1043. package/sdk/dist/query-gtd-tools-path.d.ts.map +1 -0
  1044. package/sdk/dist/query-gtd-tools-path.js +2 -0
  1045. package/sdk/dist/query-gtd-tools-path.js.map +1 -0
  1046. package/sdk/dist/query-gtd-tools-runtime.d.ts +20 -0
  1047. package/sdk/dist/query-gtd-tools-runtime.d.ts.map +1 -0
  1048. package/sdk/dist/query-gtd-tools-runtime.js +47 -0
  1049. package/sdk/dist/query-gtd-tools-runtime.js.map +1 -0
  1050. package/sdk/dist/query-hotpath-methods.d.ts +19 -0
  1051. package/sdk/dist/query-hotpath-methods.d.ts.map +1 -0
  1052. package/sdk/dist/query-hotpath-methods.js +34 -0
  1053. package/sdk/dist/query-hotpath-methods.js.map +1 -0
  1054. package/sdk/dist/query-native-direct-adapter.d.ts +20 -0
  1055. package/sdk/dist/query-native-direct-adapter.d.ts.map +1 -0
  1056. package/sdk/dist/query-native-direct-adapter.js +52 -0
  1057. package/sdk/dist/query-native-direct-adapter.js.map +1 -0
  1058. package/sdk/dist/query-native-hotpath-adapter.d.ts +15 -0
  1059. package/sdk/dist/query-native-hotpath-adapter.d.ts.map +1 -0
  1060. package/sdk/dist/query-native-hotpath-adapter.js +32 -0
  1061. package/sdk/dist/query-native-hotpath-adapter.js.map +1 -0
  1062. package/sdk/dist/query-raw-output-projection.d.ts +6 -0
  1063. package/sdk/dist/query-raw-output-projection.d.ts.map +1 -0
  1064. package/sdk/dist/query-raw-output-projection.js +67 -0
  1065. package/sdk/dist/query-raw-output-projection.js.map +1 -0
  1066. package/sdk/dist/query-runtime-bridge.d.ts +61 -0
  1067. package/sdk/dist/query-runtime-bridge.d.ts.map +1 -0
  1068. package/sdk/dist/query-runtime-bridge.js +144 -0
  1069. package/sdk/dist/query-runtime-bridge.js.map +1 -0
  1070. package/sdk/dist/query-subprocess-adapter.d.ts +18 -0
  1071. package/sdk/dist/query-subprocess-adapter.d.ts.map +1 -0
  1072. package/sdk/dist/query-subprocess-adapter.js +92 -0
  1073. package/sdk/dist/query-subprocess-adapter.js.map +1 -0
  1074. package/sdk/dist/query-tools-error-factory.d.ts +16 -0
  1075. package/sdk/dist/query-tools-error-factory.d.ts.map +1 -0
  1076. package/sdk/dist/query-tools-error-factory.js +33 -0
  1077. package/sdk/dist/query-tools-error-factory.js.map +1 -0
  1078. package/sdk/dist/research-gate.d.ts +24 -0
  1079. package/sdk/dist/research-gate.d.ts.map +1 -0
  1080. package/sdk/dist/research-gate.js +70 -0
  1081. package/sdk/dist/research-gate.js.map +1 -0
  1082. package/sdk/dist/runtime-bridge-sync/index.d.ts +96 -0
  1083. package/sdk/dist/runtime-bridge-sync/index.d.ts.map +1 -0
  1084. package/sdk/dist/runtime-bridge-sync/index.js +109 -0
  1085. package/sdk/dist/runtime-bridge-sync/index.js.map +1 -0
  1086. package/sdk/dist/runtime-bridge-sync/worker.d.ts +2 -0
  1087. package/sdk/dist/runtime-bridge-sync/worker.d.ts.map +1 -0
  1088. package/sdk/dist/runtime-bridge-sync/worker.js +138 -0
  1089. package/sdk/dist/runtime-bridge-sync/worker.js.map +1 -0
  1090. package/sdk/dist/runtime-gate.d.ts +14 -0
  1091. package/sdk/dist/runtime-gate.d.ts.map +1 -0
  1092. package/sdk/dist/runtime-gate.js +48 -0
  1093. package/sdk/dist/runtime-gate.js.map +1 -0
  1094. package/sdk/dist/sdk-package-compatibility.d.ts +40 -0
  1095. package/sdk/dist/sdk-package-compatibility.d.ts.map +1 -0
  1096. package/sdk/dist/sdk-package-compatibility.js +94 -0
  1097. package/sdk/dist/sdk-package-compatibility.js.map +1 -0
  1098. package/sdk/dist/session-runner.d.ts +40 -0
  1099. package/sdk/dist/session-runner.d.ts.map +1 -0
  1100. package/sdk/dist/session-runner.js +274 -0
  1101. package/sdk/dist/session-runner.js.map +1 -0
  1102. package/sdk/dist/task-issues/adapters.d.ts +94 -0
  1103. package/sdk/dist/task-issues/adapters.d.ts.map +1 -0
  1104. package/sdk/dist/task-issues/adapters.js +2 -0
  1105. package/sdk/dist/task-issues/adapters.js.map +1 -0
  1106. package/sdk/dist/task-issues/core.d.ts +16 -0
  1107. package/sdk/dist/task-issues/core.d.ts.map +1 -0
  1108. package/sdk/dist/task-issues/core.js +283 -0
  1109. package/sdk/dist/task-issues/core.js.map +1 -0
  1110. package/sdk/dist/task-issues/export-phase-issues.d.ts +326 -0
  1111. package/sdk/dist/task-issues/export-phase-issues.d.ts.map +1 -0
  1112. package/sdk/dist/task-issues/export-phase-issues.js +1675 -0
  1113. package/sdk/dist/task-issues/export-phase-issues.js.map +1 -0
  1114. package/sdk/dist/task-issues/github-api-client.d.ts +23 -0
  1115. package/sdk/dist/task-issues/github-api-client.d.ts.map +1 -0
  1116. package/sdk/dist/task-issues/github-api-client.js +66 -0
  1117. package/sdk/dist/task-issues/github-api-client.js.map +1 -0
  1118. package/sdk/dist/task-issues/github-repo.d.ts +4 -0
  1119. package/sdk/dist/task-issues/github-repo.d.ts.map +1 -0
  1120. package/sdk/dist/task-issues/github-repo.js +108 -0
  1121. package/sdk/dist/task-issues/github-repo.js.map +1 -0
  1122. package/sdk/dist/task-issues/orchestrate-tasks.d.ts +319 -0
  1123. package/sdk/dist/task-issues/orchestrate-tasks.d.ts.map +1 -0
  1124. package/sdk/dist/task-issues/orchestrate-tasks.js +2040 -0
  1125. package/sdk/dist/task-issues/orchestrate-tasks.js.map +1 -0
  1126. package/sdk/dist/task-issues/plan-scan.d.ts +13 -0
  1127. package/sdk/dist/task-issues/plan-scan.d.ts.map +1 -0
  1128. package/sdk/dist/task-issues/plan-scan.js +70 -0
  1129. package/sdk/dist/task-issues/plan-scan.js.map +1 -0
  1130. package/sdk/dist/task-issues/runtime-slash.d.ts +4 -0
  1131. package/sdk/dist/task-issues/runtime-slash.d.ts.map +1 -0
  1132. package/sdk/dist/task-issues/runtime-slash.js +40 -0
  1133. package/sdk/dist/task-issues/runtime-slash.js.map +1 -0
  1134. package/sdk/dist/task-issues/task-issue-shared.d.ts +18 -0
  1135. package/sdk/dist/task-issues/task-issue-shared.d.ts.map +1 -0
  1136. package/sdk/dist/task-issues/task-issue-shared.js +44 -0
  1137. package/sdk/dist/task-issues/task-issue-shared.js.map +1 -0
  1138. package/sdk/dist/task-issues/types.d.ts +30 -0
  1139. package/sdk/dist/task-issues/types.d.ts.map +1 -0
  1140. package/sdk/dist/task-issues/types.js +2 -0
  1141. package/sdk/dist/task-issues/types.js.map +1 -0
  1142. package/sdk/dist/task-issues/work-task-issue.d.ts +1199 -0
  1143. package/sdk/dist/task-issues/work-task-issue.d.ts.map +1 -0
  1144. package/sdk/dist/task-issues/work-task-issue.js +3255 -0
  1145. package/sdk/dist/task-issues/work-task-issue.js.map +1 -0
  1146. package/sdk/dist/task-issues/worktree-safety.d.ts +5 -0
  1147. package/sdk/dist/task-issues/worktree-safety.d.ts.map +1 -0
  1148. package/sdk/dist/task-issues/worktree-safety.js +18 -0
  1149. package/sdk/dist/task-issues/worktree-safety.js.map +1 -0
  1150. package/sdk/dist/tool-scoping.d.ts +31 -0
  1151. package/sdk/dist/tool-scoping.d.ts.map +1 -0
  1152. package/sdk/dist/tool-scoping.js +54 -0
  1153. package/sdk/dist/tool-scoping.js.map +1 -0
  1154. package/sdk/dist/types.d.ts +795 -0
  1155. package/sdk/dist/types.d.ts.map +1 -0
  1156. package/sdk/dist/types.js +77 -0
  1157. package/sdk/dist/types.js.map +1 -0
  1158. package/sdk/dist/workstream-inventory/builder.d.ts +88 -0
  1159. package/sdk/dist/workstream-inventory/builder.d.ts.map +1 -0
  1160. package/sdk/dist/workstream-inventory/builder.js +84 -0
  1161. package/sdk/dist/workstream-inventory/builder.js.map +1 -0
  1162. package/sdk/dist/workstream-name-policy.d.ts +13 -0
  1163. package/sdk/dist/workstream-name-policy.d.ts.map +1 -0
  1164. package/sdk/dist/workstream-name-policy.js +24 -0
  1165. package/sdk/dist/workstream-name-policy.js.map +1 -0
  1166. package/sdk/dist/workstream-utils.d.ts +23 -0
  1167. package/sdk/dist/workstream-utils.d.ts.map +1 -0
  1168. package/sdk/dist/workstream-utils.js +34 -0
  1169. package/sdk/dist/workstream-utils.js.map +1 -0
  1170. package/sdk/dist/ws-transport.d.ts +32 -0
  1171. package/sdk/dist/ws-transport.d.ts.map +1 -0
  1172. package/sdk/dist/ws-transport.js +84 -0
  1173. package/sdk/dist/ws-transport.js.map +1 -0
  1174. package/sdk/package-lock.json +2530 -0
  1175. package/sdk/package.json +67 -0
  1176. package/sdk/prompts/templates/project.md +186 -0
  1177. package/sdk/prompts/templates/requirements.md +231 -0
  1178. package/sdk/prompts/templates/research-project/ARCHITECTURE.md +204 -0
  1179. package/sdk/prompts/templates/research-project/FEATURES.md +147 -0
  1180. package/sdk/prompts/templates/research-project/PITFALLS.md +200 -0
  1181. package/sdk/prompts/templates/research-project/STACK.md +120 -0
  1182. package/sdk/prompts/templates/research-project/SUMMARY.md +170 -0
  1183. package/sdk/prompts/templates/roadmap.md +202 -0
  1184. package/sdk/prompts/templates/state.md +175 -0
  1185. package/sdk/shared/config-defaults.manifest.json +71 -0
  1186. package/sdk/shared/config-schema.manifest.json +139 -0
  1187. package/sdk/shared/model-catalog.json +122 -0
  1188. package/sdk/src/assembled-prompts.test.ts +349 -0
  1189. package/sdk/src/bug-3589-planning-paths-validation.test.ts +89 -0
  1190. package/sdk/src/bug-3591-gtdtools-runtime-workstream.test.ts +179 -0
  1191. package/sdk/src/cli-transport.test.ts +388 -0
  1192. package/sdk/src/cli-transport.ts +130 -0
  1193. package/sdk/src/cli.test.ts +426 -0
  1194. package/sdk/src/cli.ts +589 -0
  1195. package/sdk/src/config.test.ts +277 -0
  1196. package/sdk/src/config.ts +201 -0
  1197. package/sdk/src/configuration/index.test.ts +318 -0
  1198. package/sdk/src/configuration/index.ts +325 -0
  1199. package/sdk/src/context-engine.test.ts +295 -0
  1200. package/sdk/src/context-engine.ts +170 -0
  1201. package/sdk/src/context-truncation.test.ts +163 -0
  1202. package/sdk/src/context-truncation.ts +233 -0
  1203. package/sdk/src/e2e.integration.test.ts +181 -0
  1204. package/sdk/src/errors.ts +72 -0
  1205. package/sdk/src/event-stream.test.ts +661 -0
  1206. package/sdk/src/event-stream.ts +441 -0
  1207. package/sdk/src/golden/capture.ts +95 -0
  1208. package/sdk/src/golden/fixtures/generate-slug.golden.json +1 -0
  1209. package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +3 -0
  1210. package/sdk/src/golden/fixtures/summary-extract-sample.md +26 -0
  1211. package/sdk/src/golden/fixtures/uat-render-checkpoint-sample.md +15 -0
  1212. package/sdk/src/golden/golden-integration-covered.ts +30 -0
  1213. package/sdk/src/golden/golden-mutation-covered.ts +17 -0
  1214. package/sdk/src/golden/golden-policy.test.ts +8 -0
  1215. package/sdk/src/golden/golden-policy.ts +118 -0
  1216. package/sdk/src/golden/golden.integration.test.ts +897 -0
  1217. package/sdk/src/golden/init-golden-normalize.ts +15 -0
  1218. package/sdk/src/golden/read-only-golden-rows.ts +77 -0
  1219. package/sdk/src/golden/read-only-parity.integration.test.ts +133 -0
  1220. package/sdk/src/golden/registry-canonical-commands.ts +31 -0
  1221. package/sdk/src/gtd-tools-error.test.ts +21 -0
  1222. package/sdk/src/gtd-tools-error.ts +65 -0
  1223. package/sdk/src/gtd-tools.test.ts +472 -0
  1224. package/sdk/src/gtd-tools.ts +285 -0
  1225. package/sdk/src/gtd-transport-policy.test.ts +34 -0
  1226. package/sdk/src/gtd-transport-policy.ts +48 -0
  1227. package/sdk/src/gtd-transport.test.ts +292 -0
  1228. package/sdk/src/gtd-transport.ts +117 -0
  1229. package/sdk/src/index.ts +371 -0
  1230. package/sdk/src/init-e2e.integration.test.ts +138 -0
  1231. package/sdk/src/init-runner.test.ts +740 -0
  1232. package/sdk/src/init-runner.ts +734 -0
  1233. package/sdk/src/lifecycle-e2e.integration.test.ts +258 -0
  1234. package/sdk/src/logger.test.ts +149 -0
  1235. package/sdk/src/logger.ts +113 -0
  1236. package/sdk/src/milestone-runner.test.ts +421 -0
  1237. package/sdk/src/model-catalog.ts +77 -0
  1238. package/sdk/src/phase-prompt.test.ts +536 -0
  1239. package/sdk/src/phase-prompt.ts +257 -0
  1240. package/sdk/src/phase-runner-types.test.ts +421 -0
  1241. package/sdk/src/phase-runner.integration.test.ts +377 -0
  1242. package/sdk/src/phase-runner.test.ts +2720 -0
  1243. package/sdk/src/phase-runner.ts +1442 -0
  1244. package/sdk/src/plan-atomicity.test.ts +220 -0
  1245. package/sdk/src/plan-atomicity.ts +162 -0
  1246. package/sdk/src/plan-parser.test.ts +579 -0
  1247. package/sdk/src/plan-parser.ts +433 -0
  1248. package/sdk/src/planning-journal.test.ts +70 -0
  1249. package/sdk/src/planning-journal.ts +153 -0
  1250. package/sdk/src/planning-runtime.test.ts +29 -0
  1251. package/sdk/src/planning-runtime.ts +100 -0
  1252. package/sdk/src/project-root/index.test.ts +186 -0
  1253. package/sdk/src/project-root/index.ts +144 -0
  1254. package/sdk/src/prompt-builder.test.ts +318 -0
  1255. package/sdk/src/prompt-builder.ts +218 -0
  1256. package/sdk/src/prompt-sanitizer.test.ts +260 -0
  1257. package/sdk/src/prompt-sanitizer.ts +116 -0
  1258. package/sdk/src/query/QUERY-HANDLERS.md +346 -0
  1259. package/sdk/src/query/active-workstream-store.ts +50 -0
  1260. package/sdk/src/query/agent-failure-classifier.test.ts +157 -0
  1261. package/sdk/src/query/agent-failure-classifier.ts +104 -0
  1262. package/sdk/src/query/audit-open.ts +722 -0
  1263. package/sdk/src/query/check-auto-mode.test.ts +77 -0
  1264. package/sdk/src/query/check-auto-mode.ts +49 -0
  1265. package/sdk/src/query/check-completion.test.ts +113 -0
  1266. package/sdk/src/query/check-completion.ts +182 -0
  1267. package/sdk/src/query/check-decision-coverage.test.ts +519 -0
  1268. package/sdk/src/query/check-decision-coverage.ts +554 -0
  1269. package/sdk/src/query/check-gates.test.ts +103 -0
  1270. package/sdk/src/query/check-gates.ts +112 -0
  1271. package/sdk/src/query/check-verification-status.test.ts +143 -0
  1272. package/sdk/src/query/check-verification-status.ts +160 -0
  1273. package/sdk/src/query/command-aliases.generated.ts +155 -0
  1274. package/sdk/src/query/command-catalog.ts +31 -0
  1275. package/sdk/src/query/command-definition.test.ts +47 -0
  1276. package/sdk/src/query/command-definition.ts +70 -0
  1277. package/sdk/src/query/command-family-handlers.ts +116 -0
  1278. package/sdk/src/query/command-manifest.init.ts +23 -0
  1279. package/sdk/src/query/command-manifest.non-family.ts +89 -0
  1280. package/sdk/src/query/command-manifest.phase.ts +16 -0
  1281. package/sdk/src/query/command-manifest.phases.ts +11 -0
  1282. package/sdk/src/query/command-manifest.roadmap.ts +11 -0
  1283. package/sdk/src/query/command-manifest.state.ts +31 -0
  1284. package/sdk/src/query/command-manifest.ts +17 -0
  1285. package/sdk/src/query/command-manifest.types.ts +13 -0
  1286. package/sdk/src/query/command-manifest.validate.ts +11 -0
  1287. package/sdk/src/query/command-manifest.verify.ts +15 -0
  1288. package/sdk/src/query/command-resolution.test.ts +70 -0
  1289. package/sdk/src/query/command-seam-coverage.test.ts +118 -0
  1290. package/sdk/src/query/command-static-catalog-domain.ts +121 -0
  1291. package/sdk/src/query/command-static-catalog-foundation.ts +100 -0
  1292. package/sdk/src/query/command-topology.test.ts +28 -0
  1293. package/sdk/src/query/command-topology.ts +114 -0
  1294. package/sdk/src/query/commands-list.test.ts +36 -0
  1295. package/sdk/src/query/commands-list.ts +19 -0
  1296. package/sdk/src/query/commit.test.ts +485 -0
  1297. package/sdk/src/query/commit.ts +383 -0
  1298. package/sdk/src/query/config-gates.test.ts +89 -0
  1299. package/sdk/src/query/config-gates.ts +69 -0
  1300. package/sdk/src/query/config-mutation.test.ts +572 -0
  1301. package/sdk/src/query/config-mutation.ts +484 -0
  1302. package/sdk/src/query/config-query.test.ts +367 -0
  1303. package/sdk/src/query/config-query.ts +244 -0
  1304. package/sdk/src/query/config-schema.ts +35 -0
  1305. package/sdk/src/query/decisions.test.ts +215 -0
  1306. package/sdk/src/query/decisions.ts +192 -0
  1307. package/sdk/src/query/decomposed-handlers.test.ts +431 -0
  1308. package/sdk/src/query/detect-custom-files.test.ts +115 -0
  1309. package/sdk/src/query/detect-custom-files.ts +96 -0
  1310. package/sdk/src/query/detect-phase-type.test.ts +105 -0
  1311. package/sdk/src/query/detect-phase-type.ts +141 -0
  1312. package/sdk/src/query/docs-init.ts +258 -0
  1313. package/sdk/src/query/fallow-audit.ts +88 -0
  1314. package/sdk/src/query/frontmatter-array.test.ts +14 -0
  1315. package/sdk/src/query/frontmatter-mutation.test.ts +259 -0
  1316. package/sdk/src/query/frontmatter-mutation.ts +343 -0
  1317. package/sdk/src/query/frontmatter.test.ts +326 -0
  1318. package/sdk/src/query/frontmatter.ts +395 -0
  1319. package/sdk/src/query/helpers.test.ts +615 -0
  1320. package/sdk/src/query/helpers.ts +523 -0
  1321. package/sdk/src/query/index-thin-seam.test.ts +16 -0
  1322. package/sdk/src/query/index.ts +9 -0
  1323. package/sdk/src/query/init-complex.test.ts +616 -0
  1324. package/sdk/src/query/init-complex.ts +805 -0
  1325. package/sdk/src/query/init-progress-precedence.test.ts +177 -0
  1326. package/sdk/src/query/init-workstream-milestone-op.test.ts +321 -0
  1327. package/sdk/src/query/init.test.ts +645 -0
  1328. package/sdk/src/query/init.ts +1167 -0
  1329. package/sdk/src/query/intel.test.ts +90 -0
  1330. package/sdk/src/query/intel.ts +404 -0
  1331. package/sdk/src/query/mutation-event-decorator.test.ts +45 -0
  1332. package/sdk/src/query/mutation-event-decorator.ts +37 -0
  1333. package/sdk/src/query/mutation-event-mapper.test.ts +33 -0
  1334. package/sdk/src/query/mutation-event-mapper.ts +102 -0
  1335. package/sdk/src/query/mvp.test.ts +335 -0
  1336. package/sdk/src/query/mvp.ts +292 -0
  1337. package/sdk/src/query/normalize-query-command.test.ts +102 -0
  1338. package/sdk/src/query/phase-filesystem-adapter.ts +35 -0
  1339. package/sdk/src/query/phase-lifecycle-policy.ts +171 -0
  1340. package/sdk/src/query/phase-lifecycle.test.ts +1750 -0
  1341. package/sdk/src/query/phase-lifecycle.ts +1833 -0
  1342. package/sdk/src/query/phase-list-queries.test.ts +88 -0
  1343. package/sdk/src/query/phase-list-queries.ts +152 -0
  1344. package/sdk/src/query/phase-ready.test.ts +65 -0
  1345. package/sdk/src/query/phase-ready.ts +159 -0
  1346. package/sdk/src/query/phase-roadmap-mutation.ts +77 -0
  1347. package/sdk/src/query/phase.test.ts +651 -0
  1348. package/sdk/src/query/phase.ts +550 -0
  1349. package/sdk/src/query/pipeline.test.ts +169 -0
  1350. package/sdk/src/query/pipeline.ts +243 -0
  1351. package/sdk/src/query/plan-scan.test.ts +35 -0
  1352. package/sdk/src/query/plan-scan.ts +82 -0
  1353. package/sdk/src/query/plan-task-structure.test.ts +65 -0
  1354. package/sdk/src/query/plan-task-structure.ts +63 -0
  1355. package/sdk/src/query/policy-convergence.test.ts +28 -0
  1356. package/sdk/src/query/profile-extract-messages.ts +247 -0
  1357. package/sdk/src/query/profile-output.ts +929 -0
  1358. package/sdk/src/query/profile-questionnaire-data.ts +181 -0
  1359. package/sdk/src/query/profile-sample.ts +184 -0
  1360. package/sdk/src/query/profile-scan-sessions.ts +174 -0
  1361. package/sdk/src/query/profile.test.ts +136 -0
  1362. package/sdk/src/query/profile.ts +337 -0
  1363. package/sdk/src/query/progress.test.ts +156 -0
  1364. package/sdk/src/query/progress.ts +566 -0
  1365. package/sdk/src/query/query-cli-adapter.test.ts +79 -0
  1366. package/sdk/src/query/query-cli-adapter.ts +39 -0
  1367. package/sdk/src/query/query-cli-output.test.ts +33 -0
  1368. package/sdk/src/query/query-cli-output.ts +63 -0
  1369. package/sdk/src/query/query-command-diagnosis.test.ts +22 -0
  1370. package/sdk/src/query/query-command-diagnosis.ts +5 -0
  1371. package/sdk/src/query/query-command-resolution-strategy.test.ts +34 -0
  1372. package/sdk/src/query/query-command-resolution-strategy.ts +121 -0
  1373. package/sdk/src/query/query-command-semantics.test.ts +22 -0
  1374. package/sdk/src/query/query-command-semantics.ts +22 -0
  1375. package/sdk/src/query/query-dispatch-contract.ts +30 -0
  1376. package/sdk/src/query/query-dispatch-error-mapper.test.ts +62 -0
  1377. package/sdk/src/query/query-dispatch-error-mapper.ts +5 -0
  1378. package/sdk/src/query/query-dispatch-formatting.test.ts +28 -0
  1379. package/sdk/src/query/query-dispatch-formatting.ts +5 -0
  1380. package/sdk/src/query/query-dispatch-input-validation.test.ts +23 -0
  1381. package/sdk/src/query/query-dispatch-input-validation.ts +5 -0
  1382. package/sdk/src/query/query-dispatch-observability.test.ts +10 -0
  1383. package/sdk/src/query/query-dispatch-observability.ts +6 -0
  1384. package/sdk/src/query/query-dispatch-plan.test.ts +25 -0
  1385. package/sdk/src/query/query-dispatch-plan.ts +5 -0
  1386. package/sdk/src/query/query-dispatch-result-builder.test.ts +16 -0
  1387. package/sdk/src/query/query-dispatch-result-builder.ts +5 -0
  1388. package/sdk/src/query/query-dispatch.test.ts +399 -0
  1389. package/sdk/src/query/query-dispatch.ts +275 -0
  1390. package/sdk/src/query/query-error-details-schema.ts +29 -0
  1391. package/sdk/src/query/query-error-taxonomy.test.ts +39 -0
  1392. package/sdk/src/query/query-error-taxonomy.ts +117 -0
  1393. package/sdk/src/query/query-fallback-bridge-adapter.test.ts +32 -0
  1394. package/sdk/src/query/query-fallback-bridge-adapter.ts +54 -0
  1395. package/sdk/src/query/query-fallback-executor.test.ts +82 -0
  1396. package/sdk/src/query/query-fallback-executor.ts +44 -0
  1397. package/sdk/src/query/query-fallback-output-classifier.test.ts +36 -0
  1398. package/sdk/src/query/query-fallback-output-classifier.ts +31 -0
  1399. package/sdk/src/query/query-fallback-policy.test.ts +13 -0
  1400. package/sdk/src/query/query-fallback-policy.ts +11 -0
  1401. package/sdk/src/query/query-native-dispatch-adapter.ts +16 -0
  1402. package/sdk/src/query/query-policy-capability.test.ts +10 -0
  1403. package/sdk/src/query/query-policy-capability.ts +26 -0
  1404. package/sdk/src/query/query-policy-snapshot.test.ts +9 -0
  1405. package/sdk/src/query/query-registry-capability.test.ts +14 -0
  1406. package/sdk/src/query/query-runtime-context.ts +44 -0
  1407. package/sdk/src/query/query-unknown-command-hints.test.ts +9 -0
  1408. package/sdk/src/query/query-unknown-command-hints.ts +5 -0
  1409. package/sdk/src/query/registry-assembly-descriptor.ts +87 -0
  1410. package/sdk/src/query/registry-assembly-invariants.ts +127 -0
  1411. package/sdk/src/query/registry-assembly.test.ts +138 -0
  1412. package/sdk/src/query/registry-assembly.ts +78 -0
  1413. package/sdk/src/query/registry.test.ts +208 -0
  1414. package/sdk/src/query/registry.ts +142 -0
  1415. package/sdk/src/query/requirements-extract-from-plans.test.ts +58 -0
  1416. package/sdk/src/query/requirements-extract-from-plans.ts +86 -0
  1417. package/sdk/src/query/roadmap-update-plan-progress.test.ts +233 -0
  1418. package/sdk/src/query/roadmap-update-plan-progress.ts +159 -0
  1419. package/sdk/src/query/roadmap.test.ts +1181 -0
  1420. package/sdk/src/query/roadmap.ts +894 -0
  1421. package/sdk/src/query/route-next-action.test.ts +142 -0
  1422. package/sdk/src/query/route-next-action.ts +370 -0
  1423. package/sdk/src/query/schema-detect.ts +189 -0
  1424. package/sdk/src/query/secrets.test.ts +66 -0
  1425. package/sdk/src/query/secrets.ts +43 -0
  1426. package/sdk/src/query/skill-manifest.test.ts +62 -0
  1427. package/sdk/src/query/skill-manifest.ts +216 -0
  1428. package/sdk/src/query/skills.test.ts +234 -0
  1429. package/sdk/src/query/skills.ts +143 -0
  1430. package/sdk/src/query/state-document.test.ts +197 -0
  1431. package/sdk/src/query/state-document.ts +129 -0
  1432. package/sdk/src/query/state-mutation.test.ts +1198 -0
  1433. package/sdk/src/query/state-mutation.ts +1718 -0
  1434. package/sdk/src/query/state-project-load.ts +80 -0
  1435. package/sdk/src/query/state.test.ts +616 -0
  1436. package/sdk/src/query/state.ts +463 -0
  1437. package/sdk/src/query/sub-repos-root.integration.test.ts +79 -0
  1438. package/sdk/src/query/summary.test.ts +95 -0
  1439. package/sdk/src/query/summary.ts +296 -0
  1440. package/sdk/src/query/task-issues.ts +86 -0
  1441. package/sdk/src/query/template.test.ts +180 -0
  1442. package/sdk/src/query/template.ts +242 -0
  1443. package/sdk/src/query/uat.test.ts +77 -0
  1444. package/sdk/src/query/uat.ts +365 -0
  1445. package/sdk/src/query/utils.test.ts +82 -0
  1446. package/sdk/src/query/utils.ts +106 -0
  1447. package/sdk/src/query/validate.test.ts +831 -0
  1448. package/sdk/src/query/validate.ts +952 -0
  1449. package/sdk/src/query/verify.test.ts +416 -0
  1450. package/sdk/src/query/verify.ts +711 -0
  1451. package/sdk/src/query/websearch.test.ts +31 -0
  1452. package/sdk/src/query/websearch.ts +82 -0
  1453. package/sdk/src/query/workspace.test.ts +120 -0
  1454. package/sdk/src/query/workspace.ts +145 -0
  1455. package/sdk/src/query/workstream-inventory.ts +143 -0
  1456. package/sdk/src/query/workstream.test.ts +153 -0
  1457. package/sdk/src/query/workstream.ts +324 -0
  1458. package/sdk/src/query/worktree.ts +39 -0
  1459. package/sdk/src/query-command-executor.ts +31 -0
  1460. package/sdk/src/query-execution-policy.test.ts +52 -0
  1461. package/sdk/src/query-execution-policy.ts +46 -0
  1462. package/sdk/src/query-failure-classification.test.ts +23 -0
  1463. package/sdk/src/query-failure-classification.ts +42 -0
  1464. package/sdk/src/query-gtd-tools-path.ts +1 -0
  1465. package/sdk/src/query-gtd-tools-runtime.ts +89 -0
  1466. package/sdk/src/query-hotpath-methods.ts +48 -0
  1467. package/sdk/src/query-native-direct-adapter.test.ts +35 -0
  1468. package/sdk/src/query-native-direct-adapter.ts +70 -0
  1469. package/sdk/src/query-native-hotpath-adapter.test.ts +43 -0
  1470. package/sdk/src/query-native-hotpath-adapter.ts +45 -0
  1471. package/sdk/src/query-raw-output-projection.test.ts +39 -0
  1472. package/sdk/src/query-raw-output-projection.ts +74 -0
  1473. package/sdk/src/query-runtime-bridge.test.ts +150 -0
  1474. package/sdk/src/query-runtime-bridge.ts +215 -0
  1475. package/sdk/src/query-runtime-seam-coverage.test.ts +20 -0
  1476. package/sdk/src/query-subprocess-adapter.test.ts +84 -0
  1477. package/sdk/src/query-subprocess-adapter.ts +146 -0
  1478. package/sdk/src/query-tools-error-factory.test.ts +35 -0
  1479. package/sdk/src/query-tools-error-factory.ts +76 -0
  1480. package/sdk/src/research-gate.test.ts +190 -0
  1481. package/sdk/src/research-gate.ts +94 -0
  1482. package/sdk/src/runtime-bridge-options.test.ts +33 -0
  1483. package/sdk/src/runtime-bridge-sync/index.test.ts +164 -0
  1484. package/sdk/src/runtime-bridge-sync/index.ts +154 -0
  1485. package/sdk/src/runtime-bridge-sync/projectdir-regression.test.ts +151 -0
  1486. package/sdk/src/runtime-bridge-sync/worker.ts +181 -0
  1487. package/sdk/src/runtime-gate.test.ts +84 -0
  1488. package/sdk/src/runtime-gate.ts +52 -0
  1489. package/sdk/src/sdk-package-compatibility.test.ts +100 -0
  1490. package/sdk/src/sdk-package-compatibility.ts +149 -0
  1491. package/sdk/src/session-runner.test.ts +164 -0
  1492. package/sdk/src/session-runner.ts +327 -0
  1493. package/sdk/src/task-issues/adapters.ts +86 -0
  1494. package/sdk/src/task-issues/core.ts +287 -0
  1495. package/sdk/src/task-issues/export-phase-issues.ts +1862 -0
  1496. package/sdk/src/task-issues/github-api-client.ts +107 -0
  1497. package/sdk/src/task-issues/github-repo.ts +111 -0
  1498. package/sdk/src/task-issues/orchestrate-tasks.ts +2167 -0
  1499. package/sdk/src/task-issues/plan-scan.ts +78 -0
  1500. package/sdk/src/task-issues/runtime-slash.ts +37 -0
  1501. package/sdk/src/task-issues/task-issue-shared.ts +48 -0
  1502. package/sdk/src/task-issues/types.ts +34 -0
  1503. package/sdk/src/task-issues/work-task-issue.ts +3429 -0
  1504. package/sdk/src/task-issues/worktree-safety.ts +15 -0
  1505. package/sdk/src/task-issues-sdk.test.ts +182 -0
  1506. package/sdk/src/tool-scoping.test.ts +160 -0
  1507. package/sdk/src/tool-scoping.ts +61 -0
  1508. package/sdk/src/types.ts +928 -0
  1509. package/sdk/src/workflow-agent-skills-consistency.test.ts +98 -0
  1510. package/sdk/src/workstream-inventory/builder.test.ts +241 -0
  1511. package/sdk/src/workstream-inventory/builder.ts +170 -0
  1512. package/sdk/src/workstream-name-policy.ts +24 -0
  1513. package/sdk/src/workstream-utils.ts +36 -0
  1514. package/sdk/src/ws-flag.test.ts +285 -0
  1515. package/sdk/src/ws-transport.test.ts +161 -0
  1516. package/sdk/src/ws-transport.ts +93 -0
  1517. package/sdk/tsconfig.json +20 -0
@@ -0,0 +1,3429 @@
1
+ // @ts-nocheck
2
+
3
+ /**
4
+ * Task issue workflow selector and executor.
5
+ *
6
+ * Read-only mode reports the state-sync labels and next action without
7
+ * mutating GitHub or git. Execution mode applies the same preflight, claims one
8
+ * workable task, runs it in an isolated task worktree through the standalone
9
+ * gtd-task-executor contract, validates the result, and opens or updates the
10
+ * task PR.
11
+ */
12
+
13
+ import * as fs from 'node:fs';
14
+ import * as os from 'node:os';
15
+ import * as path from 'node:path';
16
+ import * as childProcess from 'node:child_process';
17
+
18
+ import {
19
+ ERROR_REASON,
20
+ error,
21
+ output,
22
+ planningDir,
23
+ toPosixPath,
24
+ } from './core.js';
25
+ import { loadExportSource } from './export-phase-issues.js';
26
+ import { parseWorktreePorcelain } from './worktree-safety.js';
27
+ import { formatGtdSlashFor } from './runtime-slash.js';
28
+ import {
29
+ normalizeGitHubRepo,
30
+ resolveGitHubRepoFromGit,
31
+ } from './github-repo.js';
32
+ import {
33
+ CHECKPOINT_RESOLVED_STATUS,
34
+ PLAN_ID_RE,
35
+ TASK_EXPORT_STATUSES,
36
+ TASK_ID_RE,
37
+ isCheckpointTaskType,
38
+ isIssueOpen,
39
+ issueLabels,
40
+ mergeLabelSet,
41
+ normalizeRepoPath,
42
+ normalizeTaskType,
43
+ } from './task-issue-shared.js';
44
+ import {
45
+ api as ghApi,
46
+ repoEndpoint as ghRepoEndpoint,
47
+ runGhCommand,
48
+ } from './github-api-client.js';
49
+
50
+ const ISSUE_URL_RE = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+)\/issues\/(\d+)(?:[/?#].*)?$/i;
51
+
52
+ const TASK_STATE_LABELS = Object.freeze([
53
+ 'gtd:ready',
54
+ 'gtd:blocked',
55
+ 'gtd:in-progress',
56
+ 'gtd:pr-open',
57
+ 'gtd:needs-rework',
58
+ 'gtd:validation-failed',
59
+ 'gtd:merged',
60
+ 'gtd:rejected',
61
+ 'gtd:blocked-human',
62
+ 'gtd:checkpoint-resolved',
63
+ 'gtd:source-drift',
64
+ ]);
65
+
66
+ const PARENT_STATE_LABELS = Object.freeze([
67
+ 'gtd:ready',
68
+ 'gtd:blocked',
69
+ 'gtd:ready-for-reconcile',
70
+ 'gtd:reconcile-pr-open',
71
+ 'gtd:reconcile-failed',
72
+ 'gtd:source-drift',
73
+ 'gtd:complete',
74
+ ]);
75
+
76
+ const BLOCKING_TASK_LABELS = Object.freeze([
77
+ 'gtd:blocked-human',
78
+ 'gtd:source-drift',
79
+ 'gtd:merged',
80
+ ]);
81
+
82
+ const REWORK_LABELS = Object.freeze([
83
+ 'gtd:needs-rework',
84
+ 'gtd:rejected',
85
+ 'gtd:validation-failed',
86
+ ]);
87
+
88
+ const DEFAULT_EXECUTOR_RETRY_BUDGET = 1;
89
+ const TASK_EXECUTOR_COMMAND = 'gtd-task-executor';
90
+ const GTD_COMPLETION_ARTIFACTS = Object.freeze([
91
+ '.planning/STATE.md',
92
+ '.planning/ROADMAP.md',
93
+ '.planning/REQUIREMENTS.md',
94
+ ]);
95
+
96
+ const SUMMARY_ARTIFACT_RE = /^\.planning\/phases\/.+\/.+-SUMMARY\.md$/;
97
+
98
+ class GitHubTaskIssueError extends Error {
99
+ constructor(message, operation = null) {
100
+ super(message);
101
+ this.name = 'GitHubTaskIssueError';
102
+ this.operation = operation;
103
+ }
104
+ }
105
+
106
+ class TaskExecutionError extends Error {
107
+ constructor(message, code = 'task_execution_failed', details = null) {
108
+ super(message);
109
+ this.name = 'TaskExecutionError';
110
+ this.code = code;
111
+ this.details = details;
112
+ }
113
+ }
114
+
115
+ function usage() {
116
+ return 'Usage: gtd-tools work-task-issue [issue-number|issue-url|task-id|plan-id] [--phase <phase>] [--repo owner/name] [--read-only|--execute] [--reconcile] [--complete-phase <phase> --execute]';
117
+ }
118
+
119
+ function parseArgs(args) {
120
+ const opts = {
121
+ selector: null,
122
+ phase: null,
123
+ repo: null,
124
+ mode: 'read-only',
125
+ explicitMode: false,
126
+ reconcile: false,
127
+ completePhase: null,
128
+ };
129
+
130
+ for (let i = 1; i < args.length; i += 1) {
131
+ const arg = args[i];
132
+ if (arg === '--phase') {
133
+ const value = args[i + 1];
134
+ if (!value || value.startsWith('--')) error(usage(), ERROR_REASON.USAGE);
135
+ opts.phase = value;
136
+ i += 1;
137
+ } else if (arg === '--repo') {
138
+ const value = args[i + 1];
139
+ if (!value || value.startsWith('--')) error(usage(), ERROR_REASON.USAGE);
140
+ opts.repo = normalizeRepo(value);
141
+ i += 1;
142
+ } else if (arg === '--read-only') {
143
+ if (opts.explicitMode && opts.mode !== 'read-only') error('Use either --read-only or --execute, not both.', ERROR_REASON.USAGE);
144
+ opts.mode = 'read-only';
145
+ opts.explicitMode = true;
146
+ } else if (arg === '--execute') {
147
+ if (opts.explicitMode && opts.mode !== 'execute') error('Use either --read-only or --execute, not both.', ERROR_REASON.USAGE);
148
+ opts.mode = 'execute';
149
+ opts.explicitMode = true;
150
+ } else if (arg === '--reconcile') {
151
+ opts.reconcile = true;
152
+ } else if (arg === '--complete-phase') {
153
+ const value = args[i + 1];
154
+ if (!value || value.startsWith('--')) error(usage(), ERROR_REASON.USAGE);
155
+ opts.completePhase = value;
156
+ i += 1;
157
+ } else if (arg.startsWith('--')) {
158
+ error(`Unknown work-task-issue flag: ${arg}`, ERROR_REASON.USAGE);
159
+ } else if (!opts.selector) {
160
+ opts.selector = arg;
161
+ } else {
162
+ error(usage(), ERROR_REASON.USAGE);
163
+ }
164
+ }
165
+
166
+ delete opts.explicitMode;
167
+ return opts;
168
+ }
169
+
170
+ function normalizeRepo(repo) {
171
+ const value = normalizeGitHubRepo(repo);
172
+ if (!value) {
173
+ error(`Invalid GitHub repository "${repo}". Expected owner/name.`, ERROR_REASON.USAGE);
174
+ }
175
+ return value;
176
+ }
177
+
178
+ function parseSelector(raw) {
179
+ if (!raw) return { mode: 'automatic', raw: null };
180
+ const text = String(raw).trim();
181
+ const url = text.match(ISSUE_URL_RE);
182
+ if (url) {
183
+ return {
184
+ mode: 'explicit',
185
+ type: 'issue',
186
+ raw: text,
187
+ issue: Number(url[3]),
188
+ repo: normalizeRepo(`${url[1]}/${url[2]}`),
189
+ };
190
+ }
191
+ if (/^#?\d+$/.test(text)) {
192
+ return {
193
+ mode: 'explicit',
194
+ type: 'issue',
195
+ raw: text,
196
+ issue: Number(text.replace(/^#/, '')),
197
+ repo: null,
198
+ };
199
+ }
200
+ if (TASK_ID_RE.test(text)) {
201
+ return {
202
+ mode: 'explicit',
203
+ type: 'task_id',
204
+ raw: text,
205
+ task_id: text.toUpperCase(),
206
+ repo: null,
207
+ };
208
+ }
209
+ if (PLAN_ID_RE.test(text)) {
210
+ return {
211
+ mode: 'explicit',
212
+ type: 'plan_id',
213
+ raw: text,
214
+ plan_id: text.toUpperCase(),
215
+ repo: null,
216
+ };
217
+ }
218
+ error(`Invalid task selector "${raw}". Expected issue number, issue URL, task id like 01-04-T02, or plan id like 01-04.`, ERROR_REASON.USAGE);
219
+ }
220
+
221
+ function parseExportMarker(body) {
222
+ const match = String(body || '').match(
223
+ /<!--\s*gtd-export:v1\s+phase=([^\s]+)\s+plan=([^\s]+)(?:\s+task=([^\s]+))?\s+source_hash=([a-f0-9]+)\s*-->/i,
224
+ );
225
+ if (!match) return null;
226
+ return {
227
+ phase: match[1],
228
+ plan: match[2],
229
+ task: match[3] || null,
230
+ source_hash: match[4],
231
+ };
232
+ }
233
+
234
+ function readManifestFile(cwd, absPath) {
235
+ try {
236
+ return {
237
+ absPath,
238
+ path: toPosixPath(path.relative(cwd, absPath)),
239
+ exists: true,
240
+ data: JSON.parse(fs.readFileSync(absPath, 'utf8')),
241
+ };
242
+ } catch (err) {
243
+ error(`Could not parse export manifest ${toPosixPath(path.relative(cwd, absPath))}: ${err.message}`, ERROR_REASON.USAGE);
244
+ }
245
+ }
246
+
247
+ function discoverManifestFiles(cwd) {
248
+ const githubDir = path.join(planningDir(cwd), 'github');
249
+ if (!fs.existsSync(githubDir)) return [];
250
+ return fs
251
+ .readdirSync(githubDir)
252
+ .filter((name) => /^phase-.+-issues\.json$/.test(name))
253
+ .map((name) => path.join(githubDir, name))
254
+ .sort();
255
+ }
256
+
257
+ function phaseArgFromManifestData(data) {
258
+ return data?.directory || data?.phase_number || data?.phase || null;
259
+ }
260
+
261
+ function makeScope(cwd, source, manifest, opts, selectorRepo) {
262
+ const manifestRepo = manifest.data?.repo || null;
263
+ if (opts.repo && manifestRepo && opts.repo !== manifestRepo) {
264
+ error(`Export manifest ${manifest.path} targets ${manifestRepo}; refusing to read ${opts.repo}.`, ERROR_REASON.USAGE);
265
+ }
266
+ if (selectorRepo && manifestRepo && selectorRepo !== manifestRepo) {
267
+ error(`Selector targets ${selectorRepo}; export manifest ${manifest.path} targets ${manifestRepo}.`, ERROR_REASON.USAGE);
268
+ }
269
+ if (selectorRepo && opts.repo && selectorRepo !== opts.repo) {
270
+ error(`Selector targets ${selectorRepo}; --repo targets ${opts.repo}.`, ERROR_REASON.USAGE);
271
+ }
272
+
273
+ let repo = opts.repo || selectorRepo || manifestRepo;
274
+ if (!repo) {
275
+ const inferred = resolveGitHubRepoFromGit(cwd);
276
+ if (!inferred.ok) {
277
+ error(`Export manifest ${manifest.path} has no repo and no GitHub repository could be inferred from current git config (${inferred.message}). Re-run export-phase-issues with --repo owner/name.`, ERROR_REASON.USAGE);
278
+ }
279
+ repo = inferred.repo;
280
+ }
281
+ repo = normalizeRepo(repo);
282
+
283
+ if (manifest.data?.status !== 'complete') {
284
+ error(`Export manifest ${manifest.path} is ${manifest.data?.status || 'missing status'}; rerun export-phase-issues before selecting task work.`, ERROR_REASON.USAGE);
285
+ }
286
+
287
+ return {
288
+ repo,
289
+ manifest,
290
+ phase: source.phase,
291
+ plans: source.plans,
292
+ planMap: new Map(source.plans.map((plan) => [plan.id, plan])),
293
+ };
294
+ }
295
+
296
+ function loadScopes(cwd, opts, selector) {
297
+ if (opts.phase) {
298
+ const source = loadExportSource(cwd, { phase: opts.phase });
299
+ if (!source.manifest.exists) {
300
+ error(`No export manifest found for phase ${opts.phase}. Run export-phase-issues write mode first.`, ERROR_REASON.USAGE);
301
+ }
302
+ return [makeScope(cwd, source, source.manifest, opts, selector.repo)];
303
+ }
304
+
305
+ const manifestFiles = discoverManifestFiles(cwd);
306
+ if (manifestFiles.length === 0) {
307
+ error('No GitHub issue export manifests found. Run export-phase-issues write mode first.', ERROR_REASON.USAGE);
308
+ }
309
+
310
+ const scopes = [];
311
+ const requestedRepo = selector.repo || opts.repo || null;
312
+ for (const file of manifestFiles) {
313
+ const manifest = readManifestFile(cwd, file);
314
+ if (requestedRepo && manifest.data?.repo && manifest.data.repo !== requestedRepo) continue;
315
+ const phaseArg = phaseArgFromManifestData(manifest.data);
316
+ if (!phaseArg) {
317
+ error(`Export manifest ${manifest.path} has no phase directory or phase id.`, ERROR_REASON.USAGE);
318
+ }
319
+ const source = loadExportSource(cwd, { phase: phaseArg });
320
+ scopes.push(makeScope(cwd, source, source.manifest, opts, selector.repo));
321
+ }
322
+ if (scopes.length === 0) {
323
+ error(`No GitHub issue export manifests matched ${requestedRepo}.`, ERROR_REASON.USAGE);
324
+ }
325
+ return scopes;
326
+ }
327
+
328
+ function manifestPlanEntry(scope, planId) {
329
+ return scope.manifest.data?.plans?.[planId] || null;
330
+ }
331
+
332
+ function manifestTaskEntry(scope, planId, taskId) {
333
+ return scope.manifest.data?.plans?.[planId]?.tasks?.[taskId] || null;
334
+ }
335
+
336
+ function manifestTaskExportStatus(entry) {
337
+ if (!entry) return null;
338
+ if (entry.exportStatus) return entry.exportStatus;
339
+ return TASK_EXPORT_STATUSES.has(entry.status) ? entry.status : null;
340
+ }
341
+
342
+ function manifestTaskCheckpointStatus(entry) {
343
+ if (!entry) return null;
344
+ if (entry.checkpointStatus) return entry.checkpointStatus;
345
+ return entry.status === CHECKPOINT_RESOLVED_STATUS ? CHECKPOINT_RESOLVED_STATUS : null;
346
+ }
347
+
348
+ function normalizeTaskManifestEntryForWrite(entry) {
349
+ if (!entry) return;
350
+ const exportStatus = manifestTaskExportStatus(entry);
351
+ if (exportStatus && !entry.exportStatus) entry.exportStatus = exportStatus;
352
+ const checkpointStatus = manifestTaskCheckpointStatus(entry);
353
+ if (checkpointStatus && !entry.checkpointStatus) entry.checkpointStatus = checkpointStatus;
354
+ delete entry.status;
355
+ }
356
+
357
+ function taskBranchName(taskId, issueNumber) {
358
+ return `gtd/task-${taskId}-${issueNumber}`;
359
+ }
360
+
361
+ function reconciliationBranchName(planId, issueNumber) {
362
+ return `gtd/reconcile-${planId}-${issueNumber}`;
363
+ }
364
+
365
+ function callRead(operation, fallback, fn, errors) {
366
+ try {
367
+ const value = fn();
368
+ return value === undefined || value === null ? fallback : value;
369
+ } catch (err) {
370
+ errors.push({
371
+ operation,
372
+ message: err.message || String(err),
373
+ });
374
+ return fallback;
375
+ }
376
+ }
377
+
378
+ function listBlockedBy(adapter, issueNumber, errors, operation) {
379
+ if (!adapter || typeof adapter.listBlockedBy !== 'function') {
380
+ errors.push({
381
+ operation,
382
+ message: 'GitHub issue dependency reads are unavailable.',
383
+ });
384
+ return [];
385
+ }
386
+ const blockers = callRead(operation, [], () => adapter.listBlockedBy(issueNumber), errors);
387
+ return Array.isArray(blockers) ? blockers : [];
388
+ }
389
+
390
+ function listPullRequestsForIssue(adapter, issueNumber, branchName, errors) {
391
+ if (!adapter || typeof adapter.listPullRequestsForIssue !== 'function') return [];
392
+ const prs = callRead(
393
+ `list_pull_requests_for_issue:${issueNumber}`,
394
+ [],
395
+ () => adapter.listPullRequestsForIssue(issueNumber, branchName),
396
+ errors,
397
+ );
398
+ return Array.isArray(prs) ? dedupePrs(prs) : [];
399
+ }
400
+
401
+ function dedupePrs(prs) {
402
+ const seen = new Set();
403
+ const result = [];
404
+ for (const pr of prs || []) {
405
+ const key = pr.url || pr.number;
406
+ if (!key || seen.has(key)) continue;
407
+ seen.add(key);
408
+ result.push(pr);
409
+ }
410
+ return result.sort((a, b) => Number(a.number || 0) - Number(b.number || 0));
411
+ }
412
+
413
+ function normalizePr(pr) {
414
+ const state = String(pr.state || '').toUpperCase();
415
+ const merged = Boolean(pr.mergedAt || pr.merged || state === 'MERGED');
416
+ const open = state === 'OPEN' || state === 'open';
417
+ const closed = state === 'CLOSED' || state === 'closed';
418
+ const changesRequested =
419
+ pr.changesRequested === true ||
420
+ String(pr.reviewDecision || '').toUpperCase() === 'CHANGES_REQUESTED' ||
421
+ Number(pr.unresolvedComments || 0) > 0 ||
422
+ Number(pr.actionableComments || 0) > 0;
423
+
424
+ return {
425
+ number: pr.number,
426
+ title: pr.title || '',
427
+ state: state || (merged ? 'MERGED' : ''),
428
+ url: pr.url || null,
429
+ headRefName: pr.headRefName || pr.head || null,
430
+ baseRefName: pr.baseRefName || pr.base || null,
431
+ isDraft: Boolean(pr.isDraft),
432
+ mergedAt: pr.mergedAt || null,
433
+ reviewDecision: pr.reviewDecision || null,
434
+ open,
435
+ merged,
436
+ closedUnmerged: closed && !merged,
437
+ changesRequested,
438
+ };
439
+ }
440
+
441
+ function prState(prs) {
442
+ const normalized = prs.map(normalizePr);
443
+ const open = normalized.filter((pr) => pr.open);
444
+ const merged = normalized.filter((pr) => pr.merged);
445
+ const closedUnmerged = normalized.filter((pr) => pr.closedUnmerged);
446
+ const openNeedsRework = open.filter((pr) => pr.changesRequested);
447
+ return {
448
+ all: normalized,
449
+ open,
450
+ merged,
451
+ closedUnmerged,
452
+ openNeedsRework,
453
+ };
454
+ }
455
+
456
+ function latestPr(prs) {
457
+ return [...(prs || [])].sort((a, b) => Number(b.number || 0) - Number(a.number || 0))[0] || null;
458
+ }
459
+
460
+ function callWrite(operation, fn) {
461
+ try {
462
+ return fn();
463
+ } catch (err) {
464
+ throw new TaskExecutionError(`${operation}: ${err.message || String(err)}`, 'github_write_failed', { operation });
465
+ }
466
+ }
467
+
468
+ function setIssueLabels(adapter, issueNumber, labels) {
469
+ if (!adapter || typeof adapter.setIssueLabels !== 'function') {
470
+ throw new TaskExecutionError('GitHub issue label writes are unavailable.', 'github_write_unavailable');
471
+ }
472
+ return callWrite(`set_issue_labels:${issueNumber}`, () => adapter.setIssueLabels(issueNumber, labels));
473
+ }
474
+
475
+ function commentIssue(adapter, issueNumber, body) {
476
+ if (!adapter || typeof adapter.commentIssue !== 'function') {
477
+ throw new TaskExecutionError('GitHub issue comments are unavailable.', 'github_write_unavailable');
478
+ }
479
+ return callWrite(`comment_issue:${issueNumber}`, () => adapter.commentIssue(issueNumber, body));
480
+ }
481
+
482
+ function updateIssueState(adapter, issueNumber, state) {
483
+ if (!adapter || typeof adapter.updateIssueState !== 'function') return null;
484
+ return callWrite(`update_issue_state:${issueNumber}:${state}`, () => adapter.updateIssueState(issueNumber, state));
485
+ }
486
+
487
+ function applyLabelActions(adapter, record) {
488
+ const actions = record.labels.actions;
489
+ if (!actions || (actions.add.length === 0 && actions.remove.length === 0)) return null;
490
+ const labels = mergeLabelSet(record.labels.current, actions.add, actions.remove);
491
+ setIssueLabels(adapter, record.issue_number, labels);
492
+ record.labels.current = labels;
493
+ record.labels.virtual = labels;
494
+ record.labels.actions = { add: [], remove: [] };
495
+ return {
496
+ issue: record.issue_number,
497
+ kind: record.kind,
498
+ plan_id: record.plan_id,
499
+ task_id: record.task_id || null,
500
+ labels,
501
+ };
502
+ }
503
+
504
+ function writeManifestData(manifest) {
505
+ manifest.data.updated_at = new Date().toISOString();
506
+ fs.writeFileSync(manifest.absPath, `${JSON.stringify(manifest.data, null, 2)}\n`, 'utf8');
507
+ }
508
+
509
+ function syncCheckpointManifestStatus(record) {
510
+ if (!isResolvedCheckpointTask(record)) return null;
511
+ const entry = manifestTaskEntry(record.scope, record.plan_id, record.task_id);
512
+ if (!entry) return null;
513
+ const alreadyResolved = manifestTaskCheckpointStatus(entry) === CHECKPOINT_RESOLVED_STATUS;
514
+ const needsSchemaWrite = Object.prototype.hasOwnProperty.call(entry, 'status') ||
515
+ (alreadyResolved && entry.checkpointStatus !== CHECKPOINT_RESOLVED_STATUS);
516
+ if (alreadyResolved && !needsSchemaWrite) return null;
517
+ normalizeTaskManifestEntryForWrite(entry);
518
+ entry.checkpointStatus = CHECKPOINT_RESOLVED_STATUS;
519
+ writeManifestData(record.scope.manifest);
520
+ return {
521
+ op: 'sync_checkpoint_manifest_status',
522
+ issue: record.issue_number,
523
+ task_id: record.task_id,
524
+ checkpointStatus: CHECKPOINT_RESOLVED_STATUS,
525
+ manifest: record.scope.manifest.path,
526
+ };
527
+ }
528
+
529
+ function summaryPathForPlan(plan) {
530
+ const sourcePath = sourcePathForPlan(plan);
531
+ const dir = sourcePath ? path.dirname(sourcePath) : null;
532
+ return dir ? toPosixPath(path.join(dir, `${plan.id}-SUMMARY.md`)) : `${plan.id}-SUMMARY.md`;
533
+ }
534
+
535
+ function reconciliationArtifactsLanded(cwd, parent) {
536
+ if (!cwd) return { ok: false, missing: ['project cwd unavailable'] };
537
+ const required = [
538
+ summaryPathForPlan(parent.plan),
539
+ '.planning/STATE.md',
540
+ '.planning/ROADMAP.md',
541
+ ];
542
+ const missing = required.filter((relPath) => !fs.existsSync(path.join(cwd, relPath)));
543
+ return {
544
+ ok: missing.length === 0,
545
+ missing,
546
+ };
547
+ }
548
+
549
+ function applyStateSync(records, adapterForRepo, cwd = null) {
550
+ const operations = [];
551
+ for (const task of records.tasks) {
552
+ const adapter = adapterForRepo(task.scope.repo);
553
+ if (task.linked_prs.merged.length > 0 && task.issue && isIssueOpen(task.issue)) {
554
+ updateIssueState(adapter, task.issue_number, 'closed');
555
+ operations.push({
556
+ op: 'close_merged_task_issue',
557
+ issue: task.issue_number,
558
+ task_id: task.task_id,
559
+ });
560
+ }
561
+ if (task.linked_prs.closedUnmerged.length > 0 && task.issue && !isIssueOpen(task.issue)) {
562
+ updateIssueState(adapter, task.issue_number, 'open');
563
+ operations.push({
564
+ op: 'reopen_rejected_task_issue',
565
+ issue: task.issue_number,
566
+ task_id: task.task_id,
567
+ });
568
+ }
569
+ }
570
+
571
+ for (const parent of records.parents) {
572
+ const adapter = adapterForRepo(parent.scope.repo);
573
+ if (parent.linked_prs?.merged?.length > 0) {
574
+ const artifacts = reconciliationArtifactsLanded(adapter?.cwd || cwd, parent);
575
+ if (!artifacts.ok) {
576
+ operations.push({
577
+ op: 'merged_reconciliation_pending_pull',
578
+ issue: parent.issue_number,
579
+ plan_id: parent.plan_id,
580
+ missing: artifacts.missing,
581
+ });
582
+ } else {
583
+ if (parent.issue && isIssueOpen(parent.issue)) {
584
+ updateIssueState(adapter, parent.issue_number, 'closed');
585
+ operations.push({
586
+ op: 'close_reconciled_parent_issue',
587
+ issue: parent.issue_number,
588
+ plan_id: parent.plan_id,
589
+ });
590
+ }
591
+ const labels = mergeLabelSet(parent.labels.virtual, ['gtd:complete'], [
592
+ 'gtd:ready',
593
+ 'gtd:blocked',
594
+ 'gtd:ready-for-reconcile',
595
+ 'gtd:reconcile-pr-open',
596
+ 'gtd:reconcile-failed',
597
+ 'gtd:source-drift',
598
+ ]);
599
+ parent.labels.virtual = labels;
600
+ parent.labels.actions = labelActions(parent.labels.current, labels, PARENT_STATE_LABELS);
601
+ }
602
+ }
603
+ }
604
+
605
+ for (const record of [...records.parents, ...records.tasks]) {
606
+ const adapter = adapterForRepo(record.scope.repo);
607
+ const applied = applyLabelActions(adapter, record);
608
+ if (applied) operations.push({ op: 'sync_labels', ...applied });
609
+ if (record.kind === 'task') {
610
+ const manifestSync = syncCheckpointManifestStatus(record);
611
+ if (manifestSync) operations.push(manifestSync);
612
+ }
613
+ }
614
+ return operations;
615
+ }
616
+
617
+ function isoTimestamp(deps = {}) {
618
+ const now = deps.now ? deps.now() : new Date();
619
+ return now.toISOString();
620
+ }
621
+
622
+ function claimTaskIssue(adapter, record, deps = {}) {
623
+ const timestamp = isoTimestamp(deps);
624
+ const labels = mergeLabelSet(record.labels.virtual, ['gtd:in-progress'], ['gtd:ready', 'gtd:blocked']);
625
+ setIssueLabels(adapter, record.issue_number, labels);
626
+ const body = [
627
+ `GTD task execution claim at ${timestamp}.`,
628
+ '',
629
+ `Branch: \`${record.branch_name}\``,
630
+ `Task: \`${record.task_id}\``,
631
+ ].join('\n');
632
+ commentIssue(adapter, record.issue_number, body);
633
+ return {
634
+ issue: record.issue_number,
635
+ branch: record.branch_name,
636
+ claimed_at: timestamp,
637
+ labels,
638
+ };
639
+ }
640
+
641
+ function pathMatchesScope(filePath, scopePath) {
642
+ const file = normalizeRepoPath(filePath);
643
+ const scope = normalizeRepoPath(scopePath);
644
+ if (!scope) return false;
645
+ if (scope === '.') return true;
646
+ if (file === scope) return true;
647
+ return file.startsWith(`${scope}/`);
648
+ }
649
+
650
+ function forbiddenCompletionArtifact(filePath) {
651
+ const file = normalizeRepoPath(filePath);
652
+ return GTD_COMPLETION_ARTIFACTS.includes(file) || SUMMARY_ARTIFACT_RE.test(file);
653
+ }
654
+
655
+ function validateDiffScope(changedFiles, check) {
656
+ const allowed = (check.paths?.allowed || []).map(normalizeRepoPath).filter(Boolean);
657
+ const forbidden = (check.paths?.forbidden || []).map(normalizeRepoPath).filter(Boolean);
658
+ const files = [...new Set((changedFiles || []).map(normalizeRepoPath).filter(Boolean))].sort();
659
+ const outOfScope = files.filter((file) => allowed.length > 0 && !allowed.some((scope) => pathMatchesScope(file, scope)));
660
+ const forbiddenHits = files.filter((file) =>
661
+ forbidden.some((scope) => pathMatchesScope(file, scope)) ||
662
+ forbiddenCompletionArtifact(file),
663
+ );
664
+
665
+ return {
666
+ id: check.id,
667
+ type: check.type,
668
+ passed: outOfScope.length === 0 && forbiddenHits.length === 0,
669
+ changed_files: files,
670
+ allowed,
671
+ forbidden,
672
+ out_of_scope: outOfScope,
673
+ forbidden_hits: forbiddenHits,
674
+ };
675
+ }
676
+
677
+ function runShellCommand(command, cwd, deps = {}) {
678
+ if (deps.runCommand) return deps.runCommand(command, cwd);
679
+ const result = childProcess.spawnSync(command, [], {
680
+ cwd,
681
+ encoding: 'utf8',
682
+ shell: true,
683
+ stdio: ['ignore', 'pipe', 'pipe'],
684
+ env: process.env,
685
+ });
686
+ return {
687
+ status: result.status,
688
+ stdout: String(result.stdout || ''),
689
+ stderr: String(result.stderr || ''),
690
+ error: result.error ? result.error.message : null,
691
+ };
692
+ }
693
+
694
+ function validateCommandCheck(worktreePath, check, deps = {}) {
695
+ const result = runShellCommand(check.run || check.command || '', worktreePath, deps);
696
+ return {
697
+ id: check.id,
698
+ type: check.type,
699
+ run: check.run || check.command || '',
700
+ passed: result.status === 0,
701
+ status: result.status,
702
+ stdout: String(result.stdout || '').trim(),
703
+ stderr: String(result.stderr || result.error || '').trim(),
704
+ };
705
+ }
706
+
707
+ function validateFileExistsCheck(worktreePath, check) {
708
+ const relPath = normalizeRepoPath(check.path || check.file || '');
709
+ return {
710
+ id: check.id,
711
+ type: check.type,
712
+ path: relPath,
713
+ passed: Boolean(relPath) && fs.existsSync(path.join(worktreePath, relPath)),
714
+ };
715
+ }
716
+
717
+ function validateContentMatchCheck(worktreePath, check) {
718
+ const relPath = normalizeRepoPath(check.path || check.file || '');
719
+ const file = relPath ? path.join(worktreePath, relPath) : null;
720
+ const expected = check.text || check.pattern || check.match || '';
721
+ let content = '';
722
+ if (file && fs.existsSync(file) && fs.statSync(file).isFile()) {
723
+ content = fs.readFileSync(file, 'utf8');
724
+ }
725
+ return {
726
+ id: check.id,
727
+ type: check.type,
728
+ path: relPath,
729
+ expected,
730
+ passed: Boolean(file && expected) && content.includes(expected),
731
+ };
732
+ }
733
+
734
+ function validateTask(worktreePath, record, changedFiles, deps = {}) {
735
+ const checks = record.task.validation_contract?.checks || [];
736
+ const results = [];
737
+ for (const check of checks) {
738
+ if (check.type === 'diff-scope') {
739
+ results.push(validateDiffScope(changedFiles, check));
740
+ } else if (check.type === 'command' || check.type === 'test-selector') {
741
+ results.push(validateCommandCheck(worktreePath, check, deps));
742
+ } else if (check.type === 'file-exists') {
743
+ results.push(validateFileExistsCheck(worktreePath, check));
744
+ } else if (check.type === 'content-match') {
745
+ results.push(validateContentMatchCheck(worktreePath, check));
746
+ } else if (check.type === 'manual') {
747
+ results.push({
748
+ id: check.id,
749
+ type: check.type,
750
+ passed: null,
751
+ description: check.description || '',
752
+ });
753
+ } else {
754
+ results.push({
755
+ id: check.id,
756
+ type: check.type || 'unknown',
757
+ passed: false,
758
+ error: `Unsupported validation check type: ${check.type || 'unknown'}`,
759
+ });
760
+ }
761
+ }
762
+
763
+ const automated = results.filter((result) => result.passed !== null);
764
+ const manual = results.filter((result) => result.passed === null);
765
+ const failed = automated.filter((result) => result.passed === false);
766
+ return {
767
+ ok: failed.length === 0,
768
+ automated_ok: failed.length === 0,
769
+ checks: results,
770
+ failed,
771
+ manual,
772
+ acceptance_criteria: record.task.acceptance_criteria.map((criterion) => ({
773
+ criterion,
774
+ mechanical: false,
775
+ passed: null,
776
+ })),
777
+ };
778
+ }
779
+
780
+ function validationMarkdown(validation) {
781
+ const lines = [
782
+ '## GTD Task Validation',
783
+ '',
784
+ validation.ok ? 'Automated validation passed.' : 'Automated validation failed.',
785
+ '',
786
+ '### Checks',
787
+ ];
788
+ for (const check of validation.checks) {
789
+ const status = check.passed === null ? 'manual' : (check.passed ? 'pass' : 'fail');
790
+ lines.push(`- ${check.id || check.type}: ${status}`);
791
+ if (check.run) lines.push(` - run: \`${check.run}\``);
792
+ if (check.out_of_scope?.length) lines.push(` - out of scope: ${check.out_of_scope.map((file) => `\`${file}\``).join(', ')}`);
793
+ if (check.forbidden_hits?.length) lines.push(` - forbidden: ${check.forbidden_hits.map((file) => `\`${file}\``).join(', ')}`);
794
+ }
795
+ if (validation.manual.length > 0 || validation.acceptance_criteria.length > 0) {
796
+ lines.push('', '### Reviewer Validation');
797
+ for (const item of validation.acceptance_criteria) lines.push(`- [ ] ${item.criterion}`);
798
+ for (const check of validation.manual) {
799
+ if (check.description && validation.acceptance_criteria.length === 0) lines.push(`- [ ] ${check.description}`);
800
+ }
801
+ }
802
+ return lines.join('\n');
803
+ }
804
+
805
+ function executorPrompt(record, reviewFeedback = []) {
806
+ if (isCheckpointTask(record)) {
807
+ return [
808
+ `You are gtd-task-executor for ${record.task_id}.`,
809
+ '',
810
+ 'This issue is a human-in-the-loop checkpoint, not executable implementation work.',
811
+ 'Stop without editing files. Report that the checkpoint requires human resolution in GitHub and must be closed before dependent tasks can run.',
812
+ ].join('\n');
813
+ }
814
+
815
+ const readFirst = (record.task.read_first || []).map((entry) => `- ${entry}`).join('\n') || '- None declared';
816
+ const allowed = (record.task.files || []).map((entry) => `- ${entry}`).join('\n') || '- No explicit files declared';
817
+ const acceptance = (record.task.acceptance_criteria || []).map((entry) => `- ${entry}`).join('\n') || '- No acceptance criteria declared';
818
+ const feedback = reviewFeedback.length
819
+ ? reviewFeedback.map((item) => `- ${item.kind || 'feedback'}${item.author ? ` by ${item.author}` : ''}: ${item.body || item.state || ''}`).join('\n')
820
+ : '- No PR review feedback supplied';
821
+
822
+ return [
823
+ `You are gtd-task-executor for ${record.task_id}.`,
824
+ '',
825
+ 'Implement exactly one exported child task issue. Stay inside the declared write scope and commit the task changes before returning.',
826
+ '',
827
+ '## Issue',
828
+ `#${record.issue_number}: ${record.issue?.title || record.task.name}`,
829
+ '',
830
+ '## Source Plan',
831
+ sourcePathForPlan(record.plan) || '',
832
+ '',
833
+ '## Required Read First',
834
+ readFirst,
835
+ '',
836
+ '## Write Scope',
837
+ 'Allowed:',
838
+ allowed,
839
+ '',
840
+ 'Boundaries:',
841
+ record.task.boundaries || 'No boundaries declared',
842
+ '',
843
+ '## Action',
844
+ record.task.action || 'No action block declared',
845
+ '',
846
+ '## Acceptance Criteria',
847
+ acceptance,
848
+ '',
849
+ '## Verification',
850
+ record.task.verify || 'No task verification command declared',
851
+ '',
852
+ '## Review Feedback',
853
+ feedback,
854
+ '',
855
+ '## Non-Responsibilities',
856
+ '- Do not open or update PRs.',
857
+ '- Do not update parent plan issues.',
858
+ '- Do not create SUMMARY, STATE, ROADMAP, or requirements completion artifacts.',
859
+ ].join('\n');
860
+ }
861
+
862
+ function executorContext(record, worktree, reviewFeedback = [], previousFindings = null) {
863
+ return {
864
+ version: 1,
865
+ task_id: record.task_id,
866
+ task_type: record.task.type || record.manifest_entry?.type || null,
867
+ is_checkpoint: isCheckpointTask(record),
868
+ issue: {
869
+ number: record.issue_number,
870
+ title: record.issue?.title || null,
871
+ body: record.issue?.body || null,
872
+ },
873
+ parent: {
874
+ issue: record.parent?.issue_number || null,
875
+ title: record.parent?.issue?.title || null,
876
+ plan_id: record.plan_id,
877
+ },
878
+ source_plan: sourcePathForPlan(record.plan),
879
+ worktree,
880
+ branch: record.branch_name,
881
+ read_first: record.task.read_first,
882
+ write_scope: {
883
+ allowed: record.task.files,
884
+ boundaries: record.task.boundaries || '',
885
+ },
886
+ action: record.task.action || '',
887
+ acceptance_criteria: record.task.acceptance_criteria,
888
+ validation_contract: record.task.validation_contract,
889
+ verification: record.task.verify || '',
890
+ review_feedback: reviewFeedback,
891
+ previous_findings: previousFindings,
892
+ prompt: executorPrompt(record, reviewFeedback),
893
+ };
894
+ }
895
+
896
+ function runTaskExecutor(context, deps = {}) {
897
+ if (deps.runTaskExecutor) return deps.runTaskExecutor(context);
898
+ const result = childProcess.spawnSync(TASK_EXECUTOR_COMMAND, [], {
899
+ cwd: context.worktree.path,
900
+ encoding: 'utf8',
901
+ input: `${JSON.stringify(context)}\n`,
902
+ stdio: ['pipe', 'pipe', 'pipe'],
903
+ env: process.env,
904
+ });
905
+ if (result.error) {
906
+ const message = result.error.code === 'ENOENT'
907
+ ? `Standalone ${TASK_EXECUTOR_COMMAND} was not found on PATH.`
908
+ : result.error.message;
909
+ throw new TaskExecutionError(message, 'executor_unavailable');
910
+ }
911
+ const stdout = String(result.stdout || '').trim();
912
+ if (result.status !== 0) {
913
+ throw new TaskExecutionError(String(result.stderr || stdout || `${TASK_EXECUTOR_COMMAND} exited with status ${result.status}`).trim(), 'executor_failed');
914
+ }
915
+ if (!stdout) return { ok: true, notes: '', raw: '' };
916
+ try {
917
+ return JSON.parse(stdout);
918
+ } catch {
919
+ return { ok: true, notes: stdout, raw: stdout };
920
+ }
921
+ }
922
+
923
+ function runGit(cwd, args, opts = {}) {
924
+ const result = childProcess.spawnSync('git', args, {
925
+ cwd,
926
+ encoding: 'utf8',
927
+ stdio: ['ignore', 'pipe', 'pipe'],
928
+ env: process.env,
929
+ });
930
+ const stdout = String(result.stdout || '').trim();
931
+ const stderr = String(result.stderr || '').trim();
932
+ if (result.error) {
933
+ throw new TaskExecutionError(result.error.message, 'git_failed', { args });
934
+ }
935
+ if (result.status !== 0 && !opts.allowFailure) {
936
+ throw new TaskExecutionError(stderr || `git ${args.join(' ')} exited with status ${result.status}`, 'git_failed', { args });
937
+ }
938
+ return {
939
+ ok: result.status === 0,
940
+ status: result.status,
941
+ stdout,
942
+ stderr,
943
+ };
944
+ }
945
+
946
+ function executorBlockers(executorResult) {
947
+ const raw = executorResult?.blockers ?? executorResult?.blocker ?? executorResult?.blocked_by ?? [];
948
+ if (Array.isArray(raw)) {
949
+ return raw.map((item) => {
950
+ if (typeof item === 'string') return item.trim();
951
+ if (item && typeof item === 'object') return String(item.message || item.reason || item.code || JSON.stringify(item)).trim();
952
+ return String(item || '').trim();
953
+ }).filter(Boolean);
954
+ }
955
+ if (typeof raw === 'string') return raw.trim() ? [raw.trim()] : [];
956
+ if (raw && typeof raw === 'object') return [String(raw.message || raw.reason || raw.code || JSON.stringify(raw)).trim()].filter(Boolean);
957
+ return raw ? [String(raw).trim()].filter(Boolean) : [];
958
+ }
959
+
960
+ function executorCommitHash(executorResult) {
961
+ const raw = executorResult?.commit
962
+ ?? executorResult?.commit_hash
963
+ ?? executorResult?.commitHash
964
+ ?? executorResult?.sha
965
+ ?? executorResult?.commit_sha
966
+ ?? null;
967
+ const value = String(raw || '').trim();
968
+ return value || null;
969
+ }
970
+
971
+ function normalizeExecutorEvidence(evidence) {
972
+ const reasons = Array.isArray(evidence?.reasons) ? evidence.reasons : [];
973
+ return {
974
+ ok: Boolean(evidence?.ok) && reasons.length === 0,
975
+ executor_success: Boolean(evidence?.executor_success),
976
+ blockers: Array.isArray(evidence?.blockers) ? evidence.blockers : [],
977
+ commit: evidence?.commit || null,
978
+ reachable_commit: Boolean(evidence?.reachable_commit),
979
+ branch_contains_commit: Boolean(evidence?.branch_contains_commit),
980
+ committed_diff: Boolean(evidence?.committed_diff),
981
+ clean_worktree: Boolean(evidence?.clean_worktree),
982
+ reasons,
983
+ };
984
+ }
985
+
986
+ function validateExecutorEvidence(worktree, executorResult, deps = {}) {
987
+ if (deps.validateExecutorEvidence) {
988
+ return normalizeExecutorEvidence(deps.validateExecutorEvidence({ worktree, executorResult }));
989
+ }
990
+
991
+ const reasons = [];
992
+ const blockers = executorBlockers(executorResult);
993
+ const executorSuccess = executorResult?.ok === true;
994
+ if (!executorSuccess) {
995
+ reasons.push({
996
+ code: 'executor_not_successful',
997
+ message: 'Executor did not report ok: true.',
998
+ });
999
+ }
1000
+ if (blockers.length > 0) {
1001
+ reasons.push({
1002
+ code: 'executor_blockers',
1003
+ message: `Executor reported blocker(s): ${blockers.join('; ')}`,
1004
+ blockers,
1005
+ });
1006
+ }
1007
+
1008
+ let commit = executorCommitHash(executorResult);
1009
+ let reachableCommit = false;
1010
+ let branchContainsCommit = false;
1011
+ let committedDiff = false;
1012
+ let cleanWorktree = false;
1013
+
1014
+ if (!commit) {
1015
+ reasons.push({
1016
+ code: 'missing_executor_commit',
1017
+ message: 'Executor did not return a commit hash.',
1018
+ });
1019
+ } else if (!/^[0-9a-f]{7,40}$/i.test(commit)) {
1020
+ reasons.push({
1021
+ code: 'invalid_executor_commit_hash',
1022
+ message: `Executor commit is not a hash: ${commit}`,
1023
+ });
1024
+ } else {
1025
+ const verified = runGit(worktree.path, ['rev-parse', '--verify', `${commit}^{commit}`], { allowFailure: true });
1026
+ if (verified.ok && verified.stdout) {
1027
+ commit = verified.stdout;
1028
+ reachableCommit = true;
1029
+ } else {
1030
+ reasons.push({
1031
+ code: 'unreachable_executor_commit',
1032
+ message: `Executor commit ${commit} is not reachable as a commit in the task worktree.`,
1033
+ });
1034
+ }
1035
+
1036
+ if (reachableCommit) {
1037
+ const contained = runGit(worktree.path, ['merge-base', '--is-ancestor', commit, 'HEAD'], { allowFailure: true });
1038
+ branchContainsCommit = contained.ok;
1039
+ if (!branchContainsCommit) {
1040
+ reasons.push({
1041
+ code: 'executor_commit_not_on_head',
1042
+ message: `Executor commit ${commit} is not reachable from HEAD.`,
1043
+ });
1044
+ }
1045
+
1046
+ const parents = runGit(worktree.path, ['rev-list', '--parents', '-n', '1', commit], { allowFailure: true });
1047
+ if (!parents.ok || !parents.stdout) {
1048
+ reasons.push({
1049
+ code: 'executor_commit_parent_unavailable',
1050
+ message: `Could not inspect parent(s) for executor commit ${commit}.`,
1051
+ });
1052
+ } else {
1053
+ const parts = parents.stdout.split(/\s+/).filter(Boolean);
1054
+ const diffArgs = parts.length > 1
1055
+ ? ['diff-tree', '--quiet', '--no-ext-diff', parts[1], commit, '--']
1056
+ : ['diff-tree', '--quiet', '--root', '--no-ext-diff', commit, '--'];
1057
+ const diff = runGit(worktree.path, diffArgs, { allowFailure: true });
1058
+ if (diff.status === 1) {
1059
+ committedDiff = true;
1060
+ } else if (diff.status === 0) {
1061
+ reasons.push({
1062
+ code: 'empty_executor_commit_diff',
1063
+ message: `Executor commit ${commit} has no committed diff.`,
1064
+ });
1065
+ } else {
1066
+ reasons.push({
1067
+ code: 'executor_commit_diff_unavailable',
1068
+ message: diff.stderr || `Could not inspect committed diff for executor commit ${commit}.`,
1069
+ });
1070
+ }
1071
+ }
1072
+ }
1073
+ }
1074
+
1075
+ const status = runGit(worktree.path, ['status', '--porcelain', '--untracked-files=normal'], { allowFailure: true });
1076
+ if (!status.ok) {
1077
+ reasons.push({
1078
+ code: 'worktree_status_unavailable',
1079
+ message: status.stderr || 'Could not inspect task worktree status.',
1080
+ });
1081
+ } else if (status.stdout) {
1082
+ reasons.push({
1083
+ code: 'dirty_task_worktree_after_executor',
1084
+ message: 'Task worktree is not clean after executor commit.',
1085
+ status: status.stdout,
1086
+ });
1087
+ } else {
1088
+ cleanWorktree = true;
1089
+ }
1090
+
1091
+ return normalizeExecutorEvidence({
1092
+ ok: reasons.length === 0,
1093
+ executor_success: executorSuccess,
1094
+ blockers,
1095
+ commit,
1096
+ reachable_commit: reachableCommit,
1097
+ branch_contains_commit: branchContainsCommit,
1098
+ committed_diff: committedDiff,
1099
+ clean_worktree: cleanWorktree,
1100
+ reasons,
1101
+ });
1102
+ }
1103
+
1104
+ function defaultBranchRef(cwd) {
1105
+ runGit(cwd, ['fetch', 'origin']);
1106
+ const symbolic = runGit(cwd, ['symbolic-ref', '--quiet', 'refs/remotes/origin/HEAD'], { allowFailure: true });
1107
+ if (symbolic.ok && symbolic.stdout) return symbolic.stdout.replace(/^refs\/remotes\//, '');
1108
+ for (const candidate of ['origin/main', 'origin/master', 'origin/trunk']) {
1109
+ const exists = runGit(cwd, ['rev-parse', '--verify', candidate], { allowFailure: true });
1110
+ if (exists.ok) return candidate;
1111
+ }
1112
+ throw new TaskExecutionError('Could not resolve the default remote branch from origin/HEAD.', 'default_branch_unresolved');
1113
+ }
1114
+
1115
+ function branchExists(cwd, branch) {
1116
+ return runGit(cwd, ['show-ref', '--verify', '--quiet', `refs/heads/${branch}`], { allowFailure: true }).ok;
1117
+ }
1118
+
1119
+ function worktreeForBranch(cwd, branch) {
1120
+ const listed = runGit(cwd, ['worktree', 'list', '--porcelain']);
1121
+ return parseWorktreePorcelain(listed.stdout).find((entry) => entry.branch === branch) || null;
1122
+ }
1123
+
1124
+ function defaultWorktreeRoot(cwd) {
1125
+ return path.join(path.dirname(cwd), `${path.basename(cwd)}.task-worktrees`);
1126
+ }
1127
+
1128
+ function safeWorktreeLeaf(branch) {
1129
+ return String(branch).replace(/[\\/]/g, '__').replace(/[^A-Za-z0-9._-]/g, '-');
1130
+ }
1131
+
1132
+ function ensureTaskWorktree(cwd, record, deps = {}) {
1133
+ if (deps.ensureTaskWorktree) return deps.ensureTaskWorktree({ cwd, record });
1134
+
1135
+ const branch = record.branch_name;
1136
+ const root = deps.worktreeRoot || defaultWorktreeRoot(cwd);
1137
+ const worktreePath = path.join(root, safeWorktreeLeaf(branch));
1138
+ fs.mkdirSync(root, { recursive: true });
1139
+
1140
+ const baseRef = defaultBranchRef(cwd);
1141
+ const existing = worktreeForBranch(cwd, branch);
1142
+ if (existing) {
1143
+ const status = runGit(existing.path, ['status', '--porcelain']).stdout;
1144
+ if (status) {
1145
+ throw new TaskExecutionError(`Task worktree ${existing.path} has uncommitted changes.`, 'dirty_task_worktree', { path: existing.path });
1146
+ }
1147
+ const rebase = runGit(existing.path, ['rebase', baseRef], { allowFailure: true });
1148
+ if (!rebase.ok) {
1149
+ runGit(existing.path, ['rebase', '--abort'], { allowFailure: true });
1150
+ throw new TaskExecutionError(`Could not rebase ${branch} onto ${baseRef}: ${rebase.stderr}`, 'task_branch_rebase_conflict');
1151
+ }
1152
+ return {
1153
+ path: existing.path,
1154
+ branch,
1155
+ base_ref: baseRef,
1156
+ reused: true,
1157
+ };
1158
+ }
1159
+
1160
+ if (fs.existsSync(worktreePath)) {
1161
+ throw new TaskExecutionError(`Task worktree path already exists without matching branch: ${worktreePath}`, 'worktree_path_collision', { path: worktreePath });
1162
+ }
1163
+
1164
+ if (branchExists(cwd, branch)) {
1165
+ runGit(cwd, ['worktree', 'add', worktreePath, branch]);
1166
+ const rebase = runGit(worktreePath, ['rebase', baseRef], { allowFailure: true });
1167
+ if (!rebase.ok) {
1168
+ runGit(worktreePath, ['rebase', '--abort'], { allowFailure: true });
1169
+ throw new TaskExecutionError(`Could not rebase ${branch} onto ${baseRef}: ${rebase.stderr}`, 'task_branch_rebase_conflict');
1170
+ }
1171
+ } else {
1172
+ runGit(cwd, ['worktree', 'add', '-b', branch, worktreePath, baseRef]);
1173
+ }
1174
+
1175
+ return {
1176
+ path: worktreePath,
1177
+ branch,
1178
+ base_ref: baseRef,
1179
+ reused: false,
1180
+ };
1181
+ }
1182
+
1183
+ function listChangedFiles(worktree, deps = {}) {
1184
+ if (deps.listChangedFiles) return deps.listChangedFiles(worktree);
1185
+ const committed = runGit(worktree.path, ['diff', '--name-only', `${worktree.base_ref}...HEAD`]).stdout;
1186
+ const unstaged = runGit(worktree.path, ['diff', '--name-only']).stdout;
1187
+ const staged = runGit(worktree.path, ['diff', '--cached', '--name-only']).stdout;
1188
+ const untracked = runGit(worktree.path, ['ls-files', '--others', '--exclude-standard']).stdout;
1189
+ return [...new Set([committed, unstaged, staged, untracked]
1190
+ .flatMap((text) => String(text || '').split(/\r?\n/))
1191
+ .map(normalizeRepoPath)
1192
+ .filter(Boolean))]
1193
+ .sort();
1194
+ }
1195
+
1196
+ function pushTaskBranch(worktree, deps = {}) {
1197
+ if (deps.pushBranch) return deps.pushBranch(worktree);
1198
+ runGit(worktree.path, ['push', '--set-upstream', 'origin', worktree.branch]);
1199
+ return {
1200
+ pushed: true,
1201
+ branch: worktree.branch,
1202
+ };
1203
+ }
1204
+
1205
+ function reviewFeedback(adapter, record) {
1206
+ const pr = latestPr([...record.linked_prs.open, ...record.linked_prs.closedUnmerged]);
1207
+ if (!pr || !adapter || typeof adapter.listPullRequestFeedback !== 'function') return [];
1208
+ return callWrite(`list_pull_request_feedback:${pr.number}`, () => adapter.listPullRequestFeedback(pr.number));
1209
+ }
1210
+
1211
+ function prBody(record, validation, executorResult, ready) {
1212
+ const lines = [
1213
+ `## Task`,
1214
+ '',
1215
+ `- Issue: #${record.issue_number}`,
1216
+ `- Task ID: \`${record.task_id}\``,
1217
+ `- Source plan: \`${sourcePathForPlan(record.plan)}\``,
1218
+ '',
1219
+ '## Implementation Notes',
1220
+ String(executorResult?.notes || executorResult?.summary || 'No implementation notes returned.').trim(),
1221
+ '',
1222
+ validationMarkdown(validation),
1223
+ ];
1224
+ if (ready) {
1225
+ lines.push('', `Closes #${record.issue_number}`);
1226
+ } else {
1227
+ lines.push('', 'This draft intentionally does not close the task issue because automated validation has not passed.');
1228
+ }
1229
+ return lines.join('\n');
1230
+ }
1231
+
1232
+ function withTemporaryPrBodyFile(body, fn) {
1233
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gtd-task-pr-body-'));
1234
+ const file = path.join(dir, 'body.md');
1235
+ try {
1236
+ fs.writeFileSync(file, String(body || ''), 'utf8');
1237
+ return fn(file);
1238
+ } finally {
1239
+ fs.rmSync(dir, { recursive: true, force: true });
1240
+ }
1241
+ }
1242
+
1243
+ function openOrUpdatePullRequest(adapter, record, worktree, validation, executorResult, ready) {
1244
+ const existingOpen = latestPr(record.linked_prs.open);
1245
+ const existingClosed = latestPr(record.linked_prs.closedUnmerged);
1246
+ const body = prBody(record, validation, executorResult, ready);
1247
+ const title = `[GTD ${record.task_id}] ${record.task.name}`;
1248
+
1249
+ if (existingOpen) {
1250
+ if (!adapter || typeof adapter.updatePullRequest !== 'function') {
1251
+ throw new TaskExecutionError('GitHub PR update is unavailable.', 'github_pr_unavailable');
1252
+ }
1253
+ return callWrite(`update_pull_request:${existingOpen.number}`, () => adapter.updatePullRequest(existingOpen.number, {
1254
+ title,
1255
+ body,
1256
+ draft: !ready,
1257
+ labels: ready ? [] : ['gtd:validation-failed'],
1258
+ }));
1259
+ }
1260
+
1261
+ if (existingClosed && adapter && typeof adapter.reopenPullRequest === 'function') {
1262
+ callWrite(`reopen_pull_request:${existingClosed.number}`, () => adapter.reopenPullRequest(existingClosed.number));
1263
+ return callWrite(`update_pull_request:${existingClosed.number}`, () => adapter.updatePullRequest(existingClosed.number, {
1264
+ title,
1265
+ body,
1266
+ draft: !ready,
1267
+ labels: ready ? [] : ['gtd:validation-failed'],
1268
+ }));
1269
+ }
1270
+
1271
+ if (!adapter || typeof adapter.createPullRequest !== 'function') {
1272
+ throw new TaskExecutionError('GitHub PR creation is unavailable.', 'github_pr_unavailable');
1273
+ }
1274
+ return callWrite(`create_pull_request:${worktree.branch}`, () => adapter.createPullRequest({
1275
+ title,
1276
+ body,
1277
+ head: worktree.branch,
1278
+ base: worktree.base_ref.replace(/^origin\//, ''),
1279
+ draft: !ready,
1280
+ labels: ready ? [] : ['gtd:validation-failed'],
1281
+ }));
1282
+ }
1283
+
1284
+ function finalizeIssueAfterPr(adapter, record, pr, validation, ready) {
1285
+ const labels = ready
1286
+ ? mergeLabelSet(record.labels.virtual, ['gtd:pr-open'], ['gtd:in-progress', 'gtd:ready', 'gtd:blocked', 'gtd:needs-rework', 'gtd:validation-failed', 'gtd:rejected'])
1287
+ : mergeLabelSet(record.labels.virtual, ['gtd:pr-open', 'gtd:validation-failed'], ['gtd:in-progress', 'gtd:ready', 'gtd:blocked']);
1288
+ setIssueLabels(adapter, record.issue_number, labels);
1289
+ const body = [
1290
+ ready ? 'Task PR is ready for review.' : 'Draft task PR opened with validation failures.',
1291
+ '',
1292
+ `PR: ${pr.url || `#${pr.number}`}`,
1293
+ '',
1294
+ validationMarkdown(validation),
1295
+ ].join('\n');
1296
+ commentIssue(adapter, record.issue_number, body);
1297
+ return {
1298
+ labels,
1299
+ comment_posted: true,
1300
+ };
1301
+ }
1302
+
1303
+ function executorEvidenceMarkdown(executorEvidence) {
1304
+ const lines = [
1305
+ '## Executor Evidence',
1306
+ '',
1307
+ executorEvidence?.ok ? 'Executor commit evidence passed.' : 'Executor commit evidence failed.',
1308
+ ];
1309
+ for (const reason of executorEvidence?.reasons || []) {
1310
+ lines.push(`- ${reason.code || 'executor_evidence'}: ${reason.message || 'Evidence check failed.'}`);
1311
+ }
1312
+ return lines.join('\n');
1313
+ }
1314
+
1315
+ function markExecutorEvidenceFailedWithoutPr(adapter, record, validation, executorEvidence) {
1316
+ const labels = mergeLabelSet(record.labels.virtual, ['gtd:validation-failed'], ['gtd:in-progress', 'gtd:ready', 'gtd:blocked']);
1317
+ setIssueLabels(adapter, record.issue_number, labels);
1318
+ commentIssue(adapter, record.issue_number, [
1319
+ 'Task execution did not produce valid executor commit evidence. No PR was opened.',
1320
+ '',
1321
+ validationMarkdown(validation),
1322
+ '',
1323
+ executorEvidenceMarkdown(executorEvidence),
1324
+ ].join('\n'));
1325
+ return {
1326
+ labels,
1327
+ comment_posted: true,
1328
+ };
1329
+ }
1330
+
1331
+ function sameMarker(marker, expected) {
1332
+ if (!marker || marker.phase !== expected.phase || marker.plan !== expected.plan) return false;
1333
+ if (Object.prototype.hasOwnProperty.call(expected, 'task')) return marker.task === expected.task;
1334
+ return marker.task === null;
1335
+ }
1336
+
1337
+ function setAddMany(set, labels) {
1338
+ for (const label of labels) set.add(label);
1339
+ }
1340
+
1341
+ function setDeleteMany(set, labels) {
1342
+ for (const label of labels) set.delete(label);
1343
+ }
1344
+
1345
+ function labelActions(currentLabels, virtualLabels, managedLabels) {
1346
+ const current = new Set(currentLabels);
1347
+ const virtual = new Set(virtualLabels);
1348
+ const managed = new Set(managedLabels);
1349
+ return {
1350
+ add: [...virtual].filter((label) => managed.has(label) && !current.has(label)).sort(),
1351
+ remove: [...current].filter((label) => managed.has(label) && !virtual.has(label)).sort(),
1352
+ };
1353
+ }
1354
+
1355
+ function openIssueNumbers(issues) {
1356
+ return (issues || []).filter(isIssueOpen).map((issue) => Number(issue.number)).filter(Boolean).sort((a, b) => a - b);
1357
+ }
1358
+
1359
+ function sourcePathForPlan(plan) {
1360
+ return plan?.source_path || null;
1361
+ }
1362
+
1363
+ function isCheckpointTask(record) {
1364
+ if (!record) return false;
1365
+ const labels = new Set(record.labels?.virtual || record.labels?.current || []);
1366
+ return isCheckpointTaskType(record.task?.type || record.manifest_entry?.type) ||
1367
+ labels.has('gtd:checkpoint') ||
1368
+ labels.has('type:checkpoint');
1369
+ }
1370
+
1371
+ function isResolvedCheckpointTask(record) {
1372
+ return isCheckpointTask(record) && record.issue && !isIssueOpen(record.issue);
1373
+ }
1374
+
1375
+ function applyCheckpointVirtualState(record, virtualLabels) {
1376
+ if (!isCheckpointTask(record) || !record.issue) return;
1377
+ setAddMany(virtualLabels, ['gtd:checkpoint', 'gtd:human-in-the-loop']);
1378
+ virtualLabels.delete('type:task');
1379
+ virtualLabels.add('type:checkpoint');
1380
+
1381
+ if (isIssueOpen(record.issue)) {
1382
+ setAddMany(virtualLabels, ['gtd:blocked', 'gtd:blocked-human']);
1383
+ setDeleteMany(virtualLabels, [
1384
+ 'gtd:ready',
1385
+ 'gtd:in-progress',
1386
+ 'gtd:pr-open',
1387
+ 'gtd:needs-rework',
1388
+ 'gtd:validation-failed',
1389
+ 'gtd:rejected',
1390
+ 'gtd:merged',
1391
+ 'gtd:checkpoint-resolved',
1392
+ ]);
1393
+ return;
1394
+ }
1395
+
1396
+ virtualLabels.add('gtd:checkpoint-resolved');
1397
+ setDeleteMany(virtualLabels, [
1398
+ 'gtd:ready',
1399
+ 'gtd:blocked',
1400
+ 'gtd:in-progress',
1401
+ 'gtd:pr-open',
1402
+ 'gtd:needs-rework',
1403
+ 'gtd:validation-failed',
1404
+ 'gtd:rejected',
1405
+ 'gtd:merged',
1406
+ 'gtd:blocked-human',
1407
+ ]);
1408
+ }
1409
+
1410
+ function makeTaskRecord(scope, plan, task, parentRecord, adapter) {
1411
+ const errors = [];
1412
+ const taskEntry = manifestTaskEntry(scope, plan.id, task.id);
1413
+ const issueNumber = taskEntry?.issue || null;
1414
+ const issue = issueNumber
1415
+ ? callRead(`get_issue:${issueNumber}`, null, () => adapter.getIssue(issueNumber), errors)
1416
+ : null;
1417
+ const blockers = issueNumber
1418
+ ? listBlockedBy(adapter, issueNumber, errors, `list_blocked_by:${issueNumber}`)
1419
+ : [];
1420
+ const branchName = issueNumber ? taskBranchName(task.id, issueNumber) : null;
1421
+ const prs = issueNumber ? listPullRequestsForIssue(adapter, issueNumber, branchName, errors) : [];
1422
+ const pr = prState(prs);
1423
+ const currentLabels = issueLabels(issue);
1424
+ const virtualLabels = new Set(currentLabels);
1425
+ setAddMany(virtualLabels, ['gtd:task']);
1426
+
1427
+ const marker = parseExportMarker(issue?.body || '');
1428
+ const expectedMarker = {
1429
+ phase: scope.phase.phaseSlug,
1430
+ plan: plan.id,
1431
+ task: task.id,
1432
+ };
1433
+ const markerValid = sameMarker(marker, expectedMarker);
1434
+ const sourceDrift =
1435
+ !markerValid ||
1436
+ marker.source_hash !== task.source_hash ||
1437
+ taskEntry?.source_hash !== task.source_hash;
1438
+
1439
+ const openBlockers = blockers.filter(isIssueOpen);
1440
+ if (sourceDrift) virtualLabels.add('gtd:source-drift');
1441
+ const checkpointTask = isCheckpointTask({
1442
+ task,
1443
+ manifest_entry: taskEntry,
1444
+ labels: {
1445
+ current: currentLabels,
1446
+ virtual: [...virtualLabels],
1447
+ },
1448
+ });
1449
+
1450
+ if (checkpointTask) {
1451
+ applyCheckpointVirtualState({
1452
+ task,
1453
+ manifest_entry: taskEntry,
1454
+ issue,
1455
+ labels: {
1456
+ current: currentLabels,
1457
+ virtual: [...virtualLabels],
1458
+ },
1459
+ }, virtualLabels);
1460
+ } else if (pr.merged.length > 0) {
1461
+ virtualLabels.add('gtd:merged');
1462
+ setDeleteMany(virtualLabels, [
1463
+ 'gtd:ready',
1464
+ 'gtd:blocked',
1465
+ 'gtd:in-progress',
1466
+ 'gtd:pr-open',
1467
+ 'gtd:needs-rework',
1468
+ 'gtd:validation-failed',
1469
+ 'gtd:rejected',
1470
+ ]);
1471
+ } else if (pr.open.length > 0) {
1472
+ virtualLabels.add('gtd:pr-open');
1473
+ virtualLabels.delete('gtd:merged');
1474
+ virtualLabels.delete('gtd:ready');
1475
+ virtualLabels.delete('gtd:blocked');
1476
+ if (pr.openNeedsRework.length > 0) virtualLabels.add('gtd:needs-rework');
1477
+ } else if (pr.closedUnmerged.length > 0) {
1478
+ virtualLabels.add('gtd:rejected');
1479
+ virtualLabels.add('gtd:needs-rework');
1480
+ virtualLabels.delete('gtd:pr-open');
1481
+ } else if (issue && isIssueOpen(issue)) {
1482
+ const hasBlockingLabel = ['gtd:blocked-human', 'gtd:source-drift'].some((label) => virtualLabels.has(label));
1483
+ if (openBlockers.length > 0 || hasBlockingLabel) {
1484
+ virtualLabels.add('gtd:blocked');
1485
+ virtualLabels.delete('gtd:ready');
1486
+ } else {
1487
+ virtualLabels.add('gtd:ready');
1488
+ virtualLabels.delete('gtd:blocked');
1489
+ }
1490
+ }
1491
+
1492
+ const record = {
1493
+ kind: 'task',
1494
+ scope,
1495
+ plan,
1496
+ task,
1497
+ task_id: task.id,
1498
+ plan_id: plan.id,
1499
+ issue_number: issueNumber,
1500
+ issue,
1501
+ parent: parentRecord,
1502
+ manifest_entry: taskEntry,
1503
+ marker,
1504
+ marker_valid: markerValid,
1505
+ source_drift: sourceDrift,
1506
+ labels: {
1507
+ current: currentLabels.sort(),
1508
+ virtual: [...virtualLabels].sort(),
1509
+ actions: labelActions(currentLabels, virtualLabels, TASK_STATE_LABELS),
1510
+ },
1511
+ blockers,
1512
+ open_blockers: openBlockers,
1513
+ linked_prs: pr,
1514
+ branch_name: branchName,
1515
+ errors,
1516
+ };
1517
+ record.workability = evaluateWorkability(record);
1518
+ record.selection_bucket = selectionBucket(record);
1519
+ return record;
1520
+ }
1521
+
1522
+ function makeParentRecord(scope, plan, adapter) {
1523
+ const errors = [];
1524
+ const planEntry = manifestPlanEntry(scope, plan.id);
1525
+ const issueNumber = planEntry?.issue || null;
1526
+ const issue = issueNumber
1527
+ ? callRead(`get_issue:${issueNumber}`, null, () => adapter.getIssue(issueNumber), errors)
1528
+ : null;
1529
+ const blockers = issueNumber
1530
+ ? listBlockedBy(adapter, issueNumber, errors, `list_blocked_by:${issueNumber}`)
1531
+ : [];
1532
+ const branchName = issueNumber ? reconciliationBranchName(plan.id, issueNumber) : null;
1533
+ const prs = issueNumber ? listPullRequestsForIssue(adapter, issueNumber, branchName, errors) : [];
1534
+ const pr = prState(prs);
1535
+ const currentLabels = issueLabels(issue);
1536
+ const virtualLabels = new Set(currentLabels);
1537
+ setAddMany(virtualLabels, ['gtd:plan']);
1538
+
1539
+ const marker = parseExportMarker(issue?.body || '');
1540
+ const expectedMarker = {
1541
+ phase: scope.phase.phaseSlug,
1542
+ plan: plan.id,
1543
+ };
1544
+ const markerValid = sameMarker(marker, expectedMarker);
1545
+ const sourceDrift =
1546
+ !markerValid ||
1547
+ marker.source_hash !== plan.source_hash ||
1548
+ planEntry?.source_hash !== plan.source_hash;
1549
+ if (sourceDrift) virtualLabels.add('gtd:source-drift');
1550
+
1551
+ const parentRecord = {
1552
+ kind: 'parent_plan',
1553
+ scope,
1554
+ plan,
1555
+ plan_id: plan.id,
1556
+ issue_number: issueNumber,
1557
+ issue,
1558
+ manifest_entry: planEntry,
1559
+ marker,
1560
+ marker_valid: markerValid,
1561
+ source_drift: sourceDrift,
1562
+ labels: {
1563
+ current: currentLabels.sort(),
1564
+ virtual: null,
1565
+ actions: null,
1566
+ },
1567
+ blockers,
1568
+ open_blockers: blockers.filter(isIssueOpen),
1569
+ linked_prs: pr,
1570
+ branch_name: branchName,
1571
+ tasks: [],
1572
+ errors,
1573
+ reconciliation: null,
1574
+ };
1575
+
1576
+ parentRecord.labels.virtual = [...virtualLabels].sort();
1577
+ parentRecord.labels.actions = labelActions(currentLabels, virtualLabels, PARENT_STATE_LABELS);
1578
+ return parentRecord;
1579
+ }
1580
+
1581
+ function evaluateWorkability(record) {
1582
+ const reasons = [];
1583
+ const virtualLabels = new Set(record.labels.virtual);
1584
+ const issueNumber = record.issue_number ? `#${record.issue_number}` : 'unknown issue';
1585
+ const checkpointTask = isCheckpointTask(record);
1586
+
1587
+ if (!record.manifest_entry?.issue) {
1588
+ reasons.push({ code: 'missing_manifest_task_issue', message: `${record.task_id} has no task issue in the export manifest.` });
1589
+ }
1590
+ if (checkpointTask) {
1591
+ reasons.push({
1592
+ code: 'checkpoint_human_resolution',
1593
+ message: record.issue && !isIssueOpen(record.issue)
1594
+ ? `${issueNumber} is a resolved human-in-the-loop checkpoint. Checkpoint tasks are not executable implementation work.`
1595
+ : `${issueNumber} is a human-in-the-loop checkpoint. Resolve it by recording the human decision/result in GitHub and closing the checkpoint issue; dependent implementation tasks remain blocked while it is open.`,
1596
+ status: record.issue && !isIssueOpen(record.issue) ? CHECKPOINT_RESOLVED_STATUS : 'checkpoint_open',
1597
+ });
1598
+ }
1599
+ if (!record.issue) {
1600
+ reasons.push({ code: 'issue_not_found', message: `${issueNumber} could not be read from GitHub.` });
1601
+ } else if (!isIssueOpen(record.issue)) {
1602
+ reasons.push({ code: 'issue_closed', message: `${issueNumber} is closed.` });
1603
+ }
1604
+ if (!virtualLabels.has('gtd:task')) {
1605
+ reasons.push({ code: 'missing_task_label', message: `${issueNumber} is not labeled gtd:task.` });
1606
+ }
1607
+ if (!record.marker_valid) {
1608
+ reasons.push({ code: 'invalid_marker', message: `${issueNumber} does not contain the expected gtd-export marker for ${record.task_id}.` });
1609
+ }
1610
+ if (record.source_drift) {
1611
+ reasons.push({
1612
+ code: 'source_drift',
1613
+ message: `${record.task_id} source hash differs from the manifest or issue marker.`,
1614
+ details: {
1615
+ issue_hash: record.marker?.source_hash || null,
1616
+ manifest_hash: record.manifest_entry?.source_hash || null,
1617
+ current_hash: record.task.source_hash,
1618
+ },
1619
+ });
1620
+ }
1621
+ for (const err of record.errors) {
1622
+ reasons.push({ code: 'preflight_read_failed', message: `${err.operation}: ${err.message}` });
1623
+ }
1624
+ const openBlockerNumbers = openIssueNumbers(record.open_blockers);
1625
+ if (openBlockerNumbers.length > 0) {
1626
+ reasons.push({
1627
+ code: 'open_task_blockers',
1628
+ message: `${issueNumber} is blocked by open issue(s): ${openBlockerNumbers.map((n) => `#${n}`).join(', ')}.`,
1629
+ blockers: openBlockerNumbers,
1630
+ });
1631
+ }
1632
+ const blockingLabels = BLOCKING_TASK_LABELS.filter((label) => virtualLabels.has(label));
1633
+ if (blockingLabels.length > 0) {
1634
+ reasons.push({
1635
+ code: 'blocking_task_labels',
1636
+ message: `${issueNumber} has blocking label(s): ${blockingLabels.join(', ')}.`,
1637
+ labels: blockingLabels,
1638
+ });
1639
+ }
1640
+ const parentBlockers = openIssueNumbers(record.parent?.open_blockers || []);
1641
+ if (parentBlockers.length > 0) {
1642
+ reasons.push({
1643
+ code: 'open_parent_blockers',
1644
+ message: `Parent plan #${record.parent.issue_number} is blocked by open issue(s): ${parentBlockers.map((n) => `#${n}`).join(', ')}.`,
1645
+ blockers: parentBlockers,
1646
+ });
1647
+ }
1648
+ if (virtualLabels.has('gtd:in-progress') && !isResumable(record)) {
1649
+ reasons.push({
1650
+ code: 'active_claim',
1651
+ message: `${issueNumber} is already labeled gtd:in-progress; read-only mode does not clear or take over claims.`,
1652
+ });
1653
+ }
1654
+ if (!isActionableState(record)) {
1655
+ reasons.push({
1656
+ code: 'not_actionable',
1657
+ message: `${issueNumber} is not ready, not a rework task, and has no resumable rejected or validation-failed state.`,
1658
+ });
1659
+ }
1660
+
1661
+ return {
1662
+ workable: reasons.length === 0,
1663
+ reasons,
1664
+ skipped_checks: [
1665
+ 'task worktree creation/reuse is checked in task execution mode',
1666
+ ],
1667
+ };
1668
+ }
1669
+
1670
+ function isResumable(record) {
1671
+ const labels = new Set(record.labels.virtual);
1672
+ return record.linked_prs.openNeedsRework.length > 0 ||
1673
+ record.linked_prs.closedUnmerged.length > 0 ||
1674
+ REWORK_LABELS.some((label) => labels.has(label));
1675
+ }
1676
+
1677
+ function isReadyNewWork(record) {
1678
+ const labels = new Set(record.labels.virtual);
1679
+ return labels.has('gtd:ready') &&
1680
+ record.open_blockers.length === 0 &&
1681
+ record.linked_prs.open.length === 0 &&
1682
+ record.linked_prs.closedUnmerged.length === 0 &&
1683
+ record.linked_prs.merged.length === 0;
1684
+ }
1685
+
1686
+ function isActionableState(record) {
1687
+ const labels = new Set(record.labels.virtual);
1688
+ return isReadyNewWork(record) ||
1689
+ record.linked_prs.openNeedsRework.length > 0 ||
1690
+ record.linked_prs.closedUnmerged.length > 0 ||
1691
+ REWORK_LABELS.some((label) => labels.has(label));
1692
+ }
1693
+
1694
+ function selectionBucket(record) {
1695
+ const labels = new Set(record.labels.virtual);
1696
+ if (!record.workability?.workable) return null;
1697
+ if (record.linked_prs.openNeedsRework.length > 0) return 1;
1698
+ if (REWORK_LABELS.some((label) => labels.has(label))) return 2;
1699
+ if (isReadyNewWork(record)) return 3;
1700
+ return null;
1701
+ }
1702
+
1703
+ function evaluateReconciliation(parent) {
1704
+ const reasons = [];
1705
+ const issueNumber = parent.issue_number ? `#${parent.issue_number}` : 'unknown issue';
1706
+ const hasMergedReconciliation = parent.linked_prs?.merged?.length > 0;
1707
+ const hasOpenReconciliation = parent.linked_prs?.open?.length > 0;
1708
+
1709
+ if (hasMergedReconciliation) {
1710
+ const virtualLabels = new Set(parent.labels.virtual);
1711
+ virtualLabels.add('gtd:complete');
1712
+ setDeleteMany(virtualLabels, [
1713
+ 'gtd:ready',
1714
+ 'gtd:blocked',
1715
+ 'gtd:ready-for-reconcile',
1716
+ 'gtd:reconcile-pr-open',
1717
+ 'gtd:reconcile-failed',
1718
+ 'gtd:source-drift',
1719
+ ]);
1720
+ parent.labels.virtual = [...virtualLabels].sort();
1721
+ parent.labels.actions = labelActions(parent.labels.current, virtualLabels, PARENT_STATE_LABELS);
1722
+ parent.reconciliation = {
1723
+ ready: false,
1724
+ permission_required: false,
1725
+ reasons: [],
1726
+ proposed_branch: parent.branch_name,
1727
+ plan_verification: parent.plan.verification || '',
1728
+ artifacts: [
1729
+ summaryPathForPlan(parent.plan),
1730
+ '.planning/STATE.md',
1731
+ '.planning/ROADMAP.md',
1732
+ 'requirements completion metadata',
1733
+ ],
1734
+ status: 'complete',
1735
+ };
1736
+ return;
1737
+ }
1738
+
1739
+ if (!parent.issue) {
1740
+ reasons.push({ code: 'parent_issue_not_found', message: `${issueNumber} could not be read from GitHub.` });
1741
+ } else if (!isIssueOpen(parent.issue)) {
1742
+ reasons.push({ code: 'parent_closed', message: `${issueNumber} is closed.` });
1743
+ }
1744
+ if (hasOpenReconciliation) {
1745
+ reasons.push({
1746
+ code: 'reconciliation_pr_open',
1747
+ message: `${issueNumber} already has an open reconciliation PR.`,
1748
+ prs: parent.linked_prs.open.map((pr) => pr.number).filter(Boolean),
1749
+ });
1750
+ }
1751
+ if (!parent.marker_valid) {
1752
+ reasons.push({ code: 'invalid_parent_marker', message: `${issueNumber} does not contain the expected parent plan marker.` });
1753
+ }
1754
+ if (parent.source_drift) {
1755
+ reasons.push({
1756
+ code: 'parent_source_drift',
1757
+ message: `${parent.plan_id} source hash differs from the manifest or parent issue marker.`,
1758
+ details: {
1759
+ issue_hash: parent.marker?.source_hash || null,
1760
+ manifest_hash: parent.manifest_entry?.source_hash || null,
1761
+ current_hash: parent.plan.source_hash,
1762
+ source_path: sourcePathForPlan(parent.plan),
1763
+ },
1764
+ });
1765
+ }
1766
+ const parentBlockers = openIssueNumbers(parent.open_blockers);
1767
+ if (parentBlockers.length > 0) {
1768
+ reasons.push({
1769
+ code: 'open_parent_blockers',
1770
+ message: `${issueNumber} is blocked by open issue(s): ${parentBlockers.map((n) => `#${n}`).join(', ')}.`,
1771
+ blockers: parentBlockers,
1772
+ });
1773
+ }
1774
+ for (const err of parent.errors) {
1775
+ reasons.push({ code: 'preflight_read_failed', message: `${err.operation}: ${err.message}` });
1776
+ }
1777
+
1778
+ for (const task of parent.tasks) {
1779
+ const labels = new Set(task.labels.virtual);
1780
+ const resolvedCheckpoint = isResolvedCheckpointTask(task);
1781
+ if (task.issue && isIssueOpen(task.issue)) {
1782
+ reasons.push({
1783
+ code: 'child_task_open',
1784
+ message: `Child task #${task.issue_number} (${task.task_id}) is still open.`,
1785
+ issue: task.issue_number,
1786
+ });
1787
+ }
1788
+ if (task.linked_prs.merged.length === 0 && !resolvedCheckpoint) {
1789
+ reasons.push({
1790
+ code: 'child_pr_not_merged',
1791
+ message: `Child task #${task.issue_number} (${task.task_id}) has no merged linked PR.`,
1792
+ issue: task.issue_number,
1793
+ });
1794
+ }
1795
+ const blockingLabels = ['gtd:needs-rework', 'gtd:blocked-human', 'gtd:source-drift'].filter((label) => labels.has(label));
1796
+ if (blockingLabels.length > 0) {
1797
+ reasons.push({
1798
+ code: 'child_blocking_labels',
1799
+ message: `Child task #${task.issue_number} (${task.task_id}) has blocking label(s): ${blockingLabels.join(', ')}.`,
1800
+ issue: task.issue_number,
1801
+ labels: blockingLabels,
1802
+ });
1803
+ }
1804
+ }
1805
+
1806
+ const virtualLabels = new Set(parent.labels.virtual);
1807
+ if (reasons.length === 0) {
1808
+ virtualLabels.add('gtd:ready-for-reconcile');
1809
+ virtualLabels.delete('gtd:blocked');
1810
+ virtualLabels.delete('gtd:reconcile-pr-open');
1811
+ } else if (parent.source_drift) {
1812
+ virtualLabels.delete('gtd:ready-for-reconcile');
1813
+ virtualLabels.add('gtd:source-drift');
1814
+ } else if (hasOpenReconciliation) {
1815
+ virtualLabels.delete('gtd:ready-for-reconcile');
1816
+ virtualLabels.add('gtd:reconcile-pr-open');
1817
+ }
1818
+
1819
+ parent.labels.virtual = [...virtualLabels].sort();
1820
+ parent.labels.actions = labelActions(parent.labels.current, virtualLabels, PARENT_STATE_LABELS);
1821
+ parent.reconciliation = {
1822
+ ready: reasons.length === 0,
1823
+ permission_required: reasons.length === 0,
1824
+ reasons,
1825
+ proposed_branch: parent.issue_number ? reconciliationBranchName(parent.plan_id, parent.issue_number) : null,
1826
+ plan_verification: parent.plan.verification || '',
1827
+ artifacts: [
1828
+ summaryPathForPlan(parent.plan),
1829
+ '.planning/STATE.md',
1830
+ '.planning/ROADMAP.md',
1831
+ 'requirements completion metadata',
1832
+ ],
1833
+ status: hasOpenReconciliation ? 'pr_open' : (reasons.length === 0 ? 'ready' : 'blocked'),
1834
+ };
1835
+ }
1836
+
1837
+ function phaseSortText(record) {
1838
+ return String(record.scope.phase.phaseNumber || record.scope.phase.phaseSlug || '');
1839
+ }
1840
+
1841
+ function taskIndex(record) {
1842
+ const match = String(record.task_id || '').match(/-T(\d+)$/i);
1843
+ return match ? Number(match[1]) : 0;
1844
+ }
1845
+
1846
+ function waveNumber(record) {
1847
+ const raw = record.plan?.wave;
1848
+ const parsed = Number(raw);
1849
+ return Number.isFinite(parsed) ? parsed : Number.MAX_SAFE_INTEGER;
1850
+ }
1851
+
1852
+ function compareRecords(a, b) {
1853
+ const phase = phaseSortText(a).localeCompare(phaseSortText(b), undefined, { numeric: true, sensitivity: 'base' });
1854
+ if (phase !== 0) return phase;
1855
+ const wave = waveNumber(a) - waveNumber(b);
1856
+ if (wave !== 0) return wave;
1857
+ const plan = String(a.plan_id).localeCompare(String(b.plan_id), undefined, { numeric: true, sensitivity: 'base' });
1858
+ if (plan !== 0) return plan;
1859
+ const task = taskIndex(a) - taskIndex(b);
1860
+ if (task !== 0) return task;
1861
+ return Number(a.issue_number || 0) - Number(b.issue_number || 0);
1862
+ }
1863
+
1864
+ function compareParents(a, b) {
1865
+ const phase = phaseSortText(a).localeCompare(phaseSortText(b), undefined, { numeric: true, sensitivity: 'base' });
1866
+ if (phase !== 0) return phase;
1867
+ const wave = waveNumber(a) - waveNumber(b);
1868
+ if (wave !== 0) return wave;
1869
+ const plan = String(a.plan_id).localeCompare(String(b.plan_id), undefined, { numeric: true, sensitivity: 'base' });
1870
+ if (plan !== 0) return plan;
1871
+ return Number(a.issue_number || 0) - Number(b.issue_number || 0);
1872
+ }
1873
+
1874
+ function collectRecords(scopes, adapterForRepo) {
1875
+ const parents = [];
1876
+ const tasks = [];
1877
+ for (const scope of scopes) {
1878
+ const adapter = adapterForRepo(scope.repo);
1879
+ for (const plan of scope.plans) {
1880
+ const parent = makeParentRecord(scope, plan, adapter);
1881
+ parents.push(parent);
1882
+ for (const task of plan.tasks) {
1883
+ const record = makeTaskRecord(scope, plan, task, parent, adapter);
1884
+ parent.tasks.push(record);
1885
+ tasks.push(record);
1886
+ }
1887
+ evaluateReconciliation(parent);
1888
+ }
1889
+ }
1890
+ return {
1891
+ parents: parents.sort(compareParents),
1892
+ tasks: tasks.sort(compareRecords),
1893
+ };
1894
+ }
1895
+
1896
+ function resolveExplicitTask(selector, tasks, parents) {
1897
+ if (selector.type === 'task_id') {
1898
+ return tasks.filter((task) => task.task_id.toUpperCase() === selector.task_id);
1899
+ }
1900
+ if (selector.type === 'plan_id') {
1901
+ const parentMatch = parents.find((parent) => parent.plan_id.toUpperCase() === selector.plan_id);
1902
+ if (parentMatch) {
1903
+ return [{
1904
+ kind: 'resolution_error',
1905
+ workability: {
1906
+ workable: false,
1907
+ reasons: [{
1908
+ code: 'selector_resolved_parent_plan',
1909
+ message: `${selector.raw} is a parent plan selector; use --reconcile to reconcile parent plans.`,
1910
+ }],
1911
+ skipped_checks: [],
1912
+ },
1913
+ }];
1914
+ }
1915
+ }
1916
+ if (selector.type === 'issue') {
1917
+ const matches = tasks.filter((task) => Number(task.issue_number) === selector.issue);
1918
+ if (matches.length > 0) return matches;
1919
+ const parentMatch = parents.find((parent) => Number(parent.issue_number) === selector.issue);
1920
+ if (parentMatch) {
1921
+ return [{
1922
+ kind: 'resolution_error',
1923
+ workability: {
1924
+ workable: false,
1925
+ reasons: [{
1926
+ code: 'selector_resolved_parent_plan',
1927
+ message: `#${selector.issue} is a parent plan issue; step 3 explicit mode only resolves child task issues.`,
1928
+ }],
1929
+ skipped_checks: [],
1930
+ },
1931
+ }];
1932
+ }
1933
+ }
1934
+ return [];
1935
+ }
1936
+
1937
+ function resolveExplicitParent(selector, parents, tasks) {
1938
+ if (selector.type === 'plan_id') {
1939
+ return parents.filter((parent) => parent.plan_id.toUpperCase() === selector.plan_id);
1940
+ }
1941
+ if (selector.type === 'issue') {
1942
+ const matches = parents.filter((parent) => Number(parent.issue_number) === selector.issue);
1943
+ if (matches.length > 0) return matches;
1944
+ const taskMatch = tasks.find((task) => Number(task.issue_number) === selector.issue);
1945
+ if (taskMatch) {
1946
+ return [{
1947
+ kind: 'resolution_error',
1948
+ reconciliation: {
1949
+ ready: false,
1950
+ permission_required: false,
1951
+ reasons: [{
1952
+ code: 'selector_resolved_child_task',
1953
+ message: `#${selector.issue} is a child task issue; omit --reconcile to work task issues.`,
1954
+ }],
1955
+ },
1956
+ }];
1957
+ }
1958
+ }
1959
+ if (selector.type === 'task_id') {
1960
+ const taskMatch = tasks.find((task) => task.task_id.toUpperCase() === selector.task_id);
1961
+ if (taskMatch) {
1962
+ return [{
1963
+ kind: 'resolution_error',
1964
+ reconciliation: {
1965
+ ready: false,
1966
+ permission_required: false,
1967
+ reasons: [{
1968
+ code: 'selector_resolved_child_task',
1969
+ message: `${selector.raw} is a child task selector; omit --reconcile to work task issues.`,
1970
+ }],
1971
+ },
1972
+ }];
1973
+ }
1974
+ }
1975
+ return [];
1976
+ }
1977
+
1978
+ function selectAutomatic(tasks, parents) {
1979
+ const workable = tasks.filter((task) => task.workability.workable && task.selection_bucket !== null);
1980
+ for (const bucket of [1, 2, 3]) {
1981
+ const match = workable.filter((task) => task.selection_bucket === bucket).sort(compareRecords)[0];
1982
+ if (match) return { kind: 'task', record: match };
1983
+ }
1984
+
1985
+ const reconcile = parents.filter((parent) => parent.reconciliation.ready).sort(compareParents)[0];
1986
+ if (reconcile) return { kind: 'reconciliation_permission', record: reconcile };
1987
+
1988
+ return { kind: 'none', record: null };
1989
+ }
1990
+
1991
+ function prOutput(pr) {
1992
+ return {
1993
+ number: pr.number || null,
1994
+ title: pr.title || '',
1995
+ state: pr.state || '',
1996
+ url: pr.url || null,
1997
+ headRefName: pr.headRefName || null,
1998
+ isDraft: pr.isDraft,
1999
+ mergedAt: pr.mergedAt || null,
2000
+ reviewDecision: pr.reviewDecision || null,
2001
+ changesRequested: pr.changesRequested,
2002
+ };
2003
+ }
2004
+
2005
+ function taskOutput(record) {
2006
+ if (record.kind === 'resolution_error') {
2007
+ return {
2008
+ kind: 'task',
2009
+ resolved: false,
2010
+ workability: record.workability,
2011
+ };
2012
+ }
2013
+ return {
2014
+ kind: 'task',
2015
+ resolved: true,
2016
+ issue: record.issue_number,
2017
+ title: record.issue?.title || null,
2018
+ state: record.issue?.state || null,
2019
+ repo: record.scope.repo,
2020
+ phase: record.scope.phase.phaseSlug,
2021
+ plan_id: record.plan_id,
2022
+ task_id: record.task_id,
2023
+ task_type: record.task.type || record.manifest_entry?.type || null,
2024
+ manifest_export_status: manifestTaskExportStatus(record.manifest_entry),
2025
+ checkpoint_status: manifestTaskCheckpointStatus(record.manifest_entry),
2026
+ checkpoint_resolved: isResolvedCheckpointTask(record),
2027
+ source_path: sourcePathForPlan(record.plan),
2028
+ branch: record.branch_name,
2029
+ labels: record.labels,
2030
+ blockers: {
2031
+ task: openIssueNumbers(record.open_blockers),
2032
+ parent: openIssueNumbers(record.parent?.open_blockers || []),
2033
+ },
2034
+ linked_prs: {
2035
+ open: record.linked_prs.open.map(prOutput),
2036
+ open_needs_rework: record.linked_prs.openNeedsRework.map(prOutput),
2037
+ closed_unmerged: record.linked_prs.closedUnmerged.map(prOutput),
2038
+ merged: record.linked_prs.merged.map(prOutput),
2039
+ },
2040
+ marker: {
2041
+ valid: record.marker_valid,
2042
+ issue_hash: record.marker?.source_hash || null,
2043
+ manifest_hash: record.manifest_entry?.source_hash || null,
2044
+ current_hash: record.task.source_hash,
2045
+ },
2046
+ source_drift: record.source_drift,
2047
+ selection_bucket: record.selection_bucket,
2048
+ workability: record.workability,
2049
+ };
2050
+ }
2051
+
2052
+ function parentOutput(parent) {
2053
+ if (parent.kind === 'resolution_error') {
2054
+ return {
2055
+ kind: 'parent_plan',
2056
+ resolved: false,
2057
+ reconciliation: parent.reconciliation,
2058
+ };
2059
+ }
2060
+ return {
2061
+ kind: 'parent_plan',
2062
+ resolved: true,
2063
+ issue: parent.issue_number,
2064
+ title: parent.issue?.title || null,
2065
+ state: parent.issue?.state || null,
2066
+ repo: parent.scope.repo,
2067
+ phase: parent.scope.phase.phaseSlug,
2068
+ plan_id: parent.plan_id,
2069
+ source_path: sourcePathForPlan(parent.plan),
2070
+ labels: parent.labels,
2071
+ blockers: {
2072
+ parent: openIssueNumbers(parent.open_blockers),
2073
+ },
2074
+ linked_prs: {
2075
+ open: parent.linked_prs.open.map(prOutput),
2076
+ merged: parent.linked_prs.merged.map(prOutput),
2077
+ closed_unmerged: parent.linked_prs.closedUnmerged.map(prOutput),
2078
+ },
2079
+ marker: {
2080
+ valid: parent.marker_valid,
2081
+ issue_hash: parent.marker?.source_hash || null,
2082
+ manifest_hash: parent.manifest_entry?.source_hash || null,
2083
+ current_hash: parent.plan.source_hash,
2084
+ },
2085
+ source_drift: parent.source_drift,
2086
+ reconciliation: {
2087
+ ready: parent.reconciliation.ready,
2088
+ permission_required: parent.reconciliation.permission_required,
2089
+ reasons: parent.reconciliation.reasons,
2090
+ proposed_branch: parent.reconciliation.proposed_branch,
2091
+ plan_verification: parent.reconciliation.plan_verification,
2092
+ artifacts: parent.reconciliation.artifacts,
2093
+ status: parent.reconciliation.status,
2094
+ child_tasks: parent.tasks.map((task) => ({
2095
+ issue: task.issue_number,
2096
+ task_id: task.task_id,
2097
+ task_type: task.task.type || task.manifest_entry?.type || null,
2098
+ checkpoint_resolved: isResolvedCheckpointTask(task),
2099
+ merged_prs: task.linked_prs.merged.map(prOutput),
2100
+ })),
2101
+ },
2102
+ };
2103
+ }
2104
+
2105
+ function labelActionSummaries(records) {
2106
+ const actions = [];
2107
+ for (const record of records) {
2108
+ if (record.labels.actions.add.length === 0 && record.labels.actions.remove.length === 0) continue;
2109
+ actions.push({
2110
+ kind: record.kind,
2111
+ issue: record.issue_number,
2112
+ plan_id: record.plan_id,
2113
+ task_id: record.task_id || null,
2114
+ add: record.labels.actions.add,
2115
+ remove: record.labels.actions.remove,
2116
+ });
2117
+ }
2118
+ return actions;
2119
+ }
2120
+
2121
+ function blockingStateOutput(tasks, parents) {
2122
+ return {
2123
+ non_workable_tasks: tasks.map((task) => ({
2124
+ issue: task.issue_number,
2125
+ task_id: task.task_id,
2126
+ plan_id: task.plan_id,
2127
+ labels: task.labels.virtual,
2128
+ reasons: task.workability.reasons,
2129
+ blockers: {
2130
+ task: openIssueNumbers(task.open_blockers),
2131
+ parent: openIssueNumbers(task.parent?.open_blockers || []),
2132
+ },
2133
+ })),
2134
+ parent_reconciliation: parents.map((parent) => ({
2135
+ issue: parent.issue_number,
2136
+ plan_id: parent.plan_id,
2137
+ ready: parent.reconciliation.ready,
2138
+ reasons: parent.reconciliation.reasons,
2139
+ })),
2140
+ };
2141
+ }
2142
+
2143
+ function buildReadOnly(cwd, opts, adapterOrFactory = null) {
2144
+ if (opts.completePhase) return buildCompletePhaseTail(cwd, opts);
2145
+ const selector = parseSelector(opts.selector);
2146
+ const effectiveOpts = {
2147
+ ...opts,
2148
+ repo: opts.repo || selector.repo || null,
2149
+ };
2150
+ const scopes = loadScopes(cwd, effectiveOpts, selector);
2151
+ const adapters = new Map();
2152
+ const adapterForRepo = (repo) => {
2153
+ if (adapterOrFactory && typeof adapterOrFactory === 'function') return adapterOrFactory(repo);
2154
+ if (adapterOrFactory) return adapterOrFactory;
2155
+ if (!adapters.has(repo)) adapters.set(repo, new GhCliTaskIssueAdapter({ cwd, repo }));
2156
+ return adapters.get(repo);
2157
+ };
2158
+
2159
+ const records = collectRecords(scopes, adapterForRepo);
2160
+ const allRecords = [...records.parents, ...records.tasks];
2161
+ const preflightErrors = allRecords.flatMap((record) => record.errors.map((err) => ({
2162
+ issue: record.issue_number,
2163
+ operation: err.operation,
2164
+ message: err.message,
2165
+ })));
2166
+
2167
+ let selected = null;
2168
+ let action = null;
2169
+ let reconciliation = {
2170
+ ready: false,
2171
+ permission_required: false,
2172
+ plans: records.parents.filter((parent) => parent.reconciliation.ready).map(parentOutput),
2173
+ };
2174
+
2175
+ if (opts.reconcile) {
2176
+ if (selector.mode === 'explicit') {
2177
+ const matches = resolveExplicitParent(selector, records.parents, records.tasks);
2178
+ if (matches.length === 1) {
2179
+ selected = parentOutput(matches[0]);
2180
+ action = selected.reconciliation?.ready ? 'preview_reconciliation_ready' : 'report_unworkable_reconciliation';
2181
+ reconciliation = {
2182
+ ready: Boolean(selected.reconciliation?.ready),
2183
+ permission_required: Boolean(selected.reconciliation?.ready),
2184
+ plans: [selected],
2185
+ };
2186
+ } else if (matches.length > 1) {
2187
+ selected = {
2188
+ kind: 'parent_plan',
2189
+ resolved: false,
2190
+ reconciliation: {
2191
+ ready: false,
2192
+ permission_required: false,
2193
+ reasons: [{
2194
+ code: 'selector_ambiguous',
2195
+ message: `Selector ${selector.raw} resolved to multiple parent plan issues: ${matches.map((parent) => `#${parent.issue_number}`).join(', ')}.`,
2196
+ }],
2197
+ },
2198
+ };
2199
+ action = 'report_unresolved_reconciliation_selector';
2200
+ } else {
2201
+ selected = {
2202
+ kind: 'parent_plan',
2203
+ resolved: false,
2204
+ reconciliation: {
2205
+ ready: false,
2206
+ permission_required: false,
2207
+ reasons: [{
2208
+ code: 'selector_not_found',
2209
+ message: `Selector ${selector.raw} did not match any exported parent plan issue in the loaded manifest scope.`,
2210
+ }],
2211
+ },
2212
+ };
2213
+ action = 'report_unresolved_reconciliation_selector';
2214
+ }
2215
+ } else {
2216
+ const reconcile = records.parents.filter((parent) => parent.reconciliation.ready).sort(compareParents)[0];
2217
+ if (reconcile) {
2218
+ selected = parentOutput(reconcile);
2219
+ action = 'request_reconciliation_permission';
2220
+ reconciliation = {
2221
+ ready: true,
2222
+ permission_required: true,
2223
+ plans: [selected],
2224
+ };
2225
+ } else {
2226
+ action = 'report_blocking_state';
2227
+ }
2228
+ }
2229
+ } else if (selector.mode === 'explicit') {
2230
+ const matches = resolveExplicitTask(selector, records.tasks, records.parents);
2231
+ if (matches.length === 1) {
2232
+ selected = taskOutput(matches[0]);
2233
+ action = selected.workability.workable ? 'report_workable_task' : 'report_unworkable_task';
2234
+ } else if (matches.length > 1) {
2235
+ selected = {
2236
+ kind: 'task',
2237
+ resolved: false,
2238
+ workability: {
2239
+ workable: false,
2240
+ reasons: [{
2241
+ code: 'selector_ambiguous',
2242
+ message: `Selector ${selector.raw} resolved to multiple task issues: ${matches.map((task) => `#${task.issue_number}`).join(', ')}.`,
2243
+ }],
2244
+ skipped_checks: [],
2245
+ },
2246
+ };
2247
+ action = 'report_unresolved_selector';
2248
+ } else {
2249
+ selected = {
2250
+ kind: 'task',
2251
+ resolved: false,
2252
+ workability: {
2253
+ workable: false,
2254
+ reasons: [{
2255
+ code: 'selector_not_found',
2256
+ message: `Selector ${selector.raw} did not match any exported child task issue in the loaded manifest scope.`,
2257
+ }],
2258
+ skipped_checks: [],
2259
+ },
2260
+ };
2261
+ action = 'report_unresolved_selector';
2262
+ }
2263
+ } else {
2264
+ const automatic = selectAutomatic(records.tasks, records.parents);
2265
+ if (automatic.kind === 'task') {
2266
+ selected = taskOutput(automatic.record);
2267
+ action = 'report_next_actionable_task';
2268
+ } else if (automatic.kind === 'reconciliation_permission') {
2269
+ selected = parentOutput(automatic.record);
2270
+ action = 'request_reconciliation_permission';
2271
+ reconciliation = {
2272
+ ready: true,
2273
+ permission_required: true,
2274
+ plans: [selected],
2275
+ };
2276
+ } else {
2277
+ action = 'report_blocking_state';
2278
+ }
2279
+ }
2280
+
2281
+ return {
2282
+ ok: true,
2283
+ version: 1,
2284
+ mode: 'read-only',
2285
+ writes: false,
2286
+ implementation: false,
2287
+ pr_creation: false,
2288
+ selector,
2289
+ scope: scopes.map((scope) => ({
2290
+ repo: scope.repo,
2291
+ phase: scope.phase.phaseSlug,
2292
+ phase_number: scope.phase.phaseNumber,
2293
+ manifest: scope.manifest.path,
2294
+ })),
2295
+ preflight: {
2296
+ ok: preflightErrors.length === 0,
2297
+ checked_parent_plans: records.parents.length,
2298
+ checked_tasks: records.tasks.length,
2299
+ label_actions: labelActionSummaries(allRecords),
2300
+ errors: preflightErrors,
2301
+ },
2302
+ action,
2303
+ selected,
2304
+ reconciliation,
2305
+ blocking_state: selected ? null : blockingStateOutput(records.tasks, records.parents),
2306
+ };
2307
+ }
2308
+
2309
+ function adapterFactoryFor(cwd, adapterOrFactory) {
2310
+ const adapters = new Map();
2311
+ return (repo) => {
2312
+ if (adapterOrFactory && typeof adapterOrFactory === 'function') return adapterOrFactory(repo);
2313
+ if (adapterOrFactory) return adapterOrFactory;
2314
+ if (!adapters.has(repo)) adapters.set(repo, new GhCliTaskIssueAdapter({ cwd, repo }));
2315
+ return adapters.get(repo);
2316
+ };
2317
+ }
2318
+
2319
+ function loadExecutionState(cwd, opts, adapterOrFactory = null) {
2320
+ const selector = parseSelector(opts.selector);
2321
+ const effectiveOpts = {
2322
+ ...opts,
2323
+ repo: opts.repo || selector.repo || null,
2324
+ };
2325
+ const scopes = loadScopes(cwd, effectiveOpts, selector);
2326
+ const adapterForRepo = adapterFactoryFor(cwd, adapterOrFactory);
2327
+ const records = collectRecords(scopes, adapterForRepo);
2328
+ return {
2329
+ selector,
2330
+ scopes,
2331
+ adapterForRepo,
2332
+ records,
2333
+ };
2334
+ }
2335
+
2336
+ function resolveExecutionSelection(selector, records) {
2337
+ if (selector.mode === 'explicit') {
2338
+ const matches = resolveExplicitTask(selector, records.tasks, records.parents);
2339
+ if (matches.length === 1) {
2340
+ const record = matches[0];
2341
+ if (record.kind === 'resolution_error') return { kind: 'unresolved', record };
2342
+ return { kind: 'task', record };
2343
+ }
2344
+ if (matches.length > 1) {
2345
+ return {
2346
+ kind: 'unresolved',
2347
+ record: {
2348
+ kind: 'resolution_error',
2349
+ workability: {
2350
+ workable: false,
2351
+ reasons: [{
2352
+ code: 'selector_ambiguous',
2353
+ message: `Selector ${selector.raw} resolved to multiple task issues: ${matches.map((task) => `#${task.issue_number}`).join(', ')}.`,
2354
+ }],
2355
+ skipped_checks: [],
2356
+ },
2357
+ },
2358
+ };
2359
+ }
2360
+ return {
2361
+ kind: 'unresolved',
2362
+ record: {
2363
+ kind: 'resolution_error',
2364
+ workability: {
2365
+ workable: false,
2366
+ reasons: [{
2367
+ code: 'selector_not_found',
2368
+ message: `Selector ${selector.raw} did not match any exported child task issue in the loaded manifest scope.`,
2369
+ }],
2370
+ skipped_checks: [],
2371
+ },
2372
+ },
2373
+ };
2374
+ }
2375
+ return selectAutomatic(records.tasks, records.parents);
2376
+ }
2377
+
2378
+ function executeTaskRecord(cwd, record, adapter, deps = {}) {
2379
+ if (isCheckpointTask(record)) {
2380
+ throw new TaskExecutionError(
2381
+ `${record.task_id} is a human-in-the-loop checkpoint task and cannot be executed. Resolve it by closing the checkpoint issue after recording the human decision/result.`,
2382
+ 'checkpoint_task_not_executable',
2383
+ { issue: record.issue_number, task_id: record.task_id },
2384
+ );
2385
+ }
2386
+
2387
+ const claim = claimTaskIssue(adapter, record, deps);
2388
+ record.labels.virtual = claim.labels;
2389
+ record.labels.current = claim.labels;
2390
+
2391
+ const worktree = ensureTaskWorktree(cwd, record, deps);
2392
+ const feedback = reviewFeedback(adapter, record);
2393
+ const attempts = [];
2394
+ let executorResult = null;
2395
+ let validation = null;
2396
+ let changedFiles = [];
2397
+ let executorEvidence = null;
2398
+ let previousFindings = null;
2399
+ const retryBudget = deps.retryBudget ?? DEFAULT_EXECUTOR_RETRY_BUDGET;
2400
+
2401
+ for (let attempt = 0; attempt <= retryBudget; attempt += 1) {
2402
+ const context = executorContext(record, worktree, feedback, previousFindings);
2403
+ executorResult = runTaskExecutor(context, deps);
2404
+ changedFiles = listChangedFiles(worktree, deps);
2405
+ validation = validateTask(worktree.path, record, changedFiles, deps);
2406
+ attempts.push({
2407
+ attempt: attempt + 1,
2408
+ executor: executorResult,
2409
+ changed_files: changedFiles,
2410
+ validation,
2411
+ });
2412
+ if (validation.ok) break;
2413
+ previousFindings = validation.failed;
2414
+ }
2415
+
2416
+ executorEvidence = validateExecutorEvidence(worktree, executorResult, deps);
2417
+ if (!executorEvidence.ok) {
2418
+ const issue_update = markExecutorEvidenceFailedWithoutPr(adapter, record, validation, executorEvidence);
2419
+ return {
2420
+ action: 'validation_failed_no_pr',
2421
+ claim,
2422
+ worktree,
2423
+ review_feedback: feedback,
2424
+ attempts,
2425
+ changed_files: changedFiles,
2426
+ validation,
2427
+ executor_evidence: executorEvidence,
2428
+ useful_changes: false,
2429
+ pushed: null,
2430
+ pr: null,
2431
+ issue_update,
2432
+ };
2433
+ }
2434
+
2435
+ const pushed = pushTaskBranch(worktree, deps);
2436
+ const ready = validation.ok;
2437
+ const pr = openOrUpdatePullRequest(adapter, record, worktree, validation, executorResult, ready);
2438
+ const issue_update = finalizeIssueAfterPr(adapter, record, pr, validation, ready);
2439
+
2440
+ return {
2441
+ action: ready ? 'ready_pr_opened_or_updated' : 'draft_pr_opened_or_updated',
2442
+ claim,
2443
+ worktree,
2444
+ review_feedback: feedback,
2445
+ attempts,
2446
+ changed_files: changedFiles,
2447
+ validation,
2448
+ executor_evidence: executorEvidence,
2449
+ useful_changes: true,
2450
+ pushed,
2451
+ pr,
2452
+ issue_update,
2453
+ };
2454
+ }
2455
+
2456
+ function ensureReconciliationWorktree(cwd, record, deps = {}) {
2457
+ if (deps.ensureReconciliationWorktree) return deps.ensureReconciliationWorktree({ cwd, record });
2458
+
2459
+ const branch = record.branch_name || reconciliationBranchName(record.plan_id, record.issue_number);
2460
+ const root = deps.worktreeRoot || defaultWorktreeRoot(cwd);
2461
+ const worktreePath = path.join(root, safeWorktreeLeaf(branch));
2462
+ fs.mkdirSync(root, { recursive: true });
2463
+
2464
+ const baseRef = defaultBranchRef(cwd);
2465
+ const existing = worktreeForBranch(cwd, branch);
2466
+ if (existing) {
2467
+ const status = runGit(existing.path, ['status', '--porcelain']).stdout;
2468
+ if (status) {
2469
+ throw new TaskExecutionError(`Reconciliation worktree ${existing.path} has uncommitted changes.`, 'dirty_reconciliation_worktree', { path: existing.path });
2470
+ }
2471
+ const rebase = runGit(existing.path, ['rebase', baseRef], { allowFailure: true });
2472
+ if (!rebase.ok) {
2473
+ runGit(existing.path, ['rebase', '--abort'], { allowFailure: true });
2474
+ throw new TaskExecutionError(`Could not rebase ${branch} onto ${baseRef}: ${rebase.stderr}`, 'reconciliation_branch_rebase_conflict');
2475
+ }
2476
+ return {
2477
+ path: existing.path,
2478
+ branch,
2479
+ base_ref: baseRef,
2480
+ reused: true,
2481
+ };
2482
+ }
2483
+
2484
+ if (fs.existsSync(worktreePath)) {
2485
+ throw new TaskExecutionError(`Reconciliation worktree path already exists without matching branch: ${worktreePath}`, 'worktree_path_collision', { path: worktreePath });
2486
+ }
2487
+
2488
+ if (branchExists(cwd, branch)) {
2489
+ runGit(cwd, ['worktree', 'add', worktreePath, branch]);
2490
+ const rebase = runGit(worktreePath, ['rebase', baseRef], { allowFailure: true });
2491
+ if (!rebase.ok) {
2492
+ runGit(worktreePath, ['rebase', '--abort'], { allowFailure: true });
2493
+ throw new TaskExecutionError(`Could not rebase ${branch} onto ${baseRef}: ${rebase.stderr}`, 'reconciliation_branch_rebase_conflict');
2494
+ }
2495
+ } else {
2496
+ runGit(cwd, ['worktree', 'add', '-b', branch, worktreePath, baseRef]);
2497
+ }
2498
+
2499
+ return {
2500
+ path: worktreePath,
2501
+ branch,
2502
+ base_ref: baseRef,
2503
+ reused: false,
2504
+ };
2505
+ }
2506
+
2507
+ function runPlanVerification(worktreePath, record, deps = {}) {
2508
+ if (deps.runPlanVerification) return deps.runPlanVerification(worktreePath, record);
2509
+ const declaredVerification = String(record.plan.verification || '').trim();
2510
+ if (isResolvedCheckpointOnlyPlan(record)) {
2511
+ return {
2512
+ ok: true,
2513
+ skipped: true,
2514
+ skip_reason: 'resolved_human_checkpoint_only_plan',
2515
+ command: '',
2516
+ declared_verification: declaredVerification,
2517
+ status: 0,
2518
+ stdout: '',
2519
+ stderr: '',
2520
+ };
2521
+ }
2522
+ const command = declaredVerification;
2523
+ if (!command) {
2524
+ return {
2525
+ ok: true,
2526
+ skipped: true,
2527
+ skip_reason: 'no_plan_verification_declared',
2528
+ command: '',
2529
+ declared_verification: '',
2530
+ status: 0,
2531
+ stdout: '',
2532
+ stderr: '',
2533
+ };
2534
+ }
2535
+ const result = runShellCommand(command, worktreePath, deps);
2536
+ return {
2537
+ ok: result.status === 0,
2538
+ skipped: false,
2539
+ command,
2540
+ declared_verification: command,
2541
+ status: result.status,
2542
+ stdout: String(result.stdout || '').trim(),
2543
+ stderr: String(result.stderr || result.error || '').trim(),
2544
+ };
2545
+ }
2546
+
2547
+ function isResolvedCheckpointOnlyPlan(record) {
2548
+ const tasks = record?.tasks || [];
2549
+ return tasks.length > 0 &&
2550
+ tasks.every((task) => isCheckpointTask(task) && isResolvedCheckpointTask(task));
2551
+ }
2552
+
2553
+ function singleLine(text) {
2554
+ return String(text || '').replace(/\s+/g, ' ').trim();
2555
+ }
2556
+
2557
+ function verificationCommandDisplay(verification) {
2558
+ if (verification.skipped && verification.skip_reason === 'resolved_human_checkpoint_only_plan') {
2559
+ return 'not run (resolved human checkpoint-only plan)';
2560
+ }
2561
+ return verification.command ? `\`${verification.command}\`` : 'not declared';
2562
+ }
2563
+
2564
+ function appendVerificationDetails(lines, verification) {
2565
+ lines.push(
2566
+ `- Command: ${verificationCommandDisplay(verification)}`,
2567
+ `- Result: ${verification.ok ? 'passed' : 'failed'}`,
2568
+ );
2569
+
2570
+ const declared = singleLine(verification.declared_verification);
2571
+ if (declared && declared !== verification.command) {
2572
+ lines.push(`- Declared verification: ${declared}`);
2573
+ }
2574
+
2575
+ if (verification.skipped && verification.skip_reason === 'resolved_human_checkpoint_only_plan') {
2576
+ lines.push('- Note: resolved checkpoint issue closure satisfied plan verification.');
2577
+ } else if (verification.skipped) {
2578
+ lines.push('- Note: no plan-level verification command was declared.');
2579
+ }
2580
+ }
2581
+
2582
+ function yamlInlineArray(items) {
2583
+ const values = (items || []).map((item) => String(item).trim()).filter(Boolean);
2584
+ if (values.length === 0) return '[]';
2585
+ return `[${values.join(', ')}]`;
2586
+ }
2587
+
2588
+ function mergedPrRefs(record) {
2589
+ return record.tasks.flatMap((task) =>
2590
+ task.linked_prs.merged.map((pr) => ({
2591
+ task_id: task.task_id,
2592
+ issue: task.issue_number,
2593
+ pr: pr.number || null,
2594
+ url: pr.url || null,
2595
+ merged_at: pr.mergedAt || null,
2596
+ })),
2597
+ );
2598
+ }
2599
+
2600
+ function renderReconciliationSummary(record, verification, deps = {}) {
2601
+ const completed = (deps.now ? deps.now() : new Date()).toISOString().split('T')[0];
2602
+ const taskCount = record.tasks.length;
2603
+ const prs = mergedPrRefs(record);
2604
+ const requirements = record.plan.requirements || [];
2605
+ const phase = record.scope.phase.phaseNumber || record.scope.phase.phaseSlug;
2606
+ const planPart = String(record.plan_id).split('-').slice(1).join('-') || record.plan_id;
2607
+ const title = `Phase ${phase} Plan ${planPart}: Issue-Driven Task Reconciliation Summary`;
2608
+ const lines = [
2609
+ '---',
2610
+ `phase: ${record.scope.phase.phaseSlug}`,
2611
+ `plan: ${record.plan_id}`,
2612
+ 'subsystem: issue-driven-task-execution',
2613
+ 'tags: [github-issues, task-reconciliation]',
2614
+ 'requires: []',
2615
+ 'provides: []',
2616
+ 'affects: []',
2617
+ 'tech-stack:',
2618
+ ' added: []',
2619
+ ' patterns: []',
2620
+ 'key-files:',
2621
+ ' created: []',
2622
+ ' modified: []',
2623
+ 'key-decisions: []',
2624
+ `requirements-completed: ${yamlInlineArray(requirements)}`,
2625
+ 'duration: issue-driven',
2626
+ `completed: ${completed}`,
2627
+ '---',
2628
+ '',
2629
+ `# ${title}`,
2630
+ '',
2631
+ `Completed parent plan \`${record.plan_id}\` through exported GitHub task issues.`,
2632
+ '',
2633
+ '## Execution Summary',
2634
+ '',
2635
+ `- Parent issue: #${record.issue_number}`,
2636
+ `- Source plan: \`${sourcePathForPlan(record.plan)}\``,
2637
+ `- Tasks reconciled: ${taskCount}`,
2638
+ `- Requirements completed: ${requirements.length ? requirements.map((req) => `\`${req}\``).join(', ') : 'none declared'}`,
2639
+ '',
2640
+ '## Child Task Evidence',
2641
+ '',
2642
+ ];
2643
+ if (prs.length === 0) {
2644
+ lines.push('- No merged child task PRs were detected.');
2645
+ } else {
2646
+ for (const pr of prs) {
2647
+ const link = pr.url ? `[PR #${pr.pr}](${pr.url})` : `PR #${pr.pr || 'unknown'}`;
2648
+ lines.push(`- \`${pr.task_id}\` via task issue #${pr.issue}: ${link}`);
2649
+ }
2650
+ }
2651
+ lines.push(
2652
+ '',
2653
+ '## Plan Verification',
2654
+ '',
2655
+ );
2656
+ appendVerificationDetails(lines, verification);
2657
+ if (verification.stdout) lines.push('', '### Stdout', '', '```text', verification.stdout, '```');
2658
+ if (verification.stderr) lines.push('', '### Stderr', '', '```text', verification.stderr, '```');
2659
+ lines.push(
2660
+ '',
2661
+ '## Issues Encountered',
2662
+ '',
2663
+ 'None.',
2664
+ '',
2665
+ '## Next',
2666
+ '',
2667
+ 'Plan reconciliation complete. Continue with phase completion when every plan in this phase has a summary.',
2668
+ '',
2669
+ );
2670
+ return lines.join('\n');
2671
+ }
2672
+
2673
+ function writeReconciliationSummary(worktreePath, record, verification, deps = {}) {
2674
+ const relPath = summaryPathForPlan(record.plan);
2675
+ const absPath = path.join(worktreePath, relPath);
2676
+ fs.mkdirSync(path.dirname(absPath), { recursive: true });
2677
+ const content = renderReconciliationSummary(record, verification, deps);
2678
+ fs.writeFileSync(absPath, `${content.replace(/\s+$/g, '')}\n`, 'utf8');
2679
+ return {
2680
+ path: relPath,
2681
+ bytes: Buffer.byteLength(content, 'utf8'),
2682
+ };
2683
+ }
2684
+
2685
+ function runGtdSdkQuery(worktreePath, args, deps = {}) {
2686
+ if (deps.runGtdSdkQuery) return deps.runGtdSdkQuery(args, worktreePath);
2687
+ const sdkPath = path.resolve(__dirname, '..', '..', '..', 'bin', 'gtd-sdk.js');
2688
+ const useLocalShim = fs.existsSync(sdkPath);
2689
+ const result = childProcess.spawnSync(useLocalShim ? process.execPath : 'gtd-sdk', useLocalShim ? [sdkPath, 'query', ...args] : ['query', ...args], {
2690
+ cwd: worktreePath,
2691
+ encoding: 'utf8',
2692
+ stdio: ['ignore', 'pipe', 'pipe'],
2693
+ env: process.env,
2694
+ });
2695
+ return {
2696
+ ok: result.status === 0,
2697
+ status: result.status,
2698
+ command: ['gtd-sdk', 'query', ...args].join(' '),
2699
+ stdout: String(result.stdout || '').trim(),
2700
+ stderr: String(result.stderr || result.error || '').trim(),
2701
+ };
2702
+ }
2703
+
2704
+ function requireSdkOk(result) {
2705
+ if (result?.ok) return result;
2706
+ throw new TaskExecutionError(result?.stderr || `${result?.command || 'gtd-sdk query'} failed`, 'canonical_state_update_failed', result);
2707
+ }
2708
+
2709
+ function updateCanonicalPlanState(worktreePath, record, deps = {}) {
2710
+ const phase = record.scope.phase.phaseNumber || record.scope.phase.phaseSlug;
2711
+ const planPart = String(record.plan_id).split('-').slice(1).join('-') || record.plan_id;
2712
+ const operations = [];
2713
+ const run = (args) => {
2714
+ const result = runGtdSdkQuery(worktreePath, args, deps);
2715
+ operations.push(result);
2716
+ requireSdkOk(result);
2717
+ };
2718
+
2719
+ run(['state.advance-plan']);
2720
+ run(['state.update-progress']);
2721
+ run([
2722
+ 'state.record-metric',
2723
+ '--phase',
2724
+ String(phase),
2725
+ '--plan',
2726
+ String(planPart),
2727
+ '--duration',
2728
+ 'issue-driven',
2729
+ '--tasks',
2730
+ String(record.tasks.length),
2731
+ '--files',
2732
+ '0',
2733
+ ]);
2734
+ run(['roadmap.update-plan-progress', String(phase)]);
2735
+ if (record.plan.requirements?.length) {
2736
+ run(['requirements.mark-complete', ...record.plan.requirements]);
2737
+ }
2738
+ run([
2739
+ 'state.record-session',
2740
+ '--stopped-at',
2741
+ `Completed ${record.plan_id}-PLAN.md via issue-driven reconciliation`,
2742
+ '--resume-file',
2743
+ 'None',
2744
+ ]);
2745
+
2746
+ return operations;
2747
+ }
2748
+
2749
+ function commitReconciliationArtifacts(worktree, record, summary, deps = {}) {
2750
+ if (deps.commitReconciliationArtifacts) return deps.commitReconciliationArtifacts(worktree, record, summary);
2751
+ const candidates = [
2752
+ summary.path,
2753
+ '.planning/STATE.md',
2754
+ '.planning/ROADMAP.md',
2755
+ '.planning/REQUIREMENTS.md',
2756
+ ].filter((relPath) => fs.existsSync(path.join(worktree.path, relPath)));
2757
+ runGit(worktree.path, ['add', ...candidates]);
2758
+ const status = runGit(worktree.path, ['status', '--porcelain']).stdout;
2759
+ if (!status) {
2760
+ return {
2761
+ committed: false,
2762
+ pushed: false,
2763
+ files: candidates,
2764
+ message: 'No reconciliation artifact changes to commit.',
2765
+ };
2766
+ }
2767
+ const message = `Reconcile GTD plan ${record.plan_id}`;
2768
+ runGit(worktree.path, ['commit', '-m', message]);
2769
+ runGit(worktree.path, ['push', '--set-upstream', 'origin', worktree.branch]);
2770
+ return {
2771
+ committed: true,
2772
+ pushed: true,
2773
+ files: candidates,
2774
+ message,
2775
+ };
2776
+ }
2777
+
2778
+ function reconciliationPrBody(record, summary, verification) {
2779
+ const lines = [
2780
+ `## GTD Plan Reconciliation`,
2781
+ '',
2782
+ `- Parent issue: #${record.issue_number}`,
2783
+ `- Plan ID: \`${record.plan_id}\``,
2784
+ `- Source plan: \`${sourcePathForPlan(record.plan)}\``,
2785
+ `- Summary: \`${summary.path}\``,
2786
+ '',
2787
+ '## Child Task Evidence',
2788
+ '',
2789
+ ];
2790
+ for (const task of record.tasks) {
2791
+ const prs = task.linked_prs.merged.map((pr) => pr.url || `#${pr.number}`).join(', ') || 'none';
2792
+ lines.push(`- \`${task.task_id}\`: Refs #${task.issue_number}; merged PRs ${prs}`);
2793
+ }
2794
+ lines.push(
2795
+ '',
2796
+ '## Verification',
2797
+ '',
2798
+ );
2799
+ appendVerificationDetails(lines, verification);
2800
+ lines.push('', `Closes #${record.issue_number}`);
2801
+ return lines.join('\n');
2802
+ }
2803
+
2804
+ function openReconciliationPullRequest(adapter, record, worktree, summary, verification) {
2805
+ if (!adapter || typeof adapter.createPullRequest !== 'function') {
2806
+ throw new TaskExecutionError('GitHub PR creation is unavailable.', 'github_pr_unavailable');
2807
+ }
2808
+ return callWrite(`create_reconciliation_pull_request:${worktree.branch}`, () => adapter.createPullRequest({
2809
+ title: `[GTD ${record.plan_id}] Reconcile completed task issues`,
2810
+ body: reconciliationPrBody(record, summary, verification),
2811
+ head: worktree.branch,
2812
+ base: worktree.base_ref.replace(/^origin\//, ''),
2813
+ draft: false,
2814
+ labels: [],
2815
+ }));
2816
+ }
2817
+
2818
+ function markReconciliationFailed(adapter, record, verification) {
2819
+ const labels = mergeLabelSet(record.labels.virtual, ['gtd:reconcile-failed'], [
2820
+ 'gtd:ready-for-reconcile',
2821
+ 'gtd:reconcile-pr-open',
2822
+ 'gtd:ready',
2823
+ ]);
2824
+ setIssueLabels(adapter, record.issue_number, labels);
2825
+ commentIssue(adapter, record.issue_number, [
2826
+ 'Parent plan reconciliation failed plan-level verification. Canonical GTD state was not updated.',
2827
+ '',
2828
+ `Command: ${verification.command ? `\`${verification.command}\`` : 'not declared'}`,
2829
+ `Status: ${verification.status}`,
2830
+ verification.stderr ? `\nStderr:\n\n\`\`\`text\n${verification.stderr}\n\`\`\`` : '',
2831
+ verification.stdout ? `\nStdout:\n\n\`\`\`text\n${verification.stdout}\n\`\`\`` : '',
2832
+ ].filter(Boolean).join('\n'));
2833
+ return {
2834
+ labels,
2835
+ comment_posted: true,
2836
+ };
2837
+ }
2838
+
2839
+ function finalizeReconciliationIssue(adapter, record, pr) {
2840
+ const labels = mergeLabelSet(record.labels.virtual, ['gtd:reconcile-pr-open'], [
2841
+ 'gtd:ready-for-reconcile',
2842
+ 'gtd:reconcile-failed',
2843
+ 'gtd:ready',
2844
+ 'gtd:blocked',
2845
+ ]);
2846
+ setIssueLabels(adapter, record.issue_number, labels);
2847
+ commentIssue(adapter, record.issue_number, [
2848
+ 'Parent plan reconciliation PR opened.',
2849
+ '',
2850
+ `PR: ${pr.url || `#${pr.number}`}`,
2851
+ '',
2852
+ 'Canonical GTD artifacts will be considered complete after this PR is merged and synced.',
2853
+ ].join('\n'));
2854
+ return {
2855
+ labels,
2856
+ comment_posted: true,
2857
+ };
2858
+ }
2859
+
2860
+ function executeReconciliationRecord(cwd, record, adapter, deps = {}) {
2861
+ if (!record.reconciliation.ready) {
2862
+ return {
2863
+ action: 'reconciliation_not_ready',
2864
+ reasons: record.reconciliation.reasons,
2865
+ };
2866
+ }
2867
+ const worktree = ensureReconciliationWorktree(cwd, record, deps);
2868
+ const verification = runPlanVerification(worktree.path, record, deps);
2869
+ if (!verification.ok) {
2870
+ const issue_update = markReconciliationFailed(adapter, record, verification);
2871
+ return {
2872
+ action: 'reconciliation_verification_failed',
2873
+ worktree,
2874
+ verification,
2875
+ summary: null,
2876
+ canonical_state: [],
2877
+ commit: null,
2878
+ pr: null,
2879
+ issue_update,
2880
+ };
2881
+ }
2882
+
2883
+ const summary = writeReconciliationSummary(worktree.path, record, verification, deps);
2884
+ const canonicalState = updateCanonicalPlanState(worktree.path, record, deps);
2885
+ const commit = commitReconciliationArtifacts(worktree, record, summary, deps);
2886
+ const pr = openReconciliationPullRequest(adapter, record, worktree, summary, verification);
2887
+ const issue_update = finalizeReconciliationIssue(adapter, record, pr);
2888
+
2889
+ return {
2890
+ action: 'reconciliation_pr_opened',
2891
+ worktree,
2892
+ verification,
2893
+ summary,
2894
+ canonical_state: canonicalState,
2895
+ commit,
2896
+ pr,
2897
+ issue_update,
2898
+ };
2899
+ }
2900
+
2901
+ function resolveReconciliationSelection(selector, records) {
2902
+ if (selector.mode === 'explicit') {
2903
+ const matches = resolveExplicitParent(selector, records.parents, records.tasks);
2904
+ if (matches.length === 1) {
2905
+ const record = matches[0];
2906
+ if (record.kind === 'resolution_error') return { kind: 'unresolved', record };
2907
+ return { kind: 'reconciliation', record };
2908
+ }
2909
+ if (matches.length > 1) {
2910
+ return {
2911
+ kind: 'unresolved',
2912
+ record: {
2913
+ kind: 'resolution_error',
2914
+ reconciliation: {
2915
+ ready: false,
2916
+ permission_required: false,
2917
+ reasons: [{
2918
+ code: 'selector_ambiguous',
2919
+ message: `Selector ${selector.raw} resolved to multiple parent plan issues: ${matches.map((parent) => `#${parent.issue_number}`).join(', ')}.`,
2920
+ }],
2921
+ },
2922
+ },
2923
+ };
2924
+ }
2925
+ return {
2926
+ kind: 'unresolved',
2927
+ record: {
2928
+ kind: 'resolution_error',
2929
+ reconciliation: {
2930
+ ready: false,
2931
+ permission_required: false,
2932
+ reasons: [{
2933
+ code: 'selector_not_found',
2934
+ message: `Selector ${selector.raw} did not match any exported parent plan issue in the loaded manifest scope.`,
2935
+ }],
2936
+ },
2937
+ },
2938
+ };
2939
+ }
2940
+ const ready = records.parents.filter((parent) => parent.reconciliation.ready).sort(compareParents)[0];
2941
+ if (ready) return { kind: 'reconciliation', record: ready };
2942
+ return { kind: 'none', record: null };
2943
+ }
2944
+
2945
+ function phaseSummaryStatus(cwd, phaseArg) {
2946
+ const source = loadExportSource(cwd, { phase: phaseArg });
2947
+ const plans = source.plans.map((plan) => {
2948
+ const summary = summaryPathForPlan(plan);
2949
+ return {
2950
+ plan_id: plan.id,
2951
+ source_path: sourcePathForPlan(plan),
2952
+ summary_path: summary,
2953
+ summary_exists: fs.existsSync(path.join(cwd, summary)),
2954
+ };
2955
+ });
2956
+ return {
2957
+ phase: source.phase.phaseSlug,
2958
+ phase_number: source.phase.phaseNumber,
2959
+ manifest: source.manifest.path,
2960
+ plan_count: plans.length,
2961
+ summary_count: plans.filter((plan) => plan.summary_exists).length,
2962
+ plans,
2963
+ missing_summaries: plans.filter((plan) => !plan.summary_exists),
2964
+ };
2965
+ }
2966
+
2967
+ function buildCompletePhaseTail(cwd, opts, deps = {}) {
2968
+ const status = phaseSummaryStatus(cwd, opts.completePhase);
2969
+ const ready = status.missing_summaries.length === 0 && status.plan_count > 0;
2970
+ const phaseRef = status.phase_number || status.phase;
2971
+ const finalizationCommand = `${formatGtdSlashFor(cwd, 'work-task-issue')} --complete-phase ${phaseRef} --execute`;
2972
+ const base = {
2973
+ ok: true,
2974
+ version: 1,
2975
+ mode: opts.mode || 'read-only',
2976
+ writes: false,
2977
+ implementation: false,
2978
+ pr_creation: false,
2979
+ action: null,
2980
+ phase_completion: {
2981
+ ready,
2982
+ ...status,
2983
+ finalization_command: finalizationCommand,
2984
+ finalization_scope: 'post_phase_gates_only',
2985
+ required_gates: [
2986
+ 'code-review',
2987
+ 'regression',
2988
+ 'schema-drift',
2989
+ 'codebase-drift',
2990
+ 'gtd-verifier',
2991
+ 'phase.complete',
2992
+ ],
2993
+ next_verify_work_command: ready
2994
+ ? `${formatGtdSlashFor(cwd, 'verify-work')} ${phaseRef}`
2995
+ : null,
2996
+ },
2997
+ };
2998
+
2999
+ if (!ready) {
3000
+ return {
3001
+ ...base,
3002
+ action: 'phase_completion_blocked_missing_summaries',
3003
+ };
3004
+ }
3005
+ if (opts.mode !== 'execute') {
3006
+ return {
3007
+ ...base,
3008
+ action: 'preview_phase_completion_finalization',
3009
+ };
3010
+ }
3011
+ const runFinalization = deps.runPhaseFinalization || deps.runPhaseCompletionTail;
3012
+ if (runFinalization) {
3013
+ const execution = runFinalization(cwd, {
3014
+ ...status,
3015
+ finalization_command: finalizationCommand,
3016
+ finalization_scope: 'post_phase_gates_only',
3017
+ required_gates: base.phase_completion.required_gates,
3018
+ });
3019
+ return {
3020
+ ...base,
3021
+ writes: Boolean(execution?.writes),
3022
+ action: execution?.action || 'phase_completion_finalization_executed',
3023
+ execution,
3024
+ };
3025
+ }
3026
+ return {
3027
+ ...base,
3028
+ action: 'phase_completion_finalization_requires_workflow_gates',
3029
+ note: `Continue through ${finalizationCommand}; this path runs only post-phase finalization gates and does not rerun implementation tasks.`,
3030
+ };
3031
+ }
3032
+
3033
+ function buildExecution(cwd, opts, adapterOrFactory = null, deps = {}) {
3034
+ if (opts.completePhase) return buildCompletePhaseTail(cwd, opts, deps);
3035
+ const state = loadExecutionState(cwd, opts, adapterOrFactory);
3036
+ const allRecords = [...state.records.parents, ...state.records.tasks];
3037
+ const readErrors = allRecords.flatMap((record) => record.errors.map((err) => ({
3038
+ issue: record.issue_number,
3039
+ operation: err.operation,
3040
+ message: err.message,
3041
+ })));
3042
+ const labelSync = applyStateSync(state.records, state.adapterForRepo, cwd);
3043
+ const selection = opts.reconcile
3044
+ ? resolveReconciliationSelection(state.selector, state.records)
3045
+ : resolveExecutionSelection(state.selector, state.records);
3046
+ const reconciliation = {
3047
+ ready: false,
3048
+ permission_required: false,
3049
+ plans: state.records.parents.filter((parent) => parent.reconciliation.ready).map(parentOutput),
3050
+ };
3051
+
3052
+ const base = {
3053
+ ok: true,
3054
+ version: 1,
3055
+ mode: 'execute',
3056
+ writes: true,
3057
+ implementation: false,
3058
+ pr_creation: false,
3059
+ selector: state.selector,
3060
+ scope: state.scopes.map((scope) => ({
3061
+ repo: scope.repo,
3062
+ phase: scope.phase.phaseSlug,
3063
+ phase_number: scope.phase.phaseNumber,
3064
+ manifest: scope.manifest.path,
3065
+ })),
3066
+ preflight: {
3067
+ ok: readErrors.length === 0,
3068
+ checked_parent_plans: state.records.parents.length,
3069
+ checked_tasks: state.records.tasks.length,
3070
+ label_sync: labelSync,
3071
+ errors: readErrors,
3072
+ },
3073
+ reconciliation,
3074
+ blocking_state: null,
3075
+ selected: null,
3076
+ execution: null,
3077
+ action: null,
3078
+ };
3079
+
3080
+ if (selection.kind === 'task') {
3081
+ const record = selection.record;
3082
+ base.selected = taskOutput(record);
3083
+ if (!record.workability.workable) {
3084
+ base.action = 'report_unworkable_task';
3085
+ return base;
3086
+ }
3087
+ const adapter = state.adapterForRepo(record.scope.repo);
3088
+ base.execution = executeTaskRecord(cwd, record, adapter, deps);
3089
+ base.implementation = true;
3090
+ base.pr_creation = Boolean(base.execution.pr);
3091
+ base.action = base.execution.action;
3092
+ return base;
3093
+ }
3094
+
3095
+ if (selection.kind === 'reconciliation') {
3096
+ const record = selection.record;
3097
+ base.selected = parentOutput(record);
3098
+ base.reconciliation = {
3099
+ ready: record.reconciliation.ready,
3100
+ permission_required: false,
3101
+ plans: [base.selected],
3102
+ };
3103
+ if (!record.reconciliation.ready) {
3104
+ base.action = 'report_unworkable_reconciliation';
3105
+ return base;
3106
+ }
3107
+ const adapter = state.adapterForRepo(record.scope.repo);
3108
+ base.execution = executeReconciliationRecord(cwd, record, adapter, deps);
3109
+ base.implementation = false;
3110
+ base.pr_creation = Boolean(base.execution.pr);
3111
+ base.action = base.execution.action;
3112
+ return base;
3113
+ }
3114
+
3115
+ if (selection.kind === 'reconciliation_permission') {
3116
+ const selected = parentOutput(selection.record);
3117
+ base.selected = selected;
3118
+ base.action = 'request_reconciliation_permission';
3119
+ base.reconciliation = {
3120
+ ready: true,
3121
+ permission_required: true,
3122
+ plans: [selected],
3123
+ };
3124
+ return base;
3125
+ }
3126
+
3127
+ if (selection.kind === 'unresolved') {
3128
+ base.selected = opts.reconcile ? parentOutput(selection.record) : taskOutput(selection.record);
3129
+ base.action = 'report_unresolved_selector';
3130
+ return base;
3131
+ }
3132
+
3133
+ base.action = 'report_blocking_state';
3134
+ base.blocking_state = blockingStateOutput(state.records.tasks, state.records.parents);
3135
+ return base;
3136
+ }
3137
+
3138
+ class GhCliTaskIssueAdapter {
3139
+ constructor({ cwd, repo }) {
3140
+ this.cwd = cwd;
3141
+ this.repo = repo;
3142
+ }
3143
+
3144
+ runGh(args, input = null, operation = null, allow404 = false) {
3145
+ return runGhCommand({
3146
+ cwd: this.cwd,
3147
+ args,
3148
+ input,
3149
+ operation,
3150
+ allow404,
3151
+ ErrorClass: GitHubTaskIssueError,
3152
+ missingGhMessage: 'GitHub CLI `gh` was not found; install and authenticate gh before running work-task-issue.',
3153
+ });
3154
+ }
3155
+
3156
+ api(method, endpoint, body = null, operation = null, allow404 = false) {
3157
+ return ghApi({
3158
+ cwd: this.cwd,
3159
+ repo: this.repo,
3160
+ method,
3161
+ endpoint,
3162
+ body,
3163
+ operation,
3164
+ allow404,
3165
+ ErrorClass: GitHubTaskIssueError,
3166
+ missingGhMessage: 'GitHub CLI `gh` was not found; install and authenticate gh before running work-task-issue.',
3167
+ });
3168
+ }
3169
+
3170
+ repoEndpoint(suffix) {
3171
+ return ghRepoEndpoint(this.repo, suffix);
3172
+ }
3173
+
3174
+ getIssue(number) {
3175
+ return this.api('GET', this.repoEndpoint(`issues/${number}`), null, `get_issue:${number}`, true);
3176
+ }
3177
+
3178
+ setIssueLabels(number, labels) {
3179
+ return this.api('PATCH', this.repoEndpoint(`issues/${number}`), { labels }, `set_issue_labels:${number}`);
3180
+ }
3181
+
3182
+ updateIssueState(number, state) {
3183
+ return this.api('PATCH', this.repoEndpoint(`issues/${number}`), { state }, `update_issue_state:${number}:${state}`);
3184
+ }
3185
+
3186
+ commentIssue(number, body) {
3187
+ return this.api('POST', this.repoEndpoint(`issues/${number}/comments`), { body }, `comment_issue:${number}`);
3188
+ }
3189
+
3190
+ listBlockedBy(issueNumber) {
3191
+ return this.api('GET', this.repoEndpoint(`issues/${issueNumber}/dependencies/blocked_by?per_page=100`), null, `list_blocked_by:${issueNumber}`);
3192
+ }
3193
+
3194
+ listPullRequestsForIssue(issueNumber, branchName) {
3195
+ const fields = 'number,title,state,isDraft,mergedAt,headRefName,url,reviewDecision,body';
3196
+ const queries = [
3197
+ `Closes #${issueNumber}`,
3198
+ `Fixes #${issueNumber}`,
3199
+ `Resolves #${issueNumber}`,
3200
+ branchName ? `head:${branchName}` : null,
3201
+ ].filter(Boolean);
3202
+ const prs = [];
3203
+
3204
+ for (const query of queries) {
3205
+ const stdout = this.runGh([
3206
+ 'pr',
3207
+ 'list',
3208
+ '--repo',
3209
+ this.repo,
3210
+ '--state',
3211
+ 'all',
3212
+ '--limit',
3213
+ '50',
3214
+ '--search',
3215
+ query,
3216
+ '--json',
3217
+ fields,
3218
+ ], null, `list_pull_requests_for_issue:${issueNumber}`);
3219
+ const parsed = stdout ? JSON.parse(stdout) : [];
3220
+ for (const pr of parsed) {
3221
+ const body = String(pr.body || '');
3222
+ if (
3223
+ pr.headRefName === branchName ||
3224
+ body.includes(`#${issueNumber}`) ||
3225
+ body.includes(`/${issueNumber}`)
3226
+ ) {
3227
+ prs.push(pr);
3228
+ }
3229
+ }
3230
+ }
3231
+
3232
+ return dedupePrs(prs);
3233
+ }
3234
+
3235
+ listPullRequestFeedback(prNumber) {
3236
+ const stdout = this.runGh([
3237
+ 'pr',
3238
+ 'view',
3239
+ String(prNumber),
3240
+ '--repo',
3241
+ this.repo,
3242
+ '--comments',
3243
+ '--json',
3244
+ 'comments,reviews',
3245
+ ], null, `list_pull_request_feedback:${prNumber}`);
3246
+ const parsed = stdout ? JSON.parse(stdout) : {};
3247
+ const comments = (parsed.comments || []).map((comment) => ({
3248
+ kind: 'comment',
3249
+ author: comment.author?.login || null,
3250
+ body: comment.body || '',
3251
+ createdAt: comment.createdAt || null,
3252
+ }));
3253
+ const reviews = (parsed.reviews || []).map((review) => ({
3254
+ kind: 'review',
3255
+ author: review.author?.login || null,
3256
+ state: review.state || null,
3257
+ body: review.body || '',
3258
+ submittedAt: review.submittedAt || null,
3259
+ }));
3260
+ const reviewComments = this.api(
3261
+ 'GET',
3262
+ this.repoEndpoint(`pulls/${prNumber}/comments?per_page=100`),
3263
+ null,
3264
+ `list_pull_request_review_comments:${prNumber}`,
3265
+ true,
3266
+ ) || [];
3267
+ return [
3268
+ ...comments,
3269
+ ...reviews,
3270
+ ...reviewComments.map((comment) => ({
3271
+ kind: 'review_comment',
3272
+ author: comment.user?.login || null,
3273
+ body: comment.body || '',
3274
+ path: comment.path || null,
3275
+ line: comment.line || comment.original_line || null,
3276
+ createdAt: comment.created_at || null,
3277
+ })),
3278
+ ];
3279
+ }
3280
+
3281
+ viewPullRequest(numberOrUrl) {
3282
+ const stdout = this.runGh([
3283
+ 'pr',
3284
+ 'view',
3285
+ String(numberOrUrl),
3286
+ '--repo',
3287
+ this.repo,
3288
+ '--json',
3289
+ 'number,title,state,isDraft,mergedAt,headRefName,baseRefName,url,reviewDecision,body',
3290
+ ], null, `view_pull_request:${numberOrUrl}`);
3291
+ return stdout ? normalizePr(JSON.parse(stdout)) : null;
3292
+ }
3293
+
3294
+ listPullRequestCommits(prNumber) {
3295
+ const stdout = this.runGh([
3296
+ 'pr',
3297
+ 'view',
3298
+ String(prNumber),
3299
+ '--repo',
3300
+ this.repo,
3301
+ '--json',
3302
+ 'commits',
3303
+ ], null, `list_pull_request_commits:${prNumber}`);
3304
+ const parsed = stdout ? JSON.parse(stdout) : {};
3305
+ return (parsed.commits || []).map((commit) => ({
3306
+ oid: commit.oid || commit.sha || null,
3307
+ messageHeadline: commit.messageHeadline || '',
3308
+ messageBody: commit.messageBody || '',
3309
+ authors: commit.authors || [],
3310
+ }));
3311
+ }
3312
+
3313
+ listPullRequestChecks(prNumber) {
3314
+ const stdout = this.runGh([
3315
+ 'pr',
3316
+ 'view',
3317
+ String(prNumber),
3318
+ '--repo',
3319
+ this.repo,
3320
+ '--json',
3321
+ 'statusCheckRollup',
3322
+ ], null, `list_pull_request_checks:${prNumber}`);
3323
+ const parsed = stdout ? JSON.parse(stdout) : {};
3324
+ return (parsed.statusCheckRollup || []).map((check) => ({
3325
+ name: check.name || check.context || '',
3326
+ status: check.status || '',
3327
+ conclusion: check.conclusion || '',
3328
+ state: check.state || '',
3329
+ }));
3330
+ }
3331
+
3332
+ createPullRequest({ title, body, head, base, draft, labels }) {
3333
+ return withTemporaryPrBodyFile(body, (bodyFile) => {
3334
+ const args = [
3335
+ 'pr',
3336
+ 'create',
3337
+ '--repo',
3338
+ this.repo,
3339
+ '--base',
3340
+ base,
3341
+ '--head',
3342
+ head,
3343
+ '--title',
3344
+ title,
3345
+ '--body-file',
3346
+ bodyFile,
3347
+ ];
3348
+ if (draft) args.push('--draft');
3349
+ for (const label of labels || []) args.push('--label', label);
3350
+ const url = this.runGh(args, null, `create_pull_request:${head}`);
3351
+ return this.viewPullRequest(url);
3352
+ });
3353
+ }
3354
+
3355
+ updatePullRequest(number, { title, body, draft, labels }) {
3356
+ withTemporaryPrBodyFile(body, (bodyFile) => {
3357
+ const args = [
3358
+ 'pr',
3359
+ 'edit',
3360
+ String(number),
3361
+ '--repo',
3362
+ this.repo,
3363
+ '--title',
3364
+ title,
3365
+ '--body-file',
3366
+ bodyFile,
3367
+ ];
3368
+ for (const label of labels || []) args.push('--add-label', label);
3369
+ this.runGh(args, null, `update_pull_request:${number}`);
3370
+ });
3371
+ if (draft === false) {
3372
+ this.runGh(['pr', 'ready', String(number), '--repo', this.repo], null, `mark_pull_request_ready:${number}`, true);
3373
+ }
3374
+ return this.viewPullRequest(number);
3375
+ }
3376
+
3377
+ reopenPullRequest(number) {
3378
+ this.runGh(['pr', 'reopen', String(number), '--repo', this.repo], null, `reopen_pull_request:${number}`);
3379
+ return this.viewPullRequest(number);
3380
+ }
3381
+
3382
+ mergePullRequest(number, { method = 'squash', subject = null, body = null } = {}) {
3383
+ const args = [
3384
+ 'pr',
3385
+ 'merge',
3386
+ String(number),
3387
+ '--repo',
3388
+ this.repo,
3389
+ ];
3390
+ if (method === 'squash') args.push('--squash');
3391
+ else if (method === 'merge') args.push('--merge');
3392
+ else if (method === 'rebase') args.push('--rebase');
3393
+ if (subject) args.push('--subject', subject);
3394
+ if (body) args.push('--body', body);
3395
+ this.runGh(args, null, `merge_pull_request:${number}`);
3396
+ return this.viewPullRequest(number);
3397
+ }
3398
+ }
3399
+
3400
+ function cmdWorkTaskIssue(cwd, args, raw) {
3401
+ const opts = parseArgs(args);
3402
+ try {
3403
+ output(opts.mode === 'execute' ? buildExecution(cwd, opts) : buildReadOnly(cwd, opts), raw);
3404
+ } catch (err) {
3405
+ error(err.message || String(err), ERROR_REASON.UNKNOWN);
3406
+ }
3407
+ }
3408
+
3409
+ export {
3410
+ buildExecution,
3411
+ buildReadOnly,
3412
+ cmdWorkTaskIssue,
3413
+ GhCliTaskIssueAdapter,
3414
+ GitHubTaskIssueError,
3415
+ TaskExecutionError,
3416
+ executorContext,
3417
+ executeReconciliationRecord,
3418
+ loadExecutionState,
3419
+ taskOutput,
3420
+ parentOutput,
3421
+ compareRecords,
3422
+ resolveExplicitParent,
3423
+ buildCompletePhaseTail,
3424
+ validateDiffScope,
3425
+ validateExecutorEvidence,
3426
+ validateTask,
3427
+ parseArgs,
3428
+ parseSelector,
3429
+ };