switchroom 0.16.38 → 0.16.46
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 +88 -82
- package/dist/auth-broker/index.js +87 -81
- package/dist/cli/autoaccept-poll.js +8 -8
- package/dist/cli/drive-write-pretool.mjs +10 -10
- package/dist/cli/notion-write-pretool.mjs +89 -83
- package/dist/cli/skill-validate-pretool.mjs +91 -91
- package/dist/cli/switchroom.js +1621 -737
- package/dist/cli/ui/index.html +877 -214
- package/dist/host-control/main.js +271 -239
- package/dist/vault/approvals/kernel-server.js +90 -84
- package/dist/vault/broker/server.js +91 -85
- package/examples/minimal.yaml +1 -1
- package/examples/switchroom.yaml +1 -1
- package/package.json +2 -2
- package/profiles/_shared/reply-discipline.md.hbs +9 -0
- package/skills/switchroom-status/SKILL.md +1 -1
- package/telegram-plugin/bridge/bridge.ts +2 -1
- package/telegram-plugin/card-format.ts +7 -1
- package/telegram-plugin/dist/bridge/bridge.js +132 -114
- package/telegram-plugin/dist/gateway/gateway.js +2090 -1046
- package/telegram-plugin/dist/server.js +180 -162
- package/telegram-plugin/format.ts +305 -31
- package/telegram-plugin/gateway/gateway.ts +262 -63
- package/telegram-plugin/gateway/model-command.ts +173 -19
- package/telegram-plugin/hooks/tool-label-pretool.d.mts +12 -0
- package/telegram-plugin/hooks/tool-label-pretool.mjs +54 -16
- package/telegram-plugin/package.json +1 -1
- package/telegram-plugin/session-tail.ts +47 -1
- package/telegram-plugin/stream-reply-handler.ts +19 -1
- package/telegram-plugin/tests/always-allow-grant.test.ts +34 -2
- package/telegram-plugin/tests/card-format.test.ts +28 -0
- package/telegram-plugin/tests/claude-code-event-contract.test.ts +151 -0
- package/telegram-plugin/tests/format-consistency.test.ts +223 -0
- package/telegram-plugin/tests/formatting-parse-regression.test.ts +272 -0
- package/telegram-plugin/tests/formatting-torture-set.ts +218 -0
- package/telegram-plugin/tests/model-command.test.ts +213 -47
- package/telegram-plugin/tests/paragraph-normalizer.test.ts +203 -21
- package/telegram-plugin/tests/rich-markdown-oracle.ts +469 -0
- package/telegram-plugin/tests/session-tail.test.ts +91 -0
- package/telegram-plugin/tests/status-vocabulary-unification.test.ts +125 -0
- package/telegram-plugin/tests/telegram-format.test.ts +33 -8
- package/telegram-plugin/tests/text-voice-scrub.test.ts +142 -22
- package/telegram-plugin/tests/tool-activity-summary.test.ts +6 -1
- package/telegram-plugin/tests/tts-normalize.test.ts +242 -0
- package/telegram-plugin/tests/vault-request-access-tool.test.ts +24 -0
- package/telegram-plugin/tests/voice-ondemand.test.ts +99 -2
- package/telegram-plugin/tests/voice-presynth.test.ts +437 -0
- package/telegram-plugin/tests/worker-activity-feed.test.ts +49 -0
- package/telegram-plugin/text-voice-scrub.ts +68 -18
- package/telegram-plugin/tool-activity-summary.ts +20 -108
- package/telegram-plugin/tts-normalize.ts +377 -0
- package/telegram-plugin/uat/driver.ts +472 -22
- package/telegram-plugin/uat/scenarios/jtbd-model-litellm-sr-dm.test.ts +34 -14
- package/telegram-plugin/uat/scenarios/jtbd-multipart-render-dm.test.ts +169 -0
- package/telegram-plugin/uat/scenarios/jtbd-narration-intent-dm.test.ts +134 -0
- package/telegram-plugin/uat/scenarios/jtbd-rich-formatting-render-dm.test.ts +254 -0
- package/telegram-plugin/uat/scenarios/jtbd-status-phase-transitions-dm.test.ts +109 -0
- package/telegram-plugin/uat/uat-driver.test.ts +297 -0
- package/telegram-plugin/voice-ondemand.ts +161 -10
- package/telegram-plugin/voice-presynth.ts +242 -0
- package/telegram-plugin/worker-activity-feed.ts +9 -1
package/examples/minimal.yaml
CHANGED
package/examples/switchroom.yaml
CHANGED
|
@@ -58,7 +58,7 @@ vault:
|
|
|
58
58
|
# Every agent inherits this. Per-agent fields win on conflict.
|
|
59
59
|
# tools/skills/schedule are unioned; scalars are overridden.
|
|
60
60
|
defaults:
|
|
61
|
-
model: claude-sonnet-
|
|
61
|
+
model: claude-sonnet-5
|
|
62
62
|
# The switchroom-telegram fork is the default. Uncomment to fall back to
|
|
63
63
|
# the upstream marketplace plugin: channels.telegram.plugin: official
|
|
64
64
|
channels:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "switchroom",
|
|
3
3
|
"//version": "NOT the release version — source of truth is the git tag, resolved by scripts/build.mjs:resolveVersion() (see CLAUDE.md > Standard release process). This field is stale by design and only the Layer-4 dev/non-tag fallback for build.mjs + src/cli/resolve-version.ts; do NOT bump it expecting a release to pick it up. npm-pack tarball naming needs a real version — do that as an UNCOMMITTED pack-time bump (see release step 6), never a committed one.",
|
|
4
|
-
"version": "0.16.
|
|
4
|
+
"version": "0.16.46",
|
|
5
5
|
"description": "Run Claude Code 24/7 on your Claude Pro/Max subscription over Telegram. Open-source alternative to OpenClaw and NanoClaw — no API keys.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"pretest": "npm run build",
|
|
27
27
|
"test": "vitest run && bun test telegram-plugin/tests/history.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/silent-reply-guard.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/registry/api-registry.test.ts telegram-plugin/registry/turns-schema.test.ts telegram-plugin/tests/idle-footer-wiring.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/resolve-calling-subagent.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
28
28
|
"test:vitest": "vitest run",
|
|
29
|
-
"test:bun": "bun test src/
|
|
29
|
+
"test:bun": "bun test src/vault/grants.test.ts src/vault/write-grants.test.ts src/vault/broker/server-grants.test.ts src/vault/broker/server-write-grants.test.ts src/vault/broker/server-mint-grant-passphrase-attest.test.ts src/vault/broker/server-passphrase-attest.test.ts src/vault/broker/server-mint-grant-posture-attest.test.ts src/vault/broker/server-admin-only-keys.test.ts src/vault/broker/client-token.test.ts src/vault/broker/server-unlock.test.ts src/vault/broker/auto-unlock.test.ts src/vault/broker/drift-detection.test.ts tests/vault-broker-passphrase.test.ts src/cli/vault-get-broker.test.ts src/vault/resolver-via-broker.test.ts src/vault/broker/scope.test.ts src/vault/broker/server.test.ts src/litellm/provision-apply-e2e.test.ts src/drive/disconnect.test.ts src/drive/grants.test.ts src/drive/oauth.test.ts src/drive/onboarding.test.ts src/drive/reconciler.test.ts src/drive/vault-slots.test.ts src/drive/wrapper.test.ts src/vault/approvals/kernel.test.ts src/vault/approvals/approval-origin.test.ts src/vault/approvals/schema-idempotent.test.ts src/vault/broker/server-approvals.test.ts telegram-plugin/tests/boot-probes.test.ts telegram-plugin/tests/boot-version-string.test.ts telegram-plugin/tests/history.test.ts telegram-plugin/tests/cross-turn-card-gate.test.ts telegram-plugin/tests/emission-authority-open-gate.test.ts telegram-plugin/tests/emission-authority-ping-gate.test.ts telegram-plugin/tests/emission-authority-card-drain-gate.test.ts telegram-plugin/tests/per-topic-current-turn.test.ts telegram-plugin/tests/history-reaper.test.ts telegram-plugin/tests/ipc-server-client.test.ts telegram-plugin/tests/ipc-server-race.test.ts telegram-plugin/tests/gateway-bridge.test.ts telegram-plugin/tests/gateway-startup-mutex.test.ts telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts telegram-plugin/tests/boot-card-dedupe.test.ts telegram-plugin/tests/boot-card-reason.test.ts telegram-plugin/tests/progress-update.test.ts telegram-plugin/tests/quota-cache.test.ts telegram-plugin/tests/silent-reply-guard.test.ts telegram-plugin/tests/unhandled-rejection-policy.test.ts telegram-plugin/tests/registry-turns.test.ts telegram-plugin/registry/subagents.test.ts telegram-plugin/registry/subagents-bugs.test.ts telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts telegram-plugin/tests/turns-writer.test.ts telegram-plugin/tests/resume-inbound-builder.test.ts telegram-plugin/tests/subagent-tracker-hooks.test.ts telegram-plugin/tests/resolve-calling-subagent.test.ts telegram-plugin/tests/gateway-update-placeholder-dispatch.test.ts telegram-plugin/tests/reaction-trigger.test.ts telegram-plugin/tests/reaction-trigger-flow.test.ts telegram-plugin/tests/subagent-watcher-workflow-visibility.test.ts telegram-plugin/uat/load-env.test.ts telegram-plugin/uat/feed-matcher.test.ts telegram-plugin/uat/uat-driver.test.ts telegram-plugin/gateway/webhook-ingest-server.test.ts telegram-plugin/tests/skill-proposal-card.test.ts",
|
|
30
30
|
"test:watch": "vitest",
|
|
31
31
|
"lint": "tsc --noEmit && node scripts/check-plugin-references.mjs && bash scripts/check-bot-api-wrapping.sh && node scripts/check-bun-test-imports.mjs && node scripts/check-no-pii-secrets.mjs && node scripts/check-vault-test-hermeticity.mjs && node scripts/check-no-broadcast-delivery.mjs && node scripts/check-stale-tool-descriptions.mjs && node scripts/check-web-subscription-honest.mjs",
|
|
32
32
|
"lint:tsc": "tsc --noEmit",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## ⛔ SENDING YOUR ANSWER (read first, applies every turn)
|
|
2
|
+
|
|
3
|
+
**Plain text you write is INVISIBLE to the user.** The only thing that reaches Telegram is text passed through the `mcp__switchroom-telegram__reply` tool. Writing the answer in your response is NOT sending it — the user sees nothing until you call the reply tool.
|
|
4
|
+
|
|
5
|
+
- Every turn that answers a user **MUST end with a `reply` tool call** carrying the full answer. No exceptions, no "I'll just write it out."
|
|
6
|
+
- If you did work first (tool calls, lookups), the reply call is still required at the end — don't let the turn end on a tool result or plain prose.
|
|
7
|
+
- If you genuinely have nothing to add, emit exactly `NO_REPLY` and nothing else.
|
|
8
|
+
|
|
9
|
+
If you skip this, the gateway's safety net eventually forces your answer out 2-4 minutes late and burns extra turns. Don't rely on the net. Send it yourself.
|
|
@@ -82,7 +82,7 @@ End with a one-line summary: "X of Y agents running."
|
|
|
82
82
|
|
|
83
83
|
```
|
|
84
84
|
assistant — running (2h 14m)
|
|
85
|
-
model: claude-sonnet-
|
|
85
|
+
model: claude-sonnet-5 collection: general
|
|
86
86
|
|
|
87
87
|
dev — running (45m)
|
|
88
88
|
model: claude-opus-4-8 collection: coding
|
|
@@ -434,7 +434,8 @@ const TOOL_SCHEMAS = [
|
|
|
434
434
|
chat_id: { type: 'string', description: 'Chat to render the approval card in (use the chat_id of the user message that triggered the workflow).' },
|
|
435
435
|
key: { type: 'string', description: 'Vault key the agent wants access to (matches the key shown in the VAULT-BROKER-DENIED error, e.g. `fatsecret/credentials`).' },
|
|
436
436
|
scope: { type: 'string', enum: ['read', 'write'], description: 'Access scope: "read" (default) for `vault:<key>` references; "write" if the agent needs to put new values.' },
|
|
437
|
-
reason: { type: 'string', description: 'REQUIRED in practice — short human-readable rationale rendered on the card (e.g. "to look up today\'s food log entries"). The approval card now renders "why: not provided" when this is omitted, which signals to the operator that the agent skipped its explanation — they will usually Deny. Always supply a one-line rationale.' },
|
|
437
|
+
reason: { type: 'string', description: 'REQUIRED in practice — short human-readable rationale rendered on the card (e.g. "to look up today\'s food log entries"). The approval card now renders "why: not provided" when this is omitted, which signals to the operator that the agent skipped its explanation — they will usually Deny. Always supply a one-line rationale. `why` is accepted as an alias (matching `vault_request_save`).' },
|
|
438
|
+
why: { type: 'string', description: 'Alias for `reason` (matches the sibling tool `vault_request_save`). If both are supplied, `reason` wins.' },
|
|
438
439
|
duration: { type: 'string', description: 'Requested grant TTL, like "30d" or "12h". Default 30d, capped at 90d. Beyond 90d the operator should use the host CLI explicitly.' },
|
|
439
440
|
message_thread_id: { type: 'string', description: 'Forum topic thread ID. Auto-applied from the last inbound message if not specified.' },
|
|
440
441
|
},
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import { escapeMarkdown, codeSpanSafe } from './format.js'
|
|
31
|
+
import { normalizeDashes } from './text-voice-scrub.js'
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Re-export so card surfaces have one import for the markdown escaper they
|
|
@@ -127,7 +128,12 @@ export function truncate(s: string, n: number): string {
|
|
|
127
128
|
* Run this BEFORE `truncate` + `escapeMarkdown`: clean → measure → escape.
|
|
128
129
|
*/
|
|
129
130
|
export function stripMarkdown(s: string): string {
|
|
130
|
-
|
|
131
|
+
// Close the em-dash leak on this model-authored-prose surface using the
|
|
132
|
+
// SAME dash logic as the reply-path voice scrub (no duplicated regex). Run
|
|
133
|
+
// it FIRST, while code spans (`` `…` ``) still have their backticks intact,
|
|
134
|
+
// so `normalizeDashes`'s own code-region masking preserves a dash inside a
|
|
135
|
+
// code span before the backtick-stripping below erases the fences.
|
|
136
|
+
let out = normalizeDashes(s);
|
|
131
137
|
// Inline + leftover code spans → bare text.
|
|
132
138
|
out = out.replace(/`+/g, '');
|
|
133
139
|
// Links / images: [text](url) and  → the label.
|