instar 1.3.516 → 1.3.517
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/dashboard/index.html +28 -19
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +15 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +1 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/poolEmptyState.d.ts +75 -0
- package/dist/server/poolEmptyState.d.ts.map +1 -0
- package/dist/server/poolEmptyState.js +89 -0
- package/dist/server/poolEmptyState.js.map +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +71 -3
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +1 -0
- package/upgrades/1.3.517.md +70 -0
- package/upgrades/side-effects/multi-machine-seamlessness-ws42-empty-state.md +91 -0
package/dashboard/index.html
CHANGED
|
@@ -4080,23 +4080,31 @@
|
|
|
4080
4080
|
// WS4.2 (multi-machine-seamlessness spec, F7 — 2026-06-12 live incident):
|
|
4081
4081
|
// a machine with zero running sessions used to render as NOTHING, identical
|
|
4082
4082
|
// to a broken or unreachable machine. Render an explicit state row per pool
|
|
4083
|
-
// machine that has no session tiles
|
|
4084
|
-
//
|
|
4085
|
-
//
|
|
4086
|
-
//
|
|
4083
|
+
// machine that has no session tiles. The three states are computed SERVER-
|
|
4084
|
+
// SIDE in pool.machines[].emptyState (honest derivation from the registry +
|
|
4085
|
+
// the live fan-out) — the dashboard just styles + prints them:
|
|
4086
|
+
// - online → "online — no active sessions" (idle but healthy)
|
|
4087
|
+
// - offline → "offline since <t>" (known absence)
|
|
4088
|
+
// - unreachable → "unreachable (last seen <t>)" (was online, now silent)
|
|
4089
|
+
// Pool disabled or single-machine → poolMachinesView is empty → zero rows,
|
|
4090
|
+
// zero behavior change (single-machine strict no-op, spec invariant 6).
|
|
4087
4091
|
function machineStatusInfo(m) {
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
+
const es = m && m.emptyState;
|
|
4093
|
+
if (es && es.kind && es.text) {
|
|
4094
|
+
// 'online' is calm; 'offline'/'unreachable' both read as offline styling.
|
|
4095
|
+
return { cls: es.kind === 'online' ? 'online' : 'offline', text: es.text };
|
|
4096
|
+
}
|
|
4097
|
+
// No server-computed empty-state present (shouldn't happen for a 0-session
|
|
4098
|
+
// machine, but never fabricate "online" — surface the honest unknown).
|
|
4099
|
+
return { cls: 'offline', text: 'state unknown' };
|
|
4092
4100
|
}
|
|
4093
4101
|
function renderMachineStatusStrip(list, allSessions) {
|
|
4094
4102
|
list.querySelectorAll('.machine-status-row').forEach(el => el.remove());
|
|
4095
4103
|
if (!poolMachinesView.length) return;
|
|
4096
|
-
const busy = new Set(allSessions.map(s => s.machineNickname || s.machineId).filter(Boolean));
|
|
4097
4104
|
for (const m of poolMachinesView) {
|
|
4105
|
+
// A machine WITH sessions already names itself via its tiles' badges.
|
|
4106
|
+
if (m.sessionCount > 0) continue;
|
|
4098
4107
|
const label = m.nickname || m.machineId || 'unnamed machine';
|
|
4099
|
-
if (busy.has(m.nickname) || busy.has(m.machineId)) continue; // has tiles — badge already names it
|
|
4100
4108
|
const info = machineStatusInfo(m);
|
|
4101
4109
|
const row = document.createElement('div');
|
|
4102
4110
|
row.className = `machine-status-row ${info.cls}`;
|
|
@@ -4656,17 +4664,18 @@
|
|
|
4656
4664
|
// (2026-06-11: five closed Mac Mini sessions reappeared on the laptop
|
|
4657
4665
|
// dashboard hours after they were closed).
|
|
4658
4666
|
remoteSessions = (j.sessions || []).filter(s => s.remote === true && (s.status === 'running' || s.status === 'starting'));
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
+
// WS4.2 (F7): the pooled sessions response now carries pool.machines —
|
|
4668
|
+
// every registered machine with its session count and, when idle, an
|
|
4669
|
+
// explicit SERVER-COMPUTED empty-state (online / offline / unreachable),
|
|
4670
|
+
// honestly derived from the registry + the live fan-out. Render it so an
|
|
4671
|
+
// idle machine reads "online — no active sessions" and a dark machine
|
|
4672
|
+
// reads "offline since"/"unreachable" — never an indistinguishable blank.
|
|
4673
|
+
// >=2 machines is the multi-machine case; single-machine stays empty (no-op).
|
|
4674
|
+
poolMachinesView = (j.pool && j.pool.enabled && Array.isArray(j.pool.machines) && j.pool.machines.length >= 2)
|
|
4675
|
+
? j.pool.machines
|
|
4667
4676
|
: [];
|
|
4668
4677
|
renderSessionList();
|
|
4669
|
-
} catch { /* best-effort —
|
|
4678
|
+
} catch { /* best-effort — peers may be offline; next tick retries */ }
|
|
4670
4679
|
}
|
|
4671
4680
|
function startPoolSessionsPolling() {
|
|
4672
4681
|
if (poolPollTimer) return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -4093,6 +4093,7 @@ Beyond the one-awake-machine model: with the pool enabled I run conversations ac
|
|
|
4093
4093
|
|
|
4094
4094
|
- **See the pool:** the **Machines tab** in the dashboard, or \`GET /pool\` (Bearer-auth) → which machine is the router ("dispatcher") + every machine's nickname, hardware, online status, load, and clock-skew status.
|
|
4095
4095
|
- **Every session, every machine:** the dashboard sessions list shows ALL sessions across the pool, each tagged with the machine it runs on. API: \`GET /sessions?scope=pool\` → \`{ sessions: [...each with machineId/machineNickname...], pool: { peersOk, failed } }\`. An unreachable peer degrades to a \`failed\` entry — local sessions always answer.
|
|
4096
|
+
- **Idle vs broken machine (WS4.2):** the same \`pool.machines[]\` carries an explicit per-machine state so an idle machine never reads as broken. A machine with ZERO sessions gets \`pool.machines[].emptyState\` = \`online — no active sessions\` (heartbeat-fresh, just idle) / \`offline since <t>\` (known offline) / \`unreachable (last seen <t>)\` (was online, now not answering — the \`failed\` case). Honest derivation from the registry online flag + last-seen + the live fan-out — never a fabricated "looks fine". The dashboard sessions view renders these per-machine; a machine WITH sessions gets no empty-state (its tiles already name it). Single-machine install = just the lone self row.
|
|
4096
4097
|
- **Post-transfer closeout (automatic):** when a topic moves to another machine, the OLD machine's session for it is closed automatically (immediately on an explicit "move", or within ~2 reaper ticks for any other path) — no duplicate sessions doing duplicate work. The close is recorded in the reap-log with reason "topic moved to <machine>"; protected sessions are never auto-closed.
|
|
4097
4098
|
- **Quota-aware placement (automatic):** capacity heartbeats carry each machine's LLM-account quota state, and placement avoids machines whose account is currently rate-limited/blocked (no more topics placed onto a silent machine). A hard pin still wins (flagged \`pinned-machine-quota-blocked\`); if EVERY machine is blocked, placement proceeds least-loaded with \`all-machines-quota-blocked\` flagged. \`GET /pool\` shows each machine's \`quotaState\`.
|
|
4098
4099
|
- **Machine nicknames** are the user-facing handle (auto-assigned, editable). Rename via \`PATCH /pool/machines/:machineId\` with \`{"nickname":"the mini"}\`, or inline on the Machines tab.
|
|
@@ -4150,6 +4151,20 @@ Beyond the one-awake-machine model: with the pool enabled I run conversations ac
|
|
|
4150
4151
|
patched = true;
|
|
4151
4152
|
result.upgraded.push('CLAUDE.md: added pool-wide session visibility line');
|
|
4152
4153
|
}
|
|
4154
|
+
// WS4.2 (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.2, F7): agents that already
|
|
4155
|
+
// carry the pool section predate the per-machine empty-state — without it
|
|
4156
|
+
// they will read an idle peer's blank row as a broken/missing machine (the
|
|
4157
|
+
// 2026-06-12 incident). Append the sub-line so they explain "online — no
|
|
4158
|
+
// active sessions" vs "offline since" vs "unreachable" correctly from the
|
|
4159
|
+
// pooled sessions response. Idempotent via the unique `pool.machines[].emptyState`
|
|
4160
|
+
// content-sniff (a sub-line of the already-tracked pool section).
|
|
4161
|
+
if (content.includes('Multi-Machine Session Pool (active-active') && !content.includes('pool.machines[].emptyState')) {
|
|
4162
|
+
const ws42line = `
|
|
4163
|
+
- **Idle vs broken machine (WS4.2):** the same \`pool.machines[]\` carries an explicit per-machine state so an idle machine never reads as broken. A machine with ZERO sessions gets \`pool.machines[].emptyState\` = \`online — no active sessions\` (heartbeat-fresh, just idle) / \`offline since <t>\` (known offline) / \`unreachable (last seen <t>)\` (was online, now not answering — the \`failed\` case). Honest derivation from the registry online flag + last-seen + the live fan-out — never a fabricated "looks fine". The dashboard sessions view renders these per-machine; a machine WITH sessions gets no empty-state (its tiles already name it). Single-machine install = just the lone self row.`;
|
|
4164
|
+
content += '\n' + ws42line + '\n';
|
|
4165
|
+
patched = true;
|
|
4166
|
+
result.upgraded.push('CLAUDE.md: added WS4.2 per-machine empty-state line');
|
|
4167
|
+
}
|
|
4153
4168
|
// Post-transfer closeout awareness (2026-06-05): agents that already carry
|
|
4154
4169
|
// the pool section must learn that a moved topic's old session now closes
|
|
4155
4170
|
// automatically (so they explain a disappeared session correctly instead of
|