@skrr-ai/cli 0.1.39 → 0.1.41

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 (134) hide show
  1. package/README.md +1 -1
  2. package/dist/base-command.d.ts +9 -0
  3. package/dist/base-command.js +26 -3
  4. package/dist/commands/agent-shares/list-for.js +4 -11
  5. package/dist/commands/agent-shares/received.js +4 -11
  6. package/dist/commands/agent-shares/sent.js +4 -11
  7. package/dist/commands/agent-shares/with.js +3 -10
  8. package/dist/commands/agents/activity.js +1 -1
  9. package/dist/commands/agents/api-actions/add.js +6 -0
  10. package/dist/commands/agents/chat.js +6 -1
  11. package/dist/commands/agents/create.d.ts +7 -0
  12. package/dist/commands/agents/create.js +19 -2
  13. package/dist/commands/agents/manager/ensure.d.ts +18 -0
  14. package/dist/commands/agents/manager/ensure.js +56 -0
  15. package/dist/commands/agents/show.js +4 -0
  16. package/dist/commands/agents/tools/auth.d.ts +6 -0
  17. package/dist/commands/agents/tools/auth.js +27 -1
  18. package/dist/commands/agents/tools/index.js +11 -1
  19. package/dist/commands/agents/triggers/policy.d.ts +1 -0
  20. package/dist/commands/agents/triggers/policy.js +32 -0
  21. package/dist/commands/agents/update.js +10 -4
  22. package/dist/commands/code/install.d.ts +4 -2
  23. package/dist/commands/code/install.js +12 -10
  24. package/dist/commands/convos/list.js +1 -3
  25. package/dist/commands/convos/show.js +4 -11
  26. package/dist/commands/daemon/index.js +3 -3
  27. package/dist/commands/daemon/install.js +4 -4
  28. package/dist/commands/daemon/login.js +1 -1
  29. package/dist/commands/daemon/logs.d.ts +3 -1
  30. package/dist/commands/daemon/logs.js +16 -1
  31. package/dist/commands/daemon/start.js +3 -3
  32. package/dist/commands/daemon/status.d.ts +9 -0
  33. package/dist/commands/daemon/status.js +22 -0
  34. package/dist/commands/dm/messages.js +1 -11
  35. package/dist/commands/followups/cancel.js +1 -1
  36. package/dist/commands/followups/observability.js +6 -2
  37. package/dist/commands/followups/remind.js +5 -2
  38. package/dist/commands/followups/reschedule.js +2 -1
  39. package/dist/commands/followups/resolve.js +1 -1
  40. package/dist/commands/followups/show.js +20 -0
  41. package/dist/commands/followups/watch.d.ts +1 -0
  42. package/dist/commands/followups/watch.js +9 -3
  43. package/dist/commands/harnesses/forget.js +20 -3
  44. package/dist/commands/harnesses/install.js +18 -6
  45. package/dist/commands/harnesses/installers.d.ts +1 -1
  46. package/dist/commands/harnesses/installers.js +36 -12
  47. package/dist/commands/harnesses/list.d.ts +74 -2
  48. package/dist/commands/harnesses/list.js +231 -15
  49. package/dist/commands/harnesses/ping.d.ts +2 -0
  50. package/dist/commands/harnesses/ping.js +21 -0
  51. package/dist/commands/harnesses/show.d.ts +22 -0
  52. package/dist/commands/harnesses/show.js +116 -17
  53. package/dist/commands/harnesses/update.d.ts +8 -0
  54. package/dist/commands/harnesses/update.js +25 -1
  55. package/dist/commands/harnesses/usage.d.ts +2 -0
  56. package/dist/commands/harnesses/usage.js +7 -2
  57. package/dist/commands/instructions/status.js +13 -0
  58. package/dist/commands/instructions/update-target.d.ts +1 -0
  59. package/dist/commands/instructions/update-target.js +11 -3
  60. package/dist/commands/login.js +5 -5
  61. package/dist/commands/machines/list.js +8 -9
  62. package/dist/commands/machines/show.js +46 -17
  63. package/dist/commands/messages/show.js +3 -10
  64. package/dist/commands/shares/get.js +2 -9
  65. package/dist/commands/shares/list.js +1 -9
  66. package/dist/commands/shortcuts/show.js +4 -11
  67. package/dist/commands/skills/local.js +6 -0
  68. package/dist/commands/spaces/actions/run.js +3 -4
  69. package/dist/commands/spaces/briefs/get.js +2 -9
  70. package/dist/commands/spaces/briefs/list.js +1 -9
  71. package/dist/commands/spaces/conversations.js +1 -9
  72. package/dist/commands/spaces/heartbeats/list.js +1 -9
  73. package/dist/commands/spaces/heartbeats/status.js +2 -9
  74. package/dist/commands/tasks/activity.js +1 -10
  75. package/dist/commands/tasks/approvals/list.js +1 -9
  76. package/dist/commands/tasks/attachments/list.js +1 -9
  77. package/dist/commands/tasks/comments/list.js +1 -9
  78. package/dist/commands/tasks/dri-status.js +2 -9
  79. package/dist/commands/tasks/events/append.js +9 -7
  80. package/dist/commands/tasks/execution-timeline.js +1 -9
  81. package/dist/commands/tasks/lifecycle/detach.js +26 -5
  82. package/dist/commands/tasks/monitor.js +1 -9
  83. package/dist/commands/tasks/result/submit.js +9 -0
  84. package/dist/commands/tasks/runs.js +1 -9
  85. package/dist/commands/tasks/show.js +5 -12
  86. package/dist/commands/token/list.d.ts +8 -0
  87. package/dist/commands/token/list.js +51 -6
  88. package/dist/help.js +8 -12
  89. package/dist/lib/agent-home-workspace.d.ts +19 -0
  90. package/dist/lib/agent-home-workspace.js +39 -0
  91. package/dist/lib/agent-resolver.js +2 -2
  92. package/dist/lib/agentic-stream.d.ts +22 -1
  93. package/dist/lib/agentic-stream.js +48 -7
  94. package/dist/lib/cli-installers.d.ts +84 -2
  95. package/dist/lib/cli-installers.js +146 -13
  96. package/dist/lib/command-miss.d.ts +22 -0
  97. package/dist/lib/command-miss.js +78 -0
  98. package/dist/lib/daemon-setup.js +2 -2
  99. package/dist/lib/daemon-target.d.ts +14 -0
  100. package/dist/lib/daemon-target.js +32 -0
  101. package/dist/lib/daemonBroker.js +1 -1
  102. package/dist/lib/daemonHandoff.js +1 -1
  103. package/dist/lib/dedicated-lease-command.js +4 -1
  104. package/dist/lib/dedicated-machines.d.ts +8 -1
  105. package/dist/lib/dedicated-machines.js +22 -6
  106. package/dist/lib/dedicated-wait.js +13 -0
  107. package/dist/lib/exec-runtime-binary.js +2 -2
  108. package/dist/lib/followups.d.ts +18 -0
  109. package/dist/lib/followups.js +14 -1
  110. package/dist/lib/format.d.ts +11 -0
  111. package/dist/lib/format.js +21 -0
  112. package/dist/lib/harness-labels.d.ts +39 -0
  113. package/dist/lib/harness-labels.js +60 -0
  114. package/dist/lib/harnesses.d.ts +6 -0
  115. package/dist/lib/instruction-input.d.ts +13 -0
  116. package/dist/lib/instruction-input.js +20 -1
  117. package/dist/lib/label-ref.d.ts +8 -1
  118. package/dist/lib/label-ref.js +12 -2
  119. package/dist/lib/local-skills.d.ts +17 -1
  120. package/dist/lib/local-skills.js +20 -2
  121. package/dist/lib/login.js +5 -5
  122. package/dist/lib/machines.d.ts +6 -0
  123. package/dist/lib/machines.js +68 -2
  124. package/dist/lib/option-hint.d.ts +15 -0
  125. package/dist/lib/option-hint.js +75 -0
  126. package/dist/lib/runtime-tool-support.d.ts +34 -0
  127. package/dist/lib/runtime-tool-support.js +77 -0
  128. package/dist/lib/share-rows.d.ts +17 -0
  129. package/dist/lib/share-rows.js +35 -0
  130. package/dist/lib/workspaces.d.ts +3 -0
  131. package/dist/lib/workspaces.js +38 -0
  132. package/dist/node_modules/@skrr-ai/data-provider/index.js +5029 -5007
  133. package/oclif.manifest.json +34255 -34142
  134. package/package.json +10 -5
