@skrr-ai/cli 0.1.32 → 0.1.34

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 (114) hide show
  1. package/bin/run.js +2 -2
  2. package/dist/base-command.js +5 -0
  3. package/dist/commands/agents/list.d.ts +2 -1
  4. package/dist/commands/agents/list.js +2 -1
  5. package/dist/commands/agents/show.js +2 -1
  6. package/dist/commands/balance/statement.js +8 -4
  7. package/dist/commands/browser/install.js +6 -2
  8. package/dist/commands/browser/uninstall.js +6 -2
  9. package/dist/commands/code/acp.js +2 -1
  10. package/dist/commands/code/doctor.d.ts +1 -1
  11. package/dist/commands/code/doctor.js +6 -5
  12. package/dist/commands/code/handover.d.ts +2 -2
  13. package/dist/commands/code/handover.js +2 -2
  14. package/dist/commands/code/index.d.ts +2 -2
  15. package/dist/commands/code/index.js +18 -17
  16. package/dist/commands/code/install.d.ts +3 -3
  17. package/dist/commands/code/install.js +18 -11
  18. package/dist/commands/code/migrate.js +3 -2
  19. package/dist/commands/code/oversky-agent.d.ts +5 -4
  20. package/dist/commands/code/oversky-agent.js +24 -22
  21. package/dist/commands/code/run.js +2 -1
  22. package/dist/commands/harnesses/list.d.ts +9 -1
  23. package/dist/commands/harnesses/list.js +28 -7
  24. package/dist/commands/harnesses/show.js +7 -2
  25. package/dist/commands/instructions/install.js +16 -6
  26. package/dist/commands/learning/delete.d.ts +9 -0
  27. package/dist/commands/learning/delete.js +40 -0
  28. package/dist/commands/learning/export.d.ts +9 -0
  29. package/dist/commands/learning/export.js +56 -0
  30. package/dist/commands/learning/reset.d.ts +9 -0
  31. package/dist/commands/learning/reset.js +36 -0
  32. package/dist/commands/learning/set.d.ts +10 -0
  33. package/dist/commands/learning/set.js +52 -0
  34. package/dist/commands/learning/status.d.ts +8 -0
  35. package/dist/commands/learning/status.js +35 -0
  36. package/dist/commands/logout.js +10 -5
  37. package/dist/commands/machines/dedicated/attach.js +2 -1
  38. package/dist/commands/tasks/runs.js +3 -1
  39. package/dist/commands/workspaces/use.js +2 -1
  40. package/dist/lib/adaptive-learning.d.ts +37 -0
  41. package/dist/lib/adaptive-learning.js +39 -0
  42. package/dist/lib/auth-core-init.d.ts +23 -0
  43. package/dist/lib/auth-core-init.js +61 -0
  44. package/dist/lib/code-handover.d.ts +1 -1
  45. package/dist/lib/code-handover.js +3 -2
  46. package/dist/lib/config.d.ts +30 -4
  47. package/dist/lib/config.js +2 -1
  48. package/dist/lib/daemon-installer.d.ts +1 -1
  49. package/dist/lib/daemon-target.js +2 -2
  50. package/dist/lib/dedicated-machines.d.ts +2 -2
  51. package/dist/lib/dedicated-machines.js +11 -4
  52. package/dist/lib/exec-runtime-binary.d.ts +2 -2
  53. package/dist/lib/exec-runtime-binary.js +2 -2
  54. package/dist/lib/{sky-code-agent.d.ts → first-party-harness-agent.d.ts} +20 -19
  55. package/dist/lib/{sky-code-agent.js → first-party-harness-agent.js} +85 -47
  56. package/dist/lib/{sky-code-broker.d.ts → first-party-harness-broker.d.ts} +6 -6
  57. package/dist/lib/{sky-code-broker.js → first-party-harness-broker.js} +23 -23
  58. package/dist/lib/{sky-code-doctor.d.ts → first-party-harness-doctor.d.ts} +12 -2
  59. package/dist/lib/{sky-code-doctor.js → first-party-harness-doctor.js} +181 -94
  60. package/dist/lib/{sky-code-managed.d.ts → first-party-harness-managed.d.ts} +55 -30
  61. package/dist/lib/{sky-code-managed.js → first-party-harness-managed.js} +92 -35
  62. package/dist/lib/{sky-code.d.ts → first-party-harness.d.ts} +107 -36
  63. package/dist/lib/{sky-code.js → first-party-harness.js} +172 -73
  64. package/dist/lib/harness-provider-input.d.ts +35 -0
  65. package/dist/lib/harness-provider-input.js +57 -0
  66. package/dist/lib/harness-tiers.d.ts +8 -2
  67. package/dist/lib/harness-tiers.js +11 -6
  68. package/dist/lib/task-instruction-offer.js +10 -4
  69. package/dist/lib/worklogs.js +2 -2
  70. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.d.ts +2 -2
  71. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/configRoot.js +2 -2
  72. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +248 -0
  73. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +361 -0
  74. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.d.ts +147 -0
  75. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessChannels.js +180 -0
  76. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.d.ts +111 -0
  77. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarnessHome.js +314 -0
  78. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.d.ts +11 -5
  79. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +14 -7
  80. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +3 -1
  81. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +51 -14
  82. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +1 -1
  83. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +4 -4
  84. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +4 -4
  85. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.d.ts +2 -2
  86. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/configRoot.js +2 -2
  87. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +248 -0
  88. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +332 -0
  89. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.d.ts +147 -0
  90. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessChannels.js +170 -0
  91. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.d.ts +111 -0
  92. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarnessHome.js +303 -0
  93. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.d.ts +11 -5
  94. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +14 -7
  95. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +3 -1
  96. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +12 -2
  97. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +1 -1
  98. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +4 -4
  99. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +4 -4
  100. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  101. package/dist/node_modules/@skrr-ai/data-provider/index.js +4816 -4782
  102. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
  103. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +1 -1
  104. package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +1 -1
  105. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
  106. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
  107. package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +1 -1
  108. package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
  109. package/oclif.manifest.json +34286 -33962
  110. package/package.json +5 -2
  111. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +0 -96
  112. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +0 -115
  113. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +0 -96
  114. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.js +0 -107
@@ -1,7 +1,7 @@
1
1
  /**
2
- * OSK-3892 — the DECISION half of a CLI-hosted managed skrr Code session.
2
+ * OSK-3892 — the DECISION half of a CLI-hosted managed first-party harness session.
3
3
  *
4
- * skrr Code is standalone-capable and daemon-preferred: when a daemon is in the
4
+ * The first-party harness is standalone-capable and daemon-preferred: when a daemon is in the
5
5
  * loop it brokers inference, and when a human just ran `skrr login` the CLI hosts
6
6
  * the broker itself. This module answers the two questions that must be answered
7
7
  * BEFORE any credential exists —
@@ -17,9 +17,9 @@
17
17
  * Everything here is pure (env, a config read, one `existsSync`) and imports no
18
18
  * auth, no data-provider and no broker. That is what lets `skrr code doctor` report
19
19
  * the posture without configuring the auth plane, and it keeps
20
- * `sky-code-doctor.ts` honest about being safe to run in any context. The
20
+ * `first-party-harness-doctor.ts` honest about being safe to run in any context. The
21
21
  * acquisition and the `execEngine` hooks that drive it live in
22
- * `sky-code-broker.ts`, which the `skrr code` commands import directly.
22
+ * `first-party-harness-broker.ts`, which the `skrr code` commands import directly.
23
23
  *
24
24
  * ── Invariant I4: managed / BYOK / offline never silently become each other ─
25
25
  *
@@ -30,21 +30,14 @@
30
30
  * once, on stderr. Acquisition failures are always announced, for the same
31
31
  * reason: the user is about to spend their own key and must know it.
32
32
  */
33
- /**
34
- * Opt OUT of a CLI-hosted managed session.
35
- *
36
- * Present because "run with my own key" has to be expressible without logging
37
- * out, and because a test that asserts argv forwarding must be able to say "this
38
- * run is not about acquisition" rather than depend on whether the machine
39
- * happens to be signed in.
40
- */
41
- export declare const MANAGED_ENV_FLAG = "OVERSKY_SKY_CODE_MANAGED";
33
+ /** The neutral operator switch for CLI-hosted managed inference. */
34
+ export declare const MANAGED_ENV_FLAG: string;
42
35
  /**
43
36
  * The CLI's own flag, deliberately NOT `--agent`.
44
37
  *
45
38
  * `skrr code` forwards argv VERBATIM and the engine owns the bare flag namespace —
46
39
  * `skrr code --agent reviewer` is the engine's flag and is pinned as such by
47
- * `sky-code-passthrough.spec.ts`. A bare `--agent` here would steal it.
40
+ * `first-party-harness-passthrough.spec.ts`. A bare `--agent` here would steal it.
48
41
  */
49
42
  export declare const SKRR_AGENT_FLAG = "--skrr-agent";
50
43
  /**
@@ -59,26 +52,58 @@ export declare const SKRR_AGENT_FLAG = "--skrr-agent";
59
52
  export declare const OVERSKY_AGENT_FLAG = "--oversky-agent";
60
53
  /** Every spelling the argv scanner honours, primary first. */
61
54
  export declare const AGENT_FLAG_SPELLINGS: readonly ["--skrr-agent", "--oversky-agent"];
62
- /** The config key `skrr code` reads when the flag is absent. */
63
- export declare const AGENT_CONFIG_KEY = "skyCodeAgentId";
64
55
  /**
65
- * The harness name this CLI is, as the server spells it.
66
- *
67
- * The server never takes it from the wire — `sessionInferenceRelay.js` fixes
68
- * `provider: 'sky-code'` itself, because it selects the relay capability and
69
- * composes the `provider_model` budget key, none of which is a caller's choice.
70
- * So this is not a request parameter; it is the CLI naming itself in the two
71
- * places that legitimately ask (the trust-tier lookup, and which default agent
72
- * to establish).
56
+ * The config key `skrr code` reads when the flag is absent — and writes.
57
+ *
58
+ * Brand-neutral, so a product rename never moves it. Earlier CLIs stored the same
59
+ * setting under a key named after the product; those are still READ
60
+ * ({@link legacyAgentConfigKeys}), and every write replaces them with this one.
61
+ *
62
+ * The harness name the CLI sends when it asks for a default agent is not a
63
+ * constant here at all: it is `FIRST_PARTY_HARNESS.provider`. The server never
64
+ * takes the managed-session provider from the wire — `sessionInferenceRelay.js`
65
+ * fixes it itself, because it selects the relay capability and composes the
66
+ * `provider_model` budget key, none of which is a caller's choice — so the CLI
67
+ * names itself only where that legitimately matters (the trust-tier lookup, and
68
+ * which default agent to establish).
69
+ */
70
+ export declare const AGENT_CONFIG_KEY: "firstPartyHarnessAgentId";
71
+ /**
72
+ * Keys earlier CLIs stored the agent setting under: `<camelCased spelling>AgentId`
73
+ * for every spelling of the harness, canonical first.
74
+ *
75
+ * Derived rather than listed so no product name is written here — and so the key
76
+ * is read for exactly as long as its spelling is accepted anywhere else.
77
+ */
78
+ export declare function legacyAgentConfigKeys(): string[];
79
+ export interface AgentSetting {
80
+ /** Trimmed, non-empty value, or undefined when nothing usable is stored. */
81
+ value: string | undefined;
82
+ /** The key that supplied `value`. */
83
+ key: string | undefined;
84
+ /** True when `key` is an older name for the setting. */
85
+ legacy: boolean;
86
+ }
87
+ /** Read the setting from a config record: the neutral key first, then each older key. */
88
+ export declare function readAgentSetting(config: Readonly<Record<string, unknown>>): AgentSetting;
89
+ /**
90
+ * The setting as the effective config holds it. THROWS when the config file is
91
+ * unparseable, exactly as `loadConfig` does — callers that must not fail catch it.
92
+ */
93
+ export declare function readConfiguredAgentSetting(): AgentSetting;
94
+ /**
95
+ * A copy of `raw` with the setting written under the neutral key (or removed when
96
+ * `id` is undefined) and EVERY older key removed — so a later read can never find a
97
+ * stale value under a name this write did not touch.
73
98
  */
74
- export declare const SKY_CODE_HARNESS = "sky-code";
99
+ export declare function withAgentSetting(raw: Readonly<Record<string, unknown>>, id: string | undefined): Record<string, unknown>;
75
100
  /**
76
101
  * Mirrored from `@skrr-ai/inference-broker`, for the same reason
77
102
  * `harness-tiers.ts` mirrors the daemon's trust table: importing the package
78
103
  * would pull a loopback SERVER into `skrr code doctor` and into every unmanaged
79
104
  * `skrr code` startup, to read two string constants.
80
105
  *
81
- * `sky-code-managed.spec.ts` asserts these against the package, so a rename there
106
+ * `first-party-harness-managed.spec.ts` asserts these against the package, so a rename there
82
107
  * fails a test here rather than silently making the posture check blind.
83
108
  */
84
109
  export declare const MANAGED_SESSION_ENV = "OVERSKY_MANAGED_SESSION";
@@ -103,8 +128,8 @@ export declare const MANAGED_SESSION_ENV = "OVERSKY_MANAGED_SESSION";
103
128
  * CLI-hosted broker cannot forge the first pair, which is what makes the order
104
129
  * load-bearing rather than stylistic.
105
130
  */
106
- export type SkyCodeTrustPlane = 'daemon-supervised' | 'cli-brokered' | 'standalone';
107
- export declare function resolveTrustPlane(env: NodeJS.ProcessEnv): SkyCodeTrustPlane;
131
+ export type EngineTrustPlane = 'daemon-supervised' | 'cli-brokered' | 'standalone';
132
+ export declare function resolveTrustPlane(env: NodeJS.ProcessEnv): EngineTrustPlane;
108
133
  export declare const BROKER_SOCKET_ENV = "OVERSKY_INFERENCE_BROKER_SOCKET";
109
134
  export type ManagedSkipKind = 'disabled' | 'daemon-brokered' | 'unsupported-platform' | 'insecure-server';
