@skrr-ai/cli 0.1.13 → 0.1.15

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 (136) hide show
  1. package/dist/base-command.d.ts +12 -36
  2. package/dist/base-command.js +96 -11
  3. package/dist/commands/agents/create.d.ts +1 -0
  4. package/dist/commands/agents/create.js +6 -1
  5. package/dist/commands/agents/instructions/add.d.ts +21 -0
  6. package/dist/commands/agents/instructions/add.js +115 -0
  7. package/dist/commands/agents/instructions/disable.d.ts +13 -0
  8. package/dist/commands/agents/instructions/disable.js +50 -0
  9. package/dist/commands/agents/instructions/edit.d.ts +16 -0
  10. package/dist/commands/agents/instructions/edit.js +79 -0
  11. package/dist/commands/agents/instructions/enable.d.ts +13 -0
  12. package/dist/commands/agents/instructions/enable.js +50 -0
  13. package/dist/commands/agents/instructions/move.d.ts +15 -0
  14. package/dist/commands/agents/instructions/move.js +61 -0
  15. package/dist/commands/agents/instructions/preview.d.ts +13 -0
  16. package/dist/commands/agents/instructions/preview.js +59 -0
  17. package/dist/commands/agents/instructions/remove.d.ts +13 -0
  18. package/dist/commands/agents/instructions/remove.js +49 -0
  19. package/dist/commands/agents/instructions/set.d.ts +17 -0
  20. package/dist/commands/agents/instructions/set.js +79 -0
  21. package/dist/commands/agents/instructions/show.d.ts +15 -0
  22. package/dist/commands/agents/instructions/show.js +76 -0
  23. package/dist/commands/agents/instructions/upgrade.d.ts +16 -0
  24. package/dist/commands/agents/instructions/upgrade.js +77 -0
  25. package/dist/commands/agents/list.d.ts +10 -0
  26. package/dist/commands/agents/list.js +16 -1
  27. package/dist/commands/agents/show.js +5 -0
  28. package/dist/commands/agents/triggers/policy.js +8 -2
  29. package/dist/commands/agents/update.d.ts +1 -0
  30. package/dist/commands/agents/update.js +8 -2
  31. package/dist/commands/browser.js +5 -5
  32. package/dist/commands/commitments/create.d.ts +2 -0
  33. package/dist/commands/commitments/create.js +30 -13
  34. package/dist/commands/commitments/update.d.ts +2 -0
  35. package/dist/commands/commitments/update.js +24 -4
  36. package/dist/commands/daemon/byok.js +5 -5
  37. package/dist/commands/daemon/index.js +5 -3
  38. package/dist/commands/daemon/install.js +8 -5
  39. package/dist/commands/daemon/login.js +5 -5
  40. package/dist/commands/daemon/logs.js +5 -5
  41. package/dist/commands/daemon/recover-offline-queue.d.ts +9 -0
  42. package/dist/commands/daemon/recover-offline-queue.js +24 -0
  43. package/dist/commands/daemon/restart.js +5 -5
  44. package/dist/commands/daemon/start.js +34 -6
  45. package/dist/commands/daemon/status.js +5 -5
  46. package/dist/commands/daemon/stop.js +5 -5
  47. package/dist/commands/daemon/uninstall.js +5 -5
  48. package/dist/commands/daemon/unlock.js +5 -5
  49. package/dist/commands/daemon/usage.js +6 -6
  50. package/dist/commands/instruction-blocks/create.d.ts +19 -0
  51. package/dist/commands/instruction-blocks/create.js +94 -0
  52. package/dist/commands/instruction-blocks/delete.d.ts +13 -0
  53. package/dist/commands/instruction-blocks/delete.js +35 -0
  54. package/dist/commands/instruction-blocks/list.d.ts +13 -0
  55. package/dist/commands/instruction-blocks/list.js +71 -0
  56. package/dist/commands/instruction-blocks/show.d.ts +12 -0
  57. package/dist/commands/instruction-blocks/show.js +35 -0
  58. package/dist/commands/instruction-blocks/update.d.ts +23 -0
  59. package/dist/commands/instruction-blocks/update.js +94 -0
  60. package/dist/commands/login.js +7 -2
  61. package/dist/commands/spaces/auto-executor/preview.d.ts +1 -0
  62. package/dist/commands/spaces/auto-executor/preview.js +62 -3
  63. package/dist/commands/spaces/auto-executor/update.d.ts +4 -0
  64. package/dist/commands/spaces/auto-executor/update.js +78 -7
  65. package/dist/commands/spaces/capacity.js +14 -2
  66. package/dist/commands/spaces/list.d.ts +13 -0
  67. package/dist/commands/spaces/list.js +20 -1
  68. package/dist/commands/spaces/update.d.ts +4 -0
  69. package/dist/commands/spaces/update.js +49 -2
  70. package/dist/commands/tasks/complete.d.ts +12 -5
  71. package/dist/commands/tasks/complete.js +50 -28
  72. package/dist/commands/tasks/continue-ready.js +9 -1
  73. package/dist/commands/tasks/create.d.ts +1 -0
  74. package/dist/commands/tasks/create.js +25 -1
  75. package/dist/commands/tasks/deliverable/add.d.ts +23 -0
  76. package/dist/commands/tasks/deliverable/add.js +70 -0
  77. package/dist/commands/tasks/events/append.d.ts +1 -1
  78. package/dist/commands/tasks/events/append.js +4 -4
  79. package/dist/commands/tasks/expectations.d.ts +12 -0
  80. package/dist/commands/tasks/expectations.js +92 -0
  81. package/dist/commands/tasks/judge.d.ts +29 -0
  82. package/dist/commands/tasks/judge.js +68 -0
  83. package/dist/commands/tasks/list.d.ts +11 -0
  84. package/dist/commands/tasks/list.js +82 -11
  85. package/dist/commands/tasks/report.d.ts +1 -1
  86. package/dist/commands/tasks/report.js +3 -3
  87. package/dist/commands/tasks/update.d.ts +1 -0
  88. package/dist/commands/tasks/update.js +34 -4
  89. package/dist/commands/tasks/waive.d.ts +25 -0
  90. package/dist/commands/tasks/waive.js +58 -0
  91. package/dist/commands/wiki/cat.js +2 -1
  92. package/dist/commands/wiki/mv.js +5 -1
  93. package/dist/commands/wiki/write.js +5 -1
  94. package/dist/lib/agent-config.js +5 -0
  95. package/dist/lib/agent-instructions.d.ts +15 -0
  96. package/dist/lib/agent-instructions.js +55 -0
  97. package/dist/lib/api-fetch.d.ts +2 -1
  98. package/dist/lib/api-fetch.js +9 -2
  99. package/dist/lib/command-hygiene.d.ts +6 -1
  100. package/dist/lib/command-hygiene.js +49 -29
  101. package/dist/lib/commitments.d.ts +44 -0
  102. package/dist/lib/commitments.js +123 -0
  103. package/dist/lib/daemon-binding.d.ts +3 -4
  104. package/dist/lib/daemon-binding.js +11 -10
  105. package/dist/lib/daemon-handoff-opt-out.d.ts +8 -0
  106. package/dist/lib/daemon-handoff-opt-out.js +17 -0
  107. package/dist/lib/daemon-installer.d.ts +1 -1
  108. package/dist/lib/daemon-installer.js +2 -2
  109. package/dist/lib/daemon-setup.js +13 -7
  110. package/dist/lib/daemonHandoff.d.ts +1 -1
  111. package/dist/lib/daemonHandoff.js +20 -7
  112. package/dist/lib/delegated-cli.d.ts +0 -9
  113. package/dist/lib/delegated-cli.js +149 -6
  114. package/dist/lib/{exec-oversky.d.ts → exec-runtime-binary.d.ts} +28 -4
  115. package/dist/lib/{exec-oversky.js → exec-runtime-binary.js} +138 -37
  116. package/dist/lib/git-task.d.ts +37 -0
  117. package/dist/lib/git-task.js +151 -0
  118. package/dist/lib/instruction-blocks.d.ts +29 -0
  119. package/dist/lib/instruction-blocks.js +159 -0
  120. package/dist/lib/node-adapter.js +6 -0
  121. package/dist/lib/runtime-start-verification.d.ts +49 -0
  122. package/dist/lib/runtime-start-verification.js +108 -0
  123. package/dist/lib/sky-code.d.ts +1 -1
  124. package/dist/lib/sky-code.js +1 -1
  125. package/dist/lib/task-execution.d.ts +18 -2
  126. package/dist/lib/task-execution.js +19 -14
  127. package/dist/lib/task-transcript.js +1 -1
  128. package/dist/lib/tasks.d.ts +50 -0
  129. package/dist/lib/tasks.js +66 -1
  130. package/dist/lib/usage-discovery.js +1 -1
  131. package/dist/lib/web-url.d.ts +16 -0
  132. package/dist/lib/web-url.js +25 -0
  133. package/dist/node_modules/@skrr-ai/data-provider/index.js +4075 -3905
  134. package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
  135. package/oclif.manifest.json +12364 -10488
  136. package/package.json +4 -1
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasFlag = hasFlag;
4
4
  exports.bindToCliSession = bindToCliSession;
