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
This commit is contained in:
@@ -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 | - |
|
||||
|
||||
@@ -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%
|
||||
|
||||
|
||||
103
.planning/phases/01-core-infrastructure/01-01-PLAN.md
Normal file
103
.planning/phases/01-core-infrastructure/01-01-PLAN.md
Normal file
@@ -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
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Initialize Node.js project with TypeScript and ESM</name>
|
||||
<files>package.json, tsconfig.json, .gitignore</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>npm install succeeds, npm run build succeeds (even with empty src)</verify>
|
||||
<done>package.json has correct config, tsconfig.json exists, dependencies installed</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Create source structure and entry point</name>
|
||||
<files>src/index.ts, src/bin/cw.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>npm run build succeeds, node dist/bin/cw.js prints version message</verify>
|
||||
<done>Build outputs to dist/, bin entry point runs, prints version</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- Project builds successfully
|
||||
- Bin entry point executes
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-infrastructure/01-01-SUMMARY.md`
|
||||
</output>
|
||||
95
.planning/phases/01-core-infrastructure/01-02-PLAN.md
Normal file
95
.planning/phases/01-core-infrastructure/01-02-PLAN.md
Normal file
@@ -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
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/01-core-infrastructure/01-01-SUMMARY.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create CLI with commander</name>
|
||||
<files>src/cli/index.ts, src/bin/cw.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>npm run build succeeds, node dist/bin/cw.js --help shows commands</verify>
|
||||
<done>CLI shows help with status/agent/task placeholders, version displays correctly</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Enable global installation via npm link</name>
|
||||
<files>package.json, src/bin/cw.ts</files>
|
||||
<action>
|
||||
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.
|
||||
</action>
|
||||
<verify>After npm link, running 'cw --version' in any directory shows version</verify>
|
||||
<done>Global cw command works, help and version display correctly</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- 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
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-infrastructure/01-02-SUMMARY.md`
|
||||
</output>
|
||||
100
.planning/phases/01-core-infrastructure/01-03-PLAN.md
Normal file
100
.planning/phases/01-core-infrastructure/01-03-PLAN.md
Normal file
@@ -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
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create process types and registry</name>
|
||||
<files>src/process/types.ts, src/process/registry.ts</files>
|
||||
<action>
|
||||
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<string, string> }
|
||||
|
||||
Create src/process/registry.ts:
|
||||
- ProcessRegistry class with Map<string, ProcessInfo> 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).
|
||||
</action>
|
||||
<verify>TypeScript compiles, registry can add/remove/list processes</verify>
|
||||
<done>ProcessRegistry class works with full CRUD operations</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Create process manager with spawn/stop</name>
|
||||
<files>src/process/manager.ts, src/process/index.ts</files>
|
||||
<action>
|
||||
Create src/process/manager.ts:
|
||||
- Import execa for process spawning
|
||||
- ProcessManager class:
|
||||
- constructor takes ProcessRegistry instance
|
||||
- spawn(options: SpawnOptions): Promise<ProcessInfo> - spawns detached child, registers in registry, returns info
|
||||
- stop(id: string): Promise<void> - sends SIGTERM, waits up to 5s, then SIGKILL if needed
|
||||
- stopAll(): Promise<void> - stops all registered processes
|
||||
- restart(id: string): Promise<ProcessInfo> - 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.
|
||||
</action>
|
||||
<verify>Can spawn a simple process (e.g., sleep 10), list it, stop it</verify>
|
||||
<done>ProcessManager can spawn, stop, restart, and list child processes</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- Process lifecycle (spawn → track → stop) works end-to-end
|
||||
- Infrastructure ready for agent management in Phase 4
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-infrastructure/01-03-SUMMARY.md`
|
||||
</output>
|
||||
104
.planning/phases/01-core-infrastructure/01-04-PLAN.md
Normal file
104
.planning/phases/01-core-infrastructure/01-04-PLAN.md
Normal file
@@ -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
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create log directory management</name>
|
||||
<files>src/logging/types.ts, src/logging/manager.ts</files>
|
||||
<action>
|
||||
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<void> - creates log directory if not exists
|
||||
- getLogPath(processId: string, stream: 'stdout' | 'stderr'): string
|
||||
- cleanOldLogs(retainDays: number): Promise<number> - removes logs older than N days
|
||||
- listLogs(): Promise<string[]> - 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
|
||||
</action>
|
||||
<verify>LogManager creates ~/.cw/logs directory, returns correct paths</verify>
|
||||
<done>Log directory management works, paths are cross-platform correct</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Create per-process log writer</name>
|
||||
<files>src/logging/writer.ts, src/logging/index.ts</files>
|
||||
<action>
|
||||
Create src/logging/writer.ts:
|
||||
- ProcessLogWriter class:
|
||||
- constructor(processId: string, logManager: LogManager)
|
||||
- open(): Promise<void> - opens file handles for stdout/stderr
|
||||
- writeStdout(data: string | Buffer): Promise<void>
|
||||
- writeStderr(data: string | Buffer): Promise<void>
|
||||
- close(): Promise<void> - 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
|
||||
</action>
|
||||
<verify>ProcessLogWriter creates files, writes stdout/stderr with timestamps</verify>
|
||||
<done>Per-process logging captures output to separate files with timestamps</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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)
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- 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)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-infrastructure/01-04-SUMMARY.md`
|
||||
</output>
|
||||
117
.planning/phases/01-core-infrastructure/01-05-PLAN.md
Normal file
117
.planning/phases/01-core-infrastructure/01-05-PLAN.md
Normal file
@@ -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
|
||||
---
|
||||
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@~/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@~/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.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
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create HTTP server with health endpoint and PID file</name>
|
||||
<files>src/server/index.ts, src/server/types.ts, src/cli/index.ts</files>
|
||||
<action>
|
||||
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<void> - starts HTTP server, writes PID file
|
||||
- stop(): Promise<void> - 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
|
||||
</action>
|
||||
<verify>cw --server starts HTTP server, curl localhost:3847/health returns OK</verify>
|
||||
<done>Server mode works, health endpoint responds, PID file created</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Implement graceful shutdown</name>
|
||||
<files>src/server/shutdown.ts, src/server/index.ts</files>
|
||||
<action>
|
||||
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<void> - 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.
|
||||
</action>
|
||||
<verify>cw --server responds to Ctrl+C by logging shutdown and cleaning up</verify>
|
||||
<done>SIGTERM/SIGINT triggers graceful shutdown, all resources cleaned up</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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)
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- All tasks completed
|
||||
- All verification checks pass
|
||||
- Server mode is the foundation for agent coordination
|
||||
- Graceful shutdown satisfies INFRA-04
|
||||
- Health endpoint enables monitoring
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-core-infrastructure/01-05-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user