feat: Task decomposition for Tailwind/Radix/shadcn foundation setup
Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind" phase into 6 executable tasks: 1. Install Tailwind CSS, PostCSS & Autoprefixer 2. Map MUI theme to Tailwind design tokens 3. Setup CSS variables for dynamic theming 4. Install Radix UI primitives 5. Initialize shadcn/ui and setup component directory 6. Move MUI to devDependencies and verify setup Tasks follow logical dependency chain with final human verification checkpoint before proceeding with component migration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
121
docs/git-process-logging.md
Normal file
121
docs/git-process-logging.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Git, Process, and Logging Modules
|
||||
|
||||
Three infrastructure modules supporting agent execution.
|
||||
|
||||
## Git Module (`src/git/`)
|
||||
|
||||
Manages git worktrees for isolated agent workspaces.
|
||||
|
||||
### Architecture
|
||||
- **Port**: `WorktreeManager` interface
|
||||
- **Adapter**: `SimpleGitWorktreeManager` using simple-git library
|
||||
|
||||
### WorktreeManager Methods
|
||||
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `create(id, branch, baseBranch?)` | Create worktree with new branch (default base: 'main') |
|
||||
| `remove(id)` | Clean up worktree directory |
|
||||
| `list()` | All worktrees including main |
|
||||
| `get(id)` | Specific worktree by ID |
|
||||
| `diff(id)` | Changed files vs HEAD |
|
||||
| `merge(id, targetBranch)` | Merge worktree branch into target |
|
||||
|
||||
### Worktree Storage
|
||||
Worktrees stored in `.cw-worktrees/` subdirectory of the repo. Each agent gets a worktree at `.cw-worktrees/agent/<alias>/`.
|
||||
|
||||
### Merge Flow
|
||||
1. Check out target branch
|
||||
2. `git merge <source> --no-edit`
|
||||
3. On success: emit `worktree:merged`
|
||||
4. On conflict: `git merge --abort`, emit `worktree:conflict` with conflicting file list
|
||||
5. Restore original branch
|
||||
|
||||
### Project Clones
|
||||
- `cloneProject(url, destPath)` — Simple git clone wrapper
|
||||
- `ensureProjectClone(project, workspaceRoot)` — Idempotent: checks if clone exists, clones if not
|
||||
- `getProjectCloneDir(name, id)` — Canonical path: `repos/<sanitized-name>-<id>/`
|
||||
|
||||
### Events Emitted
|
||||
`worktree:created`, `worktree:removed`, `worktree:merged`, `worktree:conflict`
|
||||
|
||||
---
|
||||
|
||||
## Process Module (`src/process/`)
|
||||
|
||||
Spawns, tracks, and controls child processes.
|
||||
|
||||
### Classes
|
||||
|
||||
**ProcessRegistry** — In-memory metadata store:
|
||||
- `register(info)`, `unregister(id)`, `get(id)`, `getAll()`, `getByPid(pid)`, `updateStatus(id, status)`
|
||||
|
||||
**ProcessManager** — Lifecycle management:
|
||||
|
||||
| Method | Purpose |
|
||||
|--------|---------|
|
||||
| `spawn(options)` | Spawn detached process (survives parent exit) |
|
||||
| `stop(id)` | SIGTERM → wait 5s → SIGKILL |
|
||||
| `stopAll()` | Stop all running processes in parallel |
|
||||
| `restart(id)` | Stop + re-spawn with same options |
|
||||
| `isRunning(id)` | Check with `process.kill(pid, 0)` |
|
||||
|
||||
### Spawn Details
|
||||
- Uses `execa` with `detached: true`, `stdio: 'ignore'`
|
||||
- Calls `subprocess.unref()` so parent can exit
|
||||
- Exit handler updates registry and emits events
|
||||
|
||||
### Events Emitted
|
||||
`process:spawned`, `process:stopped`, `process:crashed`
|
||||
|
||||
---
|
||||
|
||||
## Logger Module (`src/logger/`)
|
||||
|
||||
Structured logging via **pino**.
|
||||
|
||||
### Usage
|
||||
```typescript
|
||||
import { createModuleLogger } from './logger/index.js';
|
||||
const log = createModuleLogger('my-module');
|
||||
log.info({ key: 'value' }, 'message');
|
||||
```
|
||||
|
||||
### Configuration
|
||||
| Env Var | Effect |
|
||||
|---------|--------|
|
||||
| `CW_LOG_LEVEL` | Override log level |
|
||||
| `CW_LOG_PRETTY` | Set to `'1'` for human-readable output |
|
||||
| `NODE_ENV=development` | Default to 'debug' level |
|
||||
|
||||
### Output
|
||||
- Default: JSON to stderr (fd 2)
|
||||
- Pretty mode: pino-pretty to stdout with colors and timestamps
|
||||
|
||||
---
|
||||
|
||||
## Logging Module (`src/logging/`)
|
||||
|
||||
File-based per-process output capture (separate from pino).
|
||||
|
||||
### Classes
|
||||
|
||||
**LogManager** — Directory management:
|
||||
- Base dir: `~/.cw/logs/`
|
||||
- Structure: `{processId}/stdout.log`, `{processId}/stderr.log`
|
||||
- `cleanOldLogs(retainDays)` — removes old directories by mtime
|
||||
|
||||
**ProcessLogWriter** — File I/O with timestamps:
|
||||
- `open()` — create directories and append-mode WriteStreams
|
||||
- `writeStdout(data)` / `writeStderr(data)` — prefix each line with `[YYYY-MM-DD HH:mm:ss.SSS]`
|
||||
- Handles backpressure (waits for drain event)
|
||||
- Emits `log:entry` event via EventBus
|
||||
|
||||
### Factory
|
||||
```typescript
|
||||
import { createLogger } from './logging/index.js';
|
||||
const writer = createLogger(processId, eventBus);
|
||||
await writer.open();
|
||||
await writer.writeStdout('output data');
|
||||
await writer.close();
|
||||
```
|
||||
Reference in New Issue
Block a user