switchroom 0.16.46 → 0.17.0
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 +83 -81
- package/dist/auth-broker/index.js +104 -88
- package/dist/cli/autoaccept-poll.js +8 -8
- package/dist/cli/drive-write-pretool.mjs +10 -15
- package/dist/cli/notion-write-pretool.mjs +85 -83
- package/dist/cli/skill-validate-pretool.mjs +91 -91
- package/dist/cli/switchroom.js +1720 -1392
- package/dist/cli/ui/index.html +84 -12
- package/dist/host-control/main.js +209 -173
- package/dist/vault/approvals/kernel-server.js +86 -83
- package/dist/vault/broker/server.js +284 -139
- package/package.json +3 -3
- package/profiles/_base/cron-session.sh.hbs +1 -1
- package/profiles/_base/start.sh.hbs +54 -3
- package/skills/switchroom-architecture/telegram.md +8 -15
- package/skills/switchroom-cli/SKILL.md +4 -5
- package/skills/telegram-test-harness/SKILL.md +1 -1
- package/telegram-plugin/README.md +18 -29
- package/telegram-plugin/bridge/bridge.ts +1 -41
- package/telegram-plugin/bridge/tool-filter.ts +3 -4
- package/telegram-plugin/dist/bridge/bridge.js +120 -155
- package/telegram-plugin/dist/gateway/gateway.js +1127 -1029
- package/telegram-plugin/dist/server.js +168 -203
- package/telegram-plugin/gateway/busy-key-reaper.ts +113 -0
- package/telegram-plugin/gateway/disconnect-flush.ts +11 -0
- package/telegram-plugin/gateway/escalation-bridge-gate.ts +46 -0
- package/telegram-plugin/gateway/gate-parity-probe.ts +102 -0
- package/telegram-plugin/gateway/gateway.ts +566 -631
- package/telegram-plugin/gateway/inbound-delivery-confirm.ts +89 -7
- package/telegram-plugin/gateway/inbound-spool.ts +108 -10
- package/telegram-plugin/gateway/model-command.ts +51 -3
- package/telegram-plugin/gateway/pending-inbound-buffer.ts +26 -0
- package/telegram-plugin/gateway/represent-guard.ts +28 -11
- package/telegram-plugin/gateway/status-pin-store.ts +124 -45
- package/telegram-plugin/gateway/worker-feed-dispatch.ts +19 -0
- package/telegram-plugin/history.ts +5 -0
- package/telegram-plugin/hooks/silent-end-interrupt-stop.mjs +1 -2
- package/telegram-plugin/hooks/subagent-tracker-pretool.mjs +9 -1
- package/telegram-plugin/registry/subagents-schema.ts +126 -1
- package/telegram-plugin/registry/turns-schema.ts +65 -1
- package/telegram-plugin/session-tail.ts +26 -4
- package/telegram-plugin/slot-banner-driver.ts +42 -2
- package/telegram-plugin/status-query-telemetry.ts +100 -0
- package/telegram-plugin/stream-reply-handler.ts +15 -16
- package/telegram-plugin/subagent-watcher.ts +182 -30
- package/telegram-plugin/tests/buffer-gate-broadened.test.ts +4 -10
- package/telegram-plugin/tests/busy-key-reaper.test.ts +191 -0
- package/telegram-plugin/tests/emission-authority-facade.test.ts +11 -17
- package/telegram-plugin/tests/emission-determinism-wiring.test.ts +5 -26
- package/telegram-plugin/tests/escalation-bridge-gate.test.ts +38 -0
- package/telegram-plugin/tests/gate-parity-probe.test.ts +171 -0
- package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +13 -0
- package/telegram-plugin/tests/gateway-outbound-redact.test.ts +14 -11
- package/telegram-plugin/tests/inbound-delivery-confirm.test.ts +146 -0
- package/telegram-plugin/tests/inbound-spool.test.ts +143 -0
- package/telegram-plugin/tests/model-command.test.ts +54 -1
- package/telegram-plugin/tests/multitopic-routing-wiring.test.ts +5 -11
- package/telegram-plugin/tests/nested-worker-visibility-harness.test.ts +329 -0
- package/telegram-plugin/tests/pending-inbound-buffer.test.ts +53 -0
- package/telegram-plugin/tests/progress-update-redact.test.ts +99 -0
- package/telegram-plugin/tests/registry-turns.test.ts +67 -0
- package/telegram-plugin/tests/represent-guard.test.ts +42 -6
- package/telegram-plugin/tests/resume-inbound-builder.test.ts +1 -0
- package/telegram-plugin/tests/session-tail.test.ts +10 -1
- package/telegram-plugin/tests/slot-banner-boot-recovery.test.ts +246 -0
- package/telegram-plugin/tests/status-pin-boot-recovery.test.ts +0 -14
- package/telegram-plugin/tests/status-pin-store.test.ts +220 -5
- package/telegram-plugin/tests/status-query-telemetry.test.ts +115 -0
- package/telegram-plugin/tests/subagent-nested-dispatch.test.ts +209 -0
- package/telegram-plugin/tests/subagent-tracker-hooks.test.ts +37 -0
- package/telegram-plugin/tests/subagent-watcher-boot-promotion-replay.test.ts +167 -0
- package/telegram-plugin/tests/subagent-watcher-env-thresholds.test.ts +46 -3
- package/telegram-plugin/tests/subagent-watcher-stall-notification.test.ts +70 -0
- package/telegram-plugin/tests/tool-activity-summary.test.ts +16 -0
- package/telegram-plugin/tests/tool-filter.test.ts +1 -3
- package/telegram-plugin/tests/tool-label-pretool.test.ts +1 -4
- package/telegram-plugin/tests/turn-flush-safety.test.ts +222 -1
- package/telegram-plugin/tests/vault-request-access-unlock-resume.test.ts +46 -0
- package/telegram-plugin/tests/worker-activity-feed.test.ts +202 -9
- package/telegram-plugin/tests/worker-feed-dispatch.test.ts +25 -0
- package/telegram-plugin/tests/worker-visibility-prose-silent-harness.test.ts +295 -0
- package/telegram-plugin/tool-activity-summary.ts +19 -0
- package/telegram-plugin/turn-flush-safety.ts +16 -1
- package/telegram-plugin/uat/scenarios/jtbd-answer-pings.test.ts +8 -9
- package/telegram-plugin/uat/scenarios/jtbd-foreground-feed-visibility-dm.test.ts +1 -1
- package/telegram-plugin/uat/scenarios/jtbd-narration-intent-dm.test.ts +1 -1
- package/telegram-plugin/worker-activity-feed.ts +75 -15
- package/vendor/hindsight-memory/CHANGELOG.md +24 -0
- package/vendor/hindsight-memory/README.md +5 -0
- package/vendor/hindsight-memory/scripts/lib/client.py +31 -1
- package/vendor/hindsight-memory/scripts/lib/config.py +41 -2
- package/vendor/hindsight-memory/scripts/lib/content.py +4 -1
- package/vendor/hindsight-memory/scripts/lib/daemon.py +11 -2
- package/vendor/hindsight-memory/scripts/recall.py +74 -1
- package/vendor/hindsight-memory/scripts/retain.py +8 -1
- package/vendor/hindsight-memory/scripts/tests/test_config_client_casts.py +111 -0
- package/vendor/hindsight-memory/scripts/tests/test_recall_integration.py +85 -1
- package/vendor/hindsight-memory/scripts/tests/test_recall_tag_filters.py +107 -0
- package/vendor/hindsight-memory/settings.json +4 -0
- package/vendor/hindsight-memory/tests/test_client.py +130 -0
- package/vendor/hindsight-memory/tests/test_config.py +47 -0
- package/vendor/hindsight-memory/tests/test_content.py +18 -0
- package/vendor/hindsight-memory/tests/test_hooks.py +62 -0
- package/telegram-plugin/gateway/error-envelope-card.ts +0 -64
- package/telegram-plugin/gateway/resolve-calling-subagent.ts +0 -78
- package/telegram-plugin/silent-reply.ts +0 -58
- package/telegram-plugin/tests/error-envelope-unlock-card.test.ts +0 -79
- package/telegram-plugin/tests/resolve-calling-subagent.test.ts +0 -269
- package/telegram-plugin/tests/silent-reply-guard.test.ts +0 -122
package/dist/cli/ui/index.html
CHANGED
|
@@ -2392,8 +2392,20 @@
|
|
|
2392
2392
|
return;
|
|
2393
2393
|
}
|
|
2394
2394
|
|
|
2395
|
+
// Worst-first posture strip + sort — not-active (down) or auth-failed
|
|
2396
|
+
// agents are the ones that need attention; surface them first.
|
|
2397
|
+
const needsAttention = (a) => a.active !== 'active' || a.auth.authenticated === false;
|
|
2398
|
+
const attnAgents = agents.filter(needsAttention);
|
|
2399
|
+
const cleanAgents = agents.filter(a => !needsAttention(a));
|
|
2400
|
+
const posture = `
|
|
2401
|
+
<div class="ac-posture" style="grid-column:1/-1;margin:0 0 0.4rem;justify-content:flex-start">
|
|
2402
|
+
<span class="ac-stat attn"><span class="n">${attnAgents.length}</span><span class="l">need attention</span></span>
|
|
2403
|
+
<span class="ac-stat clean"><span class="n">${cleanAgents.length}</span><span class="l">running clean</span></span>
|
|
2404
|
+
</div>`;
|
|
2405
|
+
const sortedAgents = attnAgents.concat(cleanAgents);
|
|
2406
|
+
|
|
2395
2407
|
container.className = 'agents-grid';
|
|
2396
|
-
container.innerHTML =
|
|
2408
|
+
container.innerHTML = posture + sortedAgents.map(a => `
|
|
2397
2409
|
<div class="agent-card" data-agent="${escapeHtml(a.name)}">
|
|
2398
2410
|
<div class="card-header" onclick="toggleLogs('${escapeHtml(a.name)}')">
|
|
2399
2411
|
<div class="status-dot ${statusClass(a)}" title="${escapeHtml(a.active)} · bridge heartbeat (not a claude-liveness signal)"></div>
|
|
@@ -2731,15 +2743,36 @@
|
|
|
2731
2743
|
const updating = h.stale
|
|
2732
2744
|
? `<span style="color:var(--text-dim);font-size:.7rem;margin-left:.4rem">(updating…)</span>`
|
|
2733
2745
|
: '';
|
|
2746
|
+
|
|
2747
|
+
// Worst-first posture strip — same "attention vs clean" pattern as
|
|
2748
|
+
// Fleet Health / Accounts. hostd counts as attention when the audit
|
|
2749
|
+
// log is missing/erroring OR any recent verb actually failed (not
|
|
2750
|
+
// the benign in-flight "started" state).
|
|
2751
|
+
const hostdHasFailure = !!(hd.recent && hd.recent.some(e =>
|
|
2752
|
+
e.result === 'error' || (e.exit_code != null && e.exit_code !== 0)));
|
|
2753
|
+
const services = [
|
|
2754
|
+
{ key: 'broker', ok: !!b.reachable, name: 'auth-broker', dotOk: b.reachable,
|
|
2755
|
+
html: `<div class="agent-card"><div class="card-header" style="cursor:default">${dot(b.reachable)}<span class="agent-name">auth-broker</span></div><div style="padding:0 1.25rem 1rem">${brokerBody}</div></div>` },
|
|
2756
|
+
{ key: 'hindsight', ok: hs.running !== false, name: 'hindsight', dotOk: hs.running,
|
|
2757
|
+
html: `<div class="agent-card"><div class="card-header" style="cursor:default">${dot(hs.running)}<span class="agent-name">hindsight</span></div><div style="padding:0 1.25rem 1rem">${hindsightBody}</div></div>` },
|
|
2758
|
+
];
|
|
2759
|
+
const attnCount = services.filter(s => !s.ok).length + (hd.auditLogPresent && !hostdHasFailure ? 0 : 1);
|
|
2760
|
+
const cleanCount = services.length + 1 - attnCount;
|
|
2761
|
+
const posture = `
|
|
2762
|
+
<div class="ac-posture" style="margin:0 0 0.6rem;justify-content:flex-start">
|
|
2763
|
+
<span class="ac-stat attn"><span class="n">${attnCount}</span><span class="l">need attention</span></span>
|
|
2764
|
+
<span class="ac-stat clean"><span class="n">${cleanCount}</span><span class="l">clean</span></span>
|
|
2765
|
+
</div>`;
|
|
2766
|
+
// Sort the service cards worst-first (down services surface before
|
|
2767
|
+
// healthy ones) — the hostd card stays pinned below since it's a
|
|
2768
|
+
// wider table, not part of the two-up grid.
|
|
2769
|
+
const servicesSorted = services.slice().sort((a, b2) => (a.ok === b2.ok) ? 0 : a.ok ? 1 : -1);
|
|
2770
|
+
|
|
2734
2771
|
container.innerHTML = `
|
|
2735
2772
|
${updating ? `<div style="margin-bottom:.4rem">System health ${updating}</div>` : ''}
|
|
2773
|
+
${posture}
|
|
2736
2774
|
<div class="agents-grid">
|
|
2737
|
-
|
|
2738
|
-
${dot(b.reachable)}<span class="agent-name">auth-broker</span></div>
|
|
2739
|
-
<div style="padding:0 1.25rem 1rem">${brokerBody}</div></div>
|
|
2740
|
-
<div class="agent-card"><div class="card-header" style="cursor:default">
|
|
2741
|
-
${dot(hs.running)}<span class="agent-name">hindsight</span></div>
|
|
2742
|
-
<div style="padding:0 1.25rem 1rem">${hindsightBody}</div></div>
|
|
2775
|
+
${servicesSorted.map(s => s.html).join('')}
|
|
2743
2776
|
</div>
|
|
2744
2777
|
<div class="agent-card" style="margin-top:1rem"><div class="card-header" style="cursor:default">
|
|
2745
2778
|
${dot(hd.auditLogPresent)}<span class="agent-name">hostd — recent privileged verbs</span></div>
|
|
@@ -2848,6 +2881,25 @@
|
|
|
2848
2881
|
const linear = data.linear || { configured: false, agents: [] };
|
|
2849
2882
|
const agentNames = data.agentNames || [];
|
|
2850
2883
|
|
|
2884
|
+
// Worst-first: a config-only account (no live broker slot — never
|
|
2885
|
+
// actually connected) is the real "needs attention" signal here. A
|
|
2886
|
+
// brokerKnown account past its (short-lived) access-token expiry is
|
|
2887
|
+
// NOT broken — it auto-refreshes on next use via the refresh token —
|
|
2888
|
+
// so it must NOT be sorted/flagged as an attention item (matches the
|
|
2889
|
+
// "don't alarm on auto-refresh" fix in renderOAuthAccountCard above).
|
|
2890
|
+
const isConnBroken = (a) => a.brokerKnown === false;
|
|
2891
|
+
const worstFirst = (list) => list.slice().sort((a, b) => (isConnBroken(a) === isConnBroken(b)) ? 0 : isConnBroken(a) ? -1 : 1);
|
|
2892
|
+
const googleSorted = worstFirst(google);
|
|
2893
|
+
const microsoftSorted = worstFirst(microsoft);
|
|
2894
|
+
const oauthAttn = google.filter(isConnBroken).length + microsoft.filter(isConnBroken).length;
|
|
2895
|
+
const oauthClean = (google.length + microsoft.length) - oauthAttn;
|
|
2896
|
+
const posture = (google.length + microsoft.length) > 0
|
|
2897
|
+
? `<div class="ac-posture" style="margin:0 0 1rem;justify-content:flex-start">
|
|
2898
|
+
<span class="ac-stat attn"><span class="n">${oauthAttn}</span><span class="l">need attention</span></span>
|
|
2899
|
+
<span class="ac-stat clean"><span class="n">${oauthClean}</span><span class="l">connected</span></span>
|
|
2900
|
+
</div>`
|
|
2901
|
+
: '';
|
|
2902
|
+
|
|
2851
2903
|
// When a provider's fetch FAILED (not genuinely empty), its empty-state
|
|
2852
2904
|
// must say "couldn't load", never "none configured" — otherwise a
|
|
2853
2905
|
// transient blip reads as "you have no accounts".
|
|
@@ -2856,10 +2908,10 @@
|
|
|
2856
2908
|
data.googleFailed
|
|
2857
2909
|
? "Couldn't load Google accounts — the data source was unreachable (retrying)."
|
|
2858
2910
|
: 'No Google accounts. Add one under <code>google_accounts:</code> and run <code>switchroom auth google account add</code>.',
|
|
2859
|
-
|
|
2911
|
+
googleSorted.map(a => renderOAuthAccountCard(a, { showType: false, provider: 'google', agentNames })).join(''),
|
|
2860
2912
|
);
|
|
2861
2913
|
|
|
2862
|
-
const msCards =
|
|
2914
|
+
const msCards = microsoftSorted.map(a => renderOAuthAccountCard(a, { showType: true, provider: 'microsoft', agentNames })).join('');
|
|
2863
2915
|
const msEmpty = data.microsoftFailed
|
|
2864
2916
|
? "Couldn't load Microsoft accounts — the data source was unreachable (retrying)."
|
|
2865
2917
|
: 'No Microsoft accounts yet — click <b>Connect a Microsoft account</b> above (or <code>/connect microsoft</code> from Telegram).';
|
|
@@ -2957,7 +3009,7 @@
|
|
|
2957
3009
|
? renderProblem(problemFor('connections-unreachable', {}))
|
|
2958
3010
|
: '';
|
|
2959
3011
|
|
|
2960
|
-
container.innerHTML = unreachableBanner + degradedBanner + googleSection + microsoftSection + notionSection + linearSection;
|
|
3012
|
+
container.innerHTML = unreachableBanner + degradedBanner + posture + googleSection + microsoftSection + notionSection + linearSection;
|
|
2961
3013
|
}
|
|
2962
3014
|
|
|
2963
3015
|
function renderSchedule(data) {
|
|
@@ -3050,7 +3102,27 @@
|
|
|
3050
3102
|
</div>`;
|
|
3051
3103
|
};
|
|
3052
3104
|
|
|
3053
|
-
|
|
3105
|
+
// Worst-first: an agent whose most recent fire for ANY of its crons
|
|
3106
|
+
// failed (non-zero exit) needs attention before agents whose fires
|
|
3107
|
+
// are all clean (or unfired). Posture strip mirrors the Fleet
|
|
3108
|
+
// Health / Accounts "need attention vs clean" pattern.
|
|
3109
|
+
const agentHasFailure = (agent) => {
|
|
3110
|
+
const agentFires = recent[agent] || [];
|
|
3111
|
+
return byAgent[agent].some(e => {
|
|
3112
|
+
const latest = agentFires.filter(f => f.promptKey === e.promptKey).slice(-1)[0];
|
|
3113
|
+
return latest && latest.exitCode !== 0;
|
|
3114
|
+
});
|
|
3115
|
+
};
|
|
3116
|
+
const agentNamesSorted = Object.keys(byAgent).sort();
|
|
3117
|
+
const attnAgentNames = agentNamesSorted.filter(agentHasFailure);
|
|
3118
|
+
const cleanAgentNames = agentNamesSorted.filter(a => !agentHasFailure(a));
|
|
3119
|
+
const posture = `
|
|
3120
|
+
<div class="ac-posture" style="margin:0 0 0.8rem;justify-content:flex-start">
|
|
3121
|
+
<span class="ac-stat attn"><span class="n">${attnAgentNames.length}</span><span class="l">need attention</span></span>
|
|
3122
|
+
<span class="ac-stat clean"><span class="n">${cleanAgentNames.length}</span><span class="l">clean</span></span>
|
|
3123
|
+
</div>`;
|
|
3124
|
+
|
|
3125
|
+
const cards = attnAgentNames.concat(cleanAgentNames).map(agent => {
|
|
3054
3126
|
const agentFires = recent[agent] || [];
|
|
3055
3127
|
const list = byAgent[agent].map(e => renderCron(e, agentFires)).join('');
|
|
3056
3128
|
return `
|
|
@@ -3062,7 +3134,7 @@
|
|
|
3062
3134
|
<div style="padding:.5rem 1.25rem 1rem">${list}</div>
|
|
3063
3135
|
</div>`;
|
|
3064
3136
|
}).join('');
|
|
3065
|
-
container.innerHTML = degradedBanner + truncatedNote + cards;
|
|
3137
|
+
container.innerHTML = degradedBanner + truncatedNote + posture + cards;
|
|
3066
3138
|
}
|
|
3067
3139
|
|
|
3068
3140
|
function renderApprovals(data, grants) {
|