@skrr-ai/cli 0.1.56 → 0.1.58

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 (36) hide show
  1. package/dist/base-command.d.ts +11 -0
  2. package/dist/base-command.js +80 -6
  3. package/dist/commands/agents/chat.js +5 -3
  4. package/dist/commands/agents/create.js +7 -0
  5. package/dist/commands/agents/show.js +13 -2
  6. package/dist/commands/agents/update.js +7 -0
  7. package/dist/commands/harnesses/ping.d.ts +2 -0
  8. package/dist/commands/harnesses/ping.js +10 -1
  9. package/dist/commands/login.js +20 -1
  10. package/dist/commands/logout.js +8 -0
  11. package/dist/commands/pair.js +1 -1
  12. package/dist/commands/tasks/move.js +11 -0
  13. package/dist/lib/agent-model-check.d.ts +19 -0
  14. package/dist/lib/agent-model-check.js +68 -0
  15. package/dist/lib/agentic-stream.d.ts +24 -0
  16. package/dist/lib/agentic-stream.js +117 -5
  17. package/dist/lib/auth-core-init.d.ts +0 -9
  18. package/dist/lib/auth-core-init.js +9 -0
  19. package/dist/lib/auth-storage.d.ts +42 -0
  20. package/dist/lib/auth-storage.js +75 -7
  21. package/dist/lib/commitments.js +4 -0
  22. package/dist/lib/config.d.ts +4 -0
  23. package/dist/lib/config.js +4 -2
  24. package/dist/lib/daemonBroker.d.ts +23 -1
  25. package/dist/lib/daemonBroker.js +66 -17
  26. package/dist/lib/daemonHandoff.d.ts +1 -1
  27. package/dist/lib/daemonHandoff.js +39 -1
  28. package/dist/lib/internal-id.d.ts +28 -0
  29. package/dist/lib/internal-id.js +41 -0
  30. package/dist/lib/login.js +2 -2
  31. package/dist/lib/oauthLogin.js +3 -1
  32. package/dist/lib/workflow-state-hint.d.ts +10 -0
  33. package/dist/lib/workflow-state-hint.js +27 -0
  34. package/dist/node_modules/@skrr-ai/data-provider/index.js +3292 -3281
  35. package/oclif.manifest.json +29800 -29800
  36. package/package.json +1 -1
@@ -5,6 +5,7 @@ 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
7
  const daemon_handoff_opt_out_1 = require("./daemon-handoff-opt-out");
8
+ const dedicated_service_1 = require("./dedicated-service");
8
9
  const exec_runtime_binary_1 = require("./exec-runtime-binary");
9
10
  const keychain_1 = require("./keychain");
