Skip to content

WIP: desktop UI (Tauri) + interactive chat-driven planning - #38

Draft
Lotus015 wants to merge 13 commits into
mainfrom
feat/37-interactive-planning
Draft

WIP: desktop UI (Tauri) + interactive chat-driven planning#38
Lotus015 wants to merge 13 commits into
mainfrom
feat/37-interactive-planning

Conversation

@Lotus015

@Lotus015 Lotus015 commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Tracks #37.

Working branch for the new direction: retire the ratatui TUI, keep a headless engine, build a Tauri desktop UI, with interactive chat-driven planning before execution as the centerpiece.

This PR starts as a design spec (docs/desktop-ui-and-interactive-planning.md) to elaborate on, then carries the F0 + F1 work:

  • F0 — headless baro streams the full event stream (incl. planning) + local bridge.
  • F1 — conversational planner (Mozaik participant, reusing the Surgeon's split/prereq/rewire/add/remove DAG-mutation vocab) + draft PRD + RUN gate; read-only DAG preview in the UI.

Draft until F0+F1 are testable. See #37 for the full rationale and phased plan.

🤖 Generated with Claude Code

Lotus015 and others added 13 commits June 3, 2026 12:39
Refs #37. Headless engine + Tauri client (retire TUI), local-first;
chat-driven planning before execution (Mozaik participant reusing the
Surgeon's DAG-mutation vocabulary); phased F0-F4, first milestone F0+F1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #37. Architect/planner runners spawn_and_capture stdout; BaroEvent
stream only starts in orchestrate after prd.json exists. F1 needs a new
long-lived conversational planner participant, not an extension of the
capture path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #37. PlannerSession (Mozaik-flavoured) holds a draft PRD + transcript
and mutates it per chat turn, reusing the Surgeon's pure applyReplan
(add/remove/rewire) + a retier pass; rejects cycle-inducing mutations via
buildDag. scripts/session.ts is ONE long-lived process: PLAN (stdin
plan_message -> stdout plan_draft/plan_reply) then run_plan -> orchestrate()
over the same event stream. Model call injectable: 5/5 deterministic tests
with a mock; verified live end-to-end (sonnet planner split+retier+rewire).

Note: scripts/ isn't in tsconfig include, so tsc doesn't check session.ts
(caught a '*/'-in-comment bug only via tsx). Follow-up: typecheck scripts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes #39. The StoryLifecycleForwarder hardcoded files_created/modified
to 0 (StoryResultData carries no per-story file stats, and the run-total
git diff only feeds the 'done' event). Now the forwarder attributes
write/edit tool calls to their story via onExternalFunctionCall (the same
signal the Sentry uses), tracking distinct paths classified by first-touch
tool (Write/write_file -> created; Edit/MultiEdit/NotebookEdit/edit_file ->
modified) and reports real counts. Backend-agnostic; no change to the
story agents or StoryResultData.

Verified e2e: a one-story run creating math.js + math.test.js now emits
files_created:2, files_modified:0 (was 0/0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #37. New desktop/ Tauri app: Rust core (src-tauri/src/lib.rs) spawns
the long-lived session.ts, forwards its stdout events as Tauri
'session-event's and writes plan_message/run_plan to its stdin. React 19 +
Tailwind v4 + shadcn cockpit (src/App.tsx, src/protocol.ts): start a run,
plan by chat with a live read-only DAG (per-story tier badges), RUN gate,
then live story status + log. Frontend builds (tsc+vite); src-tauri
cargo check passes against Tauri 2.11. Root workspace excludes
desktop/src-tauri.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ory_log feed

Refs #37. session.ts now emits plan_status (planning/refining/idle) around
the planner calls so the UI shows activity during the otherwise-silent
~10-20s planner turn. The desktop cockpit gains: a live activity strip
('Planning with sonnet…' / 'Running S4, S5' with a spinner), a typewriter
reveal for planner messages, a 'thinking…' indicator, pulsing active DAG
nodes showing each running story's latest log line ('where'), and a live
story_log feed (the agents' real per-line stream, tool calls included) —
previously dropped by the UI. Frontend builds (tsc+vite).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t composer

Refs #37. RUN now lives top-right of the DAG panel (planning phase only),
where the plan it gates lives; the chat composer gets an always-present
Send icon button (lucide) in RUN's old spot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…unning

Refs #37. Nodes were min-w only, so the card grew/shrank to fit the longest
content — and the streaming 'last line' changes constantly, making cards
resize. Now: fixed w-56, title line-clamp-2, and a reserved fixed-height
truncated activity row so width and height stay stable as the run streams.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… / effort

Refs #37. The start screen was hardcoded to sonnet/no_git:false, so the
0.48.0 per-story tiering + endpoints were invisible in the app. Adds a
'Run options' section (shadcn select/switch/label): planner model,
execution backend, effort, --tier-map, --openai-endpoint list (name=url,
keys still from env), and a no-git switch — all passed through start_session
(Rust already accepted them). Now a mixed-fleet run (e.g. MiniMax + Claude)
is configurable from the UI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #37. Closes the 'message a running story' gap. orchestrate() gains an
onOperatorReady hook so a caller can grab the Operator before stories run;
session.ts no longer blocks/closes stdin on run_plan — it keeps reading and
dispatches redirect/abort/shutdown to the live Operator (redirect →
AgentTargetedMessage → the story agent's inbox). In the cockpit, during
execution you click a running DAG node to target it (ring), and the composer
sends a redirect there (placeholder shows the target); planning still sends
plan_message. Orchestrator typecheck + desktop build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, brand accent

Refs #37. Decomposes the monolithic App.tsx into a proper structure:
- hooks/useSession.ts owns all runtime state + the Tauri event bridge
- components/: TitleBar, StatusBar, StartView, RunOptions, ChatPanel,
  DagPanel, StoryNode, DoneSummary, Typed, Spinner
- App.tsx is now a thin shell composing them

IDE polish: rebranded to BDE (Baro Development Environment) — product name +
window title; VS Code-style bottom StatusBar (activity · backend · planner ·
tokens · stories · elapsed); resizable chat|DAG panels (react-resizable-panels);
a done-summary banner (result · counts · tokens · PR · New run). The baro brand
orange (#ffb547, from baro-website) is wired as a Tailwind `baro` token and used
subtly — brand dot, RUN button, running-node ring, spinner edge, PR links.

Frontend builds clean (tsc + vite). Adds shadcn select/switch/label/resizable/tooltip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs #37. Addresses run feedback:
- The planner now speaks on the INITIAL plan, not just on refinements: seed
  asks the model for a conversational 'reply' (what it built, what's
  parallel, why those tiers, a nudge to refine or RUN), emitted as plan_reply.
  Previously the left pane was empty until you typed.
- Status-bar timer only ticks while something is actually happening (planner
  thinking or stories executing); it freezes once the plan is drafted and
  waiting, and the clock restarts at RUN so it measures the run. (Was ticking
  during idle planning.)
- Chat polished into proper conversation bubbles (planner left w/ baro dot +
  typewriter, you right); 'Output' header on the feed pane.

session.ts transforms; planner tests 5/5; desktop builds clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant