@skrr-ai/cli 0.1.36 → 0.1.38

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 (266) hide show
  1. package/README.md +17 -4
  2. package/bin/dev-fallback.js +167 -4
  3. package/dist/base-command.js +46 -2
  4. package/dist/commands/agents/actions/create.d.ts +5 -0
  5. package/dist/commands/agents/actions/create.js +42 -5
  6. package/dist/commands/agents/actions/delete.d.ts +1 -0
  7. package/dist/commands/agents/actions/delete.js +7 -0
  8. package/dist/commands/agents/actions/update.d.ts +5 -0
  9. package/dist/commands/agents/actions/update.js +27 -1
  10. package/dist/commands/agents/api-actions/add.d.ts +41 -0
  11. package/dist/commands/agents/api-actions/add.js +205 -0
  12. package/dist/commands/agents/api-actions/index.d.ts +39 -0
  13. package/dist/commands/agents/api-actions/index.js +103 -0
  14. package/dist/commands/agents/api-actions/remove.d.ts +14 -0
  15. package/dist/commands/agents/api-actions/remove.js +36 -0
  16. package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
  17. package/dist/commands/agents/avatar/default/apply.js +56 -0
  18. package/dist/commands/agents/avatar/default/index.d.ts +29 -0
  19. package/dist/commands/agents/avatar/default/index.js +61 -0
  20. package/dist/commands/agents/avatar/default/set.d.ts +24 -0
  21. package/dist/commands/agents/avatar/default/set.js +120 -0
  22. package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
  23. package/dist/commands/agents/avatar/library/delete.js +47 -0
  24. package/dist/commands/agents/avatar/library/index.d.ts +16 -0
  25. package/dist/commands/agents/avatar/library/index.js +56 -0
  26. package/dist/commands/agents/avatar/presets.d.ts +19 -0
  27. package/dist/commands/agents/avatar/presets.js +56 -0
  28. package/dist/commands/agents/avatar/upload.js +7 -1
  29. package/dist/commands/agents/categories/create.d.ts +14 -0
  30. package/dist/commands/agents/categories/create.js +46 -0
  31. package/dist/commands/agents/categories/delete.d.ts +13 -0
  32. package/dist/commands/agents/categories/delete.js +41 -0
  33. package/dist/commands/agents/categories/index.d.ts +36 -0
  34. package/dist/commands/agents/categories/index.js +135 -0
  35. package/dist/commands/agents/categories/update.d.ts +22 -0
  36. package/dist/commands/agents/categories/update.js +59 -0
  37. package/dist/commands/agents/chat.d.ts +21 -0
  38. package/dist/commands/agents/chat.js +94 -7
  39. package/dist/commands/agents/create.d.ts +10 -0
  40. package/dist/commands/agents/create.js +64 -3
  41. package/dist/commands/agents/ensure-default.d.ts +27 -0
  42. package/dist/commands/agents/ensure-default.js +65 -0
  43. package/dist/commands/agents/list.d.ts +15 -0
  44. package/dist/commands/agents/list.js +31 -1
  45. package/dist/commands/agents/mute.d.ts +16 -0
  46. package/dist/commands/agents/mute.js +38 -0
  47. package/dist/commands/agents/pin.d.ts +16 -0
  48. package/dist/commands/agents/pin.js +38 -0
  49. package/dist/commands/agents/scene-background/upload.d.ts +30 -0
  50. package/dist/commands/agents/scene-background/upload.js +97 -0
  51. package/dist/commands/agents/show.js +13 -0
  52. package/dist/commands/agents/tools/auth.d.ts +19 -0
  53. package/dist/commands/agents/tools/auth.js +41 -0
  54. package/dist/commands/agents/tools/calls.d.ts +36 -0
  55. package/dist/commands/agents/tools/calls.js +117 -0
  56. package/dist/commands/agents/tools/index.d.ts +20 -0
  57. package/dist/commands/agents/tools/index.js +77 -0
  58. package/dist/commands/agents/unmute.d.ts +16 -0
  59. package/dist/commands/agents/unmute.js +38 -0
  60. package/dist/commands/agents/unpin.d.ts +16 -0
  61. package/dist/commands/agents/unpin.js +38 -0
  62. package/dist/commands/agents/update.d.ts +12 -0
  63. package/dist/commands/agents/update.js +74 -3
  64. package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
  65. package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
  66. package/dist/commands/convos/messages.d.ts +13 -0
  67. package/dist/commands/convos/messages.js +40 -16
  68. package/dist/commands/daemon/index.js +8 -1
  69. package/dist/commands/daemon/logs.d.ts +26 -0
  70. package/dist/commands/daemon/logs.js +56 -0
  71. package/dist/commands/daemon/uninstall.js +1 -1
  72. package/dist/commands/followups/act.d.ts +22 -0
  73. package/dist/commands/followups/act.js +103 -0
  74. package/dist/commands/followups/cancel.d.ts +20 -0
  75. package/dist/commands/followups/cancel.js +50 -0
  76. package/dist/commands/followups/checkin.d.ts +27 -0
  77. package/dist/commands/followups/checkin.js +107 -0
  78. package/dist/commands/followups/list.d.ts +24 -0
  79. package/dist/commands/followups/list.js +90 -0
  80. package/dist/commands/followups/observability.d.ts +23 -0
  81. package/dist/commands/followups/observability.js +114 -0
  82. package/dist/commands/followups/remind.d.ts +26 -0
  83. package/dist/commands/followups/remind.js +106 -0
  84. package/dist/commands/followups/reschedule.d.ts +15 -0
  85. package/dist/commands/followups/reschedule.js +48 -0
  86. package/dist/commands/followups/resolve.d.ts +23 -0
  87. package/dist/commands/followups/resolve.js +54 -0
  88. package/dist/commands/followups/show.d.ts +12 -0
  89. package/dist/commands/followups/show.js +46 -0
  90. package/dist/commands/followups/watch.d.ts +51 -0
  91. package/dist/commands/followups/watch.js +211 -0
  92. package/dist/commands/goals/labels/add.js +19 -2
  93. package/dist/commands/goals/labels/remove.js +22 -2
  94. package/dist/commands/harnesses/forget.js +28 -0
  95. package/dist/commands/harnesses/install.d.ts +41 -0
  96. package/dist/commands/harnesses/install.js +165 -0
  97. package/dist/commands/harnesses/installers.d.ts +45 -0
  98. package/dist/commands/harnesses/installers.js +155 -0
  99. package/dist/commands/harnesses/list.d.ts +82 -1
  100. package/dist/commands/harnesses/list.js +104 -12
  101. package/dist/commands/harnesses/models.js +10 -1
  102. package/dist/commands/harnesses/show.d.ts +15 -0
  103. package/dist/commands/harnesses/show.js +44 -3
  104. package/dist/commands/harnesses/update.js +1 -1
  105. package/dist/commands/harnesses/usage.d.ts +25 -0
  106. package/dist/commands/harnesses/usage.js +24 -2
  107. package/dist/commands/instructions/status.js +13 -1
  108. package/dist/commands/labels/list.d.ts +24 -1
  109. package/dist/commands/labels/list.js +62 -19
  110. package/dist/commands/machines/dedicated/catalog.js +4 -15
  111. package/dist/commands/machines/dedicated/create.d.ts +8 -0
  112. package/dist/commands/machines/dedicated/create.js +58 -1
  113. package/dist/commands/machines/dedicated/destroy.js +18 -4
  114. package/dist/commands/machines/dedicated/list.js +9 -6
  115. package/dist/commands/machines/hosted/list.js +12 -0
  116. package/dist/commands/machines/list.js +11 -0
  117. package/dist/commands/machines/show.d.ts +1 -0
  118. package/dist/commands/machines/show.js +40 -11
  119. package/dist/commands/memory/governance/index.d.ts +21 -0
  120. package/dist/commands/memory/governance/index.js +64 -0
  121. package/dist/commands/memory/governance/set.d.ts +24 -0
  122. package/dist/commands/memory/governance/set.js +95 -0
  123. package/dist/commands/memory/provenance.d.ts +18 -0
  124. package/dist/commands/memory/provenance.js +66 -0
  125. package/dist/commands/profiles/list.d.ts +23 -0
  126. package/dist/commands/profiles/list.js +96 -0
  127. package/dist/commands/search/skills.d.ts +11 -1
  128. package/dist/commands/search/skills.js +26 -8
  129. package/dist/commands/skills/details.d.ts +2 -0
  130. package/dist/commands/skills/details.js +24 -1
  131. package/dist/commands/skills/import-as-actions.d.ts +32 -0
  132. package/dist/commands/skills/import-as-actions.js +175 -0
  133. package/dist/commands/skills/install.d.ts +2 -0
  134. package/dist/commands/skills/install.js +24 -1
  135. package/dist/commands/skills/invocable.js +6 -2
  136. package/dist/commands/skills/local.d.ts +40 -0
  137. package/dist/commands/skills/local.js +160 -0
  138. package/dist/commands/skills/search.d.ts +11 -1
  139. package/dist/commands/skills/search.js +29 -8
  140. package/dist/commands/spaces/actions/add.js +23 -5
  141. package/dist/commands/spaces/actions/available.js +3 -0
  142. package/dist/commands/spaces/actions/list.d.ts +5 -0
  143. package/dist/commands/spaces/actions/list.js +49 -3
  144. package/dist/commands/spaces/actions/run.d.ts +28 -0
  145. package/dist/commands/spaces/actions/run.js +146 -0
  146. package/dist/commands/spaces/actions/update.js +27 -5
  147. package/dist/commands/spaces/create.d.ts +3 -0
  148. package/dist/commands/spaces/create.js +32 -2
  149. package/dist/commands/spaces/label-summaries.d.ts +27 -0
  150. package/dist/commands/spaces/label-summaries.js +64 -0
  151. package/dist/commands/spaces/labels/add.js +19 -2
  152. package/dist/commands/spaces/labels/remove.js +22 -2
  153. package/dist/commands/spaces/show.js +2 -0
  154. package/dist/commands/spaces/task-rollups.d.ts +5 -0
  155. package/dist/commands/spaces/task-rollups.js +15 -4
  156. package/dist/commands/spaces/update.d.ts +5 -0
  157. package/dist/commands/spaces/update.js +41 -4
  158. package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
  159. package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +105 -0
  160. package/dist/commands/tasks/actions/attach.js +32 -7
  161. package/dist/commands/tasks/complete.d.ts +1 -0
  162. package/dist/commands/tasks/complete.js +21 -1
  163. package/dist/commands/tasks/create.d.ts +3 -0
  164. package/dist/commands/tasks/create.js +34 -2
  165. package/dist/commands/tasks/events/append.js +29 -6
  166. package/dist/commands/tasks/expectations/assess.d.ts +12 -0
  167. package/dist/commands/tasks/expectations/assess.js +123 -14
  168. package/dist/commands/tasks/expectations.js +95 -17
  169. package/dist/commands/tasks/follow-up.js +2 -2
  170. package/dist/commands/tasks/labels/attach.js +20 -3
  171. package/dist/commands/tasks/labels/detach.js +21 -3
  172. package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
  173. package/dist/commands/tasks/lifecycle/attach.js +47 -0
  174. package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
  175. package/dist/commands/tasks/lifecycle/definitions.js +59 -0
  176. package/dist/commands/tasks/lifecycle/detach.d.ts +19 -0
  177. package/dist/commands/tasks/lifecycle/detach.js +72 -0
  178. package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
  179. package/dist/commands/tasks/lifecycle/history.js +38 -0
  180. package/dist/commands/tasks/lifecycle/migrate.d.ts +14 -0
  181. package/dist/commands/tasks/lifecycle/migrate.js +68 -0
  182. package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
  183. package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
  184. package/dist/commands/tasks/lifecycle/reopen.d.ts +15 -0
  185. package/dist/commands/tasks/lifecycle/reopen.js +71 -0
  186. package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
  187. package/dist/commands/tasks/lifecycle/show.js +27 -0
  188. package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
  189. package/dist/commands/tasks/lifecycle/start.js +30 -0
  190. package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
  191. package/dist/commands/tasks/lifecycle/transition.js +109 -0
  192. package/dist/commands/tasks/list.js +16 -9
  193. package/dist/commands/tasks/move.d.ts +1 -0
  194. package/dist/commands/tasks/move.js +29 -0
  195. package/dist/commands/tasks/result/submit.js +11 -1
  196. package/dist/commands/tasks/review-queue.d.ts +44 -0
  197. package/dist/commands/tasks/review-queue.js +314 -0
  198. package/dist/commands/tasks/show.d.ts +11 -0
  199. package/dist/commands/tasks/show.js +139 -4
  200. package/dist/commands/tasks/trust.js +7 -2
  201. package/dist/commands/tasks/update.d.ts +1 -0
  202. package/dist/commands/tasks/update.js +83 -0
  203. package/dist/commands/tasks/updates/add.js +1 -1
  204. package/dist/commands/token/list.d.ts +22 -0
  205. package/dist/commands/token/list.js +68 -0
  206. package/dist/commands/token/revoke.d.ts +23 -0
  207. package/dist/commands/token/revoke.js +53 -0
  208. package/dist/lib/agent-actions.d.ts +92 -11
  209. package/dist/lib/agent-actions.js +171 -25
  210. package/dist/lib/agent-config.d.ts +11 -0
  211. package/dist/lib/agent-config.js +85 -3
  212. package/dist/lib/agent-pin-mute.d.ts +29 -0
  213. package/dist/lib/agent-pin-mute.js +30 -0
  214. package/dist/lib/agent-visual-refs.d.ts +33 -0
  215. package/dist/lib/agent-visual-refs.js +267 -0
  216. package/dist/lib/agentic-stream.d.ts +6 -0
  217. package/dist/lib/agentic-stream.js +34 -3
  218. package/dist/lib/assignee-resolver.d.ts +1 -1
  219. package/dist/lib/assignee-resolver.js +8 -0
  220. package/dist/lib/bulk-task-targets.d.ts +12 -0
  221. package/dist/lib/bulk-task-targets.js +34 -1
  222. package/dist/lib/cli-installers.d.ts +130 -0
  223. package/dist/lib/cli-installers.js +145 -0
  224. package/dist/lib/command-miss.js +55 -7
  225. package/dist/lib/dedicated-lease-command.d.ts +13 -0
  226. package/dist/lib/dedicated-lease-command.js +22 -1
  227. package/dist/lib/dedicated-machines.d.ts +95 -1
  228. package/dist/lib/dedicated-machines.js +236 -2
  229. package/dist/lib/failed-lookup.d.ts +3 -0
  230. package/dist/lib/failed-lookup.js +40 -0
  231. package/dist/lib/first-party-harness-agent.js +16 -2
  232. package/dist/lib/first-party-harness-doctor.d.ts +15 -0
  233. package/dist/lib/first-party-harness-doctor.js +126 -27
  234. package/dist/lib/followups.d.ts +115 -0
  235. package/dist/lib/followups.js +127 -0
  236. package/dist/lib/harnesses.d.ts +8 -0
  237. package/dist/lib/instruction-input.d.ts +19 -1
  238. package/dist/lib/instruction-input.js +52 -1
  239. package/dist/lib/label-ref.d.ts +95 -0
  240. package/dist/lib/label-ref.js +163 -0
  241. package/dist/lib/label-scope.d.ts +17 -2
  242. package/dist/lib/label-scope.js +27 -7
  243. package/dist/lib/local-skills.d.ts +98 -0
  244. package/dist/lib/local-skills.js +195 -0
  245. package/dist/lib/machines.d.ts +10 -10
  246. package/dist/lib/machines.js +23 -1
  247. package/dist/lib/search-query.d.ts +19 -0
  248. package/dist/lib/search-query.js +35 -0
  249. package/dist/lib/space-custom-actions.d.ts +72 -0
  250. package/dist/lib/space-custom-actions.js +117 -0
  251. package/dist/lib/space-resolver.d.ts +1 -21
  252. package/dist/lib/space-resolver.js +19 -10
  253. package/dist/lib/task-closure.d.ts +33 -0
  254. package/dist/lib/task-closure.js +104 -0
  255. package/dist/lib/task-lifecycle-output.d.ts +14 -0
  256. package/dist/lib/task-lifecycle-output.js +209 -0
  257. package/dist/lib/task-ref-resolver.d.ts +1 -17
  258. package/dist/lib/task-ref-resolver.js +18 -8
  259. package/dist/lib/tasks.d.ts +3 -0
  260. package/dist/lib/tasks.js +40 -3
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
  263. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  264. package/dist/node_modules/@skrr-ai/data-provider/index.js +5559 -4897
  265. package/oclif.manifest.json +33890 -28690
  266. package/package.json +24 -6
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Shared plumbing for the unified label commands (`skrr labels …`).
4
4
  *
5
- * Labels are anchored to exactly one scope — a user, a space, or a workspace —
5
+ * Labels are anchored to exactly one scope — a user or a workspace —
6
6
  * via the `(scope, scopeId)` pair. That pair is simultaneously the uniqueness
7
7
  * key and the permission boundary server-side (see
8
8
  * `api/server/services/Labels/LabelService.js`), so every label command has to
@@ -11,12 +11,31 @@
11
11
  * id the server can infer (it falls back to the caller).
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.labelScopeFlags = exports.HEX_COLOR_RE = exports.LABEL_APPLICABLE = exports.LABEL_SCOPES = void 0;
14
+ exports.labelScopeFlags = exports.HEX_COLOR_RE = exports.LABEL_APPLICABLE = exports.LABEL_SCOPES_INFERRED = exports.LABEL_SCOPES_REQUIRING_ID = exports.LABEL_SCOPES = void 0;
15
15
  exports.normalizeLabelColor = normalizeLabelColor;
16
16
  exports.resolveLabelScope = resolveLabelScope;
17
17
  exports.resolveApplicableTo = resolveApplicableTo;
18
18
  const core_1 = require("@oclif/core");
19
- exports.LABEL_SCOPES = ['user', 'space', 'workspace'];
19
+ exports.LABEL_SCOPES = ['user', 'workspace'];
20
+ /**
21
+ * Scopes whose id the server cannot infer, so `--scope-id` must name it.
22
+ *
23
+ * `resolveLabelScope` below and the `--scope-id` help text are BOTH derived
24
+ * from this, rather than each restating the list. They drifted once already:
25
+ * `0298b7e4fd` collapsed the vocabulary from three scopes to two, and the help
26
+ * kept advertising `--scope space` for months after the validator had stopped
27
+ * accepting it — so following `--help` produced `Expected --scope=space to be
28
+ * one of: user, workspace`, whose last line points back at the help that was
29
+ * wrong. Static prose describing a value set is how that happens; deriving it
30
+ * is what stops the next collapse doing the same.
31
+ */
32
+ exports.LABEL_SCOPES_REQUIRING_ID = ['workspace'];
33
+ const scopesRequiringId = () => exports.LABEL_SCOPES_REQUIRING_ID;
34
+ /** Scopes the server resolves from the caller — passing an id is an error. */
35
+ exports.LABEL_SCOPES_INFERRED = exports.LABEL_SCOPES.filter((scope) => !exports.LABEL_SCOPES_REQUIRING_ID.includes(scope));
36
+ function joinScopes(scopes) {
37
+ return scopes.map((scope) => `--scope ${scope}`).join(' / ');
38
+ }
20
39
  exports.LABEL_APPLICABLE = ['task', 'space', 'goal', 'routine'];
21
40
  /**
22
41
  * The server stores colors as bare 6-hex (`api/server/routes/labels.js` Zod is
@@ -34,7 +53,7 @@ exports.labelScopeFlags = {
34
53
  default: 'user',
35
54
  }),
36
55
  'scope-id': core_1.Flags.string({
37
- description: 'Space or workspace ID — required for --scope space|workspace. Omit for --scope user (defaults to you).',
56
+ description: `Scope owner ID — required for ${joinScopes(scopesRequiringId())}. Omit for ${joinScopes(exports.LABEL_SCOPES_INFERRED)} (defaults to you).`,
38
57
  }),
39
58
  };
40
59
  /**
@@ -44,11 +63,12 @@ exports.labelScopeFlags = {
44
63
  function resolveLabelScope(flags) {
45
64
  const scope = (flags.scope ?? 'user');
46
65
  const scopeId = flags['scope-id'];
47
- if ((scope === 'space' || scope === 'workspace') && !scopeId) {
66
+ const requiresId = exports.LABEL_SCOPES_REQUIRING_ID.includes(scope);
67
+ if (requiresId && !scopeId) {
48
68
  throw new Error(`--scope-id is required for --scope ${scope}.`);
49
69
  }
50
- if (scope === 'user' && scopeId) {
51
- throw new Error('--scope-id is not accepted for --scope user; user-scope labels are always your own.');
70
+ if (!requiresId && scopeId) {
71
+ throw new Error(`--scope-id is not accepted for --scope ${scope}; ${scope}-scope labels are always your own.`);
52
72
  }
53
73
  return { scope, ...(scopeId ? { scopeId } : {}) };
54
74
  }
@@ -0,0 +1,98 @@
1
+ import type { DaemonLocalSkill } from '@skrr-ai/data-provider';
2
+ /**
3
+ * Skills on a machine, as its daemon lists them — the CLI half of the `/` menu.
4
+ *
5
+ * `skrr` had two things called "skill" and commands for only one: store and
6
+ * workspace skills (`skills *`, `--skill <skill-id>`) had a full surface, while
7
+ * the skills in a machine's `.claude/skills` and sibling roots — the ones the
8
+ * web `/` menu offers — could be neither listed nor invoked, so a headless
9
+ * operator or a locally-running coding agent could not use them at all
10
+ * (OSK-9478). `skills local` lists them; `agents chat --local-skill` invokes
11
+ * one. Both resolve through here, so a name means the same skill in each.
12
+ */
13
+ export type ConnectedDaemon = {
14
+ daemonId: string;
15
+ deviceName?: string | null;
16
+ };
17
+ /**
18
+ * Which machine to ask, or why there is no single answer.
19
+ *
20
+ * Resolves rather than guesses: picking one of several machines and reporting
21
+ * its skills as "the" answer is the same silent narrowing the listing exists
22
+ * to remove.
23
+ */
24
+ export declare function chooseDaemon(active: ReadonlyArray<ConnectedDaemon>): {
25
+ daemonId: string;
26
+ } | {
27
+ problem: string;
28
+ candidates: ConnectedDaemon[];
29
+ };
30
+ /** A skill with no declared triggers is invocable both ways — the walker's default. */
31
+ export declare function isUserInvocable(skill: Pick<DaemonLocalSkill, 'triggers'>): boolean;
32
+ /**
33
+ * Turn requested names into the references the server resolves.
34
+ *
35
+ * A request is `name`, or `<root>/<name>` when the same name exists under more
36
+ * than one root (`.claude/skills/review` vs `.agents/skills/review`). Each
37
+ * problem is reported in words that say what to type instead; nothing is
38
+ * dropped, because the server's own rule is that a skill the user picked and
39
+ * the turn did not load must fail the turn rather than run without it.
40
+ */
41
+ export declare function resolveLocalSkillRefs(inventory: ReadonlyArray<DaemonLocalSkill>, requested: ReadonlyArray<string>): {
42
+ refs: Array<{
43
+ name: string;
44
+ pathHash: string;
45
+ }>;
46
+ problems: string[];
47
+ };
48
+ /**
49
+ * The prompt with a `/name` for every invoked skill it does not already name.
50
+ *
51
+ * The web composer sends the `/name` in the text beside the reference, and
52
+ * drops a reference whose `/name` is gone; a CLI turn carries the same pair so
53
+ * the agent reads the same invocation either way.
54
+ */
55
+ export declare function withSkillInvocations(prompt: string, refs: ReadonlyArray<{
56
+ name: string;
57
+ }>): string;
58
+ /** Whether a skill argument names a place on disk rather than a store id. */
59
+ export declare function looksLikeSkillPath(arg: string): boolean;
60
+ export type LocalSkillSighting = {
61
+ daemonId: string;
62
+ deviceName?: string | null;
63
+ source?: string;
64
+ };
65
+ /**
66
+ * Where a skill with this name exists on the caller's connected machines.
67
+ *
68
+ * Best-effort by design: it runs only to word an error that is already going
69
+ * to be reported, so a machine that cannot be asked contributes nothing rather
70
+ * than replacing the real error with a second one.
71
+ */
72
+ export declare function findLocalSkillsNamed(name: string): Promise<LocalSkillSighting[]>;
73
+ /**
74
+ * The error for a skill argument a STORE command could not use.
75
+ *
76
+ * `skills install <name>` and `skills details <name>` answered a local skill's
77
+ * name or path with "Skill not found / NOT_FOUND": true of the store, and no
78
+ * help to someone the product had just told it reads their `.claude/skills`
79
+ * (OSK-9412). The answer depends on what the argument was, so it says which:
80
+ * a path (never a store id), a name found on a connected machine (needs no
81
+ * install), or neither (look the id up in the store).
82
+ */
83
+ export declare function describeStoreSkillMiss(arg: string, sightings: ReadonlyArray<LocalSkillSighting>, command: 'install' | 'details'): string;
84
+ /**
85
+ * The first daemon release whose walker scans the skill conventions — the
86
+ * project's `.claude/skills`, `.agents/skills`, `.devin/skills`,
87
+ * `.windsurf/skills` and the global `~/.claude/skills`. It arrived in
88
+ * `e9dfa732cd` and first shipped in 0.8.44; an older daemon scans only
89
+ * `claudeSession.skillsDir`, which is empty unless someone set it by hand.
90
+ */
91
+ export declare const SKILL_CONVENTION_DISCOVERY_SINCE = "0.8.44";
92
+ /**
93
+ * Whether a daemon's reported version is older than `floor`.
94
+ *
95
+ * Unknown or unparseable versions answer false: this decides only whether to
96
+ * add an explanation, and claiming an unknown daemon is old would be a guess.
97
+ */
98
+ export declare function daemonPredates(version: string | null | undefined, floor: string): boolean;
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SKILL_CONVENTION_DISCOVERY_SINCE = void 0;
4
+ exports.chooseDaemon = chooseDaemon;
5
+ exports.isUserInvocable = isUserInvocable;
6
+ exports.resolveLocalSkillRefs = resolveLocalSkillRefs;
7
+ exports.withSkillInvocations = withSkillInvocations;
8
+ exports.looksLikeSkillPath = looksLikeSkillPath;
9
+ exports.findLocalSkillsNamed = findLocalSkillsNamed;
10
+ exports.describeStoreSkillMiss = describeStoreSkillMiss;
11
+ exports.daemonPredates = daemonPredates;
12
+ const data_provider_1 = require("@skrr-ai/data-provider");
13
+ /**
14
+ * Which machine to ask, or why there is no single answer.
15
+ *
16
+ * Resolves rather than guesses: picking one of several machines and reporting
17
+ * its skills as "the" answer is the same silent narrowing the listing exists
18
+ * to remove.
19
+ */
20
+ function chooseDaemon(active) {
21
+ if (active.length === 1)
22
+ return { daemonId: active[0].daemonId };
23
+ if (active.length === 0) {
24
+ return {
25
+ problem: 'No connected machine. Start one with `skrr daemon start`, then try again.',
26
+ candidates: [],
27
+ };
28
+ }
29
+ return {
30
+ problem: `${active.length} machines are connected. Pick one with --daemon:`,
31
+ candidates: [...active],
32
+ };
33
+ }
34
+ /** A skill with no declared triggers is invocable both ways — the walker's default. */
35
+ function isUserInvocable(skill) {
36
+ return !skill.triggers || skill.triggers.includes('user');
37
+ }
38
+ /**
39
+ * Turn requested names into the references the server resolves.
40
+ *
41
+ * A request is `name`, or `<root>/<name>` when the same name exists under more
42
+ * than one root (`.claude/skills/review` vs `.agents/skills/review`). Each
43
+ * problem is reported in words that say what to type instead; nothing is
44
+ * dropped, because the server's own rule is that a skill the user picked and
45
+ * the turn did not load must fail the turn rather than run without it.
46
+ */
47
+ function resolveLocalSkillRefs(inventory, requested) {
48
+ const refs = [];
49
+ const problems = [];
50
+ const seen = new Set();
51
+ for (const raw of requested) {
52
+ const request = raw.trim().replace(/^\//, '');
53
+ const slash = request.lastIndexOf('/');
54
+ const root = slash > 0 ? request.slice(0, slash) : null;
55
+ const name = slash > 0 ? request.slice(slash + 1) : request;
56
+ const named = inventory.filter((skill) => skill.name === name);
57
+ const matches = root ? named.filter((skill) => skill.source === root) : named;
58
+ if (matches.length === 0) {
59
+ problems.push(named.length > 0
60
+ ? `No skill "${name}" under ${root}. It is under: ${named.map((s) => s.source ?? '?').join(', ')}.`
61
+ : `No skill named "${name}" on this machine. See \`skrr skills local\`.`);
62
+ continue;
63
+ }
64
+ if (matches.length > 1) {
65
+ problems.push(`"${name}" exists under ${matches.length} roots. Name one: ` +
66
+ matches.map((s) => `--local-skill ${s.source ?? '?'}/${name}`).join(' | '));
67
+ continue;
68
+ }
69
+ const [skill] = matches;
70
+ if (!isUserInvocable(skill)) {
71
+ problems.push(`"${name}" declares it is for the agent to reach for, not to invoke (triggers: model).`);
72
+ continue;
73
+ }
74
+ if (seen.has(skill.pathHash))
75
+ continue;
76
+ seen.add(skill.pathHash);
77
+ refs.push({ name: skill.name, pathHash: skill.pathHash });
78
+ }
79
+ return { refs, problems };
80
+ }
81
+ /**
82
+ * The prompt with a `/name` for every invoked skill it does not already name.
83
+ *
84
+ * The web composer sends the `/name` in the text beside the reference, and
85
+ * drops a reference whose `/name` is gone; a CLI turn carries the same pair so
86
+ * the agent reads the same invocation either way.
87
+ */
88
+ function withSkillInvocations(prompt, refs) {
89
+ const missing = refs.filter((ref) => !new RegExp(`(^|\\s)/${ref.name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?=\\s|$)`).test(prompt));
90
+ if (missing.length === 0)
91
+ return prompt;
92
+ return `${missing.map((ref) => `/${ref.name}`).join(' ')} ${prompt}`;
93
+ }
94
+ /** Whether a skill argument names a place on disk rather than a store id. */
95
+ function looksLikeSkillPath(arg) {
96
+ return /[\\/]/.test(arg) || arg.startsWith('.') || arg.startsWith('~');
97
+ }
98
+ /**
99
+ * Where a skill with this name exists on the caller's connected machines.
100
+ *
101
+ * Best-effort by design: it runs only to word an error that is already going
102
+ * to be reported, so a machine that cannot be asked contributes nothing rather
103
+ * than replacing the real error with a second one.
104
+ */
105
+ async function findLocalSkillsNamed(name) {
106
+ const bare = name.replace(/^\//, '');
107
+ let active = [];
108
+ try {
109
+ active = (await data_provider_1.dataService.getDaemons()).active ?? [];
110
+ }
111
+ catch {
112
+ return [];
113
+ }
114
+ const sightings = await Promise.all(active.map(async (daemon) => {
115
+ try {
116
+ const { skills } = await data_provider_1.dataService.getDaemonSkills(daemon.daemonId);
117
+ return (skills ?? [])
118
+ .filter((skill) => skill.name === bare)
119
+ .map((skill) => ({
120
+ daemonId: daemon.daemonId,
121
+ deviceName: daemon.deviceName,
122
+ source: skill.source,
123
+ }));
124
+ }
125
+ catch {
126
+ return [];
127
+ }
128
+ }));
129
+ return sightings.flat();
130
+ }
131
+ /**
132
+ * The error for a skill argument a STORE command could not use.
133
+ *
134
+ * `skills install <name>` and `skills details <name>` answered a local skill's
135
+ * name or path with "Skill not found / NOT_FOUND": true of the store, and no
136
+ * help to someone the product had just told it reads their `.claude/skills`
137
+ * (OSK-9412). The answer depends on what the argument was, so it says which:
138
+ * a path (never a store id), a name found on a connected machine (needs no
139
+ * install), or neither (look the id up in the store).
140
+ */
141
+ function describeStoreSkillMiss(arg, sightings, command) {
142
+ const verb = command === 'install' ? 'installs' : 'shows';
143
+ if (looksLikeSkillPath(arg)) {
144
+ return [
145
+ `\`skills ${command}\` ${verb} a skill from the store by its id; "${arg}" is a path.`,
146
+ "A skill in one of your machine's skill roots needs no install.",
147
+ '→ See what your machine has: skrr skills local',
148
+ '→ Use one on a turn: skrr agents chat <agent-id> --local-skill <name>',
149
+ ].join('\n');
150
+ }
151
+ if (sightings.length > 0) {
152
+ const where = sightings
153
+ .map((s) => `${s.daemonId}${s.deviceName ? ` (${s.deviceName})` : ''}${s.source ? `, ${s.source}` : ''}`)
154
+ .join('; ');
155
+ return [
156
+ `No store skill has the id "${arg}", but a skill named "${arg}" is on your machine: ${where}.`,
157
+ 'It needs no install.',
158
+ `→ Use it on a turn: skrr agents chat <agent-id> --local-skill ${arg.replace(/^\//, '')}`,
159
+ ].join('\n');
160
+ }
161
+ return [
162
+ `No store skill has the id "${arg}".`,
163
+ '→ Find a store id: skrr skills search <term>',
164
+ '→ Skills on your machine are not in the store: skrr skills local',
165
+ ].join('\n');
166
+ }
167
+ /**
168
+ * The first daemon release whose walker scans the skill conventions — the
169
+ * project's `.claude/skills`, `.agents/skills`, `.devin/skills`,
170
+ * `.windsurf/skills` and the global `~/.claude/skills`. It arrived in
171
+ * `e9dfa732cd` and first shipped in 0.8.44; an older daemon scans only
172
+ * `claudeSession.skillsDir`, which is empty unless someone set it by hand.
173
+ */
174
+ exports.SKILL_CONVENTION_DISCOVERY_SINCE = '0.8.44';
175
+ /**
176
+ * Whether a daemon's reported version is older than `floor`.
177
+ *
178
+ * Unknown or unparseable versions answer false: this decides only whether to
179
+ * add an explanation, and claiming an unknown daemon is old would be a guess.
180
+ */
181
+ function daemonPredates(version, floor) {
182
+ const parse = (value) => {
183
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(String(value ?? '').trim());
184
+ return match ? match.slice(1).map(Number) : null;
185
+ };
186
+ const have = parse(version);
187
+ const need = parse(floor);
188
+ if (!have || !need)
189
+ return false;
190
+ for (let i = 0; i < 3; i += 1) {
191
+ if (have[i] !== need[i])
192
+ return have[i] < need[i];
193
+ }
194
+ return false;
195
+ }
@@ -59,6 +59,16 @@ export interface Machine {
59
59
  identityKind: MachineIdentityKind;
60
60
  name: string;
61
61
  status: 'online' | 'offline' | 'degraded';
62
+ /**
63
+ * One sentence naming what decided the status, or null when nothing needs
64
+ * explaining. Optional because the CLI ships separately from the server.
65
+ *
66
+ * `degraded` alone is unactionable, and on a laptop it is usually permanent —
67
+ * one offline row for a provider that was uninstalled holds the verdict
68
+ * forever, because supersession needs a NEWER row for the same provider and
69
+ * none will ever arrive.
70
+ */
71
+ statusReason?: string | null;
62
72
  machineUuid: string | null;
63
73
  stableDaemonId: string | null;
64
74
  daemonId: string | null;
@@ -135,14 +145,4 @@ export declare function listMachines(): Promise<Machine[]>;
135
145
  export declare function getMachine(machineId: string): Promise<Machine | null>;
136
146
  export declare function updateMachine(machineId: string, patch: MachinePreferencesPatch): Promise<Machine | null>;
137
147
  export declare function disconnectMachine(machineId: string): Promise<Record<string, unknown> | null>;
138
- /**
139
- * Resolve a user-supplied reference to exactly one machine.
140
- *
141
- * A machine is addressable by several ids (`id`, `machineUuid`,
142
- * `stableDaemonId`, `daemonId`) and `skrr harnesses list` prints a TRUNCATED
143
- * uuid, so the id a user has to hand is often a prefix of the one the API
144
- * wants. Resolving here keeps every command accepting the same references, and
145
- * makes an ambiguous prefix an error rather than a silent pick of the first
146
- * match.
147
- */
148
148
  export declare function resolveMachineRef(machines: Machine[], ref: string): Machine;
@@ -93,13 +93,35 @@ async function disconnectMachine(machineId) {
93
93
  * makes an ambiguous prefix an error rather than a silent pick of the first
94
94
  * match.
95
95
  */
96
+ /**
97
+ * The daemon ids a hosted machine's sandbox id can appear inside.
98
+ *
99
+ * `machines hosted list` prints `sbs_…`; the machine row carries
100
+ * `hosted-machine-sbs_…` as its daemon id. Composed rather than matched by
101
+ * substring so a longer id cannot be resolved by a shorter one's text.
102
+ */
103
+ function hostedSandboxDaemonIds(ref) {
104
+ if (!ref.startsWith('sbs_'))
105
+ return [];
106
+ return [`hosted-machine-${ref}`, `hosted-job-machine-${ref}`];
107
+ }
96
108
  function resolveMachineRef(machines, ref) {
97
109
  const needle = ref.trim();
98
110
  const lower = needle.toLowerCase();
99
111
  const exact = machines.filter((m) => m.id === needle ||
100
112
  m.machineUuid === needle ||
101
113
  m.stableDaemonId === needle ||
102
- m.daemonId === needle);
114
+ m.daemonId === needle ||
115
+ // The sandbox id, which is the ONLY id `machines hosted list` prints.
116
+ // One hosted machine carries five identifiers and, before this, the one
117
+ // its own list showed you was the one `machines show` refused: the
118
+ // sandbox id appears here only INSIDE the daemon id, as
119
+ // `hosted-machine-<sbs_…>`, while `machines list --all` shows the same
120
+ // box as `lease:rtl_…` — a different random string entirely. Two lists,
121
+ // two unrelated-looking ids, no way on screen to tell they are one
122
+ // machine. Exact composition, not a substring search, so this cannot
123
+ // match a machine that merely contains the text.
124
+ hostedSandboxDaemonIds(needle).some((candidate) => m.daemonId === candidate));
103
125
  if (exact.length === 1)
104
126
  return exact[0];
105
127
  const byName = machines.filter((m) => m.name?.toLowerCase() === lower);
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The search term, from a positional or `--query`, resolved the same way by
3
+ * both spellings of the same search.
4
+ *
5
+ * `skills search` and `search skills` run the identical store search. Neither
6
+ * accepted the obvious invocation — `skrr skills search git` — so the single
7
+ * most natural way to call a search command failed on both, and `--query` was
8
+ * `required` on both, which is what made it fail rather than prompt.
9
+ *
10
+ * Shared rather than copied because the two spellings staying in step is the
11
+ * whole point: the reason a reader could not tell them apart was that they had
12
+ * drifted (different one-liners, short flags on one of them), and a second copy
13
+ * of this is how that starts again.
14
+ */
15
+ export declare function resolveSearchQuery(cmd: {
16
+ error: (message: string, options?: {
17
+ exit?: number;
18
+ }) => never;
19
+ }, positional: string | undefined, flag: string | undefined, command: string): string;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveSearchQuery = resolveSearchQuery;
4
+ /**
5
+ * The search term, from a positional or `--query`, resolved the same way by
6
+ * both spellings of the same search.
7
+ *
8
+ * `skills search` and `search skills` run the identical store search. Neither
9
+ * accepted the obvious invocation — `skrr skills search git` — so the single
10
+ * most natural way to call a search command failed on both, and `--query` was
11
+ * `required` on both, which is what made it fail rather than prompt.
12
+ *
13
+ * Shared rather than copied because the two spellings staying in step is the
14
+ * whole point: the reason a reader could not tell them apart was that they had
15
+ * drifted (different one-liners, short flags on one of them), and a second copy
16
+ * of this is how that starts again.
17
+ */
18
+ function resolveSearchQuery(cmd, positional, flag, command) {
19
+ const fromPositional = positional?.trim();
20
+ const fromFlag = flag?.trim();
21
+ // Both given and DIFFERENT is a real ambiguity — refuse rather than pick.
22
+ // Both given and identical is a script that passes belt and braces; that is
23
+ // not an error and silently accepting it costs nobody anything.
24
+ if (fromPositional && fromFlag && fromPositional !== fromFlag) {
25
+ cmd.error(`Two different search terms: "${fromPositional}" and --query "${fromFlag}". Pass one.`, { exit: 2 });
26
+ }
27
+ const query = fromPositional || fromFlag;
28
+ if (!query) {
29
+ // `--query` used to be `required`, so oclif refused with its own generic
30
+ // sentence. Naming the shape people actually type is the point of the
31
+ // change, so the error names it too.
32
+ cmd.error(`What should I search for? Try \`skrr ${command} <term>\`.`, { exit: 2 });
33
+ }
34
+ return query;
35
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Shared shape for `skrr spaces actions add|update`.
3
+ *
4
+ * Both commands describe the same stored object, and they had drifted from the
5
+ * server that validates it (`spaceCustomActionSchema` in api/server/routes/spaces.js).
6
+ */
7
+ import type { SpaceCustomAction, SpaceMemberActionsResponse } from '@skrr-ai/data-provider';
8
+ /**
9
+ * The server's limit on `icon`, which is `z.string().max(4)`.
10
+ *
11
+ * The flag used to be documented as "Lucide icon name". It is not one: the web
12
+ * settings page renders `action.icon` as literal text, and almost no Lucide name
13
+ * fits in four characters, so following the help produced a 400 with a raw Zod
14
+ * message and no hint that an emoji was wanted (OSK-9631).
15
+ *
16
+ * Zod's `max` counts UTF-16 code units, not visible characters, so the check
17
+ * below uses `String.prototype.length` to agree with it exactly. Counting
18
+ * graphemes instead would accept a family emoji the server then refuses.
19
+ */
20
+ export declare const SPACE_CUSTOM_ACTION_ICON_MAX = 4;
21
+ export declare const spaceCustomActionIconFlag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ export declare const spaceCustomActionLabelFlag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ /** Refuse an icon the server would refuse, with a message that says what fits. */
24
+ export declare function spaceCustomActionIconProblem(icon: unknown): string | null;
25
+ type SpaceWithActions = {
26
+ id: string;
27
+ title?: string;
28
+ leadAgentId?: string | null;
29
+ customActions?: SpaceCustomAction[] | null;
30
+ };
31
+ /**
32
+ * Why a space's OWN actions cannot run, or null when they can.
33
+ *
34
+ * A space custom action runs as a task assigned to the Space Leader, so on a
35
+ * space with no Leader every one of them is dead on arrival. That fact used to
36
+ * live only in a tooltip on a disabled web button: `spaces actions add` reported
37
+ * success, `spaces actions list` listed the action happily, and nothing on the
38
+ * CLI said it could never run (OSK-9641).
39
+ */
40
+ export declare function spaceActionsNotRunnableReason(space: Pick<SpaceWithActions, 'id' | 'leadAgentId'>, bin: string): string | null;
41
+ /**
42
+ * Find a space custom action by the id `spaces actions list` prints, or by the
43
+ * `space-custom:<id>` form the projected quick-action surfaces use.
44
+ */
45
+ export declare function findSpaceCustomAction(space: SpaceWithActions, ref: string): {
46
+ customAction: SpaceCustomAction;
47
+ index: number;
48
+ } | {
49
+ problem: string;
50
+ };
51
+ export type SpaceQuickActionRow = {
52
+ source: 'space' | 'agent';
53
+ title: string;
54
+ owner: string;
55
+ type: string;
56
+ ref: string;
57
+ run: string;
58
+ };
59
+ /**
60
+ * Everything a space's action panel offers, in the order the web shows it: the
61
+ * space's own actions first, then the actions of member agents the caller can
62
+ * view, filtered by scope with the same predicate the web and server use.
63
+ *
64
+ * `spaces actions list` showed only the first half and `spaces actions
65
+ * available` a wider second half (every member agent, including ones the caller
66
+ * cannot run), so "what can I run here?" had no answer on the CLI (OSK-9641).
67
+ * Every row's `run` is a command `spaces actions run` accepts.
68
+ */
69
+ export declare function spaceQuickActionRows(space: SpaceWithActions & {
70
+ labelIds?: string[] | null;
71
+ }, members: SpaceMemberActionsResponse['agents'], bin: string): SpaceQuickActionRow[];
72
+ export {};