@skrr-ai/cli 0.1.80 → 0.1.81

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 (80) hide show
  1. package/dist/base-command.d.ts +4 -0
  2. package/dist/base-command.js +31 -2
  3. package/dist/commands/agents/visibility.d.ts +14 -0
  4. package/dist/commands/agents/visibility.js +52 -0
  5. package/dist/commands/create-token.d.ts +0 -1
  6. package/dist/commands/create-token.js +3 -1
  7. package/dist/commands/list-tokens.d.ts +0 -1
  8. package/dist/commands/list-tokens.js +1 -1
  9. package/dist/commands/machines/dedicated/ssh-proxy.js +1 -0
  10. package/dist/commands/revoke-token.d.ts +0 -1
  11. package/dist/commands/revoke-token.js +1 -1
  12. package/dist/commands/store/follow.d.ts +1 -0
  13. package/dist/commands/store/follow.js +7 -1
  14. package/dist/commands/store/follows/list.d.ts +11 -0
  15. package/dist/commands/store/follows/list.js +29 -0
  16. package/dist/commands/store/follows/remove.d.ts +16 -0
  17. package/dist/commands/store/follows/remove.js +37 -0
  18. package/dist/commands/store/publishers/profile/draft.d.ts +17 -0
  19. package/dist/commands/store/publishers/profile/draft.js +54 -0
  20. package/dist/commands/store/publishers/profile/handle.d.ts +14 -0
  21. package/dist/commands/store/publishers/profile/handle.js +39 -0
  22. package/dist/commands/store/publishers/profile/hide.d.ts +12 -0
  23. package/dist/commands/store/publishers/profile/hide.js +39 -0
  24. package/dist/commands/store/publishers/profile/preview.d.ts +11 -0
  25. package/dist/commands/store/publishers/profile/preview.js +39 -0
  26. package/dist/commands/store/publishers/profile/publish.d.ts +12 -0
  27. package/dist/commands/store/publishers/profile/publish.js +41 -0
  28. package/dist/commands/store/publishers/profile/restore.d.ts +15 -0
  29. package/dist/commands/store/publishers/profile/restore.js +49 -0
  30. package/dist/commands/store/publishers/profile/revisions.d.ts +11 -0
  31. package/dist/commands/store/publishers/profile/revisions.js +30 -0
  32. package/dist/commands/store/publishers/profile/show.d.ts +11 -0
  33. package/dist/commands/store/publishers/profile/show.js +39 -0
  34. package/dist/commands/store/review.d.ts +26 -0
  35. package/dist/commands/store/review.js +93 -0
  36. package/dist/commands/store/reviews.d.ts +29 -0
  37. package/dist/commands/store/reviews.js +170 -0
  38. package/dist/commands/store/tip.d.ts +20 -0
  39. package/dist/commands/store/tip.js +57 -0
  40. package/dist/commands/tokens/create.d.ts +28 -0
  41. package/dist/commands/tokens/create.js +136 -0
  42. package/dist/commands/tokens/list.d.ts +11 -0
  43. package/dist/commands/tokens/list.js +53 -0
  44. package/dist/commands/tokens/revoke.d.ts +14 -0
  45. package/dist/commands/tokens/revoke.js +42 -0
  46. package/dist/lib/access-tokens.d.ts +59 -0
  47. package/dist/lib/access-tokens.js +50 -0
  48. package/dist/lib/auth-core-init.d.ts +6 -0
  49. package/dist/lib/auth-core-init.js +28 -6
  50. package/dist/lib/credential-resolver.d.ts +1 -1
  51. package/dist/lib/credential-resolver.js +8 -2
  52. package/dist/lib/daemonBroker.d.ts +13 -2
  53. package/dist/lib/daemonBroker.js +6 -4
  54. package/dist/lib/dedicated-ssh.d.ts +9 -0
  55. package/dist/lib/dedicated-ssh.js +232 -63
  56. package/dist/lib/node-adapter.js +2 -2
  57. package/dist/lib/publisher-profile-flags.d.ts +19 -0
  58. package/dist/lib/publisher-profile-flags.js +48 -0
  59. package/dist/lib/refresh.d.ts +1 -1
  60. package/dist/lib/refresh.js +6 -1
  61. package/dist/lib/ssh-ordered-bytes.d.ts +8 -0
  62. package/dist/lib/ssh-ordered-bytes.js +31 -0
  63. package/dist/lib/usd-micros.d.ts +9 -0
  64. package/dist/lib/usd-micros.js +21 -0
  65. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.d.ts +22 -3
  66. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.js +29 -5
  67. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +7 -1
  68. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +7 -1
  69. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
  70. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +7 -5
  71. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.d.ts +22 -3
  72. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.js +27 -4
  73. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +7 -1
  74. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +7 -1
  75. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
  76. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
  77. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  78. package/dist/node_modules/@skrr-ai/data-provider/index.js +3857 -3859
  79. package/oclif.manifest.json +38008 -36666
  80. package/package.json +28 -4
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CredentialResolver = exports.AuthHelperUntrustedError = exports.AuthHelperUnavailableError = exports.CI_TOKEN_PREFIX = exports.CREDENTIAL_PRECEDENCE = void 0;
3
+ exports.CredentialResolver = exports.AuthHelperUntrustedError = exports.AuthHelperUnavailableError = exports.PERSONAL_ACCESS_TOKEN_PREFIX = exports.CI_TOKEN_PREFIX = exports.CREDENTIAL_PRECEDENCE = void 0;
4
+ exports.isStaticTokenKind = isStaticTokenKind;
4
5
  exports.classifyTokenKind = classifyTokenKind;
5
6
  exports.__resetCredentialResolverForTest = __resetCredentialResolverForTest;
6
7
  exports.invalidateAuthHelperCache = invalidateAuthHelperCache;
@@ -19,8 +20,11 @@ exports.invalidateAuthHelperCache = invalidateAuthHelperCache;
19
20
  * Precedence (high → low):
20
21
  *
21
22
  * 1. flag — `--token <jwt>` CLI flag (debugging)
22
- * 2. env-token — `OVERSKY_TOKEN` env (CI / static; Phase I adds
23
- * server-side scope=ci validation)
23
+ * 2. env-token — `OVERSKY_TOKEN` (CI / static). The CLI also reads
24
+ * `SKRR_TOKEN` via `envTokenNames`; `OVERSKY_TOKEN` wins
25
+ * when both are set, matching the CLI config overlay. A
26
+ * personal access token (`osk_pat_*`) is the credential
27
+ * CI should put here.
24
28
  * 3. auth-helper — `OVERSKY_AUTH_HELPER` script output (rotating
25
29
  * creds — Vault, AWS SM, internal SSO proxy)
26
30
  * 4. fd-handoff — `OVERSKY_AUTH_FD` parent→child IPC (Electron
@@ -68,6 +72,16 @@ exports.CREDENTIAL_PRECEDENCE = [
68
72
  ];
69
73
  /** CI-token plaintext prefix; mirrors api/server/services/Auth/daemonCiTokens.js. */
70
74
  exports.CI_TOKEN_PREFIX = 'osk_ci_';
75
+ /** Personal-access-token prefix; mirrors api/server/services/Auth/personalAccessTokens.js. */
76
+ exports.PERSONAL_ACCESS_TOKEN_PREFIX = 'osk_pat_';
77
+ /**
78
+ * True for a kind whose token is static by construction: never refreshed,
79
+ * never rotated into a store. Like `TokenKind` itself this selects a local
80
+ * code path and grants nothing.
81
+ */
82
+ function isStaticTokenKind(kind) {
83
+ return kind === 'ci' || kind === 'pat';
84
+ }
71
85
  /**
72
86
  * Classify a token by local shape. Pure function; safe to call on any string
73
87
  * (including `null`-coerced empty). Returns `'standard'` for empty input
@@ -103,6 +117,8 @@ function classifyTokenKind(token) {
103
117
  return 'standard';
104
118
  if (token.startsWith(exports.CI_TOKEN_PREFIX))
105
119
  return 'ci';
120
+ if (token.startsWith(exports.PERSONAL_ACCESS_TOKEN_PREFIX))
121
+ return 'pat';
106
122
  const payload = (0, jwtUtils_js_1.decodeJwtPayload)(token);
107
123
  if (payload &&
108
124
  typeof payload === 'object' &&
@@ -260,8 +276,16 @@ class CredentialResolver {
260
276
  if (typeof this.opts.envTokenOverride === 'string') {
261
277
  return this.opts.envTokenOverride.length > 0 ? this.opts.envTokenOverride : null;
262
278
  }
263
- const v = process.env.OVERSKY_TOKEN;
264
- return typeof v === 'string' && v.length > 0 ? v : null;
279
+ // `OVERSKY_TOKEN` first (retained by decision, docs/product/skrr-env-inventory.md),
280
+ // then any renamed spelling the caller opted into (`SKRR_TOKEN` for the CLI,
281
+ // OSK-13208). The daemon does not opt in: a CI job that sets `SKRR_TOKEN`
282
+ // for `skrr` must not have a co-located `skrrd` silently adopt it.
283
+ for (const name of this.opts.envTokenNames ?? ['OVERSKY_TOKEN']) {
284
+ const v = process.env[name];
285
+ if (typeof v === 'string' && v.length > 0)
286
+ return v;
287
+ }
288
+ return null;
265
289
  }
266
290
  async tryResolveAuthHelper() {
267
291
  let helperPath;
@@ -38,7 +38,13 @@ export declare function describeDeviceKeySplit(profile: string): {
38
38
  * Order:
39
39
  * 1. Try to load existing keypair from disk.
40
40
  * - Success → state = active.
41
- * - Missing files / corruption / decrypt failure → step 2.
41
+ * - No key material at all (first install) → step 2.
42
+ * - Key material present but unloadable (corruption, decrypt failure,
43
+ * public/private mismatch) → disabled+unreadable_key and a
44
+ * `recovery_required` event, UNLESS `recoverUnreadable` is set. Only
45
+ * an explicit interactive login sets it, because that login proves and
46
+ * re-pins the new key; replacing it on ordinary boot would sign the
47
+ * next refresh with a key the server never pinned.
42
48
  * 2. Generate fresh keypair and persist. Failure to persist is a hard
43
49
  * error landing in disabled+persist_failed.
44
50
  */
@@ -355,7 +355,13 @@ async function consolidateDeviceIdentity(profile) {
355
355
  * Order:
356
356
  * 1. Try to load existing keypair from disk.
357
357
  * - Success → state = active.
358
- * - Missing files / corruption / decrypt failure → step 2.
358
+ * - No key material at all (first install) → step 2.
359
+ * - Key material present but unloadable (corruption, decrypt failure,
360
+ * public/private mismatch) → disabled+unreadable_key and a
361
+ * `recovery_required` event, UNLESS `recoverUnreadable` is set. Only
362
+ * an explicit interactive login sets it, because that login proves and
363
+ * re-pins the new key; replacing it on ordinary boot would sign the
364
+ * next refresh with a key the server never pinned.
359
365
  * 2. Generate fresh keypair and persist. Failure to persist is a hard
360
366
  * error landing in disabled+persist_failed.
361
367
  */
@@ -16,7 +16,7 @@ export { classifyRefreshResponse, type RefreshResponseShape, type ClassifiedRefr
16
16
  export { refreshDaemonToken, revokeDaemonRefreshSession, withAuthLock, persistReauthState, needsReauthState, clearReauthState, installLockExitHandlers, __refreshDiagnostics, __resetUnknown401StreaksForTest, UNKNOWN_401_BUDGET, } from './refresh.js';
17
17
  export { createRefreshScheduler, type RefreshScheduler, type RefreshSchedulerOptions, } from './refreshScheduler.js';
18
18
  export { readAuthFromFd, __setFdReaderForTest, type FdAuthPayload } from './fdToken.js';
19
- export { CredentialResolver, CREDENTIAL_PRECEDENCE, __resetCredentialResolverForTest, invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX, AuthHelperUntrustedError, AuthHelperUnavailableError, type CredentialSource, type CredentialStoreMode, type CredentialResolverOptions, type ResolvedCredential, type TokenKind, type HelperTrustDecision, type AuthHelperBlockedInfo, type AuthHelperSentinelInfo, } from './credentialResolver.js';
19
+ export { CredentialResolver, CREDENTIAL_PRECEDENCE, __resetCredentialResolverForTest, invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX, PERSONAL_ACCESS_TOKEN_PREFIX, isStaticTokenKind, AuthHelperUntrustedError, AuthHelperUnavailableError, type CredentialSource, type CredentialStoreMode, type CredentialResolverOptions, type ResolvedCredential, type TokenKind, type HelperTrustDecision, type AuthHelperBlockedInfo, type AuthHelperSentinelInfo, } from './credentialResolver.js';
20
20
  export { invokeAuthHelper, getDefaultHelperTtlMs, getLastAuthHelperFailureReason, __resetAuthHelperFailureReasonForTest, SENTINEL_TRIGGERING_FAILURES, type HelperResult, type InvokeAuthHelperOptions, type AuthHelperFailureReason, } from './authHelper.js';
21
21
  export { runHeadersHelper, invalidateHeadersHelperCache, type RunHeadersHelperOptions, } from './headers-helper.js';
22
22
  export { generateVerifier, challenge, generateState, safeEqual, verifyChallenge, type PkceChallengeMethod, } from './pkce.js';
@@ -22,11 +22,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
22
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.generateVerifier = exports.invalidateHeadersHelperCache = exports.runHeadersHelper = exports.SENTINEL_TRIGGERING_FAILURES = exports.__resetAuthHelperFailureReasonForTest = exports.getLastAuthHelperFailureReason = exports.getDefaultHelperTtlMs = exports.invokeAuthHelper = exports.AuthHelperUnavailableError = exports.AuthHelperUntrustedError = exports.CI_TOKEN_PREFIX = exports.classifyTokenKind = exports.invalidateAuthHelperCache = exports.__resetCredentialResolverForTest = exports.CREDENTIAL_PRECEDENCE = exports.CredentialResolver = exports.__setFdReaderForTest = exports.readAuthFromFd = exports.createRefreshScheduler = exports.UNKNOWN_401_BUDGET = exports.__resetUnknown401StreaksForTest = exports.__refreshDiagnostics = exports.installLockExitHandlers = exports.clearReauthState = exports.needsReauthState = exports.persistReauthState = exports.withAuthLock = exports.revokeDaemonRefreshSession = exports.refreshDaemonToken = exports.classifyRefreshResponse = exports.EXIT_NEEDS_REAUTH = exports.reauthCommand = exports.formatReauthMessage = exports.handleMidStreamAuthExpiry = exports.isAuthExpiredSseEvent = exports.decodeJwtPayload = exports.decodeJwtExpiry = exports.TransientAuthFailure = exports.PermanentAuthFailure = exports.emitAuthTelemetry = exports.getAuthBinaryName = exports.getAuthKillSwitches = exports.getAuthConfigDir = exports.getAuthLogger = exports.configureAuthCore = exports.OAUTH_CLI_SCOPE = exports.isDaemonScope = exports.VALID_DAEMON_SCOPE_SET = exports.ALL_DAEMON_SCOPES = exports.SCOPES = void 0;
26
- exports.publicJwkFromX = exports.normalizeHtu = exports.jwkThumbprint = exports.generateDeviceKeyPair = exports.buildDeviceProof = exports.zeroizeKekCaches = exports.WindowsKek = exports.registerZeroizeHook = exports.MacosKek = exports.LinuxKek = exports.KekUnavailableError = exports.UnavailableKek = exports.InMemoryKek = exports.getKekStrategy = exports.__setKekStrategyForTest = exports.credEnvelopeWrap = exports.credEnvelopeUnwrap = exports.credEnvelopeSerialize = exports.credSealBuffer = exports.credOpenBuffer = exports.CRED_KEY_LEN = exports.isCredEnvelopeString = exports.generateDek = exports.CRED_ENVELOPE_MAGIC = exports.credEnvelopeEncrypt = exports.credEnvelopeDeserialize = exports.credEnvelopeDecrypt = exports.buildCredentialAad = exports.isValidRecoveryCode = exports.normalizeRecoveryCode = exports.parseRecoveryCode = exports.formatRecoveryCode = exports.MAX_TTL_DAYS = exports.MIN_TTL_DAYS = exports.parseTtlDays = exports.LoginExchangeError = exports.LoginInitError = exports.loginWithLocalhost = exports.LocalCallbackMalformedError = exports.LocalCallbackDeniedError = exports.LocalCallbackStateMismatchError = exports.LocalCallbackTimeoutError = exports.LocalCallbackBindError = exports.LocalCallbackError = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.startLocalCallback = exports.verifyChallenge = exports.safeEqual = exports.generateState = exports.challenge = void 0;
27
- exports.__resetCachedDaemonIdForTest = exports.legacyDaemonUuids = exports.ensureMachineDaemonId = exports.__resetMachineUuidCacheForTest = exports.HOSTED_RUNTIME_MACHINE_SOURCES = exports.hostedRuntimeIdOverride = exports.getMachineUuid = exports.__getDeviceIdentityStateForTest = exports.__setDeviceIdentityStateForTest = exports.__enrollmentBackoffPathForTest = exports.__enrollmentMarkerPathForTest = exports.__privateKeyPathForTest = exports.__publicKeyPathForTest = exports.describeDeviceKeySplit = exports.describeDeviceIdentityState = exports.getDevicePublicKey = exports.isDeviceIdentityActive = exports.clearEnrollmentMarker = exports.enrollWithServer = exports.signServerRequest = exports.resetDeviceIdentity = exports.initDeviceIdentity = exports.__resetShutdownGuardForTest = exports.__getCredEnvelopeStateForTest = exports.__setCredEnvelopeStateForTest = exports.__wrappedDekFilePathForTest = exports.DEFAULT_UNREADABLE_CREDENTIAL_HINT = exports.maybeDecryptOnRead = exports.maybeEncryptForWrite = exports.splitKeyConvergencePolicy = exports.describeCredEnvelopeState = exports.hasCredEnvelopePathConflict = exports.isCredEnvelopeActive = exports.shutdownCredEnvelope = exports.resetCredEnvelope = exports.initCredEnvelope = exports.verifyDpopProof = exports.normalizeDpopHtu = exports.isJwkThumbprint = exports.isAth = exports.createDpopKey = exports.accessTokenHash = exports.DPOP_PROOF_VERIFY_UNAVAILABLE = exports.DPOP_PROOF_TYP = exports.DPOP_PROOF_REQUIRED = exports.DPOP_PROOF_INVALID = exports.DPOP_MAX_AGE_SECONDS = exports.DPOP_HEADER = exports.verifyDeviceProof = exports.tokenHash = void 0;
28
- exports.FIRST_PARTY_HARNESS_PROVENANCE_SUFFIX = exports.FIRST_PARTY_HARNESS_PREVIOUS_SUFFIX = exports.describeLegacyState = exports.findLegacyLocalState = exports.DEFAULT_BINARY_NAME = exports.LEGACY_NATIVE_ID_PREFIXES = exports.NATIVE_ID_PREFIX = exports.LEGACY_CONFIG_DIR_NAMES = exports.CONFIG_DIR_NAME = exports.LOOPBACK_DEFAULT_MAX_BODY_BYTES = exports.LoopbackTargetRefusedError = exports.isLoopbackAddress = exports.isLoopbackHostname = exports.assertLoopbackHttpUrl = exports.loopbackFetch = exports.withLoopbackNoProxy = exports.envHasProxy = exports.LOOPBACK_NO_PROXY_HOSTS = exports.SENSITIVE_ENV_PREFIX_EXCEPTIONS = exports.SENSITIVE_ENV_NAME_TOKENS = exports.SENSITIVE_ENV_SUFFIXES = exports.SENSITIVE_ENV_PREFIXES = exports.SENSITIVE_ENV_VARS = exports.sanitizeSpawnEnv = exports.harnessLoadsClaudeSkillsLayout = exports.claudeSkillsLayoutEvidence = exports.HARNESSES_LOADING_CLAUDE_SKILLS_LAYOUT = exports.tierPermitsConfiguredAutoMode = exports.credentialPolicyForTier = exports.getHarnessTier = exports.HARNESS_TIERS = exports.pairUint8ArrayToBase64Url = exports.pairUint8ArrayToBase64 = exports.parsePairUrl = exports.parsePairPlaintext = exports.parsePairBundle = exports.openPairBundleBase64 = exports.generatePairKeyPair = exports.buildPairUrl = exports.buildPairAad = exports.pairBase64UrlToUint8Array = exports.pairBase64ToUint8Array = exports.assemblePairBundleBase64 = exports.PairBundleError = exports.PAIR_SECRET_LEN = exports.PAIR_PUBKEY_LEN = exports.PAIR_NONCE_LEN = exports.PAIR_BUNDLE_MAX_BASE64_LEN = exports.PAIR_AAD_MAX_LEN = exports.PAIR_AAD_PREFIX = void 0;
29
- exports.consolidateProfileState = exports.profileStateFilePathsToClear = exports.profileStateFileLocations = exports.resolveProfileStateFile = exports.resolveProfileStateDir = exports.legacyProfileStateDir = exports.profileStateDir = exports.SUPERSEDED_COPY_SUFFIX = exports.SUPERSEDED_MARKER_SUFFIX = exports.PROFILES_SEGMENT = exports.isConfigRootOverridden = exports.configRootPath = exports.resolveConfigRoot = exports.verifyManifest = exports.verifyArtifact = exports.isTrustedArtifactOrigin = exports.getDeltaFor = exports.buildManifestMessage = exports.buildArtifactMessage = exports.TRUSTED_FEED_ORIGINS = exports.MAX_SIGS = exports.OVERSKY_RELEASE_PUBLIC_KEYS = exports.resolveFirstPartyHarnessChannel = exports.resolveChannelManifestUrl = exports.isFirstPartyHarnessChannel = exports.firstPartyHarnessFeedCandidates = exports.firstPartyHarnessFeedBase = exports.firstPartyHarnessChannelPrefix = exports.FIRST_PARTY_HARNESS_CHANNELS = exports.DEFAULT_FIRST_PARTY_HARNESS_CHANNEL = exports.migrateFirstPartyHarnessHome = exports.linkFirstPartyHarnessAliases = exports.firstPartyHarnessInstalledBinaryPath = exports.firstPartyHarnessHomeDir = exports.firstPartyHarnessBinDir = void 0;
25
+ exports.runHeadersHelper = exports.SENTINEL_TRIGGERING_FAILURES = exports.__resetAuthHelperFailureReasonForTest = exports.getLastAuthHelperFailureReason = exports.getDefaultHelperTtlMs = exports.invokeAuthHelper = exports.AuthHelperUnavailableError = exports.AuthHelperUntrustedError = exports.isStaticTokenKind = exports.PERSONAL_ACCESS_TOKEN_PREFIX = exports.CI_TOKEN_PREFIX = exports.classifyTokenKind = exports.invalidateAuthHelperCache = exports.__resetCredentialResolverForTest = exports.CREDENTIAL_PRECEDENCE = exports.CredentialResolver = exports.__setFdReaderForTest = exports.readAuthFromFd = exports.createRefreshScheduler = exports.UNKNOWN_401_BUDGET = exports.__resetUnknown401StreaksForTest = exports.__refreshDiagnostics = exports.installLockExitHandlers = exports.clearReauthState = exports.needsReauthState = exports.persistReauthState = exports.withAuthLock = exports.revokeDaemonRefreshSession = exports.refreshDaemonToken = exports.classifyRefreshResponse = exports.EXIT_NEEDS_REAUTH = exports.reauthCommand = exports.formatReauthMessage = exports.handleMidStreamAuthExpiry = exports.isAuthExpiredSseEvent = exports.decodeJwtPayload = exports.decodeJwtExpiry = exports.TransientAuthFailure = exports.PermanentAuthFailure = exports.emitAuthTelemetry = exports.getAuthBinaryName = exports.getAuthKillSwitches = exports.getAuthConfigDir = exports.getAuthLogger = exports.configureAuthCore = exports.OAUTH_CLI_SCOPE = exports.isDaemonScope = exports.VALID_DAEMON_SCOPE_SET = exports.ALL_DAEMON_SCOPES = exports.SCOPES = void 0;
26
+ exports.jwkThumbprint = exports.generateDeviceKeyPair = exports.buildDeviceProof = exports.zeroizeKekCaches = exports.WindowsKek = exports.registerZeroizeHook = exports.MacosKek = exports.LinuxKek = exports.KekUnavailableError = exports.UnavailableKek = exports.InMemoryKek = exports.getKekStrategy = exports.__setKekStrategyForTest = exports.credEnvelopeWrap = exports.credEnvelopeUnwrap = exports.credEnvelopeSerialize = exports.credSealBuffer = exports.credOpenBuffer = exports.CRED_KEY_LEN = exports.isCredEnvelopeString = exports.generateDek = exports.CRED_ENVELOPE_MAGIC = exports.credEnvelopeEncrypt = exports.credEnvelopeDeserialize = exports.credEnvelopeDecrypt = exports.buildCredentialAad = exports.isValidRecoveryCode = exports.normalizeRecoveryCode = exports.parseRecoveryCode = exports.formatRecoveryCode = exports.MAX_TTL_DAYS = exports.MIN_TTL_DAYS = exports.parseTtlDays = exports.LoginExchangeError = exports.LoginInitError = exports.loginWithLocalhost = exports.LocalCallbackMalformedError = exports.LocalCallbackDeniedError = exports.LocalCallbackStateMismatchError = exports.LocalCallbackTimeoutError = exports.LocalCallbackBindError = exports.LocalCallbackError = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.startLocalCallback = exports.verifyChallenge = exports.safeEqual = exports.generateState = exports.challenge = exports.generateVerifier = exports.invalidateHeadersHelperCache = void 0;
27
+ exports.ensureMachineDaemonId = exports.__resetMachineUuidCacheForTest = exports.HOSTED_RUNTIME_MACHINE_SOURCES = exports.hostedRuntimeIdOverride = exports.getMachineUuid = exports.__getDeviceIdentityStateForTest = exports.__setDeviceIdentityStateForTest = exports.__enrollmentBackoffPathForTest = exports.__enrollmentMarkerPathForTest = exports.__privateKeyPathForTest = exports.__publicKeyPathForTest = exports.describeDeviceKeySplit = exports.describeDeviceIdentityState = exports.getDevicePublicKey = exports.isDeviceIdentityActive = exports.clearEnrollmentMarker = exports.enrollWithServer = exports.signServerRequest = exports.resetDeviceIdentity = exports.initDeviceIdentity = exports.__resetShutdownGuardForTest = exports.__getCredEnvelopeStateForTest = exports.__setCredEnvelopeStateForTest = exports.__wrappedDekFilePathForTest = exports.DEFAULT_UNREADABLE_CREDENTIAL_HINT = exports.maybeDecryptOnRead = exports.maybeEncryptForWrite = exports.splitKeyConvergencePolicy = exports.describeCredEnvelopeState = exports.hasCredEnvelopePathConflict = exports.isCredEnvelopeActive = exports.shutdownCredEnvelope = exports.resetCredEnvelope = exports.initCredEnvelope = exports.verifyDpopProof = exports.normalizeDpopHtu = exports.isJwkThumbprint = exports.isAth = exports.createDpopKey = exports.accessTokenHash = exports.DPOP_PROOF_VERIFY_UNAVAILABLE = exports.DPOP_PROOF_TYP = exports.DPOP_PROOF_REQUIRED = exports.DPOP_PROOF_INVALID = exports.DPOP_MAX_AGE_SECONDS = exports.DPOP_HEADER = exports.verifyDeviceProof = exports.tokenHash = exports.publicJwkFromX = exports.normalizeHtu = void 0;
28
+ exports.describeLegacyState = exports.findLegacyLocalState = exports.DEFAULT_BINARY_NAME = exports.LEGACY_NATIVE_ID_PREFIXES = exports.NATIVE_ID_PREFIX = exports.LEGACY_CONFIG_DIR_NAMES = exports.CONFIG_DIR_NAME = exports.LOOPBACK_DEFAULT_MAX_BODY_BYTES = exports.LoopbackTargetRefusedError = exports.isLoopbackAddress = exports.isLoopbackHostname = exports.assertLoopbackHttpUrl = exports.loopbackFetch = exports.withLoopbackNoProxy = exports.envHasProxy = exports.LOOPBACK_NO_PROXY_HOSTS = exports.SENSITIVE_ENV_PREFIX_EXCEPTIONS = exports.SENSITIVE_ENV_NAME_TOKENS = exports.SENSITIVE_ENV_SUFFIXES = exports.SENSITIVE_ENV_PREFIXES = exports.SENSITIVE_ENV_VARS = exports.sanitizeSpawnEnv = exports.harnessLoadsClaudeSkillsLayout = exports.claudeSkillsLayoutEvidence = exports.HARNESSES_LOADING_CLAUDE_SKILLS_LAYOUT = exports.tierPermitsConfiguredAutoMode = exports.credentialPolicyForTier = exports.getHarnessTier = exports.HARNESS_TIERS = exports.pairUint8ArrayToBase64Url = exports.pairUint8ArrayToBase64 = exports.parsePairUrl = exports.parsePairPlaintext = exports.parsePairBundle = exports.openPairBundleBase64 = exports.generatePairKeyPair = exports.buildPairUrl = exports.buildPairAad = exports.pairBase64UrlToUint8Array = exports.pairBase64ToUint8Array = exports.assemblePairBundleBase64 = exports.PairBundleError = exports.PAIR_SECRET_LEN = exports.PAIR_PUBKEY_LEN = exports.PAIR_NONCE_LEN = exports.PAIR_BUNDLE_MAX_BASE64_LEN = exports.PAIR_AAD_MAX_LEN = exports.PAIR_AAD_PREFIX = exports.__resetCachedDaemonIdForTest = exports.legacyDaemonUuids = void 0;
29
+ exports.consolidateProfileState = exports.profileStateFilePathsToClear = exports.profileStateFileLocations = exports.resolveProfileStateFile = exports.resolveProfileStateDir = exports.legacyProfileStateDir = exports.profileStateDir = exports.SUPERSEDED_COPY_SUFFIX = exports.SUPERSEDED_MARKER_SUFFIX = exports.PROFILES_SEGMENT = exports.isConfigRootOverridden = exports.configRootPath = exports.resolveConfigRoot = exports.verifyManifest = exports.verifyArtifact = exports.isTrustedArtifactOrigin = exports.getDeltaFor = exports.buildManifestMessage = exports.buildArtifactMessage = exports.TRUSTED_FEED_ORIGINS = exports.MAX_SIGS = exports.OVERSKY_RELEASE_PUBLIC_KEYS = exports.resolveFirstPartyHarnessChannel = exports.resolveChannelManifestUrl = exports.isFirstPartyHarnessChannel = exports.firstPartyHarnessFeedCandidates = exports.firstPartyHarnessFeedBase = exports.firstPartyHarnessChannelPrefix = exports.FIRST_PARTY_HARNESS_CHANNELS = exports.DEFAULT_FIRST_PARTY_HARNESS_CHANNEL = exports.migrateFirstPartyHarnessHome = exports.linkFirstPartyHarnessAliases = exports.firstPartyHarnessInstalledBinaryPath = exports.firstPartyHarnessHomeDir = exports.firstPartyHarnessBinDir = exports.FIRST_PARTY_HARNESS_PROVENANCE_SUFFIX = exports.FIRST_PARTY_HARNESS_PREVIOUS_SUFFIX = void 0;
30
30
  // Daemon scope vocabulary — single source of truth for non-Mongoose tiers
31
31
  // (daemon, desktop, cli). Schema-bound canonical lives in
32
32
  // `@skrr-ai/data-schemas/common/daemonScopes`; the two are kept byte-equal
@@ -109,6 +109,8 @@ Object.defineProperty(exports, "__resetCredentialResolverForTest", { enumerable:
109
109
  Object.defineProperty(exports, "invalidateAuthHelperCache", { enumerable: true, get: function () { return credentialResolver_js_1.invalidateAuthHelperCache; } });
110
110
  Object.defineProperty(exports, "classifyTokenKind", { enumerable: true, get: function () { return credentialResolver_js_1.classifyTokenKind; } });
111
111
  Object.defineProperty(exports, "CI_TOKEN_PREFIX", { enumerable: true, get: function () { return credentialResolver_js_1.CI_TOKEN_PREFIX; } });
112
+ Object.defineProperty(exports, "PERSONAL_ACCESS_TOKEN_PREFIX", { enumerable: true, get: function () { return credentialResolver_js_1.PERSONAL_ACCESS_TOKEN_PREFIX; } });
113
+ Object.defineProperty(exports, "isStaticTokenKind", { enumerable: true, get: function () { return credentialResolver_js_1.isStaticTokenKind; } });
112
114
  // L6.1 / L6.3 — fail-closed errors thrown by the auth-helper slot.
113
115
  Object.defineProperty(exports, "AuthHelperUntrustedError", { enumerable: true, get: function () { return credentialResolver_js_1.AuthHelperUntrustedError; } });
114
116
  Object.defineProperty(exports, "AuthHelperUnavailableError", { enumerable: true, get: function () { return credentialResolver_js_1.AuthHelperUnavailableError; } });
@@ -13,8 +13,11 @@
13
13
  * Precedence (high → low):
14
14
  *
15
15
  * 1. flag — `--token <jwt>` CLI flag (debugging)
16
- * 2. env-token — `OVERSKY_TOKEN` env (CI / static; Phase I adds
17
- * server-side scope=ci validation)
16
+ * 2. env-token — `OVERSKY_TOKEN` (CI / static). The CLI also reads
17
+ * `SKRR_TOKEN` via `envTokenNames`; `OVERSKY_TOKEN` wins
18
+ * when both are set, matching the CLI config overlay. A
19
+ * personal access token (`osk_pat_*`) is the credential
20
+ * CI should put here.
18
21
  * 3. auth-helper — `OVERSKY_AUTH_HELPER` script output (rotating
19
22
  * creds — Vault, AWS SM, internal SSO proxy)
20
23
  * 4. fd-handoff — `OVERSKY_AUTH_FD` parent→child IPC (Electron
@@ -64,6 +67,12 @@ export interface CredentialResolverOptions {
64
67
  * string to use that value directly.
65
68
  */
66
69
  envTokenOverride?: string | null;
70
+ /**
71
+ * Environment variables read by the env-token slot, in precedence order.
72
+ * Defaults to `['OVERSKY_TOKEN']`. The CLI passes
73
+ * `['OVERSKY_TOKEN', 'SKRR_TOKEN']` (OSK-13208).
74
+ */
75
+ envTokenNames?: readonly string[];
67
76
  /** Test/explicit override for `OVERSKY_AUTH_HELPER` env. Same semantics. */
68
77
  authHelperPathOverride?: string | null;
69
78
  /**
@@ -143,6 +152,8 @@ export interface AuthHelperSentinelInfo {
143
152
  * (POST /api/daemons/token), MUST NOT schedule refresh,
144
153
  * and on auth failure exits 75 with a CI-specific error
145
154
  * rather than writing needs-reauth.json.
155
+ * - 'pat' — personal access token (`osk_pat_*`, OSK-13208): a static
156
+ * bearer used AS the user by the CLI. Never refreshed.
146
157
  * - 'install' — short-lived web-minted JWT with `scope=daemon-install`.
147
158
  * The daemon exchanges it through the same /api/daemons/token
148
159
  * bootstrap path, persists only the returned daemon
@@ -157,9 +168,17 @@ export interface AuthHelperSentinelInfo {
157
168
  * The kill switch `OVERSKY_DISABLE_CI_TOKEN_RESOLVER=1` forces every token to
158
169
  * `'standard'` for triage purposes.
159
170
  */
160
- export type TokenKind = 'standard' | 'ci' | 'install';
171
+ export type TokenKind = 'standard' | 'ci' | 'install' | 'pat';
161
172
  /** CI-token plaintext prefix; mirrors api/server/services/Auth/daemonCiTokens.js. */
162
173
  export declare const CI_TOKEN_PREFIX = "osk_ci_";
174
+ /** Personal-access-token prefix; mirrors api/server/services/Auth/personalAccessTokens.js. */
175
+ export declare const PERSONAL_ACCESS_TOKEN_PREFIX = "osk_pat_";
176
+ /**
177
+ * True for a kind whose token is static by construction: never refreshed,
178
+ * never rotated into a store. Like `TokenKind` itself this selects a local
179
+ * code path and grants nothing.
180
+ */
181
+ export declare function isStaticTokenKind(kind: TokenKind): boolean;
163
182
  /**
164
183
  * Classify a token by local shape. Pure function; safe to call on any string
165
184
  * (including `null`-coerced empty). Returns `'standard'` for empty input
@@ -13,8 +13,11 @@
13
13
  * Precedence (high → low):
14
14
  *
15
15
  * 1. flag — `--token <jwt>` CLI flag (debugging)
16
- * 2. env-token — `OVERSKY_TOKEN` env (CI / static; Phase I adds
17
- * server-side scope=ci validation)
16
+ * 2. env-token — `OVERSKY_TOKEN` (CI / static). The CLI also reads
17
+ * `SKRR_TOKEN` via `envTokenNames`; `OVERSKY_TOKEN` wins
18
+ * when both are set, matching the CLI config overlay. A
19
+ * personal access token (`osk_pat_*`) is the credential
20
+ * CI should put here.
18
21
  * 3. auth-helper — `OVERSKY_AUTH_HELPER` script output (rotating
19
22
  * creds — Vault, AWS SM, internal SSO proxy)
20
23
  * 4. fd-handoff — `OVERSKY_AUTH_FD` parent→child IPC (Electron
@@ -62,6 +65,16 @@ export const CREDENTIAL_PRECEDENCE = [
62
65
  ];
63
66
  /** CI-token plaintext prefix; mirrors api/server/services/Auth/daemonCiTokens.js. */
64
67
  export const CI_TOKEN_PREFIX = 'osk_ci_';
68
+ /** Personal-access-token prefix; mirrors api/server/services/Auth/personalAccessTokens.js. */
69
+ export const PERSONAL_ACCESS_TOKEN_PREFIX = 'osk_pat_';
70
+ /**
71
+ * True for a kind whose token is static by construction: never refreshed,
72
+ * never rotated into a store. Like `TokenKind` itself this selects a local
73
+ * code path and grants nothing.
74
+ */
75
+ export function isStaticTokenKind(kind) {
76
+ return kind === 'ci' || kind === 'pat';
77
+ }
65
78
  /**
66
79
  * Classify a token by local shape. Pure function; safe to call on any string
67
80
  * (including `null`-coerced empty). Returns `'standard'` for empty input
@@ -97,6 +110,8 @@ export function classifyTokenKind(token) {
97
110
  return 'standard';
98
111
  if (token.startsWith(CI_TOKEN_PREFIX))
99
112
  return 'ci';
113
+ if (token.startsWith(PERSONAL_ACCESS_TOKEN_PREFIX))
114
+ return 'pat';
100
115
  const payload = decodeJwtPayload(token);
101
116
  if (payload &&
102
117
  typeof payload === 'object' &&
@@ -252,8 +267,16 @@ export class CredentialResolver {
252
267
  if (typeof this.opts.envTokenOverride === 'string') {
253
268
  return this.opts.envTokenOverride.length > 0 ? this.opts.envTokenOverride : null;
254
269
  }
255
- const v = process.env.OVERSKY_TOKEN;
256
- return typeof v === 'string' && v.length > 0 ? v : null;
270
+ // `OVERSKY_TOKEN` first (retained by decision, docs/product/skrr-env-inventory.md),
271
+ // then any renamed spelling the caller opted into (`SKRR_TOKEN` for the CLI,
272
+ // OSK-13208). The daemon does not opt in: a CI job that sets `SKRR_TOKEN`
273
+ // for `skrr` must not have a co-located `skrrd` silently adopt it.
274
+ for (const name of this.opts.envTokenNames ?? ['OVERSKY_TOKEN']) {
275
+ const v = process.env[name];
276
+ if (typeof v === 'string' && v.length > 0)
277
+ return v;
278
+ }
279
+ return null;
257
280
  }
258
281
  async tryResolveAuthHelper() {
259
282
  let helperPath;
@@ -38,7 +38,13 @@ export declare function describeDeviceKeySplit(profile: string): {
38
38
  * Order:
39
39
  * 1. Try to load existing keypair from disk.
40
40
  * - Success → state = active.
41
- * - Missing files / corruption / decrypt failure → step 2.
41
+ * - No key material at all (first install) → step 2.
42
+ * - Key material present but unloadable (corruption, decrypt failure,
43
+ * public/private mismatch) → disabled+unreadable_key and a
44
+ * `recovery_required` event, UNLESS `recoverUnreadable` is set. Only
45
+ * an explicit interactive login sets it, because that login proves and
46
+ * re-pins the new key; replacing it on ordinary boot would sign the
47
+ * next refresh with a key the server never pinned.
42
48
  * 2. Generate fresh keypair and persist. Failure to persist is a hard
43
49
  * error landing in disabled+persist_failed.
44
50
  */
@@ -335,7 +335,13 @@ async function consolidateDeviceIdentity(profile) {
335
335
  * Order:
336
336
  * 1. Try to load existing keypair from disk.
337
337
  * - Success → state = active.
338
- * - Missing files / corruption / decrypt failure → step 2.
338
+ * - No key material at all (first install) → step 2.
339
+ * - Key material present but unloadable (corruption, decrypt failure,
340
+ * public/private mismatch) → disabled+unreadable_key and a
341
+ * `recovery_required` event, UNLESS `recoverUnreadable` is set. Only
342
+ * an explicit interactive login sets it, because that login proves and
343
+ * re-pins the new key; replacing it on ordinary boot would sign the
344
+ * next refresh with a key the server never pinned.
339
345
  * 2. Generate fresh keypair and persist. Failure to persist is a hard
340
346
  * error landing in disabled+persist_failed.
341
347
  */
@@ -16,7 +16,7 @@ export { classifyRefreshResponse, type RefreshResponseShape, type ClassifiedRefr
16
16
  export { refreshDaemonToken, revokeDaemonRefreshSession, withAuthLock, persistReauthState, needsReauthState, clearReauthState, installLockExitHandlers, __refreshDiagnostics, __resetUnknown401StreaksForTest, UNKNOWN_401_BUDGET, } from './refresh.js';
17
17
  export { createRefreshScheduler, type RefreshScheduler, type RefreshSchedulerOptions, } from './refreshScheduler.js';
18
18
  export { readAuthFromFd, __setFdReaderForTest, type FdAuthPayload } from './fdToken.js';
19
- export { CredentialResolver, CREDENTIAL_PRECEDENCE, __resetCredentialResolverForTest, invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX, AuthHelperUntrustedError, AuthHelperUnavailableError, type CredentialSource, type CredentialStoreMode, type CredentialResolverOptions, type ResolvedCredential, type TokenKind, type HelperTrustDecision, type AuthHelperBlockedInfo, type AuthHelperSentinelInfo, } from './credentialResolver.js';
19
+ export { CredentialResolver, CREDENTIAL_PRECEDENCE, __resetCredentialResolverForTest, invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX, PERSONAL_ACCESS_TOKEN_PREFIX, isStaticTokenKind, AuthHelperUntrustedError, AuthHelperUnavailableError, type CredentialSource, type CredentialStoreMode, type CredentialResolverOptions, type ResolvedCredential, type TokenKind, type HelperTrustDecision, type AuthHelperBlockedInfo, type AuthHelperSentinelInfo, } from './credentialResolver.js';
20
20
  export { invokeAuthHelper, getDefaultHelperTtlMs, getLastAuthHelperFailureReason, __resetAuthHelperFailureReasonForTest, SENTINEL_TRIGGERING_FAILURES, type HelperResult, type InvokeAuthHelperOptions, type AuthHelperFailureReason, } from './authHelper.js';
21
21
  export { runHeadersHelper, invalidateHeadersHelperCache, type RunHeadersHelperOptions, } from './headers-helper.js';
22
22
  export { generateVerifier, challenge, generateState, safeEqual, verifyChallenge, type PkceChallengeMethod, } from './pkce.js';
@@ -51,7 +51,7 @@ export { CredentialResolver, CREDENTIAL_PRECEDENCE, __resetCredentialResolverFor
51
51
  // H3-6 — public seam 401 handlers call to bust the helper cache so
52
52
  // the next resolve re-invokes OVERSKY_AUTH_HELPER immediately
53
53
  // instead of serving the stale cached token for up to its TTL.
54
- invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX,
54
+ invalidateAuthHelperCache, classifyTokenKind, CI_TOKEN_PREFIX, PERSONAL_ACCESS_TOKEN_PREFIX, isStaticTokenKind,
55
55
  // L6.1 / L6.3 — fail-closed errors thrown by the auth-helper slot.
56
56
  AuthHelperUntrustedError, AuthHelperUnavailableError, } from './credentialResolver.js';
57
57
  // Auth helper — invocation contract for OVERSKY_AUTH_HELPER
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skrr-ai/auth-core",
3
- "version": "0.4.10",
3
+ "version": "0.4.11",
4
4
  "main": "dist/cjs/index.js",
5
5
  "types": "dist/esm/index.d.ts",
6
6
  "exports": {