@skrr-ai/cli 0.1.82 → 0.1.83

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.
@@ -374,6 +374,10 @@ async function attemptDaemonBrokerLogin(opts) {
374
374
  const first = await attemptDaemonBrokerLoginOnce(opts);
375
375
  if (first.ok || !isRestartShapedFailure(first))
376
376
  return first;
377
+ // The guest descriptor is owned by the runtime supervisor, not this CLI's
378
+ // local daemon service. Waiting on a laptop launchd restart cannot repair it.
379
+ if (opts.bootstrapPathOverride === exports.DEDICATED_RUNTIME_CLI_HANDOFF_DESCRIPTOR)
380
+ return first;
377
381
  // The local service may be restarting: a graceful restart removes the
378
382
  // descriptor and republishes it only once the new daemon is listening
379
383
  // (measured ~14s), and a crash leaves it naming a dead pid until launchd
@@ -146,6 +146,8 @@ export interface AcquireManagedSessionInput {
146
146
  export interface AcquireManagedSessionDeps {
147
147
  prefetchAuth?: () => Promise<void>;
148
148
  hasCredential?: () => boolean;
149
+ /** null means this is not a standalone Dedicated guest invocation. */
150
+ borrowGuestCredential?: () => Promise<boolean | null>;
149
151
  /** `signal` is the acquisition-wide deadline; an override that ignores it is unbounded. */
150
152
  resolveAgent?: (ref?: string, signal?: AbortSignal) => Promise<FirstPartyHarnessAgent>;
151
153
  /** The user-JWT call. Defaults to `apiFetch`. */
@@ -75,6 +75,13 @@ const auth_core_init_1 = require("./auth-core-init");
75
75
  const config_1 = require("./config");
76
76
  const cli_id_1 = require("./cli-id");
77
77
  const cred_envelope_1 = require("./cred-envelope");
78
+ const dedicated_guest_1 = require("./dedicated-guest");
79
+ const daemonBroker_1 = require("./daemonBroker");
80
+ const daemonBrokerRefusal_1 = require("./daemonBrokerRefusal");
81
+ const cli_identity_1 = require("./cli-identity");
82
+ const credential_resolver_1 = require("./credential-resolver");
83
+ const harness_context_1 = require("./harness-context");
84
+ const node_adapter_1 = require("./node-adapter");
78
85
  const first_party_harness_1 = require("./first-party-harness");
79
86
  const first_party_harness_agent_1 = require("./first-party-harness-agent");
80
87
  const first_party_harness_managed_1 = require("./first-party-harness-managed");
@@ -162,6 +169,47 @@ class ManagedAcquisitionError extends Error {
162
169
  }
163
170
  }
164
171
  exports.ManagedAcquisitionError = ManagedAcquisitionError;
172
+ async function borrowDedicatedGuestCredential() {
173
+ if (!(0, dedicated_guest_1.runningOnDedicatedRuntimeGuest)() ||
174
+ (0, harness_context_1.isHarnessCliContext)() ||
175
+ (0, credential_resolver_1.resolveTrustedAutonomousCredential)()) {
176
+ return null;
177
+ }
178
+ // `skrr code run` does not extend BaseCommand, so its local credential check
179
+ // used to stop before the guest's daemon hand-off could be redeemed. Borrow
180
+ // only the fixed root-owned guest descriptor. No refresh family or credential
181
+ // is persisted, and apiFetch can re-redeem this DPoP-bound token on a 401.
182
+ try {
183
+ const cfg = (0, config_1.loadConfig)();
184
+ const outcome = await (0, daemonBroker_1.attemptDaemonBrokerLogin)({
185
+ cliId: (0, cli_identity_1.planLoginCliId)(cfg).cliId,
186
+ baseURL: cfg.baseURL,
187
+ bootstrapPathOverride: daemonBroker_1.DEDICATED_RUNTIME_CLI_HANDOFF_DESCRIPTOR,
188
+ preferHandoffMode: 'access_token',
189
+ borrowOnly: true,
190
+ timeoutMs: 10_000,
191
+ });
192
+ if (!outcome.ok) {
193
+ const description = (0, daemonBrokerRefusal_1.describeBrokerFailure)(outcome);
194
+ throw new ManagedAcquisitionError(outcome.code ?? 'guest-handoff-unavailable', description
195
+ ? `${description.headline} ${description.remedy}`
196
+ : `the Dedicated Runtime could not provide its managed skrr session (${outcome.reason})`);
197
+ }
198
+ if (!outcome.brokered)
199
+ return false;
200
+ (0, node_adapter_1.setAdapterCredentialOverride)({
201
+ token: outcome.accessToken,
202
+ source: 'env-token',
203
+ kind: (0, auth_core_1.classifyTokenKind)(outcome.accessToken),
204
+ });
205
+ return true;
206
+ }
207
+ catch (error) {
208
+ if (error instanceof ManagedAcquisitionError)
209
+ throw error;
210
+ return false;
211
+ }
212
+ }
165
213
  /**
166
214
  * Acquire a managed session, or throw a typed `ManagedAcquisitionError`.
167
215
  *
@@ -183,11 +231,28 @@ async function acquireManagedSession(input = {}, deps = {}) {
183
231
  // Checked locally, BEFORE any network. A fresh machine that has never run
184
232
  // `skrr login` must fall back to BYOK without a round trip and without a 401 that
185
233
  // would drag `apiFetch`'s refresh machinery in behind it.
186
- let localCredentialAvailable;
187
- if (deps.hasCredential) {
234
+ let localCredentialAvailable = false;
235
+ // Match BaseCommand's narrowly scoped retirement path: a stale guest refresh
236
+ // family must not prevent the live machine descriptor from lending a token.
237
+ const brokerBeforeStored = !deps.hasCredential &&
238
+ !(0, config_1.isEnvAuthOverride)() &&
239
+ !(0, harness_context_1.isHarnessCliContext)() &&
240
+ !(0, credential_resolver_1.resolveTrustedAutonomousCredential)() &&
241
+ (0, daemonBroker_1.shouldBrokerBeforeStoredCredential)();
242
+ if (brokerBeforeStored) {
243
+ try {
244
+ const guestHandoff = await (deps.borrowGuestCredential ?? borrowDedicatedGuestCredential)();
245
+ if (guestHandoff === true)
246
+ localCredentialAvailable = true;
247
+ }
248
+ catch {
249
+ // A usable stored credential remains the fallback during a hand-off outage.
250
+ }
251
+ }
252
+ if (!localCredentialAvailable && deps.hasCredential) {
188
253
  localCredentialAvailable = deps.hasCredential();
189
254
  }
190
- else {
255
+ else if (!localCredentialAvailable) {
191
256
  (0, cred_envelope_1.consumeEncryptedCredentialReadWhileInactive)();
192
257
  localCredentialAvailable = hasLocalCredential();
193
258
  if (!localCredentialAvailable && (0, cred_envelope_1.consumeEncryptedCredentialReadWhileInactive)()) {
@@ -195,6 +260,15 @@ async function acquireManagedSession(input = {}, deps = {}) {
195
260
  localCredentialAvailable = hasLocalCredential();
196
261
  }
197
262
  }
263
+ if (!localCredentialAvailable) {
264
+ const guestHandoff = await (deps.borrowGuestCredential ?? borrowDedicatedGuestCredential)();
265
+ if (guestHandoff === true) {
266
+ localCredentialAvailable = true;
267
+ }
268
+ else if (guestHandoff === false) {
269
+ throw new ManagedAcquisitionError('guest-handoff-unavailable', 'the Dedicated Runtime could not provide its managed skrr session');
270
+ }
271
+ }
198
272
  if (!localCredentialAvailable) {
199
273
  throw new ManagedAcquisitionError('not-signed-in', 'no skrr session on this machine — run `skrr login`');
200
274
  }