10
11
  /**
@@ -196,6 +197,41 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
196
197
  detail: 'the local daemon brokered this login, so it already has a working credential',
197
198
  };
198
199
  }
200
+ // A Dedicated Runtime guest's daemon belongs to the platform: the image
201
+ // installs it, the platform signs it in, and it runs as a uid the workload
202
+ // cannot touch. A person's login is theirs alone and is never handed to it,
203
+ // and there is nothing for them to install. Without this the workload found
204
+ // no daemon it could use and login ended by telling them to run
205
+ // `skrr daemon install` on a machine where that is wrong (OSK-12296).
206
+ //
207
+ // Detected the way the rest of the CLI detects a guest — the workload uid
208
+ // stamp, or the guest markers the image and daemon own, among them the
209
+ // hand-off descriptor directory under /run/skrr-dedicated-runtime.
210
+ if ((0, dedicated_service_1.runningOnDedicatedRuntimeGuest)(env)) {
211
+ return {
212
+ status: 'skipped',
213
+ reason: 'platform-managed',
214
+ detail: "this machine's daemon is managed by the platform",
215
+ };
216
+ }
217
+ // A relocated config root (`SKRR_CONFIG_DIR`) is a second sign-in on this
218
+ // machine, not the machine's sign-in. The installed daemon service carries no
219
+ // config-root override, so it reads the DEFAULT root — its credential, its
220
+ // deployment, its account belong there. Offering this root's login to it would
221
+ // re-point the machine at whatever this root signed in as, and when the server
222
+ // refused the offer the CLI used to report a healthy, signed-in daemon as
223
+ // "not signed in" and send the user to re-login it (OSK-12189).
224
+ //
225
+ // Decided on the root alone, before anything is spawned or minted: nothing
226
+ // about this machine's daemon should change because a second root signed in.
227
+ if (!(0, config_1.isDefaultConfigRoot)(env)) {
228
+ return {
229
+ status: 'skipped',
230
+ reason: 'foreign-root',
231
+ detail: `this login is in the config root ${(0, config_1.configRoot)(env)}; the local daemon ` +
232
+ `belongs to ${(0, config_1.defaultConfigRoot)()} and keeps its own sign-in`,
233
+ };
234
+ }
199
235
  const binary = (0, exec_runtime_binary_1.findRuntimeBinary)();
200
236
  if (!binary) {
201
237
  return { status: 'skipped', reason: 'no-binary', detail: 'no local daemon installed' };
@@ -264,7 +300,9 @@ async function handOffToLocalDaemon(env = process.env, opts = {}) {
264
300
  }));
265
301
  }
266
302
  catch (err) {
267
- return { status: 'failed', detail: err.message };
303
+ // Refused BEFORE the daemon was touched: it still holds exactly the
304
+ // credential it had, so this is "not handed this login", never "signed out".
305
+ return { status: 'failed', reason: 'mint-refused', detail: err.message };
268
306
  }
269
307
  const payload = JSON.stringify({
270
308
  refreshToken: bundle.refreshToken,
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The internal Mongo `_id` handed back where a command wants the `id`.
3
+ *
4
+ * `--json` prints every row's `_id` FIRST, so it is the value a person or a
5
+ * script copies. Spaces and Tasks are addressed by `id` (a UUID) everywhere in
6
+ * the API, and no resolver accepts both forms, so `spaces show <_id>`,
7
+ * `tasks show <_id>` and `tasks create --space <_id>` answered with not-found
8
+ * or a raw HTTP 404 — true, and no help: nothing said which field to use
9
+ * (OSK-12205).
10
+ *
11
+ * Only the refusal lives here. Finding the `id` that goes with an `_id` needs
12
+ * a listing, so the caller does that (it holds the API) and passes the answer
13
+ * in when it has one.
14
+ */
15
+ /** A 24-hex Mongo ObjectId, the shape of `_id`. */
16
+ export declare function looksLikeInternalObjectId(value: string): boolean;
17
+ /**
18
+ * The sentence for an `_id` passed where the `id` belongs.
19
+ *
20
+ * `canonicalId` is the row's `id` when the caller could find it — then the
21
+ * remedy is the exact value to use. Without it the remedy names the field.
22
+ */
23
+ export declare function describeInternalIdMisuse(opts: {
24
+ value: string;
25
+ noun: 'space' | 'task';
26
+ canonicalId?: string | null;
27
+ bin: string;
28
+ }): string;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * The internal Mongo `_id` handed back where a command wants the `id`.
4
+ *
5
+ * `--json` prints every row's `_id` FIRST, so it is the value a person or a
6
+ * script copies. Spaces and Tasks are addressed by `id` (a UUID) everywhere in
7
+ * the API, and no resolver accepts both forms, so `spaces show <_id>`,
8
+ * `tasks show <_id>` and `tasks create --space <_id>` answered with not-found
9
+ * or a raw HTTP 404 — true, and no help: nothing said which field to use
10
+ * (OSK-12205).
11
+ *
12
+ * Only the refusal lives here. Finding the `id` that goes with an `_id` needs
13
+ * a listing, so the caller does that (it holds the API) and passes the answer
14
+ * in when it has one.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.looksLikeInternalObjectId = looksLikeInternalObjectId;
18
+ exports.describeInternalIdMisuse = describeInternalIdMisuse;
19
+ const OBJECT_ID_RE = /^[0-9a-fA-F]{24}$/;
20
+ /** A 24-hex Mongo ObjectId, the shape of `_id`. */
21
+ function looksLikeInternalObjectId(value) {
22
+ return OBJECT_ID_RE.test(value.trim());
23
+ }
24
+ /**
25
+ * The sentence for an `_id` passed where the `id` belongs.
26
+ *
27
+ * `canonicalId` is the row's `id` when the caller could find it — then the
28
+ * remedy is the exact value to use. Without it the remedy names the field.
29
+ */
30
+ function describeInternalIdMisuse(opts) {
31
+ const { value, noun, canonicalId, bin } = opts;
32
+ const head = `"${value.trim()}" is the internal _id of a ${noun}; commands take its \`id\``;
33
+ if (canonicalId) {
34
+ return `${head}. Use \`id\` ${canonicalId}.`;
35
+ }
36
+ const alternatives = noun === 'task'
37
+ ? 'the `id` field (a UUID) or the `identifier` (OSK-123) from the same --json output'
38
+ : 'the `id` field (a UUID) or the `identifier` (OSK-S-12) from the same --json output';
39
+ return (`${head}.\n` +
40
+ ` → use ${alternatives}; \`${bin} ${noun === 'task' ? 'tasks' : 'spaces'} list --json\` prints both.`);
41
+ }
package/dist/lib/login.js CHANGED
@@ -332,7 +332,7 @@ async function cliLoginWithRefreshToken(opts) {
332
332
  ...(pair.accessExpiresAt !== undefined ? { expiresAt: pair.accessExpiresAt } : {}),
333
333
  refreshToken: pair.refreshToken,
334
334
  ...(pair.refreshExpiresAt !== undefined ? { refreshExpiresAt: pair.refreshExpiresAt } : {}),
335
- }, { serverOrigin: serverUrl, clearReauth: true });
335
+ }, { serverOrigin: serverUrl, clearReauth: true, provenance: 'user_login' });
336
336
  return {
337
337
  token: accessToken,
338
338
  refreshToken: pair.refreshToken,
@@ -490,7 +490,7 @@ async function runDeviceCode(serverUrl, cliId, reason, ssh, errorMessage) {
490
490
  : {}),
491
491
  }
