sisyphi 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Silas Rhyneer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # sisyphi
2
+
3
+ A tmux-integrated orchestration daemon for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) multi-agent workflows.
4
+
5
+ A background daemon manages sessions where an **orchestrator** Claude instance breaks tasks into subtasks, spawns **agent** Claude instances in tmux panes, and coordinates their lifecycle through cycles. Agents work in parallel, submit reports, and the orchestrator respawns each cycle with fresh context to review progress and plan next steps.
6
+
7
+ ## How It Works
8
+
9
+ ```
10
+ You ──► sisyphus start "build auth system"
11
+
12
+
13
+ ┌─────────────┐
14
+ │ Orchestrator │ ◄── Reads state, plans work, spawns agents
15
+ └──────┬──────┘
16
+ │ sisyphus spawn (×N)
17
+
18
+ ┌─────┐ ┌─────┐ ┌─────┐
19
+ │ A-1 │ │ A-2 │ │ A-3 │ ◄── Parallel Claude agents in tmux panes
20
+ └──┬──┘ └──┬──┘ └──┬──┘
21
+ │ │ │
22
+ ▼ ▼ ▼
23
+ sisyphus submit (each agent reports back)
24
+
25
+
26
+ ┌─────────────┐
27
+ │ Orchestrator │ ◄── Respawned with updated state (next cycle)
28
+ └─────────────┘
29
+ ```
30
+
31
+ 1. **You** run `sisyphus start` with a high-level task
32
+ 2. **Orchestrator** decomposes it, adds tasks, spawns agents, yields
33
+ 3. **Agents** work in parallel tmux panes, send progress reports, submit when done
34
+ 4. **Daemon** detects completion, respawns orchestrator with updated state
35
+ 5. **Orchestrator** reviews reports, spawns more agents or completes the session
36
+
37
+ The orchestrator is stateless — it's killed after yielding and respawned fresh each cycle with the full session state. This means it never runs out of context, no matter how many cycles a session takes.
38
+
39
+ ## Requirements
40
+
41
+ - **Node.js** >= 22
42
+ - **tmux** (you must be inside a tmux session)
43
+ - **Claude Code** CLI (`claude`) installed and authenticated
44
+
45
+ ## Install
46
+
47
+ ```bash
48
+ npm install -g sisyphi
49
+ ```
50
+
51
+ This gives you two commands:
52
+ - `sisyphus` — the CLI for interacting with sessions
53
+ - `sisyphusd` — the background daemon
54
+
55
+ ## Quick Start
56
+
57
+ ### 1. Start the daemon
58
+
59
+ ```bash
60
+ sisyphusd
61
+ ```
62
+
63
+ Or run it in the background. On macOS you can use launchd — create `~/Library/LaunchAgents/com.sisyphus.daemon.plist`:
64
+
65
+ ```xml
66
+ <?xml version="1.0" encoding="UTF-8"?>
67
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
68
+ <plist version="1.0">
69
+ <dict>
70
+ <key>Label</key>
71
+ <string>com.sisyphus.daemon</string>
72
+ <key>ProgramArguments</key>
73
+ <array>
74
+ <string>sisyphusd</string>
75
+ </array>
76
+ <key>KeepAlive</key>
77
+ <true/>
78
+ <key>RunAtLoad</key>
79
+ <true/>
80
+ <key>StandardOutPath</key>
81
+ <string>~/.sisyphus/daemon.log</string>
82
+ <key>StandardErrorPath</key>
83
+ <string>~/.sisyphus/daemon.log</string>
84
+ </dict>
85
+ </plist>
86
+ ```
87
+
88
+ Then load it:
89
+
90
+ ```bash
91
+ launchctl load ~/Library/LaunchAgents/com.sisyphus.daemon.plist
92
+ ```
93
+
94
+ ### 2. Start a session (inside tmux)
95
+
96
+ ```bash
97
+ sisyphus start "Refactor the authentication module to use JWT tokens"
98
+ ```
99
+
100
+ The orchestrator spawns in a yellow tmux pane and begins planning.
101
+
102
+ ### 3. Watch it work
103
+
104
+ ```bash
105
+ sisyphus status # Check session state, tasks, agents
106
+ sisyphus tasks list # View task breakdown
107
+ ```
108
+
109
+ Agent panes appear as the orchestrator spawns them, color-coded by agent:
110
+
111
+ | Role | Color |
112
+ |------|-------|
113
+ | Orchestrator | Yellow |
114
+ | Agents | Blue, Green, Magenta, Cyan, Red, White (rotating) |
115
+
116
+ ### 4. Resume or complete
117
+
118
+ ```bash
119
+ sisyphus resume <session-id> # Resume a paused session
120
+ sisyphus resume <session-id> "focus on tests" # Resume with new instructions
121
+ sisyphus list # List all sessions
122
+ ```
123
+
124
+ ## CLI Reference
125
+
126
+ ```bash
127
+ # Session lifecycle
128
+ sisyphus start "task description" # Create session, launch orchestrator
129
+ sisyphus status # Current session state
130
+ sisyphus list # List all sessions
131
+ sisyphus resume <id> [message] # Resume paused session
132
+ sisyphus kill <id> # Kill a session
133
+
134
+ # These are used by the orchestrator/agents (not typically run manually):
135
+ sisyphus spawn --agent-type <t> --name <n> --instruction "..."
136
+ sisyphus yield # Orchestrator yields control
137
+ sisyphus complete --report "summary" # Mark session done
138
+ sisyphus submit --report "findings" # Agent submits final report
139
+ sisyphus report --message "progress" # Agent sends progress update
140
+
141
+ # Task management
142
+ sisyphus tasks list
143
+ sisyphus tasks add "description"
144
+ sisyphus tasks add "idea" --status draft
145
+ echo "long description" | sisyphus tasks add # stdin piping
146
+ sisyphus tasks update <taskId> --status done
147
+ sisyphus tasks update <taskId> --description "refined"
148
+ ```
149
+
150
+ ## Architecture
151
+
152
+ Three layers communicating over a Unix socket (`~/.sisyphus/daemon.sock`):
153
+
154
+ - **CLI** (`sisyphus`) — Commander.js program that sends JSON requests to the daemon
155
+ - **Daemon** (`sisyphusd`) — Manages sessions, spawns/monitors tmux panes, tracks state
156
+ - **Shared** — Types, protocol definitions, config resolution
157
+
158
+ State is persisted as JSON at `.sisyphus/sessions/{id}/state.json` (relative to your project directory), written atomically via temp file + rename.
159
+
160
+ ## Configuration
161
+
162
+ Config is layered: project (`.sisyphus/config.json`) overrides global (`~/.sisyphus/config.json`).
163
+
164
+ ```json
165
+ {
166
+ "model": "sonnet",
167
+ "pollIntervalMs": 3000
168
+ }
169
+ ```
170
+
171
+ You can also override the orchestrator prompt per-project by placing a file at `.sisyphus/orchestrator.md`.
172
+
173
+ ## License
174
+
175
+ MIT
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/shared/paths.ts
4
+ import { homedir } from "os";
5
+ import { join } from "path";
6
+ function globalDir() {
7
+ return join(homedir(), ".sisyphus");
8
+ }
9
+ function socketPath() {
10
+ return join(globalDir(), "daemon.sock");
11
+ }
12
+ function globalConfigPath() {
13
+ return join(globalDir(), "config.json");
14
+ }
15
+ function daemonPidPath() {
16
+ return join(globalDir(), "daemon.pid");
17
+ }
18
+ function projectDir(cwd) {
19
+ return join(cwd, ".sisyphus");
20
+ }
21
+ function projectConfigPath(cwd) {
22
+ return join(projectDir(cwd), "config.json");
23
+ }
24
+ function projectOrchestratorPromptPath(cwd) {
25
+ return join(projectDir(cwd), "orchestrator.md");
26
+ }
27
+ function sessionsDir(cwd) {
28
+ return join(projectDir(cwd), "sessions");
29
+ }
30
+ function sessionDir(cwd, sessionId) {
31
+ return join(sessionsDir(cwd), sessionId);
32
+ }
33
+ function statePath(cwd, sessionId) {
34
+ return join(sessionDir(cwd, sessionId), "state.json");
35
+ }
36
+ function reportsDir(cwd, sessionId) {
37
+ return join(sessionDir(cwd, sessionId), "reports");
38
+ }
39
+ function reportFilePath(cwd, sessionId, agentId, suffix) {
40
+ return join(reportsDir(cwd, sessionId), `${agentId}-${suffix}.md`);
41
+ }
42
+
43
+ export {
44
+ globalDir,
45
+ socketPath,
46
+ globalConfigPath,
47
+ daemonPidPath,
48
+ projectConfigPath,
49
+ projectOrchestratorPromptPath,
50
+ sessionsDir,
51
+ sessionDir,
52
+ statePath,
53
+ reportsDir,
54
+ reportFilePath
55
+ };
56
+ //# sourceMappingURL=chunk-5WP7O7D3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/paths.ts"],"sourcesContent":["import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport function globalDir(): string {\n return join(homedir(), '.sisyphus');\n}\n\nexport function socketPath(): string {\n return join(globalDir(), 'daemon.sock');\n}\n\nexport function globalConfigPath(): string {\n return join(globalDir(), 'config.json');\n}\n\nexport function daemonLogPath(): string {\n return join(globalDir(), 'daemon.log');\n}\n\nexport function daemonPidPath(): string {\n return join(globalDir(), 'daemon.pid');\n}\n\nexport function projectDir(cwd: string): string {\n return join(cwd, '.sisyphus');\n}\n\nexport function projectConfigPath(cwd: string): string {\n return join(projectDir(cwd), 'config.json');\n}\n\nexport function projectOrchestratorPromptPath(cwd: string): string {\n return join(projectDir(cwd), 'orchestrator.md');\n}\n\nexport function sessionsDir(cwd: string): string {\n return join(projectDir(cwd), 'sessions');\n}\n\nexport function sessionDir(cwd: string, sessionId: string): string {\n return join(sessionsDir(cwd), sessionId);\n}\n\nexport function statePath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'state.json');\n}\n\nexport function reportsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'reports');\n}\n\nexport function reportFilePath(cwd: string, sessionId: string, agentId: string, suffix: string): string {\n return join(reportsDir(cwd, sessionId), `${agentId}-${suffix}.md`);\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,SAAS,YAAY;AAEd,SAAS,YAAoB;AAClC,SAAO,KAAK,QAAQ,GAAG,WAAW;AACpC;AAEO,SAAS,aAAqB;AACnC,SAAO,KAAK,UAAU,GAAG,aAAa;AACxC;AAEO,SAAS,mBAA2B;AACzC,SAAO,KAAK,UAAU,GAAG,aAAa;AACxC;AAMO,SAAS,gBAAwB;AACtC,SAAO,KAAK,UAAU,GAAG,YAAY;AACvC;AAEO,SAAS,WAAW,KAAqB;AAC9C,SAAO,KAAK,KAAK,WAAW;AAC9B;AAEO,SAAS,kBAAkB,KAAqB;AACrD,SAAO,KAAK,WAAW,GAAG,GAAG,aAAa;AAC5C;AAEO,SAAS,8BAA8B,KAAqB;AACjE,SAAO,KAAK,WAAW,GAAG,GAAG,iBAAiB;AAChD;AAEO,SAAS,YAAY,KAAqB;AAC/C,SAAO,KAAK,WAAW,GAAG,GAAG,UAAU;AACzC;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,YAAY,GAAG,GAAG,SAAS;AACzC;AAEO,SAAS,UAAU,KAAa,WAA2B;AAChE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,YAAY;AACtD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,eAAe,KAAa,WAAmB,SAAiB,QAAwB;AACtG,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,GAAG,OAAO,IAAI,MAAM,KAAK;AACnE;","names":[]}