okstra 0.174.0 → 0.176.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 (419) hide show
  1. package/README.md +18 -9
  2. package/bin/okstra +8 -4
  3. package/dist/cli-registry.d.mts +16 -0
  4. package/dist/cli-registry.mjs +560 -0
  5. package/dist/cli-registry.mjs.map +1 -0
  6. package/dist/commands/execute/agent-prompt.d.mts +1 -0
  7. package/{src → dist}/commands/execute/agent-prompt.mjs +10 -11
  8. package/dist/commands/execute/agent-prompt.mjs.map +1 -0
  9. package/dist/commands/execute/codex-dispatch.d.mts +3 -0
  10. package/dist/commands/execute/codex-dispatch.mjs +6 -0
  11. package/dist/commands/execute/codex-dispatch.mjs.map +1 -0
  12. package/dist/commands/execute/codex-run.d.mts +3 -0
  13. package/{src → dist}/commands/execute/codex-run.mjs +30 -37
  14. package/dist/commands/execute/codex-run.mjs.map +1 -0
  15. package/dist/commands/execute/convergence.d.mts +1 -0
  16. package/{src → dist}/commands/execute/convergence.mjs +15 -16
  17. package/dist/commands/execute/convergence.mjs.map +1 -0
  18. package/dist/commands/execute/error-log.d.mts +1 -0
  19. package/{src → dist}/commands/execute/error-log.mjs +2 -3
  20. package/dist/commands/execute/error-log.mjs.map +1 -0
  21. package/dist/commands/execute/git-reconcile.d.mts +1 -0
  22. package/{src → dist}/commands/execute/git-reconcile.mjs +10 -11
  23. package/dist/commands/execute/git-reconcile.mjs.map +1 -0
  24. package/dist/commands/execute/handoff.d.mts +1 -0
  25. package/{src → dist}/commands/execute/handoff.mjs +10 -11
  26. package/dist/commands/execute/handoff.mjs.map +1 -0
  27. package/dist/commands/execute/incremental-carry.d.mts +1 -0
  28. package/{src → dist}/commands/execute/incremental-carry.mjs +2 -3
  29. package/dist/commands/execute/incremental-carry.mjs.map +1 -0
  30. package/dist/commands/execute/incremental-scope.d.mts +1 -0
  31. package/{src → dist}/commands/execute/incremental-scope.mjs +2 -3
  32. package/dist/commands/execute/incremental-scope.mjs.map +1 -0
  33. package/dist/commands/execute/integrate-stages.d.mts +1 -0
  34. package/{src → dist}/commands/execute/integrate-stages.mjs +10 -11
  35. package/dist/commands/execute/integrate-stages.mjs.map +1 -0
  36. package/dist/commands/execute/pane-title.d.mts +1 -0
  37. package/dist/commands/execute/pane-title.mjs +20 -0
  38. package/dist/commands/execute/pane-title.mjs.map +1 -0
  39. package/dist/commands/execute/plan-items.d.mts +1 -0
  40. package/dist/commands/execute/plan-items.mjs +9 -0
  41. package/dist/commands/execute/plan-items.mjs.map +1 -0
  42. package/dist/commands/execute/plan-validate.d.mts +1 -0
  43. package/dist/commands/execute/plan-validate.mjs +68 -0
  44. package/dist/commands/execute/plan-validate.mjs.map +1 -0
  45. package/dist/commands/execute/plan-verify.d.mts +1 -0
  46. package/{src → dist}/commands/execute/plan-verify.mjs +13 -16
  47. package/dist/commands/execute/plan-verify.mjs.map +1 -0
  48. package/dist/commands/execute/render-bundle.d.mts +3 -0
  49. package/{src → dist}/commands/execute/render-bundle.mjs +65 -61
  50. package/dist/commands/execute/render-bundle.mjs.map +1 -0
  51. package/dist/commands/execute/run.d.mts +24 -0
  52. package/dist/commands/execute/run.mjs +196 -0
  53. package/dist/commands/execute/run.mjs.map +1 -0
  54. package/dist/commands/execute/spawn-followups.d.mts +1 -0
  55. package/{src → dist}/commands/execute/spawn-followups.mjs +6 -7
  56. package/dist/commands/execute/spawn-followups.mjs.map +1 -0
  57. package/dist/commands/execute/team.d.mts +3 -0
  58. package/{src → dist}/commands/execute/team.mjs +29 -36
  59. package/dist/commands/execute/team.mjs.map +1 -0
  60. package/dist/commands/execute/token-usage.d.mts +1 -0
  61. package/{src → dist}/commands/execute/token-usage.mjs +2 -3
  62. package/dist/commands/execute/token-usage.mjs.map +1 -0
  63. package/dist/commands/execute/wizard.d.mts +8 -0
  64. package/dist/commands/execute/wizard.mjs +191 -0
  65. package/dist/commands/execute/wizard.mjs.map +1 -0
  66. package/dist/commands/execute/worker-audit-check.d.mts +1 -0
  67. package/{src → dist}/commands/execute/worker-audit-check.mjs +11 -12
  68. package/dist/commands/execute/worker-audit-check.mjs.map +1 -0
  69. package/dist/commands/execute/worker-dispatch.d.mts +7 -0
  70. package/{src → dist}/commands/execute/worker-dispatch.mjs +34 -46
  71. package/dist/commands/execute/worker-dispatch.mjs.map +1 -0
  72. package/dist/commands/execute/worker-state.d.mts +1 -0
  73. package/{src → dist}/commands/execute/worker-state.mjs +15 -16
  74. package/dist/commands/execute/worker-state.mjs.map +1 -0
  75. package/dist/commands/execute/worktree-lookup.d.mts +1 -0
  76. package/{src → dist}/commands/execute/worktree-lookup.mjs +38 -37
  77. package/dist/commands/execute/worktree-lookup.mjs.map +1 -0
  78. package/dist/commands/execute/worktree-status.d.mts +1 -0
  79. package/{src → dist}/commands/execute/worktree-status.mjs +52 -46
  80. package/dist/commands/execute/worktree-status.mjs.map +1 -0
  81. package/dist/commands/inspect/code-review.d.mts +1 -0
  82. package/{src → dist}/commands/inspect/code-review.mjs +16 -19
  83. package/dist/commands/inspect/code-review.mjs.map +1 -0
  84. package/dist/commands/inspect/container.d.mts +1 -0
  85. package/{src → dist}/commands/inspect/container.mjs +11 -13
  86. package/dist/commands/inspect/container.mjs.map +1 -0
  87. package/dist/commands/inspect/context-cost.d.mts +1 -0
  88. package/{src → dist}/commands/inspect/context-cost.mjs +11 -13
  89. package/dist/commands/inspect/context-cost.mjs.map +1 -0
  90. package/dist/commands/inspect/design-prep.d.mts +1 -0
  91. package/{src → dist}/commands/inspect/design-prep.mjs +10 -11
  92. package/dist/commands/inspect/design-prep.mjs.map +1 -0
  93. package/dist/commands/inspect/error-report.d.mts +1 -0
  94. package/{src → dist}/commands/inspect/error-report.mjs +11 -13
  95. package/dist/commands/inspect/error-report.mjs.map +1 -0
  96. package/dist/commands/inspect/error-zip.d.mts +1 -0
  97. package/{src → dist}/commands/inspect/error-zip.mjs +11 -12
  98. package/dist/commands/inspect/error-zip.mjs.map +1 -0
  99. package/dist/commands/inspect/log-report.d.mts +1 -0
  100. package/{src → dist}/commands/inspect/log-report.mjs +11 -13
  101. package/dist/commands/inspect/log-report.mjs.map +1 -0
  102. package/dist/commands/inspect/profile-show.d.mts +1 -0
  103. package/{src → dist}/commands/inspect/profile-show.mjs +10 -11
  104. package/dist/commands/inspect/profile-show.mjs.map +1 -0
  105. package/dist/commands/inspect/recap.d.mts +1 -0
  106. package/{src → dist}/commands/inspect/recap.mjs +11 -13
  107. package/dist/commands/inspect/recap.mjs.map +1 -0
  108. package/dist/commands/inspect/resolve-task-key.d.mts +1 -0
  109. package/{src → dist}/commands/inspect/resolve-task-key.mjs +11 -13
  110. package/dist/commands/inspect/resolve-task-key.mjs.map +1 -0
  111. package/dist/commands/inspect/rollup.d.mts +1 -0
  112. package/{src → dist}/commands/inspect/rollup.mjs +11 -13
  113. package/dist/commands/inspect/rollup.mjs.map +1 -0
  114. package/dist/commands/inspect/run-audit.d.mts +1 -0
  115. package/{src → dist}/commands/inspect/run-audit.mjs +11 -12
  116. package/dist/commands/inspect/run-audit.mjs.map +1 -0
  117. package/dist/commands/inspect/set-work-status.d.mts +1 -0
  118. package/{src → dist}/commands/inspect/set-work-status.mjs +11 -13
  119. package/dist/commands/inspect/set-work-status.mjs.map +1 -0
  120. package/dist/commands/inspect/stage-map.d.mts +1 -0
  121. package/dist/commands/inspect/stage-map.mjs +110 -0
  122. package/dist/commands/inspect/stage-map.mjs.map +1 -0
  123. package/dist/commands/inspect/task-list.d.mts +1 -0
  124. package/dist/commands/inspect/task-list.mjs +103 -0
  125. package/dist/commands/inspect/task-list.mjs.map +1 -0
  126. package/dist/commands/inspect/task-show.d.mts +1 -0
  127. package/dist/commands/inspect/task-show.mjs +108 -0
  128. package/dist/commands/inspect/task-show.mjs.map +1 -0
  129. package/dist/commands/inspect/time-report.d.mts +1 -0
  130. package/{src → dist}/commands/inspect/time-report.mjs +11 -13
  131. package/dist/commands/inspect/time-report.mjs.map +1 -0
  132. package/dist/commands/inspect/usage-report.d.mts +1 -0
  133. package/{src → dist}/commands/inspect/usage-report.mjs +11 -13
  134. package/dist/commands/inspect/usage-report.mjs.map +1 -0
  135. package/dist/commands/inspect/user-response.d.mts +1 -0
  136. package/{src → dist}/commands/inspect/user-response.mjs +10 -11
  137. package/dist/commands/inspect/user-response.mjs.map +1 -0
  138. package/dist/commands/inspect/worker-liveness.d.mts +1 -0
  139. package/{src → dist}/commands/inspect/worker-liveness.mjs +11 -13
  140. package/dist/commands/inspect/worker-liveness.mjs.map +1 -0
  141. package/dist/commands/lifecycle/check-project.d.mts +21 -0
  142. package/dist/commands/lifecycle/check-project.mjs +175 -0
  143. package/dist/commands/lifecycle/check-project.mjs.map +1 -0
  144. package/dist/commands/lifecycle/config.d.mts +1 -0
  145. package/dist/commands/lifecycle/config.mjs +369 -0
  146. package/dist/commands/lifecycle/config.mjs.map +1 -0
  147. package/dist/commands/lifecycle/doctor.d.mts +10 -0
  148. package/dist/commands/lifecycle/doctor.mjs +317 -0
  149. package/dist/commands/lifecycle/doctor.mjs.map +1 -0
  150. package/dist/commands/lifecycle/install.d.mts +17 -0
  151. package/dist/commands/lifecycle/install.mjs +1077 -0
  152. package/dist/commands/lifecycle/install.mjs.map +1 -0
  153. package/dist/commands/lifecycle/migrate.d.mts +1 -0
  154. package/{src → dist}/commands/lifecycle/migrate.mjs +10 -11
  155. package/dist/commands/lifecycle/migrate.mjs.map +1 -0
  156. package/dist/commands/lifecycle/model.d.mts +1 -0
  157. package/dist/commands/lifecycle/model.mjs +22 -0
  158. package/dist/commands/lifecycle/model.mjs.map +1 -0
  159. package/dist/commands/lifecycle/paths.d.mts +1 -0
  160. package/dist/commands/lifecycle/paths.mjs +102 -0
  161. package/dist/commands/lifecycle/paths.mjs.map +1 -0
  162. package/dist/commands/lifecycle/preflight.d.mts +1 -0
  163. package/dist/commands/lifecycle/preflight.mjs +124 -0
  164. package/dist/commands/lifecycle/preflight.mjs.map +1 -0
  165. package/dist/commands/lifecycle/setup.d.mts +1 -0
  166. package/dist/commands/lifecycle/setup.mjs +297 -0
  167. package/dist/commands/lifecycle/setup.mjs.map +1 -0
  168. package/dist/commands/lifecycle/uninstall.d.mts +4 -0
  169. package/dist/commands/lifecycle/uninstall.mjs +262 -0
  170. package/dist/commands/lifecycle/uninstall.mjs.map +1 -0
  171. package/dist/commands/manager.d.mts +3 -0
  172. package/{src → dist}/commands/manager.mjs +25 -32
  173. package/dist/commands/manager.mjs.map +1 -0
  174. package/dist/commands/memory/memory.d.mts +1 -0
  175. package/dist/commands/memory/memory.mjs +569 -0
  176. package/dist/commands/memory/memory.mjs.map +1 -0
  177. package/dist/commands/pr/pr.d.mts +33 -0
  178. package/dist/commands/pr/pr.mjs +296 -0
  179. package/dist/commands/pr/pr.mjs.map +1 -0
  180. package/dist/commands/report/agent-activity.d.mts +1 -0
  181. package/{src → dist}/commands/report/agent-activity.mjs +11 -12
  182. package/dist/commands/report/agent-activity.mjs.map +1 -0
  183. package/dist/commands/report/finalize.d.mts +4 -0
  184. package/{src → dist}/commands/report/finalize.mjs +25 -32
  185. package/dist/commands/report/finalize.mjs.map +1 -0
  186. package/dist/commands/report/inject-report-index.d.mts +1 -0
  187. package/{src → dist}/commands/report/inject-report-index.mjs +6 -7
  188. package/dist/commands/report/inject-report-index.mjs.map +1 -0
  189. package/dist/commands/report/render-final-report.d.mts +1 -0
  190. package/{src → dist}/commands/report/render-final-report.mjs +6 -7
  191. package/dist/commands/report/render-final-report.mjs.map +1 -0
  192. package/dist/commands/report/render-views.d.mts +1 -0
  193. package/{src → dist}/commands/report/render-views.mjs +6 -7
  194. package/dist/commands/report/render-views.mjs.map +1 -0
  195. package/dist/commands/report/translate.d.mts +1 -0
  196. package/{src → dist}/commands/report/translate.mjs +6 -7
  197. package/dist/commands/report/translate.mjs.map +1 -0
  198. package/dist/lib/helper-scripts.d.mts +3 -0
  199. package/{src → dist}/lib/helper-scripts.mjs +11 -14
  200. package/dist/lib/helper-scripts.mjs.map +1 -0
  201. package/dist/lib/host-registry-client.d.mts +25 -0
  202. package/dist/lib/host-registry-client.mjs +152 -0
  203. package/dist/lib/host-registry-client.mjs.map +1 -0
  204. package/dist/lib/install-assets.d.mts +8 -0
  205. package/{src → dist}/lib/install-assets.mjs +17 -20
  206. package/dist/lib/install-assets.mjs.map +1 -0
  207. package/dist/lib/okstra-dirs.d.mts +4 -0
  208. package/{src → dist}/lib/okstra-dirs.mjs +3 -6
  209. package/dist/lib/okstra-dirs.mjs.map +1 -0
  210. package/dist/lib/paths.d.mts +4 -0
  211. package/dist/lib/paths.mjs +78 -0
  212. package/dist/lib/paths.mjs.map +1 -0
  213. package/dist/lib/proc.d.mts +3 -0
  214. package/dist/lib/proc.mjs +31 -0
  215. package/dist/lib/proc.mjs.map +1 -0
  216. package/dist/lib/python-helper.d.mts +8 -0
  217. package/dist/lib/python-helper.mjs +123 -0
  218. package/dist/lib/python-helper.mjs.map +1 -0
  219. package/dist/lib/runtime-manifest.d.mts +7 -0
  220. package/dist/lib/runtime-manifest.mjs +73 -0
  221. package/dist/lib/runtime-manifest.mjs.map +1 -0
  222. package/dist/lib/skill-catalog.d.mts +4 -0
  223. package/dist/lib/skill-catalog.mjs +50 -0
  224. package/dist/lib/skill-catalog.mjs.map +1 -0
  225. package/dist/lib/types.d.mts +129 -0
  226. package/dist/lib/types.mjs +2 -0
  227. package/dist/lib/types.mjs.map +1 -0
  228. package/dist/lib/version.d.mts +2 -0
  229. package/dist/lib/version.mjs +27 -0
  230. package/dist/lib/version.mjs.map +1 -0
  231. package/docs/architecture/storage-model.md +6 -2
  232. package/docs/architecture.md +29 -20
  233. package/docs/cli.md +40 -16
  234. package/docs/contributor-change-matrix.md +2 -2
  235. package/docs/for-ai/skills/okstra-inspect.md +2 -3
  236. package/docs/for-ai/skills/okstra-rollup.md +1 -0
  237. package/docs/project-structure-overview.md +72 -62
  238. package/docs/task-process/README.md +12 -8
  239. package/docs/task-process/common-flow.md +13 -16
  240. package/docs/task-process/error-analysis.md +9 -10
  241. package/docs/task-process/final-verification.md +7 -7
  242. package/docs/task-process/implementation-planning.md +9 -9
  243. package/docs/task-process/implementation.md +6 -6
  244. package/docs/task-process/release-handoff.md +8 -7
  245. package/docs/task-process/requirements-discovery.md +8 -8
  246. package/package.json +11 -5
  247. package/runtime/BUILD.json +2 -2
  248. package/runtime/agents/workers/claude-worker.md +2 -1
  249. package/runtime/agents/workers/report-writer-worker.md +3 -1
  250. package/runtime/agents/workers/translator-worker.md +3 -1
  251. package/runtime/bin/lib/okstra/cli.sh +12 -0
  252. package/runtime/bin/lib/okstra/globals.sh +3 -0
  253. package/runtime/bin/lib/okstra/interactive.sh +12 -6
  254. package/runtime/bin/lib/okstra/usage.sh +7 -6
  255. package/runtime/bin/okstra-error-log.py +27 -0
  256. package/runtime/bin/okstra-provider-exec.py +217 -5
  257. package/runtime/bin/okstra-spawn-followups.py +4 -2
  258. package/runtime/bin/okstra.sh +10 -0
  259. package/runtime/prompts/launch.template.md +2 -2
  260. package/runtime/prompts/lead/context-loader.md +1 -2
  261. package/runtime/prompts/lead/convergence.md +27 -18
  262. package/runtime/prompts/lead/okstra-lead-contract.md +6 -5
  263. package/runtime/prompts/lead/plan-body-verification.md +10 -3
  264. package/runtime/prompts/lead/report-writer.md +15 -1
  265. package/runtime/prompts/lead/team-contract.md +17 -13
  266. package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
  267. package/runtime/prompts/profiles/_implementation-executor.md +0 -3
  268. package/runtime/prompts/profiles/_implementation-verifier.md +3 -7
  269. package/runtime/prompts/profiles/change-impact-analysis.md +20 -0
  270. package/runtime/prompts/profiles/error-analysis.md +27 -1
  271. package/runtime/prompts/profiles/feature-analysis.md +20 -0
  272. package/runtime/prompts/profiles/final-verification.md +20 -1
  273. package/runtime/prompts/profiles/implementation-option-selection.md +20 -0
  274. package/runtime/prompts/profiles/implementation-planning.md +26 -0
  275. package/runtime/prompts/profiles/implementation.md +19 -0
  276. package/runtime/prompts/profiles/improvement-discovery.md +21 -1
  277. package/runtime/prompts/profiles/project-analysis.md +20 -0
  278. package/runtime/prompts/profiles/release-handoff.md +4 -0
  279. package/runtime/prompts/profiles/requirements-discovery.md +27 -1
  280. package/runtime/prompts/wizard/prompts.ko.json +35 -0
  281. package/runtime/python/okstra_ctl/adapters/dispatch/cli_wrapper.py +8 -0
  282. package/runtime/python/okstra_ctl/adapters/dispatch/cmux.py +8 -0
  283. package/runtime/python/okstra_ctl/adapters/dispatch/native_team.py +13 -0
  284. package/runtime/python/okstra_ctl/adapters/hosts/antigravity/adapter.py +2 -2
  285. package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +25 -5
  286. package/runtime/python/okstra_ctl/adapters/hosts/codex/adapter.py +2 -2
  287. package/runtime/python/okstra_ctl/adapters/hosts/external/adapter.py +4 -1
  288. package/runtime/python/okstra_ctl/adapters/hosts/grok/adapter.py +2 -2
  289. package/runtime/python/okstra_ctl/adapters/hosts/kimi/adapter.py +2 -2
  290. package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +79 -11
  291. package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +95 -25
  292. package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +59 -14
  293. package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +55 -9
  294. package/runtime/python/okstra_ctl/adapters/providers/kimi/adapter.py +51 -12
  295. package/runtime/python/okstra_ctl/adapters/runtime/__init__.py +1 -0
  296. package/runtime/python/okstra_ctl/adapters/runtime/assembly.py +27 -0
  297. package/runtime/python/okstra_ctl/adapters/runtime/cli_wrapper.py +49 -0
  298. package/runtime/python/okstra_ctl/adapters/runtime/cmux.py +74 -0
  299. package/runtime/python/okstra_ctl/agent_activity.py +5 -1
  300. package/runtime/python/okstra_ctl/agent_invocation.py +608 -14
  301. package/runtime/python/okstra_ctl/agent_prompt_cli.py +249 -50
  302. package/runtime/python/okstra_ctl/application/open_worker.py +29 -0
  303. package/runtime/python/okstra_ctl/application/resolve_assignment.py +53 -12
  304. package/runtime/python/okstra_ctl/assignment_environment.py +102 -0
  305. package/runtime/python/okstra_ctl/assignment_resolver.py +790 -0
  306. package/runtime/python/okstra_ctl/attempt_evidence.py +342 -0
  307. package/runtime/python/okstra_ctl/convergence.py +409 -3
  308. package/runtime/python/okstra_ctl/convergence_engine.py +248 -15
  309. package/runtime/python/okstra_ctl/convergence_store.py +170 -1
  310. package/runtime/python/okstra_ctl/dispatch_core.py +1204 -155
  311. package/runtime/python/okstra_ctl/dispatch_state.py +696 -11
  312. package/runtime/python/okstra_ctl/doctor.py +14 -0
  313. package/runtime/python/okstra_ctl/domain/host.py +34 -1
  314. package/runtime/python/okstra_ctl/domain/provider.py +212 -6
  315. package/runtime/python/okstra_ctl/domain/role.py +125 -0
  316. package/runtime/python/okstra_ctl/domain/wizard/interaction.py +18 -0
  317. package/runtime/python/okstra_ctl/domain/worker_exec.py +34 -1
  318. package/runtime/python/okstra_ctl/domain/worker_role.py +13 -3
  319. package/runtime/python/okstra_ctl/domain/worker_runtime.py +44 -0
  320. package/runtime/python/okstra_ctl/domain/worker_stream.py +24 -0
  321. package/runtime/python/okstra_ctl/error_log_write.py +9 -0
  322. package/runtime/python/okstra_ctl/error_report.py +21 -1
  323. package/runtime/python/okstra_ctl/execution_identity.py +529 -0
  324. package/runtime/python/okstra_ctl/execution_manifest.py +1281 -0
  325. package/runtime/python/okstra_ctl/execution_mutation_audit.py +619 -0
  326. package/runtime/python/okstra_ctl/implementation_outcome.py +21 -5
  327. package/runtime/python/okstra_ctl/index.py +6 -2
  328. package/runtime/python/okstra_ctl/initial_prompt_materialization.py +43 -3
  329. package/runtime/python/okstra_ctl/legacy_model_selection.py +578 -0
  330. package/runtime/python/okstra_ctl/manager_sync.py +4 -1
  331. package/runtime/python/okstra_ctl/model_cli.py +278 -0
  332. package/runtime/python/okstra_ctl/model_defaults.py +46 -0
  333. package/runtime/python/okstra_ctl/model_discovery.py +26 -7
  334. package/runtime/python/okstra_ctl/model_pool.py +501 -0
  335. package/runtime/python/okstra_ctl/models.py +47 -27
  336. package/runtime/python/okstra_ctl/mutation_recovery.py +293 -0
  337. package/runtime/python/okstra_ctl/next_phase.py +236 -0
  338. package/runtime/python/okstra_ctl/pane_title.py +151 -0
  339. package/runtime/python/okstra_ctl/ports/host_model.py +48 -17
  340. package/runtime/python/okstra_ctl/ports/worker_dispatch.py +4 -0
  341. package/runtime/python/okstra_ctl/ports/worker_runtime.py +26 -0
  342. package/runtime/python/okstra_ctl/recap.py +4 -1
  343. package/runtime/python/okstra_ctl/registry/provider_registry.py +8 -4
  344. package/runtime/python/okstra_ctl/render.py +124 -57
  345. package/runtime/python/okstra_ctl/render_final_report.py +19 -0
  346. package/runtime/python/okstra_ctl/report_contract.py +39 -0
  347. package/runtime/python/okstra_ctl/report_finalize.py +16 -0
  348. package/runtime/python/okstra_ctl/report_html/render.py +1 -0
  349. package/runtime/python/okstra_ctl/role_requirements.py +210 -0
  350. package/runtime/python/okstra_ctl/rollup.py +4 -1
  351. package/runtime/python/okstra_ctl/run.py +1210 -258
  352. package/runtime/python/okstra_ctl/run_index_row.py +7 -1
  353. package/runtime/python/okstra_ctl/stage_fix_carry.py +17 -1
  354. package/runtime/python/okstra_ctl/team.py +14 -18
  355. package/runtime/python/okstra_ctl/time_report.py +38 -4
  356. package/runtime/python/okstra_ctl/usage_identity.py +86 -0
  357. package/runtime/python/okstra_ctl/usage_report.py +15 -3
  358. package/runtime/python/okstra_ctl/wizard.py +1449 -66
  359. package/runtime/python/okstra_ctl/worker_audit_ledger.py +68 -65
  360. package/runtime/python/okstra_ctl/worker_prompt_body.py +18 -2
  361. package/runtime/python/okstra_ctl/worker_prompt_contract.py +40 -9
  362. package/runtime/python/okstra_ctl/worker_prompt_headers.py +16 -1
  363. package/runtime/python/okstra_ctl/worker_request.py +7 -1
  364. package/runtime/python/okstra_ctl/worker_runner.py +130 -5
  365. package/runtime/python/okstra_ctl/workers.py +7 -5
  366. package/runtime/python/okstra_ctl/workflow.py +18 -32
  367. package/runtime/python/okstra_ctl/worktree.py +3 -3
  368. package/runtime/python/okstra_ctl/worktree_registry.py +5 -4
  369. package/runtime/python/okstra_ctl/write_policy.py +571 -0
  370. package/runtime/python/okstra_project/state.py +54 -6
  371. package/runtime/schemas/convergence-groups-v2.0.schema.json +128 -0
  372. package/runtime/schemas/execution-manifest-v2.schema.json +340 -0
  373. package/runtime/schemas/final-report-v2.0.schema.json +68 -5
  374. package/runtime/skills/okstra-inspect/facets/recap.md +2 -0
  375. package/runtime/skills/okstra-inspect/facets/report.md +1 -1
  376. package/runtime/skills/okstra-inspect/facets/status.md +15 -13
  377. package/runtime/skills/okstra-rollup/SKILL.md +1 -0
  378. package/runtime/skills/okstra-run/SKILL.md +14 -14
  379. package/runtime/templates/implementation-worker-preamble.md +3 -18
  380. package/runtime/templates/project-docs/task-index.template.md +0 -1
  381. package/runtime/templates/report-writer-prompt-preamble.md +2 -0
  382. package/runtime/templates/reports/final-report-v2.template.md +7 -1
  383. package/runtime/templates/reports/html/base.template.html +21 -0
  384. package/runtime/templates/reports/html/i18n/en.json +4 -0
  385. package/runtime/templates/reports/html/i18n/ko.json +4 -0
  386. package/runtime/templates/reports/html/macros/forms.html +5 -4
  387. package/runtime/templates/reports/html/tasks/final-verification.template.html +1 -1
  388. package/runtime/templates/reports/html/tasks/implementation.template.html +1 -1
  389. package/runtime/templates/worker-prompt-preamble.md +6 -35
  390. package/runtime/validators/lib/fixtures.sh +49 -16
  391. package/runtime/validators/validate-run.py +486 -134
  392. package/runtime/validators/validate_session_conformance.py +25 -7
  393. package/src/cli-registry.mjs +0 -539
  394. package/src/commands/execute/codex-dispatch.mjs +0 -10
  395. package/src/commands/execute/plan-items.mjs +0 -9
  396. package/src/commands/execute/plan-validate.mjs +0 -68
  397. package/src/commands/execute/run.mjs +0 -208
  398. package/src/commands/execute/wizard.mjs +0 -167
  399. package/src/commands/inspect/stage-map.mjs +0 -98
  400. package/src/commands/inspect/task-list.mjs +0 -97
  401. package/src/commands/inspect/task-show.mjs +0 -100
  402. package/src/commands/lifecycle/check-project.mjs +0 -187
  403. package/src/commands/lifecycle/config.mjs +0 -385
  404. package/src/commands/lifecycle/doctor.mjs +0 -308
  405. package/src/commands/lifecycle/install.mjs +0 -1170
  406. package/src/commands/lifecycle/paths.mjs +0 -104
  407. package/src/commands/lifecycle/preflight.mjs +0 -125
  408. package/src/commands/lifecycle/setup.mjs +0 -333
  409. package/src/commands/lifecycle/uninstall.mjs +0 -279
  410. package/src/commands/memory/memory.mjs +0 -524
  411. package/src/commands/pr/pr.mjs +0 -261
  412. package/src/lib/host-registry-client.mjs +0 -176
  413. package/src/lib/paths.mjs +0 -86
  414. package/src/lib/proc.mjs +0 -31
  415. package/src/lib/python-helper.mjs +0 -142
  416. package/src/lib/runtime-manifest.mjs +0 -70
  417. package/src/lib/skill-catalog.mjs +0 -53
  418. package/src/lib/version.mjs +0 -20
  419. /package/{src → dist}/commands/pr/default.md +0 -0
