instar 1.3.1287 → 1.3.1288

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.
Files changed (86) hide show
  1. package/dashboard/subscriptions.js +10 -0
  2. package/dist/commands/server.d.ts.map +1 -1
  3. package/dist/commands/server.js +55 -18
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/core/CliLoginStatus.d.ts +38 -0
  6. package/dist/core/CliLoginStatus.d.ts.map +1 -0
  7. package/dist/core/CliLoginStatus.js +116 -0
  8. package/dist/core/CliLoginStatus.js.map +1 -0
  9. package/dist/core/PostUpdateMigrator.d.ts +8 -0
  10. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  11. package/dist/core/PostUpdateMigrator.js +45 -0
  12. package/dist/core/PostUpdateMigrator.js.map +1 -1
  13. package/dist/core/QuotaPoller.d.ts +42 -0
  14. package/dist/core/QuotaPoller.d.ts.map +1 -1
  15. package/dist/core/QuotaPoller.js +110 -11
  16. package/dist/core/QuotaPoller.js.map +1 -1
  17. package/dist/core/SessionManager.d.ts +13 -0
  18. package/dist/core/SessionManager.d.ts.map +1 -1
  19. package/dist/core/SessionManager.js +22 -6
  20. package/dist/core/SessionManager.js.map +1 -1
  21. package/dist/core/SubscriptionLoginLedger.d.ts +1 -1
  22. package/dist/core/SubscriptionLoginLedger.d.ts.map +1 -1
  23. package/dist/core/SubscriptionLoginLedger.js +3 -0
  24. package/dist/core/SubscriptionLoginLedger.js.map +1 -1
  25. package/dist/core/SubscriptionReloginHelper.d.ts +119 -0
  26. package/dist/core/SubscriptionReloginHelper.d.ts.map +1 -0
  27. package/dist/core/SubscriptionReloginHelper.js +329 -0
  28. package/dist/core/SubscriptionReloginHelper.js.map +1 -0
  29. package/dist/core/SubscriptionReloginOrchestrator.d.ts +25 -2
  30. package/dist/core/SubscriptionReloginOrchestrator.d.ts.map +1 -1
  31. package/dist/core/SubscriptionReloginOrchestrator.js +58 -3
  32. package/dist/core/SubscriptionReloginOrchestrator.js.map +1 -1
  33. package/dist/core/SubscriptionReloginPolicy.d.ts +1 -1
  34. package/dist/core/SubscriptionReloginPolicy.d.ts.map +1 -1
  35. package/dist/core/SubscriptionReloginPolicy.js +1 -0
  36. package/dist/core/SubscriptionReloginPolicy.js.map +1 -1
  37. package/dist/core/SubscriptionReloginRuntime.d.ts +74 -4
  38. package/dist/core/SubscriptionReloginRuntime.d.ts.map +1 -1
  39. package/dist/core/SubscriptionReloginRuntime.js +163 -7
  40. package/dist/core/SubscriptionReloginRuntime.js.map +1 -1
  41. package/dist/core/SubscriptionReloginService.d.ts +17 -0
  42. package/dist/core/SubscriptionReloginService.d.ts.map +1 -1
  43. package/dist/core/SubscriptionReloginService.js +54 -4
  44. package/dist/core/SubscriptionReloginService.js.map +1 -1
  45. package/dist/core/SubscriptionReloginStore.d.ts +22 -2
  46. package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
  47. package/dist/core/SubscriptionReloginStore.js +82 -2
  48. package/dist/core/SubscriptionReloginStore.js.map +1 -1
  49. package/dist/core/types.d.ts +6 -3
  50. package/dist/core/types.d.ts.map +1 -1
  51. package/dist/core/types.js.map +1 -1
  52. package/dist/data/builtinSkillContent.d.ts +1 -1
  53. package/dist/data/builtinSkillContent.d.ts.map +1 -1
  54. package/dist/data/builtinSkillContent.js +11 -0
  55. package/dist/data/builtinSkillContent.js.map +1 -1
  56. package/dist/data/standards-guard-index.json +1 -1
  57. package/dist/data/standards-guard-index.meta.json +2 -2
  58. package/dist/data/standards-registry.meta.json +1 -1
  59. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.d.ts +29 -0
  60. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.d.ts.map +1 -1
  61. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js +37 -9
  62. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js.map +1 -1
  63. package/dist/scaffold/templates.d.ts.map +1 -1
  64. package/dist/scaffold/templates.js +1 -0
  65. package/dist/scaffold/templates.js.map +1 -1
  66. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  67. package/dist/server/CapabilityIndex.js +3 -1
  68. package/dist/server/CapabilityIndex.js.map +1 -1
  69. package/dist/server/middleware.d.ts +2 -0
  70. package/dist/server/middleware.d.ts.map +1 -1
  71. package/dist/server/middleware.js +18 -0
  72. package/dist/server/middleware.js.map +1 -1
  73. package/dist/server/routes.d.ts +5 -0
  74. package/dist/server/routes.d.ts.map +1 -1
  75. package/dist/server/routes.js +58 -1
  76. package/dist/server/routes.js.map +1 -1
  77. package/package.json +1 -1
  78. package/src/data/builtin-manifest.json +64 -64
  79. package/src/data/builtinSkillContent.ts +11 -0
  80. package/src/data/standards-guard-index.json +1 -1
  81. package/src/data/standards-guard-index.meta.json +2 -2
  82. package/src/data/standards-registry.meta.json +1 -1
  83. package/src/scaffold/templates.ts +1 -0
  84. package/upgrades/1.3.1288.md +58 -0
  85. package/upgrades/side-effects/skill-driven-signin-repair.md +197 -0
  86. package/upgrades/1.3.1287.md +0 -21
