@skrr-ai/cli 0.1.12 → 0.1.14
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 +1 -39
- package/dist/base-command.js +36 -10
- package/dist/commands/agents/list.d.ts +10 -0
- package/dist/commands/agents/list.js +16 -1
- package/dist/commands/browser.js +5 -5
- package/dist/commands/commitments/create.d.ts +2 -0
- package/dist/commands/commitments/create.js +30 -13
- package/dist/commands/commitments/update.d.ts +2 -0
- package/dist/commands/commitments/update.js +24 -4
- package/dist/commands/daemon/byok.js +5 -5
- package/dist/commands/daemon/index.js +7 -4
- package/dist/commands/daemon/install.js +8 -5
- package/dist/commands/daemon/login.js +5 -5
- package/dist/commands/daemon/logs.js +5 -5
- package/dist/commands/daemon/restart.js +5 -5
- package/dist/commands/daemon/start.js +5 -5
- package/dist/commands/daemon/status.js +5 -5
- package/dist/commands/daemon/stop.js +5 -5
- package/dist/commands/daemon/uninstall.js +5 -5
- package/dist/commands/daemon/unlock.js +5 -5
- package/dist/commands/daemon/usage.js +6 -6
- package/dist/commands/login.js +7 -2
- package/dist/commands/spaces/list.d.ts +13 -0
- package/dist/commands/spaces/list.js +20 -1
- package/dist/commands/tasks/list.d.ts +11 -0
- package/dist/commands/tasks/list.js +82 -11
- package/dist/commands/wiki/cat.js +2 -1
- package/dist/commands/wiki/mv.js +5 -1
- package/dist/commands/wiki/write.js +5 -1
- package/dist/help.d.ts +20 -1
- package/dist/help.js +26 -1
- package/dist/lib/api-fetch.d.ts +2 -1
- package/dist/lib/api-fetch.js +9 -2
- package/dist/lib/commitments.d.ts +44 -0
- package/dist/lib/commitments.js +123 -0
- package/dist/lib/daemon-binding.d.ts +3 -4
- package/dist/lib/daemon-binding.js +11 -10
- package/dist/lib/daemon-handoff-opt-out.d.ts +8 -0
- package/dist/lib/daemon-handoff-opt-out.js +17 -0
- package/dist/lib/daemon-installer.d.ts +1 -1
- package/dist/lib/daemon-installer.js +2 -2
- package/dist/lib/daemon-setup.js +13 -7
- package/dist/lib/daemonHandoff.d.ts +1 -1
- package/dist/lib/daemonHandoff.js +20 -7
- package/dist/lib/delegated-cli.d.ts +0 -9
- package/dist/lib/delegated-cli.js +149 -6
- package/dist/lib/{exec-oversky.d.ts → exec-runtime-binary.d.ts} +15 -4
- package/dist/lib/{exec-oversky.js → exec-runtime-binary.js} +93 -37
- package/dist/lib/node-adapter.js +6 -0
- package/dist/lib/sky-code.d.ts +1 -1
- package/dist/lib/sky-code.js +1 -1
- package/dist/lib/usage-discovery.js +1 -1
- package/dist/lib/web-url.d.ts +16 -0
- package/dist/lib/web-url.js +25 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3931 -3884
- package/oclif.manifest.json +9932 -9904
- package/package.json +2 -2
package/dist/base-command.d.ts
CHANGED
|
@@ -369,44 +369,6 @@ export declare function withSubject(subject: string | undefined, message: string
|
|
|
369
369
|
export declare function describeHarnessUnavailable(body: Record<string, unknown> | null, bin?: string): string;
|
|
370
370
|
export declare function describeResourceNotFound(serverMessage: string | undefined, bin?: string, baseURL?: string): string | null;
|
|
371
371
|
export declare function describeAssigneeNotInSpace(serverMessage: string | undefined, bin?: string): string;
|
|
372
|
-
|
|
373
|
-
* Whether an automated retry of the IDENTICAL request could plausibly succeed.
|
|
374
|
-
*
|
|
375
|
-
* Precedence:
|
|
376
|
-
* 1. An explicit `retryable` boolean in the error body — the server knows
|
|
377
|
-
* more about its own failure than any status heuristic does.
|
|
378
|
-
* 2. A known terminal refusal code → never retryable.
|
|
379
|
-
* 3. Status heuristic, restricted to genuinely TRANSIENT conditions: request
|
|
380
|
-
* timeout, too-early, rate limit, server error. 409 Conflict is
|
|
381
|
-
* deliberately absent — by definition it means the request conflicts with
|
|
382
|
-
* the resource's current state, which an identical retry cannot change.
|
|
383
|
-
*
|
|
384
|
-
* Exported for tests.
|
|
385
|
-
*/
|
|
386
|
-
/**
|
|
387
|
-
* What a 403 means, given whether the server said anything.
|
|
388
|
-
*
|
|
389
|
-
* Exported and pure so the wording is testable without an oclif runtime — the
|
|
390
|
-
* convention `isRetryableFailure` follows below.
|
|
391
|
-
*
|
|
392
|
-
* A 403 WITH a body is the API deciding, and it says why; we relay it. A 403
|
|
393
|
-
* with NO body did not come from the API — every application 403 in this
|
|
394
|
-
* codebase carries a message — so it is the edge refusing the request before it
|
|
395
|
-
* arrived, and the two must not share a sentence.
|
|
396
|
-
*
|
|
397
|
-
* This used to assert "your account does not have access to this resource" for
|
|
398
|
-
* both. For an edge refusal that names a cause this process never observed, and
|
|
399
|
-
* it is the expensive kind of wrong: it sends the user to audit their
|
|
400
|
-
* membership, their role and their token, which is the one place the problem is
|
|
401
|
-
* not. Dogfooded as OSK-263 — `skrr tasks create` refused a task description
|
|
402
|
-
* containing a dotted AWS-credentials path, in a project the same session had
|
|
403
|
-
* created a minute earlier, as an ADMIN who owned the space, and finding the
|
|
404
|
-
* real cause took a line-by-line bisect of the description body.
|
|
405
|
-
*
|
|
406
|
-
* The 404 branch has always done the honest thing (`bodyMessage || 'Not
|
|
407
|
-
* found.'`, which claims nothing); this brings 403 into line and adds the one
|
|
408
|
-
* lead worth having.
|
|
409
|
-
*/
|
|
410
|
-
export declare function describeForbidden(bodyMessage?: string | null): string;
|
|
372
|
+
export declare function describeForbidden(bodyMessage?: string | null, method?: string | null): string;
|
|
411
373
|
export declare function isRetryableFailure(status: number | undefined, body: Record<string, unknown> | null): boolean;
|
|
412
374
|
export { Flags };
|
package/dist/base-command.js
CHANGED
|
@@ -870,12 +870,17 @@ class BaseCommand extends core_1.Command {
|
|
|
870
870
|
// named a cause and the cause was fiction. The 404 branch below has
|
|
871
871
|
// always done the honest thing — `bodyMessage || 'Not found.'`, which
|
|
872
872
|
// claims nothing.
|
|
873
|
+
// An API-authored 403 (has a body) is a terminal refusal — retrying
|
|
874
|
+
// the same request will fail the same way. An edge-authored 403 (no
|
|
875
|
+
// body) is commonly transient (OSK-6765), so the JSON envelope's
|
|
876
|
+
// `retryable` should match what the human line already says: retry.
|
|
877
|
+
const edgeRefusal = !bodyMessage;
|
|
873
878
|
this.failWithCliError({
|
|
874
|
-
message: say(describeForbidden(bodyMessage)),
|
|
879
|
+
message: say(describeForbidden(bodyMessage, e.method)),
|
|
875
880
|
code: bodyCode || 'FORBIDDEN',
|
|
876
881
|
status: e.status,
|
|
877
882
|
exit: 3,
|
|
878
|
-
retryable:
|
|
883
|
+
retryable: edgeRefusal,
|
|
879
884
|
});
|
|
880
885
|
}
|
|
881
886
|
else if (e.status === 404) {
|
|
@@ -1353,17 +1358,38 @@ const TERMINAL_ERROR_CODES = new Set(['task_output_required', 'task_output_not_a
|
|
|
1353
1358
|
* created a minute earlier, as an ADMIN who owned the space, and finding the
|
|
1354
1359
|
* real cause took a line-by-line bisect of the description body.
|
|
1355
1360
|
*
|
|
1356
|
-
*
|
|
1357
|
-
*
|
|
1358
|
-
*
|
|
1361
|
+
* OSK-6765 refined this again. The original replacement led with the body
|
|
1362
|
+
* explanation ("try again with less of the request body") as a diagnosis, and
|
|
1363
|
+
* it was wrong two ways for `skrr agents show <id>`: (1) that command is a GET
|
|
1364
|
+
* and has no body to trim, so the advice was impossible to follow; (2) the
|
|
1365
|
+
* failure was TRANSIENT — the same command succeeded 5/5 on retry with nothing
|
|
1366
|
+
* changed — and the one action that actually fixed it (retry) was the one thing
|
|
1367
|
+
* the message did not mention. A user hunting for the trigger burned six probe
|
|
1368
|
+
* agents isolating candidate strings in their own data before noticing the
|
|
1369
|
+
* request had no body at all.
|
|
1370
|
+
*
|
|
1371
|
+
* So: LEAD with retry (edge rejections are commonly transient). Then, ONLY on
|
|
1372
|
+
* a method that actually carries a body, offer the body-content explanation as
|
|
1373
|
+
* a possibility, not as the diagnosis. The 404 branch has always done the
|
|
1374
|
+
* honest thing (`bodyMessage || 'Not found.'`, which claims nothing).
|
|
1359
1375
|
*/
|
|
1360
|
-
function
|
|
1376
|
+
function methodCarriesRequestBody(method) {
|
|
1377
|
+
if (!method)
|
|
1378
|
+
return false;
|
|
1379
|
+
const m = method.toUpperCase();
|
|
1380
|
+
return m === 'POST' || m === 'PUT' || m === 'PATCH';
|
|
1381
|
+
}
|
|
1382
|
+
function describeForbidden(bodyMessage, method) {
|
|
1361
1383
|
if (bodyMessage)
|
|
1362
1384
|
return bodyMessage;
|
|
1363
|
-
|
|
1364
|
-
'edge rule
|
|
1365
|
-
'you can read this resource elsewhere
|
|
1366
|
-
|
|
1385
|
+
const lead = 'Forbidden: the server refused this request and gave no reason. This is often a ' +
|
|
1386
|
+
'transient edge rule rather than a permission you lack — retry once. If it keeps ' +
|
|
1387
|
+
'failing, check that you can read this resource elsewhere';
|
|
1388
|
+
if (methodCarriesRequestBody(method)) {
|
|
1389
|
+
return (`${lead}, and consider that a path or token-shaped string in the request body can ` +
|
|
1390
|
+
'be enough to trigger an edge rule; try again with less.');
|
|
1391
|
+
}
|
|
1392
|
+
return `${lead}.`;
|
|
1367
1393
|
}
|
|
1368
1394
|
function isRetryableFailure(status, body) {
|
|
1369
1395
|
const declared = body?.retryable;
|
|
@@ -12,6 +12,16 @@ export declare function agentRow(a: Record<string, unknown>): {
|
|
|
12
12
|
name: string;
|
|
13
13
|
description: string;
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* What the zero-row case is allowed to say. The account-is-new empty state
|
|
17
|
+
* showed a bare `No agents.` and named no next step, which is what the
|
|
18
|
+
* `commitments/list.ts` empty state was fixed to stop doing. Point at the
|
|
19
|
+
* shortest path a new user actually wants (`skrr code`, which lazily creates
|
|
20
|
+
* a `Sky Code` agent), and at `agents create` for the explicit path.
|
|
21
|
+
*
|
|
22
|
+
* Exported and pure so the wording is testable without an oclif runtime.
|
|
23
|
+
*/
|
|
24
|
+
export declare function noAgentsEmptyMessage(bin?: string): string;
|
|
15
25
|
export default class AgentsList extends BaseCommand {
|
|
16
26
|
static description: string;
|
|
17
27
|
static examples: string[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.agentRow = agentRow;
|
|
4
|
+
exports.noAgentsEmptyMessage = noAgentsEmptyMessage;
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
6
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
7
|
const base_command_1 = require("../../base-command");
|
|
@@ -21,6 +22,20 @@ function agentRow(a) {
|
|
|
21
22
|
description: (0, format_1.formatCell)(a.description, ''),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* What the zero-row case is allowed to say. The account-is-new empty state
|
|
27
|
+
* showed a bare `No agents.` and named no next step, which is what the
|
|
28
|
+
* `commitments/list.ts` empty state was fixed to stop doing. Point at the
|
|
29
|
+
* shortest path a new user actually wants (`skrr code`, which lazily creates
|
|
30
|
+
* a `Sky Code` agent), and at `agents create` for the explicit path.
|
|
31
|
+
*
|
|
32
|
+
* Exported and pure so the wording is testable without an oclif runtime.
|
|
33
|
+
*/
|
|
34
|
+
function noAgentsEmptyMessage(bin = 'skrr') {
|
|
35
|
+
return ('No agents yet.\n' +
|
|
36
|
+
` → Start a coding session and one will be created for you: \`${bin} code\`\n` +
|
|
37
|
+
` → Or create one explicitly: \`${bin} agents create --name "..." --provider anthropic --model claude-sonnet-4-5 --target hosted-machine\``);
|
|
38
|
+
}
|
|
24
39
|
class AgentsList extends base_command_1.BaseCommand {
|
|
25
40
|
static description = 'List agents available to you';
|
|
26
41
|
static examples = [
|
|
@@ -57,7 +72,7 @@ class AgentsList extends base_command_1.BaseCommand {
|
|
|
57
72
|
? r
|
|
58
73
|
: (r?.data ?? r?.agents ?? []);
|
|
59
74
|
if (items.length === 0) {
|
|
60
|
-
this.log(
|
|
75
|
+
this.log(noAgentsEmptyMessage(this.config.bin));
|
|
61
76
|
return;
|
|
62
77
|
}
|
|
63
78
|
const rows = items.map((item) => ({
|
package/dist/commands/browser.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildBrowserArgs = buildBrowserArgs;
|
|
4
4
|
exports.forwardBrowserCommand = forwardBrowserCommand;
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
|
-
const
|
|
6
|
+
const exec_runtime_binary_1 = require("../lib/exec-runtime-binary");
|
|
7
7
|
function buildBrowserArgs(passthrough) {
|
|
8
8
|
return ['browser', ...passthrough];
|
|
9
9
|
}
|
|
@@ -17,14 +17,14 @@ async function forwardBrowserCommand(command, passthrough) {
|
|
|
17
17
|
// Older daemons treated unknown subcommands as a daemon startup in some
|
|
18
18
|
// releases. Probe the command list before forwarding so an install command
|
|
19
19
|
// cannot turn into a surprising service mutation.
|
|
20
|
-
if ((await (0,
|
|
20
|
+
if ((await (0, exec_runtime_binary_1.runtimeBinarySupportsSubcommand)('browser')) === false) {
|
|
21
21
|
command.error('The local `oversky` daemon does not support skrr Browser yet. Update or reinstall the daemon, then retry `skrr browser`.', { exit: 2 });
|
|
22
22
|
}
|
|
23
|
-
command.exit(await (0,
|
|
23
|
+
command.exit(await (0, exec_runtime_binary_1.execRuntimeBinary)(buildBrowserArgs(passthrough)));
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
|
-
if (error.message === '
|
|
27
|
-
command.log((0,
|
|
26
|
+
if (error.message === 'runtime-binary-not-installed') {
|
|
27
|
+
command.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
28
28
|
command.exit(127);
|
|
29
29
|
}
|
|
30
30
|
throw error;
|
|
@@ -41,6 +41,8 @@ export default class CommitmentsCreate extends BaseCommand {
|
|
|
41
41
|
source: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
42
42
|
watch: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
43
43
|
'metric-key': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
44
|
+
'watch-space': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
45
|
+
'watch-monitor': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
44
46
|
cadence: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
45
47
|
'cadence-mode': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
46
48
|
timezone: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -85,7 +85,7 @@ class CommitmentsCreate extends base_command_1.BaseCommand {
|
|
|
85
85
|
description: 'Watched source the criterion reads (implies --evaluator source_state), e.g. github',
|
|
86
86
|
}),
|
|
87
87
|
watch: core_1.Flags.string({
|
|
88
|
-
description: `Watched source (repeatable). One of: ${commitments_1.COMMITMENT_WATCHED_SOURCES.join(', ')}
|
|
88
|
+
description: `Watched source (repeatable). One of: ${commitments_1.COMMITMENT_WATCHED_SOURCES.join(', ')}. Some sources need companion flags: --watch-space, --watch-monitor, --metric-key.`,
|
|
89
89
|
multiple: true,
|
|
90
90
|
options: [...commitments_1.COMMITMENT_WATCHED_SOURCES],
|
|
91
91
|
}),
|
|
@@ -93,6 +93,20 @@ class CommitmentsCreate extends base_command_1.BaseCommand {
|
|
|
93
93
|
description: 'Metric key to read when --watch metrics is used (repeatable)',
|
|
94
94
|
multiple: true,
|
|
95
95
|
}),
|
|
96
|
+
// `space` and `monitor` sources REQUIRE a scope id in `config`, and the
|
|
97
|
+
// watched-source enum on its own cannot express it (the API rejects the
|
|
98
|
+
// create with `Space watched source requires config.spaceId` / `Monitor
|
|
99
|
+
// watchedSources require a bounded config.monitorId`). Providing the
|
|
100
|
+
// companion flag implicitly opts the source in — mirroring how
|
|
101
|
+
// `--metric-key` works — so the enum and its config never disagree.
|
|
102
|
+
'watch-space': core_1.Flags.string({
|
|
103
|
+
description: 'Space to watch (repeatable). Accepts a space id, ref, or unique title. Implies --watch space.',
|
|
104
|
+
multiple: true,
|
|
105
|
+
}),
|
|
106
|
+
'watch-monitor': core_1.Flags.string({
|
|
107
|
+
description: 'Signal Monitor id to watch (repeatable). Implies --watch monitor.',
|
|
108
|
+
multiple: true,
|
|
109
|
+
}),
|
|
96
110
|
cadence: core_1.Flags.string({
|
|
97
111
|
description: 'Check interval, e.g. "15m", "6h", "1d" (1m..30d). Implies --cadence-mode interval.',
|
|
98
112
|
}),
|
|
@@ -153,18 +167,21 @@ class CommitmentsCreate extends base_command_1.BaseCommand {
|
|
|
153
167
|
else if (flags.deadline || criteria.length) {
|
|
154
168
|
throw new Error('--outcome is required when passing --deadline or --criterion.');
|
|
155
169
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
// Resolve space references up front (ref/title → uuid), so a name in
|
|
171
|
+
// `--watch-space` is treated the same way it is everywhere else that
|
|
172
|
+
// takes a space.
|
|
173
|
+
const watchSpaces = (0, triggers_1.splitRepeated)(flags['watch-space']);
|
|
174
|
+
const resolvedSpaceIds = watchSpaces
|
|
175
|
+
? await Promise.all(watchSpaces.map((ref) => this.resolveSpaceReference(ref)))
|
|
176
|
+
: [];
|
|
177
|
+
const built = (0, commitments_1.buildWatchedSources)({
|
|
178
|
+
watch: (0, triggers_1.splitRepeated)(flags.watch),
|
|
179
|
+
metricKey: (0, triggers_1.splitRepeated)(flags['metric-key']),
|
|
180
|
+
spaceIds: resolvedSpaceIds,
|
|
181
|
+
monitorIds: (0, triggers_1.splitRepeated)(flags['watch-monitor']),
|
|
182
|
+
});
|
|
183
|
+
if (built)
|
|
184
|
+
payload.watchedSources = built;
|
|
168
185
|
const cadence = {};
|
|
169
186
|
if (flags.cadence) {
|
|
170
187
|
cadence.intervalMs = (0, commitments_1.parseIntervalToMs)(flags.cadence);
|
|
@@ -35,6 +35,8 @@ export default class CommitmentsUpdate extends BaseCommand {
|
|
|
35
35
|
measure: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
36
36
|
source: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
37
37
|
watch: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
38
|
+
'watch-space': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
39
|
+
'watch-monitor': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
38
40
|
cadence: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
39
41
|
'cadence-mode': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
40
42
|
timezone: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -64,10 +64,18 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
64
64
|
description: 'Watched source the criterion reads (implies --evaluator source_state), e.g. github',
|
|
65
65
|
}),
|
|
66
66
|
watch: core_1.Flags.string({
|
|
67
|
-
description: 'Watched source (repeatable). Replaces the existing set.',
|
|
67
|
+
description: 'Watched source (repeatable). Replaces the existing set. Some sources need companion flags: --watch-space, --watch-monitor.',
|
|
68
68
|
multiple: true,
|
|
69
69
|
options: [...commitments_1.COMMITMENT_WATCHED_SOURCES],
|
|
70
70
|
}),
|
|
71
|
+
'watch-space': core_1.Flags.string({
|
|
72
|
+
description: 'Space to watch (repeatable). Accepts a space id, ref, or unique title. Implies --watch space.',
|
|
73
|
+
multiple: true,
|
|
74
|
+
}),
|
|
75
|
+
'watch-monitor': core_1.Flags.string({
|
|
76
|
+
description: 'Signal Monitor id to watch (repeatable). Implies --watch monitor.',
|
|
77
|
+
multiple: true,
|
|
78
|
+
}),
|
|
71
79
|
cadence: core_1.Flags.string({ description: 'New check interval, e.g. "15m", "6h", "1d" (1m..30d)' }),
|
|
72
80
|
'cadence-mode': core_1.Flags.string({
|
|
73
81
|
description: 'Cadence mode',
|
|
@@ -143,9 +151,21 @@ class CommitmentsUpdate extends base_command_1.BaseCommand {
|
|
|
143
151
|
: {}),
|
|
144
152
|
};
|
|
145
153
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
// Companion flags carry the config required by `space` / `monitor`, and
|
|
155
|
+
// implicitly opt each source in — same shape as `create`. The API
|
|
156
|
+
// replaces watchedSources WHOLESALE, so passing `--watch-space` alone
|
|
157
|
+
// still names the FULL new set (`space`) rather than adding to it.
|
|
158
|
+
const watchSpaces = (0, triggers_1.splitRepeated)(flags['watch-space']);
|
|
159
|
+
const resolvedSpaceIds = watchSpaces
|
|
160
|
+
? await Promise.all(watchSpaces.map((ref) => this.resolveSpaceReference(ref)))
|
|
161
|
+
: [];
|
|
162
|
+
const built = (0, commitments_1.buildWatchedSources)({
|
|
163
|
+
watch: watched,
|
|
164
|
+
spaceIds: resolvedSpaceIds,
|
|
165
|
+
monitorIds: (0, triggers_1.splitRepeated)(flags['watch-monitor']),
|
|
166
|
+
});
|
|
167
|
+
if (built)
|
|
168
|
+
payload.watchedSources = built;
|
|
149
169
|
if (wantsCadence) {
|
|
150
170
|
const existing = current?.cadence ?? {};
|
|
151
171
|
const cadence = {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
/**
|
|
6
6
|
* `skrr daemon byok ...` forwards the Keychain operation to the daemon. The
|
|
7
7
|
* daemon owns profile selection and secret custody; this CLI never receives a
|
|
@@ -13,7 +13,7 @@ class DaemonByok extends core_1.Command {
|
|
|
13
13
|
// resolved: every subcommand under it failed.
|
|
14
14
|
static aliases = ['daemons:byok'];
|
|
15
15
|
static summary = 'Manage local BYOK provider credentials in the daemon profile Keychain';
|
|
16
|
-
static description = (0,
|
|
16
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('byok');
|
|
17
17
|
static strict = false;
|
|
18
18
|
static examples = [
|
|
19
19
|
'<%= config.bin %> daemon byok status',
|
|
@@ -33,11 +33,11 @@ class DaemonByok extends core_1.Command {
|
|
|
33
33
|
// mistake, one directory over.
|
|
34
34
|
const argv = this.argv;
|
|
35
35
|
try {
|
|
36
|
-
this.exit(await (0,
|
|
36
|
+
this.exit(await (0, exec_runtime_binary_1.execRuntimeBinary)(['byok', ...argv]));
|
|
37
37
|
}
|
|
38
38
|
catch (error) {
|
|
39
|
-
if (error.message === '
|
|
40
|
-
this.log((0,
|
|
39
|
+
if (error.message === 'runtime-binary-not-installed') {
|
|
40
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
41
41
|
this.exit(127);
|
|
42
42
|
}
|
|
43
43
|
throw error;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
/**
|
|
6
6
|
* `skrr daemon` — top-level help for the daemon subcommands.
|
|
7
7
|
*
|
|
@@ -10,7 +10,10 @@ const exec_oversky_1 = require("../../lib/exec-oversky");
|
|
|
10
10
|
* quick install check.
|
|
11
11
|
*/
|
|
12
12
|
class Daemon extends core_1.Command {
|
|
13
|
-
|
|
13
|
+
// "Wraps the `skrrd` binary" read, cold, as though you must already HAVE one —
|
|
14
|
+
// the opposite of what `skrr daemon install` does now that it fetches the
|
|
15
|
+
// signed release. Dogfooding 0.1.12 hit exactly that reading.
|
|
16
|
+
static description = 'Manage the local skrr runtime — install it, sign it in, and check on it.';
|
|
14
17
|
static examples = [
|
|
15
18
|
'<%= config.bin %> daemon install',
|
|
16
19
|
'<%= config.bin %> daemon status',
|
|
@@ -21,9 +24,9 @@ class Daemon extends core_1.Command {
|
|
|
21
24
|
'<%= config.bin %> daemon byok status',
|
|
22
25
|
];
|
|
23
26
|
async run() {
|
|
24
|
-
const bin = (0,
|
|
27
|
+
const bin = (0, exec_runtime_binary_1.findRuntimeBinary)();
|
|
25
28
|
if (!bin) {
|
|
26
|
-
this.log((0,
|
|
29
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
27
30
|
this.exit(127);
|
|
28
31
|
}
|
|
29
32
|
this.log(`runtime binary: ${bin}`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
const daemon_binding_1 = require("../../lib/daemon-binding");
|
|
6
6
|
const daemon_installer_1 = require("../../lib/daemon-installer");
|
|
7
7
|
/**
|
|
@@ -36,7 +36,10 @@ class DaemonInstall extends core_1.Command {
|
|
|
36
36
|
// resolved: every subcommand under it failed.
|
|
37
37
|
static aliases = ['daemons:install'];
|
|
38
38
|
static summary = 'Install the local skrr runtime as a background service';
|
|
39
|
-
static description = (0,
|
|
39
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('install', {
|
|
40
|
+
binds: true,
|
|
41
|
+
bootstrapsRuntime: true,
|
|
42
|
+
});
|
|
40
43
|
static strict = false; // forward all args verbatim — see run()
|
|
41
44
|
async run() {
|
|
42
45
|
// `this.argv`, NOT `this.parse()`. `strict = false` relaxes POSITIONAL
|
|
@@ -53,7 +56,7 @@ class DaemonInstall extends core_1.Command {
|
|
|
53
56
|
// brew, the script installer, a dev checkout — is left exactly alone; this
|
|
54
57
|
// is a floor under the missing case, not a second update channel competing
|
|
55
58
|
// with the daemon's own.
|
|
56
|
-
if (!(0,
|
|
59
|
+
if (!(0, exec_runtime_binary_1.isCurrentRuntimeBinary)((0, exec_runtime_binary_1.findRuntimeBinary)())) {
|
|
57
60
|
this.log('No local skrr runtime found. Fetching the signed release...');
|
|
58
61
|
const outcome = await (0, daemon_installer_1.installDaemon)();
|
|
59
62
|
if (!outcome.ok) {
|
|
@@ -73,11 +76,11 @@ class DaemonInstall extends core_1.Command {
|
|
|
73
76
|
// moment the binding is chosen, and leaving it to a separate command
|
|
74
77
|
// is how a CLI and its daemon end up on different deployments
|
|
75
78
|
// (OSK-279) without anyone doing anything wrong.
|
|
76
|
-
const code = await (0,
|
|
79
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['install', ...(0, daemon_binding_1.bindToCliSession)(argv)]);
|
|
77
80
|
this.exit(code);
|
|
78
81
|
}
|
|
79
82
|
catch (err) {
|
|
80
|
-
if (err.message === '
|
|
83
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
81
84
|
// Reachable only if the runtime vanished between the bootstrap above
|
|
82
85
|
// and this line. Saying so beats repeating install instructions for
|
|
83
86
|
// something that was just installed.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
const daemon_binding_1 = require("../../lib/daemon-binding");
|
|
5
|
-
const
|
|
5
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
6
6
|
/**
|
|
7
7
|
* `skrr daemon login` — authenticate the local runtime.
|
|
8
8
|
*
|
|
@@ -29,7 +29,7 @@ const exec_oversky_1 = require("../../lib/exec-oversky");
|
|
|
29
29
|
class DaemonLogin extends core_1.Command {
|
|
30
30
|
static aliases = ['daemons:login'];
|
|
31
31
|
static summary = 'Authenticate the local skrr runtime (separate from `skrr login`)';
|
|
32
|
-
static description = (0,
|
|
32
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('login', { binds: true });
|
|
33
33
|
static strict = false; // forward all args verbatim — see run()
|
|
34
34
|
async run() {
|
|
35
35
|
// `this.argv`, NOT `this.parse()` — `strict = false` relaxes POSITIONAL
|
|
@@ -41,12 +41,12 @@ class DaemonLogin extends core_1.Command {
|
|
|
41
41
|
// from the installed service definition, which is the only authoritative
|
|
42
42
|
// answer; guessing it from the CLI's cwd is exactly the mistake that made
|
|
43
43
|
// the old default wrong.
|
|
44
|
-
const code = await (0,
|
|
44
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['login', ...(0, daemon_binding_1.bindToCliSession)(argv)]);
|
|
45
45
|
this.exit(code);
|
|
46
46
|
}
|
|
47
47
|
catch (err) {
|
|
48
|
-
if (err.message === '
|
|
49
|
-
this.log((0,
|
|
48
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
49
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
50
50
|
this.exit(127);
|
|
51
51
|
}
|
|
52
52
|
throw err;
|
|
@@ -10,7 +10,7 @@ const core_1 = require("@oclif/core");
|
|
|
10
10
|
const node_fs_1 = require("node:fs");
|
|
11
11
|
const node_os_1 = require("node:os");
|
|
12
12
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
-
const
|
|
13
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
14
14
|
const MAX_FALLBACK_LOG_BYTES = 1024 * 1024;
|
|
15
15
|
const PROFILE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
16
16
|
/**
|
|
@@ -122,7 +122,7 @@ class DaemonLogs extends core_1.Command {
|
|
|
122
122
|
// `oversky 0.2.x` has profiles and writes the same files, but has no
|
|
123
123
|
// `logs` subcommand. Probe top-level help first so forwarding does not
|
|
124
124
|
// print an unrelated "unknown option" error before the useful output.
|
|
125
|
-
if ((await (0,
|
|
125
|
+
if ((await (0, exec_runtime_binary_1.runtimeBinarySupportsSubcommand)('logs')) === false) {
|
|
126
126
|
const logPath = resolveLegacyDaemonLogPath(flags);
|
|
127
127
|
if (flags.path) {
|
|
128
128
|
this.log(logPath);
|
|
@@ -163,12 +163,12 @@ class DaemonLogs extends core_1.Command {
|
|
|
163
163
|
}
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
|
-
const code = await (0,
|
|
166
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(args);
|
|
167
167
|
this.exit(code);
|
|
168
168
|
}
|
|
169
169
|
catch (err) {
|
|
170
|
-
if (err.message === '
|
|
171
|
-
this.log((0,
|
|
170
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
171
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
172
172
|
this.log('');
|
|
173
173
|
this.log('Daemon logs live under the per-profile config dir, e.g.:');
|
|
174
174
|
this.log(` ${node_path_1.default.join((0, node_os_1.homedir)(), '.skrr', 'profiles', '<profile>', 'logs', 'daemon.log')}`);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
class DaemonRestart extends core_1.Command {
|
|
6
6
|
// `skrr daemons <sub>` — the plural is advertised as an alias for the
|
|
7
7
|
// whole topic, and without a per-command alias only the bare topic
|
|
8
8
|
// resolved: every subcommand under it failed.
|
|
9
9
|
static aliases = ['daemons:restart'];
|
|
10
10
|
static summary = 'Restart the local skrr daemon, preserving its current supervision mode';
|
|
11
|
-
static description = (0,
|
|
11
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('restart');
|
|
12
12
|
static strict = false; // forward all args verbatim — see run()
|
|
13
13
|
static examples = [
|
|
14
14
|
'<%= config.bin %> daemon restart',
|
|
@@ -21,12 +21,12 @@ class DaemonRestart extends core_1.Command {
|
|
|
21
21
|
// exists to reach it (OSK-296).
|
|
22
22
|
const argv = this.argv;
|
|
23
23
|
try {
|
|
24
|
-
const code = await (0,
|
|
24
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['restart', ...argv]);
|
|
25
25
|
this.exit(code);
|
|
26
26
|
}
|
|
27
27
|
catch (err) {
|
|
28
|
-
if (err.message === '
|
|
29
|
-
this.log((0,
|
|
28
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
29
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
30
30
|
this.exit(127);
|
|
31
31
|
}
|
|
32
32
|
throw err;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
class DaemonStart extends core_1.Command {
|
|
6
6
|
// `skrr daemons <sub>` — the plural is advertised as an alias for the
|
|
7
7
|
// whole topic, and without a per-command alias only the bare topic
|
|
8
8
|
// resolved: every subcommand under it failed.
|
|
9
9
|
static aliases = ['daemons:start'];
|
|
10
10
|
static summary = 'Start the local skrr daemon';
|
|
11
|
-
static description = (0,
|
|
11
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('start');
|
|
12
12
|
static strict = false; // forward all args verbatim — see run()
|
|
13
13
|
async run() {
|
|
14
14
|
// `this.argv`, NOT `this.parse()`. `strict = false` relaxes POSITIONAL
|
|
@@ -22,12 +22,12 @@ class DaemonStart extends core_1.Command {
|
|
|
22
22
|
// mistake, one directory over.
|
|
23
23
|
const argv = this.argv;
|
|
24
24
|
try {
|
|
25
|
-
const code = await (0,
|
|
25
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['start', ...argv]);
|
|
26
26
|
this.exit(code);
|
|
27
27
|
}
|
|
28
28
|
catch (err) {
|
|
29
|
-
if (err.message === '
|
|
30
|
-
this.log((0,
|
|
29
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
30
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
31
31
|
this.exit(127);
|
|
32
32
|
}
|
|
33
33
|
throw err;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const exec_runtime_binary_1 = require("../../lib/exec-runtime-binary");
|
|
5
5
|
class DaemonStatus extends core_1.Command {
|
|
6
6
|
// `skrr daemons <sub>` — the plural is advertised as an alias for the
|
|
7
7
|
// whole topic, and without a per-command alias only the bare topic
|
|
8
8
|
// resolved: every subcommand under it failed.
|
|
9
9
|
static aliases = ['daemons:status'];
|
|
10
10
|
static summary = 'Show skrr daemon status (config, connection, services)';
|
|
11
|
-
static description = (0,
|
|
11
|
+
static description = (0, exec_runtime_binary_1.forwardedFlagsNote)('status');
|
|
12
12
|
static strict = false;
|
|
13
13
|
async run() {
|
|
14
14
|
// `this.argv`, NOT `this.parse()`. `strict = false` relaxes POSITIONAL
|
|
@@ -22,12 +22,12 @@ class DaemonStatus extends core_1.Command {
|
|
|
22
22
|
// mistake, one directory over.
|
|
23
23
|
const argv = this.argv;
|
|
24
24
|
try {
|
|
25
|
-
const code = await (0,
|
|
25
|
+
const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['status', ...argv]);
|
|
26
26
|
this.exit(code);
|
|
27
27
|
}
|
|
28
28
|
catch (err) {
|
|
29
|
-
if (err.message === '
|
|
30
|
-
this.log((0,
|
|
29
|
+
if (err.message === 'runtime-binary-not-installed') {
|
|
30
|
+
this.log((0, exec_runtime_binary_1.notInstalledMessage)());
|
|
31
31
|
this.exit(127);
|
|
32
32
|
}
|
|
33
33
|
throw err;
|