Revert spike ports to 3001/5173, add stories 32 and 33

Reverts port changes made during the spike back to default (3001/5173).
Adds two new stories for multi-worktree support: dynamic port management
(story 32) and worktree diff inspection with editor integration (story 33).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-19 15:30:23 +00:00
parent 68a19c393e
commit f17cd63d2f
6 changed files with 46 additions and 8 deletions

View File

@@ -0,0 +1,18 @@
# Story 32: Worktree Agent Orchestration — Dynamic Port Management
## User Story
**As a** developer running multiple agents in parallel worktrees,
**I want** each server instance to bind to a unique port automatically,
**So that** I can run multiple worktree-based agents concurrently without port conflicts.
## Acceptance Criteria
- [ ] Server discovers an available port instead of hardcoding 3001 (e.g., try 3001, then 3002, etc., or use port 0 and report back).
- [ ] Server prints the actual bound port on startup so callers can discover it.
- [ ] Frontend dev server proxy target is configurable (env var or auto-detected from server).
- [ ] WebSocket client in the frontend reads the port dynamically rather than hardcoding it.
- [ ] Agent pool can target agents at different worktree server instances by URL.
- [ ] A simple registry or file-based mechanism lets a supervisor discover which ports map to which worktrees.
## Out of Scope
- Service mesh or container orchestration.
- Multi-machine distributed agents (local only for now).

View File

@@ -0,0 +1,20 @@
# Story 33: Worktree Diff Inspection and Editor Integration
## User Story
**As a** supervisor coordinating agents across worktrees,
**I want to** view diffs of in-progress agent work and open worktrees in my editor,
**So that** I can review changes, catch problems early, and intervene when needed.
## Acceptance Criteria
- [ ] API endpoint (or CLI command) returns `git diff` output for a given worktree path.
- [ ] API endpoint returns `git diff --stat` summary for a quick overview.
- [ ] API endpoint can return diff against the base branch (e.g., `git diff main...HEAD`).
- [ ] A "open in editor" action launches the configured editor (e.g., `zed`) pointed at a worktree directory.
- [ ] Editor preference is configurable (stored in app settings, defaults to `$EDITOR` or `zed`).
- [ ] Frontend can trigger "open in editor" for any listed worktree/agent.
- [ ] Frontend can display a diff view for any worktree with syntax-highlighted changes.
## Out of Scope
- Full code review workflow (comments, approvals).
- Automatic merge or conflict resolution.
- Editor plugin integration (just launching the editor at the worktree path is sufficient).

View File

@@ -226,7 +226,7 @@ export class ChatWebSocket {
const protocol = window.location.protocol === "https:" ? "wss" : "ws"; const protocol = window.location.protocol === "https:" ? "wss" : "ws";
const wsHost = import.meta.env.DEV const wsHost = import.meta.env.DEV
? "127.0.0.1:3002" ? "127.0.0.1:3001"
: window.location.host; : window.location.host;
const wsUrl = `${protocol}://${wsHost}${wsPath}`; const wsUrl = `${protocol}://${wsHost}${wsPath}`;

View File

@@ -5,9 +5,9 @@ import { defineConfig } from "vite";
export default defineConfig(() => ({ export default defineConfig(() => ({
plugins: [react()], plugins: [react()],
server: { server: {
port: 5174, port: 5173,
proxy: { proxy: {
"/api": "http://127.0.0.1:3002", "/api": "http://127.0.0.1:3001",
}, },
}, },
build: { build: {

View File

@@ -65,7 +65,7 @@ pub fn build_openapi_service(ctx: Arc<AppContext>) -> (ApiService, ApiService) {
); );
let api_service = let api_service =
OpenApiService::new(api, "Story Kit API", "1.0").server("http://127.0.0.1:3002/api"); OpenApiService::new(api, "Story Kit API", "1.0").server("http://127.0.0.1:3001/api");
let docs_api = ( let docs_api = (
ProjectApi { ctx: ctx.clone() }, ProjectApi { ctx: ctx.clone() },
@@ -78,7 +78,7 @@ pub fn build_openapi_service(ctx: Arc<AppContext>) -> (ApiService, ApiService) {
); );
let docs_service = let docs_service =
OpenApiService::new(docs_api, "Story Kit API", "1.0").server("http://127.0.0.1:3002/api"); OpenApiService::new(docs_api, "Story Kit API", "1.0").server("http://127.0.0.1:3001/api");
(api_service, docs_service) (api_service, docs_service)
} }

View File

@@ -38,10 +38,10 @@ async fn main() -> Result<(), std::io::Error> {
println!( println!(
"\x1b[95;1m ____ _ _ ___ _ \n / ___|| |_ ___ _ __| | _|_ _| |_ \n \\___ \\| __/ _ \\| '__| |/ /| || __|\n ___) | || (_) | | | < | || |_ \n |____/ \\__\\___/|_| |_|\\_\\___|\\__|\n\x1b[0m" "\x1b[95;1m ____ _ _ ___ _ \n / ___|| |_ ___ _ __| | _|_ _| |_ \n \\___ \\| __/ _ \\| '__| |/ /| || __|\n ___) | || (_) | | | < | || |_ \n |____/ \\__\\___/|_| |_|\\_\\___|\\__|\n\x1b[0m"
); );
println!("\x1b[96;1mFrontend:\x1b[0m \x1b[94mhttp://127.0.0.1:3002\x1b[0m"); println!("\x1b[96;1mFrontend:\x1b[0m \x1b[94mhttp://127.0.0.1:3001\x1b[0m");
println!("\x1b[92;1mOpenAPI Docs:\x1b[0m \x1b[94mhttp://127.0.0.1:3002/docs\x1b[0m"); println!("\x1b[92;1mOpenAPI Docs:\x1b[0m \x1b[94mhttp://127.0.0.1:3001/docs\x1b[0m");
Server::new(TcpListener::bind("127.0.0.1:3002")) Server::new(TcpListener::bind("127.0.0.1:3001"))
.run(app) .run(app)
.await .await
} }