From 074f79b85595d1518736edb8a39503cfbb1c79e9 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 30 Jan 2026 13:06:38 +0100 Subject: [PATCH] docs(01): create phase 1 plan Phase 01: Core Infrastructure - 5 plans in 3 waves - Wave 1: Project foundation (01-01) - Wave 2: CLI, process mgmt, logging (01-02, 01-03, 01-04) [parallel] - Wave 3: Server mode & shutdown (01-05) - Ready for execution --- .planning/ROADMAP.md | 11 +- .planning/STATE.md | 6 +- .../01-core-infrastructure/01-01-PLAN.md | 103 +++++++++++++++ .../01-core-infrastructure/01-02-PLAN.md | 95 ++++++++++++++ .../01-core-infrastructure/01-03-PLAN.md | 100 +++++++++++++++ .../01-core-infrastructure/01-04-PLAN.md | 104 ++++++++++++++++ .../01-core-infrastructure/01-05-PLAN.md | 117 ++++++++++++++++++ 7 files changed, 529 insertions(+), 7 deletions(-) create mode 100644 .planning/phases/01-core-infrastructure/01-01-PLAN.md create mode 100644 .planning/phases/01-core-infrastructure/01-02-PLAN.md create mode 100644 .planning/phases/01-core-infrastructure/01-03-PLAN.md create mode 100644 .planning/phases/01-core-infrastructure/01-04-PLAN.md create mode 100644 .planning/phases/01-core-infrastructure/01-05-PLAN.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 8f5a581..087e448 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -29,11 +29,14 @@ None **Depends on**: Nothing (first phase) **Requirements**: INFRA-01, INFRA-02, INFRA-03, INFRA-04, INFRA-05 **Research**: Unlikely (Node.js process patterns well-documented) -**Plans**: TBD +**Plans**: 5 plans in 3 waves Plans: -- [ ] 01-01: TBD -- [ ] 01-02: TBD +- [ ] 01-01: Project Foundation (Wave 1) +- [ ] 01-02: CLI Entry Point (Wave 2) +- [ ] 01-03: Process Management (Wave 2) +- [ ] 01-04: Logging Infrastructure (Wave 2) +- [ ] 01-05: Coordination Server & Shutdown (Wave 3) ### Phase 2: Data Layer **Goal**: SQLite database with Drizzle ORM, task hierarchy schema (initiative → phase → plan → task) @@ -109,7 +112,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| -| 1. Core Infrastructure | 0/? | Not started | - | +| 1. Core Infrastructure | 0/5 | Planned | - | | 2. Data Layer | 0/? | Not started | - | | 3. Git Integration | 0/? | Not started | - | | 4. Agent Lifecycle | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index d889799..cfd9cdf 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -10,9 +10,9 @@ See: .planning/PROJECT.md (updated 2026-01-30) ## Current Position Phase: 1 of 7 (Core Infrastructure) -Plan: Not started -Status: Ready to plan -Last activity: 2026-01-30 — Project initialized +Plan: 5 plans created, ready to execute +Status: Ready to execute +Last activity: 2026-01-30 — Phase 1 planned Progress: ░░░░░░░░░░ 0% diff --git a/.planning/phases/01-core-infrastructure/01-01-PLAN.md b/.planning/phases/01-core-infrastructure/01-01-PLAN.md new file mode 100644 index 0000000..12231c5 --- /dev/null +++ b/.planning/phases/01-core-infrastructure/01-01-PLAN.md @@ -0,0 +1,103 @@ +--- +phase: 01-core-infrastructure +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: [package.json, tsconfig.json, src/index.ts, bin/cw] +autonomous: true +--- + + +Initialize TypeScript project with ESM, build tooling, and bin directory structure. + +Purpose: Establish the project foundation that all other Phase 1 plans depend on. +Output: Buildable TypeScript project with `npm run build` and `npm run dev` working. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + + + + + + Task 1: Initialize Node.js project with TypeScript and ESM + package.json, tsconfig.json, .gitignore + + Initialize project with `npm init -y`. Configure for ESM: + - package.json: "type": "module" + - Add dependencies: typescript, @types/node, commander (CLI), execa (process mgmt) + - Add devDependencies: tsx (dev runner), rimraf (clean) + - Configure scripts: build (tsc), dev (tsx watch), clean (rimraf dist) + - Set "bin": { "cw": "./dist/bin/cw.js" } + - Set "main": "./dist/index.js" + + tsconfig.json: + - target: ES2022 + - module: NodeNext + - moduleResolution: NodeNext + - outDir: ./dist + - rootDir: ./src + - strict: true + - esModuleInterop: true + - declaration: true + + Add node_modules and dist to .gitignore. + + npm install succeeds, npm run build succeeds (even with empty src) + package.json has correct config, tsconfig.json exists, dependencies installed + + + + Task 2: Create source structure and entry point + src/index.ts, src/bin/cw.ts + + Create directory structure: + - src/bin/cw.ts - CLI entry point (will be built to dist/bin/cw.js) + - src/index.ts - library entry point (exports public API) + + src/bin/cw.ts: + - Add shebang: #!/usr/bin/env node + - Import and call main function placeholder + - Log "cw cli v0.0.1" for now + + src/index.ts: + - Export version constant + - Export placeholder for future modules + + Ensure the bin file is executable after build. + + npm run build succeeds, node dist/bin/cw.js prints version message + Build outputs to dist/, bin entry point runs, prints version + + + + + +Before declaring plan complete: +- [ ] `npm install` runs without errors +- [ ] `npm run build` compiles TypeScript without errors +- [ ] `node dist/bin/cw.js` outputs version message +- [ ] dist/ contains compiled .js and .d.ts files +- [ ] .gitignore includes node_modules and dist + + + + +- All tasks completed +- All verification checks pass +- Project builds successfully +- Bin entry point executes + + + +After completion, create `.planning/phases/01-core-infrastructure/01-01-SUMMARY.md` + diff --git a/.planning/phases/01-core-infrastructure/01-02-PLAN.md b/.planning/phases/01-core-infrastructure/01-02-PLAN.md new file mode 100644 index 0000000..8fd1e5d --- /dev/null +++ b/.planning/phases/01-core-infrastructure/01-02-PLAN.md @@ -0,0 +1,95 @@ +--- +phase: 01-core-infrastructure +plan: 02 +type: execute +wave: 2 +depends_on: ["01-01"] +files_modified: [src/bin/cw.ts, src/cli/index.ts, src/cli/commands/index.ts] +autonomous: true +--- + + +Create CLI foundation with commander, help system, and version display. + +Purpose: Establish the `cw` command as the user-facing entry point for all operations. +Output: Working CLI with `cw --help` and `cw --version` that can be globally installed. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/01-core-infrastructure/01-01-SUMMARY.md + + + + + + Task 1: Create CLI with commander + src/cli/index.ts, src/bin/cw.ts + + Create src/cli/index.ts: + - Import { Command } from 'commander' + - Create program with name('cw'), description, version from package.json + - Add placeholder commands: 'status', 'agent', 'task' (just stubs that log "not implemented") + - Export createCli() function that returns configured program + + Update src/bin/cw.ts: + - Import createCli from '../cli/index.js' + - Call program.parse(process.argv) + - Handle uncaught errors gracefully (log and exit 1) + + Read version from package.json using import with assert { type: "json" } or createRequire pattern. + + npm run build succeeds, node dist/bin/cw.js --help shows commands + CLI shows help with status/agent/task placeholders, version displays correctly + + + + Task 2: Enable global installation via npm link + package.json, src/bin/cw.ts + + Verify package.json bin field points to correct path: "bin": { "cw": "./dist/bin/cw.js" } + + Ensure the built bin file: + - Has correct shebang (#!/usr/bin/env node) + - Is executable (add postbuild script to chmod if needed) + + Test npm link workflow: + - Run npm run build + - Run npm link + - Verify 'cw' command available globally + + Document in comments: users can install via npm link during development or npm i -g for release. + + After npm link, running 'cw --version' in any directory shows version + Global cw command works, help and version display correctly + + + + + +Before declaring plan complete: +- [ ] `npm run build` succeeds +- [ ] `cw --help` displays usage with command list +- [ ] `cw --version` displays version from package.json +- [ ] `cw status` outputs "not implemented" placeholder +- [ ] Global install via npm link works + + + + +- All tasks completed +- All verification checks pass +- CLI is the single entry point for all commands +- Foundation ready for adding real commands in later phases + + + +After completion, create `.planning/phases/01-core-infrastructure/01-02-SUMMARY.md` + diff --git a/.planning/phases/01-core-infrastructure/01-03-PLAN.md b/.planning/phases/01-core-infrastructure/01-03-PLAN.md new file mode 100644 index 0000000..63a3f1c --- /dev/null +++ b/.planning/phases/01-core-infrastructure/01-03-PLAN.md @@ -0,0 +1,100 @@ +--- +phase: 01-core-infrastructure +plan: 03 +type: execute +wave: 2 +depends_on: ["01-01"] +files_modified: [src/process/registry.ts, src/process/manager.ts, src/process/types.ts] +autonomous: true +--- + + +Create process management utilities for spawning, tracking, and stopping child processes. + +Purpose: Infrastructure for managing agent processes in later phases. Agents are child processes that need lifecycle management. +Output: ProcessManager class with spawn, stop, list, and restart operations. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + + + + + + Task 1: Create process types and registry + src/process/types.ts, src/process/registry.ts + + Create src/process/types.ts: + - ProcessInfo interface: { id: string, pid: number, command: string, args: string[], startedAt: Date, status: 'running' | 'stopped' | 'crashed' } + - SpawnOptions: { id: string, command: string, args?: string[], cwd?: string, env?: Record } + + Create src/process/registry.ts: + - ProcessRegistry class with Map storage + - register(info: ProcessInfo): void + - unregister(id: string): void + - get(id: string): ProcessInfo | undefined + - getAll(): ProcessInfo[] + - getByPid(pid: number): ProcessInfo | undefined + - clear(): void + + Registry is in-memory for now (Phase 2 adds SQLite persistence). + + TypeScript compiles, registry can add/remove/list processes + ProcessRegistry class works with full CRUD operations + + + + Task 2: Create process manager with spawn/stop + src/process/manager.ts, src/process/index.ts + + Create src/process/manager.ts: + - Import execa for process spawning + - ProcessManager class: + - constructor takes ProcessRegistry instance + - spawn(options: SpawnOptions): Promise - spawns detached child, registers in registry, returns info + - stop(id: string): Promise - sends SIGTERM, waits up to 5s, then SIGKILL if needed + - stopAll(): Promise - stops all registered processes + - restart(id: string): Promise - stops then respawns with same config + - isRunning(id: string): boolean - checks if process is alive + + Use execa with { detached: true } for background processes. + Store spawned process reference to enable stop/restart. + Handle process exit events to update registry status. + + Create src/process/index.ts - export ProcessManager, ProcessRegistry, types. + + Can spawn a simple process (e.g., sleep 10), list it, stop it + ProcessManager can spawn, stop, restart, and list child processes + + + + + +Before declaring plan complete: +- [ ] `npm run build` succeeds +- [ ] ProcessRegistry correctly tracks process info +- [ ] ProcessManager.spawn() starts a detached process +- [ ] ProcessManager.stop() terminates running process +- [ ] ProcessManager.isRunning() correctly reports status +- [ ] Process exit updates registry status automatically + + + + +- All tasks completed +- All verification checks pass +- Process lifecycle (spawn → track → stop) works end-to-end +- Infrastructure ready for agent management in Phase 4 + + + +After completion, create `.planning/phases/01-core-infrastructure/01-03-SUMMARY.md` + diff --git a/.planning/phases/01-core-infrastructure/01-04-PLAN.md b/.planning/phases/01-core-infrastructure/01-04-PLAN.md new file mode 100644 index 0000000..10d44d7 --- /dev/null +++ b/.planning/phases/01-core-infrastructure/01-04-PLAN.md @@ -0,0 +1,104 @@ +--- +phase: 01-core-infrastructure +plan: 04 +type: execute +wave: 2 +depends_on: ["01-01"] +files_modified: [src/logging/types.ts, src/logging/writer.ts, src/logging/manager.ts, src/logging/index.ts] +autonomous: true +--- + + +Create file-based logging infrastructure for per-process stdout/stderr capture. + +Purpose: Each agent process needs its own log files. This creates the logging infrastructure that agent processes will use. +Output: LogManager that creates and manages per-process log files in a dedicated directory. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + + + + + + Task 1: Create log directory management + src/logging/types.ts, src/logging/manager.ts + + Create src/logging/types.ts: + - LogLevel: 'debug' | 'info' | 'warn' | 'error' + - LogEntry: { timestamp: Date, level: LogLevel, processId: string, message: string } + - LogConfig: { baseDir: string, maxFileSize?: number, retainDays?: number } + + Create src/logging/manager.ts: + - LogManager class: + - constructor(config: LogConfig) - baseDir defaults to ~/.cw/logs + - ensureLogDir(): Promise - creates log directory if not exists + - getLogPath(processId: string, stream: 'stdout' | 'stderr'): string + - cleanOldLogs(retainDays: number): Promise - removes logs older than N days + - listLogs(): Promise - lists all log files + + Use node:fs/promises for all file operations. + Use node:path and node:os for cross-platform paths. + Log directory structure: ~/.cw/logs/{processId}/stdout.log, stderr.log + + LogManager creates ~/.cw/logs directory, returns correct paths + Log directory management works, paths are cross-platform correct + + + + Task 2: Create per-process log writer + src/logging/writer.ts, src/logging/index.ts + + Create src/logging/writer.ts: + - ProcessLogWriter class: + - constructor(processId: string, logManager: LogManager) + - open(): Promise - opens file handles for stdout/stderr + - writeStdout(data: string | Buffer): Promise + - writeStderr(data: string | Buffer): Promise + - close(): Promise - flushes and closes file handles + - getStdoutStream(): fs.WriteStream + - getStderrStream(): fs.WriteStream + + Use fs.createWriteStream with { flags: 'a' } for append mode. + Add timestamps to each line of output. + Handle backpressure properly (pause source if drain needed). + + Create src/logging/index.ts: + - Export LogManager, ProcessLogWriter, types + - Export createLogger(processId: string) convenience function + + ProcessLogWriter creates files, writes stdout/stderr with timestamps + Per-process logging captures output to separate files with timestamps + + + + + +Before declaring plan complete: +- [ ] `npm run build` succeeds +- [ ] LogManager creates ~/.cw/logs/ directory +- [ ] ProcessLogWriter creates per-process log files +- [ ] Stdout and stderr go to separate files +- [ ] Log entries include timestamps +- [ ] File handles close properly (no resource leaks) + + + + +- All tasks completed +- All verification checks pass +- Logging infrastructure ready for agent process output capture +- Satisfies INFRA-05 (basic logging captures stdout/stderr per agent) + + + +After completion, create `.planning/phases/01-core-infrastructure/01-04-SUMMARY.md` + diff --git a/.planning/phases/01-core-infrastructure/01-05-PLAN.md b/.planning/phases/01-core-infrastructure/01-05-PLAN.md new file mode 100644 index 0000000..82ecf3d --- /dev/null +++ b/.planning/phases/01-core-infrastructure/01-05-PLAN.md @@ -0,0 +1,117 @@ +--- +phase: 01-core-infrastructure +plan: 05 +type: execute +wave: 3 +depends_on: ["01-02", "01-03", "01-04"] +files_modified: [src/server/index.ts, src/server/shutdown.ts, src/cli/commands/server.ts, src/bin/cw.ts] +autonomous: true +--- + + +Add server mode to CLI with HTTP health endpoint and graceful shutdown handling. + +Purpose: `cw --server` runs the background coordination server that manages agents. Server must handle signals gracefully. +Output: Server mode with health endpoint, PID file, and clean shutdown on SIGTERM/SIGINT. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md +@.planning/phases/01-core-infrastructure/01-02-SUMMARY.md +@.planning/phases/01-core-infrastructure/01-03-SUMMARY.md +@.planning/phases/01-core-infrastructure/01-04-SUMMARY.md + + + + + + Task 1: Create HTTP server with health endpoint and PID file + src/server/index.ts, src/server/types.ts, src/cli/index.ts + + Create src/server/types.ts: + - ServerConfig: { port: number, host: string, pidFile: string } + - ServerState: { startedAt: Date, processCount: number } + + Create src/server/index.ts: + - Use node:http (not Express - keep it minimal) + - CoordinationServer class: + - constructor(config: ServerConfig, processManager: ProcessManager, logManager: LogManager) + - start(): Promise - starts HTTP server, writes PID file + - stop(): Promise - stops server, removes PID file + - isRunning(): boolean + + HTTP routes (simple path matching): + - GET /health → { status: 'ok', uptime: number, processCount: number } + - GET /status → { server: ServerState, processes: ProcessInfo[] } + + PID file: ~/.cw/server.pid - contains process ID, checked to prevent duplicate servers. + Default port: 3847 (arbitrary, configurable via env CW_PORT). + + Update src/cli/index.ts: + - Add --server flag that starts CoordinationServer instead of CLI commands + - Add --port option for custom port + + cw --server starts HTTP server, curl localhost:3847/health returns OK + Server mode works, health endpoint responds, PID file created + + + + Task 2: Implement graceful shutdown + src/server/shutdown.ts, src/server/index.ts + + Create src/server/shutdown.ts: + - GracefulShutdown class: + - constructor(server: CoordinationServer, processManager: ProcessManager, logManager: LogManager) + - install(): void - registers signal handlers for SIGTERM, SIGINT, SIGHUP + - shutdown(signal: string): Promise - orchestrates cleanup + + Shutdown sequence: + 1. Log "Received {signal}, shutting down..." + 2. Stop accepting new connections + 3. Stop all managed processes (ProcessManager.stopAll()) + 4. Close all log file handles + 5. Remove PID file + 6. Exit with code 0 + + Timeout: If cleanup takes >10s, force exit with code 1. + + Handle double-signal: If SIGINT received twice, force immediate exit. + + Integrate into CoordinationServer.start() - install shutdown handlers after server starts. + + cw --server responds to Ctrl+C by logging shutdown and cleaning up + SIGTERM/SIGINT triggers graceful shutdown, all resources cleaned up + + + + + +Before declaring plan complete: +- [ ] `npm run build` succeeds +- [ ] `cw --server` starts server on port 3847 +- [ ] `curl localhost:3847/health` returns JSON with status: 'ok' +- [ ] PID file created at ~/.cw/server.pid +- [ ] Ctrl+C (SIGINT) triggers graceful shutdown message +- [ ] PID file removed after shutdown +- [ ] Cannot start second server (PID file check prevents it) + + + + +- All tasks completed +- All verification checks pass +- Server mode is the foundation for agent coordination +- Graceful shutdown satisfies INFRA-04 +- Health endpoint enables monitoring + + + +After completion, create `.planning/phases/01-core-infrastructure/01-05-SUMMARY.md` +