instar 1.3.623 → 1.3.624
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/subscriptions.js +72 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +2 -3
- package/dist/commands/server.js.map +1 -1
- package/dist/core/FrameworkLoginDriver.d.ts +10 -0
- package/dist/core/FrameworkLoginDriver.d.ts.map +1 -1
- package/dist/core/FrameworkLoginDriver.js +13 -0
- package/dist/core/FrameworkLoginDriver.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +199 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +46 -46
- package/upgrades/1.3.624.md +23 -0
- package/upgrades/side-effects/ws52-code-paste-back.md +105 -0
|
@@ -271,6 +271,9 @@ export function renderPendingLogins(doc, target, logins, now = Date.now()) {
|
|
|
271
271
|
}
|
|
272
272
|
for (const l of logins) {
|
|
273
273
|
const row = el(doc, 'div', 'sub-pending');
|
|
274
|
+
// Non-sensitive identifiers for the code-submit handler (never a credential).
|
|
275
|
+
row.setAttribute('data-login-id', sanitizeForDisplay(l && l.id, 'label'));
|
|
276
|
+
if (l && (l.machineId || l.machineNickname)) row.setAttribute('data-machine-id', sanitizeForDisplay(l.machineId, 'label'));
|
|
274
277
|
|
|
275
278
|
// Lead with a plain-language headline naming what to do + where (machine).
|
|
276
279
|
const machine = sanitizeForDisplay(l && (l.machineNickname || l.machineId), 'label');
|
|
@@ -300,6 +303,22 @@ export function renderPendingLogins(doc, target, logins, now = Date.now()) {
|
|
|
300
303
|
row.appendChild(el(doc, 'div', 'sub-pending-code', `Code: ${sanitizeForDisplay(l.userCode, 'code')}`));
|
|
301
304
|
}
|
|
302
305
|
|
|
306
|
+
// url-code-paste flow (Claude): after signing in, the provider hands the operator a
|
|
307
|
+
// CODE to paste back. Give them a field for it right here — so it goes straight to the
|
|
308
|
+
// machine doing the login (off-chat), not relayed by hand. (ws52-code-paste-back)
|
|
309
|
+
if (l && l.kind === 'url-code-paste') {
|
|
310
|
+
row.appendChild(el(doc, 'div', 'sub-pending-codehint', 'After you sign in, paste the code the page gives you here:'));
|
|
311
|
+
const input = doc.createElement('input');
|
|
312
|
+
input.setAttribute('type', 'text');
|
|
313
|
+
input.setAttribute('class', 'sub-pending-code-input');
|
|
314
|
+
input.setAttribute('placeholder', 'Paste your sign-in code');
|
|
315
|
+
input.setAttribute('autocomplete', 'off');
|
|
316
|
+
row.appendChild(input);
|
|
317
|
+
const submit = el(doc, 'button', 'sub-pending-code-submit', 'Submit code');
|
|
318
|
+
submit.setAttribute('data-submit-code', '1');
|
|
319
|
+
row.appendChild(submit);
|
|
320
|
+
}
|
|
321
|
+
|
|
303
322
|
// One short secondary line: the TTL, and the flow notice only if present (trimmed).
|
|
304
323
|
const ttl = l && l.ttlExpiresAt ? countdown(l.ttlExpiresAt, now) : '';
|
|
305
324
|
if (ttl) row.appendChild(el(doc, 'div', 'sub-pending-ttl', `Link expires in ${ttl}`));
|
|
@@ -327,6 +346,7 @@ const URLS = {
|
|
|
327
346
|
// operator's single dashboard (WS5.2 seam #3) — without it the device-code link never appears here.
|
|
328
347
|
pending: '/subscription-pool/pending-logins?scope=pool',
|
|
329
348
|
inUse: '/subscription-pool/in-use',
|
|
349
|
+
submitCode: '/subscription-pool/follow-me/submit-code', // POST — paste-back the sign-in code (ws52-code-paste-back)
|
|
330
350
|
scan: '/subscription-pool/follow-me/scan', // POST — follow-me consent offers (one-tap card)
|
|
331
351
|
issue: '/mandate/issue-for-machine', // POST (PIN-gated) — Approve issues the mandate
|
|
332
352
|
};
|
|
@@ -404,6 +424,7 @@ export function createController(opts) {
|
|
|
404
424
|
const inUseAccountId = inUseBody && inUseBody.activeAccountId ? inUseBody.activeAccountId : null;
|
|
405
425
|
renderAccounts(doc, els.accounts, accounts, now(), inUseAccountId);
|
|
406
426
|
renderPendingLogins(doc, els.pending, logins, now());
|
|
427
|
+
wireCodeSubmit();
|
|
407
428
|
// The one-tap follow-me Approve card(s) — rendered into els.followMe from the scan offers
|
|
408
429
|
// (ws52-operator-tap-not-text Part A). Silent when there are none. The Approve click is wired
|
|
409
430
|
// once (delegated) so re-renders never stack listeners.
|
|
@@ -456,6 +477,57 @@ export function createController(opts) {
|
|
|
456
477
|
s.textContent = text;
|
|
457
478
|
}
|
|
458
479
|
|
|
480
|
+
// Delegated, wired ONCE: a "Submit code" tap on a pending-login row reads the pasted
|
|
481
|
+
// sign-in code and POSTs it (with the login's id + machineId) to the fronting relay,
|
|
482
|
+
// which carries it to the machine doing the login (off-chat). The code is never stored
|
|
483
|
+
// client-side beyond the input; it's cleared on success. (ws52-code-paste-back)
|
|
484
|
+
function wireCodeSubmit() {
|
|
485
|
+
if (state.codeSubmitWired || !els.pending) return;
|
|
486
|
+
state.codeSubmitWired = true;
|
|
487
|
+
els.pending.addEventListener('click', (ev) => {
|
|
488
|
+
const btn = ev.target && ev.target.closest ? ev.target.closest('[data-submit-code]') : null;
|
|
489
|
+
if (!btn || !els.pending.contains(btn)) return;
|
|
490
|
+
const row = btn.closest('.sub-pending');
|
|
491
|
+
if (!row) return;
|
|
492
|
+
const input = row.querySelector('.sub-pending-code-input');
|
|
493
|
+
const code = input ? input.value.trim() : '';
|
|
494
|
+
const id = row.getAttribute('data-login-id');
|
|
495
|
+
const machineId = row.getAttribute('data-machine-id') || undefined;
|
|
496
|
+
if (!code) { setRowStatus(row, 'Paste the code the sign-in page gave you, then tap Submit.'); return; }
|
|
497
|
+
if (!id) { setRowStatus(row, 'Couldn’t identify this login — please refresh.'); return; }
|
|
498
|
+
setRowStatus(row, 'Sending your code…');
|
|
499
|
+
btn.setAttribute('disabled', '1');
|
|
500
|
+
void (async () => {
|
|
501
|
+
try {
|
|
502
|
+
const r = await postJson(URLS.submitCode, { machineId, id, code });
|
|
503
|
+
if (r.ok && r.json && r.json.outcome === 'validated') {
|
|
504
|
+
setRowStatus(row, 'Done — this machine is set up with the account.');
|
|
505
|
+
if (input) input.value = '';
|
|
506
|
+
} else if (r.ok && r.json && r.json.outcome === 'submitted') {
|
|
507
|
+
setRowStatus(row, 'Code sent — finishing sign-in…');
|
|
508
|
+
if (input) input.value = '';
|
|
509
|
+
} else if (r.ok && r.json && r.json.outcome === 'held') {
|
|
510
|
+
setRowStatus(row, 'Signed in, but the account didn’t match what was approved — check with the operator.');
|
|
511
|
+
btn.removeAttribute('disabled');
|
|
512
|
+
} else {
|
|
513
|
+
const msg = (r.json && (r.json.error || r.json.reason)) ? (r.json.error || r.json.reason) : `failed (${r.status})`;
|
|
514
|
+
setRowStatus(row, `Couldn’t submit the code: ${msg}`);
|
|
515
|
+
btn.removeAttribute('disabled');
|
|
516
|
+
}
|
|
517
|
+
} catch (e) {
|
|
518
|
+
setRowStatus(row, 'Couldn’t reach the server — try again.');
|
|
519
|
+
btn.removeAttribute('disabled');
|
|
520
|
+
}
|
|
521
|
+
})();
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function setRowStatus(row, text) {
|
|
526
|
+
let s = row.querySelector('.sub-pending-status');
|
|
527
|
+
if (!s) { s = el(doc, 'div', 'sub-pending-status', ''); row.appendChild(s); }
|
|
528
|
+
s.textContent = text;
|
|
529
|
+
}
|
|
530
|
+
|
|
459
531
|
function reschedule() {
|
|
460
532
|
if (!state.active) return;
|
|
461
533
|
if (state.timerId != null) cancel(state.timerId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAy4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAy4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAi8etE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -9874,7 +9874,7 @@ export async function startServer(options) {
|
|
|
9874
9874
|
// a 2nd account never clobbers the 1st.
|
|
9875
9875
|
const { PendingLoginStore } = await import('../core/PendingLoginStore.js');
|
|
9876
9876
|
const { EnrollmentWizard } = await import('../core/EnrollmentWizard.js');
|
|
9877
|
-
const { FrameworkLoginDriver } = await import('../core/FrameworkLoginDriver.js');
|
|
9877
|
+
const { FrameworkLoginDriver, enrollPaneSessionName } = await import('../core/FrameworkLoginDriver.js');
|
|
9878
9878
|
const DEFAULT_ENROLL_LOGIN_COMMANDS = {
|
|
9879
9879
|
'claude-code': 'claude auth login',
|
|
9880
9880
|
'codex-cli': 'codex login',
|
|
@@ -9933,8 +9933,7 @@ export async function startServer(options) {
|
|
|
9933
9933
|
const cmd = configHome
|
|
9934
9934
|
? `env CLAUDE_CONFIG_DIR=${JSON.stringify(configHome)} ${baseCmd}`
|
|
9935
9935
|
: baseCmd;
|
|
9936
|
-
const
|
|
9937
|
-
const session = `instar-enroll-${framework}-${slug}`;
|
|
9936
|
+
const session = enrollPaneSessionName(framework, configHome);
|
|
9938
9937
|
try {
|
|
9939
9938
|
execFileSync(tmuxPath, ['kill-session', '-t', `=${session}`], { stdio: 'ignore' });
|
|
9940
9939
|
}
|