sisyphi 1.1.13 → 1.1.15

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/daemon.js CHANGED
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ resolveRequiredPluginDirs
4
+ } from "./chunk-UIVQXCWB.js";
2
5
  import {
3
6
  EXEC_ENV,
4
7
  exec,
5
8
  execEnv,
6
- execSafe,
7
- loadConfig
8
- } from "./chunk-CAJEBTUE.js";
9
+ execSafe
10
+ } from "./chunk-6TIO23U3.js";
9
11
  import {
12
+ loadConfig,
10
13
  shellQuote
11
- } from "./chunk-6G226ZK7.js";
14
+ } from "./chunk-IF55HPWX.js";
12
15
  import {
13
16
  contextDir,
14
17
  cycleLogPath,
@@ -873,8 +876,10 @@ ${instruction}`);
873
876
  const config = loadConfig(cwd);
874
877
  const effort = agentConfig?.frontmatter.effort ?? config.agentEffort ?? "medium";
875
878
  const pluginPath = createAgentPlugin(cwd, sessionId, agentId, agentType, agentConfig);
879
+ const requiredPluginDirs = resolveRequiredPluginDirs(cwd);
880
+ const extraPluginFlags = requiredPluginDirs.map((p) => `--plugin-dir "${p}"`).join(" ");
876
881
  const sessionIdFlag = claudeSessionId ? ` --session-id "${claudeSessionId}"` : "";
877
- mainCmd = `claude --dangerously-skip-permissions --effort ${effort} --plugin-dir "${pluginPath}"${agentFlag}${sessionIdFlag} --name ${shellQuote(agentTitle)} --append-system-prompt "$(cat '${suffixFilePath}')" ${shellQuote(instruction)}`;
882
+ mainCmd = `claude --dangerously-skip-permissions --effort ${effort} --plugin-dir "${pluginPath}"${agentFlag}${sessionIdFlag}${extraPluginFlags ? ` ${extraPluginFlags}` : ""} --name ${shellQuote(agentTitle)} --append-system-prompt "$(cat '${suffixFilePath}')" ${shellQuote(instruction)}`;
878
883
  }
879
884
  const scriptPath = writeRunScript(promptsDir(cwd, sessionId), `${agentId}-run`, [
880
885
  "#!/usr/bin/env bash",
@@ -1083,6 +1088,9 @@ function allAgentsDone(session) {
1083
1088
  return running.length === 0 && session.agents.length > 0;
1084
1089
  }
1085
1090
 
1091
+ // src/daemon/respawn-guard.ts
1092
+ var respawningSessions = /* @__PURE__ */ new Set();
1093
+
1086
1094
  // src/daemon/pane-monitor.ts
1087
1095
  var monitorInterval = null;
1088
1096
  var onAllAgentsDone = null;
@@ -1220,6 +1228,7 @@ async function pollSession(sessionId, cwd, windowId, increment) {
1220
1228
  if (session.status !== "active") return;
1221
1229
  const livePanes = listPanes(windowId);
1222
1230
  if (livePanes.length === 0) {
1231
+ if (respawningSessions.has(sessionId)) return;
1223
1232
  const tracked = trackedSessions.get(sessionId);
1224
1233
  if (tracked && !sessionExists(tracked.tmuxSession)) {
1225
1234
  await flushTimers(sessionId);
@@ -1525,8 +1534,10 @@ ${continuationText}`;
1525
1534
  const settingsPath = resolve3(import.meta.dirname, "../templates/orchestrator-settings.json");
1526
1535
  const config = loadConfig(cwd);
1527
1536
  const effort = config.orchestratorEffort ?? "high";
1537
+ const requiredPluginDirs = resolveRequiredPluginDirs(cwd);
1538
+ const extraPluginFlags = requiredPluginDirs.map((p) => `--plugin-dir "${p}"`).join(" ");
1528
1539
  const claudeSessionId = randomUUID3();
1529
- const claudeCmd = `claude --dangerously-skip-permissions --disallowed-tools "Task,Agent" --effort ${effort} --session-id "${claudeSessionId}" --settings "${settingsPath}" --plugin-dir "${pluginPath}" --name "ssph:orch ${session.name ?? sessionId.slice(0, 8)} c${cycleNum}" --system-prompt "$(cat '${promptFilePath}')" "$(cat '${userPromptFilePath}')"`;
1540
+ const claudeCmd = `claude --dangerously-skip-permissions --disallowed-tools "Task,Agent" --effort ${effort} --session-id "${claudeSessionId}" --settings "${settingsPath}" --plugin-dir "${pluginPath}"${extraPluginFlags ? ` ${extraPluginFlags}` : ""} --name "ssph:orch ${session.name ?? sessionId.slice(0, 8)} c${cycleNum}" --system-prompt "$(cat '${promptFilePath}')" "$(cat '${userPromptFilePath}')"`;
1530
1541
  const paneId = createPane(windowId, cwd, "left");
1531
1542
  sessionOrchestratorPane.set(sessionId, paneId);
1532
1543
  registerPane(paneId, sessionId, "orchestrator");
@@ -1818,7 +1829,10 @@ function onAllAgentsDone2(sessionId, cwd, windowId) {
1818
1829
  }
1819
1830
  }