5
5
  const config_1 = require("./config");
6
+ const exec_runtime_binary_1 = require("./exec-runtime-binary");
6
7
  const keychain_1 = require("./keychain");
7
8
  /**
8
9
  * Defaults for the flags that decide WHICH deployment and WHICH profile a
@@ -35,10 +36,9 @@ function hasFlag(argv, name, alias) {
35
36
  });
36
37
  }
37
38
  /**
38
- * Append `--server` / `--profile` describing the CLI's own session, for any
39
- * the caller did not pass. An explicit flag always wins this only fills a
40
- * silence, so `skrr daemon install --env prod` still installs against prod
41
- * while the CLI sits on dev.
39
+ * Fill `--server` / `--profile` from the CLI's own session when the caller did
40
+ * not pass them. The runtime's profile is global, so normalize it before the
41
+ * subcommand even when the caller supplied it after one.
42
42
  */
43
43
  function bindToCliSession(argv) {
44
44
  const extra = [];
@@ -51,13 +51,14 @@ function bindToCliSession(argv) {
51
51
  extra.push('--server', baseURL);
52
52
  }
53
53
  if (!hasFlag(argv, '--profile')) {
54
- // The CLI's own profile, resolved the same way `BaseCommand` resolves it.
55
- // These commands extend `Command`, so `init()` never ran and the module
56
- // state `getActiveProfile()` reads was never set asking it here would
57
- // report `default` no matter what the user typed.
58
- const profile = (0, keychain_1.resolveProfileFromArgv)(argv) ?? process.env.OVERSKY_PROFILE ?? null;
54
+ // Direct daemon wrappers extend Command, so their caller-supplied argv is
55
+ // authoritative. Login's automatic setup has no forwarded argv because it
56
+ // is already inside a BaseCommand; fall back to that process's resolved
57
+ // active profile so it cannot silently install the default service after
58
+ // `skrr login --profile <name>`.
59
+ const profile = (0, keychain_1.resolveProfileFromArgv)(argv) ?? process.env.OVERSKY_PROFILE ?? (0, keychain_1.getActiveProfile)() ?? null;
59
60
  if (profile && profile !== keychain_1.DEFAULT_PROFILE)
60
61
  extra.push('--profile', profile);
61
62
  }
62
- return [...argv, ...extra];
63
+ return (0, exec_runtime_binary_1.normalizeRuntimeGlobalArgs)([...argv, ...extra]);
63
64
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolve the explicit operator switch that disables CLI-to-runtime handoff.
3
+ *
4
+ * `SKRR_*` is the current spelling, while the older `OVERSKY_*` name remains
5
+ * compatible. Returning the actual matched spelling keeps status output honest
6
+ * and makes the canonical alias win when an environment happens to carry both.
7
+ */
8
+ export declare function daemonHandoffOptOut(env: NodeJS.ProcessEnv): string | null;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.daemonHandoffOptOut = daemonHandoffOptOut;
4
+ /**
5
+ * Resolve the explicit operator switch that disables CLI-to-runtime handoff.
6
+ *
7
+ * `SKRR_*` is the current spelling, while the older `OVERSKY_*` name remains
8
+ * compatible. Returning the actual matched spelling keeps status output honest
9
+ * and makes the canonical alias win when an environment happens to carry both.
10
+ */
11
+ function daemonHandoffOptOut(env) {
12
+ if (env.SKRR_SKIP_DAEMON_HANDOFF === '1')
13
+ return 'SKRR_SKIP_DAEMON_HANDOFF';
14
+ if (env.OVERSKY_SKIP_DAEMON_HANDOFF === '1')
15
+ return 'OVERSKY_SKIP_DAEMON_HANDOFF';
16
+ return null;
17
+ }
@@ -31,7 +31,7 @@ export interface DaemonInstallOptions {
31
31
  }
32
32
  export declare function daemonFeedBase(env?: NodeJS.ProcessEnv): string;
33
33
  /**
34
- * Where the fetched binary lands. `exec-oversky.ts` already looks here, so a
34
+ * Where the fetched binary lands. `exec-runtime-binary.ts` already looks here, so a
35
35
  * daemon installed by this path is found by every `skrr daemon *` command
36
36
  * without the user touching PATH.
37
37
  */
@@ -15,7 +15,7 @@ exports.installDaemon = installDaemon;
15
15
  *
16
16
  * ## Why this exists
17
17
  *
18
- * `skrr daemon install` forwarded to `skrrd install`, and `findOverskyBinary()`
18
+ * `skrr daemon install` forwarded to `skrrd install`, and `findRuntimeBinary()`
19
19
  * refused with "install it with brew" when there was no `skrrd` to forward to.
20
20
  * So the one command whose job is to set the machine up required the machine to
21
21
  * already be set up, and onboarding's first step was a second install from a
@@ -77,7 +77,7 @@ function daemonFeedBase(env = process.env) {
77
77
  return (env[exports.DAEMON_FEED_BASE_ENV]?.trim() || exports.DEFAULT_DAEMON_FEED_BASE).replace(/\/+$/, '');
78
78
  }
79
79
  /**
80
- * Where the fetched binary lands. `exec-oversky.ts` already looks here, so a
80
+ * Where the fetched binary lands. `exec-runtime-binary.ts` already looks here, so a
81
81
  * daemon installed by this path is found by every `skrr daemon *` command
82
82
  * without the user touching PATH.
83
83
  */
@@ -33,7 +33,8 @@ exports.offerDaemonSetup = offerDaemonSetup;
33
33
  */
34
34
  const prompt_1 = require("./prompt");
35
35
  const daemon_binding_1 = require("./daemon-binding");
36
- const exec_oversky_1 = require("./exec-oversky");
36
+ const daemon_handoff_opt_out_1 = require("./daemon-handoff-opt-out");
37
+ const exec_runtime_binary_1 = require("./exec-runtime-binary");
37
38
  const daemon_installer_1 = require("./daemon-installer");
38
39
  const ssh_detect_1 = require("./ssh-detect");
39
40
  /**
@@ -46,8 +47,9 @@ async function offerDaemonSetup(opts = {}) {
46
47
  // The same switch that turns the credential handoff off. An operator who has
47
48
  // said "do not touch my daemon" has not asked a narrower question, and a
48
49
  // second variable for the same intent is a second thing to remember.
49
- if (env.OVERSKY_SKIP_DAEMON_HANDOFF === '1' || env.SKRR_SKIP_DAEMON_HANDOFF === '1') {
50
- return { status: 'skipped', detail: 'skipped by OVERSKY_SKIP_DAEMON_HANDOFF' };
50
+ const optOut = (0, daemon_handoff_opt_out_1.daemonHandoffOptOut)(env);
51
+ if (optOut) {
52
+ return { status: 'skipped', detail: `skipped by ${optOut}` };
51
53
  }
52
54
  const interactive = opts.interactive ?? !(0, ssh_detect_1.isNonInteractive)();
53
55
  if (!interactive) {
@@ -62,7 +64,11 @@ async function offerDaemonSetup(opts = {}) {
62
64
  log('');
63
65
  log(' This machine has no skrr runtime. It is what lets your agents work here —');
64
66
  log(' running commands, editing files, and driving a browser on this machine.');
65
- const yes = await confirmImpl(' Set it up now?', false);
67
+ // This creates a persistent service with broad local capabilities, so a
68
+ // bare Enter must visibly and behaviorally decline it. `confirm` names its
69
+ // second argument `defaultNo`; passing false showed `[Y/n]` and accepted an
70
+ // accidental Enter, the opposite of this onboarding promise.
71
+ const yes = await confirmImpl(' Set it up now?', true);
66
72
  if (!yes) {
67
73
  return {
68
74
  status: 'declined',
@@ -72,7 +78,7 @@ async function offerDaemonSetup(opts = {}) {
72
78
  // Fetch the signed binary only when there is none. When the binary is already
73
79
  // present and only the service is missing, this step is skipped entirely —
74
80
  // downloading over a working runtime is not what "set it up" asked for.
75
- const binaryPresent = opts.binaryPresent ?? Boolean((0, exec_oversky_1.findOverskyBinary)());
81
+ const binaryPresent = opts.binaryPresent ?? (0, exec_runtime_binary_1.isCurrentRuntimeBinary)((0, exec_runtime_binary_1.findRuntimeBinary)());
76
82
  if (!binaryPresent) {
77
83
  log(' Fetching the signed release...');
78
84
  const fetched = await (0, daemon_installer_1.installDaemon)({ env });
@@ -85,13 +91,13 @@ async function offerDaemonSetup(opts = {}) {
85
91
  // that just authenticated — which is the whole reason this runs here and not
86
92
  // at install time.
87
93
  try {
88
- const code = await (0, exec_oversky_1.execOversky)(['install', ...(0, daemon_binding_1.bindToCliSession)([])]);
94
+ const code = await (0, exec_runtime_binary_1.execRuntimeBinary)(['install', ...(0, daemon_binding_1.bindToCliSession)([])]);
89
95
  if (code !== 0) {
90
96
  return { status: 'failed', detail: `\`skrrd install\` exited ${code}` };
91
97
  }
92
98
  }
93
99
  catch (err) {
94
- if (err.message === 'oversky-not-installed') {
100
+ if (err.message === 'runtime-binary-not-installed') {
95
101
  return {
96
102
  status: 'failed',
97
103
  detail: 'the runtime vanished between fetching and installing it',
@@ -40,7 +40,7 @@ export interface DaemonHandoffOutcome {
40
40
  * The two absent cases are separated because they need different work — one
41
41
  * needs a binary fetched, the other only needs the service registered.
42
42
  */
43
- reason?: 'opted-out' | 'brokered' | 'no-binary' | 'unsupported-daemon' | 'no-service';
43
+ reason?: 'opted-out' | 'brokered' | 'no-binary' | 'legacy-binary' | 'unsupported-daemon' | 'no-service';
44
44
  }