package/README.md CHANGED
@@ -38,7 +38,7 @@ observability), and shared links.
38
38
  | **spaces widgets** | `list`, `add`, `remove` |
39
39
  | **spaces skills** | `list`, `add`, `remove`, `pin` |
40
40
  | **spaces labels** | `list`, `add`, `remove` (attach/detach; filter with `spaces list --label`) |
41
- | **labels** | `list`, `palette`, `create`, `update`, `archive`, `restore`, `delete`, `reorder` (unified labels across `user`, `space`, and `workspace` scopes) |
41
+ | **labels** | `list`, `palette`, `create`, `update`, `archive`, `restore`, `delete`, `reorder` (unified labels across `user` and `workspace` scopes) |
42
42
  | **chats triggers** | `show`, `set` |
43
43
  | **dm** | `list`, `show`, `messages`, `threads`, `thread show/messages/follow/mute/share`, `send` (agent 1:1 main chat and Slack-style Thread controls) |
44
44
  | **diagnostics** | `context`, `doctor`, `usage`, `commands` (agent-friendly runtime identity, readiness, progressive token-budgeted discovery, and complete machine-readable schemas) |
@@ -338,6 +338,15 @@ export interface ParsedGlobals {
338
338
  workspace?: string;
339
339
  }
340
340
  export declare function parseGlobalFlags(argv: readonly string[]): ParsedGlobals;
