@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
@@ -369,44 +369,20 @@ 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
+ export declare function describeForbidden(bodyMessage?: string | null, method?: string | null): string;
372
373
  /**
373
- * Whether an automated retry of the IDENTICAL request could plausibly succeed.
374
+ * True when a credential is unmistakably machine/daemon authority rather
375
+ * than a human CLI session. This is a diagnostic guard only, never an
376
+ * authorization decision: the server remains authoritative for every token.
374
377
  *
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.
378
+ * Opaque daemon access tokens have a stable public prefix. Legacy daemon JWTs
379
+ * expose `scope: "daemon"`; decoding the unsigned payload lets the CLI give a
380
+ * repair instruction instead of calling a predictable 403 a transient edge
381
+ * failure. Malformed and unknown token shapes intentionally return false so a
382
+ * generic authentication failure remains honest.
409
383
  */
410
- export declare function describeForbidden(bodyMessage?: string | null): string;
384
+ export declare function isDaemonScopedCredential(token?: string | null): boolean;
385
+ /** The one repair for a daemon token passed to a human CLI command. */
386
+ export declare function describeDaemonScopedCredential(bin: string): string;
411
387
  export declare function isRetryableFailure(status: number | undefined, body: Record<string, unknown> | null): boolean;
412
388
  export { Flags };
@@ -8,6 +8,8 @@ exports.describeHarnessUnavailable = describeHarnessUnavailable;
8
8
  exports.describeResourceNotFound = describeResourceNotFound;
9
9
  exports.describeAssigneeNotInSpace = describeAssigneeNotInSpace;
10
10
  exports.describeForbidden = describeForbidden;
11
+ exports.isDaemonScopedCredential = isDaemonScopedCredential;
12
+ exports.describeDaemonScopedCredential = describeDaemonScopedCredential;
11
13
  exports.isRetryableFailure = isRetryableFailure;
12
14
  const core_1 = require("@oclif/core");
13
15
  Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { return core_1.Flags; } });
@@ -576,6 +578,14 @@ class BaseCommand extends core_1.Command {
576
578
  retryable: false,
577
579
  });
578
580
  }
581
+ if (isDaemonScopedCredential(this.resolvedCredential.token)) {
582
+ this.failWithCliError({
583
+ message: describeDaemonScopedCredential(this.config.bin),
584
+ code: 'DAEMON_SCOPE_CREDENTIAL',
585
+ exit: 2,
586
+ retryable: false,
587
+ });
588
+ }
579
589
  }
