sisyphi 0.1.4 → 0.1.5

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/dist/cli.js CHANGED
@@ -262,6 +262,9 @@ function registerSpawn(program2) {
262
262
  });
263
263
  }
264
264
 
265
+ // src/cli/commands/submit.ts
266
+ import { execSync as execSync3 } from "child_process";
267
+
265
268
  // src/cli/stdin.ts
266
269
  function readStdin() {
267
270
  if (process.stdin.isTTY) return Promise.resolve(null);
@@ -277,6 +280,23 @@ function readStdin() {
277
280
  }
278
281
 
279
282
  // src/cli/commands/submit.ts
283
+ function isInWorktree() {
284
+ try {
285
+ const gitDir = execSync3("git rev-parse --git-dir", { encoding: "utf-8" }).trim();
286
+ const commonDir = execSync3("git rev-parse --git-common-dir", { encoding: "utf-8" }).trim();
287
+ return gitDir !== commonDir;
288
+ } catch {
289
+ return false;
290
+ }
291
+ }
292
+ function getUncommittedChanges() {
293
+ try {
294
+ const status = execSync3("git status --porcelain", { encoding: "utf-8" }).trim();
295
+ return status || null;
296
+ } catch {
297
+ return null;
298
+ }
299
+ }
280
300
  function registerSubmit(program2) {
281
301
  program2.command("submit").description("Submit work report and exit (agent only)").option("--report <report>", "Work report (or pipe via stdin)").action(async (opts) => {
282
302
  assertTmux();
@@ -286,6 +306,17 @@ function registerSubmit(program2) {
286
306
  console.error("Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set");
287
307
  process.exit(1);
288
308
  }
309
+ if (isInWorktree()) {
310
+ const changes = getUncommittedChanges();
311
+ if (changes) {
312
+ console.error("Error: uncommitted changes in worktree. Your branch is merged automatically after submit \u2014 uncommitted work will be lost.");
313
+ console.error('\nCommit first:\n git add -A && git commit -m "description of changes"\n');
314
+ console.error("Or discard:\n git checkout -- .\n");
315
+ console.error("Uncommitted changes:");
316
+ console.error(changes);
317
+ process.exit(1);
318
+ }
319
+ }
289
320
  const report = opts.report ?? await readStdin();
290
321
  if (!report) {
291
322
  console.error("Error: provide --report or pipe content via stdin");
@@ -304,6 +335,7 @@ function registerSubmit(program2) {
304
335
  }
305
336
 
306
337
  // src/cli/commands/yield.ts
338
+ import { writeFileSync as writeFileSync2 } from "fs";
307
339
  function registerYield(program2) {
308
340
  program2.command("yield").description("Yield control back to daemon (orchestrator only)").option("--prompt <text>", "Instructions for the next orchestrator cycle (or pipe via stdin)").action(async (opts) => {
309
341
  assertTmux();
@@ -316,6 +348,7 @@ function registerYield(program2) {
316
348
  const request = { type: "yield", sessionId, agentId: "orchestrator", nextPrompt };
317
349
  const response = await sendRequest(request);
318
350
  if (response.ok) {
351
+ writeFileSync2(`/tmp/sisyphus-exit-${sessionId}`, "");
319
352
  console.log("Yielded. Waiting for agents to complete.");
320
353
  } else {
321
354
  console.error(`Error: ${response.error}`);
@@ -325,6 +358,7 @@ function registerYield(program2) {
325
358
  }
326
359
 
327
360
  // src/cli/commands/complete.ts
361
+ import { writeFileSync as writeFileSync3 } from "fs";
328
362
  function registerComplete(program2) {
329
363
  program2.command("complete").description("Mark session as completed (orchestrator only)").requiredOption("--report <report>", "Final completion report").action(async (opts) => {
330
364
  assertTmux();
@@ -336,6 +370,7 @@ function registerComplete(program2) {
336
370
  const request = { type: "complete", sessionId, report: opts.report };
337
371
  const response = await sendRequest(request);
338
372
  if (response.ok) {
373
+ writeFileSync3(`/tmp/sisyphus-exit-${sessionId}`, "");
339
374
  console.log("Session completed.");
340
375
  } else {
341
376
  console.error(`Error: ${response.error}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/cli/client.ts","../src/cli/install.ts","../src/cli/tmux.ts","../src/cli/commands/start.ts","../src/cli/commands/spawn.ts","../src/cli/stdin.ts","../src/cli/commands/submit.ts","../src/cli/commands/yield.ts","../src/cli/commands/complete.ts","../src/cli/commands/status.ts","../src/cli/commands/list.ts","../src/cli/commands/report.ts","../src/cli/commands/resume.ts","../src/cli/commands/kill.ts","../src/cli/commands/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerStart } from './commands/start.js';\nimport { registerSpawn } from './commands/spawn.js';\nimport { registerSubmit } from './commands/submit.js';\nimport { registerYield } from './commands/yield.js';\nimport { registerComplete } from './commands/complete.js';\nimport { registerStatus } from './commands/status.js';\nimport { registerList } from './commands/list.js';\nimport { registerReport } from './commands/report.js';\nimport { registerResume } from './commands/resume.js';\nimport { registerKill } from './commands/kill.js';\nimport { registerUninstall } from './commands/uninstall.js';\n\nconst program = new Command();\n\nprogram\n .name('sisyphus')\n .description('tmux-integrated orchestration daemon for Claude Code')\n .version('0.1.0');\n\nregisterStart(program);\nregisterSpawn(program);\nregisterSubmit(program);\nregisterReport(program);\nregisterYield(program);\nregisterComplete(program);\nregisterStatus(program);\nregisterList(program);\nregisterResume(program);\nregisterKill(program);\nregisterUninstall(program);\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n console.error(err.message);\n process.exit(1);\n});\n","import { connect } from 'node:net';\nimport { socketPath } from '../shared/paths.js';\nimport type { Request, Response } from '../shared/protocol.js';\nimport { ensureDaemonInstalled, waitForDaemon } from './install.js';\n\nfunction rawSend(request: Request): Promise<Response> {\n const sock = socketPath();\n\n return new Promise<Response>((resolve, reject) => {\n const socket = connect(sock);\n let data = '';\n\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error('Request timed out after 10s'));\n }, 10_000);\n\n socket.on('connect', () => {\n socket.write(JSON.stringify(request) + '\\n');\n });\n\n socket.on('data', (chunk) => {\n data += chunk.toString();\n const newlineIdx = data.indexOf('\\n');\n if (newlineIdx !== -1) {\n clearTimeout(timeout);\n const line = data.slice(0, newlineIdx);\n socket.destroy();\n try {\n resolve(JSON.parse(line) as Response);\n } catch {\n reject(new Error(`Invalid JSON response from daemon: ${line}`));\n }\n }\n });\n\n socket.on('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n}\n\nexport async function sendRequest(request: Request): Promise<Response> {\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n const MAX_ATTEMPTS = 5;\n const RETRY_DELAY_MS = 2000;\n let installedDaemon = false;\n let lastErr: unknown;\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n return await rawSend(request);\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT' && code !== 'ECONNREFUSED') {\n throw err;\n }\n\n if (attempt === MAX_ATTEMPTS) break;\n\n if (process.platform === 'darwin' && !installedDaemon) {\n installedDaemon = true;\n await ensureDaemonInstalled();\n await waitForDaemon(5000);\n } else {\n process.stderr.write(`Daemon not ready, retrying (${attempt}/${MAX_ATTEMPTS - 1})...\\n`);\n await sleep(RETRY_DELAY_MS);\n }\n }\n }\n\n if (process.platform !== 'darwin') {\n throw new Error(\n `Sisyphus daemon is not running.\\n` +\n ` Start it manually: sisyphusd &\\n` +\n ` Or check logs at: ~/.sisyphus/daemon.log`\n );\n }\n throw lastErr;\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { connect } from 'node:net';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { daemonLogPath, globalDir, socketPath } from '../shared/paths.js';\n\nconst PLIST_LABEL = 'com.sisyphus.daemon';\nconst PLIST_FILENAME = `${PLIST_LABEL}.plist`;\n\nfunction launchAgentDir(): string {\n return join(homedir(), 'Library', 'LaunchAgents');\n}\n\nfunction plistPath(): string {\n return join(launchAgentDir(), PLIST_FILENAME);\n}\n\nfunction daemonBinPath(): string {\n const installDir = dirname(fileURLToPath(import.meta.url));\n return resolve(installDir, '..', 'daemon.js');\n}\n\nfunction generatePlist(nodePath: string, daemonPath: string, logPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${nodePath}</string>\n <string>${daemonPath}</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${logPath}</string>\n <key>StandardErrorPath</key>\n <string>${logPath}</string>\n</dict>\n</plist>\n`;\n}\n\nexport function isInstalled(): boolean {\n return existsSync(plistPath());\n}\n\nexport async function ensureDaemonInstalled(): Promise<void> {\n if (process.platform !== 'darwin') return;\n\n if (!isInstalled()) {\n const nodePath = process.execPath;\n const daemonPath = daemonBinPath();\n const logPath = daemonLogPath();\n\n mkdirSync(globalDir(), { recursive: true });\n mkdirSync(launchAgentDir(), { recursive: true });\n\n const plist = generatePlist(nodePath, daemonPath, logPath);\n writeFileSync(plistPath(), plist, 'utf8');\n\n execSync(`launchctl load -w ${plistPath()}`);\n }\n\n await waitForDaemon();\n}\n\nexport async function uninstallDaemon(purge: boolean): Promise<void> {\n if (process.platform !== 'darwin') {\n console.log('Auto-install is only supported on macOS.');\n return;\n }\n\n const plist = plistPath();\n if (existsSync(plist)) {\n try {\n execSync(`launchctl unload -w ${plist}`, { stdio: 'pipe' });\n } catch {\n // already unloaded or not registered — ignore\n }\n unlinkSync(plist);\n console.log('Daemon unloaded and plist removed.');\n } else {\n console.log('Daemon is not installed (plist not found).');\n }\n\n if (purge) {\n const dir = globalDir();\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n console.log(`Removed ${dir}`);\n }\n }\n}\n\nfunction testConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n const sock = connect(socketPath());\n sock.on('connect', () => { sock.destroy(); resolve(); });\n sock.on('error', (err) => { sock.destroy(); reject(err); });\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function waitForDaemon(maxWaitMs = 6000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < maxWaitMs) {\n if (existsSync(socketPath())) {\n try {\n await testConnection();\n return;\n } catch {\n // not ready yet\n }\n }\n await sleep(300);\n }\n throw new Error(`Daemon did not start within ${maxWaitMs}ms. Check ${daemonLogPath()}`);\n}\n","import { execSync } from 'node:child_process';\n\nexport function assertTmux(): void {\n if (!process.env.TMUX) {\n throw new Error('Not running inside a tmux pane. Sisyphus requires tmux.');\n }\n}\n\nexport function getTmuxSession(): string {\n assertTmux();\n return execSync('tmux display-message -p \"#{session_name}\"', { encoding: 'utf8' }).trim();\n}\n\nexport function getTmuxWindow(): string {\n assertTmux();\n return execSync('tmux display-message -p \"#{window_id}\"', { encoding: 'utf8' }).trim();\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { getTmuxSession, getTmuxWindow } from '../tmux.js';\n\nexport function registerStart(program: Command): void {\n program\n .command('start')\n .description('Start a new sisyphus session')\n .argument('<task>', 'Task description for the orchestrator')\n .action(async (task: string) => {\n const tmuxSession = getTmuxSession();\n const tmuxWindow = getTmuxWindow();\n const request: Request = { type: 'start', task, cwd: process.cwd(), tmuxSession, tmuxWindow };\n const response = await sendRequest(request);\n if (response.ok) {\n const sessionId = response.data?.sessionId as string;\n console.log(`Session started: ${sessionId}`);\n if (response.data?.tmuxWindow) {\n console.log(`Orchestrator spawned in tmux window: ${response.data.tmuxWindow}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerSpawn(program: Command): void {\n program\n .command('spawn')\n .description('Spawn a new agent (orchestrator only)')\n .option('--agent-type <type>', 'Agent role label (default: worker)', 'worker')\n .requiredOption('--name <name>', 'Agent name')\n .requiredOption('--instruction <instruction>', 'Task instruction for the agent')\n .option('--worktree', 'Spawn agent in an isolated git worktree')\n .action(async (opts: { agentType: string; name: string; instruction: string; worktree?: boolean }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const request: Request = {\n type: 'spawn',\n sessionId,\n agentType: opts.agentType,\n name: opts.name,\n instruction: opts.instruction,\n ...(opts.worktree ? { worktree: true } : {}),\n };\n const response = await sendRequest(request);\n if (response.ok) {\n const agentId = response.data?.agentId as string;\n console.log(`Agent spawned: ${agentId}`);\n console.log(\"Run `sisyphus yield` when done spawning agents.\");\n } else {\n console.error(`Error: ${response.error}`);\n if (response.error?.includes(\"Unknown session\")) console.error(\"Hint: run `sisyphus list` to see active sessions.\");\n process.exit(1);\n }\n });\n}\n","export function readStdin(): Promise<string | null> {\n if (process.stdin.isTTY) return Promise.resolve(null);\n\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => chunks.push(chunk));\n process.stdin.on('end', () => {\n const text = Buffer.concat(chunks).toString('utf-8').trim();\n resolve(text || null);\n });\n process.stdin.on('error', reject);\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerSubmit(program: Command): void {\n program\n .command('submit')\n .description('Submit work report and exit (agent only)')\n .option('--report <report>', 'Work report (or pipe via stdin)')\n .action(async (opts: { report?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n const agentId = process.env.SISYPHUS_AGENT_ID;\n if (!sessionId || !agentId) {\n console.error('Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set');\n process.exit(1);\n }\n\n const report = opts.report ?? await readStdin();\n if (!report) {\n console.error('Error: provide --report or pipe content via stdin');\n process.exit(1);\n }\n\n const request: Request = { type: 'submit', sessionId, agentId, report };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Report submitted successfully');\n console.log('Your pane will close. The orchestrator resumes when all agents finish.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerYield(program: Command): void {\n program\n .command('yield')\n .description('Yield control back to daemon (orchestrator only)')\n .option('--prompt <text>', 'Instructions for the next orchestrator cycle (or pipe via stdin)')\n .action(async (opts: { prompt?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const nextPrompt = opts.prompt ?? await readStdin() ?? undefined;\n\n const request: Request = { type: 'yield', sessionId, agentId: 'orchestrator', nextPrompt };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Yielded. Waiting for agents to complete.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerComplete(program: Command): void {\n program\n .command('complete')\n .description('Mark session as completed (orchestrator only)')\n .requiredOption('--report <report>', 'Final completion report')\n .action(async (opts: { report: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const request: Request = { type: 'complete', sessionId, report: opts.report };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Session completed.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\n\nconst STATUS_COLORS: Record<string, string> = {\n active: '\\x1b[32m', // green\n paused: '\\x1b[33m', // yellow\n completed: '\\x1b[36m', // cyan\n running: '\\x1b[32m', // green\n killed: '\\x1b[31m', // red\n crashed: '\\x1b[31m', // red\n lost: '\\x1b[90m', // gray\n};\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\nfunction colorize(text: string, status: string): string {\n const color = STATUS_COLORS[status] ?? '';\n return `${color}${text}${RESET}`;\n}\n\nfunction formatDuration(startIso: string, endIso?: string | null): string {\n const start = new Date(startIso).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n const totalSeconds = Math.floor((end - start) / 1000);\n if (totalSeconds < 0) return '0s';\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const parts: string[] = [];\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n parts.push(`${seconds}s`);\n return parts.join(' ');\n}\n\nfunction formatAgent(agent: Agent): string {\n const status = colorize(agent.status, agent.status);\n const name = `${BOLD}${agent.name}${RESET}`;\n const type = `${DIM}(${agent.agentType})${RESET}`;\n const duration = formatDuration(agent.spawnedAt, agent.completedAt);\n let line = ` ${agent.id} ${name} ${type} — ${status} ${DIM}(${duration})${RESET}`;\n if (agent.reports.length > 0) {\n for (const r of agent.reports) {\n const label = r.type === 'final' ? 'Final' : 'Update';\n line += `\\n ${label}: ${r.summary}`;\n }\n }\n if (agent.killedReason) {\n line += `\\n Reason: ${agent.killedReason}`;\n }\n return line;\n}\n\nfunction formatCycle(cycle: OrchestratorCycle): string {\n const duration = cycle.completedAt\n ? ` ${DIM}(${formatDuration(cycle.timestamp, cycle.completedAt)})${RESET}`\n : ` ${DIM}(running)${RESET}`;\n const agents = cycle.agentsSpawned.length > 0\n ? ` — agents: ${cycle.agentsSpawned.join(', ')}`\n : '';\n return ` Cycle ${cycle.cycle}${duration}${agents}`;\n}\n\nfunction printSession(session: Session): void {\n const status = colorize(session.status, session.status);\n const sessionDuration = formatDuration(session.createdAt, session.completedAt);\n console.log(`\\n${BOLD}Session: ${session.id}${RESET}`);\n console.log(` Status: ${status}`);\n console.log(` Task: ${session.task}`);\n console.log(` CWD: ${session.cwd}`);\n console.log(` Created: ${session.createdAt}`);\n console.log(` Duration: ${sessionDuration}${session.completedAt ? '' : ' (ongoing)'}`);\n console.log(` Orchestrator cycles: ${session.orchestratorCycles.length}`);\n\n if (session.orchestratorCycles.length > 0) {\n console.log(`\\n ${BOLD}Cycles:${RESET}`);\n for (const cycle of session.orchestratorCycles) {\n console.log(formatCycle(cycle));\n }\n }\n\n if (session.agents.length > 0) {\n console.log(`\\n ${BOLD}Agents:${RESET}`);\n for (const agent of session.agents) {\n console.log(formatAgent(agent));\n }\n }\n}\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Show session status')\n .argument('[session-id]', 'Session ID (defaults to SISYPHUS_SESSION_ID env)')\n .action(async (sessionIdArg?: string) => {\n const sessionId = sessionIdArg ?? process.env.SISYPHUS_SESSION_ID;\n\n const request: Request = { type: 'status', sessionId };\n const response = await sendRequest(request);\n if (response.ok) {\n const session = response.data?.session as Session | undefined;\n if (session) {\n printSession(session);\n } else {\n console.log('No session found');\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { basename } from 'node:path';\n\ninterface SessionSummary {\n id: string;\n task: string;\n status: string;\n agentCount: number;\n createdAt: string;\n cwd?: string;\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n active: '\\x1b[32m',\n paused: '\\x1b[33m',\n completed: '\\x1b[36m',\n};\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\nfunction truncateTask(task: string, max: number): string {\n if (task.length <= max) return task;\n return task.slice(0, max - 1) + '…';\n}\n\nexport function registerList(program: Command): void {\n program\n .command('list')\n .description('List sessions (defaults to current project)')\n .option('-a, --all', 'Show sessions from all projects')\n .action(async (opts: { all?: boolean }) => {\n const cwd = process.cwd();\n const request: Request = { type: 'list', cwd, all: opts.all };\n const response = await sendRequest(request);\n if (response.ok) {\n const sessions = (response.data?.sessions ?? []) as SessionSummary[];\n const totalCount = response.data?.totalCount as number | undefined;\n const filtered = response.data?.filtered as boolean | undefined;\n\n if (sessions.length === 0) {\n if (filtered && totalCount && totalCount > 0) {\n console.log(`No sessions in this project. ${totalCount} session(s) in other projects.`);\n console.log(`${DIM}Run ${RESET}sisyphus list --all${DIM} to show all.${RESET}`);\n } else {\n console.log('No sessions');\n }\n return;\n }\n\n for (const s of sessions) {\n const color = STATUS_COLORS[s.status] ?? '';\n const status = `${color}${s.status}${RESET}`;\n const agents = `${DIM}${s.agentCount} agent(s)${RESET}`;\n const task = truncateTask(s.task, 60);\n const cwdLabel = opts.all && s.cwd ? ` ${DIM}${basename(s.cwd)}${RESET}` : '';\n console.log(` ${BOLD}${s.id}${RESET} ${status} ${agents} ${task}${cwdLabel}`);\n }\n\n if (filtered && totalCount && totalCount > sessions.length) {\n const otherCount = totalCount - sessions.length;\n console.log(`\\n${DIM}${otherCount} more session(s) in other projects. Run ${RESET}sisyphus list --all${DIM} to show all.${RESET}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerReport(program: Command): void {\n program\n .command('report')\n .description('Send a progress report without exiting (agent only)')\n .option('--message <message>', 'Progress report content')\n .action(async (opts: { message?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n const agentId = process.env.SISYPHUS_AGENT_ID;\n if (!sessionId || !agentId) {\n console.error('Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set');\n process.exit(1);\n }\n\n const content = opts.message ?? await readStdin();\n if (!content) {\n console.error('Error: provide --message or pipe content via stdin');\n process.exit(1);\n }\n\n const request: Request = { type: 'report', sessionId, agentId, content };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Progress report recorded');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { getTmuxSession, getTmuxWindow } from '../tmux.js';\n\nexport function registerResume(program: Command): void {\n program\n .command('resume')\n .description('Resume a paused session')\n .argument('<session-id>', 'Session ID to resume')\n .argument('[message]', 'Additional instructions for the orchestrator')\n .action(async (sessionId: string, message?: string) => {\n const tmuxSession = getTmuxSession();\n const tmuxWindow = getTmuxWindow();\n const cwd = process.cwd();\n const request: Request = { type: 'resume', sessionId, cwd, tmuxSession, tmuxWindow, message };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log(`Session ${sessionId} resumed`);\n if (response.data?.tmuxWindow) {\n console.log(`Orchestrator respawned in tmux window: ${response.data.tmuxWindow}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\n\nexport function registerKill(program: Command): void {\n program\n .command('kill <sessionId>')\n .description('Kill a running session and all its agents')\n .action(async (sessionId: string) => {\n const request: Request = { type: 'kill', sessionId };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log(`Session ${sessionId} killed.`);\n if (response.data) {\n const { killedAgents } = response.data as { killedAgents: number };\n console.log(`Cleaned up: ${killedAgents} agent(s) killed, tmux window removed.`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { createInterface } from 'node:readline';\nimport { uninstallDaemon } from '../install.js';\n\nasync function confirm(question: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y');\n });\n });\n}\n\nexport function registerUninstall(program: Command): void {\n program\n .command('uninstall')\n .description('Unload the sisyphus daemon from launchd and remove the plist')\n .option('--purge', 'Also remove all session data in ~/.sisyphus')\n .option('-y, --yes', 'Skip confirmation prompt for --purge')\n .action(async (opts: { purge?: boolean; yes?: boolean }) => {\n const purge = opts.purge ?? false;\n\n if (purge && !opts.yes) {\n const ok = await confirm('This will delete all session data in ~/.sisyphus. Continue? (y/N) ');\n if (!ok) {\n console.log('Aborted.');\n return;\n }\n }\n\n await uninstallDaemon(purge);\n });\n}\n"],"mappings":"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","names":["connect","resolve","resolve","connect","sleep","execSync","program","program","resolve","program","program","program","program","STATUS_COLORS","RESET","BOLD","DIM","program","program","program","program","resolve","program"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/cli/client.ts","../src/cli/install.ts","../src/cli/tmux.ts","../src/cli/commands/start.ts","../src/cli/commands/spawn.ts","../src/cli/commands/submit.ts","../src/cli/stdin.ts","../src/cli/commands/yield.ts","../src/cli/commands/complete.ts","../src/cli/commands/status.ts","../src/cli/commands/list.ts","../src/cli/commands/report.ts","../src/cli/commands/resume.ts","../src/cli/commands/kill.ts","../src/cli/commands/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerStart } from './commands/start.js';\nimport { registerSpawn } from './commands/spawn.js';\nimport { registerSubmit } from './commands/submit.js';\nimport { registerYield } from './commands/yield.js';\nimport { registerComplete } from './commands/complete.js';\nimport { registerStatus } from './commands/status.js';\nimport { registerList } from './commands/list.js';\nimport { registerReport } from './commands/report.js';\nimport { registerResume } from './commands/resume.js';\nimport { registerKill } from './commands/kill.js';\nimport { registerUninstall } from './commands/uninstall.js';\n\nconst program = new Command();\n\nprogram\n .name('sisyphus')\n .description('tmux-integrated orchestration daemon for Claude Code')\n .version('0.1.0');\n\nregisterStart(program);\nregisterSpawn(program);\nregisterSubmit(program);\nregisterReport(program);\nregisterYield(program);\nregisterComplete(program);\nregisterStatus(program);\nregisterList(program);\nregisterResume(program);\nregisterKill(program);\nregisterUninstall(program);\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n console.error(err.message);\n process.exit(1);\n});\n","import { connect } from 'node:net';\nimport { socketPath } from '../shared/paths.js';\nimport type { Request, Response } from '../shared/protocol.js';\nimport { ensureDaemonInstalled, waitForDaemon } from './install.js';\n\nfunction rawSend(request: Request): Promise<Response> {\n const sock = socketPath();\n\n return new Promise<Response>((resolve, reject) => {\n const socket = connect(sock);\n let data = '';\n\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error('Request timed out after 10s'));\n }, 10_000);\n\n socket.on('connect', () => {\n socket.write(JSON.stringify(request) + '\\n');\n });\n\n socket.on('data', (chunk) => {\n data += chunk.toString();\n const newlineIdx = data.indexOf('\\n');\n if (newlineIdx !== -1) {\n clearTimeout(timeout);\n const line = data.slice(0, newlineIdx);\n socket.destroy();\n try {\n resolve(JSON.parse(line) as Response);\n } catch {\n reject(new Error(`Invalid JSON response from daemon: ${line}`));\n }\n }\n });\n\n socket.on('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n}\n\nexport async function sendRequest(request: Request): Promise<Response> {\n const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n const MAX_ATTEMPTS = 5;\n const RETRY_DELAY_MS = 2000;\n let installedDaemon = false;\n let lastErr: unknown;\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n try {\n return await rawSend(request);\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT' && code !== 'ECONNREFUSED') {\n throw err;\n }\n\n if (attempt === MAX_ATTEMPTS) break;\n\n if (process.platform === 'darwin' && !installedDaemon) {\n installedDaemon = true;\n await ensureDaemonInstalled();\n await waitForDaemon(5000);\n } else {\n process.stderr.write(`Daemon not ready, retrying (${attempt}/${MAX_ATTEMPTS - 1})...\\n`);\n await sleep(RETRY_DELAY_MS);\n }\n }\n }\n\n if (process.platform !== 'darwin') {\n throw new Error(\n `Sisyphus daemon is not running.\\n` +\n ` Start it manually: sisyphusd &\\n` +\n ` Or check logs at: ~/.sisyphus/daemon.log`\n );\n }\n throw lastErr;\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { connect } from 'node:net';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { daemonLogPath, globalDir, socketPath } from '../shared/paths.js';\n\nconst PLIST_LABEL = 'com.sisyphus.daemon';\nconst PLIST_FILENAME = `${PLIST_LABEL}.plist`;\n\nfunction launchAgentDir(): string {\n return join(homedir(), 'Library', 'LaunchAgents');\n}\n\nfunction plistPath(): string {\n return join(launchAgentDir(), PLIST_FILENAME);\n}\n\nfunction daemonBinPath(): string {\n const installDir = dirname(fileURLToPath(import.meta.url));\n return resolve(installDir, '..', 'daemon.js');\n}\n\nfunction generatePlist(nodePath: string, daemonPath: string, logPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${nodePath}</string>\n <string>${daemonPath}</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${logPath}</string>\n <key>StandardErrorPath</key>\n <string>${logPath}</string>\n</dict>\n</plist>\n`;\n}\n\nexport function isInstalled(): boolean {\n return existsSync(plistPath());\n}\n\nexport async function ensureDaemonInstalled(): Promise<void> {\n if (process.platform !== 'darwin') return;\n\n if (!isInstalled()) {\n const nodePath = process.execPath;\n const daemonPath = daemonBinPath();\n const logPath = daemonLogPath();\n\n mkdirSync(globalDir(), { recursive: true });\n mkdirSync(launchAgentDir(), { recursive: true });\n\n const plist = generatePlist(nodePath, daemonPath, logPath);\n writeFileSync(plistPath(), plist, 'utf8');\n\n execSync(`launchctl load -w ${plistPath()}`);\n }\n\n await waitForDaemon();\n}\n\nexport async function uninstallDaemon(purge: boolean): Promise<void> {\n if (process.platform !== 'darwin') {\n console.log('Auto-install is only supported on macOS.');\n return;\n }\n\n const plist = plistPath();\n if (existsSync(plist)) {\n try {\n execSync(`launchctl unload -w ${plist}`, { stdio: 'pipe' });\n } catch {\n // already unloaded or not registered — ignore\n }\n unlinkSync(plist);\n console.log('Daemon unloaded and plist removed.');\n } else {\n console.log('Daemon is not installed (plist not found).');\n }\n\n if (purge) {\n const dir = globalDir();\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n console.log(`Removed ${dir}`);\n }\n }\n}\n\nfunction testConnection(): Promise<void> {\n return new Promise((resolve, reject) => {\n const sock = connect(socketPath());\n sock.on('connect', () => { sock.destroy(); resolve(); });\n sock.on('error', (err) => { sock.destroy(); reject(err); });\n });\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function waitForDaemon(maxWaitMs = 6000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < maxWaitMs) {\n if (existsSync(socketPath())) {\n try {\n await testConnection();\n return;\n } catch {\n // not ready yet\n }\n }\n await sleep(300);\n }\n throw new Error(`Daemon did not start within ${maxWaitMs}ms. Check ${daemonLogPath()}`);\n}\n","import { execSync } from 'node:child_process';\n\nexport function assertTmux(): void {\n if (!process.env.TMUX) {\n throw new Error('Not running inside a tmux pane. Sisyphus requires tmux.');\n }\n}\n\nexport function getTmuxSession(): string {\n assertTmux();\n return execSync('tmux display-message -p \"#{session_name}\"', { encoding: 'utf8' }).trim();\n}\n\nexport function getTmuxWindow(): string {\n assertTmux();\n return execSync('tmux display-message -p \"#{window_id}\"', { encoding: 'utf8' }).trim();\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { getTmuxSession, getTmuxWindow } from '../tmux.js';\n\nexport function registerStart(program: Command): void {\n program\n .command('start')\n .description('Start a new sisyphus session')\n .argument('<task>', 'Task description for the orchestrator')\n .action(async (task: string) => {\n const tmuxSession = getTmuxSession();\n const tmuxWindow = getTmuxWindow();\n const request: Request = { type: 'start', task, cwd: process.cwd(), tmuxSession, tmuxWindow };\n const response = await sendRequest(request);\n if (response.ok) {\n const sessionId = response.data?.sessionId as string;\n console.log(`Session started: ${sessionId}`);\n if (response.data?.tmuxWindow) {\n console.log(`Orchestrator spawned in tmux window: ${response.data.tmuxWindow}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerSpawn(program: Command): void {\n program\n .command('spawn')\n .description('Spawn a new agent (orchestrator only)')\n .option('--agent-type <type>', 'Agent role label (default: worker)', 'worker')\n .requiredOption('--name <name>', 'Agent name')\n .requiredOption('--instruction <instruction>', 'Task instruction for the agent')\n .option('--worktree', 'Spawn agent in an isolated git worktree')\n .action(async (opts: { agentType: string; name: string; instruction: string; worktree?: boolean }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const request: Request = {\n type: 'spawn',\n sessionId,\n agentType: opts.agentType,\n name: opts.name,\n instruction: opts.instruction,\n ...(opts.worktree ? { worktree: true } : {}),\n };\n const response = await sendRequest(request);\n if (response.ok) {\n const agentId = response.data?.agentId as string;\n console.log(`Agent spawned: ${agentId}`);\n console.log(\"Run `sisyphus yield` when done spawning agents.\");\n } else {\n console.error(`Error: ${response.error}`);\n if (response.error?.includes(\"Unknown session\")) console.error(\"Hint: run `sisyphus list` to see active sessions.\");\n process.exit(1);\n }\n });\n}\n","import { execSync } from 'node:child_process';\nimport type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nfunction isInWorktree(): boolean {\n try {\n const gitDir = execSync('git rev-parse --git-dir', { encoding: 'utf-8' }).trim();\n const commonDir = execSync('git rev-parse --git-common-dir', { encoding: 'utf-8' }).trim();\n return gitDir !== commonDir;\n } catch {\n return false;\n }\n}\n\nfunction getUncommittedChanges(): string | null {\n try {\n const status = execSync('git status --porcelain', { encoding: 'utf-8' }).trim();\n return status || null;\n } catch {\n return null;\n }\n}\n\nexport function registerSubmit(program: Command): void {\n program\n .command('submit')\n .description('Submit work report and exit (agent only)')\n .option('--report <report>', 'Work report (or pipe via stdin)')\n .action(async (opts: { report?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n const agentId = process.env.SISYPHUS_AGENT_ID;\n if (!sessionId || !agentId) {\n console.error('Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set');\n process.exit(1);\n }\n\n // Block submit if worktree has uncommitted changes — they'd be lost on merge\n if (isInWorktree()) {\n const changes = getUncommittedChanges();\n if (changes) {\n console.error('Error: uncommitted changes in worktree. Your branch is merged automatically after submit — uncommitted work will be lost.');\n console.error('\\nCommit first:\\n git add -A && git commit -m \"description of changes\"\\n');\n console.error('Or discard:\\n git checkout -- .\\n');\n console.error('Uncommitted changes:');\n console.error(changes);\n process.exit(1);\n }\n }\n\n const report = opts.report ?? await readStdin();\n if (!report) {\n console.error('Error: provide --report or pipe content via stdin');\n process.exit(1);\n }\n\n const request: Request = { type: 'submit', sessionId, agentId, report };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Report submitted successfully');\n console.log('Your pane will close. The orchestrator resumes when all agents finish.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","export function readStdin(): Promise<string | null> {\n if (process.stdin.isTTY) return Promise.resolve(null);\n\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => chunks.push(chunk));\n process.stdin.on('end', () => {\n const text = Buffer.concat(chunks).toString('utf-8').trim();\n resolve(text || null);\n });\n process.stdin.on('error', reject);\n });\n}\n","import type { Command } from 'commander';\nimport { writeFileSync } from 'node:fs';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerYield(program: Command): void {\n program\n .command('yield')\n .description('Yield control back to daemon (orchestrator only)')\n .option('--prompt <text>', 'Instructions for the next orchestrator cycle (or pipe via stdin)')\n .action(async (opts: { prompt?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const nextPrompt = opts.prompt ?? await readStdin() ?? undefined;\n\n const request: Request = { type: 'yield', sessionId, agentId: 'orchestrator', nextPrompt };\n const response = await sendRequest(request);\n if (response.ok) {\n writeFileSync(`/tmp/sisyphus-exit-${sessionId}`, '');\n console.log('Yielded. Waiting for agents to complete.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { writeFileSync } from 'node:fs';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerComplete(program: Command): void {\n program\n .command('complete')\n .description('Mark session as completed (orchestrator only)')\n .requiredOption('--report <report>', 'Final completion report')\n .action(async (opts: { report: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n if (!sessionId) {\n console.error('Error: SISYPHUS_SESSION_ID environment variable not set');\n process.exit(1);\n }\n\n const request: Request = { type: 'complete', sessionId, report: opts.report };\n const response = await sendRequest(request);\n if (response.ok) {\n writeFileSync(`/tmp/sisyphus-exit-${sessionId}`, '');\n console.log('Session completed.');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport type { Session, Agent, OrchestratorCycle } from '../../shared/types.js';\n\nconst STATUS_COLORS: Record<string, string> = {\n active: '\\x1b[32m', // green\n paused: '\\x1b[33m', // yellow\n completed: '\\x1b[36m', // cyan\n running: '\\x1b[32m', // green\n killed: '\\x1b[31m', // red\n crashed: '\\x1b[31m', // red\n lost: '\\x1b[90m', // gray\n};\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\nfunction colorize(text: string, status: string): string {\n const color = STATUS_COLORS[status] ?? '';\n return `${color}${text}${RESET}`;\n}\n\nfunction formatDuration(startIso: string, endIso?: string | null): string {\n const start = new Date(startIso).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n const totalSeconds = Math.floor((end - start) / 1000);\n if (totalSeconds < 0) return '0s';\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const parts: string[] = [];\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n parts.push(`${seconds}s`);\n return parts.join(' ');\n}\n\nfunction formatAgent(agent: Agent): string {\n const status = colorize(agent.status, agent.status);\n const name = `${BOLD}${agent.name}${RESET}`;\n const type = `${DIM}(${agent.agentType})${RESET}`;\n const duration = formatDuration(agent.spawnedAt, agent.completedAt);\n let line = ` ${agent.id} ${name} ${type} — ${status} ${DIM}(${duration})${RESET}`;\n if (agent.reports.length > 0) {\n for (const r of agent.reports) {\n const label = r.type === 'final' ? 'Final' : 'Update';\n line += `\\n ${label}: ${r.summary}`;\n }\n }\n if (agent.killedReason) {\n line += `\\n Reason: ${agent.killedReason}`;\n }\n return line;\n}\n\nfunction formatCycle(cycle: OrchestratorCycle): string {\n const duration = cycle.completedAt\n ? ` ${DIM}(${formatDuration(cycle.timestamp, cycle.completedAt)})${RESET}`\n : ` ${DIM}(running)${RESET}`;\n const agents = cycle.agentsSpawned.length > 0\n ? ` — agents: ${cycle.agentsSpawned.join(', ')}`\n : '';\n return ` Cycle ${cycle.cycle}${duration}${agents}`;\n}\n\nfunction printSession(session: Session): void {\n const status = colorize(session.status, session.status);\n const sessionDuration = formatDuration(session.createdAt, session.completedAt);\n console.log(`\\n${BOLD}Session: ${session.id}${RESET}`);\n console.log(` Status: ${status}`);\n console.log(` Task: ${session.task}`);\n console.log(` CWD: ${session.cwd}`);\n console.log(` Created: ${session.createdAt}`);\n console.log(` Duration: ${sessionDuration}${session.completedAt ? '' : ' (ongoing)'}`);\n console.log(` Orchestrator cycles: ${session.orchestratorCycles.length}`);\n\n if (session.orchestratorCycles.length > 0) {\n console.log(`\\n ${BOLD}Cycles:${RESET}`);\n for (const cycle of session.orchestratorCycles) {\n console.log(formatCycle(cycle));\n }\n }\n\n if (session.agents.length > 0) {\n console.log(`\\n ${BOLD}Agents:${RESET}`);\n for (const agent of session.agents) {\n console.log(formatAgent(agent));\n }\n }\n}\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Show session status')\n .argument('[session-id]', 'Session ID (defaults to SISYPHUS_SESSION_ID env)')\n .action(async (sessionIdArg?: string) => {\n const sessionId = sessionIdArg ?? process.env.SISYPHUS_SESSION_ID;\n\n const request: Request = { type: 'status', sessionId };\n const response = await sendRequest(request);\n if (response.ok) {\n const session = response.data?.session as Session | undefined;\n if (session) {\n printSession(session);\n } else {\n console.log('No session found');\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { basename } from 'node:path';\n\ninterface SessionSummary {\n id: string;\n task: string;\n status: string;\n agentCount: number;\n createdAt: string;\n cwd?: string;\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n active: '\\x1b[32m',\n paused: '\\x1b[33m',\n completed: '\\x1b[36m',\n};\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\nfunction truncateTask(task: string, max: number): string {\n if (task.length <= max) return task;\n return task.slice(0, max - 1) + '…';\n}\n\nexport function registerList(program: Command): void {\n program\n .command('list')\n .description('List sessions (defaults to current project)')\n .option('-a, --all', 'Show sessions from all projects')\n .action(async (opts: { all?: boolean }) => {\n const cwd = process.cwd();\n const request: Request = { type: 'list', cwd, all: opts.all };\n const response = await sendRequest(request);\n if (response.ok) {\n const sessions = (response.data?.sessions ?? []) as SessionSummary[];\n const totalCount = response.data?.totalCount as number | undefined;\n const filtered = response.data?.filtered as boolean | undefined;\n\n if (sessions.length === 0) {\n if (filtered && totalCount && totalCount > 0) {\n console.log(`No sessions in this project. ${totalCount} session(s) in other projects.`);\n console.log(`${DIM}Run ${RESET}sisyphus list --all${DIM} to show all.${RESET}`);\n } else {\n console.log('No sessions');\n }\n return;\n }\n\n for (const s of sessions) {\n const color = STATUS_COLORS[s.status] ?? '';\n const status = `${color}${s.status}${RESET}`;\n const agents = `${DIM}${s.agentCount} agent(s)${RESET}`;\n const task = truncateTask(s.task, 60);\n const cwdLabel = opts.all && s.cwd ? ` ${DIM}${basename(s.cwd)}${RESET}` : '';\n console.log(` ${BOLD}${s.id}${RESET} ${status} ${agents} ${task}${cwdLabel}`);\n }\n\n if (filtered && totalCount && totalCount > sessions.length) {\n const otherCount = totalCount - sessions.length;\n console.log(`\\n${DIM}${otherCount} more session(s) in other projects. Run ${RESET}sisyphus list --all${DIM} to show all.${RESET}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { readStdin } from '../stdin.js';\nimport { assertTmux } from '../tmux.js';\n\nexport function registerReport(program: Command): void {\n program\n .command('report')\n .description('Send a progress report without exiting (agent only)')\n .option('--message <message>', 'Progress report content')\n .action(async (opts: { message?: string }) => {\n assertTmux();\n const sessionId = process.env.SISYPHUS_SESSION_ID;\n const agentId = process.env.SISYPHUS_AGENT_ID;\n if (!sessionId || !agentId) {\n console.error('Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set');\n process.exit(1);\n }\n\n const content = opts.message ?? await readStdin();\n if (!content) {\n console.error('Error: provide --message or pipe content via stdin');\n process.exit(1);\n }\n\n const request: Request = { type: 'report', sessionId, agentId, content };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log('Progress report recorded');\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\nimport { getTmuxSession, getTmuxWindow } from '../tmux.js';\n\nexport function registerResume(program: Command): void {\n program\n .command('resume')\n .description('Resume a paused session')\n .argument('<session-id>', 'Session ID to resume')\n .argument('[message]', 'Additional instructions for the orchestrator')\n .action(async (sessionId: string, message?: string) => {\n const tmuxSession = getTmuxSession();\n const tmuxWindow = getTmuxWindow();\n const cwd = process.cwd();\n const request: Request = { type: 'resume', sessionId, cwd, tmuxSession, tmuxWindow, message };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log(`Session ${sessionId} resumed`);\n if (response.data?.tmuxWindow) {\n console.log(`Orchestrator respawned in tmux window: ${response.data.tmuxWindow}`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { sendRequest } from '../client.js';\nimport type { Request } from '../../shared/protocol.js';\n\nexport function registerKill(program: Command): void {\n program\n .command('kill <sessionId>')\n .description('Kill a running session and all its agents')\n .action(async (sessionId: string) => {\n const request: Request = { type: 'kill', sessionId };\n const response = await sendRequest(request);\n if (response.ok) {\n console.log(`Session ${sessionId} killed.`);\n if (response.data) {\n const { killedAgents } = response.data as { killedAgents: number };\n console.log(`Cleaned up: ${killedAgents} agent(s) killed, tmux window removed.`);\n }\n } else {\n console.error(`Error: ${response.error}`);\n process.exit(1);\n }\n });\n}\n","import type { Command } from 'commander';\nimport { createInterface } from 'node:readline';\nimport { uninstallDaemon } from '../install.js';\n\nasync function confirm(question: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === 'y');\n });\n });\n}\n\nexport function registerUninstall(program: Command): void {\n program\n .command('uninstall')\n .description('Unload the sisyphus daemon from launchd and remove the plist')\n .option('--purge', 'Also remove all session data in ~/.sisyphus')\n .option('-y, --yes', 'Skip confirmation prompt for --purge')\n .action(async (opts: { purge?: boolean; yes?: boolean }) => {\n const purge = opts.purge ?? false;\n\n if (purge && !opts.yes) {\n const ok = await confirm('This will delete all session data in ~/.sisyphus. Continue? (y/N) ');\n if (!ok) {\n console.log('Aborted.');\n return;\n }\n }\n\n await uninstallDaemon(purge);\n });\n}\n"],"mappings":"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","names":["connect","resolve","resolve","connect","sleep","execSync","program","program","execSync","resolve","execSync","program","writeFileSync","program","writeFileSync","writeFileSync","program","writeFileSync","program","STATUS_COLORS","RESET","BOLD","DIM","program","program","program","program","resolve","program"]}
package/dist/daemon.js CHANGED
@@ -48,18 +48,15 @@ import { join as join4 } from "path";
48
48
 
49
49
  // src/daemon/session-manager.ts
50
50
  import { v4 as uuidv4 } from "uuid";
51
- import { existsSync as existsSync4, readdirSync as readdirSync4 } from "fs";
51
+ import { existsSync as existsSync4, readdirSync as readdirSync4, rmSync as rmSync2 } from "fs";
52
52
 
53
53
  // src/daemon/state.ts
54
- import { readFileSync as readFileSync2, writeFileSync, mkdirSync, renameSync } from "fs";
55
- import { dirname, join } from "path";
56
54
  import { randomUUID } from "crypto";
55
+ import { mkdirSync, readFileSync as readFileSync2, renameSync, writeFileSync } from "fs";
56
+ import { dirname, join } from "path";
57
57
  var PLAN_SEED = `---
58
58
  description: >
59
- Living document of what still needs to happen. Write your remaining work plan
60
- here: phases, next steps, file references, open questions. Remove or collapse
61
- items as they're completed so this file only reflects outstanding work. The
62
- orchestrator sees this every cycle \u2014 keep it focused and current.
59
+ Living document of what still needs to happen. Write out ne
63
60
  ---
64
61
  `;
65
62
  var LOGS_SEED = `---
@@ -67,7 +64,7 @@ description: >
67
64
  Session memory. Record important observations, decisions, and findings here.
68
65
  This is your persistent memory across cycles: things you tried, what
69
66
  worked/failed, design decisions and their rationale, gotchas discovered during
70
- implementation. Unlike plan.md, entries here accumulate \u2014 they're a log.
67
+ implementation.
71
68
  ---
72
69
  `;
73
70
  var sessionLocks = /* @__PURE__ */ new Map();
@@ -388,10 +385,13 @@ function formatStateForOrchestrator(session) {
388
385
  if (worktreeAgents.length > 0) {
389
386
  const wtLines = worktreeAgents.map((a) => {
390
387
  if (a.mergeStatus === "conflict") {
391
- return `- ${a.id}: conflict \u2014 ${a.mergeDetails ?? "unknown"}
388
+ return `- ${a.id}: CONFLICT \u2014 ${a.mergeDetails ?? "unknown"}
392
389
  Branch: ${a.branchName}
393
390
  Worktree: ${a.worktreePath}`;
394
391
  }
392
+ if (a.mergeStatus === "no-changes") {
393
+ return `- ${a.id}: NO CHANGES \u2014 agent did not commit any work to branch ${a.branchName}`;
394
+ }
395
395
  const status = a.mergeStatus ?? "pending";
396
396
  return `- ${a.id}: ${status} (branch ${a.branchName})`;
397
397
  }).join("\n");
@@ -493,7 +493,7 @@ async function handleOrchestratorYield(sessionId, cwd, nextPrompt) {
493
493
  const session = getSession(cwd, sessionId);
494
494
  const runningAgents = session.agents.filter((a) => a.status === "running");
495
495
  if (runningAgents.length === 0) {
496
- console.error(`[sisyphus] WARNING: Orchestrator yielded but no agents are running for session ${sessionId}`);
496
+ console.log(`[sisyphus] Orchestrator yielded with no running agents for session ${sessionId}`);
497
497
  }
498
498
  }
499
499
  async function handleOrchestratorComplete(sessionId, cwd, report) {
@@ -539,23 +539,17 @@ function loadWorktreeConfig(cwd) {
539
539
  return null;
540
540
  }
541
541
  }
542
- function createWorktree(cwd, sessionId, agentId) {
542
+ function createWorktreeShell(cwd, sessionId, agentId) {
543
543
  const branchName = `sisyphus/${sessionId.slice(0, 8)}/${agentId}`;
544
- const worktreePath = join3(worktreeBaseDir(cwd), agentId);
544
+ const worktreePath = join3(worktreeBaseDir(cwd), sessionId.slice(0, 8), agentId);
545
545
  mkdirSync2(dirname2(worktreePath), { recursive: true });
546
+ execSafe2(`git -C ${shellQuote2(cwd)} worktree prune`);
547
+ if (existsSync2(worktreePath)) {
548
+ execSafe2(`git -C ${shellQuote2(cwd)} worktree remove --force ${shellQuote2(worktreePath)}`);
549
+ }
550
+ execSafe2(`git -C ${shellQuote2(cwd)} branch -D ${shellQuote2(branchName)}`);
546
551
  exec2(`git -C ${shellQuote2(cwd)} branch ${shellQuote2(branchName)} HEAD`);
547
552
  exec2(`git -C ${shellQuote2(cwd)} worktree add ${shellQuote2(worktreePath)} ${shellQuote2(branchName)}`);
548
- const symlinks = [".sisyphus", ".claude"];
549
- for (const entry of symlinks) {
550
- const src = join3(cwd, entry);
551
- if (existsSync2(src)) {
552
- execSafe2(`ln -s ${shellQuote2(src)} ${shellQuote2(join3(worktreePath, entry))}`);
553
- }
554
- }
555
- const config = loadWorktreeConfig(cwd);
556
- if (config) {
557
- bootstrapWorktree(cwd, worktreePath, config);
558
- }
559
553
  return { worktreePath, branchName };
560
554
  }
561
555
  function bootstrapWorktree(cwd, worktreePath, config) {
@@ -615,6 +609,8 @@ function mergeWorktrees(cwd, agents) {
615
609
  (a) => a.worktreePath && a.mergeStatus === "pending"
616
610
  );
617
611
  const results = [];
612
+ execSafe2(`git -C ${shellQuote2(cwd)} add .sisyphus`);
613
+ execSafe2(`git -C ${shellQuote2(cwd)} commit -m 'sisyphus: snapshot session state before merge'`);
618
614
  for (const agent of pending) {
619
615
  const branch = resolveWorktreeBranch(cwd, agent.worktreePath);
620
616
  if (!branch) {
@@ -637,8 +633,10 @@ function mergeWorktrees(cwd, agents) {
637
633
  results.push({ agentId: agent.id, name: agent.name, status: "merged" });
638
634
  } catch (err) {
639
635
  execSafe2(`git -C ${shellQuote2(cwd)} merge --abort`);
640
- const stderr = err?.stderr;
641
- const conflictDetails = stderr ? (typeof stderr === "string" ? stderr : stderr.toString("utf-8")).trim() : err instanceof Error ? err.message : String(err);
636
+ const errObj = err;
637
+ const stdout = errObj.stdout ? (typeof errObj.stdout === "string" ? errObj.stdout : errObj.stdout.toString("utf-8")).trim() : "";
638
+ const stderr = errObj.stderr ? (typeof errObj.stderr === "string" ? errObj.stderr : errObj.stderr.toString("utf-8")).trim() : "";
639
+ const conflictDetails = stdout || stderr || (err instanceof Error ? err.message : String(err));
642
640
  results.push({ agentId: agent.id, name: agent.name, status: "conflict", conflictDetails });
643
641
  }
644
642
  }
@@ -687,7 +685,7 @@ Task: {{INSTRUCTION}}`;
687
685
  if (worktreeContext) {
688
686
  worktreeBlock = [
689
687
  "## Worktree Context",
690
- `You are working in worktree ${worktreeContext.offset} of ${worktreeContext.total} concurrent worktrees on branch \`${worktreeContext.branchName}\`.`,
688
+ `You are working in an isolated git worktree on branch \`${worktreeContext.branchName}\`.`,
691
689
  `If you start any services that require ports, add ${worktreeContext.offset} to the default port.`
692
690
  ].join("\n");
693
691
  }
@@ -705,7 +703,7 @@ async function spawnAgent(opts) {
705
703
  let branchName;
706
704
  let worktreeContext;
707
705
  if (opts.worktree) {
708
- const wt = createWorktree(cwd, sessionId, agentId);
706
+ const wt = createWorktreeShell(cwd, sessionId, agentId);
709
707
  worktreePath = wt.worktreePath;
710
708
  branchName = wt.branchName;
711
709
  paneCwd = worktreePath;
@@ -728,7 +726,7 @@ async function spawnAgent(opts) {
728
726
  ].join(" && ");
729
727
  const agentFlag = agentType ? ` --agent ${shellQuote3(agentType)}` : "";
730
728
  const claudeCmd = `claude --dangerously-skip-permissions --plugin-dir "${pluginPath}"${agentFlag} --append-system-prompt "$(cat '${suffixFilePath}')" ${shellQuote3(instruction)}`;
731
- sendKeys(paneId, `${bannerCmd} ${envExports} && ${claudeCmd}`);
729
+ const fullCmd = `${bannerCmd} ${envExports} && ${claudeCmd}`;
732
730
  const agent = {
733
731
  id: agentId,
734
732
  name,
@@ -743,6 +741,24 @@ async function spawnAgent(opts) {
743
741
  ...worktreePath ? { worktreePath, branchName, mergeStatus: "pending" } : {}
744
742
  };
745
743
  await addAgent(cwd, sessionId, agent);
744
+ if (opts.worktree && worktreePath) {
745
+ const config = loadWorktreeConfig(cwd);
746
+ if (config) {
747
+ const wtPath = worktreePath;
748
+ setImmediate(() => {
749
+ try {
750
+ bootstrapWorktree(cwd, wtPath, config);
751
+ } catch (err) {
752
+ console.error(`[sisyphus] worktree bootstrap failed for ${agentId}: ${err instanceof Error ? err.message : err}`);
753
+ }
754
+ sendKeys(paneId, fullCmd);
755
+ });
756
+ } else {
757
+ sendKeys(paneId, fullCmd);
758
+ }
759
+ } else {
760
+ sendKeys(paneId, fullCmd);
761
+ }
746
762
  return agent;
747
763
  }
748
764
  function nextReportNumber(cwd, sessionId, agentId) {
@@ -914,8 +930,44 @@ async function startSession(task, cwd, tmuxSession, windowId) {
914
930
  trackSession(sessionId, cwd, tmuxSession);
915
931
  await spawnOrchestrator(sessionId, cwd, windowId);
916
932
  updateTrackedWindow(sessionId, windowId);
933
+ pruneOldSessions(cwd);
917
934
  return session;
918
935
  }
936
+ var PRUNE_KEEP_COUNT = 10;
937
+ var PRUNE_KEEP_DAYS = 7;
938
+ function pruneOldSessions(cwd) {
939
+ try {
940
+ const dir = sessionsDir(cwd);
941
+ if (!existsSync4(dir)) return;
942
+ const entries = readdirSync4(dir, { withFileTypes: true });
943
+ const candidates = [];
944
+ for (const entry of entries) {
945
+ if (!entry.isDirectory()) continue;
946
+ try {
947
+ const session = getSession(cwd, entry.name);
948
+ if (session.status === "active" || session.status === "paused") continue;
949
+ candidates.push({ id: session.id, createdAt: new Date(session.createdAt).getTime() });
950
+ } catch {
951
+ }
952
+ }
953
+ if (candidates.length <= PRUNE_KEEP_COUNT) return;
954
+ candidates.sort((a, b) => b.createdAt - a.createdAt);
955
+ const cutoff = Date.now() - PRUNE_KEEP_DAYS * 24 * 60 * 60 * 1e3;
956
+ const keep = /* @__PURE__ */ new Set();
957
+ for (let i = 0; i < Math.min(PRUNE_KEEP_COUNT, candidates.length); i++) {
958
+ keep.add(candidates[i].id);
959
+ }
960
+ for (const c of candidates) {
961
+ if (c.createdAt >= cutoff) keep.add(c.id);
962
+ }
963
+ for (const c of candidates) {
964
+ if (keep.has(c.id)) continue;
965
+ rmSync2(sessionDir(cwd, c.id), { recursive: true, force: true });
966
+ }
967
+ } catch (err) {
968
+ console.error("[sisyphus] Session pruning failed:", err);
969
+ }
970
+ }
919
971
  async function resumeSession(sessionId, cwd, tmuxSession, windowId, message) {
920
972
  const session = getSession(cwd, sessionId);
921
973
  if (session.status !== "active") {
@@ -973,14 +1025,17 @@ function listSessions(cwd) {
973
1025
  }
974
1026
  return sessions;
975
1027
  }
1028
+ var pendingRespawns = /* @__PURE__ */ new Set();
976
1029
  function onAllAgentsDone2(sessionId, cwd, windowId) {
1030
+ if (pendingRespawns.has(sessionId)) return;
977
1031
  const session = getSession(cwd, sessionId);
978
1032
  if (session.status !== "active") return;
1033
+ pendingRespawns.add(sessionId);
979
1034
  const worktreeAgents = session.agents.filter((a) => a.worktreePath && a.mergeStatus === "pending");
980
1035
  if (worktreeAgents.length > 0) {
981
1036
  const results = mergeWorktrees(cwd, worktreeAgents);
982
1037
  for (const result of results) {
983
- const mergeStatus = result.status === "conflict" ? "conflict" : "merged";
1038
+ const mergeStatus = result.status;
984
1039
  updateAgent(cwd, sessionId, result.agentId, {
985
1040
  mergeStatus,
986
1041
  mergeDetails: result.conflictDetails
@@ -988,6 +1043,7 @@ function onAllAgentsDone2(sessionId, cwd, windowId) {
988
1043
  }
989
1044
  }
990
1045
  setTimeout(() => {
1046
+ pendingRespawns.delete(sessionId);
991
1047
  spawnOrchestrator(sessionId, cwd, windowId).then(() => updateTrackedWindow(sessionId, windowId)).catch((err) => console.error(`[sisyphus] Failed to respawn orchestrator for session ${sessionId}:`, err));
992
1048
  }, 2e3);
993
1049
  }
@@ -1016,7 +1072,19 @@ async function handleReport(cwd, sessionId, agentId, content) {
1016
1072
  await handleAgentReport(cwd, sessionId, agentId, content);
1017
1073
  }
1018
1074
  async function handleYield(sessionId, cwd, nextPrompt) {
1075
+ const pre = getSession(cwd, sessionId);
1076
+ if (pre.status === "paused") {
1077
+ await updateSessionStatus(cwd, sessionId, "active");
1078
+ }
1019
1079
  await handleOrchestratorYield(sessionId, cwd, nextPrompt);
1080
+ const session = getSession(cwd, sessionId);
1081
+ const hasRunningAgents = session.agents.some((a) => a.status === "running");
1082
+ if (!hasRunningAgents) {
1083
+ const windowId = getWindowId(sessionId);
1084
+ if (windowId) {
1085
+ onAllAgentsDone2(sessionId, cwd, windowId);
1086
+ }
1087
+ }
1020
1088
  }
1021
1089
  async function handleComplete(sessionId, cwd, report) {
1022
1090
  await handleOrchestratorComplete(sessionId, cwd, report);
@@ -1415,6 +1483,11 @@ switch (command) {
1415
1483
  const wait = Date.now() + 500;
1416
1484
  while (Date.now() < wait) {
1417
1485
  }
1486
+ const respawnedPid = readPid();
1487
+ if (respawnedPid) {
1488
+ console.log(`[sisyphus] Daemon restarted (pid ${respawnedPid}) by process manager`);
1489
+ break;
1490
+ }
1418
1491
  startDaemon().catch((err) => {
1419
1492
  console.error("[sisyphus] Fatal error:", err);
1420
1493
  process.exit(1);
@@ -1428,9 +1501,20 @@ switch (command) {
1428
1501
  process.exit(1);
1429
1502
  });
1430
1503
  break;
1504
+ case "help":
1505
+ case "--help":
1506
+ case "-h":
1507
+ console.log("Usage: sisyphusd [command]");
1508
+ console.log("");
1509
+ console.log("Commands:");
1510
+ console.log(" start Start the daemon (default if no command given)");
1511
+ console.log(" stop Stop the running daemon");
1512
+ console.log(" restart Stop and restart the daemon");
1513
+ console.log(" help Show this help message");
1514
+ break;
1431
1515
  default:
1432
1516
  console.error(`[sisyphus] Unknown command: ${command}`);
1433
- console.error("Usage: sisyphusd [start|stop|restart]");
1517
+ console.error("Usage: sisyphusd [start|stop|restart|help]");
1434
1518
  process.exit(1);
1435
1519
  }
1436
1520
  //# sourceMappingURL=daemon.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/daemon/index.ts","../src/shared/config.ts","../src/daemon/server.ts","../src/daemon/session-manager.ts","../src/daemon/state.ts","../src/daemon/orchestrator.ts","../src/daemon/colors.ts","../src/daemon/tmux.ts","../src/daemon/agent.ts","../src/daemon/worktree.ts","../src/daemon/pane-monitor.ts"],"sourcesContent":["import { mkdirSync, readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs';\nimport { globalDir, daemonPidPath, statePath } from '../shared/paths.js';\nimport { loadConfig } from '../shared/config.js';\nimport { startServer, stopServer, registerSessionCwd, registerSessionTmux, loadSessionRegistry } from './server.js';\nimport { startMonitor, stopMonitor, setRespawnCallback, trackSession, updateTrackedWindow } from './pane-monitor.js';\nimport { onAllAgentsDone } from './session-manager.js';\nimport { resetAgentCounterFromState } from './agent.js';\nimport { setWindowId, setOrchestratorPaneId, getOrchestratorPaneId } from './orchestrator.js';\nimport { listPanes } from './tmux.js';\nimport * as stateModule from './state.js';\nimport type { Session } from '../shared/types.js';\n\nfunction ensureDirs(): void {\n mkdirSync(globalDir(), { recursive: true });\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction readPid(): number | null {\n const pidFile = daemonPidPath();\n try {\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n return pid && isProcessAlive(pid) ? pid : null;\n } catch {\n return null;\n }\n}\n\nfunction acquirePidLock(): void {\n const pid = readPid();\n if (pid) {\n console.error(`[sisyphus] Daemon already running (pid ${pid}). Use 'sisyphusd restart' or 'sisyphusd stop' first.`);\n process.exit(0);\n }\n writeFileSync(daemonPidPath(), String(process.pid), 'utf-8');\n}\n\nfunction releasePidLock(): void {\n try {\n unlinkSync(daemonPidPath());\n } catch {\n // Already gone\n }\n}\n\nfunction stopDaemon(): boolean {\n const pid = readPid();\n if (!pid) {\n console.log('[sisyphus] Daemon is not running');\n // Clean up stale pid file if it exists\n releasePidLock();\n return false;\n }\n\n console.log(`[sisyphus] Stopping daemon (pid ${pid})...`);\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n console.error(`[sisyphus] Failed to send SIGTERM to pid ${pid}`);\n return false;\n }\n\n // Wait for process to exit (up to 5s)\n const deadline = Date.now() + 5000;\n while (Date.now() < deadline) {\n if (!isProcessAlive(pid)) {\n console.log('[sisyphus] Daemon stopped');\n releasePidLock();\n return true;\n }\n // Busy-wait in small increments (synchronous — fine for a CLI command)\n const wait = Date.now() + 100;\n while (Date.now() < wait) { /* spin */ }\n }\n\n console.error(`[sisyphus] Daemon (pid ${pid}) did not exit within 5s, sending SIGKILL`);\n try {\n process.kill(pid, 'SIGKILL');\n } catch { /* already dead */ }\n releasePidLock();\n return true;\n}\n\nasync function recoverSessions(): Promise<void> {\n const registry = loadSessionRegistry();\n const entries = Object.entries(registry);\n\n if (entries.length === 0) {\n console.log('[sisyphus] No sessions to recover');\n return;\n }\n\n let recovered = 0;\n for (const [sessionId, cwd] of entries) {\n const stateFile = statePath(cwd, sessionId);\n if (!existsSync(stateFile)) {\n continue;\n }\n\n try {\n const session = JSON.parse(readFileSync(stateFile, 'utf-8')) as Session;\n if (session.status === 'active' || session.status === 'paused') {\n registerSessionCwd(sessionId, cwd);\n resetAgentCounterFromState(sessionId, session.agents ?? []);\n\n // Reconnect to tmux panes if info was persisted\n if (session.tmuxSessionName && session.tmuxWindowId) {\n const livePanes = listPanes(session.tmuxWindowId);\n if (livePanes.length > 0) {\n registerSessionTmux(sessionId, session.tmuxSessionName, session.tmuxWindowId);\n setWindowId(sessionId, session.tmuxWindowId);\n trackSession(sessionId, cwd, session.tmuxSessionName);\n updateTrackedWindow(sessionId, session.tmuxWindowId);\n\n // Recover orchestrator pane from last incomplete cycle\n const lastIncompleteCycle = [...session.orchestratorCycles].reverse().find(c => !c.completedAt && c.paneId);\n if (lastIncompleteCycle?.paneId) {\n setOrchestratorPaneId(sessionId, lastIncompleteCycle.paneId);\n }\n\n console.log(`[sisyphus] Reconnected session ${sessionId} to tmux window ${session.tmuxWindowId}`);\n\n // Detect sessions stuck in \"all agents done, no orchestrator\" state\n if (session.status === 'active' && session.agents.length > 0) {\n const hasRunningAgents = session.agents.some(a => a.status === 'running');\n if (!hasRunningAgents) {\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n const orchestratorPaneId = getOrchestratorPaneId(sessionId);\n const orchestratorAlive = orchestratorPaneId && livePaneIds.has(orchestratorPaneId);\n if (!orchestratorAlive) {\n console.log(`[sisyphus] Detected stuck session ${sessionId} on recovery: triggering orchestrator respawn`);\n await onAllAgentsDone(sessionId, cwd, session.tmuxWindowId!);\n }\n }\n }\n } else {\n // Window gone — pause the session so user can `sisyphus resume`\n if (session.status === 'active') {\n await stateModule.updateSessionStatus(cwd, sessionId, 'paused');\n console.log(`[sisyphus] Session ${sessionId} paused: tmux window no longer exists`);\n }\n }\n }\n\n recovered++;\n }\n } catch {\n console.error(`[sisyphus] Failed to read session state for ${sessionId}, skipping`);\n }\n }\n\n console.log(`[sisyphus] Recovered ${recovered} session(s) from registry`);\n}\n\nasync function startDaemon(): Promise<void> {\n console.log('[sisyphus] Starting daemon...');\n ensureDirs();\n acquirePidLock();\n\n const config = loadConfig(process.cwd());\n\n setRespawnCallback(onAllAgentsDone);\n\n await startServer();\n startMonitor(config.pollIntervalMs);\n\n await recoverSessions();\n\n const shutdown = async () => {\n console.log('[sisyphus] Shutting down...');\n stopMonitor();\n await stopServer();\n releasePidLock();\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nconst command = process.argv[2];\n\nswitch (command) {\n case 'stop':\n stopDaemon();\n break;\n\n case 'restart': {\n stopDaemon();\n // Small delay to let socket release\n const wait = Date.now() + 500;\n while (Date.now() < wait) { /* spin */ }\n startDaemon().catch((err) => {\n console.error('[sisyphus] Fatal error:', err);\n process.exit(1);\n });\n break;\n }\n\n case 'start':\n case undefined:\n startDaemon().catch((err) => {\n console.error('[sisyphus] Fatal error:', err);\n process.exit(1);\n });\n break;\n\n default:\n console.error(`[sisyphus] Unknown command: ${command}`);\n console.error('Usage: sisyphusd [start|stop|restart]');\n process.exit(1);\n}\n","import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport interface WorktreeConfig {\n copy?: string[];\n clone?: string[];\n symlink?: string[];\n init?: string;\n}\n\nexport interface Config {\n model?: string;\n tmuxSession?: string;\n orchestratorPrompt?: string;\n pollIntervalMs?: number;\n}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 1000,\n};\n\nfunction readJsonFile(filePath: string): Partial<Config> {\n try {\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as Partial<Config>;\n } catch {\n return {};\n }\n}\n\nexport function loadConfig(cwd: string): Config {\n const global = readJsonFile(globalConfigPath());\n const project = readJsonFile(projectConfigPath(cwd));\n return { ...DEFAULT_CONFIG, ...global, ...project };\n}\n","import { createServer, type Server } from 'node:net';\nimport { unlinkSync, existsSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs';\nimport { socketPath, globalDir } from '../shared/paths.js';\nimport { join } from 'node:path';\nimport type { Request, Response } from '../shared/protocol.js';\nimport * as sessionManager from './session-manager.js';\n\nlet server: Server | null = null;\n\n// Track the cwd for each session so we can route requests\nconst sessionCwdMap = new Map<string, string>();\n// Track the originating tmux session for each sisyphus session\nconst sessionTmuxMap = new Map<string, string>();\n// Track the originating tmux window for each sisyphus session\nconst sessionWindowMap = new Map<string, string>();\n\nexport function getSessionCwd(sessionId: string): string | undefined {\n return sessionCwdMap.get(sessionId);\n}\n\nexport function getSessionTmux(sessionId: string): string | undefined {\n return sessionTmuxMap.get(sessionId);\n}\n\nfunction registryPath(): string {\n return join(globalDir(), 'session-registry.json');\n}\n\nfunction persistSessionRegistry(): void {\n const dir = globalDir();\n mkdirSync(dir, { recursive: true });\n const registry: Record<string, string> = {};\n for (const [id, cwd] of sessionCwdMap) {\n registry[id] = cwd;\n }\n writeFileSync(registryPath(), JSON.stringify(registry, null, 2), 'utf-8');\n}\n\nexport function loadSessionRegistry(): Record<string, string> {\n const p = registryPath();\n if (!existsSync(p)) return {};\n try {\n return JSON.parse(readFileSync(p, 'utf-8')) as Record<string, string>;\n } catch {\n return {};\n }\n}\n\nexport function registerSessionCwd(sessionId: string, cwd: string): void {\n sessionCwdMap.set(sessionId, cwd);\n persistSessionRegistry();\n}\n\nexport function registerSessionTmux(sessionId: string, tmuxSession: string, windowId: string): void {\n sessionTmuxMap.set(sessionId, tmuxSession);\n sessionWindowMap.set(sessionId, windowId);\n}\n\nasync function handleRequest(req: Request): Promise<Response> {\n try {\n switch (req.type) {\n case 'start': {\n const session = await sessionManager.startSession(req.task, req.cwd, req.tmuxSession, req.tmuxWindow);\n registerSessionCwd(session.id, req.cwd);\n sessionTmuxMap.set(session.id, req.tmuxSession);\n sessionWindowMap.set(session.id, req.tmuxWindow);\n return { ok: true, data: { sessionId: session.id } };\n }\n\n case 'spawn': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const result = await sessionManager.handleSpawn(req.sessionId, cwd, req.agentType, req.name, req.instruction, req.worktree);\n return { ok: true, data: { agentId: result.agentId } };\n }\n\n case 'submit': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const windowId = sessionWindowMap.get(req.sessionId);\n if (!windowId) return { ok: false, error: `No tmux window found for session: ${req.sessionId}` };\n await sessionManager.handleSubmit(cwd, req.sessionId, req.agentId, req.report, windowId);\n return { ok: true };\n }\n\n case 'report': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleReport(cwd, req.sessionId, req.agentId, req.content);\n return { ok: true };\n }\n\n case 'yield': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleYield(req.sessionId, cwd, req.nextPrompt);\n return { ok: true };\n }\n\n case 'complete': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleComplete(req.sessionId, cwd, req.report);\n return { ok: true };\n }\n\n case 'status': {\n if (req.sessionId) {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const session = sessionManager.getSessionStatus(cwd, req.sessionId);\n return { ok: true, data: { session: session as unknown as Record<string, unknown> } };\n }\n return { ok: true, data: { message: 'daemon running' } };\n }\n\n case 'list': {\n const allSessions: Array<Record<string, unknown>> = [];\n if (req.all) {\n // List sessions across all known cwds\n const seenCwds = new Set<string>();\n for (const cwd of sessionCwdMap.values()) {\n if (seenCwds.has(cwd)) continue;\n seenCwds.add(cwd);\n const sessions = sessionManager.listSessions(cwd);\n allSessions.push(...sessions.map(s => ({ ...s, cwd } as unknown as Record<string, unknown>)));\n }\n } else {\n // List sessions for the requesting cwd only\n const sessions = sessionManager.listSessions(req.cwd);\n allSessions.push(...sessions.map(s => ({ ...s, cwd: req.cwd } as unknown as Record<string, unknown>)));\n // Count total across all cwds for the hint\n let totalCount = allSessions.length;\n const seenCwds = new Set<string>([req.cwd]);\n for (const cwd of sessionCwdMap.values()) {\n if (seenCwds.has(cwd)) continue;\n seenCwds.add(cwd);\n totalCount += sessionManager.listSessions(cwd).length;\n }\n if (totalCount > allSessions.length) {\n return { ok: true, data: { sessions: allSessions, totalCount, filtered: true } };\n }\n }\n return { ok: true, data: { sessions: allSessions } };\n }\n\n case 'resume': {\n let cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) {\n // Session not in memory — try to recover from disk using the cwd provided by CLI\n const stateFile = `${req.cwd}/.sisyphus/sessions/${req.sessionId}/state.json`;\n if (existsSync(stateFile)) {\n cwd = req.cwd;\n registerSessionCwd(req.sessionId, cwd);\n } else {\n return { ok: false, error: `Unknown session: ${req.sessionId}. No state.json found at ${stateFile}` };\n }\n }\n sessionTmuxMap.set(req.sessionId, req.tmuxSession);\n sessionWindowMap.set(req.sessionId, req.tmuxWindow);\n const session = await sessionManager.resumeSession(req.sessionId, cwd, req.tmuxSession, req.tmuxWindow, req.message);\n return { ok: true, data: { sessionId: session.id, status: session.status } };\n }\n\n case 'register_claude_session': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleRegisterClaudeSession(cwd, req.sessionId, req.agentId, req.claudeSessionId);\n return { ok: true };\n }\n\n case 'kill': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const killedAgents = await sessionManager.handleKill(req.sessionId, cwd);\n sessionCwdMap.delete(req.sessionId);\n sessionTmuxMap.delete(req.sessionId);\n sessionWindowMap.delete(req.sessionId);\n persistSessionRegistry();\n return { ok: true, data: { killedAgents, sessionId: req.sessionId } };\n }\n\n default:\n return { ok: false, error: `Unknown request type: ${(req as Record<string, unknown>).type}` };\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { ok: false, error: message };\n }\n}\n\nexport function startServer(): Promise<Server> {\n return new Promise((resolve, reject) => {\n const sock = socketPath();\n\n if (existsSync(sock)) {\n unlinkSync(sock);\n }\n\n server = createServer((conn) => {\n let buffer = '';\n\n conn.on('data', (chunk) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop()!;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n let req: Request;\n try {\n req = JSON.parse(line) as Request;\n } catch {\n conn.write(JSON.stringify({ ok: false, error: 'Invalid JSON' }) + '\\n');\n continue;\n }\n\n handleRequest(req).then((res) => {\n conn.write(JSON.stringify(res) + '\\n');\n });\n }\n });\n\n conn.on('error', (err) => {\n console.error('[sisyphus] Connection error:', err.message);\n });\n });\n\n server.on('error', reject);\n\n server.listen(sock, () => {\n console.log(`[sisyphus] Daemon listening on ${sock}`);\n resolve(server!);\n });\n });\n}\n\nexport function stopServer(): Promise<void> {\n return new Promise((resolve) => {\n if (!server) {\n resolve();\n return;\n }\n server.close(() => {\n const sock = socketPath();\n if (existsSync(sock)) {\n unlinkSync(sock);\n }\n server = null;\n resolve();\n });\n });\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { existsSync, readdirSync } from 'node:fs';\nimport * as state from './state.js';\nimport * as orchestrator from './orchestrator.js';\nimport * as tmux from './tmux.js';\nimport { spawnAgent, resetAgentCounterFromState, clearAgentCounter, handleAgentSubmit, handleAgentReport } from './agent.js';\nimport { trackSession, untrackSession, updateTrackedWindow } from './pane-monitor.js';\nimport { resetColors } from './colors.js';\nimport { sessionsDir } from '../shared/paths.js';\nimport type { Session } from '../shared/types.js';\nimport { mergeWorktrees, cleanupWorktree } from './worktree.js';\n\nexport async function startSession(task: string, cwd: string, tmuxSession: string, windowId: string): Promise<Session> {\n const sessionId = uuidv4();\n const session = state.createSession(sessionId, task, cwd);\n await state.updateSessionTmux(cwd, sessionId, tmuxSession, windowId);\n\n trackSession(sessionId, cwd, tmuxSession);\n await orchestrator.spawnOrchestrator(sessionId, cwd, windowId);\n updateTrackedWindow(sessionId, windowId);\n\n return session;\n}\n\nexport async function resumeSession(sessionId: string, cwd: string, tmuxSession: string, windowId: string, message?: string): Promise<Session> {\n const session = state.getSession(cwd, sessionId);\n\n if (session.status !== 'active') {\n // Determine which agents still have live panes\n const livePaneIds = new Set<string>();\n if (session.tmuxWindowId) {\n const panes = tmux.listPanes(session.tmuxWindowId);\n for (const pane of panes) {\n livePaneIds.add(pane.paneId);\n }\n }\n\n // Mark running agents as \"lost\" only if their pane is gone (or no window ID to check)\n for (const agent of session.agents) {\n if (agent.status === 'running') {\n const isAlive = agent.paneId != null && livePaneIds.has(agent.paneId);\n if (!isAlive) {\n await state.updateAgent(cwd, sessionId, agent.id, {\n status: 'lost',\n completedAt: new Date().toISOString(),\n killedReason: 'session resumed — agent was still running',\n });\n }\n }\n }\n }\n\n await state.updateSessionStatus(cwd, sessionId, 'active');\n await state.updateSessionTmux(cwd, sessionId, tmuxSession, windowId);\n\n // Reset counters based on existing agents\n resetAgentCounterFromState(sessionId, session.agents);\n resetColors(sessionId);\n\n trackSession(sessionId, cwd, tmuxSession);\n await orchestrator.spawnOrchestrator(sessionId, cwd, windowId, message);\n updateTrackedWindow(sessionId, windowId);\n\n return state.getSession(cwd, sessionId);\n}\n\nexport function getSessionStatus(cwd: string, sessionId: string): Session {\n return state.getSession(cwd, sessionId);\n}\n\nexport function listSessions(cwd: string): Array<{ id: string; task: string; status: string; createdAt: string; agentCount: number }> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return [];\n\n const entries = readdirSync(dir, { withFileTypes: true });\n const sessions: Array<{ id: string; task: string; status: string; createdAt: string; agentCount: number }> = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n try {\n const session = state.getSession(cwd, entry.name);\n sessions.push({\n id: session.id,\n task: session.task,\n status: session.status,\n createdAt: session.createdAt,\n agentCount: session.agents.length,\n });\n } catch (err) {\n console.error(`[sisyphus] Failed to read session ${entry.name}:`, err);\n }\n }\n\n return sessions;\n}\n\nexport function onAllAgentsDone(sessionId: string, cwd: string, windowId: string): void {\n const session = state.getSession(cwd, sessionId);\n if (session.status !== 'active') return;\n\n // Merge any worktree agents before respawning orchestrator\n const worktreeAgents = session.agents.filter(a => a.worktreePath && a.mergeStatus === 'pending');\n if (worktreeAgents.length > 0) {\n const results = mergeWorktrees(cwd, worktreeAgents);\n for (const result of results) {\n const mergeStatus = result.status === 'conflict' ? 'conflict' as const : 'merged' as const;\n state.updateAgent(cwd, sessionId, result.agentId, {\n mergeStatus,\n mergeDetails: result.conflictDetails,\n }).catch((err: unknown) => console.error(`[sisyphus] Failed to update merge status for ${result.agentId}:`, err));\n }\n }\n\n // Delay to let /exit finish quitting the previous Claude session\n setTimeout(() => {\n orchestrator.spawnOrchestrator(sessionId, cwd, windowId)\n .then(() => updateTrackedWindow(sessionId, windowId))\n .catch((err: unknown) => console.error(`[sisyphus] Failed to respawn orchestrator for session ${sessionId}:`, err));\n }, 2000);\n}\n\nexport async function handleSpawn(\n sessionId: string,\n cwd: string,\n agentType: string,\n name: string,\n instruction: string,\n worktree?: boolean,\n): Promise<{ agentId: string }> {\n const windowId = orchestrator.getWindowId(sessionId);\n if (!windowId) throw new Error(`No tmux window found for session ${sessionId}`);\n\n const agent = await spawnAgent({\n sessionId,\n cwd,\n agentType,\n name,\n instruction,\n windowId,\n worktree,\n });\n\n await state.appendAgentToLastCycle(cwd, sessionId, agent.id);\n\n return { agentId: agent.id };\n}\n\nexport async function handleSubmit(cwd: string, sessionId: string, agentId: string, report: string, windowId: string): Promise<void> {\n const allDone = await handleAgentSubmit(cwd, sessionId, agentId, report);\n if (allDone) {\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n}\n\nexport async function handleReport(cwd: string, sessionId: string, agentId: string, content: string): Promise<void> {\n await handleAgentReport(cwd, sessionId, agentId, content);\n}\n\nexport async function handleYield(sessionId: string, cwd: string, nextPrompt?: string): Promise<void> {\n await orchestrator.handleOrchestratorYield(sessionId, cwd, nextPrompt);\n}\n\nexport async function handleComplete(sessionId: string, cwd: string, report: string): Promise<void> {\n await orchestrator.handleOrchestratorComplete(sessionId, cwd, report);\n}\n\nexport async function handleRegisterClaudeSession(\n cwd: string,\n sessionId: string,\n agentId: string,\n claudeSessionId: string,\n): Promise<void> {\n await state.updateAgent(cwd, sessionId, agentId, { claudeSessionId });\n}\n\nexport async function handleKill(sessionId: string, cwd: string): Promise<number> {\n const session = state.getSession(cwd, sessionId);\n const windowId = orchestrator.getWindowId(sessionId);\n\n // Kill all running agents\n let killedAgents = 0;\n for (const agent of session.agents) {\n if (agent.status === 'running') {\n await state.updateAgent(cwd, sessionId, agent.id, {\n status: 'killed',\n killedReason: 'session killed by user',\n completedAt: new Date().toISOString(),\n });\n killedAgents++;\n }\n }\n\n // Clean up worktrees for agents that had them\n for (const agent of session.agents) {\n if (agent.worktreePath && agent.branchName) {\n cleanupWorktree(cwd, agent.worktreePath, agent.branchName);\n }\n }\n\n // Kill the orchestrator pane if it exists\n const orchPaneId = orchestrator.getOrchestratorPaneId(sessionId);\n if (orchPaneId) {\n tmux.killPane(orchPaneId);\n }\n\n // Mark session as completed\n await state.updateSessionStatus(cwd, sessionId, 'completed');\n\n // Untrack from pane monitor\n untrackSession(sessionId);\n\n // Kill the entire tmux window\n if (windowId) {\n tmux.killWindow(windowId);\n }\n\n // Clean up agent counter\n clearAgentCounter(sessionId);\n\n return killedAgents;\n}\n","import { readFileSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport type { Session, Agent, AgentReport, OrchestratorCycle, SessionStatus } from '../shared/types.js';\nimport { statePath, sessionDir, contextDir, promptsDir, planPath, logsPath } from '../shared/paths.js';\n\nconst PLAN_SEED = `---\ndescription: >\n Living document of what still needs to happen. Write your remaining work plan\n here: phases, next steps, file references, open questions. Remove or collapse\n items as they're completed so this file only reflects outstanding work. The\n orchestrator sees this every cycle — keep it focused and current.\n---\n`;\n\nconst LOGS_SEED = `---\ndescription: >\n Session memory. Record important observations, decisions, and findings here.\n This is your persistent memory across cycles: things you tried, what\n worked/failed, design decisions and their rationale, gotchas discovered during\n implementation. Unlike plan.md, entries here accumulate — they're a log.\n---\n`;\n\n// Per-session mutex to prevent read-modify-write races\nconst sessionLocks = new Map<string, Promise<void>>();\n\nasync function withSessionLock<T>(sessionId: string, fn: () => T): Promise<T> {\n const prev = sessionLocks.get(sessionId) ?? Promise.resolve();\n let resolve: () => void;\n const next = new Promise<void>(r => { resolve = r; });\n sessionLocks.set(sessionId, next);\n await prev;\n try {\n return fn();\n } finally {\n resolve!();\n }\n}\n\nfunction atomicWrite(filePath: string, data: string): void {\n const dir = dirname(filePath);\n const tmpPath = join(dir, `.state.${randomUUID()}.tmp`);\n writeFileSync(tmpPath, data, 'utf-8');\n renameSync(tmpPath, filePath);\n}\n\nexport function createSession(id: string, task: string, cwd: string): Session {\n const dir = sessionDir(cwd, id);\n mkdirSync(dir, { recursive: true });\n mkdirSync(contextDir(cwd, id), { recursive: true });\n mkdirSync(promptsDir(cwd, id), { recursive: true });\n\n writeFileSync(planPath(cwd, id), PLAN_SEED, 'utf-8');\n writeFileSync(logsPath(cwd, id), LOGS_SEED, 'utf-8');\n\n const session: Session = {\n id,\n task,\n cwd,\n status: 'active',\n createdAt: new Date().toISOString(),\n agents: [],\n orchestratorCycles: [],\n };\n\n atomicWrite(statePath(cwd, id), JSON.stringify(session, null, 2));\n return session;\n}\n\nexport function getSession(cwd: string, sessionId: string): Session {\n const content = readFileSync(statePath(cwd, sessionId), 'utf-8');\n return JSON.parse(content) as Session;\n}\n\nfunction saveSession(session: Session): void {\n atomicWrite(statePath(session.cwd, session.id), JSON.stringify(session, null, 2));\n}\n\nexport async function addAgent(cwd: string, sessionId: string, agent: Agent): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.agents.push(agent);\n saveSession(session);\n });\n}\n\nexport async function updateAgent(cwd: string, sessionId: string, agentId: string, updates: Partial<Agent>): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n Object.assign(agent, updates);\n saveSession(session);\n });\n}\n\nexport async function addOrchestratorCycle(cwd: string, sessionId: string, cycle: OrchestratorCycle): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.orchestratorCycles.push(cycle);\n saveSession(session);\n });\n}\n\nexport async function updateSessionStatus(cwd: string, sessionId: string, status: SessionStatus, completionReport?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = status;\n if (completionReport !== undefined) {\n session.completionReport = completionReport;\n }\n saveSession(session);\n });\n}\n\nexport async function appendAgentToLastCycle(cwd: string, sessionId: string, agentId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n cycles[cycles.length - 1]!.agentsSpawned.push(agentId);\n saveSession(session);\n });\n}\n\nexport async function completeSession(cwd: string, sessionId: string, report: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = 'completed';\n session.completedAt = new Date().toISOString();\n session.completionReport = report;\n saveSession(session);\n });\n}\n\nexport async function appendAgentReport(cwd: string, sessionId: string, agentId: string, entry: AgentReport): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n agent.reports.push(entry);\n saveSession(session);\n });\n}\n\nexport async function updateSessionTmux(cwd: string, sessionId: string, tmuxSessionName: string, tmuxWindowId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.tmuxSessionName = tmuxSessionName;\n session.tmuxWindowId = tmuxWindowId;\n saveSession(session);\n });\n}\n\nexport async function completeOrchestratorCycle(cwd: string, sessionId: string, nextPrompt?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n const cycle = cycles[cycles.length - 1]!;\n cycle.completedAt = new Date().toISOString();\n if (nextPrompt) cycle.nextPrompt = nextPrompt;\n saveSession(session);\n });\n}\n","import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { contextDir, logsPath, planPath, projectOrchestratorPromptPath, promptsDir, worktreeConfigPath } from '../shared/paths.js';\nimport type { Agent, Session } from '../shared/types.js';\nimport { ORCHESTRATOR_COLOR } from './colors.js';\nimport * as state from './state.js';\nimport * as tmux from './tmux.js';\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nconst sessionWindowMap = new Map<string, string>();\nconst sessionOrchestratorPane = new Map<string, string>();\n\nexport function getWindowId(sessionId: string): string | undefined {\n return sessionWindowMap.get(sessionId);\n}\n\nexport function setWindowId(sessionId: string, windowId: string): void {\n sessionWindowMap.set(sessionId, windowId);\n}\n\nexport function getOrchestratorPaneId(sessionId: string): string | undefined {\n return sessionOrchestratorPane.get(sessionId);\n}\n\nexport function setOrchestratorPaneId(sessionId: string, paneId: string): void {\n sessionOrchestratorPane.set(sessionId, paneId);\n}\n\nfunction loadOrchestratorPrompt(cwd: string): string {\n const projectPath = projectOrchestratorPromptPath(cwd);\n if (existsSync(projectPath)) {\n return readFileSync(projectPath, 'utf-8');\n }\n const bundledPath = resolve(import.meta.dirname, '../templates/orchestrator.md');\n return readFileSync(bundledPath, 'utf-8');\n}\n\nfunction formatStateForOrchestrator(session: Session): string {\n const shortId = session.id.slice(0, 8);\n const cycleNum = session.orchestratorCycles.length;\n\n const ctxDir = contextDir(session.cwd, session.id);\n let contextLines: string;\n if (existsSync(ctxDir)) {\n const files = readdirSync(ctxDir);\n contextLines = files.length > 0 ? files.map(f => `- ${f}`).join('\\n') : ' (none)';\n } else {\n contextLines = ' (none)';\n }\n\n const planFile = planPath(session.cwd, session.id);\n const planRef = existsSync(planFile) ? `@${planFile}` : '(empty)';\n\n const logsFile = logsPath(session.cwd, session.id);\n const logsRef = existsSync(logsFile) ? `@${logsFile}` : '(empty)';\n\n const agentLines = session.agents.length > 0\n ? session.agents.map((a: Agent) => {\n const header = `- ${a.id} (${a.name}): ${a.status} — ${a.reports.length} report(s)`;\n if (a.reports.length === 0) return header;\n let updateNum = 0;\n const reportLines = a.reports.map(r => {\n const label = r.type === 'final' ? '[final]' : `[update ${String(++updateNum).padStart(3, '0')}]`;\n return ` ${label} \"${r.summary}\" → ${r.filePath}`;\n });\n return [header, ...reportLines].join('\\n');\n }).join('\\n')\n : ' (none)';\n\n const cycleLines = session.orchestratorCycles.length > 0\n ? session.orchestratorCycles.map(c => {\n const spawnedList = c.agentsSpawned.length > 0 ? c.agentsSpawned.join(', ') : '(none)';\n return `Cycle ${c.cycle}: Spawned ${spawnedList}`;\n }).join('\\n')\n : ' (none)';\n\n // Worktree status — only if any agents have worktree info\n const worktreeAgents = session.agents.filter(a => a.worktreePath);\n let worktreeSection = '';\n if (worktreeAgents.length > 0) {\n const wtLines = worktreeAgents.map((a: Agent) => {\n if (a.mergeStatus === 'conflict') {\n return `- ${a.id}: conflict — ${a.mergeDetails ?? 'unknown'}\\n Branch: ${a.branchName}\\n Worktree: ${a.worktreePath}`;\n }\n const status = a.mergeStatus ?? 'pending';\n return `- ${a.id}: ${status} (branch ${a.branchName})`;\n }).join('\\n');\n worktreeSection = `\\n\\n## Worktrees\\n${wtLines}`;\n }\n\n // Worktree hint\n const worktreeHint = existsSync(worktreeConfigPath(session.cwd))\n ? 'Worktree config active (`.sisyphus/worktree.json`). Use `--worktree` flag with `sisyphus spawn` to isolate agents in their own worktrees. Recommended for feature work, especially with potential file overlap.'\n : 'No worktree configuration found. If this session involves parallel work where agents may edit overlapping files, use the `git-management` skill to set up `.sisyphus/worktree.json` and enable worktree isolation.';\n\n return `<state>\nsession: ${shortId} (cycle ${cycleNum})\ntask: ${session.task}\nstatus: ${session.status}\n\n## Plan\n${planRef}\n\n## Logs\n${logsRef}\n\n## Agents\n${agentLines}${worktreeSection}\n\n## Previous Cycles\n${cycleLines}\n\n## Context Files\n${contextLines}\n\n## Git Worktrees\n${worktreeHint}\n</state>`;\n}\n\nexport async function spawnOrchestrator(sessionId: string, cwd: string, windowId: string, message?: string): Promise<void> {\n const session = state.getSession(cwd, sessionId);\n const basePrompt = loadOrchestratorPrompt(cwd);\n const formattedState = formatStateForOrchestrator(session);\n\n // System prompt: template only (no state)\n const cycleNum = session.orchestratorCycles.length + 1;\n const promptFilePath = `${promptsDir(cwd, sessionId)}/orchestrator-system-${cycleNum}.md`;\n writeFileSync(promptFilePath, basePrompt, 'utf-8');\n\n sessionWindowMap.set(sessionId, windowId);\n\n const envExports = [\n `export SISYPHUS_SESSION_ID='${sessionId}'`,\n `export SISYPHUS_AGENT_ID='orchestrator'`,\n ].join(' && ');\n\n // User message: state block + contextual prompt\n let userPrompt: string;\n if (message) {\n userPrompt = `${formattedState}\\n\\nThe user resumed this session with new instructions: ${message}`;\n } else {\n // Check last completed cycle for a stored nextPrompt\n const lastCycle = [...session.orchestratorCycles].reverse().find(c => c.completedAt);\n const storedPrompt = lastCycle?.nextPrompt;\n if (storedPrompt) {\n userPrompt = `${formattedState}\\n\\n${storedPrompt}`;\n } else {\n userPrompt = `${formattedState}\\n\\nReview the current session and delegate the next cycle of work.`;\n }\n }\n\n const userPromptFilePath = `${promptsDir(cwd, sessionId)}/orchestrator-user-${cycleNum}.md`;\n writeFileSync(userPromptFilePath, userPrompt, 'utf-8');\n const pluginPath = resolve(import.meta.dirname, '../templates/orchestrator-plugin');\n const settingsPath = resolve(import.meta.dirname, '../templates/orchestrator-settings.json');\n const claudeCmd = `claude --dangerously-skip-permissions --settings \"${settingsPath}\" --plugin-dir \"${pluginPath}\" --append-system-prompt \"$(cat '${promptFilePath}')\" \"$(cat '${userPromptFilePath}')\"`;\n\n const paneId = tmux.createPane(windowId, cwd);\n\n sessionOrchestratorPane.set(sessionId, paneId);\n tmux.setPaneTitle(paneId, `orchestrator (${sessionId.slice(0, 8)})`);\n tmux.setPaneStyle(paneId, ORCHESTRATOR_COLOR);\n\n const bannerPath = resolve(import.meta.dirname, '../templates/banner.txt');\n const bannerCmd = existsSync(bannerPath) ? `cat '${bannerPath}' &&` : '';\n tmux.sendKeys(paneId, `${bannerCmd} ${envExports} && ${claudeCmd}`);\n\n await state.addOrchestratorCycle(cwd, sessionId, {\n cycle: cycleNum,\n timestamp: new Date().toISOString(),\n agentsSpawned: [],\n paneId,\n });\n}\n\nfunction resolveOrchestratorPane(sessionId: string, cwd: string): string | undefined {\n const memPane = sessionOrchestratorPane.get(sessionId);\n if (memPane) return memPane;\n const session = state.getSession(cwd, sessionId);\n const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];\n return lastCycle?.paneId ?? undefined;\n}\n\nexport async function handleOrchestratorYield(sessionId: string, cwd: string, nextPrompt?: string): Promise<void> {\n const paneId = resolveOrchestratorPane(sessionId, cwd);\n if (paneId) {\n tmux.killPane(paneId);\n sessionOrchestratorPane.delete(sessionId);\n }\n\n const windowId = sessionWindowMap.get(sessionId);\n if (windowId) tmux.selectLayout(windowId);\n\n await state.completeOrchestratorCycle(cwd, sessionId, nextPrompt);\n\n const session = state.getSession(cwd, sessionId);\n const runningAgents = session.agents.filter(a => a.status === 'running');\n if (runningAgents.length === 0) {\n console.error(`[sisyphus] WARNING: Orchestrator yielded but no agents are running for session ${sessionId}`);\n }\n}\n\nexport async function handleOrchestratorComplete(sessionId: string, cwd: string, report: string): Promise<void> {\n await state.completeOrchestratorCycle(cwd, sessionId);\n await state.completeSession(cwd, sessionId, report);\n\n console.log(`[sisyphus] Session ${sessionId} completed: ${report}`);\n}\n\nexport function cleanupSessionMaps(sessionId: string): void {\n sessionOrchestratorPane.delete(sessionId);\n sessionWindowMap.delete(sessionId);\n}\n","import { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const ORCHESTRATOR_COLOR = 'yellow';\n\nconst AGENT_PALETTE = ['blue', 'green', 'magenta', 'cyan', 'red', 'white'] as const;\n\nconst TMUX_COLOR_MAP: Record<string, string> = {\n orange: 'colour208',\n teal: 'colour6',\n};\n\nfunction normalizeTmuxColor(color: string): string {\n return TMUX_COLOR_MAP[color] ?? color;\n}\n\nconst sessionColorIndex = new Map<string, number>();\n\nexport function getNextColor(sessionId: string): string {\n const idx = sessionColorIndex.get(sessionId) ?? 0;\n const color = AGENT_PALETTE[idx % AGENT_PALETTE.length]!;\n sessionColorIndex.set(sessionId, idx + 1);\n return color;\n}\n\nexport function resetColors(sessionId: string): void {\n sessionColorIndex.delete(sessionId);\n}\n\nfunction extractFrontmatterColor(content: string): string | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n const colorMatch = match[1]!.match(/^color:\\s*(.+)$/m);\n return colorMatch ? colorMatch[1]!.trim() : null;\n}\n\nfunction findPluginInstallPath(namespace: string): string | null {\n try {\n const registryPath = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');\n const registry = JSON.parse(readFileSync(registryPath, 'utf-8'));\n for (const key of Object.keys(registry)) {\n if (key.startsWith(`${namespace}@`)) {\n return registry[key].installPath ?? null;\n }\n }\n } catch {\n // File missing, parse error, or no match\n }\n return null;\n}\n\nexport function resolveAgentTypeColor(agentType: string, pluginDir: string, cwd: string): string | null {\n if (!agentType) return null;\n\n let namespace: string | undefined;\n let name: string;\n\n if (agentType.includes(':')) {\n [namespace, name] = agentType.split(':', 2) as [string, string];\n } else {\n name = agentType;\n }\n\n const searchPaths: string[] = [];\n\n if (namespace) {\n // Bundled (handles sisyphus:* via pluginDir)\n searchPaths.push(join(pluginDir, 'agents', `${name}.md`));\n // Installed plugin\n const installPath = findPluginInstallPath(namespace);\n if (installPath) {\n searchPaths.push(join(installPath, 'agents', `${name}.md`));\n }\n } else {\n // Project-local\n searchPaths.push(join(cwd, '.claude', 'agents', `${name}.md`));\n // User-global\n searchPaths.push(join(homedir(), '.claude', 'agents', `${name}.md`));\n // Bundled\n searchPaths.push(join(pluginDir, 'agents', `${name}.md`));\n }\n\n for (const path of searchPaths) {\n try {\n const content = readFileSync(path, 'utf-8');\n const color = extractFrontmatterColor(content);\n if (color) return normalizeTmuxColor(color);\n } catch {\n // File doesn't exist, try next\n }\n }\n\n return null;\n}\n","import { execSync } from 'node:child_process';\n\nconst EXEC_ENV = {\n ...process.env,\n PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env['PATH'] ?? '/usr/bin:/bin'}`,\n};\n\nfunction exec(cmd: string): string {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV }).trim();\n}\n\nfunction execSafe(cmd: string): string | null {\n try {\n return exec(cmd);\n } catch {\n return null;\n }\n}\n\nexport function getCurrentTmuxSession(): string {\n const tmuxEnv = process.env['TMUX'];\n if (!tmuxEnv) throw new Error('Not running inside tmux');\n return exec('tmux display-message -p \"#{session_name}\"');\n}\n\nexport function createWindow(sessionName: string, windowName: string, cwd?: string): string {\n const cwdFlag = cwd ? ` -c ${shellQuote(cwd)}` : '';\n exec(`tmux new-window -t \"${sessionName}\" -n \"${windowName}\"${cwdFlag} -P -F \"#{window_id}\"`);\n return exec(`tmux display-message -t \"${sessionName}:${windowName}\" -p \"#{window_id}\"`);\n}\n\nexport function createPane(windowTarget: string, cwd?: string): string {\n const cwdFlag = cwd ? ` -c ${shellQuote(cwd)}` : '';\n const paneId = exec(`tmux split-window -h -t \"${windowTarget}\"${cwdFlag} -P -F \"#{pane_id}\"`);\n execSafe(`tmux select-layout -t \"${windowTarget}\" even-horizontal`);\n return paneId;\n}\n\nexport function sendKeys(paneTarget: string, command: string): void {\n exec(`tmux send-keys -t \"${paneTarget}\" ${shellQuote(command)} Enter`);\n}\n\nexport function killPane(paneTarget: string): void {\n execSafe(`tmux kill-pane -t \"${paneTarget}\"`);\n}\n\nexport function killWindow(windowTarget: string): void {\n execSafe(`tmux kill-window -t \"${windowTarget}\"`);\n}\n\nexport interface PaneInfo {\n paneId: string;\n panePid: string;\n}\n\nexport function listPanes(windowTarget: string): PaneInfo[] {\n const output = execSafe(`tmux list-panes -t \"${windowTarget}\" -F \"#{pane_id} #{pane_pid}\"`);\n if (!output) return [];\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => {\n const [paneId, panePid] = line.split(' ');\n return { paneId: paneId!, panePid: panePid! };\n });\n}\n\nexport function setPaneTitle(paneTarget: string, title: string): void {\n execSafe(`tmux select-pane -t \"${paneTarget}\" -T ${shellQuote(title)}`);\n}\n\nexport function setPaneStyle(paneTarget: string, color: string): void {\n const fmt = `#[fg=${color},bold] #{pane_title} #[fg=${color}]#{pane_current_path} #[default]`;\n execSafe(`tmux set -p -t \"${paneTarget}\" pane-border-format ${shellQuote(fmt)}`);\n // Store color as a per-pane user variable. The window-level border styles use a\n // format string that resolves #{@pane_color} per-pane at render time, giving each\n // pane its own border color (pane-border-style itself is window-level / last-write-wins).\n execSafe(`tmux set -p -t \"${paneTarget}\" @pane_color \"${color}\"`);\n execSafe(`tmux set -w -t \"${paneTarget}\" pane-border-style \"fg=#{?#{@pane_color},#{@pane_color},default}\"`);\n execSafe(`tmux set -w -t \"${paneTarget}\" pane-active-border-style \"fg=#{?#{@pane_color},#{@pane_color},default}\"`);\n}\n\nexport function sendSignal(paneTarget: string, signal: string): void {\n const info = execSafe(`tmux list-panes -t \"${paneTarget}\" -F \"#{pane_pid}\"`);\n if (!info) return;\n const pid = info.split('\\n')[0]?.trim();\n if (pid) {\n execSafe(`kill -${signal} ${pid}`);\n }\n}\n\nexport function selectLayout(windowTarget: string, layout: string = 'even-horizontal'): void {\n execSafe(`tmux select-layout -t \"${windowTarget}\" ${layout}`);\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Agent, AgentReport } from '../shared/types.js';\nimport * as state from './state.js';\nimport * as tmux from './tmux.js';\nimport { getNextColor, resolveAgentTypeColor } from './colors.js';\nimport { getWindowId } from './orchestrator.js';\nimport { promptsDir, reportsDir, reportFilePath } from '../shared/paths.js';\nimport { createWorktree, countWorktreeAgents } from './worktree.js';\n\nconst agentCounters = new Map<string, number>();\n\nexport function resetAgentCounter(sessionId: string, value: number = 0): void {\n agentCounters.set(sessionId, value);\n}\n\nexport function resetAgentCounterFromState(sessionId: string, agents: { id: string }[]): void {\n let max = 0;\n for (const a of agents) {\n const match = a.id.match(/^agent-(\\d+)$/);\n if (match) max = Math.max(max, parseInt(match[1]!, 10));\n }\n agentCounters.set(sessionId, max);\n}\n\nexport function clearAgentCounter(sessionId: string): void {\n agentCounters.delete(sessionId);\n}\n\ninterface WorktreeContext {\n offset: number;\n total: number;\n branchName: string;\n}\n\nfunction renderAgentSuffix(sessionId: string, instruction: string, worktreeContext?: WorktreeContext): string {\n const templatePath = resolve(import.meta.dirname, '../templates/agent-suffix.md');\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf-8');\n } catch {\n template = `# Sisyphus Agent\\nSession: {{SESSION_ID}}\\nTask: {{INSTRUCTION}}`;\n }\n\n let worktreeBlock = '';\n if (worktreeContext) {\n worktreeBlock = [\n '## Worktree Context',\n `You are working in worktree ${worktreeContext.offset} of ${worktreeContext.total} concurrent worktrees on branch \\`${worktreeContext.branchName}\\`.`,\n `If you start any services that require ports, add ${worktreeContext.offset} to the default port.`,\n ].join('\\n');\n }\n\n return template\n .replace(/\\{\\{SESSION_ID\\}\\}/g, sessionId)\n .replace(/\\{\\{INSTRUCTION\\}\\}/g, instruction)\n .replace(/\\{\\{WORKTREE_CONTEXT\\}\\}/g, worktreeBlock);\n}\n\nexport interface SpawnAgentOpts {\n sessionId: string;\n cwd: string;\n agentType: string;\n name: string;\n instruction: string;\n windowId: string;\n worktree?: boolean;\n}\n\nexport async function spawnAgent(opts: SpawnAgentOpts): Promise<Agent> {\n const { sessionId, cwd, agentType, name, instruction, windowId } = opts;\n const count = (agentCounters.get(sessionId) ?? 0) + 1;\n agentCounters.set(sessionId, count);\n const agentId = `agent-${String(count).padStart(3, '0')}`;\n const pluginPath = resolve(import.meta.dirname, '../templates/agent-plugin');\n const color = resolveAgentTypeColor(agentType, pluginPath, cwd) ?? getNextColor(sessionId);\n\n let paneCwd = cwd;\n let worktreePath: string | undefined;\n let branchName: string | undefined;\n let worktreeContext: WorktreeContext | undefined;\n\n if (opts.worktree) {\n const wt = createWorktree(cwd, sessionId, agentId);\n worktreePath = wt.worktreePath;\n branchName = wt.branchName;\n paneCwd = worktreePath;\n\n const session = state.getSession(cwd, sessionId);\n const portOffset = countWorktreeAgents(session.agents) + 1;\n worktreeContext = { offset: portOffset, total: portOffset, branchName };\n }\n\n const paneId = tmux.createPane(windowId, paneCwd);\n tmux.setPaneTitle(paneId, `${name} (${agentId})`);\n tmux.setPaneStyle(paneId, color);\n\n const suffix = renderAgentSuffix(sessionId, instruction, worktreeContext);\n const suffixFilePath = `${promptsDir(cwd, sessionId)}/${agentId}-system.md`;\n writeFileSync(suffixFilePath, suffix, 'utf-8');\n\n const bannerPath = resolve(import.meta.dirname, '../templates/banner.txt');\n const bannerCmd = existsSync(bannerPath) ? `cat '${bannerPath}' &&` : '';\n\n const envExports = [\n `export SISYPHUS_SESSION_ID='${sessionId}'`,\n `export SISYPHUS_AGENT_ID='${agentId}'`,\n ...(worktreeContext ? [`export SISYPHUS_PORT_OFFSET='${worktreeContext.offset}'`] : []),\n ].join(' && ');\n\n const agentFlag = agentType ? ` --agent ${shellQuote(agentType)}` : '';\n const claudeCmd = `claude --dangerously-skip-permissions --plugin-dir \"${pluginPath}\"${agentFlag} --append-system-prompt \"$(cat '${suffixFilePath}')\" ${shellQuote(instruction)}`;\n tmux.sendKeys(paneId, `${bannerCmd} ${envExports} && ${claudeCmd}`);\n\n const agent: Agent = {\n id: agentId,\n name,\n agentType,\n color,\n instruction,\n status: 'running',\n spawnedAt: new Date().toISOString(),\n completedAt: null,\n reports: [],\n paneId,\n ...(worktreePath ? { worktreePath, branchName, mergeStatus: 'pending' as const } : {}),\n };\n\n await state.addAgent(cwd, sessionId, agent);\n return agent;\n}\n\nfunction nextReportNumber(cwd: string, sessionId: string, agentId: string): string {\n const dir = reportsDir(cwd, sessionId);\n try {\n const files = readdirSync(dir).filter(f => f.startsWith(`${agentId}-`) && !f.endsWith('-final.md'));\n return String(files.length + 1).padStart(3, '0');\n } catch {\n return '001';\n }\n}\n\nexport async function handleAgentReport(\n cwd: string,\n sessionId: string,\n agentId: string,\n content: string,\n): Promise<void> {\n const dir = reportsDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n\n const num = nextReportNumber(cwd, sessionId, agentId);\n const filePath = reportFilePath(cwd, sessionId, agentId, num);\n writeFileSync(filePath, content, 'utf-8');\n\n const entry: AgentReport = {\n type: 'update',\n filePath,\n summary: content.slice(0, 200),\n timestamp: new Date().toISOString(),\n };\n await state.appendAgentReport(cwd, sessionId, agentId, entry);\n}\n\nexport async function handleAgentSubmit(\n cwd: string,\n sessionId: string,\n agentId: string,\n report: string,\n): Promise<boolean> {\n const dir = reportsDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n\n const filePath = reportFilePath(cwd, sessionId, agentId, 'final');\n writeFileSync(filePath, report, 'utf-8');\n\n const entry: AgentReport = {\n type: 'final',\n filePath,\n summary: report.slice(0, 200),\n timestamp: new Date().toISOString(),\n };\n await state.appendAgentReport(cwd, sessionId, agentId, entry);\n\n await state.updateAgent(cwd, sessionId, agentId, {\n status: 'completed',\n completedAt: new Date().toISOString(),\n });\n\n const session = state.getSession(cwd, sessionId);\n const agentArr = session.agents;\n const agent = agentArr.slice().reverse().find(a => a.id === agentId);\n if (agent) {\n tmux.killPane(agent.paneId);\n }\n\n const windowId = getWindowId(sessionId);\n if (windowId) tmux.selectLayout(windowId);\n\n return allAgentsDone(session);\n}\n\nexport async function handleAgentKilled(\n cwd: string,\n sessionId: string,\n agentId: string,\n reason: string,\n): Promise<boolean> {\n await state.updateAgent(cwd, sessionId, agentId, {\n status: 'killed',\n killedReason: reason,\n completedAt: new Date().toISOString(),\n });\n\n const session = state.getSession(cwd, sessionId);\n return allAgentsDone(session);\n}\n\n// Note: this checks ALL running agents in the session, not just orchestrator-spawned ones.\n// Agents can also call `sisyphus spawn`, and those child agents are included here —\n// the orchestrator won't respawn until every agent (including agent-spawned ones) finishes.\nfunction allAgentsDone(session: import('../shared/types.js').Session): boolean {\n const running = session.agents.filter(a => a.status === 'running');\n return running.length === 0 && session.agents.length > 0;\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Agent } from '../shared/types.js';\nimport type { WorktreeConfig } from '../shared/config.js';\nimport { worktreeConfigPath, worktreeBaseDir } from '../shared/paths.js';\n\nconst EXEC_ENV = {\n ...process.env,\n PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env['PATH'] ?? '/usr/bin:/bin'}`,\n};\n\nfunction exec(cmd: string, cwd?: string): string {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV, cwd }).trim();\n}\n\nfunction execSafe(cmd: string, cwd?: string): string | null {\n try {\n return exec(cmd, cwd);\n } catch {\n return null;\n }\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nexport interface MergeResult {\n agentId: string;\n name: string;\n status: 'merged' | 'conflict' | 'no-changes';\n conflictDetails?: string;\n}\n\nexport function loadWorktreeConfig(cwd: string): WorktreeConfig | null {\n try {\n const content = readFileSync(worktreeConfigPath(cwd), 'utf-8');\n return JSON.parse(content) as WorktreeConfig;\n } catch {\n return null;\n }\n}\n\nexport function createWorktree(\n cwd: string,\n sessionId: string,\n agentId: string,\n): { worktreePath: string; branchName: string } {\n const branchName = `sisyphus/${sessionId.slice(0, 8)}/${agentId}`;\n const worktreePath = join(worktreeBaseDir(cwd), agentId);\n\n mkdirSync(dirname(worktreePath), { recursive: true });\n\n exec(`git -C ${shellQuote(cwd)} branch ${shellQuote(branchName)} HEAD`);\n exec(`git -C ${shellQuote(cwd)} worktree add ${shellQuote(worktreePath)} ${shellQuote(branchName)}`);\n\n // Always symlink .sisyphus and .claude from cwd into worktree\n const symlinks = ['.sisyphus', '.claude'];\n for (const entry of symlinks) {\n const src = join(cwd, entry);\n if (existsSync(src)) {\n execSafe(`ln -s ${shellQuote(src)} ${shellQuote(join(worktreePath, entry))}`);\n }\n }\n\n // Load worktree config and bootstrap if present\n const config = loadWorktreeConfig(cwd);\n if (config) {\n bootstrapWorktree(cwd, worktreePath, config);\n }\n\n return { worktreePath, branchName };\n}\n\nexport function bootstrapWorktree(cwd: string, worktreePath: string, config: WorktreeConfig): void {\n // Process copy entries\n if (config.copy) {\n for (const entry of config.copy) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n execSafe(`cp -r ${shellQuote(join(cwd, entry))} ${shellQuote(dest)}`);\n }\n }\n\n // Process clone entries (APFS CoW on macOS, fallback to cp -r)\n if (config.clone) {\n for (const entry of config.clone) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n const src = shellQuote(join(cwd, entry));\n const dstQ = shellQuote(dest);\n if (execSafe(`cp -Rc ${src} ${dstQ}`) === null) {\n execSafe(`cp -r ${src} ${dstQ}`);\n }\n }\n }\n\n // Process symlink entries\n if (config.symlink) {\n for (const entry of config.symlink) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n execSafe(`ln -s ${shellQuote(join(cwd, entry))} ${shellQuote(dest)}`);\n }\n }\n\n // Process init command\n if (config.init) {\n try {\n exec(config.init, worktreePath);\n } catch (err) {\n console.error(`[sisyphus] worktree init command failed: ${err instanceof Error ? err.message : err}`);\n }\n }\n}\n\n/**\n * Resolve the branch checked out in a worktree by parsing `git worktree list --porcelain`.\n * Returns null if the worktree isn't found or has a detached HEAD.\n */\nfunction resolveWorktreeBranch(cwd: string, worktreePath: string): string | null {\n const output = execSafe(`git -C ${shellQuote(cwd)} worktree list --porcelain`);\n if (!output) return null;\n\n const lines = output.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (lines[i] === `worktree ${worktreePath}`) {\n for (let j = i + 1; j < lines.length; j++) {\n const line = lines[j]!;\n if (line === '') break; // end of this worktree block\n if (line.startsWith('branch refs/heads/')) {\n return line.slice('branch refs/heads/'.length);\n }\n }\n break;\n }\n }\n return null;\n}\n\nexport function mergeWorktrees(cwd: string, agents: Agent[]): MergeResult[] {\n const pending = agents.filter(\n a => a.worktreePath && a.mergeStatus === 'pending',\n );\n\n const results: MergeResult[] = [];\n\n for (const agent of pending) {\n const branch = resolveWorktreeBranch(cwd, agent.worktreePath!);\n\n if (!branch) {\n results.push({ agentId: agent.id, name: agent.name, status: 'no-changes' });\n // Best-effort cleanup — branch name unknown, just remove worktree dir\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(agent.worktreePath!)} --force`);\n continue;\n }\n\n // Check if branch has commits ahead of merge base\n const aheadLog = execSafe(`git -C ${shellQuote(cwd)} log HEAD..${shellQuote(branch)} --oneline`);\n if (!aheadLog) {\n results.push({ agentId: agent.id, name: agent.name, status: 'no-changes' });\n cleanupWorktree(cwd, agent.worktreePath!, branch);\n continue;\n }\n\n // Attempt merge — capture stderr on failure for conflict details\n const mergeMsg = `sisyphus: merge ${agent.id} (${agent.name})`;\n const mergeCmd = `git -C ${shellQuote(cwd)} merge --no-ff ${shellQuote(branch)} -m ${shellQuote(mergeMsg)}`;\n\n try {\n exec(mergeCmd);\n // Merge succeeded — clean up worktree and branch\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(agent.worktreePath!)}`);\n execSafe(`git -C ${shellQuote(cwd)} branch -d ${shellQuote(branch)}`);\n results.push({ agentId: agent.id, name: agent.name, status: 'merged' });\n } catch (err: unknown) {\n // Merge failed — abort and leave worktree intact for manual resolution\n execSafe(`git -C ${shellQuote(cwd)} merge --abort`);\n const stderr = (err as { stderr?: Buffer | string })?.stderr;\n const conflictDetails = stderr\n ? (typeof stderr === 'string' ? stderr : stderr.toString('utf-8')).trim()\n : (err instanceof Error ? err.message : String(err));\n results.push({ agentId: agent.id, name: agent.name, status: 'conflict', conflictDetails });\n }\n }\n\n return results;\n}\n\nexport function cleanupWorktree(cwd: string, worktreePath: string, branchName: string): void {\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(worktreePath)} --force`);\n execSafe(`git -C ${shellQuote(cwd)} branch -D ${shellQuote(branchName)}`);\n\n // Remove the worktree base dir if empty\n const baseDir = dirname(worktreePath);\n try {\n const entries = readdirSync(baseDir);\n if (entries.length === 0) {\n rmSync(baseDir, { recursive: true });\n }\n } catch {\n // Ignore — directory may already be gone\n }\n}\n\nexport function countWorktreeAgents(agents: Agent[]): number {\n return agents.filter(a => a.worktreePath && a.status === 'running').length;\n}\n","import * as state from './state.js';\nimport * as tmux from './tmux.js';\nimport { getOrchestratorPaneId, cleanupSessionMaps } from './orchestrator.js';\nimport { handleAgentKilled } from './agent.js';\n\ntype RespawnCallback = (sessionId: string, cwd: string, windowId: string) => void;\n\nlet monitorInterval: ReturnType<typeof setInterval> | null = null;\nlet onAllAgentsDone: RespawnCallback | null = null;\n\nexport function setRespawnCallback(cb: RespawnCallback): void {\n onAllAgentsDone = cb;\n}\n\nexport function startMonitor(pollIntervalMs: number = 1000): void {\n if (monitorInterval) return;\n monitorInterval = setInterval(() => {\n pollAllSessions().catch(err => {\n console.error('[sisyphus] Pane monitor error:', err);\n });\n }, pollIntervalMs);\n}\n\nexport function stopMonitor(): void {\n if (monitorInterval) {\n clearInterval(monitorInterval);\n monitorInterval = null;\n }\n}\n\nconst trackedSessions = new Map<string, { id: string; cwd: string; tmuxSession: string; windowId: string | null }>();\n\nexport function trackSession(sessionId: string, cwd: string, tmuxSession: string): void {\n // windowId is registered separately via updateTrackedWindow after spawnOrchestrator sets it\n const existing = trackedSessions.get(sessionId);\n trackedSessions.set(sessionId, { id: sessionId, cwd, tmuxSession, windowId: existing ? existing.windowId : null });\n}\n\nexport function updateTrackedWindow(sessionId: string, windowId: string): void {\n const entry = trackedSessions.get(sessionId);\n if (!entry) throw new Error(`Cannot update window for untracked session: ${sessionId}`);\n entry.windowId = windowId;\n}\n\nexport function untrackSession(sessionId: string): void {\n trackedSessions.delete(sessionId);\n}\n\nasync function pollAllSessions(): Promise<void> {\n for (const { id: sessionId, cwd, windowId } of trackedSessions.values()) {\n if (windowId) {\n await pollSession(sessionId, cwd, windowId);\n }\n }\n}\n\nasync function pollSession(sessionId: string, cwd: string, windowId: string): Promise<void> {\n let session;\n try {\n session = state.getSession(cwd, sessionId);\n } catch (err) {\n console.error(`[sisyphus] Failed to read state for session ${sessionId}:`, err);\n return;\n }\n\n if (session.status === 'completed') {\n const orchPaneId = getOrchestratorPaneId(sessionId);\n if (orchPaneId) {\n const livePanes = tmux.listPanes(windowId);\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n if (!livePaneIds.has(orchPaneId)) {\n cleanupSessionMaps(sessionId);\n untrackSession(sessionId);\n console.log(`[sisyphus] Session ${sessionId} cleaned up: orchestrator pane closed by user`);\n }\n } else {\n // No orchestrator pane tracked — clean up immediately\n cleanupSessionMaps(sessionId);\n untrackSession(sessionId);\n }\n return;\n }\n\n if (session.status !== 'active') return;\n\n const livePanes = tmux.listPanes(windowId);\n if (livePanes.length === 0) return;\n\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n\n let paneRemoved = false;\n for (const agent of session.agents) {\n if (agent.status !== 'running') continue;\n if (!livePaneIds.has(agent.paneId)) {\n paneRemoved = true;\n const allDone = await handleAgentKilled(cwd, sessionId, agent.id, 'pane closed by user');\n if (allDone && onAllAgentsDone) {\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n }\n }\n\n if (paneRemoved) tmux.selectLayout(windowId);\n\n // Check orchestrator pane\n const orchPaneId = getOrchestratorPaneId(sessionId);\n if (orchPaneId && !livePaneIds.has(orchPaneId)) {\n // Orchestrator pane disappeared without a yield command\n const runningAgents = session.agents.filter(a => a.status === 'running');\n if (runningAgents.length === 0) {\n // No agents running and orchestrator gone — pause\n await state.updateSessionStatus(cwd, sessionId, 'paused');\n console.log(`[sisyphus] Session ${sessionId} paused: orchestrator pane disappeared`);\n }\n }\n\n // Re-read state since handleAgentKilled may have mutated it\n session = state.getSession(cwd, sessionId);\n if (\n session.status === 'active' &&\n session.agents.length > 0 &&\n session.agents.every(a => a.status !== 'running') &&\n (!orchPaneId || !livePaneIds.has(orchPaneId)) &&\n onAllAgentsDone\n ) {\n console.log(`[sisyphus] Detected stuck session ${sessionId}: all agents done, no orchestrator — triggering respawn`);\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n}\n"],"mappings":"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","names":["mkdirSync","readFileSync","writeFileSync","unlinkSync","existsSync","existsSync","writeFileSync","readFileSync","mkdirSync","join","existsSync","readdirSync","readFileSync","resolve","readFileSync","readFileSync","writeFileSync","readFileSync","join","registryPath","command","readFileSync","writeFileSync","readFileSync","writeFileSync","mkdirSync","readdirSync","existsSync","resolve","execSync","existsSync","mkdirSync","readFileSync","readdirSync","dirname","join","EXEC_ENV","exec","execSync","execSafe","shellQuote","readFileSync","join","mkdirSync","dirname","existsSync","readdirSync","resolve","readFileSync","writeFileSync","existsSync","shellQuote","readdirSync","mkdirSync","orchPaneId","livePanes","livePaneIds","existsSync","readdirSync","onAllAgentsDone","sessionWindowMap","join","mkdirSync","writeFileSync","existsSync","readFileSync","sessionWindowMap","resolve","mkdirSync","readFileSync","writeFileSync","unlinkSync","existsSync","onAllAgentsDone"]}
1
+ {"version":3,"sources":["../src/daemon/index.ts","../src/shared/config.ts","../src/daemon/server.ts","../src/daemon/session-manager.ts","../src/daemon/state.ts","../src/daemon/orchestrator.ts","../src/daemon/colors.ts","../src/daemon/tmux.ts","../src/daemon/agent.ts","../src/daemon/worktree.ts","../src/daemon/pane-monitor.ts"],"sourcesContent":["import { mkdirSync, readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs';\nimport { globalDir, daemonPidPath, statePath } from '../shared/paths.js';\nimport { loadConfig } from '../shared/config.js';\nimport { startServer, stopServer, registerSessionCwd, registerSessionTmux, loadSessionRegistry } from './server.js';\nimport { startMonitor, stopMonitor, setRespawnCallback, trackSession, updateTrackedWindow } from './pane-monitor.js';\nimport { onAllAgentsDone } from './session-manager.js';\nimport { resetAgentCounterFromState } from './agent.js';\nimport { setWindowId, setOrchestratorPaneId, getOrchestratorPaneId } from './orchestrator.js';\nimport { listPanes } from './tmux.js';\nimport * as stateModule from './state.js';\nimport type { Session } from '../shared/types.js';\n\nfunction ensureDirs(): void {\n mkdirSync(globalDir(), { recursive: true });\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction readPid(): number | null {\n const pidFile = daemonPidPath();\n try {\n const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);\n return pid && isProcessAlive(pid) ? pid : null;\n } catch {\n return null;\n }\n}\n\nfunction acquirePidLock(): void {\n const pid = readPid();\n if (pid) {\n console.error(`[sisyphus] Daemon already running (pid ${pid}). Use 'sisyphusd restart' or 'sisyphusd stop' first.`);\n process.exit(0);\n }\n writeFileSync(daemonPidPath(), String(process.pid), 'utf-8');\n}\n\nfunction releasePidLock(): void {\n try {\n unlinkSync(daemonPidPath());\n } catch {\n // Already gone\n }\n}\n\nfunction stopDaemon(): boolean {\n const pid = readPid();\n if (!pid) {\n console.log('[sisyphus] Daemon is not running');\n // Clean up stale pid file if it exists\n releasePidLock();\n return false;\n }\n\n console.log(`[sisyphus] Stopping daemon (pid ${pid})...`);\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n console.error(`[sisyphus] Failed to send SIGTERM to pid ${pid}`);\n return false;\n }\n\n // Wait for process to exit (up to 5s)\n const deadline = Date.now() + 5000;\n while (Date.now() < deadline) {\n if (!isProcessAlive(pid)) {\n console.log('[sisyphus] Daemon stopped');\n releasePidLock();\n return true;\n }\n // Busy-wait in small increments (synchronous — fine for a CLI command)\n const wait = Date.now() + 100;\n while (Date.now() < wait) { /* spin */ }\n }\n\n console.error(`[sisyphus] Daemon (pid ${pid}) did not exit within 5s, sending SIGKILL`);\n try {\n process.kill(pid, 'SIGKILL');\n } catch { /* already dead */ }\n releasePidLock();\n return true;\n}\n\nasync function recoverSessions(): Promise<void> {\n const registry = loadSessionRegistry();\n const entries = Object.entries(registry);\n\n if (entries.length === 0) {\n console.log('[sisyphus] No sessions to recover');\n return;\n }\n\n let recovered = 0;\n for (const [sessionId, cwd] of entries) {\n const stateFile = statePath(cwd, sessionId);\n if (!existsSync(stateFile)) {\n continue;\n }\n\n try {\n const session = JSON.parse(readFileSync(stateFile, 'utf-8')) as Session;\n if (session.status === 'active' || session.status === 'paused') {\n registerSessionCwd(sessionId, cwd);\n resetAgentCounterFromState(sessionId, session.agents ?? []);\n\n // Reconnect to tmux panes if info was persisted\n if (session.tmuxSessionName && session.tmuxWindowId) {\n const livePanes = listPanes(session.tmuxWindowId);\n if (livePanes.length > 0) {\n registerSessionTmux(sessionId, session.tmuxSessionName, session.tmuxWindowId);\n setWindowId(sessionId, session.tmuxWindowId);\n trackSession(sessionId, cwd, session.tmuxSessionName);\n updateTrackedWindow(sessionId, session.tmuxWindowId);\n\n // Recover orchestrator pane from last incomplete cycle\n const lastIncompleteCycle = [...session.orchestratorCycles].reverse().find(c => !c.completedAt && c.paneId);\n if (lastIncompleteCycle?.paneId) {\n setOrchestratorPaneId(sessionId, lastIncompleteCycle.paneId);\n }\n\n console.log(`[sisyphus] Reconnected session ${sessionId} to tmux window ${session.tmuxWindowId}`);\n\n // Detect sessions stuck in \"all agents done, no orchestrator\" state\n if (session.status === 'active' && session.agents.length > 0) {\n const hasRunningAgents = session.agents.some(a => a.status === 'running');\n if (!hasRunningAgents) {\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n const orchestratorPaneId = getOrchestratorPaneId(sessionId);\n const orchestratorAlive = orchestratorPaneId && livePaneIds.has(orchestratorPaneId);\n if (!orchestratorAlive) {\n console.log(`[sisyphus] Detected stuck session ${sessionId} on recovery: triggering orchestrator respawn`);\n await onAllAgentsDone(sessionId, cwd, session.tmuxWindowId!);\n }\n }\n }\n } else {\n // Window gone — pause the session so user can `sisyphus resume`\n if (session.status === 'active') {\n await stateModule.updateSessionStatus(cwd, sessionId, 'paused');\n console.log(`[sisyphus] Session ${sessionId} paused: tmux window no longer exists`);\n }\n }\n }\n\n recovered++;\n }\n } catch {\n console.error(`[sisyphus] Failed to read session state for ${sessionId}, skipping`);\n }\n }\n\n console.log(`[sisyphus] Recovered ${recovered} session(s) from registry`);\n}\n\nasync function startDaemon(): Promise<void> {\n console.log('[sisyphus] Starting daemon...');\n ensureDirs();\n acquirePidLock();\n\n const config = loadConfig(process.cwd());\n\n setRespawnCallback(onAllAgentsDone);\n\n await startServer();\n startMonitor(config.pollIntervalMs);\n\n await recoverSessions();\n\n const shutdown = async () => {\n console.log('[sisyphus] Shutting down...');\n stopMonitor();\n await stopServer();\n releasePidLock();\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nconst command = process.argv[2];\n\nswitch (command) {\n case 'stop':\n stopDaemon();\n break;\n\n case 'restart': {\n stopDaemon();\n // Small delay to let socket release\n const wait = Date.now() + 500;\n while (Date.now() < wait) { /* spin */ }\n // Check if a process manager (e.g. launchd) already respawned the daemon\n const respawnedPid = readPid();\n if (respawnedPid) {\n console.log(`[sisyphus] Daemon restarted (pid ${respawnedPid}) by process manager`);\n break;\n }\n startDaemon().catch((err) => {\n console.error('[sisyphus] Fatal error:', err);\n process.exit(1);\n });\n break;\n }\n\n case 'start':\n case undefined:\n startDaemon().catch((err) => {\n console.error('[sisyphus] Fatal error:', err);\n process.exit(1);\n });\n break;\n\n case 'help':\n case '--help':\n case '-h':\n console.log('Usage: sisyphusd [command]');\n console.log('');\n console.log('Commands:');\n console.log(' start Start the daemon (default if no command given)');\n console.log(' stop Stop the running daemon');\n console.log(' restart Stop and restart the daemon');\n console.log(' help Show this help message');\n break;\n\n default:\n console.error(`[sisyphus] Unknown command: ${command}`);\n console.error('Usage: sisyphusd [start|stop|restart|help]');\n process.exit(1);\n}\n","import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport interface WorktreeConfig {\n copy?: string[];\n clone?: string[];\n symlink?: string[];\n init?: string;\n}\n\nexport interface Config {\n model?: string;\n tmuxSession?: string;\n orchestratorPrompt?: string;\n pollIntervalMs?: number;\n}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 1000,\n};\n\nfunction readJsonFile(filePath: string): Partial<Config> {\n try {\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as Partial<Config>;\n } catch {\n return {};\n }\n}\n\nexport function loadConfig(cwd: string): Config {\n const global = readJsonFile(globalConfigPath());\n const project = readJsonFile(projectConfigPath(cwd));\n return { ...DEFAULT_CONFIG, ...global, ...project };\n}\n","import { createServer, type Server } from 'node:net';\nimport { unlinkSync, existsSync, writeFileSync, readFileSync, mkdirSync } from 'node:fs';\nimport { socketPath, globalDir } from '../shared/paths.js';\nimport { join } from 'node:path';\nimport type { Request, Response } from '../shared/protocol.js';\nimport * as sessionManager from './session-manager.js';\n\nlet server: Server | null = null;\n\n// Track the cwd for each session so we can route requests\nconst sessionCwdMap = new Map<string, string>();\n// Track the originating tmux session for each sisyphus session\nconst sessionTmuxMap = new Map<string, string>();\n// Track the originating tmux window for each sisyphus session\nconst sessionWindowMap = new Map<string, string>();\n\nexport function getSessionCwd(sessionId: string): string | undefined {\n return sessionCwdMap.get(sessionId);\n}\n\nexport function getSessionTmux(sessionId: string): string | undefined {\n return sessionTmuxMap.get(sessionId);\n}\n\nfunction registryPath(): string {\n return join(globalDir(), 'session-registry.json');\n}\n\nfunction persistSessionRegistry(): void {\n const dir = globalDir();\n mkdirSync(dir, { recursive: true });\n const registry: Record<string, string> = {};\n for (const [id, cwd] of sessionCwdMap) {\n registry[id] = cwd;\n }\n writeFileSync(registryPath(), JSON.stringify(registry, null, 2), 'utf-8');\n}\n\nexport function loadSessionRegistry(): Record<string, string> {\n const p = registryPath();\n if (!existsSync(p)) return {};\n try {\n return JSON.parse(readFileSync(p, 'utf-8')) as Record<string, string>;\n } catch {\n return {};\n }\n}\n\nexport function registerSessionCwd(sessionId: string, cwd: string): void {\n sessionCwdMap.set(sessionId, cwd);\n persistSessionRegistry();\n}\n\nexport function registerSessionTmux(sessionId: string, tmuxSession: string, windowId: string): void {\n sessionTmuxMap.set(sessionId, tmuxSession);\n sessionWindowMap.set(sessionId, windowId);\n}\n\nasync function handleRequest(req: Request): Promise<Response> {\n try {\n switch (req.type) {\n case 'start': {\n const session = await sessionManager.startSession(req.task, req.cwd, req.tmuxSession, req.tmuxWindow);\n registerSessionCwd(session.id, req.cwd);\n sessionTmuxMap.set(session.id, req.tmuxSession);\n sessionWindowMap.set(session.id, req.tmuxWindow);\n return { ok: true, data: { sessionId: session.id } };\n }\n\n case 'spawn': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const result = await sessionManager.handleSpawn(req.sessionId, cwd, req.agentType, req.name, req.instruction, req.worktree);\n return { ok: true, data: { agentId: result.agentId } };\n }\n\n case 'submit': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const windowId = sessionWindowMap.get(req.sessionId);\n if (!windowId) return { ok: false, error: `No tmux window found for session: ${req.sessionId}` };\n await sessionManager.handleSubmit(cwd, req.sessionId, req.agentId, req.report, windowId);\n return { ok: true };\n }\n\n case 'report': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleReport(cwd, req.sessionId, req.agentId, req.content);\n return { ok: true };\n }\n\n case 'yield': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleYield(req.sessionId, cwd, req.nextPrompt);\n return { ok: true };\n }\n\n case 'complete': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleComplete(req.sessionId, cwd, req.report);\n return { ok: true };\n }\n\n case 'status': {\n if (req.sessionId) {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const session = sessionManager.getSessionStatus(cwd, req.sessionId);\n return { ok: true, data: { session: session as unknown as Record<string, unknown> } };\n }\n return { ok: true, data: { message: 'daemon running' } };\n }\n\n case 'list': {\n const allSessions: Array<Record<string, unknown>> = [];\n if (req.all) {\n // List sessions across all known cwds\n const seenCwds = new Set<string>();\n for (const cwd of sessionCwdMap.values()) {\n if (seenCwds.has(cwd)) continue;\n seenCwds.add(cwd);\n const sessions = sessionManager.listSessions(cwd);\n allSessions.push(...sessions.map(s => ({ ...s, cwd } as unknown as Record<string, unknown>)));\n }\n } else {\n // List sessions for the requesting cwd only\n const sessions = sessionManager.listSessions(req.cwd);\n allSessions.push(...sessions.map(s => ({ ...s, cwd: req.cwd } as unknown as Record<string, unknown>)));\n // Count total across all cwds for the hint\n let totalCount = allSessions.length;\n const seenCwds = new Set<string>([req.cwd]);\n for (const cwd of sessionCwdMap.values()) {\n if (seenCwds.has(cwd)) continue;\n seenCwds.add(cwd);\n totalCount += sessionManager.listSessions(cwd).length;\n }\n if (totalCount > allSessions.length) {\n return { ok: true, data: { sessions: allSessions, totalCount, filtered: true } };\n }\n }\n return { ok: true, data: { sessions: allSessions } };\n }\n\n case 'resume': {\n let cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) {\n // Session not in memory — try to recover from disk using the cwd provided by CLI\n const stateFile = `${req.cwd}/.sisyphus/sessions/${req.sessionId}/state.json`;\n if (existsSync(stateFile)) {\n cwd = req.cwd;\n registerSessionCwd(req.sessionId, cwd);\n } else {\n return { ok: false, error: `Unknown session: ${req.sessionId}. No state.json found at ${stateFile}` };\n }\n }\n sessionTmuxMap.set(req.sessionId, req.tmuxSession);\n sessionWindowMap.set(req.sessionId, req.tmuxWindow);\n const session = await sessionManager.resumeSession(req.sessionId, cwd, req.tmuxSession, req.tmuxWindow, req.message);\n return { ok: true, data: { sessionId: session.id, status: session.status } };\n }\n\n case 'register_claude_session': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n await sessionManager.handleRegisterClaudeSession(cwd, req.sessionId, req.agentId, req.claudeSessionId);\n return { ok: true };\n }\n\n case 'kill': {\n const cwd = sessionCwdMap.get(req.sessionId);\n if (!cwd) return { ok: false, error: `Unknown session: ${req.sessionId}` };\n const killedAgents = await sessionManager.handleKill(req.sessionId, cwd);\n sessionCwdMap.delete(req.sessionId);\n sessionTmuxMap.delete(req.sessionId);\n sessionWindowMap.delete(req.sessionId);\n persistSessionRegistry();\n return { ok: true, data: { killedAgents, sessionId: req.sessionId } };\n }\n\n default:\n return { ok: false, error: `Unknown request type: ${(req as Record<string, unknown>).type}` };\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return { ok: false, error: message };\n }\n}\n\nexport function startServer(): Promise<Server> {\n return new Promise((resolve, reject) => {\n const sock = socketPath();\n\n if (existsSync(sock)) {\n unlinkSync(sock);\n }\n\n server = createServer((conn) => {\n let buffer = '';\n\n conn.on('data', (chunk) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop()!;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n let req: Request;\n try {\n req = JSON.parse(line) as Request;\n } catch {\n conn.write(JSON.stringify({ ok: false, error: 'Invalid JSON' }) + '\\n');\n continue;\n }\n\n handleRequest(req).then((res) => {\n conn.write(JSON.stringify(res) + '\\n');\n });\n }\n });\n\n conn.on('error', (err) => {\n console.error('[sisyphus] Connection error:', err.message);\n });\n });\n\n server.on('error', reject);\n\n server.listen(sock, () => {\n console.log(`[sisyphus] Daemon listening on ${sock}`);\n resolve(server!);\n });\n });\n}\n\nexport function stopServer(): Promise<void> {\n return new Promise((resolve) => {\n if (!server) {\n resolve();\n return;\n }\n server.close(() => {\n const sock = socketPath();\n if (existsSync(sock)) {\n unlinkSync(sock);\n }\n server = null;\n resolve();\n });\n });\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { existsSync, readdirSync, rmSync } from 'node:fs';\nimport * as state from './state.js';\nimport * as orchestrator from './orchestrator.js';\nimport * as tmux from './tmux.js';\nimport { spawnAgent, resetAgentCounterFromState, clearAgentCounter, handleAgentSubmit, handleAgentReport } from './agent.js';\nimport { trackSession, untrackSession, updateTrackedWindow } from './pane-monitor.js';\nimport { resetColors } from './colors.js';\nimport { sessionDir, sessionsDir } from '../shared/paths.js';\nimport type { Session } from '../shared/types.js';\nimport { mergeWorktrees, cleanupWorktree } from './worktree.js';\n\nexport async function startSession(task: string, cwd: string, tmuxSession: string, windowId: string): Promise<Session> {\n const sessionId = uuidv4();\n const session = state.createSession(sessionId, task, cwd);\n await state.updateSessionTmux(cwd, sessionId, tmuxSession, windowId);\n\n trackSession(sessionId, cwd, tmuxSession);\n await orchestrator.spawnOrchestrator(sessionId, cwd, windowId);\n updateTrackedWindow(sessionId, windowId);\n\n pruneOldSessions(cwd);\n\n return session;\n}\n\nconst PRUNE_KEEP_COUNT = 10;\nconst PRUNE_KEEP_DAYS = 7;\n\nfunction pruneOldSessions(cwd: string): void {\n try {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return;\n\n const entries = readdirSync(dir, { withFileTypes: true });\n const candidates: Array<{ id: string; createdAt: number }> = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n try {\n const session = state.getSession(cwd, entry.name);\n if (session.status === 'active' || session.status === 'paused') continue;\n candidates.push({ id: session.id, createdAt: new Date(session.createdAt).getTime() });\n } catch {\n // Unreadable session dir — skip, don't delete\n }\n }\n\n if (candidates.length <= PRUNE_KEEP_COUNT) return;\n\n candidates.sort((a, b) => b.createdAt - a.createdAt);\n\n const cutoff = Date.now() - PRUNE_KEEP_DAYS * 24 * 60 * 60 * 1000;\n const keep = new Set<string>();\n\n for (let i = 0; i < Math.min(PRUNE_KEEP_COUNT, candidates.length); i++) {\n keep.add(candidates[i]!.id);\n }\n for (const c of candidates) {\n if (c.createdAt >= cutoff) keep.add(c.id);\n }\n\n for (const c of candidates) {\n if (keep.has(c.id)) continue;\n rmSync(sessionDir(cwd, c.id), { recursive: true, force: true });\n }\n } catch (err) {\n console.error('[sisyphus] Session pruning failed:', err);\n }\n}\n\nexport async function resumeSession(sessionId: string, cwd: string, tmuxSession: string, windowId: string, message?: string): Promise<Session> {\n const session = state.getSession(cwd, sessionId);\n\n if (session.status !== 'active') {\n // Determine which agents still have live panes\n const livePaneIds = new Set<string>();\n if (session.tmuxWindowId) {\n const panes = tmux.listPanes(session.tmuxWindowId);\n for (const pane of panes) {\n livePaneIds.add(pane.paneId);\n }\n }\n\n // Mark running agents as \"lost\" only if their pane is gone (or no window ID to check)\n for (const agent of session.agents) {\n if (agent.status === 'running') {\n const isAlive = agent.paneId != null && livePaneIds.has(agent.paneId);\n if (!isAlive) {\n await state.updateAgent(cwd, sessionId, agent.id, {\n status: 'lost',\n completedAt: new Date().toISOString(),\n killedReason: 'session resumed — agent was still running',\n });\n }\n }\n }\n }\n\n await state.updateSessionStatus(cwd, sessionId, 'active');\n await state.updateSessionTmux(cwd, sessionId, tmuxSession, windowId);\n\n // Reset counters based on existing agents\n resetAgentCounterFromState(sessionId, session.agents);\n resetColors(sessionId);\n\n trackSession(sessionId, cwd, tmuxSession);\n await orchestrator.spawnOrchestrator(sessionId, cwd, windowId, message);\n updateTrackedWindow(sessionId, windowId);\n\n return state.getSession(cwd, sessionId);\n}\n\nexport function getSessionStatus(cwd: string, sessionId: string): Session {\n return state.getSession(cwd, sessionId);\n}\n\nexport function listSessions(cwd: string): Array<{ id: string; task: string; status: string; createdAt: string; agentCount: number }> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return [];\n\n const entries = readdirSync(dir, { withFileTypes: true });\n const sessions: Array<{ id: string; task: string; status: string; createdAt: string; agentCount: number }> = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n try {\n const session = state.getSession(cwd, entry.name);\n sessions.push({\n id: session.id,\n task: session.task,\n status: session.status,\n createdAt: session.createdAt,\n agentCount: session.agents.length,\n });\n } catch (err) {\n console.error(`[sisyphus] Failed to read session ${entry.name}:`, err);\n }\n }\n\n return sessions;\n}\n\nconst pendingRespawns = new Set<string>();\n\nexport function onAllAgentsDone(sessionId: string, cwd: string, windowId: string): void {\n if (pendingRespawns.has(sessionId)) return;\n\n const session = state.getSession(cwd, sessionId);\n if (session.status !== 'active') return;\n\n pendingRespawns.add(sessionId);\n\n // Merge any worktree agents before respawning orchestrator\n const worktreeAgents = session.agents.filter(a => a.worktreePath && a.mergeStatus === 'pending');\n if (worktreeAgents.length > 0) {\n const results = mergeWorktrees(cwd, worktreeAgents);\n for (const result of results) {\n const mergeStatus = result.status as 'merged' | 'no-changes' | 'conflict';\n state.updateAgent(cwd, sessionId, result.agentId, {\n mergeStatus,\n mergeDetails: result.conflictDetails,\n }).catch((err: unknown) => console.error(`[sisyphus] Failed to update merge status for ${result.agentId}:`, err));\n }\n }\n\n // Delay to let /exit finish quitting the previous Claude session\n setTimeout(() => {\n pendingRespawns.delete(sessionId);\n orchestrator.spawnOrchestrator(sessionId, cwd, windowId)\n .then(() => updateTrackedWindow(sessionId, windowId))\n .catch((err: unknown) => console.error(`[sisyphus] Failed to respawn orchestrator for session ${sessionId}:`, err));\n }, 2000);\n}\n\nexport async function handleSpawn(\n sessionId: string,\n cwd: string,\n agentType: string,\n name: string,\n instruction: string,\n worktree?: boolean,\n): Promise<{ agentId: string }> {\n const windowId = orchestrator.getWindowId(sessionId);\n if (!windowId) throw new Error(`No tmux window found for session ${sessionId}`);\n\n const agent = await spawnAgent({\n sessionId,\n cwd,\n agentType,\n name,\n instruction,\n windowId,\n worktree,\n });\n\n await state.appendAgentToLastCycle(cwd, sessionId, agent.id);\n\n return { agentId: agent.id };\n}\n\nexport async function handleSubmit(cwd: string, sessionId: string, agentId: string, report: string, windowId: string): Promise<void> {\n const allDone = await handleAgentSubmit(cwd, sessionId, agentId, report);\n if (allDone) {\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n}\n\nexport async function handleReport(cwd: string, sessionId: string, agentId: string, content: string): Promise<void> {\n await handleAgentReport(cwd, sessionId, agentId, content);\n}\n\nexport async function handleYield(sessionId: string, cwd: string, nextPrompt?: string): Promise<void> {\n // Re-activate paused sessions so respawn can proceed\n const pre = state.getSession(cwd, sessionId);\n if (pre.status === 'paused') {\n await state.updateSessionStatus(cwd, sessionId, 'active');\n }\n\n await orchestrator.handleOrchestratorYield(sessionId, cwd, nextPrompt);\n\n const session = state.getSession(cwd, sessionId);\n const hasRunningAgents = session.agents.some(a => a.status === 'running');\n if (!hasRunningAgents) {\n const windowId = orchestrator.getWindowId(sessionId);\n if (windowId) {\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n }\n}\n\nexport async function handleComplete(sessionId: string, cwd: string, report: string): Promise<void> {\n await orchestrator.handleOrchestratorComplete(sessionId, cwd, report);\n}\n\nexport async function handleRegisterClaudeSession(\n cwd: string,\n sessionId: string,\n agentId: string,\n claudeSessionId: string,\n): Promise<void> {\n await state.updateAgent(cwd, sessionId, agentId, { claudeSessionId });\n}\n\nexport async function handleKill(sessionId: string, cwd: string): Promise<number> {\n const session = state.getSession(cwd, sessionId);\n const windowId = orchestrator.getWindowId(sessionId);\n\n // Kill all running agents\n let killedAgents = 0;\n for (const agent of session.agents) {\n if (agent.status === 'running') {\n await state.updateAgent(cwd, sessionId, agent.id, {\n status: 'killed',\n killedReason: 'session killed by user',\n completedAt: new Date().toISOString(),\n });\n killedAgents++;\n }\n }\n\n // Clean up worktrees for agents that had them\n for (const agent of session.agents) {\n if (agent.worktreePath && agent.branchName) {\n cleanupWorktree(cwd, agent.worktreePath, agent.branchName);\n }\n }\n\n // Kill the orchestrator pane if it exists\n const orchPaneId = orchestrator.getOrchestratorPaneId(sessionId);\n if (orchPaneId) {\n tmux.killPane(orchPaneId);\n }\n\n // Mark session as completed\n await state.updateSessionStatus(cwd, sessionId, 'completed');\n\n // Untrack from pane monitor\n untrackSession(sessionId);\n\n // Kill the entire tmux window\n if (windowId) {\n tmux.killWindow(windowId);\n }\n\n // Clean up agent counter\n clearAgentCounter(sessionId);\n\n return killedAgents;\n}\n","import { randomUUID } from 'node:crypto';\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { contextDir, logsPath, planPath, promptsDir, sessionDir, statePath } from '../shared/paths.js';\nimport type { Agent, AgentReport, OrchestratorCycle, Session, SessionStatus } from '../shared/types.js';\n\nconst PLAN_SEED = `---\ndescription: >\n Living document of what still needs to happen. Write out ne\n---\n`;\n\nconst LOGS_SEED = `---\ndescription: >\n Session memory. Record important observations, decisions, and findings here.\n This is your persistent memory across cycles: things you tried, what\n worked/failed, design decisions and their rationale, gotchas discovered during\n implementation.\n---\n`;\n\n// Per-session mutex to prevent read-modify-write races\nconst sessionLocks = new Map<string, Promise<void>>();\n\nasync function withSessionLock<T>(sessionId: string, fn: () => T): Promise<T> {\n const prev = sessionLocks.get(sessionId) ?? Promise.resolve();\n let resolve: () => void;\n const next = new Promise<void>(r => { resolve = r; });\n sessionLocks.set(sessionId, next);\n await prev;\n try {\n return fn();\n } finally {\n resolve!();\n }\n}\n\nfunction atomicWrite(filePath: string, data: string): void {\n const dir = dirname(filePath);\n const tmpPath = join(dir, `.state.${randomUUID()}.tmp`);\n writeFileSync(tmpPath, data, 'utf-8');\n renameSync(tmpPath, filePath);\n}\n\nexport function createSession(id: string, task: string, cwd: string): Session {\n const dir = sessionDir(cwd, id);\n mkdirSync(dir, { recursive: true });\n mkdirSync(contextDir(cwd, id), { recursive: true });\n mkdirSync(promptsDir(cwd, id), { recursive: true });\n\n writeFileSync(planPath(cwd, id), PLAN_SEED, 'utf-8');\n writeFileSync(logsPath(cwd, id), LOGS_SEED, 'utf-8');\n\n const session: Session = {\n id,\n task,\n cwd,\n status: 'active',\n createdAt: new Date().toISOString(),\n agents: [],\n orchestratorCycles: [],\n };\n\n atomicWrite(statePath(cwd, id), JSON.stringify(session, null, 2));\n return session;\n}\n\nexport function getSession(cwd: string, sessionId: string): Session {\n const content = readFileSync(statePath(cwd, sessionId), 'utf-8');\n return JSON.parse(content) as Session;\n}\n\nfunction saveSession(session: Session): void {\n atomicWrite(statePath(session.cwd, session.id), JSON.stringify(session, null, 2));\n}\n\nexport async function addAgent(cwd: string, sessionId: string, agent: Agent): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.agents.push(agent);\n saveSession(session);\n });\n}\n\nexport async function updateAgent(cwd: string, sessionId: string, agentId: string, updates: Partial<Agent>): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n Object.assign(agent, updates);\n saveSession(session);\n });\n}\n\nexport async function addOrchestratorCycle(cwd: string, sessionId: string, cycle: OrchestratorCycle): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.orchestratorCycles.push(cycle);\n saveSession(session);\n });\n}\n\nexport async function updateSessionStatus(cwd: string, sessionId: string, status: SessionStatus, completionReport?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = status;\n if (completionReport !== undefined) {\n session.completionReport = completionReport;\n }\n saveSession(session);\n });\n}\n\nexport async function appendAgentToLastCycle(cwd: string, sessionId: string, agentId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n cycles[cycles.length - 1]!.agentsSpawned.push(agentId);\n saveSession(session);\n });\n}\n\nexport async function completeSession(cwd: string, sessionId: string, report: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = 'completed';\n session.completedAt = new Date().toISOString();\n session.completionReport = report;\n saveSession(session);\n });\n}\n\nexport async function appendAgentReport(cwd: string, sessionId: string, agentId: string, entry: AgentReport): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n agent.reports.push(entry);\n saveSession(session);\n });\n}\n\nexport async function updateSessionTmux(cwd: string, sessionId: string, tmuxSessionName: string, tmuxWindowId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.tmuxSessionName = tmuxSessionName;\n session.tmuxWindowId = tmuxWindowId;\n saveSession(session);\n });\n}\n\nexport async function completeOrchestratorCycle(cwd: string, sessionId: string, nextPrompt?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n const cycle = cycles[cycles.length - 1]!;\n cycle.completedAt = new Date().toISOString();\n if (nextPrompt) cycle.nextPrompt = nextPrompt;\n saveSession(session);\n });\n}\n","import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { contextDir, logsPath, planPath, projectOrchestratorPromptPath, promptsDir, worktreeConfigPath } from '../shared/paths.js';\nimport type { Agent, Session } from '../shared/types.js';\nimport { ORCHESTRATOR_COLOR } from './colors.js';\nimport * as state from './state.js';\nimport * as tmux from './tmux.js';\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nconst sessionWindowMap = new Map<string, string>();\nconst sessionOrchestratorPane = new Map<string, string>();\n\nexport function getWindowId(sessionId: string): string | undefined {\n return sessionWindowMap.get(sessionId);\n}\n\nexport function setWindowId(sessionId: string, windowId: string): void {\n sessionWindowMap.set(sessionId, windowId);\n}\n\nexport function getOrchestratorPaneId(sessionId: string): string | undefined {\n return sessionOrchestratorPane.get(sessionId);\n}\n\nexport function setOrchestratorPaneId(sessionId: string, paneId: string): void {\n sessionOrchestratorPane.set(sessionId, paneId);\n}\n\nfunction loadOrchestratorPrompt(cwd: string): string {\n const projectPath = projectOrchestratorPromptPath(cwd);\n if (existsSync(projectPath)) {\n return readFileSync(projectPath, 'utf-8');\n }\n const bundledPath = resolve(import.meta.dirname, '../templates/orchestrator.md');\n return readFileSync(bundledPath, 'utf-8');\n}\n\nfunction formatStateForOrchestrator(session: Session): string {\n const shortId = session.id.slice(0, 8);\n const cycleNum = session.orchestratorCycles.length;\n\n const ctxDir = contextDir(session.cwd, session.id);\n let contextLines: string;\n if (existsSync(ctxDir)) {\n const files = readdirSync(ctxDir);\n contextLines = files.length > 0 ? files.map(f => `- ${f}`).join('\\n') : ' (none)';\n } else {\n contextLines = ' (none)';\n }\n\n const planFile = planPath(session.cwd, session.id);\n const planRef = existsSync(planFile) ? `@${planFile}` : '(empty)';\n\n const logsFile = logsPath(session.cwd, session.id);\n const logsRef = existsSync(logsFile) ? `@${logsFile}` : '(empty)';\n\n const agentLines = session.agents.length > 0\n ? session.agents.map((a: Agent) => {\n const header = `- ${a.id} (${a.name}): ${a.status} — ${a.reports.length} report(s)`;\n if (a.reports.length === 0) return header;\n let updateNum = 0;\n const reportLines = a.reports.map(r => {\n const label = r.type === 'final' ? '[final]' : `[update ${String(++updateNum).padStart(3, '0')}]`;\n return ` ${label} \"${r.summary}\" → ${r.filePath}`;\n });\n return [header, ...reportLines].join('\\n');\n }).join('\\n')\n : ' (none)';\n\n const cycleLines = session.orchestratorCycles.length > 0\n ? session.orchestratorCycles.map(c => {\n const spawnedList = c.agentsSpawned.length > 0 ? c.agentsSpawned.join(', ') : '(none)';\n return `Cycle ${c.cycle}: Spawned ${spawnedList}`;\n }).join('\\n')\n : ' (none)';\n\n // Worktree status — only if any agents have worktree info\n const worktreeAgents = session.agents.filter(a => a.worktreePath);\n let worktreeSection = '';\n if (worktreeAgents.length > 0) {\n const wtLines = worktreeAgents.map((a: Agent) => {\n if (a.mergeStatus === 'conflict') {\n return `- ${a.id}: CONFLICT — ${a.mergeDetails ?? 'unknown'}\\n Branch: ${a.branchName}\\n Worktree: ${a.worktreePath}`;\n }\n if (a.mergeStatus === 'no-changes') {\n return `- ${a.id}: NO CHANGES — agent did not commit any work to branch ${a.branchName}`;\n }\n const status = a.mergeStatus ?? 'pending';\n return `- ${a.id}: ${status} (branch ${a.branchName})`;\n }).join('\\n');\n worktreeSection = `\\n\\n## Worktrees\\n${wtLines}`;\n }\n\n // Worktree hint\n const worktreeHint = existsSync(worktreeConfigPath(session.cwd))\n ? 'Worktree config active (`.sisyphus/worktree.json`). Use `--worktree` flag with `sisyphus spawn` to isolate agents in their own worktrees. Recommended for feature work, especially with potential file overlap.'\n : 'No worktree configuration found. If this session involves parallel work where agents may edit overlapping files, use the `git-management` skill to set up `.sisyphus/worktree.json` and enable worktree isolation.';\n\n return `<state>\nsession: ${shortId} (cycle ${cycleNum})\ntask: ${session.task}\nstatus: ${session.status}\n\n## Plan\n${planRef}\n\n## Logs\n${logsRef}\n\n## Agents\n${agentLines}${worktreeSection}\n\n## Previous Cycles\n${cycleLines}\n\n## Context Files\n${contextLines}\n\n## Git Worktrees\n${worktreeHint}\n</state>`;\n}\n\nexport async function spawnOrchestrator(sessionId: string, cwd: string, windowId: string, message?: string): Promise<void> {\n const session = state.getSession(cwd, sessionId);\n const basePrompt = loadOrchestratorPrompt(cwd);\n const formattedState = formatStateForOrchestrator(session);\n\n // System prompt: template only (no state)\n const cycleNum = session.orchestratorCycles.length + 1;\n const promptFilePath = `${promptsDir(cwd, sessionId)}/orchestrator-system-${cycleNum}.md`;\n writeFileSync(promptFilePath, basePrompt, 'utf-8');\n\n sessionWindowMap.set(sessionId, windowId);\n\n const envExports = [\n `export SISYPHUS_SESSION_ID='${sessionId}'`,\n `export SISYPHUS_AGENT_ID='orchestrator'`,\n ].join(' && ');\n\n // User message: state block + contextual prompt\n let userPrompt: string;\n if (message) {\n userPrompt = `${formattedState}\\n\\nThe user resumed this session with new instructions: ${message}`;\n } else {\n // Check last completed cycle for a stored nextPrompt\n const lastCycle = [...session.orchestratorCycles].reverse().find(c => c.completedAt);\n const storedPrompt = lastCycle?.nextPrompt;\n if (storedPrompt) {\n userPrompt = `${formattedState}\\n\\n${storedPrompt}`;\n } else {\n userPrompt = `${formattedState}\\n\\nReview the current session and delegate the next cycle of work.`;\n }\n }\n\n const userPromptFilePath = `${promptsDir(cwd, sessionId)}/orchestrator-user-${cycleNum}.md`;\n writeFileSync(userPromptFilePath, userPrompt, 'utf-8');\n const pluginPath = resolve(import.meta.dirname, '../templates/orchestrator-plugin');\n const settingsPath = resolve(import.meta.dirname, '../templates/orchestrator-settings.json');\n const claudeCmd = `claude --dangerously-skip-permissions --settings \"${settingsPath}\" --plugin-dir \"${pluginPath}\" --append-system-prompt \"$(cat '${promptFilePath}')\" \"$(cat '${userPromptFilePath}')\"`;\n\n const paneId = tmux.createPane(windowId, cwd);\n\n sessionOrchestratorPane.set(sessionId, paneId);\n tmux.setPaneTitle(paneId, `orchestrator (${sessionId.slice(0, 8)})`);\n tmux.setPaneStyle(paneId, ORCHESTRATOR_COLOR);\n\n const bannerPath = resolve(import.meta.dirname, '../templates/banner.txt');\n const bannerCmd = existsSync(bannerPath) ? `cat '${bannerPath}' &&` : '';\n tmux.sendKeys(paneId, `${bannerCmd} ${envExports} && ${claudeCmd}`);\n\n await state.addOrchestratorCycle(cwd, sessionId, {\n cycle: cycleNum,\n timestamp: new Date().toISOString(),\n agentsSpawned: [],\n paneId,\n });\n}\n\nfunction resolveOrchestratorPane(sessionId: string, cwd: string): string | undefined {\n const memPane = sessionOrchestratorPane.get(sessionId);\n if (memPane) return memPane;\n const session = state.getSession(cwd, sessionId);\n const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];\n return lastCycle?.paneId ?? undefined;\n}\n\nexport async function handleOrchestratorYield(sessionId: string, cwd: string, nextPrompt?: string): Promise<void> {\n const paneId = resolveOrchestratorPane(sessionId, cwd);\n if (paneId) {\n tmux.killPane(paneId);\n sessionOrchestratorPane.delete(sessionId);\n }\n\n const windowId = sessionWindowMap.get(sessionId);\n if (windowId) tmux.selectLayout(windowId);\n\n await state.completeOrchestratorCycle(cwd, sessionId, nextPrompt);\n\n const session = state.getSession(cwd, sessionId);\n const runningAgents = session.agents.filter(a => a.status === 'running');\n if (runningAgents.length === 0) {\n console.log(`[sisyphus] Orchestrator yielded with no running agents for session ${sessionId}`);\n }\n}\n\nexport async function handleOrchestratorComplete(sessionId: string, cwd: string, report: string): Promise<void> {\n await state.completeOrchestratorCycle(cwd, sessionId);\n await state.completeSession(cwd, sessionId, report);\n\n console.log(`[sisyphus] Session ${sessionId} completed: ${report}`);\n}\n\nexport function cleanupSessionMaps(sessionId: string): void {\n sessionOrchestratorPane.delete(sessionId);\n sessionWindowMap.delete(sessionId);\n}\n","import { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const ORCHESTRATOR_COLOR = 'yellow';\n\nconst AGENT_PALETTE = ['blue', 'green', 'magenta', 'cyan', 'red', 'white'] as const;\n\nconst TMUX_COLOR_MAP: Record<string, string> = {\n orange: 'colour208',\n teal: 'colour6',\n};\n\nfunction normalizeTmuxColor(color: string): string {\n return TMUX_COLOR_MAP[color] ?? color;\n}\n\nconst sessionColorIndex = new Map<string, number>();\n\nexport function getNextColor(sessionId: string): string {\n const idx = sessionColorIndex.get(sessionId) ?? 0;\n const color = AGENT_PALETTE[idx % AGENT_PALETTE.length]!;\n sessionColorIndex.set(sessionId, idx + 1);\n return color;\n}\n\nexport function resetColors(sessionId: string): void {\n sessionColorIndex.delete(sessionId);\n}\n\nfunction extractFrontmatterColor(content: string): string | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n const colorMatch = match[1]!.match(/^color:\\s*(.+)$/m);\n return colorMatch ? colorMatch[1]!.trim() : null;\n}\n\nfunction findPluginInstallPath(namespace: string): string | null {\n try {\n const registryPath = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');\n const registry = JSON.parse(readFileSync(registryPath, 'utf-8'));\n for (const key of Object.keys(registry)) {\n if (key.startsWith(`${namespace}@`)) {\n return registry[key].installPath ?? null;\n }\n }\n } catch {\n // File missing, parse error, or no match\n }\n return null;\n}\n\nexport function resolveAgentTypeColor(agentType: string, pluginDir: string, cwd: string): string | null {\n if (!agentType) return null;\n\n let namespace: string | undefined;\n let name: string;\n\n if (agentType.includes(':')) {\n [namespace, name] = agentType.split(':', 2) as [string, string];\n } else {\n name = agentType;\n }\n\n const searchPaths: string[] = [];\n\n if (namespace) {\n // Bundled (handles sisyphus:* via pluginDir)\n searchPaths.push(join(pluginDir, 'agents', `${name}.md`));\n // Installed plugin\n const installPath = findPluginInstallPath(namespace);\n if (installPath) {\n searchPaths.push(join(installPath, 'agents', `${name}.md`));\n }\n } else {\n // Project-local\n searchPaths.push(join(cwd, '.claude', 'agents', `${name}.md`));\n // User-global\n searchPaths.push(join(homedir(), '.claude', 'agents', `${name}.md`));\n // Bundled\n searchPaths.push(join(pluginDir, 'agents', `${name}.md`));\n }\n\n for (const path of searchPaths) {\n try {\n const content = readFileSync(path, 'utf-8');\n const color = extractFrontmatterColor(content);\n if (color) return normalizeTmuxColor(color);\n } catch {\n // File doesn't exist, try next\n }\n }\n\n return null;\n}\n","import { execSync } from 'node:child_process';\n\nconst EXEC_ENV = {\n ...process.env,\n PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env['PATH'] ?? '/usr/bin:/bin'}`,\n};\n\nfunction exec(cmd: string): string {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV }).trim();\n}\n\nfunction execSafe(cmd: string): string | null {\n try {\n return exec(cmd);\n } catch {\n return null;\n }\n}\n\nexport function getCurrentTmuxSession(): string {\n const tmuxEnv = process.env['TMUX'];\n if (!tmuxEnv) throw new Error('Not running inside tmux');\n return exec('tmux display-message -p \"#{session_name}\"');\n}\n\nexport function createWindow(sessionName: string, windowName: string, cwd?: string): string {\n const cwdFlag = cwd ? ` -c ${shellQuote(cwd)}` : '';\n exec(`tmux new-window -t \"${sessionName}\" -n \"${windowName}\"${cwdFlag} -P -F \"#{window_id}\"`);\n return exec(`tmux display-message -t \"${sessionName}:${windowName}\" -p \"#{window_id}\"`);\n}\n\nexport function createPane(windowTarget: string, cwd?: string): string {\n const cwdFlag = cwd ? ` -c ${shellQuote(cwd)}` : '';\n const paneId = exec(`tmux split-window -h -t \"${windowTarget}\"${cwdFlag} -P -F \"#{pane_id}\"`);\n execSafe(`tmux select-layout -t \"${windowTarget}\" even-horizontal`);\n return paneId;\n}\n\nexport function sendKeys(paneTarget: string, command: string): void {\n exec(`tmux send-keys -t \"${paneTarget}\" ${shellQuote(command)} Enter`);\n}\n\nexport function killPane(paneTarget: string): void {\n execSafe(`tmux kill-pane -t \"${paneTarget}\"`);\n}\n\nexport function killWindow(windowTarget: string): void {\n execSafe(`tmux kill-window -t \"${windowTarget}\"`);\n}\n\nexport interface PaneInfo {\n paneId: string;\n panePid: string;\n}\n\nexport function listPanes(windowTarget: string): PaneInfo[] {\n const output = execSafe(`tmux list-panes -t \"${windowTarget}\" -F \"#{pane_id} #{pane_pid}\"`);\n if (!output) return [];\n return output\n .split('\\n')\n .filter(Boolean)\n .map(line => {\n const [paneId, panePid] = line.split(' ');\n return { paneId: paneId!, panePid: panePid! };\n });\n}\n\nexport function setPaneTitle(paneTarget: string, title: string): void {\n execSafe(`tmux select-pane -t \"${paneTarget}\" -T ${shellQuote(title)}`);\n}\n\nexport function setPaneStyle(paneTarget: string, color: string): void {\n const fmt = `#[fg=${color},bold] #{pane_title} #[fg=${color}]#{pane_current_path} #[default]`;\n execSafe(`tmux set -p -t \"${paneTarget}\" pane-border-format ${shellQuote(fmt)}`);\n // Store color as a per-pane user variable. The window-level border styles use a\n // format string that resolves #{@pane_color} per-pane at render time, giving each\n // pane its own border color (pane-border-style itself is window-level / last-write-wins).\n execSafe(`tmux set -p -t \"${paneTarget}\" @pane_color \"${color}\"`);\n execSafe(`tmux set -w -t \"${paneTarget}\" pane-border-style \"fg=#{?#{@pane_color},#{@pane_color},default}\"`);\n execSafe(`tmux set -w -t \"${paneTarget}\" pane-active-border-style \"fg=#{?#{@pane_color},#{@pane_color},default}\"`);\n}\n\nexport function sendSignal(paneTarget: string, signal: string): void {\n const info = execSafe(`tmux list-panes -t \"${paneTarget}\" -F \"#{pane_pid}\"`);\n if (!info) return;\n const pid = info.split('\\n')[0]?.trim();\n if (pid) {\n execSafe(`kill -${signal} ${pid}`);\n }\n}\n\nexport function selectLayout(windowTarget: string, layout: string = 'even-horizontal'): void {\n execSafe(`tmux select-layout -t \"${windowTarget}\" ${layout}`);\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { Agent, AgentReport } from '../shared/types.js';\nimport * as state from './state.js';\nimport * as tmux from './tmux.js';\nimport { getNextColor, resolveAgentTypeColor } from './colors.js';\nimport { getWindowId } from './orchestrator.js';\nimport { promptsDir, reportsDir, reportFilePath } from '../shared/paths.js';\nimport { createWorktreeShell, bootstrapWorktree, loadWorktreeConfig, countWorktreeAgents } from './worktree.js';\n\nconst agentCounters = new Map<string, number>();\n\nexport function resetAgentCounter(sessionId: string, value: number = 0): void {\n agentCounters.set(sessionId, value);\n}\n\nexport function resetAgentCounterFromState(sessionId: string, agents: { id: string }[]): void {\n let max = 0;\n for (const a of agents) {\n const match = a.id.match(/^agent-(\\d+)$/);\n if (match) max = Math.max(max, parseInt(match[1]!, 10));\n }\n agentCounters.set(sessionId, max);\n}\n\nexport function clearAgentCounter(sessionId: string): void {\n agentCounters.delete(sessionId);\n}\n\ninterface WorktreeContext {\n offset: number;\n total: number;\n branchName: string;\n}\n\nfunction renderAgentSuffix(sessionId: string, instruction: string, worktreeContext?: WorktreeContext): string {\n const templatePath = resolve(import.meta.dirname, '../templates/agent-suffix.md');\n let template: string;\n try {\n template = readFileSync(templatePath, 'utf-8');\n } catch {\n template = `# Sisyphus Agent\\nSession: {{SESSION_ID}}\\nTask: {{INSTRUCTION}}`;\n }\n\n let worktreeBlock = '';\n if (worktreeContext) {\n worktreeBlock = [\n '## Worktree Context',\n `You are working in an isolated git worktree on branch \\`${worktreeContext.branchName}\\`.`,\n `If you start any services that require ports, add ${worktreeContext.offset} to the default port.`,\n ].join('\\n');\n }\n\n return template\n .replace(/\\{\\{SESSION_ID\\}\\}/g, sessionId)\n .replace(/\\{\\{INSTRUCTION\\}\\}/g, instruction)\n .replace(/\\{\\{WORKTREE_CONTEXT\\}\\}/g, worktreeBlock);\n}\n\nexport interface SpawnAgentOpts {\n sessionId: string;\n cwd: string;\n agentType: string;\n name: string;\n instruction: string;\n windowId: string;\n worktree?: boolean;\n}\n\nexport async function spawnAgent(opts: SpawnAgentOpts): Promise<Agent> {\n const { sessionId, cwd, agentType, name, instruction, windowId } = opts;\n const count = (agentCounters.get(sessionId) ?? 0) + 1;\n agentCounters.set(sessionId, count);\n const agentId = `agent-${String(count).padStart(3, '0')}`;\n const pluginPath = resolve(import.meta.dirname, '../templates/agent-plugin');\n const color = resolveAgentTypeColor(agentType, pluginPath, cwd) ?? getNextColor(sessionId);\n\n let paneCwd = cwd;\n let worktreePath: string | undefined;\n let branchName: string | undefined;\n let worktreeContext: WorktreeContext | undefined;\n\n if (opts.worktree) {\n // Fast: git branch + worktree add + symlinks only (no bootstrap/init)\n const wt = createWorktreeShell(cwd, sessionId, agentId);\n worktreePath = wt.worktreePath;\n branchName = wt.branchName;\n paneCwd = worktreePath;\n\n const session = state.getSession(cwd, sessionId);\n const portOffset = countWorktreeAgents(session.agents) + 1;\n worktreeContext = { offset: portOffset, total: portOffset, branchName };\n }\n\n const paneId = tmux.createPane(windowId, paneCwd);\n tmux.setPaneTitle(paneId, `${name} (${agentId})`);\n tmux.setPaneStyle(paneId, color);\n\n const suffix = renderAgentSuffix(sessionId, instruction, worktreeContext);\n const suffixFilePath = `${promptsDir(cwd, sessionId)}/${agentId}-system.md`;\n writeFileSync(suffixFilePath, suffix, 'utf-8');\n\n const bannerPath = resolve(import.meta.dirname, '../templates/banner.txt');\n const bannerCmd = existsSync(bannerPath) ? `cat '${bannerPath}' &&` : '';\n\n const envExports = [\n `export SISYPHUS_SESSION_ID='${sessionId}'`,\n `export SISYPHUS_AGENT_ID='${agentId}'`,\n ...(worktreeContext ? [`export SISYPHUS_PORT_OFFSET='${worktreeContext.offset}'`] : []),\n ].join(' && ');\n\n const agentFlag = agentType ? ` --agent ${shellQuote(agentType)}` : '';\n const claudeCmd = `claude --dangerously-skip-permissions --plugin-dir \"${pluginPath}\"${agentFlag} --append-system-prompt \"$(cat '${suffixFilePath}')\" ${shellQuote(instruction)}`;\n const fullCmd = `${bannerCmd} ${envExports} && ${claudeCmd}`;\n\n const agent: Agent = {\n id: agentId,\n name,\n agentType,\n color,\n instruction,\n status: 'running',\n spawnedAt: new Date().toISOString(),\n completedAt: null,\n reports: [],\n paneId,\n ...(worktreePath ? { worktreePath, branchName, mergeStatus: 'pending' as const } : {}),\n };\n\n await state.addAgent(cwd, sessionId, agent);\n\n if (opts.worktree && worktreePath) {\n // Defer bootstrap so the daemon can respond to the CLI before running\n // the potentially slow init command (e.g. npm install).\n // The pane is already visible; Claude command is sent after bootstrap.\n const config = loadWorktreeConfig(cwd);\n if (config) {\n const wtPath = worktreePath;\n setImmediate(() => {\n try {\n bootstrapWorktree(cwd, wtPath, config);\n } catch (err) {\n console.error(`[sisyphus] worktree bootstrap failed for ${agentId}: ${err instanceof Error ? err.message : err}`);\n }\n tmux.sendKeys(paneId, fullCmd);\n });\n } else {\n tmux.sendKeys(paneId, fullCmd);\n }\n } else {\n tmux.sendKeys(paneId, fullCmd);\n }\n\n return agent;\n}\n\nfunction nextReportNumber(cwd: string, sessionId: string, agentId: string): string {\n const dir = reportsDir(cwd, sessionId);\n try {\n const files = readdirSync(dir).filter(f => f.startsWith(`${agentId}-`) && !f.endsWith('-final.md'));\n return String(files.length + 1).padStart(3, '0');\n } catch {\n return '001';\n }\n}\n\nexport async function handleAgentReport(\n cwd: string,\n sessionId: string,\n agentId: string,\n content: string,\n): Promise<void> {\n const dir = reportsDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n\n const num = nextReportNumber(cwd, sessionId, agentId);\n const filePath = reportFilePath(cwd, sessionId, agentId, num);\n writeFileSync(filePath, content, 'utf-8');\n\n const entry: AgentReport = {\n type: 'update',\n filePath,\n summary: content.slice(0, 200),\n timestamp: new Date().toISOString(),\n };\n await state.appendAgentReport(cwd, sessionId, agentId, entry);\n}\n\nexport async function handleAgentSubmit(\n cwd: string,\n sessionId: string,\n agentId: string,\n report: string,\n): Promise<boolean> {\n const dir = reportsDir(cwd, sessionId);\n mkdirSync(dir, { recursive: true });\n\n const filePath = reportFilePath(cwd, sessionId, agentId, 'final');\n writeFileSync(filePath, report, 'utf-8');\n\n const entry: AgentReport = {\n type: 'final',\n filePath,\n summary: report.slice(0, 200),\n timestamp: new Date().toISOString(),\n };\n await state.appendAgentReport(cwd, sessionId, agentId, entry);\n\n await state.updateAgent(cwd, sessionId, agentId, {\n status: 'completed',\n completedAt: new Date().toISOString(),\n });\n\n const session = state.getSession(cwd, sessionId);\n const agentArr = session.agents;\n const agent = agentArr.slice().reverse().find(a => a.id === agentId);\n if (agent) {\n tmux.killPane(agent.paneId);\n }\n\n const windowId = getWindowId(sessionId);\n if (windowId) tmux.selectLayout(windowId);\n\n return allAgentsDone(session);\n}\n\nexport async function handleAgentKilled(\n cwd: string,\n sessionId: string,\n agentId: string,\n reason: string,\n): Promise<boolean> {\n await state.updateAgent(cwd, sessionId, agentId, {\n status: 'killed',\n killedReason: reason,\n completedAt: new Date().toISOString(),\n });\n\n const session = state.getSession(cwd, sessionId);\n return allAgentsDone(session);\n}\n\n// Note: this checks ALL running agents in the session, not just orchestrator-spawned ones.\n// Agents can also call `sisyphus spawn`, and those child agents are included here —\n// the orchestrator won't respawn until every agent (including agent-spawned ones) finishes.\nfunction allAgentsDone(session: import('../shared/types.js').Session): boolean {\n const running = session.agents.filter(a => a.status === 'running');\n return running.length === 0 && session.agents.length > 0;\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { Agent } from '../shared/types.js';\nimport type { WorktreeConfig } from '../shared/config.js';\nimport { worktreeConfigPath, worktreeBaseDir } from '../shared/paths.js';\n\nconst EXEC_ENV = {\n ...process.env,\n PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env['PATH'] ?? '/usr/bin:/bin'}`,\n};\n\nfunction exec(cmd: string, cwd?: string): string {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV, cwd }).trim();\n}\n\nfunction execSafe(cmd: string, cwd?: string): string | null {\n try {\n return exec(cmd, cwd);\n } catch {\n return null;\n }\n}\n\nfunction shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nexport interface MergeResult {\n agentId: string;\n name: string;\n status: 'merged' | 'conflict' | 'no-changes';\n conflictDetails?: string;\n}\n\nexport function loadWorktreeConfig(cwd: string): WorktreeConfig | null {\n try {\n const content = readFileSync(worktreeConfigPath(cwd), 'utf-8');\n return JSON.parse(content) as WorktreeConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Create git worktree (branch + add + symlinks) without running bootstrap.\n * Fast enough to run synchronously before responding to the CLI.\n */\nexport function createWorktreeShell(\n cwd: string,\n sessionId: string,\n agentId: string,\n): { worktreePath: string; branchName: string } {\n const branchName = `sisyphus/${sessionId.slice(0, 8)}/${agentId}`;\n // Bug B: Include session prefix in path to prevent cross-session collisions\n const worktreePath = join(worktreeBaseDir(cwd), sessionId.slice(0, 8), agentId);\n\n mkdirSync(dirname(worktreePath), { recursive: true });\n\n // Bug C: Clean stale worktree entries before creating\n execSafe(`git -C ${shellQuote(cwd)} worktree prune`);\n if (existsSync(worktreePath)) {\n execSafe(`git -C ${shellQuote(cwd)} worktree remove --force ${shellQuote(worktreePath)}`);\n }\n // If the branch already exists from a previous run, remove it\n execSafe(`git -C ${shellQuote(cwd)} branch -D ${shellQuote(branchName)}`);\n\n exec(`git -C ${shellQuote(cwd)} branch ${shellQuote(branchName)} HEAD`);\n exec(`git -C ${shellQuote(cwd)} worktree add ${shellQuote(worktreePath)} ${shellQuote(branchName)}`);\n\n return { worktreePath, branchName };\n}\n\n/**\n * Create git worktree AND run bootstrap synchronously.\n * Use createWorktreeShell + bootstrapWorktree separately when you need\n * to defer the slow bootstrap to avoid blocking.\n */\nexport function createWorktree(\n cwd: string,\n sessionId: string,\n agentId: string,\n): { worktreePath: string; branchName: string } {\n const result = createWorktreeShell(cwd, sessionId, agentId);\n\n const config = loadWorktreeConfig(cwd);\n if (config) {\n bootstrapWorktree(cwd, result.worktreePath, config);\n }\n\n return result;\n}\n\nexport function bootstrapWorktree(cwd: string, worktreePath: string, config: WorktreeConfig): void {\n // Process copy entries\n if (config.copy) {\n for (const entry of config.copy) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n execSafe(`cp -r ${shellQuote(join(cwd, entry))} ${shellQuote(dest)}`);\n }\n }\n\n // Process clone entries (APFS CoW on macOS, fallback to cp -r)\n if (config.clone) {\n for (const entry of config.clone) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n const src = shellQuote(join(cwd, entry));\n const dstQ = shellQuote(dest);\n if (execSafe(`cp -Rc ${src} ${dstQ}`) === null) {\n execSafe(`cp -r ${src} ${dstQ}`);\n }\n }\n }\n\n // Process symlink entries\n if (config.symlink) {\n for (const entry of config.symlink) {\n const dest = join(worktreePath, entry);\n mkdirSync(dirname(dest), { recursive: true });\n execSafe(`ln -s ${shellQuote(join(cwd, entry))} ${shellQuote(dest)}`);\n }\n }\n\n // Process init command\n if (config.init) {\n try {\n exec(config.init, worktreePath);\n } catch (err) {\n console.error(`[sisyphus] worktree init command failed: ${err instanceof Error ? err.message : err}`);\n }\n }\n}\n\n/**\n * Resolve the branch checked out in a worktree by parsing `git worktree list --porcelain`.\n * Returns null if the worktree isn't found or has a detached HEAD.\n */\nfunction resolveWorktreeBranch(cwd: string, worktreePath: string): string | null {\n const output = execSafe(`git -C ${shellQuote(cwd)} worktree list --porcelain`);\n if (!output) return null;\n\n const lines = output.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (lines[i] === `worktree ${worktreePath}`) {\n for (let j = i + 1; j < lines.length; j++) {\n const line = lines[j]!;\n if (line === '') break; // end of this worktree block\n if (line.startsWith('branch refs/heads/')) {\n return line.slice('branch refs/heads/'.length);\n }\n }\n break;\n }\n }\n return null;\n}\n\nexport function mergeWorktrees(cwd: string, agents: Agent[]): MergeResult[] {\n const pending = agents.filter(\n a => a.worktreePath && a.mergeStatus === 'pending',\n );\n\n const results: MergeResult[] = [];\n\n // Snapshot any uncommitted .sisyphus state changes before merging\n // so agent branches don't conflict with main's session state updates\n execSafe(`git -C ${shellQuote(cwd)} add .sisyphus`);\n execSafe(`git -C ${shellQuote(cwd)} commit -m 'sisyphus: snapshot session state before merge'`);\n\n for (const agent of pending) {\n const branch = resolveWorktreeBranch(cwd, agent.worktreePath!);\n\n if (!branch) {\n results.push({ agentId: agent.id, name: agent.name, status: 'no-changes' });\n // Best-effort cleanup — branch name unknown, just remove worktree dir\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(agent.worktreePath!)} --force`);\n continue;\n }\n\n // Check if branch has commits ahead of merge base\n const aheadLog = execSafe(`git -C ${shellQuote(cwd)} log HEAD..${shellQuote(branch)} --oneline`);\n if (!aheadLog) {\n results.push({ agentId: agent.id, name: agent.name, status: 'no-changes' });\n cleanupWorktree(cwd, agent.worktreePath!, branch);\n continue;\n }\n\n // Attempt merge — capture stderr on failure for conflict details\n const mergeMsg = `sisyphus: merge ${agent.id} (${agent.name})`;\n const mergeCmd = `git -C ${shellQuote(cwd)} merge --no-ff ${shellQuote(branch)} -m ${shellQuote(mergeMsg)}`;\n\n try {\n exec(mergeCmd);\n // Merge succeeded — clean up worktree and branch\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(agent.worktreePath!)}`);\n execSafe(`git -C ${shellQuote(cwd)} branch -d ${shellQuote(branch)}`);\n results.push({ agentId: agent.id, name: agent.name, status: 'merged' });\n } catch (err: unknown) {\n // Merge failed — abort and leave worktree intact for manual resolution\n execSafe(`git -C ${shellQuote(cwd)} merge --abort`);\n // Git outputs conflict details (which files, conflict type) to stdout, not stderr\n const errObj = err as { stdout?: Buffer | string; stderr?: Buffer | string };\n const stdout = errObj.stdout\n ? (typeof errObj.stdout === 'string' ? errObj.stdout : errObj.stdout.toString('utf-8')).trim()\n : '';\n const stderr = errObj.stderr\n ? (typeof errObj.stderr === 'string' ? errObj.stderr : errObj.stderr.toString('utf-8')).trim()\n : '';\n const conflictDetails = stdout || stderr || (err instanceof Error ? err.message : String(err));\n results.push({ agentId: agent.id, name: agent.name, status: 'conflict', conflictDetails });\n }\n }\n\n return results;\n}\n\nexport function cleanupWorktree(cwd: string, worktreePath: string, branchName: string): void {\n execSafe(`git -C ${shellQuote(cwd)} worktree remove ${shellQuote(worktreePath)} --force`);\n execSafe(`git -C ${shellQuote(cwd)} branch -D ${shellQuote(branchName)}`);\n\n // Remove the worktree base dir if empty\n const baseDir = dirname(worktreePath);\n try {\n const entries = readdirSync(baseDir);\n if (entries.length === 0) {\n rmSync(baseDir, { recursive: true });\n }\n } catch {\n // Ignore — directory may already be gone\n }\n}\n\nexport function countWorktreeAgents(agents: Agent[]): number {\n return agents.filter(a => a.worktreePath && a.status === 'running').length;\n}\n","import * as state from './state.js';\nimport * as tmux from './tmux.js';\nimport { getOrchestratorPaneId, cleanupSessionMaps } from './orchestrator.js';\nimport { handleAgentKilled } from './agent.js';\n\ntype RespawnCallback = (sessionId: string, cwd: string, windowId: string) => void;\n\nlet monitorInterval: ReturnType<typeof setInterval> | null = null;\nlet onAllAgentsDone: RespawnCallback | null = null;\n\nexport function setRespawnCallback(cb: RespawnCallback): void {\n onAllAgentsDone = cb;\n}\n\nexport function startMonitor(pollIntervalMs: number = 1000): void {\n if (monitorInterval) return;\n monitorInterval = setInterval(() => {\n pollAllSessions().catch(err => {\n console.error('[sisyphus] Pane monitor error:', err);\n });\n }, pollIntervalMs);\n}\n\nexport function stopMonitor(): void {\n if (monitorInterval) {\n clearInterval(monitorInterval);\n monitorInterval = null;\n }\n}\n\nconst trackedSessions = new Map<string, { id: string; cwd: string; tmuxSession: string; windowId: string | null }>();\n\nexport function trackSession(sessionId: string, cwd: string, tmuxSession: string): void {\n // windowId is registered separately via updateTrackedWindow after spawnOrchestrator sets it\n const existing = trackedSessions.get(sessionId);\n trackedSessions.set(sessionId, { id: sessionId, cwd, tmuxSession, windowId: existing ? existing.windowId : null });\n}\n\nexport function updateTrackedWindow(sessionId: string, windowId: string): void {\n const entry = trackedSessions.get(sessionId);\n if (!entry) throw new Error(`Cannot update window for untracked session: ${sessionId}`);\n entry.windowId = windowId;\n}\n\nexport function untrackSession(sessionId: string): void {\n trackedSessions.delete(sessionId);\n}\n\nasync function pollAllSessions(): Promise<void> {\n for (const { id: sessionId, cwd, windowId } of trackedSessions.values()) {\n if (windowId) {\n await pollSession(sessionId, cwd, windowId);\n }\n }\n}\n\nasync function pollSession(sessionId: string, cwd: string, windowId: string): Promise<void> {\n let session;\n try {\n session = state.getSession(cwd, sessionId);\n } catch (err) {\n console.error(`[sisyphus] Failed to read state for session ${sessionId}:`, err);\n return;\n }\n\n if (session.status === 'completed') {\n const orchPaneId = getOrchestratorPaneId(sessionId);\n if (orchPaneId) {\n const livePanes = tmux.listPanes(windowId);\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n if (!livePaneIds.has(orchPaneId)) {\n cleanupSessionMaps(sessionId);\n untrackSession(sessionId);\n console.log(`[sisyphus] Session ${sessionId} cleaned up: orchestrator pane closed by user`);\n }\n } else {\n // No orchestrator pane tracked — clean up immediately\n cleanupSessionMaps(sessionId);\n untrackSession(sessionId);\n }\n return;\n }\n\n if (session.status !== 'active') return;\n\n const livePanes = tmux.listPanes(windowId);\n if (livePanes.length === 0) return;\n\n const livePaneIds = new Set(livePanes.map(p => p.paneId));\n\n let paneRemoved = false;\n for (const agent of session.agents) {\n if (agent.status !== 'running') continue;\n if (!livePaneIds.has(agent.paneId)) {\n paneRemoved = true;\n const allDone = await handleAgentKilled(cwd, sessionId, agent.id, 'pane closed by user');\n if (allDone && onAllAgentsDone) {\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n }\n }\n\n if (paneRemoved) tmux.selectLayout(windowId);\n\n // Check orchestrator pane\n const orchPaneId = getOrchestratorPaneId(sessionId);\n if (orchPaneId && !livePaneIds.has(orchPaneId)) {\n // Orchestrator pane disappeared without a yield command\n const runningAgents = session.agents.filter(a => a.status === 'running');\n if (runningAgents.length === 0) {\n // No agents running and orchestrator gone — pause\n await state.updateSessionStatus(cwd, sessionId, 'paused');\n console.log(`[sisyphus] Session ${sessionId} paused: orchestrator pane disappeared`);\n }\n }\n\n // Re-read state since handleAgentKilled may have mutated it\n session = state.getSession(cwd, sessionId);\n if (\n session.status === 'active' &&\n session.agents.length > 0 &&\n session.agents.every(a => a.status !== 'running') &&\n (!orchPaneId || !livePaneIds.has(orchPaneId)) &&\n onAllAgentsDone\n ) {\n console.log(`[sisyphus] Detected stuck session ${sessionId}: all agents done, no orchestrator — triggering respawn`);\n onAllAgentsDone(sessionId, cwd, windowId);\n }\n}\n"],"mappings":"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","names":["mkdirSync","readFileSync","writeFileSync","unlinkSync","existsSync","existsSync","writeFileSync","readFileSync","mkdirSync","join","existsSync","readdirSync","rmSync","readFileSync","resolve","readFileSync","readFileSync","writeFileSync","readFileSync","join","registryPath","command","readFileSync","writeFileSync","readFileSync","writeFileSync","mkdirSync","readdirSync","existsSync","resolve","execSync","existsSync","mkdirSync","readFileSync","readdirSync","dirname","join","EXEC_ENV","exec","execSync","execSafe","shellQuote","readFileSync","join","mkdirSync","dirname","existsSync","join","mkdirSync","dirname","execSafe","shellQuote","exec","readdirSync","resolve","readFileSync","writeFileSync","existsSync","shellQuote","readdirSync","mkdirSync","orchPaneId","livePanes","livePaneIds","existsSync","readdirSync","rmSync","onAllAgentsDone","sessionWindowMap","join","mkdirSync","writeFileSync","existsSync","readFileSync","sessionWindowMap","resolve","mkdirSync","readFileSync","writeFileSync","unlinkSync","existsSync","onAllAgentsDone"]}
@@ -1,4 +1,12 @@
1
1
  #!/bin/bash
2
- cat <<'EOF'
2
+ MARKER="/tmp/sisyphus-exit-${SISYPHUS_SESSION_ID}"
3
+ if [ -f "$MARKER" ]; then
4
+ rm -f "$MARKER"
5
+ cat <<'EOF'
6
+ {"decision":"approve"}
7
+ EOF
8
+ else
9
+ cat <<'EOF'
3
10
  {"decision":"block","reason":"Before stopping, consider: use `sisyphus yield` to end this cycle and let the daemon respawn you with updated state, or use AskUserQuestion if you need clarification from the user."}
4
11
  EOF
12
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sisyphi",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "tmux-integrated orchestration daemon for Claude Code multi-agent workflows",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,4 +1,12 @@
1
1
  #!/bin/bash
2
- cat <<'EOF'
2
+ MARKER="/tmp/sisyphus-exit-${SISYPHUS_SESSION_ID}"
3
+ if [ -f "$MARKER" ]; then
4
+ rm -f "$MARKER"
5
+ cat <<'EOF'
6
+ {"decision":"approve"}
7
+ EOF
8
+ else
9
+ cat <<'EOF'
3
10
  {"decision":"block","reason":"Before stopping, consider: use `sisyphus yield` to end this cycle and let the daemon respawn you with updated state, or use AskUserQuestion if you need clarification from the user."}
4
11
  EOF
12
+ fi