@skrr-ai/cli 0.1.8 → 0.1.10
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 +78 -33
- 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/commands/whoami.js +4 -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 +43 -3
- package/dist/lib/config.js +391 -31
- 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 +110 -7
- 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 +7969 -1397
- package/package.json +22 -19
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two halves of the daemon-reference contract: how a daemon id is DISPLAYED
|
|
3
|
+
* and how a displayed one is READ BACK.
|
|
4
|
+
*
|
|
5
|
+
* `list-daemons` prints a decorated short form — `d_6a323ae4...` — and the two
|
|
6
|
+
* commands that consume a daemon reference (`revoke-daemon`,
|
|
7
|
+
* `set-capabilities`) matched the raw argument against `id.startsWith(prefix)`.
|
|
8
|
+
* So the value the product printed in a column literally headed DAEMON REF was
|
|
9
|
+
* rejected by every command that takes one, and the failure looked like "no such
|
|
10
|
+
* daemon" rather than "that is not the format I want". The sibling
|
|
11
|
+
* `machines show` accepts what `machines list` prints, which is the behaviour
|
|
12
|
+
* people reasonably expect here too.
|
|
13
|
+
*
|
|
14
|
+
* Keeping the decoration and accepting it back is the right trade: the `d_`
|
|
15
|
+
* prefix and the ellipsis are what tell a reader the value is truncated, and
|
|
16
|
+
* dropping them would make an 8-character fragment look like a full id.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Format a full daemon ObjectId as a short readable label:
|
|
20
|
+
* `d_xY3p...` — prefix + first 8 hex chars + an ellipsis.
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatDaemonRef(id: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Read back anything `formatDaemonRef` may have produced, plus what a person
|
|
25
|
+
* plausibly pastes: with or without the `d_`, with or without a trailing `...`
|
|
26
|
+
* or a real ellipsis character, and with surrounding whitespace.
|
|
27
|
+
*
|
|
28
|
+
* A value that was never decorated passes through untouched, so a full id and a
|
|
29
|
+
* hand-typed prefix keep working exactly as before.
|
|
30
|
+
*/
|
|
31
|
+
export declare function normalizeDaemonRef(input: string): string;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The two halves of the daemon-reference contract: how a daemon id is DISPLAYED
|
|
4
|
+
* and how a displayed one is READ BACK.
|
|
5
|
+
*
|
|
6
|
+
* `list-daemons` prints a decorated short form — `d_6a323ae4...` — and the two
|
|
7
|
+
* commands that consume a daemon reference (`revoke-daemon`,
|
|
8
|
+
* `set-capabilities`) matched the raw argument against `id.startsWith(prefix)`.
|
|
9
|
+
* So the value the product printed in a column literally headed DAEMON REF was
|
|
10
|
+
* rejected by every command that takes one, and the failure looked like "no such
|
|
11
|
+
* daemon" rather than "that is not the format I want". The sibling
|
|
12
|
+
* `machines show` accepts what `machines list` prints, which is the behaviour
|
|
13
|
+
* people reasonably expect here too.
|
|
14
|
+
*
|
|
15
|
+
* Keeping the decoration and accepting it back is the right trade: the `d_`
|
|
16
|
+
* prefix and the ellipsis are what tell a reader the value is truncated, and
|
|
17
|
+
* dropping them would make an 8-character fragment look like a full id.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.formatDaemonRef = formatDaemonRef;
|
|
21
|
+
exports.normalizeDaemonRef = normalizeDaemonRef;
|
|
22
|
+
/** Prefix the short form carries so a truncated id is visibly truncated. */
|
|
23
|
+
const DISPLAY_PREFIX = 'd_';
|
|
24
|
+
/**
|
|
25
|
+
* Format a full daemon ObjectId as a short readable label:
|
|
26
|
+
* `d_xY3p...` — prefix + first 8 hex chars + an ellipsis.
|
|
27
|
+
*/
|
|
28
|
+
function formatDaemonRef(id) {
|
|
29
|
+
if (!id || id.length < 8)
|
|
30
|
+
return id || '—';
|
|
31
|
+
return `${DISPLAY_PREFIX}${id.slice(0, 8)}...`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Read back anything `formatDaemonRef` may have produced, plus what a person
|
|
35
|
+
* plausibly pastes: with or without the `d_`, with or without a trailing `...`
|
|
36
|
+
* or a real ellipsis character, and with surrounding whitespace.
|
|
37
|
+
*
|
|
38
|
+
* A value that was never decorated passes through untouched, so a full id and a
|
|
39
|
+
* hand-typed prefix keep working exactly as before.
|
|
40
|
+
*/
|
|
41
|
+
function normalizeDaemonRef(input) {
|
|
42
|
+
let out = input.trim();
|
|
43
|
+
if (out.toLowerCase().startsWith(DISPLAY_PREFIX))
|
|
44
|
+
out = out.slice(DISPLAY_PREFIX.length);
|
|
45
|
+
out = out.replace(/(?:\.{3}|…)$/, '');
|
|
46
|
+
return out.trim();
|
|
47
|
+
}
|
package/dist/lib/daemonBroker.js
CHANGED
|
@@ -286,7 +286,7 @@ async function attemptDaemonBrokerLogin(opts) {
|
|
|
286
286
|
return {
|
|
287
287
|
ok: false,
|
|
288
288
|
reason: 'base_url_mismatch',
|
|
289
|
-
detail: `No local
|
|
289
|
+
detail: `No local skrr runtime is logged in to ${opts.baseURL}; available daemon is logged in to ${mismatchedBootstrap.serverUrl}.`,
|
|
290
290
|
daemonServerUrl: mismatchedBootstrap.serverUrl,
|
|
291
291
|
};
|
|
292
292
|
}
|
|
@@ -22,7 +22,7 @@ function isDelegatedCliSession(env = process.env) {
|
|
|
22
22
|
function trustedLoopbackUrl(raw) {
|
|
23
23
|
const url = new URL(raw);
|
|
24
24
|
if (url.protocol !== 'http:' || !['127.0.0.1', 'localhost', '::1'].includes(url.hostname)) {
|
|
25
|
-
throw new Error('Delegated
|
|
25
|
+
throw new Error('Delegated skrr CLI broker must be a loopback HTTP URL.');
|
|
26
26
|
}
|
|
27
27
|
return url.toString();
|
|
28
28
|
}
|
|
@@ -82,11 +82,11 @@ async function fetchDelegatedCliCredential(env = process.env, options = {}) {
|
|
|
82
82
|
if (body?.code === 'DELEGATED_CLI_CAPABILITY_REJECTED')
|
|
83
83
|
return null;
|
|
84
84
|
}
|
|
85
|
-
throw new Error(`Delegated
|
|
85
|
+
throw new Error(`Delegated skrr CLI credential broker returned HTTP ${res.status}.`);
|
|
86
86
|
}
|
|
87
87
|
const body = (await res.json());
|
|
88
88
|
if (typeof body.accessToken !== 'string' || body.accessToken.length === 0) {
|
|
89
|
-
throw new Error('Delegated
|
|
89
|
+
throw new Error('Delegated skrr CLI credential broker returned no access token.');
|
|
90
90
|
}
|
|
91
91
|
const credential = {
|
|
92
92
|
token: body.accessToken,
|
|
@@ -3,8 +3,25 @@ export declare const RUNTIME_BINARY_NAMES: readonly ["skrrd", "oversky"];
|
|
|
3
3
|
/** Resolve the absolute path of `oversky` if it exists, else return null. */
|
|
4
4
|
export declare function findOverskyBinary(): string | null;
|
|
5
5
|
/**
|
|
6
|
-
* Pretty hint shown when
|
|
6
|
+
* Pretty hint shown when the runtime isn't installed. Kept short — points
|
|
7
7
|
* users at the canonical install paths rather than enumerating them.
|
|
8
|
+
*
|
|
9
|
+
* THE ADDRESSES BELOW STILL SAY `oversky`, ON PURPOSE.
|
|
10
|
+
* ---------------------------------------------------
|
|
11
|
+
* The rename moved this text to `skrr` and pointed it at
|
|
12
|
+
* `dush1023/skrr/skrrd`, `raw.githubusercontent.com/dush1023/skrr/...` and
|
|
13
|
+
* `github.com/dush1023/skrr` — none of which exist. The tap
|
|
14
|
+
* `dush1023/homebrew-skrr` 404s; only `dush1023/homebrew-oversky` is
|
|
15
|
+
* published, and the repository is still `dush1023/OverSky`.
|
|
16
|
+
*
|
|
17
|
+
* An install instruction is only worth what it installs. Renaming these
|
|
18
|
+
* before the tap and repository move produces a message that reads correct
|
|
19
|
+
* and fails when followed — the same defect as the "install it with
|
|
20
|
+
* `sky code install`" hint, which named a command that never existed.
|
|
21
|
+
*
|
|
22
|
+
* They move when the Homebrew tap is published (that work is tracked
|
|
23
|
+
* separately) and when the repository is renamed — not before, and not as
|
|
24
|
+
* part of a copy sweep.
|
|
8
25
|
*/
|
|
9
26
|
export declare function notInstalledMessage(): string;
|
|
10
27
|
/**
|
package/dist/lib/exec-oversky.js
CHANGED
|
@@ -76,17 +76,34 @@ function isExecutable(p) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
* Pretty hint shown when
|
|
79
|
+
* Pretty hint shown when the runtime isn't installed. Kept short — points
|
|
80
80
|
* users at the canonical install paths rather than enumerating them.
|
|
81
|
+
*
|
|
82
|
+
* THE ADDRESSES BELOW STILL SAY `oversky`, ON PURPOSE.
|
|
83
|
+
* ---------------------------------------------------
|
|
84
|
+
* The rename moved this text to `skrr` and pointed it at
|
|
85
|
+
* `dush1023/skrr/skrrd`, `raw.githubusercontent.com/dush1023/skrr/...` and
|
|
86
|
+
* `github.com/dush1023/skrr` — none of which exist. The tap
|
|
87
|
+
* `dush1023/homebrew-skrr` 404s; only `dush1023/homebrew-oversky` is
|
|
88
|
+
* published, and the repository is still `dush1023/OverSky`.
|
|
89
|
+
*
|
|
90
|
+
* An install instruction is only worth what it installs. Renaming these
|
|
91
|
+
* before the tap and repository move produces a message that reads correct
|
|
92
|
+
* and fails when followed — the same defect as the "install it with
|
|
93
|
+
* `sky code install`" hint, which named a command that never existed.
|
|
94
|
+
*
|
|
95
|
+
* They move when the Homebrew tap is published (that work is tracked
|
|
96
|
+
* separately) and when the repository is renamed — not before, and not as
|
|
97
|
+
* part of a copy sweep.
|
|
81
98
|
*/
|
|
82
99
|
function notInstalledMessage() {
|
|
83
100
|
return [
|
|
84
101
|
'The skrr local runtime is not installed on this machine.',
|
|
85
102
|
'',
|
|
86
103
|
'Install:',
|
|
87
|
-
' macOS: brew install dush1023/
|
|
88
|
-
' Linux: curl -fsSL https://raw.githubusercontent.com/dush1023/
|
|
89
|
-
' Other: https://github.com/dush1023/
|
|
104
|
+
' macOS: brew install dush1023/oversky/oversky',
|
|
105
|
+
' Linux: curl -fsSL https://raw.githubusercontent.com/dush1023/OverSky/main/scripts/install-daemon.sh | bash',
|
|
106
|
+
' Other: https://github.com/dush1023/OverSky#installation',
|
|
90
107
|
'',
|
|
91
108
|
'Once installed, re-run your command.',
|
|
92
109
|
].join('\n');
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render server-stored rich text as something a terminal can read.
|
|
3
|
+
*
|
|
4
|
+
* Task, goal and project descriptions are persisted as HTML — `--description
|
|
5
|
+
* -format markdown` is converted on the way in — so a CLI that prints the field
|
|
6
|
+
* verbatim shows the user `<p>…</p>` and `<code>…</code>` around their own
|
|
7
|
+
* words. They wrote markdown and got tags back.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately NOT a general HTML renderer. It converts the block boundaries
|
|
10
|
+
* that carry meaning in a paragraph of prose, drops the rest of the tags, and
|
|
11
|
+
* decodes the entity set the server actually emits. Anything that does not look
|
|
12
|
+
* like markup is returned untouched, so a plain-text description keeps its own
|
|
13
|
+
* whitespace instead of being reflowed by a converter it never needed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function htmlToDisplayText(value: string): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Render server-stored rich text as something a terminal can read.
|
|
4
|
+
*
|
|
5
|
+
* Task, goal and project descriptions are persisted as HTML — `--description
|
|
6
|
+
* -format markdown` is converted on the way in — so a CLI that prints the field
|
|
7
|
+
* verbatim shows the user `<p>…</p>` and `<code>…</code>` around their own
|
|
8
|
+
* words. They wrote markdown and got tags back.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately NOT a general HTML renderer. It converts the block boundaries
|
|
11
|
+
* that carry meaning in a paragraph of prose, drops the rest of the tags, and
|
|
12
|
+
* decodes the entity set the server actually emits. Anything that does not look
|
|
13
|
+
* like markup is returned untouched, so a plain-text description keeps its own
|
|
14
|
+
* whitespace instead of being reflowed by a converter it never needed.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.htmlToDisplayText = htmlToDisplayText;
|
|
18
|
+
/** Cheap, deliberate: a tag-shaped substring is the only trigger. */
|
|
19
|
+
function looksLikeHtml(value) {
|
|
20
|
+
return /<\/?[a-z][^>]*>/i.test(value);
|
|
21
|
+
}
|
|
22
|
+
function htmlToDisplayText(value) {
|
|
23
|
+
if (!looksLikeHtml(value))
|
|
24
|
+
return value;
|
|
25
|
+
return (value
|
|
26
|
+
.replace(/<br\s*\/?>/gi, '\n')
|
|
27
|
+
.replace(/<\/(p|div|li|h[1-6])>/gi, '\n')
|
|
28
|
+
.replace(/<li[^>]*>/gi, ' - ')
|
|
29
|
+
.replace(/<[^>]+>/g, '')
|
|
30
|
+
.replace(/ /g, ' ')
|
|
31
|
+
.replace(/'/g, "'")
|
|
32
|
+
.replace(/"/g, '"')
|
|
33
|
+
.replace(/</g, '<')
|
|
34
|
+
.replace(/>/g, '>')
|
|
35
|
+
// `&` LAST, or `&lt;` would decode twice into a bare `<`.
|
|
36
|
+
.replace(/&/g, '&')
|
|
37
|
+
.replace(/[ \t]+/g, ' ')
|
|
38
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
39
|
+
.trim());
|
|
40
|
+
}
|
package/dist/lib/keychain.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
+
/** Pre-Phase-K namespace; reserved for a future migration helper. */
|
|
2
|
+
export declare const DEFAULT_PROFILE = "default";
|
|
1
3
|
export declare function setActiveProfile(profile: string): void;
|
|
4
|
+
/**
|
|
5
|
+
* Whether the profile has been chosen for this process.
|
|
6
|
+
*
|
|
7
|
+
* Borrowed from `daemon/src/config.ts`, which warns when a writer runs before
|
|
8
|
+
* `setActiveProfile()` and says why: such a caller "is a bug — they're writing
|
|
9
|
+
* to the legacy single-tenant root instead of the active profile's dir". The
|
|
10
|
+
* failure is silent and permanent, so it needs to be noisy once.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isProfileResolved(): boolean;
|
|
2
13
|
export declare function getActiveProfile(): string;
|
|
3
14
|
/** @internal exposed for tests / diagnostics. */
|
|
4
15
|
export declare function __currentServiceForTest(): string;
|
|
@@ -38,8 +49,40 @@ export declare function writeServerOrigin(origin: string): boolean;
|
|
|
38
49
|
export declare function deleteServerOrigin(): void;
|
|
39
50
|
export declare function deleteToken(): void;
|
|
40
51
|
export declare function deleteRefreshToken(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Remove the credentials this product wrote under its previous brand.
|
|
54
|
+
*
|
|
55
|
+
* `logout` used to delete only the CURRENT service and report an unqualified
|
|
56
|
+
* "Signed out." On a machine carried through the rename that left the
|
|
57
|
+
* pre-rename CLI credential, the pre-rename daemon credentials, and BOTH KEKs
|
|
58
|
+
* in place — so the sealed envelope and the key that unwraps it were still
|
|
59
|
+
* sitting there after the product said you were signed out. `logout --help`
|
|
60
|
+
* offers `--all-devices` for "a stolen-laptop incident", which is the one
|
|
61
|
+
* situation where that is exactly wrong.
|
|
62
|
+
*
|
|
63
|
+
* Returns the services it actually removed something from, so the caller can
|
|
64
|
+
* say what happened instead of destroying credentials silently.
|
|
65
|
+
*
|
|
66
|
+
* NOTE this also signs out the retired `oversky` binary, if one is still
|
|
67
|
+
* installed. That is the intent — same account, same machine — and the cutover
|
|
68
|
+
* runbook already lists these items for removal.
|
|
69
|
+
*/
|
|
70
|
+
export declare function deleteLegacyBrandEntries(): string[];
|
|
41
71
|
/**
|
|
42
72
|
* Remove every CLI keychain slot for the active profile. Used by `skrr logout`.
|
|
43
73
|
* Safe to call on a clean system — missing items are not an error.
|
|
44
74
|
*/
|
|
45
75
|
export declare function deleteAll(): void;
|
|
76
|
+
/**
|
|
77
|
+
* Pull `--profile` out of raw argv.
|
|
78
|
+
*
|
|
79
|
+
* Deliberately minimal: it recognises `--profile x` and `--profile=x` and
|
|
80
|
+
* nothing else. This runs before any validation, so it must not throw, must not
|
|
81
|
+
* consume anything it does not own, and must not care about flag ordering —
|
|
82
|
+
* anything it gets wrong is corrected microseconds later when oclif parses the
|
|
83
|
+
* same argv properly and rejects a malformed invocation.
|
|
84
|
+
*
|
|
85
|
+
* Returns null rather than the default, so the caller can fall through to
|
|
86
|
+
* `OVERSKY_PROFILE` without a flag having to out-rank an env var it never saw.
|
|
87
|
+
*/
|
|
88
|
+
export declare function resolveProfileFromArgv(argv: readonly string[] | undefined): string | null;
|
package/dist/lib/keychain.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_PROFILE = void 0;
|
|
3
4
|
exports.setActiveProfile = setActiveProfile;
|
|
5
|
+
exports.isProfileResolved = isProfileResolved;
|
|
4
6
|
exports.getActiveProfile = getActiveProfile;
|
|
5
7
|
exports.__currentServiceForTest = __currentServiceForTest;
|
|
6
8
|
exports.isAvailable = isAvailable;
|
|
@@ -14,7 +16,9 @@ exports.writeServerOrigin = writeServerOrigin;
|
|
|
14
16
|
exports.deleteServerOrigin = deleteServerOrigin;
|
|
15
17
|
exports.deleteToken = deleteToken;
|
|
16
18
|
exports.deleteRefreshToken = deleteRefreshToken;
|
|
19
|
+
exports.deleteLegacyBrandEntries = deleteLegacyBrandEntries;
|
|
17
20
|
exports.deleteAll = deleteAll;
|
|
21
|
+
exports.resolveProfileFromArgv = resolveProfileFromArgv;
|
|
18
22
|
/**
|
|
19
23
|
* keychain.ts — macOS Keychain-backed token storage for the Sky CLI.
|
|
20
24
|
*
|
|
@@ -44,10 +48,11 @@ exports.deleteAll = deleteAll;
|
|
|
44
48
|
*/
|
|
45
49
|
const node_child_process_1 = require("node:child_process");
|
|
46
50
|
const cred_envelope_1 = require("./cred-envelope");
|
|
51
|
+
const auth_core_1 = require("@skrr-ai/auth-core");
|
|
47
52
|
/** Service-name prefix. Always followed by `.<profile>`. */
|
|
48
53
|
const SERVICE_BASE = 'ai.skrr.cli';
|
|
49
54
|
/** Pre-Phase-K namespace; reserved for a future migration helper. */
|
|
50
|
-
|
|
55
|
+
exports.DEFAULT_PROFILE = 'default';
|
|
51
56
|
const ACCOUNT_TOKEN = 'cli-token';
|
|
52
57
|
const ACCOUNT_EXPIRES = 'cli-token-expires';
|
|
53
58
|
const ACCOUNT_REFRESH = 'cli-refresh';
|
|
@@ -58,14 +63,35 @@ const SECURITY_ITEM_NOT_FOUND = 44;
|
|
|
58
63
|
/** Cached availability — probed once at first call. */
|
|
59
64
|
let _availability = null;
|
|
60
65
|
/**
|
|
61
|
-
* Active profile for this process.
|
|
62
|
-
*
|
|
66
|
+
* Active profile for this process.
|
|
67
|
+
*
|
|
68
|
+
* Wired from `--profile` / `OVERSKY_PROFILE` in `BaseCommand.init()`, before
|
|
69
|
+
* anything reads a credential. The comment here used to say "Phase K will wire
|
|
70
|
+
* `setActiveProfile('work')` onto a `--profile` flag; today everything resolves
|
|
71
|
+
* to `default`" — and that stayed true long enough to cost something: with one
|
|
72
|
+
* slot, signing into a second deployment EVICTED the first, so a round trip
|
|
73
|
+
* meant two interactive logins and an agent could not make one at all
|
|
74
|
+
* (OSK-290).
|
|
63
75
|
*/
|
|
64
|
-
let _activeProfile = DEFAULT_PROFILE;
|
|
76
|
+
let _activeProfile = exports.DEFAULT_PROFILE;
|
|
77
|
+
/** True once a caller has chosen, so a writer can tell "default" from "unset". */
|
|
78
|
+
let _profileResolved = false;
|
|
65
79
|
function setActiveProfile(profile) {
|
|
80
|
+
_profileResolved = true;
|
|
66
81
|
if (profile && profile.length > 0)
|
|
67
82
|
_activeProfile = profile;
|
|
68
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether the profile has been chosen for this process.
|
|
86
|
+
*
|
|
87
|
+
* Borrowed from `daemon/src/config.ts`, which warns when a writer runs before
|
|
88
|
+
* `setActiveProfile()` and says why: such a caller "is a bug — they're writing
|
|
89
|
+
* to the legacy single-tenant root instead of the active profile's dir". The
|
|
90
|
+
* failure is silent and permanent, so it needs to be noisy once.
|
|
91
|
+
*/
|
|
92
|
+
function isProfileResolved() {
|
|
93
|
+
return _profileResolved;
|
|
94
|
+
}
|
|
69
95
|
function getActiveProfile() {
|
|
70
96
|
return _activeProfile;
|
|
71
97
|
}
|
|
@@ -307,6 +333,88 @@ function deleteRefreshToken() {
|
|
|
307
333
|
deleteSlot(ACCOUNT_REFRESH);
|
|
308
334
|
deleteSlot(ACCOUNT_REFRESH_EXPIRES);
|
|
309
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Every Keychain service this product wrote under its PREVIOUS brand.
|
|
338
|
+
*
|
|
339
|
+
* Discovered rather than enumerated, because the daemon's services carry a
|
|
340
|
+
* per-profile hash (`ai.oversky.daemon.dev-f00ad7c1`) that cannot be
|
|
341
|
+
* reconstructed from a name. Metadata only — `dump-keychain` without `-d`
|
|
342
|
+
* prints service names and does not prompt for or reveal any secret.
|
|
343
|
+
*
|
|
344
|
+
* Filtered to `LEGACY_NATIVE_ID_PREFIXES` followed by a dot, so a third-party
|
|
345
|
+
* item that merely starts with the same letters is never in scope.
|
|
346
|
+
*/
|
|
347
|
+
function discoverLegacyBrandServices() {
|
|
348
|
+
let dump;
|
|
349
|
+
try {
|
|
350
|
+
dump = (0, node_child_process_1.execFileSync)('security', ['dump-keychain'], {
|
|
351
|
+
encoding: 'utf-8',
|
|
352
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
const found = new Set();
|
|
359
|
+
for (const match of dump.matchAll(/"svce"<blob>="([^"]*)"/g)) {
|
|
360
|
+
const service = match[1];
|
|
361
|
+
if (auth_core_1.LEGACY_NATIVE_ID_PREFIXES.some((prefix) => service.startsWith(`${prefix}.`))) {
|
|
362
|
+
found.add(service);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return [...found].sort();
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Delete every item under one service, without needing its account names.
|
|
369
|
+
*
|
|
370
|
+
* `delete-generic-password -s <svc>` removes ONE matching item, so a service
|
|
371
|
+
* holding a token, its expiry and a refresh pair needs several passes. Bounded,
|
|
372
|
+
* because a delete that never reports "not found" would otherwise spin.
|
|
373
|
+
*/
|
|
374
|
+
function deleteEntireService(service) {
|
|
375
|
+
let removedAny = false;
|
|
376
|
+
for (let i = 0; i < 32; i += 1) {
|
|
377
|
+
try {
|
|
378
|
+
(0, node_child_process_1.execFileSync)('security', ['delete-generic-password', '-s', service], {
|
|
379
|
+
stdio: ['ignore', 'ignore', 'ignore'],
|
|
380
|
+
});
|
|
381
|
+
removedAny = true;
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
const status = err.status;
|
|
385
|
+
if (status === SECURITY_ITEM_NOT_FOUND)
|
|
386
|
+
return removedAny;
|
|
387
|
+
if (process.env.DEBUG) {
|
|
388
|
+
console.error(`[cli/keychain] legacy sweep failed for ${service} (status=${status ?? 'unknown'})`);
|
|
389
|
+
}
|
|
390
|
+
return removedAny;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return removedAny;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Remove the credentials this product wrote under its previous brand.
|
|
397
|
+
*
|
|
398
|
+
* `logout` used to delete only the CURRENT service and report an unqualified
|
|
399
|
+
* "Signed out." On a machine carried through the rename that left the
|
|
400
|
+
* pre-rename CLI credential, the pre-rename daemon credentials, and BOTH KEKs
|
|
401
|
+
* in place — so the sealed envelope and the key that unwraps it were still
|
|
402
|
+
* sitting there after the product said you were signed out. `logout --help`
|
|
403
|
+
* offers `--all-devices` for "a stolen-laptop incident", which is the one
|
|
404
|
+
* situation where that is exactly wrong.
|
|
405
|
+
*
|
|
406
|
+
* Returns the services it actually removed something from, so the caller can
|
|
407
|
+
* say what happened instead of destroying credentials silently.
|
|
408
|
+
*
|
|
409
|
+
* NOTE this also signs out the retired `oversky` binary, if one is still
|
|
410
|
+
* installed. That is the intent — same account, same machine — and the cutover
|
|
411
|
+
* runbook already lists these items for removal.
|
|
412
|
+
*/
|
|
413
|
+
function deleteLegacyBrandEntries() {
|
|
414
|
+
if (!isAvailable())
|
|
415
|
+
return [];
|
|
416
|
+
return discoverLegacyBrandServices().filter((service) => deleteEntireService(service));
|
|
417
|
+
}
|
|
310
418
|
/**
|
|
311
419
|
* Remove every CLI keychain slot for the active profile. Used by `skrr logout`.
|
|
312
420
|
* Safe to call on a clean system — missing items are not an error.
|
|
@@ -316,3 +424,36 @@ function deleteAll() {
|
|
|
316
424
|
deleteRefreshToken();
|
|
317
425
|
deleteServerOrigin();
|
|
318
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Pull `--profile` out of raw argv.
|
|
429
|
+
*
|
|
430
|
+
* Deliberately minimal: it recognises `--profile x` and `--profile=x` and
|
|
431
|
+
* nothing else. This runs before any validation, so it must not throw, must not
|
|
432
|
+
* consume anything it does not own, and must not care about flag ordering —
|
|
433
|
+
* anything it gets wrong is corrected microseconds later when oclif parses the
|
|
434
|
+
* same argv properly and rejects a malformed invocation.
|
|
435
|
+
*
|
|
436
|
+
* Returns null rather than the default, so the caller can fall through to
|
|
437
|
+
* `OVERSKY_PROFILE` without a flag having to out-rank an env var it never saw.
|
|
438
|
+
*/
|
|
439
|
+
function resolveProfileFromArgv(argv) {
|
|
440
|
+
// `undefined` is a real input, not a defensive flourish: a command
|
|
441
|
+
// constructed directly — as several suites do — has no argv yet when `init()`
|
|
442
|
+
// runs. The contract above says this must not throw, and it did.
|
|
443
|
+
if (!Array.isArray(argv))
|
|
444
|
+
return null;
|
|
445
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
446
|
+
const token = argv[i];
|
|
447
|
+
if (token === '--')
|
|
448
|
+
break;
|
|
449
|
+
if (token === '--profile') {
|
|
450
|
+
const value = argv[i + 1];
|
|
451
|
+
return value && !value.startsWith('-') ? value : null;
|
|
452
|
+
}
|
|
453
|
+
if (token.startsWith('--profile=')) {
|
|
454
|
+
const value = token.slice('--profile='.length);
|
|
455
|
+
return value.length > 0 ? value : null;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return null;
|
|
459
|
+
}
|
package/dist/lib/login.js
CHANGED
|
@@ -82,7 +82,7 @@ async function cliLogin(opts = {}) {
|
|
|
82
82
|
});
|
|
83
83
|
if (brokerResult.ok) {
|
|
84
84
|
console.log('');
|
|
85
|
-
console.log(' Authorized via the local
|
|
85
|
+
console.log(' Authorized via the local skrr runtime (no browser needed).');
|
|
86
86
|
return {
|
|
87
87
|
token: brokerResult.accessToken,
|
|
88
88
|
refreshToken: brokerResult.refreshToken,
|
|
@@ -105,7 +105,7 @@ async function cliLogin(opts = {}) {
|
|
|
105
105
|
// broker failures — missing bootstrap, network blip, server 5xx —
|
|
106
106
|
// silently fall through to PKCE / device-code below.
|
|
107
107
|
if (brokerResult.reason === 'ci_token_refused') {
|
|
108
|
-
throw new Error('The local
|
|
108
|
+
throw new Error('The local skrr runtime is bootstrapped from a CI token, which cannot broker an interactive CLI login. ' +
|
|
109
109
|
'Use `skrr create-token --name <name>` to mint a long-lived CI credential directly, ' +
|
|
110
110
|
'or run `skrr login` on a machine where the daemon was authenticated interactively.');
|
|
111
111
|
}
|
|
@@ -116,7 +116,7 @@ async function cliLogin(opts = {}) {
|
|
|
116
116
|
// "I'm logging into a different server than the daemon".
|
|
117
117
|
if (brokerResult.reason === 'base_url_mismatch' && brokerResult.daemonServerUrl) {
|
|
118
118
|
console.log('');
|
|
119
|
-
console.log(` The local
|
|
119
|
+
console.log(` The local skrr runtime is logged in to ${brokerResult.daemonServerUrl}, but skrr is configured for ${serverUrl}.`);
|
|
120
120
|
console.log(` Skipping the daemon-broker handoff. Run \`skrr login --base-url ${brokerResult.daemonServerUrl}\` to use the daemon instead.`);
|
|
121
121
|
}
|
|
122
122
|
}
|
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);
|