@@ -25,7 +25,9 @@ def build_run_index_row(*, project_id: str, project_root: str,
25
25
  run_seq: int, status: str, started_at: str,
26
26
  finished_at: Optional[str], workers: list, lead_model: str,
27
27
  validation: str, run_dir_rel: str,
28
- final_report_rel: str, final_status_rel: str) -> dict:
28
+ final_report_rel: str, final_status_rel: str,
29
+ execution_manifest_path: str = "",
30
+ role_execution_refs: list | None = None) -> dict:
29
31
  """slim run-index row(14필드)를 만든다. 파생 4필드는 포함하지 않는다."""
30
32
  return {
31
33
  "runId": build_run_id(project_id, task_group, task_id,
@@ -43,6 +45,10 @@ def build_run_index_row(*, project_id: str, project_root: str,
43
45
  "finalReportRel": final_report_rel,
44
46
  "finalStatusRel": final_status_rel,
45
47
  "runDirRel": run_dir_rel,
48
+ **({
49
+ "executionManifestPath": execution_manifest_path,
50
+ "roleExecutionRefs": list(role_execution_refs or []),
51
+ } if execution_manifest_path else {}),
46
52
  }
47
53
 
48
54
 
@@ -84,10 +84,26 @@ def derive_stage_fix_carry(
84
84
  str(row.get("discrepancy") or row.get("verifier") or "")
85
85
  for row in failed
86
86
  ],
87
- routing_recommendation=str(impl.get("routingRecommendation") or ""),
87
+ routing_recommendation=_routing_line(impl.get("routingRecommendation")),
88
88
  )
89
89
 
90
90
 
91
+ def _routing_line(value: object) -> str:
92
+ """구조체 라우팅을 캐리 프롬프트에 실을 한 줄로 편다.
93
+
94
+ 리포트의 `implementation.routingRecommendation` 은 `{target, rationale}`
95
+ 구조체다. dict 를 str() 로 강제하면 executor 프롬프트에 파이썬 dict repr 이
96
+ 그대로 실려 사람도 모델도 읽을 수 없는 줄이 된다.
97
+ """
98
+ if not isinstance(value, dict):
99
+ return ""
100
+ target = str(value.get("target") or "").strip()
101
+ rationale = str(value.get("rationale") or "").strip()
102
+ if target and rationale:
103
+ return f"{target} — {rationale}"
104
+ return target or rationale
105
+
106
+
91
107
  def _latest_report(stage_run_dir: Path) -> Path | None:
92
108
  reports_dir = stage_run_dir / "reports"
93
109
  if not reports_dir.is_dir():
@@ -163,10 +163,21 @@ def _teardown(args) -> int:
163
163
  if args.dry_run:
164
164
  _emit_teardown(args.json, panes)
165
165
  return 0
166
- if _is_cmux_run(manifest):
166
+ from .adapters.runtime.assembly import port_for, runtime_chain
167
+ from .domain.worker_runtime import RuntimeHandle, SURFACE_CMUX_PANE
168
+
169
+ chain = runtime_chain(_manifest_backend(manifest))
170
+ # cli-wrapper chains have no cmux port; leftover paneIds must not KeyError.
171
+ if panes and any(port.surface == SURFACE_CMUX_PANE for port in chain):
172
+ closer = port_for(chain, SURFACE_CMUX_PANE)
167
173
  for pane in panes:
168
- cmux.close_surface(pane["paneId"])
169
- _restore_lead_width()
174
+ closer.close(
175
+ RuntimeHandle(SURFACE_CMUX_PANE, pane["paneId"], False)
176
+ )
177
+ try:
178
+ chain[0].restore_lead()
179
+ except (OSError, subprocess.SubprocessError, RuntimeError) as exc:
180
+ print(f"okstra team: could not restore the lead's width: {exc}", file=sys.stderr)
170
181
  _mark_teardown_errors(team_state_path)
171
182
  _emit_teardown(args.json, panes)
172
183
  return 0
@@ -280,21 +291,6 @@ def _append_pane(panes: list[dict[str, str]], seen: set[str], pane_id: str, kind
280
291
  seen.add(pane_id)
281
292
 
282
293
 
283
- def _restore_lead_width() -> None:
284
- """Give the lead back the width the reclaimed panes left behind.
285
-
286
- Reported rather than raised: teardown's contract is to reclaim the run's
287
- panes and print what it reclaimed, and a failed resize must not cost the
288
- caller that record — the panes are already closed by the time this runs.
289
- Reported rather than swallowed, because a width failure nobody is told
290
- about is what left the lead at 18 columns unnoticed.
291
- """
292
- try:
293
- cmux.restore_lead_width()
294
- except (OSError, subprocess.SubprocessError, RuntimeError) as exc:
295
- print(f"okstra team: could not restore the lead's width: {exc}", file=sys.stderr)
296
-
297
-
298
294
  def _mark_teardown_errors(team_state_path: Path) -> None:
299
295
  def mark(payload: dict[str, Any]) -> bool:
300
296
  changed = False
@@ -19,6 +19,18 @@ from okstra_project import read_task_key
19
19
  from okstra_ctl.task_target import resolve_task_root
20
20
 
21
21
 
22
+ def time_rows_with_identity(run_root: Path) -> list[dict]:
23
+ """Project time rows from stored execution labels without reparsing them."""
24
+ from okstra_ctl.usage_identity import identity_rows_from_state
25
+
26
+ state_path = run_root / "state" / "team-state.json"
27
+ try:
28
+ state = json.loads(state_path.read_text(encoding="utf-8"))
29
+ except (OSError, ValueError):
30
+ return []
31
+ return identity_rows_from_state(state if isinstance(state, dict) else {})
32
+
33
+
22
34
  def load_runs(task_root: Path) -> tuple[list[dict], bool]:
23
35
  path = task_timeline_file(task_root)
24
36
  try:
@@ -98,14 +110,26 @@ def _collect_run(run: dict, project_root: Path) -> dict:
98
110
  state = _read_state(project_root, run.get("teamStatePath", ""))
99
111
  if state is None:
100
112
  return {**base, "reason": "team-state missing"}
113
+ from okstra_ctl.execution_identity import stored_identity
114
+ from okstra_ctl.usage_identity import identity_rows_from_state
115
+
101
116
  lead = _duration_ms(state.get("leadUsage"))
102
- workers = [{"workerId": w.get("workerId", ""), "agent": w.get("agent", ""),
103
- "durationMs": _duration_ms(w.get("usage"))}
104
- for w in (state.get("workers") or []) if isinstance(w, dict)]
117
+ workers = []
118
+ for worker in (state.get("workers") or []):
119
+ if not isinstance(worker, dict):
120
+ continue
121
+ row = {
122
+ "workerId": worker.get("workerId", ""),
123
+ "agent": worker.get("agent", ""),
124
+ "durationMs": _duration_ms(worker.get("usage")),
125
+ }
126
+ row.update(stored_identity(worker))
127
+ workers.append(row)
105
128
  if lead == 0 and all(w["durationMs"] == 0 for w in workers):
106
129
  return {**base, "reason": "no durationMs (Phase 7 not reached)"}
107
130
  return {**base, "leadMs": lead, "workers": workers,
108
- "wallClockMs": wall_clock_ms(state), "phases": _phase_rows(state)}
131
+ "wallClockMs": wall_clock_ms(state), "phases": _phase_rows(state),
132
+ "identityRows": identity_rows_from_state(state)}
109
133
 
110
134
 
111
135
  def _by_task_type(collected: list[dict]) -> list[dict]:
@@ -165,6 +189,15 @@ def aggregate_time(runs: list[dict], project_root: Path) -> dict:
165
189
  (unavailable if "reason" in c else collected).append(c)
166
190
  by_tt = _by_task_type(collected)
167
191
  grand = {k: sum(r[k] for r in by_tt) for k in ("runs", "leadMs", "workersMs", "cpuSumMs")}
192
+ identity_rows = []
193
+ seen: set[str] = set()
194
+ for collected_run in collected:
195
+ for row in collected_run.get("identityRows") or []:
196
+ key = str(row.get("roleExecutionRef") or row.get("executionLabel"))
197
+ if key in seen:
198
+ continue
199
+ seen.add(key)
200
+ identity_rows.append(row)
168
201
  return {
169
202
  "byTaskType": by_tt,
170
203
  "grandTotal": grand,
@@ -173,6 +206,7 @@ def aggregate_time(runs: list[dict], project_root: Path) -> dict:
173
206
  "wallClockMs": c["wallClockMs"]} for c in collected],
174
207
  "phaseTimelines": [{"runTimestamp": c["runTimestamp"], "taskType": c["taskType"],
175
208
  "phases": c["phases"]} for c in collected if c["phases"]],
209
+ "identityRows": identity_rows,
176
210
  "unavailable": unavailable,
177
211
  }
178
212
 
@@ -0,0 +1,86 @@
1
+ """Project usage rows from stored execution-identity refs."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from pathlib import Path
6
+ from collections.abc import Mapping
7
+ from typing import Any
8
+
9
+ from .execution_identity import (
10
+ ExecutionManifest,
11
+ execution_identity_for_ref,
12
+ stored_execution_label,
13
+ stored_identity,
14
+ )
15
+ from .execution_manifest import read_execution_manifest
16
+
17
+
18
+ def run_execution_manifest(run_root: Path) -> ExecutionManifest:
19
+ """Load the first run-manifest under ``run_root/manifests``."""
20
+ return read_execution_manifest(_manifest_path(run_root))
21
+
22
+
23
+ def identity_rows_from_state(state: Mapping[str, Any] | None) -> list[dict[str, Any]]:
24
+ """Collect stored identity rows from a team-state document."""
25
+ if not isinstance(state, Mapping):
26
+ return []
27
+ rows: list[dict[str, Any]] = []
28
+ seen: set[str] = set()
29
+ for collection in (
30
+ state.get("workers") or [],
31
+ state.get("workerDispatches") or [],
32
+ state.get("agentDispatches") or [],
33
+ ):
34
+ if not isinstance(collection, list):
35
+ continue
36
+ for item in collection:
37
+ ident = stored_identity(item if isinstance(item, Mapping) else None)
38
+ if not ident:
39
+ continue
40
+ key = str(ident.get("roleExecutionRef") or ident.get("executionLabel"))
41
+ if key in seen:
42
+ continue
43
+ seen.add(key)
44
+ rows.append(ident)
45
+ return rows
46
+
47
+
48
+ def collect_usage_rows(run_root: Path) -> list[dict[str, Any]]:
49
+ """Project usage rows with stored execution identity refs."""
50
+ manifest = run_execution_manifest(run_root)
51
+ team_state = _load_json(run_root / "state" / "team-state.json")
52
+ rows: list[dict[str, Any]] = []
53
+ for collection in (
54
+ team_state.get("workerDispatches") or [],
55
+ team_state.get("agentDispatches") or [],
56
+ ):
57
+ for item in collection:
58
+ if not isinstance(item, Mapping):
59
+ continue
60
+ rows.append(_usage_row(manifest, item))
61
+ return rows
62
+
63
+
64
+ def _usage_row(manifest: ExecutionManifest, item: Mapping[str, Any]) -> dict[str, Any]:
65
+ ref = str(item.get("roleExecutionRef") or "")
66
+ role = execution_identity_for_ref(manifest, ref)
67
+ return {
68
+ "participantRef": item.get("participantRef") or role.participant_ref,
69
+ "roleExecutionRef": role.role_execution_ref,
70
+ "invocationRef": item.get("invocationRef"),
71
+ "attempt": item.get("attempt", 1),
72
+ "executionLabel": stored_execution_label(
73
+ {"executionLabel": item.get("executionLabel") or role.execution_label}
74
+ ),
75
+ }
76
+
77
+
78
+ def _manifest_path(run_root: Path) -> Path:
79
+ manifests = run_root / "manifests"
80
+ for path in sorted(manifests.glob("*.json")):
81
+ return path
82
+ raise FileNotFoundError(f"no run manifest under {run_root}")
83
+
84
+
85
+ def _load_json(path: Path) -> dict[str, Any]:
86
+ return json.loads(path.read_text(encoding="utf-8"))
@@ -147,9 +147,13 @@ def _collect_usage(
147
147
  end_at: dt.datetime,
148
148
  unavailable: dict[str, int],
149
149
  warnings: dict[str, int],
150
- ) -> tuple[dict[str, dict], set[str], int, int]:
150
+ ) -> tuple[dict[str, dict], set[str], int, int, list[dict]]:
151
+ from okstra_ctl.usage_identity import identity_rows_from_state
152
+
151
153
  buckets: dict[str, dict] = {}
152
154
  unmatched_models: set[str] = set()
155
+ identity_rows: list[dict] = []
156
+ seen_identity: set[str] = set()
153
157
  total_runs = 0
154
158
  collected_runs = 0
155
159
  for entry in list_project_tasks(project_root):
@@ -173,6 +177,13 @@ def _collect_usage(
173
177
  total_runs += 1
174
178
  bucket["runs"] += 1
175
179
  metrics, reason = _run_metrics(run, project_root)
180
+ state = _read_state(project_root, str(run.get("teamStatePath") or ""))
181
+ for row in identity_rows_from_state(state):
182
+ key = str(row.get("roleExecutionRef") or row.get("executionLabel"))
183
+ if key in seen_identity:
184
+ continue
185
+ seen_identity.add(key)
186
+ identity_rows.append(row)
176
187
  if reason is not None:
177
188
  unavailable[reason] += 1
178
189
  continue
@@ -182,7 +193,7 @@ def _collect_usage(
182
193
  bucket[key] += metrics[key]
183
194
  bucket["costUsd"] += metrics["costUsd"]
184
195
  unmatched_models.update(metrics["unmatchedModels"])
185
- return buckets, unmatched_models, total_runs, collected_runs
196
+ return buckets, unmatched_models, total_runs, collected_runs, identity_rows
186
197
 
187
198
 
188
199
  def build_usage_report(project_root: Path, days: int, now: dt.datetime) -> dict:
@@ -196,7 +207,7 @@ def build_usage_report(project_root: Path, days: int, now: dt.datetime) -> dict:
196
207
  start_at = dt.datetime.min.replace(tzinfo=UTC)
197
208
  unavailable = {key: 0 for key in UNAVAILABLE_KEYS}
198
209
  warnings = {"missingOrInvalidTimelines": 0}
199
- buckets, unmatched_models, total_runs, collected_runs = _collect_usage(
210
+ buckets, unmatched_models, total_runs, collected_runs, identity_rows = _collect_usage(
200
211
  project_root, start_at, end_at, unavailable, warnings
201
212
  )
202
213
 
@@ -226,6 +237,7 @@ def build_usage_report(project_root: Path, days: int, now: dt.datetime) -> dict:
226
237
  "unavailable": unavailable,
227
238
  "warnings": warnings,
228
239
  "unmatchedModels": sorted(unmatched_models),
240
+ "identityRows": identity_rows,
229
241
  }
230
242
 
231
243