okstra 0.106.0 → 0.106.1
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/docs/kr/cli.md
CHANGED
|
@@ -634,6 +634,7 @@ chmod +x ~/.local/bin/okstra-ctl
|
|
|
634
634
|
| `okstra config <get\|set\|unset\|show> [key] [value] [--scope project\|global\|all]` | 영구 설정 관리 (예: `pr-template-path`). 원자적 JSON 쓰기 |
|
|
635
635
|
| `okstra memory <add\|list\|search\|show\|archive>` | `~/.okstra/memory-book` 전역 대화 메모리 관리. 프로젝트 `.okstra/` 와 분리된 user-home 저장소이며, `okstra 에 정리해서 보관해` 자연어 스킬의 CLI 기반 |
|
|
636
636
|
| `okstra manager <init\|discover-projects\|new\|task>` | 여러 프로젝트의 okstra task 를 manager-owned context 로 묶는 공개 CLI. `new project`, `new task-group`, `new task` 로 manager 계획을 만들고, `task assign` / `task note` / `task sync` / `task status` / `task run` 으로 프로젝트별 할당과 snapshot 을 관리한다. `new project --project-root` 는 이미 존재하는 디렉터리만 받으며, 그 안의 `.okstra/project.json` 이 없을 때만 setup-equivalent registration 을 수행한다. child task key 는 공개 문서에서 `project-id:task-group:task-id` 전체 형식을 사용하고, 같은 manager task 안에서 child task id 가 다르면 `--child-task-id` 로 exact child 를 지정한다. `task run` 은 child lead 를 직접 실행하지 않고 `prepared` launch metadata/event 와 child launch context packet 을 JSON 으로 반환한다 |
|
|
637
|
+
| `okstra rollup [--task-group <group>] [--project-root <dir>] [--cwd <dir>]` | okstra-rollup 스킬의 read-only 백엔드. catalog 의 모든 task(또는 한 task-group)에 대해 task 별 run 수·소요 시간(raw ms)·에러 수·최신 report 경로와 group 차원 합계 및 상태/카테고리/phase 분포를 JSON 으로 출력한다. `--task-group` 생략 시 프로젝트 전체 catalog 를 대상으로 한다. 시간은 raw ms 이며 HH:MM:SS 포맷·report 본문 종합은 호출자(skill)에 위임한다. 단일 task drill-down 은 `okstra inspect` 계열을 쓴다 |
|
|
637
638
|
| `okstra migrate [--apply] [--cwd <dir>] [--quiet]` | 한 번만 실행: 프로젝트 산출물 루트를 `.project-docs/okstra/` → `.okstra/` 로 이동. 기본 dry-run, `--apply` 로 실제 실행. `git mv` (git worktree) + 빈 `.project-docs/` 제거 + `<PROJECT>/CLAUDE.md` import 라인 + `.gitignore` + `~/.okstra/{recent,active}.jsonl` + `~/.okstra/worktrees/registry.json` 의 해당 프로젝트 row 동기화. 이미 `.okstra/` 가 존재하거나 레거시 디렉토리가 없으면 exit 1 로 거부. v0.x 말까지 유지 후 제거 예정 |
|
|
638
639
|
| `okstra task-list [--project-root <path>]` | `list_project_tasks` + `read_latest_task` 결과를 합쳐 task 카탈로그 + 최근 task 를 JSON 으로 반환 |
|
|
639
640
|
| `okstra task-show <task-key> [--project-root <path>]` | task-manifest.json 의 workflow / phase / status 요약 |
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
## 3. 소스 리포지토리 안 원본
|
|
30
30
|
|
|
31
|
-
- [`
|
|
31
|
+
- [`templates/prd/pr-body.template.md`](../templates/prd/pr-body.template.md) — `npx okstra install` 이 §2 의 default 위치로 복사하는 원본. 카피를 바꾸고 싶으면 이 파일을 수정한 뒤 다시 install 한다.
|
|
32
32
|
|
|
33
33
|
## 4. 설정 명령 — 영속화
|
|
34
34
|
|
|
@@ -174,6 +174,7 @@ Runtime/install asset changes follow this checklist:
|
|
|
174
174
|
| `spawn-followups`, `error-log` | `src/commands/execute/*.mjs` | Follow-up task bundle creation and run error-log append helpers |
|
|
175
175
|
| `memory` | `src/commands/memory/memory.mjs` | Store/find global conversation memory under `~/.okstra/memory-book` |
|
|
176
176
|
| `recap` | `src/commands/inspect/recap.mjs` | `okstra recap <assemble\|record>` Node wrapper backing the okstra-inspect `recap` facet |
|
|
177
|
+
| `rollup` | `src/commands/inspect/rollup.mjs` | `okstra rollup` thin shim into `scripts/okstra_ctl/rollup.py` — read-only cross-task roll-up backing the okstra-rollup skill |
|
|
177
178
|
| `container` | `src/commands/inspect/container.mjs` | `bin okstra container` thin shim into `scripts/okstra_ctl/container.py` for the okstra-container-build skill |
|
|
178
179
|
| `manager` | `src/commands/manager.mjs` | Thin shim into `scripts/okstra_ctl/manager_cli.py` for cross-project manager state and child launch packets |
|
|
179
180
|
|
|
@@ -231,6 +232,8 @@ Important modules:
|
|
|
231
232
|
| `run_index_row.py` | `~/.okstra` run-index row 의 생성/축약(slim)/복원(hydrate) 단일 참조점 — runId SSOT, projectId raw 보존 |
|
|
232
233
|
| `error_report.py`, `error_log_core.py`, `error_zip.py` | okstra-inspect errors/error-zip facet 백엔드 — `error_log_core` 는 `errors-*.jsonl` 글롭·파싱·집계 read-only 코어, `error_report` 는 errors facet 렌더, `error_zip` 은 cross-project run 디렉터리 수집·allowlist 익명화·클러스터 집계·zip 생성 |
|
|
233
234
|
| `log_report.py`, `time_report.py` | okstra-inspect logs/time facet 의 read-side 백엔드 (`okstra log-report` 는 wrapper sidecar 로그 인벤토리, `okstra time-report` 는 task 단위 시간 집계) |
|
|
235
|
+
| `rollup.py` | okstra-rollup 스킬의 read-side 백엔드 — catalog 를 task-group(또는 프로젝트 전체) 단위로 fan-out 해 task 별 run 수·소요 시간(raw ms)·에러 수·최신 report 경로와 group 차원 합계/상태·카테고리·phase 분포를 deterministic 하게 집계. `time_report`/`error_log_core` 함수 재사용, report 본문 종합은 skill 에 위임 |
|
|
236
|
+
| `json_registry.py` | 작은 okstra 레지스트리 공용 flock + atomic JSON persistence (`registry_lock`/`load_registry_json`/`save_registry_json`) — `container_registry`·`worktree_registry` 가 공유 |
|
|
234
237
|
| `stage_integrate.py` | whole-task stage 통합(머지)+worktree teardown 코어 (`integrate_stages`) — whole-task final-verification 진입·`okstra integrate-stages`·container up 이 공유 |
|
|
235
238
|
| `resolve_task_key.py` | bare task-id → `task-catalog.json` 후보 entry 해석 skill 공용 helper (`okstra resolve-task-key`) |
|
|
236
239
|
| `session.py`, `tmux.py`, `seeding.py`, `locks.py`, `invocation.py`, `sequence.py`, `ids.py`, `material.py` | Supporting lifecycle helpers |
|
|
@@ -322,8 +325,8 @@ Token/cost accounting:
|
|
|
322
325
|
| File | Role |
|
|
323
326
|
|---|---|
|
|
324
327
|
| `agents/workers/claude-worker.md` | Claude analyzer/verifier/executor spec |
|
|
325
|
-
| `agents/workers/codex-worker.
|
|
326
|
-
| `agents/workers/antigravity-worker.
|
|
328
|
+
| `agents/workers/codex-worker.params.json` | Codex analyzer/verifier/executor wrapper params (build 가 `_cli-wrapper-template.md` 로 `.md` 렌더) |
|
|
329
|
+
| `agents/workers/antigravity-worker.params.json` | Antigravity analyzer/verifier/executor wrapper params (build 가 `_cli-wrapper-template.md` 로 `.md` 렌더) |
|
|
327
330
|
| `agents/workers/report-writer-worker.md` | data.json SSOT author and audit sidecar writer |
|
|
328
331
|
|
|
329
332
|
The lead operating contract moved out of `agents/` to `prompts/lead/okstra-lead-contract.md` (a runtime resource installed to `~/.okstra/prompts/lead/`, not an agent skill).
|
|
@@ -217,5 +217,5 @@ flowchart TD
|
|
|
217
217
|
- [`scripts/okstra_ctl/wizard.py`](../../scripts/okstra_ctl/wizard.py)
|
|
218
218
|
- [`scripts/okstra_ctl/run.py`](../../scripts/okstra_ctl/run.py)
|
|
219
219
|
- [`scripts/okstra_ctl/pr_template.py`](../../scripts/okstra_ctl/pr_template.py)
|
|
220
|
-
- [`src/config.mjs`](../../src/config.mjs)
|
|
220
|
+
- [`src/commands/lifecycle/config.mjs`](../../src/commands/lifecycle/config.mjs)
|
|
221
221
|
- [`scripts/okstra_ctl/worktree.py`](../../scripts/okstra_ctl/worktree.py)
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: okstra-inspect
|
|
3
|
-
description:
|
|
4
|
-
Use for
|
|
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 (결론·통과); 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 (에러 리포트). Also bundles cross-project okstra errors into an anonymized feedback zip (에러 환류). 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), a brief (okstra-brief), setup (okstra-setup), or cross-project management (okstra-manager).
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# OKSTRA Inspect
|
|
@@ -28,12 +28,17 @@ Before any sub-command, run each of the following commands as a **separate Bash
|
|
|
28
28
|
If this exits non-zero, tell the user: "okstra not installed — run `/okstra-setup` first." Then stop. Do **not** try to invoke `npx -y okstra@latest ...` as a fallback.
|
|
29
29
|
|
|
30
30
|
2. `okstra check-project --json`
|
|
31
|
-
|
|
31
|
+
Resolves PROJECT_ROOT from the directory the Bash call runs in, looks for `.okstra/project.json`, and prints `{ok, projectRoot, projectJsonPath, projectId}` (plus a `stage` on failure). Parse the JSON from stdout.
|
|
32
32
|
|
|
33
|
-
-
|
|
34
|
-
- `ok: true` → carry `projectRoot` as a literal string and use it as the base for sub-command steps.
|
|
33
|
+
`check-project` only sees the cwd of the Bash call. When the session cwd already *is* the target project — the common case — the bare form is right. But when the user is asking about a project that is **not** the cwd (a sibling repo, a monorepo subdir, or a project named explicitly in the request), the bare form resolves to the wrong project or none and returns `ok:false`. That is a false negative, not a missing setup — do not hard-stop on it.
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
Branch on the result:
|
|
36
|
+
- `ok: true` → carry `projectRoot` as a literal string; it is the base for every sub-command step below.
|
|
37
|
+
- `ok: false` (or exit code 2 / a `stage` like `project_root_unresolved`) → before concluding "no setup", ask whether the user pointed at a specific project directory. If they did, re-run targeting it:
|
|
38
|
+
`okstra check-project --cwd <that-dir> --json`
|
|
39
|
+
`--cwd` is the sanctioned way to target a project without a leading `cd`/`export`: the command still starts with the literal `okstra` token, so the `Bash(okstra:*)` permission match holds (a leading `cd` is exactly what would break it). Only if this **also** returns `ok:false` do you tell the user: "this project has no okstra setup. Run `/okstra-setup` first." Then stop.
|
|
40
|
+
|
|
41
|
+
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. Subsequent `okstra <subcmd>` calls self-bootstrap their Python path, so this skill never needs `okstra paths --shell` / `export PYTHONPATH=...`.
|
|
37
42
|
|
|
38
43
|
## Step 1: Dispatch by intent
|
|
39
44
|
|
|
@@ -253,6 +258,7 @@ When a user selects a specific task:
|
|
|
253
258
|
Builds a fresh run — new run-seq, new manifest, new report — using parameters from a previous `run-manifest-*.json`. Does NOT touch old artifacts; use `history.4` to continue an interrupted session.
|
|
254
259
|
|
|
255
260
|
1. Pick the source run-manifest: `runManifestPath` from `history.2`, or task's `latestRunManifestPath` from `history.1`. Note: `latestRunManifestPath` is projected from the timeline's latest run, so it is empty when the task has no recorded run yet (timeline absent) — in that case fall back to a `history.2` per-run `runManifestPath`, or ask the user.
|
|
261
|
+
**Migrated-task fallback (do not bail out on empty paths).** Tasks migrated from the old `.project-docs/okstra/...` layout often have empty `latestRunManifestPath` / per-run `runManifestPath` in the catalog and timeline even though the manifests exist on disk. Before asking the user, glob `<projectRoot>/.okstra/tasks/<group-seg>/<id-seg>/runs/**/manifests/run-manifest-*.json` and pick the latest by the `YYYY-MM-DD_HH-MM-SS` timestamp in the filename. Only if that glob is also empty do you ask the user.
|
|
256
262
|
2. Read the manifest and extract required arguments:
|
|
257
263
|
- `projectId` → `--project-id`
|
|
258
264
|
- `taskGroup` → `--task-group`
|
|
@@ -283,8 +289,9 @@ Continues an existing Claude session for an unfinished run. Does NOT create a ne
|
|
|
283
289
|
|
|
284
290
|
1. Read `latestResumeCommandPath` from `history.1` (or `resumeCommandPath` from a `history.2` timeline entry).
|
|
285
291
|
2. Verify the file exists on disk.
|
|
286
|
-
3. If
|
|
287
|
-
4. If
|
|
292
|
+
3. **Migrated-task fallback (do not declare "no resume" on an empty catalog path).** If the catalog/timeline path is empty or points at a non-existent `.project-docs/okstra/...` location, glob the on-disk scripts before concluding absent: `<projectRoot>/.okstra/tasks/<group-seg>/<id-seg>/runs/**/sessions/claude-resume-*.sh`, pick the latest by the `YYYY-MM-DD_HH-MM-SS` timestamp in the filename, and confirm it exists.
|
|
293
|
+
4. If a script is found: `bash <resume-command-path>`.
|
|
294
|
+
5. If the glob is also empty: `No resume script available for this run. Use 'history.3' to start a fresh run instead.`
|
|
288
295
|
|
|
289
296
|
---
|
|
290
297
|
|
|
@@ -320,7 +327,12 @@ D. **Specific task-type (fallback):** `latestReportPath` is task-type-agnostic.
|
|
|
320
327
|
|
|
321
328
|
### report.3 — Read + next-step guidance
|
|
322
329
|
|
|
323
|
-
|
|
330
|
+
Match the depth of read to the request — final reports routinely run 300+ lines / 50K+ tokens, so ingesting the whole file just to answer "핵심만 요약" is wasteful:
|
|
331
|
+
|
|
332
|
+
- **Summary / verdict intent** ("요약", "핵심만", "결론", "통과했어?", "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 "종합 판정" / "Executive" / verdict heading and its body) to quote the gist. Offer to read the full report if the user wants detail.
|
|
333
|
+
- **Full-read intent** ("전체", "다 읽어", "본문"): ingest the resolved report file.
|
|
334
|
+
|
|
335
|
+
After reading, surface follow-up options:
|
|
324
336
|
|
|
325
337
|
1. **구현 진행:** based on the report's "권장 다음 단계" section.
|
|
326
338
|
2. **추가 검증:** 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.
|
|
@@ -372,7 +384,7 @@ Convert every `*Ms` to `HH:MM:SS` (zero-pad; never show raw ms). Task types in `
|
|
|
372
384
|
|
|
373
385
|
- **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`.
|
|
374
386
|
- **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)`.
|
|
375
|
-
- **Phase breakdown** — only when the user
|
|
387
|
+
- **Phase breakdown** — "단계별"/"stage별"/"어느 단계가 오래" 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 ("어느 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 "측정 불가" — the By-task-type table is the stage answer; mention the missing intra-run markers only as a trailing footnote.
|
|
376
388
|
- If `unavailable[]` is non-empty, append a trailing note listing each run with its reason. Never fold them into totals.
|
|
377
389
|
- Show the resolved `<task-key>` in the heading.
|
|
378
390
|
|