instar 1.3.839 → 1.3.841
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 +1 -1
- package/dashboard/subscriptions.js +17 -9
- package/dist/commands/server.js +5 -5
- package/dist/commands/server.js.map +1 -1
- package/dist/core/EnrollmentWizard.d.ts +3 -0
- package/dist/core/EnrollmentWizard.d.ts.map +1 -1
- package/dist/core/EnrollmentWizard.js +4 -0
- package/dist/core/EnrollmentWizard.js.map +1 -1
- package/dist/core/FrameworkLoginDriver.d.ts +7 -0
- package/dist/core/FrameworkLoginDriver.d.ts.map +1 -1
- package/dist/core/FrameworkLoginDriver.js +7 -0
- package/dist/core/FrameworkLoginDriver.js.map +1 -1
- package/dist/monitoring/ApprenticeshipCycleStore.d.ts.map +1 -1
- package/dist/monitoring/ApprenticeshipCycleStore.js +11 -2
- package/dist/monitoring/ApprenticeshipCycleStore.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.840.md +26 -0
- package/upgrades/1.3.841.md +23 -0
- package/upgrades/side-effects/cycles-integrity-tolerant-read.md +64 -0
- package/upgrades/side-effects/subscription-cell-login-integrity.md +70 -0
package/dashboard/index.html
CHANGED
|
@@ -3644,7 +3644,7 @@
|
|
|
3644
3644
|
the dashboard (PIN → sign-in link → paste the code). Hidden when there's nothing to show. -->
|
|
3645
3645
|
<section class="ph-section">
|
|
3646
3646
|
<h3 class="ph-h">Accounts on each machine</h3>
|
|
3647
|
-
<p class="ph-h-sub">Which subscription is set up on which machine. Tap “Set up” on an empty cell
|
|
3647
|
+
<p class="ph-h-sub">Which subscription is set up on which machine. Tap “Set up” on an empty cell, or “Sign in” on a cell that needs attention — you’ll enter your PIN, open the sign-in link, and paste the code right here.</p>
|
|
3648
3648
|
<div id="subMatrix"></div>
|
|
3649
3649
|
</section>
|
|
3650
3650
|
<section class="ph-section">
|
|
@@ -512,7 +512,13 @@ export function buildMatrixModel(poolScope, pendingScope, transient = {}) {
|
|
|
512
512
|
const mid = a && a.machineId;
|
|
513
513
|
if (!a || !a.id || !mid || offlineMachineIds.has(mid)) continue;
|
|
514
514
|
const status = effectiveAccountStatus(a);
|
|
515
|
-
|
|
515
|
+
const key = `${a.id}::${mid}`;
|
|
516
|
+
const next = status === 'needs-reauth' ? 'needs-reauth' : (status === 'active' ? 'active' : 'other');
|
|
517
|
+
// Pool reads may contain more than one observation for the same account/machine.
|
|
518
|
+
// Safety state is monotonic within a render: a later stale Active row must never
|
|
519
|
+
// overwrite a live identity-drift verdict.
|
|
520
|
+
const prior = cellStatus.get(key);
|
|
521
|
+
cellStatus.set(key, prior === 'needs-reauth' || next === 'needs-reauth' ? 'needs-reauth' : next);
|
|
516
522
|
}
|
|
517
523
|
// (accountId, machineId) in-progress, correlated on (login.id === accountId, machineId) (FD6 r3 #2).
|
|
518
524
|
// The MAP carries the pending-login RECORD so the in-progress cell can render the COMPLETE
|
|
@@ -546,20 +552,22 @@ export function buildMatrixModel(poolScope, pendingScope, transient = {}) {
|
|
|
546
552
|
if (m.offline) state = 'offline'; // whole column offline (FD6)
|
|
547
553
|
else if (t && t.state === 'held') state = 'held';
|
|
548
554
|
else if (t && t.state === 'cant-resolve') state = 'cant-resolve';
|
|
549
|
-
|
|
550
|
-
//
|
|
551
|
-
// next pool read that shows the account active — the cell must flip to an unmistakable
|
|
552
|
-
// verified presentation the moment the enrollment verifies (topic 29836 D4), never blink
|
|
553
|
-
// back to a "Set up" button while the server catches up.
|
|
554
|
-
else if (t && t.state === 'just-verified') state = 'just-verified';
|
|
555
|
+
// Durable pending state wins over enrollment bookkeeping after restart: the
|
|
556
|
+
// full flow rehydrates into its cell even if the pool row still says Active.
|
|
555
557
|
// broken (D5): the server says this attempt's sign-in pane is DEAD (record ⟂ pane
|
|
556
558
|
// reconciliation) — or the client just watched a code-submit refuse with pane-dead.
|
|
557
559
|
// Presenting it as submittable would be a lie; it gets an explicit needs-restart
|
|
558
560
|
// presentation with a working Retry (start-cell supersedes the zombie atomically).
|
|
559
|
-
else if ((
|
|
560
|
-
else if (pendingLogin) state = 'in-progress';
|
|
561
|
+
else if (cellStatus.get(key) === 'needs-reauth' && pendingLogin && pendingLogin.paneAlive === false) state = 'broken';
|
|
562
|
+
else if (cellStatus.get(key) === 'needs-reauth' && pendingLogin) state = 'in-progress';
|
|
561
563
|
else if (t && t.state === 'expired') state = 'expired';
|
|
562
564
|
else if (cellStatus.get(key) === 'needs-reauth') state = 'needs-reauth';
|
|
565
|
+
else if (cellStatus.get(key) === 'active') state = 'active';
|
|
566
|
+
else if ((pendingLogin && pendingLogin.paneAlive === false) || (t && t.state === 'broken')) state = 'broken';
|
|
567
|
+
else if (pendingLogin) state = 'in-progress';
|
|
568
|
+
// just-verified bridges the short interval before the pool row becomes active.
|
|
569
|
+
// Once active, keep state=active and carry this transient as the highlight detail.
|
|
570
|
+
else if (t && t.state === 'just-verified') state = 'just-verified';
|
|
563
571
|
else state = 'empty'; // → "Set up" button
|
|
564
572
|
rowCells.push({
|
|
565
573
|
accountId: acct.accountId, machineId: m.machineId, state,
|
package/dist/commands/server.js
CHANGED
|
@@ -12353,7 +12353,7 @@ export async function startServer(options) {
|
|
|
12353
12353
|
// a 2nd account never clobbers the 1st.
|
|
12354
12354
|
const { PendingLoginStore } = await import('../core/PendingLoginStore.js');
|
|
12355
12355
|
const { EnrollmentWizard } = await import('../core/EnrollmentWizard.js');
|
|
12356
|
-
const { FrameworkLoginDriver, enrollPaneSessionName } = await import('../core/FrameworkLoginDriver.js');
|
|
12356
|
+
const { FrameworkLoginDriver, enrollPaneSessionName, enrollmentBrowserEnv } = await import('../core/FrameworkLoginDriver.js');
|
|
12357
12357
|
const DEFAULT_ENROLL_LOGIN_COMMANDS = {
|
|
12358
12358
|
'claude-code': 'claude auth login',
|
|
12359
12359
|
'codex-cli': 'codex login',
|
|
@@ -12402,16 +12402,16 @@ export async function startServer(options) {
|
|
|
12402
12402
|
}
|
|
12403
12403
|
return sessionManager.captureOutput(session, 120) || '';
|
|
12404
12404
|
},
|
|
12405
|
-
spawn: async ({ framework, configHome }) => {
|
|
12405
|
+
spawn: async ({ framework, configHome, openBrowser }) => {
|
|
12406
12406
|
const tmuxPath = detectTmuxPath();
|
|
12407
12407
|
if (!tmuxPath)
|
|
12408
12408
|
throw new Error('tmux not available for enrollment login');
|
|
12409
12409
|
const baseCmd = enrollLoginCommands[framework] ?? `${framework} login`;
|
|
12410
12410
|
// env-prefix sets the per-account config home for the login process so
|
|
12411
12411
|
// the credential lands in its own slot (CLAUDE_CONFIG_DIR isolation).
|
|
12412
|
-
const
|
|
12413
|
-
|
|
12414
|
-
|
|
12412
|
+
const env = { ...(configHome ? { CLAUDE_CONFIG_DIR: configHome } : {}), ...enrollmentBrowserEnv(openBrowser) };
|
|
12413
|
+
const prefix = Object.entries(env).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(' ');
|
|
12414
|
+
const cmd = prefix ? `env ${prefix} ${baseCmd}` : baseCmd;
|
|
12415
12415
|
const session = enrollPaneSessionName(framework, configHome);
|
|
12416
12416
|
try {
|
|
12417
12417
|
execFileSync(tmuxPath, ['kill-session', '-t', `=${session}`], { stdio: 'ignore' });
|