@skrr-ai/cli 0.1.32 → 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.
Files changed (111) hide show
  1. package/bin/run.js +2 -2
  2. package/dist/commands/agents/list.d.ts +2 -1
  3. package/dist/commands/agents/list.js +2 -1
  4. package/dist/commands/agents/show.js +2 -1
  5. package/dist/commands/balance/statement.js +8 -4
  6. package/dist/commands/browser/install.js +6 -2
  7. package/dist/commands/browser/uninstall.js +6 -2
  8. package/dist/commands/code/acp.js +2 -1
  9. package/dist/commands/code/doctor.d.ts +1 -1
  10. package/dist/commands/code/doctor.js +6 -5
  11. package/dist/commands/code/handover.d.ts +2 -2
  12. package/dist/commands/code/handover.js +2 -2
  13. package/dist/commands/code/index.d.ts +2 -2
  14. package/dist/commands/code/index.js +18 -17
  15. package/dist/commands/code/install.d.ts +3 -3
  16. package/dist/commands/code/install.js +18 -11
  17. package/dist/commands/code/migrate.js +3 -2
  18. package/dist/commands/code/oversky-agent.d.ts +5 -4
  19. package/dist/commands/code/oversky-agent.js +24 -22
  20. package/dist/commands/code/run.js +2 -1
  21. package/dist/commands/harnesses/list.d.ts +9 -1
  22. package/dist/commands/harnesses/list.js +28 -7
  23. package/dist/commands/harnesses/show.js +7 -2
  24. package/dist/commands/instructions/install.js +16 -6
  25. package/dist/commands/learning/delete.d.ts +9 -0
  26. package/dist/commands/learning/delete.js +39 -0
  27. package/dist/commands/learning/export.d.ts +5 -0
  28. package/dist/commands/learning/export.js +22 -0
  29. package/dist/commands/learning/reset.d.ts +9 -0
  30. package/dist/commands/learning/reset.js +34 -0
  31. package/dist/commands/learning/set.d.ts +10 -0
  32. package/dist/commands/learning/set.js +52 -0
  33. package/dist/commands/learning/status.d.ts +8 -0
  34. package/dist/commands/learning/status.js +35 -0
  35. package/dist/commands/logout.js +10 -5
  36. package/dist/commands/machines/dedicated/attach.js +2 -1
  37. package/dist/commands/tasks/runs.js +3 -1
  38. package/dist/commands/workspaces/use.js +2 -1
  39. package/dist/lib/adaptive-learning.d.ts +37 -0
  40. package/dist/lib/adaptive-learning.js +39 -0
  41. package/dist/lib/code-handover.d.ts +1 -1
  42. package/dist/lib/code-handover.js +3 -2
  43. package/dist/lib/config.d.ts +30 -4
  44. package/dist/lib/config.js +2 -1
  45. package/dist/lib/daemon-installer.d.ts +1 -1
  46. package/dist/lib/daemon-target.js +2 -2
  47. package/dist/lib/dedicated-machines.d.ts +2 -2
  48. package/dist/lib/dedicated-machines.js +6 -3
  49. package/dist/lib/exec-runtime-binary.d.ts +2 -2
  50. package/dist/lib/exec-runtime-binary.js +2 -2
  51. package/dist/lib/{sky-code-agent.d.ts → first-party-harness-agent.d.ts} +20 -19
  52. package/dist/lib/{sky-code-agent.js → first-party-harness-agent.js} +85 -47
  53. package/dist/lib/{sky-code-broker.d.ts → first-party-harness-broker.d.ts} +6 -6
  54. package/dist/lib/{sky-code-broker.js → first-party-harness-broker.js} +23 -23
  55. package/dist/lib/{sky-code-doctor.d.ts → first-party-harness-doctor.d.ts} +12 -2
  56. package/dist/lib/{sky-code-doctor.js → first-party-harness-doctor.js} +181 -94
  57. package/dist/lib/{sky-code-managed.d.ts → first-party-harness-managed.d.ts} +55 -30
  58. package/dist/lib/{sky-code-managed.js → first-party-harness-managed.js} +92 -35
  59. package/dist/lib/{sky-code.d.ts → first-party-harness.d.ts} +107 -36
  60. package/dist/lib/{sky-code.js → first-party-harness.js} +172 -73
  61. package/dist/lib/harness-provider-input.d.ts +35 -0
  62. package/dist/lib/harness-provider-input.js +57 -0
  63. package/dist/lib/harness-tiers.d.ts +8 -2
  64. package/dist/lib/harness-tiers.js +11 -6
  65. package/dist/lib/task-instruction-offer.js +10 -4
  66. package/dist/lib/worklogs.js +2 -2
  67. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.d.ts +2 -2
  68. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.js +2 -2
  69. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +248 -0
  70. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +361 -0
  71. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +147 -0
  72. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +180 -0
  73. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +111 -0
  74. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +314 -0
  75. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +11 -5
  76. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +14 -7
  77. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
  78. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +51 -14
  79. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +1 -1
  80. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +4 -4
  81. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +4 -4
  82. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.d.ts +2 -2
  83. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.js +2 -2
  84. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +248 -0
  85. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +332 -0
  86. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +147 -0
  87. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +170 -0
  88. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +111 -0
  89. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +303 -0
  90. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +11 -5
  91. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +14 -7
  92. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
  93. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +12 -2
  94. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +1 -1
  95. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +4 -4
  96. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +4 -4
  97. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  98. package/dist/node_modules/@skrr-ai/data-provider/index.js +4816 -4782
  99. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
  100. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +1 -1
  101. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +1 -1
  102. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
  103. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
  104. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +1 -1
  105. package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
  106. package/oclif.manifest.json +34682 -34371
  107. package/package.json +5 -2
  108. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +0 -96
  109. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +0 -115
  110. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +0 -96
  111. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.js +0 -107
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * WL-6.9 — skrr Code diagnostics.
3
+ * WL-6.9 — first-party harness diagnostics (`skrr code doctor`).
4
4
  *
5
5
  * The plan makes this a launch gate, phrased as: support must be able to
6
6
  * identify the product version, upstream base, config source, and runtime mode
@@ -21,6 +21,12 @@
21
21
  * actions, and collapsing them into one red line is how a user spends an
22
22
  * hour reinstalling something that was merely absent. Hence three statuses,
23
23
  * not two.
24
+ *
25
+ * Every product-named value — display name, binary name, project directory, env
26
+ * var names — comes from the identity module in `@skrr-ai/auth-core`. A variable
27
+ * that was read under an OLDER name is reported by that name, with the neutral
28
+ * one to move to: the older names are still honoured, and a diagnostic that
29
+ * hid which one was in effect would send an operator to edit the wrong line.
24
30
  */
25
31
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
32
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -31,14 +37,28 @@ exports.runDoctor = runDoctor;
31
37
  exports.formatReport = formatReport;
32
38
  const node_fs_1 = require("node:fs");
33
39
  const node_path_1 = __importDefault(require("node:path"));
34
- const sky_code_1 = require("./sky-code");
40
+ const first_party_harness_1 = require("./first-party-harness");
35
41
  const auth_core_1 = require("@skrr-ai/auth-core");
36
42
  const harness_tiers_1 = require("./harness-tiers");
37
- const config_1 = require("./config");
38
- const sky_code_managed_1 = require("./sky-code-managed");
39
- /** Project-level state dir. Basename deliberately differs from `~/.skrr`. */
43
+ const first_party_harness_managed_1 = require("./first-party-harness-managed");
44
+ /**
45
+ * The variable one purpose was read from, and — when that was an older name — the
46
+ * sentence that says so. `undefined` when the neutral name (or nothing) was used.
47
+ */
48
+ function legacyEnvNote(key, name) {
49
+ const neutral = auth_core_1.FIRST_PARTY_HARNESS_ENV[key].name;
50
+ if (!name || name === neutral)
51
+ return undefined;
52
+ return (`${name} is an older name for this setting and is still read; ` +
53
+ `rename it to ${neutral}, which wins when both are set.`);
54
+ }
55
+ /**
56
+ * Project-level state dir — the ENGINE's own project marker
57
+ * (`FIRST_PARTY_HARNESS_ENGINE.projectDirectory`). Basename deliberately differs
58
+ * from `~/.skrr`.
59
+ */
40
60
  function projectStateDir(cwd) {
41
- return node_path_1.default.join(node_path_1.default.resolve(cwd), '.sky-code');
61
+ return node_path_1.default.join(node_path_1.default.resolve(cwd), auth_core_1.FIRST_PARTY_HARNESS_ENGINE.projectDirectory);
42
62
  }
43
63
  /**
44
64
  * Which release channel this machine follows, and where its manifest lives.
@@ -46,7 +66,7 @@ function projectStateDir(cwd) {
46
66
  * `notInstalledMessage()` has always ended by promising that this command names
47
67
  * "which channel this machine follows and whether that channel has a published
48
68
  * release", and nothing here knew what a channel was — the whole vocabulary sat
49
- * in `daemon/src/sky-code/channels.ts`, whose only importer was the daemon's own
69
+ * in `daemon/src/first-party-harness/channels.ts`, whose only importer was the daemon's own
50
70
  * installer. So the user with no engine, who is exactly the audience for that
51
71
  * sentence, was sent to a command that could not answer (dogfood OSK-274).
52
72
  *
@@ -57,67 +77,98 @@ function projectStateDir(cwd) {
57
77
  * the answer one copy-paste away and keeps the property — and the promise is
58
78
  * reworded to match what is delivered rather than the other way round.
59
79
  *
60
- * `warn` on an unrecognised channel, because `resolveSkyCodeChannel` falls back
61
- * to the default rather than throwing: a typo must not brick updates, and a
62
- * silent fallback must not look like agreement.
80
+ * The URL is the CANONICAL feed candidate. A manifest may also be published under
81
+ * each older spelling (`firstPartyHarnessFeedCandidates`), and an installer that
82
+ * finds nothing at the canonical URL tries those next — so the remedy names them
83
+ * too. Without that, "the canonical URL 404s" would read as "there is no release"
84
+ * on a feed an older pipeline published under the other spelling. The doctor
85
+ * cannot say which candidate actually holds a release, because it does not probe;
86
+ * it says where to look, in the order an installer looks.
87
+ *
88
+ * `warn` on an unrecognised channel, because `resolveFirstPartyHarnessChannel`
89
+ * falls back to the default rather than throwing: a typo must not brick updates,
90
+ * and a silent fallback must not look like agreement.
63
91
  */
64
92
  function releaseChannelCheck(env) {
65
- const { channel, invalid } = (0, auth_core_1.resolveSkyCodeChannel)(env);
66
- const url = (0, auth_core_1.resolveChannelManifestUrl)({
67
- base: (0, auth_core_1.skyCodeFeedBase)(env),
68
- manifestFilename: auth_core_1.SKY_CODE_MANIFEST_FILE,
93
+ const { channel, invalid, source } = (0, auth_core_1.resolveFirstPartyHarnessChannel)(env);
94
+ const [canonical, ...alternates] = (0, auth_core_1.firstPartyHarnessFeedCandidates)(env).map((candidate) => (0, auth_core_1.resolveChannelManifestUrl)({
95
+ base: candidate.base,
96
+ manifestFilename: candidate.manifestFilename,
69
97
  channel,
70
- });
98
+ }));
99
+ const legacyNote = legacyEnvNote('channel', source);
71
100
  if (invalid) {
72
101
  return {
73
102
  name: 'release-channel',
74
103
  status: 'warn',
75
- detail: `${auth_core_1.SKY_CODE_CHANNEL_ENV}='${invalid}' is not a channel; following '${channel}' instead — ${url}`,
76
- remedy: `Set ${auth_core_1.SKY_CODE_CHANNEL_ENV} to one of internal, canary, beta, stable, or unset it to follow the default.`,
104
+ detail: `${source}='${invalid}' is not a channel; following '${channel}' instead — ${canonical}`,
105
+ remedy: `Set ${auth_core_1.FIRST_PARTY_HARNESS_ENV.channel.name} to one of ${auth_core_1.FIRST_PARTY_HARNESS_CHANNELS.join(', ')}, ` +
106
+ 'or unset it to follow the default.' +
107
+ (legacyNote ? ` ${legacyNote}` : ''),
77
108
  };
78
109
  }
110
+ const alsoTried = alternates.filter((url) => url !== canonical);
79
111
  return {
80
112
  name: 'release-channel',
81
113
  status: 'ok',
82
- detail: `${channel} — ${url}`,
83
- remedy: `Fetch that URL to see whether the channel has a published release, and which version.`,
114
+ detail: `${channel} — ${canonical}`,
115
+ remedy: 'Fetch that URL to see whether the channel has a published release, and which version.' +
116
+ (alsoTried.length
117
+ ? ` If it has none, an installer also tries ${alsoTried.join(', ')}.`
118
+ : '') +
119
+ (legacyNote ? ` ${legacyNote}` : ''),
84
120
  };
85
121
  }
86
122
  /**
87
123
  * What the pre-rename engine directory still holds, for a machine that has moved on.
88
124
  *
89
- * Round 1 gave both readers a fallback to `~/.oversky/sky-code/bin` so nothing
90
- * BREAKS on a machine that installed before the rename. Nothing was given the job
91
- * of finishing the move: no installer sweep, and — once the current root wins —
92
- * no mention anywhere. This machine converged on two engine directories and
93
- * reported one, the older holding 713 MB across six binaries (dogfood OSK-278).
125
+ * Round 1 gave both readers a fallback to the managed `bin` directory under the
126
+ * pre-rename `~/.oversky` root so nothing BREAKS on a machine that installed before
127
+ * the rename. Nothing was given the job of finishing the move: no installer sweep,
128
+ * and — once the current root wins — no mention anywhere. This machine converged
129
+ * on two engine directories and reported one, the older holding 713 MB across six
130
+ * binaries (dogfood OSK-278).
94
131
  *
95
132
  * Flat, never recursive, and failures are swallowed: this is a footnote on a
96
133
  * diagnostic, and a doctor that throws while counting bytes it was only going to
97
134
  * mention has made things worse than the clutter it was reporting.
98
135
  */
