switchroom 0.14.6 → 0.14.8
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 +80 -80
- package/dist/auth-broker/index.js +80 -80
- package/dist/cli/drive-write-pretool.mjs +10 -10
- package/dist/cli/notion-write-pretool.mjs +82 -82
- package/dist/cli/skill-validate-pretool.mjs +72 -72
- package/dist/cli/switchroom.js +396 -358
- package/dist/host-control/main.js +148 -148
- package/dist/vault/approvals/kernel-server.js +82 -82
- package/dist/vault/broker/server.js +83 -83
- package/examples/switchroom.yaml +1 -1
- package/package.json +1 -1
- package/profiles/_base/start.sh.hbs +23 -0
- package/skills/switchroom-status/SKILL.md +1 -1
- package/telegram-plugin/dist/bridge/bridge.js +112 -112
- package/telegram-plugin/dist/gateway/gateway.js +583 -284
- package/telegram-plugin/dist/server.js +160 -160
- package/telegram-plugin/gateway/config-approval-handler.ts +36 -0
- package/telegram-plugin/gateway/gateway.ts +296 -180
- package/telegram-plugin/gateway/hostd-dispatch.ts +2 -1
- package/telegram-plugin/permission-diff.ts +382 -0
- package/telegram-plugin/tests/always-allow-correlation.test.ts +147 -0
- package/telegram-plugin/tests/always-allow-grant.test.ts +84 -88
- package/telegram-plugin/tests/permission-diff.test.ts +336 -0
- package/telegram-plugin/tests/tool-activity-summary.test.ts +25 -13
- package/telegram-plugin/tool-activity-summary.ts +27 -15
|
@@ -64,6 +64,28 @@ export interface ConfigApprovalHandlerDeps {
|
|
|
64
64
|
content: string;
|
|
65
65
|
}) => Promise<void>;
|
|
66
66
|
log?: (msg: string) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Single-tap correlation auto-resolve (#1977, security-critical).
|
|
69
|
+
*
|
|
70
|
+
* The durable "🔁 Always allow" flow has the gateway itself call
|
|
71
|
+
* hostd's `config_propose_edit`. hostd then calls BACK to the gateway
|
|
72
|
+
* asking for operator approval — but the operator already tapped the
|
|
73
|
+
* permission card, so posting a SECOND approval card would be a
|
|
74
|
+
* confusing double-tap.
|
|
75
|
+
*
|
|
76
|
+
* When this hook returns `'approve'`, the handler resolves the
|
|
77
|
+
* request immediately WITHOUT posting a card, creating a pending
|
|
78
|
+
* entry, or arming a timer. Returning `null` (the default / no-hook
|
|
79
|
+
* behaviour) falls through to the normal operator-approval card —
|
|
80
|
+
* which is what ANY uncorrelated edit (e.g. an agent-forged config
|
|
81
|
+
* change) gets, preserving the human-in-the-loop control.
|
|
82
|
+
*
|
|
83
|
+
* Forge-resistance lives in the caller's implementation: it must
|
|
84
|
+
* require the rule the diff *adds* to match a rule the gateway just
|
|
85
|
+
* queued, so a forged edit touching any other field finds no
|
|
86
|
+
* correlation and gets a real card.
|
|
87
|
+
*/
|
|
88
|
+
tryAutoResolve?: (msg: RequestConfigApprovalMessage) => "approve" | null;
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
/**
|
|
@@ -212,6 +234,20 @@ export async function handleRequestConfigApproval(
|
|
|
212
234
|
return;
|
|
213
235
|
}
|
|
214
236
|
|
|
237
|
+
// Single-tap correlation (#1977): if THIS edit was initiated by the
|
|
238
|
+
// gateway itself in response to an operator tap on the permission
|
|
239
|
+
// card, auto-approve without posting a second card. Forge-resistance
|
|
240
|
+
// is the caller's job — it correlates on the rule the diff adds. Any
|
|
241
|
+
// uncorrelated (e.g. agent-forged) edit returns null here and falls
|
|
242
|
+
// through to the real operator-approval card below.
|
|
243
|
+
if (deps.tryAutoResolve?.(msg) === "approve") {
|
|
244
|
+
deps.log?.(
|
|
245
|
+
`config_approval_auto_resolved requestId=${msg.requestId} agent=${msg.agentName} (operator-tapped always-allow correlation)`,
|
|
246
|
+
);
|
|
247
|
+
reply("approve");
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
215
251
|
const target = deps.loadTargetChat();
|
|
216
252
|
if (target === null) {
|
|
217
253
|
reply(
|