sisyphi 0.1.18 → 0.1.21

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
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-LTAW6OWS.js";
22
22
 
23
23
  // src/daemon/index.ts
24
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, existsSync as existsSync6 } from "fs";
24
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync9, writeFileSync as writeFileSync6, unlinkSync as unlinkSync3, existsSync as existsSync7 } from "fs";
25
25
  import { execSync as execSync4 } from "child_process";
26
26
  import { setTimeout as sleep } from "timers/promises";
27
27
 
@@ -46,12 +46,12 @@ function loadConfig(cwd) {
46
46
 
47
47
  // src/daemon/server.ts
48
48
  import { createServer } from "net";
49
- import { unlinkSync, existsSync as existsSync5, writeFileSync as writeFileSync4, readFileSync as readFileSync7, mkdirSync as mkdirSync4 } from "fs";
49
+ import { unlinkSync, existsSync as existsSync6, writeFileSync as writeFileSync4, readFileSync as readFileSync7, mkdirSync as mkdirSync4 } from "fs";
50
50
  import { join as join4 } from "path";
51
51
 
52
52
  // src/daemon/session-manager.ts
53
53
  import { v4 as uuidv4 } from "uuid";
54
- import { existsSync as existsSync4, readdirSync as readdirSync4, rmSync as rmSync2 } from "fs";
54
+ import { existsSync as existsSync5, readdirSync as readdirSync4, rmSync as rmSync2 } from "fs";
55
55
 
56
56
  // src/daemon/state.ts
57
57
  import { randomUUID } from "crypto";
@@ -95,7 +95,7 @@ function atomicWrite(filePath, data) {
95
95
  writeFileSync(tmpPath, data, "utf-8");
96
96
  renameSync(tmpPath, filePath);
97
97
  }
98
- function createSession(id, task, cwd) {
98
+ function createSession(id, task, cwd, context) {
99
99
  const dir = sessionDir(cwd, id);
100
100
  mkdirSync(dir, { recursive: true });
101
101
  mkdirSync(contextDir(cwd, id), { recursive: true });
@@ -106,6 +106,7 @@ function createSession(id, task, cwd) {
106
106
  const session = {
107
107
  id,
108
108
  task,
109
+ ...context ? { context } : {},
109
110
  cwd,
110
111
  status: "active",
111
112
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -203,13 +204,10 @@ async function completeOrchestratorCycle(cwd, sessionId, nextPrompt) {
203
204
  }
204
205
 
205
206
  // src/daemon/orchestrator.ts
206
- import { existsSync, readdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
207
+ import { existsSync, readdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
207
208
  import { resolve } from "path";
208
209
 
209
210
  // src/daemon/colors.ts
210
- import { readFileSync as readFileSync3 } from "fs";
211
- import { homedir } from "os";
212
- import { join as join2 } from "path";
213
211
  var ORCHESTRATOR_COLOR = "yellow";
214
212
  var AGENT_PALETTE = ["blue", "green", "magenta", "cyan", "red", "white"];
215
213
  var TMUX_COLOR_MAP = {
@@ -229,56 +227,6 @@ function getNextColor(sessionId) {
229
227
  function resetColors(sessionId) {
230
228
  sessionColorIndex.delete(sessionId);
231
229
  }
232
- function extractFrontmatterColor(content) {
233
- const match = content.match(/^---\n([\s\S]*?)\n---/);
234
- if (!match) return null;
235
- const colorMatch = match[1].match(/^color:\s*(.+)$/m);
236
- return colorMatch ? colorMatch[1].trim() : null;
237
- }
238
- function findPluginInstallPath(namespace) {
239
- try {
240
- const registryPath2 = join2(homedir(), ".claude", "plugins", "installed_plugins.json");
241
- const registry = JSON.parse(readFileSync3(registryPath2, "utf-8"));
242
- for (const key of Object.keys(registry)) {
243
- if (key.startsWith(`${namespace}@`)) {
244
- return registry[key].installPath ?? null;
245
- }
246
- }
247
- } catch {
248
- }
249
- return null;
250
- }
251
- function resolveAgentTypeColor(agentType, pluginDir, cwd) {
252
- if (!agentType) return null;
253
- let namespace;
254
- let name;
255
- if (agentType.includes(":")) {
256
- [namespace, name] = agentType.split(":", 2);
257
- } else {
258
- name = agentType;
259
- }
260
- const searchPaths = [];
261
- if (namespace) {
262
- searchPaths.push(join2(pluginDir, "agents", `${name}.md`));
263
- const installPath = findPluginInstallPath(namespace);
264
- if (installPath) {
265
- searchPaths.push(join2(installPath, "agents", `${name}.md`));
266
- }
267
- } else {
268
- searchPaths.push(join2(cwd, ".claude", "agents", `${name}.md`));
269
- searchPaths.push(join2(homedir(), ".claude", "agents", `${name}.md`));
270
- searchPaths.push(join2(pluginDir, "agents", `${name}.md`));
271
- }
272
- for (const path of searchPaths) {
273
- try {
274
- const content = readFileSync3(path, "utf-8");
275
- const color = extractFrontmatterColor(content);
276
- if (color) return normalizeTmuxColor(color);
277
- } catch {
278
- }
279
- }
280
- return null;
281
- }
282
230
 
283
231
  // src/daemon/tmux.ts
284
232
  import { execSync } from "child_process";
@@ -296,9 +244,13 @@ function execSafe(cmd) {
296
244
  return null;
297
245
  }
298
246
  }
299
- function createPane(windowTarget, cwd) {
247
+ function createPane(windowTarget, cwd, position = "right") {
300
248
  const cwdFlag = cwd ? ` -c ${shellQuote(cwd)}` : "";
301
- const paneId = exec(`tmux split-window -h -t "${windowTarget}"${cwdFlag} -P -F "#{pane_id}"`);
249
+ const panes = listPanes(windowTarget);
250
+ const target = position === "left" ? panes[0]?.paneId : panes[panes.length - 1]?.paneId;
251
+ const targetFlag = target ? ` -t "${target}"` : ` -t "${windowTarget}"`;
252
+ const beforeFlag = position === "left" ? "b" : "";
253
+ const paneId = exec(`tmux split-window -h${beforeFlag}${targetFlag}${cwdFlag} -P -F "#{pane_id}"`);
302
254
  execSafe(`tmux select-layout -t "${windowTarget}" even-horizontal`);
303
255
  return paneId;
304
256
  }
@@ -381,10 +333,10 @@ function setOrchestratorPaneId(sessionId, paneId) {
381
333
  function loadOrchestratorPrompt(cwd) {
382
334
  const projectPath = projectOrchestratorPromptPath(cwd);
383
335
  if (existsSync(projectPath)) {
384
- return readFileSync4(projectPath, "utf-8");
336
+ return readFileSync3(projectPath, "utf-8");
385
337
  }
386
338
  const bundledPath = resolve(import.meta.dirname, "../templates/orchestrator.md");
387
- return readFileSync4(bundledPath, "utf-8");
339
+ return readFileSync3(bundledPath, "utf-8");
388
340
  }
389
341
  function formatStateForOrchestrator(session) {
390
342
  const shortId = session.id.slice(0, 8);
@@ -436,11 +388,15 @@ function formatStateForOrchestrator(session) {
436
388
  ${wtLines}`;
437
389
  }
438
390
  const worktreeHint = existsSync(worktreeConfigPath(session.cwd)) ? "Worktree config active (`.sisyphus/worktree.json`). Use `--worktree` flag with `sisyphus spawn` to isolate agents in their own worktrees. Recommended for feature work, especially with potential file overlap." : "No worktree configuration found. If this session involves parallel work where agents may edit overlapping files, use the `git-management` skill to set up `.sisyphus/worktree.json` and enable worktree isolation.";
391
+ const contextSection = session.context ? `
392
+ ## Background Context
393
+ ${session.context}
394
+ ` : "";
439
395
  return `<state>
440
396
  session: ${shortId} (cycle ${cycleNum})
441
397
  task: ${session.task}
442
398
  status: ${session.status}
443
-
399
+ ${contextSection}
444
400
  ## Plan
445
401
  ${planRef}
446
402
 
@@ -494,8 +450,8 @@ Review the current session and delegate the next cycle of work.`;
494
450
  writeFileSync2(userPromptFilePath, userPrompt, "utf-8");
495
451
  const pluginPath = resolve(import.meta.dirname, "../templates/orchestrator-plugin");
496
452
  const settingsPath = resolve(import.meta.dirname, "../templates/orchestrator-settings.json");
497
- const claudeCmd = `claude --dangerously-skip-permissions --agent-name Sisyphus --agent-id orchestrator --team-name sisyphus-${sessionId.slice(0, 8)} --settings "${settingsPath}" --plugin-dir "${pluginPath}" --append-system-prompt "$(cat '${promptFilePath}')" "$(cat '${userPromptFilePath}')"`;
498
- const paneId = createPane(windowId, cwd);
453
+ const claudeCmd = `claude --dangerously-skip-permissions --settings "${settingsPath}" --plugin-dir "${pluginPath}" --append-system-prompt "$(cat '${promptFilePath}')" "$(cat '${userPromptFilePath}')"`;
454
+ const paneId = createPane(windowId, cwd, "left");
499
455
  sessionOrchestratorPane.set(sessionId, paneId);
500
456
  registerPane(paneId, sessionId, "orchestrator");
501
457
  setPaneTitle(paneId, `Sisyphus`);
@@ -546,13 +502,13 @@ function cleanupSessionMaps(sessionId) {
546
502
  }
547
503
 
548
504
  // src/daemon/agent.ts
549
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, readdirSync as readdirSync3, existsSync as existsSync3 } from "fs";
505
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, readdirSync as readdirSync3, existsSync as existsSync4 } from "fs";
550
506
  import { resolve as resolve2 } from "path";
551
507
 
552
508
  // src/daemon/worktree.ts
553
509
  import { execSync as execSync2 } from "child_process";
554
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync5, readdirSync as readdirSync2, rmSync } from "fs";
555
- import { dirname as dirname2, join as join3 } from "path";
510
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync4, readdirSync as readdirSync2, rmSync } from "fs";
511
+ import { dirname as dirname2, join as join2 } from "path";
556
512
  var EXEC_ENV2 = {
557
513
  ...process.env,
558
514
  PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env["PATH"] ?? "/usr/bin:/bin"}`
@@ -572,7 +528,7 @@ function shellQuote2(s) {
572
528
  }
573
529
  function loadWorktreeConfig(cwd) {
574
530
  try {
575
- const content = readFileSync5(worktreeConfigPath(cwd), "utf-8");
531
+ const content = readFileSync4(worktreeConfigPath(cwd), "utf-8");
576
532
  return JSON.parse(content);
577
533
  } catch {
578
534
  return null;
@@ -580,7 +536,7 @@ function loadWorktreeConfig(cwd) {
580
536
  }
581
537
  function createWorktreeShell(cwd, sessionId, agentId) {
582
538
  const branchName = `sisyphus/${sessionId.slice(0, 8)}/${agentId}`;
583
- const worktreePath = join3(worktreeBaseDir(cwd), sessionId.slice(0, 8), agentId);
539
+ const worktreePath = join2(worktreeBaseDir(cwd), sessionId.slice(0, 8), agentId);
584
540
  mkdirSync2(dirname2(worktreePath), { recursive: true });
585
541
  execSafe2(`git -C ${shellQuote2(cwd)} worktree prune`);
586
542
  if (existsSync2(worktreePath)) {
@@ -594,16 +550,16 @@ function createWorktreeShell(cwd, sessionId, agentId) {
594
550
  function bootstrapWorktree(cwd, worktreePath, config) {
595
551
  if (config.copy) {
596
552
  for (const entry of config.copy) {
597
- const dest = join3(worktreePath, entry);
553
+ const dest = join2(worktreePath, entry);
598
554
  mkdirSync2(dirname2(dest), { recursive: true });
599
- execSafe2(`cp -r ${shellQuote2(join3(cwd, entry))} ${shellQuote2(dest)}`);
555
+ execSafe2(`cp -r ${shellQuote2(join2(cwd, entry))} ${shellQuote2(dest)}`);
600
556
  }
601
557
  }
602
558
  if (config.clone) {
603
559
  for (const entry of config.clone) {
604
- const dest = join3(worktreePath, entry);
560
+ const dest = join2(worktreePath, entry);
605
561
  mkdirSync2(dirname2(dest), { recursive: true });
606
- const src = shellQuote2(join3(cwd, entry));
562
+ const src = shellQuote2(join2(cwd, entry));
607
563
  const dstQ = shellQuote2(dest);
608
564
  if (execSafe2(`cp -Rc ${src} ${dstQ}`) === null) {
609
565
  execSafe2(`cp -r ${src} ${dstQ}`);
@@ -612,9 +568,9 @@ function bootstrapWorktree(cwd, worktreePath, config) {
612
568
  }
613
569
  if (config.symlink) {
614
570
  for (const entry of config.symlink) {
615
- const dest = join3(worktreePath, entry);
571
+ const dest = join2(worktreePath, entry);
616
572
  mkdirSync2(dirname2(dest), { recursive: true });
617
- execSafe2(`ln -s ${shellQuote2(join3(cwd, entry))} ${shellQuote2(dest)}`);
573
+ execSafe2(`ln -s ${shellQuote2(join2(cwd, entry))} ${shellQuote2(dest)}`);
618
574
  }
619
575
  }
620
576
  if (config.init) {
@@ -697,6 +653,93 @@ function countWorktreeAgents(agents) {
697
653
  return agents.filter((a) => a.worktreePath && a.status === "running").length;
698
654
  }
699
655
 
656
+ // src/daemon/frontmatter.ts
657
+ import { readFileSync as readFileSync5, existsSync as existsSync3 } from "fs";
658
+ import { homedir } from "os";
659
+ import { join as join3 } from "path";
660
+ function detectProvider(model) {
661
+ if (!model) return "anthropic";
662
+ if (/^(gpt-|codex-)/.test(model)) return "openai";
663
+ return "anthropic";
664
+ }
665
+ function parseAgentFrontmatter(content) {
666
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
667
+ if (!match) return {};
668
+ const block = match[1];
669
+ const fm = {};
670
+ const str = (key) => {
671
+ const m = block.match(new RegExp(`^${key}:\\s*(.+)$`, "m"));
672
+ return m ? m[1].trim() : void 0;
673
+ };
674
+ fm.name = str("name");
675
+ fm.model = str("model");
676
+ fm.color = str("color");
677
+ fm.description = str("description");
678
+ fm.permissionMode = str("permissionMode");
679
+ const skillsMatch = block.match(/^skills:\s*\n((?:\s+-\s+.+\n?)*)/m);
680
+ if (skillsMatch) {
681
+ fm.skills = skillsMatch[1].split("\n").map((line) => line.replace(/^\s+-\s+/, "").trim()).filter(Boolean);
682
+ }
683
+ return fm;
684
+ }
685
+ function extractAgentBody(content) {
686
+ const match = content.match(/^---\n[\s\S]*?\n---\n?([\s\S]*)$/);
687
+ return match ? match[1].trim() : content.trim();
688
+ }
689
+ function findPluginInstallPath(namespace) {
690
+ try {
691
+ const registryPath2 = join3(homedir(), ".claude", "plugins", "installed_plugins.json");
692
+ const registry = JSON.parse(readFileSync5(registryPath2, "utf-8"));
693
+ for (const key of Object.keys(registry)) {
694
+ if (key.startsWith(`${namespace}@`)) {
695
+ return registry[key].installPath ?? null;
696
+ }
697
+ }
698
+ } catch {
699
+ }
700
+ return null;
701
+ }
702
+ function resolveAgentTypePath(agentType, pluginDir, cwd) {
703
+ if (!agentType) return null;
704
+ let namespace;
705
+ let name;
706
+ if (agentType.includes(":")) {
707
+ [namespace, name] = agentType.split(":", 2);
708
+ } else {
709
+ name = agentType;
710
+ }
711
+ const searchPaths = [];
712
+ if (namespace) {
713
+ searchPaths.push(join3(pluginDir, "agents", `${name}.md`));
714
+ const installPath = findPluginInstallPath(namespace);
715
+ if (installPath) {
716
+ searchPaths.push(join3(installPath, "agents", `${name}.md`));
717
+ }
718
+ } else {
719
+ searchPaths.push(join3(cwd, ".claude", "agents", `${name}.md`));
720
+ searchPaths.push(join3(homedir(), ".claude", "agents", `${name}.md`));
721
+ searchPaths.push(join3(pluginDir, "agents", `${name}.md`));
722
+ }
723
+ for (const path of searchPaths) {
724
+ if (existsSync3(path)) return path;
725
+ }
726
+ return null;
727
+ }
728
+ function resolveAgentConfig(agentType, pluginDir, cwd) {
729
+ const filePath = resolveAgentTypePath(agentType, pluginDir, cwd);
730
+ if (!filePath) return null;
731
+ try {
732
+ const content = readFileSync5(filePath, "utf-8");
733
+ return {
734
+ frontmatter: parseAgentFrontmatter(content),
735
+ body: extractAgentBody(content),
736
+ filePath
737
+ };
738
+ } catch {
739
+ return null;
740
+ }
741
+ }
742
+
700
743
  // src/daemon/agent.ts
701
744
  var agentCounters = /* @__PURE__ */ new Map();
702
745
  function resetAgentCounterFromState(sessionId, agents) {
@@ -736,7 +779,9 @@ async function spawnAgent(opts) {
736
779
  agentCounters.set(sessionId, count);
737
780
  const agentId = `agent-${String(count).padStart(3, "0")}`;
738
781
  const pluginPath = resolve2(import.meta.dirname, "../templates/agent-plugin");
739
- const color = resolveAgentTypeColor(agentType, pluginPath, cwd) ?? getNextColor(sessionId);
782
+ const agentConfig = resolveAgentConfig(agentType, pluginPath, cwd);
783
+ const provider = detectProvider(agentConfig?.frontmatter.model);
784
+ const color = (agentConfig?.frontmatter.color ? normalizeTmuxColor(agentConfig.frontmatter.color) : null) ?? getNextColor(sessionId);
740
785
  let paneCwd = cwd;
741
786
  let worktreePath;
742
787
  let branchName;
@@ -760,22 +805,37 @@ async function spawnAgent(opts) {
760
805
  const suffixFilePath = `${promptsDir(cwd, sessionId)}/${agentId}-system.md`;
761
806
  writeFileSync3(suffixFilePath, suffix, "utf-8");
762
807
  const bannerPath = resolve2(import.meta.dirname, "../templates/banner.txt");
763
- const bannerCmd = existsSync3(bannerPath) ? `cat '${bannerPath}' &&` : "";
808
+ const bannerCmd = existsSync4(bannerPath) ? `cat '${bannerPath}' &&` : "";
764
809
  const envExports = [
765
810
  `export SISYPHUS_SESSION_ID='${sessionId}'`,
766
811
  `export SISYPHUS_AGENT_ID='${agentId}'`,
767
812
  ...worktreeContext ? [`export SISYPHUS_PORT_OFFSET='${worktreeContext.offset}'`] : []
768
813
  ].join(" && ");
769
- const agentFlag = agentType && agentType !== "worker" ? ` --agent ${shellQuote3(agentType)}` : "";
770
- const agentNameFlag = ` --agent-name ${shellQuote3(paneLabel)}`;
771
- const teamFlag = ` --agent-id ${shellQuote3(agentId)} --team-name sisyphus-${sessionId.slice(0, 8)}`;
772
- const claudeCmd = `claude --dangerously-skip-permissions --plugin-dir "${pluginPath}"${agentFlag}${agentNameFlag}${teamFlag} --append-system-prompt "$(cat '${suffixFilePath}')" ${shellQuote3(instruction)}`;
773
814
  const notifyCmd = `sisyphus notify pane-exited --pane-id ${paneId}`;
774
- const fullCmd = `${bannerCmd} ${envExports} && ${claudeCmd}; ${notifyCmd}`;
815
+ let mainCmd;
816
+ if (provider === "openai") {
817
+ const codexPromptPath = `${promptsDir(cwd, sessionId)}/${agentId}-codex-prompt.md`;
818
+ const parts = [];
819
+ if (agentConfig?.body) {
820
+ parts.push(agentConfig.body);
821
+ }
822
+ parts.push(suffix);
823
+ parts.push(`## Task
824
+
825
+ ${instruction}`);
826
+ writeFileSync3(codexPromptPath, parts.join("\n\n"), "utf-8");
827
+ const model = agentConfig?.frontmatter.model ?? "codex-mini";
828
+ mainCmd = `codex -m ${shellQuote3(model)} --dangerously-bypass-approvals-and-sandbox "$(cat '${codexPromptPath}')"`;
829
+ } else {
830
+ const agentFlag = agentType && agentType !== "worker" ? ` --agent ${shellQuote3(agentType)}` : "";
831
+ mainCmd = `claude --dangerously-skip-permissions --plugin-dir "${pluginPath}"${agentFlag} --append-system-prompt "$(cat '${suffixFilePath}')" ${shellQuote3(instruction)}`;
832
+ }
833
+ const fullCmd = `${bannerCmd} ${envExports} && ${mainCmd}; ${notifyCmd}`;
775
834
  const agent = {
776
835
  id: agentId,
777
836
  name,
778
837
  agentType,
838
+ provider,
779
839
  color,
780
840
  instruction,
781
841
  status: "running",
@@ -970,9 +1030,9 @@ async function pollSession(sessionId, cwd, windowId) {
970
1030
  }
971
1031
 
972
1032
  // src/daemon/session-manager.ts
973
- async function startSession(task, cwd, tmuxSession, windowId) {
1033
+ async function startSession(task, cwd, tmuxSession, windowId, context) {
974
1034
  const sessionId = uuidv4();
975
- const session = createSession(sessionId, task, cwd);
1035
+ const session = createSession(sessionId, task, cwd, context);
976
1036
  await updateSessionTmux(cwd, sessionId, tmuxSession, windowId);
977
1037
  trackSession(sessionId, cwd, tmuxSession);
978
1038
  await spawnOrchestrator(sessionId, cwd, windowId);
@@ -985,7 +1045,7 @@ var PRUNE_KEEP_DAYS = 7;
985
1045
  function pruneOldSessions(cwd) {
986
1046
  try {
987
1047
  const dir = sessionsDir(cwd);
988
- if (!existsSync4(dir)) return;
1048
+ if (!existsSync5(dir)) return;
989
1049
  const entries = readdirSync4(dir, { withFileTypes: true });
990
1050
  const candidates = [];
991
1051
  for (const entry of entries) {
@@ -1052,7 +1112,7 @@ function getSessionStatus(cwd, sessionId) {
1052
1112
  }
1053
1113
  function listSessions(cwd) {
1054
1114
  const dir = sessionsDir(cwd);
1055
- if (!existsSync4(dir)) return [];
1115
+ if (!existsSync5(dir)) return [];
1056
1116
  const entries = readdirSync4(dir, { withFileTypes: true });
1057
1117
  const sessions = [];
1058
1118
  for (const entry of entries) {
@@ -1223,7 +1283,7 @@ function persistSessionRegistry() {
1223
1283
  }
1224
1284
  function loadSessionRegistry() {
1225
1285
  const p = registryPath();
1226
- if (!existsSync5(p)) return {};
1286
+ if (!existsSync6(p)) return {};
1227
1287
  try {
1228
1288
  return JSON.parse(readFileSync7(p, "utf-8"));
1229
1289
  } catch {
@@ -1242,7 +1302,7 @@ async function handleRequest(req) {
1242
1302
  try {
1243
1303
  switch (req.type) {
1244
1304
  case "start": {
1245
- const session = await startSession(req.task, req.cwd, req.tmuxSession, req.tmuxWindow);
1305
+ const session = await startSession(req.task, req.cwd, req.tmuxSession, req.tmuxWindow, req.context);
1246
1306
  registerSessionCwd(session.id, req.cwd);
1247
1307
  sessionTmuxMap.set(session.id, req.tmuxSession);
1248
1308
  sessionWindowMap2.set(session.id, req.tmuxWindow);
@@ -1319,7 +1379,7 @@ async function handleRequest(req) {
1319
1379
  let cwd = sessionCwdMap.get(req.sessionId);
1320
1380
  if (!cwd) {
1321
1381
  const stateFile = `${req.cwd}/.sisyphus/sessions/${req.sessionId}/state.json`;
1322
- if (existsSync5(stateFile)) {
1382
+ if (existsSync6(stateFile)) {
1323
1383
  cwd = req.cwd;
1324
1384
  registerSessionCwd(req.sessionId, cwd);
1325
1385
  } else {
@@ -1370,7 +1430,7 @@ async function handleRequest(req) {
1370
1430
  function startServer() {
1371
1431
  return new Promise((resolve4, reject) => {
1372
1432
  const sock = socketPath();
1373
- if (existsSync5(sock)) {
1433
+ if (existsSync6(sock)) {
1374
1434
  unlinkSync(sock);
1375
1435
  }
1376
1436
  server = createServer((conn) => {
@@ -1412,7 +1472,7 @@ function stopServer() {
1412
1472
  }
1413
1473
  server.close(() => {
1414
1474
  const sock = socketPath();
1415
- if (existsSync5(sock)) {
1475
+ if (existsSync6(sock)) {
1416
1476
  unlinkSync(sock);
1417
1477
  }
1418
1478
  server = null;
@@ -1618,7 +1678,7 @@ async function recoverSessions() {
1618
1678
  let recovered = 0;
1619
1679
  for (const [sessionId, cwd] of entries) {
1620
1680
  const stateFile = statePath(cwd, sessionId);
1621
- if (!existsSync6(stateFile)) {
1681
+ if (!existsSync7(stateFile)) {
1622
1682
  continue;
1623
1683
  }
1624
1684
  try {