Commit Graph

15 Commits

Author SHA1 Message Date
607f3fbd8b feat(kanban): auto-resolve merge-all conflicts with an agent
Some checks failed
CI / Rust Check (push) Has been cancelled
CI / TypeScript Check (docs) (push) Has been cancelled
CI / TypeScript Check (site) (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
When the merge-all batch hits a conflict, spawn a conflict-resolution
agent in the main worktree (where the merge is mid-conflict), await it,
and continue the batch through the remaining branches instead of
aborting for manual resolution.

- worktrees: replace abort-on-conflict mergeBranches with non-aborting
  attemptMerge (leaves the tree mid-merge, returns conflicted paths),
  plus abortMerge/hasMergeInProgress/unmergedPaths/createRecoveryBranch.
  Batch types gain conflict/resolutionRunId/recoveryRef.
- prompt: buildConflictResolutionPrompt resolves both sides preserving
  intent, honors repo conventions (no Rust warning suppression), runs
  cargo/pnpm checks, then completes the merge with a commit.
- runs: mergeAll() is async; per branch it attemptMerges, and on conflict
  starts a streamable resolution run in REPO_ROOT, awaits it, and
  verifies the merge actually completed (no MERGE_HEAD, clean tree) before
  continuing — otherwise aborts and halts. A mergeBatchInProgress guard
  prevents two batches at once; a pre-batch recovery ref snapshots HEAD.
- route: /runs/merge-all is async; node request/socket timeouts disabled
  so a long multi-conflict batch survives.
- UI: per-branch status shows "conflict resolved by agent" + resolution
  run id; a recovery-ref banner documents how to roll the batch back.

Safety: resolution only counts if verified; otherwise the merge is
aborted and main left clean. Resolution runs are real agent_runs (stream
into the dock, stoppable) and own no worktree.
EOF && echo "" && git log --oneline -3
2026-06-17 22:07:49 -04:00
d538ccdd4e feat(kanban): merge-all branches + floating running-agents dock
Two board-level additions:

Merge all reviewable agent branches into the main branch sequentially:
- worktrees.mergeBranches() merges candidates in order, advancing HEAD each
  time; refuses if the main tree is dirty, and on the first conflict aborts
  that merge (main left clean) and stops — prior merges stay, untried
  branches reported as unattempted.
- runManager.mergeAll() picks candidates (settled runs that own their
  worktree, branch present, not yet in HEAD; deduped, oldest-first) — so
  refinement runs (which inherit a worktree) are correctly excluded.
- POST /runs/merge-all; ⬇ Merge all button in the board header opens a
  results modal (per-branch ✓/⇢/⚠, conflict banner, inline git output).

Floating dock to view/open running agents (front-end only):
- RunningAgentsBar pins bottom-right (below the card modal), lists every
  running run with live elapsed times, and opens that card's modal on click;
  auto-hides when nothing runs, collapsible otherwise.
EOF && echo "" && git log --oneline -4
2026-06-17 21:04:51 -04:00
408bdb6dd7 fix(kanban): recover and self-heal stuck agent runs
A run could get stranded at 'running' in the UI after a crash/disconnect/
restart, with no way to clear it. Root cause was a race: the SSE history
replay re-asserted a stale `running` status that beat the poll's settled
status, leaving the run showing "Running" + the settle error at once.

Server (runs.ts / runner.ts / index.ts):
- reconcile() on every read force-settles any 'running' run with no live
  runner, so the board self-heals on the next poll (≤3s) — no restart needed.
- forceSettle() emits a persisted `status` event so an open/reconnecting
  SSE stream replays the terminal state last, not a stale `running`.
- Startup orphan-reconciliation now also emits that event (was the gap that
  let the replay re-assert `running` after a server restart).
- Idle watchdog (10min): a silent pi is settled as 'failed' instead of
  hanging forever; SIGKILL escalation (20s) reaps wedged processes.
- stop() now recovers: active→abort, orphaned-but-running→force-stop
  (the Stop button clears wedged runs instead of 409'ing).
- start() catch force-settles 'failed' so a spawn failure never orphans a
  half-created 'running' row.

Client (useOrchestrator.ts):
- patchRun refuses to un-settle a terminal run, dropping stale replayed
  status as a belt-and-suspenders guard against any such race.
EOF && echo "" && git log --oneline -3
2026-06-17 18:53:44 -04:00
6531dc00df feat(kanban): resume runs' chat via Refine + isolate the event stream
Two intertwined changes that both touch the orchestrator hook + run console:

Isolate the agent event stream (perf):
- useRunStream owns the SSE stream + event log locally inside AgentRunBar, so a
  burst of streamed events re-renders only the console — never the board page or
  card modal (which was causing frame drops at run start).
- useOrchestrator is now a registry only; lifecycle events reflect back up via
  stable patchRun/reflectBevy reflectors (effect deps depend on those, not the
  whole object, avoiding a stream-teardown loop).

Session resume for Refine:
- Runs now persist their pi session (drop --no-session); each fresh run captures
  its session JSONL path into a new agent_runs.session_file column (additive,
  idempotent migration).
- Refine resumes the prior run's actual session (--session <path> → appends) in
  that run's own worktree (inherited, never owned), sending the operator's
  feedback as the next message in the same conversation with full prior context.
- owns_worktree guards remove()/cleanup so a refinement never destroys the
  owning run's worktree; bad refinement targets return 409.
- AgentRunBar shows Refine only for settled runs with a recorded session.
EOF && echo "" && git log --oneline -3
2026-06-17 18:34:05 -04:00
292005edbb perf(kanban): stop board cards re-rendering on every agent event
Memoize the board so streaming events from an active run no longer force
all 38 collapsed cards to re-render — only the open CardModal/AgentRunBar
re-renders, since its props stay referentially equal.

- KanbanCard: wrap in React.memo; take isRunning/bevyRunning primitives
  instead of the whole orchestrator object; onOpen now takes the card id.
- useOrchestrator: expose a memoized activeByCard map, recomputed only
  when runs/bevyRunning change (not on every streamed text/tool event).
- KanbanBoardPage: pass a stable openById callback + primitive props so
  memo bails; memoize StatCard; extract the static category legend to a
  memoized CategoryLegend component.

Also drops the per-card .filter().find() status scans each render.
2026-06-16 20:32:08 -04:00
72a41c2d76 feat(kanban): card detail modal and rich agent-run console
- RunEventList: grouped activity timeline. Assistant text becomes chat
  bubbles (auto-collapsing long messages); tool_start/tool_end pair into
  entries with spinners and expandable input/result blocks; bevy output
  rolls into a live console; relative timestamps on a left rail
- AgentRunBar: redesigned as a mission console. Live stats header (elapsed
  time, tool count, events), animated status banner with sweep/glow while
  running, clearer action bar. All controls preserved (run/steer/stop,
  diff/merge/bevy) so the human-only merge/complete safety model holds
- tailwind.css: vn-flow, vn-sweep, vn-dots, vn-spin keyframes
- CardModal: full card overlay (orchestrator, references, tags, comments)
- DiffModal: branch-diff review (commits, stat, capped patch)
- useOrchestrator: background polling + bevy status sync + ref-counted SSE
- KanbanCard: pulsing agent/bevy running badge on collapsed cards
2026-06-16 18:17:35 -04:00
a3c72bb878 feat(kanban): persist board, reference pages, and run agents
Replace the localStorage kanban with the backend-backed board, add typed clients
and a React hook with optimistic updates. Cards can reference static doc pages
and user-created custom pages (new "custom" reference type with purple chips).

Add the agentic orchestrator UI: a per-card panel to launch `pi` runs, watch a
live tool/thought stream over SSE, steer mid-run, and stop — while the board
stays fully interactive. The board page wires the orchestrator and custom-pages
stores into every card.
2026-06-16 15:44:29 -04:00
c24a6106bf feat(docs): add custom documentation pages with AI beautify
User-created dynamic doc pages live at /docs/custom/:slug, persisted in the new
backend. The editor offers "Beautify with AI", which regenerates the page as
structured HTML with Mermaid diagrams and replaces the raw markdown source (the
beautified version becomes the page's canonical content and survives edits).

Adds a DocHtml renderer that lazily renders Mermaid blocks, a purple design
token, sidebar/topbar entries for custom pages, and routing.
2026-06-16 15:44:16 -04:00
efdc34637e feat(api): add backend with kanban, docs store, and orchestrator
Introduce the @void-nav/api Hono + SQLite backend that powers the docs site:
a persisted implementation board (kanban), a custom documentation-pages store
with AI beautify, and an agentic orchestrator that runs `pi` agents per card.

The orchestrator spawns `pi --mode rpc` inside an isolated git worktree per run,
streams slim events over SSE, and lets the agent drive the board/docs via
token-gated internal endpoints (all SQLite writes stay in-process). Interrupted
runs are reconciled to "stopped" on boot.

Workspace wiring: root `dev:api`/`dev:web` scripts with `concurrently`, the
docs Vite `/api` proxy, and `.worktrees/` gitignore.
2026-06-16 15:43:58 -04:00
57633addfe chore: sync codebase remediation, gameplay systems, and docs
Security & infrastructure:
- Remove unused services/ (auth, spacetimedb) and auth.db
- Add .env.example template, expand .gitignore for env/db files
- Add GitHub Actions CI + commitlint config and workflows
- Add manual vendor chunking and source maps to docs/site vite configs

Shared UI & docs app:
- Add ARIA props and focus-visible rings to Button/Panel
- Add ButtonAsLink primitive; use shared Button in NotFound
- Wire @void-nav/ui into docs app; refresh content pages
- Replace Todo page with Kanban board

Gameplay (Bevy):
- Add ai module (behavior, faction, navigation, perception, spawning, states)
- Add narrative module (events, history, synthesis, ui)
- Refine galaxy contents and in-system flight/scene systems
2026-06-16 11:49:13 -04:00
c14f684b09 Add galaxy parameter UI, star selection, and movement/physics scaffolding
Galaxy creation scene (Bevy 0.16):
- Split into module folder: params.rs, mod.rs (generation + spawn), ui.rs,
  selection.rs
- GalaxyParams resource (seed, count, arms, vertical_arms, size, twist,
  vertical_twist) with generation counter for change detection
- Control panel: 7 +/- slider rows + Regenerate button, no native Bevy slider
  widget so uses label + icon buttons
- Info panel: live-refreshes on selection change via despawn_related::<Children>
- Click-to-select: screen-space picking (project each star to viewport, closest
  within 18px threshold wins); selected star lerps scale to 2.2x
- Generation faithfully ports the docs TS reference including vertical arms
- Regeneration system: despawns GalaxyScene root only, preserves UI panels

Camera:
- Camera2d -> Camera3d + OrbitCamera (left-drag yaw/pitch, scroll zoom,
  pitch/distance clamped to avoid gimbal)
- Orbit drag suppressed when cursor over UI

New plugins (scaffolding):
- movement/: Velocity, MaxSpeed, TurnRate, Drag, MoveTarget, Player components
  + click-to-move (no player spawned yet)
- physics/: pure-data geometry (ray_vs_sphere, overlaps, separate,
  segment_vs_sphere) with 7 passing unit tests; no systems wired yet
- star_map/: plugin skeleton gated on AppState::InGame

Shared:
- ui/util.rs: cursor_over_ui helper for UI-hover detection
- docs: ARCH-9 decision record (custom movement & collision, no physics engine)
2026-06-04 12:29:33 -04:00
a1717e12db Replace TS game shell with Bevy/Rust client, add auth service, purge legacy archive
- Replace apps/game (TypeScript/Vite/R3F) with a Bevy 0.16 Rust client
  featuring main menu, star map, and flight states
- Add services/auth: Express + better-auth server with SpacetimeDB
  token exchange endpoint
- Delete archive/legacy-static/ (old JS demos, CSS, assets)
- Update docs pages (architecture, gameplay, roadmap, social, overview)
  to reflect Bevy pivot
- Clean up workspace config: remove apps/game from pnpm workspace,
  update dev scripts, tsconfig, and AGENTS.md files
- Add .vscode/settings.json for Rust tooling
2026-06-04 01:10:02 -04:00
7c93b8a1ae Add game UI panels, keyboard shortcuts, docs narrative overhaul, and unified dev script
- Add MiniStarMap, NpcMarketPanel, ShipStatusPanel, useKeyboardShortcuts
- Add progress bars for approach/mining operations and cargo fill indicator
- Rewrite docs from spreadsheet-first to exploration-first open-world RPG
- Replace dev:db + dev:standalone with unified dev script (scripts/dev.sh)
- Add Vite chunk splitting for three.js and spacetimedb
- Fix displayName dependency in useSpacetimeConnection
- Remove stale usePlayerSession.ts
- Add AGENTS.md files across all packages
2026-06-02 17:32:15 -04:00
01bfaedcf3 Fix workspace setup: move build tools to devDeps, remove stale files
- Move vite, tailwindcss, @tailwindcss/vite to devDependencies in all 3 apps
- Remove orphaned tsconfig.node.json from apps/game and apps/docs
- Remove leftover root src/ directory (duplicate module_bindings)
2026-05-31 18:01:35 -04:00
316a44661b Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo
- apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection
- apps/docs: design docs and prototypes
- apps/site: landing page
- packages/ui: shared Button and Panel primitives
- services/spacetimedb: backend module (9 tables, 11 reducers)
- Archive legacy static files to archive/legacy-static/
- Game loop: connect, undock, target, approach, dock, mine, sell
- Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
2026-05-31 17:56:56 -04:00