For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Build a shared interaction control layer that powers a project-scoped writing TUI first and becomes the common control brain for both TUI and Studio.
Architecture: Introduce a new core/interaction subsystem for session state, intent routing, execution status, automation policy, and edit transactions. Keep PipelineRunner as the execution substrate, build a thin TUI shell in packages/cli, and refit Studio to call the same interaction APIs instead of owning separate orchestration logic.
Tech Stack: TypeScript, InkOS core pipeline, Commander CLI, Ink-based TUI shell, existing Studio React client, Vitest.
Files:
packages/core/src/interaction/session.tspackages/core/src/interaction/intents.tspackages/core/src/interaction/modes.tspackages/core/src/interaction/events.tspackages/core/src/index.tspackages/core/src/__tests__/interaction-models.test.tsStep 1: Write the failing test
Create coverage for:
InteractionSessionAutomationModeInteractionIntentExecutionStatusPendingDecisionInclude assertions for:
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-models.test.ts
Expected:
Step 3: Write minimal implementation
Implement:
AutomationMode = "auto" | "semi" | "manual"InteractionIntentType unionExecutionStatus unionInteractionSession interfacePendingDecision interfacebindActiveBookclearPendingDecisionisTerminalExecutionStatusKeep each file under 200 lines.
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-models.test.ts
Expected:
Step 5: Commit
git add packages/core/src/interaction/session.ts packages/core/src/interaction/intents.ts packages/core/src/interaction/modes.ts packages/core/src/interaction/events.ts packages/core/src/index.ts packages/core/src/__tests__/interaction-models.test.ts
git commit -m "feat(interaction): add shared control models"
Files:
packages/core/src/interaction/runtime.tspackages/core/src/interaction/request-router.tspackages/core/src/index.tspackages/core/src/__tests__/interaction-runtime.test.tsStep 1: Write the failing test
Cover:
continue_book routes to writeNextChapterrevise_chapter routes to reviseDraftrewrite_chapter routes to reviseDraft(mode="rewrite")update_current_focus routes to the existing write surfaceswitch_mode updates session policy onlyUse a mocked PipelineRunner-shaped object.
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-runtime.test.ts
Expected:
Step 3: Write minimal implementation
Implement:
InteractionRuntimerunInteractionRequest(...)routeIntentToRequest(...)Rules:
ExecutionStatus transitionsStep 4: Run test to verify it passes
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-runtime.test.ts
Expected:
Step 5: Commit
git add packages/core/src/interaction/runtime.ts packages/core/src/interaction/request-router.ts packages/core/src/index.ts packages/core/src/__tests__/interaction-runtime.test.ts
git commit -m "feat(interaction): add runtime bridge"
Files:
packages/cli/src/commands/tui.tspackages/cli/src/index.tspackages/cli/src/__tests__/tui-command.test.tsStep 1: Write the failing test
Cover:
inkos without a subcommand launches the TUI entryStep 2: Run test to verify it fails
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/tui-command.test.ts
Expected:
Step 3: Write minimal implementation
Implement:
tuiCommandinkos opens TUI when no subcommand is providedDo not add visual complexity yet.
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/tui-command.test.ts
Expected:
Step 5: Commit
git add packages/cli/src/commands/tui.ts packages/cli/src/index.ts packages/cli/src/__tests__/tui-command.test.ts
git commit -m "feat(cli): add project-scoped TUI entry"
Files:
packages/cli/src/tui/app.tsxpackages/cli/src/tui/status-bar.tsxpackages/cli/src/tui/session-pane.tsxpackages/cli/src/tui/process-pane.tsxpackages/cli/src/tui/input-bar.tsxpackages/cli/src/__tests__/tui-layout.test.tsxStep 1: Write the failing test
Cover rendering for:
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/tui-layout.test.tsx
Expected:
Step 3: Write minimal implementation
Render:
Keep all components small:
< 180 lines eachStep 4: Run test to verify it passes
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/tui-layout.test.tsx
Expected:
Step 5: Commit
git add packages/cli/src/tui/app.tsx packages/cli/src/tui/status-bar.tsx packages/cli/src/tui/session-pane.tsx packages/cli/src/tui/process-pane.tsx packages/cli/src/tui/input-bar.tsx packages/cli/src/__tests__/tui-layout.test.tsx
git commit -m "feat(tui): scaffold interaction shell"
Files:
packages/core/src/interaction/nl-router.tspackages/core/src/interaction/request-router.tspackages/core/src/__tests__/interaction-nl-router.test.tsStep 1: Write the failing test
Cover parsing for:
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-nl-router.test.ts
Expected:
Step 3: Write minimal implementation
Implement a deterministic first-wave parser:
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-nl-router.test.ts
Expected:
Step 5: Commit
git add packages/core/src/interaction/nl-router.ts packages/core/src/interaction/request-router.ts packages/core/src/__tests__/interaction-nl-router.test.ts
git commit -m "feat(interaction): add deterministic natural-language routing"
Files:
packages/core/src/interaction/modes.tspackages/core/src/interaction/runtime.tspackages/core/src/pipeline/runner.tspackages/core/src/__tests__/interaction-modes.test.tsStep 1: Write the failing test
Cover:
auto continues chapter progression unless a hard stop occurssemi requires an explicit next-chapter startmanual never self-continuesstate-degraded still hard-blocks in all modesStep 2: Run test to verify it fails
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-modes.test.ts
Expected:
Step 3: Write minimal implementation
Add:
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/core exec vitest run src/__tests__/interaction-modes.test.ts
Expected:
Step 5: Commit
git add packages/core/src/interaction/modes.ts packages/core/src/interaction/runtime.ts packages/core/src/pipeline/runner.ts packages/core/src/__tests__/interaction-modes.test.ts
git commit -m "feat(interaction): add automation modes"
Files:
packages/core/src/interaction/edit-controller.tspackages/core/src/interaction/truth-authority.tspackages/core/src/__tests__/edit-controller.test.tsStep 1: Write the failing test
Cover:
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/core exec vitest run src/__tests__/edit-controller.test.ts
Expected:
Step 3: Write minimal implementation
Implement:
Do not yet perform all downstream rewrites automatically; phase 1 only needs correct planning and scope marking.
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/core exec vitest run src/__tests__/edit-controller.test.ts
Expected:
Step 5: Commit
git add packages/core/src/interaction/edit-controller.ts packages/core/src/interaction/truth-authority.ts packages/core/src/__tests__/edit-controller.test.ts
git commit -m "feat(interaction): add edit controller"
Files:
packages/studio/src/api/server.tspackages/studio/src/components/ChatBar.tsxpackages/studio/src/App.tsxpackages/studio/src/api/server.test.tspackages/studio/src/components/chatbar-state.test.tsStep 1: Write the failing test
Cover:
Step 2: Run test to verify it fails
Run:
pnpm --dir packages/studio exec vitest run src/api/server.test.ts src/components/chatbar-state.test.ts
Expected:
/api/agentStep 3: Write minimal implementation
Replace one-shot behavior with:
Keep Studio page structure mostly intact for phase 1.
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/studio exec vitest run src/api/server.test.ts src/components/chatbar-state.test.ts
Expected:
Step 5: Commit
git add packages/studio/src/api/server.ts packages/studio/src/components/ChatBar.tsx packages/studio/src/App.tsx packages/studio/src/api/server.test.ts packages/studio/src/components/chatbar-state.test.ts
git commit -m "feat(studio): route chat through interaction control layer"
Files:
packages/cli/src/__tests__/cli-integration.test.tspackages/core/src/__tests__/pipeline-agent.test.tsStep 1: Write the failing test
Add one flow that covers:
semiStep 2: Run test to verify it fails
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/cli-integration.test.ts
Expected:
Step 3: Write minimal implementation
Fill any missing glue only.
Avoid broad refactors at this stage.
Step 4: Run test to verify it passes
Run:
pnpm --dir packages/cli exec vitest run src/__tests__/cli-integration.test.ts
pnpm --dir packages/core exec tsc --noEmit --pretty false
pnpm --dir packages/core run build
Expected:
Step 5: Commit
git add packages/cli/src/__tests__/cli-integration.test.ts packages/core/src/__tests__/pipeline-agent.test.ts
git commit -m "test(interaction): verify end-to-end control flow"