sisyphi 1.1.12 → 1.1.13
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-ZSIYQB45.js → chunk-CAJEBTUE.js} +6 -2
- package/dist/chunk-CAJEBTUE.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +53 -47
- package/dist/daemon.js.map +1 -1
- package/dist/templates/orchestrator-base.md +9 -7
- package/dist/templates/orchestrator-completion.md +5 -0
- package/dist/templates/orchestrator-impl.md +5 -0
- package/dist/templates/orchestrator-planning.md +5 -0
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/dist/templates/orchestrator-strategy.md +5 -0
- package/dist/templates/orchestrator-validation.md +5 -0
- package/dist/tui.js +577 -125
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/orchestrator-base.md +9 -7
- package/templates/orchestrator-completion.md +5 -0
- package/templates/orchestrator-impl.md +5 -0
- package/templates/orchestrator-planning.md +5 -0
- package/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/templates/orchestrator-strategy.md +5 -0
- package/templates/orchestrator-validation.md +5 -0
- package/dist/chunk-ZSIYQB45.js.map +0 -1
package/dist/daemon.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
execEnv,
|
|
6
6
|
execSafe,
|
|
7
7
|
loadConfig
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CAJEBTUE.js";
|
|
9
9
|
import {
|
|
10
10
|
shellQuote
|
|
11
11
|
} from "./chunk-6G226ZK7.js";
|
|
@@ -339,7 +339,7 @@ function deleteSnapshotsAfter(cwd, sessionId, afterCycle) {
|
|
|
339
339
|
import { existsSync as existsSync5, readdirSync as readdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
340
340
|
import { execSync as execSync2 } from "child_process";
|
|
341
341
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
342
|
-
import { resolve as resolve3, join as join4 } from "path";
|
|
342
|
+
import { resolve as resolve3, join as join4, relative } from "path";
|
|
343
343
|
|
|
344
344
|
// src/daemon/spawn-helpers.ts
|
|
345
345
|
import { writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
|
|
@@ -603,9 +603,14 @@ function setPaneStyle(paneTarget, color, meta) {
|
|
|
603
603
|
execSafe(`tmux set -p -t "${paneTarget}" @pane_role ${shellQuote(meta.role)}`);
|
|
604
604
|
execSafe(`tmux set -p -t "${paneTarget}" @pane_session ${shellQuote(meta.session)}`);
|
|
605
605
|
execSafe(`tmux set -p -t "${paneTarget}" @pane_cycle ${shellQuote(meta.cycle)}`);
|
|
606
|
+
if (meta.mode) {
|
|
607
|
+
execSafe(`tmux set -p -t "${paneTarget}" @pane_mode ${shellQuote(meta.mode)}`);
|
|
608
|
+
}
|
|
609
|
+
const modeSegment = `#{?#{@pane_mode}, #[fg=${color}\\,italics]#{@pane_mode}#[default],}`;
|
|
606
610
|
const fmt = [
|
|
607
611
|
`#[bg=${color},fg=black,bold] #{@pane_role} #[default]`,
|
|
608
612
|
` #[fg=${color},bold]#{@pane_session}`,
|
|
613
|
+
modeSegment,
|
|
609
614
|
` #[default,dim]#{@pane_cycle}`,
|
|
610
615
|
` ${homePath}${branchSuffix}`,
|
|
611
616
|
`#[default]`
|
|
@@ -619,6 +624,7 @@ function updatePaneMeta(paneTarget, updates) {
|
|
|
619
624
|
if (updates.role !== void 0) execSafe(`tmux set -p -t "${paneTarget}" @pane_role ${shellQuote(updates.role)}`);
|
|
620
625
|
if (updates.session !== void 0) execSafe(`tmux set -p -t "${paneTarget}" @pane_session ${shellQuote(updates.session)}`);
|
|
621
626
|
if (updates.cycle !== void 0) execSafe(`tmux set -p -t "${paneTarget}" @pane_cycle ${shellQuote(updates.cycle)}`);
|
|
627
|
+
if (updates.mode !== void 0) execSafe(`tmux set -p -t "${paneTarget}" @pane_mode ${shellQuote(updates.mode)}`);
|
|
622
628
|
}
|
|
623
629
|
function selectLayout(windowTarget, layout = "even-horizontal") {
|
|
624
630
|
execSafe(`tmux select-layout -t "${windowTarget}" ${layout}`);
|
|
@@ -1328,6 +1334,18 @@ function getOrchestratorPaneId(sessionId) {
|
|
|
1328
1334
|
function setOrchestratorPaneId(sessionId, paneId) {
|
|
1329
1335
|
sessionOrchestratorPane.set(sessionId, paneId);
|
|
1330
1336
|
}
|
|
1337
|
+
function discoverOrchestratorModes() {
|
|
1338
|
+
const templatesDir = resolve3(import.meta.dirname, "../templates");
|
|
1339
|
+
const files = readdirSync4(templatesDir).filter(
|
|
1340
|
+
(f) => f.startsWith("orchestrator-") && f.endsWith(".md") && f !== "orchestrator-base.md"
|
|
1341
|
+
);
|
|
1342
|
+
return files.map((file) => {
|
|
1343
|
+
const content = readFileSync4(join4(templatesDir, file), "utf-8");
|
|
1344
|
+
const fm = parseAgentFrontmatter(content);
|
|
1345
|
+
const name = fm.name ?? file.replace(/^orchestrator-/, "").replace(/\.md$/, "");
|
|
1346
|
+
return { name, description: fm.description, filePath: join4(templatesDir, file) };
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1331
1349
|
function loadOrchestratorPrompt(cwd, sessionId, mode) {
|
|
1332
1350
|
const projectPath = projectOrchestratorPromptPath(cwd);
|
|
1333
1351
|
if (existsSync5(projectPath)) {
|
|
@@ -1335,24 +1353,14 @@ function loadOrchestratorPrompt(cwd, sessionId, mode) {
|
|
|
1335
1353
|
}
|
|
1336
1354
|
const basePath = resolve3(import.meta.dirname, "../templates/orchestrator-base.md");
|
|
1337
1355
|
const base = readFileSync4(basePath, "utf-8");
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
} else if (mode === "implementation") {
|
|
1343
|
-
const implPath = resolve3(import.meta.dirname, "../templates/orchestrator-impl.md");
|
|
1344
|
-
modePrompt = readFileSync4(implPath, "utf-8");
|
|
1345
|
-
} else if (mode === "validation") {
|
|
1346
|
-
const validationPath = resolve3(import.meta.dirname, "../templates/orchestrator-validation.md");
|
|
1347
|
-
modePrompt = readFileSync4(validationPath, "utf-8");
|
|
1348
|
-
} else if (mode === "completion") {
|
|
1349
|
-
const completionPath = resolve3(import.meta.dirname, "../templates/orchestrator-completion.md");
|
|
1350
|
-
modePrompt = readFileSync4(completionPath, "utf-8");
|
|
1351
|
-
} else {
|
|
1352
|
-
const planningPath = resolve3(import.meta.dirname, "../templates/orchestrator-planning.md");
|
|
1353
|
-
modePrompt = readFileSync4(planningPath, "utf-8");
|
|
1356
|
+
const modes = discoverOrchestratorModes();
|
|
1357
|
+
const selected = modes.find((m) => m.name === mode) ?? modes.find((m) => m.name === "strategy");
|
|
1358
|
+
if (!selected) {
|
|
1359
|
+
throw new Error(`Unknown orchestrator mode '${mode}' and no fallback found. Available: ${modes.map((m) => m.name).join(", ")}`);
|
|
1354
1360
|
}
|
|
1355
|
-
|
|
1361
|
+
const modeContent = readFileSync4(selected.filePath, "utf-8");
|
|
1362
|
+
const modeBody = extractAgentBody(modeContent);
|
|
1363
|
+
return base + "\n\n" + modeBody;
|
|
1356
1364
|
}
|
|
1357
1365
|
function formatStateForOrchestrator(session) {
|
|
1358
1366
|
const cycleNum = session.orchestratorCycles.length;
|
|
@@ -1374,37 +1382,19 @@ ${session.context}
|
|
|
1374
1382
|
ctxFiles = readdirSync4(ctxDir).filter((f) => f !== "CLAUDE.md");
|
|
1375
1383
|
}
|
|
1376
1384
|
if (ctxFiles.length > 0) {
|
|
1377
|
-
const ctxLines = ctxFiles.map((f) => `- ${join4(ctxDir, f)}`).join("\n");
|
|
1378
1385
|
contextSection = `
|
|
1379
1386
|
## Context
|
|
1380
1387
|
|
|
1381
|
-
|
|
1388
|
+
@${relative(session.cwd, ctxDir)}
|
|
1382
1389
|
`;
|
|
1383
1390
|
}
|
|
1384
1391
|
}
|
|
1385
1392
|
const messages = session.messages ?? [];
|
|
1386
1393
|
const messagesSection = messages.length > 0 ? "\n### Messages\n\n" + messages.map((m) => {
|
|
1387
1394
|
const sourceLabel = m.source.type === "agent" ? `agent:${m.source.agentId}` : m.source.type === "system" && m.source.detail ? `system:${m.source.detail}` : m.source.type;
|
|
1388
|
-
const fileRef = m.filePath ? ` \u2192 ${m.filePath}` : "";
|
|
1395
|
+
const fileRef = m.filePath ? ` \u2192 ${relative(session.cwd, m.filePath)}` : "";
|
|
1389
1396
|
return `- [${sourceLabel} @ ${m.timestamp}] "${m.summary}"${fileRef}`;
|
|
1390
1397
|
}).join("\n") + "\n" : "";
|
|
1391
|
-
let previousCyclesSection = "";
|
|
1392
|
-
if (session.orchestratorCycles.length > 1) {
|
|
1393
|
-
const previousCycles = session.orchestratorCycles.slice(0, -1);
|
|
1394
|
-
const agentMap = new Map(session.agents.map((a) => [a.id, a]));
|
|
1395
|
-
const lines = previousCycles.map((c) => {
|
|
1396
|
-
const agentDescs = c.agentsSpawned.map((id) => {
|
|
1397
|
-
const agent = agentMap.get(id);
|
|
1398
|
-
return agent ? `${id} (${agent.name})` : id;
|
|
1399
|
-
}).join(", ");
|
|
1400
|
-
return `Cycle ${c.cycle}: ${agentDescs || "(none)"}`;
|
|
1401
|
-
});
|
|
1402
|
-
previousCyclesSection = `
|
|
1403
|
-
### Previous Cycles
|
|
1404
|
-
|
|
1405
|
-
${lines.join("\n")}
|
|
1406
|
-
`;
|
|
1407
|
-
}
|
|
1408
1398
|
let mostRecentCycleSection = "";
|
|
1409
1399
|
const lastCycle = session.orchestratorCycles[session.orchestratorCycles.length - 1];
|
|
1410
1400
|
if (lastCycle && lastCycle.agentsSpawned.length > 0) {
|
|
@@ -1414,7 +1404,7 @@ ${lines.join("\n")}
|
|
|
1414
1404
|
if (!agent) return `- **${id}**: unknown (no agent data)`;
|
|
1415
1405
|
const finalReport = agent.reports.find((r) => r.type === "final");
|
|
1416
1406
|
const reportToUse = finalReport ?? agent.reports[agent.reports.length - 1];
|
|
1417
|
-
const reportRef = reportToUse ? `@${reportToUse.filePath}` : "(no reports)";
|
|
1407
|
+
const reportRef = reportToUse ? `@${relative(session.cwd, reportToUse.filePath)}` : "(no reports)";
|
|
1418
1408
|
return `- **${id}** (${agent.name}) [${agent.status}]: ${reportRef}`;
|
|
1419
1409
|
}).join("\n");
|
|
1420
1410
|
mostRecentCycleSection = `
|
|
@@ -1424,8 +1414,8 @@ ${agentLines}
|
|
|
1424
1414
|
`;
|
|
1425
1415
|
}
|
|
1426
1416
|
const strategyFile = strategyPath(session.cwd, session.id);
|
|
1427
|
-
const strategyRef = existsSync5(strategyFile) ? `@${strategyFile}` : "(empty)";
|
|
1428
|
-
const roadmapRef = existsSync5(roadmapFile) ? `@${roadmapFile}` : "(empty)";
|
|
1417
|
+
const strategyRef = existsSync5(strategyFile) ? `@${relative(session.cwd, strategyFile)}` : "(empty)";
|
|
1418
|
+
const roadmapRef = existsSync5(roadmapFile) ? `@${relative(session.cwd, roadmapFile)}` : "(empty)";
|
|
1429
1419
|
const repos = detectRepos(session.cwd);
|
|
1430
1420
|
let repositoriesSection = "\n\n## Repositories\n";
|
|
1431
1421
|
if (repos.length === 0) {
|
|
@@ -1459,8 +1449,8 @@ ${goalContent}
|
|
|
1459
1449
|
${contextSection}${messagesSection}
|
|
1460
1450
|
### Cycle Log
|
|
1461
1451
|
|
|
1462
|
-
Write your cycle summary to: ${logFile}
|
|
1463
|
-
${
|
|
1452
|
+
Write your cycle summary to: ${relative(session.cwd, logFile)}
|
|
1453
|
+
${mostRecentCycleSection}
|
|
1464
1454
|
## Strategy
|
|
1465
1455
|
|
|
1466
1456
|
${strategyRef}
|
|
@@ -1490,7 +1480,14 @@ async function spawnOrchestrator(sessionId, cwd, windowId, message) {
|
|
|
1490
1480
|
}).join("\n") : " (none)";
|
|
1491
1481
|
const sesDir = sessionDir(cwd, sessionId);
|
|
1492
1482
|
const substituteEnvVars = (text) => text.replace(/\$SISYPHUS_SESSION_DIR/g, sesDir).replace(/\$SISYPHUS_SESSION_ID/g, sessionId);
|
|
1493
|
-
const
|
|
1483
|
+
const modes = discoverOrchestratorModes();
|
|
1484
|
+
const modeLines = modes.map((m) => {
|
|
1485
|
+
const desc = m.description ? ` \u2014 ${m.description}` : "";
|
|
1486
|
+
return `- \`${m.name}\`${desc}`;
|
|
1487
|
+
}).join("\n");
|
|
1488
|
+
const systemPrompt = substituteEnvVars(
|
|
1489
|
+
basePrompt.replace("{{AGENT_TYPES}}", agentTypeLines).replace("{{ORCHESTRATOR_MODES}}", modeLines)
|
|
1490
|
+
);
|
|
1494
1491
|
const cycleNum = session.orchestratorCycles.length + 1;
|
|
1495
1492
|
const promptFilePath = `${promptsDir(cwd, sessionId)}/orchestrator-system-${cycleNum}.md`;
|
|
1496
1493
|
writeFileSync4(promptFilePath, systemPrompt, "utf-8");
|
|
@@ -1535,13 +1532,21 @@ ${continuationText}`;
|
|
|
1535
1532
|
registerPane(paneId, sessionId, "orchestrator");
|
|
1536
1533
|
const sessionLabel = session.name ?? sessionId.slice(0, 8);
|
|
1537
1534
|
setPaneTitle(paneId, `ssph:orch ${sessionLabel} c${cycleNum}`);
|
|
1538
|
-
setPaneStyle(paneId, ORCHESTRATOR_COLOR, { role: "orch", session: sessionLabel, cycle: `c${cycleNum}
|
|
1535
|
+
setPaneStyle(paneId, ORCHESTRATOR_COLOR, { role: "orch", session: sessionLabel, cycle: `c${cycleNum}`, mode });
|
|
1536
|
+
const notifyEnabled = config.notifications?.enabled !== false ? "1" : "0";
|
|
1537
|
+
const notifySound = config.notifications?.sound ?? "/System/Library/Sounds/Hero.aiff";
|
|
1538
|
+
const notifyEnvExports = buildEnvExports([
|
|
1539
|
+
`export SISYPHUS_NOTIFY_ENABLED='${notifyEnabled}'`,
|
|
1540
|
+
`export SISYPHUS_NOTIFY_SOUND='${notifySound}'`,
|
|
1541
|
+
`export SISYPHUS_SESSION_NAME='${sessionLabel}'`
|
|
1542
|
+
]);
|
|
1539
1543
|
const bannerCmd = resolveBannerCmd();
|
|
1540
1544
|
const notifyCmd = buildNotifyCmd(paneId);
|
|
1541
1545
|
const scriptPath = writeRunScript(promptsDir(cwd, sessionId), `orchestrator-run-${cycleNum}`, [
|
|
1542
1546
|
"#!/usr/bin/env bash",
|
|
1543
1547
|
...bannerCmd ? [bannerCmd] : [],
|
|
1544
1548
|
envExports,
|
|
1549
|
+
notifyEnvExports,
|
|
1545
1550
|
claudeCmd,
|
|
1546
1551
|
notifyCmd
|
|
1547
1552
|
]);
|
|
@@ -1552,7 +1557,8 @@ ${continuationText}`;
|
|
|
1552
1557
|
activeMs: 0,
|
|
1553
1558
|
agentsSpawned: [],
|
|
1554
1559
|
paneId,
|
|
1555
|
-
claudeSessionId
|
|
1560
|
+
claudeSessionId,
|
|
1561
|
+
mode
|
|
1556
1562
|
});
|
|
1557
1563
|
}
|
|
1558
1564
|
function resolveOrchestratorPane(sessionId, cwd) {
|