switchroom 0.20.9 → 0.20.11
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/bin/handoff-briefing.sh +57 -5
- package/bin/working-state-reload-hook.sh +262 -0
- package/dist/agent-scheduler/index.js +65 -2
- package/dist/auth-broker/index.js +204 -24
- package/dist/cli/notion-write-pretool.mjs +65 -2
- package/dist/cli/self-improve-apply-guard-pretool.mjs +357 -92
- package/dist/cli/self-improve-stop.mjs +889 -7
- package/dist/cli/skill-validate-pretool.mjs +82 -3
- package/dist/cli/switchroom.js +3699 -2110
- package/dist/host-control/main.js +67 -4
- package/dist/vault/approvals/kernel-server.js +66 -3
- package/dist/vault/broker/server.js +66 -3
- package/package.json +1 -1
- package/profiles/_base/start.sh.hbs +49 -0
- package/profiles/_shared/agent-self-service.md.hbs +15 -22
- package/profiles/_shared/delegation-golden-rule.md.hbs +1 -1
- package/profiles/_shared/dev-protocol.md.hbs +1 -1
- package/profiles/_shared/execution-discipline.md.hbs +4 -4
- package/profiles/_shared/vault-protocol.md.hbs +2 -18
- package/profiles/default/CLAUDE.md.hbs +3 -5
- package/telegram-plugin/auto-fallback-fleet.ts +37 -2
- package/telegram-plugin/dist/gateway/gateway.js +1414 -918
- package/telegram-plugin/fallback-card-collapse.ts +1 -0
- package/telegram-plugin/gateway/auth-command.ts +11 -1
- package/telegram-plugin/gateway/callback-query-handlers.ts +100 -0
- package/telegram-plugin/gateway/eval-case-proposal-card.ts +86 -0
- package/telegram-plugin/gateway/fleet-fallback-notice-cooldown.test.ts +74 -0
- package/telegram-plugin/gateway/fleet-fallback-notice-cooldown.ts +71 -0
- package/telegram-plugin/gateway/gateway.ts +85 -90
- package/telegram-plugin/gateway/ipc-protocol.ts +43 -0
- package/telegram-plugin/gateway/ipc-server.ts +28 -0
- package/telegram-plugin/gateway/narrative-lane.ts +33 -2
- package/telegram-plugin/gateway/privacy-reset.test.ts +216 -0
- package/telegram-plugin/gateway/privacy-reset.ts +87 -0
- package/telegram-plugin/gateway/privacy-state.test.ts +165 -0
- package/telegram-plugin/gateway/privacy-state.ts +206 -0
- package/telegram-plugin/gateway/self-improve-proposal-wiring.ts +176 -0
- package/telegram-plugin/gateway/stale-pin-sweep-wiring.ts +24 -14
- package/telegram-plugin/gateway/stale-pin-sweep.test.ts +123 -26
- package/telegram-plugin/gateway/stale-pin-sweep.ts +48 -32
- package/telegram-plugin/gateway/throttle-tier-wiring.ts +15 -4
- package/telegram-plugin/slot-banner-driver.ts +42 -5
- package/telegram-plugin/tests/auto-fallback-fleet.test.ts +24 -0
- package/telegram-plugin/tests/gateway-handler-registration-wiring.test.ts +2 -0
- package/telegram-plugin/tests/narrative-lane-golden.test.ts +97 -0
- package/telegram-plugin/tests/privacy-reset-call-sites.test.ts +120 -0
- package/telegram-plugin/tests/status-pin-store.test.ts +25 -0
- package/telegram-plugin/tests/throttle-tier.test.ts +16 -0
- package/telegram-plugin/tests/turn-flush-safety.test.ts +67 -0
- package/telegram-plugin/throttle-tier.ts +12 -3
- package/telegram-plugin/turn-flush-safety.ts +97 -0
- package/vendor/hindsight-memory/CHANGELOG.md +31 -0
- package/vendor/hindsight-memory/hooks/hooks.json +2 -1
- package/vendor/hindsight-memory/scripts/retain.py +306 -0
- package/vendor/hindsight-memory/scripts/session_start.py +35 -8
- package/vendor/hindsight-memory/scripts/subagent_retain.py +29 -1
- package/vendor/hindsight-memory/scripts/tests/test_private_mode.py +415 -0
- package/vendor/hindsight-memory/scripts/tests/test_self_improve_correction_tag.py +167 -0
- package/vendor/hindsight-memory/scripts/tests/test_session_start_durability.py +107 -0
|
@@ -6919,7 +6919,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6919
6919
|
|
|
6920
6920
|
// src/cli/skill-validate-pretool.ts
|
|
6921
6921
|
import { readFileSync, lstatSync, readdirSync } from "node:fs";
|
|
6922
|
-
import { join } from "node:path";
|
|
6922
|
+
import { join, resolve } from "node:path";
|
|
6923
6923
|
|
|
6924
6924
|
// node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
|
|
6925
6925
|
var composer = require_composer();
|
|
@@ -7219,9 +7219,16 @@ function validateSkillMd(content, expectedName) {
|
|
|
7219
7219
|
}
|
|
7220
7220
|
var BANNED_PHRASE = "claude" + " -p";
|
|
7221
7221
|
|
|
7222
|
+
// src/self-improve/config.ts
|
|
7223
|
+
function selfImproveEnabled() {
|
|
7224
|
+
return process.env.SWITCHROOM_SELF_IMPROVE !== "0";
|
|
7225
|
+
}
|
|
7226
|
+
|
|
7222
7227
|
// src/cli/skill-validate-pretool.ts
|
|
7223
7228
|
var SKILLS_SEGMENT = "/.claude/skills/";
|
|
7224
7229
|
var EDIT_TOOLS = new Set(["Write", "Edit", "MultiEdit"]);
|
|
7230
|
+
var EVALS_JSON_REL = "evals/evals.json";
|
|
7231
|
+
var ABS_SKILL_EVALS_RE = /\/\.claude\/skills\/[^/]+\/evals\/evals\.json$/;
|
|
7225
7232
|
function readStdin() {
|
|
7226
7233
|
try {
|
|
7227
7234
|
return readFileSync(0, "utf8");
|
|
@@ -7280,6 +7287,72 @@ function fileSize(p) {
|
|
|
7280
7287
|
return 0;
|
|
7281
7288
|
}
|
|
7282
7289
|
}
|
|
7290
|
+
var BASH_WRITERS = new Set([
|
|
7291
|
+
"tee",
|
|
7292
|
+
"cp",
|
|
7293
|
+
"mv",
|
|
7294
|
+
"dd",
|
|
7295
|
+
"install",
|
|
7296
|
+
"truncate",
|
|
7297
|
+
"rsync"
|
|
7298
|
+
]);
|
|
7299
|
+
function tokenIsSkillEvalsJson(token) {
|
|
7300
|
+
const t = token.replace(/^['"]+/, "").replace(/['"]+$/, "");
|
|
7301
|
+
if (!t.includes(".claude/skills/"))
|
|
7302
|
+
return false;
|
|
7303
|
+
return ABS_SKILL_EVALS_RE.test(resolve("/", t));
|
|
7304
|
+
}
|
|
7305
|
+
function redirectWritesEvals(command) {
|
|
7306
|
+
const re = /(?:^|[^<>&\d])(?:\d+|&)?>>?(?:&(?![\d-]))?\|?\s*(['"]?)([^\s'"|;&()<>]+)\1/g;
|
|
7307
|
+
let m;
|
|
7308
|
+
while ((m = re.exec(command)) !== null) {
|
|
7309
|
+
if (m[2] && tokenIsSkillEvalsJson(m[2]))
|
|
7310
|
+
return true;
|
|
7311
|
+
}
|
|
7312
|
+
return false;
|
|
7313
|
+
}
|
|
7314
|
+
function writerVerbWritesEvals(command) {
|
|
7315
|
+
for (const seg of command.split(/&&|\|\||[;|\n]/g)) {
|
|
7316
|
+
const tokens = seg.trim().split(/\s+/).filter((s) => s.length > 0);
|
|
7317
|
+
if (tokens.length === 0)
|
|
7318
|
+
continue;
|
|
7319
|
+
const verb = tokens[0].replace(/^['"]+/, "");
|
|
7320
|
+
const rest = tokens.slice(1);
|
|
7321
|
+
if (BASH_WRITERS.has(verb)) {
|
|
7322
|
+
for (const tok of rest) {
|
|
7323
|
+
const p = tok.startsWith("of=") ? tok.slice(3) : tok;
|
|
7324
|
+
if (tokenIsSkillEvalsJson(p))
|
|
7325
|
+
return true;
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
if (verb === "sed" && rest.some((r) => r === "-i" || r.startsWith("-i"))) {
|
|
7329
|
+
for (const tok of rest)
|
|
7330
|
+
if (tokenIsSkillEvalsJson(tok))
|
|
7331
|
+
return true;
|
|
7332
|
+
}
|
|
7333
|
+
}
|
|
7334
|
+
return false;
|
|
7335
|
+
}
|
|
7336
|
+
function detectBashEvalsWrite(command) {
|
|
7337
|
+
if (redirectWritesEvals(command))
|
|
7338
|
+
return "a shell redirect into";
|
|
7339
|
+
if (writerVerbWritesEvals(command))
|
|
7340
|
+
return "a shell write into";
|
|
7341
|
+
return null;
|
|
7342
|
+
}
|
|
7343
|
+
function handleBash(event) {
|
|
7344
|
+
if (!selfImproveEnabled())
|
|
7345
|
+
allow();
|
|
7346
|
+
const input = event.tool_input && typeof event.tool_input === "object" ? event.tool_input : {};
|
|
7347
|
+
const command = typeof input.command === "string" ? input.command : "";
|
|
7348
|
+
if (!command)
|
|
7349
|
+
allow();
|
|
7350
|
+
const how = detectBashEvalsWrite(command);
|
|
7351
|
+
if (how) {
|
|
7352
|
+
block(`evals/evals.json is machine-managed under self-improvement \u2014 ${how} it ` + `via Bash bypasses the PII/secret scan and the operator's one-tap ` + `approval. Add a case with: switchroom self-improve add-eval-case ` + `--skill <slug> --prompt "<the correction, as a test prompt>". ` + `(To hand-author evals via skill-creator instead, set ` + `SWITCHROOM_SELF_IMPROVE=0.)`);
|
|
7353
|
+
}
|
|
7354
|
+
allow();
|
|
7355
|
+
}
|
|
7283
7356
|
function main() {
|
|
7284
7357
|
const raw = readStdin().trim();
|
|
7285
7358
|
if (!raw)
|
|
@@ -7291,12 +7364,15 @@ function main() {
|
|
|
7291
7364
|
allow();
|
|
7292
7365
|
}
|
|
7293
7366
|
const toolName = typeof event.tool_name === "string" ? event.tool_name : "";
|
|
7367
|
+
if (toolName === "Bash")
|
|
7368
|
+
handleBash(event);
|
|
7294
7369
|
if (!EDIT_TOOLS.has(toolName))
|
|
7295
7370
|
allow();
|
|
7296
7371
|
const input = event.tool_input && typeof event.tool_input === "object" ? event.tool_input : {};
|
|
7297
|
-
const
|
|
7298
|
-
if (!
|
|
7372
|
+
const rawFilePath = typeof input.file_path === "string" ? input.file_path : "";
|
|
7373
|
+
if (!rawFilePath)
|
|
7299
7374
|
allow();
|
|
7375
|
+
const filePath = resolve(rawFilePath);
|
|
7300
7376
|
const segIdx = filePath.indexOf(SKILLS_SEGMENT);
|
|
7301
7377
|
if (segIdx < 0)
|
|
7302
7378
|
allow();
|
|
@@ -7307,6 +7383,9 @@ function main() {
|
|
|
7307
7383
|
const slug = segs[0];
|
|
7308
7384
|
const relPath = segs.slice(1).join("/");
|
|
7309
7385
|
const skillDir = filePath.slice(0, segIdx + SKILLS_SEGMENT.length) + slug;
|
|
7386
|
+
if (selfImproveEnabled() && relPath === EVALS_JSON_REL) {
|
|
7387
|
+
block(`evals/evals.json is machine-managed under self-improvement \u2014 a direct ` + `write bypasses the PII/secret scan and the operator's one-tap ` + `approval. Add a case with: switchroom self-improve add-eval-case ` + `--skill ${slug} --prompt "<the correction, as a test prompt>". ` + `(To hand-author evals via skill-creator instead, set ` + `SWITCHROOM_SELF_IMPROVE=0.)`);
|
|
7388
|
+
}
|
|
7310
7389
|
const warnings = [];
|
|
7311
7390
|
if (!validateSkillName(slug)) {
|
|
7312
7391
|
warnings.push(`skill slug "${slug}" is invalid \u2014 must match ` + `[a-z0-9][a-z0-9_-]{0,62}. Claude won't discover a skill at an ` + `invalid slug.`);
|