---
name: okstra-setup
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 .okstra/project.json. Trigger words include "okstra setup", "setup okstra", "initialize okstra", "okstra init", "first time okstra setup", "configure okstra here".
---

# okstra-setup

One-time bootstrap. Run when okstra is being used for the first time on this
machine, or when adopting okstra in a new project.

## When to use

- `~/.okstra/version` is missing or stale → okstra runtime is not installed yet.
- The current project has no `.okstra/project.json` yet.
- The user says "set up okstra here", "first time", "okstra init", etc.

## When NOT to use

- A task is already in flight → use [`okstra-run`](../okstra-run/SKILL.md) or
  [`okstra-inspect status`](../okstra-inspect/SKILL.md).
- Day-to-day usage in a project that already has `project.json` — skip this skill.

## Prerequisites

Inform the user up-front and confirm before continuing:

- **Node 18+** required (runs `npx`). If missing, point to `brew install node`
  or `nvm`.
- **Python 3.10+** required (runs the okstra core).
- The current working directory must be inside the project that will host the
  okstra metadata. If unsure, ask with `AskUserQuestion` for an absolute project
  root before proceeding.

## Step 1: Install okstra

```bash
npx -y okstra@latest install --runtime claude-code
```

This single command populates everything the user needs:

- `~/.okstra/{lib/python, bin, version}` — python + bash runtime
- `~/.claude/skills/<name>/SKILL.md` — all okstra skills (canonical count
  in `~/.okstra/installed-skills.json`)
- `~/.okstra/installed-skills.json` — manifest for safe uninstall

The skill should run this even if `~/.okstra/version` already exists —
`install` is idempotent (per-file hash skip), so re-running is cheap and
ensures the install matches the package version currently on disk.

Show the final summary line back to the user (`version stamp: x.y.z`).

If install fails, surface the stderr verbatim. Do NOT try to "fix" it by
running the legacy `okstra-install.sh` — that path is dev-only.

**Bash invocation rule (permission-friendly)**: after Step 1, every Bash command in this skill MUST begin with the literal token `okstra` and pass literal argument values. Do not introduce shell variables (`$PROJECT_ROOT`, `$PROJECT_ID`, ...), `$(...)` command substitution, leading `VAR=...` assignments, or wrap commands in `if`/`eval`/`||`/`&&` — any of those make the leading token non-literal, defeat the `Bash(okstra:*)` permission match, and force a confirmation prompt on every call. When a prior tool call emitted a path or value, paste the literal string into the next command. Every `okstra <subcmd>` call self-bootstraps its Python path — never run `okstra paths --shell` / `export PYTHONPATH=...`.

## Step 2: Resolve PROJECT_ROOT

```bash
okstra preflight
```

Read the fixed `Okstra preflight`, `Project root`, `Project JSON`, `Project ID`,
`Reason`, and `Recovery` lines.

- `Ok: true` → carry `Project root` as a literal absolute string and paste it into every subsequent command in this skill.
- `Ok: false`, `Stage: resolve` → ask the user (`AskUserQuestion`, free text) for an absolute project root and rerun as a separate Bash tool call with the literal absolute path:

  ```bash
  okstra preflight --cwd /abs/path/from/user
  ```

- `Ok: false`, `Stage: project_json_missing` → proceed to Step 3 (this is the normal create path).
- `Ok: false`, any other `Stage` (`python`, `parse`, `project_json_invalid`) → show the fixed `Reason` line to the user verbatim and follow the `Recovery` line (typically `okstra doctor` to diagnose, then `okstra ensure-installed` or re-running the Step 1 install). `Reason` is the SSOT — do not hand-enumerate stage causes.

## Step 3: Project metadata setup

Render the existing project metadata with the purpose-specific view. Paste the
literal `projectRoot` value parsed in Step 2:

```bash
okstra model-io project-context --project-root /abs/path/to/projectRoot
```