580
590
  /**
581
591
  * Resolve the authenticated user's id via `GET /api/user`.
@@ -802,7 +812,22 @@ class BaseCommand extends core_1.Command {
802
812
  const body = parseErrorBody(e.body);
803
813
  const bodyCode = stringProp(body, 'code') || stringProp(body, 'errorType');
804
814
  const bodyMessage = stringProp(body, 'message') || stringProp(body, 'error');
805
- if (bodyCode === 'AGENT_RUNTIME_UNAVAILABLE') {
815
+ // `requireAuth()` catches this before requests for normal commands, but
816
+ // keep the API-error check too: a handful of commands make a direct
817
+ // request and a supplied `--token` can bypass their normal preflight.
818
+ // A daemon credential reaching a human endpoint is deterministic, not
819
+ // an edge outage; retrying only repeats the same 401/403.
820
+ if ((e.status === 401 || e.status === 403) &&
821
+ isDaemonScopedCredential(this.resolvedCredential?.token)) {
822
+ this.failWithCliError({
823
+ message: say(describeDaemonScopedCredential(this.config.bin)),
824
+ code: 'DAEMON_SCOPE_CREDENTIAL',
825
+ status: e.status,
826
+ exit: 2,
827
+ retryable: false,
828
+ });
829
+ }
830
+ else if (bodyCode === 'AGENT_RUNTIME_UNAVAILABLE') {
806
831
  // A specific agent's runtime is offline — not a platform outage, even
807
832
  // though the server returns 503. Intercept before the 503→outage
808
833
  // heuristic so we neither claim a service outage nor promise a
@@ -870,12 +895,17 @@ class BaseCommand extends core_1.Command {
870
895
  // named a cause and the cause was fiction. The 404 branch below has
871
896
  // always done the honest thing — `bodyMessage || 'Not found.'`, which
872
897
  // claims nothing.
898
+ // An API-authored 403 (has a body) is a terminal refusal — retrying
899
+ // the same request will fail the same way. An edge-authored 403 (no
900
+ // body) is commonly transient (OSK-6765), so the JSON envelope's
901
+ // `retryable` should match what the human line already says: retry.
902
+ const edgeRefusal = !bodyMessage;
873
903
  this.failWithCliError({
874
- message: say(describeForbidden(bodyMessage)),
904
+ message: say(describeForbidden(bodyMessage, e.method)),
875
905
  code: bodyCode || 'FORBIDDEN',
876
906
  status: e.status,
877
907
  exit: 3,
878
- retryable: false,
908
+ retryable: edgeRefusal,
879
909
  });
880
910
  }
881
911
  else if (e.status === 404) {
@@ -1353,17 +1383,72 @@ const TERMINAL_ERROR_CODES = new Set(['task_output_required', 'task_output_not_a
1353
1383
  * created a minute earlier, as an ADMIN who owned the space, and finding the
1354
1384
  * real cause took a line-by-line bisect of the description body.
1355
1385
  *
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.
1386
+ * OSK-6765 refined this again. The original replacement led with the body
1387
+ * explanation ("try again with less of the request body") as a diagnosis, and
1388
+ * it was wrong two ways for `skrr agents show <id>`: (1) that command is a GET
1389
+ * and has no body to trim, so the advice was impossible to follow; (2) the
1390
+ * failure was TRANSIENT — the same command succeeded 5/5 on retry with nothing
1391
+ * changed — and the one action that actually fixed it (retry) was the one thing
1392
+ * the message did not mention. A user hunting for the trigger burned six probe
1393
+ * agents isolating candidate strings in their own data before noticing the
1394
+ * request had no body at all.
1395
+ *
1396
+ * So: LEAD with retry (edge rejections are commonly transient). Then, ONLY on
1397
+ * a method that actually carries a body, offer the body-content explanation as
1398
+ * a possibility, not as the diagnosis. The 404 branch has always done the
1399
+ * honest thing (`bodyMessage || 'Not found.'`, which claims nothing).
1359
1400
  */
1360
- function describeForbidden(bodyMessage) {
1401
+ function methodCarriesRequestBody(method) {
1402
+ if (!method)
1403
+ return false;
1404
+ const m = method.toUpperCase();
1405
+ return m === 'POST' || m === 'PUT' || m === 'PATCH';
1406
+ }
1407
+ function describeForbidden(bodyMessage, method) {
1361
1408
  if (bodyMessage)
1362
1409
  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).');
1410
+ const lead = 'Forbidden: the server refused this request and gave no reason. This is often a ' +
1411
+ 'transient edge rule rather than a permission you lack — retry once. If it keeps ' +
1412
+ 'failing, check that you can read this resource elsewhere';
1413
+ if (methodCarriesRequestBody(method)) {
1414
+ return (`${lead}, and consider that a path or token-shaped string in the request body can ` +
1415
+ 'be enough to trigger an edge rule; try again with less.');
1416
+ }
1417
+ return `${lead}.`;
1418
+ }
1419
+ /**
1420
+ * True when a credential is unmistakably machine/daemon authority rather
1421
+ * than a human CLI session. This is a diagnostic guard only, never an
1422
+ * authorization decision: the server remains authoritative for every token.
1423
+ *
1424
+ * Opaque daemon access tokens have a stable public prefix. Legacy daemon JWTs
1425
+ * expose `scope: "daemon"`; decoding the unsigned payload lets the CLI give a
1426
+ * repair instruction instead of calling a predictable 403 a transient edge
1427
+ * failure. Malformed and unknown token shapes intentionally return false so a
1428
+ * generic authentication failure remains honest.
1429
+ */
1430
+ function isDaemonScopedCredential(token) {
1431
+ if (typeof token !== 'string' || token.length === 0)
1432
+ return false;
1433
+ if (token.startsWith('osk_dmn_'))
1434
+ return true;
1435
+ const payload = token.split('.')[1];
1436
+ if (!payload)
1437
+ return false;
1438
+ try {
1439
+ const decoded = JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
1440
+ return (typeof decoded === 'object' &&
1441
+ decoded !== null &&
1442
+ decoded.scope === 'daemon');
1443
+ }
1444
+ catch {
1445
+ return false;
1446
+ }
1447
+ }
1448
+ /** The one repair for a daemon token passed to a human CLI command. */
1449
+ function describeDaemonScopedCredential(bin) {
1450
+ return ('This command received a daemon-scoped credential, which cannot access user API commands. ' +
1451
+ `Run \`${bin} login\` to create a CLI credential. For the local runtime itself, use \`${bin} daemon login\`.`);
1367
1452
  }
