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
@@ -0,0 +1,278 @@
1
+ """List models and atomically write role defaults. No inference calls."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ import os
7
+ import tempfile
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ from okstra_project import project_json_path, resolve_project_root
12
+ from okstra_project.dirs import okstra_home
13
+
14
+ from .domain.provider import UnknownModelError
15
+ from .domain.role import RoleCatalogError, normalize_role
16
+ from .model_pool import ModelPool, ModelPoolValidationError
17
+ from .ports.host_model import HostModelBindingError, HostModelBindingRequest
18
+ from .registry.host_registry import default_host_registry
19
+ from .registry.provider_registry import default_provider_registry
20
+
21
+
22
+ class ModelCliError(ValueError):
23
+ """Raised when a model list or default write cannot be completed."""
24
+
25
+
26
+ def list_models(
27
+ *,
28
+ role: str | None,
29
+ host_runtime: str,
30
+ as_json: bool,
31
+ ) -> int:
32
+ wanted = normalize_role(role) if role else None
33
+ pool, adapter = _pool_and_host(host_runtime)
34
+ rows = [
35
+ _catalog_row(model, adapter, wanted)
36
+ for model in pool.list_catalog(role=wanted)
37
+ ]
38
+ if as_json:
39
+ print(json.dumps({"models": rows}, ensure_ascii=False))
40
+ return 0
41
+ for row in rows:
42
+ mark = "yes" if row["selectable"] else "no"
43
+ print(f"{row['modelRef']}\t{mark}\t{row['reason']}")
44
+ return 0
45
+
46
+
47
+ def set_model_default(
48
+ *,
49
+ role: str,
50
+ refs: tuple[str, ...],
51
+ scope: str,
52
+ cwd: Path,
53
+ ) -> int:
54
+ canonical = normalize_role(role)
55
+ if not refs or len(refs) != len(set(refs)):
56
+ raise ModelCliError("model defaults must be a unique non-empty list")
57
+ pool, _adapter = _pool_and_host("claude-code")
58
+ for ref in refs:
59
+ try:
60
+ availability = pool.availability(ref, canonical)
61
+ except UnknownModelError as exc:
62
+ raise ModelCliError(str(exc)) from exc
63
+ if not availability.available:
64
+ raise ModelCliError(
65
+ f"model {ref!r} cannot default role {canonical}: "
66
+ f"{availability.reason}"
67
+ )
68
+ path = _config_path(scope, cwd)
69
+ payload = _read_json(path)
70
+ defaults = dict(payload.get("modelDefaults") or {})
71
+ defaults[canonical] = list(refs)
72
+ payload["modelDefaults"] = defaults
73
+ _write_json_atomic(path, payload)
74
+ return 0
75
+
76
+
77
+ def unset_model_default(*, role: str, scope: str, cwd: Path) -> int:
78
+ canonical = normalize_role(role)
79
+ path = _config_path(scope, cwd)
80
+ payload = _read_json(path)
81
+ defaults = dict(payload.get("modelDefaults") or {})
82
+ defaults.pop(canonical, None)
83
+ payload["modelDefaults"] = defaults
84
+ _write_json_atomic(path, payload)
85
+ return 0
86
+
87
+
88
+ def model_diagnostics(
89
+ *,
90
+ host_runtime: str = "claude-code",
91
+ cwd: Path | None = None,
92
+ ) -> dict[str, Any]:
93
+ """Report pool and default issues without making an inference call."""
94
+ root = Path(cwd) if cwd is not None else Path.cwd()
95
+ try:
96
+ pool, adapter = _pool_and_host(host_runtime)
97
+ pool_errors: list[str] = []
98
+ except ModelPoolValidationError as exc:
99
+ return {
100
+ "poolErrors": [str(exc)],
101
+ "defaultErrors": [],
102
+ "bindingPrecision": "unknown",
103
+ "observedModel": None,
104
+ "maxWriteBoundary": "none",
105
+ "invocationDowngradeReason": None,
106
+ "inferenceCall": False,
107
+ }
108
+ default_errors = [
109
+ *_default_errors(pool, _try_project_json(root), "project"),
110
+ *_default_errors(pool, okstra_home() / "config.json", "global"),
111
+ ]
112
+ capability = adapter.worker_dispatch().worker_write_capability()
113
+ max_boundary = (
114
+ capability.max_boundary_precision if capability is not None else "none"
115
+ )
116
+ return {
117
+ "poolErrors": pool_errors,
118
+ "defaultErrors": default_errors,
119
+ "bindingPrecision": "channel" if host_runtime == "claude-code" else "exact",
120
+ "observedModel": None,
121
+ "maxWriteBoundary": max_boundary,
122
+ "invocationDowngradeReason": None,
123
+ "inferenceCall": False,
124
+ }
125
+
126
+
127
+ def _pool_and_host(host_runtime: str):
128
+ registry = default_provider_registry()
129
+ return ModelPool.from_registry(registry), default_host_registry(registry).resolve(
130
+ host_runtime
131
+ )
132
+
133
+
134
+ def _catalog_row(model, adapter, role: str | None) -> dict[str, Any]:
135
+ row = {
136
+ "modelRef": str(model.model_ref),
137
+ "provider": model.provider_id,
138
+ "displayName": model.display_name,
139
+ "selectable": bool(model.selectable),
140
+ "reason": "",
141
+ }
142
+ if not model.selectable:
143
+ row["reason"] = "not selectable"
144
+ return row
145
+ if role != "leader":
146
+ return row
147
+ if model.provider_id != adapter.descriptor.native_provider_id:
148
+ return row
149
+ try:
150
+ adapter.host_model().resolve(
151
+ HostModelBindingRequest(
152
+ host_runtime=adapter.descriptor.id,
153
+ provider=model.provider_id,
154
+ model_ref=str(model.model_ref),
155
+ version_kind=model.version_kind,
156
+ model_execution_value=model.execution_value,
157
+ runner="native-session",
158
+ )
159
+ )
160
+ except HostModelBindingError as exc:
161
+ row["selectable"] = False
162
+ row["reason"] = str(exc)
163
+ return row
164
+
165
+
166
+ def _default_errors(pool: ModelPool, path: Path, scope: str) -> list[str]:
167
+ if not path.is_file():
168
+ return []
169
+ payload = _read_json(path)
170
+ defaults = payload.get("modelDefaults")
171
+ if defaults is None:
172
+ return []
173
+ if not isinstance(defaults, dict):
174
+ return [f"{scope} modelDefaults must be an object"]
175
+ errors: list[str] = []
176
+ for role, refs in defaults.items():
177
+ try:
178
+ canonical = normalize_role(str(role))
179
+ except RoleCatalogError as exc:
180
+ errors.append(str(exc))
181
+ continue
182
+ if not isinstance(refs, list) or not refs:
183
+ errors.append(f"{scope} model defaults for {canonical!r} are empty")
184
+ continue
185
+ seen: set[str] = set()
186
+ for ref in refs:
187
+ token = str(ref)
188
+ if token in seen:
189
+ errors.append(f"{scope} duplicate model default {token}")
190
+ seen.add(token)
191
+ try:
192
+ availability = pool.availability(token, canonical)
193
+ except UnknownModelError as exc:
194
+ errors.append(str(exc))
195
+ continue
196
+ if not availability.available:
197
+ errors.append(
198
+ f"{scope} model {token!r} cannot default role {canonical}: "
199
+ f"{availability.reason}"
200
+ )
201
+ return errors
202
+
203
+
204
+ def _try_project_json(cwd: Path) -> Path:
205
+ try:
206
+ return project_json_path(resolve_project_root(cwd=str(cwd)))
207
+ except Exception:
208
+ return cwd / ".okstra" / "project.json"
209
+
210
+
211
+ def _config_path(scope: str, cwd: Path) -> Path:
212
+ if scope == "global":
213
+ return okstra_home() / "config.json"
214
+ return project_json_path(resolve_project_root(cwd=str(cwd)))
215
+
216
+
217
+ def _read_json(path: Path) -> dict[str, Any]:
218
+ if not path.is_file():
219
+ return {}
220
+ payload = json.loads(path.read_text(encoding="utf-8"))
221
+ return payload if isinstance(payload, dict) else {}
222
+
223
+
224
+ def _write_json_atomic(path: Path, payload: dict[str, Any]) -> None:
225
+ path.parent.mkdir(parents=True, exist_ok=True)
226
+ handle = tempfile.NamedTemporaryFile(
227
+ "w", encoding="utf-8", delete=False, dir=path.parent
228
+ )
229
+ try:
230
+ json.dump(payload, handle, ensure_ascii=False, indent=2)
231
+ handle.write("\n")
232
+ handle.close()
233
+ os.replace(handle.name, path)
234
+ except Exception:
235
+ handle.close()
236
+ Path(handle.name).unlink(missing_ok=True)
237
+ raise
238
+
239
+
240
+ def main(argv: list[str] | None = None) -> int:
241
+ parser = argparse.ArgumentParser(prog="okstra model")
242
+ sub = parser.add_subparsers(dest="command", required=True)
243
+ listed = sub.add_parser("list")
244
+ listed.add_argument("--role")
245
+ listed.add_argument("--host", default="claude-code")
246
+ listed.add_argument("--json", action="store_true")
247
+ default = sub.add_parser("default")
248
+ default_sub = default.add_subparsers(dest="default_command", required=True)
249
+ setter = default_sub.add_parser("set")
250
+ setter.add_argument("role")
251
+ setter.add_argument("refs")
252
+ setter.add_argument("--scope", choices=("project", "global"), required=True)
253
+ setter.add_argument("--cwd", default=".")
254
+ unsetter = default_sub.add_parser("unset")
255
+ unsetter.add_argument("role")
256
+ unsetter.add_argument("--scope", choices=("project", "global"), required=True)
257
+ unsetter.add_argument("--cwd", default=".")
258
+ args = parser.parse_args(argv)
259
+ try:
260
+ if args.command == "list":
261
+ return list_models(
262
+ role=args.role, host_runtime=args.host, as_json=args.json
263
+ )
264
+ if args.default_command == "set":
265
+ refs = tuple(part for part in args.refs.split(",") if part)
266
+ return set_model_default(
267
+ role=args.role, refs=refs, scope=args.scope, cwd=Path(args.cwd)
268
+ )
269
+ return unset_model_default(
270
+ role=args.role, scope=args.scope, cwd=Path(args.cwd)
271
+ )
272
+ except (ModelCliError, RoleCatalogError, UnknownModelError, OSError, ValueError) as exc:
273
+ print(f"error: {exc}", flush=True)
274
+ return 1
275
+
276
+
277
+ if __name__ == "__main__":
278
+ raise SystemExit(main())
@@ -0,0 +1,46 @@
1
+ """Pure role-model default scope replacement."""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass
5
+ from typing import Mapping
6
+
7
+
8
+ class ModelDefaultError(ValueError):
9
+ """Raised when the selected default scope cannot supply candidates."""
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class ModelDefaultScopes:
14
+ project: Mapping[str, tuple[str, ...]]
15
+ global_: Mapping[str, tuple[str, ...]]
16
+ bundled: Mapping[str, tuple[str, ...]]
17
+
18
+
19
+ def default_candidates(role: str, scopes: ModelDefaultScopes) -> tuple[str, ...]:
20
+ """Return the first scope containing ``role`` without merging arrays."""
21
+ for scope_name, values in (
22
+ ("project", scopes.project),
23
+ ("global", scopes.global_),
24
+ ("bundled", scopes.bundled),
25
+ ):
26
+ if role not in values:
27
+ continue
28
+ candidates = tuple(values[role])
29
+ if not candidates:
30
+ raise ModelDefaultError(
31
+ f"{scope_name} model defaults for {role!r} are empty"
32
+ )
33
+ return candidates
34
+ return ()
35
+
36
+
37
+ def default_scope(role: str, scopes: ModelDefaultScopes) -> str | None:
38
+ """Name the selected scope for resolver validation and diagnostics."""
39
+ for scope_name, values in (
40
+ ("project", scopes.project),
41
+ ("global", scopes.global_),
42
+ ("bundled", scopes.bundled),
43
+ ):
44
+ if role in values:
45
+ return scope_name
46
+ return None
@@ -105,21 +105,40 @@ def normalize_execution_for_dispatch(
105
105
  blocking. Raise ModelUnavailableError when the identity is definitely not
106
106
  offered (never substitute a different model)."""