110
135
  export interface ManagedSkip {
@@ -125,7 +150,7 @@ export interface ManagedSkip {
125
150
  * posture computed from the real `process.env` while claiming to describe the
126
151
  * supplied one is a diagnostic that lies.
127
152
  */
128
- export declare function skyCodeServerUrl(env?: NodeJS.ProcessEnv): string;
153
+ export declare function configuredServerUrl(env?: NodeJS.ProcessEnv): string;
129
154
  /**
130
155
  * Why this process would NOT host a managed session — or `null` if it would.
131
156
  *
@@ -142,7 +167,7 @@ export declare function managedSkipReason(env?: NodeJS.ProcessEnv): ManagedSkip
142
167
  * or not this run ends up brokering. Both spellings are accepted, and the
143
168
  * space-separated form consumes its value token.
144
169
  *
145
- * Everything else is spliced out IN PLACE: `sky-code-passthrough.spec.ts` asserts
170
+ * Everything else is spliced out IN PLACE: `first-party-harness-passthrough.spec.ts` asserts
146
171
  * exact array equality, so order and adjacency are the contract, and a flag
147
172
  * separated from its value is a different command.
148
173
  */
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * OSK-3892 — the DECISION half of a CLI-hosted managed skrr Code session.
3
+ * OSK-3892 — the DECISION half of a CLI-hosted managed first-party harness session.
4
4
  *
5
- * skrr Code is standalone-capable and daemon-preferred: when a daemon is in the
5
+ * The first-party harness is standalone-capable and daemon-preferred: when a daemon is in the
6
6
  * loop it brokers inference, and when a human just ran `skrr login` the CLI hosts
7
7
  * the broker itself. This module answers the two questions that must be answered
8
8
  * BEFORE any credential exists —
@@ -18,9 +18,9 @@
18
18
  * Everything here is pure (env, a config read, one `existsSync`) and imports no
19
19
  * auth, no data-provider and no broker. That is what lets `skrr code doctor` report
20
20
  * the posture without configuring the auth plane, and it keeps
21
- * `sky-code-doctor.ts` honest about being safe to run in any context. The
21
+ * `first-party-harness-doctor.ts` honest about being safe to run in any context. The
22
22
  * acquisition and the `execEngine` hooks that drive it live in
23
- * `sky-code-broker.ts`, which the `skrr code` commands import directly.
23
+ * `first-party-harness-broker.ts`, which the `skrr code` commands import directly.
24
24
  *
25
25
  * ── Invariant I4: managed / BYOK / offline never silently become each other ─
26
26
  *
@@ -32,32 +32,30 @@
32
32
  * reason: the user is about to spend their own key and must know it.
33
33
  */
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.BROKER_SOCKET_ENV = exports.MANAGED_SESSION_ENV = exports.SKY_CODE_HARNESS = exports.AGENT_CONFIG_KEY = exports.AGENT_FLAG_SPELLINGS = exports.OVERSKY_AGENT_FLAG = exports.SKRR_AGENT_FLAG = exports.MANAGED_ENV_FLAG = void 0;
35
+ exports.BROKER_SOCKET_ENV = exports.MANAGED_SESSION_ENV = exports.AGENT_CONFIG_KEY = exports.AGENT_FLAG_SPELLINGS = exports.OVERSKY_AGENT_FLAG = exports.SKRR_AGENT_FLAG = exports.MANAGED_ENV_FLAG = void 0;
36
+ exports.legacyAgentConfigKeys = legacyAgentConfigKeys;
37
+ exports.readAgentSetting = readAgentSetting;
38
+ exports.readConfiguredAgentSetting = readConfiguredAgentSetting;
39
+ exports.withAgentSetting = withAgentSetting;
36
40
  exports.resolveTrustPlane = resolveTrustPlane;
37
- exports.skyCodeServerUrl = skyCodeServerUrl;
41
+ exports.configuredServerUrl = configuredServerUrl;
38
42
  exports.managedSkipReason = managedSkipReason;
39
43
  exports.takeOverskyAgentFlag = takeOverskyAgentFlag;
40
44
  exports.namedEngineModel = namedEngineModel;
41
45
  exports.withManagedModel = withManagedModel;
42
46
  exports.managedInferencePosture = managedInferencePosture;
43
47
  const node_fs_1 = require("node:fs");
48
+ const auth_core_1 = require("@skrr-ai/auth-core");
44
49
  const config_1 = require("./config");
45
50
  const runtime_context_1 = require("./runtime-context");
46
- /**
47
- * Opt OUT of a CLI-hosted managed session.
48
- *
49
- * Present because "run with my own key" has to be expressible without logging
50
- * out, and because a test that asserts argv forwarding must be able to say "this
51
- * run is not about acquisition" rather than depend on whether the machine
52
- * happens to be signed in.
53
- */
54
- exports.MANAGED_ENV_FLAG = 'OVERSKY_SKY_CODE_MANAGED';
51
+ /** The neutral operator switch for CLI-hosted managed inference. */
52
+ exports.MANAGED_ENV_FLAG = auth_core_1.FIRST_PARTY_HARNESS_ENV.managed.name;
55
53
  /**
56
54
  * The CLI's own flag, deliberately NOT `--agent`.
57
55
  *
58
56
  * `skrr code` forwards argv VERBATIM and the engine owns the bare flag namespace —
59
57
  * `skrr code --agent reviewer` is the engine's flag and is pinned as such by
60
- * `sky-code-passthrough.spec.ts`. A bare `--agent` here would steal it.
58
+ * `first-party-harness-passthrough.spec.ts`. A bare `--agent` here would steal it.
61
59
  */
62
60
  exports.SKRR_AGENT_FLAG = '--skrr-agent';
63
61
  /**
@@ -72,26 +70,77 @@ exports.SKRR_AGENT_FLAG = '--skrr-agent';
72
70
  exports.OVERSKY_AGENT_FLAG = '--oversky-agent';
73
71
  /** Every spelling the argv scanner honours, primary first. */
74
72
  exports.AGENT_FLAG_SPELLINGS = [exports.SKRR_AGENT_FLAG, exports.OVERSKY_AGENT_FLAG];
75
- /** The config key `skrr code` reads when the flag is absent. */
76
- exports.AGENT_CONFIG_KEY = 'skyCodeAgentId';
77
73
  /**
78
- * The harness name this CLI is, as the server spells it.
74
+ * The config key `skrr code` reads when the flag is absent — and writes.
79
75
  *
80
- * The server never takes it from the wire — `sessionInferenceRelay.js` fixes
81
- * `provider: 'sky-code'` itself, because it selects the relay capability and
82
- * composes the `provider_model` budget key, none of which is a caller's choice.
83
- * So this is not a request parameter; it is the CLI naming itself in the two
84
- * places that legitimately ask (the trust-tier lookup, and which default agent
85
- * to establish).
76
+ * Brand-neutral, so a product rename never moves it. Earlier CLIs stored the same
77
+ * setting under a key named after the product; those are still READ
78
+ * ({@link legacyAgentConfigKeys}), and every write replaces them with this one.
79
+ *
80
+ * The harness name the CLI sends when it asks for a default agent is not a
81
+ * constant here at all: it is `FIRST_PARTY_HARNESS.provider`. The server never
82
+ * takes the managed-session provider from the wire — `sessionInferenceRelay.js`
83
+ * fixes it itself, because it selects the relay capability and composes the
84
+ * `provider_model` budget key, none of which is a caller's choice — so the CLI
85
+ * names itself only where that legitimately matters (the trust-tier lookup, and
86
+ * which default agent to establish).
87
+ */
88
+ exports.AGENT_CONFIG_KEY = 'firstPartyHarnessAgentId';
89
+ /** `a-b` → `aB`: how a hyphenated spelling became part of a config key. */
90
+ function camelCaseSlug(slug) {
91
+ return slug.replace(/-([a-z0-9])/g, (_, next) => next.toUpperCase());
92
+ }
93
+ // TODO(identity): move to auth-core — the identity module records legacy ENV
94
+ // names; it has no notion of a legacy CONFIG key yet.
95
+ /**
96
+ * Keys earlier CLIs stored the agent setting under: `<camelCased spelling>AgentId`
97
+ * for every spelling of the harness, canonical first.
98
+ *
99
+ * Derived rather than listed so no product name is written here — and so the key
100
+ * is read for exactly as long as its spelling is accepted anywhere else.
101
+ */
102
+ function legacyAgentConfigKeys() {
103
+ return (0, auth_core_1.firstPartyHarnessSpellings)().map((spelling) => `${camelCaseSlug(spelling)}AgentId`);
104
+ }
105
+ /** Read the setting from a config record: the neutral key first, then each older key. */
106
+ function readAgentSetting(config) {
107
+ for (const key of [exports.AGENT_CONFIG_KEY, ...legacyAgentConfigKeys()]) {
108
+ const raw = config[key];
109
+ if (typeof raw === 'string' && raw.trim()) {
110
+ return { value: raw.trim(), key, legacy: key !== exports.AGENT_CONFIG_KEY };
111
+ }
112
+ }
113
+ return { value: undefined, key: undefined, legacy: false };
114
+ }
115
+ /**
116
+ * The setting as the effective config holds it. THROWS when the config file is
117
+ * unparseable, exactly as `loadConfig` does — callers that must not fail catch it.
86
118
  */
87
- exports.SKY_CODE_HARNESS = 'sky-code';
119
+ function readConfiguredAgentSetting() {
120
+ return readAgentSetting((0, config_1.loadConfig)());
121
+ }
122
+ /**
123
+ * A copy of `raw` with the setting written under the neutral key (or removed when
124
+ * `id` is undefined) and EVERY older key removed — so a later read can never find a
125
+ * stale value under a name this write did not touch.
126
+ */
127
+ function withAgentSetting(raw, id) {
128
+ const next = { ...raw };
129
+ for (const key of legacyAgentConfigKeys())
130
+ delete next[key];
131
+ if (id)
132
+ next[exports.AGENT_CONFIG_KEY] = id;
133
+ else
134
+ delete next[exports.AGENT_CONFIG_KEY];
135
+ return next;
136
+ }
88
137
  /**
89
138
  * Mirrored from `@skrr-ai/inference-broker`, for the same reason
90
139
  * `harness-tiers.ts` mirrors the daemon's trust table: importing the package
91
140
  * would pull a loopback SERVER into `skrr code doctor` and into every unmanaged
92
141
  * `skrr code` startup, to read two string constants.
93
142
  *
94
- * `sky-code-managed.spec.ts` asserts these against the package, so a rename there
143
+ * `first-party-harness-managed.spec.ts` asserts these against the package, so a rename there
95
144
  * fails a test here rather than silently making the posture check blind.
96
145
  */
97
146
  exports.MANAGED_SESSION_ENV = 'OVERSKY_MANAGED_SESSION';
@@ -112,7 +161,7 @@ exports.BROKER_SOCKET_ENV = 'OVERSKY_INFERENCE_BROKER_SOCKET';
112
161
  * posture computed from the real `process.env` while claiming to describe the
113
162
  * supplied one is a diagnostic that lies.
114
163
  */
115
- function skyCodeServerUrl(env = process.env) {
164
+ function configuredServerUrl(env = process.env) {
116
165
  const fromEnv = (env.OVERSKY_BASE_URL || env.OVERSKY_SERVER_URL || '').trim();
117
166
  if (fromEnv)
118
167
  return fromEnv;
@@ -137,7 +186,7 @@ function isHttpsUrl(value) {
137
186
  /**
138
187
  * The server URL as a diagnostic is allowed to say it: SCHEME AND HOST ONLY.
139
188
  *
140
- * `skyCodeServerUrl` returns `OVERSKY_BASE_URL` / `OVERSKY_SERVER_URL` /
189
+ * `configuredServerUrl` returns `OVERSKY_BASE_URL` / `OVERSKY_SERVER_URL` /
141
190
  * `loadConfig().baseURL` unmodified, and a URL may legally carry userinfo — so
142
191
  * `https://user:s3cret@host` put a password into `skrr code doctor --json`, which
143
192
  * `docs/cli/SKRR_CODE.md` calls safe to paste into a ticket and promises never
@@ -201,10 +250,18 @@ function managedSkipReason(env = process.env) {
201
250
  announce: false,
202
251
  };
203
252
  }
204
- if (envFlagIsOff(env[exports.MANAGED_ENV_FLAG])) {
253
+ // The operator's opt-OUT (`FIRST_PARTY_HARNESS_ENV.managed`, neutral name first,
254
+ // older name second). Present because "run with my own key" has to be
255
+ // expressible without logging out, and because a test that asserts argv
256
+ // forwarding must be able to say "this run is not about acquisition" rather
257
+ // than depend on whether the machine happens to be signed in.
258
+ const managedFlag = (0, auth_core_1.readFirstPartyHarnessEnv)(env, 'managed');
259
+ if (envFlagIsOff(managedFlag.value)) {
205
260
  return {
206
261
  kind: 'disabled',
207
- detail: `${exports.MANAGED_ENV_FLAG} is off`,
262
+ // The variable that was actually read — two names are honoured, and the one
263
+ // to change is the one that is set.
264
+ detail: `${managedFlag.name} is off`,
208
265
  announce: false,
209
266
  };
210
267
  }
@@ -218,7 +275,7 @@ function managedSkipReason(env = process.env) {
218
275
  announce: true,
219
276
  };
220
277
  }
221
- const serverUrl = skyCodeServerUrl(env);
278
+ const serverUrl = configuredServerUrl(env);
222
279
  if (!isHttpsUrl(serverUrl)) {
223
280
  // The single most likely reason a developer sees BYOK when they expected
224
281
  // managed: `buildManagedInferenceRelayCredential` requires HTTPS, and
@@ -241,7 +298,7 @@ function managedSkipReason(env = process.env) {
241
298
  * or not this run ends up brokering. Both spellings are accepted, and the
242
299
  * space-separated form consumes its value token.
243
300
  *
244
- * Everything else is spliced out IN PLACE: `sky-code-passthrough.spec.ts` asserts
301
+ * Everything else is spliced out IN PLACE: `first-party-harness-passthrough.spec.ts` asserts
245
302
  * exact array equality, so order and adjacency are the contract, and a flag
246
303
  * separated from its value is a different command.
247
304
  */
@@ -336,7 +393,7 @@ function managedInferencePosture(env = process.env) {
336
393
  return {
337
394
  status: 'warn',
338
395
  detail: `${exports.MANAGED_SESSION_ENV}=1 but no ${exports.BROKER_SOCKET_ENV} is present — this process cannot reach a broker`,
339
- remedy: 'Do not set the managed marker by hand; let `skrr code` or the daemon set it.',
396
+ remedy: `Do not set the managed marker by hand; let \`${auth_core_1.FIRST_PARTY_HARNESS.command}\` or the daemon set it.`,
340
397
  };
341
398
  }
342
399
  return {
@@ -352,7 +409,7 @@ function managedInferencePosture(env = process.env) {
352
409
  // than as a guess about what to print.
353
410
  return {
354
411
  status: 'ok',
355
- detail: `would broker a managed session against ${serverOrigin(skyCodeServerUrl(env)) ?? 'the configured skrr server'}`,
412
+ detail: `would broker a managed session against ${serverOrigin(configuredServerUrl(env)) ?? 'the configured skrr server'}`,
356
413
  };
357
414
  }
358
415
  return {
@@ -1,38 +1,65 @@
1
1
  /**
2
- * WL-2.2 — locate and forward to the local `sky-code` engine.
2
+ * WL-2.2 — locate and forward to the local first-party harness engine.
3
3
  *
4
4
  * The same `gh → git` shape `exec-runtime-binary.ts` uses, for the same reason: the
5
- * Sky CLI is a REST client, the engine is a separately-built, separately-
5
+ * skrr CLI is a REST client, the engine is a separately-built, separately-
6
6
  * released binary with its own lifetime and failure model. Unifying them at
7
7
  * the command surface (`skrr code`) gives users one thing to type without
8
8
  * coupling the two release cycles.
9
9
  *
10
10
  * The naming constraint from the plan (§3) is load-bearing and easy to get
11
11
  * wrong: skrr already publishes `oversky` (daemon) and `skrr` (control
12
- * plane). This must NOT become a third top-level executable. `sky-code` is an
13
- * internal binary name; `skrr code` is the only public entry point.
12
+ * plane). This must NOT become a third top-level executable. The engine's file
13
+ * name (`firstPartyHarnessBinaryName()`) is internal; `skrr code` is the only
14
+ * public entry point.
15
+ *
16
+ * ── No product name in this file ──────────────────────────────────────────
17
+ *
18
+ * Every product-named value — the binary's file name, the engine home, the env
19
+ * var names, the display name — is read from the identity module in
20
+ * `@skrr-ai/auth-core` (`docs/architecture/skrr-code-identifier-rename-2026-09-13.md`).
21
+ * The engine's file name has more than one spelling while a rename is in
22
+ * flight, so resolution tries every spelling, canonical first, in each location.
23
+ */
24
+ /**
25
+ * The error `execEngine` throws when no engine resolves. A value the commands
26
+ * compare against, so it is exported rather than retyped at each catch site.
14
27
  */
15
- /** Env override, mirroring the daemon's `OVERSKY_SKY_CODE_PATH`. */
16
- export declare const ENGINE_PATH_ENV = "OVERSKY_SKY_CODE_PATH";
28
+ export declare const ENGINE_NOT_INSTALLED = "engine-not-installed";
17
29
  /**
18
- * The engine's user-state root. skrr Code's child of skrr's `~/.skrr/`.
30
+ * The engine's user-state root: the engine home under skrr's `~/.skrr/`.
19
31
  *
20
32
  * Honours `OVERSKY_CONFIG_DIR`, the same root override the daemon reads
21
33
  * (`daemon/src/bun-entry.ts`). Without it the CLI would keep looking under
22
34
  * `$HOME` for a user who relocated their skrr root, and would resolve a
23
35
  * different engine than the daemon — the exact divergence the managed-first
24
36
  * ordering below exists to prevent.
37
+ *
38
+ * The directory NAME follows the engine's own namespace, not the provider slug
39
+ * (`firstPartyHarnessHomeDirname`, contract §5): the engine reads its config and
40
+ * the managed `AGENTS.md` from here, so a home named after anything else would be
41
+ * a directory the engine never reads.
25
42
  */
26
43
  export declare function engineHome(env?: NodeJS.ProcessEnv): string;
27
- /** The user-level instruction root owned by skrr Code. */
28
- export declare function skyCodeInstructionHome(env?: NodeJS.ProcessEnv): string;
29
44
  /**
30
- * The managed install location — where the daemon, the Desktop app, and
31
- * `scripts/sky-code/build.mjs --install` all put the engine.
45
+ * The user-level instruction root the engine owns.
46
+ *
47
+ * Read under the neutral variable first and its older name second
48
+ * (`readFirstPartyHarnessEnv`). The older name is also the one the ENGINE reads,
49
+ * which is why {@link engineOwnedEnv} hands the resolved value to the engine under
50
+ * that name — otherwise the doctor would honour the neutral variable and the
51
+ * engine would not.
52
+ */
53
+ export declare function engineInstructionHome(env?: NodeJS.ProcessEnv): string;
54
+ /**
55
+ * The managed install location for one spelling of the binary (canonical by
56
+ * default) — where the daemon, the Desktop app, and
57
+ * `scripts/first-party-harness/build.mjs --install` all put the engine.
32
58
  */
33
- export declare function managedEnginePath(exeName: string, env?: NodeJS.ProcessEnv): string;
59
+ export declare function managedEnginePath(env?: NodeJS.ProcessEnv, provider?: string): string;
34
60
  /**
35
- * The same managed location under the PREVIOUS config root.
61
+ * The same managed location under the PREVIOUS config root, for every spelling of
62
+ * the binary and every engine home name, canonical first.
36
63
  *
37
64
  * The root moved `~/.oversky` → `~/.skrr` in the skrr rename, and an engine
38
65
  * installed before that is still on disk under the old one. `daemon/src/
@@ -40,14 +67,28 @@ export declare function managedEnginePath(exeName: string, env?: NodeJS.ProcessE
40
67
  * the same machine the daemon found the engine and `skrr code` reported that no
41
68
  * engine was installed — the same product, the same 106 MB binary, two answers.
42
69
  *
43
- * Returns null when an explicit `OVERSKY_CONFIG_DIR` is set, matching the
44
- * daemon: that override names one root deliberately, and reaching past it to a
45
- * hard-coded home would defeat the pinning {@link engineHome} relies on.
70
+ * The engine-home move (`migrateFirstPartyHarnessHome`) only ever works under the
71
+ * CURRENT root, so nothing renames a binary here — which is why this list carries
72
+ * every spelling rather than only the canonical one.
73
+ *
74
+ * Empty when an explicit `OVERSKY_CONFIG_DIR` is set, matching the daemon: that
75
+ * override names one root deliberately, and reaching past it to a hard-coded home
76
+ * would defeat the pinning {@link engineHome} relies on.
46
77
  */
47
- export declare function legacyManagedEnginePath(exeName: string, env?: NodeJS.ProcessEnv): string | null;
78
+ export declare function legacyManagedEnginePaths(env?: NodeJS.ProcessEnv): string[];
79
+ /** The `bin` directories {@link legacyManagedEnginePaths} looks in. */
80
+ export declare function legacyManagedEngineBinDirs(env?: NodeJS.ProcessEnv): string[];
48
81
  export interface EngineResolution {
49
82
  path: string | null;
50
83
  source: 'env' | 'path' | 'managed' | 'legacy-managed' | 'fallback' | 'unresolved';
84
+ /**
85
+ * The variable an explicit override was read from — set whenever one was set,
86
+ * including an override that was refused. The doctor names it, because an
87
+ * operator fixing a bad override needs to know WHICH of its names they set.
88
+ */
89
+ envName?: string;
90
+ /** True when {@link envName} is an older name for the override. */
91
+ legacyEnv?: boolean;
51
92
  }
52
93
  /**
53
94
  * Resolve the engine binary, reporting WHERE it came from.
@@ -56,19 +97,23 @@ export interface EngineResolution {
56
97
  * binary am I actually running" is the first question when a managed session
57
98
  * and an interactive session behave differently.
58
99
  *
59
- * `env` is checked first and is absolute-only. A relative `OVERSKY_SKY_CODE_PATH`
100
+ * The env override is checked first and is absolute-only. A relative override
60
101
  * would resolve against the caller's cwd, which for an agent-invoked command is
61
- * attacker-influenced: a repo containing `./sky-code` could hijack the engine.
102
+ * attacker-influenced: a repo containing a file named like the engine could
103
+ * hijack it. It is read under its neutral name first and its older name second.
62
104
  *
63
- * **Order: env → managed → PATH → well-known (WL-6.2).**
105
+ * **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 order —
107
+ * so an engine installed under an older name still resolves, and the canonical
108
+ * one wins wherever both exist.
64
109
  *
65
110
  * The managed location beating `PATH` is the load-bearing part, and it is a
66
111
  * deliberate reversal of the obvious ordering.
67
112
  *
68
113
  * WL-6.2's acceptance criterion is that "Desktop-bundled and standalone
69
114
  * installations resolve the same version deterministically". With `PATH` first
70
- * they do not: a Desktop app that ships a pinned, signed engine into
71
- * `~/.skrr/sky-code/bin` silently loses to whatever `sky-code` happens to sit
115
+ * they do not: a Desktop app that ships a pinned, signed engine into the managed
116
+ * `bin` directory silently loses to whatever engine binary happens to sit
72
117
  * earlier on the user's `PATH` — a months-old dev build, a Homebrew copy of a
73
118
  * different version, a shim from an uninstalled package manager. The user sees
74
119
  * one product and gets two engines depending on their shell, and the daemon
@@ -81,6 +126,9 @@ export interface EngineResolution {
81
126
  *
82
127
  * `skrr code doctor` prints the winning `source`, so a surprising resolution is
83
128
  * one command away from being explained rather than being a mystery.
129
+ *
130
+ * Pure: it reads the filesystem and moves nothing. The engine-home move runs in
131
+ * {@link execEngine}, before it resolves, so the doctor stays safe to run anywhere.
84
132
  */
85
133
  export declare function resolveEngine(env?: NodeJS.ProcessEnv): EngineResolution;
86
134
  /**
@@ -124,20 +172,20 @@ export declare const DEDICATED_RUNTIME_ENGINE_MESSAGE = "On a Dedicated Runtime,
124
172
  * Message shown when no engine is installed.
125
173
  *
126
174
  * Points at the DAEMON's managed installer rather than at a package manager.
127
- * The earlier version of this text offered `brew install
128
- * dush1023/oversky/sky-code` and `curl .../sky-code/install.sh | bash`; neither
129
- * exists — the tap carries only the `oversky` formula and the feed serves no
130
- * install script — so a user following it hit a 404 and a 403 and reasonably
131
- * concluded the engine was not real.
175
+ * The earlier version of this text offered a Homebrew formula for the engine and
176
+ * a `curl .../install.sh | bash` on the update feed; neither exists — the tap
177
+ * carries only the `oversky` formula and the feed serves no install script — so
178
+ * a user following it hit a 404 and a 403 and reasonably concluded the engine
179
+ * was not real.
132
180
  *
133
181
  * The managed path is also the only one that establishes provenance: it
134
182
  * verifies the signed manifest and writes the sidecar the daemon reads before
135
183
  * it will hand the engine a platform credential. A hand-placed binary works, and
136
184
  * since the owner decision of 2026-08-11 it runs at the SAME tier as a managed
137
- * one — the daemon's floor for `sky-code` is Tier 1 regardless of provenance
138
- * (OSK-3894; this said "stays at Tier 2"). The managed path is still the
139
- * recommendation, but the reason is now "you can prove which bytes ran" rather
140
- * than "otherwise you get a weaker credential".
185
+ * one — the daemon's floor for the first-party harness is Tier 1 regardless of
186
+ * provenance (OSK-3894; this said "stays at Tier 2"). The managed path is still
187
+ * the recommendation, but the reason is now "you can prove which bytes ran"
188
+ * rather than "otherwise you get a weaker credential".
141
189
  *
142
190
  * Keep this in step with what actually ships. An install instruction that does
143
191
  * not work is worse than none: it moves the failure from "I could not find how
@@ -253,7 +301,7 @@ export interface EngineSpawnOptions {
253
301
  *
254
302
  * Exported because two callers need ONE answer to "does this machine have a
255
303
  * provider key at all": this module, to decide what the engine inherits, and the
256
- * BYOK fallback line in `sky-code-broker.ts`, which used to promise "continuing
304
+ * BYOK fallback line in `first-party-harness-broker.ts`, which used to promise "continuing
257
305
  * with your own provider credentials" on a machine that had none (invariant I4 —
258
306
  * managed, BYOK and offline must never be confused). Two definitions of that
259
307
  * question is how the promise and the reality drift apart.
@@ -308,10 +356,33 @@ export declare function strippedProviderCredentialNames(env?: NodeJS.ProcessEnv)
308
356
  *
309
357
  * One sharp edge to know about before adding a subcommand: the shared sanitizer
310
358
  * strips anything ending in `_PASSWORD`, which includes the engine's own
311
- * `SKY_CODE_SERVER_PASSWORD` (Basic auth for `sky-code serve` / `web`). No
312
- * `skrr code` subcommand reaches those today — they are run against the engine
313
- * binary directly — so nothing regresses; a future `skrr code serve` would have to
314
- * pass that credential deliberately rather than rely on inheritance.
359
+ * server-password variable (`FIRST_PARTY_HARNESS_ENGINE.env.serverPassword`, Basic
360
+ * auth for the engine's `serve` / `web`). No `skrr code` subcommand reaches those
361
+ * today — they are run against the engine binary directly — so nothing regresses;
362
+ * a future `skrr code serve` would have to pass that credential deliberately,
363
+ * under that name, rather than rely on inheritance.
364
+ *
365
+ * The layering, in full: sanitized parent → the user's own model credential (BYOK
366
+ * only) → {@link engineOwnedEnv} → `extraEnv`.
315
367
  */
316
368
  export declare function engineSpawnEnv(env: NodeJS.ProcessEnv, extraEnv: Record<string, string>, mode: 'managed' | 'byok'): NodeJS.ProcessEnv;
369
+ /**
370
+ * Settings the platform reads under NEUTRAL names, handed to the engine under the
371
+ * engine's OWN names.
372
+ *
373
+ * The engine is a fork with its own variable namespace
374
+ * (`FIRST_PARTY_HARNESS_ENGINE.env`), and it reads none of the platform's neutral
375
+ * names. So an operator who sets the neutral home override would see
376
+ * `skrr code doctor` honour it while the engine it launches ignored it — two
377
+ * answers to "where do my instructions live" from one command.
378
+ *
379
+ * Only when the value came from a name the engine does NOT read: a value set under
380
+ * the engine's own name is inherited already, and rewriting it would only replace
381
+ * the user's spelling of a path with ours. The resolved path is passed rather than
382
+ * the raw value, so the engine and the doctor agree on `~` expansion too.
383
+ *
384
+ * Not a credential and never one: it cannot reintroduce anything the sanitizer
385
+ * strips, and `extraEnv` still layers over it.
386
+ */
387
+ export declare function engineOwnedEnv(env: NodeJS.ProcessEnv): Record<string, string>;
317
388
  export declare function execEngine(args: string[], env?: NodeJS.ProcessEnv, options?: EngineSpawnOptions): Promise<number>;