okstra 0.122.0 → 0.124.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.md +5 -2
- package/docs/architecture/storage-model.md +15 -1
- package/docs/architecture.md +45 -7
- package/docs/cli.md +47 -5
- package/docs/for-ai/README.md +42 -36
- package/docs/for-ai/skills/okstra-brief-gen.md +105 -105
- package/docs/for-ai/skills/okstra-container-build.md +61 -61
- package/docs/for-ai/skills/okstra-graphify.md +64 -0
- package/docs/for-ai/skills/okstra-inspect.md +86 -86
- package/docs/for-ai/skills/okstra-manager.md +32 -32
- package/docs/for-ai/skills/okstra-memory.md +49 -50
- package/docs/for-ai/skills/okstra-pr-gen.md +48 -0
- package/docs/for-ai/skills/okstra-rollup.md +58 -58
- package/docs/for-ai/skills/okstra-run.md +95 -95
- package/docs/for-ai/skills/okstra-schedule-gen.md +320 -0
- package/docs/for-ai/skills/okstra-setup.md +63 -64
- package/docs/for-ai/skills/okstra-user-response.md +48 -0
- package/docs/performance-improvement-plan-v2.md +4 -4
- package/docs/pr-template-usage.md +34 -34
- package/docs/project-structure-overview.md +92 -70
- package/docs/task-process/README.md +33 -33
- package/docs/task-process/common-flow.md +26 -26
- package/docs/task-process/error-analysis.md +20 -21
- package/docs/task-process/final-verification.md +41 -41
- package/docs/task-process/implementation-planning.md +52 -28
- package/docs/task-process/implementation.md +51 -32
- package/docs/task-process/release-handoff.md +46 -46
- package/docs/task-process/requirements-discovery.md +22 -23
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +4 -4
- package/runtime/agents/workers/claude-worker.md +2 -2
- package/runtime/agents/workers/codex-worker.md +4 -4
- package/runtime/agents/workers/report-writer-worker.md +4 -4
- package/runtime/bin/lib/okstra/usage.sh +3 -3
- package/runtime/prompts/coding-preflight/frameworks/node-server.md +1 -1
- package/runtime/prompts/launch.template.md +6 -3
- package/runtime/prompts/lead/convergence.md +11 -21
- package/runtime/prompts/lead/okstra-lead-contract.md +16 -18
- package/runtime/prompts/lead/plan-body-verification.md +47 -18
- package/runtime/prompts/lead/report-writer.md +50 -45
- package/runtime/prompts/lead/team-contract.md +11 -122
- package/runtime/prompts/profiles/_common-contract.md +15 -22
- package/runtime/prompts/profiles/_implementation-deliverable.md +4 -2
- package/runtime/prompts/profiles/_implementation-executor.md +6 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
- package/runtime/prompts/profiles/error-analysis.md +2 -2
- package/runtime/prompts/profiles/final-verification.md +3 -1
- package/runtime/prompts/profiles/implementation-planning.md +24 -14
- package/runtime/prompts/profiles/implementation.md +1 -1
- package/runtime/prompts/profiles/improvement-discovery.md +1 -1
- package/runtime/prompts/profiles/release-handoff.md +3 -3
- package/runtime/prompts/profiles/requirements-discovery.md +18 -18
- package/runtime/prompts/wizard/prompts.ko.json +44 -0
- package/runtime/python/okstra_ctl/codex_dispatch.py +23 -1
- package/runtime/python/okstra_ctl/design_prep.py +1462 -0
- package/runtime/python/okstra_ctl/design_surfaces.py +243 -0
- package/runtime/python/okstra_ctl/final_report_schema.py +33 -1
- package/runtime/python/okstra_ctl/implementation_stage.py +35 -0
- package/runtime/python/okstra_ctl/incremental_carry.py +294 -21
- package/runtime/python/okstra_ctl/incremental_scope.py +51 -5
- package/runtime/python/okstra_ctl/material.py +1 -1
- package/runtime/python/okstra_ctl/model_discovery.py +98 -0
- package/runtime/python/okstra_ctl/models.py +8 -3
- package/runtime/python/okstra_ctl/render.py +5 -0
- package/runtime/python/okstra_ctl/run.py +53 -5
- package/runtime/python/okstra_ctl/user_response.py +67 -2
- package/runtime/python/okstra_ctl/wizard.py +283 -3
- package/runtime/python/okstra_token_usage/report.py +11 -0
- package/runtime/schemas/final-report-v1.0.schema.json +336 -0
- package/runtime/skills/_fragments/bash-invocation-rule.md +1 -0
- package/runtime/skills/_fragments/preflight-outdated-cli.md +1 -0
- package/runtime/skills/_fragments/python-bootstrap-note.md +1 -0
- package/runtime/skills/okstra-brief-gen/SKILL.md +117 -122
- package/runtime/skills/okstra-container-build/SKILL.md +24 -14
- package/runtime/skills/okstra-graphify/SKILL.md +12 -4
- package/runtime/skills/okstra-inspect/SKILL.md +105 -99
- package/runtime/skills/okstra-manager/SKILL.md +1 -1
- package/runtime/skills/okstra-memory/SKILL.md +3 -3
- package/runtime/skills/okstra-rollup/SKILL.md +12 -6
- package/runtime/skills/okstra-run/SKILL.md +49 -88
- package/runtime/skills/{okstra-schedule → okstra-schedule-gen}/SKILL.md +38 -32
- package/runtime/skills/okstra-setup/SKILL.md +1 -1
- package/runtime/skills/okstra-setup/references/project-config.md +17 -16
- package/runtime/skills/okstra-usage/SKILL.md +5 -2
- package/runtime/skills/okstra-user-response/SKILL.md +23 -9
- package/runtime/templates/prd/brief.template.md +92 -92
- package/runtime/templates/reports/error-analysis-input.template.md +1 -1
- package/runtime/templates/reports/fan-out-unit.template.md +6 -6
- package/runtime/templates/reports/final-report.template.md +67 -0
- package/runtime/templates/reports/final-verification-input.template.md +6 -6
- package/runtime/templates/reports/i18n/en.json +31 -0
- package/runtime/templates/reports/i18n/ko.json +31 -0
- package/runtime/templates/reports/implementation-input.template.md +1 -1
- package/runtime/templates/reports/implementation-planning-input.template.md +1 -1
- package/runtime/templates/reports/improvement-discovery-input.template.md +1 -1
- package/runtime/templates/reports/quick-input.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +1 -1
- package/runtime/templates/reports/schedule.template.md +22 -22
- package/runtime/templates/reports/task-brief.template.md +3 -3
- package/runtime/templates/reports/user-response.template.md +20 -20
- package/runtime/templates/worker-prompt-preamble.md +111 -13
- package/runtime/validators/validate-run.py +426 -5
- package/runtime/validators/validate-schedule.py +5 -5
- package/src/cli-registry.mjs +7 -0
- package/src/commands/inspect/design-prep.mjs +23 -0
- package/src/lib/skill-catalog.mjs +2 -1
- package/docs/for-ai/skills/okstra-schedule.md +0 -320
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-inspect
|
|
3
3
|
description: >-
|
|
4
|
-
Use this for everything that happens AFTER a single okstra task has already run — inspecting it or light bookkeeping on it, never launching new work. The tell is usually a named task id (PROD-1623, dev-9184), often dropped without the word "okstra." Reach for it when the user wants one task's: status, current/next phase, blockers, or approval gate; its final report — where it is or whether it passed (
|
|
4
|
+
Use this for everything that happens AFTER a single okstra task has already run — inspecting it or light bookkeeping on it, never launching new work. The tell is usually a named task id (PROD-1623, dev-9184), often dropped without the word "okstra." Reach for it when the user wants one task's: status, current/next phase, blockers, or approval gate; its final report — where it is or whether it passed (verdict / pass); its elapsed time or context/read cost; its run history, re-run, or resume; to mark it done / in-progress / blocked / todo; or a failed run's error logs gathered into a report (error report). Also bundles cross-project okstra errors into an anonymized feedback zip (error feedback). Use it even for a bare "mark it done" or "where's the report." NOT for starting a run (okstra-run), rollups/schedules (okstra-rollup / okstra-schedule-gen), a brief (okstra-brief-gen), setup (okstra-setup), or cross-project management (okstra-manager).
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# OKSTRA Inspect
|
|
@@ -22,7 +22,9 @@ Single read-side entry point for okstra runtime inspection plus the one status m
|
|
|
22
22
|
|
|
23
23
|
## Step 0: Preflight (shared)
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
<!-- BEGIN FRAGMENT: bash-invocation-rule -->
|
|
26
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
27
|
+
<!-- END FRAGMENT: bash-invocation-rule -->
|
|
26
28
|
|
|
27
29
|
```bash
|
|
28
30
|
okstra preflight --runtime claude-code --json
|
|
@@ -32,13 +34,21 @@ The project check only sees the cwd of the Bash call. When the user is asking ab
|
|
|
32
34
|
|
|
33
35
|
Branch on the stdout JSON:
|
|
34
36
|
- `ok: true` → carry `projectRoot` as a literal string; it is the base for every sub-command step below.
|
|
35
|
-
- `ok: false` → before concluding "no setup", ask whether the user pointed at a specific project directory. If they did, re-run targeting it: `okstra preflight --runtime claude-code --cwd <that-dir> --json` (`--cwd` is the sanctioned way to target a project — a leading `cd` would break the permission match). Only if this **also** returns `ok:false` do you tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop.
|
|
37
|
+
- `ok: false` → before concluding "no setup", ask whether the user pointed at a specific project directory. If they did, re-run targeting it: `okstra preflight --runtime claude-code --cwd <that-dir> --json` (`--cwd` is the sanctioned way to target a project — a leading `cd` would break the permission match). Only if this **also** returns `ok:false` do you tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop.
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
<!-- BEGIN FRAGMENT: preflight-outdated-cli -->
|
|
40
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
41
|
+
<!-- END FRAGMENT: preflight-outdated-cli -->
|
|
42
|
+
|
|
43
|
+
Carry the resolved `projectRoot` into the sub-commands: read file artifacts under `<projectRoot>/.okstra/...`, and for sub-command CLIs that accept it (e.g. `recap`, `context-cost`) pass `--cwd <projectRoot>` / `--project-root <projectRoot>` so they target the same project rather than the Bash cwd.
|
|
44
|
+
|
|
45
|
+
<!-- BEGIN FRAGMENT: python-bootstrap-note -->
|
|
46
|
+
Every subsequent `okstra <subcmd>` call self-bootstraps its Python path, so this skill never needs `okstra paths --shell` / `export PYTHONPATH=...`.
|
|
47
|
+
<!-- END FRAGMENT: python-bootstrap-note -->
|
|
38
48
|
|
|
39
49
|
## Step 1: Dispatch by intent
|
|
40
50
|
|
|
41
|
-
Classify the user's request into one sub-command using the trigger table above. If ambiguous (e.g. "okstra
|
|
51
|
+
Classify the user's request into one sub-command using the trigger table above. If ambiguous (e.g. "show me okstra"), ask which facet — do not silently default. After routing, the chosen sub-command's section below governs the rest of the response.
|
|
42
52
|
|
|
43
53
|
When you ask which facet, the option list is **authoritative**: enumerate every sub-command in the `Sub-command | What it does` table above as a numbered text list, in table order, each with its one-line description, and let the user pick by number or name. Never present a hand-picked subset — the AskUserQuestion 4-option cap is not a reason to drop facets; render the full menu as text in the question body so no facet (e.g. a newly added one) is ever hidden. The table is the single source of truth for this menu; adding a row there is all it takes for the facet to appear here.
|
|
44
54
|
|
|
@@ -48,7 +58,7 @@ When the user chains multiple facets in one message (e.g. "status, and then time
|
|
|
48
58
|
|
|
49
59
|
## status
|
|
50
60
|
|
|
51
|
-
Trigger phrases: "okstra status", "task status", "current phase", "next phase", "what is pending", "resume point", "okstra status set", "okstra mark", "<task-id> done", "<task-id> in-progress", "<task-id>
|
|
61
|
+
Trigger phrases: "okstra status", "task status", "current phase", "next phase", "what is pending", "resume point", "okstra status set", "okstra mark", "<task-id> done", "<task-id> in-progress", "<task-id> in progress", "<task-id> complete".
|
|
52
62
|
|
|
53
63
|
### status.1 — Overall project status
|
|
54
64
|
|
|
@@ -64,7 +74,7 @@ Read `.okstra/discovery/task-catalog.json`. The catalog is the authoritative sou
|
|
|
64
74
|
| `currentPhaseState` | lifecycle phase state |
|
|
65
75
|
| `nextRecommendedPhase` | next recommended phase |
|
|
66
76
|
| `routingStatus` | routing decision status |
|
|
67
|
-
| `awaitingApproval` |
|
|
77
|
+
| `awaitingApproval` | whether awaiting approval |
|
|
68
78
|
| `latestRunStatus` | latest run status |
|
|
69
79
|
| `latestReportPath` | latest report path |
|
|
70
80
|
| `latestResumeCommandPath` | latest resume command |
|
|
@@ -149,7 +159,7 @@ Recognize requests to change a task's `workStatus` and update the corresponding
|
|
|
149
159
|
|
|
150
160
|
**Trigger patterns** (recognize both):
|
|
151
161
|
|
|
152
|
-
Natural language: "DEV-6827 done
|
|
162
|
+
Natural language: "change DEV-6827 to done", "mark PROD-1623 as blocked", "set DEV-9047 in progress", "Mark DEV-6827 as done".
|
|
153
163
|
|
|
154
164
|
Explicit phrasing (recognized user utterances — normalize each to a `okstra set-work-status` call below):
|
|
155
165
|
- `okstra status set <task-id> <status>`
|
|
@@ -166,14 +176,14 @@ okstra set-work-status <token> <status> --project-root <projectRoot> --json
|
|
|
166
176
|
```
|
|
167
177
|
|
|
168
178
|
- `<token>` is a full task-key or a bare task-id. Add `--task-group <group>` to scope a duplicated id, `--note "<note>"` to set `workStatusNote` (flag omitted → any existing note is left untouched).
|
|
169
|
-
- Branch on the stdout JSON: `ok: true` → confirm below. `stage: "ambiguous"` → list `matches[]` (with `_matchedVia`) via a 3-option picker and retry with the chosen full task-key. `stage: "not-found"` → `<TASK-ID
|
|
179
|
+
- Branch on the stdout JSON: `ok: true` → confirm below. `stage: "ambiguous"` → list `matches[]` (with `_matchedVia`) via a 3-option picker and retry with the chosen full task-key. `stage: "not-found"` → `<TASK-ID> cannot be found.` An invalid `<status>` makes the CLI exit 2 with the allowed-values list — surface it verbatim; nothing was modified.
|
|
170
180
|
|
|
171
181
|
Confirm in Korean:
|
|
172
182
|
```
|
|
173
183
|
✓ <TASK-ID> workStatus: <previousWorkStatus> → <workStatus>
|
|
174
|
-
✓ task-manifest.json
|
|
184
|
+
✓ task-manifest.json updated
|
|
175
185
|
```
|
|
176
|
-
`<previousWorkStatus>` = `(
|
|
186
|
+
`<previousWorkStatus>` = `(none)` when the JSON's `previousWorkStatus` is empty.
|
|
177
187
|
|
|
178
188
|
**Default value convention:** if `workStatus` is missing or empty, infer the display value from lifecycle state (DO NOT default to a static `in-progress`):
|
|
179
189
|
|
|
@@ -186,13 +196,13 @@ Confirm in Korean:
|
|
|
186
196
|
|
|
187
197
|
Annotate inferred values with `(inferred)` or `(default)`. Do not back-fill on read; only write when the user explicitly issues an update.
|
|
188
198
|
|
|
189
|
-
**Catalog sync note:** the CLI updates `task-manifest.json` only. `discovery/task-catalog.json` may be stale until the next run regenerates it; downstream consumers (e.g. `okstra-schedule`) re-read each manifest directly.
|
|
199
|
+
**Catalog sync note:** the CLI updates `task-manifest.json` only. `discovery/task-catalog.json` may be stale until the next run regenerates it; downstream consumers (e.g. `okstra-schedule-gen`) re-read each manifest directly.
|
|
190
200
|
|
|
191
201
|
---
|
|
192
202
|
|
|
193
203
|
## history
|
|
194
204
|
|
|
195
|
-
Trigger phrases: "okstra history", "past runs", "run history", "re-run", "list tasks", "
|
|
205
|
+
Trigger phrases: "okstra history", "past runs", "run history", "re-run", "list tasks", "run again", "resume", "continue".
|
|
196
206
|
|
|
197
207
|
**Re-run vs Resume — decide upfront.** Re-run = start a fresh run (new run-seq, new manifest, new report) reusing an old run's parameters → `history.3`. Resume = continue an interrupted Claude session for an existing run, no new run-seq → `history.4`. If the user is ambiguous, ask — defaulting to the wrong one either wastes a fresh run-seq or silently abandons a recoverable session.
|
|
198
208
|
|
|
@@ -293,7 +303,7 @@ Lookup methods (in priority order):
|
|
|
293
303
|
|
|
294
304
|
A. **`task-catalog.json` (fast):** read `.okstra/discovery/task-catalog.json`, match `taskKey` lowercase. `latestReportPath` is task-type-agnostic "most recent report".
|
|
295
305
|
|
|
296
|
-
B. **`task-manifest.json` (direct):** if catalog missing, slugify task-group / task-id, read `.okstra/tasks/<group-segment>/<id-segment>/task-manifest.json`, use `latestReportPath` (task-type-agnostic).
|
|
306
|
+
B. **`task-manifest.json` (direct):** if catalog missing, slugify task-group / task-id, read `.okstra/tasks/<group-segment>/<task-id-segment>/task-manifest.json`, use `latestReportPath` (task-type-agnostic).
|
|
297
307
|
|
|
298
308
|
C. **`timeline.json` (specific run):** for a specific date or run, read `.okstra/tasks/<group-segment>/<id-segment>/history/timeline.json`, filter `runs[]` by `runTimestamp` / `status` / `taskType`, use `runs[].reportPath`.
|
|
299
309
|
|
|
@@ -304,23 +314,23 @@ D. **Specific task-type (fallback):** `latestReportPath` is task-type-agnostic.
|
|
|
304
314
|
1. Verify `latestReportPath` is non-empty AND the file exists on disk. Either signal indicates report presence (tolerant).
|
|
305
315
|
2. If present, display the path and ask the user whether to read it.
|
|
306
316
|
3. If absent, check `task-manifest.json` signals:
|
|
307
|
-
- `latestReportPath` empty/missing AND `currentStatus != completed` AND `workStatus != done` AND `workflow.routingStatus` not completion-like →
|
|
308
|
-
- Any signal indicates completion but the file is missing →
|
|
317
|
+
- `latestReportPath` empty/missing AND `currentStatus != completed` AND `workStatus != done` AND `workflow.routingStatus` not completion-like → `This task is not yet complete (currentStatus: <currentStatus>, workStatus: <workStatus>).`
|
|
318
|
+
- Any signal indicates completion but the file is missing → `Report file does not exist: <path>`
|
|
309
319
|
|
|
310
320
|
`workStatus` enum: `todo | in-progress | blocked | done`. `currentStatus`: `completed` / `contract-violated` etc. `"completed"` string does NOT exist in `workStatus` — do not confuse the two.
|
|
311
321
|
|
|
312
322
|
### report.3 — Read + next-step guidance
|
|
313
323
|
|
|
314
|
-
Match the depth of read to the request — final reports routinely run 300+ lines / 50K+ tokens, so ingesting the whole file just to answer "
|
|
324
|
+
Match the depth of read to the request — final reports routinely run 300+ lines / 50K+ tokens, so ingesting the whole file just to answer "just the gist" is wasteful:
|
|
315
325
|
|
|
316
|
-
- **Summary / verdict intent** ("
|
|
317
|
-
- **Full-read intent** ("
|
|
326
|
+
- **Summary / verdict intent** ("summary", "just the key points", "conclusion", "did it pass?", "verdict"): do **not** read the whole report first. Read the `final-<task-type-segment>-<NNN>.status` sidecar under `runs/<task-type-segment>/status/` (stage-isolated: `runs/<task-type-segment>/stage-<N>/status/`) for the machine verdict, then read only the report's leading summary block (the first "Overall Verdict" / "Executive" / verdict heading and its body) to quote the gist. Offer to read the full report if the user wants detail.
|
|
327
|
+
- **Full-read intent** ("the whole thing", "read it all", "full body"): ingest the resolved report file.
|
|
318
328
|
|
|
319
329
|
After reading, surface follow-up options:
|
|
320
330
|
|
|
321
|
-
1.
|
|
322
|
-
2.
|
|
323
|
-
3.
|
|
331
|
+
1. **Proceed to implementation:** based on the report's "Recommended Next Steps" section.
|
|
332
|
+
2. **Additional verification:** to launch a new okstra run with the same task-key, assemble the command through the `history` sub-command — it offers the full option set (base-ref, workers, render-only) and renders a host-correct invocation.
|
|
333
|
+
3. **Check related tasks:** if the report references related task-keys, fetch their reports too.
|
|
324
334
|
|
|
325
335
|
### report — Output template
|
|
326
336
|
|
|
@@ -341,7 +351,7 @@ After reading, surface follow-up options:
|
|
|
341
351
|
|
|
342
352
|
## time
|
|
343
353
|
|
|
344
|
-
Trigger phrases: "
|
|
354
|
+
Trigger phrases: "work time", "elapsed time", "time summary", "duration", "elapsed", "how long did it take", "time analysis".
|
|
345
355
|
|
|
346
356
|
Aggregate elapsed work time for a task, grouped by **task type** and broken down by **worker** (lead + each worker). The `time-report` CLI reads both data sources (`history/timeline.json` runs + each run's `team-state-*.json` usage blocks) and does **all** aggregation — cross-run sums, CPU-sum vs wall-clock, timestamp parsing, unavailable detection. You only resolve the task-key, call it, and render. **Never recompute durations by hand.**
|
|
347
357
|
|
|
@@ -368,7 +378,7 @@ Convert every `*Ms` to `HH:MM:SS` (zero-pad; never show raw ms). Task types in `
|
|
|
368
378
|
|
|
369
379
|
- **By task type** — `| Task type | Runs | CPU sum | Lead | Workers |` from `byTaskType`, plus a `grandTotal` row. `CPU sum` (= Lead + Workers) overlaps because workers run inside the lead's window — it is *not* wall-clock. Surface wall-clock only when the user explicitly asks, from `perRunWallClock`.
|
|
370
380
|
- **Per worker** (per task type) — `| Worker | Runs | Total | Avg/run |` from `perWorker`. Render the worker as bare `workerId` when `agents` is empty, else `workerId (agent1, agent2)`.
|
|
371
|
-
- **Phase breakdown** — "
|
|
381
|
+
- **Phase breakdown** — "by stage"/"per stage"/"which stage took longest" in okstra most often means the **lifecycle stage (task-type)** view, which the *By task type* table above already answers — lead with that table, do not treat the request as unanswerable. Render the intra-run phase timeline only when the user clearly means within-a-run phases ("which phase", "Phase 1~7", "phase timeline"): one table per run from `phaseTimelines`: `| Phase | Start | Wall to next |` using `firstAt`/`wallMsToNext` (`null` → `--`). When `phaseTimelines` is empty, do **not** headline "not measurable" — the By-task-type table is the stage answer; mention the missing intra-run markers only as a trailing footnote.
|
|
372
382
|
- If `unavailable[]` is non-empty, append a trailing note listing each run with its reason. Never fold them into totals.
|
|
373
383
|
- Show the resolved `<task-key>` in the heading.
|
|
374
384
|
|
|
@@ -396,7 +406,7 @@ Convert every `*Ms` to `HH:MM:SS` (zero-pad; never show raw ms). Task types in `
|
|
|
396
406
|
|
|
397
407
|
## cost
|
|
398
408
|
|
|
399
|
-
Trigger phrases: "okstra context-cost", "context cost", "context-cost", "
|
|
409
|
+
Trigger phrases: "okstra context-cost", "context cost", "context-cost", "context cost (Korean)", "read cost", "artifact cost", "task bundle cost", "agent read cost".
|
|
400
410
|
|
|
401
411
|
Read-only estimate of how much file/context surface a prepared task bundle asks the lead, analysis workers, and report-writer to absorb. This sub-command does **not** mutate task artifacts.
|
|
402
412
|
|
|
@@ -423,11 +433,11 @@ okstra resolve-task-key <token> --project-root <projectRoot> --json
|
|
|
423
433
|
```
|
|
424
434
|
|
|
425
435
|
Branch on the stdout JSON `matches[]` — this **standard 0/1/N rule** is referenced by `errors`/`recap` below:
|
|
426
|
-
- **0
|
|
427
|
-
- **1
|
|
428
|
-
- **N
|
|
436
|
+
- **0** → report the task cannot be found. Do not guess.
|
|
437
|
+
- **1** → use that entry's `taskKey`.
|
|
438
|
+
- **N** → list the candidate `taskKey`s (with `updatedAt`, and `_matchedVia` so the user sees which came from a task-id vs a task-group) and ask via a 3-option picker (1–2 recommendations + `Enter directly`), then use the chosen `taskKey`.
|
|
429
439
|
|
|
430
|
-
If the user asks generally ("
|
|
440
|
+
If the user asks generally ("show me the context cost") and does not name a task:
|
|
431
441
|
|
|
432
442
|
1. Read `.okstra/discovery/task-catalog.json`.
|
|
433
443
|
2. If exactly one task exists, use it.
|
|
@@ -492,7 +502,7 @@ Interpretation rules:
|
|
|
492
502
|
|
|
493
503
|
## logs
|
|
494
504
|
|
|
495
|
-
Trigger phrases: "okstra logs", "
|
|
505
|
+
Trigger phrases: "okstra logs", "log status", "log files", "log files", "log size", "log status", "log cleanup", "log cleanup".
|
|
496
506
|
|
|
497
507
|
Read-only inventory of codex/antigravity wrapper log files written next to each prompt history file (`<prompt>.log`). Reports sizes, ages, totals, and suggests cleanup commands. **Does not delete** — the user runs whichever `find … -delete` line they like.
|
|
498
508
|
|
|
@@ -536,31 +546,31 @@ Emit a fenced bash block the user can copy-paste. Do NOT execute. Each block pai
|
|
|
536
546
|
```markdown
|
|
537
547
|
## Cleanup options (manual)
|
|
538
548
|
|
|
539
|
-
#
|
|
549
|
+
# Delete only logs older than 7 days
|
|
540
550
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
541
551
|
-type f -path '*/runs/*/prompts/*.log' -mtime +7 -print # dry-run
|
|
542
552
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
543
553
|
-type f -path '*/runs/*/prompts/*.log' -mtime +7 -delete
|
|
544
554
|
|
|
545
|
-
#
|
|
555
|
+
# Delete only logs older than 30 days
|
|
546
556
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
547
557
|
-type f -path '*/runs/*/prompts/*.log' -mtime +30 -print # dry-run
|
|
548
558
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
549
559
|
-type f -path '*/runs/*/prompts/*.log' -mtime +30 -delete
|
|
550
560
|
|
|
551
|
-
#
|
|
561
|
+
# Delete all logs for a specific task-group (e.g. dev-9388)
|
|
552
562
|
find <PROJECT_ROOT>/.okstra/tasks/dev-9388 \
|
|
553
563
|
-type f -name '*.log' -print # dry-run
|
|
554
564
|
find <PROJECT_ROOT>/.okstra/tasks/dev-9388 \
|
|
555
565
|
-type f -name '*.log' -delete
|
|
556
566
|
|
|
557
|
-
#
|
|
567
|
+
# Delete all logs for a specific task-id (e.g. dev-9428)
|
|
558
568
|
find <PROJECT_ROOT>/.okstra/tasks/*/dev-9428 \
|
|
559
569
|
-type f -name '*.log' -print # dry-run
|
|
560
570
|
find <PROJECT_ROOT>/.okstra/tasks/*/dev-9428 \
|
|
561
571
|
-type f -name '*.log' -delete
|
|
562
572
|
|
|
563
|
-
#
|
|
573
|
+
# Delete everything (caution)
|
|
564
574
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
565
575
|
-type f -path '*/runs/*/prompts/*.log' -print # dry-run
|
|
566
576
|
find <PROJECT_ROOT>/.okstra/tasks \
|
|
@@ -580,7 +590,7 @@ Substitute the literal `<PROJECT_ROOT>` with the resolved absolute path so the c
|
|
|
580
590
|
|
|
581
591
|
## errors
|
|
582
592
|
|
|
583
|
-
Trigger phrases: "okstra errors", "error report", "
|
|
593
|
+
Trigger phrases: "okstra errors", "error report", "error report (Korean)", "error summary", "gather the errors", "clean up failure logs".
|
|
584
594
|
|
|
585
595
|
Aggregate a task's okstra-run error logs (`runs/*/logs/errors-*.jsonl`, lead-observed + worker-reported) into a timestamped markdown report and summarize it. This sub-command renders a **read-derived artifact** (a `.md` file) but never mutates task state (`task-manifest.json`, catalog, timeline).
|
|
586
596
|
|
|
@@ -592,7 +602,7 @@ Accepted target forms (same as `cost`):
|
|
|
592
602
|
2. Bare token (task-id or task-group) — resolve via `okstra resolve-task-key <token> --project-root <projectRoot> --json` and branch on `matches[]` using the standard 0/1/N rule from `cost.1` (0 = not found, 1 = use, N = picker).
|
|
593
603
|
3. Task root path.
|
|
594
604
|
|
|
595
|
-
|
|
605
|
+
If the user asks for an error report without naming a task, apply the same no-task fallback as `cost.1` — list only the placeholder forms and do not ask back: read `.okstra/discovery/task-catalog.json`, use the single task as-is if there is one, and if there are several, list the latest 10 by `updatedAt` as real task-keys and ask (no guessing).
|
|
596
606
|
|
|
597
607
|
### errors.2 — Run the renderer
|
|
598
608
|
|
|
@@ -619,7 +629,7 @@ Parse the stdout JSON and report:
|
|
|
619
629
|
| By agent | `byAgent[]` |
|
|
620
630
|
| Parse-skipped lines | `parseSkipped` |
|
|
621
631
|
|
|
622
|
-
- If `reportPath` is empty AND `totals.errorCount == 0`: report
|
|
632
|
+
- If `reportPath` is empty AND `totals.errorCount == 0`: report `This task has no recorded error logs.` and do not claim a file was written.
|
|
623
633
|
- Otherwise show the `.md` path and offer to read it.
|
|
624
634
|
- If `parseSkipped > 0`, surface it (do not silently hide malformed lines).
|
|
625
635
|
|
|
@@ -641,147 +651,143 @@ Parse the stdout JSON and report:
|
|
|
641
651
|
|---|---:|
|
|
642
652
|
| codex-worker | 2 |
|
|
643
653
|
|
|
644
|
-
<If parseSkipped > 0: "⚠
|
|
654
|
+
<If parseSkipped > 0: "⚠ Parse-skipped lines: <N>">
|
|
645
655
|
```
|
|
646
656
|
|
|
647
657
|
---
|
|
648
658
|
|
|
649
659
|
## error-zip
|
|
650
660
|
|
|
651
|
-
Trigger phrases: "okstra error-zip", "
|
|
661
|
+
Trigger phrases: "okstra error-zip", "error zip", "error feedback", "error bundle", "cross-project errors".
|
|
652
662
|
|
|
653
|
-
|
|
663
|
+
Collect and anonymize the okstra run errors (`runs/*/logs/errors-*.jsonl`) of every target project on the machine into the global run-index, then bundle them as a `.zip` (aggregate report + anonymized JSONL). Read-only over every target's `.okstra/`.
|
|
654
664
|
|
|
655
|
-
### error-zip.1 —
|
|
665
|
+
### error-zip.1 — Decide the output path (picker)
|
|
656
666
|
|
|
657
|
-
|
|
667
|
+
Read the previous output path from `lastOutputPath` in `~/.okstra/error-zip.json`. If that value exists, present it in a 3-option picker:
|
|
658
668
|
|
|
659
|
-
1. (
|
|
660
|
-
(
|
|
661
|
-
2.
|
|
669
|
+
1. (previous path exists) reuse `<lastOutputPath>` — recommended, first option.
|
|
670
|
+
(no previous path) propose the default path `~/okstra-error-feedback-<YYYY-MM-DD>.zip` — recommended.
|
|
671
|
+
2. Enter directly (always the last option).
|
|
662
672
|
|
|
663
|
-
`~/.okstra/error-zip.json`
|
|
673
|
+
Read `~/.okstra/error-zip.json` directly with Read (if absent, treat it as no previous path).
|
|
664
674
|
|
|
665
|
-
### error-zip.2 —
|
|
675
|
+
### error-zip.2 — Run the renderer
|
|
666
676
|
|
|
667
677
|
```bash
|
|
668
|
-
okstra error-zip --out
|
|
678
|
+
okstra error-zip --out <resolved-path>
|
|
669
679
|
```
|
|
670
680
|
|
|
671
|
-
### error-zip.3 —
|
|
681
|
+
### error-zip.3 — Report the summary
|
|
672
682
|
|
|
673
|
-
stdout JSON
|
|
683
|
+
Parse the stdout JSON and report:
|
|
674
684
|
|
|
675
|
-
|
|
|
685
|
+
| Field | Source |
|
|
676
686
|
|---|---|
|
|
677
|
-
|
|
|
678
|
-
|
|
|
679
|
-
|
|
|
680
|
-
|
|
|
681
|
-
|
|
|
682
|
-
|
|
|
687
|
+
| Output zip | `outPath` |
|
|
688
|
+
| Total errors | `errorCount` |
|
|
689
|
+
| Logs (runs) | `runCount` |
|
|
690
|
+
| Unreachable runs | `unreachableRuns` |
|
|
691
|
+
| Cluster count | `clusterCount` |
|
|
692
|
+
| Project count | `projectCount` |
|
|
683
693
|
|
|
684
|
-
- `unreachableRuns > 0
|
|
685
|
-
-
|
|
694
|
+
- If `unreachableRuns > 0`, surface it (no silent omission).
|
|
695
|
+
- End with the next step: "To fix okstra itself with this zip, build a brief with the error-feedback variant of `/okstra-brief-gen`, then run `okstra-run --task-type error-analysis` in the okstra repo."
|
|
686
696
|
|
|
687
697
|
---
|
|
688
698
|
|
|
689
699
|
## recap
|
|
690
700
|
|
|
691
|
-
Trigger phrases: "okstra recap", "recap", "
|
|
701
|
+
Trigger phrases: "okstra recap", "recap", "work summary", "summarize this task", "before/after summary", "explain this work", "task question".
|
|
692
702
|
|
|
693
|
-
|
|
703
|
+
On top of the `.okstra` artifacts accumulated for a single task-id, (a) produce a before/after summary and (b) answer free-form questions about that work. By default it reads only the `.okstra/` subtree (artifact mode). It expands to code mode only when the user explicitly asks to look at the code changes too. This sub-command performs only the `recap/recap-log.jsonl` append and the `notes/` note authoring (recap.5); it never mutates `task-manifest.json` / catalog / timeline.
|
|
694
704
|
|
|
695
705
|
### recap.1 — Resolve target
|
|
696
706
|
|
|
697
|
-
`cost` / `errors
|
|
698
|
-
|
|
699
|
-
사용자가 task 를 지정하지 않고 그냥 recap 을 요청하면(예: "이 작업 요약해줘"), `cost.1` 과 동일한 no-task fallback 을 적용한다 — 절대 `<task-group>` 같은 플레이스홀더 형식만 나열하고 되묻지 않는다:
|
|
707
|
+
The same three forms as `cost` / `errors`: ① full task-key, ② bare token (task-id or task-group → `okstra resolve-task-key <token> --project-root <projectRoot> --json`; the standard 0/1/N branch from `cost.1`), ③ task-root path.
|
|
700
708
|
|
|
701
|
-
|
|
702
|
-
2. task 가 정확히 1개면 그 task 를 그대로 사용한다.
|
|
703
|
-
3. 여러 개면 `updatedAt` 최신 10개를 실제 task-key 로 나열하고 어느 task 인지 물어본다(추측 금지).
|
|
709
|
+
If the user asks for a recap without naming a task (e.g. "summarize this work"), apply the `cost.1` no-task fallback as-is — do not list only a placeholder form like `<task-group>` and ask back; read `.okstra/discovery/task-catalog.json`, use the single task as-is if there is one, and if there are several, list the latest 10 by `updatedAt` as real task-keys and ask (no guessing).
|
|
704
710
|
|
|
705
711
|
### recap.2 — Assemble the before/after summary
|
|
706
712
|
|
|
707
|
-
CLI
|
|
713
|
+
Use the CLI output as the source of truth:
|
|
708
714
|
|
|
709
715
|
```bash
|
|
710
716
|
okstra recap assemble <resolved-target> --project-root <projectRoot>
|
|
711
717
|
```
|
|
712
718
|
|
|
713
|
-
stdout JSON(`{taskKey, runCount, transitions[], latestPhaseStates}`)
|
|
719
|
+
Parse the stdout JSON (`{taskKey, runCount, transitions[], latestPhaseStates}`) and narrate the per-run before/after transitions. For each `transitions[]` entry, show `fromPhase → toPhase` (previous run currentPhase → this run currentPhase), `status`, `lastCompletedPhase`, `nextRecommendedPhase`, and `reportPath` in chronological order. If `runCount == 0`, answer only "This task has no recorded runs." and do not claim to have read any file.
|
|
714
720
|
|
|
715
|
-
`reportPath
|
|
721
|
+
For a run that has a `reportPath`, read that final-report to enrich the summary only when the user wants a deeper one (do not read them all automatically).
|
|
716
722
|
|
|
717
723
|
### recap.3 — Free-form Q&A loop
|
|
718
724
|
|
|
719
|
-
|
|
725
|
+
After the summary output, take the user's free-form questions.
|
|
720
726
|
|
|
721
|
-
- **artifact
|
|
722
|
-
- **code
|
|
727
|
+
- **artifact mode (default)**: answer only from `.okstra/` artifacts (timeline, task-manifest, that run's final-report). Every factual claim is accompanied by a `path:line` citation to the `.okstra` file.
|
|
728
|
+
- **code mode (opt-in)**: only when the user **explicitly asks** — "look at the code changes / the diff too" — additionally read `git diff` · `git log` from that task's worktree/branch and answer at the code level. Entering recap never by itself switches to code mode.
|
|
723
729
|
|
|
724
730
|
### recap.4 — Persist each turn
|
|
725
731
|
|
|
726
|
-
|
|
732
|
+
Log one summary and each Q&A answer (append-only):
|
|
727
733
|
|
|
728
734
|
```bash
|
|
729
735
|
okstra recap record <resolved-target> --project-root <projectRoot> \
|
|
730
736
|
--kind <summary|qa> --mode <artifact|code> \
|
|
731
|
-
--question "
|
|
737
|
+
--question "<question or omit>" --answer "<one or two line summary>" \
|
|
732
738
|
--citation "<path:line>" --citation "<path:line>"
|
|
733
739
|
```
|
|
734
740
|
|
|
735
|
-
`--answer
|
|
741
|
+
Put a one-or-two-line summary in `--answer`, not the full answer transcript. If there are multiple citations, repeat `--citation`. Do not silently swallow a recording failure (abnormal exit) — tell the user.
|
|
736
742
|
|
|
737
743
|
### recap — Output template
|
|
738
744
|
|
|
739
745
|
```markdown
|
|
740
746
|
## okstra Recap — <task-key>
|
|
741
747
|
|
|
742
|
-
|
|
748
|
+
Before/after summary (runs: <N>):
|
|
743
749
|
|
|
744
750
|
| # | when | task-type | from → to | status | next |
|
|
745
751
|
|---|---|---|---|---|---|
|
|
746
|
-
| 1 | <ts> | requirements-discovery | (
|
|
752
|
+
| 1 | <ts> | requirements-discovery | (start) → requirements-discovery | done | error-analysis |
|
|
747
753
|
|
|
748
|
-
|
|
754
|
+
<Free-form questions follow. To include code changes, ask "also show me the diff".>
|
|
749
755
|
```
|
|
750
756
|
|
|
751
|
-
### recap.5 — Agent
|
|
757
|
+
### recap.5 — Agent-authored notes (`notes/`)
|
|
752
758
|
|
|
753
|
-
recap
|
|
759
|
+
Leave something in `notes/` only when, during recap, you produced an artifact **for the okstra task** — verification evidence, a design/decision draft, an analysis note — that may serve as grounding for future runs, and whose content is **neither a rendered report nor a user decision**.
|
|
754
760
|
|
|
755
|
-
|
|
761
|
+
**Route by ownership.** First determine which of the following the thing you are about to write belongs to:
|
|
756
762
|
|
|
757
|
-
|
|
|
763
|
+
| Content | Lane (path) | Author |
|
|
758
764
|
|---|---|---|
|
|
759
|
-
| final report
|
|
760
|
-
|
|
|
761
|
-
|
|
|
762
|
-
| **Agent
|
|
765
|
+
| final report body | `runs/<type>/reports/*.md` (rendered from `*.data.json`) | okstra renderer — never hand-edit |
|
|
766
|
+
| user's answer to a clarification | `runs/<type>/user-responses/*.md` (`created-by: user`) | user only |
|
|
767
|
+
| finalized ADR | `.okstra/decisions/NNNN-*.md` | promoted / managed |
|
|
768
|
+
| **Agent evidence / design draft / analysis** | **`.okstra/tasks/<group>/<id>/notes/`** | you (the AI) |
|
|
763
769
|
|
|
764
|
-
|
|
770
|
+
If it is **your own grounding/draft** — not a rendered artifact, not a user decision — it goes to `notes/`. Do not hand-stamp the note; write it via the CLI — code guarantees the path/frontmatter/date and prints the argument to pass into the next run:
|
|
765
771
|
|
|
766
772
|
```bash
|
|
767
773
|
okstra recap note <resolved-target> --project-root <projectRoot> \
|
|
768
774
|
--kind <verification-evidence|decision-draft|analysis-note> \
|
|
769
775
|
--slug <short-topic-slug> \
|
|
770
|
-
--purpose "
|
|
771
|
-
--scope-note "
|
|
772
|
-
--body-file
|
|
776
|
+
--purpose "<one line — what it is and which run/decision it feeds>" \
|
|
777
|
+
--scope-note "<one line — what it is NOT, e.g. not a user decision on C-00x>" \
|
|
778
|
+
--body-file <note-body markdown path>
|
|
773
779
|
```
|
|
774
780
|
|
|
775
|
-
|
|
781
|
+
Write the body to the scratchpad as markdown first, then pass it with `--body-file` (if short, an inline `--body "<md>"` also works). The CLI creates `.okstra/tasks/<group>/<id>/notes/<slug>-<YYYY-MM-DD>.md` and returns `notePath` and `clarificationResponseArg` as stdout JSON.
|
|
776
782
|
|
|
777
|
-
**self-check
|
|
783
|
+
**self-check rules (there is no validator, so you keep them yourself):**
|
|
778
784
|
|
|
779
|
-
1.
|
|
780
|
-
2.
|
|
781
|
-
3. **
|
|
782
|
-
4. **`notes/`
|
|
785
|
+
1. **Do not hand-edit a rendered report** (`*.md` / `*.data.json` / `*.html` under `runs/*/reports/`). Because it is regenerated from `data.json`, an edit is overwritten and diverges from the SSOT. Write findings to `notes/` instead.
|
|
786
|
+
2. **Do not author a `user-responses/` file or apply `created-by: user`.** That is the user's decision, and writing it for them forges a decision the user never made. If your evidence supports a particular answer, write that in `notes/` and leave the decision to the user. The one exception is the echo-back confirmation flow of the `okstra-user-response` skill — there the user makes the decision in-session and the CLI is merely a transcription channel, so recording a `created-by: user` sidecar with `write` is legitimate. This exception holds only after the user has explicitly confirmed "correct", and only for verbatim input.
|
|
787
|
+
3. **Do not write to okstra-managed directories** (`runs/`, `instruction-set/`, `history/`, `recap/`, `.okstra/decisions/`). `notes/` is the only agent-owned lane. `recap/recap-log.jsonl` is the exception — write it, but not by hand; only via the `okstra recap record` CLI.
|
|
788
|
+
4. **`notes/` is inert to okstra** — no run reads it automatically. After writing, relay the `clarificationResponseArg` the CLI printed (e.g. `--clarification-response <notePath>`) to the user verbatim, telling them it only takes effect when the next run is executed with that argument.
|
|
783
789
|
|
|
784
|
-
**Guardrail:** `.okstra/`
|
|
790
|
+
**Guardrail:** `.okstra/` is gitignored — treat `notes/` as local scratch and never `git add` it. Creating a new note is easy to undo (delete the file), so always prefer it over editing a generated or user-owned file.
|
|
785
791
|
|
|
786
792
|
---
|
|
787
793
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-manager
|
|
3
|
-
description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "
|
|
3
|
+
description: Use when the user wants to manage okstra work across multiple project roots, register or discover projects under a manager, create or update a shared manager task, sync project child-task status into manager state, or launch a child task from manager context. Trigger words include "okstra manager", "okstra-manager", "multiple projects", "cross-project", "group projects together", "manager task".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OKSTRA Manager
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-memory
|
|
3
|
-
description: Use when the user wants to preserve, remember, store, recall, search, or archive AI/human conversation notes in okstra's global Memory Book. Trigger words include "
|
|
3
|
+
description: Use when the user wants to preserve, remember, store, recall, search, or archive AI/human conversation notes in okstra's global Memory Book. Trigger words include "organize and store this in okstra", "memory-book", "remember this for me", "save the conversation", "summarize and save", "remember this", "store this conversation", "save this decision", "search the memory-book", "find the note I saved", "recall a saved decision".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# okstra-memory
|
|
@@ -14,7 +14,7 @@ explicitly cites a memory entry later.
|
|
|
14
14
|
|
|
15
15
|
## When to use
|
|
16
16
|
|
|
17
|
-
- The user says "
|
|
17
|
+
- The user says "organize and store this in okstra", "remember this for me", "save the conversation",
|
|
18
18
|
"remember this", or similar.
|
|
19
19
|
- The user asks to search, list, show, or archive stored conversation memory.
|
|
20
20
|
- The user wants decisions, preferences, requirements, people/context notes,
|
|
@@ -58,7 +58,7 @@ searching so the rest of the skill can scope to it.
|
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
2. Present a 3-option picker (most-used existing group, next existing group,
|
|
61
|
-
then always
|
|
61
|
+
then always `Enter directly`). For a personal note, recommend `private` as the
|
|
62
62
|
first option. If `groups` is empty or the user makes no selection, the
|
|
63
63
|
default group is `global` (the CLI default in `memory.mjs`).
|
|
64
64
|
3. Carry the chosen group name into every `add` (`--project-group <name>`) and
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-rollup
|
|
3
3
|
description: |
|
|
4
|
-
Use when the user wants run results from MULTIPLE okstra tasks collected and summarized at once — a task-group digest or a whole-project roll-up, not a single task. Aggregates per-task run count, elapsed time, error count, and latest report path, plus group-level totals and status/category/phase tallies, then synthesizes a cross-task prose summary from the report files. Make sure to use this skill whenever the user mentions "okstra rollup", "
|
|
4
|
+
Use when the user wants run results from MULTIPLE okstra tasks collected and summarized at once — a task-group digest or a whole-project roll-up, not a single task. Aggregates per-task run count, elapsed time, error count, and latest report path, plus group-level totals and status/category/phase tallies, then synthesizes a cross-task prose summary from the report files. Make sure to use this skill whenever the user mentions "okstra rollup", "rollup", "task-group summary", "group-level report", "collect multiple task results", "whole-project task status summary", "cross-task summary", "consolidated group report", "organize all tasks", "run results all at once", even if they don't say "rollup". For a SINGLE task's report/time/errors/recap use okstra-inspect instead; for a forward-looking work plan over non-done tasks use okstra-schedule-gen.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# OKSTRA Rollup
|
|
@@ -12,18 +12,24 @@ This skill is read-only. It never mutates task artifacts.
|
|
|
12
12
|
|
|
13
13
|
## Step 0: Preflight
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
<!-- BEGIN FRAGMENT: bash-invocation-rule -->
|
|
16
|
+
Run one Bash tool call, starting with the literal token `okstra` (never wrapped in `if`/`eval`/`export`/`$(...)`/`VAR=...`/`||`/`&&`/`npx` — a non-literal leading token defeats the `Bash(okstra:*)` permission match):
|
|
17
|
+
<!-- END FRAGMENT: bash-invocation-rule -->
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
20
|
okstra preflight --runtime claude-code --json
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string. `ok: false` → tell the user to run `/okstra-setup` first, then stop.
|
|
23
|
+
Parse the stdout JSON. `ok: true` → carry `projectRoot` as a literal string. `ok: false` → tell the user to run `/okstra-setup` first, then stop.
|
|
24
|
+
|
|
25
|
+
<!-- BEGIN FRAGMENT: preflight-outdated-cli -->
|
|
26
|
+
If the call fails with `unknown command: preflight`, the `okstra` binary on PATH predates this skill — tell the user to update it (`npm i -g okstra@latest`), then stop (`/okstra-setup` does not update the binary).
|
|
27
|
+
<!-- END FRAGMENT: preflight-outdated-cli -->
|
|
22
28
|
|
|
23
29
|
## Step 1: Resolve scope
|
|
24
30
|
|
|
25
|
-
- User named a task-group (e.g. "alpha
|
|
26
|
-
- User asked for the whole project ("
|
|
31
|
+
- User named a task-group (e.g. "summarize the alpha group") → use it as `--task-group <group>`.
|
|
32
|
+
- User asked for the whole project ("all tasks", "the whole project") or named no scope → omit `--task-group` (whole catalog).
|
|
27
33
|
- If genuinely ambiguous, ask once: one task-group, or the whole project? Do not silently guess a specific group.
|
|
28
34
|
|
|
29
35
|
## Step 2: Fetch the roll-up
|
|
@@ -62,7 +68,7 @@ Render `Report` as `✓` when `reportPath` is non-empty, else `—`. Build the s
|
|
|
62
68
|
|
|
63
69
|
## Step 4: Synthesize the digest (the summary)
|
|
64
70
|
|
|
65
|
-
This is the skill's value-add over a bare table. When the user asked to "
|
|
71
|
+
This is the skill's value-add over a bare table. When the user asked to "summarize"/"digest"/"organize" (the common case), produce a short cross-task narrative:
|
|
66
72
|
|
|
67
73
|
1. For each task with a non-empty `reportPath` whose file exists under `<projectRoot>/<reportPath>`, read it and write a 1–2 line summary of what it accomplished and its recommended next step.
|
|
68
74
|
2. Above the per-task lines, write a 2–4 sentence group-level synthesis: what was delivered across the group, where the open work sits (use `byWorkStatus`/`byCurrentPhase`), and any error hot-spots (tasks with high `errorCount`).
|