okstra 0.96.1 → 0.97.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.
- package/README.kr.md +1 -1
- package/README.md +1 -1
- package/bin/okstra +1 -1
- package/docs/contributor-change-matrix.md +1 -1
- package/docs/kr/architecture/storage-model.md +273 -0
- package/docs/kr/architecture.md +6 -277
- package/docs/kr/cli.md +1 -1
- package/docs/project-structure-overview.md +26 -22
- package/docs/superpowers/plans/2026-06-20-error-feedback-loop.md +1019 -0
- package/docs/superpowers/plans/2026-06-20-run-index-row-normalization.md +583 -0
- package/docs/superpowers/plans/2026-06-20-stage-auto-integrate-teardown.md +819 -0
- package/docs/superpowers/plans/2026-06-21-release-handoff-local-checkout.md +348 -0
- package/docs/superpowers/specs/2026-06-06-stage-worktree-isolation-design.md +2 -2
- package/docs/superpowers/specs/2026-06-20-error-feedback-loop-design.md +171 -0
- package/docs/superpowers/specs/2026-06-20-run-index-row-normalization-design.md +112 -0
- package/docs/superpowers/specs/2026-06-20-stage-auto-integrate-teardown-design.md +145 -0
- package/docs/superpowers/specs/2026-06-21-release-handoff-local-checkout-design.md +113 -0
- package/docs/task-process/release-handoff.md +3 -3
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/bin/lib/okstra/cli.sh +1 -1
- package/runtime/bin/lib/okstra/interactive.sh +22 -4
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +18 -5
- package/runtime/bin/okstra-render-final-report.py +4 -15
- package/runtime/bin/okstra.sh +5 -2
- package/runtime/prompts/launch.template.md +1 -0
- package/runtime/prompts/lead/report-writer.md +1 -1
- package/runtime/prompts/lead/team-contract.md +1 -1
- package/runtime/prompts/profiles/final-verification.md +1 -0
- package/runtime/prompts/profiles/forbidden-actions.json +1 -1
- package/runtime/prompts/profiles/release-handoff.md +10 -4
- package/runtime/python/okstra_ctl/__init__.py +3 -2
- package/runtime/python/okstra_ctl/backfill.py +12 -21
- package/runtime/python/okstra_ctl/codex_dispatch.py +7 -2
- package/runtime/python/okstra_ctl/conformance.py +21 -3
- package/runtime/python/okstra_ctl/consumers.py +7 -1
- package/runtime/python/okstra_ctl/dispatch_core.py +10 -2
- package/runtime/python/okstra_ctl/doctor.py +29 -12
- package/runtime/python/okstra_ctl/error_log_core.py +72 -0
- package/runtime/python/okstra_ctl/error_report.py +8 -58
- package/runtime/python/okstra_ctl/error_zip.py +319 -0
- package/runtime/python/okstra_ctl/fanout.py +5 -2
- package/runtime/python/okstra_ctl/fix_cycles.py +14 -2
- package/runtime/python/okstra_ctl/git_reconcile.py +7 -1
- package/runtime/python/okstra_ctl/handoff.py +125 -26
- package/runtime/python/okstra_ctl/implementation_stage.py +9 -2
- package/runtime/python/okstra_ctl/improvement_lenses.py +2 -0
- package/runtime/python/okstra_ctl/index.py +34 -91
- package/runtime/python/okstra_ctl/jsonl.py +29 -18
- package/runtime/python/okstra_ctl/listing.py +30 -5
- package/runtime/python/okstra_ctl/md_table.py +1 -1
- package/runtime/python/okstra_ctl/migrate.py +17 -7
- package/runtime/python/okstra_ctl/paths.py +1 -1
- package/runtime/python/okstra_ctl/recap.py +12 -3
- package/runtime/python/okstra_ctl/reconcile.py +13 -11
- package/runtime/python/okstra_ctl/render.py +49 -12
- package/runtime/python/okstra_ctl/render_final_report.py +4 -0
- package/runtime/python/okstra_ctl/report_views.py +47 -6
- package/runtime/python/okstra_ctl/run.py +128 -100
- package/runtime/python/okstra_ctl/run_index_row.py +118 -0
- package/runtime/python/okstra_ctl/schema_excerpt.py +8 -2
- package/runtime/python/okstra_ctl/sequence.py +2 -2
- package/runtime/python/okstra_ctl/stage_integrate.py +193 -0
- package/runtime/python/okstra_ctl/stage_targets.py +2 -8
- package/runtime/python/okstra_ctl/task_target.py +4 -1
- package/runtime/python/okstra_ctl/team_reconcile.py +6 -1
- package/runtime/python/okstra_ctl/wizard.py +27 -12
- package/runtime/python/okstra_ctl/workflow.py +9 -1
- package/runtime/python/okstra_ctl/worktree.py +93 -4
- package/runtime/python/okstra_ctl/worktree_registry.py +57 -8
- package/runtime/python/okstra_token_usage/collect.py +43 -38
- package/runtime/skills/okstra-brief/SKILL.md +43 -12
- package/runtime/skills/okstra-inspect/SKILL.md +44 -1
- package/runtime/templates/reports/final-report.template.md +2 -2
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/validators/forbidden_actions.py +8 -1
- package/runtime/validators/validate-brief.py +13 -2
- package/runtime/validators/validate-run.py +27 -6
- package/runtime/validators/validate-schedule.py +1 -2
- package/runtime/validators/validate_improvement_report.py +14 -0
- package/src/cli-registry.mjs +45 -31
- package/src/{codex-dispatch.mjs → commands/execute/codex-dispatch.mjs} +3 -3
- package/src/{codex-run.mjs → commands/execute/codex-run.mjs} +3 -3
- package/src/{error-log.mjs → commands/execute/error-log.mjs} +1 -1
- package/src/{git-reconcile.mjs → commands/execute/git-reconcile.mjs} +1 -1
- package/src/{handoff.mjs → commands/execute/handoff.mjs} +3 -1
- package/src/commands/execute/integrate-stages.mjs +25 -0
- package/src/{plan-validate.mjs → commands/execute/plan-validate.mjs} +1 -1
- package/src/{render-bundle.mjs → commands/execute/render-bundle.mjs} +4 -4
- package/src/{run.mjs → commands/execute/run.mjs} +4 -4
- package/src/{spawn-followups.mjs → commands/execute/spawn-followups.mjs} +1 -1
- package/src/{team.mjs → commands/execute/team.mjs} +3 -3
- package/src/{token-usage.mjs → commands/execute/token-usage.mjs} +1 -1
- package/src/{wizard.mjs → commands/execute/wizard.mjs} +15 -6
- package/src/{worktree-lookup.mjs → commands/execute/worktree-lookup.mjs} +1 -1
- package/src/{context-cost.mjs → commands/inspect/context-cost.mjs} +2 -2
- package/src/{error-report.mjs → commands/inspect/error-report.mjs} +2 -2
- package/src/commands/inspect/error-zip.mjs +25 -0
- package/src/{recap.mjs → commands/inspect/recap.mjs} +2 -2
- package/src/{task-list.mjs → commands/inspect/task-list.mjs} +1 -1
- package/src/{task-show.mjs → commands/inspect/task-show.mjs} +1 -1
- package/src/{check-project.mjs → commands/lifecycle/check-project.mjs} +2 -2
- package/src/{config.mjs → commands/lifecycle/config.mjs} +3 -3
- package/src/{doctor.mjs → commands/lifecycle/doctor.mjs} +4 -4
- package/src/{install.mjs → commands/lifecycle/install.mjs} +18 -13
- package/src/{migrate.mjs → commands/lifecycle/migrate.mjs} +1 -1
- package/src/{paths.mjs → commands/lifecycle/paths.mjs} +1 -60
- package/src/{setup.mjs → commands/lifecycle/setup.mjs} +4 -4
- package/src/{uninstall.mjs → commands/lifecycle/uninstall.mjs} +20 -32
- package/src/{memory.mjs → commands/memory/memory.mjs} +32 -7
- package/src/{inject-report-index.mjs → commands/report/inject-report-index.mjs} +1 -1
- package/src/{render-final-report.mjs → commands/report/render-final-report.mjs} +1 -1
- package/src/{render-views.mjs → commands/report/render-views.mjs} +1 -1
- package/src/lib/paths.mjs +60 -0
- package/src/{_python-helper.mjs → lib/python-helper.mjs} +35 -13
- package/src/{version.mjs → lib/version.mjs} +2 -2
- /package/src/{okstra-dirs.mjs → lib/okstra-dirs.mjs} +0 -0
- /package/src/{_proc.mjs → lib/proc.mjs} +0 -0
- /package/src/{runtime-manifest.mjs → lib/runtime-manifest.mjs} +0 -0
- /package/src/{runtime-resolver.mjs → lib/runtime-resolver.mjs} +0 -0
- /package/src/{skill-catalog.mjs → lib/skill-catalog.mjs} +0 -0
package/src/cli-registry.mjs
CHANGED
|
@@ -3,35 +3,35 @@ const SUMMARY_COLUMN = 25;
|
|
|
3
3
|
export const COMMAND_REGISTRY = [
|
|
4
4
|
{
|
|
5
5
|
name: "install",
|
|
6
|
-
module: "./install.mjs",
|
|
6
|
+
module: "./commands/lifecycle/install.mjs",
|
|
7
7
|
export: "runInstall",
|
|
8
8
|
category: "admin",
|
|
9
9
|
summary: ["Install runtime; seed skills into existing agent homes"],
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
name: "ensure-installed",
|
|
13
|
-
module: "./install.mjs",
|
|
13
|
+
module: "./commands/lifecycle/install.mjs",
|
|
14
14
|
export: "runEnsureInstalled",
|
|
15
15
|
category: "admin",
|
|
16
16
|
summary: ["Verify install is fresh; reinstall if stale (idempotent)"],
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
name: "uninstall",
|
|
20
|
-
module: "./uninstall.mjs",
|
|
20
|
+
module: "./commands/lifecycle/uninstall.mjs",
|
|
21
21
|
export: "runUninstall",
|
|
22
22
|
category: "admin",
|
|
23
23
|
summary: ["Remove runtime + skills (user data preserved by default)"],
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: "setup",
|
|
27
|
-
module: "./setup.mjs",
|
|
27
|
+
module: "./commands/lifecycle/setup.mjs",
|
|
28
28
|
export: "run",
|
|
29
29
|
category: "admin",
|
|
30
30
|
summary: ["Register the current project (.okstra/project.json)"],
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
name: "doctor",
|
|
34
|
-
module: "./doctor.mjs",
|
|
34
|
+
module: "./commands/lifecycle/doctor.mjs",
|
|
35
35
|
export: "run",
|
|
36
36
|
category: "admin",
|
|
37
37
|
summary: [
|
|
@@ -40,42 +40,49 @@ export const COMMAND_REGISTRY = [
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
name: "check-project",
|
|
43
|
-
module: "./check-project.mjs",
|
|
43
|
+
module: "./commands/lifecycle/check-project.mjs",
|
|
44
44
|
export: "run",
|
|
45
45
|
category: "admin",
|
|
46
46
|
summary: ["Verify the current project has been registered with setup"],
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
name: "config",
|
|
50
|
-
module: "./config.mjs",
|
|
50
|
+
module: "./commands/lifecycle/config.mjs",
|
|
51
51
|
export: "run",
|
|
52
52
|
category: "admin",
|
|
53
53
|
summary: ["Read / write okstra settings (e.g. PR template path)"],
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
name: "migrate",
|
|
57
|
-
module: "./migrate.mjs",
|
|
57
|
+
module: "./commands/lifecycle/migrate.mjs",
|
|
58
58
|
export: "run",
|
|
59
59
|
category: "admin",
|
|
60
60
|
summary: ["Move legacy .project-docs/okstra/ to .okstra/ (one-shot)"],
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
name: "git-reconcile",
|
|
64
|
-
module: "./git-reconcile.mjs",
|
|
64
|
+
module: "./commands/execute/git-reconcile.mjs",
|
|
65
65
|
export: "run",
|
|
66
66
|
category: "admin",
|
|
67
67
|
summary: ["Reconcile stale stage SHAs after external git history changes"],
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
name: "handoff",
|
|
71
|
-
module: "./handoff.mjs",
|
|
71
|
+
module: "./commands/execute/handoff.mjs",
|
|
72
72
|
export: "run",
|
|
73
73
|
category: "admin",
|
|
74
74
|
summary: ["Stage-group release-handoff helpers (eligible/assemble/record)"],
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
name: "integrate-stages",
|
|
78
|
+
module: "./commands/execute/integrate-stages.mjs",
|
|
79
|
+
export: "run",
|
|
80
|
+
category: "admin",
|
|
81
|
+
summary: ["stage 들을 task 브랜치에 통합 머지하고 stage worktree 를 정리"],
|
|
82
|
+
},
|
|
76
83
|
{
|
|
77
84
|
name: "paths",
|
|
78
|
-
module: "./paths.mjs",
|
|
85
|
+
module: "./commands/lifecycle/paths.mjs",
|
|
79
86
|
export: "run",
|
|
80
87
|
category: "admin",
|
|
81
88
|
summary: [
|
|
@@ -84,56 +91,63 @@ export const COMMAND_REGISTRY = [
|
|
|
84
91
|
},
|
|
85
92
|
{
|
|
86
93
|
name: "task-list",
|
|
87
|
-
module: "./task-list.mjs",
|
|
94
|
+
module: "./commands/inspect/task-list.mjs",
|
|
88
95
|
export: "run",
|
|
89
96
|
category: "introspection",
|
|
90
97
|
summary: ["List tasks registered in the current project"],
|
|
91
98
|
},
|
|
92
99
|
{
|
|
93
100
|
name: "task-show",
|
|
94
|
-
module: "./task-show.mjs",
|
|
101
|
+
module: "./commands/inspect/task-show.mjs",
|
|
95
102
|
export: "run",
|
|
96
103
|
category: "introspection",
|
|
97
104
|
summary: ["Summarize a task's manifest + workflow phase state"],
|
|
98
105
|
},
|
|
99
106
|
{
|
|
100
107
|
name: "context-cost",
|
|
101
|
-
module: "./context-cost.mjs",
|
|
108
|
+
module: "./commands/inspect/context-cost.mjs",
|
|
102
109
|
export: "run",
|
|
103
110
|
category: "introspection",
|
|
104
111
|
summary: ["Estimate file/read context cost for a task bundle"],
|
|
105
112
|
},
|
|
106
113
|
{
|
|
107
114
|
name: "error-report",
|
|
108
|
-
module: "./error-report.mjs",
|
|
115
|
+
module: "./commands/inspect/error-report.mjs",
|
|
109
116
|
export: "run",
|
|
110
117
|
category: "introspection",
|
|
111
118
|
summary: ["Aggregate okstra-run error logs into a task-level report"],
|
|
112
119
|
},
|
|
120
|
+
{
|
|
121
|
+
name: "error-zip",
|
|
122
|
+
module: "./commands/inspect/error-zip.mjs",
|
|
123
|
+
export: "run",
|
|
124
|
+
category: "introspection",
|
|
125
|
+
summary: ["Bundle cross-project okstra error logs into a zip"],
|
|
126
|
+
},
|
|
113
127
|
{
|
|
114
128
|
name: "recap",
|
|
115
|
-
module: "./recap.mjs",
|
|
129
|
+
module: "./commands/inspect/recap.mjs",
|
|
116
130
|
export: "run",
|
|
117
131
|
category: "introspection",
|
|
118
132
|
summary: ["Assemble a task's run-to-run phase recap or append a recap log entry"],
|
|
119
133
|
},
|
|
120
134
|
{
|
|
121
135
|
name: "worktree-lookup",
|
|
122
|
-
module: "./worktree-lookup.mjs",
|
|
136
|
+
module: "./commands/execute/worktree-lookup.mjs",
|
|
123
137
|
export: "run",
|
|
124
138
|
category: "introspection",
|
|
125
139
|
summary: ["Look up registered worktree for a task-key"],
|
|
126
140
|
},
|
|
127
141
|
{
|
|
128
142
|
name: "plan-validate",
|
|
129
|
-
module: "./plan-validate.mjs",
|
|
143
|
+
module: "./commands/execute/plan-validate.mjs",
|
|
130
144
|
export: "run",
|
|
131
145
|
category: "introspection",
|
|
132
146
|
summary: ["Check an approved-plan file for the approval marker"],
|
|
133
147
|
},
|
|
134
148
|
{
|
|
135
149
|
name: "render-bundle",
|
|
136
|
-
module: "./render-bundle.mjs",
|
|
150
|
+
module: "./commands/execute/render-bundle.mjs",
|
|
137
151
|
export: "run",
|
|
138
152
|
category: "introspection",
|
|
139
153
|
summary: [
|
|
@@ -143,14 +157,14 @@ export const COMMAND_REGISTRY = [
|
|
|
143
157
|
},
|
|
144
158
|
{
|
|
145
159
|
name: "run",
|
|
146
|
-
module: "./run.mjs",
|
|
160
|
+
module: "./commands/execute/run.mjs",
|
|
147
161
|
export: "run",
|
|
148
162
|
category: "introspection",
|
|
149
163
|
summary: ["Host-aware auto execution front door"],
|
|
150
164
|
},
|
|
151
165
|
{
|
|
152
166
|
name: "codex-run",
|
|
153
|
-
module: "./codex-run.mjs",
|
|
167
|
+
module: "./commands/execute/codex-run.mjs",
|
|
154
168
|
export: "run",
|
|
155
169
|
category: "introspection",
|
|
156
170
|
summary: [
|
|
@@ -160,21 +174,21 @@ export const COMMAND_REGISTRY = [
|
|
|
160
174
|
},
|
|
161
175
|
{
|
|
162
176
|
name: "codex-dispatch",
|
|
163
|
-
module: "./codex-dispatch.mjs",
|
|
177
|
+
module: "./commands/execute/codex-dispatch.mjs",
|
|
164
178
|
export: "run",
|
|
165
179
|
category: "introspection",
|
|
166
180
|
summary: ["Dispatch CLI-backed workers for a prepared Codex run"],
|
|
167
181
|
},
|
|
168
182
|
{
|
|
169
183
|
name: "team",
|
|
170
|
-
module: "./team.mjs",
|
|
184
|
+
module: "./commands/execute/team.mjs",
|
|
171
185
|
export: "run",
|
|
172
186
|
category: "introspection",
|
|
173
187
|
summary: ["Dispatch and await tmux-pane workers for external leads"],
|
|
174
188
|
},
|
|
175
189
|
{
|
|
176
190
|
name: "wizard",
|
|
177
|
-
module: "./wizard.mjs",
|
|
191
|
+
module: "./commands/execute/wizard.mjs",
|
|
178
192
|
export: "run",
|
|
179
193
|
category: "introspection",
|
|
180
194
|
summary: [
|
|
@@ -184,7 +198,7 @@ export const COMMAND_REGISTRY = [
|
|
|
184
198
|
},
|
|
185
199
|
{
|
|
186
200
|
name: "token-usage",
|
|
187
|
-
module: "./token-usage.mjs",
|
|
201
|
+
module: "./commands/execute/token-usage.mjs",
|
|
188
202
|
export: "run",
|
|
189
203
|
category: "introspection",
|
|
190
204
|
summary: [
|
|
@@ -195,42 +209,42 @@ export const COMMAND_REGISTRY = [
|
|
|
195
209
|
},
|
|
196
210
|
{
|
|
197
211
|
name: "render-views",
|
|
198
|
-
module: "./render-views.mjs",
|
|
212
|
+
module: "./commands/report/render-views.mjs",
|
|
199
213
|
export: "run",
|
|
200
214
|
category: "introspection",
|
|
201
215
|
summary: ["Render slim AI + self-contained HTML views of a final report"],
|
|
202
216
|
},
|
|
203
217
|
{
|
|
204
218
|
name: "render-final-report",
|
|
205
|
-
module: "./render-final-report.mjs",
|
|
219
|
+
module: "./commands/report/render-final-report.mjs",
|
|
206
220
|
export: "run",
|
|
207
221
|
category: "introspection",
|
|
208
222
|
summary: ["Render the markdown sibling of a final-report data.json"],
|
|
209
223
|
},
|
|
210
224
|
{
|
|
211
225
|
name: "inject-report-index",
|
|
212
|
-
module: "./inject-report-index.mjs",
|
|
226
|
+
module: "./commands/report/inject-report-index.mjs",
|
|
213
227
|
export: "run",
|
|
214
228
|
category: "introspection",
|
|
215
229
|
summary: ["Add the top-of-report Index + scroll anchors to a report"],
|
|
216
230
|
},
|
|
217
231
|
{
|
|
218
232
|
name: "spawn-followups",
|
|
219
|
-
module: "./spawn-followups.mjs",
|
|
233
|
+
module: "./commands/execute/spawn-followups.mjs",
|
|
220
234
|
export: "run",
|
|
221
235
|
category: "introspection",
|
|
222
236
|
summary: ["Create follow-up task bundles from a final report"],
|
|
223
237
|
},
|
|
224
238
|
{
|
|
225
239
|
name: "error-log",
|
|
226
|
-
module: "./error-log.mjs",
|
|
240
|
+
module: "./commands/execute/error-log.mjs",
|
|
227
241
|
export: "run",
|
|
228
242
|
category: "introspection",
|
|
229
243
|
summary: ["Append run error events to the run error log"],
|
|
230
244
|
},
|
|
231
245
|
{
|
|
232
246
|
name: "memory",
|
|
233
|
-
module: "./memory.mjs",
|
|
247
|
+
module: "./commands/memory/memory.mjs",
|
|
234
248
|
export: "run",
|
|
235
249
|
category: "introspection",
|
|
236
250
|
summary: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
2
|
-
import { resolvePaths } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
3
3
|
|
|
4
4
|
const USAGE = `okstra codex-dispatch — dispatch CLI-backed workers for a prepared Codex run
|
|
5
5
|
|
|
@@ -66,5 +66,5 @@ export async function run(args) {
|
|
|
66
66
|
args: buildCodexDispatchArgs(args, paths),
|
|
67
67
|
stdio: "inherit-stdout",
|
|
68
68
|
});
|
|
69
|
-
return result.code
|
|
69
|
+
return result.code;
|
|
70
70
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
2
|
-
import { resolvePaths } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
3
3
|
|
|
4
4
|
const USAGE = `okstra codex-run — prepare a render-only Codex lead task bundle
|
|
5
5
|
|
|
@@ -64,5 +64,5 @@ export async function run(args) {
|
|
|
64
64
|
args: buildCodexRunArgs(args, paths.workspace),
|
|
65
65
|
stdio: "inherit-stdout",
|
|
66
66
|
});
|
|
67
|
-
return result.code
|
|
67
|
+
return result.code;
|
|
68
68
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
2
|
|
|
3
3
|
const USAGE = `okstra handoff — release-handoff stage-group 보조 (자격/수집/기록)
|
|
4
4
|
|
|
@@ -13,6 +13,8 @@ Usage:
|
|
|
13
13
|
--report-path <md> --data-json <json>
|
|
14
14
|
okstra handoff record-pr --plan-run-root <dir> --stages 2,3 \\
|
|
15
15
|
--branch <b> --url <u>
|
|
16
|
+
okstra handoff local-checkout --project-root <dir> --project-id <id> \\
|
|
17
|
+
--task-group <g> --task-id <t>
|
|
16
18
|
|
|
17
19
|
Exit codes: 0 ok / 1 자격·전제 위반 / 2 stage 간 merge 충돌(conflicts 동봉)
|
|
18
20
|
`;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
|
|
3
|
+
const USAGE = `okstra integrate-stages — stage 들을 task 브랜치에 통합 머지 + worktree 정리
|
|
4
|
+
|
|
5
|
+
A thin shim over \`python3 -m okstra_ctl.stage_integrate\`.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
okstra integrate-stages --project-id <id> \\
|
|
9
|
+
--task-group <g> --task-id <t> --plan-run-root <dir> \\
|
|
10
|
+
--task-worktree-path <dir> [--stage-map-json '<json>']
|
|
11
|
+
|
|
12
|
+
Exit codes: 0 ok / 2 stage 간 merge 충돌 / 1 python 프로세스 비정상 종료(폴백)
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export async function run(args) {
|
|
16
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
17
|
+
process.stdout.write(USAGE);
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
const { code } = await runPythonModule({
|
|
21
|
+
module: "okstra_ctl.stage_integrate",
|
|
22
|
+
args,
|
|
23
|
+
});
|
|
24
|
+
return code ?? 1;
|
|
25
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
2
|
-
import { resolvePaths } from "
|
|
3
|
-
import { resolveRuntime } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
3
|
+
import { resolveRuntime } from "../../lib/runtime-resolver.mjs";
|
|
4
4
|
|
|
5
5
|
const USAGE = `okstra render-bundle — preview the task bundle without launching claude
|
|
6
6
|
|
|
@@ -107,5 +107,5 @@ export async function run(args) {
|
|
|
107
107
|
args: finalArgs,
|
|
108
108
|
stdio: "inherit-stdout",
|
|
109
109
|
});
|
|
110
|
-
return result.code
|
|
110
|
+
return result.code;
|
|
111
111
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { runEnsureInstalled } from "
|
|
2
|
-
import { runPythonModule } from "
|
|
3
|
-
import { resolvePaths } from "
|
|
4
|
-
import { resolveRuntime } from "
|
|
1
|
+
import { runEnsureInstalled } from "../lifecycle/install.mjs";
|
|
2
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
3
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
4
|
+
import { resolveRuntime } from "../../lib/runtime-resolver.mjs";
|
|
5
5
|
|
|
6
6
|
const USAGE = `okstra run — host-aware okstra execution front door
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
2
|
-
import { resolvePaths } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
3
3
|
|
|
4
4
|
const USAGE = `okstra team — dispatch and await tmux-pane workers for external leads
|
|
5
5
|
|
|
@@ -59,5 +59,5 @@ export async function run(args) {
|
|
|
59
59
|
args: buildTeamArgs(args, paths),
|
|
60
60
|
stdio: "inherit-stdout",
|
|
61
61
|
});
|
|
62
|
-
return result.code
|
|
62
|
+
return result.code;
|
|
63
63
|
}
|
|
@@ -2,8 +2,8 @@ import { mkdtempSync } from "node:fs";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
5
|
-
import { runPythonModule } from "
|
|
6
|
-
import { resolvePaths } from "
|
|
5
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
6
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
7
7
|
|
|
8
8
|
const USAGE = `okstra wizard — interactive okstra-run input collector
|
|
9
9
|
|
|
@@ -31,19 +31,28 @@ All subcommands emit a single JSON object on stdout. On validation failure
|
|
|
31
31
|
'step' returns {ok:false, error, current} so the skill can re-prompt.
|
|
32
32
|
`;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
// Every wizard flag takes a value (there are no boolean flags), so the token
|
|
35
|
+
// after a flag is always its value — even free-text answers that begin with
|
|
36
|
+
// "--". A heuristic that rejects "--"-prefixed values would make legitimate
|
|
37
|
+
// directive/base-ref answers unsubmittable. The inline "--key=value" form lets
|
|
38
|
+
// callers pass any value (including empty) unambiguously.
|
|
39
|
+
export function parseFlags(args) {
|
|
35
40
|
const out = {};
|
|
36
41
|
for (let i = 0; i < args.length; i += 1) {
|
|
37
42
|
const a = args[i];
|
|
38
43
|
if (!a.startsWith("--")) {
|
|
39
44
|
throw new Error(`unexpected positional argument: ${a}`);
|
|
40
45
|
}
|
|
46
|
+
const eq = a.indexOf("=");
|
|
47
|
+
if (eq !== -1) {
|
|
48
|
+
out[a.slice(2, eq)] = a.slice(eq + 1);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
41
51
|
const key = a.slice(2);
|
|
42
|
-
|
|
43
|
-
if (next === undefined || next.startsWith("--")) {
|
|
52
|
+
if (i + 1 >= args.length) {
|
|
44
53
|
throw new Error(`flag --${key} requires a value`);
|
|
45
54
|
}
|
|
46
|
-
out[key] =
|
|
55
|
+
out[key] = args[i + 1];
|
|
47
56
|
i += 1;
|
|
48
57
|
}
|
|
49
58
|
return out;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
2
|
|
|
3
3
|
const USAGE = `okstra context-cost — estimate context/read cost for a task bundle
|
|
4
4
|
|
|
@@ -23,5 +23,5 @@ export async function run(args) {
|
|
|
23
23
|
args,
|
|
24
24
|
stdio: "inherit-stdout",
|
|
25
25
|
});
|
|
26
|
-
return result.code
|
|
26
|
+
return result.code;
|
|
27
27
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
2
|
|
|
3
3
|
const USAGE = `okstra error-report — aggregate okstra-run error logs into a task report
|
|
4
4
|
|
|
@@ -23,5 +23,5 @@ export async function run(args) {
|
|
|
23
23
|
args,
|
|
24
24
|
stdio: "inherit-stdout",
|
|
25
25
|
});
|
|
26
|
-
return result.code
|
|
26
|
+
return result.code;
|
|
27
27
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
|
+
|
|
3
|
+
const USAGE = `okstra error-zip — bundle cross-project okstra error logs into a zip
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
okstra error-zip --out <path>
|
|
7
|
+
|
|
8
|
+
Walks the global run-index (~/.okstra/recent.jsonl + active.jsonl), collects
|
|
9
|
+
every target project's runs/*/logs/errors-*.jsonl, anonymizes records, and
|
|
10
|
+
writes a .zip (report.md + errors/anonymized.jsonl) to <path>. Read-only
|
|
11
|
+
against every target's .okstra/. Prints a JSON summary to stdout.
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export async function run(args) {
|
|
15
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
16
|
+
process.stdout.write(USAGE);
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
const result = await runPythonModule({
|
|
20
|
+
module: "okstra_ctl.error_zip",
|
|
21
|
+
args,
|
|
22
|
+
stdio: "inherit-stdout",
|
|
23
|
+
});
|
|
24
|
+
return result.code;
|
|
25
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { runPythonModule } from "
|
|
1
|
+
import { runPythonModule } from "../../lib/python-helper.mjs";
|
|
2
2
|
|
|
3
3
|
const USAGE = `okstra recap — assemble a task's run-to-run phase recap, or append a recap log entry
|
|
4
4
|
|
|
@@ -23,5 +23,5 @@ export async function run(args) {
|
|
|
23
23
|
args,
|
|
24
24
|
stdio: "inherit-stdout",
|
|
25
25
|
});
|
|
26
|
-
return result.code
|
|
26
|
+
return result.code;
|
|
27
27
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { buildPythonpath, resolvePaths } from "
|
|
4
|
-
import { fileExists, runProcess } from "
|
|
3
|
+
import { buildPythonpath, resolvePaths } from "../../lib/paths.mjs";
|
|
4
|
+
import { fileExists, runProcess } from "../../lib/proc.mjs";
|
|
5
5
|
|
|
6
6
|
const USAGE = `okstra check-project — verify that the current project has okstra setup
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { dirname, join, resolve, isAbsolute } from "node:path";
|
|
4
|
-
import { buildPythonpath, resolvePaths } from "
|
|
5
|
-
import { OKSTRA_DIR, projectJsonPath } from "
|
|
6
|
-
import { fileExists, runProcess } from "
|
|
4
|
+
import { buildPythonpath, resolvePaths } from "../../lib/paths.mjs";
|
|
5
|
+
import { OKSTRA_DIR, projectJsonPath } from "../../lib/okstra-dirs.mjs";
|
|
6
|
+
import { fileExists, runProcess } from "../../lib/proc.mjs";
|
|
7
7
|
|
|
8
8
|
const USAGE = `okstra config — read / write okstra settings (project + global scopes)
|
|
9
9
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { resolvePaths } from "
|
|
5
|
-
import { fileExists, runProcess } from "
|
|
6
|
-
import { runPythonSnippet } from "
|
|
4
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
5
|
+
import { fileExists, runProcess } from "../../lib/proc.mjs";
|
|
6
|
+
import { runPythonSnippet } from "../../lib/python-helper.mjs";
|
|
7
7
|
import { runtimeIncludesClaudeAssets, validateInstallRuntime } from "./install.mjs";
|
|
8
|
-
import { resolveRuntime } from "
|
|
8
|
+
import { resolveRuntime } from "../../lib/runtime-resolver.mjs";
|
|
9
9
|
|
|
10
10
|
const CLAUDE_SKILLS_DIR = join(homedir(), ".claude", "skills");
|
|
11
11
|
const REQUIRED_SKILLS = ["okstra-setup", "okstra-run"];
|
|
@@ -2,12 +2,12 @@ import { promises as fs } from "node:fs";
|
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join, relative, resolve as resolveAbs } from "node:path";
|
|
5
|
-
import { getPackageRoot } from "
|
|
6
|
-
import { resolvePaths } from "
|
|
7
|
-
import { fileExists } from "
|
|
8
|
-
import { buildRuntimeManifest, RUNTIMES_MANIFEST_REL } from "
|
|
9
|
-
import { normalizeRuntimeRequest, resolveRuntime } from "
|
|
10
|
-
import { OBSOLETE_INTERNAL_SKILL_NAMES, USER_SKILL_NAMES } from "
|
|
5
|
+
import { getPackageRoot } from "../../lib/version.mjs";
|
|
6
|
+
import { resolvePaths } from "../../lib/paths.mjs";
|
|
7
|
+
import { fileExists } from "../../lib/proc.mjs";
|
|
8
|
+
import { buildRuntimeManifest, RUNTIMES_MANIFEST_REL } from "../../lib/runtime-manifest.mjs";
|
|
9
|
+
import { normalizeRuntimeRequest, resolveRuntime } from "../../lib/runtime-resolver.mjs";
|
|
10
|
+
import { OBSOLETE_INTERNAL_SKILL_NAMES, USER_SKILL_NAMES } from "../../lib/skill-catalog.mjs";
|
|
11
11
|
|
|
12
12
|
const SKILLS_MANIFEST_REL = "installed-skills.json";
|
|
13
13
|
const AGENTS_MANIFEST_REL = "installed-agents.json";
|
|
@@ -284,16 +284,21 @@ async function ensureSymlink(target, linkPath, opts) {
|
|
|
284
284
|
return "linked";
|
|
285
285
|
}
|
|
286
286
|
await fs.mkdir(join(linkPath, ".."), { recursive: true });
|
|
287
|
+
// readlink returns EINVAL for both a missing link and an existing non-symlink
|
|
288
|
+
// file, so unlink alone would silently destroy a real file. lstat lets us
|
|
289
|
+
// refuse to clobber any existing entry that is not a symlink.
|
|
290
|
+
let existing;
|
|
287
291
|
try {
|
|
288
|
-
await fs.
|
|
292
|
+
existing = await fs.lstat(linkPath);
|
|
289
293
|
} catch (err) {
|
|
290
|
-
if (err.code !== "ENOENT")
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
)
|
|
295
|
-
|
|
294
|
+
if (err.code !== "ENOENT") throw err;
|
|
295
|
+
}
|
|
296
|
+
if (existing && !existing.isSymbolicLink()) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
`refuse to replace ${linkPath} (not a symlink). Remove it manually and retry, or run 'okstra uninstall' first.`,
|
|
299
|
+
);
|
|
296
300
|
}
|
|
301
|
+
if (existing) await fs.unlink(linkPath);
|
|
297
302
|
await fs.symlink(target, linkPath);
|
|
298
303
|
return "linked";
|
|
299
304
|
}
|