sisyphi 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ZSIYQB45.js → chunk-CAJEBTUE.js} +6 -2
- package/dist/chunk-CAJEBTUE.js.map +1 -0
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +53 -47
- package/dist/daemon.js.map +1 -1
- package/dist/templates/orchestrator-base.md +9 -7
- package/dist/templates/orchestrator-completion.md +5 -0
- package/dist/templates/orchestrator-impl.md +5 -0
- package/dist/templates/orchestrator-planning.md +5 -0
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/dist/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/dist/templates/orchestrator-strategy.md +5 -0
- package/dist/templates/orchestrator-validation.md +5 -0
- package/dist/tui.js +577 -125
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/orchestrator-base.md +9 -7
- package/templates/orchestrator-completion.md +5 -0
- package/templates/orchestrator-impl.md +5 -0
- package/templates/orchestrator-planning.md +5 -0
- package/templates/orchestrator-plugin/hooks/hooks.json +10 -0
- package/templates/orchestrator-plugin/hooks/idle-notify.sh +71 -0
- package/templates/orchestrator-strategy.md +5 -0
- package/templates/orchestrator-validation.md +5 -0
- package/dist/chunk-ZSIYQB45.js.map +0 -1
package/package.json
CHANGED
|
@@ -62,7 +62,13 @@ Wait for the user to respond. After receiving their answer, update roadmap, spaw
|
|
|
62
62
|
|
|
63
63
|
The rule:
|
|
64
64
|
- **Need user input?** Ask and wait. Continue after they respond.
|
|
65
|
-
- **Done with cycle work?** Yield with a prompt for next cycle.
|
|
65
|
+
- **Done with cycle work?** Yield with a prompt for next cycle. Include `--mode` when transitioning phases.
|
|
66
|
+
|
|
67
|
+
### Mode Transitions
|
|
68
|
+
|
|
69
|
+
Each yield can switch your mode — the mode determines the system prompt for the next cycle. Omitting `--mode` keeps the current mode.
|
|
70
|
+
|
|
71
|
+
{{ORCHESTRATOR_MODES}}
|
|
66
72
|
|
|
67
73
|
**Seek user alignment when:**
|
|
68
74
|
- The goal is ambiguous or under-specified
|
|
@@ -218,7 +224,7 @@ You have unlimited cycles. Failed implementations, deferred issues, and skipped
|
|
|
218
224
|
|
|
219
225
|
- **Critique** — spawn review agents to find flaws, code smells, missed edge cases. They report problems, not fixes.
|
|
220
226
|
- **Refine** — spawn agents to fix what reviewers found.
|
|
221
|
-
- **Validate** — e2e verification that the feature actually works. When all stages are done, transition to validation mode
|
|
227
|
+
- **Validate** — e2e verification that the feature actually works. When all stages are done, transition to `validation` mode for the comprehensive final pass.
|
|
222
228
|
|
|
223
229
|
</development-heuristics>
|
|
224
230
|
|
|
@@ -259,11 +265,7 @@ sisyphus spawn --name "debug-auth" --agent-type sisyphus:debug "/devcore:debuggi
|
|
|
259
265
|
```bash
|
|
260
266
|
sisyphus yield # yield — NEVER use when waiting for user input
|
|
261
267
|
sisyphus yield --prompt "focus on auth middleware next" # yield with guidance for next cycle
|
|
262
|
-
sisyphus yield --mode
|
|
263
|
-
sisyphus yield --mode planning --prompt "re-evaluate" # switch to planning mode
|
|
264
|
-
sisyphus yield --mode implementation --prompt "begin" # switch to implementation mode
|
|
265
|
-
sisyphus yield --mode validation --prompt "validate" # switch to validation mode
|
|
266
|
-
sisyphus yield --mode completion --prompt "validated" # switch to completion mode (user sign-off)
|
|
268
|
+
sisyphus yield --mode <mode> --prompt "guidance" # switch mode for next cycle
|
|
267
269
|
sisyphus complete --report "summary of accomplishments" # complete the session (only from completion mode)
|
|
268
270
|
sisyphus continue # reactivate a completed session
|
|
269
271
|
sisyphus status # check session status
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: completion
|
|
3
|
+
description: Present accomplishments and get explicit user confirmation before finalizing. Use only after validation passes and all checks are satisfied.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Completion Phase
|
|
2
7
|
|
|
3
8
|
You are in completion mode. Your job is to **present what was accomplished and get explicit user confirmation before finalizing the session.** This is the handoff — the user sees the results, asks questions, requests fixes, and confirms when they're satisfied.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Stop hook: notify user when orchestrator is idle and tmux window not attended.
|
|
3
|
+
# If terminal-notifier is available, clicking the notification switches tmux to
|
|
4
|
+
# the orchestrator's window. Falls back to osascript (no click action).
|
|
5
|
+
# Always exits 0 with no stdout — never blocks stop.
|
|
6
|
+
|
|
7
|
+
[ "$SISYPHUS_NOTIFY_ENABLED" = "0" ] && exit 0
|
|
8
|
+
[ -z "$TMUX_PANE" ] && exit 0
|
|
9
|
+
|
|
10
|
+
WINDOW_ACTIVE=$(tmux display-message -t "$TMUX_PANE" -p "#{window_active}" 2>/dev/null)
|
|
11
|
+
SESSION_ATTACHED=$(tmux display-message -t "$TMUX_PANE" -p "#{session_attached}" 2>/dev/null)
|
|
12
|
+
|
|
13
|
+
# User is watching — no notification needed
|
|
14
|
+
[ "$WINDOW_ACTIVE" = "1" ] && [ -n "$SESSION_ATTACHED" ] && [ "$SESSION_ATTACHED" != "0" ] && exit 0
|
|
15
|
+
|
|
16
|
+
SOUND="${SISYPHUS_NOTIFY_SOUND:-/System/Library/Sounds/Hero.aiff}"
|
|
17
|
+
LABEL="${SISYPHUS_SESSION_NAME:-orchestrator}"
|
|
18
|
+
|
|
19
|
+
# Resolve session/window for click-to-switch
|
|
20
|
+
SESSION_NAME=$(tmux display-message -t "$TMUX_PANE" -p "#{session_name}" 2>/dev/null)
|
|
21
|
+
WINDOW_ID=$(tmux display-message -t "$TMUX_PANE" -p "#{window_index}" 2>/dev/null)
|
|
22
|
+
|
|
23
|
+
if [ -n "$SESSION_NAME" ] && [ -n "$WINDOW_ID" ] && command -v terminal-notifier &>/dev/null; then
|
|
24
|
+
# Write a one-shot switch script (self-deleting on execution)
|
|
25
|
+
# terminal-notifier -execute runs with minimal PATH, so resolve paths now
|
|
26
|
+
TMUX_BIN=$(command -v tmux)
|
|
27
|
+
# Find the tmux client tty attached to this session (for iTerm2 tab lookup)
|
|
28
|
+
CLIENT_TTY=$("$TMUX_BIN" list-clients -t "$SESSION_NAME" -F "#{client_tty}" 2>/dev/null | head -1)
|
|
29
|
+
SWITCH_SCRIPT=$(mktemp /tmp/sisyphus-switch.XXXXXX.sh)
|
|
30
|
+
cat > "$SWITCH_SCRIPT" <<EOF
|
|
31
|
+
#!/bin/bash
|
|
32
|
+
# Activate the correct iTerm2 window+tab (matched by tty), or fall back to generic activate
|
|
33
|
+
osascript -e '
|
|
34
|
+
tell application "iTerm"
|
|
35
|
+
activate
|
|
36
|
+
repeat with w in windows
|
|
37
|
+
repeat with t in tabs of w
|
|
38
|
+
repeat with s in sessions of t
|
|
39
|
+
if tty of s is "${CLIENT_TTY}" then
|
|
40
|
+
select w
|
|
41
|
+
tell w to select t
|
|
42
|
+
return
|
|
43
|
+
end if
|
|
44
|
+
end repeat
|
|
45
|
+
end repeat
|
|
46
|
+
end repeat
|
|
47
|
+
end tell' 2>/dev/null || osascript -e 'tell application "Terminal" to activate' 2>/dev/null
|
|
48
|
+
# Switch tmux to the orchestrator window
|
|
49
|
+
"${TMUX_BIN}" switch-client -c "${CLIENT_TTY}" -t "${SESSION_NAME}:${WINDOW_ID}" 2>/dev/null
|
|
50
|
+
"${TMUX_BIN}" select-window -t "${SESSION_NAME}:${WINDOW_ID}" 2>/dev/null
|
|
51
|
+
rm -f "\$0"
|
|
52
|
+
EOF
|
|
53
|
+
chmod +x "$SWITCH_SCRIPT"
|
|
54
|
+
|
|
55
|
+
SOUND_NAME=$(basename "${SOUND}" .aiff)
|
|
56
|
+
(
|
|
57
|
+
terminal-notifier \
|
|
58
|
+
-title "Sisyphus: ${LABEL}" \
|
|
59
|
+
-message "Orchestrator waiting for input" \
|
|
60
|
+
-sound "$SOUND_NAME" \
|
|
61
|
+
-execute "$SWITCH_SCRIPT" 2>/dev/null
|
|
62
|
+
) &
|
|
63
|
+
else
|
|
64
|
+
# Fallback: osascript notification + sound (no click-to-switch)
|
|
65
|
+
(
|
|
66
|
+
osascript -e "display notification \"Orchestrator waiting for input\" with title \"Sisyphus: ${LABEL}\"" 2>/dev/null
|
|
67
|
+
[ -f "$SOUND" ] && afplay "$SOUND" 2>/dev/null
|
|
68
|
+
) &
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
exit 0
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: strategy
|
|
3
|
+
description: Understand the goal and map out how to get there. Use when starting a new session, when the goal has fundamentally shifted, or when the current approach needs rethinking.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Strategy Phase
|
|
2
7
|
|
|
3
8
|
You are in strategy mode. Your job is to understand the goal and produce a strategy that maps out how to get there — but only as far as you can currently see.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: validation
|
|
3
|
+
description: Prove that what was built actually works via end-to-end verification. Use when all implementation stages are complete and before transitioning to completion.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Validation Phase
|
|
2
7
|
|
|
3
8
|
You are in validation mode. Your job is not to build — it is to **prove that what was built actually works.** No new implementation unless a validation failure demands it. No assumptions about correctness. No hedging.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/config.ts","../src/shared/env.ts","../src/shared/exec.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport type EffortLevel = 'low' | 'medium' | 'high' | 'max';\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}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 5000,\n orchestratorEffort: 'high',\n agentEffort: 'medium',\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","/**\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 candidates = [\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,oBAAoB;AAiB7B,IAAM,iBAAyB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,aAAa;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;;;AC5BO,SAAS,gBAAwB;AACtC,QAAM,UAAU,QAAQ,IAAI,MAAM;AAClC,QAAM,WAAW,YAAY,UAAa,QAAQ,SAAS,IAAI,UAAU;AAIzE,QAAM,aAAa;AAAA,IACjB;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;;;AC/CA,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":[]}
|