@skrr-ai/cli 0.1.31 → 0.1.33
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/bin/run.js +2 -2
- package/dist/commands/agents/list.d.ts +2 -1
- package/dist/commands/agents/list.js +2 -1
- package/dist/commands/agents/show.js +2 -1
- package/dist/commands/balance/statement.js +8 -4
- package/dist/commands/browser/install.js +6 -2
- package/dist/commands/browser/uninstall.js +6 -2
- package/dist/commands/code/acp.js +2 -1
- package/dist/commands/code/doctor.d.ts +1 -1
- package/dist/commands/code/doctor.js +6 -5
- package/dist/commands/code/handover.d.ts +2 -2
- package/dist/commands/code/handover.js +2 -2
- package/dist/commands/code/index.d.ts +2 -2
- package/dist/commands/code/index.js +18 -17
- package/dist/commands/code/install.d.ts +3 -3
- package/dist/commands/code/install.js +18 -11
- package/dist/commands/code/migrate.js +3 -2
- package/dist/commands/code/oversky-agent.d.ts +5 -4
- package/dist/commands/code/oversky-agent.js +24 -22
- package/dist/commands/code/run.js +2 -1
- package/dist/commands/harnesses/list.d.ts +9 -1
- package/dist/commands/harnesses/list.js +28 -7
- package/dist/commands/harnesses/show.js +7 -2
- package/dist/commands/instructions/install.js +16 -6
- package/dist/commands/learning/delete.d.ts +9 -0
- package/dist/commands/learning/delete.js +39 -0
- package/dist/commands/learning/export.d.ts +5 -0
- package/dist/commands/learning/export.js +22 -0
- package/dist/commands/learning/reset.d.ts +9 -0
- package/dist/commands/learning/reset.js +34 -0
- package/dist/commands/learning/set.d.ts +10 -0
- package/dist/commands/learning/set.js +52 -0
- package/dist/commands/learning/status.d.ts +8 -0
- package/dist/commands/learning/status.js +35 -0
- package/dist/commands/logout.js +10 -5
- package/dist/commands/machines/dedicated/attach.js +2 -1
- package/dist/commands/tasks/runs.js +3 -1
- package/dist/commands/workspaces/use.js +2 -1
- package/dist/lib/adaptive-learning.d.ts +37 -0
- package/dist/lib/adaptive-learning.js +39 -0
- package/dist/lib/code-handover.d.ts +1 -1
- package/dist/lib/code-handover.js +3 -2
- package/dist/lib/config.d.ts +30 -4
- package/dist/lib/config.js +2 -1
- package/dist/lib/daemon-installer.d.ts +1 -1
- package/dist/lib/daemon-target.js +2 -2
- package/dist/lib/dedicated-lease-command.js +2 -1
- package/dist/lib/dedicated-machines.d.ts +2 -2
- package/dist/lib/dedicated-machines.js +6 -3
- package/dist/lib/exec-runtime-binary.d.ts +2 -2
- package/dist/lib/exec-runtime-binary.js +2 -2
- package/dist/lib/{sky-code-agent.d.ts → first-party-harness-agent.d.ts} +20 -19
- package/dist/lib/{sky-code-agent.js → first-party-harness-agent.js} +85 -47
- package/dist/lib/{sky-code-broker.d.ts → first-party-harness-broker.d.ts} +6 -6
- package/dist/lib/{sky-code-broker.js → first-party-harness-broker.js} +23 -23
- package/dist/lib/{sky-code-doctor.d.ts → first-party-harness-doctor.d.ts} +12 -2
- package/dist/lib/{sky-code-doctor.js → first-party-harness-doctor.js} +181 -94
- package/dist/lib/{sky-code-managed.d.ts → first-party-harness-managed.d.ts} +55 -30
- package/dist/lib/{sky-code-managed.js → first-party-harness-managed.js} +92 -35
- package/dist/lib/{sky-code.d.ts → first-party-harness.d.ts} +107 -36
- package/dist/lib/{sky-code.js → first-party-harness.js} +172 -73
- package/dist/lib/harness-provider-input.d.ts +35 -0
- package/dist/lib/harness-provider-input.js +57 -0
- package/dist/lib/harness-tiers.d.ts +8 -2
- package/dist/lib/harness-tiers.js +11 -6
- package/dist/lib/task-instruction-offer.js +10 -4
- package/dist/lib/worklogs.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +248 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +361 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +180 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +111 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +314 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +11 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +14 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +51 -14
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +248 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +332 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +170 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +111 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +303 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +11 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +14 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +12 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +4 -4
- package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +4816 -4782
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
- package/oclif.manifest.json +27119 -26808
- package/package.json +5 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +0 -96
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +0 -115
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +0 -96
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.js +0 -107
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first-party harness identity — the ONLY place its product name is written.
|
|
3
|
+
*
|
|
4
|
+
* "First-party harness" is the harness provider this platform builds, signs,
|
|
5
|
+
* distributes and installs itself: today a fork of OpenCode sold as skrr Code.
|
|
6
|
+
* It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
|
|
7
|
+
* "first-party" means an audited VENDOR harness such as Claude Code.
|
|
8
|
+
*
|
|
9
|
+
* ── Why a module, not a find/replace ──────────────────────────────────────
|
|
10
|
+
*
|
|
11
|
+
* The product was renamed twice ("OverSky" engine → "Sky Code" → "skrr Code"),
|
|
12
|
+
* and because its name was used as an IDENTIFIER — in file names, function
|
|
13
|
+
* names, env vars, workflow inputs, Mongo values, wire events — the second
|
|
14
|
+
* rename left 2,826 occurrences in 361 files spelled eleven ways. Every one was
|
|
15
|
+
* a place the next rename would have to find again.
|
|
16
|
+
*
|
|
17
|
+
* So the rule is: the product name is a VALUE held here, and every NAME in the
|
|
18
|
+
* codebase is brand-neutral and reads it. Renaming the product again is:
|
|
19
|
+
*
|
|
20
|
+
* 1. set `displayName` and `provider`;
|
|
21
|
+
* 2. move the old `provider` to the front of `aliases`;
|
|
22
|
+
* 3. leave `wireProvider` on the spelling installed daemons still speak;
|
|
23
|
+
* 4. regenerate `first-party-harness.json`
|
|
24
|
+
* (`node --import tsx scripts/emit-first-party-harness-json.mjs`);
|
|
25
|
+
* 5. ship the data migration, which is generic over `aliases`.
|
|
26
|
+
*
|
|
27
|
+
* No identifier, file, env var name or workflow input moves.
|
|
28
|
+
*
|
|
29
|
+
* ── Three spellings, kept apart on purpose ────────────────────────────────
|
|
30
|
+
*
|
|
31
|
+
* `provider` CANONICAL. What the platform stores, returns and renders.
|
|
32
|
+
* `aliases` ACCEPTED on every ingress until contract, and normalised to
|
|
33
|
+
* canonical at the edge. Nothing new is ever written with one.
|
|
34
|
+
* `wireProvider` What the server and a daemon say to EACH OTHER — the
|
|
35
|
+
* capability a daemon advertises, `daemon:<p>:request|response`,
|
|
36
|
+
* the `provider` of a session RPC. It moves LAST, because a
|
|
37
|
+
* daemon on a user's machine may be any version and the server
|
|
38
|
+
* cannot tell which one sent a request.
|
|
39
|
+
*
|
|
40
|
+
* The old code treated those three as one string, which is why no single
|
|
41
|
+
* change could rename it safely. See
|
|
42
|
+
* `docs/architecture/skrr-code-identifier-rename-2026-09-13.md`.
|
|
43
|
+
*
|
|
44
|
+
* ── Constraints on this file ──────────────────────────────────────────────
|
|
45
|
+
*
|
|
46
|
+
* Pure: no `node:` imports, no `process` at module load. It is published as the
|
|
47
|
+
* `@skrr-ai/auth-core/first-party-harness` subpath so the browser client and
|
|
48
|
+
* the React Native app can read it, and a Node-only import here would break
|
|
49
|
+
* both bundles at a distance.
|
|
50
|
+
*/
|
|
51
|
+
export interface FirstPartyHarnessIdentity {
|
|
52
|
+
/** What a person reads. Lowercase brand inside a compound (naming map §1). */
|
|
53
|
+
readonly displayName: string;
|
|
54
|
+
/** The command a person types, as it appears in prose. */
|
|
55
|
+
readonly command: string;
|
|
56
|
+
/** Canonical provider slug: stored, returned by the API, rendered. */
|
|
57
|
+
readonly provider: string;
|
|
58
|
+
/** Older spellings still ACCEPTED on every ingress, newest first. */
|
|
59
|
+
readonly aliases: readonly string[];
|
|
60
|
+
/** The spelling daemons and the server exchange on the wire. */
|
|
61
|
+
readonly wireProvider: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* THE identity — the only literal product name in the codebase.
|
|
65
|
+
*
|
|
66
|
+
* Phase: EXPAND. `provider` is still the spelling every stored row carries;
|
|
67
|
+
* `skrr-code` is accepted everywhere so the flip can follow once every reader
|
|
68
|
+
* has shipped.
|
|
69
|
+
*/
|
|
70
|
+
declare const IDENTITY: {
|
|
71
|
+
readonly displayName: "skrr Code";
|
|
72
|
+
readonly command: "skrr code";
|
|
73
|
+
readonly provider: "sky-code";
|
|
74
|
+
readonly aliases: readonly ["skrr-code"];
|
|
75
|
+
readonly wireProvider: "sky-code";
|
|
76
|
+
};
|
|
77
|
+
/** The canonical slug, as a literal type. */
|
|
78
|
+
export type FirstPartyHarnessCanonicalProvider = typeof IDENTITY.provider;
|
|
79
|
+
/** Any accepted spelling, as a literal type — for unions that must admit an alias. */
|
|
80
|
+
export type FirstPartyHarnessProvider = typeof IDENTITY.provider | (typeof IDENTITY.aliases)[number];
|
|
81
|
+
/** `local-<spelling>` for every accepted spelling. */
|
|
82
|
+
export type FirstPartyHarnessEnvironmentName = `local-${FirstPartyHarnessProvider}`;
|
|
83
|
+
/** `<spelling>_session` for every accepted spelling. */
|
|
84
|
+
export type FirstPartyHarnessCapabilityName = `${FirstPartyHarnessProvider}_session`;
|
|
85
|
+
export declare const FIRST_PARTY_HARNESS: FirstPartyHarnessIdentity;
|
|
86
|
+
/** The canonical slug with its literal type, for `as const` tuples and keyed tables. */
|
|
87
|
+
export declare const FIRST_PARTY_HARNESS_PROVIDER: FirstPartyHarnessCanonicalProvider;
|
|
88
|
+
/** Every spelling, canonical first. The order is the resolution order. */
|
|
89
|
+
export declare function firstPartyHarnessSpellings(): readonly string[];
|
|
90
|
+
/** True for the canonical provider or any alias (case- and whitespace-insensitive). */
|
|
91
|
+
export declare function isFirstPartyHarnessProvider(value: unknown): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The canonical provider for any spelling of the first-party harness; every
|
|
94
|
+
* other value is returned UNCHANGED (this is not a general normaliser — the
|
|
95
|
+
* caller's own normalisation still owns case and shape for other providers).
|
|
96
|
+
*/
|
|
97
|
+
export declare function canonicalHarnessProvider<T>(value: T): T | string;
|
|
98
|
+
/**
|
|
99
|
+
* Every spelling a stored row for this provider may carry, canonical first —
|
|
100
|
+
* for a Mongo `$in` filter while rows written before a flip still exist. Any
|
|
101
|
+
* other provider is returned as a one-element list.
|
|
102
|
+
*/
|
|
103
|
+
export declare function harnessProviderSpellings(value: string): string[];
|
|
104
|
+
/** The spelling to put ON THE WIRE to a daemon; other providers pass through. */
|
|
105
|
+
export declare function wireHarnessProvider(value: string): string;
|
|
106
|
+
/** True when two provider values name the same harness, whatever spelling each uses. */
|
|
107
|
+
export declare function isSameHarnessProvider(a: unknown, b: unknown): boolean;
|
|
108
|
+
export declare function firstPartyHarnessCapability(provider?: string): string;
|
|
109
|
+
/** Every capability spelling, canonical first. */
|
|
110
|
+
export declare function firstPartyHarnessCapabilities(): readonly string[];
|
|
111
|
+
/** The capability a daemon advertises. */
|
|
112
|
+
export declare function firstPartyHarnessWireCapability(): string;
|
|
113
|
+
export declare function isFirstPartyHarnessCapability(value: unknown): boolean;
|
|
114
|
+
/** `<alias>_session` → `<provider>_session`; every other value unchanged. */
|
|
115
|
+
export declare function canonicalSessionCapability<T>(value: T): T | string;
|
|
116
|
+
/**
|
|
117
|
+
* Whether a capability list contains `capability` under ANY accepted spelling.
|
|
118
|
+
*
|
|
119
|
+
* A daemon advertises the capability it was built with, and a daemon on a user's
|
|
120
|
+
* machine may be any version, so around a rename the same harness arrives as
|
|
121
|
+
* more than one `<provider>_session`. An exact `includes` against the canonical
|
|
122
|
+
* spelling reads the older one as "not installed" — a card that never lights up,
|
|
123
|
+
* a dispatch refused — with no error. Every other capability compares exactly.
|
|
124
|
+
*/
|
|
125
|
+
export declare function advertisesSessionCapability(capabilities: readonly unknown[] | null | undefined, capability: string): boolean;
|
|
126
|
+
export declare function firstPartyHarnessEnvironment(provider?: string): string;
|
|
127
|
+
/** Every environment spelling, canonical first. */
|
|
128
|
+
export declare function firstPartyHarnessEnvironments(): readonly string[];
|
|
129
|
+
export declare function isFirstPartyHarnessEnvironment(value: unknown): boolean;
|
|
130
|
+
/** `local-<alias>` → `local-<provider>`; every other value unchanged. */
|
|
131
|
+
export declare function canonicalExecutionEnvironment<T>(value: T): T | string;
|
|
132
|
+
/** Binary file name. `platform` is a `process.platform` value; only `win32` differs. */
|
|
133
|
+
export declare function firstPartyHarnessBinaryName(provider?: string, platform?: string): string;
|
|
134
|
+
/** Every binary file name, canonical first — the lookup order. */
|
|
135
|
+
export declare function firstPartyHarnessBinaryNames(platform?: string): readonly string[];
|
|
136
|
+
/**
|
|
137
|
+
* The engine home directory name under the skrr config root.
|
|
138
|
+
*
|
|
139
|
+
* It follows the ENGINE's namespace (`FIRST_PARTY_HARNESS_ENGINE.appName`), not
|
|
140
|
+
* the provider slug, because it is one directory with two owners: the platform
|
|
141
|
+
* installs the binary into `<home>/bin`, and the engine reads its own config and
|
|
142
|
+
* the managed `AGENTS.md` from `<home>`. Deriving it from the provider would, on
|
|
143
|
+
* a fresh install after a provider rename, create a second directory the engine
|
|
144
|
+
* never reads — managed instructions would stop applying with no error. It moves
|
|
145
|
+
* when the engine's namespace moves, and not before.
|
|
146
|
+
*/
|
|
147
|
+
export declare function firstPartyHarnessHomeDirname(): string;
|
|
148
|
+
/** Signed release manifest file name. */
|
|
149
|
+
export declare function firstPartyHarnessManifestFile(provider?: string): string;
|
|
150
|
+
/**
|
|
151
|
+
* The update feed ORIGIN. Not a product name, and not moved by this identity:
|
|
152
|
+
* a feed host sits inside signed manifests (naming map §2 "Update feed").
|
|
153
|
+
*/
|
|
154
|
+
export declare const FIRST_PARTY_HARNESS_FEED_ORIGIN = "https://updates.oversky.ai";
|
|
155
|
+
/** Object-key prefix for one spelling's feed, e.g. `skrr-code/`. */
|
|
156
|
+
export declare function firstPartyHarnessFeedPrefix(provider?: string): string;
|
|
157
|
+
/** Every feed prefix, canonical first. Publishing writes all of them. */
|
|
158
|
+
export declare function firstPartyHarnessFeedPrefixes(): readonly string[];
|
|
159
|
+
/** Object-key prefix the fork stages unsigned builds under, e.g. `skrr-code-staging/`. */
|
|
160
|
+
export declare function firstPartyHarnessStagingPrefix(provider?: string): string;
|
|
161
|
+
/** Default feed base URL for one spelling. */
|
|
162
|
+
export declare function firstPartyHarnessDefaultFeedBase(provider?: string): string;
|
|
163
|
+
export interface FirstPartyHarnessEnvName {
|
|
164
|
+
/** Brand-neutral name. Set this one. */
|
|
165
|
+
readonly name: string;
|
|
166
|
+
/** Older names still read, in precedence order, until contract. */
|
|
167
|
+
readonly legacy: readonly string[];
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Every environment variable the platform reads for the first-party harness,
|
|
171
|
+
* by purpose. The neutral name wins; a legacy name is read only when the neutral
|
|
172
|
+
* one is unset or blank, because a variable set in an ECS task definition, a
|
|
173
|
+
* user's shell or a LaunchAgent does not change when the code does.
|
|
174
|
+
*/
|
|
175
|
+
export declare const FIRST_PARTY_HARNESS_ENV: Readonly<{
|
|
176
|
+
/** Absolute path to an engine binary, overriding resolution. */
|
|
177
|
+
path: FirstPartyHarnessEnvName;
|
|
178
|
+
/** Forces the CLI's managed-inference mode. */
|
|
179
|
+
managed: FirstPartyHarnessEnvName;
|
|
180
|
+
/** Update channel. */
|
|
181
|
+
channel: FirstPartyHarnessEnvName;
|
|
182
|
+
/** Update-feed base URL override. */
|
|
183
|
+
updateFeedBase: FirstPartyHarnessEnvName;
|
|
184
|
+
/** Path to a file of development release keys. */
|
|
185
|
+
devKeys: FirstPartyHarnessEnvName;
|
|
186
|
+
/** Engine version the desktop build bundles. */
|
|
187
|
+
bundleVersion: FirstPartyHarnessEnvName;
|
|
188
|
+
/** Engine home override (the engine reads its own name too — see ENGINE env below). */
|
|
189
|
+
home: FirstPartyHarnessEnvName;
|
|
190
|
+
/** Engine version baked into the cloud-coding image. */
|
|
191
|
+
cloudCodingVersion: FirstPartyHarnessEnvName;
|
|
192
|
+
/** Engine version baked into the Dedicated Runtime AMI. */
|
|
193
|
+
dedicatedRuntimeVersion: FirstPartyHarnessEnvName;
|
|
194
|
+
/** Engine version the desktop release workflow bundles. */
|
|
195
|
+
desktopBundledVersion: FirstPartyHarnessEnvName;
|
|
196
|
+
/** Update-feed bucket used by publish and promote. */
|
|
197
|
+
updatesBucket: FirstPartyHarnessEnvName;
|
|
198
|
+
/** Release signing key (CI secret). */
|
|
199
|
+
signingKey: FirstPartyHarnessEnvName;
|
|
200
|
+
/** Release signing key id (CI secret). */
|
|
201
|
+
signingKeyId: FirstPartyHarnessEnvName;
|
|
202
|
+
}>;
|
|
203
|
+
export type FirstPartyHarnessEnvKey = keyof typeof FIRST_PARTY_HARNESS_ENV;
|
|
204
|
+
export interface FirstPartyHarnessEnvReading {
|
|
205
|
+
/** Trimmed, non-empty value, or undefined when nothing is set. */
|
|
206
|
+
readonly value: string | undefined;
|
|
207
|
+
/** The variable that supplied `value`. */
|
|
208
|
+
readonly name: string | undefined;
|
|
209
|
+
/** True when the value came from a legacy name — worth telling the operator. */
|
|
210
|
+
readonly legacy: boolean;
|
|
211
|
+
}
|
|
212
|
+
/** Every name for one purpose, neutral first — for spawn-env forwarding and sanitisers. */
|
|
213
|
+
export declare function firstPartyHarnessEnvNames(key: FirstPartyHarnessEnvKey): readonly string[];
|
|
214
|
+
/** Read one purpose's variable: neutral name first, legacy names after. */
|
|
215
|
+
export declare function readFirstPartyHarnessEnv(env: Readonly<Record<string, string | undefined>>, key: FirstPartyHarnessEnvKey): FirstPartyHarnessEnvReading;
|
|
216
|
+
/**
|
|
217
|
+
* Names the ENGINE itself defines and reads. The platform sets or reads them
|
|
218
|
+
* across the daemon↔engine boundary, so they are recorded here as values rather
|
|
219
|
+
* than scattered as literals — but they are the fork's to change, and moving
|
|
220
|
+
* one is a two-sided change (contract §6). Not part of this identity's rename.
|
|
221
|
+
*/
|
|
222
|
+
export declare const FIRST_PARTY_HARNESS_ENGINE: Readonly<{
|
|
223
|
+
/**
|
|
224
|
+
* The engine's state namespace: XDG dirs, project marker, config basename, and
|
|
225
|
+
* the engine home under the skrr root (`firstPartyHarnessHomeDirname`).
|
|
226
|
+
*/
|
|
227
|
+
appName: "sky-code";
|
|
228
|
+
/**
|
|
229
|
+
* Earlier `appName`s whose home directory `migrateFirstPartyHarnessHome` moves
|
|
230
|
+
* onto the current one. Empty until the engine's namespace is renamed.
|
|
231
|
+
*/
|
|
232
|
+
legacyAppNames: readonly string[];
|
|
233
|
+
/** Project-local configuration directory inside a user's repository. */
|
|
234
|
+
projectDirectory: ".sky-code";
|
|
235
|
+
/** Environment variables the engine reads. */
|
|
236
|
+
env: Readonly<{
|
|
237
|
+
serverPassword: "SKY_CODE_SERVER_PASSWORD";
|
|
238
|
+
serverUsername: "SKY_CODE_SERVER_USERNAME";
|
|
239
|
+
home: "SKY_CODE_HOME";
|
|
240
|
+
config: "SKY_CODE_CONFIG";
|
|
241
|
+
appName: "SKY_CODE_APP_NAME";
|
|
242
|
+
scriptName: "SKY_CODE_SCRIPT_NAME";
|
|
243
|
+
allowUpstreamEgress: "SKY_CODE_ALLOW_UPSTREAM_EGRESS";
|
|
244
|
+
compatOpencode: "SKY_CODE_COMPAT_OPENCODE";
|
|
245
|
+
noCompatPrompts: "SKY_CODE_NO_COMPAT_PROMPTS";
|
|
246
|
+
}>;
|
|
247
|
+
}>;
|
|
248
|
+
export {};
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first-party harness identity — the ONLY place its product name is written.
|
|
3
|
+
*
|
|
4
|
+
* "First-party harness" is the harness provider this platform builds, signs,
|
|
5
|
+
* distributes and installs itself: today a fork of OpenCode sold as skrr Code.
|
|
6
|
+
* It is a different axis from trust Tier 1 in `harnessTrust.ts`, whose
|
|
7
|
+
* "first-party" means an audited VENDOR harness such as Claude Code.
|
|
8
|
+
*
|
|
9
|
+
* ── Why a module, not a find/replace ──────────────────────────────────────
|
|
10
|
+
*
|
|
11
|
+
* The product was renamed twice ("OverSky" engine → "Sky Code" → "skrr Code"),
|
|
12
|
+
* and because its name was used as an IDENTIFIER — in file names, function
|
|
13
|
+
* names, env vars, workflow inputs, Mongo values, wire events — the second
|
|
14
|
+
* rename left 2,826 occurrences in 361 files spelled eleven ways. Every one was
|
|
15
|
+
* a place the next rename would have to find again.
|
|
16
|
+
*
|
|
17
|
+
* So the rule is: the product name is a VALUE held here, and every NAME in the
|
|
18
|
+
* codebase is brand-neutral and reads it. Renaming the product again is:
|
|
19
|
+
*
|
|
20
|
+
* 1. set `displayName` and `provider`;
|
|
21
|
+
* 2. move the old `provider` to the front of `aliases`;
|
|
22
|
+
* 3. leave `wireProvider` on the spelling installed daemons still speak;
|
|
23
|
+
* 4. regenerate `first-party-harness.json`
|
|
24
|
+
* (`node --import tsx scripts/emit-first-party-harness-json.mjs`);
|
|
25
|
+
* 5. ship the data migration, which is generic over `aliases`.
|
|
26
|
+
*
|
|
27
|
+
* No identifier, file, env var name or workflow input moves.
|
|
28
|
+
*
|
|
29
|
+
* ── Three spellings, kept apart on purpose ────────────────────────────────
|
|
30
|
+
*
|
|
31
|
+
* `provider` CANONICAL. What the platform stores, returns and renders.
|
|
32
|
+
* `aliases` ACCEPTED on every ingress until contract, and normalised to
|
|
33
|
+
* canonical at the edge. Nothing new is ever written with one.
|
|
34
|
+
* `wireProvider` What the server and a daemon say to EACH OTHER — the
|
|
35
|
+
* capability a daemon advertises, `daemon:<p>:request|response`,
|
|
36
|
+
* the `provider` of a session RPC. It moves LAST, because a
|
|
37
|
+
* daemon on a user's machine may be any version and the server
|
|
38
|
+
* cannot tell which one sent a request.
|
|
39
|
+
*
|
|
40
|
+
* The old code treated those three as one string, which is why no single
|
|
41
|
+
* change could rename it safely. See
|
|
42
|
+
* `docs/architecture/skrr-code-identifier-rename-2026-09-13.md`.
|
|
43
|
+
*
|
|
44
|
+
* ── Constraints on this file ──────────────────────────────────────────────
|
|
45
|
+
*
|
|
46
|
+
* Pure: no `node:` imports, no `process` at module load. It is published as the
|
|
47
|
+
* `@skrr-ai/auth-core/first-party-harness` subpath so the browser client and
|
|
48
|
+
* the React Native app can read it, and a Node-only import here would break
|
|
49
|
+
* both bundles at a distance.
|
|
50
|
+
*/
|
|
51
|
+
/** A slug usable as a directory name, a capability prefix and an event segment. */
|
|
52
|
+
const SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
53
|
+
function defineIdentity(identity) {
|
|
54
|
+
const spellings = [identity.provider, ...identity.aliases];
|
|
55
|
+
for (const spelling of spellings) {
|
|
56
|
+
if (!SLUG.test(spelling)) {
|
|
57
|
+
throw new Error(`first-party harness spelling ${JSON.stringify(spelling)} is not a slug; it becomes a ` +
|
|
58
|
+
`directory name, a capability prefix and a wire event segment`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (new Set(spellings).size !== spellings.length) {
|
|
62
|
+
throw new Error('first-party harness provider and aliases must be distinct');
|
|
63
|
+
}
|
|
64
|
+
if (!spellings.includes(identity.wireProvider)) {
|
|
65
|
+
throw new Error(`first-party harness wireProvider ${JSON.stringify(identity.wireProvider)} must be the ` +
|
|
66
|
+
'provider or one of its aliases — a peer can only accept a spelling it knows');
|
|
67
|
+
}
|
|
68
|
+
return Object.freeze({ ...identity, aliases: Object.freeze([...identity.aliases]) });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* THE identity — the only literal product name in the codebase.
|
|
72
|
+
*
|
|
73
|
+
* Phase: EXPAND. `provider` is still the spelling every stored row carries;
|
|
74
|
+
* `skrr-code` is accepted everywhere so the flip can follow once every reader
|
|
75
|
+
* has shipped.
|
|
76
|
+
*/
|
|
77
|
+
const IDENTITY = {
|
|
78
|
+
displayName: 'skrr Code',
|
|
79
|
+
command: 'skrr code',
|
|
80
|
+
provider: 'sky-code',
|
|
81
|
+
aliases: ['skrr-code'],
|
|
82
|
+
wireProvider: 'sky-code',
|
|
83
|
+
};
|
|
84
|
+
export const FIRST_PARTY_HARNESS = defineIdentity(IDENTITY);
|
|
85
|
+
/** The canonical slug with its literal type, for `as const` tuples and keyed tables. */
|
|
86
|
+
export const FIRST_PARTY_HARNESS_PROVIDER = IDENTITY.provider;
|
|
87
|
+
const SPELLINGS = Object.freeze([
|
|
88
|
+
FIRST_PARTY_HARNESS.provider,
|
|
89
|
+
...FIRST_PARTY_HARNESS.aliases,
|
|
90
|
+
]);
|
|
91
|
+
const SPELLING_SET = new Set(SPELLINGS);
|
|
92
|
+
const SESSION_SUFFIX = '_session';
|
|
93
|
+
const ENVIRONMENT_PREFIX = 'local-';
|
|
94
|
+
function asSlug(value) {
|
|
95
|
+
if (typeof value !== 'string')
|
|
96
|
+
return null;
|
|
97
|
+
const slug = value.trim().toLowerCase();
|
|
98
|
+
return slug ? slug : null;
|
|
99
|
+
}
|
|
100
|
+
/** Every spelling, canonical first. The order is the resolution order. */
|
|
101
|
+
export function firstPartyHarnessSpellings() {
|
|
102
|
+
return SPELLINGS;
|
|
103
|
+
}
|
|
104
|
+
/** True for the canonical provider or any alias (case- and whitespace-insensitive). */
|
|
105
|
+
export function isFirstPartyHarnessProvider(value) {
|
|
106
|
+
const slug = asSlug(value);
|
|
107
|
+
return slug !== null && SPELLING_SET.has(slug);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The canonical provider for any spelling of the first-party harness; every
|
|
111
|
+
* other value is returned UNCHANGED (this is not a general normaliser — the
|
|
112
|
+
* caller's own normalisation still owns case and shape for other providers).
|
|
113
|
+
*/
|
|
114
|
+
export function canonicalHarnessProvider(value) {
|
|
115
|
+
return isFirstPartyHarnessProvider(value) ? FIRST_PARTY_HARNESS.provider : value;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Every spelling a stored row for this provider may carry, canonical first —
|
|
119
|
+
* for a Mongo `$in` filter while rows written before a flip still exist. Any
|
|
120
|
+
* other provider is returned as a one-element list.
|
|
121
|
+
*/
|
|
122
|
+
export function harnessProviderSpellings(value) {
|
|
123
|
+
return isFirstPartyHarnessProvider(value) ? [...SPELLINGS] : [value];
|
|
124
|
+
}
|
|
125
|
+
/** The spelling to put ON THE WIRE to a daemon; other providers pass through. */
|
|
126
|
+
export function wireHarnessProvider(value) {
|
|
127
|
+
return isFirstPartyHarnessProvider(value) ? FIRST_PARTY_HARNESS.wireProvider : value;
|
|
128
|
+
}
|
|
129
|
+
/** True when two provider values name the same harness, whatever spelling each uses. */
|
|
130
|
+
export function isSameHarnessProvider(a, b) {
|
|
131
|
+
if (typeof a !== 'string' || typeof b !== 'string')
|
|
132
|
+
return false;
|
|
133
|
+
return (canonicalHarnessProvider(a.trim().toLowerCase()) ===
|
|
134
|
+
canonicalHarnessProvider(b.trim().toLowerCase()));
|
|
135
|
+
}
|
|
136
|
+
/* ── Derived: session capability ─────────────────────────────────────────── */
|
|
137
|
+
export function firstPartyHarnessCapability(provider = FIRST_PARTY_HARNESS.provider) {
|
|
138
|
+
return `${provider}${SESSION_SUFFIX}`;
|
|
139
|
+
}
|
|
140
|
+
/** Every capability spelling, canonical first. */
|
|
141
|
+
export function firstPartyHarnessCapabilities() {
|
|
142
|
+
return SPELLINGS.map((spelling) => firstPartyHarnessCapability(spelling));
|
|
143
|
+
}
|
|
144
|
+
/** The capability a daemon advertises. */
|
|
145
|
+
export function firstPartyHarnessWireCapability() {
|
|
146
|
+
return firstPartyHarnessCapability(FIRST_PARTY_HARNESS.wireProvider);
|
|
147
|
+
}
|
|
148
|
+
export function isFirstPartyHarnessCapability(value) {
|
|
149
|
+
const slug = asSlug(value);
|
|
150
|
+
if (slug === null || !slug.endsWith(SESSION_SUFFIX))
|
|
151
|
+
return false;
|
|
152
|
+
return SPELLING_SET.has(slug.slice(0, -SESSION_SUFFIX.length));
|
|
153
|
+
}
|
|
154
|
+
/** `<alias>_session` → `<provider>_session`; every other value unchanged. */
|
|
155
|
+
export function canonicalSessionCapability(value) {
|
|
156
|
+
return isFirstPartyHarnessCapability(value) ? firstPartyHarnessCapability() : value;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Whether a capability list contains `capability` under ANY accepted spelling.
|
|
160
|
+
*
|
|
161
|
+
* A daemon advertises the capability it was built with, and a daemon on a user's
|
|
162
|
+
* machine may be any version, so around a rename the same harness arrives as
|
|
163
|
+
* more than one `<provider>_session`. An exact `includes` against the canonical
|
|
164
|
+
* spelling reads the older one as "not installed" — a card that never lights up,
|
|
165
|
+
* a dispatch refused — with no error. Every other capability compares exactly.
|
|
166
|
+
*/
|
|
167
|
+
export function advertisesSessionCapability(capabilities, capability) {
|
|
168
|
+
if (!Array.isArray(capabilities) || capabilities.length === 0)
|
|
169
|
+
return false;
|
|
170
|
+
const wanted = canonicalSessionCapability(capability);
|
|
171
|
+
return capabilities.some((advertised) => canonicalSessionCapability(advertised) === wanted);
|
|
172
|
+
}
|
|
173
|
+
/* ── Derived: pinned execution environment ───────────────────────────────── */
|
|
174
|
+
export function firstPartyHarnessEnvironment(provider = FIRST_PARTY_HARNESS.provider) {
|
|
175
|
+
return `${ENVIRONMENT_PREFIX}${provider}`;
|
|
176
|
+
}
|
|
177
|
+
/** Every environment spelling, canonical first. */
|
|
178
|
+
export function firstPartyHarnessEnvironments() {
|
|
179
|
+
return SPELLINGS.map((spelling) => firstPartyHarnessEnvironment(spelling));
|
|
180
|
+
}
|
|
181
|
+
export function isFirstPartyHarnessEnvironment(value) {
|
|
182
|
+
const slug = asSlug(value);
|
|
183
|
+
if (slug === null || !slug.startsWith(ENVIRONMENT_PREFIX))
|
|
184
|
+
return false;
|
|
185
|
+
return SPELLING_SET.has(slug.slice(ENVIRONMENT_PREFIX.length));
|
|
186
|
+
}
|
|
187
|
+
/** `local-<alias>` → `local-<provider>`; every other value unchanged. */
|
|
188
|
+
export function canonicalExecutionEnvironment(value) {
|
|
189
|
+
return isFirstPartyHarnessEnvironment(value) ? firstPartyHarnessEnvironment() : value;
|
|
190
|
+
}
|
|
191
|
+
/* ── Derived: on-disk and distribution names ─────────────────────────────── */
|
|
192
|
+
/** Binary file name. `platform` is a `process.platform` value; only `win32` differs. */
|
|
193
|
+
export function firstPartyHarnessBinaryName(provider = FIRST_PARTY_HARNESS.provider, platform) {
|
|
194
|
+
return platform === 'win32' ? `${provider}.exe` : provider;
|
|
195
|
+
}
|
|
196
|
+
/** Every binary file name, canonical first — the lookup order. */
|
|
197
|
+
export function firstPartyHarnessBinaryNames(platform) {
|
|
198
|
+
return SPELLINGS.map((spelling) => firstPartyHarnessBinaryName(spelling, platform));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The engine home directory name under the skrr config root.
|
|
202
|
+
*
|
|
203
|
+
* It follows the ENGINE's namespace (`FIRST_PARTY_HARNESS_ENGINE.appName`), not
|
|
204
|
+
* the provider slug, because it is one directory with two owners: the platform
|
|
205
|
+
* installs the binary into `<home>/bin`, and the engine reads its own config and
|
|
206
|
+
* the managed `AGENTS.md` from `<home>`. Deriving it from the provider would, on
|
|
207
|
+
* a fresh install after a provider rename, create a second directory the engine
|
|
208
|
+
* never reads — managed instructions would stop applying with no error. It moves
|
|
209
|
+
* when the engine's namespace moves, and not before.
|
|
210
|
+
*/
|
|
211
|
+
export function firstPartyHarnessHomeDirname() {
|
|
212
|
+
return FIRST_PARTY_HARNESS_ENGINE.appName;
|
|
213
|
+
}
|
|
214
|
+
/** Signed release manifest file name. */
|
|
215
|
+
export function firstPartyHarnessManifestFile(provider = FIRST_PARTY_HARNESS.provider) {
|
|
216
|
+
return `${provider}-version.json`;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The update feed ORIGIN. Not a product name, and not moved by this identity:
|
|
220
|
+
* a feed host sits inside signed manifests (naming map §2 "Update feed").
|
|
221
|
+
*/
|
|
222
|
+
export const FIRST_PARTY_HARNESS_FEED_ORIGIN = 'https://updates.oversky.ai';
|
|
223
|
+
/** Object-key prefix for one spelling's feed, e.g. `skrr-code/`. */
|
|
224
|
+
export function firstPartyHarnessFeedPrefix(provider = FIRST_PARTY_HARNESS.provider) {
|
|
225
|
+
return `${provider}/`;
|
|
226
|
+
}
|
|
227
|
+
/** Every feed prefix, canonical first. Publishing writes all of them. */
|
|
228
|
+
export function firstPartyHarnessFeedPrefixes() {
|
|
229
|
+
return SPELLINGS.map((spelling) => firstPartyHarnessFeedPrefix(spelling));
|
|
230
|
+
}
|
|
231
|
+
/** Object-key prefix the fork stages unsigned builds under, e.g. `skrr-code-staging/`. */
|
|
232
|
+
export function firstPartyHarnessStagingPrefix(provider = FIRST_PARTY_HARNESS.provider) {
|
|
233
|
+
return `${provider}-staging/`;
|
|
234
|
+
}
|
|
235
|
+
/** Default feed base URL for one spelling. */
|
|
236
|
+
export function firstPartyHarnessDefaultFeedBase(provider = FIRST_PARTY_HARNESS.provider) {
|
|
237
|
+
return `${FIRST_PARTY_HARNESS_FEED_ORIGIN}/${provider}`;
|
|
238
|
+
}
|
|
239
|
+
function envName(name, legacy) {
|
|
240
|
+
return Object.freeze({ name, legacy: Object.freeze([...legacy]) });
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Every environment variable the platform reads for the first-party harness,
|
|
244
|
+
* by purpose. The neutral name wins; a legacy name is read only when the neutral
|
|
245
|
+
* one is unset or blank, because a variable set in an ECS task definition, a
|
|
246
|
+
* user's shell or a LaunchAgent does not change when the code does.
|
|
247
|
+
*/
|
|
248
|
+
export const FIRST_PARTY_HARNESS_ENV = Object.freeze({
|
|
249
|
+
/** Absolute path to an engine binary, overriding resolution. */
|
|
250
|
+
path: envName('SKRR_FIRST_PARTY_HARNESS_PATH', ['OVERSKY_SKY_CODE_PATH']),
|
|
251
|
+
/** Forces the CLI's managed-inference mode. */
|
|
252
|
+
managed: envName('SKRR_FIRST_PARTY_HARNESS_MANAGED', ['OVERSKY_SKY_CODE_MANAGED']),
|
|
253
|
+
/** Update channel. */
|
|
254
|
+
channel: envName('SKRR_FIRST_PARTY_HARNESS_CHANNEL', ['OVERSKY_SKY_CODE_CHANNEL']),
|
|
255
|
+
/** Update-feed base URL override. */
|
|
256
|
+
updateFeedBase: envName('SKRR_FIRST_PARTY_HARNESS_UPDATE_FEED_BASE', [
|
|
257
|
+
'OVERSKY_SKY_CODE_UPDATE_FEED_BASE',
|
|
258
|
+
]),
|
|
259
|
+
/** Path to a file of development release keys. */
|
|
260
|
+
devKeys: envName('SKRR_FIRST_PARTY_HARNESS_DEV_KEYS', ['OVERSKY_SKY_CODE_DEV_KEYS']),
|
|
261
|
+
/** Engine version the desktop build bundles. */
|
|
262
|
+
bundleVersion: envName('SKRR_FIRST_PARTY_HARNESS_BUNDLE_VERSION', ['OVERSKY_BUNDLE_SKY_CODE']),
|
|
263
|
+
/** Engine home override (the engine reads its own name too — see ENGINE env below). */
|
|
264
|
+
home: envName('SKRR_FIRST_PARTY_HARNESS_HOME', ['SKY_CODE_HOME']),
|
|
265
|
+
/** Engine version baked into the cloud-coding image. */
|
|
266
|
+
cloudCodingVersion: envName('CLOUD_CODING_FIRST_PARTY_HARNESS_VERSION', [
|
|
267
|
+
'CLOUD_CODING_SKY_CODE_VERSION',
|
|
268
|
+
]),
|
|
269
|
+
/** Engine version baked into the Dedicated Runtime AMI. */
|
|
270
|
+
dedicatedRuntimeVersion: envName('SKRR_DEDICATED_RUNTIME_FIRST_PARTY_HARNESS_VERSION', [
|
|
271
|
+
'SKRR_DEDICATED_RUNTIME_SKY_CODE_VERSION',
|
|
272
|
+
]),
|
|
273
|
+
/** Engine version the desktop release workflow bundles. */
|
|
274
|
+
desktopBundledVersion: envName('DESKTOP_BUNDLED_FIRST_PARTY_HARNESS_VERSION', [
|
|
275
|
+
'DESKTOP_BUNDLED_SKY_CODE_VERSION',
|
|
276
|
+
]),
|
|
277
|
+
/** Update-feed bucket used by publish and promote. */
|
|
278
|
+
updatesBucket: envName('FIRST_PARTY_HARNESS_UPDATES_BUCKET', ['SKY_CODE_UPDATES_BUCKET']),
|
|
279
|
+
/** Release signing key (CI secret). */
|
|
280
|
+
signingKey: envName('FIRST_PARTY_HARNESS_SIGNING_KEY', ['SKY_CODE_SIGNING_KEY']),
|
|
281
|
+
/** Release signing key id (CI secret). */
|
|
282
|
+
signingKeyId: envName('FIRST_PARTY_HARNESS_SIGNING_KEY_ID', ['SKY_CODE_SIGNING_KEY_ID']),
|
|
283
|
+
});
|
|
284
|
+
/** Every name for one purpose, neutral first — for spawn-env forwarding and sanitisers. */
|
|
285
|
+
export function firstPartyHarnessEnvNames(key) {
|
|
286
|
+
const entry = FIRST_PARTY_HARNESS_ENV[key];
|
|
287
|
+
return [entry.name, ...entry.legacy];
|
|
288
|
+
}
|
|
289
|
+
/** Read one purpose's variable: neutral name first, legacy names after. */
|
|
290
|
+
export function readFirstPartyHarnessEnv(env, key) {
|
|
291
|
+
const entry = FIRST_PARTY_HARNESS_ENV[key];
|
|
292
|
+
for (const name of [entry.name, ...entry.legacy]) {
|
|
293
|
+
const raw = env[name];
|
|
294
|
+
if (typeof raw === 'string' && raw.trim() !== '') {
|
|
295
|
+
return { value: raw.trim(), name, legacy: name !== entry.name };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return { value: undefined, name: undefined, legacy: false };
|
|
299
|
+
}
|
|
300
|
+
/* ── The ENGINE's own namespace (defined inside the fork) ───────────────── */
|
|
301
|
+
/**
|
|
302
|
+
* Names the ENGINE itself defines and reads. The platform sets or reads them
|
|
303
|
+
* across the daemon↔engine boundary, so they are recorded here as values rather
|
|
304
|
+
* than scattered as literals — but they are the fork's to change, and moving
|
|
305
|
+
* one is a two-sided change (contract §6). Not part of this identity's rename.
|
|
306
|
+
*/
|
|
307
|
+
export const FIRST_PARTY_HARNESS_ENGINE = Object.freeze({
|
|
308
|
+
/**
|
|
309
|
+
* The engine's state namespace: XDG dirs, project marker, config basename, and
|
|
310
|
+
* the engine home under the skrr root (`firstPartyHarnessHomeDirname`).
|
|
311
|
+
*/
|
|
312
|
+
appName: 'sky-code',
|
|
313
|
+
/**
|
|
314
|
+
* Earlier `appName`s whose home directory `migrateFirstPartyHarnessHome` moves
|
|
315
|
+
* onto the current one. Empty until the engine's namespace is renamed.
|
|
316
|
+
*/
|
|
317
|
+
legacyAppNames: Object.freeze([]),
|
|
318
|
+
/** Project-local configuration directory inside a user's repository. */
|
|
319
|
+
projectDirectory: '.sky-code',
|
|
320
|
+
/** Environment variables the engine reads. */
|
|
321
|
+
env: Object.freeze({
|
|
322
|
+
serverPassword: 'SKY_CODE_SERVER_PASSWORD',
|
|
323
|
+
serverUsername: 'SKY_CODE_SERVER_USERNAME',
|
|
324
|
+
home: 'SKY_CODE_HOME',
|
|
325
|
+
config: 'SKY_CODE_CONFIG',
|
|
326
|
+
appName: 'SKY_CODE_APP_NAME',
|
|
327
|
+
scriptName: 'SKY_CODE_SCRIPT_NAME',
|
|
328
|
+
allowUpstreamEgress: 'SKY_CODE_ALLOW_UPSTREAM_EGRESS',
|
|
329
|
+
compatOpencode: 'SKY_CODE_COMPAT_OPENCODE',
|
|
330
|
+
noCompatPrompts: 'SKY_CODE_NO_COMPAT_PROMPTS',
|
|
331
|
+
}),
|
|
332
|
+
});
|