okstra 0.21.0 → 0.21.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/README.kr.md +2 -2
- package/README.md +2 -2
- package/docs/kr/architecture.md +1 -0
- package/docs/kr/cli.md +1 -1
- package/docs/project-structure-overview.md +3 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/claude-worker.md +3 -1
- package/runtime/bin/okstra-codex-exec.sh +11 -0
- package/runtime/bin/okstra-gemini-exec.sh +7 -0
- package/runtime/bin/okstra-trace-cleanup.sh +42 -0
- package/runtime/templates/reports/settings.template.json +9 -0
- package/src/install.mjs +1 -0
- package/src/uninstall.mjs +1 -0
package/README.kr.md
CHANGED
|
@@ -28,7 +28,7 @@ okstra/ npm 패키지 = repo 루트
|
|
|
28
28
|
├── tools/build.mjs runtime/ 동기화 스크립트 (prepack 에서 호출)
|
|
29
29
|
├── runtime/ gitignored 빌드 산출물; ~/.okstra 로 배포되는 유일한 자산
|
|
30
30
|
├── scripts/ python + bash 런타임 소스
|
|
31
|
-
├── skills/ Claude Code 스킬 마크다운 소스 (스킬
|
|
31
|
+
├── skills/ Claude Code 스킬 마크다운 소스 (스킬 13종)
|
|
32
32
|
├── agents/ lead SKILL.md + workers/
|
|
33
33
|
├── prompts/, templates/, validators/
|
|
34
34
|
├── docs/kr/ 한국어 상세 매뉴얼 (architecture.md, cli.md)
|
|
@@ -87,7 +87,7 @@ okstra/ npm 패키지 = repo 루트
|
|
|
87
87
|
npx -y okstra@latest install
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
`~/.okstra/{lib/python, bin, version}`, `~/.claude/skills/` 아래 스킬 마크다운
|
|
90
|
+
`~/.okstra/{lib/python, bin, version}`, `~/.claude/skills/` 아래 스킬 마크다운 13개, `~/.okstra/installed-skills.json` 을 생성합니다. 재실행은 idempotent — 파일별 hash 를 비교하고 바뀐 파일만 갱신합니다.
|
|
91
91
|
|
|
92
92
|
검증:
|
|
93
93
|
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ okstra/ npm package = repo root
|
|
|
28
28
|
├── tools/build.mjs runtime/ sync script (invoked by prepack)
|
|
29
29
|
├── runtime/ gitignored build output; the only thing shipped to ~/.okstra
|
|
30
30
|
├── scripts/ python + bash runtime sources
|
|
31
|
-
├── skills/ Claude Code skill markdown sources (
|
|
31
|
+
├── skills/ Claude Code skill markdown sources (13 skills)
|
|
32
32
|
├── agents/ lead SKILL.md + workers/
|
|
33
33
|
├── prompts/, templates/, validators/
|
|
34
34
|
├── tests/, tests-e2e/
|
|
@@ -86,7 +86,7 @@ okstra/ npm package = repo root
|
|
|
86
86
|
npx -y okstra@latest install
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
Provisions `~/.okstra/{lib/python, bin, version}`, the
|
|
89
|
+
Provisions `~/.okstra/{lib/python, bin, version}`, the 13 skill markdown files under `~/.claude/skills/`, and `~/.okstra/installed-skills.json`. Re-running is idempotent — per-file hashes are compared and only changed files are touched.
|
|
90
90
|
|
|
91
91
|
Verify:
|
|
92
92
|
|
package/docs/kr/architecture.md
CHANGED
|
@@ -837,6 +837,7 @@ Claude가 작성하는 최종 보고서는 brief에 더 구체적인 형식이
|
|
|
837
837
|
|
|
838
838
|
- `scripts/okstra-codex-exec.sh`, `scripts/okstra-gemini-exec.sh` 는 dispatch 마다 prompt path 옆에 `<prompt>.log` sidecar 를 만들고 stdout 을 거기로 mirror 합니다 (`tee`, `PIPESTATUS[0]` 로 종료코드 보존). stderr 은 같은 파일에 append (subagent stderr 캡처 contract 보존), 매 dispatch 시 truncate. 호출 subagent 의 `BashOutput` 폴링은 60s 간격이라 long-running run (analysis 의 large-codebase scan, implementation 의 cargo / pytest) 동안 사용자가 stalled state 를 탐지할 수 없는 문제를 해소합니다.
|
|
839
839
|
- `$TMUX` 가 셋팅된 lead 환경이면 wrapper 가 sibling pane 을 자동 분할해 `tail -F <log-path>` 를 띄웁니다. pane title 은 `<cli>-<role>-trace` (e.g. `codex-worker-trace`, `gemini-worker-trace`); role 은 wrapper 의 5번째 optional positional 인자이며, 누락 시 기본값 `worker` 로 떨어집니다. caller 가 다른 라벨(예: `executor`)을 원하면 5번째 인자로 명시해야 합니다. focus 는 caller pane 으로 복귀하고, CLI 종료 후 pane 은 유지돼 스크롤백 가능. `$TMUX` 미설정, split 실패, 구버전 tmux 등 모든 경로는 silent degrade.
|
|
840
|
+
- **Claude `/exit` 시 자동 정리**: trace pane 의 `tail -F` 는 tmux 셸의 자식이라 Claude 가 종료돼도 살아남는 문제를 막기 위해, wrapper 는 spawn 한 pane id 를 caller `$TMUX_PANE` 으로 키된 registry (`${TMPDIR:-/tmp}/okstra-trace-panes/<caller-pane>.list`) 에 append 합니다. `templates/reports/settings.template.json` 의 `hooks.SessionEnd` 가 `$HOME/.okstra/bin/okstra-trace-cleanup.sh` 를 호출해 자신의 caller pane registry 만 읽어 `tmux kill-pane` 합니다. caller pane 단위로 scope 가 잡혀 있어 같은 tmux 세션에 Claude 인스턴스가 여러 개 떠 있어도 서로의 trace pane 을 죽이지 않습니다. tmux 가 없거나 stale pane id 인 경우 silent degrade.
|
|
840
841
|
- 디스크 누적은 `okstra-logs` skill 이 read-only 로 인벤토리 + cleanup 명령을 제안합니다 (실행은 사용자 copy-paste).
|
|
841
842
|
|
|
842
843
|
### Linked-worktree `.git/` write 권한 (codex / gemini)
|
package/docs/kr/cli.md
CHANGED
|
@@ -497,5 +497,5 @@ chmod +x ~/.local/bin/okstra-ctl
|
|
|
497
497
|
|
|
498
498
|
### Live-log sidecar
|
|
499
499
|
|
|
500
|
-
codex / gemini wrapper 는 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` sidecar 를 만들고 stdout / stderr 를 mirror 합니다. tmux 안에서 lead 를 띄우면 wrapper 가 자동으로 `tail -F` pane 을 분할합니다 (title: `<cli>-<role>-trace`). 사용량 인벤토리와 `find … -delete` cleanup 명령은 `okstra-logs` skill 이 read-only 로 제안합니다. 자세한 와이어링은 [`docs/kr/architecture.md`](architecture.md) 의 *Live-log mirror* 절 참고.
|
|
500
|
+
codex / gemini wrapper 는 매 dispatch 마다 `runs/<task-type>/prompts/<worker>-prompt-<phase>-<seq>.log` sidecar 를 만들고 stdout / stderr 를 mirror 합니다. tmux 안에서 lead 를 띄우면 wrapper 가 자동으로 `tail -F` pane 을 분할합니다 (title: `<cli>-<role>-trace`). 분할된 trace pane 은 caller `$TMUX_PANE` 으로 키된 registry 에 등록돼, Claude `/exit` 시 `SessionEnd` 훅이 `okstra-trace-cleanup.sh` 로 자동 정리합니다. 사용량 인벤토리와 `find … -delete` cleanup 명령은 `okstra-logs` skill 이 read-only 로 제안합니다. 자세한 와이어링은 [`docs/kr/architecture.md`](architecture.md) 의 *Live-log mirror* 절 참고.
|
|
501
501
|
|
|
@@ -165,6 +165,7 @@ okstra/
|
|
|
165
165
|
| `okstra-central.sh` | `record_start` 중앙 lock 관리 |
|
|
166
166
|
| `okstra-codex-exec.sh` | Codex worker executor (live log mirror, tmux trace pane) |
|
|
167
167
|
| `okstra-gemini-exec.sh` | Gemini worker executor |
|
|
168
|
+
| `okstra-trace-cleanup.sh` | Claude `/exit` 시 trace pane registry 청소 (`SessionEnd` 훅에서 호출) |
|
|
168
169
|
| `okstra-error-log.py` | Worker 오류 패턴 분석 |
|
|
169
170
|
| `okstra-spawn-followups.py` | Phase 완료 후 다음 phase dispatch |
|
|
170
171
|
| `okstra-token-usage.py` | Token collection CLI 엔트리 |
|
|
@@ -217,7 +218,7 @@ okstra/
|
|
|
217
218
|
|
|
218
219
|
---
|
|
219
220
|
|
|
220
|
-
### 3.7 `skills/` —
|
|
221
|
+
### 3.7 `skills/` — 13개 Claude Code 슬래시 커맨드
|
|
221
222
|
|
|
222
223
|
| ID | 이름 | 공개 | 용도 |
|
|
223
224
|
|----|------|------|------|
|
|
@@ -233,6 +234,7 @@ okstra/
|
|
|
233
234
|
| 10 | okstra-report-finder | NO | 보고서 검색 (자동 트리거) |
|
|
234
235
|
| 11 | okstra-time-summary | NO | 소요 시간 분석 |
|
|
235
236
|
| 12 | okstra-logs | YES | 로그 인벤토리·정리 (worker wrapper `*.log` sidecars 조회 및 cleanup 제안) |
|
|
237
|
+
| 13 | okstra-brief | YES | 요구사항 문서·티켓·링크·대화로부터 `okstra-run` 입력용 task brief 마크다운 생성 |
|
|
236
238
|
|
|
237
239
|
각 skill 구조: **Step 0 런타임 검증 → Step 1-N 작업 수행 → 실패 시 사용자 안내**.
|
|
238
240
|
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -44,7 +44,9 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
|
|
|
44
44
|
- If the parent directory does not exist yet, create it before writing.
|
|
45
45
|
|
|
46
46
|
4. Anchor all file operations to the absolute `Project Root` from the lead prompt. Use absolute paths — do NOT rely on inherited cwd. Never use `cd` to change directory.
|
|
47
|
-
- **Executor exception (implementation phase only):** when this worker is dispatched as the `Executor` and the lead prompt provides an `EXECUTOR_WORKTREE_PATH` that differs from the session's inherited cwd, cwd-sensitive Bash commands (`cargo *`, `npm *`, `pnpm *`, `bun *`, `pytest`, `make *`, `go *`, language-toolchain test/build commands) MUST be prefixed with `cd <EXECUTOR_WORKTREE_PATH> && ` in the same Bash invocation — e.g. `cd /Users/.../worktrees/foo && cargo test -p bar`. Do NOT wrap the whole thing in `bash -lc "..."` or `bash -c "..."`; pass the chained command directly to the Bash tool so the leading `cd` token remains visible to the permission layer. The `cd` is scoped to the single Bash subshell and does not mutate the session's shell state, so this does not conflict with the "never use cd" rule above (which prevents the worker from drifting the session cwd across calls).
|
|
47
|
+
- **Executor exception (implementation phase only):** when this worker is dispatched as the `Executor` and the lead prompt provides an `EXECUTOR_WORKTREE_PATH` that differs from the session's inherited cwd, cwd-sensitive Bash commands (`cargo *`, `npm *`, `pnpm *`, `bun *`, `pytest`, `make *`, `go *`, language-toolchain test/build commands) MUST be prefixed with `cd <EXECUTOR_WORKTREE_PATH> && ` in the same Bash invocation — e.g. `cd /Users/.../worktrees/foo && cargo test -p bar`. Do NOT wrap the whole thing in `bash -lc "..."` or `bash -c "..."`; pass the chained command directly to the Bash tool so the leading `cd` token remains visible to the permission layer. The `cd` is scoped to the single Bash subshell and does not mutate the session's shell state, so this does not conflict with the "never use cd" rule above (which prevents the worker from drifting the session cwd across calls).
|
|
48
|
+
- **Verifier QA-gate exception:** verifier roles MAY use the same `cd <WORKTREE> && <cmd>` shape when executing project-declared `qaCommands` (lint / format / typecheck / test) from `project.json`, since those commands are cwd-sensitive by nature. Outside the QA gate, verifiers still read with absolute paths only — do NOT use `cd` for file inspection.
|
|
49
|
+
- **No extra chaining beyond `cd && cmd`:** the permission matcher only allows the exact two-segment shape `cd <PATH> && <single-command>`. Do NOT append additional pipes, semicolons, redirects, or `&&` chains — e.g. `cd ... && cargo test ... 2>&1 | tail -20; echo "exit:$?"` will trigger a permission prompt every dispatch because the trailing `| tail`, `; echo`, and `2>&1` tokens disqualify the prefix match against `Bash(cargo:*)`. Let Claude Code capture the full stdout/stderr and exit code natively — do not post-process with `tail`, `head`, or `echo "exit:$?"`. If output truncation is genuinely needed, run the command first and read the result in a separate tool call.
|
|
48
50
|
|
|
49
51
|
5. **MCP usage**: The canonical list of MCP servers and tools available for this run lives in the lead prompt's `## Available MCP Servers` section (sourced from `.project-docs/okstra/project.json`'s `mcpServers` array). When the task requires inspection of an external system covered by one of those servers, call the listed tool directly by name (e.g. `mcp__<server>__<tool>`). Do NOT shell out via `claude --mcp-cli call ...` or run the tool name as a Bash command — those are not valid invocation paths. If a server you need is not listed, record `MCP not available for this run` in your worker output rather than guessing a tool name.
|
|
50
52
|
|
|
@@ -172,6 +172,17 @@ if [[ -n "${TMUX:-}" ]]; then
|
|
|
172
172
|
if [[ -n "$trace_pane" ]]; then
|
|
173
173
|
tmux select-pane -t "$trace_pane" -T "codex-${role}-trace" 2>/dev/null || true
|
|
174
174
|
tmux last-pane 2>/dev/null || true
|
|
175
|
+
# Register the spawned pane so the `SessionEnd` hook (see
|
|
176
|
+
# `okstra-trace-cleanup.sh`) can kill it when the caller's Claude
|
|
177
|
+
# session exits. Scope by caller `$TMUX_PANE` — the pane Claude itself
|
|
178
|
+
# is attached to — so concurrent Claude instances in the same tmux
|
|
179
|
+
# session do not stomp each other's trace panes.
|
|
180
|
+
if [[ -n "${TMUX_PANE:-}" ]]; then
|
|
181
|
+
registry_dir="${TMPDIR:-/tmp}/okstra-trace-panes"
|
|
182
|
+
mkdir -p "$registry_dir" 2>/dev/null || true
|
|
183
|
+
safe_pane="${TMUX_PANE//[^A-Za-z0-9]/_}"
|
|
184
|
+
printf '%s\n' "$trace_pane" >> "$registry_dir/${safe_pane}.list" 2>/dev/null || true
|
|
185
|
+
fi
|
|
175
186
|
fi
|
|
176
187
|
fi
|
|
177
188
|
|
|
@@ -121,6 +121,13 @@ if [[ -n "${TMUX:-}" ]]; then
|
|
|
121
121
|
if [[ -n "$trace_pane" ]]; then
|
|
122
122
|
tmux select-pane -t "$trace_pane" -T "gemini-${role}-trace" 2>/dev/null || true
|
|
123
123
|
tmux last-pane 2>/dev/null || true
|
|
124
|
+
# See `okstra-codex-exec.sh` for the registry rationale — kept in lock-step.
|
|
125
|
+
if [[ -n "${TMUX_PANE:-}" ]]; then
|
|
126
|
+
registry_dir="${TMPDIR:-/tmp}/okstra-trace-panes"
|
|
127
|
+
mkdir -p "$registry_dir" 2>/dev/null || true
|
|
128
|
+
safe_pane="${TMUX_PANE//[^A-Za-z0-9]/_}"
|
|
129
|
+
printf '%s\n' "$trace_pane" >> "$registry_dir/${safe_pane}.list" 2>/dev/null || true
|
|
130
|
+
fi
|
|
124
131
|
fi
|
|
125
132
|
fi
|
|
126
133
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# okstra-trace-cleanup.sh — kill tmux trace panes spawned by okstra worker
|
|
4
|
+
# wrappers (`okstra-codex-exec.sh`, `okstra-gemini-exec.sh`) for the current
|
|
5
|
+
# Claude Code session.
|
|
6
|
+
#
|
|
7
|
+
# Invoked from the `SessionEnd` hook in
|
|
8
|
+
# `templates/reports/settings.template.json`. The wrappers register every
|
|
9
|
+
# pane they split into a registry file keyed by the caller's `$TMUX_PANE`
|
|
10
|
+
# (i.e. the pane Claude itself is attached to). On Claude `/exit`, the hook
|
|
11
|
+
# runs in that same pane's env, reads its own registry file, and kills each
|
|
12
|
+
# registered pane.
|
|
13
|
+
#
|
|
14
|
+
# Scoping by caller `$TMUX_PANE` (not by tmux session) lets multiple Claude
|
|
15
|
+
# instances coexist in the same tmux session without stomping each other's
|
|
16
|
+
# trace panes.
|
|
17
|
+
#
|
|
18
|
+
# Failures are tolerated silently — a stale pane id, missing $TMUX, or a
|
|
19
|
+
# locked tmux client must never prevent Claude from exiting cleanly.
|
|
20
|
+
|
|
21
|
+
set -u
|
|
22
|
+
|
|
23
|
+
# No tmux pane context → nothing to clean.
|
|
24
|
+
if [[ -z "${TMUX_PANE:-}" ]]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
registry_dir="${TMPDIR:-/tmp}/okstra-trace-panes"
|
|
29
|
+
safe_pane="${TMUX_PANE//[^A-Za-z0-9]/_}"
|
|
30
|
+
registry_file="$registry_dir/${safe_pane}.list"
|
|
31
|
+
|
|
32
|
+
if [[ ! -f "$registry_file" ]]; then
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
while IFS= read -r pane_id; do
|
|
37
|
+
[[ -n "$pane_id" ]] || continue
|
|
38
|
+
tmux kill-pane -t "$pane_id" 2>/dev/null || true
|
|
39
|
+
done < "$registry_file"
|
|
40
|
+
|
|
41
|
+
rm -f "$registry_file" 2>/dev/null || true
|
|
42
|
+
exit 0
|
|
@@ -143,5 +143,14 @@
|
|
|
143
143
|
"mcp__test-context7__resolve-library-id",
|
|
144
144
|
"mcp__test-context7__query-docs"
|
|
145
145
|
]
|
|
146
|
+
},
|
|
147
|
+
"hooks": {
|
|
148
|
+
"SessionEnd": [
|
|
149
|
+
{
|
|
150
|
+
"hooks": [
|
|
151
|
+
{ "type": "command", "command": "$HOME/.okstra/bin/okstra-trace-cleanup.sh" }
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
]
|
|
146
155
|
}
|
|
147
156
|
}
|
package/src/install.mjs
CHANGED