If the command reports that project metadata is missing, treat that as the
"create" branch below. Otherwise, surface the rendered `Project ID` and
`Project root`, then ask whether to keep or overwrite. Default is to keep —
okstra refuses to change `projectId` on an existing project (see
`okstra_project.resolver.upsert_project_json`), so overwriting requires
manually deleting the file first.

If the file does NOT exist, ask via `AskUserQuestion`:

- **Question**: `"Project id for okstra (e.g. INV-1234, my-app, okstra)"`
- **Validate**: the answer must be non-empty AND contain at least one
  alphanumeric character. Re-ask on empty input — `okstra setup --yes`
  with no `--project-id` exits 1 with
  `error: --project-id is required (no existing project.json, not a TTY)`,
  so passing the user's empty answer through is a silent failure path.

Then create the file — paste the literal `projectRoot` from Step 2 and the literal `projectId` from the user's answer (no shell variables):

```bash
okstra setup --yes --project-root /abs/path/to/projectRoot --project-id my-project-id
```

## Step 3.5 (optional): project customisation

The built-in defaults work for most projects — skip straight to Step 4
(`doctor`) unless the user explicitly asks for one of these. When they do,
**read `references/project-config.md` next to this SKILL.md** and follow the
matching section:

- **A. worktree sync dirs** (`worktreeSyncDirs`) — extra directories symlinked
  into task worktrees.
- **B. project QA commands** (`qaCommands`, recommended) + **B.1 `qaEnv`** —
  check-only lint/format/typecheck/test baselines and the Tier 3 environment.
  Local `io` conformance is blocking; DB/HTTP/external QA is advisory and
  remains user-owned when automatic execution cannot PASS.
- **C. `.claude/settings.local.json` symlink** — automatic; read only to
  diagnose a symlink/backup warning.
- **D. PR body template** (release-handoff) — opt-in pre-registration; also
  offered on the first release-handoff run.
- **E. final report language** (`reportLanguage`) — default is auto (follows
  the brief's language).
- **F. declared architecture style** (`architecture.style`) — `hexagonal` /
  `layered` / `none`; hand-added, default `none`. Declaring one makes that
  architecture's placement rules binding in planning + verification.

## Step 4: Verify

```bash
okstra doctor --runtime claude-code
```

If all checks return `OK`, the setup is complete. If any check fails, surface
the output and let the user decide whether to re-run install or skip.

## Step 5: Hand-off

Inform the user with a short summary:

> okstra is ready. Runtime: `~/.okstra` (version stamp). Project metadata:
> `<PROJECT_ROOT>/.okstra/project.json` (`projectId`). Run
> `/okstra-run` to start your first task.

## Failure modes

| Symptom | Cause | Fix |
|---|---|---|
| `command not found: npx` | Node missing | Install node 18+. |
| `okstra ensure-installed` keeps reinstalling | `~/.okstra/version` write fails (permissions) | Check `~/.okstra` ownership and writability. |
| `error: --project-id is required (no existing project.json, not a TTY)` | `okstra setup --yes` invoked without `--project-id`, or with empty answer to Step 3 prompt | Re-ask Step 3 and pass a non-empty id via `--project-id`. |
| `projectId mismatch` / `projectId mismatch` | `project.json` already exists with a different id | Decide which id is canonical; manually delete `<PROJECT_ROOT>/.okstra/project.json` to re-register, or re-run with the existing id. |
| `EACCES` writing under `.okstra/` | directory owned by another user (e.g. created by a previous root-shell run) | `chown -R "$USER" <PROJECT_ROOT>/.okstra` or delete and let setup recreate. |
| `warning: failed to provision .claude/settings.local.json symlink` | a non-symlink `.claude/settings.local.json` already exists and the backup-and-replace step failed | Inspect `<PROJECT_ROOT>/.claude/settings.local.json{,.bak.*}`; manually merge project-specific rules, then re-run setup. |
| `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>`. |
