instar 1.3.1287 → 1.3.1289

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 (97) 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 +57 -18
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/core/AgentOwnedMemory.d.ts +90 -0
  6. package/dist/core/AgentOwnedMemory.d.ts.map +1 -0
  7. package/dist/core/AgentOwnedMemory.js +404 -0
  8. package/dist/core/AgentOwnedMemory.js.map +1 -0
  9. package/dist/core/CliLoginStatus.d.ts +38 -0
  10. package/dist/core/CliLoginStatus.d.ts.map +1 -0
  11. package/dist/core/CliLoginStatus.js +116 -0
  12. package/dist/core/CliLoginStatus.js.map +1 -0
  13. package/dist/core/EnrollmentWizard.d.ts +7 -0
  14. package/dist/core/EnrollmentWizard.d.ts.map +1 -1
  15. package/dist/core/EnrollmentWizard.js +14 -0
  16. package/dist/core/EnrollmentWizard.js.map +1 -1
  17. package/dist/core/PostUpdateMigrator.d.ts +16 -0
  18. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  19. package/dist/core/PostUpdateMigrator.js +72 -0
  20. package/dist/core/PostUpdateMigrator.js.map +1 -1
  21. package/dist/core/QuotaPoller.d.ts +42 -0
  22. package/dist/core/QuotaPoller.d.ts.map +1 -1
  23. package/dist/core/QuotaPoller.js +110 -11
  24. package/dist/core/QuotaPoller.js.map +1 -1
  25. package/dist/core/SessionManager.d.ts +21 -0
  26. package/dist/core/SessionManager.d.ts.map +1 -1
  27. package/dist/core/SessionManager.js +49 -6
  28. package/dist/core/SessionManager.js.map +1 -1
  29. package/dist/core/SubscriptionLoginLedger.d.ts +1 -1
  30. package/dist/core/SubscriptionLoginLedger.d.ts.map +1 -1
  31. package/dist/core/SubscriptionLoginLedger.js +3 -0
  32. package/dist/core/SubscriptionLoginLedger.js.map +1 -1
  33. package/dist/core/SubscriptionReloginHelper.d.ts +119 -0
  34. package/dist/core/SubscriptionReloginHelper.d.ts.map +1 -0
  35. package/dist/core/SubscriptionReloginHelper.js +329 -0
  36. package/dist/core/SubscriptionReloginHelper.js.map +1 -0
  37. package/dist/core/SubscriptionReloginOrchestrator.d.ts +25 -2
  38. package/dist/core/SubscriptionReloginOrchestrator.d.ts.map +1 -1
  39. package/dist/core/SubscriptionReloginOrchestrator.js +58 -3
  40. package/dist/core/SubscriptionReloginOrchestrator.js.map +1 -1
  41. package/dist/core/SubscriptionReloginPolicy.d.ts +1 -1
  42. package/dist/core/SubscriptionReloginPolicy.d.ts.map +1 -1
  43. package/dist/core/SubscriptionReloginPolicy.js +1 -0
  44. package/dist/core/SubscriptionReloginPolicy.js.map +1 -1
  45. package/dist/core/SubscriptionReloginRuntime.d.ts +74 -4
  46. package/dist/core/SubscriptionReloginRuntime.d.ts.map +1 -1
  47. package/dist/core/SubscriptionReloginRuntime.js +163 -7
  48. package/dist/core/SubscriptionReloginRuntime.js.map +1 -1
  49. package/dist/core/SubscriptionReloginService.d.ts +17 -0
  50. package/dist/core/SubscriptionReloginService.d.ts.map +1 -1
  51. package/dist/core/SubscriptionReloginService.js +54 -4
  52. package/dist/core/SubscriptionReloginService.js.map +1 -1
  53. package/dist/core/SubscriptionReloginStore.d.ts +22 -2
  54. package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
  55. package/dist/core/SubscriptionReloginStore.js +82 -2
  56. package/dist/core/SubscriptionReloginStore.js.map +1 -1
  57. package/dist/core/types.d.ts +6 -3
  58. package/dist/core/types.d.ts.map +1 -1
  59. package/dist/core/types.js.map +1 -1
  60. package/dist/data/builtinSkillContent.d.ts +1 -1
  61. package/dist/data/builtinSkillContent.d.ts.map +1 -1
  62. package/dist/data/builtinSkillContent.js +11 -0
  63. package/dist/data/builtinSkillContent.js.map +1 -1
  64. package/dist/data/standards-guard-index.json +1 -1
  65. package/dist/data/standards-guard-index.meta.json +2 -2
  66. package/dist/data/standards-registry.meta.json +1 -1
  67. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.d.ts +29 -0
  68. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.d.ts.map +1 -1
  69. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js +37 -9
  70. package/dist/providers/adapters/openai-codex/observability/codexLiveRateLimitReader.js.map +1 -1
  71. package/dist/scaffold/templates.d.ts.map +1 -1
  72. package/dist/scaffold/templates.js +3 -2
  73. package/dist/scaffold/templates.js.map +1 -1
  74. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  75. package/dist/server/CapabilityIndex.js +3 -1
  76. package/dist/server/CapabilityIndex.js.map +1 -1
  77. package/dist/server/middleware.d.ts +2 -0
  78. package/dist/server/middleware.d.ts.map +1 -1
  79. package/dist/server/middleware.js +18 -0
  80. package/dist/server/middleware.js.map +1 -1
  81. package/dist/server/routes.d.ts +5 -0
  82. package/dist/server/routes.d.ts.map +1 -1
  83. package/dist/server/routes.js +58 -1
  84. package/dist/server/routes.js.map +1 -1
  85. package/package.json +1 -1
  86. package/src/data/builtin-manifest.json +64 -64
  87. package/src/data/builtinSkillContent.ts +11 -0
  88. package/src/data/standards-guard-index.json +1 -1
  89. package/src/data/standards-guard-index.meta.json +2 -2
  90. package/src/data/standards-registry.meta.json +1 -1
  91. package/src/scaffold/templates.ts +3 -2
  92. package/upgrades/1.3.1288.md +58 -0
  93. package/upgrades/1.3.1289.md +39 -0
  94. package/upgrades/agent-owned-memory.eli16.md +15 -0
  95. package/upgrades/side-effects/agent-owned-memory.md +94 -0
  96. package/upgrades/side-effects/skill-driven-signin-repair.md +197 -0
  97. 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,
