@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.
Files changed (57) hide show
  1. package/dist/base-command.d.ts +1 -39
  2. package/dist/base-command.js +36 -10
  3. package/dist/commands/agents/list.d.ts +10 -0
  4. package/dist/commands/agents/list.js +16 -1
  5. package/dist/commands/browser.js +5 -5
  6. package/dist/commands/commitments/create.d.ts +2 -0
  7. package/dist/commands/commitments/create.js +30 -13
  8. package/dist/commands/commitments/update.d.ts +2 -0
  9. package/dist/commands/commitments/update.js +24 -4
  10. package/dist/commands/daemon/byok.js +5 -5
  11. package/dist/commands/daemon/index.js +7 -4
  12. package/dist/commands/daemon/install.js +8 -5
  13. package/dist/commands/daemon/login.js +5 -5
  14. package/dist/commands/daemon/logs.js +5 -5
  15. package/dist/commands/daemon/restart.js +5 -5
  16. package/dist/commands/daemon/start.js +5 -5
  17. package/dist/commands/daemon/status.js +5 -5
  18. package/dist/commands/daemon/stop.js +5 -5
  19. package/dist/commands/daemon/uninstall.js +5 -5
  20. package/dist/commands/daemon/unlock.js +5 -5
  21. package/dist/commands/daemon/usage.js +6 -6
  22. package/dist/commands/login.js +7 -2
  23. package/dist/commands/spaces/list.d.ts +13 -0
  24. package/dist/commands/spaces/list.js +20 -1
  25. package/dist/commands/tasks/list.d.ts +11 -0
  26. package/dist/commands/tasks/list.js +82 -11
  27. package/dist/commands/wiki/cat.js +2 -1
  28. package/dist/commands/wiki/mv.js +5 -1
  29. package/dist/commands/wiki/write.js +5 -1
  30. package/dist/help.d.ts +20 -1
  31. package/dist/help.js +26 -1
  32. package/dist/lib/api-fetch.d.ts +2 -1
  33. package/dist/lib/api-fetch.js +9 -2
  34. package/dist/lib/commitments.d.ts +44 -0
  35. package/dist/lib/commitments.js +123 -0
  36. package/dist/lib/daemon-binding.d.ts +3 -4
  37. package/dist/lib/daemon-binding.js +11 -10
  38. package/dist/lib/daemon-handoff-opt-out.d.ts +8 -0
  39. package/dist/lib/daemon-handoff-opt-out.js +17 -0
  40. package/dist/lib/daemon-installer.d.ts +1 -1
  41. package/dist/lib/daemon-installer.js +2 -2
  42. package/dist/lib/daemon-setup.js +13 -7
  43. package/dist/lib/daemonHandoff.d.ts +1 -1
  44. package/dist/lib/daemonHandoff.js +20 -7
  45. package/dist/lib/delegated-cli.d.ts +0 -9
  46. package/dist/lib/delegated-cli.js +149 -6
  47. package/dist/lib/{exec-oversky.d.ts → exec-runtime-binary.d.ts} +15 -4
  48. package/dist/lib/{exec-oversky.js → exec-runtime-binary.js} +93 -37
  49. package/dist/lib/node-adapter.js +6 -0
  50. package/dist/lib/sky-code.d.ts +1 -1
  51. package/dist/lib/sky-code.js +1 -1
  52. package/dist/lib/usage-discovery.js +1 -1
  53. package/dist/lib/web-url.d.ts +16 -0
  54. package/dist/lib/web-url.js +25 -0
  55. package/dist/node_modules/@skrr-ai/data-provider/index.js +3931 -3884
  56. package/oclif.manifest.json +9932 -9904
  57. package/package.json +2 -2
@@ -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 };
@@ -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: false,
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
- * The 404 branch has always done the honest thing (`bodyMessage || 'Not
1357
- * found.'`, which claims nothing); this brings 403 into line and adds the one
1358
- * lead worth having.
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 describeForbidden(bodyMessage) {
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
- return ('Forbidden: the server refused this request and gave no reason. That usually means an ' +
1364
- 'edge rule rejected it before it reached the API rather than a permission you lack — if ' +
1365
- 'you can read this resource elsewhere, try again with less of the request body (a path ' +
1366
- 'or token-shaped string in your text is enough to trigger one).');
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('No agents.');
75
+ this.log(noAgentsEmptyMessage(this.config.bin));
61
76
  return;
62
77
  }
63
78
  const rows = items.map((item) => ({
@@ -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 exec_oversky_1 = require("../lib/exec-oversky");
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, exec_oversky_1.overskySupportsSubcommand)('browser')) === false) {
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, exec_oversky_1.execOversky)(buildBrowserArgs(passthrough)));
23
+ command.exit(await (0, exec_runtime_binary_1.execRuntimeBinary)(buildBrowserArgs(passthrough)));
24
24
  }
25
25
  catch (error) {
26
- if (error.message === 'oversky-not-installed') {
27
- command.log((0, exec_oversky_1.notInstalledMessage)());
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
- const watched = (0, triggers_1.splitRepeated)(flags.watch);
157
- if (watched && watched.length) {
158
- const metricKeys = (0, triggers_1.splitRepeated)(flags['metric-key']);
159
- if (metricKeys?.length && !watched.includes('metrics')) {
160
- throw new Error('--metric-key requires --watch metrics.');
161
- }
162
- payload.watchedSources = watched.map((source) => ({
163
- source,
164
- enabled: true,
165
- ...(source === 'metrics' && metricKeys?.length ? { config: { metricKeys } } : {}),
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
- if (watched && watched.length) {
147
- payload.watchedSources = watched.map((source) => ({ source, enabled: true }));
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('byok');
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, exec_oversky_1.execOversky)(['byok', ...argv]));
36
+ this.exit(await (0, exec_runtime_binary_1.execRuntimeBinary)(['byok', ...argv]));
37
37
  }
38
38
  catch (error) {
39
- if (error.message === 'oversky-not-installed') {
40
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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
- static description = 'Manage the local skrr runtime. Wraps the `skrrd` binary.';
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, exec_oversky_1.findOverskyBinary)();
27
+ const bin = (0, exec_runtime_binary_1.findRuntimeBinary)();
25
28
  if (!bin) {
26
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('install', { binds: true });
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, exec_oversky_1.findOverskyBinary)()) {
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, exec_oversky_1.execOversky)(['install', ...(0, daemon_binding_1.bindToCliSession)(argv)]);
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 === 'oversky-not-installed') {
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('login', { binds: true });
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, exec_oversky_1.execOversky)(['login', ...(0, daemon_binding_1.bindToCliSession)(argv)]);
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 === 'oversky-not-installed') {
49
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.overskySupportsSubcommand)('logs')) === false) {
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, exec_oversky_1.execOversky)(args);
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 === 'oversky-not-installed') {
171
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('restart');
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, exec_oversky_1.execOversky)(['restart', ...argv]);
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 === 'oversky-not-installed') {
29
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('start');
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, exec_oversky_1.execOversky)(['start', ...argv]);
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 === 'oversky-not-installed') {
30
- this.log((0, exec_oversky_1.notInstalledMessage)());
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 exec_oversky_1 = require("../../lib/exec-oversky");
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, exec_oversky_1.forwardedFlagsNote)('status');
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, exec_oversky_1.execOversky)(['status', ...argv]);
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 === 'oversky-not-installed') {
30
- this.log((0, exec_oversky_1.notInstalledMessage)());
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;