492
492
  : {}),
493
- }, { serverOrigin: serverUrl, clearReauth: true });
493
+ }, { serverOrigin: serverUrl, clearReauth: true, provenance: 'user_login' });
494
494
  console.log(' ✓ Authorized.');
495
495
  return {
496
496
  token: approved.token,
@@ -366,7 +366,9 @@ async function runOAuthLogin(opts) {
366
366
  // server URL — daemonBroker.ts:543, login.ts:322, refresh.ts:282 —
367
367
  // so this was the lone outlier, and it only bites a deployment
368
368
  // whose web and API origins differ.
369
- { serverOrigin: requestedServerUrl, clearReauth: true });
369
+ // A person signed in on purpose: a brokered Dedicated guest must
370
+ // keep this family rather than retire it as pre-broker (OSK-12293).
371
+ { serverOrigin: requestedServerUrl, clearReauth: true, provenance: 'user_login' });
370
372
  console.log(' ✓ Login successful! Token saved.');
371
373
  finish({
372
374
  ok: true,
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The remedy for `tasks move --status <unknown>` (OSK-12205).
3
+ *
4
+ * Workflow states are Space-local, so the CLI cannot declare them as flag
5
+ * options and cannot list them ahead of the refusal. The server now names the
6
+ * accepted states in its message (and in `details.validStates`); this adds the
7
+ * command that lists them with their types, and quotes the states itself when
8
+ * a server sent them only in `details`.
9
+ */
10
+ export declare function describeUnknownWorkflowState(body: Record<string, unknown> | undefined, bin: string): string | null;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeUnknownWorkflowState = describeUnknownWorkflowState;
4
+ /**
5
+ * The remedy for `tasks move --status <unknown>` (OSK-12205).
6
+ *
7
+ * Workflow states are Space-local, so the CLI cannot declare them as flag
8
+ * options and cannot list them ahead of the refusal. The server now names the
9
+ * accepted states in its message (and in `details.validStates`); this adds the
10
+ * command that lists them with their types, and quotes the states itself when
11
+ * a server sent them only in `details`.
12
+ */
13
+ function describeUnknownWorkflowState(body, bin) {
14
+ if (!body || body.code !== 'WORKFLOW_STATE_UNKNOWN')
15
+ return null;
16
+ const details = (body.details ?? {});
17
+ const valid = Array.isArray(details.validStates)
18
+ ? details.validStates.filter((v) => typeof v === 'string')
19
+ : [];
20
+ let message = typeof body.error === 'string' && body.error ? body.error : 'Unknown workflow state';
21
+ if (valid.length > 0 && !message.includes(valid[0])) {
22
+ message += `. This Space accepts: ${valid.join(', ')}.`;
23
+ }
24
+ return (`${message}\n` +
25
+ ` → \`${bin} spaces states list <space-id>\` lists this Space's states with their types; ` +
26
+ '`--status` takes a state id or its display name.');
27
+ }