switchroom 0.14.66 → 0.14.68
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/cli/switchroom.js +556 -325
- package/dist/cli/ui/index.html +103 -38
- package/package.json +1 -1
- package/telegram-plugin/answer-stream-flag.ts +19 -0
- package/telegram-plugin/dist/gateway/gateway.js +35 -11
- package/telegram-plugin/gateway/gateway.ts +71 -7
- package/telegram-plugin/silence-poke.ts +25 -0
- package/telegram-plugin/tests/answer-stream-flag.test.ts +19 -1
- package/telegram-plugin/tests/draft-retirement-wiring.test.ts +52 -0
- package/telegram-plugin/tests/silence-liveness-wiring.test.ts +67 -0
- package/telegram-plugin/tests/silence-poke.test.ts +42 -0
- package/telegram-plugin/uat/real-work-prompts.ts +332 -0
- package/telegram-plugin/uat/scenarios/fuzz-real-work-channel.test.ts +82 -0
- package/telegram-plugin/uat/scenarios/fuzz-real-work-dm.test.ts +64 -0
package/dist/cli/switchroom.js
CHANGED
|
@@ -14593,6 +14593,35 @@ function shouldEmitNotionMcp(agentName, config) {
|
|
|
14593
14593
|
return false;
|
|
14594
14594
|
return true;
|
|
14595
14595
|
}
|
|
14596
|
+
function normalizeNotionUuid(uuid) {
|
|
14597
|
+
if (typeof uuid !== "string")
|
|
14598
|
+
return null;
|
|
14599
|
+
const stripped = uuid.replace(/-/g, "").toLowerCase();
|
|
14600
|
+
if (!/^[0-9a-f]{32}$/.test(stripped))
|
|
14601
|
+
return null;
|
|
14602
|
+
return stripped;
|
|
14603
|
+
}
|
|
14604
|
+
function agentCanAccessNotionDB(config, agentName, dbUuid) {
|
|
14605
|
+
if (!shouldEmitNotionMcp(agentName, config))
|
|
14606
|
+
return false;
|
|
14607
|
+
const targetNorm = normalizeNotionUuid(dbUuid);
|
|
14608
|
+
if (targetNorm === null)
|
|
14609
|
+
return false;
|
|
14610
|
+
const agentConfig = config.agents?.[agentName];
|
|
14611
|
+
const allowedNames = agentConfig?.notion_workspace?.databases;
|
|
14612
|
+
if (allowedNames === undefined || allowedNames.length === 0) {
|
|
14613
|
+
return true;
|
|
14614
|
+
}
|
|
14615
|
+
const dbMap = config.notion_workspace?.databases ?? {};
|
|
14616
|
+
for (const name of allowedNames) {
|
|
14617
|
+
const uuid = dbMap[name];
|
|
14618
|
+
if (!uuid)
|
|
14619
|
+
continue;
|
|
14620
|
+
if (normalizeNotionUuid(uuid) === targetNorm)
|
|
14621
|
+
return true;
|
|
14622
|
+
}
|
|
14623
|
+
return false;
|
|
14624
|
+
}
|
|
14596
14625
|
function validateNotionWorkspaceConfig(config) {
|
|
14597
14626
|
const issues = [];
|
|
14598
14627
|
const dbMap = config.notion_workspace?.databases ?? {};
|
|
@@ -23623,7 +23652,7 @@ function bringUpAgentService(opts) {
|
|
|
23623
23652
|
writeFileSync6(composePath, compose, { mode: 384 });
|
|
23624
23653
|
const dockerBin = opts.dockerBin ?? "docker";
|
|
23625
23654
|
const stdio = opts.stdio ?? "inherit";
|
|
23626
|
-
for (const svc of ["vault-broker", "approval-kernel"]) {
|
|
23655
|
+
for (const svc of ["vault-broker", "approval-kernel", "switchroom-auth-broker"]) {
|
|
23627
23656
|
execFileSync6(dockerBin, [
|
|
23628
23657
|
"compose",
|
|
23629
23658
|
"-f",
|
|
@@ -23651,9 +23680,93 @@ var init_docker_fleet = __esm(() => {
|
|
|
23651
23680
|
init_loader();
|
|
23652
23681
|
});
|
|
23653
23682
|
|
|
23683
|
+
// src/agents/singleton-reconcile.ts
|
|
23684
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
23685
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
23686
|
+
function singletonContainerName(svc) {
|
|
23687
|
+
return svc.startsWith("switchroom-") ? svc : `switchroom-${svc}`;
|
|
23688
|
+
}
|
|
23689
|
+
function readPinnedSingletonImages(composeText) {
|
|
23690
|
+
let doc;
|
|
23691
|
+
try {
|
|
23692
|
+
doc = import_yaml3.parse(composeText);
|
|
23693
|
+
} catch {
|
|
23694
|
+
return {};
|
|
23695
|
+
}
|
|
23696
|
+
const out = {};
|
|
23697
|
+
for (const svc of SINGLETON_SERVICES) {
|
|
23698
|
+
const img = doc?.services?.[svc]?.image;
|
|
23699
|
+
if (typeof img === "string" && img.length > 0)
|
|
23700
|
+
out[svc] = img;
|
|
23701
|
+
}
|
|
23702
|
+
return out;
|
|
23703
|
+
}
|
|
23704
|
+
function defaultInspectImage(dockerBin, container) {
|
|
23705
|
+
try {
|
|
23706
|
+
const out = execFileSync7(dockerBin, ["inspect", "-f", "{{.Config.Image}}", container], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], timeout: 5000 }).trim();
|
|
23707
|
+
return out.length > 0 ? out : null;
|
|
23708
|
+
} catch {
|
|
23709
|
+
return null;
|
|
23710
|
+
}
|
|
23711
|
+
}
|
|
23712
|
+
function detectSingletonDrift(deps) {
|
|
23713
|
+
const dockerBin = deps.dockerBin ?? "docker";
|
|
23714
|
+
const readCompose = deps.readCompose ?? ((p) => readFileSync13(p, "utf-8"));
|
|
23715
|
+
const inspectImage = deps.inspectImage ?? ((c) => defaultInspectImage(dockerBin, c));
|
|
23716
|
+
let pinned = {};
|
|
23717
|
+
try {
|
|
23718
|
+
pinned = readPinnedSingletonImages(readCompose(deps.composeFile));
|
|
23719
|
+
} catch {
|
|
23720
|
+
pinned = {};
|
|
23721
|
+
}
|
|
23722
|
+
return SINGLETON_SERVICES.map((service) => {
|
|
23723
|
+
const container = singletonContainerName(service);
|
|
23724
|
+
const running = inspectImage(container);
|
|
23725
|
+
const pin = pinned[service] ?? null;
|
|
23726
|
+
const needsRecreate = pin !== null && running !== pin;
|
|
23727
|
+
return { service, container, running, pinned: pin, needsRecreate };
|
|
23728
|
+
});
|
|
23729
|
+
}
|
|
23730
|
+
function defaultRecreate(dockerBin, project, composeFile, service) {
|
|
23731
|
+
execFileSync7(dockerBin, ["compose", "-p", project, "-f", composeFile, "up", "-d", "--no-deps", service], { stdio: ["ignore", "pipe", "pipe"], timeout: 120000 });
|
|
23732
|
+
}
|
|
23733
|
+
function reconcileSingletons(deps) {
|
|
23734
|
+
const dockerBin = deps.dockerBin ?? "docker";
|
|
23735
|
+
const project = deps.project ?? "switchroom";
|
|
23736
|
+
const log = deps.log ?? ((m) => process.stderr.write(m + `
|
|
23737
|
+
`));
|
|
23738
|
+
const recreate = deps.recreate ?? ((svc) => defaultRecreate(dockerBin, project, deps.composeFile, svc));
|
|
23739
|
+
const drift = detectSingletonDrift(deps);
|
|
23740
|
+
const recreated = [];
|
|
23741
|
+
const failed = [];
|
|
23742
|
+
for (const d of drift) {
|
|
23743
|
+
if (!d.needsRecreate)
|
|
23744
|
+
continue;
|
|
23745
|
+
log(`singleton-reconcile: ${d.service} drift ${d.running ?? "<absent>"} \u2192 ${d.pinned} \u2014 recreating`);
|
|
23746
|
+
try {
|
|
23747
|
+
recreate(d.service);
|
|
23748
|
+
recreated.push(d.service);
|
|
23749
|
+
} catch (err) {
|
|
23750
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
23751
|
+
log(`singleton-reconcile: ${d.service} recreate FAILED: ${msg}`);
|
|
23752
|
+
failed.push({ service: d.service, error: msg });
|
|
23753
|
+
}
|
|
23754
|
+
}
|
|
23755
|
+
return { drift, recreated, failed };
|
|
23756
|
+
}
|
|
23757
|
+
var import_yaml3, SINGLETON_SERVICES;
|
|
23758
|
+
var init_singleton_reconcile = __esm(() => {
|
|
23759
|
+
import_yaml3 = __toESM(require_dist(), 1);
|
|
23760
|
+
SINGLETON_SERVICES = [
|
|
23761
|
+
"vault-broker",
|
|
23762
|
+
"approval-kernel",
|
|
23763
|
+
"switchroom-auth-broker"
|
|
23764
|
+
];
|
|
23765
|
+
});
|
|
23766
|
+
|
|
23654
23767
|
// src/agents/lifecycle.ts
|
|
23655
|
-
import { execFileSync as
|
|
23656
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync12, writeFileSync as writeFileSync7, renameSync as renameSync4, readFileSync as
|
|
23768
|
+
import { execFileSync as execFileSync8, spawn, spawnSync } from "node:child_process";
|
|
23769
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync12, writeFileSync as writeFileSync7, renameSync as renameSync4, readFileSync as readFileSync14 } from "node:fs";
|
|
23657
23770
|
import { resolve as resolve13, join as join10 } from "node:path";
|
|
23658
23771
|
import { connect } from "node:net";
|
|
23659
23772
|
function cleanShutdownMarkerPathForAgent(name) {
|
|
@@ -23666,7 +23779,7 @@ function writeRestartReasonMarker(name, reason, opts = {}) {
|
|
|
23666
23779
|
mkdirSync12(join10(path, ".."), { recursive: true });
|
|
23667
23780
|
if (opts.preserveExisting && existsSync15(path)) {
|
|
23668
23781
|
try {
|
|
23669
|
-
const prev = JSON.parse(
|
|
23782
|
+
const prev = JSON.parse(readFileSync14(path, "utf-8"));
|
|
23670
23783
|
if (prev && typeof prev.ts === "number" && Date.now() - prev.ts < 30000 && prev.reason) {
|
|
23671
23784
|
return;
|
|
23672
23785
|
}
|
|
@@ -23683,7 +23796,7 @@ function buildCliRestartReason(opts) {
|
|
|
23683
23796
|
if (!buildCommit)
|
|
23684
23797
|
return "cli: restart";
|
|
23685
23798
|
try {
|
|
23686
|
-
const head =
|
|
23799
|
+
const head = execFileSync8("git", ["rev-parse", "HEAD"], {
|
|
23687
23800
|
cwd: cwd ?? process.cwd(),
|
|
23688
23801
|
encoding: "utf-8",
|
|
23689
23802
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -23694,7 +23807,7 @@ function buildCliRestartReason(opts) {
|
|
|
23694
23807
|
return "cli: restart";
|
|
23695
23808
|
let subject = "";
|
|
23696
23809
|
try {
|
|
23697
|
-
subject =
|
|
23810
|
+
subject = execFileSync8("git", ["log", "-1", "--pretty=%s", head], {
|
|
23698
23811
|
cwd: cwd ?? process.cwd(),
|
|
23699
23812
|
encoding: "utf-8",
|
|
23700
23813
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -23719,9 +23832,12 @@ function composeFilePath() {
|
|
|
23719
23832
|
return override;
|
|
23720
23833
|
return resolve13(resolveSwitchroomHome(), "compose", "docker-compose.yml");
|
|
23721
23834
|
}
|
|
23835
|
+
function reconcileSingletonImages(log) {
|
|
23836
|
+
return reconcileSingletons({ composeFile: composeFilePath(), log });
|
|
23837
|
+
}
|
|
23722
23838
|
function dockerSync(args) {
|
|
23723
23839
|
try {
|
|
23724
|
-
return
|
|
23840
|
+
return execFileSync8("docker", args, {
|
|
23725
23841
|
encoding: "utf-8",
|
|
23726
23842
|
stdio: ["ignore", "pipe", "pipe"]
|
|
23727
23843
|
}).trim();
|
|
@@ -24103,15 +24219,16 @@ var init_lifecycle = __esm(() => {
|
|
|
24103
24219
|
init_loader();
|
|
24104
24220
|
init_tmux();
|
|
24105
24221
|
init_docker_fleet();
|
|
24222
|
+
init_singleton_reconcile();
|
|
24106
24223
|
});
|
|
24107
24224
|
|
|
24108
24225
|
// src/auth/pane-ready-probe.ts
|
|
24109
|
-
import { execFileSync as
|
|
24226
|
+
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
24110
24227
|
function defaultPaneReadyDeps() {
|
|
24111
24228
|
return {
|
|
24112
24229
|
capturePane(sessionName) {
|
|
24113
24230
|
try {
|
|
24114
|
-
return
|
|
24231
|
+
return execFileSync10("tmux", ["capture-pane", "-p", "-t", sessionName, "-S", "-200"], {
|
|
24115
24232
|
encoding: "utf-8",
|
|
24116
24233
|
stdio: ["pipe", "pipe", "pipe"]
|
|
24117
24234
|
}).trim();
|
|
@@ -24151,7 +24268,7 @@ import {
|
|
|
24151
24268
|
copyFileSync as copyFileSync5,
|
|
24152
24269
|
existsSync as existsSync19,
|
|
24153
24270
|
mkdirSync as mkdirSync14,
|
|
24154
|
-
readFileSync as
|
|
24271
|
+
readFileSync as readFileSync18,
|
|
24155
24272
|
readdirSync as readdirSync9,
|
|
24156
24273
|
renameSync as renameSync6,
|
|
24157
24274
|
rmSync as rmSync4,
|
|
@@ -24206,7 +24323,7 @@ function readActiveSlot(agentDir) {
|
|
|
24206
24323
|
if (!existsSync19(p))
|
|
24207
24324
|
return null;
|
|
24208
24325
|
try {
|
|
24209
|
-
const val =
|
|
24326
|
+
const val = readFileSync18(p, "utf-8").trim();
|
|
24210
24327
|
return val.length > 0 ? val : null;
|
|
24211
24328
|
} catch {
|
|
24212
24329
|
return null;
|
|
@@ -24242,7 +24359,7 @@ function readSlotMeta(agentDir, slot) {
|
|
|
24242
24359
|
if (!existsSync19(p))
|
|
24243
24360
|
return null;
|
|
24244
24361
|
try {
|
|
24245
|
-
return JSON.parse(
|
|
24362
|
+
return JSON.parse(readFileSync18(p, "utf-8"));
|
|
24246
24363
|
} catch {
|
|
24247
24364
|
return null;
|
|
24248
24365
|
}
|
|
@@ -24291,7 +24408,7 @@ function syncLegacyFromActive(agentDir) {
|
|
|
24291
24408
|
}
|
|
24292
24409
|
}
|
|
24293
24410
|
function atomicCopy(src, dest, mode) {
|
|
24294
|
-
const contents =
|
|
24411
|
+
const contents = readFileSync18(src);
|
|
24295
24412
|
const tmp = `${dest}.tmp-${process.pid}-${randomBytes2(4).toString("hex")}`;
|
|
24296
24413
|
try {
|
|
24297
24414
|
writeFileSync9(tmp, contents, { mode });
|
|
@@ -24320,7 +24437,7 @@ function migrateLegacyIfNeeded(agentDir) {
|
|
|
24320
24437
|
}
|
|
24321
24438
|
let token;
|
|
24322
24439
|
try {
|
|
24323
|
-
token =
|
|
24440
|
+
token = readFileSync18(legacyToken, "utf-8").trim();
|
|
24324
24441
|
} catch {
|
|
24325
24442
|
return { migrated: false };
|
|
24326
24443
|
}
|
|
@@ -24392,9 +24509,9 @@ var init_accounts = __esm(() => {
|
|
|
24392
24509
|
});
|
|
24393
24510
|
|
|
24394
24511
|
// src/auth/manager.ts
|
|
24395
|
-
import { execFileSync as
|
|
24512
|
+
import { execFileSync as execFileSync11 } from "node:child_process";
|
|
24396
24513
|
import {
|
|
24397
|
-
readFileSync as
|
|
24514
|
+
readFileSync as readFileSync19,
|
|
24398
24515
|
readdirSync as readdirSync10,
|
|
24399
24516
|
existsSync as existsSync20,
|
|
24400
24517
|
writeFileSync as writeFileSync10,
|
|
@@ -24443,14 +24560,14 @@ function authSessionName(name, slot) {
|
|
|
24443
24560
|
return `${base}-${slot.replace(/[^a-zA-Z0-9_.-]/g, "-")}`;
|
|
24444
24561
|
}
|
|
24445
24562
|
function tmux(args) {
|
|
24446
|
-
return
|
|
24563
|
+
return execFileSync11("tmux", args, {
|
|
24447
24564
|
encoding: "utf-8",
|
|
24448
24565
|
stdio: ["pipe", "pipe", "pipe"]
|
|
24449
24566
|
}).trim();
|
|
24450
24567
|
}
|
|
24451
24568
|
function tmuxSessionExists(sessionName) {
|
|
24452
24569
|
try {
|
|
24453
|
-
|
|
24570
|
+
execFileSync11("tmux", ["has-session", "-t", sessionName], {
|
|
24454
24571
|
stdio: ["pipe", "pipe", "pipe"]
|
|
24455
24572
|
});
|
|
24456
24573
|
return true;
|
|
@@ -24465,7 +24582,7 @@ function readJsonFile(path) {
|
|
|
24465
24582
|
if (!existsSync20(path))
|
|
24466
24583
|
return null;
|
|
24467
24584
|
try {
|
|
24468
|
-
return JSON.parse(
|
|
24585
|
+
return JSON.parse(readFileSync19(path, "utf-8"));
|
|
24469
24586
|
} catch {
|
|
24470
24587
|
return null;
|
|
24471
24588
|
}
|
|
@@ -24475,7 +24592,7 @@ function readOAuthToken(agentDir) {
|
|
|
24475
24592
|
if (!existsSync20(path))
|
|
24476
24593
|
return null;
|
|
24477
24594
|
try {
|
|
24478
|
-
const token =
|
|
24595
|
+
const token = readFileSync19(path, "utf-8").trim();
|
|
24479
24596
|
return token.length > 0 ? token : null;
|
|
24480
24597
|
} catch {
|
|
24481
24598
|
return null;
|
|
@@ -24487,7 +24604,7 @@ function authFilesAreInaccessible(agentDir) {
|
|
|
24487
24604
|
if (!existsSync20(p))
|
|
24488
24605
|
continue;
|
|
24489
24606
|
try {
|
|
24490
|
-
|
|
24607
|
+
readFileSync19(p, "utf-8");
|
|
24491
24608
|
} catch (err) {
|
|
24492
24609
|
const code = err?.code;
|
|
24493
24610
|
if (code === "EACCES" || code === "EPERM")
|
|
@@ -24586,7 +24703,7 @@ function readTokenFromCredentialsFile(credentialsFilePath) {
|
|
|
24586
24703
|
try {
|
|
24587
24704
|
if (!existsSync20(credentialsFilePath))
|
|
24588
24705
|
return null;
|
|
24589
|
-
const raw =
|
|
24706
|
+
const raw = readFileSync19(credentialsFilePath, "utf-8");
|
|
24590
24707
|
const parsed = JSON.parse(raw);
|
|
24591
24708
|
const token = parsed?.claudeAiOauth?.accessToken;
|
|
24592
24709
|
if (typeof token !== "string")
|
|
@@ -24610,7 +24727,7 @@ function readCredentials(agentDir) {
|
|
|
24610
24727
|
if (!existsSync20(credPath))
|
|
24611
24728
|
return null;
|
|
24612
24729
|
try {
|
|
24613
|
-
const parsed = JSON.parse(
|
|
24730
|
+
const parsed = JSON.parse(readFileSync19(credPath, "utf-8"));
|
|
24614
24731
|
return parsed.claudeAiOauth ?? null;
|
|
24615
24732
|
} catch {
|
|
24616
24733
|
return null;
|
|
@@ -24766,7 +24883,7 @@ function readTokenFromLogFile(logPath) {
|
|
|
24766
24883
|
if (!existsSync20(logPath))
|
|
24767
24884
|
return null;
|
|
24768
24885
|
try {
|
|
24769
|
-
const content =
|
|
24886
|
+
const content = readFileSync19(logPath, "utf-8");
|
|
24770
24887
|
return parseSetupTokenValue(content);
|
|
24771
24888
|
} catch {
|
|
24772
24889
|
return null;
|
|
@@ -24912,7 +25029,7 @@ var init_manager = __esm(() => {
|
|
|
24912
25029
|
import {
|
|
24913
25030
|
existsSync as existsSync25,
|
|
24914
25031
|
mkdirSync as mkdirSync16,
|
|
24915
|
-
readFileSync as
|
|
25032
|
+
readFileSync as readFileSync21,
|
|
24916
25033
|
unlinkSync as unlinkSync6,
|
|
24917
25034
|
writeFileSync as writeFileSync12
|
|
24918
25035
|
} from "node:fs";
|
|
@@ -24925,7 +25042,7 @@ function readQuarantineMarker(telegramStateDir) {
|
|
|
24925
25042
|
if (!existsSync25(path))
|
|
24926
25043
|
return null;
|
|
24927
25044
|
try {
|
|
24928
|
-
const raw =
|
|
25045
|
+
const raw = readFileSync21(path, "utf-8");
|
|
24929
25046
|
const parsed = JSON.parse(raw);
|
|
24930
25047
|
if (!parsed || typeof parsed !== "object")
|
|
24931
25048
|
return null;
|
|
@@ -24981,7 +25098,7 @@ __export(exports_inject, {
|
|
|
24981
25098
|
INJECT_BLOCKED: () => INJECT_BLOCKED,
|
|
24982
25099
|
INJECT_ALLOWLIST: () => INJECT_ALLOWLIST
|
|
24983
25100
|
});
|
|
24984
|
-
import { execFile, execFileSync as
|
|
25101
|
+
import { execFile, execFileSync as execFileSync13 } from "node:child_process";
|
|
24985
25102
|
import { promisify } from "node:util";
|
|
24986
25103
|
function validateInjectCommand(command) {
|
|
24987
25104
|
if (typeof command !== "string" || command.trim().length === 0) {
|
|
@@ -25009,7 +25126,7 @@ function makeTmuxRunner(tmuxBin) {
|
|
|
25009
25126
|
return {
|
|
25010
25127
|
capture(socket, session) {
|
|
25011
25128
|
try {
|
|
25012
|
-
return
|
|
25129
|
+
return execFileSync13(tmuxBin, ["-L", socket, "capture-pane", "-p", "-t", session, "-S", "-200"], { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
25013
25130
|
} catch {
|
|
25014
25131
|
return null;
|
|
25015
25132
|
}
|
|
@@ -25019,11 +25136,11 @@ function makeTmuxRunner(tmuxBin) {
|
|
|
25019
25136
|
const flagEnd = rest.findIndex((a) => !a.startsWith("-"));
|
|
25020
25137
|
const flagsBeforeKeys = flagEnd === -1 ? rest : rest.slice(0, flagEnd);
|
|
25021
25138
|
const keys = flagEnd === -1 ? [] : rest.slice(flagEnd);
|
|
25022
|
-
|
|
25139
|
+
execFileSync13(tmuxBin, ["-L", socket, subcmd, ...flagsBeforeKeys, "-t", session, ...keys], { stdio: ["pipe", "pipe", "pipe"] });
|
|
25023
25140
|
},
|
|
25024
25141
|
hasSession(socket, session) {
|
|
25025
25142
|
try {
|
|
25026
|
-
|
|
25143
|
+
execFileSync13(tmuxBin, ["-L", socket, "has-session", "-t", session], {
|
|
25027
25144
|
stdio: ["pipe", "pipe", "pipe"]
|
|
25028
25145
|
});
|
|
25029
25146
|
return true;
|
|
@@ -25856,7 +25973,7 @@ import {
|
|
|
25856
25973
|
chownSync,
|
|
25857
25974
|
existsSync as existsSync28,
|
|
25858
25975
|
mkdirSync as mkdirSync17,
|
|
25859
|
-
readFileSync as
|
|
25976
|
+
readFileSync as readFileSync23,
|
|
25860
25977
|
readdirSync as readdirSync14,
|
|
25861
25978
|
renameSync as renameSync7,
|
|
25862
25979
|
rmSync as rmSync10,
|
|
@@ -25904,7 +26021,7 @@ function readAccountCredentials(label, home2 = homedir9()) {
|
|
|
25904
26021
|
if (!existsSync28(p))
|
|
25905
26022
|
return null;
|
|
25906
26023
|
try {
|
|
25907
|
-
return JSON.parse(
|
|
26024
|
+
return JSON.parse(readFileSync23(p, "utf-8"));
|
|
25908
26025
|
} catch {
|
|
25909
26026
|
return null;
|
|
25910
26027
|
}
|
|
@@ -25914,7 +26031,7 @@ function readAccountMeta(label, home2 = homedir9()) {
|
|
|
25914
26031
|
if (!existsSync28(p))
|
|
25915
26032
|
return null;
|
|
25916
26033
|
try {
|
|
25917
|
-
return JSON.parse(
|
|
26034
|
+
return JSON.parse(readFileSync23(p, "utf-8"));
|
|
25918
26035
|
} catch {
|
|
25919
26036
|
return null;
|
|
25920
26037
|
}
|
|
@@ -25964,9 +26081,9 @@ function setGoogleWorkspaceBlock(yamlText, block) {
|
|
|
25964
26081
|
if (!Array.isArray(block.approvers) || block.approvers.length === 0) {
|
|
25965
26082
|
throw new Error("setGoogleWorkspaceBlock: at least one approver id is required");
|
|
25966
26083
|
}
|
|
25967
|
-
const doc =
|
|
26084
|
+
const doc = import_yaml7.parseDocument(yamlText);
|
|
25968
26085
|
const root = doc.contents;
|
|
25969
|
-
if (!
|
|
26086
|
+
if (!import_yaml7.isMap(root)) {
|
|
25970
26087
|
throw new Error("setGoogleWorkspaceBlock: YAML root is not a map");
|
|
25971
26088
|
}
|
|
25972
26089
|
if (root.has("google_workspace") || root.has("drive")) {
|
|
@@ -25983,9 +26100,9 @@ function setGoogleWorkspaceBlock(yamlText, block) {
|
|
|
25983
26100
|
`) ? out : out + `
|
|
25984
26101
|
`;
|
|
25985
26102
|
}
|
|
25986
|
-
var
|
|
26103
|
+
var import_yaml7;
|
|
25987
26104
|
var init_google_workspace_yaml = __esm(() => {
|
|
25988
|
-
|
|
26105
|
+
import_yaml7 = __toESM(require_dist(), 1);
|
|
25989
26106
|
});
|
|
25990
26107
|
|
|
25991
26108
|
// src/util/atomic.ts
|
|
@@ -27655,13 +27772,13 @@ function setAuthActive(yamlText, label) {
|
|
|
27655
27772
|
if (typeof label !== "string" || label.length === 0) {
|
|
27656
27773
|
throw new Error("setAuthActive: label must be a non-empty string");
|
|
27657
27774
|
}
|
|
27658
|
-
const doc =
|
|
27775
|
+
const doc = import_yaml9.parseDocument(yamlText);
|
|
27659
27776
|
const root = doc.contents;
|
|
27660
|
-
if (!
|
|
27777
|
+
if (!import_yaml9.isMap(root)) {
|
|
27661
27778
|
throw new Error("setAuthActive: YAML root is not a map");
|
|
27662
27779
|
}
|
|
27663
27780
|
const existing = root.get("auth", true);
|
|
27664
|
-
if (
|
|
27781
|
+
if (import_yaml9.isMap(existing)) {
|
|
27665
27782
|
if (existing.get("active") === label) {
|
|
27666
27783
|
return yamlText;
|
|
27667
27784
|
}
|
|
@@ -27674,9 +27791,9 @@ function setAuthActive(yamlText, label) {
|
|
|
27674
27791
|
`) ? out : out + `
|
|
27675
27792
|
`;
|
|
27676
27793
|
}
|
|
27677
|
-
var
|
|
27794
|
+
var import_yaml9;
|
|
27678
27795
|
var init_auth_active_yaml = __esm(() => {
|
|
27679
|
-
|
|
27796
|
+
import_yaml9 = __toESM(require_dist(), 1);
|
|
27680
27797
|
});
|
|
27681
27798
|
|
|
27682
27799
|
// src/auth/via-claude.ts
|
|
@@ -27690,8 +27807,8 @@ __export(exports_via_claude, {
|
|
|
27690
27807
|
PRE_PASTE_RULES: () => PRE_PASTE_RULES,
|
|
27691
27808
|
POST_PASTE_RULES: () => POST_PASTE_RULES
|
|
27692
27809
|
});
|
|
27693
|
-
import { execFileSync as
|
|
27694
|
-
import { existsSync as existsSync30, mkdirSync as mkdirSync18, readFileSync as
|
|
27810
|
+
import { execFileSync as execFileSync14, spawnSync as spawnSync2 } from "node:child_process";
|
|
27811
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync18, readFileSync as readFileSync26 } from "node:fs";
|
|
27695
27812
|
import { join as join22, resolve as resolve23 } from "node:path";
|
|
27696
27813
|
function tmuxHasSession(session) {
|
|
27697
27814
|
const r = spawnSync2("tmux", ["has-session", "-t", session], {
|
|
@@ -27701,7 +27818,7 @@ function tmuxHasSession(session) {
|
|
|
27701
27818
|
}
|
|
27702
27819
|
function tmuxKillSession(session) {
|
|
27703
27820
|
try {
|
|
27704
|
-
|
|
27821
|
+
execFileSync14("tmux", ["kill-session", "-t", session], {
|
|
27705
27822
|
stdio: "ignore",
|
|
27706
27823
|
timeout: 3000
|
|
27707
27824
|
});
|
|
@@ -27709,7 +27826,7 @@ function tmuxKillSession(session) {
|
|
|
27709
27826
|
}
|
|
27710
27827
|
function tmuxCapturePane(session) {
|
|
27711
27828
|
try {
|
|
27712
|
-
const out =
|
|
27829
|
+
const out = execFileSync14("tmux", ["capture-pane", "-p", "-t", session, "-S", "-200"], { timeout: 3000, stdio: ["ignore", "pipe", "pipe"], maxBuffer: 4 * 1024 * 1024 });
|
|
27713
27830
|
return out.toString("utf8");
|
|
27714
27831
|
} catch {
|
|
27715
27832
|
return "";
|
|
@@ -27717,7 +27834,7 @@ function tmuxCapturePane(session) {
|
|
|
27717
27834
|
}
|
|
27718
27835
|
function tmuxSendKeys(session, keys, literal = false) {
|
|
27719
27836
|
try {
|
|
27720
|
-
|
|
27837
|
+
execFileSync14("tmux", ["send-keys", "-t", session, ...literal ? ["-l"] : [], ...keys], { timeout: 3000, stdio: ["ignore", "pipe", "pipe"] });
|
|
27721
27838
|
} catch {}
|
|
27722
27839
|
}
|
|
27723
27840
|
function extractAuthorizeUrl(pane) {
|
|
@@ -27746,7 +27863,7 @@ async function runViaClaude(opts) {
|
|
|
27746
27863
|
tmuxKillSession(SESSION);
|
|
27747
27864
|
}
|
|
27748
27865
|
const spawn4 = opts.spawnClaude ?? (() => {
|
|
27749
|
-
|
|
27866
|
+
execFileSync14("tmux", [
|
|
27750
27867
|
"new-session",
|
|
27751
27868
|
"-d",
|
|
27752
27869
|
"-s",
|
|
@@ -27801,7 +27918,7 @@ async function runViaClaude(opts) {
|
|
|
27801
27918
|
await sleep3(poll);
|
|
27802
27919
|
if (existsSync30(credentialsPath2)) {
|
|
27803
27920
|
await sleep3(200);
|
|
27804
|
-
const raw =
|
|
27921
|
+
const raw = readFileSync26(credentialsPath2, "utf-8");
|
|
27805
27922
|
let parsed;
|
|
27806
27923
|
try {
|
|
27807
27924
|
parsed = JSON.parse(raw);
|
|
@@ -28563,7 +28680,7 @@ var init_thinking_effort_risk = __esm(() => {
|
|
|
28563
28680
|
// src/manifest.ts
|
|
28564
28681
|
import {
|
|
28565
28682
|
existsSync as existsSync49,
|
|
28566
|
-
readFileSync as
|
|
28683
|
+
readFileSync as readFileSync45,
|
|
28567
28684
|
readdirSync as readdirSync18
|
|
28568
28685
|
} from "node:fs";
|
|
28569
28686
|
import { dirname as dirname11, join as join42 } from "node:path";
|
|
@@ -28585,7 +28702,7 @@ function loadManifest(manifestPath) {
|
|
|
28585
28702
|
}
|
|
28586
28703
|
let raw;
|
|
28587
28704
|
try {
|
|
28588
|
-
raw =
|
|
28705
|
+
raw = readFileSync45(path4, "utf-8");
|
|
28589
28706
|
} catch (err) {
|
|
28590
28707
|
throw new Error(`Failed to read manifest at ${path4}: ${err.message}`);
|
|
28591
28708
|
}
|
|
@@ -28650,7 +28767,7 @@ function probePlaywrightMcpVersion() {
|
|
|
28650
28767
|
const pkgPath = join42(npxCache, entry, "node_modules/@playwright/mcp/package.json");
|
|
28651
28768
|
if (existsSync49(pkgPath)) {
|
|
28652
28769
|
try {
|
|
28653
|
-
const pkg = JSON.parse(
|
|
28770
|
+
const pkg = JSON.parse(readFileSync45(pkgPath, "utf-8"));
|
|
28654
28771
|
if (pkg.version)
|
|
28655
28772
|
return pkg.version;
|
|
28656
28773
|
} catch {}
|
|
@@ -28742,13 +28859,22 @@ var init_manifest = __esm(() => {
|
|
|
28742
28859
|
});
|
|
28743
28860
|
|
|
28744
28861
|
// src/cli/doctor-docker.ts
|
|
28745
|
-
import { readFileSync as
|
|
28862
|
+
import { readFileSync as readFileSync46 } from "node:fs";
|
|
28863
|
+
function imageTagOf(ref) {
|
|
28864
|
+
if (!ref)
|
|
28865
|
+
return "<absent>";
|
|
28866
|
+
const at = ref.lastIndexOf("@");
|
|
28867
|
+
const base = at >= 0 ? ref.slice(0, at) : ref;
|
|
28868
|
+
const colon = base.lastIndexOf(":");
|
|
28869
|
+
const slash = base.lastIndexOf("/");
|
|
28870
|
+
return colon > slash ? base.slice(colon + 1) : ref;
|
|
28871
|
+
}
|
|
28746
28872
|
function isDockerMode(opts) {
|
|
28747
28873
|
if (process.env.SWITCHROOM_RUNTIME === "docker")
|
|
28748
28874
|
return true;
|
|
28749
28875
|
if (opts?.composePath) {
|
|
28750
28876
|
try {
|
|
28751
|
-
|
|
28877
|
+
readFileSync46(opts.composePath, "utf8");
|
|
28752
28878
|
return true;
|
|
28753
28879
|
} catch {}
|
|
28754
28880
|
}
|
|
@@ -28883,6 +29009,27 @@ function checkDockerfileUserAlignment(composeYaml, dockerfileAgent) {
|
|
|
28883
29009
|
fix: "Drop the USER directive from Dockerfile.agent (preferred \u2014 the image is identity-neutral) or align per-agent UIDs by renaming."
|
|
28884
29010
|
};
|
|
28885
29011
|
}
|
|
29012
|
+
function checkSingletonImageDrift(composeYaml, deps) {
|
|
29013
|
+
const drift = detectSingletonDrift({
|
|
29014
|
+
composeFile: "(in-memory)",
|
|
29015
|
+
readCompose: () => composeYaml,
|
|
29016
|
+
inspectImage: deps?.inspectImage
|
|
29017
|
+
});
|
|
29018
|
+
const stale = drift.filter((d) => d.needsRecreate && d.running !== null);
|
|
29019
|
+
if (stale.length === 0) {
|
|
29020
|
+
return {
|
|
29021
|
+
name: "singleton image drift",
|
|
29022
|
+
status: "ok",
|
|
29023
|
+
detail: "vault-broker / approval-kernel / auth-broker match the pinned image"
|
|
29024
|
+
};
|
|
29025
|
+
}
|
|
29026
|
+
return {
|
|
29027
|
+
name: "singleton image drift",
|
|
29028
|
+
status: "warn",
|
|
29029
|
+
detail: "singleton(s) running an image older than the pin: " + stale.map((d) => `${d.service} ${imageTagOf(d.running)}\u2260${imageTagOf(d.pinned)}`).join(", "),
|
|
29030
|
+
fix: "Recreate them \u2014 `switchroom agent restart <any-agent>` now self-heals stale singletons, or `switchroom update` (whole-project recreate)."
|
|
29031
|
+
};
|
|
29032
|
+
}
|
|
28886
29033
|
function runDockerChecks(args) {
|
|
28887
29034
|
if (!args.active) {
|
|
28888
29035
|
return [{
|
|
@@ -28896,6 +29043,7 @@ function runDockerChecks(args) {
|
|
|
28896
29043
|
out.push(checkAgentCaps(args.config));
|
|
28897
29044
|
if (args.composeYaml) {
|
|
28898
29045
|
out.push(checkAgentSocketMounts(args.composeYaml));
|
|
29046
|
+
out.push(checkSingletonImageDrift(args.composeYaml));
|
|
28899
29047
|
if (args.dockerfileAgent) {
|
|
28900
29048
|
out.push(checkDockerfileUserAlignment(args.composeYaml, args.dockerfileAgent));
|
|
28901
29049
|
}
|
|
@@ -28911,10 +29059,11 @@ function runDockerChecks(args) {
|
|
|
28911
29059
|
}
|
|
28912
29060
|
var init_doctor_docker = __esm(() => {
|
|
28913
29061
|
init_compose();
|
|
29062
|
+
init_singleton_reconcile();
|
|
28914
29063
|
});
|
|
28915
29064
|
|
|
28916
29065
|
// src/cli/doctor-auth-broker.ts
|
|
28917
|
-
import { existsSync as existsSync50, readFileSync as
|
|
29066
|
+
import { existsSync as existsSync50, readFileSync as readFileSync47 } from "node:fs";
|
|
28918
29067
|
import { createHash as createHash10 } from "node:crypto";
|
|
28919
29068
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
28920
29069
|
import { homedir as homedir23 } from "node:os";
|
|
@@ -29028,7 +29177,7 @@ function checkAuthBrokerDrift(deps = {}) {
|
|
|
29028
29177
|
}
|
|
29029
29178
|
let index;
|
|
29030
29179
|
try {
|
|
29031
|
-
index = JSON.parse(
|
|
29180
|
+
index = JSON.parse(readFileSync47(indexPath, "utf-8"));
|
|
29032
29181
|
} catch (err) {
|
|
29033
29182
|
return {
|
|
29034
29183
|
name: "auth-broker: drift",
|
|
@@ -29048,7 +29197,7 @@ function checkAuthBrokerDrift(deps = {}) {
|
|
|
29048
29197
|
}
|
|
29049
29198
|
let got;
|
|
29050
29199
|
try {
|
|
29051
|
-
got = sha256Hex(
|
|
29200
|
+
got = sha256Hex(readFileSync47(credsPath, "utf-8"));
|
|
29052
29201
|
} catch (err) {
|
|
29053
29202
|
divergent.push(`${label} (read failed: ${err.message})`);
|
|
29054
29203
|
continue;
|
|
@@ -29089,7 +29238,7 @@ function checkAuthBrokerThresholdViolations(deps = {}) {
|
|
|
29089
29238
|
}
|
|
29090
29239
|
let violations;
|
|
29091
29240
|
try {
|
|
29092
|
-
violations = JSON.parse(
|
|
29241
|
+
violations = JSON.parse(readFileSync47(path4, "utf-8"));
|
|
29093
29242
|
} catch (err) {
|
|
29094
29243
|
return {
|
|
29095
29244
|
name: "auth-broker: threshold violations",
|
|
@@ -30586,7 +30735,7 @@ function runInlinedSecretChecks(_config, deps = {}) {
|
|
|
30586
30735
|
}
|
|
30587
30736
|
let parsed;
|
|
30588
30737
|
try {
|
|
30589
|
-
parsed =
|
|
30738
|
+
parsed = import_yaml15.parse(raw);
|
|
30590
30739
|
} catch {
|
|
30591
30740
|
return [
|
|
30592
30741
|
{
|
|
@@ -30614,9 +30763,9 @@ function runInlinedSecretChecks(_config, deps = {}) {
|
|
|
30614
30763
|
fix: `Move it to the per-agent-ACL'd vault: \`switchroom vault set <name>\` ` + `then replace the literal with \`vault:<name>\`. Rotate the exposed ` + `value if any agent may already have read it.`
|
|
30615
30764
|
}));
|
|
30616
30765
|
}
|
|
30617
|
-
var
|
|
30766
|
+
var import_yaml15, SECRET_KEY_EXACT;
|
|
30618
30767
|
var init_doctor_inlined_secrets = __esm(() => {
|
|
30619
|
-
|
|
30768
|
+
import_yaml15 = __toESM(require_dist(), 1);
|
|
30620
30769
|
SECRET_KEY_EXACT = new Set([
|
|
30621
30770
|
"bot_token",
|
|
30622
30771
|
"client_secret",
|
|
@@ -30868,7 +31017,7 @@ var init_doctor_agent_smoke = __esm(() => {
|
|
|
30868
31017
|
});
|
|
30869
31018
|
|
|
30870
31019
|
// src/cli/doctor-vault-broker-durability.ts
|
|
30871
|
-
import { execFileSync as
|
|
31020
|
+
import { execFileSync as execFileSync17 } from "node:child_process";
|
|
30872
31021
|
import { existsSync as existsSync53, statSync as statSync22 } from "node:fs";
|
|
30873
31022
|
import { homedir as homedir32 } from "node:os";
|
|
30874
31023
|
import { join as join53 } from "node:path";
|
|
@@ -30930,7 +31079,7 @@ function spawnDockerStat(p) {
|
|
|
30930
31079
|
}
|
|
30931
31080
|
function spawnDockerStatForContainer(containerName2, p) {
|
|
30932
31081
|
try {
|
|
30933
|
-
const stdout =
|
|
31082
|
+
const stdout = execFileSync17("docker", ["exec", containerName2, "stat", "-c", "%i %s", p], { stdio: ["ignore", "pipe", "pipe"], timeout: 3000, encoding: "utf8" });
|
|
30934
31083
|
return { status: 0, stdout, stderr: "", error: null };
|
|
30935
31084
|
} catch (err) {
|
|
30936
31085
|
const e = err;
|
|
@@ -31004,7 +31153,7 @@ function probeBrokerUnlocked(opts) {
|
|
|
31004
31153
|
}
|
|
31005
31154
|
function defaultBrokerStatusProbe() {
|
|
31006
31155
|
try {
|
|
31007
|
-
const out =
|
|
31156
|
+
const out = execFileSync17("switchroom", ["vault", "broker", "status"], { stdio: ["ignore", "pipe", "pipe"], timeout: 3000, encoding: "utf8" });
|
|
31008
31157
|
const parsed = JSON.parse(out.trim());
|
|
31009
31158
|
if (!parsed.running)
|
|
31010
31159
|
return null;
|
|
@@ -31204,7 +31353,7 @@ import {
|
|
|
31204
31353
|
existsSync as existsSync54,
|
|
31205
31354
|
lstatSync as lstatSync5,
|
|
31206
31355
|
mkdirSync as mkdirSync29,
|
|
31207
|
-
readFileSync as
|
|
31356
|
+
readFileSync as readFileSync48,
|
|
31208
31357
|
readdirSync as readdirSync20,
|
|
31209
31358
|
statSync as statSync23
|
|
31210
31359
|
} from "node:fs";
|
|
@@ -31882,7 +32031,7 @@ function classifyReadError(err) {
|
|
|
31882
32031
|
}
|
|
31883
32032
|
function tryReadHostFile(path4) {
|
|
31884
32033
|
try {
|
|
31885
|
-
return { kind: "ok", content:
|
|
32034
|
+
return { kind: "ok", content: readFileSync48(path4, "utf-8") };
|
|
31886
32035
|
} catch (err) {
|
|
31887
32036
|
const kind = classifyReadError(err);
|
|
31888
32037
|
const error = err?.message ?? String(err);
|
|
@@ -31898,7 +32047,7 @@ function parseEnvFile(path4) {
|
|
|
31898
32047
|
return {};
|
|
31899
32048
|
let content;
|
|
31900
32049
|
try {
|
|
31901
|
-
content =
|
|
32050
|
+
content = readFileSync48(path4, "utf-8");
|
|
31902
32051
|
} catch {
|
|
31903
32052
|
return {};
|
|
31904
32053
|
}
|
|
@@ -32015,7 +32164,7 @@ function checkStartShStale(agentName, startShPath) {
|
|
|
32015
32164
|
}
|
|
32016
32165
|
let content;
|
|
32017
32166
|
try {
|
|
32018
|
-
content =
|
|
32167
|
+
content = readFileSync48(startShPath, "utf-8");
|
|
32019
32168
|
} catch (err) {
|
|
32020
32169
|
return {
|
|
32021
32170
|
name: label,
|
|
@@ -32128,7 +32277,7 @@ function isSwitchroomCheckout(dir) {
|
|
|
32128
32277
|
const pkgPath = join54(dir, "package.json");
|
|
32129
32278
|
if (!existsSync54(pkgPath))
|
|
32130
32279
|
return false;
|
|
32131
|
-
const pkg = JSON.parse(
|
|
32280
|
+
const pkg = JSON.parse(readFileSync48(pkgPath, "utf-8"));
|
|
32132
32281
|
return pkg.name === "switchroom";
|
|
32133
32282
|
} catch {
|
|
32134
32283
|
return false;
|
|
@@ -32249,7 +32398,7 @@ function checkAgents(config, configPath) {
|
|
|
32249
32398
|
});
|
|
32250
32399
|
} else {
|
|
32251
32400
|
try {
|
|
32252
|
-
const mcp = JSON.parse(
|
|
32401
|
+
const mcp = JSON.parse(readFileSync48(mcpJsonPath, "utf-8"));
|
|
32253
32402
|
const hasSwitchroomTelegram = !!mcp.mcpServers?.["switchroom-telegram"];
|
|
32254
32403
|
const memoryEnabled = isHindsightEnabled(config);
|
|
32255
32404
|
const hasHindsight = !!mcp.mcpServers?.hindsight;
|
|
@@ -32744,11 +32893,11 @@ function runDockerSection(config) {
|
|
|
32744
32893
|
let composeYaml;
|
|
32745
32894
|
let dockerfileAgent;
|
|
32746
32895
|
try {
|
|
32747
|
-
composeYaml =
|
|
32896
|
+
composeYaml = readFileSync48(composePath, "utf8");
|
|
32748
32897
|
} catch {}
|
|
32749
32898
|
const dockerfilePath = resolve32(process.env.HOME ?? "", ".switchroom", "docker", "Dockerfile.agent");
|
|
32750
32899
|
try {
|
|
32751
|
-
dockerfileAgent =
|
|
32900
|
+
dockerfileAgent = readFileSync48(dockerfilePath, "utf8");
|
|
32752
32901
|
} catch {}
|
|
32753
32902
|
return runDockerChecks({
|
|
32754
32903
|
config,
|
|
@@ -49041,7 +49190,7 @@ __export(exports_server2, {
|
|
|
49041
49190
|
TOOLS: () => TOOLS2
|
|
49042
49191
|
});
|
|
49043
49192
|
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
49044
|
-
import { existsSync as existsSync82, readFileSync as
|
|
49193
|
+
import { existsSync as existsSync82, readFileSync as readFileSync67 } from "node:fs";
|
|
49045
49194
|
function selfSocketPath() {
|
|
49046
49195
|
return `/run/switchroom/hostd/${SELF_AGENT}/sock`;
|
|
49047
49196
|
}
|
|
@@ -49219,7 +49368,7 @@ function getLastUpdateApplyStatus() {
|
|
|
49219
49368
|
}
|
|
49220
49369
|
let raw;
|
|
49221
49370
|
try {
|
|
49222
|
-
raw =
|
|
49371
|
+
raw = readFileSync67(path8, "utf-8");
|
|
49223
49372
|
} catch (err2) {
|
|
49224
49373
|
return errorText2(`get_status: failed to read audit log at ${path8}: ${err2.message}`);
|
|
49225
49374
|
}
|
|
@@ -49452,13 +49601,13 @@ var {
|
|
|
49452
49601
|
} = import__.default;
|
|
49453
49602
|
|
|
49454
49603
|
// src/build-info.ts
|
|
49455
|
-
var VERSION = "0.14.
|
|
49456
|
-
var COMMIT_SHA = "
|
|
49604
|
+
var VERSION = "0.14.68";
|
|
49605
|
+
var COMMIT_SHA = "4f371b79";
|
|
49457
49606
|
|
|
49458
49607
|
// src/cli/agent.ts
|
|
49459
49608
|
init_source();
|
|
49460
49609
|
import { join as join17, resolve as resolve21 } from "node:path";
|
|
49461
|
-
import { rmSync as rmSync9, existsSync as existsSync26, readFileSync as
|
|
49610
|
+
import { rmSync as rmSync9, existsSync as existsSync26, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "node:fs";
|
|
49462
49611
|
import { homedir as homedir6 } from "node:os";
|
|
49463
49612
|
|
|
49464
49613
|
// src/agents/scheduler-state.ts
|
|
@@ -49524,7 +49673,7 @@ function formatSchedulerState(state) {
|
|
|
49524
49673
|
init_loader();
|
|
49525
49674
|
init_hindsight();
|
|
49526
49675
|
init_helpers();
|
|
49527
|
-
var
|
|
49676
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
49528
49677
|
|
|
49529
49678
|
// src/agents/scaffold.ts
|
|
49530
49679
|
init_source();
|
|
@@ -53079,12 +53228,12 @@ function spinner(message) {
|
|
|
53079
53228
|
}
|
|
53080
53229
|
|
|
53081
53230
|
// src/agents/status.ts
|
|
53082
|
-
import { existsSync as existsSync18, readFileSync as
|
|
53231
|
+
import { existsSync as existsSync18, readFileSync as readFileSync17, statSync as statSync10 } from "node:fs";
|
|
53083
53232
|
import { join as join12 } from "node:path";
|
|
53084
|
-
import { execFileSync as
|
|
53233
|
+
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
53085
53234
|
|
|
53086
53235
|
// src/agents/handoff-summarizer.ts
|
|
53087
|
-
import { readFileSync as
|
|
53236
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, renameSync as renameSync5, mkdirSync as mkdirSync13, existsSync as existsSync16, statSync as statSync9, readdirSync as readdirSync8 } from "node:fs";
|
|
53088
53237
|
import { join as join11 } from "node:path";
|
|
53089
53238
|
var DEFAULT_MAX_TURNS = 50;
|
|
53090
53239
|
var TOPIC_MAX_CHARS = 117;
|
|
@@ -53092,7 +53241,7 @@ var TURN_TEXT_MAX_CHARS = 1200;
|
|
|
53092
53241
|
function extractTurnsFromJsonl(path, maxTurns) {
|
|
53093
53242
|
let raw;
|
|
53094
53243
|
try {
|
|
53095
|
-
raw =
|
|
53244
|
+
raw = readFileSync15(path, "utf-8");
|
|
53096
53245
|
} catch {
|
|
53097
53246
|
return [];
|
|
53098
53247
|
}
|
|
@@ -53317,7 +53466,7 @@ function findLatestSessionJsonl(claudeConfigDir) {
|
|
|
53317
53466
|
}
|
|
53318
53467
|
|
|
53319
53468
|
// src/agents/perf.ts
|
|
53320
|
-
import { existsSync as existsSync17, readFileSync as
|
|
53469
|
+
import { existsSync as existsSync17, readFileSync as readFileSync16 } from "node:fs";
|
|
53321
53470
|
function readTurnUsages(jsonlPath, lastN) {
|
|
53322
53471
|
if (!existsSync17(jsonlPath))
|
|
53323
53472
|
return [];
|
|
@@ -53325,7 +53474,7 @@ function readTurnUsages(jsonlPath, lastN) {
|
|
|
53325
53474
|
return [];
|
|
53326
53475
|
let raw;
|
|
53327
53476
|
try {
|
|
53328
|
-
raw =
|
|
53477
|
+
raw = readFileSync16(jsonlPath, "utf-8");
|
|
53329
53478
|
} catch {
|
|
53330
53479
|
return [];
|
|
53331
53480
|
}
|
|
@@ -53734,7 +53883,7 @@ function readLogFile(logPath) {
|
|
|
53734
53883
|
const stat = statSync10(logPath);
|
|
53735
53884
|
const cap = 256 * 1024;
|
|
53736
53885
|
if (stat.size <= cap) {
|
|
53737
|
-
return
|
|
53886
|
+
return readFileSync17(logPath, "utf-8");
|
|
53738
53887
|
}
|
|
53739
53888
|
const fs2 = __require("node:fs");
|
|
53740
53889
|
const fd = fs2.openSync(logPath, "r");
|
|
@@ -53758,14 +53907,14 @@ function readLastMessages(historyDbPath) {
|
|
|
53758
53907
|
};
|
|
53759
53908
|
}
|
|
53760
53909
|
try {
|
|
53761
|
-
const out =
|
|
53910
|
+
const out = execFileSync9("bun", [
|
|
53762
53911
|
"-e",
|
|
53763
53912
|
`const { Database } = require("bun:sqlite"); ` + `const db = new Database(${JSON.stringify(historyDbPath)}, { readonly: true }); ` + `const rows = db.prepare("SELECT role, MAX(ts) as ts FROM messages GROUP BY role").all(); ` + `for (const r of rows) console.log(r.role + "|" + r.ts); ` + `db.close();`
|
|
53764
53913
|
], { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
53765
53914
|
return parseSqliteRoleTsOutput(out);
|
|
53766
53915
|
} catch {}
|
|
53767
53916
|
try {
|
|
53768
|
-
const out =
|
|
53917
|
+
const out = execFileSync9("sqlite3", [
|
|
53769
53918
|
historyDbPath,
|
|
53770
53919
|
"SELECT role, MAX(ts) FROM messages GROUP BY role;"
|
|
53771
53920
|
], { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
@@ -53877,7 +54026,7 @@ function escapeRegex(s) {
|
|
|
53877
54026
|
}
|
|
53878
54027
|
function readDockerContainer(containerName2) {
|
|
53879
54028
|
try {
|
|
53880
|
-
const out =
|
|
54029
|
+
const out = execFileSync9("docker", ["inspect", "--format", "{{json .State}}", containerName2], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
53881
54030
|
const state = JSON.parse(out.trim());
|
|
53882
54031
|
const active = state.Status === "running" ? "active" : state.Status === "restarting" ? "restarting" : "inactive";
|
|
53883
54032
|
const pid = typeof state.Pid === "number" && state.Pid > 0 ? state.Pid : null;
|
|
@@ -54153,7 +54302,7 @@ async function completeCreation(name, code, opts = {}) {
|
|
|
54153
54302
|
// src/agents/add-orchestrator.ts
|
|
54154
54303
|
import { resolve as resolve18, join as join15 } from "node:path";
|
|
54155
54304
|
import { existsSync as existsSync23, rmSync as rmSync7, statSync as statSync14 } from "node:fs";
|
|
54156
|
-
import { execFileSync as
|
|
54305
|
+
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
54157
54306
|
|
|
54158
54307
|
// src/setup/botfather-walkthrough.ts
|
|
54159
54308
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
@@ -54725,7 +54874,7 @@ function pruneBundledSkills(agentDir, keep, scope) {
|
|
|
54725
54874
|
}
|
|
54726
54875
|
function defaultIsUnitActive(unitName) {
|
|
54727
54876
|
try {
|
|
54728
|
-
const out =
|
|
54877
|
+
const out = execFileSync12("systemctl", ["--user", "is-active", unitName], {
|
|
54729
54878
|
encoding: "utf-8",
|
|
54730
54879
|
stdio: ["ignore", "pipe", "pipe"]
|
|
54731
54880
|
}).trim();
|
|
@@ -54754,8 +54903,8 @@ import { tmpdir as tmpdir2 } from "node:os";
|
|
|
54754
54903
|
init_merge();
|
|
54755
54904
|
init_timezone();
|
|
54756
54905
|
init_resolver();
|
|
54757
|
-
var
|
|
54758
|
-
import { readFileSync as
|
|
54906
|
+
var import_yaml4 = __toESM(require_dist(), 1);
|
|
54907
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "node:fs";
|
|
54759
54908
|
var AGENT_NAME_RE2 = /^[a-z0-9][a-z0-9_-]{0,50}$/;
|
|
54760
54909
|
function defaultDeps() {
|
|
54761
54910
|
return {
|
|
@@ -54778,12 +54927,12 @@ function defaultDeps() {
|
|
|
54778
54927
|
copyDir: (src, dst) => cpSync(src, dst, { recursive: true }),
|
|
54779
54928
|
removeDir: (p) => rmSync8(p, { recursive: true, force: true }),
|
|
54780
54929
|
existsSync: existsSync24,
|
|
54781
|
-
readFileSync: (p, enc) =>
|
|
54930
|
+
readFileSync: (p, enc) => readFileSync20(p, enc)
|
|
54782
54931
|
};
|
|
54783
54932
|
}
|
|
54784
54933
|
function renameAgentInConfig(configPath, oldName, newName) {
|
|
54785
|
-
const raw =
|
|
54786
|
-
const doc =
|
|
54934
|
+
const raw = readFileSync20(configPath, "utf-8");
|
|
54935
|
+
const doc = import_yaml4.default.parseDocument(raw);
|
|
54787
54936
|
const agents = doc.get("agents");
|
|
54788
54937
|
if (!agents || !agents.has(oldName)) {
|
|
54789
54938
|
throw new Error(`Agent "${oldName}" not found in ${configPath}`);
|
|
@@ -54825,7 +54974,7 @@ async function renameAgent(opts, injectedDeps) {
|
|
|
54825
54974
|
const deps = { ...defaultDeps(), ...injectedDeps };
|
|
54826
54975
|
const { oldName, newName, configPath, hindsightMode = "preserve" } = opts;
|
|
54827
54976
|
const _existsSync = deps.existsSync;
|
|
54828
|
-
const _readFileSync = deps.readFileSync ?? ((p, enc) =>
|
|
54977
|
+
const _readFileSync = deps.readFileSync ?? ((p, enc) => readFileSync20(p, enc));
|
|
54829
54978
|
if (!AGENT_NAME_RE2.test(oldName)) {
|
|
54830
54979
|
throw new Error(`Invalid old agent name: "${oldName}". ` + `Names must match ^[a-z0-9][a-z0-9_-]{0,50}$`);
|
|
54831
54980
|
}
|
|
@@ -55145,16 +55294,16 @@ function parsePorcelainDirty(porcelain) {
|
|
|
55145
55294
|
}
|
|
55146
55295
|
function checkSwitchroomBranch() {
|
|
55147
55296
|
try {
|
|
55148
|
-
const { execFileSync:
|
|
55297
|
+
const { execFileSync: execFileSync14 } = __require("node:child_process");
|
|
55149
55298
|
const cwd = process.cwd();
|
|
55150
|
-
const branch =
|
|
55299
|
+
const branch = execFileSync14("git", ["-C", cwd, "rev-parse", "--abbrev-ref", "HEAD"], {
|
|
55151
55300
|
encoding: "utf-8",
|
|
55152
55301
|
stdio: ["ignore", "pipe", "ignore"]
|
|
55153
55302
|
}).trim();
|
|
55154
55303
|
if (branch === "" || branch === "HEAD")
|
|
55155
55304
|
return null;
|
|
55156
55305
|
if (branch === "main" || branch === "master") {
|
|
55157
|
-
const porcelain =
|
|
55306
|
+
const porcelain = execFileSync14("git", ["-C", cwd, "status", "--porcelain"], {
|
|
55158
55307
|
encoding: "utf-8",
|
|
55159
55308
|
stdio: ["ignore", "pipe", "ignore"]
|
|
55160
55309
|
});
|
|
@@ -55199,7 +55348,7 @@ function preflightCheck(name, agentDir, _usesDevChannels) {
|
|
|
55199
55348
|
}
|
|
55200
55349
|
const envPath = resolve21(agentDir, "telegram", ".env");
|
|
55201
55350
|
if (existsSync26(envPath)) {
|
|
55202
|
-
const envContent =
|
|
55351
|
+
const envContent = readFileSync22(envPath, "utf-8");
|
|
55203
55352
|
if (!envContent.includes("TELEGRAM_BOT_TOKEN=") || envContent.includes("# Set your bot token")) {
|
|
55204
55353
|
errors2.push(`telegram/.env is missing TELEGRAM_BOT_TOKEN. ` + `Set it or run: switchroom setup`);
|
|
55205
55354
|
}
|
|
@@ -55286,25 +55435,25 @@ function writeAgentEntryToConfig(configPath, name, profile) {
|
|
|
55286
55435
|
if (!existsSync26(configPath)) {
|
|
55287
55436
|
throw new Error(`switchroom.yaml not found at ${configPath}`);
|
|
55288
55437
|
}
|
|
55289
|
-
const raw =
|
|
55290
|
-
const doc =
|
|
55438
|
+
const raw = readFileSync22(configPath, "utf-8");
|
|
55439
|
+
const doc = import_yaml5.default.parseDocument(raw);
|
|
55291
55440
|
let agents = doc.get("agents");
|
|
55292
55441
|
if (!agents) {
|
|
55293
|
-
agents = new
|
|
55442
|
+
agents = new import_yaml5.default.YAMLMap;
|
|
55294
55443
|
doc.set("agents", agents);
|
|
55295
55444
|
}
|
|
55296
55445
|
if (agents.has(name)) {
|
|
55297
55446
|
throw new Error(`Agent "${name}" already exists in ${configPath}. Use updateAgentExtendsInConfig to change its profile.`);
|
|
55298
55447
|
}
|
|
55299
|
-
const entry = new
|
|
55448
|
+
const entry = new import_yaml5.default.YAMLMap;
|
|
55300
55449
|
entry.set("extends", profile);
|
|
55301
55450
|
entry.set("topic_name", synthesizeTopicName2(name));
|
|
55302
55451
|
agents.set(name, entry);
|
|
55303
55452
|
writeFileSync13(configPath, doc.toString(), "utf-8");
|
|
55304
55453
|
}
|
|
55305
55454
|
function updateAgentExtendsInConfig(configPath, name, profile) {
|
|
55306
|
-
const raw =
|
|
55307
|
-
const doc =
|
|
55455
|
+
const raw = readFileSync22(configPath, "utf-8");
|
|
55456
|
+
const doc = import_yaml5.default.parseDocument(raw);
|
|
55308
55457
|
const agents = doc.get("agents");
|
|
55309
55458
|
if (!agents || !agents.has(name)) {
|
|
55310
55459
|
throw new Error(`Agent "${name}" not found in ${configPath}; cannot update extends.`);
|
|
@@ -55316,8 +55465,8 @@ function updateAgentExtendsInConfig(configPath, name, profile) {
|
|
|
55316
55465
|
function removeAgentFromConfig(configPath, name) {
|
|
55317
55466
|
if (!existsSync26(configPath))
|
|
55318
55467
|
return;
|
|
55319
|
-
const raw =
|
|
55320
|
-
const doc =
|
|
55468
|
+
const raw = readFileSync22(configPath, "utf-8");
|
|
55469
|
+
const doc = import_yaml5.default.parseDocument(raw);
|
|
55321
55470
|
const agents = doc.get("agents");
|
|
55322
55471
|
if (!agents || !agents.has(name))
|
|
55323
55472
|
return;
|
|
@@ -55362,7 +55511,7 @@ async function reconcileAndRestartAgent(name, config, agentsDir, configPath, opt
|
|
|
55362
55511
|
if (!opts.force) {
|
|
55363
55512
|
const envPath = resolve21(agentsDir, name, "telegram", ".env");
|
|
55364
55513
|
if (existsSync26(envPath)) {
|
|
55365
|
-
const envContent =
|
|
55514
|
+
const envContent = readFileSync22(envPath, "utf-8");
|
|
55366
55515
|
const match = envContent.match(/^TELEGRAM_BOT_TOKEN=(.+)$/m);
|
|
55367
55516
|
if (match) {
|
|
55368
55517
|
const token = match[1].trim();
|
|
@@ -55637,6 +55786,14 @@ Scaffolding agent: ${name}
|
|
|
55637
55786
|
}
|
|
55638
55787
|
}
|
|
55639
55788
|
let sawAbort = false;
|
|
55789
|
+
try {
|
|
55790
|
+
const recon = reconcileSingletonImages((m) => console.error(source_default.gray(` ${m}`)));
|
|
55791
|
+
if (recon.recreated.length > 0) {
|
|
55792
|
+
console.error(source_default.cyan(` \u21bb Recreated stale singleton(s) to the pinned image: ${recon.recreated.join(", ")}`));
|
|
55793
|
+
}
|
|
55794
|
+
} catch (err) {
|
|
55795
|
+
console.error(source_default.yellow(` \u26a0 singleton reconcile skipped: ${err instanceof Error ? err.message : String(err)}`));
|
|
55796
|
+
}
|
|
55640
55797
|
for (const n of names) {
|
|
55641
55798
|
if (!config.agents[n]) {
|
|
55642
55799
|
console.error(source_default.red(`Agent "${n}" is not defined in switchroom.yaml`));
|
|
@@ -55836,7 +55993,7 @@ Scaffolding agent: ${name}
|
|
|
55836
55993
|
let actual = {};
|
|
55837
55994
|
if (existsSync26(settingsPath)) {
|
|
55838
55995
|
try {
|
|
55839
|
-
const raw = JSON.parse(
|
|
55996
|
+
const raw = JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
55840
55997
|
actual = raw.hooks ?? {};
|
|
55841
55998
|
} catch {
|
|
55842
55999
|
console.error(source_default.red(` ${n}: could not parse settings.json`));
|
|
@@ -55978,8 +56135,8 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
55978
56135
|
console.error(source_default.red(`switchroom.yaml not found at ${configPath}`));
|
|
55979
56136
|
process.exit(1);
|
|
55980
56137
|
}
|
|
55981
|
-
const raw =
|
|
55982
|
-
const doc =
|
|
56138
|
+
const raw = readFileSync22(configPath, "utf-8");
|
|
56139
|
+
const doc = import_yaml5.default.parseDocument(raw);
|
|
55983
56140
|
const agents = doc.get("agents");
|
|
55984
56141
|
if (!agents || !agents.has(name)) {
|
|
55985
56142
|
console.error(source_default.red(`Agent "${name}" is not defined in switchroom.yaml`));
|
|
@@ -55988,12 +56145,12 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
55988
56145
|
const agentNode = agents.get(name);
|
|
55989
56146
|
let tools = agentNode.get("tools");
|
|
55990
56147
|
if (!tools) {
|
|
55991
|
-
tools = new
|
|
56148
|
+
tools = new import_yaml5.default.YAMLMap;
|
|
55992
56149
|
agentNode.set("tools", tools);
|
|
55993
56150
|
}
|
|
55994
56151
|
let allow = tools.get("allow");
|
|
55995
56152
|
if (!allow) {
|
|
55996
|
-
allow = new
|
|
56153
|
+
allow = new import_yaml5.default.YAMLSeq;
|
|
55997
56154
|
tools.set("allow", allow);
|
|
55998
56155
|
}
|
|
55999
56156
|
const existingAllow = allow.toJSON() ?? [];
|
|
@@ -56027,8 +56184,8 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
56027
56184
|
console.error(source_default.red(`switchroom.yaml not found at ${configPath}`));
|
|
56028
56185
|
process.exit(1);
|
|
56029
56186
|
}
|
|
56030
|
-
const raw =
|
|
56031
|
-
const doc =
|
|
56187
|
+
const raw = readFileSync22(configPath, "utf-8");
|
|
56188
|
+
const doc = import_yaml5.default.parseDocument(raw);
|
|
56032
56189
|
const agents = doc.get("agents");
|
|
56033
56190
|
if (!agents || !agents.has(name)) {
|
|
56034
56191
|
console.error(source_default.red(`Agent "${name}" is not defined in switchroom.yaml`));
|
|
@@ -56038,7 +56195,7 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
56038
56195
|
if (opts.off) {
|
|
56039
56196
|
const tools = agentNode.get("tools");
|
|
56040
56197
|
if (tools && tools.has("allow")) {
|
|
56041
|
-
tools.set("allow", new
|
|
56198
|
+
tools.set("allow", new import_yaml5.default.YAMLSeq);
|
|
56042
56199
|
writeFileSync13(configPath, doc.toString(), "utf-8");
|
|
56043
56200
|
console.log(source_default.yellow(` ${name}: dangerous mode OFF (tools.allow cleared)`));
|
|
56044
56201
|
} else {
|
|
@@ -56047,10 +56204,10 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
56047
56204
|
} else {
|
|
56048
56205
|
let tools = agentNode.get("tools");
|
|
56049
56206
|
if (!tools) {
|
|
56050
|
-
tools = new
|
|
56207
|
+
tools = new import_yaml5.default.YAMLMap;
|
|
56051
56208
|
agentNode.set("tools", tools);
|
|
56052
56209
|
}
|
|
56053
|
-
const allowSeq = new
|
|
56210
|
+
const allowSeq = new import_yaml5.default.YAMLSeq;
|
|
56054
56211
|
allowSeq.add("all");
|
|
56055
56212
|
tools.set("allow", allowSeq);
|
|
56056
56213
|
writeFileSync13(configPath, doc.toString(), "utf-8");
|
|
@@ -56082,7 +56239,7 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
|
|
|
56082
56239
|
console.error(source_default.red(`Agent "${name}" not found at ${settingsPath}`));
|
|
56083
56240
|
process.exit(1);
|
|
56084
56241
|
}
|
|
56085
|
-
const settings = JSON.parse(
|
|
56242
|
+
const settings = JSON.parse(readFileSync22(settingsPath, "utf-8"));
|
|
56086
56243
|
const allow = settings.permissions?.allow ?? [];
|
|
56087
56244
|
const deny = settings.permissions?.deny ?? [];
|
|
56088
56245
|
const defaultMode = settings.permissions?.defaultMode;
|
|
@@ -56922,24 +57079,24 @@ init_account_store();
|
|
|
56922
57079
|
init_loader();
|
|
56923
57080
|
init_manager();
|
|
56924
57081
|
init_helpers();
|
|
56925
|
-
import { existsSync as existsSync31, readFileSync as
|
|
57082
|
+
import { existsSync as existsSync31, readFileSync as readFileSync27 } from "node:fs";
|
|
56926
57083
|
import { join as join23, resolve as resolve24 } from "node:path";
|
|
56927
57084
|
|
|
56928
57085
|
// src/cli/auth-google.ts
|
|
56929
57086
|
init_source();
|
|
56930
|
-
import { readFileSync as
|
|
57087
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync15 } from "node:fs";
|
|
56931
57088
|
|
|
56932
57089
|
// src/cli/google-accounts-yaml.ts
|
|
56933
|
-
var
|
|
57090
|
+
var import_yaml6 = __toESM(require_dist(), 1);
|
|
56934
57091
|
function enableAgentsOnGoogleAccount(yamlText, account, agentsToEnable) {
|
|
56935
|
-
const doc =
|
|
57092
|
+
const doc = import_yaml6.parseDocument(yamlText);
|
|
56936
57093
|
ensureGoogleAccountEntry(doc, account);
|
|
56937
57094
|
const existing = doc.getIn(["google_accounts", account, "enabled_for"]);
|
|
56938
57095
|
const currentAgents = readEnabledFor(existing);
|
|
56939
57096
|
const additions = agentsToEnable.filter((a) => !currentAgents.includes(a));
|
|
56940
57097
|
if (additions.length === 0)
|
|
56941
57098
|
return yamlText;
|
|
56942
|
-
if (
|
|
57099
|
+
if (import_yaml6.isSeq(existing)) {
|
|
56943
57100
|
const seq = existing;
|
|
56944
57101
|
for (const a of additions)
|
|
56945
57102
|
seq.add(a);
|
|
@@ -56949,11 +57106,11 @@ function enableAgentsOnGoogleAccount(yamlText, account, agentsToEnable) {
|
|
|
56949
57106
|
return String(doc);
|
|
56950
57107
|
}
|
|
56951
57108
|
function disableAgentsOnGoogleAccount(yamlText, account, agentsToDisable) {
|
|
56952
|
-
const doc =
|
|
57109
|
+
const doc = import_yaml6.parseDocument(yamlText);
|
|
56953
57110
|
if (!hasGoogleAccountEntry(doc, account))
|
|
56954
57111
|
return yamlText;
|
|
56955
57112
|
const existing = doc.getIn(["google_accounts", account, "enabled_for"]);
|
|
56956
|
-
if (!
|
|
57113
|
+
if (!import_yaml6.isSeq(existing))
|
|
56957
57114
|
return yamlText;
|
|
56958
57115
|
const seq = existing;
|
|
56959
57116
|
const beforeLen = seq.items.length;
|
|
@@ -56969,16 +57126,16 @@ function disableAgentsOnGoogleAccount(yamlText, account, agentsToDisable) {
|
|
|
56969
57126
|
return String(doc);
|
|
56970
57127
|
}
|
|
56971
57128
|
function getEnabledAgentsForGoogleAccount(yamlText, account) {
|
|
56972
|
-
const doc =
|
|
57129
|
+
const doc = import_yaml6.parseDocument(yamlText);
|
|
56973
57130
|
if (!hasGoogleAccountEntry(doc, account))
|
|
56974
57131
|
return null;
|
|
56975
57132
|
const existing = doc.getIn(["google_accounts", account, "enabled_for"]);
|
|
56976
57133
|
return readEnabledFor(existing);
|
|
56977
57134
|
}
|
|
56978
57135
|
function listGoogleAccounts(yamlText) {
|
|
56979
|
-
const doc =
|
|
57136
|
+
const doc = import_yaml6.parseDocument(yamlText);
|
|
56980
57137
|
const accounts = doc.get("google_accounts");
|
|
56981
|
-
if (!
|
|
57138
|
+
if (!import_yaml6.isMap(accounts))
|
|
56982
57139
|
return [];
|
|
56983
57140
|
const out = [];
|
|
56984
57141
|
for (const item of accounts.items) {
|
|
@@ -56993,7 +57150,7 @@ function listGoogleAccounts(yamlText) {
|
|
|
56993
57150
|
return out;
|
|
56994
57151
|
}
|
|
56995
57152
|
function readEnabledFor(node) {
|
|
56996
|
-
if (!
|
|
57153
|
+
if (!import_yaml6.isSeq(node))
|
|
56997
57154
|
return [];
|
|
56998
57155
|
const seq = node;
|
|
56999
57156
|
return seq.items.map((item) => item.value ?? item).filter((v) => typeof v === "string");
|
|
@@ -57005,7 +57162,7 @@ function ensureGoogleAccountEntry(doc, account) {
|
|
|
57005
57162
|
}
|
|
57006
57163
|
function hasGoogleAccountEntry(doc, account) {
|
|
57007
57164
|
const accounts = doc.get("google_accounts");
|
|
57008
|
-
if (!
|
|
57165
|
+
if (!import_yaml6.isMap(accounts))
|
|
57009
57166
|
return false;
|
|
57010
57167
|
return accounts.has(account);
|
|
57011
57168
|
}
|
|
@@ -57122,7 +57279,7 @@ function registerConnect(googleParent, program3) {
|
|
|
57122
57279
|
` tier: ${tier}`
|
|
57123
57280
|
].join(`
|
|
57124
57281
|
`);
|
|
57125
|
-
const raw =
|
|
57282
|
+
const raw = readFileSync24(configPath, "utf-8");
|
|
57126
57283
|
const patched = setGoogleWorkspaceBlock2(raw, {
|
|
57127
57284
|
clientIdRef: "vault:google-oauth-client-id",
|
|
57128
57285
|
clientSecretRef: "vault:google-oauth-client-secret",
|
|
@@ -57168,7 +57325,7 @@ function registerEnable(googleParent, program3) {
|
|
|
57168
57325
|
}
|
|
57169
57326
|
}
|
|
57170
57327
|
const yamlPath = getConfigPath(program3);
|
|
57171
|
-
const before =
|
|
57328
|
+
const before = readFileSync24(yamlPath, "utf-8");
|
|
57172
57329
|
const after = enableAgentsOnGoogleAccount(before, normalizedAccount, agents);
|
|
57173
57330
|
const noop = after === before;
|
|
57174
57331
|
if (!noop) {
|
|
@@ -57196,7 +57353,7 @@ function registerDisable(googleParent, program3) {
|
|
|
57196
57353
|
const config = getConfig(program3);
|
|
57197
57354
|
agents = expandAllAgents(agents, config);
|
|
57198
57355
|
const yamlPath = getConfigPath(program3);
|
|
57199
|
-
const before =
|
|
57356
|
+
const before = readFileSync24(yamlPath, "utf-8");
|
|
57200
57357
|
const enabledBefore = getEnabledAgentsBefore(before, normalizedAccount);
|
|
57201
57358
|
if (enabledBefore.length === 0) {
|
|
57202
57359
|
console.log();
|
|
@@ -57233,7 +57390,7 @@ function registerDisable(googleParent, program3) {
|
|
|
57233
57390
|
function registerList(googleParent, program3) {
|
|
57234
57391
|
googleParent.command("list").description("List every Google account configured in switchroom.yaml with its enabled_for[] agents. Matrix view of accounts \u00d7 agents.").option("--json", "Emit raw JSON instead of a table").action(withConfigError(async (opts) => {
|
|
57235
57392
|
const yamlPath = getConfigPath(program3);
|
|
57236
|
-
const yaml =
|
|
57393
|
+
const yaml = readFileSync24(yamlPath, "utf-8");
|
|
57237
57394
|
const accounts = listGoogleAccounts(yaml);
|
|
57238
57395
|
if (opts.json) {
|
|
57239
57396
|
console.log(JSON.stringify(accounts, null, 2));
|
|
@@ -57619,19 +57776,19 @@ function buildGoogleCredentials(args) {
|
|
|
57619
57776
|
|
|
57620
57777
|
// src/cli/auth-microsoft.ts
|
|
57621
57778
|
init_source();
|
|
57622
|
-
import { readFileSync as
|
|
57779
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync16 } from "node:fs";
|
|
57623
57780
|
|
|
57624
57781
|
// src/cli/microsoft-accounts-yaml.ts
|
|
57625
|
-
var
|
|
57782
|
+
var import_yaml8 = __toESM(require_dist(), 1);
|
|
57626
57783
|
function enableAgentsOnMicrosoftAccount(yamlText, account, agentsToEnable) {
|
|
57627
|
-
const doc =
|
|
57784
|
+
const doc = import_yaml8.parseDocument(yamlText);
|
|
57628
57785
|
ensureMicrosoftAccountEntry(doc, account);
|
|
57629
57786
|
const existing = doc.getIn(["microsoft_accounts", account, "enabled_for"]);
|
|
57630
57787
|
const currentAgents = readEnabledFor2(existing);
|
|
57631
57788
|
const additions = agentsToEnable.filter((a) => !currentAgents.includes(a));
|
|
57632
57789
|
if (additions.length === 0)
|
|
57633
57790
|
return yamlText;
|
|
57634
|
-
if (
|
|
57791
|
+
if (import_yaml8.isSeq(existing)) {
|
|
57635
57792
|
const seq = existing;
|
|
57636
57793
|
for (const a of additions)
|
|
57637
57794
|
seq.add(a);
|
|
@@ -57641,11 +57798,11 @@ function enableAgentsOnMicrosoftAccount(yamlText, account, agentsToEnable) {
|
|
|
57641
57798
|
return String(doc);
|
|
57642
57799
|
}
|
|
57643
57800
|
function disableAgentsOnMicrosoftAccount(yamlText, account, agentsToDisable) {
|
|
57644
|
-
const doc =
|
|
57801
|
+
const doc = import_yaml8.parseDocument(yamlText);
|
|
57645
57802
|
if (!hasMicrosoftAccountEntry(doc, account))
|
|
57646
57803
|
return yamlText;
|
|
57647
57804
|
const existing = doc.getIn(["microsoft_accounts", account, "enabled_for"]);
|
|
57648
|
-
if (!
|
|
57805
|
+
if (!import_yaml8.isSeq(existing))
|
|
57649
57806
|
return yamlText;
|
|
57650
57807
|
const seq = existing;
|
|
57651
57808
|
const beforeLen = seq.items.length;
|
|
@@ -57661,16 +57818,16 @@ function disableAgentsOnMicrosoftAccount(yamlText, account, agentsToDisable) {
|
|
|
57661
57818
|
return String(doc);
|
|
57662
57819
|
}
|
|
57663
57820
|
function getEnabledAgentsForMicrosoftAccount(yamlText, account) {
|
|
57664
|
-
const doc =
|
|
57821
|
+
const doc = import_yaml8.parseDocument(yamlText);
|
|
57665
57822
|
if (!hasMicrosoftAccountEntry(doc, account))
|
|
57666
57823
|
return null;
|
|
57667
57824
|
const existing = doc.getIn(["microsoft_accounts", account, "enabled_for"]);
|
|
57668
57825
|
return readEnabledFor2(existing);
|
|
57669
57826
|
}
|
|
57670
57827
|
function listMicrosoftAccounts(yamlText) {
|
|
57671
|
-
const doc =
|
|
57828
|
+
const doc = import_yaml8.parseDocument(yamlText);
|
|
57672
57829
|
const accounts = doc.get("microsoft_accounts");
|
|
57673
|
-
if (!
|
|
57830
|
+
if (!import_yaml8.isMap(accounts))
|
|
57674
57831
|
return [];
|
|
57675
57832
|
const out = [];
|
|
57676
57833
|
for (const item of accounts.items) {
|
|
@@ -57685,7 +57842,7 @@ function listMicrosoftAccounts(yamlText) {
|
|
|
57685
57842
|
return out;
|
|
57686
57843
|
}
|
|
57687
57844
|
function removeMicrosoftAccountEntry(yamlText, account) {
|
|
57688
|
-
const doc =
|
|
57845
|
+
const doc = import_yaml8.parseDocument(yamlText);
|
|
57689
57846
|
if (!hasMicrosoftAccountEntry(doc, account))
|
|
57690
57847
|
return yamlText;
|
|
57691
57848
|
doc.deleteIn(["microsoft_accounts", account]);
|
|
@@ -57693,7 +57850,7 @@ function removeMicrosoftAccountEntry(yamlText, account) {
|
|
|
57693
57850
|
return String(doc);
|
|
57694
57851
|
}
|
|
57695
57852
|
function readEnabledFor2(node) {
|
|
57696
|
-
if (!
|
|
57853
|
+
if (!import_yaml8.isSeq(node))
|
|
57697
57854
|
return [];
|
|
57698
57855
|
const seq = node;
|
|
57699
57856
|
return seq.items.map((item) => item.value ?? item).filter((v) => typeof v === "string");
|
|
@@ -57705,13 +57862,13 @@ function ensureMicrosoftAccountEntry(doc, account) {
|
|
|
57705
57862
|
}
|
|
57706
57863
|
function hasMicrosoftAccountEntry(doc, account) {
|
|
57707
57864
|
const accounts = doc.get("microsoft_accounts");
|
|
57708
|
-
if (!
|
|
57865
|
+
if (!import_yaml8.isMap(accounts))
|
|
57709
57866
|
return false;
|
|
57710
57867
|
return accounts.has(account);
|
|
57711
57868
|
}
|
|
57712
57869
|
function pruneEmptyMap(doc, path) {
|
|
57713
57870
|
const node = doc.getIn(path);
|
|
57714
|
-
if (
|
|
57871
|
+
if (import_yaml8.isMap(node) && node.items.length === 0) {
|
|
57715
57872
|
doc.deleteIn(path);
|
|
57716
57873
|
}
|
|
57717
57874
|
}
|
|
@@ -57813,7 +57970,7 @@ function registerEnable2(microsoftParent, program3) {
|
|
|
57813
57970
|
agents = expandAllAgents2(agents, config);
|
|
57814
57971
|
validateAgentSlugs(agents, config);
|
|
57815
57972
|
const yamlPath = getConfigPath(program3);
|
|
57816
|
-
const before =
|
|
57973
|
+
const before = readFileSync25(yamlPath, "utf-8");
|
|
57817
57974
|
const enabledBefore = getEnabledAgentsBefore2(before, normalizedAccount);
|
|
57818
57975
|
const after = enableAgentsOnMicrosoftAccount(before, normalizedAccount, agents);
|
|
57819
57976
|
if (after !== before)
|
|
@@ -57843,7 +58000,7 @@ function registerDisable2(microsoftParent, program3) {
|
|
|
57843
58000
|
const config = getConfig(program3);
|
|
57844
58001
|
agents = expandAllAgents2(agents, config);
|
|
57845
58002
|
const yamlPath = getConfigPath(program3);
|
|
57846
|
-
const before =
|
|
58003
|
+
const before = readFileSync25(yamlPath, "utf-8");
|
|
57847
58004
|
const enabledBefore = getEnabledAgentsBefore2(before, normalizedAccount);
|
|
57848
58005
|
if (enabledBefore.length === 0) {
|
|
57849
58006
|
console.log();
|
|
@@ -57877,7 +58034,7 @@ function registerDisable2(microsoftParent, program3) {
|
|
|
57877
58034
|
function registerList2(microsoftParent, program3) {
|
|
57878
58035
|
microsoftParent.command("list").description("List every Microsoft account configured in switchroom.yaml with its enabled_for[] agents.").option("--json", "Emit raw JSON instead of a table").action(withConfigError(async (opts) => {
|
|
57879
58036
|
const yamlPath = getConfigPath(program3);
|
|
57880
|
-
const yaml =
|
|
58037
|
+
const yaml = readFileSync25(yamlPath, "utf-8");
|
|
57881
58038
|
const accounts = listMicrosoftAccounts(yaml);
|
|
57882
58039
|
if (opts.json) {
|
|
57883
58040
|
console.log(JSON.stringify(accounts, null, 2));
|
|
@@ -58052,7 +58209,7 @@ function registerAccountRemove2(accountParent) {
|
|
|
58052
58209
|
const { brokerCall: brokerCall2 } = await Promise.resolve().then(() => (init_broker_call(), exports_broker_call));
|
|
58053
58210
|
const program3 = command.parent?.parent?.parent ?? command;
|
|
58054
58211
|
const yamlPath = getConfigPath(program3);
|
|
58055
|
-
const before =
|
|
58212
|
+
const before = readFileSync25(yamlPath, "utf-8");
|
|
58056
58213
|
const enabled = getEnabledAgentsForMicrosoftAccount(before, normalizedAccount);
|
|
58057
58214
|
if (enabled && enabled.length > 0) {
|
|
58058
58215
|
throw new Error(`Account ${normalizedAccount} is still enabled on agents: ${enabled.join(", ")}. Run 'switchroom auth microsoft disable ${normalizedAccount} all' first.`);
|
|
@@ -58236,7 +58393,7 @@ function diagnoseAuthState(claudeConfigDir) {
|
|
|
58236
58393
|
} else if (hasCreds) {
|
|
58237
58394
|
let parsed;
|
|
58238
58395
|
try {
|
|
58239
|
-
parsed = JSON.parse(
|
|
58396
|
+
parsed = JSON.parse(readFileSync27(credsPath, "utf-8"));
|
|
58240
58397
|
} catch (err) {
|
|
58241
58398
|
const code = err?.code;
|
|
58242
58399
|
if (code === "EACCES" || code === "EPERM") {
|
|
@@ -58404,7 +58561,7 @@ function loadCredentialsFromAgent(agentName) {
|
|
|
58404
58561
|
}
|
|
58405
58562
|
let parsed;
|
|
58406
58563
|
try {
|
|
58407
|
-
parsed = JSON.parse(
|
|
58564
|
+
parsed = JSON.parse(readFileSync27(credsPath, "utf-8"));
|
|
58408
58565
|
} catch (err) {
|
|
58409
58566
|
console.error(source_default.red(` Failed to parse credentials.json: ${err.message}`));
|
|
58410
58567
|
process.exit(1);
|
|
@@ -58422,7 +58579,7 @@ function loadCredentialsFromFile(path) {
|
|
|
58422
58579
|
}
|
|
58423
58580
|
let parsed;
|
|
58424
58581
|
try {
|
|
58425
|
-
parsed = JSON.parse(
|
|
58582
|
+
parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
58426
58583
|
} catch (err) {
|
|
58427
58584
|
console.error(source_default.red(` Failed to parse ${path}: ${err.message}`));
|
|
58428
58585
|
process.exit(1);
|
|
@@ -58555,7 +58712,7 @@ function registerAuthCommand(program3) {
|
|
|
58555
58712
|
function pinAuthActiveInYaml(label, quiet = false) {
|
|
58556
58713
|
try {
|
|
58557
58714
|
const yamlPath = getConfigPath(program3);
|
|
58558
|
-
const before =
|
|
58715
|
+
const before = readFileSync27(yamlPath, "utf-8");
|
|
58559
58716
|
const after = setAuthActive(before, label);
|
|
58560
58717
|
if (after !== before) {
|
|
58561
58718
|
let mode = 420;
|
|
@@ -58703,15 +58860,15 @@ init_loader();
|
|
|
58703
58860
|
init_loader();
|
|
58704
58861
|
init_vault();
|
|
58705
58862
|
import { createInterface as createInterface3 } from "node:readline";
|
|
58706
|
-
import { readFileSync as
|
|
58863
|
+
import { readFileSync as readFileSync36 } from "node:fs";
|
|
58707
58864
|
|
|
58708
58865
|
// src/cli/vault-sweep.ts
|
|
58709
58866
|
init_source();
|
|
58710
58867
|
init_loader();
|
|
58711
58868
|
init_vault();
|
|
58712
58869
|
init_hindsight();
|
|
58713
|
-
import { readFileSync as
|
|
58714
|
-
import { execFileSync as
|
|
58870
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync17, copyFileSync as copyFileSync6, existsSync as existsSync32, readdirSync as readdirSync15, statSync as statSync17 } from "node:fs";
|
|
58871
|
+
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
58715
58872
|
import { join as join24 } from "node:path";
|
|
58716
58873
|
import { homedir as homedir11 } from "node:os";
|
|
58717
58874
|
function getVaultPath2(configPath) {
|
|
@@ -58771,7 +58928,7 @@ function findTelegramHistoryDb() {
|
|
|
58771
58928
|
function scrubJsonl(path, values, dryRun) {
|
|
58772
58929
|
let content;
|
|
58773
58930
|
try {
|
|
58774
|
-
content =
|
|
58931
|
+
content = readFileSync28(path, "utf8");
|
|
58775
58932
|
} catch {
|
|
58776
58933
|
return { target: path, matches: 0, modified: false };
|
|
58777
58934
|
}
|
|
@@ -59049,7 +59206,7 @@ function registerVaultSweep(vault, program3) {
|
|
|
59049
59206
|
function scrubSqlite(path, values, dryRun) {
|
|
59050
59207
|
let hasSqlite = true;
|
|
59051
59208
|
try {
|
|
59052
|
-
|
|
59209
|
+
execFileSync15("sqlite3", ["-version"], { timeout: 2000, stdio: "ignore" });
|
|
59053
59210
|
} catch {
|
|
59054
59211
|
hasSqlite = false;
|
|
59055
59212
|
}
|
|
@@ -59061,7 +59218,7 @@ function scrubSqlite(path, values, dryRun) {
|
|
|
59061
59218
|
for (const { value } of values) {
|
|
59062
59219
|
const esc = value.replace(/'/g, "''");
|
|
59063
59220
|
try {
|
|
59064
|
-
const out =
|
|
59221
|
+
const out = execFileSync15("sqlite3", [path, `SELECT COUNT(*) FROM messages WHERE text LIKE '%${esc}%'`], { encoding: "utf8", timeout: 1e4 });
|
|
59065
59222
|
const n = parseInt(out.trim(), 10);
|
|
59066
59223
|
if (!Number.isNaN(n))
|
|
59067
59224
|
matches += n;
|
|
@@ -59075,7 +59232,7 @@ function scrubSqlite(path, values, dryRun) {
|
|
|
59075
59232
|
for (const { key, value } of values) {
|
|
59076
59233
|
const esc = value.replace(/'/g, "''");
|
|
59077
59234
|
const replacement = `vault:${key}`.replace(/'/g, "''");
|
|
59078
|
-
|
|
59235
|
+
execFileSync15("sqlite3", [path, `UPDATE messages SET text = replace(text, '${esc}', '${replacement}')`], { timeout: 15000 });
|
|
59079
59236
|
}
|
|
59080
59237
|
return { target: path, matches, modified: true };
|
|
59081
59238
|
} catch (err) {
|
|
@@ -59113,14 +59270,14 @@ function suggestVaultKeys(requested, available, max = 3) {
|
|
|
59113
59270
|
init_loader();
|
|
59114
59271
|
init_loader();
|
|
59115
59272
|
init_client();
|
|
59116
|
-
import { readFileSync as
|
|
59273
|
+
import { readFileSync as readFileSync33, existsSync as existsSync36, unlinkSync as unlinkSync9 } from "node:fs";
|
|
59117
59274
|
import { spawn as spawn4 } from "node:child_process";
|
|
59118
59275
|
|
|
59119
59276
|
// src/vault/broker/server.ts
|
|
59120
59277
|
init_compose();
|
|
59121
59278
|
init_vault();
|
|
59122
59279
|
import * as net3 from "node:net";
|
|
59123
|
-
import { mkdirSync as mkdirSync22, chmodSync as chmodSync7, chownSync as chownSync2, existsSync as existsSync35, readFileSync as
|
|
59280
|
+
import { mkdirSync as mkdirSync22, chmodSync as chmodSync7, chownSync as chownSync2, existsSync as existsSync35, readFileSync as readFileSync31, readdirSync as readdirSync16, statSync as statSync19, unlinkSync as unlinkSync8, writeFileSync as writeFileSync19, renameSync as renameSync10 } from "node:fs";
|
|
59124
59281
|
import { dirname as dirname6, resolve as resolve26, basename as basename4 } from "node:path";
|
|
59125
59282
|
import * as os4 from "node:os";
|
|
59126
59283
|
import * as path3 from "node:path";
|
|
@@ -59136,7 +59293,7 @@ import {
|
|
|
59136
59293
|
mkdirSync as mkdirSync19,
|
|
59137
59294
|
openSync as openSync6,
|
|
59138
59295
|
closeSync as closeSync6,
|
|
59139
|
-
readFileSync as
|
|
59296
|
+
readFileSync as readFileSync29,
|
|
59140
59297
|
renameSync as renameSync9,
|
|
59141
59298
|
statSync as statSync18,
|
|
59142
59299
|
symlinkSync as symlinkSync3,
|
|
@@ -59292,7 +59449,7 @@ function lstatSyncOrNull(path) {
|
|
|
59292
59449
|
}
|
|
59293
59450
|
}
|
|
59294
59451
|
function sha256File(path) {
|
|
59295
|
-
const data =
|
|
59452
|
+
const data = readFileSync29(path);
|
|
59296
59453
|
return createHash5("sha256").update(data).digest("hex");
|
|
59297
59454
|
}
|
|
59298
59455
|
function atomicReplaceWithSymlink(target, linkTarget) {
|
|
@@ -59327,7 +59484,7 @@ init_loader();
|
|
|
59327
59484
|
|
|
59328
59485
|
// src/vault/auto-unlock.ts
|
|
59329
59486
|
import { createHmac, randomBytes as randomBytes6, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2 } from "node:crypto";
|
|
59330
|
-
import { chmodSync as chmodSync5, existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as
|
|
59487
|
+
import { chmodSync as chmodSync5, existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as readFileSync30, writeFileSync as writeFileSync18 } from "node:fs";
|
|
59331
59488
|
import { dirname as dirname4 } from "node:path";
|
|
59332
59489
|
var FORMAT_VERSION = 1;
|
|
59333
59490
|
var SALT_LEN = 16;
|
|
@@ -59363,7 +59520,7 @@ function readMachineId() {
|
|
|
59363
59520
|
}
|
|
59364
59521
|
for (const path of [MACHINE_ID_PRIMARY, MACHINE_ID_FALLBACK]) {
|
|
59365
59522
|
try {
|
|
59366
|
-
const id =
|
|
59523
|
+
const id = readFileSync30(path, "utf8").trim();
|
|
59367
59524
|
if (id.length > 0)
|
|
59368
59525
|
return id;
|
|
59369
59526
|
} catch {}
|
|
@@ -59427,7 +59584,7 @@ function readAutoUnlockFile(filePath) {
|
|
|
59427
59584
|
}
|
|
59428
59585
|
let blob;
|
|
59429
59586
|
try {
|
|
59430
|
-
blob =
|
|
59587
|
+
blob = readFileSync30(filePath);
|
|
59431
59588
|
} catch {
|
|
59432
59589
|
throw new AutoUnlockDecryptError("io");
|
|
59433
59590
|
}
|
|
@@ -63284,7 +63441,7 @@ class VaultBroker {
|
|
|
63284
63441
|
const credPath = `${dir}/vault-passphrase`;
|
|
63285
63442
|
let passphrase;
|
|
63286
63443
|
try {
|
|
63287
|
-
passphrase =
|
|
63444
|
+
passphrase = readFileSync31(credPath, "utf8").replace(/\n+$/, "");
|
|
63288
63445
|
} catch (err) {
|
|
63289
63446
|
const code = err.code;
|
|
63290
63447
|
if (code === "ENOENT") {
|
|
@@ -63435,9 +63592,9 @@ init_vault();
|
|
|
63435
63592
|
// src/cli/vault-auto-unlock.ts
|
|
63436
63593
|
init_loader();
|
|
63437
63594
|
init_client();
|
|
63438
|
-
var
|
|
63595
|
+
var import_yaml10 = __toESM(require_dist(), 1);
|
|
63439
63596
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
63440
|
-
import { readFileSync as
|
|
63597
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync20 } from "node:fs";
|
|
63441
63598
|
import { homedir as homedir16 } from "node:os";
|
|
63442
63599
|
import { join as join31 } from "node:path";
|
|
63443
63600
|
class EncryptFailedError extends Error {
|
|
@@ -63467,8 +63624,8 @@ function encryptCredential(passphrase, credPath) {
|
|
|
63467
63624
|
}
|
|
63468
63625
|
}
|
|
63469
63626
|
function setVaultBrokerAutoUnlock(configPath, value) {
|
|
63470
|
-
const raw =
|
|
63471
|
-
const doc =
|
|
63627
|
+
const raw = readFileSync32(configPath, "utf-8");
|
|
63628
|
+
const doc = import_yaml10.default.parseDocument(raw);
|
|
63472
63629
|
doc.setIn(["vault", "broker", "autoUnlock"], value);
|
|
63473
63630
|
writeFileSync20(configPath, doc.toString(), "utf-8");
|
|
63474
63631
|
}
|
|
@@ -63662,7 +63819,7 @@ function registerVaultBrokerCommand(vaultCmd, program3) {
|
|
|
63662
63819
|
console.error("vault-broker PID file not found \u2014 is the daemon running?");
|
|
63663
63820
|
process.exit(1);
|
|
63664
63821
|
}
|
|
63665
|
-
const pid = parseInt(
|
|
63822
|
+
const pid = parseInt(readFileSync33(pidPath, "utf8").trim(), 10);
|
|
63666
63823
|
if (isNaN(pid) || pid <= 0) {
|
|
63667
63824
|
console.error("Invalid PID file contents");
|
|
63668
63825
|
process.exit(1);
|
|
@@ -64035,7 +64192,7 @@ Vault Doctor`));
|
|
|
64035
64192
|
|
|
64036
64193
|
// src/cli/vault-audit.ts
|
|
64037
64194
|
init_source();
|
|
64038
|
-
import { existsSync as existsSync38, readFileSync as
|
|
64195
|
+
import { existsSync as existsSync38, readFileSync as readFileSync34 } from "node:fs";
|
|
64039
64196
|
|
|
64040
64197
|
// src/vault/audit-reader.ts
|
|
64041
64198
|
function parseAuditLine(line) {
|
|
@@ -64114,7 +64271,7 @@ function registerVaultAuditCommand(vault, _program) {
|
|
|
64114
64271
|
The log is created when the vault broker handles its first request.`));
|
|
64115
64272
|
process.exit(0);
|
|
64116
64273
|
}
|
|
64117
|
-
const raw =
|
|
64274
|
+
const raw = readFileSync34(logPath, "utf-8");
|
|
64118
64275
|
const rawLines = raw.split(`
|
|
64119
64276
|
`);
|
|
64120
64277
|
const limit = Math.max(1, parseInt(opts.tail ?? "50", 10) || 50);
|
|
@@ -64324,7 +64481,7 @@ import {
|
|
|
64324
64481
|
mkdirSync as mkdirSync23,
|
|
64325
64482
|
openSync as openSync9,
|
|
64326
64483
|
readdirSync as readdirSync17,
|
|
64327
|
-
readFileSync as
|
|
64484
|
+
readFileSync as readFileSync35,
|
|
64328
64485
|
renameSync as renameSync11,
|
|
64329
64486
|
statSync as statSync20,
|
|
64330
64487
|
symlinkSync as symlinkSync4,
|
|
@@ -64371,7 +64528,7 @@ function parseBackupFilename(name) {
|
|
|
64371
64528
|
function validateVaultEnvelopeFile(path4) {
|
|
64372
64529
|
let buf;
|
|
64373
64530
|
try {
|
|
64374
|
-
buf =
|
|
64531
|
+
buf = readFileSync35(path4);
|
|
64375
64532
|
} catch (err) {
|
|
64376
64533
|
return `cannot read ${path4}: ${err.message}`;
|
|
64377
64534
|
}
|
|
@@ -64443,7 +64600,7 @@ function listBackupFiles(dir) {
|
|
|
64443
64600
|
}
|
|
64444
64601
|
function sha256OfFile(path4) {
|
|
64445
64602
|
const h = createHash8("sha256");
|
|
64446
|
-
h.update(
|
|
64603
|
+
h.update(readFileSync35(path4));
|
|
64447
64604
|
return h.digest("hex");
|
|
64448
64605
|
}
|
|
64449
64606
|
function backupVault(opts) {
|
|
@@ -64463,7 +64620,7 @@ function backupVault(opts) {
|
|
|
64463
64620
|
const fullPath = join33(opts.destDir, filename);
|
|
64464
64621
|
const tmpName = `.tmp.${process.pid}.${randomBytes10(4).toString("hex")}`;
|
|
64465
64622
|
const tmpPath = join33(opts.destDir, tmpName);
|
|
64466
|
-
const src =
|
|
64623
|
+
const src = readFileSync35(opts.vaultPath);
|
|
64467
64624
|
const fd = openSync9(tmpPath, "wx", 384);
|
|
64468
64625
|
try {
|
|
64469
64626
|
writeSync5(fd, src);
|
|
@@ -64838,7 +64995,7 @@ function registerVaultCommand(program3) {
|
|
|
64838
64995
|
let isBinaryFile = false;
|
|
64839
64996
|
if (opts.file) {
|
|
64840
64997
|
try {
|
|
64841
|
-
const buf =
|
|
64998
|
+
const buf = readFileSync36(resolvePath(opts.file));
|
|
64842
64999
|
const asUtf8 = buf.toString("utf8");
|
|
64843
65000
|
if (Buffer.compare(buf, Buffer.from(asUtf8, "utf8")) === 0) {
|
|
64844
65001
|
value = asUtf8;
|
|
@@ -65182,7 +65339,7 @@ Push passphrase to broker for future requests? [Y/n]: `);
|
|
|
65182
65339
|
|
|
65183
65340
|
// src/cli/telegram.ts
|
|
65184
65341
|
init_source();
|
|
65185
|
-
import { existsSync as existsSync41, readFileSync as
|
|
65342
|
+
import { existsSync as existsSync41, readFileSync as readFileSync37, writeFileSync as writeFileSync21 } from "node:fs";
|
|
65186
65343
|
import { join as join35 } from "node:path";
|
|
65187
65344
|
|
|
65188
65345
|
// src/web/webhook-dispatch.ts
|
|
@@ -65286,15 +65443,15 @@ init_paths();
|
|
|
65286
65443
|
import { createInterface as createInterface4 } from "node:readline";
|
|
65287
65444
|
|
|
65288
65445
|
// src/cli/telegram-yaml.ts
|
|
65289
|
-
var
|
|
65446
|
+
var import_yaml11 = __toESM(require_dist(), 1);
|
|
65290
65447
|
function setTelegramFeature(yamlText, agentName, feature, value) {
|
|
65291
|
-
const doc =
|
|
65448
|
+
const doc = import_yaml11.parseDocument(yamlText);
|
|
65292
65449
|
ensureAgent(doc, agentName);
|
|
65293
65450
|
doc.setIn(["agents", agentName, "channels", "telegram", feature], value);
|
|
65294
65451
|
return String(doc);
|
|
65295
65452
|
}
|
|
65296
65453
|
function removeTelegramFeature(yamlText, agentName, feature) {
|
|
65297
|
-
const doc =
|
|
65454
|
+
const doc = import_yaml11.parseDocument(yamlText);
|
|
65298
65455
|
if (!hasAgent(doc, agentName))
|
|
65299
65456
|
return yamlText;
|
|
65300
65457
|
if (!doc.hasIn(["agents", agentName, "channels", "telegram", feature])) {
|
|
@@ -65312,21 +65469,21 @@ function ensureAgent(doc, agentName) {
|
|
|
65312
65469
|
}
|
|
65313
65470
|
function hasAgent(doc, agentName) {
|
|
65314
65471
|
const agents = doc.get("agents");
|
|
65315
|
-
if (!
|
|
65472
|
+
if (!import_yaml11.isMap(agents))
|
|
65316
65473
|
return false;
|
|
65317
65474
|
return agents.has(agentName);
|
|
65318
65475
|
}
|
|
65319
65476
|
function pruneEmptyMap2(doc, path4) {
|
|
65320
65477
|
const node = doc.getIn(path4);
|
|
65321
|
-
if (
|
|
65478
|
+
if (import_yaml11.isMap(node) && node.items.length === 0) {
|
|
65322
65479
|
doc.deleteIn(path4);
|
|
65323
65480
|
}
|
|
65324
65481
|
}
|
|
65325
65482
|
function addWebhookSource(yamlText, agentName, source) {
|
|
65326
|
-
const doc =
|
|
65483
|
+
const doc = import_yaml11.parseDocument(yamlText);
|
|
65327
65484
|
ensureAgent(doc, agentName);
|
|
65328
65485
|
const existing = doc.getIn(["agents", agentName, "channels", "telegram", "webhook_sources"]);
|
|
65329
|
-
if (
|
|
65486
|
+
if (import_yaml11.isSeq(existing)) {
|
|
65330
65487
|
const seq = existing;
|
|
65331
65488
|
for (const item of seq.items) {
|
|
65332
65489
|
const v = item.value ?? item;
|
|
@@ -65340,11 +65497,11 @@ function addWebhookSource(yamlText, agentName, source) {
|
|
|
65340
65497
|
return String(doc);
|
|
65341
65498
|
}
|
|
65342
65499
|
function removeWebhookSource(yamlText, agentName, source) {
|
|
65343
|
-
const doc =
|
|
65500
|
+
const doc = import_yaml11.parseDocument(yamlText);
|
|
65344
65501
|
if (!hasAgent(doc, agentName))
|
|
65345
65502
|
return yamlText;
|
|
65346
65503
|
const existing = doc.getIn(["agents", agentName, "channels", "telegram", "webhook_sources"]);
|
|
65347
|
-
if (!
|
|
65504
|
+
if (!import_yaml11.isSeq(existing))
|
|
65348
65505
|
return yamlText;
|
|
65349
65506
|
const seq = existing;
|
|
65350
65507
|
const beforeLen = seq.items.length;
|
|
@@ -65613,7 +65770,7 @@ function registerDisableVerb(tg, program3) {
|
|
|
65613
65770
|
}
|
|
65614
65771
|
async function applyYamlEdit(program3, agent, feature, value, dryRun) {
|
|
65615
65772
|
const path4 = getConfigPath(program3);
|
|
65616
|
-
const before =
|
|
65773
|
+
const before = readFileSync37(path4, "utf-8");
|
|
65617
65774
|
let after;
|
|
65618
65775
|
try {
|
|
65619
65776
|
after = setTelegramFeature(before, agent, feature, value);
|
|
@@ -65628,7 +65785,7 @@ async function applyYamlEdit(program3, agent, feature, value, dryRun) {
|
|
|
65628
65785
|
}
|
|
65629
65786
|
async function applyYamlRemove(program3, agent, feature, dryRun) {
|
|
65630
65787
|
const path4 = getConfigPath(program3);
|
|
65631
|
-
const before =
|
|
65788
|
+
const before = readFileSync37(path4, "utf-8");
|
|
65632
65789
|
const after = removeTelegramFeature(before, agent, feature);
|
|
65633
65790
|
if (before === after) {
|
|
65634
65791
|
console.log(source_default.yellow(`No change \u2014 ${feature.replace("_", "-")} is not set for agent '${agent}'.`));
|
|
@@ -65677,7 +65834,7 @@ function fail(msg) {
|
|
|
65677
65834
|
}
|
|
65678
65835
|
async function applyYamlAddWebhook(program3, agent, source, dryRun) {
|
|
65679
65836
|
const path4 = getConfigPath(program3);
|
|
65680
|
-
const before =
|
|
65837
|
+
const before = readFileSync37(path4, "utf-8");
|
|
65681
65838
|
let after;
|
|
65682
65839
|
try {
|
|
65683
65840
|
after = addWebhookSource(before, agent, source);
|
|
@@ -65697,7 +65854,7 @@ async function applyYamlAddWebhook(program3, agent, source, dryRun) {
|
|
|
65697
65854
|
}
|
|
65698
65855
|
async function applyYamlRemoveWebhook(program3, agent, source, dryRun) {
|
|
65699
65856
|
const path4 = getConfigPath(program3);
|
|
65700
|
-
const before =
|
|
65857
|
+
const before = readFileSync37(path4, "utf-8");
|
|
65701
65858
|
const after = removeWebhookSource(before, agent, source);
|
|
65702
65859
|
if (before === after) {
|
|
65703
65860
|
console.log(source_default.yellow(`No change \u2014 webhook source '${source}' is not currently enabled for agent '${agent}'.`));
|
|
@@ -65754,7 +65911,7 @@ function registerDispatchVerb(tg, _program) {
|
|
|
65754
65911
|
}
|
|
65755
65912
|
let payload;
|
|
65756
65913
|
try {
|
|
65757
|
-
payload = JSON.parse(
|
|
65914
|
+
payload = JSON.parse(readFileSync37(opts.payload, "utf-8"));
|
|
65758
65915
|
} catch (err) {
|
|
65759
65916
|
fail(`Could not read payload file '${opts.payload}': ${err.message}`);
|
|
65760
65917
|
}
|
|
@@ -65875,7 +66032,7 @@ function reflectAcrossAgents(config) {
|
|
|
65875
66032
|
init_helpers();
|
|
65876
66033
|
|
|
65877
66034
|
// src/setup/hindsight.ts
|
|
65878
|
-
import { execFileSync as
|
|
66035
|
+
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
65879
66036
|
import { createServer as createServer4 } from "node:net";
|
|
65880
66037
|
var HINDSIGHT_DEFAULT_API_PORT = 8888;
|
|
65881
66038
|
var HINDSIGHT_DEFAULT_UI_PORT = 9999;
|
|
@@ -65930,7 +66087,7 @@ async function pickHindsightPorts() {
|
|
|
65930
66087
|
}
|
|
65931
66088
|
function isDockerAvailable() {
|
|
65932
66089
|
try {
|
|
65933
|
-
|
|
66090
|
+
execFileSync16("docker", ["--version"], { stdio: "pipe" });
|
|
65934
66091
|
return true;
|
|
65935
66092
|
} catch {
|
|
65936
66093
|
return false;
|
|
@@ -65938,7 +66095,7 @@ function isDockerAvailable() {
|
|
|
65938
66095
|
}
|
|
65939
66096
|
function isHindsightRunning() {
|
|
65940
66097
|
try {
|
|
65941
|
-
const output =
|
|
66098
|
+
const output = execFileSync16("docker", ["ps", "--filter", "name=switchroom-hindsight", "--format", "{{.Status}}"], { stdio: "pipe", encoding: "utf-8" });
|
|
65942
66099
|
return output.trim().length > 0;
|
|
65943
66100
|
} catch {
|
|
65944
66101
|
return false;
|
|
@@ -65946,7 +66103,7 @@ function isHindsightRunning() {
|
|
|
65946
66103
|
}
|
|
65947
66104
|
function isHindsightContainerExists() {
|
|
65948
66105
|
try {
|
|
65949
|
-
const output =
|
|
66106
|
+
const output = execFileSync16("docker", ["ps", "-a", "--filter", "name=switchroom-hindsight", "--format", "{{.Names}}"], { stdio: "pipe", encoding: "utf-8" });
|
|
65950
66107
|
return output.trim().length > 0;
|
|
65951
66108
|
} catch {
|
|
65952
66109
|
return false;
|
|
@@ -65996,19 +66153,19 @@ function startHindsight(ports) {
|
|
|
65996
66153
|
...envArgs,
|
|
65997
66154
|
HINDSIGHT_IMAGE
|
|
65998
66155
|
];
|
|
65999
|
-
|
|
66156
|
+
execFileSync16("docker", args, { stdio: "pipe" });
|
|
66000
66157
|
}
|
|
66001
66158
|
function stopHindsight() {
|
|
66002
66159
|
try {
|
|
66003
|
-
|
|
66160
|
+
execFileSync16("docker", ["stop", "switchroom-hindsight"], { stdio: "pipe" });
|
|
66004
66161
|
} catch {}
|
|
66005
66162
|
try {
|
|
66006
|
-
|
|
66163
|
+
execFileSync16("docker", ["rm", "switchroom-hindsight"], { stdio: "pipe" });
|
|
66007
66164
|
} catch {}
|
|
66008
66165
|
}
|
|
66009
66166
|
function getHindsightStatus() {
|
|
66010
66167
|
try {
|
|
66011
|
-
const output =
|
|
66168
|
+
const output = execFileSync16("docker", ["ps", "-a", "--filter", "name=switchroom-hindsight", "--format", "{{.Status}}"], { stdio: "pipe", encoding: "utf-8" });
|
|
66012
66169
|
const status = output.trim();
|
|
66013
66170
|
return status.length > 0 ? status : null;
|
|
66014
66171
|
} catch {
|
|
@@ -66106,8 +66263,8 @@ async function ensureHindsightConsumer(configPath, account, uid = HINDSIGHT_DEFA
|
|
|
66106
66263
|
|
|
66107
66264
|
// src/cli/memory.ts
|
|
66108
66265
|
init_loader();
|
|
66109
|
-
var
|
|
66110
|
-
import { existsSync as existsSync42, readFileSync as
|
|
66266
|
+
var import_yaml12 = __toESM(require_dist(), 1);
|
|
66267
|
+
import { existsSync as existsSync42, readFileSync as readFileSync38, writeFileSync as writeFileSync22 } from "node:fs";
|
|
66111
66268
|
import { join as join36 } from "node:path";
|
|
66112
66269
|
function readRecallLog(agentDir, limit) {
|
|
66113
66270
|
const path4 = join36(agentDir, ".claude", "plugins", "data", "hindsight-memory-inline", "state", "recall_log.jsonl");
|
|
@@ -66115,7 +66272,7 @@ function readRecallLog(agentDir, limit) {
|
|
|
66115
66272
|
return [];
|
|
66116
66273
|
let raw;
|
|
66117
66274
|
try {
|
|
66118
|
-
raw =
|
|
66275
|
+
raw = readFileSync38(path4, "utf-8");
|
|
66119
66276
|
} catch {
|
|
66120
66277
|
return [];
|
|
66121
66278
|
}
|
|
@@ -66310,8 +66467,8 @@ Cross-agent reflection plan
|
|
|
66310
66467
|
const configPath = getConfigPath(program3);
|
|
66311
66468
|
try {
|
|
66312
66469
|
if (existsSync42(configPath)) {
|
|
66313
|
-
const raw =
|
|
66314
|
-
const doc =
|
|
66470
|
+
const raw = readFileSync38(configPath, "utf-8");
|
|
66471
|
+
const doc = import_yaml12.default.parseDocument(raw);
|
|
66315
66472
|
if (!doc.has("memory")) {
|
|
66316
66473
|
doc.set("memory", { backend: "hindsight", shared_collection: "shared", config: { provider, url } });
|
|
66317
66474
|
} else {
|
|
@@ -66417,7 +66574,7 @@ init_source();
|
|
|
66417
66574
|
init_merge();
|
|
66418
66575
|
init_lifecycle();
|
|
66419
66576
|
import {
|
|
66420
|
-
readFileSync as
|
|
66577
|
+
readFileSync as readFileSync43,
|
|
66421
66578
|
existsSync as existsSync47,
|
|
66422
66579
|
realpathSync as realpathSync3,
|
|
66423
66580
|
mkdirSync as mkdirSync27,
|
|
@@ -66436,7 +66593,7 @@ init_lifecycle();
|
|
|
66436
66593
|
init_manager();
|
|
66437
66594
|
init_hindsight();
|
|
66438
66595
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
66439
|
-
import { existsSync as existsSync44, readFileSync as
|
|
66596
|
+
import { existsSync as existsSync44, readFileSync as readFileSync40 } from "node:fs";
|
|
66440
66597
|
import { resolve as resolve27 } from "node:path";
|
|
66441
66598
|
init_audit_reader();
|
|
66442
66599
|
|
|
@@ -70940,7 +71097,7 @@ init_paths();
|
|
|
70940
71097
|
import {
|
|
70941
71098
|
existsSync as existsSync43,
|
|
70942
71099
|
mkdirSync as mkdirSync24,
|
|
70943
|
-
readFileSync as
|
|
71100
|
+
readFileSync as readFileSync39,
|
|
70944
71101
|
writeFileSync as writeFileSync23
|
|
70945
71102
|
} from "node:fs";
|
|
70946
71103
|
import { dirname as dirname8 } from "node:path";
|
|
@@ -70961,7 +71118,7 @@ function getDistinctId() {
|
|
|
70961
71118
|
const path4 = resolveStatePath("analytics-id");
|
|
70962
71119
|
try {
|
|
70963
71120
|
if (existsSync43(path4)) {
|
|
70964
|
-
const existing =
|
|
71121
|
+
const existing = readFileSync39(path4, "utf-8").trim();
|
|
70965
71122
|
if (existing) {
|
|
70966
71123
|
cachedDistinctId = existing;
|
|
70967
71124
|
return existing;
|
|
@@ -71537,7 +71694,7 @@ async function handleGetSystemHealth(home2) {
|
|
|
71537
71694
|
const logPath = defaultAuditLogPath2(home2);
|
|
71538
71695
|
if (existsSync44(logPath)) {
|
|
71539
71696
|
hostd.auditLogPresent = true;
|
|
71540
|
-
const raw =
|
|
71697
|
+
const raw = readFileSync40(logPath, "utf-8");
|
|
71541
71698
|
hostd.recent = readAndFilter(raw, {}, 10);
|
|
71542
71699
|
}
|
|
71543
71700
|
} catch (err) {
|
|
@@ -71582,6 +71739,70 @@ async function handleGetGoogleAccounts(config) {
|
|
|
71582
71739
|
}
|
|
71583
71740
|
return out;
|
|
71584
71741
|
}
|
|
71742
|
+
async function handleGetMicrosoftAccounts(config) {
|
|
71743
|
+
const live = new Map;
|
|
71744
|
+
try {
|
|
71745
|
+
await withAuthBrokerClient(async (client2) => {
|
|
71746
|
+
const data = await client2.listMicrosoftAccounts();
|
|
71747
|
+
for (const a of data.accounts) {
|
|
71748
|
+
live.set(a.account.toLowerCase(), {
|
|
71749
|
+
expiresAt: a.expiresAt,
|
|
71750
|
+
scope: a.scope,
|
|
71751
|
+
clientId: a.clientId,
|
|
71752
|
+
accountType: a.accountType
|
|
71753
|
+
});
|
|
71754
|
+
}
|
|
71755
|
+
});
|
|
71756
|
+
} catch (err) {
|
|
71757
|
+
if (!(err instanceof AuthBrokerUnreachableError))
|
|
71758
|
+
throw err;
|
|
71759
|
+
}
|
|
71760
|
+
const cfgAccounts = config.microsoft_accounts ?? {};
|
|
71761
|
+
const keys = new Set([
|
|
71762
|
+
...Object.keys(cfgAccounts).map((k) => k.toLowerCase()),
|
|
71763
|
+
...live.keys()
|
|
71764
|
+
]);
|
|
71765
|
+
const out = [];
|
|
71766
|
+
for (const key of [...keys].sort()) {
|
|
71767
|
+
const cfg = cfgAccounts[key];
|
|
71768
|
+
const l = live.get(key);
|
|
71769
|
+
out.push({
|
|
71770
|
+
account: key,
|
|
71771
|
+
expiresAt: l?.expiresAt ?? null,
|
|
71772
|
+
scope: l?.scope ?? null,
|
|
71773
|
+
clientId: l?.clientId ?? null,
|
|
71774
|
+
accountType: l?.accountType ?? null,
|
|
71775
|
+
enabledFor: cfg?.enabled_for ? [...cfg.enabled_for].sort() : [],
|
|
71776
|
+
brokerKnown: l != null
|
|
71777
|
+
});
|
|
71778
|
+
}
|
|
71779
|
+
return out;
|
|
71780
|
+
}
|
|
71781
|
+
function handleGetNotionWorkspace(config) {
|
|
71782
|
+
const nw = config.notion_workspace;
|
|
71783
|
+
if (!nw) {
|
|
71784
|
+
return { configured: false, vaultKey: null, databases: [], fullAccessAgents: [] };
|
|
71785
|
+
}
|
|
71786
|
+
const declared = nw.databases ?? {};
|
|
71787
|
+
const agentNames = Object.keys(config.agents ?? {});
|
|
71788
|
+
const databases = Object.entries(declared).map(([name, id]) => {
|
|
71789
|
+
const enabledFor = agentNames.filter((n) => agentCanAccessNotionDB(config, n, id)).sort();
|
|
71790
|
+
return { name, id, enabledFor };
|
|
71791
|
+
}).sort((a, b) => a.name.localeCompare(b.name));
|
|
71792
|
+
const agentsRaw = config.agents ?? {};
|
|
71793
|
+
const fullAccessAgents = agentNames.filter((n) => {
|
|
71794
|
+
if (!shouldEmitNotionMcp(n, config))
|
|
71795
|
+
return false;
|
|
71796
|
+
const dbs = agentsRaw[n]?.notion_workspace?.databases;
|
|
71797
|
+
return dbs === undefined || dbs.length === 0;
|
|
71798
|
+
}).sort();
|
|
71799
|
+
return {
|
|
71800
|
+
configured: true,
|
|
71801
|
+
vaultKey: nw.vault_key ?? null,
|
|
71802
|
+
databases,
|
|
71803
|
+
fullAccessAgents
|
|
71804
|
+
};
|
|
71805
|
+
}
|
|
71585
71806
|
function handleGetSchedule(config) {
|
|
71586
71807
|
const entries = collectScheduleEntries(config);
|
|
71587
71808
|
const agentsDir = resolveAgentsDir(config);
|
|
@@ -71616,7 +71837,7 @@ async function handleGetApprovals() {
|
|
|
71616
71837
|
}
|
|
71617
71838
|
|
|
71618
71839
|
// src/web/webhook-handler.ts
|
|
71619
|
-
import { appendFileSync as appendFileSync3, existsSync as existsSync46, mkdirSync as mkdirSync26, readFileSync as
|
|
71840
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync46, mkdirSync as mkdirSync26, readFileSync as readFileSync42, writeFileSync as writeFileSync24 } from "fs";
|
|
71620
71841
|
import { join as join40 } from "path";
|
|
71621
71842
|
import { homedir as homedir21 } from "os";
|
|
71622
71843
|
|
|
@@ -71768,7 +71989,7 @@ function forwardToGateway(socketPath, req, opts = {}) {
|
|
|
71768
71989
|
}
|
|
71769
71990
|
|
|
71770
71991
|
// src/web/webhook-edge.ts
|
|
71771
|
-
import { existsSync as existsSync45, readFileSync as
|
|
71992
|
+
import { existsSync as existsSync45, readFileSync as readFileSync41 } from "fs";
|
|
71772
71993
|
import { join as join39 } from "path";
|
|
71773
71994
|
import { homedir as homedir20 } from "os";
|
|
71774
71995
|
import { timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
@@ -71781,7 +72002,7 @@ function loadEdgeSecret(path4) {
|
|
|
71781
72002
|
try {
|
|
71782
72003
|
if (!existsSync45(p))
|
|
71783
72004
|
return null;
|
|
71784
|
-
const raw =
|
|
72005
|
+
const raw = readFileSync41(p, "utf-8").trim();
|
|
71785
72006
|
return raw.length > 0 ? raw : null;
|
|
71786
72007
|
} catch {
|
|
71787
72008
|
return null;
|
|
@@ -71815,7 +72036,7 @@ function loadDedupFile(path4) {
|
|
|
71815
72036
|
try {
|
|
71816
72037
|
if (!existsSync46(path4))
|
|
71817
72038
|
return {};
|
|
71818
|
-
const raw = JSON.parse(
|
|
72039
|
+
const raw = JSON.parse(readFileSync42(path4, "utf-8"));
|
|
71819
72040
|
return typeof raw.deliveries === "object" && raw.deliveries !== null ? raw.deliveries : {};
|
|
71820
72041
|
} catch {
|
|
71821
72042
|
return {};
|
|
@@ -72095,7 +72316,7 @@ function resolveWebToken() {
|
|
|
72095
72316
|
const home2 = process.env.HOME ?? homedir22();
|
|
72096
72317
|
const tokenPath = join41(home2, ".switchroom", "web-token");
|
|
72097
72318
|
if (existsSync47(tokenPath)) {
|
|
72098
|
-
const existing =
|
|
72319
|
+
const existing = readFileSync43(tokenPath, "utf8").trim();
|
|
72099
72320
|
if (existing.length > 0)
|
|
72100
72321
|
return existing;
|
|
72101
72322
|
}
|
|
@@ -72112,7 +72333,7 @@ function resolveWebToken() {
|
|
|
72112
72333
|
return token;
|
|
72113
72334
|
} catch (err) {
|
|
72114
72335
|
if (err.code === "EEXIST") {
|
|
72115
|
-
const existing =
|
|
72336
|
+
const existing = readFileSync43(tokenPath, "utf8").trim();
|
|
72116
72337
|
if (existing.length > 0)
|
|
72117
72338
|
return existing;
|
|
72118
72339
|
}
|
|
@@ -72182,7 +72403,7 @@ function loadWebhookSecrets() {
|
|
|
72182
72403
|
if (!existsSync47(path4))
|
|
72183
72404
|
return {};
|
|
72184
72405
|
try {
|
|
72185
|
-
const parsed = JSON.parse(
|
|
72406
|
+
const parsed = JSON.parse(readFileSync43(path4, "utf-8"));
|
|
72186
72407
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
72187
72408
|
} catch (err) {
|
|
72188
72409
|
process.stderr.write(`webhook-ingest: failed to parse ${path4}: ${err.message} \u2014 webhooks will return 401 until fixed
|
|
@@ -72259,6 +72480,12 @@ function parseRoute(pathname, method) {
|
|
|
72259
72480
|
if (method === "GET" && pathname === "/api/google-accounts") {
|
|
72260
72481
|
return { handler: "getGoogleAccounts", params: {} };
|
|
72261
72482
|
}
|
|
72483
|
+
if (method === "GET" && pathname === "/api/microsoft-accounts") {
|
|
72484
|
+
return { handler: "getMicrosoftAccounts", params: {} };
|
|
72485
|
+
}
|
|
72486
|
+
if (method === "GET" && pathname === "/api/notion-workspace") {
|
|
72487
|
+
return { handler: "getNotionWorkspace", params: {} };
|
|
72488
|
+
}
|
|
72262
72489
|
if (method === "GET" && pathname === "/api/schedule") {
|
|
72263
72490
|
return { handler: "getSchedule", params: {} };
|
|
72264
72491
|
}
|
|
@@ -72384,6 +72611,10 @@ function startWebServer(config, port, hostname = "127.0.0.1", configPath) {
|
|
|
72384
72611
|
return (async () => jsonResponse(await handleGetSystemHealth()))();
|
|
72385
72612
|
case "getGoogleAccounts":
|
|
72386
72613
|
return (async () => jsonResponse(await handleGetGoogleAccounts(config)))();
|
|
72614
|
+
case "getMicrosoftAccounts":
|
|
72615
|
+
return (async () => jsonResponse(await handleGetMicrosoftAccounts(config)))();
|
|
72616
|
+
case "getNotionWorkspace":
|
|
72617
|
+
return jsonResponse(handleGetNotionWorkspace(config));
|
|
72387
72618
|
case "getSchedule":
|
|
72388
72619
|
return jsonResponse(handleGetSchedule(config));
|
|
72389
72620
|
case "getApprovals":
|
|
@@ -72457,7 +72688,7 @@ function startWebServer(config, port, hostname = "127.0.0.1", configPath) {
|
|
|
72457
72688
|
}
|
|
72458
72689
|
const ext = extname(realFullPath);
|
|
72459
72690
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
72460
|
-
const content =
|
|
72691
|
+
const content = readFileSync43(realFullPath);
|
|
72461
72692
|
return new Response(content, {
|
|
72462
72693
|
headers: { "Content-Type": contentType }
|
|
72463
72694
|
});
|
|
@@ -72591,26 +72822,26 @@ Starting Switchroom dashboard...
|
|
|
72591
72822
|
// src/cli/setup.ts
|
|
72592
72823
|
init_source();
|
|
72593
72824
|
init_loader();
|
|
72594
|
-
import { existsSync as existsSync48, copyFileSync as copyFileSync8, readFileSync as
|
|
72825
|
+
import { existsSync as existsSync48, copyFileSync as copyFileSync8, readFileSync as readFileSync44, writeFileSync as writeFileSync25, mkdirSync as mkdirSync28 } from "node:fs";
|
|
72595
72826
|
import { resolve as resolve29, dirname as dirname10 } from "node:path";
|
|
72596
72827
|
init_vault();
|
|
72597
72828
|
init_manager();
|
|
72598
72829
|
|
|
72599
72830
|
// src/cli/setup-posture-rewrite.ts
|
|
72600
|
-
var
|
|
72831
|
+
var import_yaml13 = __toESM(require_dist(), 1);
|
|
72601
72832
|
function insertVaultBrokerApprovalAuth(source, value = "telegram-id") {
|
|
72602
72833
|
let doc;
|
|
72603
72834
|
try {
|
|
72604
|
-
doc =
|
|
72835
|
+
doc = import_yaml13.default.parseDocument(source);
|
|
72605
72836
|
} catch {
|
|
72606
72837
|
return { kind: "not-found" };
|
|
72607
72838
|
}
|
|
72608
72839
|
const vault = doc.get("vault");
|
|
72609
|
-
if (!vault || !
|
|
72840
|
+
if (!vault || !import_yaml13.default.isMap(vault)) {
|
|
72610
72841
|
return { kind: "not-found" };
|
|
72611
72842
|
}
|
|
72612
72843
|
const broker = vault.get("broker");
|
|
72613
|
-
if (!broker || !
|
|
72844
|
+
if (!broker || !import_yaml13.default.isMap(broker)) {
|
|
72614
72845
|
return { kind: "not-found" };
|
|
72615
72846
|
}
|
|
72616
72847
|
if (broker.has("approvalAuth")) {
|
|
@@ -72661,7 +72892,7 @@ ${childIndent}approvalAuth: ${value}`;
|
|
|
72661
72892
|
}
|
|
72662
72893
|
|
|
72663
72894
|
// src/cli/supergroup-setup-yaml.ts
|
|
72664
|
-
var
|
|
72895
|
+
var import_yaml14 = __toESM(require_dist(), 1);
|
|
72665
72896
|
function isValidSupergroupChatId(value) {
|
|
72666
72897
|
return /^-\d+$/.test(value);
|
|
72667
72898
|
}
|
|
@@ -72669,23 +72900,23 @@ function setAgentSupergroupChatId(yamlText, agentName, chatId) {
|
|
|
72669
72900
|
if (!isValidSupergroupChatId(chatId)) {
|
|
72670
72901
|
throw new Error(`setAgentSupergroupChatId: chat_id must be a negative integer string (got "${chatId}")`);
|
|
72671
72902
|
}
|
|
72672
|
-
const doc =
|
|
72903
|
+
const doc = import_yaml14.parseDocument(yamlText);
|
|
72673
72904
|
const root = doc.contents;
|
|
72674
|
-
if (!
|
|
72905
|
+
if (!import_yaml14.isMap(root)) {
|
|
72675
72906
|
throw new Error("setAgentSupergroupChatId: YAML root is not a map");
|
|
72676
72907
|
}
|
|
72677
72908
|
const agents = root.get("agents", true);
|
|
72678
|
-
if (!
|
|
72909
|
+
if (!import_yaml14.isMap(agents)) {
|
|
72679
72910
|
throw new Error("setAgentSupergroupChatId: config has no `agents:` map");
|
|
72680
72911
|
}
|
|
72681
72912
|
const agent = agents.get(agentName, true);
|
|
72682
|
-
if (!
|
|
72913
|
+
if (!import_yaml14.isMap(agent)) {
|
|
72683
72914
|
throw new Error(`setAgentSupergroupChatId: agent "${agentName}" not found in config`);
|
|
72684
72915
|
}
|
|
72685
72916
|
const channels = agent.get("channels", true);
|
|
72686
|
-
if (
|
|
72917
|
+
if (import_yaml14.isMap(channels)) {
|
|
72687
72918
|
const telegram = channels.get("telegram", true);
|
|
72688
|
-
if (
|
|
72919
|
+
if (import_yaml14.isMap(telegram)) {
|
|
72689
72920
|
if (telegram.get("chat_id") === chatId)
|
|
72690
72921
|
return yamlText;
|
|
72691
72922
|
telegram.set("chat_id", chatId);
|
|
@@ -73320,7 +73551,7 @@ async function stepAutoUnlock(config, switchroomConfigPath, nonInteractive) {
|
|
|
73320
73551
|
try {
|
|
73321
73552
|
const yamlPath = existsSync48(resolve29(process.cwd(), "switchroom.yaml")) ? resolve29(process.cwd(), "switchroom.yaml") : resolve29(process.cwd(), "switchroom.yml");
|
|
73322
73553
|
if (existsSync48(yamlPath)) {
|
|
73323
|
-
const content =
|
|
73554
|
+
const content = readFileSync44(yamlPath, "utf-8");
|
|
73324
73555
|
const result = insertVaultBrokerApprovalAuth(content, "telegram-id");
|
|
73325
73556
|
if (result.kind === "rewritten") {
|
|
73326
73557
|
writeFileSync25(yamlPath, result.content, "utf-8");
|
|
@@ -73355,7 +73586,7 @@ async function stepDangerousMode(config, nonInteractive) {
|
|
|
73355
73586
|
];
|
|
73356
73587
|
for (const configPath of configPaths) {
|
|
73357
73588
|
if (existsSync48(configPath)) {
|
|
73358
|
-
let content =
|
|
73589
|
+
let content = readFileSync44(configPath, "utf-8");
|
|
73359
73590
|
const agentNames = Object.keys(config.agents);
|
|
73360
73591
|
for (const name of agentNames) {
|
|
73361
73592
|
const agentPattern = new RegExp(`(^ ${name}:\\s*\\n)`, "m");
|
|
@@ -73465,9 +73696,9 @@ async function stepVerification(config, nonInteractive) {
|
|
|
73465
73696
|
Start ${source_default.cyan(firstName)} now?`, false);
|
|
73466
73697
|
if (startNow) {
|
|
73467
73698
|
try {
|
|
73468
|
-
const { execFileSync:
|
|
73699
|
+
const { execFileSync: execFileSync17 } = await import("node:child_process");
|
|
73469
73700
|
console.log(source_default.gray(` Starting ${firstName}...`));
|
|
73470
|
-
|
|
73701
|
+
execFileSync17("switchroom", ["agent", "start", firstName], { stdio: "inherit" });
|
|
73471
73702
|
console.log(source_default.green(` ${STEP_DONE} Agent started`));
|
|
73472
73703
|
} catch {
|
|
73473
73704
|
console.log(source_default.yellow(` Could not start automatically. Run: switchroom agent start ${firstName}`));
|
|
@@ -73484,7 +73715,7 @@ init_doctor();
|
|
|
73484
73715
|
init_source();
|
|
73485
73716
|
init_loader();
|
|
73486
73717
|
init_lifecycle();
|
|
73487
|
-
import { cpSync as cpSync2, existsSync as existsSync55, mkdirSync as mkdirSync30, readFileSync as
|
|
73718
|
+
import { cpSync as cpSync2, existsSync as existsSync55, mkdirSync as mkdirSync30, readFileSync as readFileSync49, realpathSync as realpathSync5, rmSync as rmSync12, statSync as statSync24 } from "node:fs";
|
|
73488
73719
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
73489
73720
|
import { join as join55, dirname as dirname13, resolve as resolve33 } from "node:path";
|
|
73490
73721
|
import { homedir as homedir33 } from "node:os";
|
|
@@ -73494,7 +73725,7 @@ function runningFromSwitchroomCheckout(scriptPath) {
|
|
|
73494
73725
|
for (let i = 0;i < 12; i++) {
|
|
73495
73726
|
if (existsSync55(join55(dir, ".git"))) {
|
|
73496
73727
|
try {
|
|
73497
|
-
const pkg = JSON.parse(
|
|
73728
|
+
const pkg = JSON.parse(readFileSync49(join55(dir, "package.json"), "utf-8"));
|
|
73498
73729
|
if (pkg.name === "switchroom")
|
|
73499
73730
|
return true;
|
|
73500
73731
|
} catch {}
|
|
@@ -73762,7 +73993,7 @@ function defaultStatusProbe(composePath) {
|
|
|
73762
73993
|
const pkgPath = join55(dir, "package.json");
|
|
73763
73994
|
if (existsSync55(pkgPath)) {
|
|
73764
73995
|
try {
|
|
73765
|
-
const pkg = JSON.parse(
|
|
73996
|
+
const pkg = JSON.parse(readFileSync49(pkgPath, "utf-8"));
|
|
73766
73997
|
if (typeof pkg.version === "string")
|
|
73767
73998
|
cliVersion = pkg.version;
|
|
73768
73999
|
} catch (err) {
|
|
@@ -73978,7 +74209,7 @@ init_source();
|
|
|
73978
74209
|
init_helpers();
|
|
73979
74210
|
init_lifecycle();
|
|
73980
74211
|
import { execSync as execSync4 } from "node:child_process";
|
|
73981
|
-
import { existsSync as existsSync56, readFileSync as
|
|
74212
|
+
import { existsSync as existsSync56, readFileSync as readFileSync50 } from "node:fs";
|
|
73982
74213
|
import { dirname as dirname14, join as join56 } from "node:path";
|
|
73983
74214
|
function getClaudeCodeVersion() {
|
|
73984
74215
|
try {
|
|
@@ -74032,7 +74263,7 @@ function locateSwitchroomInstallDir() {
|
|
|
74032
74263
|
const pkgPath = join56(dir, "package.json");
|
|
74033
74264
|
if (existsSync56(pkgPath)) {
|
|
74034
74265
|
try {
|
|
74035
|
-
const pkg = JSON.parse(
|
|
74266
|
+
const pkg = JSON.parse(readFileSync50(pkgPath, "utf-8"));
|
|
74036
74267
|
if (pkg.name === "switchroom" && existsSync56(join56(dir, ".git"))) {
|
|
74037
74268
|
return dir;
|
|
74038
74269
|
}
|
|
@@ -74263,7 +74494,7 @@ import {
|
|
|
74263
74494
|
mkdirSync as mkdirSync31,
|
|
74264
74495
|
openSync as openSync11,
|
|
74265
74496
|
readdirSync as readdirSync21,
|
|
74266
|
-
readFileSync as
|
|
74497
|
+
readFileSync as readFileSync51,
|
|
74267
74498
|
renameSync as renameSync12,
|
|
74268
74499
|
statSync as statSync25,
|
|
74269
74500
|
unlinkSync as unlinkSync11,
|
|
@@ -74673,7 +74904,7 @@ function readAll(stateDir) {
|
|
|
74673
74904
|
return [];
|
|
74674
74905
|
let raw;
|
|
74675
74906
|
try {
|
|
74676
|
-
raw =
|
|
74907
|
+
raw = readFileSync51(path4, "utf-8");
|
|
74677
74908
|
} catch {
|
|
74678
74909
|
return [];
|
|
74679
74910
|
}
|
|
@@ -74884,7 +75115,7 @@ function withLock(stateDir, fn) {
|
|
|
74884
75115
|
function tryStealStaleLock(lockPath) {
|
|
74885
75116
|
let pidStr;
|
|
74886
75117
|
try {
|
|
74887
|
-
pidStr =
|
|
75118
|
+
pidStr = readFileSync51(lockPath, "utf-8").trim();
|
|
74888
75119
|
} catch {
|
|
74889
75120
|
return true;
|
|
74890
75121
|
}
|
|
@@ -75141,13 +75372,13 @@ import { createHash as createHash11 } from "node:crypto";
|
|
|
75141
75372
|
import {
|
|
75142
75373
|
existsSync as existsSync58,
|
|
75143
75374
|
mkdirSync as mkdirSync32,
|
|
75144
|
-
readFileSync as
|
|
75375
|
+
readFileSync as readFileSync52,
|
|
75145
75376
|
rmSync as rmSync13,
|
|
75146
75377
|
writeFileSync as writeFileSync27
|
|
75147
75378
|
} from "node:fs";
|
|
75148
75379
|
import { dirname as dirname15, join as join58 } from "node:path";
|
|
75149
75380
|
import { homedir as homedir34 } from "node:os";
|
|
75150
|
-
import { execFileSync as
|
|
75381
|
+
import { execFileSync as execFileSync18 } from "node:child_process";
|
|
75151
75382
|
|
|
75152
75383
|
class PythonEnvError extends Error {
|
|
75153
75384
|
stderr;
|
|
@@ -75161,7 +75392,7 @@ function defaultPythonCacheRoot() {
|
|
|
75161
75392
|
return join58(homedir34(), ".switchroom", "deps", "python");
|
|
75162
75393
|
}
|
|
75163
75394
|
function hashFile(path4) {
|
|
75164
|
-
return createHash11("sha256").update(
|
|
75395
|
+
return createHash11("sha256").update(readFileSync52(path4)).digest("hex");
|
|
75165
75396
|
}
|
|
75166
75397
|
function ensurePythonEnv(opts) {
|
|
75167
75398
|
const { skillName, requirementsPath, force = false } = opts;
|
|
@@ -75177,7 +75408,7 @@ function ensurePythonEnv(opts) {
|
|
|
75177
75408
|
const pipBin = join58(binDir, "pip");
|
|
75178
75409
|
const targetHash = hashFile(requirementsPath);
|
|
75179
75410
|
if (!force && existsSync58(stampPath) && existsSync58(pythonBin)) {
|
|
75180
|
-
const existingHash =
|
|
75411
|
+
const existingHash = readFileSync52(stampPath, "utf8").trim();
|
|
75181
75412
|
if (existingHash === targetHash) {
|
|
75182
75413
|
return {
|
|
75183
75414
|
skillName,
|
|
@@ -75194,7 +75425,7 @@ function ensurePythonEnv(opts) {
|
|
|
75194
75425
|
}
|
|
75195
75426
|
mkdirSync32(dirname15(venvDir), { recursive: true });
|
|
75196
75427
|
try {
|
|
75197
|
-
|
|
75428
|
+
execFileSync18(hostPython, ["-m", "venv", venvDir], { stdio: "pipe" });
|
|
75198
75429
|
} catch (err) {
|
|
75199
75430
|
const e = err;
|
|
75200
75431
|
throw new PythonEnvError(`Failed to create venv for skill "${skillName}" with ${hostPython}: ${e.message}`, e.stderr?.toString());
|
|
@@ -75206,7 +75437,7 @@ function ensurePythonEnv(opts) {
|
|
|
75206
75437
|
delete childEnv.PIP_TARGET;
|
|
75207
75438
|
delete childEnv.PIP_PREFIX;
|
|
75208
75439
|
delete childEnv.PYTHONUSERBASE;
|
|
75209
|
-
|
|
75440
|
+
execFileSync18(pipBin, ["install", "--disable-pip-version-check", "-r", requirementsPath], { stdio: "pipe", env: childEnv });
|
|
75210
75441
|
} catch (err) {
|
|
75211
75442
|
const e = err;
|
|
75212
75443
|
throw new PythonEnvError(`Failed to install requirements for skill "${skillName}": ${e.message}`, e.stderr?.toString());
|
|
@@ -75229,13 +75460,13 @@ import {
|
|
|
75229
75460
|
copyFileSync as copyFileSync9,
|
|
75230
75461
|
existsSync as existsSync59,
|
|
75231
75462
|
mkdirSync as mkdirSync33,
|
|
75232
|
-
readFileSync as
|
|
75463
|
+
readFileSync as readFileSync53,
|
|
75233
75464
|
rmSync as rmSync14,
|
|
75234
75465
|
writeFileSync as writeFileSync28
|
|
75235
75466
|
} from "node:fs";
|
|
75236
75467
|
import { dirname as dirname16, join as join59 } from "node:path";
|
|
75237
75468
|
import { homedir as homedir35 } from "node:os";
|
|
75238
|
-
import { execFileSync as
|
|
75469
|
+
import { execFileSync as execFileSync19 } from "node:child_process";
|
|
75239
75470
|
|
|
75240
75471
|
class NodeEnvError extends Error {
|
|
75241
75472
|
stderr;
|
|
@@ -75264,7 +75495,7 @@ function hashDepInputs(packageJsonPath) {
|
|
|
75264
75495
|
const hasher = createHash12("sha256");
|
|
75265
75496
|
hasher.update(`package.json
|
|
75266
75497
|
`);
|
|
75267
|
-
hasher.update(
|
|
75498
|
+
hasher.update(readFileSync53(packageJsonPath));
|
|
75268
75499
|
for (const lockName of ALL_LOCKFILES) {
|
|
75269
75500
|
const lockPath = join59(sourceDir, lockName);
|
|
75270
75501
|
if (existsSync59(lockPath)) {
|
|
@@ -75273,7 +75504,7 @@ function hashDepInputs(packageJsonPath) {
|
|
|
75273
75504
|
hasher.update(lockName);
|
|
75274
75505
|
hasher.update(`
|
|
75275
75506
|
`);
|
|
75276
|
-
hasher.update(
|
|
75507
|
+
hasher.update(readFileSync53(lockPath));
|
|
75277
75508
|
}
|
|
75278
75509
|
}
|
|
75279
75510
|
return hasher.digest("hex");
|
|
@@ -75292,7 +75523,7 @@ function ensureNodeEnv(opts) {
|
|
|
75292
75523
|
const binDir = join59(nodeModulesDir, ".bin");
|
|
75293
75524
|
const targetHash = hashDepInputs(packageJsonPath);
|
|
75294
75525
|
if (!force && existsSync59(stampPath) && existsSync59(nodeModulesDir)) {
|
|
75295
|
-
const existingHash =
|
|
75526
|
+
const existingHash = readFileSync53(stampPath, "utf8").trim();
|
|
75296
75527
|
if (existingHash === targetHash) {
|
|
75297
75528
|
return {
|
|
75298
75529
|
skillName,
|
|
@@ -75319,10 +75550,10 @@ function ensureNodeEnv(opts) {
|
|
|
75319
75550
|
try {
|
|
75320
75551
|
if (installer === "bun") {
|
|
75321
75552
|
const args = copiedLockfile ? ["install", "--frozen-lockfile"] : ["install"];
|
|
75322
|
-
|
|
75553
|
+
execFileSync19("bun", args, { cwd: envDir, stdio: "pipe" });
|
|
75323
75554
|
} else {
|
|
75324
75555
|
const args = copiedLockfile ? ["ci"] : ["install"];
|
|
75325
|
-
|
|
75556
|
+
execFileSync19("npm", args, { cwd: envDir, stdio: "pipe" });
|
|
75326
75557
|
}
|
|
75327
75558
|
} catch (err) {
|
|
75328
75559
|
const e = err;
|
|
@@ -76311,7 +76542,7 @@ function safeParseInt(value, fallback) {
|
|
|
76311
76542
|
init_helpers();
|
|
76312
76543
|
init_loader();
|
|
76313
76544
|
init_merge();
|
|
76314
|
-
import { copyFileSync as copyFileSync10, existsSync as existsSync62, readFileSync as
|
|
76545
|
+
import { copyFileSync as copyFileSync10, existsSync as existsSync62, readFileSync as readFileSync54, writeFileSync as writeFileSync29 } from "node:fs";
|
|
76315
76546
|
import { join as join61, resolve as resolve39 } from "node:path";
|
|
76316
76547
|
init_schema();
|
|
76317
76548
|
function resolveSoulTargetOrExit(program3, agentName) {
|
|
@@ -76357,7 +76588,7 @@ function registerSoulCommand(program3) {
|
|
|
76357
76588
|
console.error(`soul: ${t.soulPath} does not exist yet \u2014 run ` + `\`switchroom soul reset ${agentName}\` to seed it.`);
|
|
76358
76589
|
process.exit(1);
|
|
76359
76590
|
}
|
|
76360
|
-
process.stdout.write(
|
|
76591
|
+
process.stdout.write(readFileSync54(t.soulPath, "utf-8"));
|
|
76361
76592
|
}));
|
|
76362
76593
|
cmd.command("reset <agent>").description("Re-seed SOUL.md from the agent's current profile " + "(backs the existing file up to SOUL.md.bak first)").option("-y, --yes", "Skip the confirmation prompt").action(withConfigError(async (agentName, opts) => {
|
|
76363
76594
|
const t = resolveSoulTargetOrExit(program3, agentName);
|
|
@@ -76402,7 +76633,7 @@ function registerSoulCommand(program3) {
|
|
|
76402
76633
|
// src/cli/debug.ts
|
|
76403
76634
|
init_helpers();
|
|
76404
76635
|
init_loader();
|
|
76405
|
-
import { existsSync as existsSync63, readFileSync as
|
|
76636
|
+
import { existsSync as existsSync63, readFileSync as readFileSync55, readdirSync as readdirSync22, statSync as statSync26 } from "node:fs";
|
|
76406
76637
|
import { resolve as resolve40, join as join62 } from "node:path";
|
|
76407
76638
|
import { createHash as createHash13 } from "node:crypto";
|
|
76408
76639
|
init_merge();
|
|
@@ -76442,7 +76673,7 @@ function findLatestTranscriptJsonl(claudeConfigDir) {
|
|
|
76442
76673
|
}
|
|
76443
76674
|
function extractLatestUserMessage(transcriptPath) {
|
|
76444
76675
|
try {
|
|
76445
|
-
const content =
|
|
76676
|
+
const content = readFileSync55(transcriptPath, "utf-8");
|
|
76446
76677
|
const lines = content.trim().split(`
|
|
76447
76678
|
`).filter(Boolean);
|
|
76448
76679
|
for (let i = lines.length - 1;i >= 0; i--) {
|
|
@@ -76546,7 +76777,7 @@ function registerDebugCommand(program3) {
|
|
|
76546
76777
|
}
|
|
76547
76778
|
console.log(`=== Append System Prompt (per-session) ===
|
|
76548
76779
|
`);
|
|
76549
|
-
const handoffContent = existsSync63(handoffPath) ?
|
|
76780
|
+
const handoffContent = existsSync63(handoffPath) ? readFileSync55(handoffPath, "utf-8") : "";
|
|
76550
76781
|
if (handoffContent.trim().length > 0) {
|
|
76551
76782
|
console.log(`-- Handoff Briefing (${formatBytes(handoffContent.length)}) --`);
|
|
76552
76783
|
console.log(handoffContent);
|
|
@@ -76557,7 +76788,7 @@ function registerDebugCommand(program3) {
|
|
|
76557
76788
|
}
|
|
76558
76789
|
console.log(`=== CLAUDE.md (auto-loaded by Claude Code) ===
|
|
76559
76790
|
`);
|
|
76560
|
-
const claudeMdContent = existsSync63(claudeMdPath) ?
|
|
76791
|
+
const claudeMdContent = existsSync63(claudeMdPath) ? readFileSync55(claudeMdPath, "utf-8") : "";
|
|
76561
76792
|
if (claudeMdContent.trim().length > 0) {
|
|
76562
76793
|
console.log(`(${formatBytes(claudeMdContent.length)})`);
|
|
76563
76794
|
console.log(claudeMdContent);
|
|
@@ -76568,7 +76799,7 @@ function registerDebugCommand(program3) {
|
|
|
76568
76799
|
}
|
|
76569
76800
|
console.log(`=== Persona (SOUL.md) ===
|
|
76570
76801
|
`);
|
|
76571
|
-
const soulMdContent = existsSync63(soulMdPath) ?
|
|
76802
|
+
const soulMdContent = existsSync63(soulMdPath) ? readFileSync55(soulMdPath, "utf-8") : existsSync63(workspaceSoulMdPath) ? readFileSync55(workspaceSoulMdPath, "utf-8") : "";
|
|
76572
76803
|
if (soulMdContent.trim().length > 0) {
|
|
76573
76804
|
console.log(`(${formatBytes(soulMdContent.length)})`);
|
|
76574
76805
|
console.log(soulMdContent);
|
|
@@ -76648,7 +76879,7 @@ function registerDebugCommand(program3) {
|
|
|
76648
76879
|
init_source();
|
|
76649
76880
|
|
|
76650
76881
|
// src/worktree/claim.ts
|
|
76651
|
-
import { execFileSync as
|
|
76882
|
+
import { execFileSync as execFileSync20 } from "node:child_process";
|
|
76652
76883
|
import { closeSync as closeSync12, mkdirSync as mkdirSync35, openSync as openSync12, existsSync as existsSync65, unlinkSync as unlinkSync13 } from "node:fs";
|
|
76653
76884
|
import { join as join64, resolve as resolve42 } from "node:path";
|
|
76654
76885
|
import { homedir as homedir38 } from "node:os";
|
|
@@ -76658,7 +76889,7 @@ import { randomBytes as randomBytes13 } from "node:crypto";
|
|
|
76658
76889
|
import {
|
|
76659
76890
|
mkdirSync as mkdirSync34,
|
|
76660
76891
|
writeFileSync as writeFileSync30,
|
|
76661
|
-
readFileSync as
|
|
76892
|
+
readFileSync as readFileSync56,
|
|
76662
76893
|
readdirSync as readdirSync23,
|
|
76663
76894
|
unlinkSync as unlinkSync12,
|
|
76664
76895
|
existsSync as existsSync64,
|
|
@@ -76686,7 +76917,7 @@ function writeRecord(record2) {
|
|
|
76686
76917
|
function readRecord(id) {
|
|
76687
76918
|
const path7 = recordPath(id);
|
|
76688
76919
|
try {
|
|
76689
|
-
const raw =
|
|
76920
|
+
const raw = readFileSync56(path7, "utf8");
|
|
76690
76921
|
return JSON.parse(raw);
|
|
76691
76922
|
} catch {
|
|
76692
76923
|
return null;
|
|
@@ -76815,7 +77046,7 @@ async function claimWorktree(input, codeRepos) {
|
|
|
76815
77046
|
releaseLock();
|
|
76816
77047
|
}
|
|
76817
77048
|
try {
|
|
76818
|
-
|
|
77049
|
+
execFileSync20("git", ["worktree", "add", "-b", branch, worktreePath], {
|
|
76819
77050
|
cwd: repoPath,
|
|
76820
77051
|
stdio: "pipe"
|
|
76821
77052
|
});
|
|
@@ -76828,7 +77059,7 @@ async function claimWorktree(input, codeRepos) {
|
|
|
76828
77059
|
}
|
|
76829
77060
|
|
|
76830
77061
|
// src/worktree/release.ts
|
|
76831
|
-
import { execFileSync as
|
|
77062
|
+
import { execFileSync as execFileSync21 } from "node:child_process";
|
|
76832
77063
|
import { existsSync as existsSync66 } from "node:fs";
|
|
76833
77064
|
function releaseWorktree(input) {
|
|
76834
77065
|
const { id } = input;
|
|
@@ -76839,7 +77070,7 @@ function releaseWorktree(input) {
|
|
|
76839
77070
|
let gitSuccess = true;
|
|
76840
77071
|
if (existsSync66(record2.path)) {
|
|
76841
77072
|
try {
|
|
76842
|
-
|
|
77073
|
+
execFileSync21("git", ["worktree", "remove", "--force", record2.path], {
|
|
76843
77074
|
cwd: record2.repo,
|
|
76844
77075
|
stdio: "pipe"
|
|
76845
77076
|
});
|
|
@@ -76875,16 +77106,16 @@ function listWorktrees() {
|
|
|
76875
77106
|
}
|
|
76876
77107
|
|
|
76877
77108
|
// src/worktree/reaper.ts
|
|
76878
|
-
import { execFileSync as
|
|
77109
|
+
import { execFileSync as execFileSync22 } from "node:child_process";
|
|
76879
77110
|
import { existsSync as existsSync67 } from "node:fs";
|
|
76880
77111
|
var STALE_THRESHOLD_MS = 10 * 60 * 1000;
|
|
76881
77112
|
function isPathInUse(path7) {
|
|
76882
77113
|
try {
|
|
76883
|
-
|
|
77114
|
+
execFileSync22("fuser", [path7], { stdio: "pipe" });
|
|
76884
77115
|
return true;
|
|
76885
77116
|
} catch {}
|
|
76886
77117
|
try {
|
|
76887
|
-
const out =
|
|
77118
|
+
const out = execFileSync22("lsof", ["-t", path7], {
|
|
76888
77119
|
stdio: ["ignore", "pipe", "ignore"]
|
|
76889
77120
|
}).toString().trim();
|
|
76890
77121
|
if (out.length > 0)
|
|
@@ -76894,7 +77125,7 @@ function isPathInUse(path7) {
|
|
|
76894
77125
|
}
|
|
76895
77126
|
function hasUncommittedChanges(repoPath, worktreePath) {
|
|
76896
77127
|
try {
|
|
76897
|
-
const out =
|
|
77128
|
+
const out = execFileSync22("git", ["-C", worktreePath, "status", "--porcelain"], { stdio: "pipe" }).toString();
|
|
76898
77129
|
return out.trim().length > 0;
|
|
76899
77130
|
} catch {
|
|
76900
77131
|
return false;
|
|
@@ -76908,7 +77139,7 @@ function reapRecord(record2) {
|
|
|
76908
77139
|
warning = `[worktree-reaper] Reaped worktree with uncommitted changes: ` + `id=${id} branch=${branch} agent=${ownerAgent ?? "unknown"} path=${path7}`;
|
|
76909
77140
|
}
|
|
76910
77141
|
try {
|
|
76911
|
-
|
|
77142
|
+
execFileSync22("git", ["worktree", "remove", "--force", path7], {
|
|
76912
77143
|
cwd: repo,
|
|
76913
77144
|
stdio: "pipe"
|
|
76914
77145
|
});
|
|
@@ -78000,7 +78231,7 @@ async function fetchToken(vaultKey) {
|
|
|
78000
78231
|
|
|
78001
78232
|
// src/cli/apply.ts
|
|
78002
78233
|
init_source();
|
|
78003
|
-
import { accessSync as accessSync3, chownSync as chownSync4, constants as fsConstants6, copyFileSync as copyFileSync11, existsSync as existsSync72, mkdirSync as mkdirSync40, readFileSync as
|
|
78234
|
+
import { accessSync as accessSync3, chownSync as chownSync4, constants as fsConstants6, copyFileSync as copyFileSync11, existsSync as existsSync72, mkdirSync as mkdirSync40, readFileSync as readFileSync58, readdirSync as readdirSync26, renameSync as renameSync14, writeFileSync as writeFileSync35 } from "node:fs";
|
|
78004
78235
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
78005
78236
|
import { spawnSync as childSpawnSync } from "node:child_process";
|
|
78006
78237
|
import readline from "node:readline";
|
|
@@ -78391,13 +78622,13 @@ agents:
|
|
|
78391
78622
|
init_resolver();
|
|
78392
78623
|
import { dirname as dirname21, join as join70, resolve as resolve44 } from "node:path";
|
|
78393
78624
|
import { homedir as homedir40 } from "node:os";
|
|
78394
|
-
import { execFileSync as
|
|
78625
|
+
import { execFileSync as execFileSync23 } from "node:child_process";
|
|
78395
78626
|
init_vault();
|
|
78396
78627
|
init_loader();
|
|
78397
78628
|
init_loader();
|
|
78398
78629
|
|
|
78399
78630
|
// src/cli/update-prompt-hook.ts
|
|
78400
|
-
import { existsSync as existsSync69, readFileSync as
|
|
78631
|
+
import { existsSync as existsSync69, readFileSync as readFileSync57, writeFileSync as writeFileSync34, chmodSync as chmodSync10, mkdirSync as mkdirSync39 } from "node:fs";
|
|
78401
78632
|
import { join as join67 } from "node:path";
|
|
78402
78633
|
var HOOK_FILENAME = "update-card-on-prompt.sh";
|
|
78403
78634
|
function updatePromptHookScript() {
|
|
@@ -78469,7 +78700,7 @@ function installUpdatePromptHook(agentDir) {
|
|
|
78469
78700
|
const scriptPath = join67(hooksDir, HOOK_FILENAME);
|
|
78470
78701
|
const desired = updatePromptHookScript();
|
|
78471
78702
|
let installed = false;
|
|
78472
|
-
const existing = existsSync69(scriptPath) ?
|
|
78703
|
+
const existing = existsSync69(scriptPath) ? readFileSync57(scriptPath, "utf-8") : "";
|
|
78473
78704
|
if (existing !== desired) {
|
|
78474
78705
|
writeFileSync34(scriptPath, desired, { mode: 493 });
|
|
78475
78706
|
chmodSync10(scriptPath, 493);
|
|
@@ -78483,7 +78714,7 @@ function installUpdatePromptHook(agentDir) {
|
|
|
78483
78714
|
if (!existsSync69(settingsPath)) {
|
|
78484
78715
|
return { scriptPath, settingsPath, installed };
|
|
78485
78716
|
}
|
|
78486
|
-
const raw =
|
|
78717
|
+
const raw = readFileSync57(settingsPath, "utf-8");
|
|
78487
78718
|
let parsed;
|
|
78488
78719
|
try {
|
|
78489
78720
|
parsed = JSON.parse(raw);
|
|
@@ -78777,7 +79008,7 @@ async function ensureHostMountSources(config) {
|
|
|
78777
79008
|
await mkdir(fleetDir, { recursive: true });
|
|
78778
79009
|
const invariantsPath = join70(fleetDir, "switchroom-invariants.md");
|
|
78779
79010
|
const invariantsCanonical = renderFleetInvariants();
|
|
78780
|
-
const invariantsCurrent = existsSync72(invariantsPath) ?
|
|
79011
|
+
const invariantsCurrent = existsSync72(invariantsPath) ? readFileSync58(invariantsPath, "utf-8") : null;
|
|
78781
79012
|
if (invariantsCurrent !== invariantsCanonical) {
|
|
78782
79013
|
writeFileSync35(invariantsPath, invariantsCanonical, { mode: 420 });
|
|
78783
79014
|
}
|
|
@@ -78799,7 +79030,7 @@ async function ensureHostMountSources(config) {
|
|
|
78799
79030
|
}
|
|
78800
79031
|
function detectComposeV2() {
|
|
78801
79032
|
try {
|
|
78802
|
-
const out =
|
|
79033
|
+
const out = execFileSync23("docker", ["compose", "version"], {
|
|
78803
79034
|
stdio: ["ignore", "pipe", "pipe"],
|
|
78804
79035
|
encoding: "utf8"
|
|
78805
79036
|
});
|
|
@@ -79314,7 +79545,7 @@ function runRedactStdin() {
|
|
|
79314
79545
|
}
|
|
79315
79546
|
|
|
79316
79547
|
// src/cli/status-ask.ts
|
|
79317
|
-
import { readFileSync as
|
|
79548
|
+
import { readFileSync as readFileSync59, existsSync as existsSync73, readdirSync as readdirSync27 } from "node:fs";
|
|
79318
79549
|
import { join as join71 } from "node:path";
|
|
79319
79550
|
import { homedir as homedir41 } from "node:os";
|
|
79320
79551
|
|
|
@@ -79590,7 +79821,7 @@ function runReport(opts) {
|
|
|
79590
79821
|
for (const src of sources) {
|
|
79591
79822
|
let content;
|
|
79592
79823
|
try {
|
|
79593
|
-
content =
|
|
79824
|
+
content = readFileSync59(src.path, "utf-8");
|
|
79594
79825
|
} catch (err) {
|
|
79595
79826
|
process.stderr.write(`status-ask report: cannot read ${src.path}: ${err instanceof Error ? err.message : String(err)}
|
|
79596
79827
|
`);
|
|
@@ -79691,7 +79922,7 @@ import {
|
|
|
79691
79922
|
existsSync as existsSync74,
|
|
79692
79923
|
mkdirSync as mkdirSync41,
|
|
79693
79924
|
appendFileSync as appendFileSync4,
|
|
79694
|
-
readFileSync as
|
|
79925
|
+
readFileSync as readFileSync60
|
|
79695
79926
|
} from "node:fs";
|
|
79696
79927
|
var AUDIT_ROOT = join72(homedir42(), ".switchroom", "audit");
|
|
79697
79928
|
function auditPathFor(agent) {
|
|
@@ -79786,7 +80017,7 @@ function readAuditTail(agent, limit, opts = {}) {
|
|
|
79786
80017
|
return [];
|
|
79787
80018
|
let raw;
|
|
79788
80019
|
try {
|
|
79789
|
-
raw =
|
|
80020
|
+
raw = readFileSync60(path8, "utf-8");
|
|
79790
80021
|
} catch {
|
|
79791
80022
|
return [];
|
|
79792
80023
|
}
|
|
@@ -79936,7 +80167,7 @@ function registerAgentConfigCommands(program3) {
|
|
|
79936
80167
|
}
|
|
79937
80168
|
|
|
79938
80169
|
// src/cli/agent-config-write.ts
|
|
79939
|
-
var
|
|
80170
|
+
var import_yaml17 = __toESM(require_dist(), 1);
|
|
79940
80171
|
|
|
79941
80172
|
// src/config/overlay-writer.ts
|
|
79942
80173
|
init_paths();
|
|
@@ -79947,7 +80178,7 @@ import {
|
|
|
79947
80178
|
mkdirSync as mkdirSync42,
|
|
79948
80179
|
openSync as openSync13,
|
|
79949
80180
|
readdirSync as readdirSync28,
|
|
79950
|
-
readFileSync as
|
|
80181
|
+
readFileSync as readFileSync61,
|
|
79951
80182
|
renameSync as renameSync15,
|
|
79952
80183
|
statSync as statSync28,
|
|
79953
80184
|
unlinkSync as unlinkSync14,
|
|
@@ -80071,7 +80302,7 @@ function listSkillsOverlayEntries(agent, opts = {}) {
|
|
|
80071
80302
|
continue;
|
|
80072
80303
|
const full = join73(paths.skillsDir, name);
|
|
80073
80304
|
try {
|
|
80074
|
-
const raw =
|
|
80305
|
+
const raw = readFileSync61(full, "utf-8");
|
|
80075
80306
|
const slug = name.replace(/\.ya?ml$/i, "");
|
|
80076
80307
|
out.push({ slug, path: full, raw });
|
|
80077
80308
|
} catch {}
|
|
@@ -80098,7 +80329,7 @@ function listOverlayEntries(agent, opts = {}) {
|
|
|
80098
80329
|
continue;
|
|
80099
80330
|
const full = join73(paths.scheduleDir, name);
|
|
80100
80331
|
try {
|
|
80101
|
-
const raw =
|
|
80332
|
+
const raw = readFileSync61(full, "utf-8");
|
|
80102
80333
|
const slug = name.replace(/\.ya?ml$/i, "");
|
|
80103
80334
|
out.push({ slug, path: full, raw });
|
|
80104
80335
|
} catch {}
|
|
@@ -80129,7 +80360,7 @@ function filterOverlaySecrets(doc, source) {
|
|
|
80129
80360
|
// src/agents/reconcile-dry-run.ts
|
|
80130
80361
|
init_overlay_schema();
|
|
80131
80362
|
init_schema();
|
|
80132
|
-
var
|
|
80363
|
+
var import_yaml16 = __toESM(require_dist(), 1);
|
|
80133
80364
|
init_lifecycle();
|
|
80134
80365
|
var MIN_CRON_INTERVAL_SECS = 5 * 60;
|
|
80135
80366
|
function violatesMinInterval(cron) {
|
|
@@ -80151,7 +80382,7 @@ function violatesMinInterval(cron) {
|
|
|
80151
80382
|
function dryRunReconcile(input) {
|
|
80152
80383
|
let parsed;
|
|
80153
80384
|
try {
|
|
80154
|
-
parsed =
|
|
80385
|
+
parsed = import_yaml16.parse(input.yamlText);
|
|
80155
80386
|
} catch (err) {
|
|
80156
80387
|
return {
|
|
80157
80388
|
ok: false,
|
|
@@ -80246,7 +80477,7 @@ import {
|
|
|
80246
80477
|
mkdirSync as mkdirSync43,
|
|
80247
80478
|
openSync as openSync14,
|
|
80248
80479
|
readdirSync as readdirSync29,
|
|
80249
|
-
readFileSync as
|
|
80480
|
+
readFileSync as readFileSync62,
|
|
80250
80481
|
renameSync as renameSync16,
|
|
80251
80482
|
unlinkSync as unlinkSync15,
|
|
80252
80483
|
writeFileSync as writeFileSync36,
|
|
@@ -80310,7 +80541,7 @@ function listPendingScheduleEntries(agent, opts = {}) {
|
|
|
80310
80541
|
if (!existsSync76(yamlPath))
|
|
80311
80542
|
continue;
|
|
80312
80543
|
try {
|
|
80313
|
-
const meta = JSON.parse(
|
|
80544
|
+
const meta = JSON.parse(readFileSync62(metaPath, "utf-8"));
|
|
80314
80545
|
if (meta?.v !== 1 || typeof meta.stage_id !== "string")
|
|
80315
80546
|
continue;
|
|
80316
80547
|
out.push({ stageId: meta.stage_id, agent: meta.agent, yamlPath, metaPath, meta });
|
|
@@ -80349,7 +80580,7 @@ function denyPendingScheduleEntry(opts) {
|
|
|
80349
80580
|
|
|
80350
80581
|
// src/cli/agent-config-write.ts
|
|
80351
80582
|
init_protocol3();
|
|
80352
|
-
import { existsSync as existsSync77, readFileSync as
|
|
80583
|
+
import { existsSync as existsSync77, readFileSync as readFileSync63 } from "node:fs";
|
|
80353
80584
|
var MAX_ENTRIES_PER_AGENT = 20;
|
|
80354
80585
|
var MIN_CRON_INTERVAL_MIN = 5;
|
|
80355
80586
|
function extractCronSmallestGapMin(expr) {
|
|
@@ -80457,7 +80688,7 @@ function scheduleAdd(opts) {
|
|
|
80457
80688
|
]
|
|
80458
80689
|
};
|
|
80459
80690
|
const yamlText = (() => {
|
|
80460
|
-
const body =
|
|
80691
|
+
const body = import_yaml17.stringify(doc);
|
|
80461
80692
|
const header = opts.name ? `# name: ${opts.name}
|
|
80462
80693
|
` : "";
|
|
80463
80694
|
return header + body;
|
|
@@ -80567,7 +80798,7 @@ function scheduleAddOrStage(opts) {
|
|
|
80567
80798
|
]
|
|
80568
80799
|
};
|
|
80569
80800
|
const yamlText = (opts.name ? `# name: ${opts.name}
|
|
80570
|
-
` : "") +
|
|
80801
|
+
` : "") + import_yaml17.stringify(doc);
|
|
80571
80802
|
const summary = (() => {
|
|
80572
80803
|
const parts = [`cron=${opts.cronExpr}`];
|
|
80573
80804
|
if (opts.secrets?.length)
|
|
@@ -80617,7 +80848,7 @@ function scheduleRemove(opts) {
|
|
|
80617
80848
|
break;
|
|
80618
80849
|
}
|
|
80619
80850
|
try {
|
|
80620
|
-
const parsed =
|
|
80851
|
+
const parsed = import_yaml17.parse(e.raw);
|
|
80621
80852
|
if (parsed && parsed.name === opts.name) {
|
|
80622
80853
|
match = e;
|
|
80623
80854
|
break;
|
|
@@ -80636,7 +80867,7 @@ function scheduleRemove(opts) {
|
|
|
80636
80867
|
let priorContent = null;
|
|
80637
80868
|
try {
|
|
80638
80869
|
if (existsSync77(match.path))
|
|
80639
|
-
priorContent =
|
|
80870
|
+
priorContent = readFileSync63(match.path, "utf-8");
|
|
80640
80871
|
} catch {}
|
|
80641
80872
|
deleteOverlayEntry(agent, match.slug, { root: opts.root });
|
|
80642
80873
|
const reconcileFn = opts.reconcile === undefined ? opts.root ? null : reconcileAgentCronOnly : opts.reconcile;
|
|
@@ -80827,10 +81058,10 @@ function registerAgentConfigWriteCommands(program3) {
|
|
|
80827
81058
|
}
|
|
80828
81059
|
|
|
80829
81060
|
// src/cli/agent-config-skill-write.ts
|
|
80830
|
-
var
|
|
81061
|
+
var import_yaml18 = __toESM(require_dist(), 1);
|
|
80831
81062
|
import { existsSync as existsSync78 } from "node:fs";
|
|
80832
81063
|
init_reconcile_default_skills();
|
|
80833
|
-
var
|
|
81064
|
+
var import_yaml19 = __toESM(require_dist(), 1);
|
|
80834
81065
|
import { join as join75 } from "node:path";
|
|
80835
81066
|
var MAX_SKILLS_PER_AGENT = 20;
|
|
80836
81067
|
var V1_ALLOWED_SOURCE_PREFIX = "bundled:";
|
|
@@ -80880,7 +81111,7 @@ function countCurrentSkills(agent, opts) {
|
|
|
80880
81111
|
let total = 0;
|
|
80881
81112
|
for (const e of entries) {
|
|
80882
81113
|
try {
|
|
80883
|
-
const doc =
|
|
81114
|
+
const doc = import_yaml19.parse(e.raw);
|
|
80884
81115
|
total += (doc?.skills ?? []).length;
|
|
80885
81116
|
} catch {}
|
|
80886
81117
|
}
|
|
@@ -80910,7 +81141,7 @@ function skillInstall(opts) {
|
|
|
80910
81141
|
if (!existsSync78(skillPath)) {
|
|
80911
81142
|
return err("E_SKILL_NOT_FOUND", `bundled skill not found at ${skillPath}. The operator needs to ` + `place the skill at this path before the agent can opt in.`);
|
|
80912
81143
|
}
|
|
80913
|
-
const yamlText =
|
|
81144
|
+
const yamlText = import_yaml18.stringify({ skills: [skillName] });
|
|
80914
81145
|
let path8;
|
|
80915
81146
|
try {
|
|
80916
81147
|
path8 = writeSkillsOverlayEntry(agent, slug, yamlText, { root: opts.root });
|
|
@@ -81076,7 +81307,7 @@ import {
|
|
|
81076
81307
|
mkdirSync as mkdirSync44,
|
|
81077
81308
|
mkdtempSync as mkdtempSync5,
|
|
81078
81309
|
openSync as openSync15,
|
|
81079
|
-
readFileSync as
|
|
81310
|
+
readFileSync as readFileSync64,
|
|
81080
81311
|
readdirSync as readdirSync30,
|
|
81081
81312
|
realpathSync as realpathSync7,
|
|
81082
81313
|
renameSync as renameSync17,
|
|
@@ -81089,7 +81320,7 @@ import { dirname as dirname22, join as join76, relative as relative2, resolve as
|
|
|
81089
81320
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
81090
81321
|
|
|
81091
81322
|
// src/cli/skill-common.ts
|
|
81092
|
-
var
|
|
81323
|
+
var import_yaml20 = __toESM(require_dist(), 1);
|
|
81093
81324
|
var MAX_FILE_BYTES = 256 * 1024;
|
|
81094
81325
|
var MAX_SKILL_BYTES = 2 * 1024 * 1024;
|
|
81095
81326
|
var MAX_FILES_PER_SKILL = 50;
|
|
@@ -81193,7 +81424,7 @@ function validateSkillMd(content, expectedName) {
|
|
|
81193
81424
|
}
|
|
81194
81425
|
let parsed;
|
|
81195
81426
|
try {
|
|
81196
|
-
parsed =
|
|
81427
|
+
parsed = import_yaml20.parse(fmText);
|
|
81197
81428
|
} catch (e) {
|
|
81198
81429
|
return authorErr("E_SKILL_INVALID_FRONTMATTER", `frontmatter is not valid YAML: ${e.message}`);
|
|
81199
81430
|
}
|
|
@@ -81328,7 +81559,7 @@ function loadFromDir(dir) {
|
|
|
81328
81559
|
continue;
|
|
81329
81560
|
}
|
|
81330
81561
|
if (ent.isFile()) {
|
|
81331
|
-
const buf =
|
|
81562
|
+
const buf = readFileSync64(full);
|
|
81332
81563
|
files[rel.replace(/\\/g, "/")] = buf.toString("utf-8");
|
|
81333
81564
|
}
|
|
81334
81565
|
}
|
|
@@ -81377,7 +81608,7 @@ function loadFromTarball(tarPath) {
|
|
|
81377
81608
|
}
|
|
81378
81609
|
}
|
|
81379
81610
|
function loadSingleFile(filePath) {
|
|
81380
|
-
const content =
|
|
81611
|
+
const content = readFileSync64(filePath, "utf-8");
|
|
81381
81612
|
return { "SKILL.md": content };
|
|
81382
81613
|
}
|
|
81383
81614
|
function loadFromStdin() {
|
|
@@ -81468,7 +81699,7 @@ function diffSummary(currentDir, files) {
|
|
|
81468
81699
|
if (ent.isDirectory()) {
|
|
81469
81700
|
walk2(full);
|
|
81470
81701
|
} else if (ent.isFile()) {
|
|
81471
|
-
currentFiles[rel.replace(/\\/g, "/")] =
|
|
81702
|
+
currentFiles[rel.replace(/\\/g, "/")] = readFileSync64(full, "utf-8");
|
|
81472
81703
|
}
|
|
81473
81704
|
}
|
|
81474
81705
|
};
|
|
@@ -81628,7 +81859,7 @@ import {
|
|
|
81628
81859
|
mkdirSync as mkdirSync45,
|
|
81629
81860
|
mkdtempSync as mkdtempSync6,
|
|
81630
81861
|
openSync as openSync16,
|
|
81631
|
-
readFileSync as
|
|
81862
|
+
readFileSync as readFileSync65,
|
|
81632
81863
|
readdirSync as readdirSync31,
|
|
81633
81864
|
renameSync as renameSync18,
|
|
81634
81865
|
rmSync as rmSync17,
|
|
@@ -81710,7 +81941,7 @@ function mirrorToConfigRepo(agent, name, liveSkillDir) {
|
|
|
81710
81941
|
if (ent.isDirectory())
|
|
81711
81942
|
walk2(s, d);
|
|
81712
81943
|
else if (ent.isFile()) {
|
|
81713
|
-
writeFileSync38(d,
|
|
81944
|
+
writeFileSync38(d, readFileSync65(s));
|
|
81714
81945
|
}
|
|
81715
81946
|
}
|
|
81716
81947
|
};
|
|
@@ -81789,7 +82020,7 @@ function loadFromDir2(dir) {
|
|
|
81789
82020
|
}
|
|
81790
82021
|
if (ent.isFile()) {
|
|
81791
82022
|
const rel = relative3(abs, full).replace(/\\/g, "/");
|
|
81792
|
-
files[rel] =
|
|
82023
|
+
files[rel] = readFileSync65(full, "utf-8");
|
|
81793
82024
|
}
|
|
81794
82025
|
}
|
|
81795
82026
|
};
|
|
@@ -81975,7 +82206,7 @@ function loadFiles(opts) {
|
|
|
81975
82206
|
return loadFromDir2(p);
|
|
81976
82207
|
}
|
|
81977
82208
|
if (p.endsWith(".md")) {
|
|
81978
|
-
return { "SKILL.md":
|
|
82209
|
+
return { "SKILL.md": readFileSync65(p, "utf-8") };
|
|
81979
82210
|
}
|
|
81980
82211
|
fail3(`--from must be a directory or a .md file. Got: ${opts.from}`);
|
|
81981
82212
|
}
|
|
@@ -82064,7 +82295,7 @@ function readSourceFiles(dir) {
|
|
|
82064
82295
|
fail3(`clone source has oversized file ${rel} (${st.size} bytes > ${CLONE_MAX_FILE_BYTES}); ` + `refuse to read`, 3);
|
|
82065
82296
|
}
|
|
82066
82297
|
} catch {}
|
|
82067
|
-
files[rel] =
|
|
82298
|
+
files[rel] = readFileSync65(full, "utf-8");
|
|
82068
82299
|
}
|
|
82069
82300
|
}
|
|
82070
82301
|
};
|
|
@@ -82232,8 +82463,8 @@ function registerSkillPersonalCommands(program3) {
|
|
|
82232
82463
|
|
|
82233
82464
|
// src/cli/skill-search.ts
|
|
82234
82465
|
init_helpers();
|
|
82235
|
-
var
|
|
82236
|
-
import { existsSync as existsSync81, readdirSync as readdirSync32, readFileSync as
|
|
82466
|
+
var import_yaml21 = __toESM(require_dist(), 1);
|
|
82467
|
+
import { existsSync as existsSync81, readdirSync as readdirSync32, readFileSync as readFileSync66, statSync as statSync31 } from "node:fs";
|
|
82237
82468
|
import { homedir as homedir45 } from "node:os";
|
|
82238
82469
|
import { join as join78, resolve as resolve48 } from "node:path";
|
|
82239
82470
|
var PERSONAL_PREFIX2 = "personal-";
|
|
@@ -82254,7 +82485,7 @@ function readSkillFrontmatter(skillDir) {
|
|
|
82254
82485
|
return null;
|
|
82255
82486
|
let content;
|
|
82256
82487
|
try {
|
|
82257
|
-
content =
|
|
82488
|
+
content = readFileSync66(mdPath, "utf-8");
|
|
82258
82489
|
} catch {
|
|
82259
82490
|
return null;
|
|
82260
82491
|
}
|
|
@@ -82272,7 +82503,7 @@ function readSkillFrontmatter(skillDir) {
|
|
|
82272
82503
|
const fmText = rest.slice(0, endIdx);
|
|
82273
82504
|
let parsed;
|
|
82274
82505
|
try {
|
|
82275
|
-
parsed =
|
|
82506
|
+
parsed = import_yaml21.parse(fmText);
|
|
82276
82507
|
} catch (e) {
|
|
82277
82508
|
return { error: `yaml parse: ${e.message}` };
|
|
82278
82509
|
}
|
|
@@ -82526,7 +82757,7 @@ function registerHostdMcpCommand(program3) {
|
|
|
82526
82757
|
// src/cli/hostd.ts
|
|
82527
82758
|
init_source();
|
|
82528
82759
|
init_helpers();
|
|
82529
|
-
import { existsSync as existsSync83, mkdirSync as mkdirSync46, readdirSync as readdirSync33, readFileSync as
|
|
82760
|
+
import { existsSync as existsSync83, mkdirSync as mkdirSync46, readdirSync as readdirSync33, readFileSync as readFileSync68, writeFileSync as writeFileSync39, statSync as statSync32, copyFileSync as copyFileSync12 } from "node:fs";
|
|
82530
82761
|
import { homedir as homedir46 } from "node:os";
|
|
82531
82762
|
import { join as join79 } from "node:path";
|
|
82532
82763
|
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
@@ -82781,7 +83012,7 @@ function registerHostdCommand(program3) {
|
|
|
82781
83012
|
The log is created when hostd handles its first privileged-verb request.`));
|
|
82782
83013
|
return;
|
|
82783
83014
|
}
|
|
82784
|
-
const raw =
|
|
83015
|
+
const raw = readFileSync68(logPath, "utf-8");
|
|
82785
83016
|
const limit = Math.max(1, parseInt(opts.tail ?? "50", 10) || 50);
|
|
82786
83017
|
const filters = {
|
|
82787
83018
|
agent: opts.agent,
|