sisyphi 1.1.18 → 1.1.19

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.
Files changed (231) hide show
  1. package/README.md +195 -75
  2. package/dist/chunk-36VJ7ZBD.js +1898 -0
  3. package/dist/chunk-36VJ7ZBD.js.map +1 -0
  4. package/dist/{chunk-C2XKXERJ.js → chunk-M6Z3KHOH.js} +159 -46
  5. package/dist/chunk-M6Z3KHOH.js.map +1 -0
  6. package/dist/chunk-O4ZHSQ5R.js +544 -0
  7. package/dist/chunk-O4ZHSQ5R.js.map +1 -0
  8. package/dist/chunk-P2HHTIPM.js +478 -0
  9. package/dist/chunk-P2HHTIPM.js.map +1 -0
  10. package/dist/{chunk-TMBAVPHH.js → chunk-PNDCVKBN.js} +73 -1
  11. package/dist/chunk-PNDCVKBN.js.map +1 -0
  12. package/dist/chunk-SVGIQ2G4.js +1076 -0
  13. package/dist/chunk-SVGIQ2G4.js.map +1 -0
  14. package/dist/cli.js +4405 -892
  15. package/dist/cli.js.map +1 -1
  16. package/dist/daemon.js +4340 -1990
  17. package/dist/daemon.js.map +1 -1
  18. package/dist/{paths-XRDEEJ5R.js → paths-JXFLR5BN.js} +38 -2
  19. package/dist/single-ask-6G4BIVY2.js +132 -0
  20. package/dist/single-ask-6G4BIVY2.js.map +1 -0
  21. package/dist/templates/CLAUDE.md +1 -56
  22. package/dist/templates/agent-plugin/agents/CLAUDE.md +2 -65
  23. package/dist/templates/agent-plugin/agents/debug.md +43 -6
  24. package/dist/templates/agent-plugin/agents/debug.settings.json +57 -0
  25. package/dist/templates/agent-plugin/agents/explore.md +28 -1
  26. package/dist/templates/agent-plugin/agents/explore.settings.json +57 -0
  27. package/dist/templates/agent-plugin/agents/implementor.md +94 -0
  28. package/dist/templates/agent-plugin/agents/implementor.settings.json +57 -0
  29. package/dist/templates/agent-plugin/agents/operator.md +43 -1
  30. package/dist/templates/agent-plugin/agents/operator.settings.json +57 -0
  31. package/dist/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
  32. package/dist/templates/agent-plugin/agents/plan.md +176 -86
  33. package/dist/templates/agent-plugin/agents/plan.settings.json +57 -0
  34. package/dist/templates/agent-plugin/agents/problem/adversarial.md +26 -0
  35. package/dist/templates/agent-plugin/agents/problem/contrarian.md +26 -0
  36. package/dist/templates/agent-plugin/agents/problem/first-principles.md +26 -0
  37. package/dist/templates/agent-plugin/agents/problem/precedent.md +25 -0
  38. package/dist/templates/agent-plugin/agents/problem/simplifier.md +26 -0
  39. package/dist/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
  40. package/dist/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
  41. package/dist/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
  42. package/dist/templates/agent-plugin/agents/problem.md +334 -79
  43. package/dist/templates/agent-plugin/agents/problem.settings.json +57 -0
  44. package/dist/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
  45. package/dist/templates/agent-plugin/agents/research-lead/critic.md +61 -0
  46. package/dist/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
  47. package/dist/templates/agent-plugin/agents/research-lead.md +184 -0
  48. package/dist/templates/agent-plugin/agents/research-lead.settings.json +57 -0
  49. package/dist/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
  50. package/dist/templates/agent-plugin/agents/review/compliance.md +14 -3
  51. package/dist/templates/agent-plugin/agents/review/efficiency.md +15 -4
  52. package/dist/templates/agent-plugin/agents/review/quality.md +20 -6
  53. package/dist/templates/agent-plugin/agents/review/reuse.md +17 -5
  54. package/dist/templates/agent-plugin/agents/review/security.md +10 -3
  55. package/dist/templates/agent-plugin/agents/review/tests.md +58 -0
  56. package/dist/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
  57. package/dist/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
  58. package/dist/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
  59. package/dist/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
  60. package/dist/templates/agent-plugin/agents/review-plan/security.md +5 -2
  61. package/dist/templates/agent-plugin/agents/review-plan.md +52 -5
  62. package/dist/templates/agent-plugin/agents/review-plan.settings.json +57 -0
  63. package/dist/templates/agent-plugin/agents/review.md +89 -16
  64. package/dist/templates/agent-plugin/agents/review.settings.json +57 -0
  65. package/dist/templates/agent-plugin/agents/spec/engineer.md +175 -0
  66. package/dist/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
  67. package/dist/templates/agent-plugin/agents/spec.md +444 -0
  68. package/dist/templates/agent-plugin/agents/spec.settings.json +57 -0
  69. package/dist/templates/agent-plugin/agents/test-spec.md +58 -2
  70. package/dist/templates/agent-plugin/agents/test-spec.settings.json +57 -0
  71. package/dist/templates/agent-plugin/hooks/CLAUDE.md +9 -57
  72. package/dist/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
  73. package/dist/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
  74. package/dist/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
  75. package/dist/templates/agent-plugin/hooks/plan-validate.sh +97 -0
  76. package/dist/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
  77. package/dist/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
  78. package/dist/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
  79. package/dist/templates/agent-plugin/hooks/require-submit.sh +51 -42
  80. package/dist/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
  81. package/dist/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
  82. package/dist/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
  83. package/dist/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
  84. package/dist/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
  85. package/dist/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
  86. package/dist/templates/agent-suffix.md +7 -4
  87. package/dist/templates/baleia.lua +42 -0
  88. package/dist/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
  89. package/dist/templates/dashboard-claude.md +7 -3
  90. package/dist/templates/orchestrator-base.md +89 -52
  91. package/dist/templates/orchestrator-completion.md +47 -24
  92. package/dist/templates/orchestrator-discovery.md +183 -0
  93. package/dist/templates/orchestrator-impl.md +47 -18
  94. package/dist/templates/orchestrator-planning.md +109 -20
  95. package/dist/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
  96. package/dist/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
  97. package/dist/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
  98. package/dist/templates/orchestrator-plugin/hooks/hooks.json +0 -10
  99. package/dist/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
  100. package/dist/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
  101. package/dist/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
  102. package/dist/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
  103. package/dist/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
  104. package/dist/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
  105. package/dist/templates/orchestrator-settings.json +55 -0
  106. package/dist/templates/orchestrator-validation.md +17 -14
  107. package/dist/templates/sisyphus-init.lua +30 -0
  108. package/dist/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
  109. package/dist/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
  110. package/dist/templates/termrender-haiku-system.md +82 -0
  111. package/dist/templates/whip-animation.sh +345 -0
  112. package/dist/tui.js +3242 -2189
  113. package/dist/tui.js.map +1 -1
  114. package/native/SisyphusNotify/main.swift +15 -5
  115. package/package.json +8 -6
  116. package/templates/CLAUDE.md +1 -56
  117. package/templates/agent-plugin/agents/CLAUDE.md +2 -65
  118. package/templates/agent-plugin/agents/debug.md +43 -6
  119. package/templates/agent-plugin/agents/debug.settings.json +57 -0
  120. package/templates/agent-plugin/agents/explore.md +28 -1
  121. package/templates/agent-plugin/agents/explore.settings.json +57 -0
  122. package/templates/agent-plugin/agents/implementor.md +94 -0
  123. package/templates/agent-plugin/agents/implementor.settings.json +57 -0
  124. package/templates/agent-plugin/agents/operator.md +43 -1
  125. package/templates/agent-plugin/agents/operator.settings.json +57 -0
  126. package/templates/agent-plugin/agents/plan/sub-planner.md +75 -0
  127. package/templates/agent-plugin/agents/plan.md +176 -86
  128. package/templates/agent-plugin/agents/plan.settings.json +57 -0
  129. package/templates/agent-plugin/agents/problem/adversarial.md +26 -0
  130. package/templates/agent-plugin/agents/problem/contrarian.md +26 -0
  131. package/templates/agent-plugin/agents/problem/first-principles.md +26 -0
  132. package/templates/agent-plugin/agents/problem/precedent.md +25 -0
  133. package/templates/agent-plugin/agents/problem/simplifier.md +26 -0
  134. package/templates/agent-plugin/agents/problem/systems-thinker.md +26 -0
  135. package/templates/agent-plugin/agents/problem/time-traveler.md +26 -0
  136. package/templates/agent-plugin/agents/problem/user-empathy.md +26 -0
  137. package/templates/agent-plugin/agents/problem.md +334 -79
  138. package/templates/agent-plugin/agents/problem.settings.json +57 -0
  139. package/templates/agent-plugin/agents/research-lead/CLAUDE.md +26 -0
  140. package/templates/agent-plugin/agents/research-lead/critic.md +61 -0
  141. package/templates/agent-plugin/agents/research-lead/researcher.md +60 -0
  142. package/templates/agent-plugin/agents/research-lead.md +184 -0
  143. package/templates/agent-plugin/agents/research-lead.settings.json +57 -0
  144. package/templates/agent-plugin/agents/review/CLAUDE.md +3 -29
  145. package/templates/agent-plugin/agents/review/compliance.md +14 -3
  146. package/templates/agent-plugin/agents/review/efficiency.md +15 -4
  147. package/templates/agent-plugin/agents/review/quality.md +20 -6
  148. package/templates/agent-plugin/agents/review/reuse.md +17 -5
  149. package/templates/agent-plugin/agents/review/security.md +10 -3
  150. package/templates/agent-plugin/agents/review/tests.md +58 -0
  151. package/templates/agent-plugin/agents/review-plan/CLAUDE.md +28 -0
  152. package/templates/agent-plugin/agents/review-plan/code-smells.md +4 -2
  153. package/templates/agent-plugin/agents/review-plan/pattern-consistency.md +4 -2
  154. package/templates/agent-plugin/agents/review-plan/requirements-coverage.md +3 -1
  155. package/templates/agent-plugin/agents/review-plan/security.md +5 -2
  156. package/templates/agent-plugin/agents/review-plan.md +52 -5
  157. package/templates/agent-plugin/agents/review-plan.settings.json +57 -0
  158. package/templates/agent-plugin/agents/review.md +89 -16
  159. package/templates/agent-plugin/agents/review.settings.json +57 -0
  160. package/templates/agent-plugin/agents/spec/engineer.md +175 -0
  161. package/templates/agent-plugin/agents/spec/requirements-writer.md +149 -0
  162. package/templates/agent-plugin/agents/spec.md +444 -0
  163. package/templates/agent-plugin/agents/spec.settings.json +57 -0
  164. package/templates/agent-plugin/agents/test-spec.md +58 -2
  165. package/templates/agent-plugin/agents/test-spec.settings.json +57 -0
  166. package/templates/agent-plugin/hooks/CLAUDE.md +9 -57
  167. package/templates/agent-plugin/hooks/ask-background-guard.sh +57 -0
  168. package/templates/agent-plugin/hooks/intercept-send-message.sh +1 -1
  169. package/templates/agent-plugin/hooks/plan-user-prompt.sh +8 -7
  170. package/templates/agent-plugin/hooks/plan-validate.sh +97 -0
  171. package/templates/agent-plugin/hooks/plan-write-path.sh +55 -0
  172. package/templates/agent-plugin/hooks/problem-user-prompt.sh +26 -0
  173. package/templates/agent-plugin/hooks/register-bg-task.sh +37 -0
  174. package/templates/agent-plugin/hooks/require-submit.sh +51 -42
  175. package/templates/agent-plugin/hooks/review-user-prompt.sh +6 -2
  176. package/templates/agent-plugin/hooks/spec-user-prompt.sh +43 -0
  177. package/templates/agent-plugin/skills/humanloop/SKILL.md +147 -0
  178. package/templates/agent-plugin/skills/perspective-fanout/SKILL.md +115 -0
  179. package/templates/agent-plugin/skills/problem-document/SKILL.md +105 -0
  180. package/templates/agent-plugin/skills/problem-plateau-breakers/SKILL.md +83 -0
  181. package/templates/agent-suffix.md +7 -4
  182. package/templates/baleia.lua +42 -0
  183. package/templates/companion-plugin/hooks/user-prompt-context.sh +1 -1
  184. package/templates/dashboard-claude.md +7 -3
  185. package/templates/orchestrator-base.md +89 -52
  186. package/templates/orchestrator-completion.md +47 -24
  187. package/templates/orchestrator-discovery.md +183 -0
  188. package/templates/orchestrator-impl.md +47 -18
  189. package/templates/orchestrator-planning.md +109 -20
  190. package/templates/orchestrator-plugin/commands/sisyphus/scratch.md +19 -0
  191. package/templates/orchestrator-plugin/commands/sisyphus/spec.md +11 -0
  192. package/templates/orchestrator-plugin/commands/sisyphus/strategize.md +5 -5
  193. package/templates/orchestrator-plugin/hooks/hooks.json +0 -10
  194. package/templates/orchestrator-plugin/skills/humanloop/SKILL.md +149 -0
  195. package/templates/orchestrator-plugin/skills/orchestration/CLAUDE.md +1 -0
  196. package/templates/orchestrator-plugin/skills/orchestration/SKILL.md +2 -1
  197. package/templates/orchestrator-plugin/skills/orchestration/strategy.md +160 -0
  198. package/templates/orchestrator-plugin/skills/orchestration/task-patterns.md +26 -28
  199. package/templates/orchestrator-plugin/skills/orchestration/workflow-examples.md +133 -25
  200. package/templates/orchestrator-settings.json +55 -0
  201. package/templates/orchestrator-validation.md +17 -14
  202. package/templates/sisyphus-init.lua +30 -0
  203. package/templates/sisyphus-tmux-plugin/hooks/hooks.json +54 -0
  204. package/templates/sisyphus-tmux-plugin/hooks/tmux-state.sh +19 -0
  205. package/templates/termrender-haiku-system.md +82 -0
  206. package/templates/whip-animation.sh +345 -0
  207. package/dist/chunk-22ZGZTGY.js +0 -67
  208. package/dist/chunk-22ZGZTGY.js.map +0 -1
  209. package/dist/chunk-6PJVJEYQ.js +0 -46
  210. package/dist/chunk-6PJVJEYQ.js.map +0 -1
  211. package/dist/chunk-C2XKXERJ.js.map +0 -1
  212. package/dist/chunk-TMBAVPHH.js.map +0 -1
  213. package/dist/chunk-V36NXMHP.js +0 -299
  214. package/dist/chunk-V36NXMHP.js.map +0 -1
  215. package/dist/templates/agent-plugin/agents/design.md +0 -134
  216. package/dist/templates/agent-plugin/agents/requirements.md +0 -138
  217. package/dist/templates/begin.md +0 -22
  218. package/dist/templates/nvim-tutorial.txt +0 -68
  219. package/dist/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
  220. package/dist/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
  221. package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
  222. package/dist/templates/orchestrator-strategy.md +0 -238
  223. package/templates/agent-plugin/agents/design.md +0 -134
  224. package/templates/agent-plugin/agents/requirements.md +0 -138
  225. package/templates/begin.md +0 -22
  226. package/templates/nvim-tutorial.txt +0 -68
  227. package/templates/orchestrator-plugin/commands/sisyphus/design.md +0 -13
  228. package/templates/orchestrator-plugin/commands/sisyphus/requirements.md +0 -13
  229. package/templates/orchestrator-plugin/hooks/idle-notify.sh +0 -71
  230. package/templates/orchestrator-strategy.md +0 -238
  231. /package/dist/{paths-XRDEEJ5R.js.map → paths-JXFLR5BN.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/config.ts","../src/daemon/state.ts","../src/daemon/lib/atomic.ts","../src/shared/gitignore.ts","../src/shared/types.ts","../src/daemon/ask-store.ts","../src/daemon/history.ts","../src/daemon/notify.ts","../src/shared/shell.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\nimport type { StatusBarConfig } from './types.js';\n\nexport type EffortLevel = 'low' | 'medium' | 'high' | 'xhigh' | '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 UploadConfig {\n /** Worker base URL, e.g. https://sisyphus-upload-proxy.rhyneer-silas.workers.dev */\n url: string;\n /** Bearer token, format `sisyphus_pat_<43-char-base64url>` */\n token: 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 companionPopup?: boolean;\n requiredPlugins?: RequiredPlugin[];\n statusBar?: StatusBarConfig;\n upload?: UploadConfig;\n}\n\nconst DEFAULT_CONFIG: Config = {\n model: 'claude-opus-4-7[1m]',\n pollIntervalMs: 5000,\n orchestratorEffort: 'xhigh',\n agentEffort: 'medium',\n notifications: {\n enabled: true,\n sound: '/System/Library/Sounds/Hero.aiff',\n },\n companionPopup: true,\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 globalConfig = readJsonFile(globalConfigPath());\n const projectConfig = readJsonFile(projectConfigPath(cwd));\n if (projectConfig.upload !== undefined) {\n console.warn(\n 'ignoring `upload` block from project-local .sisyphus/config.json — only the global config can set upload credentials',\n );\n delete projectConfig.upload;\n }\n const merged: Config = { ...DEFAULT_CONFIG, ...globalConfig, ...projectConfig };\n if (globalConfig.statusBar || projectConfig.statusBar) {\n merged.statusBar = {\n ...merged.statusBar,\n ...globalConfig.statusBar,\n ...projectConfig.statusBar,\n colors: {\n ...merged.statusBar?.colors,\n ...globalConfig.statusBar?.colors,\n ...projectConfig.statusBar?.colors,\n },\n segments: {\n ...merged.statusBar?.segments,\n ...globalConfig.statusBar?.segments,\n ...projectConfig.statusBar?.segments,\n },\n };\n }\n return merged;\n}\n","import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { atomicWrite, withLock } from './lib/atomic.js';\nimport { contextDir, goalPath, initialPromptPath, legacyLogsPath, logsDir, reportsDir, roadmapPath, promptsDir, sessionDir, snapshotDir, snapshotsDir, statePath, strategyPath } from '../shared/paths.js';\nimport { ensureSisyphusGitignore } from '../shared/gitignore.js';\nimport type { Agent, AgentReport, AgentStatus, Message, OrchestratorCycle, Session, SessionStatus } from '../shared/types.js';\nimport { ORCHESTRATOR_ASKED_BY } from '../shared/types.js';\n\nconst ROADMAP_SEED = `---\ndescription: >\n Living document tracking development phases and outstanding work.\n---\n`;\n\nconst CONTEXT_CLAUDE_MD = `# context/\n\nAgents save exploration findings, architectural notes, and reference material here for use across cycles.\n`;\n\nfunction withSessionLock<T>(sessionId: string, fn: () => T): Promise<T> {\n return withLock(sessionId, fn);\n}\n\nexport function createSession(id: string, task: string, cwd: string, context?: string, name?: string, effort?: 'low' | 'medium' | 'high' | 'xhigh'): Session {\n ensureSisyphusGitignore(cwd);\n\n const dir = sessionDir(cwd, id);\n mkdirSync(dir, { recursive: true });\n mkdirSync(contextDir(cwd, id), { recursive: true });\n mkdirSync(promptsDir(cwd, id), { recursive: true });\n\n writeFileSync(roadmapPath(cwd, id), ROADMAP_SEED, 'utf-8');\n mkdirSync(logsDir(cwd, id), { recursive: true });\n writeFileSync(goalPath(cwd, id), task, 'utf-8');\n writeFileSync(initialPromptPath(cwd, id), task, 'utf-8');\n writeFileSync(join(contextDir(cwd, id), 'CLAUDE.md'), CONTEXT_CLAUDE_MD, 'utf-8');\n if (context) {\n writeFileSync(join(contextDir(cwd, id), 'initial-context.md'), context, 'utf-8');\n }\n\n const createdAt = new Date().toISOString();\n const created = new Date(createdAt);\n const session: Session = {\n id,\n ...(name ? { name } : {}),\n task,\n ...(context ? { context } : {}),\n cwd,\n status: 'active',\n createdAt,\n activeMs: 0,\n userBlockedMs: 0,\n agents: [],\n orchestratorCycles: [],\n messages: [],\n startHour: created.getHours(),\n startDayOfWeek: created.getDay(),\n orphaned: false,\n ...(effort ? { effort } : {}),\n };\n\n atomicWrite(statePath(cwd, id), JSON.stringify(session, null, 2));\n return session;\n}\n\nexport function getSession(cwd: string, sessionId: string): Session {\n const content = readFileSync(statePath(cwd, sessionId), 'utf-8');\n const session = JSON.parse(content) as Session;\n // Normalize fields from pre-existing sessions that may lack newer properties\n if (session.activeMs == null) session.activeMs = 0;\n if (session.userBlockedMs == null) session.userBlockedMs = 0;\n for (const agent of session.agents) {\n if (!agent.repo) agent.repo = '.';\n if (agent.activeMs == null) agent.activeMs = 0;\n if (agent.orphaned == null) agent.orphaned = false;\n // pid / pidLstart left undefined when absent — their absence signals \"not yet captured\"\n }\n if (session.orphaned == null) session.orphaned = false;\n // session.effort is intentionally not defaulted here — absence means \"not explicitly set\"\n // and consumers (agent.ts, orchestrator.ts, status.ts) fall back to 'high' at read time.\n // orphanReason is only set alongside orphaned=true; absent on healthy sessions and old state files\n for (const cycle of session.orchestratorCycles) {\n if (cycle.activeMs == null) cycle.activeMs = 0;\n if (cycle.userBlockedMs == null) cycle.userBlockedMs = 0;\n }\n return session;\n}\n\nfunction saveSession(session: Session): void {\n atomicWrite(statePath(session.cwd, session.id), JSON.stringify(session, null, 2));\n}\n\nexport async function addAgent(cwd: string, sessionId: string, agent: Agent): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.agents.push(agent);\n saveSession(session);\n });\n}\n\nexport async function updateAgent(cwd: string, sessionId: string, agentId: string, updates: Partial<Agent>): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n Object.assign(agent, updates);\n saveSession(session);\n });\n}\n\nexport async function markAgentOrphan(\n cwd: string,\n sessionId: string,\n agentId: string,\n opts: { reason: string; status?: AgentStatus; activeMs?: number },\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n agent.orphaned = true;\n agent.status = opts.status !== undefined ? opts.status : 'lost';\n agent.killedReason = opts.reason;\n agent.completedAt = new Date().toISOString();\n if (opts.activeMs !== undefined) agent.activeMs = opts.activeMs;\n delete agent.pid;\n delete agent.pidLstart;\n saveSession(session);\n });\n}\n\nexport async function markSessionOrphan(\n cwd: string,\n sessionId: string,\n opts: { reason: string },\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.orphaned = true;\n session.orphanReason = opts.reason;\n saveSession(session);\n });\n}\n\nexport async function clearSessionOrphan(cwd: string, sessionId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n if (!session.orphaned && session.orphanReason == null) return;\n session.orphaned = false;\n delete session.orphanReason;\n saveSession(session);\n });\n}\n\nexport async function clearAgentPidInfo(\n cwd: string,\n sessionId: string,\n agentId: string,\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) return;\n delete agent.pid;\n delete agent.pidLstart;\n saveSession(session);\n });\n}\n\nexport async function setAgentPid(\n cwd: string,\n sessionId: string,\n agentId: string,\n pid: number,\n pidLstart: string,\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) return;\n agent.pid = pid;\n agent.pidLstart = pidLstart;\n saveSession(session);\n });\n}\n\nexport async function setAgentConsumedInline(cwd: string, sessionId: string, agentId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n if (agent.consumedInline) return;\n agent.consumedInline = true;\n saveSession(session);\n });\n}\n\nexport async function addOrchestratorCycle(cwd: string, sessionId: string, cycle: OrchestratorCycle): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.orchestratorCycles.push(cycle);\n saveSession(session);\n });\n}\n\nexport async function updateSessionStatus(cwd: string, sessionId: string, status: SessionStatus, completionReport?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = status;\n if (completionReport !== undefined) {\n session.completionReport = completionReport;\n }\n saveSession(session);\n });\n}\n\nexport async function appendAgentToLastCycle(cwd: string, sessionId: string, agentId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n cycles[cycles.length - 1]!.agentsSpawned.push(agentId);\n saveSession(session);\n });\n}\n\nexport async function completeSession(cwd: string, sessionId: string, report: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.status = 'completed';\n session.completedAt = new Date().toISOString();\n session.completionReport = report;\n saveSession(session);\n });\n}\n\nexport async function continueSession(cwd: string, sessionId: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n if (session.status !== 'completed') {\n throw new Error(`Session ${sessionId} is not completed (status: ${session.status})`);\n }\n session.status = 'active';\n session.completedAt = undefined;\n session.completionReport = undefined;\n const cycles = session.orchestratorCycles;\n if (cycles.length > 0) {\n cycles[cycles.length - 1]!.completedAt = undefined;\n }\n saveSession(session);\n writeFileSync(roadmapPath(cwd, sessionId), '', 'utf-8');\n });\n}\n\nexport async function appendAgentReport(cwd: string, sessionId: string, agentId: string, entry: AgentReport): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) throw new Error(`Agent ${agentId} not found in session ${sessionId}`);\n agent.reports.push(entry);\n saveSession(session);\n });\n}\n\nexport async function updateReportSummary(\n cwd: string,\n sessionId: string,\n agentId: string,\n filePath: string,\n summary: string,\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const agent = session.agents.slice().reverse().find((a: Agent) => a.id === agentId);\n if (!agent) return;\n const report = agent.reports.find((r) => r.filePath === filePath);\n if (report) {\n report.summary = summary;\n saveSession(session);\n }\n });\n}\n\nexport async function updateSessionName(cwd: string, sessionId: string, name: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.name = name;\n saveSession(session);\n });\n}\n\nexport async function updateSessionTmux(cwd: string, sessionId: string, tmuxSessionName: string, tmuxWindowId: string, tmuxSessionId?: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.tmuxSessionName = tmuxSessionName;\n session.tmuxSessionId = tmuxSessionId;\n session.tmuxWindowId = tmuxWindowId;\n saveSession(session);\n });\n}\n\nexport async function updateSession(cwd: string, sessionId: string, updates: Partial<Session>): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n Object.assign(session, updates);\n saveSession(session);\n });\n}\n\nexport async function drainMessages(cwd: string, sessionId: string, count: number): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n if (!session.messages || count <= 0) return;\n session.messages = session.messages.slice(count);\n saveSession(session);\n });\n}\n\nexport async function appendMessage(cwd: string, sessionId: string, message: Message): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n if (!session.messages) session.messages = [];\n session.messages.push(message);\n saveSession(session);\n });\n}\n\nexport async function updateTask(cwd: string, sessionId: string, task: string): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.task = task;\n saveSession(session);\n writeFileSync(goalPath(cwd, sessionId), task, 'utf-8');\n });\n}\n\nexport async function completeOrchestratorCycle(cwd: string, sessionId: string, nextPrompt?: string, mode?: string, activeMs?: number): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n const cycles = session.orchestratorCycles;\n if (cycles.length === 0) return;\n const cycle = cycles[cycles.length - 1]!;\n if (cycle.completedAt) return;\n cycle.completedAt = new Date().toISOString();\n if (nextPrompt) cycle.nextPrompt = nextPrompt;\n if (mode) cycle.mode = mode;\n if (activeMs != null) cycle.activeMs += activeMs;\n saveSession(session);\n });\n}\n\nexport async function incrementUserBlockedMs(\n cwd: string,\n sessionId: string,\n deltaMs: number,\n askedAt?: string,\n askedBy?: string,\n): Promise<void> {\n if (deltaMs <= 0) return;\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.userBlockedMs = (session.userBlockedMs ?? 0) + deltaMs;\n if (askedAt) {\n const askedAtMs = new Date(askedAt).getTime();\n const cycle = session.orchestratorCycles.find(c => {\n const startMs = new Date(c.timestamp).getTime();\n const endMs = c.completedAt ? new Date(c.completedAt).getTime() : Infinity;\n return startMs <= askedAtMs && askedAtMs < endMs;\n });\n if (cycle) cycle.userBlockedMs = (cycle.userBlockedMs ?? 0) + deltaMs;\n }\n if (askedBy && askedBy !== ORCHESTRATOR_ASKED_BY) {\n const agent = session.agents.slice().reverse().find(a => a.id === askedBy);\n if (agent) agent.userBlockedMs = (agent.userBlockedMs ?? 0) + deltaMs;\n }\n saveSession(session);\n });\n}\n\nexport async function incrementActiveTime(\n cwd: string,\n sessionId: string,\n sessionDelta: number,\n agentDeltas: Map<string, number>,\n cycleDeltas: Map<number, number>,\n): Promise<void> {\n return withSessionLock(sessionId, () => {\n const session = getSession(cwd, sessionId);\n session.activeMs += sessionDelta;\n for (const [agentId, delta] of agentDeltas) {\n const agent = session.agents.slice().reverse().find(a => a.id === agentId);\n if (agent) agent.activeMs += delta;\n }\n for (const [cycleNum, delta] of cycleDeltas) {\n const cycle = session.orchestratorCycles.find(c => c.cycle === cycleNum);\n if (cycle) cycle.activeMs += delta;\n }\n saveSession(session);\n });\n}\n\nexport function createSnapshot(cwd: string, sessionId: string, cycleNumber: number): void {\n const dir = snapshotDir(cwd, sessionId, cycleNumber);\n mkdirSync(dir, { recursive: true });\n\n copyFileSync(statePath(cwd, sessionId), join(dir, 'state.json'));\n\n const roadmap = roadmapPath(cwd, sessionId);\n if (existsSync(roadmap)) copyFileSync(roadmap, join(dir, 'roadmap.md'));\n\n const strategy = strategyPath(cwd, sessionId);\n if (existsSync(strategy)) copyFileSync(strategy, join(dir, 'strategy.md'));\n\n const ld = logsDir(cwd, sessionId);\n if (existsSync(ld)) cpSync(ld, join(dir, 'logs'), { recursive: true });\n const legacyLogs = legacyLogsPath(cwd, sessionId);\n if (existsSync(legacyLogs)) copyFileSync(legacyLogs, join(dir, 'logs.md'));\n}\n\nexport async function restoreSnapshot(cwd: string, sessionId: string, toCycle: number): Promise<void> {\n return withSessionLock(sessionId, () => {\n const dir = snapshotDir(cwd, sessionId, toCycle);\n if (!existsSync(dir)) throw new Error(`No snapshot found for cycle ${toCycle}`);\n\n // Restore state.json atomically\n const snapshotState = readFileSync(join(dir, 'state.json'), 'utf-8');\n const session = JSON.parse(snapshotState) as Session;\n session.status = 'paused';\n session.completedAt = undefined;\n session.completionReport = undefined;\n session.tmuxSessionName = undefined;\n session.tmuxSessionId = undefined;\n session.tmuxWindowId = undefined;\n atomicWrite(statePath(cwd, sessionId), JSON.stringify(session, null, 2));\n\n // Restore roadmap.md, strategy.md, and logs\n const snapshotRoadmap = join(dir, 'roadmap.md');\n if (existsSync(snapshotRoadmap)) copyFileSync(snapshotRoadmap, roadmapPath(cwd, sessionId));\n\n const snapshotStrategy = join(dir, 'strategy.md');\n if (existsSync(snapshotStrategy)) copyFileSync(snapshotStrategy, strategyPath(cwd, sessionId));\n\n const snapshotLogsDir = join(dir, 'logs');\n if (existsSync(snapshotLogsDir)) {\n const currentLogsDir = logsDir(cwd, sessionId);\n if (existsSync(currentLogsDir)) rmSync(currentLogsDir, { recursive: true, force: true });\n cpSync(snapshotLogsDir, currentLogsDir, { recursive: true });\n } else {\n // Legacy fallback: snapshot has logs.md instead of logs/\n const snapshotLogs = join(dir, 'logs.md');\n if (existsSync(snapshotLogs)) copyFileSync(snapshotLogs, legacyLogsPath(cwd, sessionId));\n }\n });\n}\n\nexport function listSnapshots(cwd: string, sessionId: string): number[] {\n const dir = snapshotsDir(cwd, sessionId);\n if (!existsSync(dir)) return [];\n\n return readdirSync(dir, { withFileTypes: true })\n .filter(e => e.isDirectory() && e.name.startsWith('cycle-'))\n .map(e => parseInt(e.name.replace('cycle-', ''), 10))\n .filter(n => !isNaN(n))\n .sort((a, b) => a - b);\n}\n\nexport function deleteSnapshotsAfter(cwd: string, sessionId: string, afterCycle: number): void {\n const dir = snapshotsDir(cwd, sessionId);\n if (!existsSync(dir)) return;\n\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isDirectory() || !entry.name.startsWith('cycle-')) continue;\n const num = parseInt(entry.name.replace('cycle-', ''), 10);\n if (!isNaN(num) && num > afterCycle) {\n rmSync(join(dir, entry.name), { recursive: true, force: true });\n }\n }\n}\n\n// --- Session cloning ---\n\nfunction replaceIdInDir(dir: string, sourceId: string, cloneId: string): void {\n if (!existsSync(dir)) return;\n const entries = readdirSync(dir, { recursive: true }) as string[];\n for (const rel of entries) {\n const fullPath = join(dir, rel);\n if (!statSync(fullPath).isFile()) continue;\n const buf = readFileSync(fullPath);\n // Skip binary files (null byte in first 8KB)\n const sample = buf.subarray(0, 8192);\n if (sample.includes(0)) continue;\n const text = buf.toString('utf-8');\n if (text.includes(sourceId)) {\n writeFileSync(fullPath, text.replaceAll(sourceId, cloneId), 'utf-8');\n }\n }\n}\n\nexport function cloneSessionDir(\n sourceCwd: string,\n sourceId: string,\n cloneId: string,\n goal: string,\n context?: string,\n strategy?: boolean,\n): void {\n const srcDir = sessionDir(sourceCwd, sourceId);\n const dstDir = sessionDir(sourceCwd, cloneId);\n mkdirSync(dstDir, { recursive: true });\n\n // Deep-copy directories\n const dirsToCopy = ['context', 'prompts', 'reports', 'snapshots'] as const;\n for (const sub of dirsToCopy) {\n const src = join(srcDir, sub);\n const dst = join(dstDir, sub);\n if (existsSync(src)) {\n cpSync(src, dst, { recursive: true });\n } else {\n mkdirSync(dst, { recursive: true });\n }\n }\n\n // Conditionally copy strategy.md\n if (strategy) {\n const srcStrategy = strategyPath(sourceCwd, sourceId);\n if (existsSync(srcStrategy)) {\n const text = readFileSync(srcStrategy, 'utf-8');\n writeFileSync(strategyPath(sourceCwd, cloneId), text.replaceAll(sourceId, cloneId), 'utf-8');\n }\n }\n\n // Replace source ID with clone ID in copied directories\n for (const sub of dirsToCopy) {\n replaceIdInDir(join(dstDir, sub), sourceId, cloneId);\n }\n\n // Write fresh files\n writeFileSync(goalPath(sourceCwd, cloneId), goal, 'utf-8');\n writeFileSync(initialPromptPath(sourceCwd, cloneId), goal, 'utf-8');\n writeFileSync(roadmapPath(sourceCwd, cloneId), ROADMAP_SEED, 'utf-8');\n mkdirSync(logsDir(sourceCwd, cloneId), { recursive: true });\n\n // Write context/CLAUDE.md\n writeFileSync(join(contextDir(sourceCwd, cloneId), 'CLAUDE.md'), CONTEXT_CLAUDE_MD, 'utf-8');\n\n // Write initial-context.md if context provided\n if (context) {\n writeFileSync(join(contextDir(sourceCwd, cloneId), 'initial-context.md'), context, 'utf-8');\n }\n}\n\nexport async function createCloneState(\n sourceCwd: string,\n sourceId: string,\n cloneId: string,\n goal: string,\n context?: string,\n configModel?: string,\n configOrchestratorPrompt?: string,\n): Promise<Session> {\n return withSessionLock(cloneId, () => {\n const source = getSession(sourceCwd, sourceId);\n\n const createdAt = new Date().toISOString();\n const created = new Date(createdAt);\n\n // Deep-copy preserved fields\n const agents = structuredClone(source.agents);\n const orchestratorCycles = structuredClone(source.orchestratorCycles);\n const messages = structuredClone(source.messages);\n\n // Normalize running agents to killed\n const now = new Date().toISOString();\n for (const agent of agents) {\n if (agent.status === 'running') {\n agent.status = 'killed';\n agent.completedAt = now;\n agent.killedReason = 'inherited from source session';\n }\n }\n\n // Resolve model and launchConfig with fallback to config\n const model = source.model ?? configModel;\n const launchConfig = source.launchConfig\n ? structuredClone(source.launchConfig)\n : {\n model,\n context,\n orchestratorPrompt: configOrchestratorPrompt,\n };\n\n const clone: Session = {\n id: cloneId,\n task: goal,\n ...(context ? { context } : {}),\n cwd: sourceCwd,\n status: 'active',\n createdAt,\n activeMs: 0,\n agents,\n orchestratorCycles,\n messages,\n startHour: created.getHours(),\n startDayOfWeek: created.getDay(),\n parentSessionId: sourceId,\n ...(model ? { model } : {}),\n launchConfig,\n ...(source.effort != null ? { effort: source.effort } : {}),\n };\n\n atomicWrite(statePath(sourceCwd, cloneId), JSON.stringify(clone, null, 2));\n return clone;\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport { dirname, join } from 'node:path';\nimport { renameSync, writeFileSync } from 'node:fs';\n\nexport function atomicWrite(filePath: string, data: string): void {\n const dir = dirname(filePath);\n const tmpPath = join(dir, `.atomic.${randomUUID()}.tmp`);\n writeFileSync(tmpPath, data, 'utf-8');\n renameSync(tmpPath, filePath);\n}\n\nconst locks = new Map<string, Promise<void>>();\n\nexport async function withLock<T>(key: string, fn: () => T): Promise<T> {\n const prev = locks.get(key) ?? Promise.resolve();\n let resolve!: () => void;\n const next = new Promise<void>(r => { resolve = r; });\n locks.set(key, next);\n await prev;\n try {\n return fn();\n } finally {\n resolve();\n if (locks.get(key) === next) {\n locks.delete(key);\n }\n }\n}\n","import { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst SISYPHUS_ENTRIES = ['.sisyphus'];\n\nconst SISYPHUS_HEADER = '# Sisyphus';\n\n/**\n * Ensures the project .gitignore includes entries for sisyphus generated artifacts.\n * Only runs in git repos. Creates .gitignore if missing. Skips entries already present.\n */\nexport function ensureSisyphusGitignore(cwd: string): void {\n // Only act in git repos\n if (!existsSync(join(cwd, '.git'))) return;\n\n const gitignorePath = join(cwd, '.gitignore');\n let content = '';\n\n if (existsSync(gitignorePath)) {\n content = readFileSync(gitignorePath, 'utf-8');\n }\n\n const lines = content.split('\\n');\n const missing = SISYPHUS_ENTRIES.filter(entry => !lines.some(line => line.trim() === entry));\n\n if (missing.length === 0) return;\n\n const block = [SISYPHUS_HEADER, ...missing].join('\\n');\n const separator = content.length > 0 && !content.endsWith('\\n\\n')\n ? content.endsWith('\\n') ? '\\n' : '\\n\\n'\n : '';\n\n writeFileSync(gitignorePath, content + separator + block + '\\n', 'utf-8');\n}\n","export type Provider = 'anthropic' | 'openai';\n\nexport interface StatusBarColors {\n processing?: string;\n stopped?: string;\n idle?: string;\n activeBg?: string;\n activeText?: string;\n inactiveText?: string;\n}\n\nexport interface SegmentConfig {\n bg?: string;\n activeBg?: string;\n [key: string]: unknown;\n}\n\nexport interface StatusBarConfig {\n enabled?: boolean;\n colors?: StatusBarColors;\n left?: string[];\n right?: string[];\n segments?: Record<string, SegmentConfig>;\n}\n\nexport type SessionStatus = 'active' | 'paused' | 'completed';\n\nexport type UploadStatus = 'pending' | 'uploaded' | 'failed';\n\nexport type MessageSource =\n | { type: 'agent'; agentId: string }\n | { type: 'user' }\n | { type: 'system'; detail?: string };\n\nexport interface Message {\n id: string;\n source: MessageSource;\n content: string;\n summary: string;\n filePath?: string;\n timestamp: string;\n}\n\nexport type AgentStatus = 'running' | 'completed' | 'killed' | 'crashed' | 'lost';\n\nexport interface AgentReport {\n type: 'update' | 'final';\n filePath: string;\n summary: string;\n timestamp: string;\n}\n\nexport interface Session {\n id: string;\n name?: string;\n task: string;\n context?: string;\n cwd: string;\n status: SessionStatus;\n createdAt: string;\n completedAt?: string;\n activeMs: number;\n /** Set true when the orchestrator pane vanished unexpectedly or daemon-startup found a stuck session. */\n orphaned?: boolean;\n /** Reason string passed to markSessionOrphan — mirrors agent.killedReason. */\n orphanReason?: string;\n /** Cumulative time blocked on `sisyphus ask` (blocking asks only). Subtracted from wallClockMs to compute efficiency. */\n userBlockedMs?: number;\n agents: Agent[];\n orchestratorCycles: OrchestratorCycle[];\n messages: Message[];\n completionReport?: string;\n parentSessionId?: string;\n tmuxSessionName?: string;\n tmuxSessionId?: string; // tmux $N session ID — stable across renames, exact-match targeting\n tmuxWindowId?: string;\n model?: string;\n wallClockMs?: number;\n startHour?: number;\n startDayOfWeek?: number;\n launchConfig?: { model?: string; context?: string; orchestratorPrompt?: string; };\n /** Cycles already credited to companion stats (prevents double-counting on continue→re-complete) */\n companionCreditedCycles?: number;\n /** activeMs already credited to companion stats */\n companionCreditedActiveMs?: number;\n /** Strength already credited to companion stats */\n companionCreditedStrength?: number;\n rollbackCount?: number;\n resumeCount?: number;\n continueCount?: number;\n companionCreditedWisdom?: number;\n /** Lifecycle of the upload to the Worker proxy. `undefined` means upload was never attempted. */\n uploadStatus?: UploadStatus;\n /** R2 storage key returned by the Worker, e.g. `users/silas/<sessionId>.zip`. Bucket is private; this is NOT a fetch-able URL. */\n uploadKey?: string;\n /** Clean error message extracted from the Worker's JSON response when `uploadStatus === 'failed'`. */\n uploadError?: string;\n /** Daemon-local `new Date().toISOString()` at the moment the success was persisted. */\n uploadCompletedAt?: string;\n effort?: 'low' | 'medium' | 'high' | 'xhigh';\n}\n\nexport interface StatusDigest {\n recentWork: string;\n unusualEvents: string[];\n currentActivity: string;\n whatsNext: string;\n effort?: string;\n}\n\nexport interface Agent {\n id: string;\n name: string;\n nickname?: string;\n agentType: string;\n provider?: Provider;\n claudeSessionId?: string;\n color: string;\n instruction: string;\n status: AgentStatus;\n spawnedAt: string;\n completedAt: string | null;\n activeMs: number;\n /** Cumulative time this agent was blocked on its own `sisyphus ask` calls (blocking only). Subset of activeMs. */\n userBlockedMs?: number;\n reports: AgentReport[];\n paneId: string;\n repo: string;\n killedReason?: string;\n restartCount?: number;\n originalSpawnedAt?: string;\n resumeEnv?: string;\n resumeArgs?: string;\n /** Set true when the agent's pane vanished unexpectedly or pid+lstart no longer match. Orthogonal to status. */\n orphaned?: boolean;\n /** Captured at spawn time by `setupAgentPane` → first `tmux display-message #{pane_pid}`. */\n pid?: number;\n /** `ps -o lstart=` output captured at spawn. Compared during pid-sweep to detect PID recycling. */\n pidLstart?: string;\n /** Set true when `sisyphus agent await` consumed this agent's report inline. Suppresses it from the next-cycle orchestrator prompt; one-way. */\n consumedInline?: boolean;\n}\n\nexport interface OrchestratorCycle {\n cycle: number;\n timestamp: string;\n completedAt?: string;\n activeMs: number;\n /** Cumulative time blocked on `sisyphus ask` during this cycle (blocking asks only). */\n userBlockedMs?: number;\n interCycleGapMs?: number;\n agentsSpawned: string[];\n paneId?: string;\n claudeSessionId?: string;\n nextPrompt?: string;\n mode?: string;\n resumeEnv?: string;\n resumeArgs?: string;\n}\n\n// ── sisyphus ask: v2 interaction / deck types (mirror humanloop's published shapes) ──\n\nexport type InteractionKind = 'notify' | 'validation' | 'decision' | 'context' | 'error';\n\nexport interface InteractionOption {\n id: string;\n label: string;\n description?: string;\n shortcut?: string;\n}\n\nexport interface Interaction {\n id: string;\n title: string;\n subtitle?: string;\n body?: string;\n bodyPath?: string;\n options: InteractionOption[];\n allowFreetext?: boolean;\n freetextLabel?: string;\n kind?: InteractionKind;\n}\n\nexport interface ModeChainEntry {\n mode: string;\n /** Cycles spent in this segment. Absent for the trailing (current) entry. */\n cycles?: number;\n /** Active ms accumulated in this segment. Absent for the trailing entry. */\n activeMs?: number;\n}\n\nexport interface DeckSource {\n sessionName?: string;\n askedBy?: string;\n blockedSince?: string;\n /** For orchestrator mode-transition notify decks: ordered chain of modes visited. Trailing entry is the current mode. */\n modeChain?: ModeChainEntry[];\n}\n\nexport interface Deck {\n title?: string;\n source?: DeckSource;\n interactions: Interaction[];\n}\n\nexport interface InteractionResponse {\n id: string;\n selectedOptionId?: string;\n freetext?: string;\n}\n\nexport interface AskOutput {\n responses: InteractionResponse[];\n completedAt: string;\n}\n\nexport interface VisualBlock {\n questionId: string;\n content: string;\n status: 'loading' | 'ready' | 'error';\n}\n\nexport const ORCHESTRATOR_ASKED_BY = 'orchestrator' as const;\n\nexport type AskStatus = 'pending' | 'in-progress' | 'answered' | 'not-found';\n\nexport interface AskMeta {\n askId: string;\n askedBy: string;\n askedAt: string;\n status: AskStatus;\n blocking: boolean;\n pid?: number;\n startedAt?: string;\n completedAt?: string;\n orphaned?: boolean;\n /** ISO timestamp set by the heartbeat scanner when a stale-question notify ask is emitted; dedup key. */\n heartbeatNotifiedAt?: string;\n claudeSessionId?: string;\n cwd: string;\n title?: string;\n subtitle?: string;\n kind?: InteractionKind;\n /** Set on system-emitted error-kind asks; carries the takeover-dispatch context. */\n orphanTarget?: { kind: 'agent'; agentId: string; paneId?: string } | { kind: 'orchestrator' };\n /** Set on orchestrator mode-transition notify asks; aggregation key for rolling mode-change notifications. */\n modeTransition?: true;\n}\n","import { existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs';\nimport {\n askDecisionsPath, askDir, askMetaPath, askOutputPath, askProgressPath, askVisualsDir,\n} from '../shared/paths.js';\nimport type { AskMeta, AskStatus, Deck, InteractionKind, InteractionResponse } from '../shared/types.js';\nimport { loadConfig } from '../shared/config.js';\nimport { emitHistoryEvent } from './history.js';\nimport { atomicWrite, withLock } from './lib/atomic.js';\nimport { sendTerminalNotification } from './notify.js';\nimport * as state from './state.js';\n\nconst ACTIONABLE_KINDS: ReadonlySet<InteractionKind> = new Set([\n 'validation', 'decision', 'context', 'error',\n]);\n\nconst HEARTBEAT_ASKED_BY = 'system:heartbeat';\n\nfunction maybeNotifyOnAskCreated(cwd: string, sessionId: string, meta: AskMeta): void {\n const isActionable = meta.kind !== undefined && ACTIONABLE_KINDS.has(meta.kind);\n const isHeartbeat = meta.askedBy === HEARTBEAT_ASKED_BY;\n if (!isActionable && !isHeartbeat) return;\n\n try {\n const config = loadConfig(cwd);\n if (config.notifications?.enabled === false) return;\n const session = state.getSession(cwd, sessionId);\n const label = session.name ?? sessionId.slice(0, 8);\n const body = meta.title ?? 'Question pending';\n sendTerminalNotification(label, body, session.tmuxSessionName, 'urgent');\n } catch {\n // notify failures must never roll back the ask write\n }\n}\n\nexport interface CreateAskParams {\n askId: string;\n askedBy: string;\n blocking: boolean;\n pid?: number;\n claudeSessionId?: string;\n cwd: string;\n title?: string;\n subtitle?: string;\n kind?: InteractionKind;\n orphanTarget?: AskMeta['orphanTarget'];\n modeTransition?: true;\n}\n\nexport function createAsk(cwd: string, sessionId: string, params: CreateAskParams): AskMeta {\n // askVisualsDir is a subdir of askEntryDir — one recursive mkdir creates both.\n mkdirSync(askVisualsDir(cwd, sessionId, params.askId), { recursive: true });\n\n const askedAt = new Date().toISOString();\n const meta: AskMeta = {\n askId: params.askId,\n askedBy: params.askedBy,\n askedAt,\n status: 'pending' as AskStatus,\n blocking: params.blocking,\n cwd: params.cwd,\n ...(params.pid !== undefined ? { pid: params.pid, startedAt: askedAt } : {}),\n ...(params.claudeSessionId !== undefined ? { claudeSessionId: params.claudeSessionId } : {}),\n ...(params.title !== undefined ? { title: params.title } : {}),\n ...(params.subtitle !== undefined ? { subtitle: params.subtitle } : {}),\n ...(params.kind !== undefined ? { kind: params.kind } : {}),\n ...(params.orphanTarget !== undefined ? { orphanTarget: params.orphanTarget } : {}),\n ...(params.modeTransition !== undefined ? { modeTransition: params.modeTransition } : {}),\n };\n\n atomicWrite(askMetaPath(cwd, sessionId, params.askId), JSON.stringify(meta, null, 2));\n emitHistoryEvent(sessionId, 'ask-issued', {\n askId: params.askId,\n askedBy: params.askedBy,\n blocking: params.blocking,\n askedAt,\n });\n maybeNotifyOnAskCreated(cwd, sessionId, meta);\n return meta;\n}\n\nexport function writeDecisions(cwd: string, sessionId: string, askId: string, deck: Deck): void {\n atomicWrite(askDecisionsPath(cwd, sessionId, askId), JSON.stringify(deck, null, 2));\n}\n\nexport function readDecisions(cwd: string, sessionId: string, askId: string): Deck | null {\n const p = askDecisionsPath(cwd, sessionId, askId);\n try {\n // { encoding } in try body intentional — keeps try content free of bare } for linter clarity\n return JSON.parse(readFileSync(p, { encoding: 'utf-8' })) as Deck;\n } catch (_e) {\n return null;\n }\n}\n\nexport async function writeProgress(\n cwd: string, sessionId: string, askId: string, responses: InteractionResponse[],\n): Promise<void> {\n atomicWrite(askProgressPath(cwd, sessionId, askId), JSON.stringify({\n partial: true,\n responses,\n savedAt: new Date().toISOString(),\n }, null, 2));\n const cur = readMeta(cwd, sessionId, askId);\n if (cur?.status === 'pending') {\n await updateMeta(cwd, sessionId, askId, { status: 'in-progress', startedAt: new Date().toISOString() });\n }\n}\n\nexport function readProgress(\n cwd: string, sessionId: string, askId: string,\n): { responses: InteractionResponse[]; savedAt: string } | null {\n const p = askProgressPath(cwd, sessionId, askId);\n try {\n const data = JSON.parse(readFileSync(p, { encoding: 'utf-8' })) as Record<string, unknown>;\n if (!Array.isArray(data['responses'])) return null;\n return { responses: data['responses'] as InteractionResponse[], savedAt: data['savedAt'] as string };\n } catch (_e) {\n return null;\n }\n}\n\nexport function writeOutput(\n cwd: string, sessionId: string, askId: string,\n responses: InteractionResponse[], completedAt?: string,\n): void {\n atomicWrite(askOutputPath(cwd, sessionId, askId), JSON.stringify({\n responses,\n completedAt: completedAt ?? new Date().toISOString(),\n }, null, 2));\n}\n\nexport function readMeta(cwd: string, sessionId: string, askId: string): AskMeta | null {\n const p = askMetaPath(cwd, sessionId, askId);\n if (!existsSync(p)) {\n return null;\n }\n return JSON.parse(readFileSync(p, 'utf-8')) as AskMeta;\n}\n\nexport async function updateMeta(\n cwd: string, sessionId: string, askId: string, patch: Partial<AskMeta>,\n): Promise<AskMeta> {\n return withLock(askId, () => {\n const cur = readMeta(cwd, sessionId, askId);\n if (!cur) {\n throw new Error(`updateMeta: askId ${askId} not found`);\n }\n const next: AskMeta = { ...cur, ...patch };\n atomicWrite(askMetaPath(cwd, sessionId, askId), JSON.stringify(next, null, 2));\n return next;\n });\n}\n\nexport function listAsks(cwd: string, sessionId: string): string[] {\n const dir = askDir(cwd, sessionId);\n if (!existsSync(dir)) {\n return [];\n }\n return readdirSync(dir, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n}\n\nexport interface PendingAskRef {\n askId: string;\n status: AskStatus;\n title?: string;\n}\n\n/**\n * Open asks (pending or in-progress) attributed to a specific caller. Used to gate\n * yield/submit so a deck can't be abandoned mid-flight — terminating the caller's\n * pane orphans any answer the user produces afterward.\n *\n * Skips: meta.orphaned, status === 'answered', decks where output.json already\n * exists (the user resolved the deck but markAnswered hasn't run yet, e.g. because\n * the original waiter died before observing the output), and non-blocking decks\n * (mode-transition notifications, heartbeat asks, orphan-recovery surfaces — these\n * have no CLI waiter, so terminating the caller doesn't orphan anything).\n */\nexport function listOpenAsksFor(cwd: string, sessionId: string, askedBy: string): PendingAskRef[] {\n const out: PendingAskRef[] = [];\n for (const askId of listAsks(cwd, sessionId)) {\n const meta = readMeta(cwd, sessionId, askId);\n if (!meta) continue;\n if (meta.askedBy !== askedBy) continue;\n if (meta.orphaned) continue;\n if (!meta.blocking) continue;\n if (meta.status !== 'pending' && meta.status !== 'in-progress') continue;\n if (existsSync(askOutputPath(cwd, sessionId, askId))) continue;\n out.push({ askId, status: meta.status, ...(meta.title !== undefined ? { title: meta.title } : {}) });\n }\n return out;\n}\n","import { appendFileSync, mkdirSync, writeFileSync, renameSync, readdirSync, readFileSync, rmSync, statSync } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport { dirname, join } from 'node:path';\nimport { historySessionDir, historyEventsPath, historySessionSummaryPath, historyBaseDir } from '../shared/paths.js';\nimport type { HistoryEventType, SessionSummary } from '../shared/history-types.js';\nimport type { MoodSignals } from '../shared/companion-types.js';\nimport type { Session } from '../shared/types.js';\n\n// Track which session dirs have been created this process to skip redundant mkdirSync\nconst knownDirs = new Set<string>();\n\nfunction ensureDir(sessionId: string): void {\n if (knownDirs.has(sessionId)) return;\n mkdirSync(historySessionDir(sessionId), { recursive: true });\n knownDirs.add(sessionId);\n}\n\nexport function emitHistoryEvent(sessionId: string, event: HistoryEventType, data: Record<string, unknown>): void {\n try {\n ensureDir(sessionId);\n const line = JSON.stringify({ ts: new Date().toISOString(), event, sessionId, data }) + '\\n';\n appendFileSync(historyEventsPath(sessionId), line, 'utf-8');\n } catch {\n // Fire-and-forget — history is best-effort\n }\n}\n\nexport function writeSessionSummary(\n session: Session,\n extra?: { achievements?: string[]; xpGained?: number; finalSignals?: MoodSignals; sentiment?: string },\n): void {\n try {\n ensureDir(session.id);\n\n const summary: SessionSummary = {\n sessionId: session.id,\n name: session.name ?? null,\n task: session.task,\n cwd: session.cwd,\n model: session.model ?? null,\n status: session.status,\n startedAt: session.createdAt,\n completedAt: session.completedAt ?? new Date().toISOString(),\n activeMs: session.activeMs,\n wallClockMs: session.wallClockMs ?? null,\n userBlockedMs: session.userBlockedMs ?? 0,\n agentCount: session.agents.length,\n crashCount: session.agents.filter(a => a.status === 'crashed').length,\n lostCount: session.agents.filter(a => a.status === 'lost').length,\n killedAgentCount: session.agents.filter(a => a.status === 'killed').length,\n rollbackCount: session.rollbackCount ?? 0,\n efficiency: session.wallClockMs\n ? Math.max(0, session.activeMs - (session.userBlockedMs ?? 0))\n / Math.max(1, session.wallClockMs - (session.userBlockedMs ?? 0))\n : null,\n cycleCount: session.orchestratorCycles.length,\n context: session.context ?? null,\n completionReport: session.completionReport ?? null,\n agents: session.agents.map(a => ({\n id: a.id,\n name: a.name,\n nickname: a.nickname ?? null,\n agentType: a.agentType,\n status: a.status,\n activeMs: a.activeMs,\n userBlockedMs: a.userBlockedMs ?? 0,\n spawnedAt: a.spawnedAt,\n completedAt: a.completedAt,\n restartCount: a.restartCount ?? 0,\n })),\n cycles: session.orchestratorCycles.map(c => ({\n cycle: c.cycle,\n mode: c.mode ?? null,\n agentsSpawned: c.agentsSpawned.length,\n activeMs: c.activeMs,\n userBlockedMs: c.userBlockedMs ?? 0,\n startedAt: c.timestamp,\n completedAt: c.completedAt ?? null,\n })),\n messages: session.messages.map(m => ({\n id: m.id,\n source: typeof m.source === 'string' ? m.source : m.source.type,\n content: m.content,\n timestamp: m.timestamp,\n })),\n finalMoodSignals: extra?.finalSignals ?? null,\n achievements: extra?.achievements ?? [],\n xpGained: extra?.xpGained ?? 0,\n sentiment: extra?.sentiment ?? null,\n };\n\n const filePath = historySessionSummaryPath(session.id);\n const tmp = join(dirname(filePath), `.session-${randomUUID()}.tmp`);\n writeFileSync(tmp, JSON.stringify(summary, null, 2), 'utf-8');\n renameSync(tmp, filePath);\n } catch (err) {\n console.error(`[history] Failed to write session summary for ${session.id}:`, err);\n }\n}\n\n/**\n * Load the most recent non-null sentiments from session history.\n * Scans at most `scanLimit` dirs (by mtime, newest first) to avoid reading everything.\n */\nexport function getRecentSentiments(count = 5, scanLimit = 30, overrideBaseDir?: string): Array<{ sentiment: string; task: string; completedAt: string }> {\n try {\n const base = overrideBaseDir ?? historyBaseDir();\n let entries: string[];\n try {\n entries = readdirSync(base);\n } catch {\n return [];\n }\n\n // Sort dirs by mtime descending (newest first)\n const withMtime: Array<{ name: string; mtime: number }> = [];\n for (const name of entries) {\n try {\n const st = statSync(join(base, name));\n if (st.isDirectory()) withMtime.push({ name, mtime: st.mtimeMs });\n } catch { continue; }\n }\n withMtime.sort((a, b) => b.mtime - a.mtime);\n\n const results: Array<{ sentiment: string; task: string; completedAt: string }> = [];\n const limit = Math.min(withMtime.length, scanLimit);\n for (let i = 0; i < limit && results.length < count; i++) {\n try {\n const raw = readFileSync(join(base, withMtime[i].name, 'session.json'), 'utf-8');\n const summary = JSON.parse(raw) as SessionSummary;\n if (summary.sentiment && summary.completedAt) {\n results.push({\n sentiment: summary.sentiment,\n task: summary.task.slice(0, 100),\n completedAt: summary.completedAt,\n });\n }\n } catch { continue; }\n }\n return results;\n } catch {\n return [];\n }\n}\n\nconst PRUNE_KEEP_COUNT = 200;\nconst PRUNE_KEEP_DAYS = 90;\n\nexport function pruneHistory(): void {\n try {\n const base = historyBaseDir();\n let entries: string[];\n try {\n entries = readdirSync(base);\n } catch {\n return; // No history dir yet\n }\n\n // Collect session dirs with their timestamps\n const sessions: Array<{ dir: string; startedAt: number }> = [];\n for (const name of entries) {\n const dir = join(base, name);\n try {\n const summaryPath = join(dir, 'session.json');\n const raw = readFileSync(summaryPath, 'utf-8');\n const summary = JSON.parse(raw) as { startedAt?: string };\n sessions.push({ dir, startedAt: new Date(summary.startedAt ?? 0).getTime() });\n } catch {\n // No session.json — try first line of events.jsonl for stable creation timestamp\n try {\n const eventsPath = join(dir, 'events.jsonl');\n const firstLine = readFileSync(eventsPath, 'utf-8').split('\\n')[0];\n const firstEvent = JSON.parse(firstLine) as { ts?: string };\n sessions.push({ dir, startedAt: new Date(firstEvent.ts ?? 0).getTime() });\n } catch {\n // Fall back to dir mtime only if events.jsonl is unreadable\n try {\n const st = statSync(dir);\n sessions.push({ dir, startedAt: st.mtimeMs });\n } catch {\n continue;\n }\n }\n }\n }\n\n if (sessions.length <= PRUNE_KEEP_COUNT) return;\n\n // Sort newest first\n sessions.sort((a, b) => b.startedAt - a.startedAt);\n\n const cutoff = Date.now() - PRUNE_KEEP_DAYS * 24 * 60 * 60 * 1000;\n for (let i = PRUNE_KEEP_COUNT; i < sessions.length; i++) {\n if (sessions[i].startedAt < cutoff) {\n rmSync(sessions[i].dir, { recursive: true, force: true });\n }\n }\n } catch {\n // Pruning is best-effort\n }\n}\n","import { spawn, execFile, type ChildProcess } from 'node:child_process';\nimport { writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { escapeAppleScript } from '../shared/shell.js';\n\n/**\n * Notification urgency.\n * - `urgent` (default): plays sound, banner; for crashes, asks, things needing real attention\n * - `info`: silent passive banner; for status updates the user only needs to acknowledge\n */\nexport type NotificationLevel = 'info' | 'urgent';\n\nexport interface NotificationOptions {\n title: string;\n message: string;\n /** tmux session name to switch to on click */\n tmuxSession?: string;\n level?: NotificationLevel;\n}\n\nconst TMUX_SOCKET = `/tmp/tmux-${process.getuid?.() ?? 0}/default`;\n\nconst SWITCH_SCRIPT = [\n '#!/bin/bash',\n 'SESSION=\"$1\"',\n `TMUX_SOCKET=\"${TMUX_SOCKET}\"`,\n 'TMUX=/opt/homebrew/bin/tmux',\n '',\n '# Find any attached client (user is likely on a different session)',\n 'CLIENT_TTY=$(\"$TMUX\" -S \"$TMUX_SOCKET\" list-clients -F \\'#{client_tty}\\' 2>/dev/null | head -1)',\n '[ -z \"$CLIENT_TTY\" ] && exit 0',\n '',\n '# Switch that client to the target session',\n '\"$TMUX\" -S \"$TMUX_SOCKET\" switch-client -c \"$CLIENT_TTY\" -t \"$SESSION\" 2>/dev/null',\n '\"$TMUX\" -S \"$TMUX_SOCKET\" select-window -t \"$SESSION\" 2>/dev/null',\n '',\n '# Bring iTerm2 to front and select the tab with this client',\n 'TTY_SHORT=$(echo \"$CLIENT_TTY\" | sed \\'s|/dev/||\\')',\n 'osascript -e \"',\n ' tell application \\\\\"iTerm2\\\\\"',\n ' activate',\n ' repeat with w in windows',\n ' tell w',\n ' repeat with t in tabs',\n ' tell t',\n ' repeat with s in sessions',\n ' tell s',\n ' if tty contains \\\\\"$TTY_SHORT\\\\\" then',\n ' select t',\n ' return',\n ' end if',\n ' end tell',\n ' end repeat',\n ' end tell',\n ' end repeat',\n ' end tell',\n ' end repeat',\n ' end tell',\n '\" 2>/dev/null || osascript -e \\'tell application \"iTerm2\" to activate\\' 2>/dev/null',\n '',\n].join('\\n');\n\nfunction ensureSwitchScript(): void {\n const dir = join(homedir(), '.sisyphus');\n const scriptPath = join(dir, 'notify-switch.sh');\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(scriptPath, SWITCH_SCRIPT, { mode: 0o755 });\n } catch {\n // Best effort\n }\n}\n\n// Long-lived SisyphusNotify.app process — accepts JSON lines on stdin\nlet notifyProcess: ChildProcess | null = null;\n\nfunction getNotifyBinary(): string {\n return join(homedir(), '.sisyphus', 'SisyphusNotify.app', 'Contents', 'MacOS', 'sisyphus-notify');\n}\n\nfunction ensureNotifyProcess(): ChildProcess | null {\n if (notifyProcess && !notifyProcess.killed && notifyProcess.stdin?.writable) {\n return notifyProcess;\n }\n\n const binary = getNotifyBinary();\n if (!existsSync(binary)) {\n return null;\n }\n\n notifyProcess = spawn(binary, [], {\n stdio: ['pipe', 'ignore', 'pipe'],\n });\n\n notifyProcess.stderr?.on('data', (data: Buffer) => {\n const msg = data.toString().trim();\n if (msg) console.error(`[sisyphus-notify] ${msg}`);\n });\n\n notifyProcess.on('close', () => {\n notifyProcess = null;\n });\n\n // Don't keep short-lived parents alive (CLI, tests). The daemon stays up\n // for other reasons; when it exits, the notify subprocess sees stdin EOF.\n notifyProcess.unref();\n notifyProcess.stdin?.unref();\n notifyProcess.stderr?.unref();\n\n return notifyProcess;\n}\n\nexport function sendTerminalNotification(opts: NotificationOptions): void;\nexport function sendTerminalNotification(title: string, message: string, tmuxSession?: string, level?: NotificationLevel): void;\nexport function sendTerminalNotification(titleOrOpts: string | NotificationOptions, message?: string, tmuxSession?: string, level?: NotificationLevel): void {\n let title: string;\n let msg: string;\n let tmuxSess: string | undefined;\n let lvl: NotificationLevel;\n\n if (typeof titleOrOpts === 'object') {\n title = titleOrOpts.title;\n msg = titleOrOpts.message;\n tmuxSess = titleOrOpts.tmuxSession;\n lvl = titleOrOpts.level ?? 'urgent';\n } else {\n title = titleOrOpts;\n msg = message!;\n tmuxSess = tmuxSession;\n lvl = level ?? 'urgent';\n }\n\n // Ensure the switch script is in place\n if (tmuxSess) ensureSwitchScript();\n\n // Try native SisyphusNotify.app (supports click-to-switch + level styling)\n const proc = ensureNotifyProcess();\n if (proc?.stdin?.writable) {\n const payload: Record<string, string> = { title, message: msg, level: lvl };\n if (tmuxSess) payload.tmuxSession = tmuxSess;\n proc.stdin.write(JSON.stringify(payload) + '\\n');\n return;\n }\n\n // Fallback: terminal-notifier — sound only on urgent\n const tnArgs = ['-title', title, '-message', msg];\n if (lvl === 'urgent') tnArgs.push('-sound', 'default');\n execFile('terminal-notifier', tnArgs, (err) => {\n if (err) {\n // Last resort: osascript — use escapeAppleScript for safe string interpolation\n const soundClause = lvl === 'urgent' ? ' sound name \"default\"' : '';\n execFile('osascript', [\n '-e',\n `display notification \"${escapeAppleScript(msg)}\" with title \"${escapeAppleScript(title)}\"${soundClause}`,\n ], () => {});\n }\n });\n}\n","export function shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/** Validate that a session ID is a safe UUID-like string (no path traversal). */\nconst SESSION_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;\nexport function validateSessionId(id: string): boolean {\n return SESSION_ID_PATTERN.test(id) && !id.includes('..');\n}\n\n/** Validate that a repo name is a simple directory name (no path components). */\nexport function validateRepoName(repo: string): boolean {\n return !repo.includes('/') && !repo.includes('\\\\') && !repo.includes('..');\n}\n\n/** Escape a string for safe interpolation inside AppleScript double quotes. */\nexport function escapeAppleScript(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n"],"mappings":"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","names":["existsSync","readFileSync","writeFileSync","join","readFileSync","writeFileSync","join","writeFileSync","join","readFileSync","writeFileSync","join","existsSync","readFileSync","existsSync","mkdirSync","readFileSync","readdirSync","mkdirSync","writeFileSync","renameSync","readdirSync","readFileSync","rmSync","statSync","randomUUID","dirname","join","mkdirSync","join","dirname","randomUUID","writeFileSync","renameSync","readdirSync","statSync","readFileSync","rmSync","writeFileSync","mkdirSync","existsSync","join","join","mkdirSync","writeFileSync","existsSync","mkdirSync","readFileSync","readFileSync","existsSync","readdirSync"]}