sisyphi 1.0.1 → 1.0.4
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/chunk-DBR33QHM.js +185 -0
- package/dist/chunk-DBR33QHM.js.map +1 -0
- package/dist/cli.js +159 -22
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +30 -2
- package/dist/daemon.js.map +1 -1
- package/dist/templates/CLAUDE.md +1 -0
- package/dist/templates/agent-plugin/agents/operator.md +1 -0
- package/dist/templates/agent-plugin/agents/plan.md +68 -4
- package/dist/templates/agent-plugin/agents/review-plan.md +1 -1
- package/dist/templates/agent-plugin/agents/review.md +1 -0
- package/dist/templates/agent-plugin/agents/spec-draft.md +32 -4
- package/dist/templates/agent-plugin/agents/test-spec.md +1 -0
- package/dist/templates/companion-plugin/.claude-plugin/plugin.json +1 -0
- package/dist/templates/companion-plugin/hooks/hooks.json +12 -0
- package/dist/templates/companion-plugin/hooks/user-prompt-context.sh +3 -0
- package/dist/templates/dashboard-claude.md +1 -1
- package/dist/templates/orchestrator-base.md +5 -9
- package/dist/templates/orchestrator-planning.md +5 -49
- package/dist/tui.js +341 -184
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +1 -0
- package/templates/agent-plugin/agents/operator.md +1 -0
- package/templates/agent-plugin/agents/plan.md +68 -4
- package/templates/agent-plugin/agents/review-plan.md +1 -1
- package/templates/agent-plugin/agents/review.md +1 -0
- package/templates/agent-plugin/agents/spec-draft.md +32 -4
- package/templates/agent-plugin/agents/test-spec.md +1 -0
- package/templates/companion-plugin/.claude-plugin/plugin.json +1 -0
- package/templates/companion-plugin/hooks/hooks.json +12 -0
- package/templates/companion-plugin/hooks/user-prompt-context.sh +3 -0
- package/templates/dashboard-claude.md +1 -1
- package/templates/orchestrator-base.md +5 -9
- package/templates/orchestrator-planning.md +5 -49
- package/dist/chunk-ZE2SKB4B.js +0 -35
- package/dist/chunk-ZE2SKB4B.js.map +0 -1
- package/dist/templates/agent-plugin/.claude/agents/debug.md +0 -39
- package/dist/templates/agent-plugin/.claude/agents/plan.md +0 -101
- package/dist/templates/agent-plugin/.claude/agents/review-plan.md +0 -81
- package/dist/templates/agent-plugin/.claude/agents/review.md +0 -56
- package/dist/templates/agent-plugin/.claude/agents/spec-draft.md +0 -73
- package/dist/templates/agent-plugin/.claude/agents/test-spec.md +0 -56
- package/dist/templates/orchestrator-plugin/.claude/commands/begin.md +0 -62
- package/dist/templates/orchestrator-plugin/.claude/skills/orchestration/SKILL.md +0 -40
- package/dist/templates/orchestrator-plugin/.claude/skills/orchestration/task-patterns.md +0 -222
- package/dist/templates/orchestrator-plugin/.claude/skills/orchestration/workflow-examples.md +0 -208
- package/dist/templates/resources/.claude/agents/debug.md +0 -39
- package/dist/templates/resources/.claude/agents/plan.md +0 -101
- package/dist/templates/resources/.claude/agents/review-plan.md +0 -81
- package/dist/templates/resources/.claude/agents/review.md +0 -56
- package/dist/templates/resources/.claude/agents/spec-draft.md +0 -73
- package/dist/templates/resources/.claude/agents/test-spec.md +0 -56
- package/dist/templates/resources/.claude/commands/begin.md +0 -62
- package/dist/templates/resources/.claude/skills/orchestration/SKILL.md +0 -40
- package/dist/templates/resources/.claude/skills/orchestration/task-patterns.md +0 -222
- package/dist/templates/resources/.claude/skills/orchestration/workflow-examples.md +0 -208
- package/dist/templates/resources/.claude-plugin/plugin.json +0 -8
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
goalPath,
|
|
4
|
+
roadmapPath,
|
|
5
|
+
sessionsDir,
|
|
6
|
+
statePath
|
|
7
|
+
} from "./chunk-YGBGKMTF.js";
|
|
8
|
+
|
|
9
|
+
// src/shared/utils.ts
|
|
10
|
+
function computeActiveTimeMs(session) {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
const intervals = [];
|
|
13
|
+
for (const cycle of session.orchestratorCycles) {
|
|
14
|
+
const start = new Date(cycle.timestamp).getTime();
|
|
15
|
+
const end = cycle.completedAt ? new Date(cycle.completedAt).getTime() : now;
|
|
16
|
+
if (end > start) intervals.push([start, end]);
|
|
17
|
+
}
|
|
18
|
+
for (const agent of session.agents) {
|
|
19
|
+
const start = new Date(agent.spawnedAt).getTime();
|
|
20
|
+
const end = agent.completedAt ? new Date(agent.completedAt).getTime() : now;
|
|
21
|
+
if (end > start) intervals.push([start, end]);
|
|
22
|
+
}
|
|
23
|
+
if (intervals.length === 0) return 0;
|
|
24
|
+
intervals.sort((a, b) => a[0] - b[0]);
|
|
25
|
+
const merged = [intervals[0]];
|
|
26
|
+
for (let i = 1; i < intervals.length; i++) {
|
|
27
|
+
const last = merged[merged.length - 1];
|
|
28
|
+
const cur = intervals[i];
|
|
29
|
+
if (cur[0] <= last[1]) {
|
|
30
|
+
last[1] = Math.max(last[1], cur[1]);
|
|
31
|
+
} else {
|
|
32
|
+
merged.push(cur);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return merged.reduce((sum, [start, end]) => sum + (end - start), 0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/tui/lib/reports.ts
|
|
39
|
+
import { readFileSync } from "fs";
|
|
40
|
+
function loadReportContent(report) {
|
|
41
|
+
try {
|
|
42
|
+
return readFileSync(report.filePath, "utf-8");
|
|
43
|
+
} catch {
|
|
44
|
+
return report.summary;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function resolveReports(reports) {
|
|
48
|
+
return [...reports].reverse().map((r) => ({
|
|
49
|
+
type: r.type,
|
|
50
|
+
timestamp: r.timestamp,
|
|
51
|
+
content: loadReportContent(r),
|
|
52
|
+
summary: r.summary
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/tui/lib/context.ts
|
|
57
|
+
import { readFileSync as readFileSync2, readdirSync } from "fs";
|
|
58
|
+
function readFileSafe(filePath) {
|
|
59
|
+
try {
|
|
60
|
+
return readFileSync2(filePath, "utf-8");
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function escapeXml(s) {
|
|
66
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
67
|
+
}
|
|
68
|
+
function buildCompanionContext(cwd) {
|
|
69
|
+
let sessionDirs;
|
|
70
|
+
try {
|
|
71
|
+
sessionDirs = readdirSync(sessionsDir(cwd));
|
|
72
|
+
} catch {
|
|
73
|
+
return "<sessions>No sessions found.</sessions>";
|
|
74
|
+
}
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1e3;
|
|
77
|
+
const sessionBlocks = [];
|
|
78
|
+
for (const sessionId of sessionDirs) {
|
|
79
|
+
const stateRaw = readFileSafe(statePath(cwd, sessionId));
|
|
80
|
+
if (!stateRaw) continue;
|
|
81
|
+
let session;
|
|
82
|
+
try {
|
|
83
|
+
session = JSON.parse(stateRaw);
|
|
84
|
+
} catch {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (session.status === "completed" && session.completedAt) {
|
|
88
|
+
if (now - new Date(session.completedAt).getTime() > sevenDaysMs) continue;
|
|
89
|
+
}
|
|
90
|
+
const lines = [];
|
|
91
|
+
const nameAttr = session.name ? ` name="${escapeXml(session.name)}"` : "";
|
|
92
|
+
lines.push(` <session id="${escapeXml(session.id)}"${nameAttr} status="${escapeXml(session.status)}">`);
|
|
93
|
+
lines.push(` <task>${escapeXml(session.task)}</task>`);
|
|
94
|
+
lines.push(` <created>${escapeXml(session.createdAt)}</created>`);
|
|
95
|
+
lines.push(` <cycles>${session.orchestratorCycles.length}</cycles>`);
|
|
96
|
+
if (session.status === "completed") {
|
|
97
|
+
if (session.completionReport) {
|
|
98
|
+
const snippet = session.completionReport.slice(0, 300).replace(/\n+/g, " ").trim();
|
|
99
|
+
lines.push(` <completion-report>${escapeXml(snippet)}${session.completionReport.length > 300 ? "\u2026" : ""}</completion-report>`);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
if (session.agents.length > 0) {
|
|
103
|
+
const counts = /* @__PURE__ */ new Map();
|
|
104
|
+
for (const agent of session.agents) {
|
|
105
|
+
counts.set(agent.status, (counts.get(agent.status) ?? 0) + 1);
|
|
106
|
+
}
|
|
107
|
+
const summary = [...counts.entries()].map(([status, n]) => `${n} ${status}`).join(", ");
|
|
108
|
+
lines.push(` <agents>${escapeXml(summary)}</agents>`);
|
|
109
|
+
}
|
|
110
|
+
const goalContent = readFileSafe(goalPath(cwd, session.id));
|
|
111
|
+
if (goalContent) {
|
|
112
|
+
const firstLine = goalContent.split("\n").map((l) => l.trim()).find((l) => l.length > 0 && !l.startsWith("#"));
|
|
113
|
+
if (firstLine) lines.push(` <goal>${escapeXml(firstLine)}</goal>`);
|
|
114
|
+
}
|
|
115
|
+
const roadmapContent = readFileSafe(roadmapPath(cwd, session.id));
|
|
116
|
+
if (roadmapContent) {
|
|
117
|
+
const todos = roadmapContent.split("\n").filter((l) => l.includes("- [ ]")).slice(0, 5).map((l) => l.trim());
|
|
118
|
+
if (todos.length > 0) {
|
|
119
|
+
lines.push(" <todos>");
|
|
120
|
+
for (const todo of todos) lines.push(` ${escapeXml(todo)}`);
|
|
121
|
+
lines.push(" </todos>");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
lines.push(" </session>");
|
|
126
|
+
sessionBlocks.push(lines.join("\n"));
|
|
127
|
+
}
|
|
128
|
+
if (sessionBlocks.length === 0) {
|
|
129
|
+
return "<sessions>No sessions found.</sessions>";
|
|
130
|
+
}
|
|
131
|
+
return ["<sessions>", ...sessionBlocks, "</sessions>"].join("\n");
|
|
132
|
+
}
|
|
133
|
+
function buildSessionContext(session, cwd) {
|
|
134
|
+
const goal = readFileSafe(goalPath(cwd, session.id));
|
|
135
|
+
const roadmap = readFileSafe(roadmapPath(cwd, session.id));
|
|
136
|
+
const agentsXml = session.agents.map((agent) => {
|
|
137
|
+
const reportBlocks = resolveReports(agent.reports);
|
|
138
|
+
const reportsXml = [...reportBlocks].reverse().map((block) => {
|
|
139
|
+
return ` <report type="${block.type}" time="${escapeXml(block.timestamp)}">${escapeXml(block.content)}</report>`;
|
|
140
|
+
}).join("\n");
|
|
141
|
+
return [
|
|
142
|
+
` <agent id="${escapeXml(agent.id)}" name="${escapeXml(agent.name)}" type="${escapeXml(agent.agentType)}" status="${escapeXml(agent.status)}">`,
|
|
143
|
+
` <instruction>${escapeXml(agent.instruction)}</instruction>`,
|
|
144
|
+
...reportsXml ? [reportsXml] : [],
|
|
145
|
+
` </agent>`
|
|
146
|
+
].join("\n");
|
|
147
|
+
}).join("\n");
|
|
148
|
+
const cyclesXml = session.orchestratorCycles.map((cycle) => {
|
|
149
|
+
const agents = cycle.agentsSpawned.join(", ");
|
|
150
|
+
const mode = cycle.mode ? ` mode="${escapeXml(cycle.mode)}"` : "";
|
|
151
|
+
return ` <cycle number="${cycle.cycle}"${mode} agents="${escapeXml(agents)}" />`;
|
|
152
|
+
}).join("\n");
|
|
153
|
+
const lines = [
|
|
154
|
+
"<context>",
|
|
155
|
+
`<session id="${escapeXml(session.id)}" status="${escapeXml(session.status)}">`,
|
|
156
|
+
` <task>${escapeXml(session.task)}</task>`,
|
|
157
|
+
` <cwd>${escapeXml(session.cwd)}</cwd>`
|
|
158
|
+
];
|
|
159
|
+
if (goal) lines.push(` <goal>${escapeXml(goal)}</goal>`);
|
|
160
|
+
if (roadmap) lines.push(` <roadmap>${escapeXml(roadmap)}</roadmap>`);
|
|
161
|
+
if (session.agents.length > 0) {
|
|
162
|
+
lines.push(" <agents>");
|
|
163
|
+
lines.push(agentsXml);
|
|
164
|
+
lines.push(" </agents>");
|
|
165
|
+
}
|
|
166
|
+
if (session.orchestratorCycles.length > 0) {
|
|
167
|
+
lines.push(" <cycles>");
|
|
168
|
+
lines.push(cyclesXml);
|
|
169
|
+
lines.push(" </cycles>");
|
|
170
|
+
}
|
|
171
|
+
if (session.completionReport) {
|
|
172
|
+
lines.push(` <completion-report>${escapeXml(session.completionReport)}</completion-report>`);
|
|
173
|
+
}
|
|
174
|
+
lines.push("</session>");
|
|
175
|
+
lines.push("</context>");
|
|
176
|
+
return lines.join("\n");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
computeActiveTimeMs,
|
|
181
|
+
resolveReports,
|
|
182
|
+
buildCompanionContext,
|
|
183
|
+
buildSessionContext
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=chunk-DBR33QHM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/utils.ts","../src/tui/lib/reports.ts","../src/tui/lib/context.ts"],"sourcesContent":["import type { Session } from './types.js';\n\n/**\n * Compute the total wall-clock milliseconds during which at least one\n * orchestrator cycle or agent was running. Merges overlapping intervals\n * so parallel agents aren't double-counted.\n */\nexport function computeActiveTimeMs(session: Session): number {\n const now = Date.now();\n const intervals: Array<[number, number]> = [];\n\n for (const cycle of session.orchestratorCycles) {\n const start = new Date(cycle.timestamp).getTime();\n const end = cycle.completedAt ? new Date(cycle.completedAt).getTime() : now;\n if (end > start) intervals.push([start, end]);\n }\n\n for (const agent of session.agents) {\n const start = new Date(agent.spawnedAt).getTime();\n const end = agent.completedAt ? new Date(agent.completedAt).getTime() : now;\n if (end > start) intervals.push([start, end]);\n }\n\n if (intervals.length === 0) return 0;\n\n intervals.sort((a, b) => a[0] - b[0]);\n\n const merged: Array<[number, number]> = [intervals[0]!];\n for (let i = 1; i < intervals.length; i++) {\n const last = merged[merged.length - 1]!;\n const cur = intervals[i]!;\n if (cur[0] <= last[1]) {\n last[1] = Math.max(last[1], cur[1]);\n } else {\n merged.push(cur);\n }\n }\n\n return merged.reduce((sum, [start, end]) => sum + (end - start), 0);\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, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\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"],"mappings":"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","names":["readFileSync","readFileSync"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
buildCompanionContext,
|
|
3
4
|
computeActiveTimeMs
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DBR33QHM.js";
|
|
5
6
|
import {
|
|
6
7
|
daemonLogPath,
|
|
7
8
|
daemonPidPath,
|
|
@@ -244,33 +245,15 @@ function printGettingStarted(keybindResult) {
|
|
|
244
245
|
const lines = [
|
|
245
246
|
"",
|
|
246
247
|
"Sisyphus installed \u2014 daemon running via launchd.",
|
|
247
|
-
"",
|
|
248
|
-
"Sisyphus is a tmux-integrated orchestration daemon for Claude Code multi-agent workflows.",
|
|
249
|
-
"A background daemon manages sessions where an orchestrator Claude breaks tasks into",
|
|
250
|
-
"subtasks, spawns agent Claude instances in tmux panes, and coordinates their lifecycle.",
|
|
251
|
-
"",
|
|
252
|
-
"Quick start:",
|
|
253
|
-
' sisyphus start "task description" Start a session (must be inside tmux)',
|
|
254
|
-
" sisyphus list List sessions",
|
|
255
|
-
" sisyphus status Show current session status",
|
|
256
|
-
" sisyphus kill <id> Kill a session",
|
|
257
|
-
"",
|
|
258
|
-
"Monitoring:",
|
|
259
|
-
" sisyphus dashboard Open TUI dashboard",
|
|
260
|
-
" tail -f ~/.sisyphus/daemon.log Watch daemon logs",
|
|
261
248
|
""
|
|
262
249
|
];
|
|
263
250
|
if (keybindResult.status === "installed") {
|
|
264
|
-
lines.push(`Tmux keybind: ${keybindResult.message}
|
|
251
|
+
lines.push(`Tmux keybind: ${keybindResult.message}`, "");
|
|
265
252
|
} else if (keybindResult.status === "conflict") {
|
|
266
|
-
lines.push(`Keybind: ${keybindResult.message}
|
|
253
|
+
lines.push(`Keybind: ${keybindResult.message}`, "");
|
|
267
254
|
}
|
|
268
255
|
lines.push(
|
|
269
|
-
"",
|
|
270
|
-
"Troubleshooting:",
|
|
271
|
-
" sisyphus doctor Check installation health",
|
|
272
|
-
" sisyphus setup-keybind [key] Configure tmux session-cycling keybind",
|
|
273
|
-
" sisyphus uninstall [--purge] Remove daemon and optionally all data",
|
|
256
|
+
"Run `sisyphus getting-started` for a complete usage guide.",
|
|
274
257
|
""
|
|
275
258
|
);
|
|
276
259
|
console.log(lines.join("\n"));
|
|
@@ -443,9 +426,23 @@ function registerDashboard(program2) {
|
|
|
443
426
|
function shellQuote2(s) {
|
|
444
427
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
445
428
|
}
|
|
429
|
+
function isTmuxInstalled() {
|
|
430
|
+
try {
|
|
431
|
+
execSync5("which tmux", { stdio: "pipe" });
|
|
432
|
+
return true;
|
|
433
|
+
} catch {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
446
437
|
function registerStart(program2) {
|
|
447
438
|
program2.command("start").description("Start a new sisyphus session").argument("<task>", "Task description for the orchestrator").option("-c, --context <context>", "Background context for the orchestrator").option("-n, --name <name>", "Human-readable name for the session").action(async (task, opts) => {
|
|
448
439
|
const cwd = process.env["SISYPHUS_CWD"] ?? process.cwd();
|
|
440
|
+
if (!process.env["TMUX"] && isTmuxInstalled()) {
|
|
441
|
+
console.log("Note: Sisyphus uses tmux to manage agent panes.");
|
|
442
|
+
console.log("It is highly recommended to run sisyphus from inside a tmux session.");
|
|
443
|
+
console.log(" tmux new-session");
|
|
444
|
+
console.log("");
|
|
445
|
+
}
|
|
449
446
|
const request = { type: "start", task, context: opts.context, cwd, name: opts.name };
|
|
450
447
|
const response = await sendRequest(request);
|
|
451
448
|
if (response.ok) {
|
|
@@ -1245,6 +1242,144 @@ function registerDoctor(program2) {
|
|
|
1245
1242
|
});
|
|
1246
1243
|
}
|
|
1247
1244
|
|
|
1245
|
+
// src/cli/commands/companion-context.ts
|
|
1246
|
+
function registerCompanionContext(program2) {
|
|
1247
|
+
program2.command("companion-context").description("Output session context JSON for companion hook").option("--cwd <path>", "Project directory", process.cwd()).action((opts) => {
|
|
1248
|
+
const context = buildCompanionContext(opts.cwd);
|
|
1249
|
+
process.stdout.write(JSON.stringify({ additionalContext: context }));
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// src/cli/commands/getting-started.ts
|
|
1254
|
+
import { execSync as execSync8 } from "child_process";
|
|
1255
|
+
function isTmuxInstalled2() {
|
|
1256
|
+
try {
|
|
1257
|
+
execSync8("which tmux", { stdio: "pipe" });
|
|
1258
|
+
return true;
|
|
1259
|
+
} catch {
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
function registerGettingStarted(program2) {
|
|
1264
|
+
program2.command("getting-started").description("Show a complete guide to using sisyphus effectively").action(() => {
|
|
1265
|
+
const hasTmux = isTmuxInstalled2();
|
|
1266
|
+
const inTmux = !!process.env["TMUX"];
|
|
1267
|
+
const lines = [
|
|
1268
|
+
"",
|
|
1269
|
+
" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557",
|
|
1270
|
+
" \u2551 Getting Started with Sisyphus \u2551",
|
|
1271
|
+
" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D",
|
|
1272
|
+
"",
|
|
1273
|
+
" Sisyphus is a multi-agent orchestration daemon for Claude Code.",
|
|
1274
|
+
" It breaks large tasks into subtasks, spawns parallel Claude agents,",
|
|
1275
|
+
" and coordinates their work across multiple cycles \u2014 autonomously.",
|
|
1276
|
+
"",
|
|
1277
|
+
" \u2500\u2500\u2500 Tmux \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1278
|
+
""
|
|
1279
|
+
];
|
|
1280
|
+
if (!hasTmux) {
|
|
1281
|
+
lines.push(
|
|
1282
|
+
" \u26A0 tmux is not installed. Sisyphus requires tmux.",
|
|
1283
|
+
" Install it: brew install tmux (macOS)",
|
|
1284
|
+
" apt install tmux (Linux)",
|
|
1285
|
+
""
|
|
1286
|
+
);
|
|
1287
|
+
} else if (!inTmux) {
|
|
1288
|
+
lines.push(
|
|
1289
|
+
" \u26A0 You are not inside a tmux session.",
|
|
1290
|
+
" Sisyphus spawns agent panes inside tmux, so you should",
|
|
1291
|
+
" start a tmux session before running sisyphus:",
|
|
1292
|
+
"",
|
|
1293
|
+
" tmux new-session",
|
|
1294
|
+
""
|
|
1295
|
+
);
|
|
1296
|
+
} else {
|
|
1297
|
+
lines.push(
|
|
1298
|
+
" \u2713 You are inside tmux. Good to go.",
|
|
1299
|
+
""
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1302
|
+
lines.push(
|
|
1303
|
+
" \u2500\u2500\u2500 What Makes a Good Sisyphus Task \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1304
|
+
"",
|
|
1305
|
+
" Sisyphus is built for BIG tasks \u2014 the kind that would take",
|
|
1306
|
+
" multiple cycles of orchestration and parallel agent work.",
|
|
1307
|
+
" If you could do it with a single Claude Code session in plan",
|
|
1308
|
+
" mode, it's too small for sisyphus.",
|
|
1309
|
+
"",
|
|
1310
|
+
" Good tasks:",
|
|
1311
|
+
' \u2022 "Implement this feature" @path/to/spec.md',
|
|
1312
|
+
' \u2022 "Do a deep dive on all SEO/AEO optimizations and',
|
|
1313
|
+
' systematically apply them across the site"',
|
|
1314
|
+
" \u2022 Large-scale refactors spanning dozens of files",
|
|
1315
|
+
" \u2022 Full feature builds from a written spec",
|
|
1316
|
+
"",
|
|
1317
|
+
" Too small for sisyphus:",
|
|
1318
|
+
' \u2022 "Add these 3 UI components to the page"',
|
|
1319
|
+
' \u2022 "Fix this bug in auth.ts"',
|
|
1320
|
+
" \u2022 Anything a single Claude session handles comfortably",
|
|
1321
|
+
"",
|
|
1322
|
+
" Tasks don't need to be hyper-specific \u2014 broad but meaningful",
|
|
1323
|
+
" tasks work great because the orchestrator will plan the approach.",
|
|
1324
|
+
" What matters is SCALE, not specificity.",
|
|
1325
|
+
"",
|
|
1326
|
+
" For best results, write a spec and reference it directly:",
|
|
1327
|
+
"",
|
|
1328
|
+
' sisyphus start "Implement this @path/to/spec.md"',
|
|
1329
|
+
"",
|
|
1330
|
+
" \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",
|
|
1331
|
+
"",
|
|
1332
|
+
' 1. You run: sisyphus start "task description"',
|
|
1333
|
+
" 2. An orchestrator Claude reviews the task and creates a roadmap",
|
|
1334
|
+
" 3. It spawns agent Claude instances in parallel tmux panes",
|
|
1335
|
+
" 4. Agents work independently, then submit reports when done",
|
|
1336
|
+
" 5. The orchestrator respawns with fresh context, reviews progress,",
|
|
1337
|
+
" and kicks off the next cycle of work",
|
|
1338
|
+
" 6. This repeats until the orchestrator marks the task complete",
|
|
1339
|
+
"",
|
|
1340
|
+
" The orchestrator is stateless \u2014 it gets killed after each cycle",
|
|
1341
|
+
" and respawned fresh with the full session state. This means it",
|
|
1342
|
+
" never runs out of context, no matter how many cycles a task takes.",
|
|
1343
|
+
"",
|
|
1344
|
+
" \u2500\u2500\u2500 Monitoring (Important!) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
1345
|
+
"",
|
|
1346
|
+
" Sisyphus sessions should be actively monitored. Agents can get",
|
|
1347
|
+
" stuck waiting for input, fail to submit reports, or take the",
|
|
1348
|
+
" roadmap in a direction you don't want. The dashboard is your",
|
|
1349
|
+
" primary tool for staying on top of things:",
|
|
1350
|
+
"",
|
|
1351
|
+
" sisyphus dashboard",
|
|
1352
|
+
"",
|
|
1353
|
+
" Key dashboard actions:",
|
|
1354
|
+
" m \u2014 Message the orchestrator to steer direction",
|
|
1355
|
+
" w \u2014 Jump directly into the sisyphus tmux session",
|
|
1356
|
+
" to see exactly what agents are doing",
|
|
1357
|
+
"",
|
|
1358
|
+
" Use `m` to course-correct from the dashboard, and `w` when you",
|
|
1359
|
+
" need the most granular view of agent activity.",
|
|
1360
|
+
"",
|
|
1361
|
+
" \u2500\u2500\u2500 Commands \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\u2500\u2500\u2500\u2500",
|
|
1362
|
+
"",
|
|
1363
|
+
" Start & monitor:",
|
|
1364
|
+
' sisyphus start "task" Start a session',
|
|
1365
|
+
' sisyphus start "task @spec.md" Start referencing a spec',
|
|
1366
|
+
" sisyphus status [id] Show session status",
|
|
1367
|
+
" sisyphus list List all sessions",
|
|
1368
|
+
" sisyphus dashboard Open TUI dashboard",
|
|
1369
|
+
"",
|
|
1370
|
+
" Control:",
|
|
1371
|
+
' sisyphus resume <id> "instructions" Resume with new direction',
|
|
1372
|
+
" sisyphus kill <id> Stop a session",
|
|
1373
|
+
"",
|
|
1374
|
+
" Health:",
|
|
1375
|
+
" sisyphus doctor Check installation health",
|
|
1376
|
+
" tail -f ~/.sisyphus/daemon.log Watch daemon logs",
|
|
1377
|
+
""
|
|
1378
|
+
);
|
|
1379
|
+
console.log(lines.join("\n"));
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1248
1383
|
// src/cli/index.ts
|
|
1249
1384
|
var program = new Command();
|
|
1250
1385
|
program.name("sisyphus").description("tmux-integrated orchestration daemon for Claude Code").version("0.1.0");
|
|
@@ -1268,6 +1403,8 @@ registerRollback(program);
|
|
|
1268
1403
|
registerRestartAgent(program);
|
|
1269
1404
|
registerSetupKeybind(program);
|
|
1270
1405
|
registerDoctor(program);
|
|
1406
|
+
registerCompanionContext(program);
|
|
1407
|
+
registerGettingStarted(program);
|
|
1271
1408
|
program.parseAsync(process.argv).catch((err) => {
|
|
1272
1409
|
console.error(err.message);
|
|
1273
1410
|
process.exit(1);
|