99
136
  function strandedLegacyEngine(env) {
100
- const exeName = process.platform === 'win32' ? 'sky-code.exe' : 'sky-code';
101
- const legacy = (0, sky_code_1.legacyManagedEnginePath)(exeName, env);
102
- if (!legacy)
103
- return null;
104
- const dir = node_path_1.default.dirname(legacy);
105
- try {
106
- const entries = (0, node_fs_1.readdirSync)(dir);
107
- let bytes = 0;
108
- let files = 0;
109
- for (const entry of entries) {
110
- const stats = (0, node_fs_1.statSync)(node_path_1.default.join(dir, entry));
111
- if (!stats.isFile())
112
- continue;
113
- files += 1;
114
- bytes += stats.size;
137
+ for (const dir of (0, first_party_harness_1.legacyManagedEngineBinDirs)(env)) {
138
+ try {
139
+ const entries = (0, node_fs_1.readdirSync)(dir);
140
+ let bytes = 0;
141
+ let files = 0;
142
+ for (const entry of entries) {
143
+ const stats = (0, node_fs_1.statSync)(node_path_1.default.join(dir, entry));
144
+ if (!stats.isFile())
145
+ continue;
146
+ files += 1;
147
+ bytes += stats.size;
148
+ }
149
+ if (files > 0)
150
+ return { dir, files, bytes };
151
+ }
152
+ catch {
153
+ // Absent or unreadable — nothing to mention for this directory.
115
154
  }
116
- return files > 0 ? { dir, files, bytes } : null;
117
155
  }
118
- catch {
156
+ return null;
157
+ }
158
+ /**
159
+ * Whether a managed engine resolved under an OLDER spelling of its file name.
160
+ *
161
+ * Not a fault: resolution tries every spelling on purpose, and the next
162
+ * `skrr code` run renames the file onto the canonical name (leaving a link at the
163
+ * old one). Said anyway, because a path that does not match the name everything
164
+ * else prints is exactly the surprise this module exists to explain.
165
+ */
166
+ function olderBinaryName(bin) {
167
+ const name = node_path_1.default.basename(bin);
168
+ const canonical = (0, auth_core_1.firstPartyHarnessBinaryName)(undefined, process.platform);
169
+ if (name === canonical)
119
170
  return null;
120
- }
171
+ return (0, auth_core_1.firstPartyHarnessBinaryNames)(process.platform).includes(name) ? name : null;
121
172
  }
122
173
  /** Bytes as the size a human would say out loud. */
123
174
  function humanBytes(bytes) {
@@ -125,7 +176,9 @@ function humanBytes(bytes) {
125
176
  return mb >= 1024 ? `${(mb / 1024).toFixed(1)} GB` : `${Math.round(mb)} MB`;
126
177
  }
127
178
  function engineCheck(env) {
128
- const { path: bin, source } = (0, sky_code_1.resolveEngine)(env);
179
+ const resolution = (0, first_party_harness_1.resolveEngine)(env);
180
+ const { path: bin, source } = resolution;
181
+ const pathVar = auth_core_1.FIRST_PARTY_HARNESS_ENV.path.name;
129
182
  if (bin && source === 'legacy-managed') {
130
183
  // `ok`, because it runs and this is the resolution the daemon has always
131
184
  // made. The remedy is here because the resolution is SURPRISING: the path
@@ -137,58 +190,79 @@ function engineCheck(env) {
137
190
  status: 'ok',
138
191
  detail: `${bin} (resolved via ${source} — the pre-rename location)`,
139
192
  remedy: 'It works, and nothing has to change today. Installing the engine again ' +
140
- `through the daemon writes it to ${(0, sky_code_1.managedEnginePath)('sky-code', env)}; ` +
193
+ `through the daemon writes it to ${(0, first_party_harness_1.managedEnginePath)(env)}; ` +
141
194
  'the copy above can be deleted once it does.',
142
195
  };
143
196
  }
197
+ if (bin && source === 'env') {
198
+ // Name the variable, not just "env": two names are read for this override,
199
+ // and the one to edit is the one that is set.
200
+ const legacyNote = resolution.legacyEnv ? legacyEnvNote('path', resolution.envName) : undefined;
201
+ return {
202
+ name: 'engine',
203
+ status: 'ok',
204
+ detail: `${bin} (resolved via env ${resolution.envName})`,
205
+ ...(legacyNote ? { remedy: legacyNote } : {}),
206
+ };
207
+ }
144
208
  if (bin) {
145
209
  // The engine resolved from the current root — and the pre-rename directory
146
210
  // may still be sitting there. Said here rather than in its own check because
147
211
  // it is a footnote on a healthy answer, not a finding of its own.
148
212
  const stranded = strandedLegacyEngine(env);
213
+ const older = source === 'managed' ? olderBinaryName(bin) : null;
214
+ const notes = [
215
+ older
216
+ ? `Installed under the older file name ${older}; the next \`${auth_core_1.FIRST_PARTY_HARNESS.command}\` ` +
217
+ `run renames it to ${(0, auth_core_1.firstPartyHarnessBinaryName)(undefined, process.platform)} and leaves a link ` +
218
+ 'at the old name, so anything still reading that path keeps working.'
219
+ : null,
220
+ stranded
221
+ ? `${stranded.dir} still holds ${stranded.files} file(s), ${humanBytes(stranded.bytes)}, ` +
222
+ 'from before the config root moved. Nothing reads it now that the engine above ' +
223
+ 'resolves, and nothing removes it either — delete it when you want the space back.'
224
+ : null,
225
+ ].filter((note) => Boolean(note));
149
226
  return {
150
227
  name: 'engine',
151
228
  status: 'ok',
152
229
  detail: `${bin} (resolved via ${source})`,
153
- ...(stranded
154
- ? {
155
- remedy: `${stranded.dir} still holds ${stranded.files} file(s), ${humanBytes(stranded.bytes)}, ` +
156
- 'from before the config root moved. Nothing reads it now that the engine above ' +
157
- 'resolves, and nothing removes it either — delete it when you want the space back.',
158
- }
159
- : {}),
230
+ ...(notes.length ? { remedy: notes.join(' ') } : {}),
160
231
  };
161
232
  }
162
- const override = env[sky_code_1.ENGINE_PATH_ENV];
163
- if (override && !node_path_1.default.isAbsolute(override)) {
233
+ const override = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'path');
234
+ const legacyNote = legacyEnvNote('path', override.name);
235
+ if (override.value && !node_path_1.default.isAbsolute(override.value)) {
164
236
  return {
165
237
  name: 'engine',
166
238
  status: 'fail',
167
239
  // A relative override is rejected rather than resolved: for an
168
240
  // agent-invoked command the cwd is attacker-influenced, so a repo
169
- // containing ./sky-code could otherwise hijack the engine.
170
- detail: `${sky_code_1.ENGINE_PATH_ENV} is set to a relative path ('${override}') and was ignored`,
171
- remedy: `Set ${sky_code_1.ENGINE_PATH_ENV} to an absolute path.`,
241
+ // containing a file named like the engine could otherwise hijack it.
242
+ detail: `${override.name} is set to a relative path ('${override.value}') and was ignored`,
243
+ remedy: `Set ${pathVar} to an absolute path.${legacyNote ? ` ${legacyNote}` : ''}`,
172
244
  };
173
245
  }
174
- if (override) {
246
+ if (override.value) {
175
247
  return {
176
248
  name: 'engine',
177
249
  status: 'fail',
178
- detail: `${sky_code_1.ENGINE_PATH_ENV}='${override}' is not an executable file`,
179
- remedy: 'Point it at a real sky-code build, or unset it to fall back to PATH.',
250
+ detail: `${override.name}='${override.value}' is not an executable file`,
251
+ remedy: `Point it at a real ${auth_core_1.FIRST_PARTY_HARNESS.displayName} engine build, or unset it to fall back to PATH.` +
252
+ (legacyNote ? ` ${legacyNote}` : ''),
180
253
  };
181
254
  }
182
255
  return {
183
256
  name: 'engine',
184
257
  status: 'fail',
185
- detail: 'no sky-code binary on PATH or in the managed location',
186
- remedy: `Install the engine, or set ${sky_code_1.ENGINE_PATH_ENV} to an existing build.`,
258
+ detail: `no ${auth_core_1.FIRST_PARTY_HARNESS.displayName} engine binary ` +
259
+ `(${(0, auth_core_1.firstPartyHarnessBinaryNames)(process.platform).join(' or ')}) on PATH or in the managed location`,
260
+ remedy: `Install the engine (\`${auth_core_1.FIRST_PARTY_HARNESS.command} install\`), or set ${pathVar} to an existing build.`,
187
261
  };
188
262
  }
189
263
  function stateDirCheck(cwd, env) {
190
264
  const project = projectStateDir(cwd);
191
- const user = (0, sky_code_1.engineHome)(env);
265
+ const user = (0, first_party_harness_1.engineHome)(env);
192
266
  // The collision the plan calls out: if the project dir resolved onto the
193
267
  // daemon's auth/profile root, running with $HOME as cwd would reinterpret
194
268
  // user credentials as project configuration.
@@ -196,13 +270,13 @@ function stateDirCheck(cwd, env) {
196
270
  // holds for a user who relocated their root with OVERSKY_CONFIG_DIR. A
197
271
  // collision check that looks at the wrong directory reports "ok" and is worse
198
272
  // than no check.
199
- const daemonRoot = node_path_1.default.dirname((0, sky_code_1.engineHome)(env));
273
+ const daemonRoot = node_path_1.default.dirname((0, first_party_harness_1.engineHome)(env));
200
274
  if (project === daemonRoot || project.startsWith(daemonRoot + node_path_1.default.sep)) {
201
275
  return {
202
276
  name: 'state-paths',
203
277
  status: 'fail',
204
278
  detail: `project state dir ${project} sits inside the skrr user root ${daemonRoot}`,
205
- remedy: 'This is a build bug — report it. Do not run skrr Code from this directory.',
279
+ remedy: `This is a build bug — report it. Do not run ${auth_core_1.FIRST_PARTY_HARNESS.displayName} from this directory.`,
206
280
  };
207
281
  }
208
282
  const parts = [
@@ -212,14 +286,14 @@ function stateDirCheck(cwd, env) {
212
286
  return { name: 'state-paths', status: 'ok', detail: parts.join('; ') };
213
287
  }
214
288
  function compatCheck(cwd, env) {
215
- // Report both skrr Code's writable instruction surfaces and read-only
289
+ // Report both the engine's own writable instruction surfaces and read-only
216
290
  // compatibility sources so "where did this instruction come from?" has an
217
291
  // answer — a WL-2 acceptance criterion.
218
292
  const root = node_path_1.default.resolve(cwd);
219
293
  const own = [];
220
294
  for (const file of [
221
- node_path_1.default.join(root, '.sky-code', 'AGENTS.md'),
222
- node_path_1.default.join((0, sky_code_1.skyCodeInstructionHome)(env), 'AGENTS.md'),
295
+ node_path_1.default.join(projectStateDir(root), 'AGENTS.md'),
296
+ node_path_1.default.join((0, first_party_harness_1.engineInstructionHome)(env), 'AGENTS.md'),
223
297
  ]) {
224
298
  if ((0, node_fs_1.existsSync)(file))
225
299
  own.push(file);
@@ -233,12 +307,12 @@ function compatCheck(cwd, env) {
233
307
  return {
234
308
  name: 'compat-sources',
235
309
  status: 'ok',
236
- detail: 'no skrr Code-owned or compatibility instruction files in this project',
310
+ detail: `no ${auth_core_1.FIRST_PARTY_HARNESS.displayName}-owned or compatibility instruction files in this project`,
237
311
  };
238
312
  }
239
313
  const details = [];
240
314
  if (own.length > 0)
241
- details.push(`skrr Code-owned: ${own.join(', ')}`);
315
+ details.push(`${auth_core_1.FIRST_PARTY_HARNESS.displayName}-owned: ${own.join(', ')}`);
242
316
  if (compatibility.length > 0)
243
317
  details.push(`compatibility (read-only): ${compatibility.join(', ')}`);
244
318
  return {
@@ -256,11 +330,11 @@ function opencodeCheck(cwd) {
256
330
  return {
257
331
  name: 'migration',
258
332
  status: 'warn',
259
- // Warn, not fail: the directory being present is not an error, and Sky
260
- // Code will not read or touch it. The user simply has config they may
333
+ // Warn, not fail: the directory being present is not an error, and the
334
+ // engine will not read or touch it. The user simply has config they may
261
335
  // want carried over.
262
- detail: `${legacy} exists and is NOT read by skrr Code`,
263
- remedy: 'Run `skrr code migrate opencode --dry-run` to see what would carry over.',
336
+ detail: `${legacy} exists and is NOT read by ${auth_core_1.FIRST_PARTY_HARNESS.displayName}`,
337
+ remedy: `Run \`${auth_core_1.FIRST_PARTY_HARNESS.command} migrate opencode --dry-run\` to see what would carry over.`,
264
338
  };
265
339
  }
266
340
  /**
@@ -270,26 +344,30 @@ function opencodeCheck(cwd) {
270
344
  * it is this one, so the check stays. What changed is that the answer is
271
345
  * computed from {@link MIRRORED_HARNESS_TIERS} instead of being restated as
272
346
  * prose: this line described Tier 2 behaviour for a day after the owner
273
- * decision of 2026-08-11 moved `sky-code` to Tier 1, which is the worst
347
+ * decision of 2026-08-11 moved the first-party harness to Tier 1, which is the worst
274
348
  * possible audience to mislead — the people running `doctor` are running it
275
349
  * because permissions already confused them.
276
350
  *
277
- * `sky-code-trust-parity.spec.ts` fails if the mirror drifts from
351
+ * `first-party-harness-trust-parity.spec.ts` fails if the mirror drifts from
278
352
  * `daemon/src/harness-trust.ts` again.
279
353
  */
280
354
  function trustCheck() {
281
- const tier = (0, harness_tiers_1.mirroredTier)(sky_code_managed_1.SKY_CODE_HARNESS);
355
+ // The canonical slug. The shared table carries every spelling at the same tier,
356
+ // so which one is asked does not change the answer — but the report prints the
357
+ // name the platform stores.
358
+ const harness = auth_core_1.FIRST_PARTY_HARNESS.provider;
359
+ const tier = (0, harness_tiers_1.mirroredTier)(harness);
282
360
  if (tier == null) {
283
361
  // Unreachable while the constant carries an entry, and deliberately not an
284
362
  // invented tier: guessing here would put a false claim in a diagnostic.
285
363
  return {
286
364
  name: 'trust-tier',
287
365
  status: 'warn',
288
- detail: `no mirrored trust tier for ${sky_code_managed_1.SKY_CODE_HARNESS} in this CLI build`,
366
+ detail: `no mirrored trust tier for ${harness} in this CLI build`,
289
367
  remedy: `The daemon decides; read ${harness_tiers_1.HARNESS_TIER_AUTHORITY} or run \`oversky doctor\`.`,
290
368
  };
291
369
  }
292
- const described = (0, harness_tiers_1.describeTier)(sky_code_managed_1.SKY_CODE_HARNESS, tier);
370
+ const described = (0, harness_tiers_1.describeTier)(harness, tier);
293
371
  return {
294
372
  name: 'trust-tier',
295
373
  status: described.notable ? 'warn' : 'ok',
@@ -317,7 +395,7 @@ function permissionAuthorityCheck(env) {
317
395
  /**
318
396
  * Hosts the engine's WL-2.7 egress policy denies, and the one it still permits.
319
397
  *
320
- * Duplicated from `packages/core/src/egress.ts` in the sky-code fork rather than
398
+ * Duplicated from `packages/core/src/egress.ts` in the engine's fork rather than
321
399
  * imported: the CLI does not depend on the engine's source tree, and `doctor`
322
400
  * must be able to answer "what will this binary refuse to talk to?" without one.
323
401
  * The cost of the duplication is bounded because the fork's own test asserts the
@@ -334,14 +412,15 @@ const EGRESS_DENIED_HOSTS = [
334
412
  'social-cards.sst.dev',
335
413
  'opencode.internal',
336
414
  ];
337
- const EGRESS_OVERRIDE_ENV = 'SKY_CODE_ALLOW_UPSTREAM_EGRESS';
415
+ /** The ENGINE reads this one under its own name; the platform only reports it. */
416
+ const EGRESS_OVERRIDE_ENV = auth_core_1.FIRST_PARTY_HARNESS_ENGINE.env.allowUpstreamEgress;
338
417
  function egressCheck(env) {
339
418
  const override = env[EGRESS_OVERRIDE_ENV];
340
419
  if (override === '1' || override === 'true') {
341
420
  return {
342
421
  name: 'upstream-egress',
343
422
  status: 'warn',
344
- detail: `${EGRESS_OVERRIDE_ENV} is set — sky-code may reach upstream hosted services`,
423
+ detail: `${EGRESS_OVERRIDE_ENV} is set — ${auth_core_1.FIRST_PARTY_HARNESS.displayName} may reach upstream hosted services`,
345
424
  remedy: 'Unset it unless you are deliberately debugging upstream behaviour. Session content, ' +
346
425
  'repository names, and account tokens can leave for a third party while it is set.',
347
426
  };
@@ -368,7 +447,7 @@ function egressCheck(env) {
368
447
  * inventing a resolved credential would not be.
369
448
  */
370
449
  function credentialCheck(env) {
371
- // The variable `daemon/src/backends/sky-code.ts` declares. Named here rather
450
+ // The variable `daemon/src/backends/first-party-harness.ts` declares. Named here rather
372
451
  // than imported because the CLI does not depend on the daemon's source.
373
452
  const ENGINE_KEY_VAR = 'OPENROUTER_API_KEY';
374
453
  const present = typeof env[ENGINE_KEY_VAR] === 'string' && env[ENGINE_KEY_VAR].length > 0;
@@ -388,7 +467,7 @@ function credentialCheck(env) {
388
467
  // matches the one `skrr code`'s fallback line gives when it says whether it is
389
468
  // falling back to BYOK or to nothing at all. Reporting only `OPENROUTER_API_KEY`
390
469
  // told a user with an `ANTHROPIC_API_KEY` they had no credential.
391
- const others = Object.keys((0, sky_code_1.inheritedProviderCredentials)(env)).sort();
470
+ const others = Object.keys((0, first_party_harness_1.inheritedProviderCredentials)(env)).sort();
392
471
  if (others.length) {
393
472
  const shown = others.slice(0, 4);
394
473
  return {
@@ -505,7 +584,7 @@ function delegatedSurfaceCheck(env) {
505
584
  * by construction never enters a child environment anyway.
506
585
  */
507
586
  function managedInferenceCheck(env) {
508
- const posture = (0, sky_code_managed_1.managedInferencePosture)(env);
587
+ const posture = (0, first_party_harness_managed_1.managedInferencePosture)(env);
509
588
  return {
510
589
  name: 'managed-inference',
511
590
  status: posture.status,
@@ -550,7 +629,7 @@ function sessionAuthorityCheck(env) {
550
629
  // "a daemon adjudicates every tool call" at a session where nothing adjudicates
551
630
  // anything. The docstring above named that conflation and the code beneath it
552
631
  // committed it.
553
- switch ((0, sky_code_managed_1.resolveTrustPlane)(env)) {
632
+ switch ((0, first_party_harness_managed_1.resolveTrustPlane)(env)) {
554
633
  case 'daemon-supervised':
555
634
  return {
556
635
  name: 'session-authority',
@@ -585,7 +664,7 @@ function sessionAuthorityCheck(env) {
585
664
  remedy: 'Intended for local use, and nothing to fix. Worth knowing because it is NOT the same ' +
586
665
  'trust plane as a daemon-dispatched run — and neither plane is an OS-level sandbox ' +
587
666
  '(no seccomp, container, or namespace). An untrusted autonomous workload needs a hosted ' +
588
- 'or container profile; see sky-code/docs/sky-code/threat-model.md.',
667
+ `or container profile; see docs/${auth_core_1.FIRST_PARTY_HARNESS_ENGINE.appName}/threat-model.md in the engine's repository.`,
589
668
  };
590
669
  }
591
670
  }
@@ -610,28 +689,36 @@ function agentAttributionCheck() {
610
689
  // whose job is to tell you your config is broken.
611
690
  let configured;
612
691
  try {
613
- configured = (0, config_1.loadConfig)().skyCodeAgentId?.trim();
692
+ configured = (0, first_party_harness_managed_1.readConfiguredAgentSetting)();
614
693
  }
615
694
  catch (err) {
616
695
  return {
617
696
  name: 'agent',
618
697
  status: 'warn',
619
- detail: `could not read ${sky_code_managed_1.AGENT_CONFIG_KEY}: ${err instanceof Error ? err.message : String(err)}`,
698
+ detail: `could not read ${first_party_harness_managed_1.AGENT_CONFIG_KEY}: ${err instanceof Error ? err.message : String(err)}`,
620
699
  remedy: 'Fix or delete ~/.skrr/cli-config.json, then sign in again.',
621
700
  };
622
701
  }
623
- if (configured) {
702
+ const { command, displayName } = auth_core_1.FIRST_PARTY_HARNESS;
703
+ if (configured.value) {
624
704
  return {
625
705
  name: 'agent',
626
706
  status: 'ok',
627
- detail: `sessions are attributed to "${configured}" (${sky_code_managed_1.AGENT_CONFIG_KEY})`,
707
+ // The key it was READ from, which is not always the key written today.
708
+ detail: `sessions are attributed to "${configured.value}" (${configured.key})`,
709
+ ...(configured.legacy
710
+ ? {
711
+ remedy: `"${configured.key}" is the older name for this setting and is still read. ` +
712
+ `\`${command} skrr-agent --set ${configured.value}\` rewrites it as "${first_party_harness_managed_1.AGENT_CONFIG_KEY}".`,
713
+ }
714
+ : {}),
628
715
  };
629
716
  }
630
717
  return {
631
718
  name: 'agent',
632
719
  status: 'ok',
633
- detail: `no ${sky_code_managed_1.AGENT_CONFIG_KEY} set — sessions use your sole owned agent, else your default ${sky_code_managed_1.SKY_CODE_HARNESS} agent`,
634
- remedy: 'Run `skrr code skrr-agent` to see which, or `skrr code skrr-agent --set <id>` to pin one.',
720
+ detail: `no ${first_party_harness_managed_1.AGENT_CONFIG_KEY} set — sessions use your sole owned agent, else your default ${displayName} agent`,
721
+ remedy: `Run \`${command} skrr-agent\` to see which, or \`${command} skrr-agent --set <id>\` to pin one.`,
635
722
  };
636
723
  }
637
724
  function runDoctor(cwd = process.cwd(), env = process.env) {
@@ -671,9 +758,9 @@ function formatReport(report) {
671
758
  }
672
759
  lines.push('');
673
760
  lines.push(report.status === 'fail'
674
- ? 'One or more checks failed — skrr Code will not run correctly until they are resolved.'
761
+ ? `One or more checks failed — ${auth_core_1.FIRST_PARTY_HARNESS.displayName} will not run correctly until they are resolved.`
675
762
  : report.status === 'warn'
676
- ? 'skrr Code is usable; the warnings above are worth reading.'
763
+ ? `${auth_core_1.FIRST_PARTY_HARNESS.displayName} is usable; the warnings above are worth reading.`
677
764
  : 'All checks passed.');
678
765
  return lines.join('\n');
679
766
  }