pure-point-guard 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/plugin.json +7 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +462 -0
- package/dist/cli.js +2896 -0
- package/dist/cli.js.map +1 -0
- package/package.json +66 -0
- package/skills/ppg/SKILL.md +16 -0
- package/skills/ppg-conductor/SKILL.md +52 -0
- package/skills/ppg-conductor/references/commands.md +248 -0
- package/skills/ppg-conductor/references/conductor.md +183 -0
- package/skills/ppg-conductor/references/modes.md +85 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/errors.ts","../src/lib/output.ts","../src/lib/paths.ts","../src/core/config.ts","../src/lib/cjs-compat.ts","../src/core/manifest.ts","../src/commands/init.ts","../src/core/worktree.ts","../src/core/env.ts","../src/core/template.ts","../src/core/tmux.ts","../src/core/agent.ts","../src/core/terminal.ts","../src/lib/id.ts","../src/commands/spawn.ts","../src/commands/status.ts","../src/core/cleanup.ts","../src/commands/kill.ts","../src/commands/attach.ts","../src/commands/logs.ts","../src/commands/aggregate.ts","../src/commands/merge.ts","../src/commands/list.ts","../src/commands/restart.ts","../src/commands/diff.ts","../src/commands/clean.ts","../src/commands/send.ts","../src/commands/wait.ts","../src/commands/worktree.ts","../src/commands/ui.ts","../src/commands/install-dashboard.ts","../src/cli.ts"],"sourcesContent":["export class PgError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly exitCode: number = 1,\n ) {\n super(message);\n this.name = 'PgError';\n }\n}\n\nexport class TmuxNotFoundError extends PgError {\n constructor() {\n super(\n 'tmux is not installed or not in PATH. Install it with: brew install tmux',\n 'TMUX_NOT_FOUND',\n );\n this.name = 'TmuxNotFoundError';\n }\n}\n\nexport class NotGitRepoError extends PgError {\n constructor(dir: string) {\n super(\n `Not a git repository: ${dir}`,\n 'NOT_GIT_REPO',\n );\n this.name = 'NotGitRepoError';\n }\n}\n\nexport class NotInitializedError extends PgError {\n constructor(dir: string) {\n super(\n `Point Guard not initialized in ${dir}. Run 'ppg init' first.`,\n 'NOT_INITIALIZED',\n );\n this.name = 'NotInitializedError';\n }\n}\n\nexport class ManifestLockError extends PgError {\n constructor() {\n super(\n 'Could not acquire manifest lock. Another ppg process may be running.',\n 'MANIFEST_LOCK',\n );\n this.name = 'ManifestLockError';\n }\n}\n\nexport class WorktreeNotFoundError extends PgError {\n constructor(id: string) {\n super(\n `Worktree not found: ${id}`,\n 'WORKTREE_NOT_FOUND',\n );\n this.name = 'WorktreeNotFoundError';\n }\n}\n\nexport class AgentNotFoundError extends PgError {\n constructor(id: string) {\n super(\n `Agent not found: ${id}`,\n 'AGENT_NOT_FOUND',\n );\n this.name = 'AgentNotFoundError';\n }\n}\n\nexport class MergeFailedError extends PgError {\n constructor(message: string) {\n super(message, 'MERGE_FAILED');\n this.name = 'MergeFailedError';\n }\n}\n","import type { AgentStatus, WorktreeStatus } from '../types/manifest.js';\n\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst MAGENTA = '\\x1b[35m';\nconst CYAN = '\\x1b[36m';\nconst GRAY = '\\x1b[90m';\n\nconst STATUS_COLORS: Record<AgentStatus | WorktreeStatus, string> = {\n spawning: YELLOW,\n running: GREEN,\n waiting: CYAN,\n completed: BLUE,\n failed: RED,\n killed: MAGENTA,\n lost: RED + BOLD,\n active: GREEN,\n merging: YELLOW,\n merged: BLUE,\n cleaned: GRAY,\n};\n\nexport function formatStatus(status: AgentStatus | WorktreeStatus): string {\n const color = STATUS_COLORS[status] ?? RESET;\n return `${color}${status}${RESET}`;\n}\n\nexport function output(data: unknown, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(data, null, 2));\n } else if (typeof data === 'string') {\n console.log(data);\n } else {\n console.log(data);\n }\n}\n\nexport function outputError(error: unknown, json: boolean): void {\n if (json) {\n const message = error instanceof Error ? error.message : String(error);\n const code = error instanceof Error && 'code' in error\n ? (error as { code: string }).code\n : 'UNKNOWN';\n console.error(JSON.stringify({ error: message, code }));\n } else {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`${RED}Error:${RESET} ${message}`);\n }\n}\n\nexport interface Column {\n header: string;\n key: string;\n width?: number;\n format?: (value: unknown) => string;\n}\n\nexport function formatTable(rows: Record<string, unknown>[], columns: Column[]): string {\n if (rows.length === 0) return 'No results.';\n\n // Calculate column widths\n const widths = columns.map((col) => {\n const headerLen = col.header.length;\n const maxDataLen = rows.reduce((max, row) => {\n const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n // Strip ANSI for width calculation\n const stripped = val.replace(/\\x1b\\[[0-9;]*m/g, '');\n return Math.max(max, stripped.length);\n }, 0);\n return col.width ?? Math.max(headerLen, maxDataLen);\n });\n\n // Header\n const header = columns\n .map((col, i) => `${BOLD}${col.header.padEnd(widths[i])}${RESET}`)\n .join(' ');\n\n const separator = widths.map((w) => DIM + '─'.repeat(w) + RESET).join(' ');\n\n // Rows\n const body = rows.map((row) =>\n columns\n .map((col, i) => {\n const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n const stripped = val.replace(/\\x1b\\[[0-9;]*m/g, '');\n const padding = Math.max(0, widths[i] - stripped.length);\n return val + ' '.repeat(padding);\n })\n .join(' '),\n ).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n\nexport function info(message: string): void {\n console.log(`${CYAN}▸${RESET} ${message}`);\n}\n\nexport function success(message: string): void {\n console.log(`${GREEN}✓${RESET} ${message}`);\n}\n\nexport function warn(message: string): void {\n console.log(`${YELLOW}⚠${RESET} ${message}`);\n}\n","import path from 'node:path';\n\nconst PG_DIR = '.pg';\n\nexport function pgDir(projectRoot: string): string {\n return path.join(projectRoot, PG_DIR);\n}\n\nexport function manifestPath(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'manifest.json');\n}\n\nexport function configPath(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'config.yaml');\n}\n\nexport function resultsDir(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'results');\n}\n\nexport function resultFile(projectRoot: string, agentId: string): string {\n return path.join(resultsDir(projectRoot), `${agentId}.md`);\n}\n\nexport function templatesDir(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'templates');\n}\n\nexport function logsDir(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'logs');\n}\n\nexport function promptsDir(projectRoot: string): string {\n return path.join(pgDir(projectRoot), 'prompts');\n}\n\nexport function promptFile(projectRoot: string, agentId: string): string {\n return path.join(promptsDir(projectRoot), `${agentId}.md`);\n}\n\nexport function worktreeBaseDir(projectRoot: string): string {\n return path.join(projectRoot, '.worktrees');\n}\n\nexport function worktreePath(projectRoot: string, id: string): string {\n return path.join(worktreeBaseDir(projectRoot), id);\n}\n","import fs from 'node:fs/promises';\nimport YAML from 'yaml';\nimport type { Config, AgentConfig } from '../types/config.js';\nimport { configPath } from '../lib/paths.js';\n\nconst DEFAULT_CONFIG: Config = {\n sessionName: 'ppg',\n defaultAgent: 'claude',\n agents: {\n claude: {\n name: 'claude',\n command: 'claude --dangerously-skip-permissions',\n interactive: true,\n resultInstructions: [\n 'When you have completed the task, write a summary of what you did and any important notes',\n 'to the result file at: {{RESULT_FILE}}',\n 'Use this exact format:',\n '',\n '# Result: {{AGENT_ID}}',\n '',\n '## Summary',\n '<what you accomplished>',\n '',\n '## Changes',\n '<list of files changed>',\n '',\n '## Notes',\n '<any important observations>',\n ].join('\\n'),\n },\n },\n worktreeBase: '.worktrees',\n templateDir: '.pg/templates',\n resultDir: '.pg/results',\n logDir: '.pg/logs',\n envFiles: ['.env', '.env.local'],\n symlinkNodeModules: true,\n};\n\nexport async function loadConfig(projectRoot: string): Promise<Config> {\n const cfgPath = configPath(projectRoot);\n try {\n const raw = await fs.readFile(cfgPath, 'utf-8');\n const parsed = YAML.parse(raw) as Partial<Config>;\n return mergeConfig(DEFAULT_CONFIG, parsed);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return DEFAULT_CONFIG;\n }\n throw err;\n }\n}\n\nfunction mergeConfig(defaults: Config, overrides: Partial<Config>): Config {\n return {\n ...defaults,\n ...overrides,\n agents: {\n ...defaults.agents,\n ...(overrides.agents ?? {}),\n },\n };\n}\n\nexport async function writeDefaultConfig(projectRoot: string): Promise<void> {\n const cfgPath = configPath(projectRoot);\n const content = YAML.stringify(DEFAULT_CONFIG, { indent: 2 });\n await fs.writeFile(cfgPath, content, 'utf-8');\n}\n\nexport function resolveAgentConfig(config: Config, name?: string): AgentConfig {\n const agentName = name ?? config.defaultAgent;\n const agent = config.agents[agentName];\n if (!agent) {\n throw new Error(`Unknown agent type: ${agentName}. Available: ${Object.keys(config.agents).join(', ')}`);\n }\n return agent;\n}\n","/**\n * Dynamic import wrappers for CJS packages that may not have proper ESM exports.\n * Uses `mod.default ?? mod` pattern to handle both CJS and ESM default exports.\n */\n\nlet _lockfile: typeof import('proper-lockfile') | undefined;\nlet _writeFileAtomic: typeof import('write-file-atomic').default | undefined;\n\nexport async function getLockfile() {\n if (!_lockfile) {\n const mod = await import('proper-lockfile');\n _lockfile = (mod.default ?? mod) as typeof import('proper-lockfile');\n }\n return _lockfile;\n}\n\nexport async function getWriteFileAtomic() {\n if (!_writeFileAtomic) {\n const mod = await import('write-file-atomic');\n _writeFileAtomic = (mod.default ?? mod) as typeof import('write-file-atomic').default;\n }\n return _writeFileAtomic;\n}\n","import fs from 'node:fs/promises';\nimport { manifestPath } from '../lib/paths.js';\nimport { getLockfile, getWriteFileAtomic } from '../lib/cjs-compat.js';\nimport { ManifestLockError } from '../lib/errors.js';\nimport type { Manifest, WorktreeEntry, AgentEntry } from '../types/manifest.js';\n\nexport function createEmptyManifest(projectRoot: string, sessionName: string): Manifest {\n const now = new Date().toISOString();\n return {\n version: 1,\n projectRoot,\n sessionName,\n worktrees: {},\n createdAt: now,\n updatedAt: now,\n };\n}\n\nexport async function readManifest(projectRoot: string): Promise<Manifest> {\n const mPath = manifestPath(projectRoot);\n const raw = await fs.readFile(mPath, 'utf-8');\n return JSON.parse(raw) as Manifest;\n}\n\nexport async function writeManifest(projectRoot: string, manifest: Manifest): Promise<void> {\n const writeFileAtomic = await getWriteFileAtomic();\n const mPath = manifestPath(projectRoot);\n manifest.updatedAt = new Date().toISOString();\n await writeFileAtomic(mPath, JSON.stringify(manifest, null, 2) + '\\n');\n}\n\nexport async function updateManifest(\n projectRoot: string,\n updater: (manifest: Manifest) => Manifest | Promise<Manifest>,\n): Promise<Manifest> {\n const lockfile = await getLockfile();\n const mPath = manifestPath(projectRoot);\n let release: (() => Promise<void>) | undefined;\n\n try {\n release = await lockfile.lock(mPath, {\n stale: 10_000,\n retries: {\n retries: 5,\n minTimeout: 100,\n maxTimeout: 1000,\n },\n });\n } catch {\n throw new ManifestLockError();\n }\n\n try {\n const manifest = await readManifest(projectRoot);\n const updated = await updater(manifest);\n await writeManifest(projectRoot, updated);\n return updated;\n } finally {\n if (release) {\n await release();\n }\n }\n}\n\nexport function getWorktree(manifest: Manifest, id: string): WorktreeEntry | undefined {\n return manifest.worktrees[id];\n}\n\nexport function findWorktreeByName(manifest: Manifest, name: string): WorktreeEntry | undefined {\n return Object.values(manifest.worktrees).find(\n (wt) => wt.name === name || wt.branch === name,\n );\n}\n\nexport function resolveWorktree(manifest: Manifest, ref: string): WorktreeEntry | undefined {\n return getWorktree(manifest, ref) ?? findWorktreeByName(manifest, ref);\n}\n\nexport function findAgent(\n manifest: Manifest,\n agentId: string,\n): { worktree: WorktreeEntry; agent: AgentEntry } | undefined {\n for (const wt of Object.values(manifest.worktrees)) {\n const agent = wt.agents[agentId];\n if (agent) {\n return { worktree: wt, agent };\n }\n }\n return undefined;\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { execa } from 'execa';\nimport { pgDir, resultsDir, logsDir, templatesDir, promptsDir, manifestPath } from '../lib/paths.js';\nimport { NotGitRepoError, TmuxNotFoundError } from '../lib/errors.js';\nimport { success, info } from '../lib/output.js';\nimport { writeDefaultConfig } from '../core/config.js';\nimport { createEmptyManifest, writeManifest } from '../core/manifest.js';\n\nconst CONDUCTOR_CONTEXT = `# PPG Conductor Context\n\nYou are operating on the master branch of a ppg-managed project.\n\n## Critical Rule\n**NEVER make code changes directly on the master branch.** Use \\`ppg spawn\\` to create worktrees.\n\n## Quick Reference\n- \\`ppg spawn --name <name> --prompt \"<task>\" --json --no-open\\` — Spawn worktree + agent\n- \\`ppg status --json\\` — Check statuses\n- \\`ppg aggregate --all --json\\` — Collect results\n- \\`ppg merge <wt-id> --json\\` — Merge completed work\n- \\`ppg kill --agent <id> --json\\` — Kill agent\n\n## Workflow\n1. Break request into parallelizable tasks\n2. Spawn each: \\`ppg spawn --name <name> --prompt \"<self-contained prompt>\" --json --no-open\\`\n3. Poll: \\`ppg status --json\\` every 5s\n4. Aggregate: \\`ppg aggregate --all --json\\`\n5. Present results, then merge confirmed worktrees\n\nEach agent prompt must be self-contained — agents have no memory of this conversation.\nAlways use \\`--json --no-open\\`.\n`;\n\nconst DEFAULT_TEMPLATE = `# Task: {{TASK_NAME}}\n\n## Context\nYou are working in a git worktree at: {{WORKTREE_PATH}}\nBranch: {{BRANCH}}\nProject root: {{PROJECT_ROOT}}\n\n## Instructions\n{{PROMPT}}\n\n## Result Reporting\nWhen you have completed the task, write your results to:\n{{RESULT_FILE}}\n`;\n\nexport async function initCommand(options: { json?: boolean }): Promise<void> {\n const cwd = process.cwd();\n\n // 1. Verify git repo\n let projectRoot: string;\n try {\n const result = await execa('git', ['rev-parse', '--show-toplevel'], { cwd });\n projectRoot = result.stdout.trim();\n } catch {\n throw new NotGitRepoError(cwd);\n }\n\n // 2. Check tmux available\n try {\n await execa('tmux', ['-V']);\n } catch {\n throw new TmuxNotFoundError();\n }\n\n // 3. Create directories\n const dirs = [\n pgDir(projectRoot),\n resultsDir(projectRoot),\n logsDir(projectRoot),\n templatesDir(projectRoot),\n promptsDir(projectRoot),\n ];\n\n for (const dir of dirs) {\n await fs.mkdir(dir, { recursive: true });\n }\n\n info('Created .pg/ directory structure');\n\n // 4. Write default config\n await writeDefaultConfig(projectRoot);\n info('Wrote default config.yaml');\n\n // 5. Write empty manifest\n const dirName = path.basename(projectRoot);\n const sessionName = `ppg-${dirName}`;\n const manifest = createEmptyManifest(projectRoot, sessionName);\n await writeManifest(projectRoot, manifest);\n info('Wrote empty manifest.json');\n\n // 6. Update .gitignore\n await updateGitignore(projectRoot);\n info('Updated .gitignore');\n\n // 7. Write sample template\n const templatePath = path.join(templatesDir(projectRoot), 'default.md');\n try {\n await fs.access(templatePath);\n } catch {\n await fs.writeFile(templatePath, DEFAULT_TEMPLATE, 'utf-8');\n info('Wrote sample template: default.md');\n }\n\n // 8. Write conductor context\n const conductorPath = path.join(pgDir(projectRoot), 'conductor-context.md');\n await fs.writeFile(conductorPath, CONDUCTOR_CONTEXT, 'utf-8');\n info('Wrote conductor-context.md');\n\n // 9. Register Claude Code plugin\n const pluginRegistered = await registerClaudePlugin();\n if (pluginRegistered) {\n info('Registered ppg Claude Code plugin');\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n success: true,\n projectRoot,\n sessionName,\n pgDir: pgDir(projectRoot),\n pluginRegistered,\n }));\n } else {\n success(`Point Guard initialized in ${projectRoot}`);\n }\n}\n\nasync function registerClaudePlugin(): Promise<boolean> {\n try {\n const home = process.env.HOME;\n if (!home) return false;\n\n const skillsDir = path.join(home, '.claude', 'skills');\n\n // Find this package's skills directory\n const pkgRoot = new URL('../../', import.meta.url);\n const srcSkillsDir = new URL('skills/', pkgRoot).pathname;\n\n // Verify source skills exist\n try {\n await fs.access(srcSkillsDir);\n } catch {\n return false;\n }\n\n // Copy skills to ~/.claude/skills/\n const skillFolders = ['ppg', 'ppg-conductor'];\n let copied = false;\n\n for (const folder of skillFolders) {\n const srcDir = path.join(srcSkillsDir, folder);\n const destDir = path.join(skillsDir, folder);\n\n try {\n await fs.access(srcDir);\n } catch {\n continue;\n }\n\n // Copy recursively (overwrite existing)\n await fs.cp(srcDir, destDir, { recursive: true, force: true });\n copied = true;\n }\n\n return copied;\n } catch {\n // Non-fatal — skill installation is best-effort\n return false;\n }\n}\n\nasync function updateGitignore(projectRoot: string): Promise<void> {\n const gitignorePath = path.join(projectRoot, '.gitignore');\n const entriesToAdd = [\n '.pg/results/',\n '.pg/logs/',\n '.pg/manifest.json',\n '.pg/prompts/',\n '.pg/conductor-context.md',\n ];\n\n let content = '';\n try {\n content = await fs.readFile(gitignorePath, 'utf-8');\n } catch {\n // No .gitignore yet\n }\n\n const lines = content.split('\\n');\n const toAdd = entriesToAdd.filter((entry) => !lines.includes(entry));\n\n if (toAdd.length > 0) {\n const addition = (content.endsWith('\\n') || content === '' ? '' : '\\n')\n + '\\n# Point Guard\\n'\n + toAdd.join('\\n')\n + '\\n';\n await fs.appendFile(gitignorePath, addition, 'utf-8');\n }\n}\n","import { execa } from 'execa';\nimport { worktreePath as getWorktreePath } from '../lib/paths.js';\nimport { NotGitRepoError } from '../lib/errors.js';\n\nexport async function getRepoRoot(cwd?: string): Promise<string> {\n try {\n const result = await execa('git', ['rev-parse', '--show-toplevel'], {\n cwd: cwd ?? process.cwd(),\n });\n return result.stdout.trim();\n } catch {\n throw new NotGitRepoError(cwd ?? process.cwd());\n }\n}\n\nexport async function getCurrentBranch(cwd?: string): Promise<string> {\n const result = await execa('git', ['branch', '--show-current'], {\n cwd: cwd ?? process.cwd(),\n });\n return result.stdout.trim();\n}\n\nexport interface CreateWorktreeOptions {\n branch: string;\n base?: string;\n}\n\nexport async function createWorktree(\n repoRoot: string,\n id: string,\n options: CreateWorktreeOptions,\n): Promise<string> {\n const wtPath = getWorktreePath(repoRoot, id);\n const args = ['worktree', 'add', wtPath, '-b', options.branch];\n if (options.base) {\n args.push(options.base);\n }\n await execa('git', args, { cwd: repoRoot });\n return wtPath;\n}\n\nexport async function removeWorktree(\n repoRoot: string,\n wtPath: string,\n options?: { force?: boolean; deleteBranch?: boolean; branchName?: string },\n): Promise<void> {\n const args = ['worktree', 'remove', wtPath];\n if (options?.force) {\n args.push('--force');\n }\n await execa('git', args, { cwd: repoRoot });\n\n if (options?.deleteBranch && options.branchName) {\n try {\n await execa('git', ['branch', '-D', options.branchName], { cwd: repoRoot });\n } catch {\n // Branch may not exist\n }\n }\n}\n\nexport async function listWorktrees(repoRoot: string): Promise<string[]> {\n const result = await execa('git', ['worktree', 'list', '--porcelain'], { cwd: repoRoot });\n return result.stdout\n .split('\\n')\n .filter((line) => line.startsWith('worktree '))\n .map((line) => line.replace('worktree ', ''));\n}\n\nexport async function pruneWorktrees(repoRoot: string): Promise<void> {\n await execa('git', ['worktree', 'prune'], { cwd: repoRoot });\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Config } from '../types/config.js';\n\nexport async function setupWorktreeEnv(\n projectRoot: string,\n wtPath: string,\n config: Config,\n): Promise<void> {\n // Copy .env files\n for (const envFile of config.envFiles) {\n const src = path.join(projectRoot, envFile);\n const dest = path.join(wtPath, envFile);\n try {\n await fs.access(src);\n await fs.copyFile(src, dest);\n } catch {\n // Source env file doesn't exist, skip\n }\n }\n\n // Symlink node_modules\n if (config.symlinkNodeModules) {\n const src = path.join(projectRoot, 'node_modules');\n const dest = path.join(wtPath, 'node_modules');\n try {\n await fs.access(src);\n // Check if dest already exists\n try {\n await fs.lstat(dest);\n // Already exists, skip\n } catch {\n await fs.symlink(src, dest, 'dir');\n }\n } catch {\n // Source node_modules doesn't exist, skip\n }\n }\n}\n\nexport async function teardownWorktreeEnv(wtPath: string): Promise<void> {\n // Remove node_modules symlink before worktree deletion\n const nmPath = path.join(wtPath, 'node_modules');\n try {\n const stat = await fs.lstat(nmPath);\n if (stat.isSymbolicLink()) {\n await fs.unlink(nmPath);\n }\n } catch {\n // Not a symlink or doesn't exist\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { templatesDir } from '../lib/paths.js';\n\nexport async function listTemplates(projectRoot: string): Promise<string[]> {\n const dir = templatesDir(projectRoot);\n try {\n const files = await fs.readdir(dir);\n return files.filter((f) => f.endsWith('.md')).map((f) => f.replace(/\\.md$/, ''));\n } catch {\n return [];\n }\n}\n\nexport async function loadTemplate(projectRoot: string, name: string): Promise<string> {\n const dir = templatesDir(projectRoot);\n const filePath = path.join(dir, `${name}.md`);\n return fs.readFile(filePath, 'utf-8');\n}\n\nexport interface TemplateContext {\n WORKTREE_PATH: string;\n BRANCH: string;\n AGENT_ID: string;\n RESULT_FILE: string;\n PROJECT_ROOT: string;\n TASK_NAME?: string;\n PROMPT?: string;\n [key: string]: string | undefined;\n}\n\nexport function renderTemplate(content: string, context: TemplateContext): string {\n return content.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key: string) => {\n return context[key] ?? `{{${key}}}`;\n });\n}\n","import { execa, ExecaError } from 'execa';\nimport { TmuxNotFoundError } from '../lib/errors.js';\n\nexport async function checkTmux(): Promise<void> {\n try {\n await execa('tmux', ['-V']);\n } catch {\n throw new TmuxNotFoundError();\n }\n}\n\nexport async function sessionExists(name: string): Promise<boolean> {\n try {\n await execa('tmux', ['has-session', '-t', name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureSession(name: string): Promise<void> {\n if (!(await sessionExists(name))) {\n await execa('tmux', ['new-session', '-d', '-s', name, '-x', '220', '-y', '50']);\n await execa('tmux', ['set-option', '-t', name, 'mouse', 'on']);\n await execa('tmux', ['set-option', '-t', name, 'history-limit', '50000']);\n }\n}\n\nexport async function createWindow(\n session: string,\n name: string,\n cwd: string,\n): Promise<string> {\n const result = await execa('tmux', [\n 'new-window',\n '-t', session,\n '-n', name,\n '-c', cwd,\n '-P', '-F', '#{window_index}',\n ]);\n const windowIndex = result.stdout.trim();\n return `${session}:${windowIndex}`;\n}\n\nexport async function splitPane(\n target: string,\n direction: 'horizontal' | 'vertical',\n cwd: string,\n): Promise<{ paneId: string; target: string }> {\n const flag = direction === 'horizontal' ? '-h' : '-v';\n const result = await execa('tmux', [\n 'split-window',\n flag,\n '-t', target,\n '-c', cwd,\n '-P', '-F', '#{session_name}:#{window_index}.#{pane_index}|#{pane_id}',\n ]);\n const [canonicalTarget, paneId] = result.stdout.trim().split('|');\n return { paneId, target: canonicalTarget };\n}\n\nexport async function sendKeys(target: string, command: string): Promise<void> {\n // Send command text with trailing newline in a single call\n await execa('tmux', ['send-keys', '-t', target, '-l', command + '\\n']);\n}\n\nexport async function sendLiteral(target: string, text: string): Promise<void> {\n await execa('tmux', ['send-keys', '-t', target, '-l', text]);\n}\n\nexport async function sendRawKeys(target: string, keys: string): Promise<void> {\n await execa('tmux', ['send-keys', '-t', target, keys]);\n}\n\nexport async function capturePane(target: string, lines?: number): Promise<string> {\n const args = ['capture-pane', '-t', target, '-p'];\n if (lines) {\n args.push('-S', `-${lines}`);\n }\n const result = await execa('tmux', args);\n return result.stdout;\n}\n\nexport async function killPane(target: string): Promise<void> {\n try {\n await execa('tmux', ['kill-pane', '-t', target]);\n } catch {\n // Pane may already be dead\n }\n}\n\nexport async function killWindow(target: string): Promise<void> {\n try {\n await execa('tmux', ['kill-window', '-t', target]);\n } catch {\n // Window may already be dead\n }\n}\n\nexport interface PaneInfo {\n paneId: string;\n panePid: string;\n currentCommand: string;\n isDead: boolean;\n deadStatus?: number;\n}\n\nexport async function listPanes(target: string): Promise<PaneInfo[]> {\n try {\n const result = await execa('tmux', [\n 'list-panes',\n '-t', target,\n '-F', '#{pane_id}|#{pane_pid}|#{pane_current_command}|#{pane_dead}|#{pane_dead_status}',\n ]);\n return result.stdout.trim().split('\\n').filter(Boolean).map((line) => {\n const [paneId, panePid, currentCommand, dead, deadStatus] = line.split('|');\n return {\n paneId,\n panePid,\n currentCommand,\n isDead: dead === '1',\n deadStatus: deadStatus ? parseInt(deadStatus, 10) : undefined,\n };\n });\n } catch {\n return [];\n }\n}\n\nexport async function getPaneInfo(target: string): Promise<PaneInfo | null> {\n try {\n const result = await execa('tmux', [\n 'display-message',\n '-t', target,\n '-p',\n '#{pane_id}|#{pane_pid}|#{pane_current_command}|#{pane_dead}|#{pane_dead_status}',\n ]);\n const [paneId, panePid, currentCommand, dead, deadStatus] = result.stdout.trim().split('|');\n return {\n paneId,\n panePid,\n currentCommand,\n isDead: dead === '1',\n deadStatus: deadStatus ? parseInt(deadStatus, 10) : undefined,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * List all panes in a session with a single tmux call.\n * Returns a map keyed by pane target (session:window.pane format).\n */\nexport async function listSessionPanes(session: string): Promise<Map<string, PaneInfo>> {\n const map = new Map<string, PaneInfo>();\n try {\n const result = await execa('tmux', [\n 'list-panes',\n '-s',\n '-t', session,\n '-F', '#{session_name}:#{window_index}.#{pane_index}|#{pane_id}|#{pane_pid}|#{pane_current_command}|#{pane_dead}|#{pane_dead_status}',\n ]);\n for (const line of result.stdout.trim().split('\\n').filter(Boolean)) {\n const [target, paneId, panePid, currentCommand, dead, deadStatus] = line.split('|');\n const info: PaneInfo = {\n paneId,\n panePid,\n currentCommand,\n isDead: dead === '1',\n deadStatus: deadStatus ? parseInt(deadStatus, 10) : undefined,\n };\n // Index by multiple target formats for flexible lookup\n map.set(target, info); // session:window.pane\n map.set(paneId, info); // %paneId\n const dotIdx = target.lastIndexOf('.');\n if (dotIdx !== -1) {\n map.set(target.slice(0, dotIdx), info); // session:window\n }\n }\n } catch {\n // Session may not exist\n }\n return map;\n}\n\nexport async function selectPane(target: string): Promise<void> {\n await execa('tmux', ['select-pane', '-t', target]);\n}\n\nexport async function selectWindow(target: string): Promise<void> {\n await execa('tmux', ['select-window', '-t', target]);\n}\n\nexport async function attachSession(session: string): Promise<void> {\n // This replaces the current process, so it should be used from a non-tmux terminal\n await execa('tmux', ['attach-session', '-t', session], { stdio: 'inherit' });\n}\n\nexport async function isInsideTmux(): Promise<boolean> {\n return !!process.env.TMUX;\n}\n\nexport async function sendCtrlC(target: string): Promise<void> {\n await execa('tmux', ['send-keys', '-t', target, 'C-c']);\n}\n","import fs from 'node:fs/promises';\nimport { resultFile, promptFile } from '../lib/paths.js';\nimport { getPaneInfo, listSessionPanes, type PaneInfo } from './tmux.js';\nimport { updateManifest } from './manifest.js';\nimport { PgError } from '../lib/errors.js';\nimport type { AgentEntry, AgentStatus } from '../types/manifest.js';\nimport type { AgentConfig } from '../types/config.js';\nimport { renderTemplate, type TemplateContext } from './template.js';\nimport * as tmux from './tmux.js';\n\nconst SHELL_COMMANDS = new Set(['bash', 'zsh', 'sh', 'fish', 'dash', 'tcsh', 'csh']);\n\nexport interface SpawnAgentOptions {\n agentId: string;\n agentConfig: AgentConfig;\n prompt: string;\n worktreePath: string;\n tmuxTarget: string;\n projectRoot: string;\n branch: string;\n sessionId?: string;\n}\n\nexport async function spawnAgent(options: SpawnAgentOptions): Promise<AgentEntry> {\n const {\n agentId,\n agentConfig,\n prompt,\n worktreePath,\n tmuxTarget,\n projectRoot,\n branch,\n } = options;\n\n const resFile = resultFile(projectRoot, agentId);\n\n // Build full prompt with result instructions\n let fullPrompt = prompt;\n if (agentConfig.resultInstructions) {\n const ctx: TemplateContext = {\n WORKTREE_PATH: worktreePath,\n BRANCH: branch,\n AGENT_ID: agentId,\n RESULT_FILE: resFile,\n PROJECT_ROOT: projectRoot,\n };\n const instructions = renderTemplate(agentConfig.resultInstructions, ctx);\n fullPrompt += `\\n\\n---\\n\\n${instructions}`;\n }\n\n // Write prompt to file\n const pFile = promptFile(projectRoot, agentId);\n await fs.writeFile(pFile, fullPrompt, 'utf-8');\n\n // Build and send command\n const command = buildAgentCommand(agentConfig, pFile, options.sessionId);\n await tmux.sendKeys(tmuxTarget, command);\n\n return {\n id: agentId,\n name: agentConfig.name,\n agentType: agentConfig.name,\n status: 'running',\n tmuxTarget,\n prompt: prompt.slice(0, 500), // Truncate for manifest storage\n resultFile: resFile,\n startedAt: new Date().toISOString(),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n };\n}\n\nfunction buildAgentCommand(agentConfig: AgentConfig, promptFilePath: string, sessionId?: string): string {\n // Unset CLAUDECODE so spawned Claude instances don't think they're nested\n const envPrefix = 'unset CLAUDECODE;';\n const { command, promptFlag } = agentConfig;\n // Inject --session-id for Claude-based commands\n const sessionFlag = sessionId && command.includes('claude') ? ` --session-id ${sessionId}` : '';\n if (promptFlag) {\n // Use explicit flag: command --flag \"$(cat prompt-file)\"\n return `${envPrefix} ${command}${sessionFlag} ${promptFlag} \"$(cat ${promptFilePath})\"`;\n }\n // Pass prompt as positional argument: command \"$(cat prompt-file)\"\n return `${envPrefix} ${command}${sessionFlag} \"$(cat ${promptFilePath})\"`;\n}\n\n/**\n * Check agent status using the layered signal stack.\n * Checked in order of signal strength:\n * 1. Result file exists → completed\n * 2. Tmux pane doesn't exist → lost\n * 3. Pane is dead → completed/failed based on exit code\n * 4. Current command is a shell → agent exited → completed/failed\n * 5. Otherwise → running\n *\n * @param paneMap Optional pre-fetched pane map from listSessionPanes() for batch queries\n */\nexport async function checkAgentStatus(\n agent: AgentEntry,\n projectRoot: string,\n paneMap?: Map<string, PaneInfo>,\n): Promise<{ status: AgentStatus; exitCode?: number }> {\n // If already in terminal state, don't re-check\n if (['completed', 'failed', 'killed', 'lost'].includes(agent.status)) {\n return { status: agent.status, exitCode: agent.exitCode };\n }\n\n // 1. Check result file\n const hasResult = await fileExists(agent.resultFile);\n if (hasResult) {\n return { status: 'completed' };\n }\n\n // 2. Check if tmux pane exists (use batch map if available)\n const paneInfo = paneMap\n ? (paneMap.get(agent.tmuxTarget) ?? null)\n : await getPaneInfo(agent.tmuxTarget);\n if (!paneInfo) {\n return { status: 'lost' };\n }\n\n // 3. Check if pane is dead\n if (paneInfo.isDead) {\n const exitCode = paneInfo.deadStatus;\n // Check result file one more time (may have been written right before exit)\n const hasResultNow = await fileExists(agent.resultFile);\n if (hasResultNow || exitCode === 0) {\n return { status: 'completed', exitCode: exitCode ?? 0 };\n }\n return { status: 'failed', exitCode };\n }\n\n // 4. Check if current command is a shell (agent process exited, returned to shell)\n if (SHELL_COMMANDS.has(paneInfo.currentCommand)) {\n // Agent process exited, back to shell prompt\n const hasResultNow = await fileExists(agent.resultFile);\n if (hasResultNow) {\n return { status: 'completed', exitCode: 0 };\n }\n return { status: 'failed', exitCode: undefined };\n }\n\n // 5. Still running\n return { status: 'running' };\n}\n\nexport async function refreshAllAgentStatuses(\n manifest: import('../types/manifest.js').Manifest,\n projectRoot: string,\n): Promise<import('../types/manifest.js').Manifest> {\n // Batch-fetch all pane info in a single tmux call\n const paneMap = await listSessionPanes(manifest.sessionName);\n\n // Collect all agents that need checking\n const checks: Array<{ agent: AgentEntry; promise: Promise<{ status: AgentStatus; exitCode?: number }> }> = [];\n for (const wt of Object.values(manifest.worktrees)) {\n for (const agent of Object.values(wt.agents)) {\n checks.push({\n agent,\n promise: checkAgentStatus(agent, projectRoot, paneMap),\n });\n }\n }\n\n // Run all status checks in parallel\n const results = await Promise.all(checks.map((c) => c.promise));\n\n // Apply results\n const now = new Date().toISOString();\n for (let i = 0; i < checks.length; i++) {\n const { agent } = checks[i];\n const { status, exitCode } = results[i];\n if (status !== agent.status) {\n agent.status = status;\n if (exitCode !== undefined) agent.exitCode = exitCode;\n if (['completed', 'failed', 'lost'].includes(status) && !agent.completedAt) {\n agent.completedAt = now;\n }\n }\n }\n\n // Check worktree directories in parallel\n const wtChecks = Object.values(manifest.worktrees)\n .filter((wt) => wt.status === 'active')\n .map(async (wt) => {\n const exists = await fileExists(wt.path);\n if (!exists) {\n wt.status = 'cleaned';\n for (const agent of Object.values(wt.agents)) {\n if (!['completed', 'failed', 'killed'].includes(agent.status)) {\n agent.status = 'lost';\n if (!agent.completedAt) agent.completedAt = now;\n }\n }\n }\n });\n await Promise.all(wtChecks);\n\n return manifest;\n}\n\nexport interface ResumeAgentOptions {\n agent: AgentEntry;\n worktreeId: string;\n sessionName: string;\n cwd: string;\n windowName: string;\n projectRoot: string;\n}\n\n/**\n * Resume a dead agent's session in a new tmux window, updating the manifest.\n * Returns the new tmux target.\n */\nexport async function resumeAgent(options: ResumeAgentOptions): Promise<string> {\n const { agent, worktreeId, sessionName, cwd, windowName, projectRoot } = options;\n\n if (!agent.sessionId) {\n throw new PgError(\n `Agent ${agent.id} has no session ID. Cannot resume agents spawned before session tracking was added.`,\n 'NO_SESSION_ID',\n );\n }\n\n await tmux.ensureSession(sessionName);\n const newTarget = await tmux.createWindow(sessionName, windowName, cwd);\n await tmux.sendKeys(newTarget, `unset CLAUDECODE; claude --resume ${agent.sessionId}`);\n\n await updateManifest(projectRoot, (m) => {\n const mAgent = m.worktrees[worktreeId]?.agents[agent.id];\n if (mAgent) {\n mAgent.tmuxTarget = newTarget;\n mAgent.status = 'running';\n }\n return m;\n });\n\n return newTarget;\n}\n\nexport async function killAgent(agent: AgentEntry): Promise<void> {\n // Send Ctrl-C first\n await tmux.sendCtrlC(agent.tmuxTarget);\n\n // Wait a moment\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n // Check if still alive\n const paneInfo = await getPaneInfo(agent.tmuxTarget);\n if (paneInfo && !paneInfo.isDead) {\n // Kill the pane\n await tmux.killPane(agent.tmuxTarget);\n }\n}\n\n/**\n * Kill multiple agents in parallel: send Ctrl-C to all, wait once, then force-kill survivors.\n */\nexport async function killAgents(agents: AgentEntry[]): Promise<void> {\n if (agents.length === 0) return;\n\n // Send Ctrl-C to all agents in parallel\n await Promise.all(agents.map((a) => tmux.sendCtrlC(a.tmuxTarget).catch(() => {})));\n\n // Single wait\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n // Check and force-kill survivors in parallel\n await Promise.all(agents.map(async (a) => {\n const paneInfo = await getPaneInfo(a.tmuxTarget);\n if (paneInfo && !paneInfo.isDead) {\n await tmux.killPane(a.tmuxTarget);\n }\n }));\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import { execa } from 'execa';\nimport { warn } from '../lib/output.js';\n\n/**\n * Open a new Terminal.app window that attaches to a specific tmux session/window.\n */\nexport async function openTerminalWindow(\n sessionName: string,\n windowTarget: string,\n title: string,\n): Promise<void> {\n const tmuxCmd = `tmux attach-session -t ${sessionName} \\\\\\\\; select-window -t ${windowTarget}`;\n\n const script = `\ntell application \"Terminal\"\n activate\n set newTab to do script \"${tmuxCmd}\"\n set custom title of newTab to \"${title}\"\nend tell\n`;\n\n try {\n await execa('osascript', ['-e', script]);\n } catch (err) {\n warn(`Could not open Terminal window for \"${title}\": ${err instanceof Error ? err.message : err}`);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { customAlphabet } from 'nanoid';\n\nconst alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\nconst shortId = customAlphabet(alphabet, 6);\nconst longId = customAlphabet(alphabet, 8);\n\nexport function worktreeId(): string {\n return `wt-${shortId()}`;\n}\n\nexport function agentId(): string {\n return `ag-${longId()}`;\n}\n\nexport function sessionId(): string {\n return randomUUID();\n}\n","import fs from 'node:fs/promises';\nimport { loadConfig, resolveAgentConfig } from '../core/config.js';\nimport { readManifest, updateManifest, resolveWorktree } from '../core/manifest.js';\nimport { getRepoRoot, getCurrentBranch, createWorktree } from '../core/worktree.js';\nimport { setupWorktreeEnv } from '../core/env.js';\nimport { loadTemplate, renderTemplate, type TemplateContext } from '../core/template.js';\nimport { spawnAgent } from '../core/agent.js';\nimport * as tmux from '../core/tmux.js';\nimport { openTerminalWindow } from '../core/terminal.js';\nimport { worktreeId as genWorktreeId, agentId as genAgentId, sessionId as genSessionId } from '../lib/id.js';\nimport { resultFile, manifestPath } from '../lib/paths.js';\nimport { PgError, NotInitializedError, WorktreeNotFoundError } from '../lib/errors.js';\nimport { output, success, info } from '../lib/output.js';\nimport type { WorktreeEntry, AgentEntry } from '../types/manifest.js';\n\nexport interface SpawnOptions {\n name?: string;\n agent?: string;\n prompt?: string;\n promptFile?: string;\n template?: string;\n var?: string[];\n base?: string;\n worktree?: string;\n count?: number;\n split?: boolean;\n open?: boolean;\n json?: boolean;\n}\n\nexport async function spawnCommand(options: SpawnOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n const config = await loadConfig(projectRoot);\n\n // Verify initialized (lightweight file check instead of full manifest read)\n try {\n await fs.access(manifestPath(projectRoot));\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const agentConfig = resolveAgentConfig(config, options.agent);\n const count = options.count ?? 1;\n\n // Resolve prompt\n const promptText = await resolvePrompt(options, projectRoot);\n\n if (options.worktree) {\n // Add agent(s) to existing worktree\n await spawnIntoExistingWorktree(\n projectRoot,\n config,\n agentConfig,\n options.worktree,\n promptText,\n count,\n options,\n );\n } else {\n // Create new worktree + agent(s)\n await spawnNewWorktree(\n projectRoot,\n config,\n agentConfig,\n promptText,\n count,\n options,\n );\n }\n}\n\nasync function resolvePrompt(options: SpawnOptions, projectRoot: string): Promise<string> {\n if (options.prompt) return options.prompt;\n\n if (options.promptFile) {\n return fs.readFile(options.promptFile, 'utf-8');\n }\n\n if (options.template) {\n const templateContent = await loadTemplate(projectRoot, options.template);\n const vars: Record<string, string> = {};\n for (const v of options.var ?? []) {\n const [key, ...rest] = v.split('=');\n vars[key] = rest.join('=');\n }\n // Template will be fully rendered later with worktree context\n return templateContent;\n }\n\n throw new PgError('One of --prompt, --prompt-file, or --template is required', 'INVALID_ARGS');\n}\n\nasync function spawnNewWorktree(\n projectRoot: string,\n config: import('../types/config.js').Config,\n agentConfig: import('../types/config.js').AgentConfig,\n promptText: string,\n count: number,\n options: SpawnOptions,\n): Promise<void> {\n const baseBranch = options.base ?? await getCurrentBranch(projectRoot);\n const wtId = genWorktreeId();\n const name = options.name ?? wtId;\n const branchName = `ppg/${name}`;\n\n // Create git worktree\n info(`Creating worktree ${wtId} on branch ${branchName}`);\n const wtPath = await createWorktree(projectRoot, wtId, {\n branch: branchName,\n base: baseBranch,\n });\n\n // Setup env\n await setupWorktreeEnv(projectRoot, wtPath, config);\n\n // Ensure tmux session (use config directly instead of re-reading manifest)\n const sessionName = config.sessionName;\n await tmux.ensureSession(sessionName);\n\n // Create tmux window\n const windowTarget = await tmux.createWindow(sessionName, name, wtPath);\n\n // Spawn agents — one tmux window per agent (default), or split panes (--split)\n const agents: AgentEntry[] = [];\n for (let i = 0; i < count; i++) {\n const aId = genAgentId();\n let target: string;\n\n if (i === 0) {\n // First agent uses the window already created for the worktree\n target = windowTarget;\n } else if (options.split) {\n // --split: additional agents share the same window as split panes\n const direction = i % 2 === 1 ? 'horizontal' : 'vertical';\n const pane = await tmux.splitPane(windowTarget, direction, wtPath);\n target = pane.target;\n } else {\n // Default: each additional agent gets its own tmux window\n target = await tmux.createWindow(sessionName, `${name}-${i}`, wtPath);\n }\n\n // Render template variables if present\n const ctx: TemplateContext = {\n WORKTREE_PATH: wtPath,\n BRANCH: branchName,\n AGENT_ID: aId,\n RESULT_FILE: resultFile(projectRoot, aId),\n PROJECT_ROOT: projectRoot,\n TASK_NAME: name,\n PROMPT: promptText,\n };\n\n // Parse user vars\n for (const v of options.var ?? []) {\n const [key, ...rest] = v.split('=');\n ctx[key] = rest.join('=');\n }\n\n const renderedPrompt = renderTemplate(promptText, ctx);\n\n const agentEntry = await spawnAgent({\n agentId: aId,\n agentConfig,\n prompt: renderedPrompt,\n worktreePath: wtPath,\n tmuxTarget: target,\n projectRoot,\n branch: branchName,\n sessionId: genSessionId(),\n });\n\n agents.push(agentEntry);\n }\n\n // Update manifest\n const worktreeEntry: WorktreeEntry = {\n id: wtId,\n name,\n path: wtPath,\n branch: branchName,\n baseBranch,\n status: 'active',\n tmuxWindow: windowTarget,\n agents: Object.fromEntries(agents.map((a) => [a.id, a])),\n createdAt: new Date().toISOString(),\n };\n\n await updateManifest(projectRoot, (m) => {\n m.worktrees[wtId] = worktreeEntry;\n return m;\n });\n\n // Auto-open Terminal window unless --no-open (fire-and-forget)\n if (options.open !== false) {\n openTerminalWindow(sessionName, windowTarget, name).catch(() => {});\n }\n\n if (options.json) {\n output({\n success: true,\n worktree: {\n id: wtId,\n name,\n branch: branchName,\n path: wtPath,\n tmuxWindow: windowTarget,\n },\n agents: agents.map((a) => ({\n id: a.id,\n tmuxTarget: a.tmuxTarget,\n sessionId: a.sessionId,\n })),\n }, true);\n } else {\n success(`Spawned worktree ${wtId} with ${agents.length} agent(s)`);\n for (const a of agents) {\n info(` Agent ${a.id} → ${a.tmuxTarget}`);\n }\n info(`Attach: ppg attach ${wtId}`);\n }\n}\n\nasync function spawnIntoExistingWorktree(\n projectRoot: string,\n config: import('../types/config.js').Config,\n agentConfig: import('../types/config.js').AgentConfig,\n worktreeRef: string,\n promptText: string,\n count: number,\n options: SpawnOptions,\n): Promise<void> {\n const manifest = await readManifest(projectRoot);\n const wt = resolveWorktree(manifest, worktreeRef);\n\n if (!wt) throw new WorktreeNotFoundError(worktreeRef);\n\n // Lazily create tmux window if worktree has none (standalone worktree)\n let windowTarget = wt.tmuxWindow;\n if (!windowTarget) {\n await tmux.ensureSession(manifest.sessionName);\n windowTarget = await tmux.createWindow(manifest.sessionName, wt.name, wt.path);\n }\n\n const agents: AgentEntry[] = [];\n for (let i = 0; i < count; i++) {\n const aId = genAgentId();\n\n let target: string;\n if (i === 0 && options.split) {\n // First agent reuses the existing window pane\n target = windowTarget;\n } else if (options.split) {\n // --split: additional agents share the same window as split panes\n const direction = i % 2 === 1 ? 'horizontal' : 'vertical';\n const pane = await tmux.splitPane(windowTarget, direction, wt.path);\n target = pane.target;\n } else {\n // Default: every agent gets its own tmux window\n target = await tmux.createWindow(manifest.sessionName, `${wt.name}-agent-${i}`, wt.path);\n }\n\n const ctx: TemplateContext = {\n WORKTREE_PATH: wt.path,\n BRANCH: wt.branch,\n AGENT_ID: aId,\n RESULT_FILE: resultFile(projectRoot, aId),\n PROJECT_ROOT: projectRoot,\n TASK_NAME: wt.name,\n PROMPT: promptText,\n };\n\n for (const v of options.var ?? []) {\n const [key, ...rest] = v.split('=');\n ctx[key] = rest.join('=');\n }\n\n const renderedPrompt = renderTemplate(promptText, ctx);\n\n const agentEntry = await spawnAgent({\n agentId: aId,\n agentConfig,\n prompt: renderedPrompt,\n worktreePath: wt.path,\n tmuxTarget: target,\n projectRoot,\n branch: wt.branch,\n sessionId: genSessionId(),\n });\n\n agents.push(agentEntry);\n }\n\n await updateManifest(projectRoot, (m) => {\n const mWt = m.worktrees[wt.id];\n if (!mWt.tmuxWindow) {\n mWt.tmuxWindow = windowTarget;\n }\n for (const a of agents) {\n mWt.agents[a.id] = a;\n }\n return m;\n });\n\n // Auto-open Terminal window unless --no-open (fire-and-forget)\n if (options.open !== false) {\n openTerminalWindow(manifest.sessionName, windowTarget, wt.name).catch(() => {});\n }\n\n if (options.json) {\n output({\n success: true,\n worktree: {\n id: wt.id,\n name: wt.name,\n branch: wt.branch,\n path: wt.path,\n tmuxWindow: windowTarget,\n },\n agents: agents.map((a) => ({ id: a.id, tmuxTarget: a.tmuxTarget, sessionId: a.sessionId })),\n }, true);\n } else {\n success(`Added ${agents.length} agent(s) to worktree ${wt.id}`);\n for (const a of agents) {\n info(` Agent ${a.id} → ${a.tmuxTarget}`);\n }\n }\n}\n","import { loadConfig } from '../core/config.js';\nimport { readManifest, updateManifest } from '../core/manifest.js';\nimport { refreshAllAgentStatuses } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { NotInitializedError } from '../lib/errors.js';\nimport { output, formatStatus, formatTable, type Column } from '../lib/output.js';\nimport type { AgentEntry, WorktreeEntry } from '../types/manifest.js';\n\nexport interface StatusOptions {\n json?: boolean;\n watch?: boolean;\n worktree?: string;\n}\n\nexport async function statusCommand(worktreeFilter?: string, options?: StatusOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n // Read manifest and refresh statuses\n let manifest;\n try {\n manifest = await updateManifest(projectRoot, async (m) => {\n return refreshAllAgentStatuses(m, projectRoot);\n });\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n // Filter worktrees if specified\n const filter = worktreeFilter ?? options?.worktree;\n let worktrees = Object.values(manifest.worktrees);\n if (filter) {\n worktrees = worktrees.filter(\n (wt) => wt.id === filter || wt.name === filter || wt.branch === filter,\n );\n }\n\n if (options?.json) {\n output({\n session: manifest.sessionName,\n worktrees: Object.fromEntries(worktrees.map((wt) => [wt.id, wt])),\n }, true);\n return;\n }\n\n if (worktrees.length === 0) {\n console.log('No active worktrees. Use `ppg spawn` to create one.');\n return;\n }\n\n for (const wt of worktrees) {\n printWorktreeStatus(wt);\n }\n\n if (options?.watch) {\n const interval = setInterval(async () => {\n console.clear();\n try {\n const m = await updateManifest(projectRoot, async (m) => {\n return refreshAllAgentStatuses(m, projectRoot);\n });\n let wts = Object.values(m.worktrees);\n if (filter) {\n wts = wts.filter(\n (wt) => wt.id === filter || wt.name === filter || wt.branch === filter,\n );\n }\n for (const wt of wts) {\n printWorktreeStatus(wt);\n }\n } catch (err) {\n console.error('Error refreshing status:', err);\n }\n }, 2000);\n\n // Handle exit\n process.on('SIGINT', () => {\n clearInterval(interval);\n process.exit(0);\n });\n }\n}\n\nfunction printWorktreeStatus(wt: WorktreeEntry): void {\n const agents = Object.values(wt.agents);\n const statusCounts = {\n running: agents.filter((a) => a.status === 'running').length,\n completed: agents.filter((a) => a.status === 'completed').length,\n failed: agents.filter((a) => a.status === 'failed').length,\n lost: agents.filter((a) => a.status === 'lost').length,\n };\n\n console.log(\n `\\n${wt.name} (${wt.id}) [${formatStatus(wt.status)}] branch:${wt.branch}`,\n );\n\n if (agents.length === 0) {\n console.log(' No agents');\n return;\n }\n\n const columns: Column[] = [\n { header: 'Agent', key: 'id', width: 14 },\n { header: 'Type', key: 'agentType', width: 10 },\n {\n header: 'Status',\n key: 'status',\n width: 12,\n format: (v) => formatStatus(v as AgentEntry['status']),\n },\n { header: 'Started', key: 'startedAt', width: 20, format: (v) => formatTime(v as string) },\n { header: 'Pane', key: 'tmuxTarget', width: 20 },\n ];\n\n const table = formatTable(agents as unknown as Record<string, unknown>[], columns);\n console.log(table.split('\\n').map((l) => ` ${l}`).join('\\n'));\n}\n\nfunction formatTime(iso: string): string {\n if (!iso) return '—';\n const d = new Date(iso);\n const now = new Date();\n const diffMs = now.getTime() - d.getTime();\n const diffMin = Math.floor(diffMs / 60_000);\n if (diffMin < 1) return 'just now';\n if (diffMin < 60) return `${diffMin}m ago`;\n const diffHr = Math.floor(diffMin / 60);\n return `${diffHr}h ${diffMin % 60}m ago`;\n}\n","import { updateManifest } from './manifest.js';\nimport { removeWorktree } from './worktree.js';\nimport { teardownWorktreeEnv } from './env.js';\nimport * as tmux from './tmux.js';\nimport { warn } from '../lib/output.js';\nimport type { WorktreeEntry } from '../types/manifest.js';\n\n/**\n * Clean up a worktree: kill tmux windows, teardown env, remove git worktree, update manifest.\n */\nexport async function cleanupWorktree(\n projectRoot: string,\n wt: WorktreeEntry,\n): Promise<void> {\n // Kill tmux windows in parallel\n const windowKills: Promise<void>[] = [];\n for (const agent of Object.values(wt.agents)) {\n if (agent.tmuxTarget) {\n windowKills.push(tmux.killWindow(agent.tmuxTarget).catch(() => {}));\n }\n }\n if (wt.tmuxWindow) {\n windowKills.push(tmux.killWindow(wt.tmuxWindow).catch(() => {}));\n }\n await Promise.all(windowKills);\n\n // Teardown env\n try {\n await teardownWorktreeEnv(wt.path);\n } catch { /* may already be cleaned */ }\n\n // Remove git worktree + branch\n try {\n await removeWorktree(projectRoot, wt.path, {\n force: true,\n deleteBranch: true,\n branchName: wt.branch,\n });\n } catch (err) {\n warn(`Could not fully remove worktree ${wt.id}: ${err instanceof Error ? err.message : err}`);\n }\n\n // Update manifest\n await updateManifest(projectRoot, (m) => {\n if (m.worktrees[wt.id]) {\n m.worktrees[wt.id].status = 'cleaned';\n }\n return m;\n });\n}\n","import { readManifest, updateManifest, findAgent, resolveWorktree } from '../core/manifest.js';\nimport { killAgent, killAgents } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { cleanupWorktree } from '../core/cleanup.js';\nimport { PgError, NotInitializedError, AgentNotFoundError, WorktreeNotFoundError } from '../lib/errors.js';\nimport { output, success, info } from '../lib/output.js';\nimport type { AgentEntry } from '../types/manifest.js';\n\nexport interface KillOptions {\n agent?: string;\n worktree?: string;\n all?: boolean;\n remove?: boolean;\n delete?: boolean;\n json?: boolean;\n}\n\nexport async function killCommand(options: KillOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n if (!options.agent && !options.worktree && !options.all) {\n throw new PgError('One of --agent, --worktree, or --all is required', 'INVALID_ARGS');\n }\n\n if (options.agent) {\n await killSingleAgent(projectRoot, options.agent, options);\n } else if (options.worktree) {\n await killWorktreeAgents(projectRoot, options.worktree, options);\n } else if (options.all) {\n await killAllAgents(projectRoot, options);\n }\n}\n\nasync function killSingleAgent(\n projectRoot: string,\n agentId: string,\n options: KillOptions,\n): Promise<void> {\n const manifest = await readManifest(projectRoot);\n const found = findAgent(manifest, agentId);\n if (!found) throw new AgentNotFoundError(agentId);\n\n const { agent } = found;\n const isTerminal = ['completed', 'failed', 'killed', 'lost'].includes(agent.status);\n\n if (options.delete) {\n // For --delete: skip kill if already in terminal state, just clean up\n if (!isTerminal) {\n info(`Killing agent ${agentId}`);\n await killAgent(agent);\n }\n // Kill the tmux pane explicitly (handles already-dead)\n await import('../core/tmux.js').then((tmux) => tmux.killPane(agent.tmuxTarget));\n\n await updateManifest(projectRoot, (m) => {\n const f = findAgent(m, agentId);\n if (f) {\n delete f.worktree.agents[agentId];\n }\n return m;\n });\n\n if (options.json) {\n output({ success: true, killed: [agentId], deleted: [agentId] }, true);\n } else {\n success(`Deleted agent ${agentId}`);\n }\n } else {\n info(`Killing agent ${agentId}`);\n await killAgent(agent);\n\n await updateManifest(projectRoot, (m) => {\n const f = findAgent(m, agentId);\n if (f) {\n f.agent.status = 'killed';\n f.agent.completedAt = new Date().toISOString();\n }\n return m;\n });\n\n if (options.json) {\n output({ success: true, killed: [agentId] }, true);\n } else {\n success(`Killed agent ${agentId}`);\n }\n }\n}\n\nasync function killWorktreeAgents(\n projectRoot: string,\n worktreeRef: string,\n options: KillOptions,\n): Promise<void> {\n const manifest = await readManifest(projectRoot);\n const wt = resolveWorktree(manifest, worktreeRef);\n\n if (!wt) throw new WorktreeNotFoundError(worktreeRef);\n\n const toKill = Object.values(wt.agents)\n .filter((a) => ['running', 'spawning', 'waiting'].includes(a.status));\n const killedIds = toKill.map((a) => a.id);\n\n for (const a of toKill) info(`Killing agent ${a.id}`);\n await killAgents(toKill);\n\n await updateManifest(projectRoot, (m) => {\n const mWt = m.worktrees[wt.id];\n if (mWt) {\n for (const agent of Object.values(mWt.agents)) {\n if (killedIds.includes(agent.id)) {\n agent.status = 'killed';\n agent.completedAt = new Date().toISOString();\n }\n }\n }\n return m;\n });\n\n // --delete implies --remove (always clean up worktree)\n const shouldRemove = options.remove || options.delete;\n if (shouldRemove) {\n await removeWorktreeCleanup(projectRoot, wt.id);\n }\n\n // --delete also removes the worktree entry from manifest\n if (options.delete) {\n await updateManifest(projectRoot, (m) => {\n delete m.worktrees[wt.id];\n return m;\n });\n }\n\n if (options.json) {\n output({\n success: true,\n killed: killedIds,\n removed: shouldRemove ? [wt.id] : [],\n deleted: options.delete ? [wt.id] : [],\n }, true);\n } else {\n success(`Killed ${killedIds.length} agent(s) in worktree ${wt.id}`);\n if (options.delete) {\n success(`Deleted worktree ${wt.id}`);\n } else if (options.remove) {\n success(`Removed worktree ${wt.id}`);\n }\n }\n}\n\nasync function killAllAgents(\n projectRoot: string,\n options: KillOptions,\n): Promise<void> {\n const manifest = await readManifest(projectRoot);\n const toKill: AgentEntry[] = [];\n\n for (const wt of Object.values(manifest.worktrees)) {\n for (const agent of Object.values(wt.agents)) {\n if (['running', 'spawning', 'waiting'].includes(agent.status)) {\n toKill.push(agent);\n }\n }\n }\n\n const killedIds = toKill.map((a) => a.id);\n for (const a of toKill) info(`Killing agent ${a.id}`);\n await killAgents(toKill);\n\n // Only track active worktrees for removal (not already merged/cleaned)\n const activeWorktreeIds = Object.values(manifest.worktrees)\n .filter((wt) => wt.status === 'active')\n .map((wt) => wt.id);\n\n await updateManifest(projectRoot, (m) => {\n for (const wt of Object.values(m.worktrees)) {\n for (const agent of Object.values(wt.agents)) {\n if (killedIds.includes(agent.id)) {\n agent.status = 'killed';\n agent.completedAt = new Date().toISOString();\n }\n }\n }\n return m;\n });\n\n // --delete implies --remove\n const shouldRemove = options.remove || options.delete;\n if (shouldRemove) {\n for (const wtId of activeWorktreeIds) {\n await removeWorktreeCleanup(projectRoot, wtId);\n }\n }\n\n // --delete also removes worktree entries from manifest\n if (options.delete) {\n await updateManifest(projectRoot, (m) => {\n for (const wtId of activeWorktreeIds) {\n delete m.worktrees[wtId];\n }\n return m;\n });\n }\n\n if (options.json) {\n output({\n success: true,\n killed: killedIds,\n removed: shouldRemove ? activeWorktreeIds : [],\n deleted: options.delete ? activeWorktreeIds : [],\n }, true);\n } else {\n success(`Killed ${killedIds.length} agent(s) across ${activeWorktreeIds.length} worktree(s)`);\n if (options.delete) {\n success(`Deleted ${activeWorktreeIds.length} worktree(s)`);\n } else if (options.remove) {\n success(`Removed ${activeWorktreeIds.length} worktree(s)`);\n }\n }\n}\n\nasync function removeWorktreeCleanup(projectRoot: string, wtId: string): Promise<void> {\n const manifest = await readManifest(projectRoot);\n const wt = resolveWorktree(manifest, wtId);\n if (!wt) return;\n await cleanupWorktree(projectRoot, wt);\n}\n","import { readManifest, resolveWorktree, findAgent } from '../core/manifest.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { getPaneInfo } from '../core/tmux.js';\nimport { resumeAgent } from '../core/agent.js';\nimport * as tmux from '../core/tmux.js';\nimport { openTerminalWindow } from '../core/terminal.js';\nimport { PgError, NotInitializedError } from '../lib/errors.js';\nimport { info, success } from '../lib/output.js';\nimport type { AgentEntry } from '../types/manifest.js';\n\nexport async function attachCommand(target: string): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n // Try to resolve target as worktree ID, worktree name, or agent ID\n let tmuxTarget: string | undefined;\n const sessionName = manifest.sessionName;\n let agent: AgentEntry | undefined;\n let worktreeId: string | undefined;\n\n // Check worktree ID\n const wt = resolveWorktree(manifest, target);\n\n if (wt) {\n if (!wt.tmuxWindow) {\n throw new PgError('Worktree has no tmux window. Spawn agents first with: ppg spawn --worktree ' + wt.id + ' --prompt \"your task\"', 'NO_TMUX_WINDOW');\n }\n tmuxTarget = wt.tmuxWindow;\n } else {\n // Check agent ID\n const found = findAgent(manifest, target);\n if (found) {\n agent = found.agent;\n worktreeId = found.worktree.id;\n tmuxTarget = found.agent.tmuxTarget;\n }\n }\n\n if (!tmuxTarget) {\n throw new PgError(`Could not resolve target: ${target}. Try a worktree ID, name, or agent ID.`, 'TARGET_NOT_FOUND');\n }\n\n // Check if the pane is dead and agent has a sessionId — auto-resume\n if (agent?.sessionId && worktreeId) {\n const paneInfo = await getPaneInfo(tmuxTarget);\n if (!paneInfo || paneInfo.isDead) {\n info(`Pane is dead. Resuming session ${agent.sessionId}...`);\n const resumeWt = manifest.worktrees[worktreeId];\n const cwd = resumeWt?.path ?? projectRoot;\n const windowName = resumeWt?.name ?? agent.name ?? target;\n\n tmuxTarget = await resumeAgent({\n agent,\n worktreeId,\n sessionName,\n cwd,\n windowName,\n projectRoot,\n });\n success(`Resumed agent ${agent.id} in ${tmuxTarget}`);\n }\n }\n\n const insideTmux = await tmux.isInsideTmux();\n\n if (insideTmux) {\n // Agent targets are now window targets (e.g. \"ppg:3\"), so use selectWindow for both\n await tmux.selectWindow(tmuxTarget);\n info(`Switched to ${tmuxTarget}`);\n } else {\n // Open a new Terminal.app window attached to the target\n const title = wt ? wt.name : target;\n info(`Opening Terminal window for ${title}`);\n await openTerminalWindow(sessionName, tmuxTarget, title);\n }\n}\n","import { readManifest, findAgent } from '../core/manifest.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport * as tmux from '../core/tmux.js';\nimport { PgError, NotInitializedError, AgentNotFoundError } from '../lib/errors.js';\nimport { output, outputError } from '../lib/output.js';\n\nexport interface LogsOptions {\n lines?: number;\n follow?: boolean;\n full?: boolean;\n json?: boolean;\n}\n\nexport async function logsCommand(agentId: string, options: LogsOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const found = findAgent(manifest, agentId);\n if (!found) throw new AgentNotFoundError(agentId);\n\n const { agent } = found;\n const lines = options.full ? undefined : (options.lines ?? 100);\n\n if (options.follow) {\n // Poll mode\n let lastOutput = '';\n const interval = setInterval(async () => {\n try {\n const content = await tmux.capturePane(agent.tmuxTarget, lines);\n if (content !== lastOutput) {\n // Find new lines\n if (lastOutput) {\n const oldLines = lastOutput.split('\\n');\n const newLines = content.split('\\n');\n // Output only lines that are new\n const diff = newLines.slice(oldLines.length);\n if (diff.length > 0) {\n process.stdout.write(diff.join('\\n') + '\\n');\n }\n } else {\n process.stdout.write(content + '\\n');\n }\n lastOutput = content;\n }\n } catch {\n clearInterval(interval);\n outputError(new Error('Pane no longer available'), options.json ?? false);\n process.exit(1);\n }\n }, 1000);\n\n process.on('SIGINT', () => {\n clearInterval(interval);\n process.exit(0);\n });\n } else {\n // One-shot capture\n try {\n const content = await tmux.capturePane(agent.tmuxTarget, lines);\n if (options.json) {\n output({\n agentId: agent.id,\n status: agent.status,\n tmuxTarget: agent.tmuxTarget,\n output: content,\n }, true);\n } else {\n console.log(content);\n }\n } catch {\n throw new PgError(`Could not capture pane for agent ${agentId}. Pane may no longer exist.`, 'PANE_NOT_FOUND');\n }\n }\n}\n","import fs from 'node:fs/promises';\nimport { readManifest, resolveWorktree, updateManifest } from '../core/manifest.js';\nimport { refreshAllAgentStatuses } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport * as tmux from '../core/tmux.js';\nimport { NotInitializedError, WorktreeNotFoundError } from '../lib/errors.js';\nimport { output, success, warn } from '../lib/output.js';\nimport type { AgentEntry, WorktreeEntry } from '../types/manifest.js';\n\nexport interface AggregateOptions {\n all?: boolean;\n output?: string;\n json?: boolean;\n}\n\nexport async function aggregateCommand(\n worktreeId?: string,\n options?: AggregateOptions,\n): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await updateManifest(projectRoot, async (m) => {\n return refreshAllAgentStatuses(m, projectRoot);\n });\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n let worktrees: WorktreeEntry[];\n\n if (options?.all) {\n worktrees = Object.values(manifest.worktrees);\n } else if (worktreeId) {\n const wt = resolveWorktree(manifest, worktreeId);\n if (!wt) throw new WorktreeNotFoundError(worktreeId);\n worktrees = [wt];\n } else {\n // Default: all worktrees with completed agents\n worktrees = Object.values(manifest.worktrees).filter((wt) =>\n Object.values(wt.agents).some((a) => a.status === 'completed'),\n );\n }\n\n const results: AggregatedResult[] = [];\n\n for (const wt of worktrees) {\n for (const agent of Object.values(wt.agents)) {\n if (agent.status !== 'completed' && agent.status !== 'failed') continue;\n\n const result = await collectAgentResult(agent, projectRoot);\n results.push({\n agentId: agent.id,\n worktreeId: wt.id,\n worktreeName: wt.name,\n branch: wt.branch,\n status: agent.status,\n content: result,\n });\n }\n }\n\n if (results.length === 0) {\n if (options?.json) {\n output({ results: [] }, true);\n } else {\n console.log('No completed agent results to aggregate.');\n }\n return;\n }\n\n if (options?.json) {\n output({ results }, true);\n return;\n }\n\n // Build combined document\n const combined = results.map((r) => {\n return [\n `# Agent: ${r.agentId}`,\n `**Worktree:** ${r.worktreeName} (${r.worktreeId})`,\n `**Branch:** ${r.branch}`,\n `**Status:** ${r.status}`,\n '',\n r.content,\n '',\n '---',\n '',\n ].join('\\n');\n }).join('\\n');\n\n if (options?.output) {\n await fs.writeFile(options.output, combined, 'utf-8');\n success(`Wrote ${results.length} result(s) to ${options.output}`);\n } else {\n console.log(combined);\n }\n}\n\ninterface AggregatedResult {\n agentId: string;\n worktreeId: string;\n worktreeName: string;\n branch: string;\n status: string;\n content: string;\n}\n\nasync function collectAgentResult(\n agent: AgentEntry,\n projectRoot: string,\n): Promise<string> {\n // Try reading result file first\n try {\n const content = await fs.readFile(agent.resultFile, 'utf-8');\n return content;\n } catch {\n // No result file\n }\n\n // Fallback: capture pane content\n try {\n const paneContent = await tmux.capturePane(agent.tmuxTarget, 500);\n return `*[No result file — pane capture fallback]*\\n\\n\\`\\`\\`\\n${paneContent}\\n\\`\\`\\``;\n } catch {\n return '*[No result file and pane not available]*';\n }\n}\n","import { execa } from 'execa';\nimport { readManifest, updateManifest, resolveWorktree } from '../core/manifest.js';\nimport { refreshAllAgentStatuses } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { cleanupWorktree } from '../core/cleanup.js';\nimport { PgError, NotInitializedError, WorktreeNotFoundError, MergeFailedError } from '../lib/errors.js';\nimport { output, success, info, warn } from '../lib/output.js';\n\nexport interface MergeOptions {\n strategy?: 'squash' | 'no-ff';\n cleanup?: boolean;\n dryRun?: boolean;\n force?: boolean;\n json?: boolean;\n}\n\nexport async function mergeCommand(worktreeId: string, options: MergeOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await updateManifest(projectRoot, async (m) => {\n return refreshAllAgentStatuses(m, projectRoot);\n });\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const wt = resolveWorktree(manifest, worktreeId);\n\n if (!wt) throw new WorktreeNotFoundError(worktreeId);\n\n // Check all agents completed\n const agents = Object.values(wt.agents);\n const incomplete = agents.filter((a) => !['completed', 'failed', 'killed'].includes(a.status));\n\n if (incomplete.length > 0 && !options.force) {\n const ids = incomplete.map((a) => a.id).join(', ');\n throw new PgError(\n `${incomplete.length} agent(s) still running: ${ids}. Use --force to merge anyway.`,\n 'AGENTS_RUNNING',\n );\n }\n\n if (options.dryRun) {\n info('Dry run — no changes will be made');\n info(`Would merge branch ${wt.branch} into ${wt.baseBranch} using ${options.strategy ?? 'squash'} strategy`);\n if (options.cleanup !== false) {\n info(`Would remove worktree ${wt.id} and delete branch ${wt.branch}`);\n }\n return;\n }\n\n // Set worktree status to merging\n await updateManifest(projectRoot, (m) => {\n if (m.worktrees[wt.id]) {\n m.worktrees[wt.id].status = 'merging';\n }\n return m;\n });\n\n const strategy = options.strategy ?? 'squash';\n\n try {\n info(`Merging ${wt.branch} into ${wt.baseBranch} (${strategy})`);\n\n if (strategy === 'squash') {\n await execa('git', ['merge', '--squash', wt.branch], { cwd: projectRoot });\n await execa('git', ['commit', '-m', `ppg: merge ${wt.name} (${wt.branch})`], {\n cwd: projectRoot,\n });\n } else {\n await execa('git', ['merge', '--no-ff', wt.branch, '-m', `ppg: merge ${wt.name} (${wt.branch})`], {\n cwd: projectRoot,\n });\n }\n\n success(`Merged ${wt.branch} into ${wt.baseBranch}`);\n } catch (err) {\n await updateManifest(projectRoot, (m) => {\n if (m.worktrees[wt.id]) {\n m.worktrees[wt.id].status = 'failed';\n }\n return m;\n });\n throw new MergeFailedError(\n `Merge failed: ${err instanceof Error ? err.message : err}`,\n );\n }\n\n // Mark as merged\n await updateManifest(projectRoot, (m) => {\n if (m.worktrees[wt.id]) {\n m.worktrees[wt.id].status = 'merged';\n m.worktrees[wt.id].mergedAt = new Date().toISOString();\n }\n return m;\n });\n\n // Cleanup\n if (options.cleanup !== false) {\n info('Cleaning up...');\n await cleanupWorktree(projectRoot, wt);\n success(`Cleaned up worktree ${wt.id}`);\n }\n\n if (options.json) {\n output({\n success: true,\n worktreeId: wt.id,\n branch: wt.branch,\n baseBranch: wt.baseBranch,\n strategy,\n cleaned: options.cleanup !== false,\n }, true);\n }\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { loadConfig } from '../core/config.js';\nimport { listTemplates } from '../core/template.js';\nimport { templatesDir } from '../lib/paths.js';\nimport { PgError } from '../lib/errors.js';\nimport { output, formatTable, type Column } from '../lib/output.js';\n\nexport interface ListOptions {\n json?: boolean;\n}\n\nexport async function listCommand(type: string, options: ListOptions): Promise<void> {\n if (type !== 'templates') {\n throw new PgError(`Unknown list type: ${type}. Available: templates`, 'INVALID_ARGS');\n }\n\n const projectRoot = await getRepoRoot();\n\n const templateNames = await listTemplates(projectRoot);\n\n if (templateNames.length === 0) {\n console.log('No templates found in .pg/templates/');\n return;\n }\n\n const templates = await Promise.all(\n templateNames.map(async (name) => {\n const filePath = path.join(templatesDir(projectRoot), `${name}.md`);\n const content = await fs.readFile(filePath, 'utf-8');\n const firstLine = content.split('\\n').find((l) => l.trim().length > 0) ?? '';\n const description = firstLine.replace(/^#+\\s*/, '').trim();\n\n // Extract template variables\n const vars = [...content.matchAll(/\\{\\{(\\w+)\\}\\}/g)].map((m) => m[1]);\n const uniqueVars = [...new Set(vars)];\n\n return { name, description, variables: uniqueVars };\n }),\n );\n\n if (options.json) {\n output({ templates }, true);\n return;\n }\n\n const columns: Column[] = [\n { header: 'Name', key: 'name', width: 20 },\n { header: 'Description', key: 'description', width: 40 },\n {\n header: 'Variables',\n key: 'variables',\n width: 30,\n format: (v) => (v as string[]).join(', '),\n },\n ];\n\n console.log(formatTable(templates, columns));\n}\n","import fs from 'node:fs/promises';\nimport { readManifest, updateManifest, findAgent } from '../core/manifest.js';\nimport { loadConfig, resolveAgentConfig } from '../core/config.js';\nimport { spawnAgent, killAgent } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport * as tmux from '../core/tmux.js';\nimport { openTerminalWindow } from '../core/terminal.js';\nimport { agentId as genAgentId, sessionId as genSessionId } from '../lib/id.js';\nimport { promptFile, resultFile } from '../lib/paths.js';\nimport { PgError, NotInitializedError, AgentNotFoundError } from '../lib/errors.js';\nimport { output, success, info } from '../lib/output.js';\nimport { renderTemplate, type TemplateContext } from '../core/template.js';\n\nexport interface RestartOptions {\n prompt?: string;\n agent?: string;\n open?: boolean;\n json?: boolean;\n}\n\nexport async function restartCommand(agentRef: string, options: RestartOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n const config = await loadConfig(projectRoot);\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const found = findAgent(manifest, agentRef);\n if (!found) throw new AgentNotFoundError(agentRef);\n\n const { worktree: wt, agent: oldAgent } = found;\n\n // Kill old agent if still running\n if (['running', 'spawning', 'waiting'].includes(oldAgent.status)) {\n info(`Killing existing agent ${oldAgent.id}`);\n await killAgent(oldAgent);\n }\n\n // Read original prompt from prompt file, or use override\n let promptText: string;\n if (options.prompt) {\n promptText = options.prompt;\n } else {\n const pFile = promptFile(projectRoot, oldAgent.id);\n try {\n promptText = await fs.readFile(pFile, 'utf-8');\n } catch {\n throw new PgError(\n `Could not read original prompt for agent ${oldAgent.id}. Use --prompt to provide one.`,\n 'PROMPT_NOT_FOUND',\n );\n }\n }\n\n // Resolve agent config\n const agentConfig = resolveAgentConfig(config, options.agent ?? oldAgent.agentType);\n\n // Ensure tmux session\n await tmux.ensureSession(manifest.sessionName);\n\n // Create new tmux window in same worktree\n const newAgentId = genAgentId();\n const windowTarget = await tmux.createWindow(manifest.sessionName, `${wt.name}-restart`, wt.path);\n\n // Render template vars\n const ctx: TemplateContext = {\n WORKTREE_PATH: wt.path,\n BRANCH: wt.branch,\n AGENT_ID: newAgentId,\n RESULT_FILE: resultFile(projectRoot, newAgentId),\n PROJECT_ROOT: projectRoot,\n TASK_NAME: wt.name,\n PROMPT: promptText,\n };\n const renderedPrompt = renderTemplate(promptText, ctx);\n\n const newSessionId = genSessionId();\n const agentEntry = await spawnAgent({\n agentId: newAgentId,\n agentConfig,\n prompt: renderedPrompt,\n worktreePath: wt.path,\n tmuxTarget: windowTarget,\n projectRoot,\n branch: wt.branch,\n sessionId: newSessionId,\n });\n\n // Update manifest: mark old agent as killed, add new agent\n await updateManifest(projectRoot, (m) => {\n const mWt = m.worktrees[wt.id];\n if (mWt) {\n const mOldAgent = mWt.agents[oldAgent.id];\n if (mOldAgent && !['completed', 'failed', 'killed', 'lost'].includes(mOldAgent.status)) {\n mOldAgent.status = 'killed';\n mOldAgent.completedAt = new Date().toISOString();\n }\n mWt.agents[newAgentId] = agentEntry;\n }\n return m;\n });\n\n // Fire-and-forget terminal open\n if (options.open !== false) {\n openTerminalWindow(manifest.sessionName, windowTarget, `${wt.name}-restart`).catch(() => {});\n }\n\n if (options.json) {\n output({\n success: true,\n oldAgentId: oldAgent.id,\n newAgent: {\n id: newAgentId,\n tmuxTarget: windowTarget,\n sessionId: newSessionId,\n worktreeId: wt.id,\n worktreeName: wt.name,\n branch: wt.branch,\n path: wt.path,\n },\n }, true);\n } else {\n success(`Restarted agent ${oldAgent.id} → ${newAgentId} in worktree ${wt.name}`);\n info(` New agent ${newAgentId} → ${windowTarget}`);\n }\n}\n","import { execa } from 'execa';\nimport { readManifest, resolveWorktree } from '../core/manifest.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { NotInitializedError, WorktreeNotFoundError } from '../lib/errors.js';\nimport { output } from '../lib/output.js';\n\nexport interface DiffOptions {\n stat?: boolean;\n nameOnly?: boolean;\n json?: boolean;\n}\n\nexport async function diffCommand(worktreeRef: string, options: DiffOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const wt = resolveWorktree(manifest, worktreeRef);\n\n if (!wt) throw new WorktreeNotFoundError(worktreeRef);\n\n const diffRange = `${wt.baseBranch}...${wt.branch}`;\n\n if (options.json) {\n // Machine-readable: numstat for file-level changes\n const result = await execa('git', ['diff', '--numstat', diffRange], { cwd: projectRoot });\n const files = result.stdout.trim().split('\\n').filter(Boolean).map((line) => {\n const [added, removed, file] = line.split('\\t');\n return {\n file,\n added: added === '-' ? 0 : parseInt(added, 10),\n removed: removed === '-' ? 0 : parseInt(removed, 10),\n };\n });\n output({\n worktreeId: wt.id,\n branch: wt.branch,\n baseBranch: wt.baseBranch,\n files,\n }, true);\n } else if (options.stat) {\n const result = await execa('git', ['diff', '--stat', diffRange], { cwd: projectRoot });\n console.log(result.stdout);\n } else if (options.nameOnly) {\n const result = await execa('git', ['diff', '--name-only', diffRange], { cwd: projectRoot });\n console.log(result.stdout);\n } else {\n const result = await execa('git', ['diff', diffRange], { cwd: projectRoot });\n console.log(result.stdout);\n }\n}\n","import { readManifest, updateManifest } from '../core/manifest.js';\nimport { getRepoRoot, pruneWorktrees } from '../core/worktree.js';\nimport { cleanupWorktree } from '../core/cleanup.js';\nimport { NotInitializedError } from '../lib/errors.js';\nimport { output, success, info, warn } from '../lib/output.js';\nimport type { WorktreeEntry } from '../types/manifest.js';\n\nexport interface CleanOptions {\n all?: boolean;\n dryRun?: boolean;\n prune?: boolean;\n json?: boolean;\n}\n\nexport async function cleanCommand(options: CleanOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n // Find worktrees in terminal states\n const terminalStatuses = ['merged', 'cleaned'];\n if (options.all) {\n terminalStatuses.push('failed');\n }\n\n const toClean = Object.values(manifest.worktrees)\n .filter((wt) => terminalStatuses.includes(wt.status));\n\n // Also find worktrees already marked 'cleaned' that still have manifest entries\n const toRemoveFromManifest = Object.values(manifest.worktrees)\n .filter((wt) => wt.status === 'cleaned');\n\n if (options.dryRun) {\n if (toClean.length === 0 && toRemoveFromManifest.length === 0) {\n info('Nothing to clean');\n } else {\n info('Dry run — would clean:');\n for (const wt of toClean) {\n if (wt.status !== 'cleaned') {\n info(` ${wt.id} (${wt.name}) — ${wt.status}`);\n }\n }\n for (const wt of toRemoveFromManifest) {\n info(` ${wt.id} (${wt.name}) — remove from manifest`);\n }\n }\n\n if (options.json) {\n output({\n dryRun: true,\n wouldClean: toClean.filter((wt) => wt.status !== 'cleaned').map((wt) => ({\n id: wt.id,\n name: wt.name,\n status: wt.status,\n })),\n wouldRemoveFromManifest: toRemoveFromManifest.map((wt) => ({\n id: wt.id,\n name: wt.name,\n })),\n }, true);\n }\n return;\n }\n\n // Clean worktrees that need cleanup (merged, failed but not yet cleaned)\n const cleaned: string[] = [];\n const removed: string[] = [];\n\n for (const wt of toClean) {\n if (wt.status !== 'cleaned') {\n info(`Cleaning worktree ${wt.id} (${wt.name})`);\n await cleanupWorktree(projectRoot, wt);\n cleaned.push(wt.id);\n }\n }\n\n // Remove cleaned entries from manifest\n const allCleanedIds = [...new Set([\n ...toRemoveFromManifest.map((wt) => wt.id),\n ...cleaned,\n ])];\n\n if (allCleanedIds.length > 0) {\n await updateManifest(projectRoot, (m) => {\n for (const id of allCleanedIds) {\n delete m.worktrees[id];\n }\n return m;\n });\n removed.push(...allCleanedIds);\n }\n\n // Git worktree prune\n if (options.prune) {\n info('Pruning stale git worktrees');\n await pruneWorktrees(projectRoot);\n }\n\n if (options.json) {\n output({\n success: true,\n cleaned,\n removedFromManifest: removed,\n pruned: options.prune ?? false,\n }, true);\n } else {\n if (cleaned.length > 0) {\n success(`Cleaned ${cleaned.length} worktree(s)`);\n }\n if (removed.length > 0) {\n success(`Removed ${removed.length} worktree(s) from manifest`);\n }\n if (cleaned.length === 0 && removed.length === 0) {\n info('Nothing to clean');\n }\n if (options.prune) {\n success('Pruned stale git worktrees');\n }\n }\n}\n","import { readManifest, findAgent } from '../core/manifest.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport * as tmux from '../core/tmux.js';\nimport { NotInitializedError, AgentNotFoundError } from '../lib/errors.js';\nimport { output, success } from '../lib/output.js';\n\nexport interface SendOptions {\n keys?: boolean;\n enter?: boolean;\n json?: boolean;\n}\n\nexport async function sendCommand(agentId: string, text: string, options: SendOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const found = findAgent(manifest, agentId);\n if (!found) throw new AgentNotFoundError(agentId);\n\n const { agent } = found;\n\n if (options.keys) {\n // Raw tmux key names (e.g., \"C-c\", \"Enter\", \"Escape\")\n await tmux.sendRawKeys(agent.tmuxTarget, text);\n } else if (options.enter === false) {\n // Send literal text without Enter\n await tmux.sendLiteral(agent.tmuxTarget, text);\n } else {\n // Default: send literal text + Enter\n await tmux.sendKeys(agent.tmuxTarget, text);\n }\n\n if (options.json) {\n output({\n success: true,\n agentId: agent.id,\n tmuxTarget: agent.tmuxTarget,\n text,\n }, true);\n } else {\n success(`Sent to agent ${agent.id}`);\n }\n}\n","import { updateManifest, resolveWorktree } from '../core/manifest.js';\nimport { refreshAllAgentStatuses } from '../core/agent.js';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { PgError, NotInitializedError, WorktreeNotFoundError } from '../lib/errors.js';\nimport { output, info } from '../lib/output.js';\nimport type { AgentEntry, AgentStatus, Manifest } from '../types/manifest.js';\n\nexport interface WaitOptions {\n all?: boolean;\n timeout?: number;\n interval?: number;\n json?: boolean;\n}\n\nconst TERMINAL_STATUSES: AgentStatus[] = ['completed', 'failed', 'killed', 'lost'];\n\nexport async function waitCommand(worktreeRef: string | undefined, options: WaitOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n const interval = (options.interval ?? 5) * 1000;\n const timeout = options.timeout ? options.timeout * 1000 : undefined;\n const startTime = Date.now();\n\n if (!worktreeRef && !options.all) {\n throw new PgError('Specify a worktree ID or use --all', 'INVALID_ARGS');\n }\n\n if (!options.json) {\n info('Waiting for agents to complete...');\n }\n\n while (true) {\n // Check timeout\n if (timeout && (Date.now() - startTime) >= timeout) {\n const manifest = await refreshAndGet(projectRoot);\n const agents = collectAgents(manifest, worktreeRef, options.all);\n if (options.json) {\n output({\n timedOut: true,\n agents: agents.map(formatAgent),\n }, true);\n }\n throw new PgError('Timed out waiting for agents', 'WAIT_TIMEOUT', 2);\n }\n\n const manifest = await refreshAndGet(projectRoot);\n const agents = collectAgents(manifest, worktreeRef, options.all);\n const allTerminal = agents.every((a) => TERMINAL_STATUSES.includes(a.status));\n\n if (allTerminal) {\n const anyFailed = agents.some((a) => ['failed', 'lost'].includes(a.status));\n\n if (options.json) {\n output({\n timedOut: false,\n agents: agents.map(formatAgent),\n }, true);\n } else {\n for (const a of agents) {\n info(` ${a.id}: ${a.status}`);\n }\n }\n\n if (anyFailed) {\n throw new PgError('Some agents failed', 'AGENTS_FAILED', 1);\n }\n return;\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n}\n\nasync function refreshAndGet(projectRoot: string): Promise<Manifest> {\n try {\n return await updateManifest(projectRoot, async (m) => {\n return refreshAllAgentStatuses(m, projectRoot);\n });\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n}\n\nfunction collectAgents(\n manifest: Manifest,\n worktreeRef: string | undefined,\n all?: boolean,\n): AgentEntry[] {\n if (all) {\n const agents: AgentEntry[] = [];\n for (const wt of Object.values(manifest.worktrees)) {\n agents.push(...Object.values(wt.agents));\n }\n return agents;\n }\n\n const wt = resolveWorktree(manifest, worktreeRef!);\n if (!wt) throw new WorktreeNotFoundError(worktreeRef!);\n return Object.values(wt.agents);\n}\n\nfunction formatAgent(a: AgentEntry) {\n return {\n id: a.id,\n status: a.status,\n agentType: a.agentType,\n exitCode: a.exitCode,\n startedAt: a.startedAt,\n completedAt: a.completedAt,\n };\n}\n","import { loadConfig } from '../core/config.js';\nimport { readManifest, updateManifest } from '../core/manifest.js';\nimport { getRepoRoot, getCurrentBranch, createWorktree } from '../core/worktree.js';\nimport { setupWorktreeEnv } from '../core/env.js';\nimport { worktreeId as genWorktreeId } from '../lib/id.js';\nimport { NotInitializedError } from '../lib/errors.js';\nimport { output, success, info } from '../lib/output.js';\nimport type { WorktreeEntry } from '../types/manifest.js';\n\nexport interface WorktreeCreateOptions {\n name?: string;\n base?: string;\n json?: boolean;\n}\n\nexport async function worktreeCreateCommand(options: WorktreeCreateOptions): Promise<void> {\n const projectRoot = await getRepoRoot();\n const config = await loadConfig(projectRoot);\n\n // Verify initialized\n try {\n await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const baseBranch = options.base ?? await getCurrentBranch(projectRoot);\n const wtId = genWorktreeId();\n const name = options.name ?? wtId;\n const branchName = `ppg/${name}`;\n\n // Create git worktree\n info(`Creating worktree ${wtId} on branch ${branchName}`);\n const wtPath = await createWorktree(projectRoot, wtId, {\n branch: branchName,\n base: baseBranch,\n });\n\n // Setup env\n await setupWorktreeEnv(projectRoot, wtPath, config);\n\n // Register in manifest with empty tmuxWindow and no agents\n const worktreeEntry: WorktreeEntry = {\n id: wtId,\n name,\n path: wtPath,\n branch: branchName,\n baseBranch,\n status: 'active',\n tmuxWindow: '',\n agents: {},\n createdAt: new Date().toISOString(),\n };\n\n await updateManifest(projectRoot, (m) => {\n m.worktrees[wtId] = worktreeEntry;\n return m;\n });\n\n if (options.json) {\n output({\n success: true,\n worktree: {\n id: wtId,\n name,\n branch: branchName,\n baseBranch,\n path: wtPath,\n },\n }, true);\n } else {\n success(`Created worktree ${wtId} (${name}) on branch ${branchName}`);\n info(`Path: ${wtPath}`);\n info(`Spawn agents: ppg spawn --worktree ${wtId} --prompt \"your task\"`);\n }\n}\n","import { access } from 'node:fs/promises';\nimport path from 'node:path';\nimport { execa } from 'execa';\nimport { getRepoRoot } from '../core/worktree.js';\nimport { readManifest } from '../core/manifest.js';\nimport { manifestPath } from '../lib/paths.js';\nimport { NotInitializedError, PgError } from '../lib/errors.js';\nimport { info } from '../lib/output.js';\n\nexport async function findDashboardBinary(projectRoot: string): Promise<string | null> {\n const localBuild = path.join(\n projectRoot,\n 'PPG CLI',\n 'build',\n 'Build',\n 'Products',\n 'Release',\n 'PPG CLI.app',\n 'Contents',\n 'MacOS',\n 'PPG CLI',\n );\n\n try {\n await access(localBuild);\n return localBuild;\n } catch {\n // not found, fall through\n }\n\n const appsBuild = '/Applications/PPG CLI.app/Contents/MacOS/PPG CLI';\n try {\n await access(appsBuild);\n return appsBuild;\n } catch {\n // not found, fall through\n }\n\n try {\n const result = await execa('mdfind', [\n 'kMDItemCFBundleIdentifier == \"com.2wit.PPG-CLI\"',\n ]);\n const appPath = result.stdout.trim().split('\\n')[0];\n if (appPath) {\n const binaryPath = path.join(appPath, 'Contents', 'MacOS', 'PPG CLI');\n try {\n await access(binaryPath);\n return binaryPath;\n } catch {\n // found app but no binary\n }\n }\n } catch {\n // mdfind failed\n }\n\n return null;\n}\n\nexport async function uiCommand(): Promise<void> {\n const projectRoot = await getRepoRoot();\n let manifest;\n try {\n manifest = await readManifest(projectRoot);\n } catch {\n throw new NotInitializedError(projectRoot);\n }\n\n const binaryPath = await findDashboardBinary(projectRoot);\n if (!binaryPath) {\n throw new PgError(\n `Dashboard app not found. Install it with:\\n ppg install-dashboard\\n\\nOr build from source:\\n cd \"PPG CLI\" && xcodebuild -scheme \"PPG CLI\" -configuration Release -derivedDataPath build build`,\n 'DASHBOARD_NOT_FOUND',\n );\n }\n\n const mPath = manifestPath(projectRoot);\n const proc = execa(binaryPath, [\n '--manifest-path', mPath,\n '--session-name', manifest.sessionName,\n '--project-root', projectRoot,\n ], {\n detached: true,\n stdio: 'ignore',\n });\n proc.unref();\n\n info(`Dashboard launched for ${manifest.sessionName}`);\n}\n","import { createWriteStream } from 'node:fs';\nimport { mkdir, cp, rm, readFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { Readable } from 'node:stream';\nimport { execa } from 'execa';\nimport { output, info, success } from '../lib/output.js';\nimport { PgError } from '../lib/errors.js';\n\nconst REPO = '2witstudios/ppg-cli';\nconst ASSET_NAME = 'PPG-CLI-Dashboard.dmg';\nconst APP_NAME = 'PPG CLI.app';\n\nasync function getVersion(): Promise<string> {\n // Find package.json relative to this module — works in both dev (src/) and built (dist/)\n const pkgPath = new URL('../../package.json', import.meta.url);\n const raw = await readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version: string };\n return pkg.version;\n}\n\nexport async function installDashboardCommand(options: {\n dir: string;\n json: boolean;\n}): Promise<void> {\n const { dir, json } = options;\n\n try {\n const version = await getVersion();\n const tag = `v${version}`;\n const url = `https://github.com/${REPO}/releases/download/${tag}/${ASSET_NAME}`;\n\n if (!json) info(`Downloading dashboard ${tag} from GitHub Releases…`);\n\n const res = await fetch(url);\n if (!res.ok) {\n if (res.status === 404) {\n throw new PgError(\n `Dashboard release not found for ${tag}. The dashboard may not be available for this version yet.\\nCheck: https://github.com/${REPO}/releases/tag/${tag}`,\n 'DASHBOARD_NOT_FOUND',\n );\n }\n throw new PgError(\n `Failed to download dashboard: HTTP ${res.status} ${res.statusText}`,\n 'DOWNLOAD_FAILED',\n );\n }\n\n // Download to temp directory\n const tmp = path.join(tmpdir(), `ppg-dashboard-${Date.now()}`);\n await mkdir(tmp, { recursive: true });\n const dmgPath = path.join(tmp, ASSET_NAME);\n\n const body = res.body;\n if (!body) throw new PgError('Empty response body', 'DOWNLOAD_FAILED');\n await pipeline(\n Readable.fromWeb(body as import('stream/web').ReadableStream),\n createWriteStream(dmgPath),\n );\n\n if (!json) info('Mounting…');\n\n // Mount DMG\n const mountResult = await execa('hdiutil', ['attach', dmgPath, '-nobrowse', '-quiet']);\n const mountLine = mountResult.stdout.trim().split('\\n').pop() ?? '';\n const mountPoint = mountLine.split('\\t').pop()?.trim();\n\n if (!mountPoint) {\n throw new PgError('Failed to mount DMG — could not determine mount point', 'INSTALL_FAILED');\n }\n\n try {\n const srcApp = path.join(mountPoint, APP_NAME);\n const destApp = path.join(dir, APP_NAME);\n\n if (!json) info('Installing…');\n\n // Remove existing installation if present\n await rm(destApp, { recursive: true, force: true });\n // Copy .app from mounted volume\n await cp(srcApp, destApp, { recursive: true });\n\n // Remove quarantine attribute\n try {\n await execa('xattr', ['-dr', 'com.apple.quarantine', destApp]);\n } catch {\n // Quarantine attribute may not exist — that's fine\n }\n\n if (json) {\n output({ success: true, version, path: destApp }, true);\n } else {\n success(`Dashboard ${tag} installed to ${destApp}`);\n }\n } finally {\n // Always unmount\n await execa('hdiutil', ['detach', mountPoint, '-quiet']).catch(() => {});\n }\n\n // Clean up temp\n await rm(tmp, { recursive: true, force: true });\n } catch (err) {\n if (err instanceof PgError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new PgError(`Dashboard installation failed: ${message}`, 'INSTALL_FAILED');\n }\n}\n","import { Command } from 'commander';\nimport { PgError } from './lib/errors.js';\nimport { outputError } from './lib/output.js';\n\nconst program = new Command();\n\nprogram\n .name('ppg')\n .description('Pure Point Guard — local orchestration runtime for parallel CLI coding agents')\n .version('0.1.0');\n\nprogram\n .command('init')\n .description('Initialize Point Guard in the current git repository')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const { initCommand } = await import('./commands/init.js');\n await initCommand(options);\n });\n\nprogram\n .command('spawn')\n .description('Spawn a new worktree and agent(s), or add agents to an existing worktree')\n .option('-n, --name <name>', 'Name for the worktree/task')\n .option('-a, --agent <type>', 'Agent type to use (default: claude)')\n .option('-p, --prompt <text>', 'Prompt text for the agent')\n .option('-f, --prompt-file <path>', 'File containing the prompt')\n .option('-t, --template <name>', 'Template name from .pg/templates/')\n .option('--var <key=value...>', 'Template variables', collectVars, [])\n .option('-b, --base <branch>', 'Base branch for the worktree')\n .option('-w, --worktree <id>', 'Add agent to existing worktree')\n .option('-c, --count <n>', 'Number of agents to spawn', (v: string) => Number(v), 1)\n .option('--split', 'Put all agents in one window as split panes')\n .option('--no-open', 'Do not open a Terminal window for the spawned agents')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const { spawnCommand } = await import('./commands/spawn.js');\n await spawnCommand(options);\n });\n\nprogram\n .command('status')\n .description('Show status of worktrees and agents')\n .argument('[worktree]', 'Filter by worktree ID or name')\n .option('--json', 'Output as JSON')\n .option('-w, --watch', 'Watch for status changes')\n .action(async (worktree, options) => {\n const { statusCommand } = await import('./commands/status.js');\n await statusCommand(worktree, options);\n });\n\nprogram\n .command('kill')\n .description('Kill agents or worktrees')\n .option('-a, --agent <id>', 'Kill a specific agent')\n .option('-w, --worktree <id>', 'Kill all agents in a worktree')\n .option('--all', 'Kill all agents in all worktrees')\n .option('-r, --remove', 'Also remove the worktree after killing')\n .option('-d, --delete', 'Delete agent/worktree entry from manifest after killing')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const { killCommand } = await import('./commands/kill.js');\n await killCommand(options);\n });\n\nprogram\n .command('attach')\n .description('Attach to a worktree or agent tmux pane')\n .argument('<target>', 'Worktree ID, agent ID, or name')\n .action(async (target) => {\n const { attachCommand } = await import('./commands/attach.js');\n await attachCommand(target);\n });\n\nprogram\n .command('logs')\n .description('View agent pane output')\n .argument('<agent-id>', 'Agent ID')\n .option('-l, --lines <n>', 'Number of lines to show', (v: string) => Number(v), 100)\n .option('-f, --follow', 'Follow output (poll every 1s)')\n .option('--full', 'Show full pane history')\n .option('--json', 'Output as JSON')\n .action(async (agentId, options) => {\n const { logsCommand } = await import('./commands/logs.js');\n await logsCommand(agentId, options);\n });\n\nprogram\n .command('aggregate')\n .description('Aggregate results from completed agents')\n .argument('[worktree-id]', 'Worktree ID to aggregate results from')\n .option('--all', 'Aggregate from all worktrees')\n .option('-o, --output <file>', 'Write output to file')\n .option('--json', 'Output as JSON')\n .action(async (worktreeId, options) => {\n const { aggregateCommand } = await import('./commands/aggregate.js');\n await aggregateCommand(worktreeId, options);\n });\n\nprogram\n .command('merge')\n .description('Merge a worktree branch back into base')\n .argument('<worktree-id>', 'Worktree ID to merge')\n .option('-s, --strategy <strategy>', 'Merge strategy: squash or no-ff', 'squash')\n .option('--no-cleanup', 'Do not remove worktree after merge')\n .option('--dry-run', 'Show what would be done without doing it')\n .option('--force', 'Merge even if agents are not completed')\n .option('--json', 'Output as JSON')\n .action(async (worktreeId, options) => {\n const { mergeCommand } = await import('./commands/merge.js');\n await mergeCommand(worktreeId, options);\n });\n\nprogram\n .command('list')\n .description('List available templates')\n .argument('<type>', 'What to list: templates')\n .option('--json', 'Output as JSON')\n .action(async (type, options) => {\n const { listCommand } = await import('./commands/list.js');\n await listCommand(type, options);\n });\n\nprogram\n .command('restart')\n .description('Restart a failed/killed agent in the same worktree')\n .argument('<agent-id>', 'Agent ID to restart')\n .option('-p, --prompt <text>', 'Override the original prompt')\n .option('-a, --agent <type>', 'Override the agent type')\n .option('--no-open', 'Do not open a Terminal window')\n .option('--json', 'Output as JSON')\n .action(async (agentId, options) => {\n const { restartCommand } = await import('./commands/restart.js');\n await restartCommand(agentId, options);\n });\n\nprogram\n .command('diff')\n .description('Show changes made in a worktree branch')\n .argument('<worktree-id>', 'Worktree ID or name')\n .option('--stat', 'Show diffstat summary')\n .option('--name-only', 'Show only changed file names')\n .option('--json', 'Output as JSON')\n .action(async (worktreeId, options) => {\n const { diffCommand } = await import('./commands/diff.js');\n await diffCommand(worktreeId, options);\n });\n\nprogram\n .command('clean')\n .description('Remove worktrees in terminal states (merged/cleaned/failed)')\n .option('--all', 'Also clean failed worktrees')\n .option('--dry-run', 'Show what would be done without doing it')\n .option('--prune', 'Also run git worktree prune')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const { cleanCommand } = await import('./commands/clean.js');\n await cleanCommand(options);\n });\n\nprogram\n .command('send')\n .description('Send text to an agent\\'s tmux pane')\n .argument('<agent-id>', 'Agent ID')\n .argument('<text>', 'Text to send')\n .option('--keys', 'Send raw tmux key names (e.g., C-c, Enter)')\n .option('--no-enter', 'Do not append Enter after the text')\n .option('--json', 'Output as JSON')\n .action(async (agentId, text, options) => {\n const { sendCommand } = await import('./commands/send.js');\n await sendCommand(agentId, text, options);\n });\n\nprogram\n .command('wait')\n .description('Wait for agents to reach terminal state')\n .argument('[worktree-id]', 'Worktree ID or name')\n .option('--all', 'Wait for all agents across all worktrees')\n .option('--timeout <seconds>', 'Timeout in seconds', parseInt)\n .option('--interval <seconds>', 'Poll interval in seconds', parseInt)\n .option('--json', 'Output as JSON')\n .action(async (worktreeId, options) => {\n const { waitCommand } = await import('./commands/wait.js');\n await waitCommand(worktreeId, options);\n });\n\nconst worktreeCmd = program.command('worktree').description('Manage worktrees');\n\nworktreeCmd\n .command('create')\n .description('Create a standalone worktree without spawning agents')\n .option('-n, --name <name>', 'Name for the worktree')\n .option('-b, --base <branch>', 'Base branch for the worktree')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n const { worktreeCreateCommand } = await import('./commands/worktree.js');\n await worktreeCreateCommand(options);\n });\n\nprogram\n .command('ui')\n .alias('dashboard')\n .description('Open the native dashboard')\n .action(async () => {\n const { uiCommand } = await import('./commands/ui.js');\n await uiCommand();\n });\n\nprogram\n .command('install-dashboard')\n .description('Download and install the macOS dashboard app')\n .option('--dir <path>', 'Install directory', '/Applications')\n .option('--json', 'JSON output')\n .action(async (options) => {\n const { installDashboardCommand } = await import('./commands/install-dashboard.js');\n await installDashboardCommand(options);\n });\n\n// Error handling\nprogram.exitOverride();\n\nfunction collectVars(value: string, previous: string[]): string[] {\n return previous.concat([value]);\n}\n\nasync function main() {\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n if (err instanceof PgError) {\n outputError(err, program.opts().json ?? false);\n process.exit(err.exitCode);\n }\n if (err instanceof Error && 'code' in err) {\n const code = (err as { code: string }).code;\n if (code === 'commander.helpDisplayed' || code === 'commander.version') {\n process.exit(0);\n }\n }\n outputError(err, false);\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["agentId","fs","agentId","fs","path","execa","fs","path","fs","path","execa","info","fs","agentId","worktreePath","sessionId","worktreeId","execa","fs","m","agentId","worktreeId","agentId","fs","worktreeId","execa","worktreeId","fs","path","fs","execa","agentId","manifest","agents","wt","init_worktree","path","execa","path","execa","initCommand","spawnCommand","statusCommand","killCommand","attachCommand","agentId","logsCommand","worktreeId","aggregateCommand","mergeCommand","listCommand","restartCommand","diffCommand","cleanCommand","sendCommand","waitCommand","worktreeCreateCommand","uiCommand","installDashboardCommand"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pure-point-guard",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Pure Point Guard — local orchestration runtime for parallel CLI coding agents",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ppg": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skills",
|
|
12
|
+
".claude-plugin",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"dev": "tsx src/cli.ts",
|
|
18
|
+
"test": "vitest",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"author": "2witstudios",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/2witstudios/ppg-cli.git"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/2witstudios/ppg-cli#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/2witstudios/ppg-cli/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"cli",
|
|
33
|
+
"agent",
|
|
34
|
+
"ai",
|
|
35
|
+
"orchestration",
|
|
36
|
+
"tmux",
|
|
37
|
+
"worktree",
|
|
38
|
+
"parallel",
|
|
39
|
+
"claude",
|
|
40
|
+
"codex",
|
|
41
|
+
"coding-agent",
|
|
42
|
+
"git-worktree",
|
|
43
|
+
"automation",
|
|
44
|
+
"conductor"
|
|
45
|
+
],
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"commander": "^14.0.0",
|
|
49
|
+
"execa": "^9.5.2",
|
|
50
|
+
"nanoid": "^5.1.5",
|
|
51
|
+
"proper-lockfile": "^4.1.2",
|
|
52
|
+
"write-file-atomic": "^7.0.0",
|
|
53
|
+
"yaml": "^2.7.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.13.4",
|
|
57
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
58
|
+
"tsx": "^4.19.3",
|
|
59
|
+
"tsup": "^8.4.0",
|
|
60
|
+
"typescript": "^5.7.3",
|
|
61
|
+
"vitest": "^3.0.6"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=20"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ppg
|
|
3
|
+
description: Orchestrate parallel AI coding agents with ppg — review PRs with swarms, tackle GH issues in batch, or run any parallelizable task
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /ppg — Parallel Agent Conductor
|
|
8
|
+
|
|
9
|
+
Read and follow the conductor hub instructions in `~/.claude/skills/ppg-conductor/SKILL.md`.
|
|
10
|
+
Read the mode guide at `~/.claude/skills/ppg-conductor/references/modes.md`.
|
|
11
|
+
Read the conductor loop protocol at `~/.claude/skills/ppg-conductor/references/conductor.md`.
|
|
12
|
+
Read the CLI command reference at `~/.claude/skills/ppg-conductor/references/commands.md`.
|
|
13
|
+
|
|
14
|
+
Run pre-flight checks. Classify the user's request as swarm or batch mode. Decompose into concrete tasks with descriptive names and self-contained prompts. Spawn immediately — do not ask for confirmation. Drive the full conductor loop: spawn, poll, aggregate, (merge if batch), summarize.
|
|
15
|
+
|
|
16
|
+
If the user provides no arguments (just `/ppg`), ask what they'd like to parallelize.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ppg-conductor
|
|
3
|
+
description: Orchestration hub for driving ppg parallel agent workflows — swarm reviews and batch task execution
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ppg Conductor — Orchestration Hub
|
|
8
|
+
|
|
9
|
+
You are a conductor — a meta-agent that drives ppg programmatically to orchestrate parallel AI coding agents.
|
|
10
|
+
|
|
11
|
+
## Pre-flight Checks
|
|
12
|
+
|
|
13
|
+
Before doing anything, verify the environment:
|
|
14
|
+
|
|
15
|
+
1. **Git repo** — Run `git rev-parse --show-toplevel`. If it fails, tell the user this must be run inside a git repo.
|
|
16
|
+
2. **ppg installed** — Run `ppg --version`. If it fails, tell the user to install ppg (`npm i -g pure-point-guard`).
|
|
17
|
+
3. **tmux available** — Run `tmux -V`. If it fails, tell the user to install tmux (`brew install tmux`).
|
|
18
|
+
4. **ppg initialized** — Run `ppg status --json`. If it errors with `NOT_INITIALIZED`, run `ppg init --json` automatically and confirm it succeeded.
|
|
19
|
+
|
|
20
|
+
If any check fails (except init, which you auto-fix), stop and report the issue clearly.
|
|
21
|
+
|
|
22
|
+
## Mode Selection
|
|
23
|
+
|
|
24
|
+
Classify the user's request into one of two modes. Read `~/.claude/skills/ppg-conductor/references/modes.md` for the full guide.
|
|
25
|
+
|
|
26
|
+
| Mode | When | Example |
|
|
27
|
+
|------|------|---------|
|
|
28
|
+
| **Swarm** | Multiple agents, ONE worktree, same branch | "review this PR", "audit security", "analyze from 3 perspectives" |
|
|
29
|
+
| **Batch** | One worktree PER task, each becomes its own PR | "work on issues #12, #15", "fix all the TODO comments", "one PR per bug" |
|
|
30
|
+
|
|
31
|
+
If ambiguous, ask the user which mode fits better.
|
|
32
|
+
|
|
33
|
+
## Execution
|
|
34
|
+
|
|
35
|
+
After classifying the mode:
|
|
36
|
+
|
|
37
|
+
1. Read the conductor loop protocol at `~/.claude/skills/ppg-conductor/references/conductor.md`
|
|
38
|
+
2. Read the CLI command reference at `~/.claude/skills/ppg-conductor/references/commands.md`
|
|
39
|
+
3. Decompose the user's request into concrete tasks (names + prompts)
|
|
40
|
+
4. **Spawn immediately** — do not ask for confirmation. The user invoked `/ppg` which signals intent to run.
|
|
41
|
+
5. Drive the full spawn -> poll -> aggregate -> merge loop
|
|
42
|
+
|
|
43
|
+
## Core Principles
|
|
44
|
+
|
|
45
|
+
- **Always use `--json`** for machine-readable output from every ppg command
|
|
46
|
+
- **Always use `--no-open`** to suppress Terminal.app windows (you're driving programmatically, not watching panes)
|
|
47
|
+
- **Poll every 5 seconds** — `ppg status --json` in a loop until all agents reach a terminal state
|
|
48
|
+
- **One concern per worktree** — in batch mode, each task gets its own isolated worktree for clean merges
|
|
49
|
+
- **Surface results before merging** — always show the user what agents produced before offering to merge
|
|
50
|
+
- **Report failures clearly** — if an agent fails, show its ID, the error, and offer to re-spawn or skip
|
|
51
|
+
- **Never auto-resolve merge conflicts** — escalate to the user with the conflict details
|
|
52
|
+
- **Prompt quality matters** — each agent prompt must be self-contained with full context. The agent has no memory of this conversation.
|