@skrr-ai/cli 0.1.42 → 0.1.44
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/base-command.d.ts +2 -0
- package/dist/base-command.js +1 -0
- package/dist/commands/balance/index.js +1 -1
- package/dist/commands/balance/overage.js +4 -3
- package/dist/commands/balance/plan.js +10 -6
- package/dist/commands/balance/show.d.ts +32 -0
- package/dist/commands/balance/show.js +74 -3
- package/dist/commands/balance/usage/events.js +3 -2
- package/dist/commands/balance/usage.js +2 -1
- package/dist/commands/browser/install.js +3 -2
- package/dist/commands/browser/uninstall.js +3 -2
- package/dist/commands/code/handover.d.ts +1 -0
- package/dist/commands/code/handover.js +4 -0
- package/dist/commands/code/install.js +3 -2
- package/dist/commands/code/jobs/run.d.ts +1 -0
- package/dist/commands/code/jobs/run.js +4 -0
- package/dist/commands/daemon/install.js +7 -0
- package/dist/commands/harnesses/install.d.ts +11 -0
- package/dist/commands/harnesses/install.js +33 -14
- package/dist/commands/harnesses/installers.d.ts +10 -0
- package/dist/commands/harnesses/installers.js +31 -0
- package/dist/commands/harnesses/leases/show.js +14 -0
- package/dist/commands/harnesses/list.js +3 -2
- package/dist/commands/instructions/install.d.ts +22 -0
- package/dist/commands/instructions/install.js +83 -7
- package/dist/commands/instructions/list.js +5 -0
- package/dist/commands/instructions/show.d.ts +6 -0
- package/dist/commands/instructions/show.js +34 -1
- package/dist/commands/instructions/status.js +17 -1
- package/dist/commands/payments/wallet.js +2 -2
- package/dist/commands/tasks/attachments/set-role.d.ts +24 -0
- package/dist/commands/tasks/attachments/set-role.js +60 -0
- package/dist/commands/tasks/attachments/upload.d.ts +1 -0
- package/dist/commands/tasks/attachments/upload.js +18 -52
- package/dist/commands/tasks/comments/add.d.ts +1 -0
- package/dist/commands/tasks/comments/add.js +67 -2
- package/dist/commands/tasks/complete.d.ts +1 -0
- package/dist/commands/tasks/complete.js +56 -1
- package/dist/commands/tasks/create.d.ts +6 -0
- package/dist/commands/tasks/create.js +26 -3
- package/dist/commands/tasks/labels/attach.js +4 -0
- package/dist/commands/tasks/list.d.ts +1 -0
- package/dist/commands/tasks/list.js +9 -0
- package/dist/commands/tasks/result/submit.d.ts +3 -0
- package/dist/commands/tasks/result/submit.js +76 -8
- package/dist/commands/tasks/show.d.ts +23 -0
- package/dist/commands/tasks/show.js +61 -1
- package/dist/commands/tasks/update.js +16 -2
- package/dist/commands/tasks/updates/add.d.ts +1 -0
- package/dist/commands/tasks/updates/add.js +63 -0
- package/dist/commands/views/create.js +12 -2
- package/dist/commands/views/list.js +3 -2
- package/dist/commands/views/show.js +2 -0
- package/dist/lib/agentic-stream.d.ts +10 -4
- package/dist/lib/agentic-stream.js +25 -11
- package/dist/lib/api-fetch.js +7 -2
- package/dist/lib/cli-installers.d.ts +23 -4
- package/dist/lib/cli-installers.js +56 -8
- package/dist/lib/daemon-setup.d.ts +18 -1
- package/dist/lib/daemon-setup.js +33 -1
- package/dist/lib/dedicated-machines.js +4 -2
- package/dist/lib/file-mime.js +1 -1
- package/dist/lib/first-party-harness-agent.d.ts +16 -1
- package/dist/lib/first-party-harness-agent.js +47 -17
- package/dist/lib/first-party-harness-doctor.js +49 -48
- package/dist/lib/first-party-harness-managed.d.ts +9 -4
- package/dist/lib/first-party-harness-managed.js +13 -10
- package/dist/lib/first-party-harness.d.ts +32 -21
- package/dist/lib/first-party-harness.js +49 -31
- package/dist/lib/harness-provider-input.d.ts +18 -12
- package/dist/lib/harness-provider-input.js +18 -12
- package/dist/lib/harness-tiers.d.ts +4 -3
- package/dist/lib/harness-tiers.js +4 -3
- package/dist/lib/harnesses.d.ts +6 -0
- package/dist/lib/html-text.js +25 -0
- package/dist/lib/instruction-input.d.ts +21 -0
- package/dist/lib/instruction-input.js +30 -0
- package/dist/lib/instruction-provenance.d.ts +54 -0
- package/dist/lib/instruction-provenance.js +84 -0
- package/dist/lib/session-task-endpoints.d.ts +1 -1
- package/dist/lib/session-task-endpoints.js +3 -0
- package/dist/lib/task-asset-upload.d.ts +84 -0
- package/dist/lib/task-asset-upload.js +374 -0
- package/dist/lib/task-closure.d.ts +15 -0
- package/dist/lib/task-closure.js +20 -0
- package/dist/lib/task-view-render.d.ts +14 -0
- package/dist/lib/task-view-render.js +55 -0
- package/dist/lib/tasks.d.ts +26 -0
- package/dist/lib/tasks.js +38 -1
- package/dist/lib/views/vocabulary.d.ts +1 -1
- package/dist/lib/views/vocabulary.js +3 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +183 -58
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +286 -100
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +21 -33
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +24 -50
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +19 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +26 -10
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +9 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +9 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +1 -13
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/legacyStatePreflight.d.ts +21 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/legacyStatePreflight.js +75 -19
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +183 -58
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +279 -99
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +21 -33
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +24 -49
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +19 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +27 -11
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +9 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +9 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/legacyStatePreflight.d.ts +21 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/legacyStatePreflight.js +74 -19
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +4588 -4509
- package/dist/node_modules/@skrr-ai/data-provider/package.json +1 -1
- package/oclif.manifest.json +33980 -33832
- package/package.json +3 -3
|
@@ -42,17 +42,6 @@ const first_party_harness_1 = require("./first-party-harness");
|
|
|
42
42
|
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
43
43
|
const harness_tiers_1 = require("./harness-tiers");
|
|
44
44
|
const first_party_harness_managed_1 = require("./first-party-harness-managed");
|
|
45
|
-
/**
|
|
46
|
-
* The variable one purpose was read from, and — when that was an older name — the
|
|
47
|
-
* sentence that says so. `undefined` when the neutral name (or nothing) was used.
|
|
48
|
-
*/
|
|
49
|
-
function legacyEnvNote(key, name) {
|
|
50
|
-
const neutral = auth_core_1.FIRST_PARTY_HARNESS_ENV[key].name;
|
|
51
|
-
if (!name || name === neutral)
|
|
52
|
-
return undefined;
|
|
53
|
-
return (`${name} is an older name for this setting and is still read; ` +
|
|
54
|
-
`rename it to ${neutral}, which wins when both are set.`);
|
|
55
|
-
}
|
|
56
45
|
/**
|
|
57
46
|
* Project-level state dir — the ENGINE's own project marker
|
|
58
47
|
* (`FIRST_PARTY_HARNESS_ENGINE.projectDirectory`). Basename deliberately differs
|
|
@@ -78,10 +67,12 @@ function projectStateDir(cwd) {
|
|
|
78
67
|
* the answer one copy-paste away and keeps the property — and the promise is
|
|
79
68
|
* reworded to match what is delivered rather than the other way round.
|
|
80
69
|
*
|
|
81
|
-
* The URL is the CANONICAL feed candidate.
|
|
82
|
-
* each
|
|
83
|
-
*
|
|
84
|
-
*
|
|
70
|
+
* The URL is the CANONICAL feed candidate. While a rename's alias window is open
|
|
71
|
+
* a manifest may also be published under each alias (`firstPartyHarnessFeedCandidates`
|
|
72
|
+
* for a channel read), and an installer that finds nothing at the canonical URL
|
|
73
|
+
* tries those next — so the remedy names them too. A retired spelling is not
|
|
74
|
+
* among them: its channel pointers stopped moving when publishing stopped writing
|
|
75
|
+
* them, and naming one would point at a stale release. Without that, "the canonical URL 404s" would read as "there is no release"
|
|
85
76
|
* on a feed an older pipeline published under the other spelling. The doctor
|
|
86
77
|
* cannot say which candidate actually holds a release, because it does not probe;
|
|
87
78
|
* it says where to look, in the order an installer looks.
|
|
@@ -97,15 +88,13 @@ function releaseChannelCheck(env) {
|
|
|
97
88
|
manifestFilename: candidate.manifestFilename,
|
|
98
89
|
channel,
|
|
99
90
|
}));
|
|
100
|
-
const legacyNote = legacyEnvNote('channel', source);
|
|
101
91
|
if (invalid) {
|
|
102
92
|
return {
|
|
103
93
|
name: 'release-channel',
|
|
104
94
|
status: 'warn',
|
|
105
95
|
detail: `${source}='${invalid}' is not a channel; following '${channel}' instead — ${canonical}`,
|
|
106
96
|
remedy: `Set ${auth_core_1.FIRST_PARTY_HARNESS_ENV.channel.name} to one of ${auth_core_1.FIRST_PARTY_HARNESS_CHANNELS.join(', ')}, ` +
|
|
107
|
-
'or unset it to follow the default.'
|
|
108
|
-
(legacyNote ? ` ${legacyNote}` : ''),
|
|
97
|
+
'or unset it to follow the default.',
|
|
109
98
|
};
|
|
110
99
|
}
|
|
111
100
|
const alsoTried = alternates.filter((url) => url !== canonical);
|
|
@@ -114,10 +103,7 @@ function releaseChannelCheck(env) {
|
|
|
114
103
|
status: 'ok',
|
|
115
104
|
detail: `${channel} — ${canonical}`,
|
|
116
105
|
remedy: 'Fetch that URL to see whether the channel has a published release, and which version.' +
|
|
117
|
-
(alsoTried.length
|
|
118
|
-
? ` If it has none, an installer also tries ${alsoTried.join(', ')}.`
|
|
119
|
-
: '') +
|
|
120
|
-
(legacyNote ? ` ${legacyNote}` : ''),
|
|
106
|
+
(alsoTried.length ? ` If it has none, an installer also tries ${alsoTried.join(', ')}.` : ''),
|
|
121
107
|
};
|
|
122
108
|
}
|
|
123
109
|
/**
|
|
@@ -159,7 +145,8 @@ function strandedLegacyEngine(env) {
|
|
|
159
145
|
/**
|
|
160
146
|
* Whether a managed engine resolved under an OLDER spelling of its file name.
|
|
161
147
|
*
|
|
162
|
-
* Not a fault: resolution tries every spelling on purpose
|
|
148
|
+
* Not a fault: resolution tries every artifact spelling on purpose (a former one
|
|
149
|
+
* included — the file predates the rename), and the next
|
|
163
150
|
* `skrr code` run renames the file onto the canonical name (leaving a link at the
|
|
164
151
|
* old one). Said anyway, because a path that does not match the name everything
|
|
165
152
|
* else prints is exactly the surprise this module exists to explain.
|
|
@@ -196,14 +183,12 @@ function engineCheck(env) {
|
|
|
196
183
|
};
|
|
197
184
|
}
|
|
198
185
|
if (bin && source === 'env') {
|
|
199
|
-
// Name the variable, not just "env":
|
|
200
|
-
// and the
|
|
201
|
-
const legacyNote = resolution.legacyEnv ? legacyEnvNote('path', resolution.envName) : undefined;
|
|
186
|
+
// Name the variable, not just "env": an override is the one resolution the
|
|
187
|
+
// user set by hand, and the variable is what they would edit.
|
|
202
188
|
return {
|
|
203
189
|
name: 'engine',
|
|
204
190
|
status: 'ok',
|
|
205
191
|
detail: `${bin} (resolved via env ${resolution.envName})`,
|
|
206
|
-
...(legacyNote ? { remedy: legacyNote } : {}),
|
|
207
192
|
};
|
|
208
193
|
}
|
|
209
194
|
if (bin) {
|
|
@@ -232,7 +217,6 @@ function engineCheck(env) {
|
|
|
232
217
|
};
|
|
233
218
|
}
|
|
234
219
|
const override = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'path');
|
|
235
|
-
const legacyNote = legacyEnvNote('path', override.name);
|
|
236
220
|
if (override.value && !node_path_1.default.isAbsolute(override.value)) {
|
|
237
221
|
return {
|
|
238
222
|
name: 'engine',
|
|
@@ -241,7 +225,7 @@ function engineCheck(env) {
|
|
|
241
225
|
// agent-invoked command the cwd is attacker-influenced, so a repo
|
|
242
226
|
// containing a file named like the engine could otherwise hijack it.
|
|
243
227
|
detail: `${override.name} is set to a relative path ('${override.value}') and was ignored`,
|
|
244
|
-
remedy: `Set ${pathVar} to an absolute path
|
|
228
|
+
remedy: `Set ${pathVar} to an absolute path.`,
|
|
245
229
|
};
|
|
246
230
|
}
|
|
247
231
|
if (override.value) {
|
|
@@ -249,8 +233,7 @@ function engineCheck(env) {
|
|
|
249
233
|
name: 'engine',
|
|
250
234
|
status: 'fail',
|
|
251
235
|
detail: `${override.name}='${override.value}' is not an executable file`,
|
|
252
|
-
remedy: `Point it at a real ${auth_core_1.FIRST_PARTY_HARNESS.displayName} engine build, or unset it to fall back to PATH
|
|
253
|
-
(legacyNote ? ` ${legacyNote}` : ''),
|
|
236
|
+
remedy: `Point it at a real ${auth_core_1.FIRST_PARTY_HARNESS.displayName} engine build, or unset it to fall back to PATH.`,
|
|
254
237
|
};
|
|
255
238
|
}
|
|
256
239
|
return {
|
|
@@ -280,8 +263,16 @@ function stateDirCheck(cwd, env) {
|
|
|
280
263
|
remedy: `This is a build bug — report it. Do not run ${auth_core_1.FIRST_PARTY_HARNESS.displayName} from this directory.`,
|
|
281
264
|
};
|
|
282
265
|
}
|
|
266
|
+
// The engine still reads a project directory under a legacy namespace, after the
|
|
267
|
+
// current one (OSK-8674); one that exists is worth naming, or "not created yet"
|
|
268
|
+
// reads as "no project config" on a repository that has some.
|
|
269
|
+
const legacyProjects = (0, auth_core_1.firstPartyHarnessEngineProjectDirectories)()
|
|
270
|
+
.slice(1)
|
|
271
|
+
.map((directory) => node_path_1.default.join(node_path_1.default.resolve(cwd), directory))
|
|
272
|
+
.filter((directory) => (0, node_fs_1.existsSync)(directory));
|
|
283
273
|
const parts = [
|
|
284
274
|
`project: ${project}${(0, node_fs_1.existsSync)(project) ? '' : ' (not created yet)'}`,
|
|
275
|
+
...legacyProjects.map((directory) => `also read (legacy): ${directory}`),
|
|
285
276
|
`user: ${user}${(0, node_fs_1.existsSync)(user) ? '' : ' (not created yet)'}`,
|
|
286
277
|
];
|
|
287
278
|
return { name: 'state-paths', status: 'ok', detail: parts.join('; ') };
|
|
@@ -323,21 +314,29 @@ function compatCheck(cwd, env) {
|
|
|
323
314
|
// session only when the daemon links them in, which `skrr skills local` shows.
|
|
324
315
|
const root = node_path_1.default.resolve(cwd);
|
|
325
316
|
const home = env.HOME || (0, node_os_1.homedir)();
|
|
326
|
-
|
|
327
|
-
const noCompatPrompts =
|
|
317
|
+
// The engine reads its variables under every namespace it has had, current first.
|
|
318
|
+
const noCompatPrompts = (0, auth_core_1.readFirstPartyHarnessEngineEnv)(env, 'noCompatPrompts').name;
|
|
328
319
|
const engineHomeDir = (0, first_party_harness_1.engineInstructionHome)(env);
|
|
329
320
|
const shown = (abs) => abs.startsWith(root + node_path_1.default.sep)
|
|
330
321
|
? node_path_1.default.relative(root, abs)
|
|
331
322
|
: abs.startsWith(home + node_path_1.default.sep)
|
|
332
323
|
? `~/${node_path_1.default.relative(home, abs)}`
|
|
333
324
|
: abs;
|
|
325
|
+
// The engine's project instruction file under every project directory it reads,
|
|
326
|
+
// current first. It reads the first that exists, so a legacy one beside a current
|
|
327
|
+
// one is present and NOT read — said, rather than listed as if it applied.
|
|
328
|
+
const projectInstructions = (0, auth_core_1.firstPartyHarnessEngineProjectDirectories)().map((directory) => node_path_1.default.join(root, directory, 'AGENTS.md'));
|
|
334
329
|
const declared = [
|
|
335
|
-
{
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
330
|
+
...projectInstructions.map((abs, i) => {
|
|
331
|
+
const newer = projectInstructions.slice(0, i).find((candidate) => (0, node_fs_1.existsSync)(candidate));
|
|
332
|
+
return {
|
|
333
|
+
abs,
|
|
334
|
+
kind: 'instructions',
|
|
335
|
+
owner: 'engine',
|
|
336
|
+
scope: 'project',
|
|
337
|
+
...(newer ? { disabled: `superseded by ${node_path_1.default.relative(root, newer)}` } : {}),
|
|
338
|
+
};
|
|
339
|
+
}),
|
|
341
340
|
{
|
|
342
341
|
abs: node_path_1.default.join(engineHomeDir, 'AGENTS.md'),
|
|
343
342
|
kind: 'instructions',
|
|
@@ -355,14 +354,14 @@ function compatCheck(cwd, env) {
|
|
|
355
354
|
kind: 'instructions',
|
|
356
355
|
owner: 'compatibility',
|
|
357
356
|
scope: 'project',
|
|
358
|
-
...(noCompatPrompts ? { disabled:
|
|
357
|
+
...(noCompatPrompts ? { disabled: noCompatPrompts } : {}),
|
|
359
358
|
},
|
|
360
359
|
{
|
|
361
360
|
abs: node_path_1.default.join(home, '.claude', 'CLAUDE.md'),
|
|
362
361
|
kind: 'instructions',
|
|
363
362
|
owner: 'compatibility',
|
|
364
363
|
scope: 'user',
|
|
365
|
-
...(noCompatPrompts ? { disabled:
|
|
364
|
+
...(noCompatPrompts ? { disabled: noCompatPrompts } : {}),
|
|
366
365
|
},
|
|
367
366
|
{
|
|
368
367
|
abs: node_path_1.default.join(root, '.agents', 'skills'),
|
|
@@ -451,7 +450,7 @@ function opencodeCheck(cwd) {
|
|
|
451
450
|
* `daemon/src/harness-trust.ts` again.
|
|
452
451
|
*/
|
|
453
452
|
function trustCheck() {
|
|
454
|
-
// The canonical slug. The shared table carries every spelling at the same tier,
|
|
453
|
+
// The canonical slug. The shared table carries every accepted spelling at the same tier,
|
|
455
454
|
// so which one is asked does not change the answer — but the report prints the
|
|
456
455
|
// name the platform stores.
|
|
457
456
|
const harness = auth_core_1.FIRST_PARTY_HARNESS.provider;
|
|
@@ -511,15 +510,17 @@ const EGRESS_DENIED_HOSTS = [
|
|
|
511
510
|
'social-cards.sst.dev',
|
|
512
511
|
'opencode.internal',
|
|
513
512
|
];
|
|
514
|
-
/**
|
|
515
|
-
|
|
513
|
+
/**
|
|
514
|
+
* The ENGINE reads this one under its own names, current namespace first; the
|
|
515
|
+
* platform only reports it, naming the variable that actually supplied it.
|
|
516
|
+
*/
|
|
516
517
|
function egressCheck(env) {
|
|
517
|
-
const override = env
|
|
518
|
-
if (override === '1' || override === 'true') {
|
|
518
|
+
const override = (0, auth_core_1.readFirstPartyHarnessEngineEnv)(env, 'allowUpstreamEgress');
|
|
519
|
+
if (override.value === '1' || override.value === 'true') {
|
|
519
520
|
return {
|
|
520
521
|
name: 'upstream-egress',
|
|
521
522
|
status: 'warn',
|
|
522
|
-
detail: `${
|
|
523
|
+
detail: `${override.name} is set — ${auth_core_1.FIRST_PARTY_HARNESS.displayName} may reach upstream hosted services`,
|
|
523
524
|
remedy: 'Unset it unless you are deliberately debugging upstream behaviour. Session content, ' +
|
|
524
525
|
'repository names, and account tokens can leave for a third party while it is set.',
|
|
525
526
|
};
|
|
@@ -763,7 +764,7 @@ function sessionAuthorityCheck(env) {
|
|
|
763
764
|
remedy: 'Intended for local use, and nothing to fix. Worth knowing because it is NOT the same ' +
|
|
764
765
|
'trust plane as a daemon-dispatched run — and neither plane is an OS-level sandbox ' +
|
|
765
766
|
'(no seccomp, container, or namespace). An untrusted autonomous workload needs a hosted ' +
|
|
766
|
-
|
|
767
|
+
"or container profile; see the threat model in the engine's repository.",
|
|
767
768
|
};
|
|
768
769
|
}
|
|
769
770
|
}
|
|
@@ -70,10 +70,15 @@ export declare const AGENT_FLAG_SPELLINGS: readonly ["--skrr-agent", "--oversky-
|
|
|
70
70
|
export declare const AGENT_CONFIG_KEY: "firstPartyHarnessAgentId";
|
|
71
71
|
/**
|
|
72
72
|
* Keys earlier CLIs stored the agent setting under: `<camelCased spelling>AgentId`
|
|
73
|
-
* for every spelling of the harness, canonical first.
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
73
|
+
* for every ARTIFACT spelling of the harness, canonical first.
|
|
74
|
+
*
|
|
75
|
+
* A config file on a user's disk is an artifact: a CLI that last ran before a
|
|
76
|
+
* rename wrote the key under the product name it had then, and that file does not
|
|
77
|
+
* change when the spelling stops being accepted anywhere. So the key is derived
|
|
78
|
+
* from `firstPartyHarnessArtifactSpellings` — former spellings included — and is
|
|
79
|
+
* read (and moved onto the neutral key) for as long as the identity remembers the
|
|
80
|
+
* spelling, not merely for as long as some ingress still accepts it. Derived
|
|
81
|
+
* rather than listed, so no product name is written here.
|
|
77
82
|
*/
|
|
78
83
|
export declare function legacyAgentConfigKeys(): string[];
|
|
79
84
|
export interface AgentSetting {
|
|
@@ -90,17 +90,22 @@ exports.AGENT_CONFIG_KEY = 'firstPartyHarnessAgentId';
|
|
|
90
90
|
function camelCaseSlug(slug) {
|
|
91
91
|
return slug.replace(/-([a-z0-9])/g, (_, next) => next.toUpperCase());
|
|
92
92
|
}
|
|
93
|
-
// TODO(identity): move to auth-core — the identity module
|
|
94
|
-
// names; it has no notion of a legacy CONFIG key yet.
|
|
93
|
+
// TODO(identity): move to auth-core — the identity module derives on-disk binary
|
|
94
|
+
// names from its artifact spellings; it has no notion of a legacy CONFIG key yet.
|
|
95
95
|
/**
|
|
96
96
|
* Keys earlier CLIs stored the agent setting under: `<camelCased spelling>AgentId`
|
|
97
|
-
* for every spelling of the harness, canonical first.
|
|
97
|
+
* for every ARTIFACT spelling of the harness, canonical first.
|
|
98
98
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
99
|
+
* A config file on a user's disk is an artifact: a CLI that last ran before a
|
|
100
|
+
* rename wrote the key under the product name it had then, and that file does not
|
|
101
|
+
* change when the spelling stops being accepted anywhere. So the key is derived
|
|
102
|
+
* from `firstPartyHarnessArtifactSpellings` — former spellings included — and is
|
|
103
|
+
* read (and moved onto the neutral key) for as long as the identity remembers the
|
|
104
|
+
* spelling, not merely for as long as some ingress still accepts it. Derived
|
|
105
|
+
* rather than listed, so no product name is written here.
|
|
101
106
|
*/
|
|
102
107
|
function legacyAgentConfigKeys() {
|
|
103
|
-
return (0, auth_core_1.
|
|
108
|
+
return (0, auth_core_1.firstPartyHarnessArtifactSpellings)().map((spelling) => `${camelCaseSlug(spelling)}AgentId`);
|
|
104
109
|
}
|
|
105
110
|
/** Read the setting from a config record: the neutral key first, then each older key. */
|
|
106
111
|
function readAgentSetting(config) {
|
|
@@ -250,8 +255,7 @@ function managedSkipReason(env = process.env) {
|
|
|
250
255
|
announce: false,
|
|
251
256
|
};
|
|
252
257
|
}
|
|
253
|
-
// The operator's opt-OUT (`FIRST_PARTY_HARNESS_ENV.managed
|
|
254
|
-
// older name second). Present because "run with my own key" has to be
|
|
258
|
+
// The operator's opt-OUT (`FIRST_PARTY_HARNESS_ENV.managed`). Present because "run with my own key" has to be
|
|
255
259
|
// expressible without logging out, and because a test that asserts argv
|
|
256
260
|
// forwarding must be able to say "this run is not about acquisition" rather
|
|
257
261
|
// than depend on whether the machine happens to be signed in.
|
|
@@ -259,8 +263,7 @@ function managedSkipReason(env = process.env) {
|
|
|
259
263
|
if (envFlagIsOff(managedFlag.value)) {
|
|
260
264
|
return {
|
|
261
265
|
kind: 'disabled',
|
|
262
|
-
// The variable that was actually read
|
|
263
|
-
// to change is the one that is set.
|
|
266
|
+
// The variable that was actually read, so the sentence names what to change.
|
|
264
267
|
detail: `${managedFlag.name} is off`,
|
|
265
268
|
announce: false,
|
|
266
269
|
};
|
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
* Every product-named value — the binary's file name, the engine home, the env
|
|
19
19
|
* var names, the display name — is read from the identity module in
|
|
20
20
|
* `@skrr-ai/auth-core` (`docs/architecture/skrr-code-identifier-rename-2026-09-13.md`).
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* An installed engine is an ARTIFACT: one installed before a rename is still on
|
|
22
|
+
* disk under its old file name after that name stops being accepted anywhere, so
|
|
23
|
+
* resolution tries every artifact spelling (`firstPartyHarnessArtifactSpellings`),
|
|
24
|
+
* canonical first, in each location. That recognises a file; it admits no input.
|
|
23
25
|
*/
|
|
24
26
|
/**
|
|
25
27
|
* The error `execEngine` throws when no engine resolves. A value the commands
|
|
@@ -44,11 +46,14 @@ export declare function engineHome(env?: NodeJS.ProcessEnv): string;
|
|
|
44
46
|
/**
|
|
45
47
|
* The user-level instruction root the engine owns.
|
|
46
48
|
*
|
|
47
|
-
* Read under the neutral variable first
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* engine
|
|
49
|
+
* Read under the platform's neutral variable first, then under the variable the
|
|
50
|
+
* ENGINE itself reads, under every name it reads it by, current namespace first
|
|
51
|
+
* (`readFirstPartyHarnessEngineEnv(env, 'home')`; the namespace moved in OSK-8674
|
|
52
|
+
* and the engine reads both). That is not a legacy fallback: it is the engine's own
|
|
53
|
+
* variable, the engine honours it whatever the platform does, and a CLI that
|
|
54
|
+
* ignored it would report one instruction root while the engine it launches used
|
|
55
|
+
* another. {@link engineOwnedEnv} closes the other direction, handing a
|
|
56
|
+
* neutral-variable value to the engine under its own names.
|
|
52
57
|
*/
|
|
53
58
|
export declare function engineInstructionHome(env?: NodeJS.ProcessEnv): string;
|
|
54
59
|
/**
|
|
@@ -58,8 +63,9 @@ export declare function engineInstructionHome(env?: NodeJS.ProcessEnv): string;
|
|
|
58
63
|
*/
|
|
59
64
|
export declare function managedEnginePath(env?: NodeJS.ProcessEnv, provider?: string): string;
|
|
60
65
|
/**
|
|
61
|
-
* The same managed location under the PREVIOUS config root, for every
|
|
62
|
-
* the binary and every engine home name,
|
|
66
|
+
* The same managed location under the PREVIOUS config root, for every artifact
|
|
67
|
+
* spelling of the binary (former spellings included) and every engine home name,
|
|
68
|
+
* canonical first.
|
|
63
69
|
*
|
|
64
70
|
* The root moved `~/.oversky` → `~/.skrr` in the skrr rename, and an engine
|
|
65
71
|
* installed before that is still on disk under the old one. `daemon/src/
|
|
@@ -69,7 +75,7 @@ export declare function managedEnginePath(env?: NodeJS.ProcessEnv, provider?: st
|
|
|
69
75
|
*
|
|
70
76
|
* The engine-home move (`migrateFirstPartyHarnessHome`) only ever works under the
|
|
71
77
|
* CURRENT root, so nothing renames a binary here — which is why this list carries
|
|
72
|
-
* every spelling rather than only the canonical one.
|
|
78
|
+
* every artifact spelling rather than only the canonical one.
|
|
73
79
|
*
|
|
74
80
|
* Empty when an explicit `OVERSKY_CONFIG_DIR` is set, matching the daemon: that
|
|
75
81
|
* override names one root deliberately, and reaching past it to a hard-coded home
|
|
@@ -84,11 +90,9 @@ export interface EngineResolution {
|
|
|
84
90
|
/**
|
|
85
91
|
* The variable an explicit override was read from — set whenever one was set,
|
|
86
92
|
* including an override that was refused. The doctor names it, because an
|
|
87
|
-
* operator fixing a bad override needs to
|
|
93
|
+
* operator fixing a bad override needs to be told which variable to change.
|
|
88
94
|
*/
|
|
89
95
|
envName?: string;
|
|
90
|
-
/** True when {@link envName} is an older name for the override. */
|
|
91
|
-
legacyEnv?: boolean;
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
98
|
* Resolve the engine binary, reporting WHERE it came from.
|
|
@@ -100,12 +104,12 @@ export interface EngineResolution {
|
|
|
100
104
|
* The env override is checked first and is absolute-only. A relative override
|
|
101
105
|
* would resolve against the caller's cwd, which for an agent-invoked command is
|
|
102
106
|
* attacker-influenced: a repo containing a file named like the engine could
|
|
103
|
-
* hijack it.
|
|
107
|
+
* hijack it.
|
|
104
108
|
*
|
|
105
109
|
* **Order: env → managed → PATH → well-known (WL-6.2).** Within each location
|
|
106
|
-
* every spelling of the binary is tried, canonical first — the daemon's
|
|
107
|
-
* so an engine installed under an older name still resolves,
|
|
108
|
-
* one wins wherever both exist.
|
|
110
|
+
* every artifact spelling of the binary is tried, canonical first — the daemon's
|
|
111
|
+
* order — so an engine installed under an older or former name still resolves,
|
|
112
|
+
* and the canonical one wins wherever both exist.
|
|
109
113
|
*
|
|
110
114
|
* The managed location beating `PATH` is the load-bearing part, and it is a
|
|
111
115
|
* deliberate reversal of the obvious ordering.
|
|
@@ -376,10 +380,17 @@ export declare function engineSpawnEnv(env: NodeJS.ProcessEnv, extraEnv: Record<
|
|
|
376
380
|
* `skrr code doctor` honour it while the engine it launches ignored it — two
|
|
377
381
|
* answers to "where do my instructions live" from one command.
|
|
378
382
|
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
+
* Under EVERY name the engine has read (`firstPartyHarnessEngineEnvEntries`). The
|
|
384
|
+
* engine's namespace moved (OSK-8674), and the binary this CLI launches may be a
|
|
385
|
+
* build from either side of that move; a value handed over under one name only
|
|
386
|
+
* reaches half of them.
|
|
387
|
+
*
|
|
388
|
+
* When the neutral variable supplied the value, every engine name gets it: the
|
|
389
|
+
* neutral one wins, as it does in {@link engineInstructionHome}. When only an
|
|
390
|
+
* engine name did, only the engine names that are UNSET are filled in — the user's
|
|
391
|
+
* own values are inherited already, and two different values the user set under
|
|
392
|
+
* two names are theirs to keep. The resolved path is passed rather than the raw
|
|
393
|
+
* value, so the engine and the doctor agree on `~` expansion too.
|
|
383
394
|
*
|
|
384
395
|
* Not a credential and never one: it cannot reintroduce anything the sanitizer
|
|
385
396
|
* strips, and `extraEnv` still layers over it.
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
* Every product-named value — the binary's file name, the engine home, the env
|
|
20
20
|
* var names, the display name — is read from the identity module in
|
|
21
21
|
* `@skrr-ai/auth-core` (`docs/architecture/skrr-code-identifier-rename-2026-09-13.md`).
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* An installed engine is an ARTIFACT: one installed before a rename is still on
|
|
23
|
+
* disk under its old file name after that name stops being accepted anywhere, so
|
|
24
|
+
* resolution tries every artifact spelling (`firstPartyHarnessArtifactSpellings`),
|
|
25
|
+
* canonical first, in each location. That recognises a file; it admits no input.
|
|
24
26
|
*/
|
|
25
27
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
28
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -81,14 +83,18 @@ function engineHome(env = process.env) {
|
|
|
81
83
|
/**
|
|
82
84
|
* The user-level instruction root the engine owns.
|
|
83
85
|
*
|
|
84
|
-
* Read under the neutral variable first
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* engine
|
|
86
|
+
* Read under the platform's neutral variable first, then under the variable the
|
|
87
|
+
* ENGINE itself reads, under every name it reads it by, current namespace first
|
|
88
|
+
* (`readFirstPartyHarnessEngineEnv(env, 'home')`; the namespace moved in OSK-8674
|
|
89
|
+
* and the engine reads both). That is not a legacy fallback: it is the engine's own
|
|
90
|
+
* variable, the engine honours it whatever the platform does, and a CLI that
|
|
91
|
+
* ignored it would report one instruction root while the engine it launches used
|
|
92
|
+
* another. {@link engineOwnedEnv} closes the other direction, handing a
|
|
93
|
+
* neutral-variable value to the engine under its own names.
|
|
89
94
|
*/
|
|
90
95
|
function engineInstructionHome(env = process.env) {
|
|
91
|
-
const configured = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'home').value
|
|
96
|
+
const configured = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'home').value ??
|
|
97
|
+
(0, auth_core_1.readFirstPartyHarnessEngineEnv)(env, 'home').value;
|
|
92
98
|
// Falls through to `engineHome()` rather than re-deriving `~/.skrr` — the two
|
|
93
99
|
// describe the same root, and re-deriving it is what made them disagree under
|
|
94
100
|
// `OVERSKY_CONFIG_DIR` (OSK-300).
|
|
@@ -109,8 +115,9 @@ function managedEnginePath(env = process.env, provider = auth_core_1.FIRST_PARTY
|
|
|
109
115
|
return (0, auth_core_1.firstPartyHarnessInstalledBinaryPath)(env, provider, process.platform);
|
|
110
116
|
}
|
|
111
117
|
/**
|
|
112
|
-
* The same managed location under the PREVIOUS config root, for every
|
|
113
|
-
* the binary and every engine home name,
|
|
118
|
+
* The same managed location under the PREVIOUS config root, for every artifact
|
|
119
|
+
* spelling of the binary (former spellings included) and every engine home name,
|
|
120
|
+
* canonical first.
|
|
114
121
|
*
|
|
115
122
|
* The root moved `~/.oversky` → `~/.skrr` in the skrr rename, and an engine
|
|
116
123
|
* installed before that is still on disk under the old one. `daemon/src/
|
|
@@ -120,7 +127,7 @@ function managedEnginePath(env = process.env, provider = auth_core_1.FIRST_PARTY
|
|
|
120
127
|
*
|
|
121
128
|
* The engine-home move (`migrateFirstPartyHarnessHome`) only ever works under the
|
|
122
129
|
* CURRENT root, so nothing renames a binary here — which is why this list carries
|
|
123
|
-
* every spelling rather than only the canonical one.
|
|
130
|
+
* every artifact spelling rather than only the canonical one.
|
|
124
131
|
*
|
|
125
132
|
* Empty when an explicit `OVERSKY_CONFIG_DIR` is set, matching the daemon: that
|
|
126
133
|
* override names one root deliberately, and reaching past it to a hard-coded home
|
|
@@ -133,7 +140,7 @@ function legacyManagedEnginePaths(env = process.env) {
|
|
|
133
140
|
function legacyManagedEngineBinDirs(env = process.env) {
|
|
134
141
|
if ((0, auth_core_1.isConfigRootOverridden)(env))
|
|
135
142
|
return [];
|
|
136
|
-
return
|
|
143
|
+
return (0, auth_core_1.firstPartyHarnessEngineHomeDirnames)().map((home) => node_path_1.default.join((0, config_1.priorConfigDir)(), home, 'bin'));
|
|
137
144
|
}
|
|
138
145
|
/**
|
|
139
146
|
* Unmanaged well-known locations, checked after PATH.
|
|
@@ -149,11 +156,13 @@ function fallbackPaths(exeName) {
|
|
|
149
156
|
];
|
|
150
157
|
}
|
|
151
158
|
/**
|
|
152
|
-
* The file names a PATH directory may hold the engine under, canonical first
|
|
153
|
-
*
|
|
159
|
+
* The file names a PATH directory may hold the engine under, canonical first —
|
|
160
|
+
* every artifact spelling, since a standalone install made before a rename keeps
|
|
161
|
+
* its old name. Windows also accepts a `.cmd` shim, as a package manager may
|
|
162
|
+
* install one.
|
|
154
163
|
*/
|
|
155
164
|
function pathExecutableNames(platform) {
|
|
156
|
-
return (0, auth_core_1.
|
|
165
|
+
return (0, auth_core_1.firstPartyHarnessArtifactSpellings)().flatMap((spelling) => platform === 'win32'
|
|
157
166
|
? [(0, auth_core_1.firstPartyHarnessBinaryName)(spelling, platform), `${spelling}.cmd`]
|
|
158
167
|
: [(0, auth_core_1.firstPartyHarnessBinaryName)(spelling, platform)]);
|
|
159
168
|
}
|
|
@@ -176,12 +185,12 @@ function isExecutable(p) {
|
|
|
176
185
|
* The env override is checked first and is absolute-only. A relative override
|
|
177
186
|
* would resolve against the caller's cwd, which for an agent-invoked command is
|
|
178
187
|
* attacker-influenced: a repo containing a file named like the engine could
|
|
179
|
-
* hijack it.
|
|
188
|
+
* hijack it.
|
|
180
189
|
*
|
|
181
190
|
* **Order: env → managed → PATH → well-known (WL-6.2).** Within each location
|
|
182
|
-
* every spelling of the binary is tried, canonical first — the daemon's
|
|
183
|
-
* so an engine installed under an older name still resolves,
|
|
184
|
-
* one wins wherever both exist.
|
|
191
|
+
* every artifact spelling of the binary is tried, canonical first — the daemon's
|
|
192
|
+
* order — so an engine installed under an older or former name still resolves,
|
|
193
|
+
* and the canonical one wins wherever both exist.
|
|
185
194
|
*
|
|
186
195
|
* The managed location beating `PATH` is the load-bearing part, and it is a
|
|
187
196
|
* deliberate reversal of the obvious ordering.
|
|
@@ -210,7 +219,7 @@ function resolveEngine(env = process.env) {
|
|
|
210
219
|
const platform = process.platform;
|
|
211
220
|
const override = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'path');
|
|
212
221
|
if (override.value && override.name) {
|
|
213
|
-
const origin = { envName: override.name
|
|
222
|
+
const origin = { envName: override.name };
|
|
214
223
|
const candidate = override.value;
|
|
215
224
|
if (!node_path_1.default.isAbsolute(candidate))
|
|
216
225
|
return { path: null, source: 'unresolved', ...origin };
|
|
@@ -218,7 +227,7 @@ function resolveEngine(env = process.env) {
|
|
|
218
227
|
? { path: candidate, source: 'env', ...origin }
|
|
219
228
|
: { path: null, source: 'unresolved', ...origin };
|
|
220
229
|
}
|
|
221
|
-
for (const spelling of (0, auth_core_1.
|
|
230
|
+
for (const spelling of (0, auth_core_1.firstPartyHarnessArtifactSpellings)()) {
|
|
222
231
|
const managed = managedEnginePath(env, spelling);
|
|
223
232
|
if (isExecutable(managed))
|
|
224
233
|
return { path: managed, source: 'managed' };
|
|
@@ -595,27 +604,36 @@ mode) {
|
|
|
595
604
|
* `skrr code doctor` honour it while the engine it launches ignored it — two
|
|
596
605
|
* answers to "where do my instructions live" from one command.
|
|
597
606
|
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
607
|
+
* Under EVERY name the engine has read (`firstPartyHarnessEngineEnvEntries`). The
|
|
608
|
+
* engine's namespace moved (OSK-8674), and the binary this CLI launches may be a
|
|
609
|
+
* build from either side of that move; a value handed over under one name only
|
|
610
|
+
* reaches half of them.
|
|
611
|
+
*
|
|
612
|
+
* When the neutral variable supplied the value, every engine name gets it: the
|
|
613
|
+
* neutral one wins, as it does in {@link engineInstructionHome}. When only an
|
|
614
|
+
* engine name did, only the engine names that are UNSET are filled in — the user's
|
|
615
|
+
* own values are inherited already, and two different values the user set under
|
|
616
|
+
* two names are theirs to keep. The resolved path is passed rather than the raw
|
|
617
|
+
* value, so the engine and the doctor agree on `~` expansion too.
|
|
602
618
|
*
|
|
603
619
|
* Not a credential and never one: it cannot reintroduce anything the sanitizer
|
|
604
620
|
* strips, and `extraEnv` still layers over it.
|
|
605
621
|
*/
|
|
606
622
|
function engineOwnedEnv(env) {
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
out[auth_core_1.FIRST_PARTY_HARNESS_ENGINE.env.home] = engineInstructionHome(env);
|
|
623
|
+
const everyName = (value) => (0, auth_core_1.firstPartyHarnessEngineEnvEntries)('home', value);
|
|
624
|
+
if ((0, auth_core_1.readFirstPartyHarnessEnv)(env, 'home').value) {
|
|
625
|
+
return everyName(engineInstructionHome(env));
|
|
611
626
|
}
|
|
612
|
-
|
|
627
|
+
if (!(0, auth_core_1.readFirstPartyHarnessEngineEnv)(env, 'home').value)
|
|
628
|
+
return {};
|
|
629
|
+
return Object.fromEntries(Object.entries(everyName(engineInstructionHome(env))).filter(([name]) => !(typeof env[name] === 'string' && env[name].trim() !== '')));
|
|
613
630
|
}
|
|
614
631
|
async function execEngine(args, env = process.env, options = {}) {
|
|
615
632
|
// Move an engine installed under an older binary name onto the canonical one,
|
|
616
633
|
// BEFORE resolving. Idempotent, lossless, and it never throws: a move that
|
|
617
634
|
// cannot be made leaves every file where it was, and `resolveEngine` still tries
|
|
618
|
-
// every spelling — so the worst case is today's path, never a missing
|
|
635
|
+
// every artifact spelling — so the worst case is today's path, never a missing
|
|
636
|
+
// engine.
|
|
619
637
|
// Here and not in `resolveEngine`, which the doctor also calls and which must
|
|
620
638
|
// not move anything.
|
|
621
639
|
(0, auth_core_1.migrateFirstPartyHarnessHome)({ env });
|
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Harness-valued INPUT, normalised at the edge.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* INGRESS: every flag, setting and filter that takes a harness name accepts
|
|
5
|
+
* exactly the identity's ACCEPTED spellings (`firstPartyHarnessSpellings`) and
|
|
6
|
+
* hands the rest of the CLI ONE value, so no comparison downstream has to know
|
|
7
|
+
* whether there were several (`docs/architecture/skrr-code-identifier-rename-2026-09-13.md`
|
|
8
|
+
* §2). During a rename's alias window that is the canonical spelling plus
|
|
9
|
+
* `FIRST_PARTY_HARNESS.aliases`, so a script written against either keeps
|
|
10
|
+
* working; outside one it is the canonical spelling alone. A FORMER spelling is
|
|
11
|
+
* accepted on no input — it is passed through unchanged, so a flag offering only
|
|
12
|
+
* the accepted spellings rejects it — even though the CLI still recognises it on
|
|
13
|
+
* an engine binary already on disk (`first-party-harness.ts`).
|
|
10
14
|
*
|
|
11
15
|
* Two destinations, two spellings, and the difference is the point:
|
|
12
16
|
*
|
|
13
17
|
* - to the SERVER (HTTP bodies, query params) and to the terminal: CANONICAL,
|
|
14
18
|
* which is what the platform stores and returns;
|
|
15
|
-
* - to the local DAEMON binary: the WIRE spelling
|
|
16
|
-
*
|
|
17
|
-
* the rename cannot be taught a new spelling by the CLI that
|
|
19
|
+
* - to the local DAEMON binary: the WIRE spelling (`wireProvider`). It sits on
|
|
20
|
+
* the old spelling from a rename's flip until its wire phase, because a daemon
|
|
21
|
+
* that predates the rename cannot be taught a new spelling by the CLI that
|
|
22
|
+
* talks to it, and is canonical otherwise.
|
|
18
23
|
*
|
|
19
24
|
* Every other harness name passes through unchanged — this normalises one
|
|
20
25
|
* harness's spellings, it is not a general lower-caser, and silently rewriting a
|
|
@@ -28,8 +33,9 @@ export declare function canonicalHarnessInputs(values: readonly string[]): strin
|
|
|
28
33
|
export declare function daemonHarnessArgument(value: string): string;
|
|
29
34
|
/**
|
|
30
35
|
* The `options` list for an oclif flag that enumerates harness names: the given
|
|
31
|
-
* names with every spelling of the first-party harness in place of its
|
|
32
|
-
* one, so oclif's own validation accepts an alias instead of rejecting
|
|
33
|
-
* the command ever runs
|
|
36
|
+
* names with every ACCEPTED spelling of the first-party harness in place of its
|
|
37
|
+
* canonical one, so oclif's own validation accepts an alias instead of rejecting
|
|
38
|
+
* it before the command ever runs — and rejects a former spelling, which no
|
|
39
|
+
* ingress accepts.
|
|
34
40
|
*/
|
|
35
41
|
export declare function harnessFlagOptions(names: readonly string[]): string[];
|