@skrr-ai/cli 0.1.8 → 0.1.9
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 +27 -0
- package/dist/base-command.js +83 -11
- package/dist/commands/agent/message/send.js +1 -1
- package/dist/commands/agents/chat.d.ts +1 -1
- package/dist/commands/agents/chat.js +1 -1
- package/dist/commands/browser/install.d.ts +1 -1
- package/dist/commands/browser/install.js +10 -2
- package/dist/commands/browser/mcp-config.js +3 -1
- package/dist/commands/browser/skill/show.js +1 -1
- package/dist/commands/browser/status.js +4 -1
- package/dist/commands/browser/uninstall.d.ts +1 -1
- package/dist/commands/browser/uninstall.js +10 -2
- package/dist/commands/browser.d.ts +1 -1
- package/dist/commands/browser.js +3 -3
- package/dist/commands/code/index.js +6 -3
- package/dist/commands/code/install.d.ts +61 -0
- package/dist/commands/code/install.js +247 -0
- package/dist/commands/code/oversky-agent.d.ts +2 -1
- package/dist/commands/code/oversky-agent.js +12 -8
- package/dist/commands/commands.js +1 -1
- package/dist/commands/context.js +1 -1
- package/dist/commands/create-token.js +1 -1
- package/dist/commands/daemon/byok.d.ts +1 -0
- package/dist/commands/daemon/byok.js +14 -1
- package/dist/commands/daemon/index.js +18 -7
- package/dist/commands/daemon/install.d.ts +1 -0
- package/dist/commands/daemon/install.js +22 -3
- package/dist/commands/daemon/logs.d.ts +1 -0
- package/dist/commands/daemon/logs.js +4 -0
- package/dist/commands/daemon/start.d.ts +1 -0
- package/dist/commands/daemon/start.js +15 -2
- package/dist/commands/daemon/status.d.ts +1 -0
- package/dist/commands/daemon/status.js +14 -1
- package/dist/commands/daemon/stop.d.ts +1 -0
- package/dist/commands/daemon/stop.js +14 -1
- package/dist/commands/daemon/uninstall.d.ts +1 -0
- package/dist/commands/daemon/uninstall.js +15 -2
- package/dist/commands/daemon/usage.d.ts +1 -0
- package/dist/commands/daemon/usage.js +5 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/github/allow-tools.d.ts +1 -0
- package/dist/commands/github/app/install.d.ts +1 -0
- package/dist/commands/github/app/status.d.ts +1 -0
- package/dist/commands/github/connect.d.ts +1 -0
- package/dist/commands/github/connections.d.ts +1 -0
- package/dist/commands/github/disconnect.d.ts +1 -0
- package/dist/commands/github/finalize.d.ts +1 -0
- package/dist/commands/github/reconnect.d.ts +1 -0
- package/dist/commands/github/run.d.ts +1 -0
- package/dist/commands/github/tools.d.ts +1 -0
- package/dist/commands/goals/create.js +2 -2
- package/dist/commands/goals/show.js +5 -0
- package/dist/commands/harnesses/list.js +14 -3
- package/dist/commands/harnesses/show.js +14 -0
- package/dist/commands/instructions/activate.js +1 -1
- package/dist/commands/instructions/archive-version.js +1 -1
- package/dist/commands/instructions/delete.js +1 -1
- package/dist/commands/instructions/diff.js +1 -1
- package/dist/commands/instructions/install.js +7 -1
- package/dist/commands/instructions/restore.js +1 -1
- package/dist/commands/instructions/show.js +17 -1
- package/dist/commands/instructions/update.js +1 -1
- package/dist/commands/integrations/connections/connect.d.ts +1 -0
- package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
- package/dist/commands/integrations/connections/finalize.d.ts +1 -0
- package/dist/commands/integrations/connections/list.d.ts +1 -0
- package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
- package/dist/commands/integrations/execute.d.ts +1 -0
- package/dist/commands/integrations/search.d.ts +1 -0
- package/dist/commands/integrations/toolkits.d.ts +1 -0
- package/dist/commands/integrations/tools/allow.d.ts +1 -0
- package/dist/commands/integrations/tools/list.d.ts +1 -0
- package/dist/commands/list-daemons.d.ts +2 -7
- package/dist/commands/list-daemons.js +13 -13
- package/dist/commands/login.js +73 -31
- package/dist/commands/logout.js +52 -1
- package/dist/commands/machines/hosted/start.js +1 -1
- package/dist/commands/pair.js +2 -2
- package/dist/commands/projects/create.js +6 -1
- package/dist/commands/projects/tasks.js +6 -1
- package/dist/commands/revoke-daemon.js +6 -2
- package/dist/commands/set-capabilities.js +6 -2
- package/dist/commands/skills/install.js +1 -1
- package/dist/commands/skills/library.js +2 -2
- package/dist/commands/spaces/create.js +6 -2
- package/dist/commands/tasks/complete.d.ts +1 -1
- package/dist/commands/tasks/complete.js +21 -8
- package/dist/commands/tasks/create.js +4 -1
- package/dist/commands/tasks/current.js +1 -1
- package/dist/commands/tasks/delete.d.ts +1 -0
- package/dist/commands/tasks/delete.js +9 -0
- package/dist/commands/tasks/export.js +5 -1
- package/dist/commands/tasks/follow-up.js +2 -1
- package/dist/commands/tasks/list.js +5 -1
- package/dist/commands/tasks/pr.js +1 -1
- package/dist/commands/tasks/show.js +10 -1
- package/dist/commands/tasks/triage.js +2 -1
- package/dist/commands/tasks/update.js +4 -1
- package/dist/commands/tasks/upsert.js +4 -1
- package/dist/commands/usage.js +1 -1
- package/dist/lib/agentic-stream.js +21 -1
- package/dist/lib/api-fetch.d.ts +1 -1
- package/dist/lib/api-fetch.js +1 -1
- package/dist/lib/auth-core-init.js +23 -3
- package/dist/lib/auth-storage.d.ts +0 -12
- package/dist/lib/auth-storage.js +37 -2
- package/dist/lib/config.d.ts +3 -3
- package/dist/lib/config.js +327 -26
- package/dist/lib/created-line.d.ts +22 -0
- package/dist/lib/created-line.js +25 -0
- package/dist/lib/daemon-binding.d.ts +29 -0
- package/dist/lib/daemon-binding.js +63 -0
- package/dist/lib/daemon-ref.d.ts +31 -0
- package/dist/lib/daemon-ref.js +47 -0
- package/dist/lib/daemonBroker.js +1 -1
- package/dist/lib/delegated-cli.js +3 -3
- package/dist/lib/exec-oversky.d.ts +18 -1
- package/dist/lib/exec-oversky.js +21 -4
- package/dist/lib/html-text.d.ts +15 -0
- package/dist/lib/html-text.js +40 -0
- package/dist/lib/keychain.d.ts +43 -0
- package/dist/lib/keychain.js +145 -4
- package/dist/lib/login.js +3 -3
- package/dist/lib/node-adapter.js +1 -1
- package/dist/lib/oauthLogin.js +17 -6
- package/dist/lib/sky-code-agent.d.ts +1 -1
- package/dist/lib/sky-code-agent.js +8 -8
- package/dist/lib/sky-code-broker.js +18 -2
- package/dist/lib/sky-code-doctor.js +120 -4
- package/dist/lib/sky-code-managed.d.ts +12 -0
- package/dist/lib/sky-code-managed.js +21 -7
- package/dist/lib/sky-code.d.ts +16 -1
- package/dist/lib/sky-code.js +102 -4
- package/dist/lib/task-execution.js +4 -11
- package/dist/lib/tasks.d.ts +1 -0
- package/dist/lib/tasks.js +9 -6
- package/dist/lib/update-check.js +1 -1
- package/dist/lib/usage-discovery.js +1 -1
- package/dist/lib/web-url.js +12 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/credentialResolver.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +13 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/linux.js +16 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/legacyStatePreflight.d.ts +0 -9
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/legacyStatePreflight.js +18 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/loginLocalhost.js +3 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +3 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/runtime.d.ts +7 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.d.ts +96 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/skyCodeChannels.js +115 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/credentialResolver.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/linux.js +16 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/legacyStatePreflight.d.ts +0 -9
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/legacyStatePreflight.js +18 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/loginLocalhost.js +3 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +3 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/runtime.d.ts +7 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.d.ts +96 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/skyCodeChannels.js +107 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +4206 -4191
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +2 -2
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +2 -2
- package/oclif.manifest.json +9924 -3352
- package/package.json +22 -19
package/dist/lib/node-adapter.js
CHANGED
|
@@ -298,7 +298,7 @@ function createNodeAdapter(opts = {}) {
|
|
|
298
298
|
else {
|
|
299
299
|
// Refresh-token rotation rejected (revoked / family burned /
|
|
300
300
|
// passwordChangedAt cutover). As a last resort, ask the local
|
|
301
|
-
//
|
|
301
|
+
// skrr runtime to broker a fresh cli-scope family — covers
|
|
302
302
|
// "user reset their account but daemon is still authed",
|
|
303
303
|
// "stale pre-broker keychain token", and similar drift cases.
|
|
304
304
|
const brokered = await tryDaemonBrokerRecovery();
|
package/dist/lib/oauthLogin.js
CHANGED
|
@@ -45,6 +45,7 @@ const node_child_process_1 = require("node:child_process");
|
|
|
45
45
|
const auth_storage_1 = require("./auth-storage");
|
|
46
46
|
const config_1 = require("./config");
|
|
47
47
|
const device_id_1 = require("./device-id");
|
|
48
|
+
const publicEndpoints_generated_1 = require("./publicEndpoints.generated");
|
|
48
49
|
// ---------------------------------------------------------------------------
|
|
49
50
|
// PKCE helpers
|
|
50
51
|
// ---------------------------------------------------------------------------
|
|
@@ -64,17 +65,27 @@ function generateState() {
|
|
|
64
65
|
// ---------------------------------------------------------------------------
|
|
65
66
|
const CLIENT_ID = 'oversky-cli';
|
|
66
67
|
const DEFAULT_SCOPES = Object.freeze(['cli']);
|
|
68
|
+
// Both directions are DERIVED from config/public-endpoints.json via the
|
|
69
|
+
// generated constant rather than hand-listed. The hand-listed pair predated the
|
|
70
|
+
// domain cutover and knew only `oversky.*`, so the CURRENT prod apex
|
|
71
|
+
// (`skrr.ai`) resolved to itself: a login against it would exchange tokens on
|
|
72
|
+
// the app origin instead of the API one. Mirrors the same derivation in
|
|
73
|
+
// `web-url.ts`, which needs the inverse map for exactly the same reason.
|
|
67
74
|
const OAUTH_API_URL_FROM_WEB = {
|
|
75
|
+
...Object.fromEntries(Object.values(publicEndpoints_generated_1.OVERSKY_ENVIRONMENT_ENDPOINTS).map((e) => [
|
|
76
|
+
e.appUrl.toLowerCase(),
|
|
77
|
+
e.realtimeUrl,
|
|
78
|
+
])),
|
|
79
|
+
// Prod's retained previous origin, and the `www.` spelling of it.
|
|
68
80
|
'https://oversky.ai': 'https://api.oversky.ai',
|
|
69
81
|
'https://www.oversky.ai': 'https://api.oversky.ai',
|
|
70
|
-
// Dev split onto its own apex (oversky.dev) with an ALB-direct api. subdomain.
|
|
71
|
-
// Mirrors config/public-endpoints.json so `skrr login` against dev exchanges
|
|
72
|
-
// tokens on the same origin family prod uses.
|
|
73
|
-
'https://oversky.dev': 'https://api.oversky.dev',
|
|
74
82
|
};
|
|
75
83
|
const OAUTH_WEB_URL_FROM_API = {
|
|
84
|
+
...Object.fromEntries(Object.values(publicEndpoints_generated_1.OVERSKY_ENVIRONMENT_ENDPOINTS).map((e) => [
|
|
85
|
+
e.realtimeUrl.toLowerCase(),
|
|
86
|
+
e.appUrl,
|
|
87
|
+
])),
|
|
76
88
|
'https://api.oversky.ai': 'https://oversky.ai',
|
|
77
|
-
'https://api.oversky.dev': 'https://oversky.dev',
|
|
78
89
|
};
|
|
79
90
|
function resolveOAuthEndpoints(serverUrl) {
|
|
80
91
|
const normalized = serverUrl.replace(/\/+$/, '');
|
|
@@ -351,7 +362,7 @@ async function runOAuthLogin(opts) {
|
|
|
351
362
|
// refresh.ts:169 and :296. So the credential was rejected by its
|
|
352
363
|
// own issuer check the instant it was written:
|
|
353
364
|
//
|
|
354
|
-
// [
|
|
365
|
+
// [skrr] Ignoring stored credentials issued by
|
|
355
366
|
// https://api.oversky.ai; skrr is configured for
|
|
356
367
|
// https://oversky.ai.
|
|
357
368
|
//
|
|
@@ -113,7 +113,7 @@ export interface SkyCodeAgentOptions {
|
|
|
113
113
|
* May resolution CREATE the default agent when nothing else answers?
|
|
114
114
|
*
|
|
115
115
|
* Defaults to true, because a session that cannot name an agent cannot run.
|
|
116
|
-
* `skrr code
|
|
116
|
+
* `skrr code skrr-agent` (with no `--create`) passes false: a command whose
|
|
117
117
|
* job is to report what would happen must not make it happen.
|
|
118
118
|
*/
|
|
119
119
|
createDefault?: boolean;
|
|
@@ -96,7 +96,7 @@ exports.SkyCodeAgentError = SkyCodeAgentError;
|
|
|
96
96
|
*/
|
|
97
97
|
async function resolveSkyCodeAgent(explicit, deps = {}, options = {}) {
|
|
98
98
|
const configured = deps.configuredAgentId ?? (() => (0, config_1.loadConfig)().skyCodeAgentId);
|
|
99
|
-
const explicitLabel = options.explicitLabel ?? sky_code_managed_1.
|
|
99
|
+
const explicitLabel = options.explicitLabel ?? sky_code_managed_1.SKRR_AGENT_FLAG;
|
|
100
100
|
let cached = null;
|
|
101
101
|
const roster = async () => {
|
|
102
102
|
if (cached)
|
|
@@ -123,7 +123,7 @@ async function resolveSkyCodeAgent(explicit, deps = {}, options = {}) {
|
|
|
123
123
|
}
|
|
124
124
|
if (byName.length > 1) {
|
|
125
125
|
throw new SkyCodeAgentError('agent-ambiguous', `${describeSource(source, ref, explicitLabel)} matches ${byName.length} agents. ` +
|
|
126
|
-
`Pass ${sky_code_managed_1.
|
|
126
|
+
`Pass ${sky_code_managed_1.SKRR_AGENT_FLAG} with an id instead: ${candidates(byName)}`);
|
|
127
127
|
}
|
|
128
128
|
// Not in the bounded roster. It may still be a real id belonging to a user with
|
|
129
129
|
// more agents than the roster shows, so ask directly before refusing.
|
|
@@ -186,7 +186,7 @@ async function resolveSkyCodeAgent(explicit, deps = {}, options = {}) {
|
|
|
186
186
|
// exactly this and belongs to nobody else.
|
|
187
187
|
// `createDefault: false` makes this a READ: the endpoint is get-or-create
|
|
188
188
|
// and has no read-only mode, so a caller that is only ASKING
|
|
189
|
-
// (`skrr code
|
|
189
|
+
// (`skrr code skrr-agent`) recognises an existing default from the roster
|
|
190
190
|
// it has already fetched instead. `defaultForHarness` rides the same
|
|
191
191
|
// summary projection `author` does, so this costs no extra request.
|
|
192
192
|
//
|
|
@@ -220,8 +220,8 @@ async function resolveSkyCodeAgent(explicit, deps = {}, options = {}) {
|
|
|
220
220
|
if (isAbortError(err))
|
|
221
221
|
throw err;
|
|
222
222
|
throw new SkyCodeAgentError('agent-unset', `could not establish your default skrr Code agent — ${message(err)}. ` +
|
|
223
|
-
`Pass ${sky_code_managed_1.
|
|
224
|
-
'`skrr code
|
|
223
|
+
`Pass ${sky_code_managed_1.SKRR_AGENT_FLAG} <id-or-name>, or set one with ` +
|
|
224
|
+
'`skrr code skrr-agent --set <id>`' +
|
|
225
225
|
(rows.length ? `. Yours: ${candidates(rows)}` : ''));
|
|
226
226
|
}
|
|
227
227
|
// Asked, not told: the caller opted out of creation, so "no default" is a fact
|
|
@@ -229,14 +229,14 @@ async function resolveSkyCodeAgent(explicit, deps = {}, options = {}) {
|
|
|
229
229
|
if (options.createDefault === false) {
|
|
230
230
|
throw new SkyCodeAgentError('agent-unset', 'nothing is configured and you have no skrr Code default agent yet. ' +
|
|
231
231
|
'One is created automatically the first time you run a managed session — ' +
|
|
232
|
-
'or make it now with `skrr code
|
|
232
|
+
'or make it now with `skrr code skrr-agent --create`' +
|
|
233
233
|
(rows.length ? `. Yours: ${candidates(rows)}` : ''));
|
|
234
234
|
}
|
|
235
235
|
// The endpoint answered without an agent. Nothing here can repair that, but
|
|
236
236
|
// the user still has every ordinary way to name one.
|
|
237
237
|
throw new SkyCodeAgentError('agent-unset', rows.length
|
|
238
238
|
? `skrr Code has no default agent for you and will not pick one of your ${rows.length}. ` +
|
|
239
|
-
`Pass ${sky_code_managed_1.
|
|
239
|
+
`Pass ${sky_code_managed_1.SKRR_AGENT_FLAG} <id-or-name>, or set "${sky_code_managed_1.AGENT_CONFIG_KEY}" in ` +
|
|
240
240
|
`${configPathHint()}. Yours: ${candidates(rows)}`
|
|
241
241
|
: 'you have no agents and no default could be created, yet a managed skrr Code session ' +
|
|
242
242
|
'runs as one. Create an agent in the skrr app first');
|
|
@@ -278,7 +278,7 @@ async function setConfiguredAgentId(ref, deps = {}, options = {}) {
|
|
|
278
278
|
// Name the thing the user actually typed. Without this a bad `--set` value
|
|
279
279
|
// is refused with "--oversky-agent \"typo\" is not an agent you can run",
|
|
280
280
|
// pointing at a flag that was never on the command line.
|
|
281
|
-
explicitLabel: 'skrr code
|
|
281
|
+
explicitLabel: 'skrr code skrr-agent --set',
|
|
282
282
|
...options,
|
|
283
283
|
});
|
|
284
284
|
writeConfigKey(resolved.id);
|
|
@@ -239,7 +239,7 @@ async function acquireManagedSession(input = {}, deps = {}) {
|
|
|
239
239
|
if (agent.createdNow) {
|
|
240
240
|
input.log?.(`Created "${agent.name ?? agent.id}" as your default skrr Code agent — ` +
|
|
241
241
|
'this session, and future ones, are attributed to it. ' +
|
|
242
|
-
'Change it with `skrr code
|
|
242
|
+
'Change it with `skrr code skrr-agent --set <id-or-name>`.');
|
|
243
243
|
}
|
|
244
244
|
const minted = await mintSessionToken({ sessionId, processStartId, agentId: agent.id, actorId: newId() }, api, acquisition.signal);
|
|
245
245
|
sessionToken = minted.token;
|
|
@@ -888,11 +888,27 @@ function describe(err) {
|
|
|
888
888
|
*
|
|
889
889
|
* The predicate is `hasProviderCredential`, the same one that decides what the
|
|
890
890
|
* engine actually inherits (`sky-code.ts`), so the sentence and the spawn cannot
|
|
891
|
-
* disagree.
|
|
891
|
+
* disagree. `strippedProviderCredentialNames` covers the third case that
|
|
892
|
+
* predicate cannot see: the machine HAS a provider credential and this run
|
|
893
|
+
* removes it, which reads as absence and is not.
|
|
892
894
|
*/
|
|
893
895
|
function fallbackTail(env) {
|
|
894
896
|
if ((0, sky_code_1.hasProviderCredential)(env))
|
|
895
897
|
return 'Continuing with your own provider credentials.';
|
|
898
|
+
// Absence and removal are different problems, and the old sentence said the
|
|
899
|
+
// first when the second was true: on a machine whose only credential is an AWS
|
|
900
|
+
// profile the engine runs fine on its own and fails through `skrr code`,
|
|
901
|
+
// because `AWS_*` is stripped on the way in. Being told "no provider
|
|
902
|
+
// credential is set here" sends that user to buy a key they do not need.
|
|
903
|
+
const stripped = (0, sky_code_1.strippedProviderCredentialNames)(env);
|
|
904
|
+
if (stripped.length > 0) {
|
|
905
|
+
return (`${stripped.join(', ')} is set here, but this run does not pass it to the engine — ` +
|
|
906
|
+
'it is stripped so a model-driven process opening other people\u2019s repositories cannot ' +
|
|
907
|
+
'reuse a cloud credential. So the engine starts without one and its first request will ' +
|
|
908
|
+
'fail. Export a provider key the engine may inherit (any `*_API_KEY`, e.g. ' +
|
|
909
|
+
'OPENROUTER_API_KEY), resolve the reason above, or run the engine directly if you ' +
|
|
910
|
+
'intend to spend that credential (`skrr code doctor` shows where it is).');
|
|
911
|
+
}
|
|
896
912
|
return ('No provider credential is set here either, so the engine will start without one and ' +
|
|
897
913
|
'its first request will fail — set OPENROUTER_API_KEY, or resolve the reason above ' +
|
|
898
914
|
'(`skrr code doctor`).');
|
|
@@ -32,6 +32,7 @@ exports.formatReport = formatReport;
|
|
|
32
32
|
const node_fs_1 = require("node:fs");
|
|
33
33
|
const node_path_1 = __importDefault(require("node:path"));
|
|
34
34
|
const sky_code_1 = require("./sky-code");
|
|
35
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
35
36
|
const harness_tiers_1 = require("./harness-tiers");
|
|
36
37
|
const config_1 = require("./config");
|
|
37
38
|
const sky_code_managed_1 = require("./sky-code-managed");
|
|
@@ -39,10 +40,124 @@ const sky_code_managed_1 = require("./sky-code-managed");
|
|
|
39
40
|
function projectStateDir(cwd) {
|
|
40
41
|
return node_path_1.default.join(node_path_1.default.resolve(cwd), '.sky-code');
|
|
41
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Which release channel this machine follows, and where its manifest lives.
|
|
45
|
+
*
|
|
46
|
+
* `notInstalledMessage()` has always ended by promising that this command names
|
|
47
|
+
* "which channel this machine follows and whether that channel has a published
|
|
48
|
+
* 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
|
|
50
|
+
* installer. So the user with no engine, who is exactly the audience for that
|
|
51
|
+
* sentence, was sent to a command that could not answer (dogfood OSK-274).
|
|
52
|
+
*
|
|
53
|
+
* It reports the channel and the exact URL, and does NOT fetch it. The doctor is
|
|
54
|
+
* documented as safe to run in any context and reads only env, config and one
|
|
55
|
+
* `existsSync`; adding a network call to satisfy a sentence would trade a broken
|
|
56
|
+
* promise for a diagnostic that hangs on a captive portal. Printing the URL puts
|
|
57
|
+
* the answer one copy-paste away and keeps the property — and the promise is
|
|
58
|
+
* reworded to match what is delivered rather than the other way round.
|
|
59
|
+
*
|
|
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.
|
|
63
|
+
*/
|
|
64
|
+
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,
|
|
69
|
+
channel,
|
|
70
|
+
});
|
|
71
|
+
if (invalid) {
|
|
72
|
+
return {
|
|
73
|
+
name: 'release-channel',
|
|
74
|
+
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.`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
name: 'release-channel',
|
|
81
|
+
status: 'ok',
|
|
82
|
+
detail: `${channel} — ${url}`,
|
|
83
|
+
remedy: `Fetch that URL to see whether the channel has a published release, and which version.`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* What the pre-rename engine directory still holds, for a machine that has moved on.
|
|
88
|
+
*
|
|
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).
|
|
94
|
+
*
|
|
95
|
+
* Flat, never recursive, and failures are swallowed: this is a footnote on a
|
|
96
|
+
* diagnostic, and a doctor that throws while counting bytes it was only going to
|
|
97
|
+
* mention has made things worse than the clutter it was reporting.
|
|
98
|
+
*/
|
|
99
|
+
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;
|
|
115
|
+
}
|
|
116
|
+
return files > 0 ? { dir, files, bytes } : null;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Bytes as the size a human would say out loud. */
|
|
123
|
+
function humanBytes(bytes) {
|
|
124
|
+
const mb = bytes / 1024 / 1024;
|
|
125
|
+
return mb >= 1024 ? `${(mb / 1024).toFixed(1)} GB` : `${Math.round(mb)} MB`;
|
|
126
|
+
}
|
|
42
127
|
function engineCheck(env) {
|
|
43
128
|
const { path: bin, source } = (0, sky_code_1.resolveEngine)(env);
|
|
129
|
+
if (bin && source === 'legacy-managed') {
|
|
130
|
+
// `ok`, because it runs and this is the resolution the daemon has always
|
|
131
|
+
// made. The remedy is here because the resolution is SURPRISING: the path
|
|
132
|
+
// says `.oversky` on a CLI that says `skrr` everywhere else, and the next
|
|
133
|
+
// daemon-driven install will write to `~/.skrr` and leave two copies of a
|
|
134
|
+
// hundred-megabyte binary on disk with no hint which one is live.
|
|
135
|
+
return {
|
|
136
|
+
name: 'engine',
|
|
137
|
+
status: 'ok',
|
|
138
|
+
detail: `${bin} (resolved via ${source} — the pre-rename location)`,
|
|
139
|
+
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)}; ` +
|
|
141
|
+
'the copy above can be deleted once it does.',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
44
144
|
if (bin) {
|
|
45
|
-
|
|
145
|
+
// The engine resolved from the current root — and the pre-rename directory
|
|
146
|
+
// may still be sitting there. Said here rather than in its own check because
|
|
147
|
+
// it is a footnote on a healthy answer, not a finding of its own.
|
|
148
|
+
const stranded = strandedLegacyEngine(env);
|
|
149
|
+
return {
|
|
150
|
+
name: 'engine',
|
|
151
|
+
status: 'ok',
|
|
152
|
+
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
|
+
: {}),
|
|
160
|
+
};
|
|
46
161
|
}
|
|
47
162
|
const override = env[sky_code_1.ENGINE_PATH_ENV];
|
|
48
163
|
if (override && !node_path_1.default.isAbsolute(override)) {
|
|
@@ -461,7 +576,7 @@ function sessionAuthorityCheck(env) {
|
|
|
461
576
|
remedy: 'Intended for local use, and nothing to fix. Worth knowing because it is NOT the same ' +
|
|
462
577
|
'trust plane as a daemon-dispatched run — and neither plane is an OS-level sandbox ' +
|
|
463
578
|
'(no seccomp, container, or namespace). An untrusted autonomous workload needs a hosted ' +
|
|
464
|
-
'or container profile; see
|
|
579
|
+
'or container profile; see sky-code/docs/sky-code/threat-model.md.',
|
|
465
580
|
};
|
|
466
581
|
}
|
|
467
582
|
}
|
|
@@ -473,7 +588,7 @@ function sessionAuthorityCheck(env) {
|
|
|
473
588
|
* a `/api/agents` read, and this module's whole contract is that it answers from
|
|
474
589
|
* env, one config read and one `existsSync` — that is what lets `skrr code doctor`
|
|
475
590
|
* run before the auth plane is configured, and on a machine with no network.
|
|
476
|
-
* `skrr code
|
|
591
|
+
* `skrr code skrr-agent` is the command that resolves for real.
|
|
477
592
|
*
|
|
478
593
|
* Never a `warn`. An unset value is the normal, supported state now that
|
|
479
594
|
* resolution ends in a default agent rather than a refusal; flagging it would
|
|
@@ -507,12 +622,13 @@ function agentAttributionCheck() {
|
|
|
507
622
|
name: 'agent',
|
|
508
623
|
status: 'ok',
|
|
509
624
|
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`,
|
|
510
|
-
remedy: 'Run `skrr code
|
|
625
|
+
remedy: 'Run `skrr code skrr-agent` to see which, or `skrr code skrr-agent --set <id>` to pin one.',
|
|
511
626
|
};
|
|
512
627
|
}
|
|
513
628
|
function runDoctor(cwd = process.cwd(), env = process.env) {
|
|
514
629
|
const checks = [
|
|
515
630
|
engineCheck(env),
|
|
631
|
+
releaseChannelCheck(env),
|
|
516
632
|
stateDirCheck(cwd, env),
|
|
517
633
|
compatCheck(cwd, env),
|
|
518
634
|
opencodeCheck(cwd),
|
|
@@ -46,7 +46,19 @@ export declare const MANAGED_ENV_FLAG = "OVERSKY_SKY_CODE_MANAGED";
|
|
|
46
46
|
* `skrr code --agent reviewer` is the engine's flag and is pinned as such by
|
|
47
47
|
* `sky-code-passthrough.spec.ts`. A bare `--agent` here would steal it.
|
|
48
48
|
*/
|
|
49
|
+
export declare const SKRR_AGENT_FLAG = "--skrr-agent";
|
|
50
|
+
/**
|
|
51
|
+
* The pre-rename spelling, still accepted.
|
|
52
|
+
*
|
|
53
|
+
* It is in muscle memory and in scripts, and `skrr code` forwards argv verbatim
|
|
54
|
+
* — so a flag this CLI stops recognising is not an error, it is silently handed
|
|
55
|
+
* to the engine, which rejects it with a message about a flag the user did not
|
|
56
|
+
* think they were passing. Accepting both is the only version of this rename
|
|
57
|
+
* that fails safely.
|
|
58
|
+
*/
|
|
49
59
|
export declare const OVERSKY_AGENT_FLAG = "--oversky-agent";
|
|
60
|
+
/** Every spelling the argv scanner honours, primary first. */
|
|
61
|
+
export declare const AGENT_FLAG_SPELLINGS: readonly ["--skrr-agent", "--oversky-agent"];
|
|
50
62
|
/** The config key `skrr code` reads when the flag is absent. */
|
|
51
63
|
export declare const AGENT_CONFIG_KEY = "skyCodeAgentId";
|
|
52
64
|
/**
|
|
@@ -32,7 +32,7 @@
|
|
|
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.OVERSKY_AGENT_FLAG = exports.MANAGED_ENV_FLAG = void 0;
|
|
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;
|
|
36
36
|
exports.resolveTrustPlane = resolveTrustPlane;
|
|
37
37
|
exports.skyCodeServerUrl = skyCodeServerUrl;
|
|
38
38
|
exports.managedSkipReason = managedSkipReason;
|
|
@@ -59,7 +59,19 @@ exports.MANAGED_ENV_FLAG = 'OVERSKY_SKY_CODE_MANAGED';
|
|
|
59
59
|
* `skrr code --agent reviewer` is the engine's flag and is pinned as such by
|
|
60
60
|
* `sky-code-passthrough.spec.ts`. A bare `--agent` here would steal it.
|
|
61
61
|
*/
|
|
62
|
+
exports.SKRR_AGENT_FLAG = '--skrr-agent';
|
|
63
|
+
/**
|
|
64
|
+
* The pre-rename spelling, still accepted.
|
|
65
|
+
*
|
|
66
|
+
* It is in muscle memory and in scripts, and `skrr code` forwards argv verbatim
|
|
67
|
+
* — so a flag this CLI stops recognising is not an error, it is silently handed
|
|
68
|
+
* to the engine, which rejects it with a message about a flag the user did not
|
|
69
|
+
* think they were passing. Accepting both is the only version of this rename
|
|
70
|
+
* that fails safely.
|
|
71
|
+
*/
|
|
62
72
|
exports.OVERSKY_AGENT_FLAG = '--oversky-agent';
|
|
73
|
+
/** Every spelling the argv scanner honours, primary first. */
|
|
74
|
+
exports.AGENT_FLAG_SPELLINGS = [exports.SKRR_AGENT_FLAG, exports.OVERSKY_AGENT_FLAG];
|
|
63
75
|
/** The config key `skrr code` reads when the flag is absent. */
|
|
64
76
|
exports.AGENT_CONFIG_KEY = 'skyCodeAgentId';
|
|
65
77
|
/**
|
|
@@ -238,19 +250,21 @@ function takeOverskyAgentFlag(passthrough) {
|
|
|
238
250
|
let agentRef;
|
|
239
251
|
for (let i = 0; i < passthrough.length; i += 1) {
|
|
240
252
|
const token = passthrough[i];
|
|
241
|
-
if (
|
|
242
|
-
// Last one wins, matching how every argv parser treats a repeated flag
|
|
253
|
+
if (exports.AGENT_FLAG_SPELLINGS.includes(token)) {
|
|
254
|
+
// Last one wins, matching how every argv parser treats a repeated flag —
|
|
255
|
+
// and across spellings too, so `--oversky-agent a --skrr-agent b` is `b`.
|
|
243
256
|
const value = passthrough[i + 1];
|
|
244
|
-
// A trailing
|
|
245
|
-
//
|
|
257
|
+
// A trailing flag with no value must not swallow the next token (there is
|
|
258
|
+
// none) nor leave the flag in the argv.
|
|
246
259
|
if (value !== undefined && !value.startsWith('-')) {
|
|
247
260
|
agentRef = value;
|
|
248
261
|
i += 1;
|
|
249
262
|
}
|
|
250
263
|
continue;
|
|
251
264
|
}
|
|
252
|
-
|
|
253
|
-
|
|
265
|
+
const inline = exports.AGENT_FLAG_SPELLINGS.find((f) => token.startsWith(`${f}=`));
|
|
266
|
+
if (inline) {
|
|
267
|
+
agentRef = token.slice(inline.length + 1);
|
|
254
268
|
continue;
|
|
255
269
|
}
|
|
256
270
|
engineArgv.push(token);
|
package/dist/lib/sky-code.d.ts
CHANGED
|
@@ -31,9 +31,23 @@ export declare function skyCodeInstructionHome(env?: NodeJS.ProcessEnv): string;
|
|
|
31
31
|
* `scripts/sky-code/build.mjs --install` all put the engine.
|
|
32
32
|
*/
|
|
33
33
|
export declare function managedEnginePath(exeName: string, env?: NodeJS.ProcessEnv): string;
|
|
34
|
+
/**
|
|
35
|
+
* The same managed location under the PREVIOUS config root.
|
|
36
|
+
*
|
|
37
|
+
* The root moved `~/.oversky` → `~/.skrr` in the skrr rename, and an engine
|
|
38
|
+
* installed before that is still on disk under the old one. `daemon/src/
|
|
39
|
+
* binary-resolver.ts` was given this fallback and this module was not, so on
|
|
40
|
+
* the same machine the daemon found the engine and `skrr code` reported that no
|
|
41
|
+
* engine was installed — the same product, the same 106 MB binary, two answers.
|
|
42
|
+
*
|
|
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.
|
|
46
|
+
*/
|
|
47
|
+
export declare function legacyManagedEnginePath(exeName: string, env?: NodeJS.ProcessEnv): string | null;
|
|
34
48
|
export interface EngineResolution {
|
|
35
49
|
path: string | null;
|
|
36
|
-
source: 'env' | 'path' | 'managed' | 'fallback' | 'unresolved';
|
|
50
|
+
source: 'env' | 'path' | 'managed' | 'legacy-managed' | 'fallback' | 'unresolved';
|
|
37
51
|
}
|
|
38
52
|
/**
|
|
39
53
|
* Resolve the engine binary, reporting WHERE it came from.
|
|
@@ -185,6 +199,7 @@ export interface EngineSpawnOptions {
|
|
|
185
199
|
export declare function inheritedProviderCredentials(env: NodeJS.ProcessEnv): Record<string, string>;
|
|
186
200
|
/** Whether an unmanaged run has anything to authenticate with. */
|
|
187
201
|
export declare function hasProviderCredential(env?: NodeJS.ProcessEnv): boolean;
|
|
202
|
+
export declare function strippedProviderCredentialNames(env?: NodeJS.ProcessEnv): string[];
|
|
188
203
|
/**
|
|
189
204
|
* The environment the engine actually receives.
|
|
190
205
|
*
|
package/dist/lib/sky-code.js
CHANGED
|
@@ -21,11 +21,13 @@ exports.ENGINE_PATH_ENV = void 0;
|
|
|
21
21
|
exports.engineHome = engineHome;
|
|
22
22
|
exports.skyCodeInstructionHome = skyCodeInstructionHome;
|
|
23
23
|
exports.managedEnginePath = managedEnginePath;
|
|
24
|
+
exports.legacyManagedEnginePath = legacyManagedEnginePath;
|
|
24
25
|
exports.resolveEngine = resolveEngine;
|
|
25
26
|
exports.buildEngineArgs = buildEngineArgs;
|
|
26
27
|
exports.notInstalledMessage = notInstalledMessage;
|
|
27
28
|
exports.inheritedProviderCredentials = inheritedProviderCredentials;
|
|
28
29
|
exports.hasProviderCredential = hasProviderCredential;
|
|
30
|
+
exports.strippedProviderCredentialNames = strippedProviderCredentialNames;
|
|
29
31
|
exports.engineSpawnEnv = engineSpawnEnv;
|
|
30
32
|
exports.execEngine = execEngine;
|
|
31
33
|
const node_child_process_1 = require("node:child_process");
|
|
@@ -70,6 +72,24 @@ function skyCodeInstructionHome(env = process.env) {
|
|
|
70
72
|
function managedEnginePath(exeName, env = process.env) {
|
|
71
73
|
return node_path_1.default.join(engineHome(env), 'bin', exeName);
|
|
72
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* The same managed location under the PREVIOUS config root.
|
|
77
|
+
*
|
|
78
|
+
* The root moved `~/.oversky` → `~/.skrr` in the skrr rename, and an engine
|
|
79
|
+
* installed before that is still on disk under the old one. `daemon/src/
|
|
80
|
+
* binary-resolver.ts` was given this fallback and this module was not, so on
|
|
81
|
+
* the same machine the daemon found the engine and `skrr code` reported that no
|
|
82
|
+
* engine was installed — the same product, the same 106 MB binary, two answers.
|
|
83
|
+
*
|
|
84
|
+
* Returns null when an explicit `OVERSKY_CONFIG_DIR` is set, matching the
|
|
85
|
+
* daemon: that override names one root deliberately, and reaching past it to a
|
|
86
|
+
* hard-coded home would defeat the pinning {@link engineHome} relies on.
|
|
87
|
+
*/
|
|
88
|
+
function legacyManagedEnginePath(exeName, env = process.env) {
|
|
89
|
+
if (env.OVERSKY_CONFIG_DIR?.trim())
|
|
90
|
+
return null;
|
|
91
|
+
return node_path_1.default.join((0, node_os_1.homedir)(), '.oversky', 'sky-code', 'bin', exeName);
|
|
92
|
+
}
|
|
73
93
|
/**
|
|
74
94
|
* Unmanaged well-known locations, checked after PATH.
|
|
75
95
|
*
|
|
@@ -139,6 +159,15 @@ function resolveEngine(env = process.env) {
|
|
|
139
159
|
const managed = managedEnginePath(exeName, env);
|
|
140
160
|
if (isExecutable(managed))
|
|
141
161
|
return { path: managed, source: 'managed' };
|
|
162
|
+
// The pre-rename managed location, SECOND. After the current one, so a fresh
|
|
163
|
+
// install always wins; before PATH, for the same WL-6.2 reason the current one
|
|
164
|
+
// beats PATH — a binary skrr installed outranks whatever happens to sit on the
|
|
165
|
+
// user's PATH, and which config root it was installed under does not change
|
|
166
|
+
// that. Reported as its own `source` so `skrr code doctor` can say where it
|
|
167
|
+
// came from rather than quietly resolving something surprising.
|
|
168
|
+
const legacy = legacyManagedEnginePath(exeName, env);
|
|
169
|
+
if (legacy && isExecutable(legacy))
|
|
170
|
+
return { path: legacy, source: 'legacy-managed' };
|
|
142
171
|
const PATH = env.PATH ?? '';
|
|
143
172
|
const sep = process.platform === 'win32' ? ';' : ':';
|
|
144
173
|
const exeNames = process.platform === 'win32' ? ['sky-code.exe', 'sky-code.cmd'] : ['sky-code'];
|
|
@@ -198,15 +227,17 @@ function notInstalledMessage() {
|
|
|
198
227
|
'The skrr Code engine (`sky-code`) is not installed on this machine.',
|
|
199
228
|
'',
|
|
200
229
|
'Install it through the daemon, which verifies the signed release:',
|
|
201
|
-
' •
|
|
202
|
-
' •
|
|
230
|
+
' • `skrr code install` — from here, no browser needed',
|
|
231
|
+
' • Or in the web app: the runtime menu beside the chat input → skrr Code → Install',
|
|
232
|
+
' • Either way a daemon must be running here: `skrr daemon status`',
|
|
203
233
|
'',
|
|
204
234
|
`Or point the CLI at an existing build: export ${exports.ENGINE_PATH_ENV}=/absolute/path/to/sky-code`,
|
|
205
235
|
' (an unsigned build runs, and since 2026-08-11 at the same trust tier as a',
|
|
206
236
|
' signed one — see `skrr code doctor` under trust-tier)',
|
|
207
237
|
'',
|
|
208
|
-
'Run `skrr code doctor` for a full diagnosis
|
|
209
|
-
'machine follows and
|
|
238
|
+
'Run `skrr code doctor` for a full diagnosis. Its `release-channel` line',
|
|
239
|
+
'names the channel this machine follows and the exact manifest URL to check',
|
|
240
|
+
'for a published release.',
|
|
210
241
|
].join('\n');
|
|
211
242
|
}
|
|
212
243
|
/**
|
|
@@ -220,6 +251,37 @@ function notInstalledMessage() {
|
|
|
220
251
|
*/
|
|
221
252
|
const BYOK_CREDENTIAL_SUFFIXES = ['_API_KEY', '_AUTH_TOKEN'];
|
|
222
253
|
const BYOK_CREDENTIAL_NAMES = new Set(['HUGGINGFACE_HUB_TOKEN']);
|
|
254
|
+
/**
|
|
255
|
+
* `AWS_*` names that are not credentials, and that Bedrock cannot run without.
|
|
256
|
+
*
|
|
257
|
+
* The `AWS_` prefix rule below exists for STS/IAM material — `AWS_ACCESS_KEY_ID`,
|
|
258
|
+
* `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`, `AWS_BEARER_TOKEN_BEDROCK` — and
|
|
259
|
+
* every one of those stays stripped. These three carry no secret: two are a
|
|
260
|
+
* region and one is the NAME of a profile whose credentials live in the AWS
|
|
261
|
+
* shared config, a file the engine can read anyway. Stripping them therefore
|
|
262
|
+
* protected nothing and cost an entire provider.
|
|
263
|
+
*
|
|
264
|
+
* Dogfooded as OSK-262, where `sky-code run "say hi"` answered on a Bedrock
|
|
265
|
+
* model and the identical run through `skrr code` died in the engine's generic
|
|
266
|
+
* error handler — because `AWS_PROFILE` did not survive the sanitizer.
|
|
267
|
+
* `env -u AWS_PROFILE` on the bare engine reproduced the failure exactly.
|
|
268
|
+
*
|
|
269
|
+
* An enumerated carve-out rather than a narrower prefix, so every future
|
|
270
|
+
* addition is a reviewable line that has to argue "this one is not a secret".
|
|
271
|
+
* The failure mode of the alternative is an exemption list that grows until the
|
|
272
|
+
* prefix rule means nothing.
|
|
273
|
+
*
|
|
274
|
+
* BYOK ONLY, and that is why it lives here rather than in `sanitizeSpawnEnv`.
|
|
275
|
+
* {@link engineSpawnEnv} re-admits nothing on a managed run, so a session
|
|
276
|
+
* spending a budgeted relay credential still cannot reach Bedrock directly and
|
|
277
|
+
* bill around its own budget. Putting the exemption in the shared sanitizer
|
|
278
|
+
* would hand it to the daemon's managed ACP path too, and lose that.
|
|
279
|
+
*/
|
|
280
|
+
const BYOK_AWS_NON_SECRETS = new Set([
|
|
281
|
+
'AWS_PROFILE',
|
|
282
|
+
'AWS_REGION',
|
|
283
|
+
'AWS_DEFAULT_REGION',
|
|
284
|
+
]);
|
|
223
285
|
/**
|
|
224
286
|
* …and these are never inherited, whatever they look like.
|
|
225
287
|
*
|
|
@@ -256,6 +318,11 @@ function inheritedProviderCredentials(env) {
|
|
|
256
318
|
continue;
|
|
257
319
|
if (ENGINE_NEVER_INHERITS.has(key))
|
|
258
320
|
continue;
|
|
321
|
+
// Before the prefix rule, which would otherwise take these with the family.
|
|
322
|
+
if (BYOK_AWS_NON_SECRETS.has(key)) {
|
|
323
|
+
out[key] = value;
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
259
326
|
if (ENGINE_NEVER_INHERITS_PREFIXES.some((prefix) => key.startsWith(prefix)))
|
|
260
327
|
continue;
|
|
261
328
|
if (BYOK_CREDENTIAL_NAMES.has(key) || BYOK_CREDENTIAL_SUFFIXES.some((s) => key.endsWith(s))) {
|
|
@@ -268,6 +335,37 @@ function inheritedProviderCredentials(env) {
|
|
|
268
335
|
function hasProviderCredential(env = process.env) {
|
|
269
336
|
return Object.keys(inheritedProviderCredentials(env)).length > 0;
|
|
270
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Provider-capable credentials this environment HAS and the engine will not get.
|
|
340
|
+
*
|
|
341
|
+
* `hasProviderCredential` answers "will the engine have a key", which is the
|
|
342
|
+
* right question for what to spawn and the wrong one for what to SAY. On a
|
|
343
|
+
* machine whose only credential is an AWS profile the two answers differ: the
|
|
344
|
+
* engine defaults to a Bedrock model and runs fine when launched directly, and
|
|
345
|
+
* `skrr code` — which strips `AWS_*` — reported "no provider credential is set
|
|
346
|
+
* here", sent the user to buy an OpenRouter key, and then died in the engine's
|
|
347
|
+
* generic error handler. The user had a working credential; this run removed it.
|
|
348
|
+
*
|
|
349
|
+
* "You have none" and "you have one and this run does not pass it on" are
|
|
350
|
+
* different problems with different fixes, so they must not share a sentence.
|
|
351
|
+
*
|
|
352
|
+
* Only the deny-listed names a PROVIDER could actually authenticate with are
|
|
353
|
+
* reported. `GH_TOKEN` and `NPM_TOKEN` are stripped too and are not model
|
|
354
|
+
* credentials, so naming them here would turn a precise sentence into noise.
|
|
355
|
+
*/
|
|
356
|
+
const STRIPPED_PROVIDER_CREDENTIALS = [
|
|
357
|
+
// Bedrock's SECRET material only. `AWS_PROFILE` and the region variables are
|
|
358
|
+
// exempt ({@link BYOK_AWS_NON_SECRETS}) and now reach the engine, so naming
|
|
359
|
+
// them here would make this sentence contradict the spawn — which is the exact
|
|
360
|
+
// defect this reporter was added to end.
|
|
361
|
+
'AWS_ACCESS_KEY_ID',
|
|
362
|
+
'AWS_BEARER_TOKEN_BEDROCK',
|
|
363
|
+
// Anthropic OAuth, deny-listed by name in ENGINE_NEVER_INHERITS.
|
|
364
|
+
'CLAUDE_CODE_OAUTH_TOKEN',
|
|
365
|
+
];
|
|
366
|
+
function strippedProviderCredentialNames(env = process.env) {
|
|
367
|
+
return STRIPPED_PROVIDER_CREDENTIALS.filter((name) => (env[name] ?? '').trim() !== '');
|
|
368
|
+
}
|
|
271
369
|
/**
|
|
272
370
|
* The environment the engine actually receives.
|
|
273
371
|
*
|
|
@@ -27,6 +27,7 @@ exports.sleep = sleep;
|
|
|
27
27
|
exports.compactSnapshotSignature = compactSnapshotSignature;
|
|
28
28
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
29
29
|
const tasks_1 = require("./tasks");
|
|
30
|
+
const html_text_1 = require("./html-text");
|
|
30
31
|
/**
|
|
31
32
|
* Statuses at which an execution is OVER — nothing further will move the task
|
|
32
33
|
* without new input.
|
|
@@ -304,17 +305,9 @@ function compactSnapshotSignature(snapshot) {
|
|
|
304
305
|
.sort()
|
|
305
306
|
.join('|');
|
|
306
307
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
.replace(/<\/p>/gi, '\n')
|
|
311
|
-
.replace(/<[^>]+>/g, ' ')
|
|
312
|
-
.replace(/ /g, ' ')
|
|
313
|
-
.replace(/'/g, "'")
|
|
314
|
-
.replace(/"/g, '"')
|
|
315
|
-
.replace(/&/g, '&')
|
|
316
|
-
.replace(/[ \t]+/g, ' ');
|
|
317
|
-
}
|
|
308
|
+
// Was a private copy here; it is the same job `tasks show` needs, and two
|
|
309
|
+
// slightly different HTML strippers is how the two surfaces drift.
|
|
310
|
+
const stripHtml = html_text_1.htmlToDisplayText;
|
|
318
311
|
function stringValue(value) {
|
|
319
312
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
320
313
|
}
|
package/dist/lib/tasks.d.ts
CHANGED