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.
- package/README.md +1451 -17
- package/bin/okstra +7 -5
- package/package.json +5 -7
- package/runtime/BUILD.json +2 -2
- package/runtime/skills/okstra-context-loader/SKILL.md +140 -0
- package/runtime/skills/okstra-convergence/SKILL.md +289 -0
- package/runtime/skills/okstra-history/SKILL.md +137 -0
- package/runtime/skills/okstra-report-finder/SKILL.md +87 -0
- package/runtime/skills/okstra-report-writer/SKILL.md +256 -0
- package/runtime/skills/okstra-run/SKILL.md +231 -0
- package/runtime/skills/okstra-schedule/SKILL.md +627 -0
- package/runtime/skills/okstra-setup/SKILL.md +138 -0
- package/runtime/skills/okstra-status/SKILL.md +230 -0
- package/runtime/skills/okstra-team-contract/SKILL.md +402 -0
- package/runtime/skills/okstra-time-summary/SKILL.md +138 -0
- package/src/check-project.mjs +188 -0
- package/src/doctor.mjs +15 -0
- package/src/install.mjs +91 -2
- package/src/paths.mjs +2 -2
- package/src/uninstall.mjs +59 -6
|
@@ -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.
|