sisyphi 1.1.14 → 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.
@@ -1,33 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- globalConfigPath,
4
- projectConfigPath
5
- } from "./chunk-GSXF3TCZ.js";
6
-
7
- // src/shared/config.ts
8
- import { readFileSync } from "fs";
9
- var DEFAULT_CONFIG = {
10
- pollIntervalMs: 5e3,
11
- orchestratorEffort: "high",
12
- agentEffort: "medium",
13
- notifications: {
14
- enabled: true,
15
- sound: "/System/Library/Sounds/Hero.aiff"
16
- }
17
- };
18
- function readJsonFile(filePath) {
19
- try {
20
- const content = readFileSync(filePath, "utf-8");
21
- return JSON.parse(content);
22
- } catch {
23
- return {};
24
- }
25
- }
26
- function loadConfig(cwd) {
27
- const global = readJsonFile(globalConfigPath());
28
- const project = readJsonFile(projectConfigPath(cwd));
29
- return { ...DEFAULT_CONFIG, ...global, ...project };
30
- }
31
2
 
32
3
  // src/shared/env.ts
33
4
  import { resolve } from "path";
@@ -87,11 +58,10 @@ function execSafe(cmd, cwd) {
87
58
  }
88
59
 
89
60
  export {
90
- loadConfig,
91
61
  augmentedPath,
92
62
  execEnv,
93
63
  EXEC_ENV,
94
64
  exec,
95
65
  execSafe
96
66
  };
97
- //# sourceMappingURL=chunk-4OVSSS2V.js.map
67
+ //# sourceMappingURL=chunk-6TIO23U3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/env.ts","../src/shared/exec.ts"],"sourcesContent":["import { resolve } from 'node:path';\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 home = process.env['HOME'];\n const candidates = [\n ...(home ? [`${home}/.local/bin`] : []), // Claude CLI, pipx, user-local installs\n resolve(process.execPath, '..'), // Node.js bin dir (ensures node/npm available)\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,eAAe;AAUjB,SAAS,gBAAwB;AACtC,QAAM,UAAU,QAAQ,IAAI,MAAM;AAClC,QAAM,WAAW,YAAY,UAAa,QAAQ,SAAS,IAAI,UAAU;AAIzE,QAAM,OAAO,QAAQ,IAAI,MAAM;AAC/B,QAAM,aAAa;AAAA,IACjB,GAAI,OAAO,CAAC,GAAG,IAAI,aAAa,IAAI,CAAC;AAAA;AAAA,IACrC,QAAQ,QAAQ,UAAU,IAAI;AAAA;AAAA,IAC9B;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;;;ACpDA,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":[]}
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ globalConfigPath,
4
+ projectConfigPath
5
+ } from "./chunk-GSXF3TCZ.js";
6
+
7
+ // src/shared/config.ts
8
+ import { readFileSync } from "fs";
9
+ var DEFAULT_CONFIG = {
10
+ pollIntervalMs: 5e3,
11
+ orchestratorEffort: "high",
12
+ agentEffort: "medium",
13
+ notifications: {
14
+ enabled: true,
15
+ sound: "/System/Library/Sounds/Hero.aiff"
16
+ },
17
+ requiredPlugins: [
18
+ { name: "devcore", marketplace: "crouton-kit" }
19
+ ]
20
+ };
21
+ function readJsonFile(filePath) {
22
+ try {
23
+ const content = readFileSync(filePath, "utf-8");
24
+ return JSON.parse(content);
25
+ } catch {
26
+ return {};
27
+ }
28
+ }
29
+ function loadConfig(cwd) {
30
+ const global = readJsonFile(globalConfigPath());
31
+ const project = readJsonFile(projectConfigPath(cwd));
32
+ return { ...DEFAULT_CONFIG, ...global, ...project };
33
+ }
34
+
35
+ // src/shared/shell.ts
36
+ function shellQuote(s) {
37
+ return `'${s.replace(/'/g, "'\\''")}'`;
38
+ }
39
+
40
+ export {
41
+ loadConfig,
42
+ shellQuote
43
+ };
44
+ //# sourceMappingURL=chunk-IF55HPWX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/config.ts","../src/shared/shell.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport type EffortLevel = 'low' | 'medium' | 'high' | 'max';\n\nexport interface NotificationConfig {\n enabled?: boolean;\n sound?: string;\n}\n\nexport interface RequiredPlugin {\n name: string;\n marketplace: string;\n}\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 notifications?: NotificationConfig;\n requiredPlugins?: RequiredPlugin[];\n}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 5000,\n orchestratorEffort: 'high',\n agentEffort: 'medium',\n notifications: {\n enabled: true,\n sound: '/System/Library/Sounds/Hero.aiff',\n },\n requiredPlugins: [\n { name: 'devcore', marketplace: 'crouton-kit' },\n ],\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","export function shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n"],"mappings":";;;;;;;AAAA,SAAS,oBAAoB;AA6B7B,IAAM,iBAAyB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,eAAe;AAAA,IACb,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AAAA,IACf,EAAE,MAAM,WAAW,aAAa,cAAc;AAAA,EAChD;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;;;ACvDO,SAAS,WAAW,GAAmB;AAC5C,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;","names":[]}
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadConfig
4
+ } from "./chunk-IF55HPWX.js";
5
+
6
+ // src/daemon/plugins.ts
7
+ import { readFileSync } from "fs";
8
+ import { homedir } from "os";
9
+ import { join } from "path";
10
+ function installedPluginsPath() {
11
+ return join(homedir(), ".claude", "plugins", "installed_plugins.json");
12
+ }
13
+ function resolveInstalledPlugin(name) {
14
+ let data;
15
+ try {
16
+ data = JSON.parse(readFileSync(installedPluginsPath(), "utf-8"));
17
+ } catch {
18
+ return null;
19
+ }
20
+ const entries = data.plugins?.[name];
21
+ if (!entries || entries.length === 0) return null;
22
+ const userEntry = entries.find((e) => e.scope === "user");
23
+ return (userEntry ?? entries[0]).installPath;
24
+ }
25
+ function resolveRequiredPluginDirs(cwd) {
26
+ const config = loadConfig(cwd);
27
+ const required = config.requiredPlugins;
28
+ if (!required || required.length === 0) return [];
29
+ const dirs = [];
30
+ for (const plugin of required) {
31
+ const key = `${plugin.name}@${plugin.marketplace}`;
32
+ const path = resolveInstalledPlugin(key);
33
+ if (path) {
34
+ dirs.push(path);
35
+ } else {
36
+ console.log(`[sisyphus] Warning: required plugin ${key} not installed \u2014 skipping`);
37
+ }
38
+ }
39
+ return dirs;
40
+ }
41
+
42
+ export {
43
+ resolveInstalledPlugin,
44
+ resolveRequiredPluginDirs
45
+ };
46
+ //# sourceMappingURL=chunk-UIVQXCWB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/daemon/plugins.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { loadConfig } from '../shared/config.js';\n\ninterface PluginEntry {\n scope: string;\n installPath: string;\n version: string;\n installedAt: string;\n lastUpdated: string;\n}\n\ninterface InstalledPlugins {\n version: number;\n plugins: Record<string, PluginEntry[]>;\n}\n\nfunction installedPluginsPath(): string {\n return join(homedir(), '.claude', 'plugins', 'installed_plugins.json');\n}\n\nexport function resolveInstalledPlugin(name: string): string | null {\n let data: InstalledPlugins;\n try {\n data = JSON.parse(readFileSync(installedPluginsPath(), 'utf-8'));\n } catch {\n return null;\n }\n\n const entries = data.plugins?.[name];\n if (!entries || entries.length === 0) return null;\n\n // Prefer user-scoped entry\n const userEntry = entries.find(e => e.scope === 'user');\n return (userEntry ?? entries[0])!.installPath;\n}\n\nexport function resolveRequiredPluginDirs(cwd: string): string[] {\n const config = loadConfig(cwd);\n const required = config.requiredPlugins;\n if (!required || required.length === 0) return [];\n\n const dirs: string[] = [];\n for (const plugin of required) {\n const key = `${plugin.name}@${plugin.marketplace}`;\n const path = resolveInstalledPlugin(key);\n if (path) {\n dirs.push(path);\n } else {\n console.log(`[sisyphus] Warning: required plugin ${key} not installed — skipping`);\n }\n }\n return dirs;\n}\n"],"mappings":";;;;;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AAgBrB,SAAS,uBAA+B;AACtC,SAAO,KAAK,QAAQ,GAAG,WAAW,WAAW,wBAAwB;AACvE;AAEO,SAAS,uBAAuB,MAA6B;AAClE,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,qBAAqB,GAAG,OAAO,CAAC;AAAA,EACjE,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,KAAK,UAAU,IAAI;AACnC,MAAI,CAAC,WAAW,QAAQ,WAAW,EAAG,QAAO;AAG7C,QAAM,YAAY,QAAQ,KAAK,OAAK,EAAE,UAAU,MAAM;AACtD,UAAQ,aAAa,QAAQ,CAAC,GAAI;AACpC;AAEO,SAAS,0BAA0B,KAAuB;AAC/D,QAAM,SAAS,WAAW,GAAG;AAC7B,QAAM,WAAW,OAAO;AACxB,MAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO,CAAC;AAEhD,QAAM,OAAiB,CAAC;AACxB,aAAW,UAAU,UAAU;AAC7B,UAAM,MAAM,GAAG,OAAO,IAAI,IAAI,OAAO,WAAW;AAChD,UAAM,OAAO,uBAAuB,GAAG;AACvC,QAAI,MAAM;AACR,WAAK,KAAK,IAAI;AAAA,IAChB,OAAO;AACL,cAAQ,IAAI,uCAAuC,GAAG,gCAA2B;AAAA,IACnF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
package/dist/cli.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ resolveInstalledPlugin
4
+ } from "./chunk-UIVQXCWB.js";
2
5
  import {
3
6
  buildCompanionContext,
4
7
  computeActiveTimeMs,
@@ -7,8 +10,9 @@ import {
7
10
  statusColor
8
11
  } from "./chunk-HQZOAX6D.js";
9
12
  import {
13
+ loadConfig,
10
14
  shellQuote
11
- } from "./chunk-6G226ZK7.js";
15
+ } from "./chunk-IF55HPWX.js";
12
16
  import {
13
17
  cycleLogPath,
14
18
  daemonLogPath,
@@ -26,10 +30,10 @@ import { dirname as dirname4, join as join8 } from "path";
26
30
  import { fileURLToPath as fileURLToPath4 } from "url";
27
31
 
28
32
  // src/cli/commands/start.ts
29
- import { execSync as execSync5 } from "child_process";
33
+ import { execSync as execSync6 } from "child_process";
30
34
 
31
35
  // src/cli/install.ts
32
- import { execSync as execSync2 } from "child_process";
36
+ import { execSync as execSync3 } from "child_process";
33
37
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
34
38
  import { connect } from "net";
35
39
  import { homedir as homedir2 } from "os";
@@ -256,6 +260,49 @@ function removeTmuxKeybind() {
256
260
  }
257
261
  }
258
262
 
263
+ // src/cli/plugins.ts
264
+ import { execSync as execSync2 } from "child_process";
265
+ function exec(cmd) {
266
+ try {
267
+ return execSync2(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
268
+ } catch {
269
+ return "";
270
+ }
271
+ }
272
+ function isMarketplaceInstalled(marketplace) {
273
+ const output = exec("claude plugins marketplace list");
274
+ return output.includes(marketplace);
275
+ }
276
+ function installMarketplace(marketplace) {
277
+ console.log(`Adding marketplace: ${marketplace}`);
278
+ execSync2(`claude plugins marketplace add CaptainCrouton89/${marketplace}`, { stdio: "inherit" });
279
+ }
280
+ function installPlugin(key) {
281
+ console.log(`Installing plugin: ${key}`);
282
+ execSync2(`claude plugins install ${key} --scope user`, { stdio: "inherit" });
283
+ }
284
+ async function ensureRequiredPlugins(cwd) {
285
+ const config = loadConfig(cwd);
286
+ const required = config.requiredPlugins;
287
+ if (!required || required.length === 0) return;
288
+ for (const plugin of required) {
289
+ const key = `${plugin.name}@${plugin.marketplace}`;
290
+ const existing = resolveInstalledPlugin(key);
291
+ if (existing) continue;
292
+ console.log(`Required plugin ${key} not found \u2014 installing...`);
293
+ if (!isMarketplaceInstalled(plugin.marketplace)) {
294
+ installMarketplace(plugin.marketplace);
295
+ }
296
+ installPlugin(key);
297
+ const verified = resolveInstalledPlugin(key);
298
+ if (verified) {
299
+ console.log(`Installed ${key} \u2192 ${verified}`);
300
+ } else {
301
+ console.warn(`Warning: failed to verify ${key} installation`);
302
+ }
303
+ }
304
+ }
305
+
259
306
  // src/cli/install.ts
260
307
  var PLIST_LABEL = "com.sisyphus.daemon";
261
308
  var PLIST_FILENAME = `${PLIST_LABEL}.plist`;
@@ -306,8 +353,9 @@ async function ensureDaemonInstalled() {
306
353
  mkdirSync2(launchAgentDir(), { recursive: true });
307
354
  const plist = generatePlist(nodePath, daemonPath, logPath);
308
355
  writeFileSync2(plistPath(), plist, "utf8");
309
- execSync2(`launchctl load -w ${plistPath()}`);
356
+ execSync3(`launchctl load -w ${plistPath()}`);
310
357
  const keybindResult = setupTmuxKeybind();
358
+ await ensureRequiredPlugins(process.cwd());
311
359
  printGettingStarted(keybindResult);
312
360
  }
313
361
  await waitForDaemon();
@@ -320,7 +368,7 @@ async function uninstallDaemon(purge) {
320
368
  const plist = plistPath();
321
369
  if (existsSync2(plist)) {
322
370
  try {
323
- execSync2(`launchctl unload -w ${plist}`, { stdio: "pipe" });
371
+ execSync3(`launchctl unload -w ${plist}`, { stdio: "pipe" });
324
372
  } catch {
325
373
  }
326
374
  unlinkSync2(plist);
@@ -467,10 +515,10 @@ async function sendRequest(request) {
467
515
  }
468
516
 
469
517
  // src/cli/tmux.ts
470
- import { execSync as execSync3 } from "child_process";
518
+ import { execSync as execSync4 } from "child_process";
471
519
  function isTmuxInstalled() {
472
520
  try {
473
- execSync3("which tmux", { stdio: "pipe" });
521
+ execSync4("which tmux", { stdio: "pipe" });
474
522
  return true;
475
523
  } catch {
476
524
  return false;
@@ -483,25 +531,25 @@ function assertTmux() {
483
531
  }
484
532
  function getTmuxSession() {
485
533
  assertTmux();
486
- return execSync3('tmux display-message -p "#{session_name}"', { encoding: "utf8" }).trim();
534
+ return execSync4('tmux display-message -p "#{session_name}"', { encoding: "utf8" }).trim();
487
535
  }
488
536
 
489
537
  // src/cli/commands/dashboard.ts
490
538
  import { join as join3 } from "path";
491
- import { execSync as execSync4 } from "child_process";
539
+ import { execSync as execSync5 } from "child_process";
492
540
  function openDashboardWindow(tmuxSession, cwd) {
493
541
  try {
494
- const storedId = execSync4(
542
+ const storedId = execSync5(
495
543
  `tmux show-option -t ${shellQuote(tmuxSession)} -v @sisyphus_dashboard`,
496
544
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
497
545
  ).trim();
498
546
  if (storedId) {
499
547
  try {
500
- execSync4(
548
+ execSync5(
501
549
  `tmux display-message -t ${shellQuote(storedId)} -p "#{window_id}"`,
502
550
  { stdio: "pipe" }
503
551
  );
504
- execSync4(`tmux select-window -t ${shellQuote(storedId)}`, { stdio: "pipe" });
552
+ execSync5(`tmux select-window -t ${shellQuote(storedId)}`, { stdio: "pipe" });
505
553
  return false;
506
554
  } catch {
507
555
  }
@@ -509,15 +557,15 @@ function openDashboardWindow(tmuxSession, cwd) {
509
557
  } catch {
510
558
  }
511
559
  const tuiPath = join3(import.meta.dirname, "tui.js");
512
- const windowId = execSync4(
560
+ const windowId = execSync5(
513
561
  `tmux new-window -n "sisyphus-dashboard" -c ${shellQuote(cwd)} -P -F "#{window_id}"`,
514
562
  { encoding: "utf-8" }
515
563
  ).trim();
516
564
  const cmd = `node ${shellQuote(tuiPath)} --cwd ${shellQuote(cwd)}; exit`;
517
- execSync4(
565
+ execSync5(
518
566
  `tmux send-keys -t ${shellQuote(windowId)} ${shellQuote(cmd)} Enter`
519
567
  );
520
- execSync4(
568
+ execSync5(
521
569
  `tmux set-option -t ${shellQuote(tmuxSession)} @sisyphus_dashboard ${shellQuote(windowId)}`,
522
570
  { stdio: "pipe" }
523
571
  );
@@ -527,7 +575,7 @@ function registerDashboard(program2) {
527
575
  program2.command("dashboard").description("Launch the TUI dashboard for monitoring and managing sessions").action(async () => {
528
576
  assertTmux();
529
577
  const tuiPath = join3(import.meta.dirname, "tui.js");
530
- execSync4(`node ${shellQuote(tuiPath)} --cwd ${shellQuote(process.cwd())}`, {
578
+ execSync5(`node ${shellQuote(tuiPath)} --cwd ${shellQuote(process.cwd())}`, {
531
579
  stdio: "inherit"
532
580
  });
533
581
  });
@@ -558,7 +606,7 @@ function registerStart(program2) {
558
606
  const tmuxSessionName = response.data?.tmuxSessionName;
559
607
  if (process.env["TMUX"]) {
560
608
  try {
561
- execSync5(`tmux set-option @sisyphus_cwd ${shellQuote(cwd)}`, { stdio: "ignore" });
609
+ execSync6(`tmux set-option @sisyphus_cwd ${shellQuote(cwd)}`, { stdio: "ignore" });
562
610
  } catch {
563
611
  }
564
612
  try {
@@ -750,7 +798,7 @@ function registerContinue(program2) {
750
798
  }
751
799
 
752
800
  // src/cli/commands/status.ts
753
- import { execSync as execSync6 } from "child_process";
801
+ import { execSync as execSync7 } from "child_process";
754
802
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
755
803
  var COLOR_CODES = {
756
804
  green: "\x1B[32m",
@@ -857,7 +905,7 @@ function readCycleLog(cwd, sessionId, cycle) {
857
905
  }
858
906
  function capturePaneOutput(paneId, lines = 50) {
859
907
  try {
860
- return execSync6(
908
+ return execSync7(
861
909
  `tmux capture-pane -t "${paneId}" -p -S -${lines}`,
862
910
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
863
911
  ).trimEnd();
@@ -1246,11 +1294,11 @@ function registerSetupKeybind(program2) {
1246
1294
  }
1247
1295
 
1248
1296
  // src/cli/commands/doctor.ts
1249
- import { execSync as execSync8 } from "child_process";
1297
+ import { execSync as execSync9 } from "child_process";
1250
1298
  import { existsSync as existsSync6, statSync } from "fs";
1251
1299
 
1252
1300
  // src/cli/onboard.ts
1253
- import { execSync as execSync7 } from "child_process";
1301
+ import { execSync as execSync8 } from "child_process";
1254
1302
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
1255
1303
  import { homedir as homedir3 } from "os";
1256
1304
  import { dirname as dirname2, join as join5 } from "path";
@@ -1262,7 +1310,7 @@ function detectTerminal() {
1262
1310
  }
1263
1311
  function isTmuxAvailable() {
1264
1312
  try {
1265
- execSync7("which tmux", { stdio: "pipe" });
1313
+ execSync8("which tmux", { stdio: "pipe" });
1266
1314
  return true;
1267
1315
  } catch {
1268
1316
  return false;
@@ -1270,7 +1318,7 @@ function isTmuxAvailable() {
1270
1318
  }
1271
1319
  function isBrewAvailable() {
1272
1320
  try {
1273
- execSync7("which brew", { stdio: "pipe" });
1321
+ execSync8("which brew", { stdio: "pipe" });
1274
1322
  return true;
1275
1323
  } catch {
1276
1324
  return false;
@@ -1280,7 +1328,7 @@ function tryAutoInstallTmux() {
1280
1328
  if (!isBrewAvailable()) return false;
1281
1329
  try {
1282
1330
  console.log(" Installing tmux via Homebrew...");
1283
- execSync7("brew install tmux", { stdio: "inherit" });
1331
+ execSync8("brew install tmux", { stdio: "inherit" });
1284
1332
  return isTmuxAvailable();
1285
1333
  } catch {
1286
1334
  return false;
@@ -1295,7 +1343,7 @@ function checkItermOptionKey() {
1295
1343
  return { checked: false, allCorrect: false, incorrectProfiles: [] };
1296
1344
  }
1297
1345
  try {
1298
- const json = execSync7(
1346
+ const json = execSync8(
1299
1347
  `plutil -extract "New Bookmarks" json -o - "${plistPath2}"`,
1300
1348
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
1301
1349
  );
@@ -1386,7 +1434,7 @@ function writeTmuxDefaults() {
1386
1434
  }
1387
1435
  function isNvimAvailable() {
1388
1436
  try {
1389
- execSync7("which nvim", { stdio: "pipe" });
1437
+ execSync8("which nvim", { stdio: "pipe" });
1390
1438
  return true;
1391
1439
  } catch {
1392
1440
  return false;
@@ -1394,7 +1442,7 @@ function isNvimAvailable() {
1394
1442
  }
1395
1443
  function getNvimVersion() {
1396
1444
  try {
1397
- return execSync7("nvim --version", { encoding: "utf-8", stdio: "pipe" }).split("\n")[0]?.replace("NVIM ", "") || "unknown";
1445
+ return execSync8("nvim --version", { encoding: "utf-8", stdio: "pipe" }).split("\n")[0]?.replace("NVIM ", "") || "unknown";
1398
1446
  } catch {
1399
1447
  return "unknown";
1400
1448
  }
@@ -1411,7 +1459,7 @@ function tryAutoInstallNvim() {
1411
1459
  }
1412
1460
  try {
1413
1461
  console.log(" Installing neovim via Homebrew...");
1414
- execSync7("brew install neovim", { stdio: "inherit" });
1462
+ execSync8("brew install neovim", { stdio: "inherit" });
1415
1463
  } catch {
1416
1464
  return { installed: false, autoInstalled: false, version: "", lazyVimInstalled: false };
1417
1465
  }
@@ -1423,10 +1471,10 @@ function tryAutoInstallNvim() {
1423
1471
  if (!existsSync5(nvimConfigDir)) {
1424
1472
  try {
1425
1473
  console.log(" Cloning LazyVim starter config...");
1426
- execSync7(`git clone https://github.com/LazyVim/starter ${nvimConfigDir}`, { stdio: "inherit" });
1474
+ execSync8(`git clone https://github.com/LazyVim/starter ${nvimConfigDir}`, { stdio: "inherit" });
1427
1475
  const gitDir = join5(nvimConfigDir, ".git");
1428
1476
  if (existsSync5(gitDir)) {
1429
- execSync7(`rm -rf "${gitDir}"`, { stdio: "pipe" });
1477
+ execSync8(`rm -rf "${gitDir}"`, { stdio: "pipe" });
1430
1478
  }
1431
1479
  lazyVimInstalled = true;
1432
1480
  } catch {
@@ -1494,7 +1542,7 @@ function checkNodeVersion() {
1494
1542
  }
1495
1543
  function checkClaudeCli() {
1496
1544
  try {
1497
- execSync8("which claude", { stdio: "pipe" });
1545
+ execSync9("which claude", { stdio: "pipe" });
1498
1546
  return { name: "Claude CLI", status: "ok", detail: "Found on PATH" };
1499
1547
  } catch {
1500
1548
  return {
@@ -1507,7 +1555,7 @@ function checkClaudeCli() {
1507
1555
  }
1508
1556
  function checkGit() {
1509
1557
  try {
1510
- const version = execSync8("git --version", { encoding: "utf-8", stdio: "pipe" }).trim();
1558
+ const version = execSync9("git --version", { encoding: "utf-8", stdio: "pipe" }).trim();
1511
1559
  return { name: "git", status: "ok", detail: version };
1512
1560
  } catch {
1513
1561
  return { name: "git", status: "fail", detail: "Not found on PATH", fix: "Install git: https://git-scm.com/downloads" };
@@ -1515,7 +1563,7 @@ function checkGit() {
1515
1563
  }
1516
1564
  function checkTmuxVersion() {
1517
1565
  try {
1518
- const version = execSync8("tmux -V", { encoding: "utf-8", stdio: "pipe" }).trim();
1566
+ const version = execSync9("tmux -V", { encoding: "utf-8", stdio: "pipe" }).trim();
1519
1567
  const match = version.match(/(\d+\.\d+)/);
1520
1568
  if (!match) return { name: "tmux version", status: "warn", detail: `Could not parse version: ${version}` };
1521
1569
  const ver = parseFloat(match[1]);
@@ -1564,7 +1612,7 @@ function checkDaemonRunning() {
1564
1612
  }
1565
1613
  try {
1566
1614
  const sock = socketPath();
1567
- execSync8(`test -S "${sock}"`, { stdio: "pipe" });
1615
+ execSync9(`test -S "${sock}"`, { stdio: "pipe" });
1568
1616
  return { name: "Daemon process", status: "ok", detail: `Socket at ${sock}` };
1569
1617
  } catch {
1570
1618
  return {
@@ -1577,13 +1625,13 @@ function checkDaemonRunning() {
1577
1625
  }
1578
1626
  function checkTmux() {
1579
1627
  try {
1580
- execSync8("which tmux", { stdio: "pipe" });
1628
+ execSync9("which tmux", { stdio: "pipe" });
1581
1629
  } catch {
1582
1630
  const installHint = process.platform === "darwin" ? "brew install tmux" : "apt install tmux (Debian/Ubuntu) or your package manager";
1583
1631
  return { name: "tmux", status: "fail", detail: "Not found on PATH", fix: installHint };
1584
1632
  }
1585
1633
  try {
1586
- execSync8("tmux list-sessions", { stdio: "pipe" });
1634
+ execSync9("tmux list-sessions", { stdio: "pipe" });
1587
1635
  return { name: "tmux", status: "ok", detail: "Running" };
1588
1636
  } catch {
1589
1637
  return { name: "tmux", status: "warn", detail: "Installed but no server running" };
@@ -1696,7 +1744,7 @@ function checkNvim() {
1696
1744
  return { name: "nvim", status: "warn", detail: "Not installed", fix };
1697
1745
  }
1698
1746
  try {
1699
- const version = execSync8("nvim --version", { encoding: "utf-8", stdio: "pipe" }).split("\n")[0]?.replace("NVIM ", "");
1747
+ const version = execSync9("nvim --version", { encoding: "utf-8", stdio: "pipe" }).split("\n")[0]?.replace("NVIM ", "");
1700
1748
  return { name: "nvim", status: "ok", detail: version ?? "installed" };
1701
1749
  } catch {
1702
1750
  return { name: "nvim", status: "ok", detail: "installed" };
@@ -1750,7 +1798,7 @@ function registerCompanionContext(program2) {
1750
1798
  }
1751
1799
 
1752
1800
  // src/cli/commands/getting-started.ts
1753
- import { execSync as execSync9 } from "child_process";
1801
+ import { execSync as execSync10 } from "child_process";
1754
1802
  import { dirname as dirname3, join as join6 } from "path";
1755
1803
  import { fileURLToPath as fileURLToPath3 } from "url";
1756
1804
  function templatePath(name) {
@@ -2240,11 +2288,11 @@ function printStep5() {
2240
2288
  let recentCommits = "";
2241
2289
  let topLevelFiles = "";
2242
2290
  try {
2243
- recentCommits = execSync9("git log --oneline -15 2>/dev/null", { encoding: "utf-8" }).trim();
2291
+ recentCommits = execSync10("git log --oneline -15 2>/dev/null", { encoding: "utf-8" }).trim();
2244
2292
  } catch {
2245
2293
  }
2246
2294
  try {
2247
- topLevelFiles = execSync9("ls -1 2>/dev/null", { encoding: "utf-8" }).trim();
2295
+ topLevelFiles = execSync10("ls -1 2>/dev/null", { encoding: "utf-8" }).trim();
2248
2296
  } catch {
2249
2297
  }
2250
2298
  console.log(`
@@ -2740,10 +2788,10 @@ function registerInit(program2) {
2740
2788
  }
2741
2789
 
2742
2790
  // src/cli/commands/setup.ts
2743
- import { execSync as execSync10 } from "child_process";
2791
+ import { execSync as execSync11 } from "child_process";
2744
2792
  function getTmuxVersion() {
2745
2793
  try {
2746
- return execSync10("tmux -V", { encoding: "utf-8", stdio: "pipe" }).trim();
2794
+ return execSync11("tmux -V", { encoding: "utf-8", stdio: "pipe" }).trim();
2747
2795
  } catch {
2748
2796
  return "installed";
2749
2797
  }