45
45
  export declare function handOffToLocalDaemon(env?: NodeJS.ProcessEnv, opts?: {
46
46
  loginFlow?: string;
@@ -4,7 +4,8 @@ exports.handOffToLocalDaemon = handOffToLocalDaemon;
4
4
  const node_child_process_1 = require("node:child_process");
5
5
  const data_provider_1 = require("@skrr-ai/data-provider");
6
6
  const config_1 = require("./config");
7
- const exec_oversky_1 = require("./exec-oversky");
7
+ const daemon_handoff_opt_out_1 = require("./daemon-handoff-opt-out");
8
+ const exec_runtime_binary_1 = require("./exec-runtime-binary");
8
9
  const keychain_1 = require("./keychain");
9
10
  /**
10
11
  * Ceilings, not expectations. Both calls finish in milliseconds when anything is
@@ -29,13 +30,13 @@ function runOversky(binary, args, opts) {
29
30
  const { input, timeoutMs } = opts;
30
31
  return new Promise((resolve) => {
31
32
  // A Windows npm-global install ships a `.cmd` shim, which `spawn` cannot
32
- // execute without a shell — Node fires ENOENT instead. `execOversky` has
33
+ // execute without a shell — Node fires ENOENT instead. `execRuntimeBinary` has
33
34
  // handled this since it was written; this function did not, so the handoff
34
35
  // failed on EVERY Windows login and reported it as the daemon refusing the
35
36
  // bundle. Restricted to the shim case so real binaries keep the argv-array
36
37
  // exec path, which needs no quoting rules to be right.
37
38
  const isWinShim = process.platform === 'win32' && /\.(cmd|bat)$/i.test(binary);
38
- const child = (0, node_child_process_1.spawn)(binary, args, {
39
+ const child = (0, node_child_process_1.spawn)(binary, (0, exec_runtime_binary_1.normalizeRuntimeGlobalArgs)(args), {
39
40
  // stderr is CAPTURED, not discarded. Discarding it cost a debugging cycle
40
41
  // on the first real run: the daemon exited non-zero with
41
42
  // `OVERSKY_KEK_REQUIRED`, and all the user saw was "the daemon refused the
@@ -172,11 +173,12 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
172
173
  // Mirrors `OVERSKY_SKIP_DAEMON_BROKER` on the other direction. An operator
173
174
  // deliberately running a daemon against a different deployment than their CLI is
174
175
  // doing a legitimate thing, and this must not overrule it.
175
- if (env.OVERSKY_SKIP_DAEMON_HANDOFF === '1' || env.SKRR_SKIP_DAEMON_HANDOFF === '1') {
176
+ const optOut = (0, daemon_handoff_opt_out_1.daemonHandoffOptOut)(env);
177
+ if (optOut) {
176
178
  return {
177
179
  status: 'skipped',
178
180
  reason: 'opted-out',
179
- detail: 'skipped by OVERSKY_SKIP_DAEMON_HANDOFF',
181
+ detail: `skipped by ${optOut}`,
180
182
  };
181
183
  }
182
184
  // The daemon brokered this login, which means it just used its OWN credential
@@ -194,15 +196,26 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
194
196
  detail: 'the local daemon brokered this login, so it already has a working credential',
195
197
  };
196
198
  }
197
- const binary = (0, exec_oversky_1.findOverskyBinary)();
199
+ const binary = (0, exec_runtime_binary_1.findRuntimeBinary)();
198
200
  if (!binary) {
199
201
  return { status: 'skipped', reason: 'no-binary', detail: 'no local daemon installed' };
200
202
  }
203
+ // A legacy binary may remain on PATH after the product rename, but it cannot
204
+ // receive a skrr CLI handoff or reliably install the new profile-scoped
205
+ // service. Tell login to bootstrap a current signed runtime instead of
206
+ // probing the old binary and treating it as a usable local daemon.
207
+ if (!(0, exec_runtime_binary_1.isCurrentRuntimeBinary)(binary)) {
208
+ return {
209
+ status: 'skipped',
210
+ reason: 'legacy-binary',
211
+ detail: 'a legacy oversky runtime is installed; bootstrap a current skrr runtime',
212
+ };
213
+ }
201
214
  // An older daemon has no `accept-handoff`, and spawning it would fail with
202
215
  // commander's "unknown command" rather than anything a reader could act on. A
203
216
  // CLI that outruns the daemon on the machine is the normal case during a
204
217
  // staged rollout, not an error.
205
- const supported = await (0, exec_oversky_1.overskySupportsSubcommand)('accept-handoff');
218
+ const supported = await (0, exec_runtime_binary_1.runtimeBinarySupportsSubcommand)('accept-handoff');
206
219
  if (supported === false) {
207
220
  return {
208
221
  status: 'skipped',
@@ -1,12 +1,3 @@
1
- /**
2
- * Daemon-owned delegated CLI credentials for autonomous Agent sessions.
3
- *
4
- * A spawned Agent never reads the human Keychain or a refresh token. Instead
5
- * it holds a random loopback capability and asks its parent daemon for a
6
- * short-lived normal `scope=cli` access token. The daemon rotates the refresh
7
- * family, so each Sky invocation retains the full command surface for the
8
- * duration of a long-running Agent session.
9
- */
10
1
  import { type ResolvedCredential } from '@skrr-ai/auth-core';
11
2
  export declare function isDelegatedCliSession(env?: Record<string, string | undefined>): boolean;
12
3
  /** Drop the memoized credential. Exported for tests. */
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.isDelegatedCliSession = isDelegatedCliSession;
4
37
  exports.resetDelegatedCliCredentialCache = resetDelegatedCliCredentialCache;
@@ -12,6 +45,9 @@ exports.fetchDelegatedCliCredential = fetchDelegatedCliCredential;
12
45
  * family, so each Sky invocation retains the full command surface for the
13
46
  * duration of a long-running Agent session.
14
47
  */
48
+ const fs = __importStar(require("node:fs"));
49
+ const os = __importStar(require("node:os"));
50
+ const path = __importStar(require("node:path"));
15
51
  const auth_core_1 = require("@skrr-ai/auth-core");
16
52
  function isDelegatedCliSession(env = process.env) {
17
53
  return Boolean(env.OVERSKY_AUTONOMOUS_SESSION === '1' &&
@@ -40,6 +76,94 @@ let _cached = null;
40
76
  function resetDelegatedCliCredentialCache() {
41
77
  _cached = null;
42
78
  }
79
+ /**
80
+ * Walk `err.cause` / `err.errors[]` looking for a `code: 'ECONNREFUSED'`.
81
+ * Node's `fetch` throws a `TypeError('fetch failed')` whose `cause` is either
82
+ * a plain `Error` with `code` set, or an `AggregateError` whose `errors[]`
83
+ * carry it (dual-stack retries). Neither shape is visible at the top level.
84
+ */
85
+ function isConnectionRefusedError(err) {
86
+ const seen = new Set();
87
+ const stack = [err];
88
+ while (stack.length) {
89
+ const cur = stack.pop();
90
+ if (!cur || typeof cur !== 'object' || seen.has(cur))
91
+ continue;
92
+ seen.add(cur);
93
+ const anyCur = cur;
94
+ if (anyCur.code === 'ECONNREFUSED')
95
+ return true;
96
+ if (anyCur.cause !== undefined)
97
+ stack.push(anyCur.cause);
98
+ if (Array.isArray(anyCur.errors))
99
+ for (const e of anyCur.errors)
100
+ stack.push(e);
101
+ }
102
+ return false;
103
+ }
104
+ /**
105
+ * Best-effort probe of the daemon's bootstrap file — the CLI's
106
+ * `daemonBroker.ts` writes it and can auto-broker off the fresh port.
107
+ * Returned only for the actionable-error diagnostic; failures are silent
108
+ * because this is a display hint, not a decision.
109
+ *
110
+ * Kept inline rather than importing from `daemonBroker.ts` so this module
111
+ * stays small and free of the auth-storage / keychain dependency chain
112
+ * that a lazily-executed broker call would drag in on every `skrr` startup.
113
+ */
114
+ function readLiveDaemonPort() {
115
+ const candidates = [];
116
+ if (process.platform === 'darwin') {
117
+ candidates.push(path.join(os.homedir(), 'Library', 'Application Support', 'skrr', 'daemon-island.default.json'));
118
+ }
119
+ else {
120
+ candidates.push(path.join(os.homedir(), '.skrr', 'profiles', 'default', 'daemon-island.json'), path.join(os.homedir(), '.skrr', 'daemon-island.json'));
121
+ }
122
+ for (const p of candidates) {
123
+ try {
124
+ if (!fs.existsSync(p))
125
+ continue;
126
+ const parsed = JSON.parse(fs.readFileSync(p, 'utf8'));
127
+ if (typeof parsed.port !== 'number' || !Number.isInteger(parsed.port))
128
+ continue;
129
+ if (typeof parsed.pid === 'number' && parsed.pid > 0) {
130
+ try {
131
+ process.kill(parsed.pid, 0);
132
+ }
133
+ catch (killErr) {
134
+ if (killErr.code === 'ESRCH')
135
+ continue;
136
+ }
137
+ }
138
+ return parsed.port;
139
+ }
140
+ catch {
141
+ // Ignore parse / IO errors — the caller has a fallback message.
142
+ }
143
+ }
144
+ return null;
145
+ }
146
+ /**
147
+ * When the broker port refuses the connection, the daemon that issued the
148
+ * capability is gone (typical trigger: a self-upgrade restart). The successor
149
+ * daemon has no memory of this capability — it lived in the dead process's
150
+ * heap — so nothing on this side can revive it. Produce an error text that
151
+ * names the stale env vars and gives the exact recovery an operator can run
152
+ * without reading source. See OSK-6861.
153
+ */
154
+ function composeStaleBrokerMessage(brokerUrl) {
155
+ const livePort = readLiveDaemonPort();
156
+ const liveHint = typeof livePort === 'number'
157
+ ? ` The live daemon is bound to port ${livePort} (from daemon-island.json), which does not match the stale URL above.`
158
+ : '';
159
+ return (`delegated CLI broker at ${brokerUrl} refused connection. ` +
160
+ `The parent daemon that issued this capability is gone (typical cause: a self-upgrade restart), ` +
161
+ `and the capability lived in that process's memory — the successor daemon cannot honour it.` +
162
+ liveHint +
163
+ ` To recover in this shell, run:\n` +
164
+ ` unset OVERSKY_DELEGATED_CLI_BROKER_URL OVERSKY_DELEGATED_CLI_CAPABILITY OVERSKY_AUTONOMOUS_SESSION\n` +
165
+ `Subsequent \`skrr\` calls will then auto-broker a fresh credential via the live daemon.`);
166
+ }
43
167
  /** Fetch a full-permission CLI access token from the local daemon. */
44
168
  async function fetchDelegatedCliCredential(env = process.env, options = {}) {
45
169
  if (!isDelegatedCliSession(env))
@@ -55,12 +179,31 @@ async function fetchDelegatedCliCredential(env = process.env, options = {}) {
55
179
  const controller = new AbortController();
56
180
  const timeout = setTimeout(() => controller.abort(), 5_000);
57
181
  try {
58
- const res = await fetch(brokerUrl, {
59
- method: 'POST',
60
- headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
61
- body: JSON.stringify({ capability, sessionId, forceRefresh: options.forceRefresh === true }),
62
- signal: controller.signal,
63
- });
182
+ let res;
183
+ try {
184
+ res = await fetch(brokerUrl, {
185
+ method: 'POST',
186
+ headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
187
+ body: JSON.stringify({
188
+ capability,
189
+ sessionId,
190
+ forceRefresh: options.forceRefresh === true,
191
+ }),
192
+ signal: controller.signal,
193
+ });
194
+ }
195
+ catch (err) {
196
+ // A connection-refused throw here is not the same failure mode as a 5xx
197
+ // from a live daemon: it means the whole loopback listener is gone, so
198
+ // the capability is unrecoverable rather than transiently unavailable.
199
+ // Rewrite the message so `base-command` surfaces recovery text instead
200
+ // of a bare `fetch failed`. Any other network error (DNS, TLS,
201
+ // AbortError, etc.) propagates unchanged.
202
+ if (isConnectionRefusedError(err)) {
203
+ throw new Error(composeStaleBrokerMessage(brokerUrl));
204
+ }
205
+ throw err;
206
+ }
64
207
  if (!res.ok) {
65
208
  // A DELIBERATE decline is not a broker failure — WL-5 Step 1.
66
209
  //
@@ -29,9 +29,20 @@ export declare const RUNTIME_BINARY_NAMES: readonly ["skrrd", "oversky"];
29
29
  */
30
30
  export declare function forwardedFlagsNote(verb: string, opts?: {
31
31
  binds?: boolean;
32
+ bootstrapsRuntime?: boolean;
32
33
  }): string;
33
- /** Resolve the absolute path of `oversky` if it exists, else return null. */
34
- export declare function findOverskyBinary(): string | null;
34
+ /** Resolve the local runtime binary `skrrd`, or the legacy `oversky` still on older PATHs. */
35
+ export declare function findRuntimeBinary(): string | null;
36
+ /** Whether a resolved path names the current runtime rather than legacy oversky. */
37
+ export declare function isCurrentRuntimeBinary(binary: string | null): boolean;
38
+ /**
39
+ * Commander reads runtime global options before the subcommand. The CLI
40
+ * wrappers naturally receive pass-through flags after a verb (`install
41
+ * --profile work`), which otherwise silently resolves the runtime profile as
42
+ * default. Move a well-formed profile flag ahead of the verb without changing
43
+ * the order of any command-specific flags or `--` payload.
44
+ */
45
+ export declare function normalizeRuntimeGlobalArgs(args: readonly string[]): string[];
35
46
  /**
36
47
  * Pretty hint shown when the runtime isn't installed. Kept short — points
37
48
  * users at the canonical install paths rather than enumerating them.
@@ -60,7 +71,20 @@ export declare function notInstalledMessage(): string;
60
71
  * preserving "exit code = the daemon's exit code" semantics that scripts
61
72
  * may depend on.
62
73
  */
63
- export declare function execOversky(args: string[]): Promise<number>;
74
+ export declare function execRuntimeBinary(args: string[]): Promise<number>;
75
+ /** Output from a short-lived runtime probe such as `skrrd status --json`. */
76
+ export type RuntimeBinaryOutput = {
77
+ code: number;
78
+ stdout: string;
79
+ stderr: string;
80
+ };
81
+ /**
82
+ * Invoke the installed runtime without inheriting its streams. The regular
83
+ * lifecycle command still owns the terminal; this is only for the wrapper's
84
+ * post-condition probes, where output is evidence rather than user-facing
85
+ * command output.
86
+ */
87
+ export declare function execRuntimeBinaryCapture(args: string[]): Promise<RuntimeBinaryOutput>;
64
88
  /**
65
89
  * Check an installed daemon's top-level help before forwarding a command that
66
90
  * was added after older daemon releases shipped. A false result is useful to
@@ -70,4 +94,4 @@ export declare function execOversky(args: string[]): Promise<number>;
70
94
  * This invokes only `oversky --help`: it never starts, stops, configures, or
71
95
  * otherwise mutates the local daemon.
72
96
  */
73
- export declare function overskySupportsSubcommand(subcommand: string): Promise<boolean | null>;
97
+ export declare function runtimeBinarySupportsSubcommand(subcommand: string): Promise<boolean | null>;