1368
1453
  function isRetryableFailure(status, body) {
1369
1454
  const declared = body?.retryable;
@@ -55,6 +55,7 @@ export default class AgentsCreate extends BaseCommand {
55
55
  'tone-mode': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
56
56
  'tone-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
57
57
  'tone-notes': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
58
+ 'max-concurrent-task-executions': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
58
59
  skills: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
59
60
  'agent-actions': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
60
61
  'tool-policy': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -86,7 +86,9 @@ class AgentsCreate extends base_command_1.BaseCommand {
86
86
  model: core_1.Flags.string({
87
87
  description: 'Model identifier (required unless set via --from-json)',
88
88
  }),
89
- instructions: core_1.Flags.string({ description: 'System instructions / prompt' }),
89
+ instructions: core_1.Flags.string({
90
+ description: 'Initial raw custom instructions (creates one inline block; use `agents instructions` to compose reusable blocks later)',
91
+ }),
90
92
  category: core_1.Flags.string({ description: 'Agent category' }),
91
93
  target: core_1.Flags.string({
92
94
  description: 'Required execution target. Use a Harness id, Hosted Machine session, or Agent Worker. Use hosted-machine, sbs_..., agent-worker, or a connected Harness id.',
@@ -116,6 +118,9 @@ class AgentsCreate extends base_command_1.BaseCommand {
116
118
  'tone-mode': core_1.Flags.string({ description: 'Tone mode' }),
117
119
  'tone-id': core_1.Flags.string({ description: 'Tone ID' }),
118
120
  'tone-notes': core_1.Flags.string({ description: 'Per-agent tone notes' }),
121
+ 'max-concurrent-task-executions': core_1.Flags.integer({
122
+ description: 'Max Task executions this agent may run at once ACROSS every space (0 = unlimited)',
123
+ }),
119
124
  skills: core_1.Flags.string({ description: 'Skills JSON array' }),
120
125
  'agent-actions': core_1.Flags.string({ description: 'Embedded actions JSON array' }),
121
126
  'tool-policy': core_1.Flags.string({ description: 'Tool policy JSON object' }),
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class AgentsInstructionsAdd extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ inline: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ block: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ version: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ binding: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ title: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ body: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
17
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
18
+ disabled: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
19
+ };
20
+ run(): Promise<void>;
21
+ }
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const base_command_1 = require("../../../base-command");
6
+ const agent_resolver_1 = require("../../../lib/agent-resolver");
7
+ const agent_instructions_1 = require("../../../lib/agent-instructions");
8
+ const instruction_blocks_1 = require("../../../lib/instruction-blocks");
9
+ const instruction_input_1 = require("../../../lib/instruction-input");
10
+ class AgentsInstructionsAdd extends base_command_1.BaseCommand {
11
+ static description = 'Add an inline instruction or a version-pinned library block to an Agent';
12
+ static examples = [
13
+ '<%= config.bin %> agents instructions add <agent-id> --inline --title "Working preferences" --body "Lead with the answer."',
14
+ '<%= config.bin %> agents instructions add <agent-id> --block block_official_github_pr_review --binding repository=acme/api',
15
+ '<%= config.bin %> agents instructions add <agent-id> --block block_… --version 2 --disabled',
16
+ ];
17
+ static args = {
18
+ id: core_1.Args.string({
19
+ description: 'Agent ID. Omit to use OVERSKY_SESSION_AGENT_ID.',
20
+ required: false,
21
+ ignoreStdin: true,
22
+ }),
23
+ };
24
+ static flags = {
25
+ json: core_1.Flags.boolean({ description: 'Output the updated Agent as JSON' }),
26
+ agent: core_1.Flags.string({ description: 'Agent ID (alias for the positional argument)' }),
27
+ inline: core_1.Flags.boolean({ description: 'Add a new inline block owned by this Agent' }),
28
+ block: core_1.Flags.string({ description: 'Library or official block ID to attach' }),
29
+ version: core_1.Flags.integer({
30
+ description: 'Version to pin (defaults to the block’s current version)',
31
+ }),
32
+ binding: core_1.Flags.string({
33
+ description: 'Parameter binding as key=value (repeatable)',
34
+ multiple: true,
35
+ }),
36
+ title: core_1.Flags.string({ description: 'Inline block title (required with --inline)' }),
37
+ body: core_1.Flags.string({ description: 'Inline instruction text' }),
38
+ file: core_1.Flags.string({ description: 'Read inline instruction text from a file, or - for stdin' }),
39
+ disabled: core_1.Flags.boolean({ description: 'Attach the block disabled' }),
40
+ };
41
+ async run() {
42
+ this.requireAuth();
43
+ const { args, flags } = await this.parse(AgentsInstructionsAdd);
44
+ if (Boolean(flags.inline) === Boolean(flags.block)) {
45
+ this.error('Choose exactly one source: --inline or --block <block-id>.', { exit: 2 });
46
+ }
47
+ if (flags.inline && (flags.version !== undefined || flags.binding?.length)) {
48
+ this.error('--version and --binding only apply to --block.', { exit: 2 });
49
+ }
50
+ let agentId;
51
+ try {
52
+ agentId = await (0, agent_instructions_1.resolveInstructionAgentId)(args.id, flags.agent);
53
+ }
54
+ catch (error) {
55
+ const failure = (0, agent_resolver_1.agentResolutionFailure)(error);
56
+ this.failWithCliError({
57
+ message: failure.message,
58
+ code: failure.code,
59
+ exit: 2,
60
+ retryable: false,
61
+ });
62
+ }
63
+ let entry;
64
+ try {
65
+ if (flags.inline) {
66
+ const body = (await (0, instruction_input_1.readInstructionBody)({
67
+ body: flags.body,
68
+ file: flags.file,
69
+ required: true,
70
+ }));
71
+ if (!flags.title?.trim())
72
+ throw new Error('--title is required with --inline.');
73
+ entry = {
74
+ instanceId: (0, instruction_blocks_1.nextInstanceId)('inline'),
75
+ enabled: !flags.disabled,
76
+ source: { kind: 'inline', title: flags.title, body },
77
+ };
78
+ }
79
+ else {
80
+ const block = await data_provider_1.dataService.getInstructionBlock(flags.block);
81
+ const version = flags.version ?? block.currentVersion;
82
+ const bindings = (0, instruction_blocks_1.parseBindings)(flags.binding);
83
+ if (!block.versions.some((candidate) => candidate.version === version)) {
84
+ throw new Error(`${block.id} has no v${version}. Run \`skrr instruction-blocks show ${block.id}\`.`);
85
+ }
86
+ entry = {
87
+ instanceId: (0, instruction_blocks_1.nextInstanceId)('library'),
88
+ enabled: !flags.disabled,
89
+ source: { kind: 'library', blockId: block.id, version },
90
+ ...(bindings ? { bindings } : {}),
91
+ };
92
+ }
93
+ }
94
+ catch (error) {
95
+ this.error(error.message, { exit: 2 });
96
+ }
97
+ let loaded;
98
+ let updated;
99
+ try {
100
+ loaded = await (0, agent_instructions_1.loadAgentInstructions)(agentId);
101
+ updated = await (0, agent_instructions_1.saveAgentInstructions)(agentId, {
102
+ schemaVersion: 1,
103
+ entries: [...loaded.composition.entries, entry],
104
+ });
105
+ }
106
+ catch (error) {
107
+ this.handleApiError(error);
108
+ }
109
+ if (flags.json)
110
+ return this.log(JSON.stringify(updated, null, 2));
111
+ this.log(`Added ${entry.source.kind === 'inline' ? entry.source.title : entry.source.blockId} to ${agentId}.`);
112
+ this.log(`Instance: ${entry.instanceId}`);
113
+ }
114
+ }
115
+ exports.default = AgentsInstructionsAdd;
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class AgentsInstructionsDisable extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ instance: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../../base-command");
5
+ const agent_resolver_1 = require("../../../lib/agent-resolver");
6
+ const agent_instructions_1 = require("../../../lib/agent-instructions");
7
+ const instruction_blocks_1 = require("../../../lib/instruction-blocks");
8
+ class AgentsInstructionsDisable extends base_command_1.BaseCommand {
9
+ static description = 'Disable one instruction block without removing its configuration';
10
+ static examples = [
11
+ '<%= config.bin %> agents instructions disable library_… --agent <agent-id>',
12
+ ];
13
+ static args = {
14
+ instance: core_1.Args.string({ description: 'Block instance ID', required: true, ignoreStdin: true }),
15
+ };
16
+ static flags = {
17
+ json: core_1.Flags.boolean({ description: 'Output the updated Agent as JSON' }),
18
+ agent: core_1.Flags.string({ description: 'Agent ID (alias for the positional argument)' }),
19
+ };
20
+ async run() {
21
+ this.requireAuth();
22
+ const { args, flags } = await this.parse(AgentsInstructionsDisable);
23
+ let agentId;
24
+ try {
25
+ agentId = await (0, agent_instructions_1.resolveInstructionAgentId)(undefined, flags.agent);
26
+ }
27
+ catch (error) {
28
+ const failure = (0, agent_resolver_1.agentResolutionFailure)(error);
29
+ this.failWithCliError({
30
+ message: failure.message,
31
+ code: failure.code,
32
+ exit: 2,
33
+ retryable: false,
34
+ });
35
+ }
36
+ let updated;
37
+ try {
38
+ const { composition } = await (0, agent_instructions_1.loadAgentInstructions)(agentId);
39
+ const entry = (0, instruction_blocks_1.entryByInstance)(composition, args.instance);
40
+ updated = await (0, agent_instructions_1.saveAgentInstructions)(agentId, (0, instruction_blocks_1.replaceEntry)(composition, args.instance, { ...entry, enabled: false }));
41
+ }
42
+ catch (error) {
43
+ this.handleApiError(error);
44
+ }
45
+ if (flags.json)
46
+ return this.log(JSON.stringify(updated, null, 2));
47
+ this.log(`Disabled ${args.instance} on ${agentId}; its configuration is retained.`);
48
+ }
49
+ }
50
+ exports.default = AgentsInstructionsDisable;
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class AgentsInstructionsEdit extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ instance: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ title: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ body: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ };
15
+ run(): Promise<void>;
16
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../../base-command");
5
+ const agent_resolver_1 = require("../../../lib/agent-resolver");
6
+ const agent_instructions_1 = require("../../../lib/agent-instructions");
7
+ const instruction_blocks_1 = require("../../../lib/instruction-blocks");
8
+ const instruction_input_1 = require("../../../lib/instruction-input");
9
+ class AgentsInstructionsEdit extends base_command_1.BaseCommand {
10
+ static description = 'Edit an inline block owned by an Agent (library blocks are immutable; fork or upgrade them instead)';
11
+ static examples = [
12
+ '<%= config.bin %> agents instructions edit inline_… --agent <agent-id> --body "Name uncertainty."',
13
+ '<%= config.bin %> agents instructions edit inline_… --agent <agent-id> --title "Reporting format" --file ./format.md',
14
+ ];
15
+ static args = {
16
+ instance: core_1.Args.string({
17
+ description: 'Inline block instance ID',
18
+ required: true,
19
+ ignoreStdin: true,
20
+ }),
21
+ };
22
+ static flags = {
23
+ json: core_1.Flags.boolean({ description: 'Output the updated Agent as JSON' }),
24
+ agent: core_1.Flags.string({ description: 'Agent ID (alias for the positional argument)' }),
25
+ title: core_1.Flags.string({ description: 'New inline block title' }),
26
+ body: core_1.Flags.string({ description: 'New inline block text' }),
27
+ file: core_1.Flags.string({ description: 'Read new inline block text from a file, or - for stdin' }),
28
+ };
29
+ async run() {
30
+ this.requireAuth();
31
+ const { args, flags } = await this.parse(AgentsInstructionsEdit);
32
+ let agentId;
33
+ try {
34
+ agentId = await (0, agent_instructions_1.resolveInstructionAgentId)(undefined, flags.agent);
35
+ }
36
+ catch (error) {
37
+ const failure = (0, agent_resolver_1.agentResolutionFailure)(error);
38
+ this.failWithCliError({
39
+ message: failure.message,
40
+ code: failure.code,
41
+ exit: 2,
42
+ retryable: false,
43
+ });
44
+ }
45
+ let body;
46
+ try {
47
+ body = await (0, instruction_input_1.readInstructionBody)({ body: flags.body, file: flags.file });
48
+ if (flags.title === undefined && body === undefined) {
49
+ throw new Error('Nothing to edit. Pass --title, --body, or --file.');
50
+ }
51
+ }
52
+ catch (error) {
53
+ this.error(error.message, { exit: 2 });
54
+ }
55
+ let updated;
56
+ try {
57
+ const { composition } = await (0, agent_instructions_1.loadAgentInstructions)(agentId);
58
+ const current = (0, instruction_blocks_1.entryByInstance)(composition, args.instance);
59
+ if (current.source.kind !== 'inline') {
60
+ throw new Error(`Instance ${args.instance} is a version-pinned library block. Edit its source with \`skrr instruction-blocks update\`, then use \`agents instructions upgrade\` when ready.`);
61
+ }
62
+ updated = await (0, agent_instructions_1.saveAgentInstructions)(agentId, (0, instruction_blocks_1.replaceEntry)(composition, args.instance, {
63
+ ...current,
64
+ source: {
65
+ kind: 'inline',
66
+ title: flags.title ?? current.source.title,
67
+ body: body ?? current.source.body,
68
+ },
69
+ }));
70
+ }
71
+ catch (error) {
72
+ this.handleApiError(error);
73
+ }
74
+ if (flags.json)
75
+ return this.log(JSON.stringify(updated, null, 2));
76
+ this.log(`Edited inline block ${args.instance} on ${agentId}.`);
77
+ }
78
+ }
79
+ exports.default = AgentsInstructionsEdit;
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class AgentsInstructionsEnable extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ instance: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_command_1 = require("../../../base-command");
5
+ const agent_resolver_1 = require("../../../lib/agent-resolver");
6
+ const agent_instructions_1 = require("../../../lib/agent-instructions");
7
+ const instruction_blocks_1 = require("../../../lib/instruction-blocks");
8
+ class AgentsInstructionsEnable extends base_command_1.BaseCommand {
9
+ static description = 'Enable one instruction block on an Agent';
10
+ static examples = [
11
+ '<%= config.bin %> agents instructions enable library_… --agent <agent-id>',
12
+ ];
13
+ static args = {
14
+ instance: core_1.Args.string({ description: 'Block instance ID', required: true, ignoreStdin: true }),
15
+ };
16
+ static flags = {
17
+ json: core_1.Flags.boolean({ description: 'Output the updated Agent as JSON' }),
18
+ agent: core_1.Flags.string({ description: 'Agent ID (alias for the positional argument)' }),
19
+ };
20
+ async run() {
21
+ this.requireAuth();
22
+ const { args, flags } = await this.parse(AgentsInstructionsEnable);
23
+ let agentId;
24
+ try {
25
+ agentId = await (0, agent_instructions_1.resolveInstructionAgentId)(undefined, flags.agent);
26
+ }
27
+ catch (error) {
28
+ const failure = (0, agent_resolver_1.agentResolutionFailure)(error);
29
+ this.failWithCliError({
30
+ message: failure.message,
31
+ code: failure.code,
32
+ exit: 2,
33
+ retryable: false,
34
+ });
35
+ }
36
+ let updated;
37
+ try {
38
+ const { composition } = await (0, agent_instructions_1.loadAgentInstructions)(agentId);
39
+ const entry = (0, instruction_blocks_1.entryByInstance)(composition, args.instance);
40
+ updated = await (0, agent_instructions_1.saveAgentInstructions)(agentId, (0, instruction_blocks_1.replaceEntry)(composition, args.instance, { ...entry, enabled: true }));
41
+ }
42
+ catch (error) {
43
+ this.handleApiError(error);
44
+ }
45
+ if (flags.json)
46
+ return this.log(JSON.stringify(updated, null, 2));
47
+ this.log(`Enabled ${args.instance} on ${agentId}.`);
48
+ }
49
+ }
50
+ exports.default = AgentsInstructionsEnable;
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ export default class AgentsInstructionsMove extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ instance: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ before: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ after: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }