sisyphi 1.0.14 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/{chunk-Q6VQOUN3.js → chunk-M7LZ2ZHD.js} +3 -27
  2. package/dist/chunk-M7LZ2ZHD.js.map +1 -0
  3. package/dist/{chunk-YGBGKMTF.js → chunk-REUQ4B45.js} +7 -11
  4. package/dist/chunk-REUQ4B45.js.map +1 -0
  5. package/dist/{chunk-MMA43N67.js → chunk-Z32YVDMY.js} +2 -2
  6. package/dist/chunk-Z32YVDMY.js.map +1 -0
  7. package/dist/cli.js +38 -47
  8. package/dist/cli.js.map +1 -1
  9. package/dist/daemon.js +795 -796
  10. package/dist/daemon.js.map +1 -1
  11. package/dist/{paths-FYYSBD27.js → paths-IJXOAN4E.js} +4 -6
  12. package/dist/templates/CLAUDE.md +16 -14
  13. package/dist/templates/agent-plugin/agents/CLAUDE.md +17 -6
  14. package/dist/templates/agent-plugin/agents/design.md +134 -0
  15. package/dist/templates/agent-plugin/agents/explore.md +39 -0
  16. package/dist/templates/agent-plugin/agents/operator.md +24 -0
  17. package/dist/templates/agent-plugin/agents/plan.md +15 -20
  18. package/dist/templates/agent-plugin/agents/problem.md +119 -0
  19. package/dist/templates/agent-plugin/agents/requirements.md +138 -0
  20. package/dist/templates/agent-plugin/agents/review/CLAUDE.md +29 -0
  21. package/dist/templates/agent-plugin/agents/review/compliance.md +6 -6
  22. package/dist/templates/agent-plugin/agents/review-plan/code-smells.md +4 -4
  23. package/dist/templates/agent-plugin/agents/review-plan/requirements-coverage.md +62 -0
  24. package/dist/templates/agent-plugin/agents/review-plan/security.md +1 -1
  25. package/dist/templates/agent-plugin/agents/review-plan.md +9 -8
  26. package/dist/templates/agent-plugin/agents/review.md +1 -1
  27. package/dist/templates/agent-plugin/agents/test-spec.md +2 -2
  28. package/dist/templates/agent-plugin/hooks/CLAUDE.md +2 -2
  29. package/dist/templates/agent-plugin/hooks/explore-user-prompt.sh +13 -0
  30. package/dist/templates/agent-plugin/hooks/plan-user-prompt.sh +1 -1
  31. package/dist/templates/agent-plugin/hooks/require-submit.sh +69 -2
  32. package/dist/templates/agent-plugin/hooks/review-plan-user-prompt.sh +4 -4
  33. package/dist/templates/agent-plugin/hooks/review-user-prompt.sh +1 -1
  34. package/dist/templates/agent-suffix.md +0 -2
  35. package/dist/templates/orchestrator-base.md +167 -145
  36. package/dist/templates/orchestrator-impl.md +92 -57
  37. package/dist/templates/orchestrator-planning.md +46 -56
  38. package/dist/templates/orchestrator-plugin/commands/sisyphus/design.md +13 -0
  39. package/dist/templates/orchestrator-plugin/commands/sisyphus/problem.md +13 -0
  40. package/dist/templates/orchestrator-plugin/commands/sisyphus/requirements.md +13 -0
  41. package/dist/templates/orchestrator-plugin/commands/sisyphus/strategize.md +19 -0
  42. package/dist/templates/orchestrator-plugin/hooks/explore-gate.sh +15 -0
  43. package/dist/templates/orchestrator-plugin/hooks/hooks.json +14 -1
  44. package/dist/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +34 -27
  45. package/dist/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +56 -24
  46. package/dist/templates/orchestrator-strategy.md +233 -0
  47. package/dist/templates/orchestrator-validation.md +94 -0
  48. package/dist/tui.js +134 -91
  49. package/dist/tui.js.map +1 -1
  50. package/package.json +1 -1
  51. package/templates/CLAUDE.md +16 -14
  52. package/templates/agent-plugin/agents/CLAUDE.md +17 -6
  53. package/templates/agent-plugin/agents/design.md +134 -0
  54. package/templates/agent-plugin/agents/explore.md +39 -0
  55. package/templates/agent-plugin/agents/operator.md +24 -0
  56. package/templates/agent-plugin/agents/plan.md +15 -20
  57. package/templates/agent-plugin/agents/problem.md +119 -0
  58. package/templates/agent-plugin/agents/requirements.md +138 -0
  59. package/templates/agent-plugin/agents/review/CLAUDE.md +29 -0
  60. package/templates/agent-plugin/agents/review/compliance.md +6 -6
  61. package/templates/agent-plugin/agents/review-plan/code-smells.md +4 -4
  62. package/templates/agent-plugin/agents/review-plan/requirements-coverage.md +62 -0
  63. package/templates/agent-plugin/agents/review-plan/security.md +1 -1
  64. package/templates/agent-plugin/agents/review-plan.md +9 -8
  65. package/templates/agent-plugin/agents/review.md +1 -1
  66. package/templates/agent-plugin/agents/test-spec.md +2 -2
  67. package/templates/agent-plugin/hooks/CLAUDE.md +2 -2
  68. package/templates/agent-plugin/hooks/explore-user-prompt.sh +13 -0
  69. package/templates/agent-plugin/hooks/plan-user-prompt.sh +1 -1
  70. package/templates/agent-plugin/hooks/require-submit.sh +69 -2
  71. package/templates/agent-plugin/hooks/review-plan-user-prompt.sh +4 -4
  72. package/templates/agent-plugin/hooks/review-user-prompt.sh +1 -1
  73. package/templates/agent-suffix.md +0 -2
  74. package/templates/orchestrator-base.md +167 -145
  75. package/templates/orchestrator-impl.md +92 -57
  76. package/templates/orchestrator-planning.md +46 -56
  77. package/templates/orchestrator-plugin/commands/sisyphus/design.md +13 -0
  78. package/templates/orchestrator-plugin/commands/sisyphus/problem.md +13 -0
  79. package/templates/orchestrator-plugin/commands/sisyphus/requirements.md +13 -0
  80. package/templates/orchestrator-plugin/commands/sisyphus/strategize.md +19 -0
  81. package/templates/orchestrator-plugin/hooks/explore-gate.sh +15 -0
  82. package/templates/orchestrator-plugin/hooks/hooks.json +14 -1
  83. package/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +34 -27
  84. package/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +56 -24
  85. package/templates/orchestrator-strategy.md +233 -0
  86. package/templates/orchestrator-validation.md +94 -0
  87. package/dist/chunk-MMA43N67.js.map +0 -1
  88. package/dist/chunk-Q6VQOUN3.js.map +0 -1
  89. package/dist/chunk-YGBGKMTF.js.map +0 -1
  90. package/dist/templates/agent-plugin/agents/review-plan/spec-coverage.md +0 -44
  91. package/dist/templates/agent-plugin/agents/spec-draft.md +0 -78
  92. package/dist/templates/agent-plugin/hooks/hooks.json +0 -25
  93. package/dist/templates/agent-plugin/hooks/spec-user-prompt.sh +0 -19
  94. package/dist/templates/orchestrator-plugin/skills/git-management/SKILL.md +0 -111
  95. package/templates/agent-plugin/agents/review-plan/spec-coverage.md +0 -44
  96. package/templates/agent-plugin/agents/spec-draft.md +0 -78
  97. package/templates/agent-plugin/hooks/hooks.json +0 -25
  98. package/templates/agent-plugin/hooks/spec-user-prompt.sh +0 -19
  99. package/templates/orchestrator-plugin/skills/git-management/SKILL.md +0 -111
  100. /package/dist/{paths-FYYSBD27.js.map → paths-IJXOAN4E.js.map} +0 -0
@@ -5,35 +5,11 @@ import {
5
5
  sessionsDir,
6
6
  socketPath,
7
7
  statePath
8
- } from "./chunk-YGBGKMTF.js";
8
+ } from "./chunk-REUQ4B45.js";
9
9
 
10
10
  // src/shared/utils.ts
11
11
  function computeActiveTimeMs(session) {
12
- const now = Date.now();
13
- const intervals = [];
14
- for (const cycle of session.orchestratorCycles) {
15
- const start = new Date(cycle.timestamp).getTime();
16
- const end = cycle.completedAt ? new Date(cycle.completedAt).getTime() : now;
17
- if (end > start) intervals.push([start, end]);
18
- }
19
- for (const agent of session.agents) {
20
- const start = new Date(agent.spawnedAt).getTime();
21
- const end = agent.completedAt ? new Date(agent.completedAt).getTime() : now;
22
- if (end > start) intervals.push([start, end]);
23
- }
24
- if (intervals.length === 0) return 0;
25
- intervals.sort((a, b) => a[0] - b[0]);
26
- const merged = [intervals[0]];
27
- for (let i = 1; i < intervals.length; i++) {
28
- const last = merged[merged.length - 1];
29
- const cur = intervals[i];
30
- if (cur[0] <= last[1]) {
31
- last[1] = Math.max(last[1], cur[1]);
32
- } else {
33
- merged.push(cur);
34
- }
35
- }
36
- return merged.reduce((sum, [start, end]) => sum + (end - start), 0);
12
+ return session.activeMs;
37
13
  }
38
14
 
39
15
  // src/shared/format.ts
@@ -261,4 +237,4 @@ export {
261
237
  buildCompanionContext,
262
238
  buildSessionContext
263
239
  };