341
+ /**
342
+ * The typed `code` and message an API refusal carried, read the way
343
+ * `handleApiError` reads them, for a command that answers one code itself
344
+ * before falling back to the uniform translation.
345
+ */
346
+ export declare function apiRefusal(err: unknown): {
347
+ code?: string;
348
+ message?: string;
349
+ };
341
350
  /**
342
351
  * Prefix a failure message with the resource it is about.
343
352
  *
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Flags = exports.BaseCommand = exports.resolveProfileFromArgv = void 0;
4
4
  exports.assigneePayloadNeedsResolution = assigneePayloadNeedsResolution;
5
5
  exports.parseGlobalFlags = parseGlobalFlags;
6
+ exports.apiRefusal = apiRefusal;
6
7
  exports.withSubject = withSubject;
7
8
  exports.describeHarnessUnavailable = describeHarnessUnavailable;
8
9
  exports.describeGitHubUnavailable = describeGitHubUnavailable;
@@ -16,6 +17,7 @@ exports.isTypedServerRefusal = isTypedServerRefusal;
16
17
  exports.isRetryableFailure = isRetryableFailure;
17
18
  const core_1 = require("@oclif/core");
18
19
  Object.defineProperty(exports, "Flags", { enumerable: true, get: function () { return core_1.Flags; } });
20
+ const option_hint_1 = require("./lib/option-hint");
19
21
  const failed_lookup_1 = require("./lib/failed-lookup");
20
22
  // Re-exported from its home in `lib/keychain`, beside the other profile
21
23
  // functions. It lived here while `init()` was its only caller; a lib module
@@ -308,7 +310,7 @@ class BaseCommand extends core_1.Command {
308
310
  // to log in again. Reachable in the ordinary way — a cold machine
309
311
  // running several skrr commands at once has every process brokering,
310
312
  // because none of them has a token yet.
311
- process.stderr.write('[skrr] The local skrr runtime is being rate-limited while brokering logins. ' +
313
+ process.stderr.write('[skrr] The skrr background service on this computer is being rate-limited while brokering logins. ' +
312
314
  'This is transient — retry in a few minutes, or run `skrr login` to sign in directly.\n');
313
315
  }
314
316
  else if (autoResult.outcome.reason === 'base_url_mismatch' &&
@@ -316,7 +318,7 @@ class BaseCommand extends core_1.Command {
316
318
  // The user is about to see "Not signed in" — give them the
317
319
  // exact fix. One stderr line so it doesn't pollute --json
318
320
  // consumers on stdout.
319
- process.stderr.write(`[skrr] Local skrr runtime is logged in to ${autoResult.outcome.daemonServerUrl}, ` +
321
+ process.stderr.write(`[skrr] The skrr background service on this computer is logged in to ${autoResult.outcome.daemonServerUrl}, ` +
320
322
  `but skrr is configured for ${this.cliConfig.baseURL}. ` +
321
323
  `Run \`skrr login --base-url ${autoResult.outcome.daemonServerUrl}\` to use the daemon.\n`);
322
324
  }
@@ -788,6 +790,13 @@ class BaseCommand extends core_1.Command {
788
790
  if (retiredHint) {
789
791
  err.message = `${err.message}\n\n${retiredHint}`;
790
792
  }
793
+ // Sibling domains spell one lifecycle differently (`in_progress` for a
794
+ // space, `active` for a goal), and oclif's enum refusal named neither the
795
+ // difference nor the value to use (OSK-9735).
796
+ const optionHint = (0, option_hint_1.invalidOptionHint)(err.message || '');
797
+ if (optionHint) {
798
+ err.message = `${err.message}\n\n${optionHint}`;
799
+ }
791
800
  if (this.wantsJsonOutput()) {
792
801
  const exit = err.exitCode ?? err.oclif?.exit ?? 1;
793
802
  process.exitCode = exit;
@@ -1347,6 +1356,20 @@ function stringProp(obj, key) {
1347
1356
  const value = obj?.[key];
1348
1357
  return typeof value === 'string' && value.trim() ? value.trim() : undefined;
1349
1358
  }
1359
+ /**
1360
+ * The typed `code` and message an API refusal carried, read the way
1361
+ * `handleApiError` reads them, for a command that answers one code itself
1362
+ * before falling back to the uniform translation.
1363
+ */
1364
+ function apiRefusal(err) {
1365
+ if (!(err instanceof Error))
1366
+ return {};
1367
+ const body = parseErrorBody(err.body);
1368
+ return {
1369
+ code: stringProp(body, 'code') || stringProp(body, 'errorType'),
1370
+ message: stringProp(body, 'message') || stringProp(body, 'error'),
1371
+ };
1372
+ }
1350
1373
  /**
1351
1374
  * Prefix a failure message with the resource it is about.
1352
1375
  *
@@ -1614,7 +1637,7 @@ function describeDaemonScopedCredential(bin, scope = 'daemon', source) {
1614
1637
  ? `The stored credential has ${scope === 'daemon-install' ? 'daemon-install' : 'daemon'} scope`
1615
1638
  : `This command received a ${scopeLabel} credential`;
1616
1639
  return (`${subject}, which cannot access user API commands. ` +
1617
- `Run \`${bin} login\` to create a CLI credential. For the local runtime itself, use \`${bin} daemon login\`.`);
1640
+ `Run \`${bin} login\` to create a CLI credential. For the background service on this computer, use \`${bin} daemon login\`.`);
1618
1641
  }
1619
1642
  /**
1620
1643
  * Did the server MEAN this 5xx, or did it fall over?
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const format_1 = require("../../lib/format");
7
+ const share_rows_1 = require("../../lib/share-rows");
7
8
  class AgentSharesListFor extends base_command_1.BaseCommand {
8
9
  static description = 'List all users an agent has been shared with';
9
10
  static examples = [
@@ -37,10 +38,10 @@ class AgentSharesListFor extends base_command_1.BaseCommand {
37
38
  return;
38
39
  }
39
40
  const rows = items.map((s) => ({
40
- shareId: String(s.id ?? s._id ?? '-'),
41
- recipient: String(s.recipientId ?? s.recipient ?? s.to ?? '-'),
41
+ shareId: (0, share_rows_1.shareIdOf)(s),
42
+ recipient: (0, share_rows_1.sharePartyLabel)(s.recipient ?? s.recipientId ?? s.to),
42
43
  status: String(s.status ?? '-'),
43
- sharedAt: formatTime(s.createdAt ?? s.sharedAt),
44
+ sharedAt: (0, format_1.localTime)(s.createdAt ?? s.sharedAt),
44
45
  }));
45
46
  (0, format_1.renderTable)(rows, [
46
47
  { key: 'shareId', header: 'SHARE ID' },
@@ -56,11 +57,3 @@ class AgentSharesListFor extends base_command_1.BaseCommand {
56
57
  }
57
58
  }
58
59
  exports.default = AgentSharesListFor;
59
- function formatTime(value) {
60
- try {
61
- return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
62
- }
63
- catch {
64
- return String(value ?? '-');
65
- }
66
- }
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const format_1 = require("../../lib/format");
7
+ const share_rows_1 = require("../../lib/share-rows");
7
8
  class AgentSharesReceived extends base_command_1.BaseCommand {
8
9
  static description = 'List agent shares received by the current user';
9
10
  static examples = [
@@ -44,12 +45,12 @@ class AgentSharesReceived extends base_command_1.BaseCommand {
44
45
  return;
45
46
  }
46
47
  const rows = items.map((s) => ({
47
- shareId: String(s.id ?? s._id ?? '-'),
48
+ shareId: (0, share_rows_1.shareIdOf)(s),
48
49
  agentId: String(s.agentId ?? '-'),
49
50
  agentName: String(s.agentName ?? s.agent?.name ?? '-'),
50
- from: String(s.senderId ?? s.from ?? s.owner ?? '-'),
51
+ from: (0, share_rows_1.sharePartyLabel)(s.owner ?? s.senderId ?? s.from),
51
52
  status: String(s.status ?? '-'),
52
- sharedAt: formatTime(s.createdAt ?? s.sharedAt),
53
+ sharedAt: (0, format_1.localTime)(s.createdAt ?? s.sharedAt),
53
54
  }));
54
55
  (0, format_1.renderTable)(rows, [
55
56
  { key: 'shareId', header: 'SHARE ID' },
@@ -67,11 +68,3 @@ class AgentSharesReceived extends base_command_1.BaseCommand {
67
68
  }
68
69
  }
69
70
  exports.default = AgentSharesReceived;
70
- function formatTime(value) {
71
- try {
72
- return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
73
- }
74
- catch {
75
- return String(value ?? '-');
76
- }
77
- }
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const format_1 = require("../../lib/format");
7
+ const share_rows_1 = require("../../lib/share-rows");
7
8
  class AgentSharesSent extends base_command_1.BaseCommand {
8
9
  static description = 'List agent shares sent by the current user';
9
10
  static examples = [
@@ -41,12 +42,12 @@ class AgentSharesSent extends base_command_1.BaseCommand {
41
42
  return;
42
43
  }
43
44
  const rows = items.map((s) => ({
44
- shareId: String(s.id ?? s._id ?? '-'),
45
+ shareId: (0, share_rows_1.shareIdOf)(s),
45
46
  agentId: String(s.agentId ?? '-'),
46
47
  agentName: String(s.agentName ?? s.agent?.name ?? '-'),
47
- to: String(s.recipientId ?? s.to ?? s.recipient ?? '-'),
48
+ to: (0, share_rows_1.sharePartyLabel)(s.recipient ?? s.recipientId ?? s.to),
48
49
  status: String(s.status ?? '-'),
49
- sharedAt: formatTime(s.createdAt ?? s.sharedAt),
50
+ sharedAt: (0, format_1.localTime)(s.createdAt ?? s.sharedAt),
50
51
  }));
51
52
  (0, format_1.renderTable)(rows, [
52
53
  { key: 'shareId', header: 'SHARE ID' },
@@ -64,11 +65,3 @@ class AgentSharesSent extends base_command_1.BaseCommand {
64
65
  }
65
66
  }
66
67
  exports.default = AgentSharesSent;
67
- function formatTime(value) {
68
- try {
69
- return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
70
- }
71
- catch {
72
- return String(value ?? '-');
73
- }
74
- }
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
5
  const base_command_1 = require("../../base-command");
6
6
  const format_1 = require("../../lib/format");
7
+ const share_rows_1 = require("../../lib/share-rows");
7
8
  class AgentSharesWith extends base_command_1.BaseCommand {
8
9
  static description = 'Show all agent shares with a specific user';
9
10
  static examples = [
@@ -39,11 +40,11 @@ class AgentSharesWith extends base_command_1.BaseCommand {
39
40
  return;
40
41
  }
41
42
  const toRows = (items) => items.map((s) => ({
42
- shareId: String(s.id ?? s._id ?? '-'),
43
+ shareId: (0, share_rows_1.shareIdOf)(s),
43
44
  agentId: String(s.agentId ?? '-'),
44
45
  agentName: String(s.agentName ?? s.agent?.name ?? '-'),
45
46
  status: String(s.status ?? '-'),
46
- sharedAt: formatTime(s.createdAt ?? s.sharedAt),
47
+ sharedAt: (0, format_1.localTime)(s.createdAt ?? s.sharedAt),
47
48
  }));
48
49
  const columns = [
49
50
  { key: 'shareId', header: 'SHARE ID' },
@@ -69,11 +70,3 @@ class AgentSharesWith extends base_command_1.BaseCommand {
69
70
  }
70
71
  }
71
72
  exports.default = AgentSharesWith;
72
- function formatTime(value) {
73
- try {
74
- return new Date(String(value)).toISOString().slice(0, 19).replace('T', ' ');
75
- }
76
- catch {
77
- return String(value ?? '-');
78
- }
79
- }
@@ -162,7 +162,7 @@ class AgentsActivity extends base_command_1.BaseCommand {
162
162
  }
163
163
  else {
164
164
  (0, format_1.renderTable)(entries.map((entry) => ({
165
- when: entry.at ? new Date(entry.at).toISOString().slice(0, 19).replace('T', ' ') : '-',
165
+ when: (0, format_1.localTime)(entry.at),
166
166
  kind: entry.kind,
167
167
  title: (0, format_1.truncate)(entry.title, 50),
168
168
  detail: (0, format_1.truncate)(entry.detail, 40),
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const promises_1 = require("node:fs/promises");
5
5
  const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const runtime_tool_support_1 = require("../../../lib/runtime-tool-support");
6
7
  const base_command_1 = require("../../../base-command");
7
8
  /**
8
9
  * Attach (or re-attach) an OpenAPI document to an agent as a tool surface.
@@ -199,6 +200,11 @@ class AgentsApiActionsAdd extends base_command_1.BaseCommand {
199
200
  }
200
201
  this.log(`${flags['action-id'] ? 'Updated' : 'Added'} an OpenAPI action on agent ${args.agentId} — ` +
201
202
  `${functions.length} operation(s) on ${domain}`);
203
+ const actionId = result[1]?.action_id;
204
+ if (flags.auth === data_provider_1.AuthTypeEnum.OAuth && actionId) {
205
+ const redirectUrl = new URL(`/api/actions/${encodeURIComponent(actionId)}/oauth/callback`, this.cliConfig.baseURL).toString();
206
+ this.log((0, runtime_tool_support_1.oauthActionNotice)(redirectUrl));
207
+ }
202
208
  this.printAgentUrl(args.agentId);
203
209
  }
204
210
  }
@@ -12,6 +12,7 @@ const node_fs_1 = require("node:fs");
12
12
  const core_1 = require("@oclif/core");
13
13
  const data_provider_1 = require("@skrr-ai/data-provider");
14
14
  const base_command_1 = require("../../base-command");
15
+ const agent_home_workspace_1 = require("../../lib/agent-home-workspace");
15
16
  const agentic_stream_1 = require("../../lib/agentic-stream");
16
17
  const web_url_1 = require("../../lib/web-url");
17
18
  const local_skills_1 = require("../../lib/local-skills");
@@ -302,7 +303,10 @@ class AgentsChat extends base_command_1.BaseCommand {
302
303
  exit: 2,
303
304
  });
304
305
  }
305
- const { refs, problems } = (0, local_skills_1.resolveLocalSkillRefs)(inventory.skills ?? [], requested);
306
+ const { refs, problems } = (0, local_skills_1.resolveLocalSkillRefs)(inventory.skills ?? [], requested, {
307
+ snapshot: inventory.cwdResolved !== true,
308
+ daemonId,
309
+ });
306
310
  if (problems.length > 0) {
307
311
  this.error(problems.join('\n'), { exit: 2 });
308
312
  }
@@ -446,6 +450,7 @@ class AgentsChat extends base_command_1.BaseCommand {
446
450
  const prompt = localSkills
447
451
  ? (0, local_skills_1.withSkillInvocations)(flags.prompt, localSkills.refs)
448
452
  : flags.prompt;
453
+ await (0, agent_home_workspace_1.applyAgentHomeWorkspaceDefault)(args.agentId, (agentId) => data_provider_1.dataService.getAgentById({ agent_id: agentId }));
449
454
  let started;
450
455
  try {
451
456
  started = await data_provider_1.dataService.startAgenticChat({
@@ -64,6 +64,13 @@ export declare function agentCreateMissingFields(payload: Record<string, unknown
64
64
  * a failed create would be worse than the silence.
65
65
  */
