@skrr-ai/auth-core 0.1.3 → 0.1.4
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/dist/cjs/configRoot.d.ts +50 -0
- package/dist/cjs/configRoot.js +67 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +7 -1
- package/dist/esm/configRoot.d.ts +50 -0
- package/dist/esm/configRoot.js +59 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skrr root — the single definition of where this machine keeps its skrr
|
|
3
|
+
* state.
|
|
4
|
+
*
|
|
5
|
+
* It lives here because BOTH binaries need the same answer and neither owns it.
|
|
6
|
+
* `skrr` and `skrrd` keep separate credentials on purpose, but they share one
|
|
7
|
+
* root, and every place that re-derived it became a place they could disagree.
|
|
8
|
+
* They did, twice in one day:
|
|
9
|
+
*
|
|
10
|
+
* - The CLI's engine path honoured `OVERSKY_CONFIG_DIR` while its config did
|
|
11
|
+
* not, so a relocated root moved the engine and left the credentials in
|
|
12
|
+
* `$HOME`. Fixed by teaching `config.ts` the variable — which promptly
|
|
13
|
+
* re-created the split in the mirror image, because `sky-code.ts` still read
|
|
14
|
+
* only the old name.
|
|
15
|
+
* - The daemon then had the same shape, and fixing the CLI's half turned it
|
|
16
|
+
* into a CLI/daemon divergence: with the variable set, the two halves of one
|
|
17
|
+
* product disagreed about where the credentials live.
|
|
18
|
+
*
|
|
19
|
+
* Each of those was a correct local fix that created the next defect, because
|
|
20
|
+
* the root was being DERIVED rather than READ. Teaching every site the same list
|
|
21
|
+
* of variable names only defers the problem to whenever the list changes again —
|
|
22
|
+
* which is exactly what `SKRR_CONFIG_DIR` did.
|
|
23
|
+
*
|
|
24
|
+
* So: one function, and a boundary test that fails if anything re-derives it.
|
|
25
|
+
*
|
|
26
|
+
* `SKRR_CONFIG_DIR` is the spelling for anything new (root `CLAUDE.md`) and wins
|
|
27
|
+
* when both are set. `OVERSKY_CONFIG_DIR` keeps working because existing installs,
|
|
28
|
+
* the engine resolver and the daemon all read it, and breaking a documented
|
|
29
|
+
* override to tidy a name would be a worse trade than carrying two.
|
|
30
|
+
*
|
|
31
|
+
* Takes `env` rather than reading the global so a caller can resolve a root for a
|
|
32
|
+
* child process it is about to spawn, and so tests need no process-wide mutation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveConfigRoot(env?: NodeJS.ProcessEnv): string;
|
|
35
|
+
/** A path under the skrr root, e.g. `configRootPath(env, 'sky-code', 'bin')`. */
|
|
36
|
+
export declare function configRootPath(env: NodeJS.ProcessEnv, ...segments: string[]): string;
|
|
37
|
+
/**
|
|
38
|
+
* Has the operator explicitly relocated the root?
|
|
39
|
+
*
|
|
40
|
+
* A distinct question from "what is the root", and it has a real caller: the
|
|
41
|
+
* legacy-location fallbacks exist to find state left by an older layout under
|
|
42
|
+
* `$HOME`, and once someone has POINTED the root somewhere, guessing at
|
|
43
|
+
* `$HOME` is no longer a helpful fallback — it is a different machine's data.
|
|
44
|
+
*
|
|
45
|
+
* Shared for the same reason as `resolveConfigRoot`: this check was copied to
|
|
46
|
+
* three call sites, each spelling the variable list itself, so adding
|
|
47
|
+
* `SKRR_CONFIG_DIR` to the resolver silently left the copies answering the old
|
|
48
|
+
* question.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isConfigRootOverridden(env?: NodeJS.ProcessEnv): boolean;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveConfigRoot = resolveConfigRoot;
|
|
7
|
+
exports.configRootPath = configRootPath;
|
|
8
|
+
exports.isConfigRootOverridden = isConfigRootOverridden;
|
|
9
|
+
const node_os_1 = require("node:os");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
/**
|
|
12
|
+
* The skrr root — the single definition of where this machine keeps its skrr
|
|
13
|
+
* state.
|
|
14
|
+
*
|
|
15
|
+
* It lives here because BOTH binaries need the same answer and neither owns it.
|
|
16
|
+
* `skrr` and `skrrd` keep separate credentials on purpose, but they share one
|
|
17
|
+
* root, and every place that re-derived it became a place they could disagree.
|
|
18
|
+
* They did, twice in one day:
|
|
19
|
+
*
|
|
20
|
+
* - The CLI's engine path honoured `OVERSKY_CONFIG_DIR` while its config did
|
|
21
|
+
* not, so a relocated root moved the engine and left the credentials in
|
|
22
|
+
* `$HOME`. Fixed by teaching `config.ts` the variable — which promptly
|
|
23
|
+
* re-created the split in the mirror image, because `sky-code.ts` still read
|
|
24
|
+
* only the old name.
|
|
25
|
+
* - The daemon then had the same shape, and fixing the CLI's half turned it
|
|
26
|
+
* into a CLI/daemon divergence: with the variable set, the two halves of one
|
|
27
|
+
* product disagreed about where the credentials live.
|
|
28
|
+
*
|
|
29
|
+
* Each of those was a correct local fix that created the next defect, because
|
|
30
|
+
* the root was being DERIVED rather than READ. Teaching every site the same list
|
|
31
|
+
* of variable names only defers the problem to whenever the list changes again —
|
|
32
|
+
* which is exactly what `SKRR_CONFIG_DIR` did.
|
|
33
|
+
*
|
|
34
|
+
* So: one function, and a boundary test that fails if anything re-derives it.
|
|
35
|
+
*
|
|
36
|
+
* `SKRR_CONFIG_DIR` is the spelling for anything new (root `CLAUDE.md`) and wins
|
|
37
|
+
* when both are set. `OVERSKY_CONFIG_DIR` keeps working because existing installs,
|
|
38
|
+
* the engine resolver and the daemon all read it, and breaking a documented
|
|
39
|
+
* override to tidy a name would be a worse trade than carrying two.
|
|
40
|
+
*
|
|
41
|
+
* Takes `env` rather than reading the global so a caller can resolve a root for a
|
|
42
|
+
* child process it is about to spawn, and so tests need no process-wide mutation.
|
|
43
|
+
*/
|
|
44
|
+
function resolveConfigRoot(env = process.env) {
|
|
45
|
+
const override = (env.SKRR_CONFIG_DIR || env.OVERSKY_CONFIG_DIR)?.trim();
|
|
46
|
+
return override || node_path_1.default.join((0, node_os_1.homedir)(), '.skrr');
|
|
47
|
+
}
|
|
48
|
+
/** A path under the skrr root, e.g. `configRootPath(env, 'sky-code', 'bin')`. */
|
|
49
|
+
function configRootPath(env, ...segments) {
|
|
50
|
+
return node_path_1.default.join(resolveConfigRoot(env), ...segments);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Has the operator explicitly relocated the root?
|
|
54
|
+
*
|
|
55
|
+
* A distinct question from "what is the root", and it has a real caller: the
|
|
56
|
+
* legacy-location fallbacks exist to find state left by an older layout under
|
|
57
|
+
* `$HOME`, and once someone has POINTED the root somewhere, guessing at
|
|
58
|
+
* `$HOME` is no longer a helpful fallback — it is a different machine's data.
|
|
59
|
+
*
|
|
60
|
+
* Shared for the same reason as `resolveConfigRoot`: this check was copied to
|
|
61
|
+
* three call sites, each spelling the variable list itself, so adding
|
|
62
|
+
* `SKRR_CONFIG_DIR` to the resolver silently left the copies answering the old
|
|
63
|
+
* question.
|
|
64
|
+
*/
|
|
65
|
+
function isConfigRootOverridden(env = process.env) {
|
|
66
|
+
return Boolean((env.SKRR_CONFIG_DIR || env.OVERSKY_CONFIG_DIR)?.trim());
|
|
67
|
+
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -36,3 +36,4 @@ export { sanitizeSpawnEnv, SENSITIVE_ENV_VARS, SENSITIVE_ENV_PREFIXES, SENSITIVE
|
|
|
36
36
|
export { CONFIG_DIR_NAME, LEGACY_CONFIG_DIR_NAMES, NATIVE_ID_PREFIX, LEGACY_NATIVE_ID_PREFIXES, DEFAULT_BINARY_NAME, } from './localIdentity.js';
|
|
37
37
|
export { findLegacyLocalState, describeLegacyState, type LegacyStateFinding, type LegacyStateReport, } from './legacyStatePreflight.js';
|
|
38
38
|
export { DEFAULT_SKY_CODE_CHANNEL, DEFAULT_SKY_CODE_FEED_BASE, SKY_CODE_CHANNELS, SKY_CODE_CHANNEL_ENV, SKY_CODE_MANIFEST_FILE, isSkyCodeChannel, resolveChannelManifestUrl, resolveSkyCodeChannel, skyCodeChannelPrefix, skyCodeFeedBase, SKY_CODE_FEED_BASE_ENV, type SkyCodeChannel, } from './skyCodeChannels.js';
|
|
39
|
+
export { resolveConfigRoot, configRootPath, isConfigRootOverridden } from './configRoot.js';
|
package/dist/cjs/index.js
CHANGED
|
@@ -11,7 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
11
11
|
exports.challenge = 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.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;
|
|
12
12
|
exports.tokenHash = 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 = void 0;
|
|
13
13
|
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 = exports.ensureMachineDaemonId = exports.__getDeviceIdentityStateForTest = exports.__setDeviceIdentityStateForTest = exports.__enrollmentBackoffPathForTest = exports.__enrollmentMarkerPathForTest = exports.__privateKeyPathForTest = exports.__publicKeyPathForTest = 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.maybeDecryptOnRead = exports.maybeEncryptForWrite = exports.describeCredEnvelopeState = exports.isCredEnvelopeActive = exports.shutdownCredEnvelope = exports.resetCredEnvelope = exports.initCredEnvelope = exports.verifyDeviceProof = void 0;
|
|
14
|
-
exports.SKY_CODE_FEED_BASE_ENV = exports.skyCodeFeedBase = exports.skyCodeChannelPrefix = exports.resolveSkyCodeChannel = exports.resolveChannelManifestUrl = exports.isSkyCodeChannel = exports.SKY_CODE_MANIFEST_FILE = exports.SKY_CODE_CHANNEL_ENV = exports.SKY_CODE_CHANNELS = exports.DEFAULT_SKY_CODE_FEED_BASE = exports.DEFAULT_SKY_CODE_CHANNEL = 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.SENSITIVE_ENV_PREFIX_EXCEPTIONS = exports.SENSITIVE_ENV_SUFFIXES = exports.SENSITIVE_ENV_PREFIXES = exports.SENSITIVE_ENV_VARS = exports.sanitizeSpawnEnv = exports.tierPermitsConfiguredAutoMode = exports.credentialPolicyForTier = void 0;
|
|
14
|
+
exports.isConfigRootOverridden = exports.configRootPath = exports.resolveConfigRoot = exports.SKY_CODE_FEED_BASE_ENV = exports.skyCodeFeedBase = exports.skyCodeChannelPrefix = exports.resolveSkyCodeChannel = exports.resolveChannelManifestUrl = exports.isSkyCodeChannel = exports.SKY_CODE_MANIFEST_FILE = exports.SKY_CODE_CHANNEL_ENV = exports.SKY_CODE_CHANNELS = exports.DEFAULT_SKY_CODE_FEED_BASE = exports.DEFAULT_SKY_CODE_CHANNEL = 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.SENSITIVE_ENV_PREFIX_EXCEPTIONS = exports.SENSITIVE_ENV_SUFFIXES = exports.SENSITIVE_ENV_PREFIXES = exports.SENSITIVE_ENV_VARS = exports.sanitizeSpawnEnv = exports.tierPermitsConfiguredAutoMode = exports.credentialPolicyForTier = void 0;
|
|
15
15
|
// Daemon scope vocabulary — single source of truth for non-Mongoose tiers
|
|
16
16
|
// (daemon, desktop, cli). Schema-bound canonical lives in
|
|
17
17
|
// `@skrr-ai/data-schemas/common/daemonScopes`; the two are kept byte-equal
|
|
@@ -315,3 +315,9 @@ Object.defineProperty(exports, "resolveSkyCodeChannel", { enumerable: true, get:
|
|
|
315
315
|
Object.defineProperty(exports, "skyCodeChannelPrefix", { enumerable: true, get: function () { return skyCodeChannels_js_1.skyCodeChannelPrefix; } });
|
|
316
316
|
Object.defineProperty(exports, "skyCodeFeedBase", { enumerable: true, get: function () { return skyCodeChannels_js_1.skyCodeFeedBase; } });
|
|
317
317
|
Object.defineProperty(exports, "SKY_CODE_FEED_BASE_ENV", { enumerable: true, get: function () { return skyCodeChannels_js_1.SKY_CODE_FEED_BASE_ENV; } });
|
|
318
|
+
// The one definition of the skrr root, shared by `skrr` and `skrrd`. See the
|
|
319
|
+
// module for why re-deriving it kept producing divergences.
|
|
320
|
+
var configRoot_js_1 = require("./configRoot.js");
|
|
321
|
+
Object.defineProperty(exports, "resolveConfigRoot", { enumerable: true, get: function () { return configRoot_js_1.resolveConfigRoot; } });
|
|
322
|
+
Object.defineProperty(exports, "configRootPath", { enumerable: true, get: function () { return configRoot_js_1.configRootPath; } });
|
|
323
|
+
Object.defineProperty(exports, "isConfigRootOverridden", { enumerable: true, get: function () { return configRoot_js_1.isConfigRootOverridden; } });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skrr root — the single definition of where this machine keeps its skrr
|
|
3
|
+
* state.
|
|
4
|
+
*
|
|
5
|
+
* It lives here because BOTH binaries need the same answer and neither owns it.
|
|
6
|
+
* `skrr` and `skrrd` keep separate credentials on purpose, but they share one
|
|
7
|
+
* root, and every place that re-derived it became a place they could disagree.
|
|
8
|
+
* They did, twice in one day:
|
|
9
|
+
*
|
|
10
|
+
* - The CLI's engine path honoured `OVERSKY_CONFIG_DIR` while its config did
|
|
11
|
+
* not, so a relocated root moved the engine and left the credentials in
|
|
12
|
+
* `$HOME`. Fixed by teaching `config.ts` the variable — which promptly
|
|
13
|
+
* re-created the split in the mirror image, because `sky-code.ts` still read
|
|
14
|
+
* only the old name.
|
|
15
|
+
* - The daemon then had the same shape, and fixing the CLI's half turned it
|
|
16
|
+
* into a CLI/daemon divergence: with the variable set, the two halves of one
|
|
17
|
+
* product disagreed about where the credentials live.
|
|
18
|
+
*
|
|
19
|
+
* Each of those was a correct local fix that created the next defect, because
|
|
20
|
+
* the root was being DERIVED rather than READ. Teaching every site the same list
|
|
21
|
+
* of variable names only defers the problem to whenever the list changes again —
|
|
22
|
+
* which is exactly what `SKRR_CONFIG_DIR` did.
|
|
23
|
+
*
|
|
24
|
+
* So: one function, and a boundary test that fails if anything re-derives it.
|
|
25
|
+
*
|
|
26
|
+
* `SKRR_CONFIG_DIR` is the spelling for anything new (root `CLAUDE.md`) and wins
|
|
27
|
+
* when both are set. `OVERSKY_CONFIG_DIR` keeps working because existing installs,
|
|
28
|
+
* the engine resolver and the daemon all read it, and breaking a documented
|
|
29
|
+
* override to tidy a name would be a worse trade than carrying two.
|
|
30
|
+
*
|
|
31
|
+
* Takes `env` rather than reading the global so a caller can resolve a root for a
|
|
32
|
+
* child process it is about to spawn, and so tests need no process-wide mutation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveConfigRoot(env?: NodeJS.ProcessEnv): string;
|
|
35
|
+
/** A path under the skrr root, e.g. `configRootPath(env, 'sky-code', 'bin')`. */
|
|
36
|
+
export declare function configRootPath(env: NodeJS.ProcessEnv, ...segments: string[]): string;
|
|
37
|
+
/**
|
|
38
|
+
* Has the operator explicitly relocated the root?
|
|
39
|
+
*
|
|
40
|
+
* A distinct question from "what is the root", and it has a real caller: the
|
|
41
|
+
* legacy-location fallbacks exist to find state left by an older layout under
|
|
42
|
+
* `$HOME`, and once someone has POINTED the root somewhere, guessing at
|
|
43
|
+
* `$HOME` is no longer a helpful fallback — it is a different machine's data.
|
|
44
|
+
*
|
|
45
|
+
* Shared for the same reason as `resolveConfigRoot`: this check was copied to
|
|
46
|
+
* three call sites, each spelling the variable list itself, so adding
|
|
47
|
+
* `SKRR_CONFIG_DIR` to the resolver silently left the copies answering the old
|
|
48
|
+
* question.
|
|
49
|
+
*/
|
|
50
|
+
export declare function isConfigRootOverridden(env?: NodeJS.ProcessEnv): boolean;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* The skrr root — the single definition of where this machine keeps its skrr
|
|
5
|
+
* state.
|
|
6
|
+
*
|
|
7
|
+
* It lives here because BOTH binaries need the same answer and neither owns it.
|
|
8
|
+
* `skrr` and `skrrd` keep separate credentials on purpose, but they share one
|
|
9
|
+
* root, and every place that re-derived it became a place they could disagree.
|
|
10
|
+
* They did, twice in one day:
|
|
11
|
+
*
|
|
12
|
+
* - The CLI's engine path honoured `OVERSKY_CONFIG_DIR` while its config did
|
|
13
|
+
* not, so a relocated root moved the engine and left the credentials in
|
|
14
|
+
* `$HOME`. Fixed by teaching `config.ts` the variable — which promptly
|
|
15
|
+
* re-created the split in the mirror image, because `sky-code.ts` still read
|
|
16
|
+
* only the old name.
|
|
17
|
+
* - The daemon then had the same shape, and fixing the CLI's half turned it
|
|
18
|
+
* into a CLI/daemon divergence: with the variable set, the two halves of one
|
|
19
|
+
* product disagreed about where the credentials live.
|
|
20
|
+
*
|
|
21
|
+
* Each of those was a correct local fix that created the next defect, because
|
|
22
|
+
* the root was being DERIVED rather than READ. Teaching every site the same list
|
|
23
|
+
* of variable names only defers the problem to whenever the list changes again —
|
|
24
|
+
* which is exactly what `SKRR_CONFIG_DIR` did.
|
|
25
|
+
*
|
|
26
|
+
* So: one function, and a boundary test that fails if anything re-derives it.
|
|
27
|
+
*
|
|
28
|
+
* `SKRR_CONFIG_DIR` is the spelling for anything new (root `CLAUDE.md`) and wins
|
|
29
|
+
* when both are set. `OVERSKY_CONFIG_DIR` keeps working because existing installs,
|
|
30
|
+
* the engine resolver and the daemon all read it, and breaking a documented
|
|
31
|
+
* override to tidy a name would be a worse trade than carrying two.
|
|
32
|
+
*
|
|
33
|
+
* Takes `env` rather than reading the global so a caller can resolve a root for a
|
|
34
|
+
* child process it is about to spawn, and so tests need no process-wide mutation.
|
|
35
|
+
*/
|
|
36
|
+
export function resolveConfigRoot(env = process.env) {
|
|
37
|
+
const override = (env.SKRR_CONFIG_DIR || env.OVERSKY_CONFIG_DIR)?.trim();
|
|
38
|
+
return override || path.join(homedir(), '.skrr');
|
|
39
|
+
}
|
|
40
|
+
/** A path under the skrr root, e.g. `configRootPath(env, 'sky-code', 'bin')`. */
|
|
41
|
+
export function configRootPath(env, ...segments) {
|
|
42
|
+
return path.join(resolveConfigRoot(env), ...segments);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Has the operator explicitly relocated the root?
|
|
46
|
+
*
|
|
47
|
+
* A distinct question from "what is the root", and it has a real caller: the
|
|
48
|
+
* legacy-location fallbacks exist to find state left by an older layout under
|
|
49
|
+
* `$HOME`, and once someone has POINTED the root somewhere, guessing at
|
|
50
|
+
* `$HOME` is no longer a helpful fallback — it is a different machine's data.
|
|
51
|
+
*
|
|
52
|
+
* Shared for the same reason as `resolveConfigRoot`: this check was copied to
|
|
53
|
+
* three call sites, each spelling the variable list itself, so adding
|
|
54
|
+
* `SKRR_CONFIG_DIR` to the resolver silently left the copies answering the old
|
|
55
|
+
* question.
|
|
56
|
+
*/
|
|
57
|
+
export function isConfigRootOverridden(env = process.env) {
|
|
58
|
+
return Boolean((env.SKRR_CONFIG_DIR || env.OVERSKY_CONFIG_DIR)?.trim());
|
|
59
|
+
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -36,3 +36,4 @@ export { sanitizeSpawnEnv, SENSITIVE_ENV_VARS, SENSITIVE_ENV_PREFIXES, SENSITIVE
|
|
|
36
36
|
export { CONFIG_DIR_NAME, LEGACY_CONFIG_DIR_NAMES, NATIVE_ID_PREFIX, LEGACY_NATIVE_ID_PREFIXES, DEFAULT_BINARY_NAME, } from './localIdentity.js';
|
|
37
37
|
export { findLegacyLocalState, describeLegacyState, type LegacyStateFinding, type LegacyStateReport, } from './legacyStatePreflight.js';
|
|
38
38
|
export { DEFAULT_SKY_CODE_CHANNEL, DEFAULT_SKY_CODE_FEED_BASE, SKY_CODE_CHANNELS, SKY_CODE_CHANNEL_ENV, SKY_CODE_MANIFEST_FILE, isSkyCodeChannel, resolveChannelManifestUrl, resolveSkyCodeChannel, skyCodeChannelPrefix, skyCodeFeedBase, SKY_CODE_FEED_BASE_ENV, type SkyCodeChannel, } from './skyCodeChannels.js';
|
|
39
|
+
export { resolveConfigRoot, configRootPath, isConfigRootOverridden } from './configRoot.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -143,3 +143,6 @@ export { CONFIG_DIR_NAME, LEGACY_CONFIG_DIR_NAMES, NATIVE_ID_PREFIX, LEGACY_NATI
|
|
|
143
143
|
reads, copies or removes what it finds (§7.2, §8.4). */
|
|
144
144
|
export { findLegacyLocalState, describeLegacyState, } from './legacyStatePreflight.js';
|
|
145
145
|
export { DEFAULT_SKY_CODE_CHANNEL, DEFAULT_SKY_CODE_FEED_BASE, SKY_CODE_CHANNELS, SKY_CODE_CHANNEL_ENV, SKY_CODE_MANIFEST_FILE, isSkyCodeChannel, resolveChannelManifestUrl, resolveSkyCodeChannel, skyCodeChannelPrefix, skyCodeFeedBase, SKY_CODE_FEED_BASE_ENV, } from './skyCodeChannels.js';
|
|
146
|
+
// The one definition of the skrr root, shared by `skrr` and `skrrd`. See the
|
|
147
|
+
// module for why re-deriving it kept producing divergences.
|
|
148
|
+
export { resolveConfigRoot, configRootPath, isConfigRootOverridden } from './configRoot.js';
|
package/package.json
CHANGED