@@ -980,6 +980,16 @@ export function renderAccountMatrix(doc, target, poolScope, pendingScope, transi
980
980
  button.setAttribute('data-episode-id', sanitizeForDisplay(repair.id, 'label'));
981
981
  td.appendChild(button);
982
982
  }
983
+ // While a repair waits on the operator (a phone tap, a macOS Allow, no helper account), the
984
+ // operator can also finish the sign-in themselves from here — the same one-tap Sign in flow
985
+ // as a needs-reauth cell (spec skill-driven-signin-repair, operator contact).
986
+ if (repair.state === 'waiting-operator-only') {
987
+ const signIn = el(doc, 'button', 'sub-matrix-setup', 'Sign in');
988
+ signIn.setAttribute('data-matrix-setup', '1');
989
+ signIn.setAttribute('data-account-id', sanitizeForDisplay(c.accountId, 'label'));
990
+ signIn.setAttribute('data-machine-id', sanitizeForDisplay(c.machineId, 'label'));
991
+ td.appendChild(signIn);
992
+ }
983
993
  } else if (c.state === 'empty' || c.state === 'needs-reauth' || c.state === 'held' || c.state === 'cant-resolve' || c.state === 'email-missing' || c.state === 'expired' || c.state === 'broken') {
984
994
  // An actionable cell → a button that runs the SAME in-dashboard sign-in flow (PIN → link →
985
995
  // paste code). empty → "Set up"; needs-reauth (an existing account whose login expired) →
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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"}
@@ -13442,12 +13442,21 @@ export async function startServer(options) {
13442
13442
  // pool is non-empty (started below); on-demand polling is always available
13443
13443
  // via POST /subscription-pool/poll.
13444
13444
  const { QuotaPoller } = await import('../core/QuotaPoller.js');
13445
- const { buildCodexLiveUsageReader } = await import('../providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js');
13445
+ const { buildCodexLiveUsageReader, buildCodexLiveUsageReaderDetailed } = await import('../providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js');
13446
+ // The Codex CLI's own login check (spec skill-driven-signin-repair), proven able to fail by
13447
+ // its canary before any "signed in" answer is trusted. Shared by the poller and the sign-in
13448
+ // repair's helper-seat pick.
13449
+ const { CodexLoginStatusChecker } = await import('../core/CliLoginStatus.js');
13450
+ const codexLoginStatusChecker = new CodexLoginStatusChecker();
13446
13451
  const quotaPoller = new QuotaPoller({
13447
13452
  pool: subscriptionPool,
13448
13453
  // Zero-spend live codex quota (app-server account/rateLimits/read). ON by
13449
13454
  // default; `subscriptionPool.codexLiveQuota: false` forces rollout-only.
13450
13455
  codexLiveUsageReader: buildCodexLiveUsageReader(config.subscriptionPool),
13456
+ // The same live read with its failure KIND kept: an app-server "authentication required"
13457
+ // refusal is told apart from a transport failure, and only a live read proves login.
13458
+ codexLiveUsageReaderDetailed: buildCodexLiveUsageReaderDetailed(config.subscriptionPool),
13459
+ codexLoginStatus: (codexHome) => codexLoginStatusChecker.check(codexHome),
13451
13460
  loginObservationSink: subscriptionLoginLedger
13452
13461
  ? (input) => subscriptionLoginLedger.recordObservation(input)
13453
13462
  : undefined,
@@ -13857,7 +13866,7 @@ export async function startServer(options) {
13857
13866
  const reloginCfg = config.subscriptionPool?.assistedRelogin;
13858
13867
  if (reloginCfg?.enabled === true && subscriptionLoginLedger && subscriptionPoolMachineId && sharedIntelligence) {
13859
13868
  try {
13860
- const [{ createSubscriptionReloginRuntime, resolveReloginNavigation, takeFirstBackupCode }, { PlaywrightProfileRegistry }, { SecretStore }, { secretKeyPaths }, { ClaudePasteBackController }, { createReloginBrowser }] = await Promise.all([
13869
+ const [{ createSubscriptionReloginRuntime, resolveReloginNavigation, takeFirstBackupCode, buildReloginHelperSessionPorts }, { PlaywrightProfileRegistry }, { SecretStore }, { secretKeyPaths }, { ClaudePasteBackController }, { createReloginBrowser }] = await Promise.all([
13861
13870
  import('../core/SubscriptionReloginRuntime.js'), import('../core/PlaywrightProfileRegistry.js'),
13862
13871
  import('../core/SecretStore.js'), import('../core/SecretSync.js'),
13863
13872
  import('../core/ClaudePasteBackController.js'), import('../core/PlainChromeReloginBrowser.js'),
@@ -13890,18 +13899,42 @@ export async function startServer(options) {
13890
13899
  });
13891
13900
  const notify = telegram ? async (episode, deliveryKey, kind) => {
13892
13901
  const doorway = episode.framework === 'codex-cli' ? 'Codex' : 'Claude Code';
13902
+ // The dashboard's Subscriptions tab, where the operator can finish from a phone.
13903
+ let subscriptionsLink = `http://localhost:${config.port}/dashboard?tab=subscriptions`;
13904
+ try {
13905
+ if (tunnel?.url)
13906
+ subscriptionsLink = `${tunnel.url}/dashboard?tab=subscriptions`;
13907
+ }
13908
+ catch { /* @silent-fallback-ok — tunnel URL is best-effort; the local link still names the tab */ }
13909
+ // A helper-reported macOS permission rides the reason token `agent-permission-<name>`.
13910
+ const permissionReason = episode.failureClass === 'automation-permission'
13911
+ ? (subscriptionReloginRuntime?.store.listEvents(episode.id, 5)
13912
+ .map((event) => event.reason ?? '').find((reason) => reason.startsWith('agent-permission-')) ?? null)
13913
+ : null;
13914
+ const permissionName = permissionReason === 'agent-permission-screen-recording' ? 'Screen Recording'
13915
+ : permissionReason === 'agent-permission-accessibility' ? 'Accessibility'
13916
+ : permissionReason === 'agent-permission-automation' ? 'Automation (control Google Chrome)' : null;
13893
13917
  const summary = kind === 'approval'
13894
- ? `A ${doorway} subscription sign-in needs repair. Open Subscriptions and tap Repair sign-in once.`
13895
- : kind === 'operator-only'
13896
- ? (episode.failureClass === 'automation-permission'
13897
- ? `${doorway} sign-in repair needs a one-time permission on this machine: allow the agent to control Google Chrome. On that machine, signed in as the Mac user the agent runs as, click Allow on the "control Google Chrome" prompt if one is showing, or turn it on in System Settings, Privacy & Security, Automation. Then open Subscriptions and tap Try repair again.`
13898
- : 'Automated sign-in paused at a provider security challenge. Open Subscriptions to continue.')
13899
- : episode.state === 'succeeded'
13900
- ? `${doorway} subscription sign-in was repaired and verified.`
13901
- : `${doorway} subscription repair ended in ${episode.state}. Open Subscriptions for the redacted audit.`;
13918
+ ? `A ${doorway} subscription sign-in needs repair. Open Subscriptions and tap Repair sign-in once: ${subscriptionsLink}`
13919
+ : kind === 'phone-tap'
13920
+ ? `${doorway} sign-in repair is waiting on your phone: tap "Yes, it's me" on the Google prompt now. The helper continues on its own after that.`
13921
+ : kind === 'operator-only'
13922
+ ? (episode.failureClass === 'no-healthy-seat'
13923
+ ? `${doorway} sign-in repair has no other healthy account on this machine to run its helper. Finish the sign-in from your phone: open ${subscriptionsLink} and tap Sign in on that account.`
13924
+ : episode.failureClass === 'automation-permission' && permissionName
13925
+ ? `${doorway} sign-in repair needs a one-time macOS permission on this machine: ${permissionName}. On that machine, click Allow if the prompt is showing, or turn it on in System Settings, Privacy & Security. Then open ${subscriptionsLink} and tap Try repair again, or tap Sign in to finish it yourself.`
13926
+ : episode.failureClass === 'automation-permission'
13927
+ ? `${doorway} sign-in repair needs a one-time permission on this machine: allow the agent to control Google Chrome. On that machine, signed in as the Mac user the agent runs as, click Allow on the "control Google Chrome" prompt if one is showing, or turn it on in System Settings, Privacy & Security, Automation. Then open Subscriptions and tap Try repair again: ${subscriptionsLink}`
13928
+ : `Automated sign-in paused and needs you. Open ${subscriptionsLink} to continue, or tap Sign in to finish it from your phone.`)
13929
+ : episode.failureClass === 'resolved-elsewhere'
13930
+ ? `${doorway} subscription is signed in again (verified), so its open sign-in repair was closed. Nothing to do.`
13931
+ : episode.state === 'succeeded'
13932
+ ? `${doorway} subscription sign-in was repaired and verified.`
13933
+ : `${doorway} subscription repair ended in ${episode.state}. Open ${subscriptionsLink} for the redacted audit, or tap Sign in to finish it from your phone.`;
13902
13934
  await telegram.createAttentionItem({ id: deliveryKey.replace(/:/g, '-'), title: `${doorway} sign-in repair`,
13903
13935
  summary, description: summary, category: 'subscription-relogin',
13904
- priority: kind === 'terminal' && episode.state === 'succeeded' ? 'NORMAL' : 'HIGH',
13936
+ priority: kind === 'phone-tap' ? 'URGENT'
13937
+ : kind === 'terminal' && (episode.state === 'succeeded' || episode.failureClass === 'resolved-elsewhere') ? 'NORMAL' : 'HIGH',
13905
13938
  sourceContext: 'assisted-subscription-relogin' });
13906
13939
  } : undefined;
13907
13940
  subscriptionReloginRuntime = createSubscriptionReloginRuntime({ stateDir: config.stateDir,
@@ -13940,7 +13973,13 @@ export async function startServer(options) {
13940
13973
  return action;
13941
13974
  },
13942
13975
  // Agent navigation (spec agent-driven-relogin): omitted ⇒ the development-agent gate.
13976
+ // `agent-session` (spec skill-driven-signin-repair) is macOS-only; omitted ⇒ agent-session
13977
+ // on a macOS development agent.
13943
13978
  navigation: resolveReloginNavigation(reloginCfg.navigation, config),
13979
+ // A Codex repair can only be proven by a LIVE app-server read (spec skill-driven-signin-repair).
13980
+ codexLiveReadAvailable: config.subscriptionPool?.codexLiveQuota !== false,
13981
+ helperSession: buildReloginHelperSessionPorts({ sessionManager, maxSessions: config.sessions.maxSessions,
13982
+ serverPort: config.port, codexLoginStatus: (codexHome) => codexLoginStatusChecker.check(codexHome) }),
13944
13983
  navigate: async (input) => {
13945
13984
  const prompt = [
13946
13985
  'You are signing an expired subscription account back in, in that account\'s own browser, the way a careful person would.',
@@ -13969,6 +14008,7 @@ export async function startServer(options) {
13969
14008
  onSuggested: notify ? (episode, key) => notify(episode, key, 'approval') : undefined,
13970
14009
  onOperatorOnly: notify ? (episode, key) => notify(episode, key, 'operator-only') : undefined,
13971
14010
  onTerminal: notify ? (episode, key) => notify(episode, key, 'terminal') : undefined,
14011
+ onPhoneTap: notify ? (episode, key) => notify(episode, key, 'phone-tap') : undefined,
13972
14012
  allowedScopes: reloginCfg.allowedScopes ?? [], tickMs: reloginCfg.tickMs,
13973
14013
  maxAttempts: reloginCfg.maxAttempts, retryBaseMs: reloginCfg.retryBaseMs,
13974
14014
  unattendedPolicy: reloginCfg.unattendedPolicy, });
@@ -26543,13 +26583,10 @@ export async function startServer(options) {
26543
26583
  });
26544
26584
  }
26545
26585
  server.setSubscriptionLoginLedger(subscriptionLoginLedger);
26546
- server.setSubscriptionRelogin(subscriptionReloginRuntime ? {
26547
- store: subscriptionReloginRuntime.store,
26548
- approve: (episodeId) => subscriptionReloginRuntime.service.approve(episodeId),
26549
- cancel: (episodeId) => subscriptionReloginRuntime.service.cancel(episodeId),
26550
- retry: (episodeId) => subscriptionReloginRuntime.service.retry(episodeId),
26551
- close: () => subscriptionReloginRuntime.close(),
26552
- } : null);
26586
+ {
26587
+ const { subscriptionReloginRouteContext } = await import('../core/SubscriptionReloginRuntime.js');
26588
+ server.setSubscriptionRelogin(subscriptionReloginRuntime ? subscriptionReloginRouteContext(subscriptionReloginRuntime) : null);
26589
+ }
26553
26590
  server.setWorkQueue(workQueue);
26554
26591
  if (_stateSyncStoresResolved?.classReview?.enabled && replicatedPeerStreamReader) {
26555
26592
  const { CLASS_REVIEW_STORE_KEY, classReviewFromOriginRecord } = await import('../core/ClassReviewReplicatedStore.js');