@@ -13518,6 +13527,8 @@ export async function startServer(options) {
13518
13527
  const pendingLoginStore = new PendingLoginStore({ stateDir: config.stateDir });
13519
13528
  const enrollmentWizard = new EnrollmentWizard({
13520
13529
  store: pendingLoginStore,
13530
+ // Agent-owned memory: a newly completed login links to this agent's memory at once.
13531
+ agentHome: config.projectDir,
13521
13532
  logger: { log: (m) => console.log(m), warn: (m) => console.warn(m) },
13522
13533
  // WS5.2 §5.3/S7 — the follow-me completion gate reads the minted login's account email
13523
13534
  // from its config-home slot and validates it against operator expectation before the
@@ -13857,7 +13868,7 @@ export async function startServer(options) {
13857
13868
  const reloginCfg = config.subscriptionPool?.assistedRelogin;
13858
13869
  if (reloginCfg?.enabled === true && subscriptionLoginLedger && subscriptionPoolMachineId && sharedIntelligence) {
13859
13870
  try {
13860
- const [{ createSubscriptionReloginRuntime, resolveReloginNavigation, takeFirstBackupCode }, { PlaywrightProfileRegistry }, { SecretStore }, { secretKeyPaths }, { ClaudePasteBackController }, { createReloginBrowser }] = await Promise.all([
13871
+ const [{ createSubscriptionReloginRuntime, resolveReloginNavigation, takeFirstBackupCode, buildReloginHelperSessionPorts }, { PlaywrightProfileRegistry }, { SecretStore }, { secretKeyPaths }, { ClaudePasteBackController }, { createReloginBrowser }] = await Promise.all([
13861
13872
  import('../core/SubscriptionReloginRuntime.js'), import('../core/PlaywrightProfileRegistry.js'),
13862
13873
  import('../core/SecretStore.js'), import('../core/SecretSync.js'),
13863
13874
  import('../core/ClaudePasteBackController.js'), import('../core/PlainChromeReloginBrowser.js'),
@@ -13890,18 +13901,42 @@ export async function startServer(options) {
13890
13901
  });
13891
13902
  const notify = telegram ? async (episode, deliveryKey, kind) => {
13892
13903
  const doorway = episode.framework === 'codex-cli' ? 'Codex' : 'Claude Code';
13904
+ // The dashboard's Subscriptions tab, where the operator can finish from a phone.
13905
+ let subscriptionsLink = `http://localhost:${config.port}/dashboard?tab=subscriptions`;
13906
+ try {
13907
+ if (tunnel?.url)
13908
+ subscriptionsLink = `${tunnel.url}/dashboard?tab=subscriptions`;
13909
+ }
13910
+ catch { /* @silent-fallback-ok — tunnel URL is best-effort; the local link still names the tab */ }
13911
+ // A helper-reported macOS permission rides the reason token `agent-permission-<name>`.
13912
+ const permissionReason = episode.failureClass === 'automation-permission'
13913
+ ? (subscriptionReloginRuntime?.store.listEvents(episode.id, 5)
13914
+ .map((event) => event.reason ?? '').find((reason) => reason.startsWith('agent-permission-')) ?? null)
13915
+ : null;
13916
+ const permissionName = permissionReason === 'agent-permission-screen-recording' ? 'Screen Recording'
13917
+ : permissionReason === 'agent-permission-accessibility' ? 'Accessibility'
13918
+ : permissionReason === 'agent-permission-automation' ? 'Automation (control Google Chrome)' : null;
13893
13919
  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.`;
13920
+ ? `A ${doorway} subscription sign-in needs repair. Open Subscriptions and tap Repair sign-in once: ${subscriptionsLink}`
13921
+ : kind === 'phone-tap'
13922
+ ? `${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.`
13923
+ : kind === 'operator-only'
13924
+ ? (episode.failureClass === 'no-healthy-seat'
13925
+ ? `${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.`
13926
+ : episode.failureClass === 'automation-permission' && permissionName
13927
+ ? `${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.`
13928
+ : episode.failureClass === 'automation-permission'
13929
+ ? `${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}`
13930
+ : `Automated sign-in paused and needs you. Open ${subscriptionsLink} to continue, or tap Sign in to finish it from your phone.`)
13931
+ : episode.failureClass === 'resolved-elsewhere'
13932
+ ? `${doorway} subscription is signed in again (verified), so its open sign-in repair was closed. Nothing to do.`
13933
+ : episode.state === 'succeeded'
13934
+ ? `${doorway} subscription sign-in was repaired and verified.`
13935
+ : `${doorway} subscription repair ended in ${episode.state}. Open ${subscriptionsLink} for the redacted audit, or tap Sign in to finish it from your phone.`;
13902
13936
  await telegram.createAttentionItem({ id: deliveryKey.replace(/:/g, '-'), title: `${doorway} sign-in repair`,
13903
13937
  summary, description: summary, category: 'subscription-relogin',
13904
- priority: kind === 'terminal' && episode.state === 'succeeded' ? 'NORMAL' : 'HIGH',
13938
+ priority: kind === 'phone-tap' ? 'URGENT'
13939
+ : kind === 'terminal' && (episode.state === 'succeeded' || episode.failureClass === 'resolved-elsewhere') ? 'NORMAL' : 'HIGH',
13905
13940
  sourceContext: 'assisted-subscription-relogin' });
13906
13941
  } : undefined;
13907
13942
  subscriptionReloginRuntime = createSubscriptionReloginRuntime({ stateDir: config.stateDir,
@@ -13940,7 +13975,13 @@ export async function startServer(options) {
13940
13975
  return action;
13941
13976
  },
13942
13977
  // Agent navigation (spec agent-driven-relogin): omitted ⇒ the development-agent gate.
13978
+ // `agent-session` (spec skill-driven-signin-repair) is macOS-only; omitted ⇒ agent-session
13979
+ // on a macOS development agent.
13943
13980
  navigation: resolveReloginNavigation(reloginCfg.navigation, config),
13981
+ // A Codex repair can only be proven by a LIVE app-server read (spec skill-driven-signin-repair).
13982
+ codexLiveReadAvailable: config.subscriptionPool?.codexLiveQuota !== false,
13983
+ helperSession: buildReloginHelperSessionPorts({ sessionManager, maxSessions: config.sessions.maxSessions,
13984
+ serverPort: config.port, codexLoginStatus: (codexHome) => codexLoginStatusChecker.check(codexHome) }),
13944
13985
  navigate: async (input) => {
13945
13986
  const prompt = [
13946
13987
  'You are signing an expired subscription account back in, in that account\'s own browser, the way a careful person would.',
@@ -13969,6 +14010,7 @@ export async function startServer(options) {
13969
14010
  onSuggested: notify ? (episode, key) => notify(episode, key, 'approval') : undefined,
13970
14011
  onOperatorOnly: notify ? (episode, key) => notify(episode, key, 'operator-only') : undefined,
13971
14012
  onTerminal: notify ? (episode, key) => notify(episode, key, 'terminal') : undefined,
14013
+ onPhoneTap: notify ? (episode, key) => notify(episode, key, 'phone-tap') : undefined,
13972
14014
  allowedScopes: reloginCfg.allowedScopes ?? [], tickMs: reloginCfg.tickMs,
13973
14015
  maxAttempts: reloginCfg.maxAttempts, retryBaseMs: reloginCfg.retryBaseMs,
13974
14016
  unattendedPolicy: reloginCfg.unattendedPolicy, });
@@ -26543,13 +26585,10 @@ export async function startServer(options) {
26543
26585
  });
26544
26586
  }
26545
26587
  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);
26588
+ {
26589
+ const { subscriptionReloginRouteContext } = await import('../core/SubscriptionReloginRuntime.js');
26590
+ server.setSubscriptionRelogin(subscriptionReloginRuntime ? subscriptionReloginRouteContext(subscriptionReloginRuntime) : null);
26591
+ }
26553
26592
  server.setWorkQueue(workQueue);
26554
26593
  if (_stateSyncStoresResolved?.classReview?.enabled && replicatedPeerStreamReader) {
26555
26594
  const { CLASS_REVIEW_STORE_KEY, classReviewFromOriginRecord } = await import('../core/ClassReviewReplicatedStore.js');