264
- //# sourceMappingURL=chunk-Q6VQOUN3.js.map
240
+ //# sourceMappingURL=chunk-M7LZ2ZHD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/utils.ts","../src/shared/format.ts","../src/tui/lib/reports.ts","../src/tui/lib/context.ts","../src/shared/client.ts"],"sourcesContent":["import type { Session } from './types.js';\n\n/**\n * Return the tracked active time for a session.\n * Active time is accumulated by the daemon's pane monitor, excluding sleep/idle gaps.\n */\nexport function computeActiveTimeMs(session: Session): number {\n return session.activeMs;\n}\n","/** Format milliseconds or ISO date range to human-readable duration */\nexport function formatDuration(startOrMs: string | number, endIso?: string | null): string {\n let totalMs: number;\n if (typeof startOrMs === 'number') {\n totalMs = startOrMs;\n } else {\n const start = new Date(startOrMs).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n totalMs = end - start;\n }\n const totalSeconds = Math.floor(totalMs / 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 if (hours > 0) return `${hours}h${minutes}m`;\n if (minutes > 0) return `${minutes}m${seconds}s`;\n return `${seconds}s`;\n}\n\n/** Map session/agent status to a color name */\nexport function statusColor(status: string): string {\n switch (status) {\n case 'active':\n case 'running':\n return 'green';\n case 'completed':\n return 'cyan';\n case 'paused':\n return 'yellow';\n case 'killed':\n case 'crashed':\n return 'red';\n case 'lost':\n return 'gray';\n default:\n return 'white';\n }\n}\n","import { readFileSync } from 'node:fs';\nimport type { AgentReport } from '../../shared/types.js';\n\nexport interface ReportBlock {\n type: 'update' | 'final';\n timestamp: string;\n content: string;\n summary: string;\n}\n\nfunction loadReportContent(report: AgentReport): string {\n try {\n return readFileSync(report.filePath, 'utf-8');\n } catch {\n return report.summary;\n }\n}\n\nexport function resolveReports(reports: AgentReport[]): ReportBlock[] {\n return [...reports].reverse().map((r) => ({\n type: r.type as 'update' | 'final',\n timestamp: r.timestamp,\n content: loadReportContent(r),\n summary: r.summary,\n }));\n}\n","import { readFileSync, readdirSync } from 'node:fs';\nimport { goalPath, roadmapPath, sessionsDir, statePath } from '../../shared/paths.js';\nimport { resolveReports } from './reports.js';\nimport type { Session, AgentStatus } from '../../shared/types.js';\n\nfunction readFileSafe(filePath: string): string | null {\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport function buildCompanionContext(cwd: string): string {\n let sessionDirs: string[];\n try {\n sessionDirs = readdirSync(sessionsDir(cwd));\n } catch {\n return '<sessions>No sessions found.</sessions>';\n }\n\n const now = Date.now();\n const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;\n const sessionBlocks: string[] = [];\n\n for (const sessionId of sessionDirs) {\n const stateRaw = readFileSafe(statePath(cwd, sessionId));\n if (!stateRaw) continue;\n\n let session: Session;\n try {\n session = JSON.parse(stateRaw) as Session;\n } catch {\n continue;\n }\n\n // Skip completed sessions older than 7 days\n if (session.status === 'completed' && session.completedAt) {\n if (now - new Date(session.completedAt).getTime() > sevenDaysMs) continue;\n }\n\n const lines: string[] = [];\n const nameAttr = session.name ? ` name=\"${escapeXml(session.name)}\"` : '';\n lines.push(` <session id=\"${escapeXml(session.id)}\"${nameAttr} status=\"${escapeXml(session.status)}\">`);\n lines.push(` <task>${escapeXml(session.task)}</task>`);\n lines.push(` <created>${escapeXml(session.createdAt)}</created>`);\n lines.push(` <cycles>${session.orchestratorCycles.length}</cycles>`);\n\n if (session.status === 'completed') {\n if (session.completionReport) {\n const snippet = session.completionReport.slice(0, 300).replace(/\\n+/g, ' ').trim();\n lines.push(` <completion-report>${escapeXml(snippet)}${session.completionReport.length > 300 ? '…' : ''}</completion-report>`);\n }\n } else {\n // Agent summary by status\n if (session.agents.length > 0) {\n const counts = new Map<AgentStatus, number>();\n for (const agent of session.agents) {\n counts.set(agent.status, (counts.get(agent.status) ?? 0) + 1);\n }\n const summary = [...counts.entries()].map(([status, n]) => `${n} ${status}`).join(', ');\n lines.push(` <agents>${escapeXml(summary)}</agents>`);\n }\n\n // Goal: first meaningful line\n const goalContent = readFileSafe(goalPath(cwd, session.id));\n if (goalContent) {\n const firstLine = goalContent.split('\\n').map(l => l.trim()).find(l => l.length > 0 && !l.startsWith('#'));\n if (firstLine) lines.push(` <goal>${escapeXml(firstLine)}</goal>`);\n }\n\n // Roadmap unchecked todos (up to 5)\n const roadmapContent = readFileSafe(roadmapPath(cwd, session.id));\n if (roadmapContent) {\n const todos = roadmapContent\n .split('\\n')\n .filter(l => l.includes('- [ ]'))\n .slice(0, 5)\n .map(l => l.trim());\n if (todos.length > 0) {\n lines.push(' <todos>');\n for (const todo of todos) lines.push(` ${escapeXml(todo)}`);\n lines.push(' </todos>');\n }\n }\n }\n\n lines.push(' </session>');\n sessionBlocks.push(lines.join('\\n'));\n }\n\n if (sessionBlocks.length === 0) {\n return '<sessions>No sessions found.</sessions>';\n }\n\n return ['<sessions>', ...sessionBlocks, '</sessions>'].join('\\n');\n}\n\nexport function buildSessionContext(session: Session, cwd: string): string {\n const goal = readFileSafe(goalPath(cwd, session.id));\n const roadmap = readFileSafe(roadmapPath(cwd, session.id));\n\n const agentsXml = session.agents.map((agent) => {\n const reportBlocks = resolveReports(agent.reports);\n // resolveReports returns newest-first; reverse to chronological for context\n const reportsXml = [...reportBlocks].reverse().map((block) => {\n return ` <report type=\"${block.type}\" time=\"${escapeXml(block.timestamp)}\">${escapeXml(block.content)}</report>`;\n }).join('\\n');\n\n return [\n ` <agent id=\"${escapeXml(agent.id)}\" name=\"${escapeXml(agent.name)}\" type=\"${escapeXml(agent.agentType)}\" status=\"${escapeXml(agent.status)}\">`,\n ` <instruction>${escapeXml(agent.instruction)}</instruction>`,\n ...(reportsXml ? [reportsXml] : []),\n ` </agent>`,\n ].join('\\n');\n }).join('\\n');\n\n const cyclesXml = session.orchestratorCycles.map((cycle) => {\n const agents = cycle.agentsSpawned.join(', ');\n const mode = cycle.mode ? ` mode=\"${escapeXml(cycle.mode)}\"` : '';\n return ` <cycle number=\"${cycle.cycle}\"${mode} agents=\"${escapeXml(agents)}\" />`;\n }).join('\\n');\n\n const lines: string[] = [\n '<context>',\n `<session id=\"${escapeXml(session.id)}\" status=\"${escapeXml(session.status)}\">`,\n ` <task>${escapeXml(session.task)}</task>`,\n ` <cwd>${escapeXml(session.cwd)}</cwd>`,\n ];\n\n if (goal) lines.push(` <goal>${escapeXml(goal)}</goal>`);\n if (roadmap) lines.push(` <roadmap>${escapeXml(roadmap)}</roadmap>`);\n\n if (session.agents.length > 0) {\n lines.push(' <agents>');\n lines.push(agentsXml);\n lines.push(' </agents>');\n }\n\n if (session.orchestratorCycles.length > 0) {\n lines.push(' <cycles>');\n lines.push(cyclesXml);\n lines.push(' </cycles>');\n }\n\n if (session.completionReport) {\n lines.push(` <completion-report>${escapeXml(session.completionReport)}</completion-report>`);\n }\n\n lines.push('</session>');\n lines.push('</context>');\n\n return lines.join('\\n');\n}\n","import { connect } from 'node:net';\nimport { socketPath } from './paths.js';\nimport type { Request, Response } from './protocol.js';\n\nexport function rawSend(request: Request, timeoutMs = 10_000): 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 ${(timeoutMs / 1000).toFixed(0)}s. The daemon may be overloaded.\\n Check: sisyphus doctor\\n Logs: tail -20 ~/.sisyphus/daemon.log`));\n }, timeoutMs);\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"],"mappings":"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","names":["readFileSync","readFileSync"]}
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/shared/paths.ts
4
4
  import { homedir } from "os";