107
107
  if provider == "codex":
108
- available = codex_availability()
109
- if not available or execution in available:
110
- return execution # no NUX list → pass through; listed → accepted
111
- raise ModelUnavailableError(
112
- f"codex model {execution!r} is not available for this account. "
113
- f"Available: {', '.join(available)} (no auto-rename — update the catalog)"
108
+ return normalize_codex_execution(
109
+ execution=execution,
110
+ available=codex_availability(),
114
111
  )
115
112
  if provider != "antigravity":
116
113
  return execution # claude runs via the Agent tool
114
+ return normalize_antigravity_execution(
115
+ execution=execution,
116
+ role=role,
117
+ available=agy_models(),
118
+ )
119
+
120
+
121
+ def normalize_codex_execution(
122
+ *, execution: str, available: tuple[str, ...]
123
+ ) -> str:
124
+ """Normalize one Codex value against a previously captured config list."""
125
+ if not available or execution in available:
126
+ return execution
127
+ raise ModelUnavailableError(
128
+ f"codex model {execution!r} is not available for this account. "
129
+ f"Available: {', '.join(available)} (no auto-rename — update the catalog)"
130
+ )
131
+
132
+
133
+ def normalize_antigravity_execution(
134
+ *, execution: str, role: str, available: tuple[str, ...]
135
+ ) -> str:
136
+ """Normalize one agy value against a previously captured model list."""
117
137
  # agy bakes the tier into the model identity as a slug suffix
118
138
  # (`gemini-3.1-pro-high`) and rejects the bare slug with "requires --effort"
119
139
  # — a flag the wrapper never sends. So the suffixed form is the only
120
140
  # dispatchable spelling, including on the un-verified fallback below.
121
141
  tiered = f"{execution}-{_dispatch_effort(execution, role)}"
122
- available = agy_models()
123
142
  if not available:
124
143
  return tiered # discovery unavailable → dispatch anyway, wrapper still guards
125
144
  if execution in available: