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
@@ -1,5 +1,4 @@
1
1
  import { runInstalledScript } from "../../lib/python-helper.mjs";
2
-
3
2
  const USAGE = `okstra report-translate — build and verify a final-report translation sidecar
4
3
 
5
4
  A thin spawn shim over \`scripts/okstra-report-translate.py\` (installed at
@@ -21,11 +20,11 @@ Usage:
21
20
  and report what is still English. Exits non-zero on a pointer that
22
21
  resolves nowhere — the translator's own gate before it returns.
23
22
  `;
24
-
25
23
  export async function run(args) {
26
- return runInstalledScript({
27
- scriptName: "okstra-report-translate.py",
28
- args,
29
- usage: USAGE,
30
- });
24
+ return runInstalledScript({
25
+ scriptName: "okstra-report-translate.py",
26
+ args,
27
+ usage: USAGE,
28
+ });
31
29
  }
30
+ //# sourceMappingURL=translate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.mjs","sourceRoot":"","sources":["../../../src/commands/report/translate.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;CAoBb,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAuB;IAC/C,OAAO,kBAAkB,CAAC;QACxB,UAAU,EAAE,4BAA4B;QACxC,IAAI;QACJ,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const HELPER_SCRIPT_NAMES: readonly string[];
2
+ import type { RuntimePaths } from "./types.mjs";
3
+ export declare function missingHelperScripts(paths: RuntimePaths, resolve: (paths: RuntimePaths, name: string) => string | null): string[];
@@ -4,21 +4,18 @@
4
4
  // environment gate instead of at the blocking lead step that calls it mid-run.
5
5
  // A contract test keeps this list in step with the `scriptName:` literals in
6
6
  // src/commands/**.
7
-
8
7
  export const HELPER_SCRIPT_NAMES = Object.freeze([
9
- "okstra-error-log.py",
10
- "okstra-incremental-carry.py",
11
- "okstra-incremental-scope.py",
12
- "okstra-inject-report-index.py",
13
- "okstra-render-final-report.py",
14
- "okstra-render-report-views.py",
15
- "okstra-report-translate.py",
16
- "okstra-spawn-followups.py",
17
- "okstra-token-usage.py",
8
+ "okstra-error-log.py",
9
+ "okstra-incremental-carry.py",
10
+ "okstra-incremental-scope.py",
11
+ "okstra-inject-report-index.py",
12
+ "okstra-render-final-report.py",
13
+ "okstra-render-report-views.py",
14
+ "okstra-report-translate.py",
15
+ "okstra-spawn-followups.py",
16
+ "okstra-token-usage.py",
18
17
  ]);
19
-
20
- // `resolve` is the same resolver the wrappers call, so preflight cannot pass a
21
- // script the dispatch path would then fail to find.
22
18
  export function missingHelperScripts(paths, resolve) {
23
- return HELPER_SCRIPT_NAMES.filter((name) => !resolve(paths, name));
19
+ return HELPER_SCRIPT_NAMES.filter((name) => !resolve(paths, name));
24
20
  }
21
+ //# sourceMappingURL=helper-scripts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper-scripts.mjs","sourceRoot":"","sources":["../../src/lib/helper-scripts.mts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAC7E,mBAAmB;AAEnB,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/C,qBAAqB;IACrB,6BAA6B;IAC7B,6BAA6B;IAC7B,+BAA+B;IAC/B,+BAA+B;IAC/B,+BAA+B;IAC/B,4BAA4B;IAC5B,2BAA2B;IAC3B,uBAAuB;CACxB,CAAC,CAAC;AAMH,MAAM,UAAU,oBAAoB,CAClC,KAAmB,EACnB,OAA6D;IAE7D,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { HostProbeOptions, HostReadiness, HostRegistryCatalog, HostResolveOptions, HostRuntimeResolution, PythonRunner } from "./types.mjs";
2
+ export declare const RUNTIME_AUTO = "auto";
3
+ export declare class HostRegistryClientError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ export declare function createHostRegistryClient({ runPython }?: {
7
+ readonly runPython?: PythonRunner;
8
+ }): {
9
+ readonly catalog: () => Promise<HostRegistryCatalog>;
10
+ readonly resolveHostRuntime: (options: HostResolveOptions) => Promise<HostRuntimeResolution>;
11
+ readonly probeHost: (options: HostProbeOptions) => Promise<HostReadiness>;
12
+ };
13
+ export declare function normalizeHostRequest(value: unknown): string;
14
+ export declare function loadHostCatalog(): Promise<HostRegistryCatalog>;
15
+ export declare function resolveHostRuntime(options: HostResolveOptions): Promise<HostRuntimeResolution>;
16
+ export declare function probeHost(options: HostProbeOptions): Promise<HostReadiness>;
17
+ export declare function resolveRuntime({ requestedRuntime, command, env, capabilities, }?: HostResolveOptions): Promise<HostRuntimeResolution>;
18
+ export declare function checkRuntimeReadiness({ runtime, projectRoot, homeDir, hostRegistryClient, }: {
19
+ readonly runtime?: string;
20
+ readonly projectRoot: string;
21
+ readonly homeDir?: string;
22
+ readonly hostRegistryClient?: {
23
+ readonly probeHost: (options: HostProbeOptions) => Promise<HostReadiness>;
24
+ };
25
+ }): Promise<HostReadiness>;
@@ -0,0 +1,152 @@
1
+ import { homedir } from "node:os";
2
+ import { runPythonModule } from "./python-helper.mjs";
3
+ export const RUNTIME_AUTO = "auto";
4
+ const HOST_REQUEST_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
5
+ const PLAIN_TEXT_INPUT = "plain_text_input";
6
+ export class HostRegistryClientError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "HostRegistryClientError";
10
+ }
11
+ }
12
+ async function callHosts(runPython, args) {
13
+ const result = await runPython({
14
+ module: "okstra_ctl.entrypoints.hosts",
15
+ args,
16
+ stdio: "capture",
17
+ });
18
+ if (result.code !== 0) {
19
+ const detail = String(result.stderr || "").trim() || `Python exited ${result.code}`;
20
+ throw new HostRegistryClientError(detail);
21
+ }
22
+ const stdout = String(result.stdout || "").trim();
23
+ if (!stdout)
24
+ throw new HostRegistryClientError("host registry returned empty stdout");
25
+ try {
26
+ const parsed = JSON.parse(stdout);
27
+ return parsed;
28
+ }
29
+ catch (error) {
30
+ const message = error instanceof Error ? error.message : String(error);
31
+ throw new HostRegistryClientError(`host registry returned invalid JSON: ${message}`);
32
+ }
33
+ }
34
+ function resolutionContext(env = {}, capabilities = {}) {
35
+ return {
36
+ env: { OKSTRA_RUNTIME_HOST: String(env?.OKSTRA_RUNTIME_HOST ?? "") },
37
+ capabilities: {
38
+ claudeSkillHandoff: capabilities?.claudeSkillHandoff === true,
39
+ tmuxAvailable: capabilities?.tmuxAvailable === true,
40
+ },
41
+ };
42
+ }
43
+ export function createHostRegistryClient({ runPython = runPythonModule } = {}) {
44
+ return {
45
+ async catalog() {
46
+ return await callHosts(runPython, ["catalog", "--json"]);
47
+ },
48
+ async resolveHostRuntime({ requestedRuntime, command, env, capabilities }) {
49
+ return await callHosts(runPython, [
50
+ "resolve",
51
+ "--requested", requestedRuntime,
52
+ "--command", command,
53
+ "--context-json", JSON.stringify(resolutionContext(env, capabilities)),
54
+ ]);
55
+ },
56
+ async probeHost({ hostRuntime, entryMode, projectRoot, homeDir, availableFunctions = [], }) {
57
+ const args = [
58
+ "probe",
59
+ "--host", hostRuntime,
60
+ "--entry-mode", entryMode,
61
+ "--project-root", projectRoot,
62
+ "--home-dir", homeDir,
63
+ ];
64
+ for (const availableFunction of availableFunctions) {
65
+ args.push("--available-function", availableFunction);
66
+ }
67
+ return await callHosts(runPython, args);
68
+ },
69
+ };
70
+ }
71
+ const hostRegistryClient = createHostRegistryClient();
72
+ export function normalizeHostRequest(value) {
73
+ const runtime = String(value ?? "").trim() || RUNTIME_AUTO;
74
+ if (!HOST_REQUEST_PATTERN.test(runtime)) {
75
+ throw new Error(`invalid runtime '${runtime}' (expected auto, all, or a lowercase host ID)`);
76
+ }
77
+ return runtime;
78
+ }
79
+ function failedResolution(requestedRuntime, error) {
80
+ return {
81
+ ok: false,
82
+ requestedRuntime,
83
+ resolvedRuntime: null,
84
+ launchMode: null,
85
+ installTargets: [],
86
+ host: "unknown",
87
+ confidence: "low",
88
+ reason: error.message,
89
+ fallbackFrom: null,
90
+ warnings: [],
91
+ };
92
+ }
93
+ function catalogResolution(catalog) {
94
+ const hosts = Array.isArray(catalog?.hosts) ? catalog.hosts : [];
95
+ const catalogHostIds = hosts.map((host) => host.id);
96
+ const installTargets = Array.from(new Set(hosts.flatMap((host) => host.install_targets ?? host.installTargets ?? []))).sort();
97
+ return {
98
+ ok: true,
99
+ requestedRuntime: "all",
100
+ resolvedRuntime: "all",
101
+ launchMode: "catalog",
102
+ installTargets,
103
+ catalogHostIds,
104
+ host: "explicit",
105
+ confidence: "high",
106
+ reason: "All registered host runtimes requested.",
107
+ fallbackFrom: null,
108
+ warnings: [],
109
+ };
110
+ }
111
+ export async function loadHostCatalog() {
112
+ return await hostRegistryClient.catalog();
113
+ }
114
+ export async function resolveHostRuntime(options) {
115
+ return await hostRegistryClient.resolveHostRuntime(options);
116
+ }
117
+ export async function probeHost(options) {
118
+ return await hostRegistryClient.probeHost(options);
119
+ }
120
+ export async function resolveRuntime({ requestedRuntime = RUNTIME_AUTO, command = "run", env = {}, capabilities = {}, } = {
121
+ requestedRuntime: RUNTIME_AUTO,
122
+ command: "run",
123
+ }) {
124
+ const request = normalizeHostRequest(requestedRuntime);
125
+ try {
126
+ if (request === "all")
127
+ return catalogResolution(await loadHostCatalog());
128
+ return await resolveHostRuntime({
129
+ requestedRuntime: request,
130
+ command,
131
+ env,
132
+ capabilities,
133
+ });
134
+ }
135
+ catch (error) {
136
+ if (!(error instanceof HostRegistryClientError))
137
+ throw error;
138
+ return failedResolution(request, error);
139
+ }
140
+ }
141
+ export async function checkRuntimeReadiness({ runtime, projectRoot, homeDir = homedir(), hostRegistryClient = { probeHost }, }) {
142
+ if (!runtime)
143
+ return { runtime: "auto", status: "ready", checks: [] };
144
+ return await hostRegistryClient.probeHost({
145
+ hostRuntime: runtime,
146
+ entryMode: "current-session",
147
+ projectRoot,
148
+ homeDir,
149
+ availableFunctions: [PLAIN_TEXT_INPUT],
150
+ });
151
+ }
152
+ //# sourceMappingURL=host-registry-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-registry-client.mjs","sourceRoot":"","sources":["../../src/lib/host-registry-client.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const INSTALLED_TREES: {
2
+ from: string;
3
+ to: string[];
4
+ }[];
5
+ export declare const INSTALLED_FILES: string[];
6
+ export declare const SKILLS_MANIFEST_REL = "installed-skills.json";
7
+ export declare const AGENTS_MANIFEST_REL = "installed-agents.json";
8
+ export declare const LEGACY_TRANSPORT_AGENT_NAMES: readonly string[];
@@ -7,40 +7,37 @@
7
7
  //