66
66
  export declare function unappliedPayloadKeys(sent: Record<string, unknown>, created: unknown, ignore?: readonly string[]): string[];
67
+ /**
68
+ * Why a key can come back missing. Both readings are live: a typo of a real
69
+ * field (`max_turns` for `maxTurns`), and a real field only the server sets
70
+ * (`nativeRole`, `author`). Naming only the first told a caller who had tried
71
+ * to claim a platform role that they had misspelled something.
72
+ */
73
+ export declare function unappliedPayloadKeysWarning(keys: readonly string[]): string;
67
74
  export declare function backgroundLoopLines(agentId: string, relationshipLoopsSkipped: boolean): string[];
68
75
  export default class AgentsCreate extends BaseCommand {
69
76
  static description: string;
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.agentCreateMissingFieldsMessage = agentCreateMissingFieldsMessage;
4
4
  exports.agentCreateMissingFields = agentCreateMissingFields;
5
5
  exports.unappliedPayloadKeys = unappliedPayloadKeys;
6
+ exports.unappliedPayloadKeysWarning = unappliedPayloadKeysWarning;
6
7
  exports.backgroundLoopLines = backgroundLoopLines;
7
8
  const core_1 = require("@oclif/core");
8
9
  const data_provider_1 = require("@skrr-ai/data-provider");
9
10
  const agent_visual_refs_1 = require("../../lib/agent-visual-refs");
11
+ const runtime_tool_support_1 = require("../../lib/runtime-tool-support");
10
12
  const base_command_1 = require("../../base-command");
11
13
  const execution_target_1 = require("../../lib/execution-target");
12
14
  const prompt_1 = require("../../lib/prompt");
@@ -105,6 +107,17 @@ function unappliedPayloadKeys(sent, created, ignore = []) {
105
107
  .filter((key) => !Object.prototype.hasOwnProperty.call(back, key))
106
108
  .sort();
107
109
  }
110
+ /**
111
+ * Why a key can come back missing. Both readings are live: a typo of a real
112
+ * field (`max_turns` for `maxTurns`), and a real field only the server sets
113
+ * (`nativeRole`, `author`). Naming only the first told a caller who had tried
114
+ * to claim a platform role that they had misspelled something.
115
+ */
116
+ function unappliedPayloadKeysWarning(keys) {
117
+ const one = keys.length === 1;
118
+ return (`The server did not keep ${keys.join(', ')}: ${one ? 'it is not an agent field' : 'they are not agent fields'}, ` +
119
+ `or only the server sets ${one ? 'it' : 'them'}. \`skrr agents show <id> --json\` shows what the agent stores.`);
120
+ }
108
121
  function backgroundLoopLines(agentId, relationshipLoopsSkipped) {
109
122
  if (relationshipLoopsSkipped) {
110
123
  return [
@@ -189,7 +202,10 @@ class AgentsCreate extends base_command_1.BaseCommand {
189
202
  description: 'Default Claude permission mode for sessions',
190
203
  options: ['default', 'acceptEdits', 'bypassPermissions', 'plan'],
191
204
  }),
192
- tools: core_1.Flags.string({ description: 'Tools JSON array' }),
205
+ tools: core_1.Flags.string({
206
+ description: 'Tools JSON array of plugin keys, e.g. \'["calculator"]\'. `skrr agents tools` lists the keys, ' +
207
+ 'and which of them an agent turn can call.',
208
+ }),
193
209
  'model-parameters': core_1.Flags.string({ description: 'Model parameters JSON object' }),
194
210
  'agent-ids': core_1.Flags.string({ description: 'Delegated agent IDs JSON array' }),
195
211
  'network-mode': core_1.Flags.string({ description: 'Agent network mode' }),
@@ -368,8 +384,9 @@ class AgentsCreate extends base_command_1.BaseCommand {
368
384
  // Agent document field and is intentionally absent from the response.
369
385
  const unapplied = unappliedPayloadKeys(payload, created, ['relationshipLoops']);
370
386
  if (unapplied.length > 0) {
371
- this.warn(`The server did not keep ${unapplied.join(', ')} — ${unapplied.length === 1 ? 'that field is' : 'those fields are'} not part of the agent it created. Check \`skrr agents show <id> --json\`.`);
387
+ this.warn(unappliedPayloadKeysWarning(unapplied));
372
388
  }
389
+ await (0, runtime_tool_support_1.warnPluginsNotLoaded)(payload.tools, (message) => this.warn(message));
373
390
  if (flags.json) {
374
391
  this.log(JSON.stringify((0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, created), null, 2));
375
392
  return;
@@ -0,0 +1,18 @@
1
+ import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * Create or repair this account's Agent Manager (the HR Agent).
4
+ *
5
+ * Wraps `POST /api/agents/manager/ensure`. New accounts get an HR Agent at
6
+ * signup; accounts that predate it had no way to get one (OSK-9745), and a
7
+ * signup whose provisioning failed part-way was never finished (OSK-9785).
8
+ * IDEMPOTENT: run it again and it reports the existing agent, or what it had
9
+ * to repair.
10
+ */
11
+ export default class AgentsManagerEnsure extends BaseCommand {
12
+ static description: string;
13
+ static examples: string[];
14
+ static flags: {
15
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
@@ -0,0 +1,56 @@
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 web_url_1 = require("../../../lib/web-url");
7
+ /**
8
+ * Create or repair this account's Agent Manager (the HR Agent).
9
+ *
10
+ * Wraps `POST /api/agents/manager/ensure`. New accounts get an HR Agent at
11
+ * signup; accounts that predate it had no way to get one (OSK-9745), and a
12
+ * signup whose provisioning failed part-way was never finished (OSK-9785).
13
+ * IDEMPOTENT: run it again and it reports the existing agent, or what it had
14
+ * to repair.
15
+ */
16
+ class AgentsManagerEnsure extends base_command_1.BaseCommand {
17
+ static description = "Create your Agent Manager (HR Agent) if you don't have one, or repair it if it is incomplete";
18
+ static examples = [
19
+ '<%= config.bin %> agents manager ensure',
20
+ '<%= config.bin %> agents manager ensure --workspace <workspace-id> --json',
21
+ ];
22
+ static flags = {
23
+ json: core_1.Flags.boolean({ description: 'Output as JSON' }),
24
+ };
25
+ async run() {
26
+ this.requireAuth();
27
+ const { flags } = await this.parse(AgentsManagerEnsure);
28
+ let result;
29
+ try {
30
+ result = await data_provider_1.dataService.ensureAgentManager();
31
+ }
32
+ catch (err) {
33
+ this.handleApiError(err);
34
+ }
35
+ const agent = (0, web_url_1.withAgentUrl)(this.cliConfig.baseURL, {
36
+ ...result.agent,
37
+ });
38
+ if (flags.json) {
39
+ this.log(JSON.stringify({ ...result, agent }, null, 2));
40
+ return;
41
+ }
42
+ const label = `${result.agent.id} — ${result.agent.name}`;
43
+ if (result.created) {
44
+ this.log(`Created your Agent Manager: ${label}`);
45
+ }
46
+ else if (result.repaired.length > 0) {
47
+ this.log(`Repaired your Agent Manager (${result.repaired.join(', ')}): ${label}`);
48
+ }
49
+ else {
50
+ this.log(`You already have an Agent Manager: ${label}`);
51
+ }
52
+ this.log(`Workspace: ${result.workspaceId}`);
53
+ this.log(`URL: ${agent.url ?? '-'}`);
54
+ }
55
+ }
56
+ exports.default = AgentsManagerEnsure;
@@ -179,6 +179,10 @@ class AgentsShow extends base_command_1.BaseCommand {
179
179
  }
180
180
  const tools = Array.isArray(a.tools) ? a.tools : [];
181
181
  this.log(`Tools: ${tools.length === 0 ? '(none)' : tools.join(', ')}`);
182
+ if (tools.length > 0) {
183
+ // Stored, not loaded: the runtime has none of these yet (OSK-9750, OSK-9754).
184
+ this.log(' (saved on the agent; the agent runtime does not load these yet)');
185
+ }
182
186
  if (a.description) {
183
187
  this.log('');
184
188
  this.log('Description:');
@@ -1,4 +1,10 @@
1
1
  import { BaseCommand } from '../../../base-command';
2
+ /**
3
+ * A credential's help text for a terminal. Plugin manifests write it as HTML
4
+ * with the signup link in an anchor; stripping the tags alone would keep
5
+ * "see Our Docs" and drop the URL, which is the part worth printing.
6
+ */
7
+ export declare function credentialHelpText(description: string): string;
2
8
  /**
3
9
  * Whether this account has credentials for one tool.
4
10
  *
@@ -1,8 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.credentialHelpText = credentialHelpText;
3
4
  const core_1 = require("@oclif/core");
4
5
  const data_provider_1 = require("@skrr-ai/data-provider");
5
6
  const base_command_1 = require("../../../base-command");
7
+ const html_text_1 = require("../../../lib/html-text");
8
+ /**
9
+ * A credential's help text for a terminal. Plugin manifests write it as HTML
10
+ * with the signup link in an anchor; stripping the tags alone would keep
11
+ * "see Our Docs" and drop the URL, which is the part worth printing.
12
+ */
13
+ function credentialHelpText(description) {
14
+ return (0, html_text_1.htmlToDisplayText)(description.replace(/<a\s[^>]*href=['"]([^'"]+)['"][^>]*>(.*?)<\/a>/gi, '$2 ($1)'));
15
+ }
6
16
  /**
7
17
  * Whether this account has credentials for one tool.
8
18
  *
@@ -33,9 +43,25 @@ class AgentsToolsAuth extends base_command_1.BaseCommand {
33
43
  this.log(JSON.stringify(result, null, 2));
34
44
  return;
35
45
  }
46
+ const missing = result.missing ?? [];
36
47
  this.log(result.authenticated
37
48
  ? `${args.toolId}: authenticated`
38
- : `${args.toolId}: not authenticated${result.message ? ` — ${result.message}` : ''}`);
49
+ : `${args.toolId}: not authenticated${missing.length === 0 && result.message ? ` — ${result.message}` : ''}`);
50
+ // The answer's next question is "what do I supply, and where do I get it"
51
+ // (OSK-9550); the manifest carries both, so print them.
52
+ if (missing.length > 0) {
53
+ this.log('Missing credentials:');
54
+ for (const credential of missing) {
55
+ this.log(` ${credential.authField} ${credential.label ?? ''}`.trimEnd());
56
+ if (credential.description) {
57
+ this.log(` ${credentialHelpText(credential.description)}`);
58
+ }
59
+ }
60
+ this.log('Add them where you add this tool to an agent in the web app.');
61
+ }
62
+ if (result.agentRuntime === false) {
63
+ this.log(`Agent turns cannot call ${args.toolId}: it saves output through a web request an agent turn does not have.`);
64
+ }
39
65
  }
40
66
  }
41
67
  exports.default = AgentsToolsAuth;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const data_provider_1 = require("@skrr-ai/data-provider");
5
+ const runtime_tool_support_1 = require("../../../lib/runtime-tool-support");
5
6
  const base_command_1 = require("../../../base-command");
6
7
  const format_1 = require("../../../lib/format");
7
8
  /**
@@ -63,15 +64,24 @@ class AgentsToolsList extends base_command_1.BaseCommand {
63
64
  pluginKey: tool.pluginKey,
64
65
  name: tool.name,
65
66
  auth: authState(tool),
67
+ agent: (0, runtime_tool_support_1.agentRuntimeLabel)(tool),
66
68
  description: String(tool.description ?? ''),
67
69
  })), [
68
70
  { key: 'pluginKey', header: 'PLUGIN KEY', verbatim: true },
69
71
  { key: 'name', header: 'NAME', maxWidth: 28 },
70
72
  { key: 'auth', header: 'AUTH' },
73
+ { key: 'agent', header: 'AGENT' },
71
74
  { key: 'description', header: 'DESCRIPTION', maxWidth: 52 },
72
75
  ], (line) => this.log(line));
73
76
  this.log('');
74
- this.log('PLUGIN KEY is what --tools stores, e.g. --tools \'["web_search"]\'.');
77
+ // The example must be a key this list printed (OSK-9600: it was web_search),
78
+ // preferably one that works without credentials.
79
+ const example = rows.find((tool) => !tool.authConfig?.length) ?? rows[0];
80
+ this.log(`PLUGIN KEY is what --tools stores, e.g. --tools '["${example.pluginKey}"]'.`);
81
+ this.log(runtime_tool_support_1.AGENT_COLUMN_FOOTNOTE);
82
+ if (rows.some((tool) => tool.authConfig?.length && !tool.authenticated)) {
83
+ this.log('`skrr agents tools auth <plugin-key>` names the credentials a tool still needs.');
84
+ }
75
85
  }
76
86
  }
77
87
  exports.default = AgentsToolsList;
@@ -15,6 +15,7 @@ export default class AgentsTriggersPolicy extends BaseCommand {
15
15
  'max-per-hour': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
16
  'working-hours': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
17
17
  'quiet-hours': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
18
+ 'followup-budget': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
18
19
  };
19
20
  run(): Promise<void>;
20
21
  }
@@ -8,6 +8,28 @@ const triggers_1 = require("../../../lib/triggers");
8
8
  // used to carry its own copy that stopped one rung short, so `auto_run` was
9
9
  // accepted by the API and unreachable from the CLI.
10
10
  const data_provider_1 = require("@skrr-ai/data-provider");
11
+ /** `watch=10 checkin=default` → `{ watch: 10, checkin: null }`; the server validates the pools. */
12
+ function parseFollowUpBudget(values) {
13
+ if (!values || values.length === 0)
14
+ return undefined;
15
+ const budget = {};
16
+ for (const entry of (0, triggers_1.splitRepeated)(values) ?? []) {
17
+ const [pool, raw] = entry.split('=');
18
+ if (!pool || raw === undefined || raw === '') {
19
+ throw new Error(`--followup-budget expects pool=count, got "${entry}"`);
20
+ }
21
+ if (raw === 'default') {
22
+ budget[pool] = null;
23
+ continue;
24
+ }
25
+ const count = Number(raw);
26
+ if (!Number.isInteger(count) || count < 0) {
27
+ throw new Error(`--followup-budget ${pool} must be a non-negative integer or "default"`);
28
+ }
29
+ budget[pool] = count;
30
+ }
31
+ return budget;
32
+ }
11
33
  class AgentsTriggersPolicy extends base_command_1.BaseCommand {
12
34
  static description = "Show or update an agent's initiative policy for agent-scoped triggers";
13
35
  static examples = [
@@ -38,6 +60,10 @@ class AgentsTriggersPolicy extends base_command_1.BaseCommand {
38
60
  'max-per-hour': core_1.Flags.integer({ description: 'Agent initiative hourly fire cap' }),
39
61
  'working-hours': core_1.Flags.string({ description: 'Policy workingHours JSON object' }),
40
62
  'quiet-hours': core_1.Flags.string({ description: 'Policy quietHours JSON object' }),
63
+ 'followup-budget': core_1.Flags.string({
64
+ description: 'Daily follow-up creation cap for this agent, as pool=count (pools: watch, checkin, act; count "default" clears it). Repeatable',
65
+ multiple: true,
66
+ }),
41
67
  };
42
68
  async run() {
43
69
  this.requireAuth();
@@ -52,6 +78,7 @@ class AgentsTriggersPolicy extends base_command_1.BaseCommand {
52
78
  maxPerHour: flags['max-per-hour'],
53
79
  workingHours: (0, triggers_1.parseJsonObject)(flags['working-hours'], '--working-hours'),
54
80
  quietHours: (0, triggers_1.parseJsonObject)(flags['quiet-hours'], '--quiet-hours'),
81
+ followUpBudget: parseFollowUpBudget(flags['followup-budget']),
55
82
  });
56
83
  }
57
84
  catch (err) {
@@ -77,6 +104,11 @@ class AgentsTriggersPolicy extends base_command_1.BaseCommand {
77
104
  this.log(`Allowed kinds: ${Array.isArray(policy.allowedKinds) ? policy.allowedKinds.join(', ') : '-'}`);
78
105
  this.log(`Max fires/day: ${String(policy.maxFiresPerDay ?? '-')}`);
79
106
  this.log(`Max/hour: ${String(policy.maxPerHour ?? '-')}`);
107
+ const followUpBudget = policy.followUpBudget;
108
+ const budgetEntries = Object.entries(followUpBudget ?? {}).filter(([, v]) => v != null);
109
+ this.log(`Follow-up caps: ${budgetEntries.length > 0
110
+ ? budgetEntries.map(([pool, cap]) => `${pool} ${String(cap)}/day`).join(', ')
111
+ : 'defaults'}`);
80
112
  if (Object.keys(counts).length > 0) {
81
113
  this.log(`Triggers: ${String(counts.total ?? 0)} total, ${String(counts.enabled ?? 0)} enabled`);
82
114
  }