1820
1831
  const session = getSession(cwd, sessionId);
1821
- if (session.status !== "active") return;
1832
+ if (session.status !== "active") {
1833
+ respawningSessions.delete(sessionId);
1834
+ return;
1835
+ }
1822
1836
  pendingRespawns.add(sessionId);
1823
1837
  orchestratorDone.delete(sessionId);
1824
1838
  const cycleNumber = session.orchestratorCycles.length;
@@ -1829,7 +1843,12 @@ function onAllAgentsDone2(sessionId, cwd, windowId) {
1829
1843
  pendingRespawns.delete(sessionId);
1830
1844
  try {
1831
1845
  const freshSession = getSession(cwd, sessionId);
1832
- if (freshSession.status !== "active") return;
1846
+ if (freshSession.status === "paused" && respawningSessions.has(sessionId)) {
1847
+ await updateSessionStatus(cwd, sessionId, "active");
1848
+ } else if (freshSession.status !== "active") {
1849
+ respawningSessions.delete(sessionId);
1850
+ return;
1851
+ }
1833
1852
  let activeWindowId = windowId;
1834
1853
  const tmuxName = freshSession.tmuxSessionName;
1835
1854
  const needsRecreation = tmuxName && (!sessionExists(tmuxName) || listPanes(activeWindowId).length === 0);
@@ -1844,6 +1863,7 @@ function onAllAgentsDone2(sessionId, cwd, windowId) {
1844
1863
  initialPaneId = created.initialPaneId;
1845
1864
  await updateSessionTmux(cwd, sessionId, tmuxName, activeWindowId);
1846
1865
  trackSession(sessionId, cwd, tmuxName);
1866
+ registerSessionTmux(sessionId, tmuxName, activeWindowId);
1847
1867
  }
1848
1868
  await spawnOrchestrator(sessionId, cwd, activeWindowId);
1849
1869
  updateTrackedWindow(sessionId, activeWindowId);
@@ -1856,6 +1876,8 @@ function onAllAgentsDone2(sessionId, cwd, windowId) {
1856
1876
  selectLayout(activeWindowId);
1857
1877
  } catch (err) {
1858
1878
  console.error(`[sisyphus] Failed to respawn orchestrator for session ${sessionId}:`, err);
1879
+ } finally {
1880
+ respawningSessions.delete(sessionId);
1859
1881
  }
1860
1882
  });
1861
1883
  }
@@ -1895,6 +1917,7 @@ async function handleYield(sessionId, cwd, nextPrompt, mode) {
1895
1917
  if (pre.status === "paused") {
1896
1918
  await updateSessionStatus(cwd, sessionId, "active");
1897
1919
  }
1920
+ respawningSessions.add(sessionId);
1898
1921
  await handleOrchestratorYield(sessionId, cwd, nextPrompt, mode);
1899
1922
  orchestratorDone.add(sessionId);
1900
1923
  const session = getSession(cwd, sessionId);
@@ -1903,7 +1926,11 @@ async function handleYield(sessionId, cwd, nextPrompt, mode) {
1903
1926
  const windowId = getWindowId(sessionId) ?? session.tmuxWindowId;
1904
1927
  if (windowId) {
1905
1928
  onAllAgentsDone2(sessionId, cwd, windowId);
1929
+ } else {
1930
+ respawningSessions.delete(sessionId);
1906
1931
  }
1932
+ } else {
1933
+ respawningSessions.delete(sessionId);
1907
1934
  }
1908
1935
  }
1909
1936
  async function handleComplete(sessionId, cwd, report) {
@@ -2023,6 +2050,7 @@ async function handlePaneExited(paneId, cwd, sessionId, role, agentId) {
2023
2050
  } else if (role === "orchestrator") {
2024
2051
  const sessionName = session.name ?? sessionId.slice(0, 8);
2025
2052
  sendTerminalNotification("Sisyphus", `Orchestrator exited without yielding (${sessionName})`);
2053
+ respawningSessions.add(sessionId);
2026
2054
  const cycleActiveMs = flushCycleTimer(sessionId, session.orchestratorCycles.length);
2027
2055
  await completeOrchestratorCycle(cwd, sessionId, void 0, void 0, cycleActiveMs);
2028
2056
  orchestratorDone.add(sessionId);
@@ -2032,10 +2060,15 @@ async function handlePaneExited(paneId, cwd, sessionId, role, agentId) {
2032
2060
  if (windowId) {
2033
2061
  console.log(`[sisyphus] Orchestrator pane exited for session ${sessionId}, all agents done \u2014 triggering respawn`);
2034
2062
  onAllAgentsDone2(sessionId, cwd, windowId);
2063
+ } else {
2064
+ respawningSessions.delete(sessionId);
2035
2065
  }
2036
2066
  } else if (!hasRunningAgents) {
2067
+ respawningSessions.delete(sessionId);
2037
2068
  await updateSessionStatus(cwd, sessionId, "paused");
2038
2069
  console.log(`[sisyphus] Session ${sessionId} paused: orchestrator pane exited with no agents`);
2070
+ } else {
2071
+ respawningSessions.delete(sessionId);
2039
2072
  }
2040
2073
  }
2041
2074
  }