Files
Codewalkers/docs/git-process-logging.md
Lukas May 342b490fe7 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>
2026-02-10 09:48:51 +01:00

3.6 KiB

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

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

import { createLogger } from './logging/index.js';
const writer = createLogger(processId, eventBus);
await writer.open();
await writer.writeStdout('output data');
await writer.close();