8
8
  // Skills and agents are NOT here: they install outside ~/.okstra (host skill
9
9
  // homes, ~/.claude/agents) and are tracked per-target by their own manifests.
10
-
11
10
  // runtime/<from> is mirrored to ~/.okstra/<to...>. Mirrored, not merged: a file
12
11
  // the payload no longer ships is removed from the install, because Python
13
12
  // imports whatever is on disk and a stale module outlives the release that
14
13
  // dropped it.
15
14
  export const INSTALLED_TREES = [
16
- { from: "python", to: ["lib", "python"] },
17
- { from: "bin", to: ["bin"] },
18
- { from: "templates", to: ["templates"] },
19
- { from: "schemas", to: ["schemas"] },
20
- { from: "validators", to: ["lib", "validators"] },
21
- { from: "prompts", to: ["prompts"] },
15
+ { from: "python", to: ["lib", "python"] },
16
+ { from: "bin", to: ["bin"] },
17
+ { from: "templates", to: ["templates"] },
18
+ { from: "schemas", to: ["schemas"] },
19
+ { from: "validators", to: ["lib", "validators"] },
20
+ { from: "prompts", to: ["prompts"] },
22
21
  ];
23
-
24
22
  // Single files the install stamps into ~/.okstra. Every one is removed by
25
23
  // uninstall; `installed-from` is written by no current code path and is listed