5
- import { basename, join } from "path";
5
+ import { join } from "path";
6
6
  function globalDir() {
7
7
  return join(homedir(), ".sisyphus");
8
8
  }
@@ -60,6 +60,9 @@ function roadmapPath(cwd, sessionId) {
60
60
  function goalPath(cwd, sessionId) {
61
61
  return join(sessionDir(cwd, sessionId), "goal.md");
62
62
  }
63
+ function strategyPath(cwd, sessionId) {
64
+ return join(sessionDir(cwd, sessionId), "strategy.md");
65
+ }
63
66
  function logsDir(cwd, sessionId) {
64
67
  return join(sessionDir(cwd, sessionId), "logs");
65
68
  }
@@ -75,12 +78,6 @@ function snapshotsDir(cwd, sessionId) {
75
78
  function snapshotDir(cwd, sessionId, cycle) {
76
79
  return join(snapshotsDir(cwd, sessionId), `cycle-${cycle}`);
77
80
  }
78
- function worktreeConfigPath(cwd) {
79
- return join(projectDir(cwd), "worktree.json");
80
- }
81
- function worktreeBaseDir(cwd) {
82
- return join(cwd, "..", `${basename(cwd)}-sisyphus-wt`);
83
- }
84
81
 
85
82
  export {
86
83
  globalDir,
@@ -102,12 +99,11 @@ export {
102
99
  contextDir,
103
100
  roadmapPath,
104
101
  goalPath,
102
+ strategyPath,
105
103
  logsDir,
106
104
  cycleLogPath,
107
105
  legacyLogsPath,
108
106
  snapshotsDir,
109
- snapshotDir,
110
- worktreeConfigPath,
111
- worktreeBaseDir
107
+ snapshotDir
112
108
  };
113
- //# sourceMappingURL=chunk-YGBGKMTF.js.map
109
+ //# sourceMappingURL=chunk-REUQ4B45.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/paths.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport function globalDir(): string {\n return join(homedir(), '.sisyphus');\n}\n\nexport function socketPath(): string {\n return join(globalDir(), 'daemon.sock');\n}\n\nexport function globalConfigPath(): string {\n return join(globalDir(), 'config.json');\n}\n\nexport function daemonLogPath(): string {\n return join(globalDir(), 'daemon.log');\n}\n\nexport function daemonPidPath(): string {\n return join(globalDir(), 'daemon.pid');\n}\n\nexport function daemonUpdatingPath(): string {\n return join(globalDir(), 'updating');\n}\n\nexport function projectDir(cwd: string): string {\n return join(cwd, '.sisyphus');\n}\n\nexport function projectConfigPath(cwd: string): string {\n return join(projectDir(cwd), 'config.json');\n}\n\nexport function projectOrchestratorPromptPath(cwd: string): string {\n return join(projectDir(cwd), 'orchestrator.md');\n}\n\nexport function sessionsDir(cwd: string): string {\n return join(projectDir(cwd), 'sessions');\n}\n\nexport function sessionDir(cwd: string, sessionId: string): string {\n return join(sessionsDir(cwd), sessionId);\n}\n\nexport function statePath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'state.json');\n}\n\nexport function reportsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'reports');\n}\n\nexport function reportFilePath(cwd: string, sessionId: string, agentId: string, suffix: string): string {\n return join(reportsDir(cwd, sessionId), `${agentId}-${suffix}.md`);\n}\n\nexport function messagesDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'messages');\n}\n\nexport function promptsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'prompts');\n}\n\nexport function contextDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'context');\n}\n\nexport function roadmapPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'roadmap.md');\n}\n\nexport function goalPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'goal.md');\n}\n\nexport function strategyPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'strategy.md');\n}\n\nexport function logsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'logs');\n}\n\nexport function cycleLogPath(cwd: string, sessionId: string, cycle: number): string {\n return join(logsDir(cwd, sessionId), `cycle-${String(cycle).padStart(3, '0')}.md`);\n}\n\n// Backwards compat for old sessions\nexport function legacyLogsPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'logs.md');\n}\n\nexport function snapshotsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'snapshots');\n}\n\nexport function snapshotDir(cwd: string, sessionId: string, cycle: number): string {\n return join(snapshotsDir(cwd, sessionId), `cycle-${cycle}`);\n}\n\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,SAAS,YAAY;AAEd,SAAS,YAAoB;AAClC,SAAO,KAAK,QAAQ,GAAG,WAAW;AACpC;AAEO,SAAS,aAAqB;AACnC,SAAO,KAAK,UAAU,GAAG,aAAa;AACxC;AAEO,SAAS,mBAA2B;AACzC,SAAO,KAAK,UAAU,GAAG,aAAa;AACxC;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,UAAU,GAAG,YAAY;AACvC;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,UAAU,GAAG,YAAY;AACvC;AAEO,SAAS,qBAA6B;AAC3C,SAAO,KAAK,UAAU,GAAG,UAAU;AACrC;AAEO,SAAS,WAAW,KAAqB;AAC9C,SAAO,KAAK,KAAK,WAAW;AAC9B;AAEO,SAAS,kBAAkB,KAAqB;AACrD,SAAO,KAAK,WAAW,GAAG,GAAG,aAAa;AAC5C;AAEO,SAAS,8BAA8B,KAAqB;AACjE,SAAO,KAAK,WAAW,GAAG,GAAG,iBAAiB;AAChD;AAEO,SAAS,YAAY,KAAqB;AAC/C,SAAO,KAAK,WAAW,GAAG,GAAG,UAAU;AACzC;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,YAAY,GAAG,GAAG,SAAS;AACzC;AAEO,SAAS,UAAU,KAAa,WAA2B;AAChE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,YAAY;AACtD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,eAAe,KAAa,WAAmB,SAAiB,QAAwB;AACtG,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,GAAG,OAAO,IAAI,MAAM,KAAK;AACnE;AAEO,SAAS,YAAY,KAAa,WAA2B;AAClE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,UAAU;AACpD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,YAAY,KAAa,WAA2B;AAClE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,YAAY;AACtD;AAEO,SAAS,SAAS,KAAa,WAA2B;AAC/D,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,aAAa,KAAa,WAA2B;AACnE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,aAAa;AACvD;AAEO,SAAS,QAAQ,KAAa,WAA2B;AAC9D,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,MAAM;AAChD;AAEO,SAAS,aAAa,KAAa,WAAmB,OAAuB;AAClF,SAAO,KAAK,QAAQ,KAAK,SAAS,GAAG,SAAS,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK;AACnF;AAGO,SAAS,eAAe,KAAa,WAA2B;AACrE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,aAAa,KAAa,WAA2B;AACnE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,WAAW;AACrD;AAEO,SAAS,YAAY,KAAa,WAAmB,OAAuB;AACjF,SAAO,KAAK,aAAa,KAAK,SAAS,GAAG,SAAS,KAAK,EAAE;AAC5D;","names":[]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  globalConfigPath,
4
4
  projectConfigPath
5
- } from "./chunk-YGBGKMTF.js";
5
+ } from "./chunk-REUQ4B45.js";
6
6
 
7
7
  // src/shared/config.ts
8
8
  import { readFileSync } from "fs";
@@ -84,4 +84,4 @@ export {
84
84
  exec,
85
85
  execSafe
86
86
  };
87
- //# sourceMappingURL=chunk-MMA43N67.js.map
87
+ //# sourceMappingURL=chunk-Z32YVDMY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/config.ts","../src/shared/env.ts","../src/shared/exec.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport type EffortLevel = 'low' | 'medium' | 'high' | 'max';\n\nexport interface Config {\n model?: string;\n tmuxSession?: string;\n orchestratorPrompt?: string;\n pollIntervalMs?: number;\n autoUpdate?: boolean;\n orchestratorEffort?: EffortLevel;\n agentEffort?: EffortLevel;\n editor?: string;\n repos?: string[];\n}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 5000,\n orchestratorEffort: 'high',\n agentEffort: 'medium',\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","/**\n * Build a PATH string that includes common binary directories\n * across package managers and platforms.\n *\n * Prepends known directories that exist on the system to the current PATH.\n * This ensures tmux commands can find binaries installed by Homebrew,\n * MacPorts, nix, and other package managers.\n */\nexport function augmentedPath(): string {\n const rawPath = process.env['PATH'];\n const basePath = rawPath !== undefined && rawPath.length > 0 ? rawPath : '/usr/bin:/bin';\n\n // Common binary directories across platforms/package managers.\n // Only prepend ones that aren't already in PATH.\n const candidates = [\n '/opt/homebrew/bin', // Homebrew (Apple Silicon macOS)\n '/opt/homebrew/sbin', // Homebrew sbin\n '/usr/local/bin', // Homebrew (Intel macOS), manual installs\n '/usr/local/sbin', // Manual installs\n '/opt/local/bin', // MacPorts\n '/opt/local/sbin', // MacPorts\n '/home/linuxbrew/.linuxbrew/bin', // Linuxbrew\n ];\n\n // Check for nix profile paths\n const nixProfile = process.env['NIX_PROFILES'];\n if (nixProfile) {\n for (const p of nixProfile.split(' ').reverse()) {\n candidates.push(`${p}/bin`);\n }\n }\n\n const existing = new Set(basePath.split(':'));\n const prepend = candidates.filter(dir => !existing.has(dir));\n\n return prepend.length > 0 ? `${prepend.join(':')}:${basePath}` : basePath;\n}\n\n/**\n * Environment variables for child processes that need access to\n * user-installed binaries (tmux, git, claude, etc.).\n */\nexport function execEnv(): Record<string, string | undefined> {\n return {\n ...process.env,\n PATH: augmentedPath(),\n };\n}\n","import { execSync } from 'node:child_process';\nimport { execEnv } from './env.js';\n\nexport const EXEC_ENV = execEnv();\n\nexport function exec(cmd: string, cwd?: string): string {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV, cwd }).trim();\n}\n\nexport function execSafe(cmd: string, cwd?: string): string | null {\n try {\n return execSync(cmd, { encoding: 'utf-8', env: EXEC_ENV, cwd, stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch { return null; }\n}\n"],"mappings":";;;;;;;AAAA,SAAS,oBAAoB;AAiB7B,IAAM,iBAAyB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,aAAa;AACf;AAEA,SAAS,aAAa,UAAmC;AACvD,MAAI;AACF,UAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,WAAW,KAAqB;AAC9C,QAAM,SAAS,aAAa,iBAAiB,CAAC;AAC9C,QAAM,UAAU,aAAa,kBAAkB,GAAG,CAAC;AACnD,SAAO,EAAE,GAAG,gBAAgB,GAAG,QAAQ,GAAG,QAAQ;AACpD;;;AC5BO,SAAS,gBAAwB;AACtC,QAAM,UAAU,QAAQ,IAAI,MAAM;AAClC,QAAM,WAAW,YAAY,UAAa,QAAQ,SAAS,IAAI,UAAU;AAIzE,QAAM,aAAa;AAAA,IACjB;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAGA,QAAM,aAAa,QAAQ,IAAI,cAAc;AAC7C,MAAI,YAAY;AACd,eAAW,KAAK,WAAW,MAAM,GAAG,EAAE,QAAQ,GAAG;AAC/C,iBAAW,KAAK,GAAG,CAAC,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,IAAI,SAAS,MAAM,GAAG,CAAC;AAC5C,QAAM,UAAU,WAAW,OAAO,SAAO,CAAC,SAAS,IAAI,GAAG,CAAC;AAE3D,SAAO,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,GAAG,CAAC,IAAI,QAAQ,KAAK;AACnE;AAMO,SAAS,UAA8C;AAC5D,SAAO;AAAA,IACL,GAAG,QAAQ;AAAA,IACX,MAAM,cAAc;AAAA,EACtB;AACF;;;AC/CA,SAAS,gBAAgB;AAGlB,IAAM,WAAW,QAAQ;AAEzB,SAAS,KAAK,KAAa,KAAsB;AACtD,SAAO,SAAS,KAAK,EAAE,UAAU,SAAS,KAAK,UAAU,IAAI,CAAC,EAAE,KAAK;AACvE;AAEO,SAAS,SAAS,KAAa,KAA6B;AACjE,MAAI;AACF,WAAO,SAAS,KAAK,EAAE,UAAU,SAAS,KAAK,UAAU,KAAK,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE,CAAC,EAAE,KAAK;AAAA,EACxG,QAAQ;AAAE,WAAO;AAAA,EAAM;AACzB;","names":[]}
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  formatDuration,
6
6
  rawSend,
7
7
  statusColor
8
- } from "./chunk-Q6VQOUN3.js";
8
+ } from "./chunk-M7LZ2ZHD.js";
9
9
  import {
10
10
  shellQuote
11
11
  } from "./chunk-6G226ZK7.js";
@@ -16,7 +16,7 @@ import {
16
16
  globalDir,
17
17
  roadmapPath,
18
18
  socketPath
19
- } from "./chunk-YGBGKMTF.js";
19
+ } from "./chunk-REUQ4B45.js";
20
20
 
21
21
  // src/cli/index.ts
22
22
  import { Command } from "commander";
@@ -596,11 +596,11 @@ function readStdin() {
596
596
 
597
597
  // src/cli/commands/spawn.ts
598
598
  function registerSpawn(program2) {
599
- program2.command("spawn").description("Spawn a new agent (orchestrator only)").argument("[instruction]", "Task instruction for the agent").option("--agent-type <type>", "Agent role label (default: worker)", "worker").requiredOption("--name <name>", "Agent name").option("--instruction <instruction>", "Task instruction for the agent (or pipe via stdin)").option("--worktree", "Spawn agent in an isolated git worktree").option("--repo <name>", "Repo subdirectory to use for this agent").action(async (positionalInstruction, opts) => {
599
+ program2.command("spawn").description("Spawn a new agent (orchestrator only)").argument("[instruction]", "Task instruction for the agent").option("--agent-type <type>", "Agent role label (default: worker)", "worker").requiredOption("--name <name>", "Agent name").option("--instruction <instruction>", "Task instruction for the agent (or pipe via stdin)").option("--repo <name>", "Repo subdirectory to use for this agent").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (positionalInstruction, opts) => {
600
600
  assertTmux();
601
- const sessionId = process.env.SISYPHUS_SESSION_ID;
601
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
602
602
  if (!sessionId) {
603
- console.error("Error: SISYPHUS_SESSION_ID environment variable not set");
603
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID environment variable");
604
604
  process.exit(1);
605
605
  }
606
606
  const instruction = opts.instruction ?? positionalInstruction ?? await readStdin();
@@ -619,15 +619,6 @@ function registerSpawn(program2) {
619
619
  console.error(`Error: repo directory does not exist: ${repoPath}`);
620
620
  process.exit(1);
621
621
  }
622
- if (opts.worktree && !existsSync3(join4(repoPath, ".git"))) {
623
- console.error(`Error: --worktree requires a git repo; no .git found at ${repoPath}`);
624
- process.exit(1);
625
- }
626
- } else if (!opts.repo) {
627
- if (!existsSync3(join4(sisyphusCwd, ".git"))) {
628
- console.error("Error: --repo is required when session root is not a git repo.");
629
- process.exit(1);
630
- }
631
622
  }
632
623
  const request = {
633
624
  type: "spawn",
@@ -635,7 +626,6 @@ function registerSpawn(program2) {
635
626
  agentType: opts.agentType,
636
627
  name: opts.name,
637
628
  instruction,
638
- ...opts.worktree ? { worktree: true } : {},
639
629
  ...opts.repo ? { repo: opts.repo } : {}
640
630
  };
641
631
  const response = await sendRequest(request);
@@ -671,18 +661,18 @@ function getUncommittedChanges() {
671
661
  }
672
662
  }
673
663
  function registerSubmit(program2) {
674
- program2.command("submit").description("Submit work report and exit (agent only)").option("--report <report>", "Work report (or pipe via stdin)").action(async (opts) => {
664
+ program2.command("submit").description("Submit work report and exit (agent only)").option("--report <report>", "Work report (or pipe via stdin)").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (opts) => {
675
665
  assertTmux();
676
- const sessionId = process.env.SISYPHUS_SESSION_ID;
666
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
677
667
  const agentId = process.env.SISYPHUS_AGENT_ID;
678
668
  if (!sessionId || !agentId) {
679
- console.error("Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set");
669
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID (and SISYPHUS_AGENT_ID) environment variables");
680
670
  process.exit(1);
681
671
  }
682
672
  if (isInWorktree()) {
683
673
  const changes = getUncommittedChanges();
684
674
  if (changes) {
685
- console.error("Error: uncommitted changes in worktree. Your branch is merged automatically after submit \u2014 uncommitted work will be lost.");
675
+ console.error("Error: uncommitted changes in worktree. Commit your changes before submitting.");
686
676
  console.error('\nCommit first:\n git add -A && git commit -m "description of changes"\n');
687
677
  console.error("Or discard:\n git checkout -- .\n");
688
678
  console.error("Uncommitted changes:");
@@ -709,11 +699,11 @@ function registerSubmit(program2) {
709
699
 
710
700
  // src/cli/commands/yield.ts
711
701
  function registerYield(program2) {
712
- program2.command("yield").description("Yield control back to daemon (orchestrator only)").option("--prompt <text>", "Instructions for the next orchestrator cycle (or pipe via stdin)").option("--mode <mode>", "System prompt mode for next cycle (planning, implementation)").action(async (opts) => {
702
+ program2.command("yield").description("Yield control back to daemon (orchestrator only)").option("--prompt <text>", "Instructions for the next orchestrator cycle (or pipe via stdin)").option("--mode <mode>", "System prompt mode for next cycle (planning, implementation, validation)").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (opts) => {
713
703
  assertTmux();
714
- const sessionId = process.env.SISYPHUS_SESSION_ID;
704
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
715
705
  if (!sessionId) {
716
- console.error("Error: SISYPHUS_SESSION_ID environment variable not set");
706
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID environment variable");
717
707
  process.exit(1);
718
708
  }
719
709
  const nextPrompt = opts.prompt ?? await readStdin() ?? void 0;
@@ -730,11 +720,11 @@ function registerYield(program2) {
730
720
 
731
721
  // src/cli/commands/complete.ts
732
722
  function registerComplete(program2) {
733
- program2.command("complete").description("Mark session as completed (orchestrator only)").requiredOption("--report <report>", "Final completion report").action(async (opts) => {
723
+ program2.command("complete").description("Mark session as completed (orchestrator only)").requiredOption("--report <report>", "Final completion report").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (opts) => {
734
724
  assertTmux();
735
- const sessionId = process.env.SISYPHUS_SESSION_ID;
725
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
736
726
  if (!sessionId) {
737
- console.error("Error: SISYPHUS_SESSION_ID environment variable not set");
727
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID environment variable");
738
728
  process.exit(1);
739
729
  }
740
730
  const request = { type: "complete", sessionId, report: opts.report };
@@ -742,9 +732,8 @@ function registerComplete(program2) {
742
732
  if (response.ok) {
743
733
  console.log("Session completed.");
744
734
  console.log(`
745
- Follow up:`);
746
- console.log(` sisyphus continue # reactivate and keep working`);
747
- console.log(` sisyphus resume ${sessionId} "new instructions" # respawn orchestrator externally`);
735
+ To keep working in this session:`);
736
+ console.log(` sisyphus continue # reactivate session and clear roadmap for new work`);
748
737
  } else {
749
738
  console.error(`Error: ${response.error}`);
750
739
  process.exit(1);
@@ -754,17 +743,19 @@ Follow up:`);
754
743
 
755
744
  // src/cli/commands/continue.ts
756
745
  function registerContinue(program2) {
757
- program2.command("continue").description("Clear roadmap and continue working on a completed session (stays in current cycle)").addHelpText("after", "\n Use `continue` when a session completed but you want to add more work.\n Use `resume` when you want to restart with specific new instructions.\n").action(async () => {
746
+ program2.command("continue").description("Clear roadmap and continue working on a completed session (stays in current cycle)").addHelpText("after", "\n Use `continue` when a session completed but you want to add more work.\n Use `resume` when you want to restart with specific new instructions.\n").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (opts) => {
758
747
  assertTmux();
759
- const sessionId = process.env.SISYPHUS_SESSION_ID;
748
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
760
749
  if (!sessionId) {
761
- console.error("Error: SISYPHUS_SESSION_ID environment variable not set");
750
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID environment variable");
762
751
  process.exit(1);
763
752
  }
764
753
  const request = { type: "continue", sessionId };
765
754
  const response = await sendRequest(request);
766
755
  if (response.ok) {
767
- console.log("Session reactivated. Plan cleared.");
756
+ console.log("Session reactivated. Roadmap cleared.");
757
+ console.log("\nThe previous roadmap has been wiped \u2014 you are starting fresh.");
758
+ console.log("Consider writing a new roadmap before spawning agents.");
768
759
  } else {
769
760
  console.error(`Error: ${response.error}`);
770
761
  process.exit(1);
@@ -813,7 +804,7 @@ function formatAgent(agent) {
813
804
  const status = colorize(agent.status, agent.status);
814
805
  const name = `${BOLD}${agent.name}${RESET}`;
815
806
  const type = `${DIM}(${agent.agentType})${RESET}`;
816
- const duration = formatDuration(agent.spawnedAt, agent.completedAt);
807
+ const duration = formatDuration(agent.activeMs);
817
808
  let line = ` ${agent.id} ${name} ${type} \u2014 ${status} ${DIM}(${duration})${RESET}`;
818
809
  if (agent.reports.length > 0) {
819
810
  for (const r of agent.reports) {
@@ -831,9 +822,9 @@ function formatAgent(agent) {
831
822
  function formatCycle(cycle, phase) {
832
823
  let duration;
833
824
  if (cycle.completedAt) {
834
- duration = ` ${DIM}(${formatDuration(cycle.timestamp, cycle.completedAt)})${RESET}`;
825
+ duration = ` ${DIM}(${formatDuration(cycle.activeMs)})${RESET}`;
835
826
  } else {
836
- const elapsed = formatDuration(cycle.timestamp, null);
827
+ const elapsed = formatDuration(cycle.activeMs);
837
828
  duration = ` ${DIM}(running, ${elapsed})${RESET}`;
838
829
  }
839
830
  const agents = cycle.agentsSpawned.length > 0 ? ` \u2014 agents: ${cycle.agentsSpawned.join(", ")}` : "";
@@ -891,7 +882,7 @@ ${BOLD}Active agents (${runningAgents.length}):${RESET}`);
891
882
  for (const agent of runningAgents) {
892
883
  const name = `${BOLD}${agent.name}${RESET}`;
893
884
  const type = `${DIM}(${agent.agentType})${RESET}`;
894
- const duration = formatDuration(agent.spawnedAt, null);
885
+ const duration = formatDuration(agent.activeMs);
895
886
  console.log(` ${agent.id} ${name} ${type} running ${duration}`);
896
887
  }
897
888
  }
@@ -955,8 +946,8 @@ function truncateTask(task, max) {
955
946
  return task.slice(0, max - 1) + "\u2026";
956
947
  }
957
948
  function registerList(program2) {
958
- program2.command("list").description("List sessions (defaults to current project)").option("-a, --all", "Show sessions from all projects").action(async (opts) => {
959
- const cwd = process.env["SISYPHUS_CWD"] ?? process.cwd();
949
+ program2.command("list").description("List sessions (defaults to current project)").option("-a, --all", "Show sessions from all projects").option("--cwd <path>", "Project directory to list sessions for (overrides SISYPHUS_CWD)").action(async (opts) => {
950
+ const cwd = opts.cwd ?? process.env["SISYPHUS_CWD"] ?? process.cwd();
960
951
  const request = { type: "list", cwd, all: opts.all };
961
952
  const response = await sendRequest(request);
962
953
  if (response.ok) {
@@ -995,12 +986,12 @@ ${DIM2}${otherCount} more session(s) in other projects. Run ${RESET2}sisyphus li
995
986
 
996
987
  // src/cli/commands/report.ts
997
988
  function registerReport(program2) {
998
- program2.command("report").description("Send a progress report without exiting (agent only)").option("--message <message>", "Progress report content").action(async (opts) => {
989
+ program2.command("report").description("Send a progress report without exiting (agent only)").option("--message <message>", "Progress report content").option("--session <sessionId>", "Session ID (defaults to SISYPHUS_SESSION_ID env var)").action(async (opts) => {
999
990
  assertTmux();
1000
- const sessionId = process.env.SISYPHUS_SESSION_ID;
991
+ const sessionId = opts.session ?? process.env.SISYPHUS_SESSION_ID;
1001
992
  const agentId = process.env.SISYPHUS_AGENT_ID;
1002
993
  if (!sessionId || !agentId) {
1003
- console.error("Error: SISYPHUS_SESSION_ID and SISYPHUS_AGENT_ID environment variables must be set");
994
+ console.error("Error: provide --session or set SISYPHUS_SESSION_ID (and SISYPHUS_AGENT_ID) environment variables");
1004
995
  process.exit(1);
1005
996
  }
1006
997
  const content = opts.message ?? await readStdin();
@@ -1455,11 +1446,11 @@ function registerGettingStarted(program2) {
1455
1446
  " mode, it's too small for sisyphus.",
1456
1447
  "",
1457
1448
  " Good tasks:",
1458
- ' \u2022 "Implement this feature" @path/to/spec.md',
1449
+ ' \u2022 "Implement this feature" @path/to/requirements.md',
1459
1450
  ' \u2022 "Do a deep dive on all SEO/AEO optimizations and',
1460
1451
  ' systematically apply them across the site"',
1461
1452
  " \u2022 Large-scale refactors spanning dozens of files",
1462
- " \u2022 Full feature builds from a written spec",
1453
+ " \u2022 Full feature builds from written requirements",
1463
1454
  "",
1464
1455
  " Too small for sisyphus:",
1465
1456
  ' \u2022 "Add these 3 UI components to the page"',
@@ -1470,9 +1461,9 @@ function registerGettingStarted(program2) {
1470
1461
  " tasks work great because the orchestrator will plan the approach.",
1471
1462
  " What matters is SCALE, not specificity.",
1472
1463
  "",
1473
- " For best results, write a spec and reference it directly:",
1464
+ " For best results, write requirements and reference them directly:",
1474
1465
  "",
1475
- ' sisyphus start "Implement this @path/to/spec.md"',
1466
+ ' sisyphus start "Implement this @path/to/requirements.md"',
1476
1467
  "",
1477
1468
  " \u2500\u2500\u2500 How It Works \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
1478
1469
  "",
@@ -1509,7 +1500,7 @@ function registerGettingStarted(program2) {
1509
1500
  "",
1510
1501
  " Start & monitor:",
1511
1502
  ' sisyphus start "task" Start a session',
1512
- ' sisyphus start "task @spec.md" Start referencing a spec',
1503
+ ' sisyphus start "task @requirements.md" Start referencing requirements',
1513
1504
  " sisyphus status [id] Show session status",
1514
1505
  " sisyphus list List all sessions",
1515
1506
  " sisyphus dashboard Open TUI dashboard",
@@ -1608,7 +1599,7 @@ registerInit(program);
1608
1599
  program.addHelpText("after", `
1609
1600
  Examples:
1610
1601
  $ sisyphus start "Implement auth system" Start a new session
1611
- $ sisyphus start "Build @spec.md" -n auth Start with a name and spec reference
1602
+ $ sisyphus start "Build @requirements.md" -n auth Start with a name and requirements reference
1612
1603
  $ sisyphus status Check current sessions
1613
1604
  $ sisyphus dashboard Open the TUI
1614
1605
  $ sisyphus doctor Verify installation