switchroom 0.15.28 → 0.15.30
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/agent-scheduler/index.js +24 -3
- package/dist/auth-broker/index.js +22 -3
- package/dist/cli/notion-write-pretool.mjs +22 -3
- package/dist/cli/switchroom.js +46 -24
- package/dist/cli/ui/index.html +64 -20
- package/dist/host-control/main.js +57 -7
- package/dist/vault/approvals/kernel-server.js +25 -6
- package/dist/vault/broker/server.js +27 -8
- package/package.json +1 -1
- package/telegram-plugin/dist/gateway/gateway.js +42 -23
|
@@ -11617,7 +11617,7 @@ function resolveDualPath(pathStr) {
|
|
|
11617
11617
|
|
|
11618
11618
|
// src/config/overlay-loader.ts
|
|
11619
11619
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "node:fs";
|
|
11620
|
-
import { resolve as resolve2 } from "node:path";
|
|
11620
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
11621
11621
|
|
|
11622
11622
|
// src/config/overlay-schema.ts
|
|
11623
11623
|
var OverlayDocSchema = exports_external.object({
|
|
@@ -11627,6 +11627,16 @@ var OverlayDocSchema = exports_external.object({
|
|
|
11627
11627
|
|
|
11628
11628
|
// src/config/overlay-loader.ts
|
|
11629
11629
|
var OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
11630
|
+
var OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
11631
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
11632
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
11633
|
+
if (titleFromComment)
|
|
11634
|
+
return titleFromComment;
|
|
11635
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
11636
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
11637
|
+
return;
|
|
11638
|
+
return base.length > 0 ? base : undefined;
|
|
11639
|
+
}
|
|
11630
11640
|
function overlayDirFor(agentName, subdir) {
|
|
11631
11641
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
11632
11642
|
return resolve2(base);
|
|
@@ -11652,13 +11662,21 @@ function listYamlFiles(dir) {
|
|
|
11652
11662
|
}
|
|
11653
11663
|
return out.sort();
|
|
11654
11664
|
}
|
|
11655
|
-
function stampOverlay(entry) {
|
|
11665
|
+
function stampOverlay(entry, title) {
|
|
11656
11666
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
11657
11667
|
value: true,
|
|
11658
11668
|
enumerable: false,
|
|
11659
11669
|
configurable: false,
|
|
11660
11670
|
writable: false
|
|
11661
11671
|
});
|
|
11672
|
+
if (title !== undefined) {
|
|
11673
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
11674
|
+
value: title,
|
|
11675
|
+
enumerable: false,
|
|
11676
|
+
configurable: false,
|
|
11677
|
+
writable: false
|
|
11678
|
+
});
|
|
11679
|
+
}
|
|
11662
11680
|
return entry;
|
|
11663
11681
|
}
|
|
11664
11682
|
function applyAgentOverlays(config) {
|
|
@@ -11675,6 +11693,7 @@ function applyAgentOverlays(config) {
|
|
|
11675
11693
|
const raw = readFileSync(file, "utf-8");
|
|
11676
11694
|
const parsed = $parse(raw);
|
|
11677
11695
|
const doc = OverlayDocSchema.parse(parsed);
|
|
11696
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
11678
11697
|
for (const entry of doc.schedule ?? []) {
|
|
11679
11698
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
11680
11699
|
const w = {
|
|
@@ -11686,7 +11705,7 @@ function applyAgentOverlays(config) {
|
|
|
11686
11705
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
11687
11706
|
continue;
|
|
11688
11707
|
}
|
|
11689
|
-
merged.push(stampOverlay(entry));
|
|
11708
|
+
merged.push(stampOverlay(entry, title));
|
|
11690
11709
|
}
|
|
11691
11710
|
} catch (err) {
|
|
11692
11711
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -12283,10 +12302,12 @@ function collectScheduleEntries(config) {
|
|
|
12283
12302
|
for (let i = 0;i < schedule.length; i++) {
|
|
12284
12303
|
const entry = schedule[i];
|
|
12285
12304
|
const auditMaterial = entry.prompt ?? `action:${JSON.stringify(entry.action ?? {})}`;
|
|
12305
|
+
const title = entry[OVERLAY_TITLE];
|
|
12286
12306
|
out.push({
|
|
12287
12307
|
agent,
|
|
12288
12308
|
scheduleIndex: i,
|
|
12289
12309
|
cron: entry.cron,
|
|
12310
|
+
...typeof title === "string" && title.length > 0 ? { name: title } : {},
|
|
12290
12311
|
...entry.prompt !== undefined ? { prompt: entry.prompt } : {},
|
|
12291
12312
|
promptKey: createHash("sha256").update(auditMaterial).digest("hex").slice(0, 12),
|
|
12292
12313
|
...entry.topic !== undefined ? { topic: entry.topic } : {},
|
|
@@ -11617,7 +11617,7 @@ function resolveDualPath(pathStr) {
|
|
|
11617
11617
|
|
|
11618
11618
|
// src/config/overlay-loader.ts
|
|
11619
11619
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "node:fs";
|
|
11620
|
-
import { resolve as resolve2 } from "node:path";
|
|
11620
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
11621
11621
|
|
|
11622
11622
|
// src/config/overlay-schema.ts
|
|
11623
11623
|
var OverlayDocSchema = exports_external.object({
|
|
@@ -11627,6 +11627,16 @@ var OverlayDocSchema = exports_external.object({
|
|
|
11627
11627
|
|
|
11628
11628
|
// src/config/overlay-loader.ts
|
|
11629
11629
|
var OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
11630
|
+
var OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
11631
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
11632
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
11633
|
+
if (titleFromComment)
|
|
11634
|
+
return titleFromComment;
|
|
11635
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
11636
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
11637
|
+
return;
|
|
11638
|
+
return base.length > 0 ? base : undefined;
|
|
11639
|
+
}
|
|
11630
11640
|
function overlayDirFor(agentName, subdir) {
|
|
11631
11641
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
11632
11642
|
return resolve2(base);
|
|
@@ -11652,13 +11662,21 @@ function listYamlFiles(dir) {
|
|
|
11652
11662
|
}
|
|
11653
11663
|
return out.sort();
|
|
11654
11664
|
}
|
|
11655
|
-
function stampOverlay(entry) {
|
|
11665
|
+
function stampOverlay(entry, title) {
|
|
11656
11666
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
11657
11667
|
value: true,
|
|
11658
11668
|
enumerable: false,
|
|
11659
11669
|
configurable: false,
|
|
11660
11670
|
writable: false
|
|
11661
11671
|
});
|
|
11672
|
+
if (title !== undefined) {
|
|
11673
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
11674
|
+
value: title,
|
|
11675
|
+
enumerable: false,
|
|
11676
|
+
configurable: false,
|
|
11677
|
+
writable: false
|
|
11678
|
+
});
|
|
11679
|
+
}
|
|
11662
11680
|
return entry;
|
|
11663
11681
|
}
|
|
11664
11682
|
function applyAgentOverlays(config) {
|
|
@@ -11675,6 +11693,7 @@ function applyAgentOverlays(config) {
|
|
|
11675
11693
|
const raw = readFileSync(file, "utf-8");
|
|
11676
11694
|
const parsed = $parse(raw);
|
|
11677
11695
|
const doc = OverlayDocSchema.parse(parsed);
|
|
11696
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
11678
11697
|
for (const entry of doc.schedule ?? []) {
|
|
11679
11698
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
11680
11699
|
const w = {
|
|
@@ -11686,7 +11705,7 @@ function applyAgentOverlays(config) {
|
|
|
11686
11705
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
11687
11706
|
continue;
|
|
11688
11707
|
}
|
|
11689
|
-
merged.push(stampOverlay(entry));
|
|
11708
|
+
merged.push(stampOverlay(entry, title));
|
|
11690
11709
|
}
|
|
11691
11710
|
} catch (err) {
|
|
11692
11711
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -12365,7 +12365,7 @@ function resolveDualPath(pathStr) {
|
|
|
12365
12365
|
|
|
12366
12366
|
// src/config/overlay-loader.ts
|
|
12367
12367
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "node:fs";
|
|
12368
|
-
import { resolve as resolve2 } from "node:path";
|
|
12368
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
12369
12369
|
init_zod();
|
|
12370
12370
|
|
|
12371
12371
|
// src/config/overlay-schema.ts
|
|
@@ -12377,6 +12377,16 @@ var OverlayDocSchema = exports_external.object({
|
|
|
12377
12377
|
|
|
12378
12378
|
// src/config/overlay-loader.ts
|
|
12379
12379
|
var OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
12380
|
+
var OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
12381
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
12382
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
12383
|
+
if (titleFromComment)
|
|
12384
|
+
return titleFromComment;
|
|
12385
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
12386
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
12387
|
+
return;
|
|
12388
|
+
return base.length > 0 ? base : undefined;
|
|
12389
|
+
}
|
|
12380
12390
|
function overlayDirFor(agentName, subdir) {
|
|
12381
12391
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
12382
12392
|
return resolve2(base);
|
|
@@ -12402,13 +12412,21 @@ function listYamlFiles(dir) {
|
|
|
12402
12412
|
}
|
|
12403
12413
|
return out.sort();
|
|
12404
12414
|
}
|
|
12405
|
-
function stampOverlay(entry) {
|
|
12415
|
+
function stampOverlay(entry, title) {
|
|
12406
12416
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
12407
12417
|
value: true,
|
|
12408
12418
|
enumerable: false,
|
|
12409
12419
|
configurable: false,
|
|
12410
12420
|
writable: false
|
|
12411
12421
|
});
|
|
12422
|
+
if (title !== undefined) {
|
|
12423
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
12424
|
+
value: title,
|
|
12425
|
+
enumerable: false,
|
|
12426
|
+
configurable: false,
|
|
12427
|
+
writable: false
|
|
12428
|
+
});
|
|
12429
|
+
}
|
|
12412
12430
|
return entry;
|
|
12413
12431
|
}
|
|
12414
12432
|
function applyAgentOverlays(config) {
|
|
@@ -12425,6 +12443,7 @@ function applyAgentOverlays(config) {
|
|
|
12425
12443
|
const raw = readFileSync(file, "utf-8");
|
|
12426
12444
|
const parsed = $parse(raw);
|
|
12427
12445
|
const doc = OverlayDocSchema.parse(parsed);
|
|
12446
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
12428
12447
|
for (const entry of doc.schedule ?? []) {
|
|
12429
12448
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
12430
12449
|
const w = {
|
|
@@ -12436,7 +12455,7 @@ function applyAgentOverlays(config) {
|
|
|
12436
12455
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
12437
12456
|
continue;
|
|
12438
12457
|
}
|
|
12439
|
-
merged.push(stampOverlay(entry));
|
|
12458
|
+
merged.push(stampOverlay(entry, title));
|
|
12440
12459
|
}
|
|
12441
12460
|
} catch (err) {
|
|
12442
12461
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
package/dist/cli/switchroom.js
CHANGED
|
@@ -14202,7 +14202,16 @@ var init_overlay_schema = __esm(() => {
|
|
|
14202
14202
|
|
|
14203
14203
|
// src/config/overlay-loader.ts
|
|
14204
14204
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync as statSync2 } from "node:fs";
|
|
14205
|
-
import { resolve as resolve2 } from "node:path";
|
|
14205
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
14206
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
14207
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
14208
|
+
if (titleFromComment)
|
|
14209
|
+
return titleFromComment;
|
|
14210
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
14211
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
14212
|
+
return;
|
|
14213
|
+
return base.length > 0 ? base : undefined;
|
|
14214
|
+
}
|
|
14206
14215
|
function overlayDirFor(agentName, subdir) {
|
|
14207
14216
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
14208
14217
|
return resolve2(base);
|
|
@@ -14228,13 +14237,21 @@ function listYamlFiles(dir) {
|
|
|
14228
14237
|
}
|
|
14229
14238
|
return out.sort();
|
|
14230
14239
|
}
|
|
14231
|
-
function stampOverlay(entry) {
|
|
14240
|
+
function stampOverlay(entry, title) {
|
|
14232
14241
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
14233
14242
|
value: true,
|
|
14234
14243
|
enumerable: false,
|
|
14235
14244
|
configurable: false,
|
|
14236
14245
|
writable: false
|
|
14237
14246
|
});
|
|
14247
|
+
if (title !== undefined) {
|
|
14248
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
14249
|
+
value: title,
|
|
14250
|
+
enumerable: false,
|
|
14251
|
+
configurable: false,
|
|
14252
|
+
writable: false
|
|
14253
|
+
});
|
|
14254
|
+
}
|
|
14238
14255
|
return entry;
|
|
14239
14256
|
}
|
|
14240
14257
|
function applyAgentOverlays(config) {
|
|
@@ -14251,6 +14268,7 @@ function applyAgentOverlays(config) {
|
|
|
14251
14268
|
const raw = readFileSync(file, "utf-8");
|
|
14252
14269
|
const parsed = import_yaml.parse(raw);
|
|
14253
14270
|
const doc = OverlayDocSchema.parse(parsed);
|
|
14271
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
14254
14272
|
for (const entry of doc.schedule ?? []) {
|
|
14255
14273
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
14256
14274
|
const w = {
|
|
@@ -14262,7 +14280,7 @@ function applyAgentOverlays(config) {
|
|
|
14262
14280
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
14263
14281
|
continue;
|
|
14264
14282
|
}
|
|
14265
|
-
merged.push(stampOverlay(entry));
|
|
14283
|
+
merged.push(stampOverlay(entry, title));
|
|
14266
14284
|
}
|
|
14267
14285
|
} catch (err) {
|
|
14268
14286
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -14316,13 +14334,14 @@ function applyAgentOverlays(config) {
|
|
|
14316
14334
|
}
|
|
14317
14335
|
return { config, warnings };
|
|
14318
14336
|
}
|
|
14319
|
-
var import_yaml, OVERLAY_SOURCE;
|
|
14337
|
+
var import_yaml, OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
14320
14338
|
var init_overlay_loader = __esm(() => {
|
|
14321
14339
|
init_zod();
|
|
14322
14340
|
init_overlay_schema();
|
|
14323
14341
|
init_paths();
|
|
14324
14342
|
import_yaml = __toESM(require_dist(), 1);
|
|
14325
14343
|
OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
14344
|
+
OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
14326
14345
|
});
|
|
14327
14346
|
|
|
14328
14347
|
// src/config/merge.ts
|
|
@@ -21871,7 +21890,7 @@ import {
|
|
|
21871
21890
|
lstatSync as lstatSync2,
|
|
21872
21891
|
realpathSync as realpathSync2
|
|
21873
21892
|
} from "node:fs";
|
|
21874
|
-
import { dirname as dirname2, basename as
|
|
21893
|
+
import { dirname as dirname2, basename as basename3, resolve as resolve7 } from "node:path";
|
|
21875
21894
|
function atomicWriteFileSync(path, data, mode) {
|
|
21876
21895
|
let effectivePath = path;
|
|
21877
21896
|
try {
|
|
@@ -21880,7 +21899,7 @@ function atomicWriteFileSync(path, data, mode) {
|
|
|
21880
21899
|
}
|
|
21881
21900
|
} catch {}
|
|
21882
21901
|
const dir = dirname2(resolve7(effectivePath));
|
|
21883
|
-
const tmp = resolve7(dir, `.${
|
|
21902
|
+
const tmp = resolve7(dir, `.${basename3(effectivePath)}.${process.pid}.${Date.now()}.tmp`);
|
|
21884
21903
|
try {
|
|
21885
21904
|
writeFileSync3(tmp, data, { encoding: "utf8", mode });
|
|
21886
21905
|
renameSync2(tmp, effectivePath);
|
|
@@ -50494,8 +50513,8 @@ var {
|
|
|
50494
50513
|
} = import__.default;
|
|
50495
50514
|
|
|
50496
50515
|
// src/build-info.ts
|
|
50497
|
-
var VERSION = "0.15.
|
|
50498
|
-
var COMMIT_SHA = "
|
|
50516
|
+
var VERSION = "0.15.30";
|
|
50517
|
+
var COMMIT_SHA = "14e64ce2";
|
|
50499
50518
|
|
|
50500
50519
|
// src/cli/agent.ts
|
|
50501
50520
|
init_source();
|
|
@@ -51153,7 +51172,7 @@ import {
|
|
|
51153
51172
|
copyFileSync as copyFileSync2,
|
|
51154
51173
|
unlinkSync
|
|
51155
51174
|
} from "node:fs";
|
|
51156
|
-
import { basename, dirname, resolve as resolve6 } from "node:path";
|
|
51175
|
+
import { basename as basename2, dirname, resolve as resolve6 } from "node:path";
|
|
51157
51176
|
function defaultStatePath() {
|
|
51158
51177
|
return resolveStatePath("topics.json");
|
|
51159
51178
|
}
|
|
@@ -51185,7 +51204,7 @@ function saveTopicState(state, statePath) {
|
|
|
51185
51204
|
mkdirSync4(dir, { recursive: true });
|
|
51186
51205
|
}
|
|
51187
51206
|
const absDir = resolve6(dir);
|
|
51188
|
-
const tmp = resolve6(absDir, `.${
|
|
51207
|
+
const tmp = resolve6(absDir, `.${basename2(path)}.${process.pid}.${Date.now()}.tmp`);
|
|
51189
51208
|
try {
|
|
51190
51209
|
writeFileSync2(tmp, JSON.stringify(state, null, 2) + `
|
|
51191
51210
|
`, "utf-8");
|
|
@@ -54443,7 +54462,7 @@ init_compose();
|
|
|
54443
54462
|
import { chownSync as chownSync2 } from "node:fs";
|
|
54444
54463
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
54445
54464
|
import { homedir as homedir6 } from "node:os";
|
|
54446
|
-
import { basename as
|
|
54465
|
+
import { basename as basename4, dirname as dirname3, join as join12 } from "node:path";
|
|
54447
54466
|
|
|
54448
54467
|
// src/config/release-resolve.ts
|
|
54449
54468
|
function resolveImageTag(release) {
|
|
@@ -54571,7 +54590,7 @@ function resolveHostSwitchroomConfigPath(rawPath) {
|
|
|
54571
54590
|
|
|
54572
54591
|
` + `Recovery: run \`switchroom apply\` once from the HOST (not from inside the container). ` + `That will regenerate the compose file with SWITCHROOM_HOST_HOME set, after which ` + `in-container apply will work correctly.`);
|
|
54573
54592
|
}
|
|
54574
|
-
const filename =
|
|
54593
|
+
const filename = basename4(rawPath);
|
|
54575
54594
|
return join12(hostHome, ".switchroom", filename);
|
|
54576
54595
|
}
|
|
54577
54596
|
async function writeComposeFile(opts) {
|
|
@@ -61148,7 +61167,7 @@ init_compose();
|
|
|
61148
61167
|
init_vault();
|
|
61149
61168
|
import * as net3 from "node:net";
|
|
61150
61169
|
import { mkdirSync as mkdirSync23, chmodSync as chmodSync7, chownSync as chownSync4, existsSync as existsSync37, readFileSync as readFileSync32, readdirSync as readdirSync17, statSync as statSync20, unlinkSync as unlinkSync8, writeFileSync as writeFileSync19, renameSync as renameSync10 } from "node:fs";
|
|
61151
|
-
import { dirname as dirname7, resolve as resolve26, basename as
|
|
61170
|
+
import { dirname as dirname7, resolve as resolve26, basename as basename6 } from "node:path";
|
|
61152
61171
|
import * as os4 from "node:os";
|
|
61153
61172
|
import * as path3 from "node:path";
|
|
61154
61173
|
|
|
@@ -61170,7 +61189,7 @@ import {
|
|
|
61170
61189
|
unlinkSync as unlinkSync7
|
|
61171
61190
|
} from "node:fs";
|
|
61172
61191
|
import { createHash as createHash5 } from "node:crypto";
|
|
61173
|
-
import { basename as
|
|
61192
|
+
import { basename as basename5, dirname as dirname4, join as join28 } from "node:path";
|
|
61174
61193
|
function vaultLayoutPaths(home2) {
|
|
61175
61194
|
const switchroomRoot = join28(home2, ".switchroom");
|
|
61176
61195
|
return {
|
|
@@ -61323,7 +61342,7 @@ function sha256File(path) {
|
|
|
61323
61342
|
return createHash5("sha256").update(data).digest("hex");
|
|
61324
61343
|
}
|
|
61325
61344
|
function atomicReplaceWithSymlink(target, linkTarget) {
|
|
61326
|
-
const tmp = join28(dirname4(target), `.${
|
|
61345
|
+
const tmp = join28(dirname4(target), `.${basename5(target)}.symlink-tmp`);
|
|
61327
61346
|
if (existsSync35(tmp)) {
|
|
61328
61347
|
try {
|
|
61329
61348
|
unlinkSync7(tmp);
|
|
@@ -65350,12 +65369,12 @@ class VaultBroker {
|
|
|
65350
65369
|
}
|
|
65351
65370
|
function detectVaultLayoutDrift(vaultPath) {
|
|
65352
65371
|
const dir = dirname7(vaultPath);
|
|
65353
|
-
if (
|
|
65372
|
+
if (basename6(dir) !== "vault")
|
|
65354
65373
|
return;
|
|
65355
|
-
if (
|
|
65374
|
+
if (basename6(vaultPath) !== "vault.enc")
|
|
65356
65375
|
return;
|
|
65357
65376
|
const switchroomDir = dirname7(dir);
|
|
65358
|
-
if (
|
|
65377
|
+
if (basename6(switchroomDir) !== ".switchroom")
|
|
65359
65378
|
return;
|
|
65360
65379
|
const home2 = dirname7(switchroomDir);
|
|
65361
65380
|
const result = inspectVaultLayout(home2);
|
|
@@ -68980,6 +68999,7 @@ init_audit_reader();
|
|
|
68980
68999
|
|
|
68981
69000
|
// src/scheduler/dispatch.ts
|
|
68982
69001
|
init_merge();
|
|
69002
|
+
init_overlay_loader();
|
|
68983
69003
|
import { createHash as createHash9 } from "node:crypto";
|
|
68984
69004
|
function collectScheduleEntries(config) {
|
|
68985
69005
|
const out = [];
|
|
@@ -68993,10 +69013,12 @@ function collectScheduleEntries(config) {
|
|
|
68993
69013
|
for (let i = 0;i < schedule.length; i++) {
|
|
68994
69014
|
const entry = schedule[i];
|
|
68995
69015
|
const auditMaterial = entry.prompt ?? `action:${JSON.stringify(entry.action ?? {})}`;
|
|
69016
|
+
const title = entry[OVERLAY_TITLE];
|
|
68996
69017
|
out.push({
|
|
68997
69018
|
agent,
|
|
68998
69019
|
scheduleIndex: i,
|
|
68999
69020
|
cron: entry.cron,
|
|
69021
|
+
...typeof title === "string" && title.length > 0 ? { name: title } : {},
|
|
69000
69022
|
...entry.prompt !== undefined ? { prompt: entry.prompt } : {},
|
|
69001
69023
|
promptKey: createHash9("sha256").update(auditMaterial).digest("hex").slice(0, 12),
|
|
69002
69024
|
...entry.topic !== undefined ? { topic: entry.topic } : {},
|
|
@@ -81891,10 +81913,10 @@ function registerNotionMcpLauncherCommand(program3) {
|
|
|
81891
81913
|
// src/cli/deliver-file.ts
|
|
81892
81914
|
init_client2();
|
|
81893
81915
|
import { readFileSync as readFileSync61, statSync as statSync30 } from "node:fs";
|
|
81894
|
-
import { basename as
|
|
81916
|
+
import { basename as basename9 } from "node:path";
|
|
81895
81917
|
|
|
81896
81918
|
// src/delivery/onedrive.ts
|
|
81897
|
-
import { basename as
|
|
81919
|
+
import { basename as basename7 } from "node:path";
|
|
81898
81920
|
var GRAPH = "https://graph.microsoft.com/v1.0";
|
|
81899
81921
|
var ONEDRIVE_INLINE_MAX_BYTES = 4 * 1024 * 1024;
|
|
81900
81922
|
function authHeaders(token) {
|
|
@@ -82017,14 +82039,14 @@ async function createShareLink(deps, item, scopes = ["anonymous", "organization"
|
|
|
82017
82039
|
async function deliverToOneDrive(args) {
|
|
82018
82040
|
const deps = { accessToken: args.accessToken, fetchImpl: args.fetchImpl };
|
|
82019
82041
|
const folder = await ensureSwitchroomFolder(deps, args.agentName);
|
|
82020
|
-
const filename =
|
|
82042
|
+
const filename = basename7(args.localPath);
|
|
82021
82043
|
const item = await uploadFile(deps, folder.id, filename, args.bytes);
|
|
82022
82044
|
const link = await createShareLink(deps, item, args.linkScopes);
|
|
82023
82045
|
return { itemId: item.id, link, folderPath: `Switchroom/${args.agentName}` };
|
|
82024
82046
|
}
|
|
82025
82047
|
|
|
82026
82048
|
// src/delivery/gdrive.ts
|
|
82027
|
-
import { basename as
|
|
82049
|
+
import { basename as basename8 } from "node:path";
|
|
82028
82050
|
var DRIVE = "https://www.googleapis.com/drive/v3";
|
|
82029
82051
|
var UPLOAD = "https://www.googleapis.com/upload/drive/v3";
|
|
82030
82052
|
var FOLDER_MIME = "application/vnd.google-apps.folder";
|
|
@@ -82172,7 +82194,7 @@ async function createShareLink2(deps, file, scopes = ["anyone"]) {
|
|
|
82172
82194
|
async function deliverToGoogleDrive(args) {
|
|
82173
82195
|
const deps = { accessToken: args.accessToken, fetchImpl: args.fetchImpl };
|
|
82174
82196
|
const folder = await ensureSwitchroomFolder2(deps, args.agentName);
|
|
82175
|
-
const filename =
|
|
82197
|
+
const filename = basename8(args.localPath);
|
|
82176
82198
|
const file = await uploadFile2(deps, folder.id, filename, args.bytes);
|
|
82177
82199
|
const link = await createShareLink2(deps, file, args.linkScopes);
|
|
82178
82200
|
return { itemId: file.id, link, folderPath: `Switchroom/${args.agentName}` };
|
|
@@ -82251,7 +82273,7 @@ async function runDeliverFile(localPath, deps = {}) {
|
|
|
82251
82273
|
try {
|
|
82252
82274
|
const bytes = read(localPath);
|
|
82253
82275
|
const out = await provider.deliver({ agentName, localPath, bytes });
|
|
82254
|
-
return { ok: true, provider: provider.name, link: out.link, folderPath: out.folderPath, filename:
|
|
82276
|
+
return { ok: true, provider: provider.name, link: out.link, folderPath: out.folderPath, filename: basename9(localPath) };
|
|
82255
82277
|
} catch (err) {
|
|
82256
82278
|
return { ok: false, provider: provider.name, error: `upload failed: ${err.message}` };
|
|
82257
82279
|
}
|
package/dist/cli/ui/index.html
CHANGED
|
@@ -1919,37 +1919,81 @@
|
|
|
1919
1919
|
return;
|
|
1920
1920
|
}
|
|
1921
1921
|
const dim = (s) => `<span style="color:var(--text-dim)">${escapeHtml(s)}</span>`;
|
|
1922
|
-
// Group entries by agent.
|
|
1922
|
+
// Group entries by agent. Agents sorted by name; within an agent the
|
|
1923
|
+
// entries keep their cascade-given order (defaults → profile → agent →
|
|
1924
|
+
// overlays), which is the order the operator/agent declared them.
|
|
1923
1925
|
const byAgent = {};
|
|
1924
1926
|
for (const e of entries) (byAgent[e.agent] ||= []).push(e);
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1927
|
+
|
|
1928
|
+
// One self-contained block per cron: title (or cron expr as fallback
|
|
1929
|
+
// heading) + badges, the prompt, then THIS cron's recent fires right
|
|
1930
|
+
// below it. Fires are matched to a cron by promptKey — both the entry
|
|
1931
|
+
// and each DispatchResult carry the same stable SHA. (Edge: two
|
|
1932
|
+
// entries with an identical prompt share a promptKey, so they'd share
|
|
1933
|
+
// the same fire list — acceptable; identical prompts are
|
|
1934
|
+
// indistinguishable in the audit ledger by design.)
|
|
1935
|
+
const renderCron = (e, agentFires) => {
|
|
1936
|
+
const hasTitle = typeof e.name === 'string' && e.name.length > 0;
|
|
1937
|
+
const heading = hasTitle
|
|
1938
|
+
? `<span style="font-weight:600;color:var(--text)">${escapeHtml(e.name)}</span>`
|
|
1939
|
+
: `<span style="color:var(--text-dim)">${escapeHtml(e.cron)}</span>`;
|
|
1940
|
+
const badges = []
|
|
1941
|
+
.concat(e.kind ? [e.kind] : [])
|
|
1942
|
+
.concat(e.model ? [e.model] : [])
|
|
1943
|
+
.concat(e.context ? [e.context] : [])
|
|
1944
|
+
.map(b => `<span class="chip">${escapeHtml(String(b))}</span>`)
|
|
1945
|
+
.join('');
|
|
1946
|
+
// Prompt: kind:action entries have no prompt (the action is
|
|
1947
|
+
// model-free), so show a muted marker rather than a blank line.
|
|
1948
|
+
const promptText = typeof e.prompt === 'string' ? e.prompt : '';
|
|
1949
|
+
const promptBlock = promptText
|
|
1950
|
+
? `<div style="margin:.4rem 0 .55rem;color:var(--text);font-size:.84rem" title="${escapeHtml(promptText)}">${escapeHtml(promptText.length > 140 ? promptText.slice(0, 140) + '…' : promptText)}</div>`
|
|
1951
|
+
: `<div style="margin:.4rem 0 .55rem">${dim(e.kind === 'action' ? 'model-free action' : '—')}</div>`;
|
|
1952
|
+
// Recent fires for THIS cron only — filter the agent's fire list by
|
|
1953
|
+
// matching promptKey, newest-first, last 8.
|
|
1954
|
+
const fires = agentFires
|
|
1955
|
+
.filter(f => f.promptKey === e.promptKey)
|
|
1956
|
+
.slice()
|
|
1957
|
+
.reverse()
|
|
1958
|
+
.slice(0, 8);
|
|
1959
|
+
const fireList = fires.length === 0
|
|
1960
|
+
? `<div style="font-size:.78rem">${dim('no recorded fires yet')}</div>`
|
|
1934
1961
|
: fires.map(f => {
|
|
1935
1962
|
const ok = f.exitCode === 0;
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1963
|
+
const when = escapeHtml(shortTs(new Date(f.startedAt).toISOString()));
|
|
1964
|
+
const summary = String(f.outputSummary || '');
|
|
1965
|
+
const summaryHtml = summary
|
|
1966
|
+
? ' · <span style="color:var(--text-dim)">' + escapeHtml(summary.length > 70 ? summary.slice(0, 70) + '…' : summary) + '</span>'
|
|
1967
|
+
: '';
|
|
1968
|
+
return `<div style="font-size:.78rem;line-height:1.55">
|
|
1969
|
+
<span class="status-dot ${ok ? 'active' : 'inactive'}" style="display:inline-block;vertical-align:middle;margin-right:.35rem"></span>${when} · ${ok ? 'ok' : 'exit ' + escapeHtml(String(f.exitCode))}${summaryHtml}
|
|
1970
|
+
</div>`;
|
|
1941
1971
|
}).join('');
|
|
1972
|
+
return `
|
|
1973
|
+
<div style="border:1px solid var(--border);border-radius:8px;padding:.7rem .85rem;margin-bottom:.7rem;background:var(--surface-hover)">
|
|
1974
|
+
<div style="display:flex;align-items:center;gap:.5rem;flex-wrap:wrap">
|
|
1975
|
+
${heading}
|
|
1976
|
+
<code style="font-size:.78rem">${escapeHtml(e.cron)}</code>
|
|
1977
|
+
${badges}
|
|
1978
|
+
</div>
|
|
1979
|
+
${promptBlock}
|
|
1980
|
+
<div style="border-top:1px solid var(--border);padding-top:.5rem">
|
|
1981
|
+
<div style="font-size:.72rem;color:var(--text-dim);margin-bottom:.3rem">Recent fires</div>
|
|
1982
|
+
${fireList}
|
|
1983
|
+
</div>
|
|
1984
|
+
</div>`;
|
|
1985
|
+
};
|
|
1986
|
+
|
|
1987
|
+
const cards = Object.keys(byAgent).sort().map(agent => {
|
|
1988
|
+
const agentFires = recent[agent] || [];
|
|
1989
|
+
const list = byAgent[agent].map(e => renderCron(e, agentFires)).join('');
|
|
1942
1990
|
return `
|
|
1943
1991
|
<div class="agent-card" style="margin-bottom:1rem">
|
|
1944
1992
|
<div class="card-header" style="cursor:default">
|
|
1945
1993
|
<span class="agent-name">${escapeHtml(agent)}</span>
|
|
1946
1994
|
<span class="agent-topic">${byAgent[agent].length} schedule entr${byAgent[agent].length === 1 ? 'y' : 'ies'}</span>
|
|
1947
1995
|
</div>
|
|
1948
|
-
<div style="padding
|
|
1949
|
-
<table class="accounts-table"><thead><tr><th>Cron</th><th>Prompt</th></tr></thead><tbody>${rows}</tbody></table>
|
|
1950
|
-
<div style="margin-top:0.6rem;font-size:0.8rem;color:var(--text-dim)">Recent fires (from scheduler.jsonl)</div>
|
|
1951
|
-
<table class="accounts-table"><thead><tr><th>When</th><th>Result</th><th>Exit</th></tr></thead><tbody>${fireRows}</tbody></table>
|
|
1952
|
-
</div>
|
|
1996
|
+
<div style="padding:.5rem 1.25rem 1rem">${list}</div>
|
|
1953
1997
|
</div>`;
|
|
1954
1998
|
}).join('');
|
|
1955
1999
|
container.innerHTML = degradedBanner + truncatedNote + cards;
|
|
@@ -14362,7 +14362,7 @@ function resolveDualPath(pathStr) {
|
|
|
14362
14362
|
|
|
14363
14363
|
// src/config/overlay-loader.ts
|
|
14364
14364
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "node:fs";
|
|
14365
|
-
import { resolve as resolve2 } from "node:path";
|
|
14365
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
14366
14366
|
|
|
14367
14367
|
// src/config/overlay-schema.ts
|
|
14368
14368
|
var OverlayDocSchema = exports_external.object({
|
|
@@ -14372,6 +14372,16 @@ var OverlayDocSchema = exports_external.object({
|
|
|
14372
14372
|
|
|
14373
14373
|
// src/config/overlay-loader.ts
|
|
14374
14374
|
var OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
14375
|
+
var OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
14376
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
14377
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
14378
|
+
if (titleFromComment)
|
|
14379
|
+
return titleFromComment;
|
|
14380
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
14381
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
14382
|
+
return;
|
|
14383
|
+
return base.length > 0 ? base : undefined;
|
|
14384
|
+
}
|
|
14375
14385
|
function overlayDirFor(agentName, subdir) {
|
|
14376
14386
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
14377
14387
|
return resolve2(base);
|
|
@@ -14397,13 +14407,21 @@ function listYamlFiles(dir) {
|
|
|
14397
14407
|
}
|
|
14398
14408
|
return out.sort();
|
|
14399
14409
|
}
|
|
14400
|
-
function stampOverlay(entry) {
|
|
14410
|
+
function stampOverlay(entry, title) {
|
|
14401
14411
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
14402
14412
|
value: true,
|
|
14403
14413
|
enumerable: false,
|
|
14404
14414
|
configurable: false,
|
|
14405
14415
|
writable: false
|
|
14406
14416
|
});
|
|
14417
|
+
if (title !== undefined) {
|
|
14418
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
14419
|
+
value: title,
|
|
14420
|
+
enumerable: false,
|
|
14421
|
+
configurable: false,
|
|
14422
|
+
writable: false
|
|
14423
|
+
});
|
|
14424
|
+
}
|
|
14407
14425
|
return entry;
|
|
14408
14426
|
}
|
|
14409
14427
|
function applyAgentOverlays(config) {
|
|
@@ -14420,6 +14438,7 @@ function applyAgentOverlays(config) {
|
|
|
14420
14438
|
const raw = readFileSync(file, "utf-8");
|
|
14421
14439
|
const parsed = $parse(raw);
|
|
14422
14440
|
const doc = OverlayDocSchema.parse(parsed);
|
|
14441
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
14423
14442
|
for (const entry of doc.schedule ?? []) {
|
|
14424
14443
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
14425
14444
|
const w = {
|
|
@@ -14431,7 +14450,7 @@ function applyAgentOverlays(config) {
|
|
|
14431
14450
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
14432
14451
|
continue;
|
|
14433
14452
|
}
|
|
14434
|
-
merged.push(stampOverlay(entry));
|
|
14453
|
+
merged.push(stampOverlay(entry, title));
|
|
14435
14454
|
}
|
|
14436
14455
|
} catch (err) {
|
|
14437
14456
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -20535,8 +20554,8 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
|
|
|
20535
20554
|
const liveContent = readFileSync4(configPath, "utf8");
|
|
20536
20555
|
const scratchDir = mkdtempSync(join2(tmpdir(), "config-propose-edit-"));
|
|
20537
20556
|
try {
|
|
20538
|
-
const
|
|
20539
|
-
const scratchFile = join2(scratchDir,
|
|
20557
|
+
const basename2 = configPath.split("/").pop() ?? "switchroom.yaml";
|
|
20558
|
+
const scratchFile = join2(scratchDir, basename2);
|
|
20540
20559
|
writeFileSync2(scratchFile, liveContent);
|
|
20541
20560
|
const patchFile = join2(scratchDir, "proposal.patch");
|
|
20542
20561
|
writeFileSync2(patchFile, unifiedDiff);
|
|
@@ -21013,10 +21032,12 @@ function collectScheduleEntries(config) {
|
|
|
21013
21032
|
for (let i = 0;i < schedule.length; i++) {
|
|
21014
21033
|
const entry = schedule[i];
|
|
21015
21034
|
const auditMaterial = entry.prompt ?? `action:${JSON.stringify(entry.action ?? {})}`;
|
|
21035
|
+
const title = entry[OVERLAY_TITLE];
|
|
21016
21036
|
out.push({
|
|
21017
21037
|
agent,
|
|
21018
21038
|
scheduleIndex: i,
|
|
21019
21039
|
cron: entry.cron,
|
|
21040
|
+
...typeof title === "string" && title.length > 0 ? { name: title } : {},
|
|
21020
21041
|
...entry.prompt !== undefined ? { prompt: entry.prompt } : {},
|
|
21021
21042
|
promptKey: createHash4("sha256").update(auditMaterial).digest("hex").slice(0, 12),
|
|
21022
21043
|
...entry.topic !== undefined ? { topic: entry.topic } : {},
|
|
@@ -22148,7 +22169,7 @@ function tail(s, bytes = TAIL_BYTES) {
|
|
|
22148
22169
|
}
|
|
22149
22170
|
var SCHEDULE_PROMPT_MAX_CHARS = 160;
|
|
22150
22171
|
var SCHEDULE_OUTPUT_SUMMARY_MAX_CHARS = 100;
|
|
22151
|
-
var
|
|
22172
|
+
var SCHEDULE_MAX_FIRES_PER_CRON = 8;
|
|
22152
22173
|
var SCHEDULE_FRAME_BUDGET_BYTES = MAX_FRAME_BYTES - 2048;
|
|
22153
22174
|
function slimScheduleEntry(e) {
|
|
22154
22175
|
const slim = {
|
|
@@ -22157,6 +22178,8 @@ function slimScheduleEntry(e) {
|
|
|
22157
22178
|
cron: e.cron,
|
|
22158
22179
|
promptKey: e.promptKey
|
|
22159
22180
|
};
|
|
22181
|
+
if (e.name !== undefined)
|
|
22182
|
+
slim.name = e.name;
|
|
22160
22183
|
if (e.prompt !== undefined) {
|
|
22161
22184
|
slim.prompt = e.prompt.length > SCHEDULE_PROMPT_MAX_CHARS ? e.prompt.slice(0, SCHEDULE_PROMPT_MAX_CHARS) : e.prompt;
|
|
22162
22185
|
}
|
|
@@ -22175,9 +22198,36 @@ function scheduleFrameBytes(view) {
|
|
|
22175
22198
|
}
|
|
22176
22199
|
function boundScheduleView(entries, recentByAgent) {
|
|
22177
22200
|
const slimEntries = entries.map(slimScheduleEntry);
|
|
22201
|
+
const truncSummary = (r) => typeof r.outputSummary === "string" && r.outputSummary.length > SCHEDULE_OUTPUT_SUMMARY_MAX_CHARS ? { ...r, outputSummary: r.outputSummary.slice(0, SCHEDULE_OUTPUT_SUMMARY_MAX_CHARS) } : { ...r };
|
|
22202
|
+
const currentKeysByAgent = new Map;
|
|
22203
|
+
for (const e of entries) {
|
|
22204
|
+
let s = currentKeysByAgent.get(e.agent);
|
|
22205
|
+
if (!s) {
|
|
22206
|
+
s = new Set;
|
|
22207
|
+
currentKeysByAgent.set(e.agent, s);
|
|
22208
|
+
}
|
|
22209
|
+
s.add(e.promptKey);
|
|
22210
|
+
}
|
|
22178
22211
|
const boundedRecent = {};
|
|
22179
22212
|
for (const [agent, rows] of Object.entries(recentByAgent)) {
|
|
22180
|
-
|
|
22213
|
+
const currentKeys = currentKeysByAgent.get(agent) ?? new Set;
|
|
22214
|
+
const byKey = new Map;
|
|
22215
|
+
for (const r of rows) {
|
|
22216
|
+
if (!currentKeys.has(r.promptKey))
|
|
22217
|
+
continue;
|
|
22218
|
+
const arr = byKey.get(r.promptKey);
|
|
22219
|
+
if (arr)
|
|
22220
|
+
arr.push(r);
|
|
22221
|
+
else
|
|
22222
|
+
byKey.set(r.promptKey, [r]);
|
|
22223
|
+
}
|
|
22224
|
+
const kept = [];
|
|
22225
|
+
for (const arr of byKey.values()) {
|
|
22226
|
+
for (const r of arr.slice(-SCHEDULE_MAX_FIRES_PER_CRON))
|
|
22227
|
+
kept.push(truncSummary(r));
|
|
22228
|
+
}
|
|
22229
|
+
if (kept.length > 0)
|
|
22230
|
+
boundedRecent[agent] = kept;
|
|
22181
22231
|
}
|
|
22182
22232
|
let view = { entries: slimEntries, recentByAgent: boundedRecent };
|
|
22183
22233
|
if (scheduleFrameBytes(view) <= SCHEDULE_FRAME_BUDGET_BYTES)
|
|
@@ -11971,7 +11971,16 @@ var init_overlay_schema = __esm(() => {
|
|
|
11971
11971
|
|
|
11972
11972
|
// src/config/overlay-loader.ts
|
|
11973
11973
|
import { existsSync as existsSync2, readFileSync, readdirSync, statSync } from "node:fs";
|
|
11974
|
-
import { resolve as resolve2 } from "node:path";
|
|
11974
|
+
import { basename, resolve as resolve2 } from "node:path";
|
|
11975
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
11976
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
11977
|
+
if (titleFromComment)
|
|
11978
|
+
return titleFromComment;
|
|
11979
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
11980
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
11981
|
+
return;
|
|
11982
|
+
return base.length > 0 ? base : undefined;
|
|
11983
|
+
}
|
|
11975
11984
|
function overlayDirFor(agentName, subdir) {
|
|
11976
11985
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
11977
11986
|
return resolve2(base);
|
|
@@ -11997,13 +12006,21 @@ function listYamlFiles(dir) {
|
|
|
11997
12006
|
}
|
|
11998
12007
|
return out.sort();
|
|
11999
12008
|
}
|
|
12000
|
-
function stampOverlay(entry) {
|
|
12009
|
+
function stampOverlay(entry, title) {
|
|
12001
12010
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
12002
12011
|
value: true,
|
|
12003
12012
|
enumerable: false,
|
|
12004
12013
|
configurable: false,
|
|
12005
12014
|
writable: false
|
|
12006
12015
|
});
|
|
12016
|
+
if (title !== undefined) {
|
|
12017
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
12018
|
+
value: title,
|
|
12019
|
+
enumerable: false,
|
|
12020
|
+
configurable: false,
|
|
12021
|
+
writable: false
|
|
12022
|
+
});
|
|
12023
|
+
}
|
|
12007
12024
|
return entry;
|
|
12008
12025
|
}
|
|
12009
12026
|
function applyAgentOverlays(config) {
|
|
@@ -12020,6 +12037,7 @@ function applyAgentOverlays(config) {
|
|
|
12020
12037
|
const raw = readFileSync(file, "utf-8");
|
|
12021
12038
|
const parsed = $parse(raw);
|
|
12022
12039
|
const doc = OverlayDocSchema.parse(parsed);
|
|
12040
|
+
const title = deriveOverlayTitle(raw, basename(file));
|
|
12023
12041
|
for (const entry of doc.schedule ?? []) {
|
|
12024
12042
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
12025
12043
|
const w = {
|
|
@@ -12031,7 +12049,7 @@ function applyAgentOverlays(config) {
|
|
|
12031
12049
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
12032
12050
|
continue;
|
|
12033
12051
|
}
|
|
12034
|
-
merged.push(stampOverlay(entry));
|
|
12052
|
+
merged.push(stampOverlay(entry, title));
|
|
12035
12053
|
}
|
|
12036
12054
|
} catch (err) {
|
|
12037
12055
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -12085,13 +12103,14 @@ function applyAgentOverlays(config) {
|
|
|
12085
12103
|
}
|
|
12086
12104
|
return { config, warnings };
|
|
12087
12105
|
}
|
|
12088
|
-
var OVERLAY_SOURCE;
|
|
12106
|
+
var OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
12089
12107
|
var init_overlay_loader = __esm(() => {
|
|
12090
12108
|
init_dist();
|
|
12091
12109
|
init_zod();
|
|
12092
12110
|
init_overlay_schema();
|
|
12093
12111
|
init_paths();
|
|
12094
12112
|
OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
12113
|
+
OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
12095
12114
|
});
|
|
12096
12115
|
|
|
12097
12116
|
// src/config/notion-workspace-acl.ts
|
|
@@ -12306,7 +12325,7 @@ var init_loader = __esm(() => {
|
|
|
12306
12325
|
// src/vault/approvals/kernel-server.ts
|
|
12307
12326
|
import * as net from "node:net";
|
|
12308
12327
|
import { mkdirSync, chmodSync, chownSync, existsSync as existsSync4, unlinkSync, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
12309
|
-
import { dirname, resolve as resolve4, basename } from "node:path";
|
|
12328
|
+
import { dirname, resolve as resolve4, basename as basename2 } from "node:path";
|
|
12310
12329
|
import { Database } from "bun:sqlite";
|
|
12311
12330
|
|
|
12312
12331
|
// src/vault/broker/protocol.ts
|
|
@@ -13507,7 +13526,7 @@ async function main() {
|
|
|
13507
13526
|
}
|
|
13508
13527
|
}
|
|
13509
13528
|
if (agents.length === 0) {
|
|
13510
|
-
const fallbackName =
|
|
13529
|
+
const fallbackName = basename2(socketEnv).replace(/\.sock$/, "");
|
|
13511
13530
|
process.umask(63);
|
|
13512
13531
|
mkdirSync(socketParent, { recursive: true, mode: 493 });
|
|
13513
13532
|
try {
|
|
@@ -11971,7 +11971,16 @@ var init_overlay_schema = __esm(() => {
|
|
|
11971
11971
|
|
|
11972
11972
|
// src/config/overlay-loader.ts
|
|
11973
11973
|
import { existsSync as existsSync5, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
11974
|
-
import { resolve as resolve3 } from "node:path";
|
|
11974
|
+
import { basename as basename3, resolve as resolve3 } from "node:path";
|
|
11975
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
11976
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
11977
|
+
if (titleFromComment)
|
|
11978
|
+
return titleFromComment;
|
|
11979
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
11980
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
11981
|
+
return;
|
|
11982
|
+
return base.length > 0 ? base : undefined;
|
|
11983
|
+
}
|
|
11975
11984
|
function overlayDirFor(agentName, subdir) {
|
|
11976
11985
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName}/${subdir}`);
|
|
11977
11986
|
return resolve3(base);
|
|
@@ -11997,13 +12006,21 @@ function listYamlFiles(dir) {
|
|
|
11997
12006
|
}
|
|
11998
12007
|
return out.sort();
|
|
11999
12008
|
}
|
|
12000
|
-
function stampOverlay(entry) {
|
|
12009
|
+
function stampOverlay(entry, title) {
|
|
12001
12010
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
12002
12011
|
value: true,
|
|
12003
12012
|
enumerable: false,
|
|
12004
12013
|
configurable: false,
|
|
12005
12014
|
writable: false
|
|
12006
12015
|
});
|
|
12016
|
+
if (title !== undefined) {
|
|
12017
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
12018
|
+
value: title,
|
|
12019
|
+
enumerable: false,
|
|
12020
|
+
configurable: false,
|
|
12021
|
+
writable: false
|
|
12022
|
+
});
|
|
12023
|
+
}
|
|
12007
12024
|
return entry;
|
|
12008
12025
|
}
|
|
12009
12026
|
function applyAgentOverlays(config) {
|
|
@@ -12020,6 +12037,7 @@ function applyAgentOverlays(config) {
|
|
|
12020
12037
|
const raw = readFileSync5(file, "utf-8");
|
|
12021
12038
|
const parsed = $parse(raw);
|
|
12022
12039
|
const doc = OverlayDocSchema.parse(parsed);
|
|
12040
|
+
const title = deriveOverlayTitle(raw, basename3(file));
|
|
12023
12041
|
for (const entry of doc.schedule ?? []) {
|
|
12024
12042
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
12025
12043
|
const w = {
|
|
@@ -12031,7 +12049,7 @@ function applyAgentOverlays(config) {
|
|
|
12031
12049
|
console.warn(`[switchroom] overlay-loader: agent='${agentName}' file='${file}': ${w.reason}`);
|
|
12032
12050
|
continue;
|
|
12033
12051
|
}
|
|
12034
|
-
merged.push(stampOverlay(entry));
|
|
12052
|
+
merged.push(stampOverlay(entry, title));
|
|
12035
12053
|
}
|
|
12036
12054
|
} catch (err) {
|
|
12037
12055
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -12085,13 +12103,14 @@ function applyAgentOverlays(config) {
|
|
|
12085
12103
|
}
|
|
12086
12104
|
return { config, warnings };
|
|
12087
12105
|
}
|
|
12088
|
-
var OVERLAY_SOURCE;
|
|
12106
|
+
var OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
12089
12107
|
var init_overlay_loader = __esm(() => {
|
|
12090
12108
|
init_dist();
|
|
12091
12109
|
init_zod();
|
|
12092
12110
|
init_overlay_schema();
|
|
12093
12111
|
init_paths();
|
|
12094
12112
|
OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
12113
|
+
OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
12095
12114
|
});
|
|
12096
12115
|
|
|
12097
12116
|
// src/config/notion-workspace-acl.ts
|
|
@@ -12640,7 +12659,7 @@ function allocateAgentUid(name) {
|
|
|
12640
12659
|
var BIND_MOUNT_EXACT_SOURCE_DENY = new Set(["/var/run/docker.sock"]);
|
|
12641
12660
|
|
|
12642
12661
|
// src/vault/broker/server.ts
|
|
12643
|
-
import { dirname as dirname4, resolve as resolve6, basename as
|
|
12662
|
+
import { dirname as dirname4, resolve as resolve6, basename as basename4 } from "node:path";
|
|
12644
12663
|
import * as os3 from "node:os";
|
|
12645
12664
|
import * as path3 from "node:path";
|
|
12646
12665
|
|
|
@@ -17778,12 +17797,12 @@ class VaultBroker {
|
|
|
17778
17797
|
}
|
|
17779
17798
|
function detectVaultLayoutDrift(vaultPath) {
|
|
17780
17799
|
const dir = dirname4(vaultPath);
|
|
17781
|
-
if (
|
|
17800
|
+
if (basename4(dir) !== "vault")
|
|
17782
17801
|
return;
|
|
17783
|
-
if (
|
|
17802
|
+
if (basename4(vaultPath) !== "vault.enc")
|
|
17784
17803
|
return;
|
|
17785
17804
|
const switchroomDir = dirname4(dir);
|
|
17786
|
-
if (
|
|
17805
|
+
if (basename4(switchroomDir) !== ".switchroom")
|
|
17787
17806
|
return;
|
|
17788
17807
|
const home2 = dirname4(switchroomDir);
|
|
17789
17808
|
const result = inspectVaultLayout(home2);
|
package/package.json
CHANGED
|
@@ -24474,7 +24474,16 @@ var init_overlay_schema = __esm(() => {
|
|
|
24474
24474
|
|
|
24475
24475
|
// ../src/config/overlay-loader.ts
|
|
24476
24476
|
import { existsSync as existsSync9, readFileSync as readFileSync5, readdirSync, statSync as statSync2 } from "node:fs";
|
|
24477
|
-
import { resolve as resolve3 } from "node:path";
|
|
24477
|
+
import { basename as basename3, resolve as resolve3 } from "node:path";
|
|
24478
|
+
function deriveOverlayTitle(raw, fileName) {
|
|
24479
|
+
const titleFromComment = raw.match(/^#[^\S\n]*name:[^\S\n]*(\S.*?)[^\S\n]*$/m)?.[1];
|
|
24480
|
+
if (titleFromComment)
|
|
24481
|
+
return titleFromComment;
|
|
24482
|
+
const base = fileName.replace(/\.ya?ml$/i, "");
|
|
24483
|
+
if (/^cron-[0-9a-f]{6,}$/i.test(base))
|
|
24484
|
+
return;
|
|
24485
|
+
return base.length > 0 ? base : undefined;
|
|
24486
|
+
}
|
|
24478
24487
|
function overlayDirFor(agentName3, subdir) {
|
|
24479
24488
|
const base = resolveDualPath(`~/.switchroom/agents/${agentName3}/${subdir}`);
|
|
24480
24489
|
return resolve3(base);
|
|
@@ -24500,13 +24509,21 @@ function listYamlFiles(dir) {
|
|
|
24500
24509
|
}
|
|
24501
24510
|
return out.sort();
|
|
24502
24511
|
}
|
|
24503
|
-
function stampOverlay(entry) {
|
|
24512
|
+
function stampOverlay(entry, title) {
|
|
24504
24513
|
Object.defineProperty(entry, OVERLAY_SOURCE, {
|
|
24505
24514
|
value: true,
|
|
24506
24515
|
enumerable: false,
|
|
24507
24516
|
configurable: false,
|
|
24508
24517
|
writable: false
|
|
24509
24518
|
});
|
|
24519
|
+
if (title !== undefined) {
|
|
24520
|
+
Object.defineProperty(entry, OVERLAY_TITLE, {
|
|
24521
|
+
value: title,
|
|
24522
|
+
enumerable: false,
|
|
24523
|
+
configurable: false,
|
|
24524
|
+
writable: false
|
|
24525
|
+
});
|
|
24526
|
+
}
|
|
24510
24527
|
return entry;
|
|
24511
24528
|
}
|
|
24512
24529
|
function applyAgentOverlays(config) {
|
|
@@ -24523,6 +24540,7 @@ function applyAgentOverlays(config) {
|
|
|
24523
24540
|
const raw = readFileSync5(file, "utf-8");
|
|
24524
24541
|
const parsed = $parse(raw);
|
|
24525
24542
|
const doc = OverlayDocSchema.parse(parsed);
|
|
24543
|
+
const title = deriveOverlayTitle(raw, basename3(file));
|
|
24526
24544
|
for (const entry of doc.schedule ?? []) {
|
|
24527
24545
|
if (entry.secrets && entry.secrets.length > 0) {
|
|
24528
24546
|
const w = {
|
|
@@ -24534,7 +24552,7 @@ function applyAgentOverlays(config) {
|
|
|
24534
24552
|
console.warn(`[switchroom] overlay-loader: agent='${agentName3}' file='${file}': ${w.reason}`);
|
|
24535
24553
|
continue;
|
|
24536
24554
|
}
|
|
24537
|
-
merged.push(stampOverlay(entry));
|
|
24555
|
+
merged.push(stampOverlay(entry, title));
|
|
24538
24556
|
}
|
|
24539
24557
|
} catch (err) {
|
|
24540
24558
|
const reason = err instanceof ZodError ? `schema rejection: ${err.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ")}` : `parse error: ${err.message}`;
|
|
@@ -24588,13 +24606,14 @@ function applyAgentOverlays(config) {
|
|
|
24588
24606
|
}
|
|
24589
24607
|
return { config, warnings };
|
|
24590
24608
|
}
|
|
24591
|
-
var OVERLAY_SOURCE;
|
|
24609
|
+
var OVERLAY_SOURCE, OVERLAY_TITLE;
|
|
24592
24610
|
var init_overlay_loader = __esm(() => {
|
|
24593
24611
|
init_dist();
|
|
24594
24612
|
init_zod();
|
|
24595
24613
|
init_overlay_schema();
|
|
24596
24614
|
init_paths();
|
|
24597
24615
|
OVERLAY_SOURCE = Symbol.for("switchroom.config.overlay-source");
|
|
24616
|
+
OVERLAY_TITLE = Symbol.for("switchroom.config.overlay-title");
|
|
24598
24617
|
});
|
|
24599
24618
|
|
|
24600
24619
|
// ../src/config/merge.ts
|
|
@@ -31522,7 +31541,7 @@ import {
|
|
|
31522
31541
|
appendFileSync as appendFileSync5
|
|
31523
31542
|
} from "fs";
|
|
31524
31543
|
import { homedir as homedir14 } from "os";
|
|
31525
|
-
import { join as join35, extname, sep as sep3, basename as
|
|
31544
|
+
import { join as join35, extname, sep as sep3, basename as basename10 } from "path";
|
|
31526
31545
|
|
|
31527
31546
|
// plugin-logger.ts
|
|
31528
31547
|
import { appendFileSync, mkdirSync, renameSync, statSync, existsSync } from "fs";
|
|
@@ -51508,7 +51527,7 @@ function sanitiseToolArg(name, raw) {
|
|
|
51508
51527
|
case "NotebookEdit": {
|
|
51509
51528
|
const fp = raw.file_path;
|
|
51510
51529
|
if (typeof fp === "string" && fp.length > 0)
|
|
51511
|
-
out =
|
|
51530
|
+
out = basename4(fp);
|
|
51512
51531
|
break;
|
|
51513
51532
|
}
|
|
51514
51533
|
case "Bash": {
|
|
@@ -51544,7 +51563,7 @@ function sanitiseToolArg(name, raw) {
|
|
|
51544
51563
|
out = out.slice(0, SANITISE_MAX_LEN - 1) + "\u2026";
|
|
51545
51564
|
return out;
|
|
51546
51565
|
}
|
|
51547
|
-
function
|
|
51566
|
+
function basename4(p) {
|
|
51548
51567
|
const idx = p.lastIndexOf("/");
|
|
51549
51568
|
return idx === -1 ? p : p.slice(idx + 1);
|
|
51550
51569
|
}
|
|
@@ -53139,10 +53158,10 @@ function defaultReadEvents(stateDir) {
|
|
|
53139
53158
|
return readAll(stateDir);
|
|
53140
53159
|
}
|
|
53141
53160
|
// permission-title.ts
|
|
53142
|
-
import { basename as
|
|
53161
|
+
import { basename as basename7 } from "node:path";
|
|
53143
53162
|
|
|
53144
53163
|
// permission-rule.ts
|
|
53145
|
-
import { basename as
|
|
53164
|
+
import { basename as basename6 } from "node:path";
|
|
53146
53165
|
var FILE_TOOLS = new Set([
|
|
53147
53166
|
"Edit",
|
|
53148
53167
|
"Write",
|
|
@@ -53203,7 +53222,7 @@ function skillBasenameFromPath(input) {
|
|
|
53203
53222
|
if (!path)
|
|
53204
53223
|
return null;
|
|
53205
53224
|
const trimmed = path.replace(/\/SKILL\.md$/i, "").replace(/\/$/, "");
|
|
53206
|
-
return
|
|
53225
|
+
return basename6(trimmed) || null;
|
|
53207
53226
|
}
|
|
53208
53227
|
function matchesAllowRule(rule, toolName, inputPreview) {
|
|
53209
53228
|
if (!rule || !toolName)
|
|
@@ -53432,11 +53451,11 @@ function describeGrant(toolName, inputPreview, option) {
|
|
|
53432
53451
|
return m ? `run ${m[1]} commands` : "run that command";
|
|
53433
53452
|
}
|
|
53434
53453
|
if (t === "Edit" || t === "MultiEdit" || t === "NotebookEdit")
|
|
53435
|
-
return `edit ${
|
|
53454
|
+
return `edit ${basename7(arg)}`;
|
|
53436
53455
|
if (t === "Write")
|
|
53437
|
-
return `write ${
|
|
53456
|
+
return `write ${basename7(arg)}`;
|
|
53438
53457
|
if (t === "Read")
|
|
53439
|
-
return `read ${
|
|
53458
|
+
return `read ${basename7(arg)}`;
|
|
53440
53459
|
return naturalAction(toolName, inputPreview);
|
|
53441
53460
|
}
|
|
53442
53461
|
switch (rule) {
|
|
@@ -53475,7 +53494,7 @@ function fileBase(input) {
|
|
|
53475
53494
|
if (!input)
|
|
53476
53495
|
return null;
|
|
53477
53496
|
const p = readString2(input, "file_path") ?? readString2(input, "notebook_path");
|
|
53478
|
-
return p ?
|
|
53497
|
+
return p ? basename7(p) : null;
|
|
53479
53498
|
}
|
|
53480
53499
|
function lowerFirst(text) {
|
|
53481
53500
|
return text.length > 0 ? text.charAt(0).toLowerCase() + text.slice(1) : text;
|
|
@@ -53521,7 +53540,7 @@ function truncate6(text, max) {
|
|
|
53521
53540
|
}
|
|
53522
53541
|
|
|
53523
53542
|
// permission-rule.ts
|
|
53524
|
-
import { basename as
|
|
53543
|
+
import { basename as basename8 } from "node:path";
|
|
53525
53544
|
var FILE_TOOLS2 = new Set([
|
|
53526
53545
|
"Edit",
|
|
53527
53546
|
"Write",
|
|
@@ -53636,14 +53655,14 @@ function skillBasenameFromPath3(input) {
|
|
|
53636
53655
|
if (!path)
|
|
53637
53656
|
return null;
|
|
53638
53657
|
const trimmed = path.replace(/\/SKILL\.md$/i, "").replace(/\/$/, "");
|
|
53639
|
-
return
|
|
53658
|
+
return basename8(trimmed) || null;
|
|
53640
53659
|
}
|
|
53641
53660
|
function isRulePersisted(resolvedAllow, ruleRule) {
|
|
53642
53661
|
return resolvedAllow.includes(ruleRule);
|
|
53643
53662
|
}
|
|
53644
53663
|
|
|
53645
53664
|
// scoped-approval.ts
|
|
53646
|
-
import { basename as
|
|
53665
|
+
import { basename as basename9 } from "node:path";
|
|
53647
53666
|
var SCOPED_APPROVAL_DEFAULT_TTL_MS = 30 * 60 * 1000;
|
|
53648
53667
|
function scopedApprovalTtlMs(env = process.env) {
|
|
53649
53668
|
const raw = env.SWITCHROOM_SCOPED_APPROVAL_TTL_MS;
|
|
@@ -53668,7 +53687,7 @@ function resolveTimeBox(toolName, inputPreview, choices) {
|
|
|
53668
53687
|
const fileMatch = FILE_RULE.exec(rule);
|
|
53669
53688
|
if (fileMatch) {
|
|
53670
53689
|
const verb = fileMatch[1] === "Read" ? "reads of" : "edits to";
|
|
53671
|
-
return { rule, breadth: `${verb} ${
|
|
53690
|
+
return { rule, breadth: `${verb} ${basename9(fileMatch[2])}` };
|
|
53672
53691
|
}
|
|
53673
53692
|
const bashMatch = BASH_FAMILY_RULE.exec(rule);
|
|
53674
53693
|
if (bashMatch) {
|
|
@@ -54441,10 +54460,10 @@ function readTurnActiveMarkerAgeMs(stateDir, now) {
|
|
|
54441
54460
|
}
|
|
54442
54461
|
|
|
54443
54462
|
// ../src/build-info.ts
|
|
54444
|
-
var VERSION = "0.15.
|
|
54445
|
-
var COMMIT_SHA = "
|
|
54446
|
-
var COMMIT_DATE = "2026-06-
|
|
54447
|
-
var LATEST_PR =
|
|
54463
|
+
var VERSION = "0.15.30";
|
|
54464
|
+
var COMMIT_SHA = "14e64ce2";
|
|
54465
|
+
var COMMIT_DATE = "2026-06-15T10:03:13Z";
|
|
54466
|
+
var LATEST_PR = 2378;
|
|
54448
54467
|
var COMMITS_AHEAD_OF_TAG = 0;
|
|
54449
54468
|
|
|
54450
54469
|
// gateway/boot-version.ts
|
|
@@ -61794,7 +61813,7 @@ function getMyAgentName() {
|
|
|
61794
61813
|
const fromEnv = process.env.SWITCHROOM_AGENT_NAME;
|
|
61795
61814
|
if (fromEnv && fromEnv.trim().length > 0)
|
|
61796
61815
|
return fromEnv.trim();
|
|
61797
|
-
return
|
|
61816
|
+
return basename10(process.cwd());
|
|
61798
61817
|
}
|
|
61799
61818
|
function isSelfTargetingCommand(name) {
|
|
61800
61819
|
if (name === "all")
|