26
24
  // so that homes carrying it from an older version still get cleaned.
27
25
  export const INSTALLED_FILES = [
28
- "version",
29
- "dev-link",
30
- "installed-from",
31
- "installed-skills.json",
32
- "installed-agents.json",
33
- "installed-runtimes.json",
26
+ "version",
27
+ "dev-link",
28
+ "installed-from",
29
+ "installed-skills.json",
30
+ "installed-agents.json",
31
+ "installed-runtimes.json",
34
32
  ];
35
-
36
33
  export const SKILLS_MANIFEST_REL = "installed-skills.json";
37
34
  export const AGENTS_MANIFEST_REL = "installed-agents.json";
38
-
39
35
  // Exact names of the retired LLM transport wrappers. Install removes an entry
40
36
  // only when the previous agent manifest proves that Okstra installed it.
41
37
  export const LEGACY_TRANSPORT_AGENT_NAMES = Object.freeze([
42
- "codex-worker.md",
43
- "antigravity-worker.md",
44
- "grok-worker.md",
45
- "kimi-worker.md",
38
+ "codex-worker.md",
39
+ "antigravity-worker.md",
40
+ "grok-worker.md",
41
+ "kimi-worker.md",
46
42
  ]);
43
+ //# sourceMappingURL=install-assets.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-assets.mjs","sourceRoot":"","sources":["../../src/lib/install-assets.mts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,iCAAiC;AACjC,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAE9E,gFAAgF;AAChF,0EAA0E;AAC1E,2EAA2E;AAC3E,cAAc;AACd,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE;IACzC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE;IAC5B,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE;IACxC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE;IACpC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE;IACjD,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE;CACrC,CAAC;AAEF,0EAA0E;AAC1E,+EAA+E;AAC/E,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,SAAS;IACT,UAAU;IACV,gBAAgB;IAChB,uBAAuB;IACvB,uBAAuB;IACvB,yBAAyB;CAC1B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D,8EAA8E;AAC9E,yEAAyE;AACzE,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,CAAC;IACxD,iBAAiB;IACjB,uBAAuB;IACvB,gBAAgB;IAChB,gBAAgB;CACjB,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const OKSTRA_DIR = ".okstra";
2
+ export declare const LEGACY_OKSTRA_DIR = "./okstra";
3
+ export declare function okstraRoot(projectRoot: string): string;
4
+ export declare function projectJsonPath(projectRoot: string): string;
@@ -8,19 +8,16 @@
8
8
  //
