sisyphi 1.1.16 → 1.1.18
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/README.md +209 -7
- package/dist/{chunk-6TIO23U3.js → chunk-22ZGZTGY.js} +3 -3
- package/dist/{chunk-6TIO23U3.js.map → chunk-22ZGZTGY.js.map} +1 -1
- package/dist/{chunk-UIVQXCWB.js → chunk-6PJVJEYQ.js} +2 -2
- package/dist/chunk-C2XKXERJ.js +1052 -0
- package/dist/chunk-C2XKXERJ.js.map +1 -0
- package/dist/{chunk-GSXF3TCZ.js → chunk-TMBAVPHH.js} +19 -3
- package/dist/chunk-TMBAVPHH.js.map +1 -0
- package/dist/chunk-V36NXMHP.js +299 -0
- package/dist/chunk-V36NXMHP.js.map +1 -0
- package/dist/cli.js +166 -8
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +1464 -129
- package/dist/daemon.js.map +1 -1
- package/dist/{paths-3EL2SCHI.js → paths-XRDEEJ5R.js} +10 -2
- package/dist/tui.js +1314 -984
- package/dist/tui.js.map +1 -1
- package/native/SisyphusNotify/AppIcon.icns +0 -0
- package/native/SisyphusNotify/Info.plist +26 -0
- package/native/SisyphusNotify/main.swift +126 -0
- package/native/SisyphusNotify/sisyphus-icon.jpg +0 -0
- package/native/build-notify.sh +58 -0
- package/package.json +3 -2
- package/dist/chunk-GSXF3TCZ.js.map +0 -1
- package/dist/chunk-HQZOAX6D.js +0 -240
- package/dist/chunk-HQZOAX6D.js.map +0 -1
- package/dist/chunk-IF55HPWX.js +0 -44
- package/dist/chunk-IF55HPWX.js.map +0 -1
- /package/dist/{chunk-UIVQXCWB.js.map → chunk-6PJVJEYQ.js.map} +0 -0
- /package/dist/{paths-3EL2SCHI.js.map → paths-XRDEEJ5R.js.map} +0 -0
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleIdentifier</key>
|
|
6
|
+
<string>com.sisyphus.notify</string>
|
|
7
|
+
<key>CFBundleName</key>
|
|
8
|
+
<string>Sisyphus</string>
|
|
9
|
+
<key>CFBundleDisplayName</key>
|
|
10
|
+
<string>Sisyphus</string>
|
|
11
|
+
<key>CFBundleExecutable</key>
|
|
12
|
+
<string>sisyphus-notify</string>
|
|
13
|
+
<key>CFBundlePackageType</key>
|
|
14
|
+
<string>APPL</string>
|
|
15
|
+
<key>CFBundleVersion</key>
|
|
16
|
+
<string>1.0</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleIconFile</key>
|
|
20
|
+
<string>AppIcon</string>
|
|
21
|
+
<key>LSUIElement</key>
|
|
22
|
+
<true/>
|
|
23
|
+
<key>NSUserNotificationAlertStyle</key>
|
|
24
|
+
<string>banner</string>
|
|
25
|
+
</dict>
|
|
26
|
+
</plist>
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import Cocoa
|
|
2
|
+
import UserNotifications
|
|
3
|
+
|
|
4
|
+
// Long-lived notification helper.
|
|
5
|
+
// Reads JSON lines from stdin: {"title":"...","message":"...","tmuxSession":"..."}
|
|
6
|
+
// Stays alive to handle click callbacks.
|
|
7
|
+
// Send SIGTERM or close stdin to stop.
|
|
8
|
+
|
|
9
|
+
class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate {
|
|
10
|
+
private var authorized = false
|
|
11
|
+
|
|
12
|
+
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
13
|
+
let center = UNUserNotificationCenter.current()
|
|
14
|
+
center.delegate = self
|
|
15
|
+
|
|
16
|
+
// Register category with "Switch" action
|
|
17
|
+
let switchAction = UNNotificationAction(
|
|
18
|
+
identifier: "SWITCH",
|
|
19
|
+
title: "Switch",
|
|
20
|
+
options: [.foreground]
|
|
21
|
+
)
|
|
22
|
+
let category = UNNotificationCategory(
|
|
23
|
+
identifier: "SISYPHUS",
|
|
24
|
+
actions: [switchAction],
|
|
25
|
+
intentIdentifiers: []
|
|
26
|
+
)
|
|
27
|
+
center.setNotificationCategories([category])
|
|
28
|
+
|
|
29
|
+
// Request permission
|
|
30
|
+
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
|
|
31
|
+
if let error = error {
|
|
32
|
+
fputs("Authorization error: \(error.localizedDescription)\n", stderr)
|
|
33
|
+
}
|
|
34
|
+
self.authorized = granted
|
|
35
|
+
if !granted {
|
|
36
|
+
fputs("Notification permission denied\n", stderr)
|
|
37
|
+
}
|
|
38
|
+
// Start reading stdin for notification requests
|
|
39
|
+
self.startStdinReader()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private func startStdinReader() {
|
|
44
|
+
DispatchQueue.global(qos: .utility).async {
|
|
45
|
+
while let line = readLine() {
|
|
46
|
+
guard !line.isEmpty else { continue }
|
|
47
|
+
guard let data = line.data(using: .utf8),
|
|
48
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: String] else {
|
|
49
|
+
fputs("Invalid JSON: \(line)\n", stderr)
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
let title = json["title"] ?? "Sisyphus"
|
|
53
|
+
let message = json["message"] ?? ""
|
|
54
|
+
let tmuxSession = json["tmuxSession"]
|
|
55
|
+
|
|
56
|
+
self.sendNotification(title: title, message: message, tmuxSession: tmuxSession)
|
|
57
|
+
}
|
|
58
|
+
// stdin closed — exit
|
|
59
|
+
DispatchQueue.main.async { NSApp.terminate(nil) }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private func sendNotification(title: String, message: String, tmuxSession: String?) {
|
|
64
|
+
guard authorized else {
|
|
65
|
+
fputs("Not authorized to send notifications\n", stderr)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let content = UNMutableNotificationContent()
|
|
70
|
+
content.title = title
|
|
71
|
+
content.body = message
|
|
72
|
+
content.sound = .default
|
|
73
|
+
content.categoryIdentifier = "SISYPHUS"
|
|
74
|
+
|
|
75
|
+
var userInfo: [String: String] = [:]
|
|
76
|
+
if let s = tmuxSession { userInfo["tmuxSession"] = s }
|
|
77
|
+
content.userInfo = userInfo
|
|
78
|
+
|
|
79
|
+
let request = UNNotificationRequest(
|
|
80
|
+
identifier: UUID().uuidString,
|
|
81
|
+
content: content,
|
|
82
|
+
trigger: nil
|
|
83
|
+
)
|
|
84
|
+
UNUserNotificationCenter.current().add(request) { error in
|
|
85
|
+
if let error = error {
|
|
86
|
+
fputs("Failed: \(error.localizedDescription)\n", stderr)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Show banner even when app is "in foreground" (it's a background daemon)
|
|
92
|
+
func userNotificationCenter(
|
|
93
|
+
_ center: UNUserNotificationCenter,
|
|
94
|
+
willPresent notification: UNNotification,
|
|
95
|
+
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
|
|
96
|
+
) {
|
|
97
|
+
completionHandler([.banner, .sound])
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Click handler — runs the switch script
|
|
101
|
+
func userNotificationCenter(
|
|
102
|
+
_ center: UNUserNotificationCenter,
|
|
103
|
+
didReceive response: UNNotificationResponse,
|
|
104
|
+
withCompletionHandler completionHandler: @escaping () -> Void
|
|
105
|
+
) {
|
|
106
|
+
let userInfo = response.notification.request.content.userInfo
|
|
107
|
+
let tmuxSession = userInfo["tmuxSession"] as? String
|
|
108
|
+
|
|
109
|
+
if let session = tmuxSession {
|
|
110
|
+
let script = NSHomeDirectory() + "/.sisyphus/notify-switch.sh"
|
|
111
|
+
let task = Process()
|
|
112
|
+
task.executableURL = URL(fileURLWithPath: "/bin/bash")
|
|
113
|
+
task.arguments = [script, session]
|
|
114
|
+
task.environment = ["PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"]
|
|
115
|
+
try? task.run()
|
|
116
|
+
task.waitUntilExit()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
completionHandler()
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let app = NSApplication.shared
|
|
124
|
+
let delegate = AppDelegate()
|
|
125
|
+
app.delegate = delegate
|
|
126
|
+
app.run()
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Build SisyphusNotify.app — macOS notification helper with click-to-switch
|
|
5
|
+
# Requires: Xcode Command Line Tools (swiftc)
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
SRC_DIR="$SCRIPT_DIR/SisyphusNotify"
|
|
9
|
+
APP_NAME="SisyphusNotify"
|
|
10
|
+
INSTALL_DIR="$HOME/.sisyphus"
|
|
11
|
+
|
|
12
|
+
# Paths
|
|
13
|
+
APP_BUNDLE="$INSTALL_DIR/$APP_NAME.app"
|
|
14
|
+
CONTENTS="$APP_BUNDLE/Contents"
|
|
15
|
+
MACOS_DIR="$CONTENTS/MacOS"
|
|
16
|
+
BINARY="$MACOS_DIR/sisyphus-notify"
|
|
17
|
+
|
|
18
|
+
# Check for swiftc
|
|
19
|
+
if ! command -v swiftc &>/dev/null; then
|
|
20
|
+
echo "Error: swiftc not found. Install Xcode Command Line Tools: xcode-select --install" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Only rebuild if source is newer than binary
|
|
25
|
+
if [ -f "$BINARY" ] && [ "$SRC_DIR/main.swift" -ot "$BINARY" ] && [ "$SRC_DIR/Info.plist" -ot "$BINARY" ]; then
|
|
26
|
+
echo "SisyphusNotify.app is up to date"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
echo "Building $APP_NAME.app..."
|
|
31
|
+
|
|
32
|
+
# Create bundle structure
|
|
33
|
+
mkdir -p "$MACOS_DIR"
|
|
34
|
+
|
|
35
|
+
# Compile
|
|
36
|
+
swiftc \
|
|
37
|
+
-O \
|
|
38
|
+
-o "$BINARY" \
|
|
39
|
+
-framework Cocoa \
|
|
40
|
+
-framework UserNotifications \
|
|
41
|
+
"$SRC_DIR/main.swift"
|
|
42
|
+
|
|
43
|
+
# Copy Info.plist
|
|
44
|
+
cp "$SRC_DIR/Info.plist" "$CONTENTS/Info.plist"
|
|
45
|
+
|
|
46
|
+
# Copy icon if available
|
|
47
|
+
RESOURCES_DIR="$CONTENTS/Resources"
|
|
48
|
+
if [ -f "$SRC_DIR/AppIcon.icns" ]; then
|
|
49
|
+
mkdir -p "$RESOURCES_DIR"
|
|
50
|
+
cp "$SRC_DIR/AppIcon.icns" "$RESOURCES_DIR/AppIcon.icns"
|
|
51
|
+
# Create PNG for notification attachment
|
|
52
|
+
sips -s format png "$SRC_DIR/AppIcon.icns" --out "$RESOURCES_DIR/icon.png" --resampleWidth 256 >/dev/null 2>&1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Ad-hoc sign
|
|
56
|
+
codesign -s - --force "$APP_BUNDLE"
|
|
57
|
+
|
|
58
|
+
echo "Built: $APP_BUNDLE"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sisyphi",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.18",
|
|
4
4
|
"description": "tmux-integrated orchestration daemon for Claude Code multi-agent workflows",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
24
|
"templates",
|
|
25
|
+
"native",
|
|
25
26
|
"README.md"
|
|
26
27
|
],
|
|
27
28
|
"bin": {
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"dev": "tsup --watch",
|
|
34
35
|
"dev:daemon": "tsup --watch --onSuccess 'node dist/daemon.js restart'",
|
|
35
36
|
"test": "node --import tsx --test src/__tests__/*.test.ts",
|
|
36
|
-
"postinstall": "chmod +x node_modules/node-pty/prebuilds/*/spawn-helper 2>/dev/null || true",
|
|
37
|
+
"postinstall": "chmod +x node_modules/node-pty/prebuilds/*/spawn-helper 2>/dev/null || true; bash native/build-notify.sh 2>/dev/null || true",
|
|
37
38
|
"prepublishOnly": "npm run build && npm test"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
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 daemonUpdatingPath(): string {\n return join(globalDir(), 'updating');\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\nexport function messagesDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'messages');\n}\n\nexport function promptsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'prompts');\n}\n\nexport function contextDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'context');\n}\n\nexport function roadmapPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'roadmap.md');\n}\n\nexport function goalPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'goal.md');\n}\n\nexport function strategyPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'strategy.md');\n}\n\nexport function logsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'logs');\n}\n\nexport function cycleLogPath(cwd: string, sessionId: string, cycle: number): string {\n return join(logsDir(cwd, sessionId), `cycle-${String(cycle).padStart(3, '0')}.md`);\n}\n\n// Backwards compat for old sessions\nexport function legacyLogsPath(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'logs.md');\n}\n\nexport function snapshotsDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), 'snapshots');\n}\n\nexport function snapshotDir(cwd: string, sessionId: string, cycle: number): string {\n return join(snapshotsDir(cwd, sessionId), `cycle-${cycle}`);\n}\n\nexport function tuiScratchDir(cwd: string, sessionId: string): string {\n return join(sessionDir(cwd, sessionId), '.tui');\n}\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;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,UAAU,GAAG,YAAY;AACvC;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,UAAU,GAAG,YAAY;AACvC;AAEO,SAAS,qBAA6B;AAC3C,SAAO,KAAK,UAAU,GAAG,UAAU;AACrC;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;AAEO,SAAS,YAAY,KAAa,WAA2B;AAClE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,UAAU;AACpD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,WAAW,KAAa,WAA2B;AACjE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,YAAY,KAAa,WAA2B;AAClE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,YAAY;AACtD;AAEO,SAAS,SAAS,KAAa,WAA2B;AAC/D,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,aAAa,KAAa,WAA2B;AACnE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,aAAa;AACvD;AAEO,SAAS,QAAQ,KAAa,WAA2B;AAC9D,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,MAAM;AAChD;AAEO,SAAS,aAAa,KAAa,WAAmB,OAAuB;AAClF,SAAO,KAAK,QAAQ,KAAK,SAAS,GAAG,SAAS,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK;AACnF;AAGO,SAAS,eAAe,KAAa,WAA2B;AACrE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,SAAS;AACnD;AAEO,SAAS,aAAa,KAAa,WAA2B;AACnE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,WAAW;AACrD;AAEO,SAAS,YAAY,KAAa,WAAmB,OAAuB;AACjF,SAAO,KAAK,aAAa,KAAK,SAAS,GAAG,SAAS,KAAK,EAAE;AAC5D;AAEO,SAAS,cAAc,KAAa,WAA2B;AACpE,SAAO,KAAK,WAAW,KAAK,SAAS,GAAG,MAAM;AAChD;","names":[]}
|
package/dist/chunk-HQZOAX6D.js
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
goalPath,
|
|
4
|
-
roadmapPath,
|
|
5
|
-
sessionsDir,
|
|
6
|
-
socketPath,
|
|
7
|
-
statePath
|
|
8
|
-
} from "./chunk-GSXF3TCZ.js";
|
|
9
|
-
|
|
10
|
-
// src/shared/utils.ts
|
|
11
|
-
function computeActiveTimeMs(session) {
|
|
12
|
-
return session.activeMs;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// src/shared/format.ts
|
|
16
|
-
function formatDuration(startOrMs, endIso) {
|
|
17
|
-
let totalMs;
|
|
18
|
-
if (typeof startOrMs === "number") {
|
|
19
|
-
totalMs = startOrMs;
|
|
20
|
-
} else {
|
|
21
|
-
const start = new Date(startOrMs).getTime();
|
|
22
|
-
const end = endIso ? new Date(endIso).getTime() : Date.now();
|
|
23
|
-
totalMs = end - start;
|
|
24
|
-
}
|
|
25
|
-
const totalSeconds = Math.floor(totalMs / 1e3);
|
|
26
|
-
if (totalSeconds < 0) return "0s";
|
|
27
|
-
const hours = Math.floor(totalSeconds / 3600);
|
|
28
|
-
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
29
|
-
const seconds = totalSeconds % 60;
|
|
30
|
-
if (hours > 0) return `${hours}h${minutes}m`;
|
|
31
|
-
if (minutes > 0) return `${minutes}m${seconds}s`;
|
|
32
|
-
return `${seconds}s`;
|
|
33
|
-
}
|
|
34
|
-
function statusColor(status) {
|
|
35
|
-
switch (status) {
|
|
36
|
-
case "active":
|
|
37
|
-
case "running":
|
|
38
|
-
return "green";
|
|
39
|
-
case "completed":
|
|
40
|
-
return "cyan";
|
|
41
|
-
case "paused":
|
|
42
|
-
return "yellow";
|
|
43
|
-
case "killed":
|
|
44
|
-
case "crashed":
|
|
45
|
-
return "red";
|
|
46
|
-
case "lost":
|
|
47
|
-
return "gray";
|
|
48
|
-
default:
|
|
49
|
-
return "white";
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/tui/lib/reports.ts
|
|
54
|
-
import { readFileSync } from "fs";
|
|
55
|
-
function loadReportContent(report) {
|
|
56
|
-
try {
|
|
57
|
-
return readFileSync(report.filePath, "utf-8");
|
|
58
|
-
} catch {
|
|
59
|
-
return report.summary;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function resolveReports(reports) {
|
|
63
|
-
return [...reports].reverse().map((r) => ({
|
|
64
|
-
type: r.type,
|
|
65
|
-
timestamp: r.timestamp,
|
|
66
|
-
content: loadReportContent(r),
|
|
67
|
-
summary: r.summary
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/tui/lib/context.ts
|
|
72
|
-
import { readFileSync as readFileSync2, readdirSync } from "fs";
|
|
73
|
-
function readFileSafe(filePath) {
|
|
74
|
-
try {
|
|
75
|
-
return readFileSync2(filePath, "utf-8");
|
|
76
|
-
} catch {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
function escapeXml(s) {
|
|
81
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
82
|
-
}
|
|
83
|
-
function buildCompanionContext(cwd) {
|
|
84
|
-
let sessionDirs;
|
|
85
|
-
try {
|
|
86
|
-
sessionDirs = readdirSync(sessionsDir(cwd));
|
|
87
|
-
} catch {
|
|
88
|
-
return "<sessions>No sessions found.</sessions>";
|
|
89
|
-
}
|
|
90
|
-
const now = Date.now();
|
|
91
|
-
const sevenDaysMs = 7 * 24 * 60 * 60 * 1e3;
|
|
92
|
-
const sessionBlocks = [];
|
|
93
|
-
for (const sessionId of sessionDirs) {
|
|
94
|
-
const stateRaw = readFileSafe(statePath(cwd, sessionId));
|
|
95
|
-
if (!stateRaw) continue;
|
|
96
|
-
let session;
|
|
97
|
-
try {
|
|
98
|
-
session = JSON.parse(stateRaw);
|
|
99
|
-
} catch {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (session.status === "completed" && session.completedAt) {
|
|
103
|
-
if (now - new Date(session.completedAt).getTime() > sevenDaysMs) continue;
|
|
104
|
-
}
|
|
105
|
-
const lines = [];
|
|
106
|
-
const nameAttr = session.name ? ` name="${escapeXml(session.name)}"` : "";
|
|
107
|
-
lines.push(` <session id="${escapeXml(session.id)}"${nameAttr} status="${escapeXml(session.status)}">`);
|
|
108
|
-
lines.push(` <task>${escapeXml(session.task)}</task>`);
|
|
109
|
-
lines.push(` <created>${escapeXml(session.createdAt)}</created>`);
|
|
110
|
-
lines.push(` <cycles>${session.orchestratorCycles.length}</cycles>`);
|
|
111
|
-
if (session.status === "completed") {
|
|
112
|
-
if (session.completionReport) {
|
|
113
|
-
const snippet = session.completionReport.slice(0, 300).replace(/\n+/g, " ").trim();
|
|
114
|
-
lines.push(` <completion-report>${escapeXml(snippet)}${session.completionReport.length > 300 ? "\u2026" : ""}</completion-report>`);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
if (session.agents.length > 0) {
|
|
118
|
-
const counts = /* @__PURE__ */ new Map();
|
|
119
|
-
for (const agent of session.agents) {
|
|
120
|
-
counts.set(agent.status, (counts.get(agent.status) ?? 0) + 1);
|
|
121
|
-
}
|
|
122
|
-
const summary = [...counts.entries()].map(([status, n]) => `${n} ${status}`).join(", ");
|
|
123
|
-
lines.push(` <agents>${escapeXml(summary)}</agents>`);
|
|
124
|
-
}
|
|
125
|
-
const goalContent = readFileSafe(goalPath(cwd, session.id));
|
|
126
|
-
if (goalContent) {
|
|
127
|
-
const firstLine = goalContent.split("\n").map((l) => l.trim()).find((l) => l.length > 0 && !l.startsWith("#"));
|
|
128
|
-
if (firstLine) lines.push(` <goal>${escapeXml(firstLine)}</goal>`);
|
|
129
|
-
}
|
|
130
|
-
const roadmapContent = readFileSafe(roadmapPath(cwd, session.id));
|
|
131
|
-
if (roadmapContent) {
|
|
132
|
-
const todos = roadmapContent.split("\n").filter((l) => l.includes("- [ ]")).slice(0, 5).map((l) => l.trim());
|
|
133
|
-
if (todos.length > 0) {
|
|
134
|
-
lines.push(" <todos>");
|
|
135
|
-
for (const todo of todos) lines.push(` ${escapeXml(todo)}`);
|
|
136
|
-
lines.push(" </todos>");
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
lines.push(" </session>");
|
|
141
|
-
sessionBlocks.push(lines.join("\n"));
|
|
142
|
-
}
|
|
143
|
-
if (sessionBlocks.length === 0) {
|
|
144
|
-
return "<sessions>No sessions found.</sessions>";
|
|
145
|
-
}
|
|
146
|
-
return ["<sessions>", ...sessionBlocks, "</sessions>"].join("\n");
|
|
147
|
-
}
|
|
148
|
-
function buildSessionContext(session, cwd) {
|
|
149
|
-
const goal = readFileSafe(goalPath(cwd, session.id));
|
|
150
|
-
const roadmap = readFileSafe(roadmapPath(cwd, session.id));
|
|
151
|
-
const agentsXml = session.agents.map((agent) => {
|
|
152
|
-
const reportBlocks = resolveReports(agent.reports);
|
|
153
|
-
const reportsXml = [...reportBlocks].reverse().map((block) => {
|
|
154
|
-
return ` <report type="${block.type}" time="${escapeXml(block.timestamp)}">${escapeXml(block.content)}</report>`;
|
|
155
|
-
}).join("\n");
|
|
156
|
-
return [
|
|
157
|
-
` <agent id="${escapeXml(agent.id)}" name="${escapeXml(agent.name)}" type="${escapeXml(agent.agentType)}" status="${escapeXml(agent.status)}">`,
|
|
158
|
-
` <instruction>${escapeXml(agent.instruction)}</instruction>`,
|
|
159
|
-
...reportsXml ? [reportsXml] : [],
|
|
160
|
-
` </agent>`
|
|
161
|
-
].join("\n");
|
|
162
|
-
}).join("\n");
|
|
163
|
-
const cyclesXml = session.orchestratorCycles.map((cycle) => {
|
|
164
|
-
const agents = cycle.agentsSpawned.join(", ");
|
|
165
|
-
const mode = cycle.mode ? ` mode="${escapeXml(cycle.mode)}"` : "";
|
|
166
|
-
return ` <cycle number="${cycle.cycle}"${mode} agents="${escapeXml(agents)}" />`;
|
|
167
|
-
}).join("\n");
|
|
168
|
-
const lines = [
|
|
169
|
-
"<context>",
|
|
170
|
-
`<session id="${escapeXml(session.id)}" status="${escapeXml(session.status)}">`,
|
|
171
|
-
` <task>${escapeXml(session.task)}</task>`,
|
|
172
|
-
` <cwd>${escapeXml(session.cwd)}</cwd>`
|
|
173
|
-
];
|
|
174
|
-
if (goal) lines.push(` <goal>${escapeXml(goal)}</goal>`);
|
|
175
|
-
if (roadmap) lines.push(` <roadmap>${escapeXml(roadmap)}</roadmap>`);
|
|
176
|
-
if (session.agents.length > 0) {
|
|
177
|
-
lines.push(" <agents>");
|
|
178
|
-
lines.push(agentsXml);
|
|
179
|
-
lines.push(" </agents>");
|
|
180
|
-
}
|
|
181
|
-
if (session.orchestratorCycles.length > 0) {
|
|
182
|
-
lines.push(" <cycles>");
|
|
183
|
-
lines.push(cyclesXml);
|
|
184
|
-
lines.push(" </cycles>");
|
|
185
|
-
}
|
|
186
|
-
if (session.completionReport) {
|
|
187
|
-
lines.push(` <completion-report>${escapeXml(session.completionReport)}</completion-report>`);
|
|
188
|
-
}
|
|
189
|
-
lines.push("</session>");
|
|
190
|
-
lines.push("</context>");
|
|
191
|
-
return lines.join("\n");
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// src/shared/client.ts
|
|
195
|
-
import { connect } from "net";
|
|
196
|
-
function rawSend(request, timeoutMs = 1e4) {
|
|
197
|
-
const sock = socketPath();
|
|
198
|
-
return new Promise((resolve, reject) => {
|
|
199
|
-
const socket = connect(sock);
|
|
200
|
-
let data = "";
|
|
201
|
-
const timeout = setTimeout(() => {
|
|
202
|
-
socket.destroy();
|
|
203
|
-
reject(new Error(`Request timed out after ${(timeoutMs / 1e3).toFixed(0)}s. The daemon may be overloaded.
|
|
204
|
-
Check: sisyphus doctor
|
|
205
|
-
Logs: tail -20 ~/.sisyphus/daemon.log`));
|
|
206
|
-
}, timeoutMs);
|
|
207
|
-
socket.on("connect", () => {
|
|
208
|
-
socket.write(JSON.stringify(request) + "\n");
|
|
209
|
-
});
|
|
210
|
-
socket.on("data", (chunk) => {
|
|
211
|
-
data += chunk.toString();
|
|
212
|
-
const newlineIdx = data.indexOf("\n");
|
|
213
|
-
if (newlineIdx !== -1) {
|
|
214
|
-
clearTimeout(timeout);
|
|
215
|
-
const line = data.slice(0, newlineIdx);
|
|
216
|
-
socket.destroy();
|
|
217
|
-
try {
|
|
218
|
-
resolve(JSON.parse(line));
|
|
219
|
-
} catch {
|
|
220
|
-
reject(new Error(`Invalid JSON response from daemon: ${line}`));
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
socket.on("error", (err) => {
|
|
225
|
-
clearTimeout(timeout);
|
|
226
|
-
reject(err);
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
export {
|
|
232
|
-
rawSend,
|
|
233
|
-
computeActiveTimeMs,
|
|
234
|
-
formatDuration,
|
|
235
|
-
statusColor,
|
|
236
|
-
resolveReports,
|
|
237
|
-
buildCompanionContext,
|
|
238
|
-
buildSessionContext
|
|
239
|
-
};
|
|
240
|
-
//# sourceMappingURL=chunk-HQZOAX6D.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/utils.ts","../src/shared/format.ts","../src/tui/lib/reports.ts","../src/tui/lib/context.ts","../src/shared/client.ts"],"sourcesContent":["import type { Session } from './types.js';\n\n/**\n * Return the tracked active time for a session.\n * Active time is accumulated by the daemon's pane monitor, excluding sleep/idle gaps.\n */\nexport function computeActiveTimeMs(session: Session): number {\n return session.activeMs;\n}\n","/** Format milliseconds or ISO date range to human-readable duration */\nexport function formatDuration(startOrMs: string | number, endIso?: string | null): string {\n let totalMs: number;\n if (typeof startOrMs === 'number') {\n totalMs = startOrMs;\n } else {\n const start = new Date(startOrMs).getTime();\n const end = endIso ? new Date(endIso).getTime() : Date.now();\n totalMs = end - start;\n }\n const totalSeconds = Math.floor(totalMs / 1000);\n if (totalSeconds < 0) return '0s';\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n if (hours > 0) return `${hours}h${minutes}m`;\n if (minutes > 0) return `${minutes}m${seconds}s`;\n return `${seconds}s`;\n}\n\n/** Map session/agent status to a color name */\nexport function statusColor(status: string): string {\n switch (status) {\n case 'active':\n case 'running':\n return 'green';\n case 'completed':\n return 'cyan';\n case 'paused':\n return 'yellow';\n case 'killed':\n case 'crashed':\n return 'red';\n case 'lost':\n return 'gray';\n default:\n return 'white';\n }\n}\n","import { readFileSync } from 'node:fs';\nimport type { AgentReport } from '../../shared/types.js';\n\nexport interface ReportBlock {\n type: 'update' | 'final';\n timestamp: string;\n content: string;\n summary: string;\n}\n\nfunction loadReportContent(report: AgentReport): string {\n try {\n return readFileSync(report.filePath, 'utf-8');\n } catch {\n return report.summary;\n }\n}\n\nexport function resolveReports(reports: AgentReport[]): ReportBlock[] {\n return [...reports].reverse().map((r) => ({\n type: r.type as 'update' | 'final',\n timestamp: r.timestamp,\n content: loadReportContent(r),\n summary: r.summary,\n }));\n}\n","import { readFileSync, readdirSync } from 'node:fs';\nimport { goalPath, roadmapPath, sessionsDir, statePath } from '../../shared/paths.js';\nimport { resolveReports } from './reports.js';\nimport type { Session, AgentStatus } from '../../shared/types.js';\n\nfunction readFileSafe(filePath: string): string | null {\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\nexport function buildCompanionContext(cwd: string): string {\n let sessionDirs: string[];\n try {\n sessionDirs = readdirSync(sessionsDir(cwd));\n } catch {\n return '<sessions>No sessions found.</sessions>';\n }\n\n const now = Date.now();\n const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;\n const sessionBlocks: string[] = [];\n\n for (const sessionId of sessionDirs) {\n const stateRaw = readFileSafe(statePath(cwd, sessionId));\n if (!stateRaw) continue;\n\n let session: Session;\n try {\n session = JSON.parse(stateRaw) as Session;\n } catch {\n continue;\n }\n\n // Skip completed sessions older than 7 days\n if (session.status === 'completed' && session.completedAt) {\n if (now - new Date(session.completedAt).getTime() > sevenDaysMs) continue;\n }\n\n const lines: string[] = [];\n const nameAttr = session.name ? ` name=\"${escapeXml(session.name)}\"` : '';\n lines.push(` <session id=\"${escapeXml(session.id)}\"${nameAttr} status=\"${escapeXml(session.status)}\">`);\n lines.push(` <task>${escapeXml(session.task)}</task>`);\n lines.push(` <created>${escapeXml(session.createdAt)}</created>`);\n lines.push(` <cycles>${session.orchestratorCycles.length}</cycles>`);\n\n if (session.status === 'completed') {\n if (session.completionReport) {\n const snippet = session.completionReport.slice(0, 300).replace(/\\n+/g, ' ').trim();\n lines.push(` <completion-report>${escapeXml(snippet)}${session.completionReport.length > 300 ? '…' : ''}</completion-report>`);\n }\n } else {\n // Agent summary by status\n if (session.agents.length > 0) {\n const counts = new Map<AgentStatus, number>();\n for (const agent of session.agents) {\n counts.set(agent.status, (counts.get(agent.status) ?? 0) + 1);\n }\n const summary = [...counts.entries()].map(([status, n]) => `${n} ${status}`).join(', ');\n lines.push(` <agents>${escapeXml(summary)}</agents>`);\n }\n\n // Goal: first meaningful line\n const goalContent = readFileSafe(goalPath(cwd, session.id));\n if (goalContent) {\n const firstLine = goalContent.split('\\n').map(l => l.trim()).find(l => l.length > 0 && !l.startsWith('#'));\n if (firstLine) lines.push(` <goal>${escapeXml(firstLine)}</goal>`);\n }\n\n // Roadmap unchecked todos (up to 5)\n const roadmapContent = readFileSafe(roadmapPath(cwd, session.id));\n if (roadmapContent) {\n const todos = roadmapContent\n .split('\\n')\n .filter(l => l.includes('- [ ]'))\n .slice(0, 5)\n .map(l => l.trim());\n if (todos.length > 0) {\n lines.push(' <todos>');\n for (const todo of todos) lines.push(` ${escapeXml(todo)}`);\n lines.push(' </todos>');\n }\n }\n }\n\n lines.push(' </session>');\n sessionBlocks.push(lines.join('\\n'));\n }\n\n if (sessionBlocks.length === 0) {\n return '<sessions>No sessions found.</sessions>';\n }\n\n return ['<sessions>', ...sessionBlocks, '</sessions>'].join('\\n');\n}\n\nexport function buildSessionContext(session: Session, cwd: string): string {\n const goal = readFileSafe(goalPath(cwd, session.id));\n const roadmap = readFileSafe(roadmapPath(cwd, session.id));\n\n const agentsXml = session.agents.map((agent) => {\n const reportBlocks = resolveReports(agent.reports);\n // resolveReports returns newest-first; reverse to chronological for context\n const reportsXml = [...reportBlocks].reverse().map((block) => {\n return ` <report type=\"${block.type}\" time=\"${escapeXml(block.timestamp)}\">${escapeXml(block.content)}</report>`;\n }).join('\\n');\n\n return [\n ` <agent id=\"${escapeXml(agent.id)}\" name=\"${escapeXml(agent.name)}\" type=\"${escapeXml(agent.agentType)}\" status=\"${escapeXml(agent.status)}\">`,\n ` <instruction>${escapeXml(agent.instruction)}</instruction>`,\n ...(reportsXml ? [reportsXml] : []),\n ` </agent>`,\n ].join('\\n');\n }).join('\\n');\n\n const cyclesXml = session.orchestratorCycles.map((cycle) => {\n const agents = cycle.agentsSpawned.join(', ');\n const mode = cycle.mode ? ` mode=\"${escapeXml(cycle.mode)}\"` : '';\n return ` <cycle number=\"${cycle.cycle}\"${mode} agents=\"${escapeXml(agents)}\" />`;\n }).join('\\n');\n\n const lines: string[] = [\n '<context>',\n `<session id=\"${escapeXml(session.id)}\" status=\"${escapeXml(session.status)}\">`,\n ` <task>${escapeXml(session.task)}</task>`,\n ` <cwd>${escapeXml(session.cwd)}</cwd>`,\n ];\n\n if (goal) lines.push(` <goal>${escapeXml(goal)}</goal>`);\n if (roadmap) lines.push(` <roadmap>${escapeXml(roadmap)}</roadmap>`);\n\n if (session.agents.length > 0) {\n lines.push(' <agents>');\n lines.push(agentsXml);\n lines.push(' </agents>');\n }\n\n if (session.orchestratorCycles.length > 0) {\n lines.push(' <cycles>');\n lines.push(cyclesXml);\n lines.push(' </cycles>');\n }\n\n if (session.completionReport) {\n lines.push(` <completion-report>${escapeXml(session.completionReport)}</completion-report>`);\n }\n\n lines.push('</session>');\n lines.push('</context>');\n\n return lines.join('\\n');\n}\n","import { connect } from 'node:net';\nimport { socketPath } from './paths.js';\nimport type { Request, Response } from './protocol.js';\n\nexport function rawSend(request: Request, timeoutMs = 10_000): Promise<Response> {\n const sock = socketPath();\n\n return new Promise<Response>((resolve, reject) => {\n const socket = connect(sock);\n let data = '';\n\n const timeout = setTimeout(() => {\n socket.destroy();\n reject(new Error(`Request timed out after ${(timeoutMs / 1000).toFixed(0)}s. The daemon may be overloaded.\\n Check: sisyphus doctor\\n Logs: tail -20 ~/.sisyphus/daemon.log`));\n }, timeoutMs);\n\n socket.on('connect', () => {\n socket.write(JSON.stringify(request) + '\\n');\n });\n\n socket.on('data', (chunk) => {\n data += chunk.toString();\n const newlineIdx = data.indexOf('\\n');\n if (newlineIdx !== -1) {\n clearTimeout(timeout);\n const line = data.slice(0, newlineIdx);\n socket.destroy();\n try {\n resolve(JSON.parse(line) as Response);\n } catch {\n reject(new Error(`Invalid JSON response from daemon: ${line}`));\n }\n }\n });\n\n socket.on('error', (err) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n}\n"],"mappings":"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","names":["readFileSync","readFileSync"]}
|
package/dist/chunk-IF55HPWX.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
globalConfigPath,
|
|
4
|
-
projectConfigPath
|
|
5
|
-
} from "./chunk-GSXF3TCZ.js";
|
|
6
|
-
|
|
7
|
-
// src/shared/config.ts
|
|
8
|
-
import { readFileSync } from "fs";
|
|
9
|
-
var DEFAULT_CONFIG = {
|
|
10
|
-
pollIntervalMs: 5e3,
|
|
11
|
-
orchestratorEffort: "high",
|
|
12
|
-
agentEffort: "medium",
|
|
13
|
-
notifications: {
|
|
14
|
-
enabled: true,
|
|
15
|
-
sound: "/System/Library/Sounds/Hero.aiff"
|
|
16
|
-
},
|
|
17
|
-
requiredPlugins: [
|
|
18
|
-
{ name: "devcore", marketplace: "crouton-kit" }
|
|
19
|
-
]
|
|
20
|
-
};
|
|
21
|
-
function readJsonFile(filePath) {
|
|
22
|
-
try {
|
|
23
|
-
const content = readFileSync(filePath, "utf-8");
|
|
24
|
-
return JSON.parse(content);
|
|
25
|
-
} catch {
|
|
26
|
-
return {};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
function loadConfig(cwd) {
|
|
30
|
-
const global = readJsonFile(globalConfigPath());
|
|
31
|
-
const project = readJsonFile(projectConfigPath(cwd));
|
|
32
|
-
return { ...DEFAULT_CONFIG, ...global, ...project };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// src/shared/shell.ts
|
|
36
|
-
function shellQuote(s) {
|
|
37
|
-
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
loadConfig,
|
|
42
|
-
shellQuote
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=chunk-IF55HPWX.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/config.ts","../src/shared/shell.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { globalConfigPath, projectConfigPath } from './paths.js';\n\nexport type EffortLevel = 'low' | 'medium' | 'high' | 'max';\n\nexport interface NotificationConfig {\n enabled?: boolean;\n sound?: string;\n}\n\nexport interface RequiredPlugin {\n name: string;\n marketplace: string;\n}\n\nexport interface Config {\n model?: string;\n tmuxSession?: string;\n orchestratorPrompt?: string;\n pollIntervalMs?: number;\n autoUpdate?: boolean;\n orchestratorEffort?: EffortLevel;\n agentEffort?: EffortLevel;\n editor?: string;\n repos?: string[];\n notifications?: NotificationConfig;\n requiredPlugins?: RequiredPlugin[];\n}\n\nconst DEFAULT_CONFIG: Config = {\n pollIntervalMs: 5000,\n orchestratorEffort: 'high',\n agentEffort: 'medium',\n notifications: {\n enabled: true,\n sound: '/System/Library/Sounds/Hero.aiff',\n },\n requiredPlugins: [\n { name: 'devcore', marketplace: 'crouton-kit' },\n ],\n};\n\nfunction readJsonFile(filePath: string): Partial<Config> {\n try {\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as Partial<Config>;\n } catch {\n return {};\n }\n}\n\nexport function loadConfig(cwd: string): Config {\n const global = readJsonFile(globalConfigPath());\n const project = readJsonFile(projectConfigPath(cwd));\n return { ...DEFAULT_CONFIG, ...global, ...project };\n}\n","export function shellQuote(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n"],"mappings":";;;;;;;AAAA,SAAS,oBAAoB;AA6B7B,IAAM,iBAAyB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,eAAe;AAAA,IACb,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,iBAAiB;AAAA,IACf,EAAE,MAAM,WAAW,aAAa,cAAc;AAAA,EAChD;AACF;AAEA,SAAS,aAAa,UAAmC;AACvD,MAAI;AACF,UAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,WAAW,KAAqB;AAC9C,QAAM,SAAS,aAAa,iBAAiB,CAAC;AAC9C,QAAM,UAAU,aAAa,kBAAkB,GAAG,CAAC;AACnD,SAAO,EAAE,GAAG,gBAAgB,GAAG,QAAQ,GAAG,QAAQ;AACpD;;;ACvDO,SAAS,WAAW,GAAmB;AAC5C,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;","names":[]}
|
|
File without changes
|
|
File without changes
|