| name | oat-project-new |
| version | 1.3.1 |
| description | Use when starting a spec-driven OAT project from scratch. Scaffolds a new project under PROJECTS_ROOT and sets it active. |
| argument-hint | <project-name> [--force] |
| disable-model-invocation | true |
| user-invocable | true |
| allowed-tools | Read, Write, Bash, Glob, Grep, AskUserQuestion |
New OAT Project
Create a new OAT project directory, scaffold standard artifacts from .oat/templates/, and set activeProject in local config.
Progress Indicators (User-Facing)
-
Print a phase banner once at start using horizontal separators, e.g.:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OAT ▸ NEW PROJECT
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
Before multi-step work, print step indicators, e.g.:
[0/3] Checking inherited git state...
[1/3] Validating project name…
[2/3] Scaffolding project artifacts…
[3/3] Refreshing dashboard…
Process
Step 0 (Preflight): Inherited Git State
Before scaffolding, surface the working tree state so unrelated changes don't get carried into the project workflow's bookkeeping commits.
- Run
git status --porcelain. If empty, continue silently to the next step.
- If non-empty, present the dirty list to the user.
- If
.oat/sync/manifest.json or paths under .claude/, .cursor/, .codex/ appear in the list, note: "These are generated by oat sync (often by pnpm run worktree:init or oat-worktree-bootstrap-auto) and are typically safe to commit as chore: run sync."
- Offer three choices via
AskUserQuestion:
- Commit now (recommended when only sync output is dirty) — stage and commit. For sync-only diffs, default the message to
chore: run sync; otherwise ask the user for the commit message.
- Proceed anyway — start the project workflow with the dirty state acknowledged.
- Abort — exit the skill so the user can clean up manually.
Tool availability is not the same as interactivity. If AskUserQuestion is unavailable but chat is available, present the three choices as a plain chat message and wait for the user's reply. Only fall back to "Proceed anyway" when OAT_NON_INTERACTIVE=1 is set or there is no user-response channel at all.
Do not advance past this gate without an explicit choice.
Step 0.5: Resolve Projects Root
Resolve {PROJECTS_ROOT} (same order as other OAT skills):
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo \".oat/projects/shared\")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
Step 1: Get Project Name
If not provided in $ARGUMENTS, ask the user for {project-name} (slug format: alphanumeric/dash/underscore only).
Step 2: Scaffold Project (Deterministic)
Use the CLI scaffolder:
oat project new "{project-name}" --mode spec-driven
Optional flags:
--force (non-destructive; only fills missing files/dirs, does not overwrite)
--no-set-active
--no-dashboard
Step 3: Confirm + Next Step
Confirm to the user:
- Project path created:
{PROJECTS_ROOT}/{project-name}
- Active project set in local config:
.oat/config.local.json (activeProject)
- Repo State Dashboard refreshed locally:
.oat/state.md (if enabled; generated and normally gitignored)
Then explicitly instruct the user to run discovery next:
- Next command:
oat-project-discover
Success Criteria
- ✅
{PROJECTS_ROOT}/{project-name}/ exists
- ✅ Standard artifacts exist in the project dir (copied from
.oat/templates/*.md)
- ✅
activeProject in .oat/config.local.json points at the project path
- ✅
.oat/state.md is refreshed locally unless disabled; it is not staged or committed.