okstra 0.2.0 → 0.4.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.
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: okstra-setup
3
+ description: One-time bootstrap for okstra in a new project or on a new machine — installs the okstra runtime via npx and creates the project's .project-docs/okstra/project.json. Trigger words include "okstra setup", "setup okstra", "initialize okstra", "okstra init", "first time okstra setup", "configure okstra here".
4
+ ---
5
+
6
+ # okstra-setup
7
+
8
+ One-time bootstrap. Run when okstra is being used for the first time on this
9
+ machine, or when adopting okstra in a new project.
10
+
11
+ ## When to use
12
+
13
+ - `~/.okstra/version` is missing or stale → okstra runtime is not installed yet.
14
+ - The current project has no `.project-docs/okstra/project.json` yet.
15
+ - The user says "set up okstra here", "first time", "okstra init", etc.
16
+
17
+ ## When NOT to use
18
+
19
+ - A task is already in flight → use [`okstra-run`](../okstra-run/SKILL.md) or
20
+ [`okstra-status`](../okstra-status/SKILL.md).
21
+ - Day-to-day usage in a project that already has `project.json` — skip this skill.
22
+
23
+ ## Prerequisites
24
+
25
+ Inform the user up-front and confirm before continuing:
26
+
27
+ - **Node 18+** required (runs `npx`). If missing, point to `brew install node`
28
+ or `nvm`.
29
+ - **Python 3.10+** required (runs the okstra core).
30
+ - The current working directory must be inside the project that will host the
31
+ okstra metadata. If unsure, ask with `AskUserQuestion` for an absolute project
32
+ root before proceeding.
33
+
34
+ ## Step 1: Install okstra
35
+
36
+ ```bash
37
+ npx -y okstra@latest install
38
+ ```
39
+
40
+ This single command populates everything the user needs:
41
+
42
+ - `~/.okstra/{lib/python, bin, version}` — python + bash runtime
43
+ - `~/.claude/skills/<name>/SKILL.md` — all 11 okstra skills (incl. this one)
44
+ - `~/.okstra/installed-skills.json` — manifest for safe uninstall
45
+
46
+ The skill should run this even if `~/.okstra/version` already exists —
47
+ `install` is idempotent (per-file hash skip), so re-running is cheap and
48
+ ensures the install matches the package version currently on disk.
49
+
50
+ Show the final summary line back to the user (`version stamp: x.y.z`).
51
+
52
+ If install fails, surface the stderr verbatim. Do NOT try to "fix" it by
53
+ running the legacy `okstra-install.sh` — that path is dev-only.
54
+
55
+ ## Step 2: Load runtime paths
56
+
57
+ ```bash
58
+ eval "$(npx -y okstra@latest paths --shell)"
59
+ export PYTHONPATH="$OKSTRA_PYTHONPATH"
60
+ ```
61
+
62
+ After this, `$OKSTRA_WORKSPACE`, `$OKSTRA_AGENTS_DIR`, `$OKSTRA_PYTHONPATH`,
63
+ `$OKSTRA_BIN`, `$OKSTRA_HOME` are all set. Do not hardcode any of these — read
64
+ them from the env vars.
65
+
66
+ ## Step 3: Resolve PROJECT_ROOT
67
+
68
+ ```bash
69
+ python3 - <<'PY'
70
+ from okstra_project import resolve_project_root, ResolverError
71
+ try:
72
+ pr = resolve_project_root(explicit_root="", cwd=".")
73
+ print(f"OK\t{pr}")
74
+ except ResolverError as e:
75
+ print(f"FAIL\t{e}")
76
+ PY
77
+ ```
78
+
79
+ - `OK` line → use that as `PROJECT_ROOT`.
80
+ - `FAIL` line → ask the user (`AskUserQuestion`, free text) for an absolute
81
+ project root. Re-run with `explicit_root=<their answer>`.
82
+
83
+ ## Step 4: Inspect or create `project.json`
84
+
85
+ ```bash
86
+ PROJECT_JSON="$PROJECT_ROOT/.project-docs/okstra/project.json"
87
+ if [ -f "$PROJECT_JSON" ]; then
88
+ cat "$PROJECT_JSON"
89
+ fi
90
+ ```
91
+
92
+ If the file exists, print its `projectId`/`projectRoot` and ask whether to
93
+ keep or overwrite. Default is to keep — okstra refuses to change `projectId`
94
+ on an existing project (see `okstra_project.resolver.upsert_project_json`),
95
+ so overwriting requires manually deleting the file first.
96
+
97
+ If the file does NOT exist, ask via `AskUserQuestion`:
98
+
99
+ - **Question**: `"Project id for okstra (e.g. INV-1234, fontsninja, okstra)"`
100
+ - **Validate**: slugified must contain at least one alphanumeric character.
101
+
102
+ Then create the file:
103
+
104
+ ```bash
105
+ python3 - <<PY
106
+ from pathlib import Path
107
+ from okstra_project import upsert_project_json
108
+ result = upsert_project_json(Path("$PROJECT_ROOT"), "$PROJECT_ID")
109
+ print(result)
110
+ PY
111
+ ```
112
+
113
+ ## Step 5: Verify
114
+
115
+ ```bash
116
+ npx -y okstra@latest doctor
117
+ ```
118
+
119
+ If all checks return `OK`, the setup is complete. If any check fails, surface
120
+ the output and let the user decide whether to re-run install or skip.
121
+
122
+ ## Step 6: Hand-off
123
+
124
+ Inform the user with a short summary:
125
+
126
+ > okstra is ready. Runtime: `~/.okstra` (version stamp). Project metadata:
127
+ > `<PROJECT_ROOT>/.project-docs/okstra/project.json` (`projectId`). Run
128
+ > `/okstra-run` to start your first task.
129
+
130
+ ## Failure modes
131
+
132
+ | Symptom | Cause | Fix |
133
+ |---|---|---|
134
+ | `command not found: npx` | Node missing | Install node 18+. |
135
+ | `okstra ensure-installed` keeps reinstalling | `~/.okstra/version` write fails (permissions) | Check `~/.okstra` ownership and writability. |
136
+ | `ResolverError: project_id required` | empty answer to Step 4 prompt | Re-ask Step 4. |
137
+ | `projectId 불일치` | `project.json` already exists with a different id | Decide which id is canonical; manually edit the file or pick the existing id. |
138
+ | `npx okstra@latest install` succeeds but `doctor` shows FAIL | runtime/{python,bin,skills} sync not yet performed (pre-release package) | Use dev install: clone the repo and run `node bin/okstra install --link <repo>`. |
@@ -0,0 +1,230 @@
1
+ ---
2
+ name: okstra-status
3
+ description: Use when the user asks for overall okstra task status, current lifecycle phase, next recommended phase, blockers, approval state, status for a specific task key, OR wants to update a task's workStatus (todo / in-progress / blocked / done). Trigger words include "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> 진행중", "<task-id> 완료".
4
+ ---
5
+
6
+ # OKSTRA Status
7
+
8
+ ## When to Use
9
+
10
+ - When user wants to view the progress of the entire project
11
+ - When user want to check the current phase, next phase, blockers, and resume points for a specific `task-key`
12
+ - When user want to check which tasks are pending approval or which tasks can be resumed
13
+
14
+ ## Step 0: Verify okstra runtime + project setup
15
+
16
+ Before any other step, ensure both the okstra runtime and the current
17
+ project's okstra metadata are in place:
18
+
19
+ ```bash
20
+ npx -y okstra@latest ensure-installed >/dev/null 2>&1 || {
21
+ echo "FAIL: okstra not installed; tell the user to run: npx okstra@latest install" >&2
22
+ exit 1
23
+ }
24
+ eval "$(npx -y okstra@latest paths --shell)"
25
+ export PYTHONPATH="$OKSTRA_PYTHONPATH"
26
+ OKSTRA_PROJECT_INFO="$(npx -y okstra@latest check-project --json)" || {
27
+ echo "FAIL: this project has no okstra setup. Tell the user to run /okstra-setup first." >&2
28
+ echo "$OKSTRA_PROJECT_INFO" >&2
29
+ exit 1
30
+ }
31
+ ```
32
+
33
+ `$OKSTRA_PROJECT_INFO` is JSON `{ok, projectRoot, projectJsonPath, projectId}` —
34
+ parse and reuse it instead of re-resolving in the steps below.
35
+
36
+ ## Step 1: Overall Project Status
37
+
38
+ To view the overall project status, first read `.project-docs/okstra/discovery/task-catalog.json`.
39
+
40
+ Extract the following fields from each task.
41
+
42
+ | Field | Description |
43
+ |------|------|
44
+ | `taskKey` | `<project-id>:<task-group>:<task-id>` |
45
+ | `taskType` | latest task type |
46
+ | `workCategory` | bugfix / feature / improvement / refactor / ops-change / unknown |
47
+ | `currentStatus` | task-level status |
48
+ | `currentPhase` | lifecycle current phase |
49
+ | `currentPhaseState` | lifecycle phase state |
50
+ | `nextRecommendedPhase` | next recommended phase |
51
+ | `routingStatus` | routing decision status |
52
+ | `awaitingApproval` | approval 대기 여부 |
53
+ | `latestRunStatus` | latest run status |
54
+ | `latestReportPath` | latest report path |
55
+ | `latestResumeCommandPath` | latest resume command |
56
+ | `workStatus` | user-managed work status (todo / in-progress / blocked / done; default in-progress) |
57
+ | `updatedAt` | last update time |
58
+
59
+ Sort by:
60
+
61
+ 1. `updatedAt` Descending
62
+ 2. Next, `taskKey`
63
+
64
+ 출력 형식:
65
+
66
+ ```markdown
67
+ ## okstra Status — <project-id>
68
+
69
+ | # | Task Key | Category | Phase | Phase State | Task Status | workStatus | Next | Routing | Approval | Last Run |
70
+ |---|----------|----------|-------|-------------|-------------|------------|------|---------|----------|----------|
71
+ | 1 | proj:group:id | bugfix | error-analysis | completed | completed | in-progress | implementation-planning | not-applicable | no | completed |
72
+ | 2 | proj:group:id2 | feature | requirements-discovery | prepared | instruction-set-generated | done | pending-routing-decision | pending | yes | prepared |
73
+ ```
74
+
75
+ ## Step 2: Specific Task Status
76
+
77
+ Given a specific `task-key` or `task-group + task-id`:
78
+
79
+ 1. If possible, quickly look it up in `task-catalog.json`.
80
+ 2. If necessary, read `.project-docs/okstra/tasks/<task-group>/<task-id>/task-manifest.json` directly.
81
+ 3. If you need the latest run information, read `history/timeline.json` along with the latest run manifest.
82
+
83
+ Required fields:
84
+
85
+ - `taskKey`
86
+ - `taskType`
87
+ - `workCategory`
88
+ - `currentStatus`
89
+ - `latestRunStatus`
90
+ - `workflow.currentPhase`
91
+ - `workflow.currentPhaseState`
92
+ - `workflow.phaseStates`
93
+ - `workflow.lastCompletedPhase`
94
+ - `workflow.nextRecommendedPhase`
95
+ - `workflow.awaitingApproval`
96
+ - `workflow.routingStatus`
97
+ - `workflow.lastSafeCheckpoint`
98
+ - `workStatus`
99
+ - `workStatusUpdatedAt`
100
+ - `workStatusNote`
101
+ - `latestReportPath`
102
+ - `latestResumeCommandPath`
103
+ - `historyTimelinePath`
104
+
105
+ Output format:
106
+
107
+ ```markdown
108
+ ## okstra Task Status — <task-key>
109
+
110
+ - Work category: `<category>`
111
+ - Current phase: `<phase>`
112
+ - Current phase state: `<phase-state>`
113
+ - Last completed phase: `<phase-or-->`
114
+ - Next recommended phase: `<phase>`
115
+ - Awaiting approval: `<yes|no>`
116
+ - Routing status: `<routing-status>`
117
+ - Task status: `<task-status>`
118
+ - Latest run status: `<run-status>`
119
+ - Latest report: `<relative-path-or-->`
120
+ - Resume command: `<relative-path-or-->`
121
+ - workStatus: `<todo|in-progress|blocked|done>` (updated `<workStatusUpdatedAt-or-->`)
122
+ - workStatus note: `<workStatusNote-or-->`
123
+
124
+ ### Phase States
125
+
126
+ - `requirements-discovery`: `<state>`
127
+ - `error-analysis`: `<state>`
128
+ - `implementation-planning`: `<state>`
129
+ - `implementation`: `<state>`
130
+ - `final-verification`: `<state>`
131
+
132
+ ### Safe Resume Checkpoint
133
+
134
+ - Label: `<checkpoint-label>`
135
+ - Run manifest: `<relative-path-or-->`
136
+ - Team state: `<relative-path-or-->`
137
+ - Report: `<relative-path-or-->`
138
+ - Resume command: `<relative-path-or-->`
139
+ ```
140
+
141
+ ## Step 3: Resume and Next-Step Guidance
142
+
143
+ The status response always includes one of the following options:
144
+
145
+ 1. **Resume current run**
146
+ - If `latestResumeCommandPath` exists, display that path.
147
+ 2. **Restart current phase**
148
+ - Indicates whether the task can be re-run with the same `task-key` and the current `taskType`.
149
+ 3. **Start next phase**
150
+ - If `workflow.nextRecommendedPhase` is one of `error-analysis`, `implementation-planning`, or `final-verification`, that phase is proposed as the next candidate for the Okstra run.
151
+ 4. **Need more information**
152
+ - If `nextRecommendedPhase` is `pending-routing-decision` or `routingStatus` is `pending`, this indicates that additional information is required.
153
+
154
+ ## Step 4: Update workStatus
155
+
156
+ The skill MUST recognize requests to change a task's `workStatus` and update the corresponding `task-manifest.json`.
157
+
158
+ ### Trigger Patterns (recognize both)
159
+
160
+ **Natural language (Korean / English)**:
161
+ - "DEV-6827 done으로 바꿔줘"
162
+ - "PROD-1623을 blocked로 표시"
163
+ - "DEV-9047 진행중"
164
+ - "Mark DEV-6827 as done"
165
+
166
+ **Explicit command**:
167
+ - `okstra status set <task-id> <status>`
168
+ - `okstra status set <task-group> <task-id> <status>` (used to disambiguate)
169
+ - `okstra mark <task-id> <status>`
170
+ - `okstra status set <task-id> <status> --note "<note>"`
171
+
172
+ Accepted `<status>` values: `todo`, `in-progress`, `blocked`, `done`.
173
+
174
+ ### Procedure
175
+
176
+ 1. **Validate status value**. If not in the enum, output an error and the allowed values list. Do not modify any file.
177
+
178
+ 2. **Look up the task** in `.project-docs/okstra/discovery/task-catalog.json` by `task-id` (case-insensitive on both `task-id` and `task-group`).
179
+ - If the user provided `<task-group>` explicitly, scope the lookup to that group (case-insensitive).
180
+ - If a single match is found → proceed.
181
+ - If multiple matches across different `task-group` values → list the groups and ask the user to retry with the explicit form. Example output:
182
+ ```
183
+ <TASK-ID>은 여러 task-group에 존재합니다:
184
+ - <group1>
185
+ - <group2>
186
+ 다음 형식으로 다시 시도하세요: okstra status set <task-group> <TASK-ID> <status>
187
+ ```
188
+ Stop without modifying any file.
189
+ - If no match → output `<TASK-ID>를 찾을 수 없습니다.` and stop.
190
+
191
+ 3. **Open the matching `task-manifest.json`** at `.project-docs/okstra/tasks/<task-group-segment>/<task-id-segment>/task-manifest.json`.
192
+
193
+ 4. **Update fields at the manifest root**:
194
+ - `workStatus` ← new status value
195
+ - `workStatusUpdatedAt` ← current ISO-8601 UTC timestamp (e.g. `2026-05-01T10:23:45Z`)
196
+ - `workStatusNote`:
197
+ - If `--note` is provided → set the field to its value.
198
+ - If `--note` is NOT provided → leave any existing `workStatusNote` field untouched (do not delete, do not blank). If the field did not exist before, do not create it.
199
+
200
+ **Manifest preservation rules** (critical to avoid silent corruption):
201
+ - Use a targeted in-place edit (e.g. the Edit tool with old_string/new_string anchors).
202
+ - Do NOT round-trip the file through `JSON.parse` + `JSON.stringify` — that reorders keys, drops trailing newlines, and normalizes spacing.
203
+ - Preserve the existing key order, indentation style, and trailing newline of the file exactly.
204
+
205
+ 5. **Confirm in Korean**:
206
+
207
+ ```
208
+ ✓ <TASK-ID> workStatus: <previous> → <new>
209
+ ✓ task-manifest.json 업데이트됨
210
+ ```
211
+
212
+ Use `<previous>` = `(없음)` if the field was absent before.
213
+
214
+ ### Default Value Convention
215
+
216
+ If `workStatus` is missing or empty in any manifest, treat it as `in-progress` for read purposes. Do not back-fill the field on read; only write it when the user explicitly issues an update.
217
+
218
+ ### Catalog Sync Note
219
+
220
+ This skill updates `task-manifest.json` only. `discovery/task-catalog.json` may become stale until it is regenerated by another tool. Downstream consumers (e.g. `okstra-schedule`) should re-read each manifest directly to obtain the authoritative `workStatus`.
221
+
222
+ ---
223
+
224
+ ## Output Rules
225
+
226
+ - Responses should be concise and written in Korean.
227
+ - Use project-relative paths whenever possible.
228
+ - If there is no recent report, display `--`.
229
+ - If a specific task does not exist, explicitly state that it cannot be found based on `task-catalog.json`.
230
+ - If `awaitingApproval` is true, clearly indicate that the task is awaiting user approval.