9
9
  // 의존성은 `node:path` 만 — `src/install.mjs` / `src/setup.mjs` 등 무거운
10
10
  // 모듈에서 import 할 때 순환 위험을 피한다.
11
-
12
11
  import { join } from "node:path";
13
-
14
12
  export const OKSTRA_DIR = ".okstra";
15
13
  // Pre-v0.37 layout. `okstra migrate` reads this to find unmigrated projects.
16
14
  // 코드 path 빌드에는 절대 사용 금지 — `OKSTRA_DIR` 만. 오로지 migration
17
15
  // 탐지/안내 메시지 용도.
18
16
  export const LEGACY_OKSTRA_DIR = "./okstra";
19
-
20
17
  export function okstraRoot(projectRoot) {
21
- return join(projectRoot, OKSTRA_DIR);
18
+ return join(projectRoot, OKSTRA_DIR);
22
19
  }
23
-
24
20
  export function projectJsonPath(projectRoot) {
25
- return join(okstraRoot(projectRoot), "project.json");
21
+ return join(okstraRoot(projectRoot), "project.json");
26
22
  }
23
+ //# sourceMappingURL=okstra-dirs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"okstra-dirs.mjs","sourceRoot":"","sources":["../../src/lib/okstra-dirs.mts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,gEAAgE;AAChE,iDAAiD;AACjD,8DAA8D;AAC9D,8CAA8C;AAC9C,wCAAwC;AACxC,EAAE;AACF,iEAAiE;AACjE,8BAA8B;AAE9B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AACpC,6EAA6E;AAC7E,wDAAwD;AACxD,gBAAgB;AAChB,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAE5C,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,OAAO,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { RuntimePaths } from "./types.mjs";
2
+ export declare function resolveOkstraHome(): string;
3
+ export declare function resolvePaths(): Promise<RuntimePaths>;
4
+ export declare function buildPythonpath(paths: RuntimePaths): string;
@@ -0,0 +1,78 @@
1
+ import { homedir, tmpdir } from "node:os";
2
+ import { join } from "node:path";
3
+ import { existsSync } from "node:fs";
4
+ import { getPackageRoot, getPackageVersion } from "./version.mjs";
5
+ function isStaleTmpHome(p) {
6
+ // tests/conftest.py creates the isolated home as `<tmp_path>/.okstra-isolated`
7
+ // under the system temp dir. Only a deleted one (env leaked, dir gone) heals;
8
+ // a soon-to-be-created `.okstra` temp home or a custom home is left untouched.
9
+ if (!p.endsWith("/.okstra-isolated"))
10
+ return false;
11
+ const roots = [tmpdir(), "/tmp", "/private/tmp", "/var/folders", "/private/var/folders"];
12
+ return roots.some((r) => r && (p === r || p.startsWith(r.replace(/\/+$/, "") + "/")));
13
+ }
14
+ // Resolve OKSTRA_HOME, healing a leaked value: when it points at a missing
15
+ // system-temp path (e.g. a deleted pytest-isolated home), warn and fall back
16
+ // to ~/.okstra instead of operating on the dead directory.
17
+ export function resolveOkstraHome() {
18
+ const raw = process.env.OKSTRA_HOME?.trim();
19
+ if (!raw)
20
+ return join(homedir(), ".okstra");
21
+ if (!existsSync(raw) && isStaleTmpHome(raw)) {
22
+ process.stderr.write(`⚠ OKSTRA_HOME=${raw} points to a missing temp dir (leaked test value); falling back to ~/.okstra\n`);
23
+ return join(homedir(), ".okstra");
24
+ }
25
+ return raw;
26
+ }
27
+ export async function resolvePaths() {
28
+ const home = resolveOkstraHome();
29
+ const pkgRoot = getPackageRoot();
30
+ const devLink = await readSimpleFile(join(home, "dev-link"));
31
+ const runtimeRoot = devLink || join(pkgRoot, "runtime");
32
+ return {
33
+ agents: join(runtimeRoot, "agents"),
34
+ workspace: runtimeRoot,
35
+ pythonpath: join(home, "lib", "python"),
36
+ bin: join(home, "bin"),
37
+ home,
38
+ package: await getPackageVersion(),
39
+ version: await readSimpleFile(join(home, "version")),
40
+ "dev-link": devLink || "",
41
+ };
42
+ }
43
+ function workspacePythonpath(paths) {
44
+ const candidates = [
45
+ join(paths.workspace, "python"),
46
+ join(paths.workspace, "scripts"),
47
+ ];
48
+ return candidates.find((candidate) => existsSync(candidate)) || "";
49
+ }
50
+ // Compose the PYTHONPATH spawned python3 subprocesses should see.
51
+ //
52
+ // Precedence (first wins):
53
+ // 1. process.env.PYTHONPATH (user override — e.g. in-repo `PYTHONPATH=scripts`
54
+ // for dev work without re-running `okstra install`).
55
+ // 2. The package/dev-link workspace runtime selected by `okstra paths`.
56
+ // 3. The installed user-runtime path (~/.okstra/lib/python).
57
+ //
58
+ // This is a colon-joined string suitable for direct assignment into the child
59
+ // process env. Empty segments are dropped so a missing env var does not produce
60
+ // a leading ':' (which Python treats as 'current directory').
61
+ export function buildPythonpath(paths) {
62
+ const fragments = [
63
+ process.env.PYTHONPATH,
64
+ workspacePythonpath(paths),
65
+ paths.pythonpath,
66
+ ].filter((s) => typeof s === "string" && s.length > 0);
67
+ return fragments.join(":");
68
+ }
69
+ async function readSimpleFile(path) {
70
+ try {
71
+ const { readFile } = await import("node:fs/promises");
72
+ return (await readFile(path, "utf8")).trim();
73
+ }
74
+ catch {
75
+ return "";
76
+ }
77
+ }
78
+ //# sourceMappingURL=paths.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.mjs","sourceRoot":"","sources":["../../src/lib/paths.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliArgs, ProcessResult } from "./types.mjs";
2
+ export declare function fileExists(p: string): Promise<boolean>;
3
+ export declare function runProcess(cmd: string, args: CliArgs, env?: Readonly<Record<string, string | undefined>>): Promise<ProcessResult>;
@@ -0,0 +1,31 @@
1
+ // Shared filesystem / subprocess helpers used by the Node command modules.
2
+ // Extracted to one place so a fix lands once instead of in each command file.
3
+ import { spawn } from "node:child_process";
4
+ import { promises as fs } from "node:fs";
5
+ export async function fileExists(p) {
6
+ try {
7
+ await fs.access(p);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ // Run `cmd args`, capturing stdout/stderr. `env` holds *additional* vars that
15
+ // are merged over the inherited process.env. Never rejects — failures resolve
16
+ // with { code: -1, stderr: <message> }.
17
+ export function runProcess(cmd, args, env = {}) {
18
+ return new Promise((resolve) => {
19
+ const child = spawn(cmd, args, {
20
+ stdio: ["ignore", "pipe", "pipe"],
21
+ env: { ...process.env, ...env },
22
+ });
23
+ let stdout = "";
24
+ let stderr = "";
25
+ child.stdout.on("data", (b) => (stdout += b.toString()));
26
+ child.stderr.on("data", (b) => (stderr += b.toString()));
27
+ child.on("error", (err) => resolve({ code: -1, stdout, stderr: err.message }));
28
+ child.on("close", (code) => resolve({ code: typeof code === "number" ? code : 1, stdout, stderr }));
29
+ });
30
+ }
31
+ //# sourceMappingURL=proc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proc.mjs","sourceRoot":"","sources":["../../src/lib/proc.mts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,8EAA8E;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,CAAS;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,wCAAwC;AACxC,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,IAAa,EACb,GAAG,GAAiD,EAAE;IAEtD,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAC7B,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;SAChC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC/E,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { InstalledScriptOptions, InstalledValidatorOptions, JsonErrorOptions, ProcessResult, PythonModuleOptions, PythonSnippetOptions, RuntimePaths } from "./types.mjs";
2
+ export declare function resolveInstalledScript(paths: RuntimePaths, scriptName: string): string | null;
3
+ export declare function resolveInstalledValidator(paths: RuntimePaths, validatorName: string): string | null;
4
+ export declare function runInstalledScript({ scriptName, args, usage, emptyArgsCode }: InstalledScriptOptions): Promise<number>;
5
+ export declare function runInstalledValidator({ validatorName, args }: InstalledValidatorOptions): Promise<number>;
6
+ export declare function runPythonSnippet({ script, args, extraEnv }: PythonSnippetOptions): Promise<ProcessResult>;
7
+ export declare function runPythonModule({ module, args, extraEnv, stdio }: PythonModuleOptions): Promise<ProcessResult>;
8
+ export declare function emitJsonError({ stage, reason, extra }: JsonErrorOptions): void;
@@ -0,0 +1,123 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join, resolve as resolvePath } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { buildPythonpath, resolvePaths } from "./paths.mjs";
6
+ export function resolveInstalledScript(paths, scriptName) {
7
+ // Prefer the installed copy under ~/.okstra/bin (what production users run);
8
+ // fall back to the in-repo source when invoked from a checkout that has not
9
+ // been installed (dev / CI).
10
+ const installed = join(paths.bin, scriptName);
11
+ if (existsSync(installed))
12
+ return installed;
13
+ const repoRoot = fileURLToPath(new URL("../..", import.meta.url));
14
+ const dev = resolvePath(repoRoot, "scripts", scriptName);
15
+ return existsSync(dev) ? dev : null;
16
+ }
17
+ export function resolveInstalledValidator(paths, validatorName) {
18
+ // `okstra install` lands the validators tree at ~/.okstra/lib/validators;
19
+ // a checkout that has not been installed still has the in-repo source.
20
+ const installed = join(paths.home, "lib", "validators", validatorName);
21
+ if (existsSync(installed))
22
+ return installed;
23
+ const repoRoot = fileURLToPath(new URL("../..", import.meta.url));
24
+ const dev = resolvePath(repoRoot, "validators", validatorName);
25
+ return existsSync(dev) ? dev : null;
26
+ }
27
+ async function spawnPythonEntry(entry, args, paths) {
28
+ return await new Promise((resolve) => {
29
+ const child = spawn("python3", [entry, ...args], {
30
+ stdio: "inherit",
31
+ env: { ...process.env, PYTHONPATH: buildPythonpath(paths) },
32
+ });
33
+ child.on("error", (err) => {
34
+ process.stderr.write(`error: failed to spawn python3: ${err.message}\n`);
35
+ resolve(1);
36
+ });
37
+ child.on("close", (code) => resolve(typeof code === "number" ? code : 1));
38
+ });
39
+ }
40
+ // Thin spawn shim shared by every `okstra <cmd>` subcommand that fronts a
41
+ // `scripts/okstra-*.py` entry point. Centralizing it keeps PYTHONPATH wiring
42
+ // and installed/dev resolution in one place so skills call `okstra <cmd>`
43
+ // instead of emitting `python3 "$HOME/..."` (which breaks `Bash(okstra:*)`
44
+ // permission matching and prompts on every call).
45
+ export async function runInstalledScript({ scriptName, args, usage, emptyArgsCode = 2 }) {
46
+ if (args.length === 0) {
47
+ process.stdout.write(usage);
48
+ return emptyArgsCode;
49
+ }
50
+ // Only a bare `--help` / `-h` prints the wrapper usage. A `--help` that
51
+ // follows a subcommand (e.g. `error-log append-observed --help`) must reach
52
+ // the python helper so its own per-subcommand help shows through.
53
+ if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
54
+ process.stdout.write(usage);
55
+ return 0;
56
+ }
57
+ const paths = await resolvePaths();
58
+ const entry = resolveInstalledScript(paths, scriptName);
59
+ if (!entry) {
60
+ process.stderr.write(`error: ${scriptName} not found — run 'okstra install' (or 'okstra ensure-installed') first\n`);
61
+ return 1;
62
+ }
63
+ return await spawnPythonEntry(entry, args, paths);
64
+ }
65
+ export async function runInstalledValidator({ validatorName, args }) {
66
+ const paths = await resolvePaths();
67
+ const entry = resolveInstalledValidator(paths, validatorName);
68
+ if (!entry) {
69
+ process.stderr.write(`error: ${validatorName} not found — run 'okstra install' (or 'okstra ensure-installed') first\n`);
70
+ return 1;
71
+ }
72
+ return await spawnPythonEntry(entry, args, paths);
73
+ }
74
+ export async function runPythonSnippet({ script, args = [], extraEnv = {} }) {
75
+ const paths = await resolvePaths();
76
+ return new Promise((resolve) => {
77
+ const child = spawn("python3", ["-c", script, ...args], {
78
+ stdio: ["ignore", "pipe", "pipe"],
79
+ env: { ...process.env, PYTHONPATH: buildPythonpath(paths), ...extraEnv },
80
+ });
81
+ // Collect chunks and join once: repeated `s += chunk` is O(n^2) for the
82
+ // large rendered prompts some capture-mode callers stream through here.
83
+ const outChunks = [];
84
+ const errChunks = [];
85
+ child.stdout?.on("data", (b) => outChunks.push(b));
86
+ child.stderr?.on("data", (b) => errChunks.push(b));
87
+ child.on("error", (err) => resolve({ code: -1, stdout: Buffer.concat(outChunks).toString(), stderr: err.message }));
88
+ child.on("close", (code) => resolve({
89
+ code: typeof code === "number" ? code : 1,
90
+ stdout: Buffer.concat(outChunks).toString(),
91
+ stderr: Buffer.concat(errChunks).toString(),
92
+ }));
93
+ });
94
+ }
95
+ export async function runPythonModule({ module, args = [], extraEnv = {}, stdio = "inherit-stdout" }) {
96
+ const paths = await resolvePaths();
97
+ return new Promise((resolve) => {
98
+ const child = spawn("python3", ["-m", module, ...args], {
99
+ stdio: stdio === "capture" ? ["ignore", "pipe", "pipe"] : ["ignore", "inherit", "inherit"],
100
+ env: { ...process.env, PYTHONPATH: buildPythonpath(paths), ...extraEnv },
101
+ });
102
+ // Collect chunks and join once: repeated `s += chunk` is O(n^2) for the
103
+ // large rendered prompts some capture-mode callers stream through here.
104
+ const outChunks = [];
105
+ const errChunks = [];
106
+ if (stdio === "capture") {
107
+ child.stdout?.on("data", (b) => outChunks.push(b));
108
+ child.stderr?.on("data", (b) => errChunks.push(b));
109
+ }
110
+ child.on("error", (err) => resolve({ code: -1, stdout: Buffer.concat(outChunks).toString(), stderr: err.message }));
111
+ // A signal-killed child reports code === null; normalize to a non-zero exit
112
+ // here so every consumer inherits correct failure semantics from one place.
113
+ child.on("close", (code) => resolve({
114
+ code: typeof code === "number" ? code : 1,
115
+ stdout: Buffer.concat(outChunks).toString(),
116
+ stderr: Buffer.concat(errChunks).toString(),
117
+ }));
118
+ });
119
+ }
120
+ export function emitJsonError({ stage, reason, extra = {} }) {
121
+ process.stdout.write(JSON.stringify({ ok: false, stage, reason, ...extra }, null, 2) + "\n");
122
+ }
123
+ //# sourceMappingURL=python-helper.mjs.map