sisyphi 1.1.32 → 1.1.33
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 +1 -0
- package/dist/cli.js +132 -67
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +692 -322
- package/dist/daemon.js.map +1 -1
- package/dist/templates/agent-plugin/hooks/hooks.json +51 -0
- package/dist/tui.js +103 -41
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
- package/templates/agent-plugin/hooks/hooks.json +51 -0
package/README.md
CHANGED
|
@@ -160,6 +160,7 @@ Key bindings — navigate mode:
|
|
|
160
160
|
| `e` | Edit context file |
|
|
161
161
|
| `S` | Session info |
|
|
162
162
|
| `F` | Filter / search |
|
|
163
|
+
| `D` | Toggle DANGEROUS mode for the selected session (auto-accepts the default for every ask) |
|
|
163
164
|
| `c` | Open companion overlay |
|
|
164
165
|
| `/` | Search sessions |
|
|
165
166
|
| `q` | Quit |
|
package/dist/cli.js
CHANGED
|
@@ -36,6 +36,12 @@ function projectDir(cwd) {
|
|
|
36
36
|
function projectConfigPath(cwd) {
|
|
37
37
|
return join(projectDir(cwd), "config.json");
|
|
38
38
|
}
|
|
39
|
+
function projectAgentPluginDir(cwd) {
|
|
40
|
+
return join(projectDir(cwd), "agent-plugin");
|
|
41
|
+
}
|
|
42
|
+
function userAgentPluginDir() {
|
|
43
|
+
return join(globalDir(), "agent-plugin");
|
|
44
|
+
}
|
|
39
45
|
function sessionsDir(cwd) {
|
|
40
46
|
return join(projectDir(cwd), "sessions");
|
|
41
47
|
}
|
|
@@ -3282,13 +3288,79 @@ function emitHistoryEvent(sessionId, event, data) {
|
|
|
3282
3288
|
}
|
|
3283
3289
|
}
|
|
3284
3290
|
|
|
3291
|
+
// src/daemon/state.ts
|
|
3292
|
+
init_atomic();
|
|
3293
|
+
init_paths();
|
|
3294
|
+
import { copyFileSync, cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync11, readdirSync as readdirSync2, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
3295
|
+
import { join as join10 } from "path";
|
|
3296
|
+
|
|
3297
|
+
// src/shared/gitignore.ts
|
|
3298
|
+
import { existsSync as existsSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
|
|
3299
|
+
import { join as join9 } from "path";
|
|
3300
|
+
|
|
3301
|
+
// src/shared/types.ts
|
|
3302
|
+
var ORCHESTRATOR_ASKED_BY = "orchestrator";
|
|
3303
|
+
|
|
3304
|
+
// src/daemon/state.ts
|
|
3305
|
+
function withSessionLock(sessionId, fn) {
|
|
3306
|
+
return withLock(sessionId, fn);
|
|
3307
|
+
}
|
|
3308
|
+
function getSession(cwd, sessionId) {
|
|
3309
|
+
const content = readFileSync11(statePath(cwd, sessionId), "utf-8");
|
|
3310
|
+
const session2 = JSON.parse(content);
|
|
3311
|
+
if (session2.activeMs == null) session2.activeMs = 0;
|
|
3312
|
+
if (session2.userBlockedMs == null) session2.userBlockedMs = 0;
|
|
3313
|
+
for (const agent2 of session2.agents) {
|
|
3314
|
+
if (!agent2.repo) agent2.repo = ".";
|
|
3315
|
+
if (agent2.activeMs == null) agent2.activeMs = 0;
|
|
3316
|
+
if (agent2.orphaned == null) agent2.orphaned = false;
|
|
3317
|
+
}
|
|
3318
|
+
if (session2.orphaned == null) session2.orphaned = false;
|
|
3319
|
+
for (const cycle of session2.orchestratorCycles) {
|
|
3320
|
+
if (cycle.activeMs == null) cycle.activeMs = 0;
|
|
3321
|
+
if (cycle.userBlockedMs == null) cycle.userBlockedMs = 0;
|
|
3322
|
+
}
|
|
3323
|
+
return session2;
|
|
3324
|
+
}
|
|
3325
|
+
function saveSession(session2) {
|
|
3326
|
+
atomicWrite(statePath(session2.cwd, session2.id), JSON.stringify(session2, null, 2));
|
|
3327
|
+
}
|
|
3328
|
+
function isSessionDangerous(cwd, sessionId) {
|
|
3329
|
+
try {
|
|
3330
|
+
return getSession(cwd, sessionId).dangerousMode === true;
|
|
3331
|
+
} catch {
|
|
3332
|
+
return false;
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
async function incrementUserBlockedMs(cwd, sessionId, deltaMs, askedAt, askedBy) {
|
|
3336
|
+
if (deltaMs <= 0) return;
|
|
3337
|
+
return withSessionLock(sessionId, () => {
|
|
3338
|
+
const session2 = getSession(cwd, sessionId);
|
|
3339
|
+
session2.userBlockedMs = (session2.userBlockedMs ?? 0) + deltaMs;
|
|
3340
|
+
if (askedAt) {
|
|
3341
|
+
const askedAtMs = new Date(askedAt).getTime();
|
|
3342
|
+
const cycle = session2.orchestratorCycles.find((c2) => {
|
|
3343
|
+
const startMs = new Date(c2.timestamp).getTime();
|
|
3344
|
+
const endMs = c2.completedAt ? new Date(c2.completedAt).getTime() : Infinity;
|
|
3345
|
+
return startMs <= askedAtMs && askedAtMs < endMs;
|
|
3346
|
+
});
|
|
3347
|
+
if (cycle) cycle.userBlockedMs = (cycle.userBlockedMs ?? 0) + deltaMs;
|
|
3348
|
+
}
|
|
3349
|
+
if (askedBy && askedBy !== ORCHESTRATOR_ASKED_BY) {
|
|
3350
|
+
const agent2 = session2.agents.slice().reverse().find((a) => a.id === askedBy);
|
|
3351
|
+
if (agent2) agent2.userBlockedMs = (agent2.userBlockedMs ?? 0) + deltaMs;
|
|
3352
|
+
}
|
|
3353
|
+
saveSession(session2);
|
|
3354
|
+
});
|
|
3355
|
+
}
|
|
3356
|
+
|
|
3285
3357
|
// src/daemon/ask-store.ts
|
|
3286
3358
|
init_atomic();
|
|
3287
3359
|
|
|
3288
3360
|
// src/daemon/notify.ts
|
|
3289
3361
|
import { spawn, execFile } from "child_process";
|
|
3290
|
-
import { writeFileSync as
|
|
3291
|
-
import { join as
|
|
3362
|
+
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync5, existsSync as existsSync8 } from "fs";
|
|
3363
|
+
import { join as join11 } from "path";
|
|
3292
3364
|
import { homedir as homedir6 } from "os";
|
|
3293
3365
|
var TMUX_SOCKET = `/tmp/tmux-${process.getuid?.() ?? 0}/default`;
|
|
3294
3366
|
var SWITCH_SCRIPT = [
|
|
@@ -3331,24 +3403,24 @@ var SWITCH_SCRIPT = [
|
|
|
3331
3403
|
""
|
|
3332
3404
|
].join("\n");
|
|
3333
3405
|
function ensureSwitchScript() {
|
|
3334
|
-
const dir =
|
|
3335
|
-
const scriptPath2 =
|
|
3406
|
+
const dir = join11(homedir6(), ".sisyphus");
|
|
3407
|
+
const scriptPath2 = join11(dir, "notify-switch.sh");
|
|
3336
3408
|
try {
|
|
3337
|
-
|
|
3338
|
-
|
|
3409
|
+
mkdirSync5(dir, { recursive: true });
|
|
3410
|
+
writeFileSync7(scriptPath2, SWITCH_SCRIPT, { mode: 493 });
|
|
3339
3411
|
} catch {
|
|
3340
3412
|
}
|
|
3341
3413
|
}
|
|
3342
3414
|
var notifyProcess = null;
|
|
3343
3415
|
function getNotifyBinary() {
|
|
3344
|
-
return
|
|
3416
|
+
return join11(homedir6(), ".sisyphus", "SisyphusNotify.app", "Contents", "MacOS", "sisyphus-notify");
|
|
3345
3417
|
}
|
|
3346
3418
|
function ensureNotifyProcess() {
|
|
3347
3419
|
if (notifyProcess && !notifyProcess.killed && notifyProcess.stdin?.writable) {
|
|
3348
3420
|
return notifyProcess;
|
|
3349
3421
|
}
|
|
3350
3422
|
const binary = getNotifyBinary();
|
|
3351
|
-
if (!
|
|
3423
|
+
if (!existsSync8(binary)) {
|
|
3352
3424
|
return null;
|
|
3353
3425
|
}
|
|
3354
3426
|
notifyProcess = spawn(binary, [], {
|
|
@@ -3404,65 +3476,6 @@ function sendTerminalNotification(titleOrOpts, message, tmuxSession, level) {
|
|
|
3404
3476
|
});
|
|
3405
3477
|
}
|
|
3406
3478
|
|
|
3407
|
-
// src/daemon/state.ts
|
|
3408
|
-
init_atomic();
|
|
3409
|
-
init_paths();
|
|
3410
|
-
import { copyFileSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync11, readdirSync as readdirSync2, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
3411
|
-
import { join as join11 } from "path";
|
|
3412
|
-
|
|
3413
|
-
// src/shared/gitignore.ts
|
|
3414
|
-
import { existsSync as existsSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
3415
|
-
import { join as join10 } from "path";
|
|
3416
|
-
|
|
3417
|
-
// src/shared/types.ts
|
|
3418
|
-
var ORCHESTRATOR_ASKED_BY = "orchestrator";
|
|
3419
|
-
|
|
3420
|
-
// src/daemon/state.ts
|
|
3421
|
-
function withSessionLock(sessionId, fn) {
|
|
3422
|
-
return withLock(sessionId, fn);
|
|
3423
|
-
}
|
|
3424
|
-
function getSession(cwd, sessionId) {
|
|
3425
|
-
const content = readFileSync11(statePath(cwd, sessionId), "utf-8");
|
|
3426
|
-
const session2 = JSON.parse(content);
|
|
3427
|
-
if (session2.activeMs == null) session2.activeMs = 0;
|
|
3428
|
-
if (session2.userBlockedMs == null) session2.userBlockedMs = 0;
|
|
3429
|
-
for (const agent2 of session2.agents) {
|
|
3430
|
-
if (!agent2.repo) agent2.repo = ".";
|
|
3431
|
-
if (agent2.activeMs == null) agent2.activeMs = 0;
|
|
3432
|
-
if (agent2.orphaned == null) agent2.orphaned = false;
|
|
3433
|
-
}
|
|
3434
|
-
if (session2.orphaned == null) session2.orphaned = false;
|
|
3435
|
-
for (const cycle of session2.orchestratorCycles) {
|
|
3436
|
-
if (cycle.activeMs == null) cycle.activeMs = 0;
|
|
3437
|
-
if (cycle.userBlockedMs == null) cycle.userBlockedMs = 0;
|
|
3438
|
-
}
|
|
3439
|
-
return session2;
|
|
3440
|
-
}
|
|
3441
|
-
function saveSession(session2) {
|
|
3442
|
-
atomicWrite(statePath(session2.cwd, session2.id), JSON.stringify(session2, null, 2));
|
|
3443
|
-
}
|
|
3444
|
-
async function incrementUserBlockedMs(cwd, sessionId, deltaMs, askedAt, askedBy) {
|
|
3445
|
-
if (deltaMs <= 0) return;
|
|
3446
|
-
return withSessionLock(sessionId, () => {
|
|
3447
|
-
const session2 = getSession(cwd, sessionId);
|
|
3448
|
-
session2.userBlockedMs = (session2.userBlockedMs ?? 0) + deltaMs;
|
|
3449
|
-
if (askedAt) {
|
|
3450
|
-
const askedAtMs = new Date(askedAt).getTime();
|
|
3451
|
-
const cycle = session2.orchestratorCycles.find((c2) => {
|
|
3452
|
-
const startMs = new Date(c2.timestamp).getTime();
|
|
3453
|
-
const endMs = c2.completedAt ? new Date(c2.completedAt).getTime() : Infinity;
|
|
3454
|
-
return startMs <= askedAtMs && askedAtMs < endMs;
|
|
3455
|
-
});
|
|
3456
|
-
if (cycle) cycle.userBlockedMs = (cycle.userBlockedMs ?? 0) + deltaMs;
|
|
3457
|
-
}
|
|
3458
|
-
if (askedBy && askedBy !== ORCHESTRATOR_ASKED_BY) {
|
|
3459
|
-
const agent2 = session2.agents.slice().reverse().find((a) => a.id === askedBy);
|
|
3460
|
-
if (agent2) agent2.userBlockedMs = (agent2.userBlockedMs ?? 0) + deltaMs;
|
|
3461
|
-
}
|
|
3462
|
-
saveSession(session2);
|
|
3463
|
-
});
|
|
3464
|
-
}
|
|
3465
|
-
|
|
3466
3479
|
// src/daemon/ask-store.ts
|
|
3467
3480
|
var ACTIONABLE_KINDS = /* @__PURE__ */ new Set([
|
|
3468
3481
|
"validation",
|
|
@@ -3516,6 +3529,21 @@ function createAsk(cwd, sessionId, params) {
|
|
|
3516
3529
|
}
|
|
3517
3530
|
function writeDecisions(cwd, sessionId, askId, deck) {
|
|
3518
3531
|
atomicWrite(askDecisionsPath(cwd, sessionId, askId), JSON.stringify(deck, null, 2));
|
|
3532
|
+
void maybeAutoResolveAsk(cwd, sessionId, askId, deck);
|
|
3533
|
+
}
|
|
3534
|
+
function readDecisions(cwd, sessionId, askId) {
|
|
3535
|
+
const p = askDecisionsPath(cwd, sessionId, askId);
|
|
3536
|
+
try {
|
|
3537
|
+
return JSON.parse(readFileSync12(p, { encoding: "utf-8" }));
|
|
3538
|
+
} catch (_e) {
|
|
3539
|
+
return null;
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
function writeOutput(cwd, sessionId, askId, responses, completedAt) {
|
|
3543
|
+
atomicWrite(askOutputPath(cwd, sessionId, askId), JSON.stringify({
|
|
3544
|
+
responses,
|
|
3545
|
+
completedAt: completedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
3546
|
+
}, null, 2));
|
|
3519
3547
|
}
|
|
3520
3548
|
function readMeta(cwd, sessionId, askId) {
|
|
3521
3549
|
const p = askMetaPath(cwd, sessionId, askId);
|
|
@@ -3535,6 +3563,40 @@ async function updateMeta(cwd, sessionId, askId, patch) {
|
|
|
3535
3563
|
return next;
|
|
3536
3564
|
});
|
|
3537
3565
|
}
|
|
3566
|
+
function buildAutoResponses(deck) {
|
|
3567
|
+
const out = [];
|
|
3568
|
+
for (const interaction of deck.interactions) {
|
|
3569
|
+
const first = interaction.options[0];
|
|
3570
|
+
if (!first) continue;
|
|
3571
|
+
out.push({ id: interaction.id, selectedOptionId: first.id });
|
|
3572
|
+
}
|
|
3573
|
+
return out;
|
|
3574
|
+
}
|
|
3575
|
+
async function autoResolveAsk(cwd, sessionId, askId, deck) {
|
|
3576
|
+
try {
|
|
3577
|
+
if (existsSync9(askOutputPath(cwd, sessionId, askId))) return false;
|
|
3578
|
+
const d = deck ?? readDecisions(cwd, sessionId, askId);
|
|
3579
|
+
if (!d) return false;
|
|
3580
|
+
const responses = buildAutoResponses(d);
|
|
3581
|
+
if (responses.length === 0) return false;
|
|
3582
|
+
writeOutput(cwd, sessionId, askId, responses);
|
|
3583
|
+
await updateMeta(cwd, sessionId, askId, {
|
|
3584
|
+
status: "answered",
|
|
3585
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3586
|
+
});
|
|
3587
|
+
return true;
|
|
3588
|
+
} catch (err) {
|
|
3589
|
+
console.warn(`[sisyphus] dangerous-mode auto-resolve failed for ask ${askId}:`, err instanceof Error ? err.message : err);
|
|
3590
|
+
return false;
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
async function maybeAutoResolveAsk(cwd, sessionId, askId, deck) {
|
|
3594
|
+
try {
|
|
3595
|
+
if (!isSessionDangerous(cwd, sessionId)) return;
|
|
3596
|
+
await autoResolveAsk(cwd, sessionId, askId, deck);
|
|
3597
|
+
} catch {
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3538
3600
|
|
|
3539
3601
|
// src/cli/commands/ask.ts
|
|
3540
3602
|
init_paths();
|
|
@@ -4235,6 +4297,7 @@ import { existsSync as existsSync12 } from "fs";
|
|
|
4235
4297
|
import { join as join14, resolve as resolve5 } from "path";
|
|
4236
4298
|
|
|
4237
4299
|
// src/daemon/frontmatter.ts
|
|
4300
|
+
init_paths();
|
|
4238
4301
|
import { readFileSync as readFileSync16, existsSync as existsSync11, readdirSync as readdirSync5 } from "fs";
|
|
4239
4302
|
import { homedir as homedir7 } from "os";
|
|
4240
4303
|
import { join as join13, basename as basename4 } from "path";
|
|
@@ -4295,6 +4358,8 @@ function discoverAgentTypes(pluginDir, cwd) {
|
|
|
4295
4358
|
}
|
|
4296
4359
|
}
|
|
4297
4360
|
}
|
|
4361
|
+
scanDir(join13(projectAgentPluginDir(cwd), "agents"), null, "project-sis");
|
|
4362
|
+
scanDir(join13(userAgentPluginDir(), "agents"), null, "user-sis");
|
|
4298
4363
|
scanDir(join13(cwd, ".claude", "agents"), null, "project");
|
|
4299
4364
|
scanDir(join13(homedir7(), ".claude", "agents"), null, "user");
|
|
4300
4365
|
scanDir(join13(pluginDir, "agents"), "sisyphus", "bundled");
|