@skrr-ai/cli 0.1.92 → 0.1.93

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 (267) hide show
  1. package/dist/base-command.d.ts +44 -0
  2. package/dist/base-command.js +96 -0
  3. package/dist/commands/agents/badge.d.ts +41 -0
  4. package/dist/commands/agents/badge.js +158 -0
  5. package/dist/commands/agents/create.d.ts +24 -0
  6. package/dist/commands/agents/create.js +212 -0
  7. package/dist/commands/agents/embed.d.ts +20 -0
  8. package/dist/commands/agents/embed.js +61 -0
  9. package/dist/commands/agents/share.d.ts +27 -0
  10. package/dist/commands/agents/share.js +100 -0
  11. package/dist/commands/agents/vanity.d.ts +21 -0
  12. package/dist/commands/agents/vanity.js +77 -0
  13. package/dist/commands/agents/visibility.d.ts +21 -1
  14. package/dist/commands/agents/visibility.js +112 -0
  15. package/dist/commands/commands.d.ts +1 -0
  16. package/dist/commands/commands.js +22 -9
  17. package/dist/commands/earnings/attributions.d.ts +17 -0
  18. package/dist/commands/earnings/attributions.js +82 -0
  19. package/dist/commands/earnings/index.js +2 -1
  20. package/dist/commands/generate-recovery-code.js +4 -3
  21. package/dist/commands/github/allow-tools.d.ts +1 -0
  22. package/dist/commands/github/app/install.d.ts +1 -0
  23. package/dist/commands/github/app/status.d.ts +1 -0
  24. package/dist/commands/github/connect.d.ts +1 -0
  25. package/dist/commands/github/connections.d.ts +1 -0
  26. package/dist/commands/github/disconnect.d.ts +1 -0
  27. package/dist/commands/github/finalize.d.ts +1 -0
  28. package/dist/commands/github/reconnect.d.ts +1 -0
  29. package/dist/commands/github/run.d.ts +1 -0
  30. package/dist/commands/github/tools.d.ts +1 -0
  31. package/dist/commands/integrations/connections/connect.d.ts +1 -0
  32. package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
  33. package/dist/commands/integrations/connections/finalize.d.ts +1 -0
  34. package/dist/commands/integrations/connections/list.d.ts +1 -0
  35. package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
  36. package/dist/commands/integrations/execute.d.ts +1 -0
  37. package/dist/commands/integrations/search.d.ts +1 -0
  38. package/dist/commands/integrations/toolkits.d.ts +1 -0
  39. package/dist/commands/integrations/tools/allow.d.ts +1 -0
  40. package/dist/commands/integrations/tools/list.d.ts +1 -0
  41. package/dist/commands/login.js +12 -0
  42. package/dist/commands/machines/dedicated/logs.d.ts +19 -0
  43. package/dist/commands/machines/dedicated/logs.js +103 -0
  44. package/dist/commands/machines/dedicated/power/set.js +1 -1
  45. package/dist/commands/open.d.ts +24 -0
  46. package/dist/commands/open.js +74 -0
  47. package/dist/commands/projects/archive.d.ts +1 -0
  48. package/dist/commands/projects/archive.js +23 -0
  49. package/dist/commands/projects/delete.d.ts +1 -0
  50. package/dist/commands/projects/delete.js +23 -0
  51. package/dist/commands/projects/list.d.ts +3 -0
  52. package/dist/commands/projects/list.js +12 -2
  53. package/dist/commands/spaces/actions/add.js +4 -3
  54. package/dist/commands/spaces/actions/available.js +3 -2
  55. package/dist/commands/spaces/actions/list.js +5 -4
  56. package/dist/commands/spaces/actions/replace.js +6 -5
  57. package/dist/commands/spaces/archive.js +3 -2
  58. package/dist/commands/spaces/auto-executor/preview.js +4 -3
  59. package/dist/commands/spaces/auto-executor/run.js +4 -3
  60. package/dist/commands/spaces/auto-executor/runs.js +3 -2
  61. package/dist/commands/spaces/auto-executor/update.js +4 -3
  62. package/dist/commands/spaces/bootstrap.js +3 -2
  63. package/dist/commands/spaces/briefs/delete.js +3 -2
  64. package/dist/commands/spaces/briefs/get.js +3 -2
  65. package/dist/commands/spaces/briefs/list.js +3 -2
  66. package/dist/commands/spaces/briefs/set.js +5 -4
  67. package/dist/commands/spaces/capacity.js +5 -4
  68. package/dist/commands/spaces/conversations.js +3 -2
  69. package/dist/commands/spaces/cycles/create.js +3 -2
  70. package/dist/commands/spaces/cycles/graph.js +2 -1
  71. package/dist/commands/spaces/cycles/list.js +3 -2
  72. package/dist/commands/spaces/cycles/settings.js +4 -3
  73. package/dist/commands/spaces/cycles/show.js +3 -2
  74. package/dist/commands/spaces/cycles/update.js +3 -2
  75. package/dist/commands/spaces/delete.js +4 -3
  76. package/dist/commands/spaces/expertise-suggestions.js +4 -3
  77. package/dist/commands/spaces/files/delete.js +3 -2
  78. package/dist/commands/spaces/files/folders/create.js +3 -2
  79. package/dist/commands/spaces/files/folders/delete.js +3 -2
  80. package/dist/commands/spaces/files/folders/list.js +3 -2
  81. package/dist/commands/spaces/files/folders/update.js +3 -2
  82. package/dist/commands/spaces/files/list.js +3 -2
  83. package/dist/commands/spaces/files/move.js +3 -2
  84. package/dist/commands/spaces/files/rename.js +3 -2
  85. package/dist/commands/spaces/files/upload.js +6 -5
  86. package/dist/commands/spaces/github-automations/set.js +3 -2
  87. package/dist/commands/spaces/github-automations/show.js +3 -2
  88. package/dist/commands/spaces/goals.js +2 -1
  89. package/dist/commands/spaces/heartbeats/create.js +4 -3
  90. package/dist/commands/spaces/heartbeats/delete.js +4 -3
  91. package/dist/commands/spaces/heartbeats/list.js +4 -3
  92. package/dist/commands/spaces/heartbeats/status.js +3 -2
  93. package/dist/commands/spaces/heartbeats/update.js +4 -3
  94. package/dist/commands/spaces/insights.js +5 -4
  95. package/dist/commands/spaces/labels/add.js +4 -3
  96. package/dist/commands/spaces/labels/list.js +2 -1
  97. package/dist/commands/spaces/labels/remove.js +4 -3
  98. package/dist/commands/spaces/list.d.ts +3 -0
  99. package/dist/commands/spaces/list.js +11 -2
  100. package/dist/commands/spaces/live/cards/create.js +3 -2
  101. package/dist/commands/spaces/live/cards/list.js +3 -2
  102. package/dist/commands/spaces/live/cards/reorder.js +7 -2
  103. package/dist/commands/spaces/live/scene.js +4 -3
  104. package/dist/commands/spaces/members/add.js +7 -6
  105. package/dist/commands/spaces/members/list.js +4 -3
  106. package/dist/commands/spaces/members/remove.js +7 -6
  107. package/dist/commands/spaces/move.js +3 -2
  108. package/dist/commands/spaces/pin.js +5 -4
  109. package/dist/commands/spaces/preferences/show.js +4 -3
  110. package/dist/commands/spaces/preferences/tabs.js +4 -3
  111. package/dist/commands/spaces/revisions.js +3 -2
  112. package/dist/commands/spaces/room/ensure.js +5 -4
  113. package/dist/commands/spaces/room/messages.js +3 -2
  114. package/dist/commands/spaces/room/show.js +5 -4
  115. package/dist/commands/spaces/skills/add.js +4 -3
  116. package/dist/commands/spaces/skills/list.js +3 -2
  117. package/dist/commands/spaces/skills/pin.js +4 -3
  118. package/dist/commands/spaces/skills/remove.js +4 -3
  119. package/dist/commands/spaces/snapshot.js +3 -2
  120. package/dist/commands/spaces/states/archive.js +3 -2
  121. package/dist/commands/spaces/states/create.js +3 -2
  122. package/dist/commands/spaces/states/list.js +3 -2
  123. package/dist/commands/spaces/states/reorder.js +2 -1
  124. package/dist/commands/spaces/states/update.js +3 -2
  125. package/dist/commands/spaces/summary.js +4 -3
  126. package/dist/commands/spaces/tasks.d.ts +3 -0
  127. package/dist/commands/spaces/tasks.js +14 -3
  128. package/dist/commands/spaces/triggers/delete.js +5 -4
  129. package/dist/commands/spaces/triggers/set.js +4 -3
  130. package/dist/commands/spaces/triggers/show.js +4 -3
  131. package/dist/commands/spaces/unarchive.js +3 -2
  132. package/dist/commands/spaces/update.js +5 -4
  133. package/dist/commands/spaces/views/create.js +3 -2
  134. package/dist/commands/spaces/views/list.js +3 -2
  135. package/dist/commands/spaces/views/reorder.js +6 -3
  136. package/dist/commands/spaces/views/subscribe.js +2 -1
  137. package/dist/commands/spaces/views/subscriptions.js +1 -0
  138. package/dist/commands/spaces/views/unsubscribe.js +2 -1
  139. package/dist/commands/spaces/widgets/add.js +4 -3
  140. package/dist/commands/spaces/widgets/list.js +3 -2
  141. package/dist/commands/spaces/widgets/remove.js +5 -4
  142. package/dist/commands/spaces/work-graph.js +2 -1
  143. package/dist/commands/store/install.d.ts +1 -1
  144. package/dist/commands/store/install.js +24 -8
  145. package/dist/commands/store/show.d.ts +25 -0
  146. package/dist/commands/store/show.js +203 -0
  147. package/dist/commands/store/stats.d.ts +33 -0
  148. package/dist/commands/store/stats.js +258 -0
  149. package/dist/commands/tasks/actions/attach.js +1 -1
  150. package/dist/commands/tasks/actions/detach.js +4 -3
  151. package/dist/commands/tasks/activity.js +3 -2
  152. package/dist/commands/tasks/ancestors.js +2 -1
  153. package/dist/commands/tasks/approvals/create.js +2 -1
  154. package/dist/commands/tasks/approvals/delete.js +3 -2
  155. package/dist/commands/tasks/approvals/list.js +5 -4
  156. package/dist/commands/tasks/approvals/resolve.js +2 -1
  157. package/dist/commands/tasks/archive.js +3 -2
  158. package/dist/commands/tasks/assign.js +4 -3
  159. package/dist/commands/tasks/attachments/delete.js +3 -2
  160. package/dist/commands/tasks/attachments/download.d.ts +1 -0
  161. package/dist/commands/tasks/attachments/download.js +20 -1
  162. package/dist/commands/tasks/attachments/list.js +2 -1
  163. package/dist/commands/tasks/attachments/set-role.js +2 -1
  164. package/dist/commands/tasks/attachments/upload.js +2 -1
  165. package/dist/commands/tasks/bulk-update.d.ts +1 -0
  166. package/dist/commands/tasks/bulk-update.js +106 -15
  167. package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
  168. package/dist/commands/tasks/cancel-cascade.js +13 -3
  169. package/dist/commands/tasks/cascade-status.js +2 -1
  170. package/dist/commands/tasks/checkout.js +3 -2
  171. package/dist/commands/tasks/children.js +2 -1
  172. package/dist/commands/tasks/comments/add.js +7 -6
  173. package/dist/commands/tasks/comments/anchor.js +8 -7
  174. package/dist/commands/tasks/comments/delete.js +3 -2
  175. package/dist/commands/tasks/comments/list.js +2 -1
  176. package/dist/commands/tasks/comments/reopen.js +3 -2
  177. package/dist/commands/tasks/comments/resolve.js +3 -2
  178. package/dist/commands/tasks/create-tree.d.ts +63 -0
  179. package/dist/commands/tasks/create-tree.js +197 -4
  180. package/dist/commands/tasks/delete.js +5 -4
  181. package/dist/commands/tasks/descendants.js +2 -1
  182. package/dist/commands/tasks/dri-plan.js +3 -2
  183. package/dist/commands/tasks/dri-run.js +3 -2
  184. package/dist/commands/tasks/dri-status.js +2 -1
  185. package/dist/commands/tasks/duplicate-pipeline.js +2 -1
  186. package/dist/commands/tasks/execution-summary.js +2 -1
  187. package/dist/commands/tasks/execution-timeline.js +2 -1
  188. package/dist/commands/tasks/fork.js +1 -0
  189. package/dist/commands/tasks/forward.js +4 -3
  190. package/dist/commands/tasks/handover.js +1 -0
  191. package/dist/commands/tasks/interrupt.js +3 -2
  192. package/dist/commands/tasks/labels/attach.js +4 -3
  193. package/dist/commands/tasks/labels/detach.js +4 -3
  194. package/dist/commands/tasks/labels/suggest.js +5 -4
  195. package/dist/commands/tasks/list.d.ts +27 -1
  196. package/dist/commands/tasks/list.js +101 -3
  197. package/dist/commands/tasks/move.js +4 -3
  198. package/dist/commands/tasks/output.js +6 -5
  199. package/dist/commands/tasks/pause-schedule.js +3 -2
  200. package/dist/commands/tasks/promote.js +1 -0
  201. package/dist/commands/tasks/prompt-log.js +2 -1
  202. package/dist/commands/tasks/release.js +5 -4
  203. package/dist/commands/tasks/remind.js +2 -1
  204. package/dist/commands/tasks/replay.js +3 -2
  205. package/dist/commands/tasks/report.js +1 -0
  206. package/dist/commands/tasks/resume-schedule.js +3 -2
  207. package/dist/commands/tasks/retry-schedule.js +3 -2
  208. package/dist/commands/tasks/retry.js +10 -9
  209. package/dist/commands/tasks/revisions.js +2 -1
  210. package/dist/commands/tasks/runs.js +6 -5
  211. package/dist/commands/tasks/schedule.js +3 -2
  212. package/dist/commands/tasks/self-schedule.js +6 -5
  213. package/dist/commands/tasks/skills/pin.js +3 -2
  214. package/dist/commands/tasks/skills/unpin.js +3 -2
  215. package/dist/commands/tasks/snooze.js +6 -5
  216. package/dist/commands/tasks/start-all.js +5 -4
  217. package/dist/commands/tasks/subscribe.js +1 -0
  218. package/dist/commands/tasks/tags/add.js +4 -3
  219. package/dist/commands/tasks/tags/remove.js +4 -3
  220. package/dist/commands/tasks/timeline.js +3 -2
  221. package/dist/commands/tasks/today.d.ts +4 -1
  222. package/dist/commands/tasks/today.js +12 -2
  223. package/dist/commands/tasks/transcript.js +6 -5
  224. package/dist/commands/tasks/unschedule.js +3 -2
  225. package/dist/commands/tasks/unsnooze.js +3 -2
  226. package/dist/commands/tasks/unsubscribe.js +2 -1
  227. package/dist/commands/tasks/update.js +5 -4
  228. package/dist/commands/tasks/wait.js +5 -4
  229. package/dist/lib/agent-distribution.d.ts +37 -0
  230. package/dist/lib/agent-distribution.js +63 -0
  231. package/dist/lib/agent-ref.d.ts +69 -0
  232. package/dist/lib/agent-ref.js +168 -0
  233. package/dist/lib/api-fetch.d.ts +2 -0
  234. package/dist/lib/api-fetch.js +14 -3
  235. package/dist/lib/command-hygiene.d.ts +13 -0
  236. package/dist/lib/command-hygiene.js +62 -2
  237. package/dist/lib/dedicated-power.d.ts +5 -0
  238. package/dist/lib/dedicated-power.js +30 -2
  239. package/dist/lib/dry-run-plans.d.ts +50 -0
  240. package/dist/lib/dry-run-plans.js +85 -0
  241. package/dist/lib/json-output.d.ts +31 -0
  242. package/dist/lib/json-output.js +78 -0
  243. package/dist/lib/list-output.d.ts +75 -0
  244. package/dist/lib/list-output.js +266 -0
  245. package/dist/lib/machine-daemon-log.d.ts +36 -0
  246. package/dist/lib/machine-daemon-log.js +78 -0
  247. package/dist/lib/node-adapter.js +10 -1
  248. package/dist/lib/open-target.d.ts +12 -0
  249. package/dist/lib/open-target.js +108 -0
  250. package/dist/lib/rate-limit-retry.d.ts +45 -0
  251. package/dist/lib/rate-limit-retry.js +88 -0
  252. package/dist/lib/store-listing.d.ts +45 -0
  253. package/dist/lib/store-listing.js +186 -0
  254. package/dist/lib/task-batch.d.ts +67 -0
  255. package/dist/lib/task-batch.js +227 -0
  256. package/dist/lib/terminal-qr.d.ts +55 -0
  257. package/dist/lib/terminal-qr.js +119 -0
  258. package/dist/lib/web-url.d.ts +11 -0
  259. package/dist/lib/web-url.js +24 -0
  260. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
  261. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
  262. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
  263. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
  264. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  265. package/dist/node_modules/@skrr-ai/data-provider/index.js +6612 -6113
  266. package/oclif.manifest.json +46778 -38019
  267. package/package.json +2 -1
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * Storage-field stripping for `--json` output (audit P9).
4
+ *
5
+ * The API returns Mongo documents, so every row carries `_id` and `__v` beside
6
+ * the real `id`: 47 keys per task row, two of which are storage detail an agent
7
+ * pays tokens for and can mistake for the identifier (OSK-12205 was exactly
8
+ * that: a 24-hex `_id` passed where a task id was wanted).
9
+ *
10
+ * This runs at the CLI SERIALIZER only (`BaseCommand.log`), never in the API or
11
+ * the data layer, so no other consumer's payload changes. `--raw` (or
12
+ * `OVERSKY_CLI_RAW=1`) turns it off for the caller that does want them.
13
+ *
14
+ * Two rules, both conservative:
15
+ * - `__v` is the Mongoose version key and is always dropped.
16
+ * - `_id` is dropped only when the same object has a usable `id`. A row that
17
+ * has ONLY `_id` (some legacy collections) keeps it: removing the sole
18
+ * identifier would turn a cosmetic cleanup into data loss.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.stripStorageFields = stripStorageFields;
22
+ exports.stripStorageFieldsFromText = stripStorageFieldsFromText;
23
+ function usableId(value) {
24
+ return (typeof value === 'string' && value.length > 0) || typeof value === 'number';
25
+ }
26
+ /**
27
+ * Returns the SAME reference when nothing needed stripping, so a caller can tell
28
+ * "unchanged" apart from "rebuilt" and leave the original text alone.
29
+ */
30
+ function stripStorageFields(value) {
31
+ if (Array.isArray(value)) {
32
+ let changed = false;
33
+ const next = value.map((item) => {
34
+ const stripped = stripStorageFields(item);
35
+ if (stripped !== item)
36
+ changed = true;
37
+ return stripped;
38
+ });
39
+ return changed ? next : value;
40
+ }
41
+ if (value === null || typeof value !== 'object')
42
+ return value;
43
+ const source = value;
44
+ const dropId = '_id' in source && usableId(source.id);
45
+ const dropVersion = '__v' in source;
46
+ let changed = dropId || dropVersion;
47
+ const next = {};
48
+ for (const [key, child] of Object.entries(source)) {
49
+ if ((key === '_id' && dropId) || (key === '__v' && dropVersion))
50
+ continue;
51
+ const stripped = stripStorageFields(child);
52
+ if (stripped !== child)
53
+ changed = true;
54
+ next[key] = stripped;
55
+ }
56
+ return changed ? next : value;
57
+ }
58
+ /**
59
+ * Apply {@link stripStorageFields} to one line of CLI output. Anything that is
60
+ * not a JSON object/array (prose, a bare string, malformed text) is returned
61
+ * untouched, as is JSON with nothing to strip, so existing formatting survives.
62
+ */
63
+ function stripStorageFieldsFromText(text) {
64
+ const head = text.trimStart()[0];
65
+ if (head !== '{' && head !== '[')
66
+ return text;
67
+ let parsed;
68
+ try {
69
+ parsed = JSON.parse(text);
70
+ }
71
+ catch {
72
+ return text;
73
+ }
74
+ const stripped = stripStorageFields(parsed);
75
+ if (stripped === parsed)
76
+ return text;
77
+ return JSON.stringify(stripped, null, text.includes('\n') ? 2 : undefined);
78
+ }
@@ -0,0 +1,75 @@
1
+ export type ListWarning = {
2
+ code: string;
3
+ value?: unknown;
4
+ hint: string;
5
+ };
6
+ export type ListEnvelope = {
7
+ object: 'list';
8
+ data: Array<Record<string, unknown>>;
9
+ has_more: boolean;
10
+ next_cursor: string | null;
11
+ limit_applied?: number;
12
+ warnings?: ListWarning[];
13
+ } & Record<string, unknown>;
14
+ /**
15
+ * The navigation projection per resource: enough to identify a row, decide
16
+ * whether it matters and fetch it with `show`. Allowlists, not drop-lists, so a
17
+ * field the server adds tomorrow does not silently re-inflate every compact row.
18
+ * Documented in docs/cli/SKRR_TASKS.md (List output for agents).
19
+ */
20
+ export declare const COMPACT_FIELDS: {
21
+ readonly task: readonly ["id", "identifier", "ref", "title", "status", "statusType", "priority", "estimate", "assigneeAgentIds", "assigneeUserIds", "parentId", "spaceId", "projectId", "goalId", "dueDate", "scheduledFor", "labelIds", "tags", "externalKey", "version", "executionMode", "nextAction", "createdAt", "updatedAt", "url"];
22
+ readonly space: readonly ["id", "identifier", "title", "status", "parentSpaceId", "leadAgentId", "labelIds", "archivedAt", "createdAt", "updatedAt", "url"];
23
+ readonly project: readonly ["id", "identifier", "title", "spaceId", "externalKey", "taskCounts", "archivedAt", "createdAt", "updatedAt", "url"];
24
+ };
25
+ export type ListResource = keyof typeof COMPACT_FIELDS;
26
+ /** The three flags every projecting list command declares. */
27
+ export declare const listOutputFlags: {
28
+ fields: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
29
+ compact: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
30
+ ndjson: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
31
+ };
32
+ export type ListOutputFlags = {
33
+ fields?: string;
34
+ compact?: boolean;
35
+ ndjson?: boolean;
36
+ };
37
+ /** `--fields a, b ,c` -> ['a','b','c']; empty/blank -> undefined. */
38
+ export declare function parseFields(raw: string | undefined): string[] | undefined;
39
+ export declare function projectRow(row: Record<string, unknown>, fields: readonly string[]): Record<string, unknown>;
40
+ /**
41
+ * Normalize any list response to the shared envelope. `data` is where rows live
42
+ * for every list command; `projects` (an older serialization) is folded into it.
43
+ * A response that is not list-shaped is returned untouched (never invent rows).
44
+ */
45
+ export declare function toListEnvelope(response: unknown): ListEnvelope | undefined;
46
+ export type ShapeListOptions = ListOutputFlags & {
47
+ resource: ListResource;
48
+ /** What the caller asked for with --limit (undefined when the command has none). */
49
+ requestedLimit?: number;
50
+ warnings?: ListWarning[];
51
+ /** A filter the CLI applied that the caller did not ask for (E12). Echoed as `filter_applied`. */
52
+ filterApplied?: Record<string, unknown>;
53
+ };
54
+ /** Pure: envelope + projection + notes. Returns the response untouched if not a list. */
55
+ export declare function shapeListResponse(response: unknown, options: ShapeListOptions): unknown;
56
+ /**
57
+ * E11: the server silently clamps `--limit` (cap) and coerces `0` to its default.
58
+ * Echo what was applied. `applied` is only reported when we can prove it: a full
59
+ * page that still has more rows means the cap is exactly the row count.
60
+ */
61
+ export declare function limitNote(requested: number | undefined, rowCount: number, hasMore: boolean): {
62
+ applied?: number;
63
+ warning?: ListWarning;
64
+ };
65
+ /** The text-mode twin of a warning: one `Note:` line a person can act on. */
66
+ export declare function warningLines(warnings: readonly ListWarning[] | undefined): string[];
67
+ export type ListOutput = {
68
+ stdout: string[];
69
+ stderr: string[];
70
+ };
71
+ /**
72
+ * Render a shaped list for `--json` (pretty envelope) or `--ndjson` (rows one per
73
+ * line, `_meta` on stderr). Pure; the caller writes the lines.
74
+ */
75
+ export declare function renderListOutput(shaped: unknown, ndjson: boolean): ListOutput;
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listOutputFlags = exports.COMPACT_FIELDS = void 0;
4
+ exports.parseFields = parseFields;
5
+ exports.projectRow = projectRow;
6
+ exports.toListEnvelope = toListEnvelope;
7
+ exports.shapeListResponse = shapeListResponse;
8
+ exports.limitNote = limitNote;
9
+ exports.warningLines = warningLines;
10
+ exports.renderListOutput = renderListOutput;
11
+ /**
12
+ * Shared output shaping for `skrr` LIST commands (agent-surface audit
13
+ * OSK-14039 / OSK-14040: P3, P4, E1, E11).
14
+ *
15
+ * A list command's `--json` used to print whatever the server sent: 4.4 KB per
16
+ * task, 38% of it `activityLog`, with no way to ask for less, and an envelope
17
+ * that differed per command. This module is the one place that decides:
18
+ *
19
+ * - the ENVELOPE: `{object:'list', data, has_more, next_cursor, ...}`, the same
20
+ * for every list command (`data` is always the row array, so a consumer that
21
+ * read `.data` keeps working);
22
+ * - the PROJECTION: `--fields a,b,c` (explicit, wins) or `--compact` (a
23
+ * documented per-resource navigation set), applied to `data` rows only;
24
+ * - `--ndjson`: one JSON row per line on stdout, metadata on stderr;
25
+ * - NOTES: `limit_applied` / `warnings[]`, so "the server clamped your limit" and
26
+ * "your filter matched nothing because it is not a state id" are visible in
27
+ * JSON the way they already are in text.
28
+ *
29
+ * Pure functions, no oclif: the commands own I/O, this owns the shape.
30
+ */
31
+ const core_1 = require("@oclif/core");
32
+ /**
33
+ * The navigation projection per resource: enough to identify a row, decide
34
+ * whether it matters and fetch it with `show`. Allowlists, not drop-lists, so a
35
+ * field the server adds tomorrow does not silently re-inflate every compact row.
36
+ * Documented in docs/cli/SKRR_TASKS.md (List output for agents).
37
+ */
38
+ exports.COMPACT_FIELDS = {
39
+ task: [
40
+ 'id',
41
+ 'identifier',
42
+ 'ref',
43
+ 'title',
44
+ 'status',
45
+ 'statusType',
46
+ 'priority',
47
+ 'estimate',
48
+ 'assigneeAgentIds',
49
+ 'assigneeUserIds',
50
+ 'parentId',
51
+ 'spaceId',
52
+ 'projectId',
53
+ 'goalId',
54
+ 'dueDate',
55
+ 'scheduledFor',
56
+ 'labelIds',
57
+ 'tags',
58
+ 'externalKey',
59
+ 'version',
60
+ 'executionMode',
61
+ 'nextAction',
62
+ 'createdAt',
63
+ 'updatedAt',
64
+ 'url',
65
+ ],
66
+ space: [
67
+ 'id',
68
+ 'identifier',
69
+ 'title',
70
+ 'status',
71
+ 'parentSpaceId',
72
+ 'leadAgentId',
73
+ 'labelIds',
74
+ 'archivedAt',
75
+ 'createdAt',
76
+ 'updatedAt',
77
+ 'url',
78
+ ],
79
+ project: [
80
+ 'id',
81
+ 'identifier',
82
+ 'title',
83
+ 'spaceId',
84
+ 'externalKey',
85
+ 'taskCounts',
86
+ 'archivedAt',
87
+ 'createdAt',
88
+ 'updatedAt',
89
+ 'url',
90
+ ],
91
+ };
92
+ /** The three flags every projecting list command declares. */
93
+ exports.listOutputFlags = {
94
+ fields: core_1.Flags.string({
95
+ description: 'JSON only: comma-separated fields to keep on each row (dotted paths allowed, e.g. id,title,assignee.name). Wins over --compact.',
96
+ }),
97
+ compact: core_1.Flags.boolean({
98
+ description: 'JSON only: keep the navigation fields of each row (id, ref, title, status, owners, dates, url) and drop activity logs, lifecycle and other bulk. See docs/cli/SKRR_TASKS.md (List output for agents).',
99
+ }),
100
+ ndjson: core_1.Flags.boolean({
101
+ description: 'One JSON object per line on stdout (rows only; paging and warnings go to stderr as one {"_meta":...} line). Implies --json.',
102
+ }),
103
+ };
104
+ /** `--fields a, b ,c` -> ['a','b','c']; empty/blank -> undefined. */
105
+ function parseFields(raw) {
106
+ if (!raw)
107
+ return undefined;
108
+ const fields = raw
109
+ .split(',')
110
+ .map((f) => f.trim())
111
+ .filter(Boolean);
112
+ return fields.length > 0 ? Array.from(new Set(fields)) : undefined;
113
+ }
114
+ function pick(row, path) {
115
+ let current = row;
116
+ for (const segment of path.split('.')) {
117
+ if (current === null || typeof current !== 'object' || !(segment in current)) {
118
+ return { found: false, value: undefined };
119
+ }
120
+ current = current[segment];
121
+ }
122
+ return { found: true, value: current };
123
+ }
124
+ function assign(target, path, value) {
125
+ const segments = path.split('.');
126
+ let cursor = target;
127
+ for (const segment of segments.slice(0, -1)) {
128
+ const next = cursor[segment];
129
+ if (next === null || typeof next !== 'object' || Array.isArray(next))
130
+ cursor[segment] = {};
131
+ cursor = cursor[segment];
132
+ }
133
+ cursor[segments[segments.length - 1]] = value;
134
+ }
135
+ function projectRow(row, fields) {
136
+ const out = {};
137
+ for (const field of fields) {
138
+ const { found, value } = pick(row, field);
139
+ if (found)
140
+ assign(out, field, value);
141
+ }
142
+ return out;
143
+ }
144
+ /**
145
+ * Normalize any list response to the shared envelope. `data` is where rows live
146
+ * for every list command; `projects` (an older serialization) is folded into it.
147
+ * A response that is not list-shaped is returned untouched (never invent rows).
148
+ */
149
+ function toListEnvelope(response) {
150
+ if (Array.isArray(response)) {
151
+ return {
152
+ object: 'list',
153
+ data: response,
154
+ has_more: false,
155
+ next_cursor: null,
156
+ };
157
+ }
158
+ if (!response || typeof response !== 'object')
159
+ return undefined;
160
+ const r = response;
161
+ const rows = Array.isArray(r.data) ? r.data : Array.isArray(r.projects) ? r.projects : undefined;
162
+ if (!rows)
163
+ return undefined;
164
+ const { projects: _legacy, ...rest } = r;
165
+ void _legacy;
166
+ return {
167
+ ...rest,
168
+ object: 'list',
169
+ data: rows,
170
+ has_more: typeof r.has_more === 'boolean' ? r.has_more : Boolean(r.next_cursor),
171
+ next_cursor: typeof r.next_cursor === 'string' ? r.next_cursor : null,
172
+ };
173
+ }
174
+ /** Pure: envelope + projection + notes. Returns the response untouched if not a list. */
175
+ function shapeListResponse(response, options) {
176
+ const envelope = toListEnvelope(response);
177
+ if (!envelope)
178
+ return response;
179
+ const warnings = [...(options.warnings ?? [])];
180
+ const fields = parseFields(options.fields);
181
+ let data = envelope.data;
182
+ if (fields) {
183
+ data = data.map((row) => projectRow(row, fields));
184
+ if (envelope.data.length > 0) {
185
+ for (const field of fields) {
186
+ if (!envelope.data.some((row) => pick(row, field).found)) {
187
+ warnings.push({
188
+ code: 'UNKNOWN_FIELD',
189
+ value: field,
190
+ hint: `No row carried "${field}". Run without --fields to see the available keys.`,
191
+ });
192
+ }
193
+ }
194
+ }
195
+ }
196
+ else if (options.compact) {
197
+ const keep = exports.COMPACT_FIELDS[options.resource];
198
+ data = data.map((row) => {
199
+ const kept = projectRow(row, keep);
200
+ // A row that carries none of the navigation fields is an unknown shape;
201
+ // dropping it to `{}` would hide it rather than compact it.
202
+ return Object.keys(kept).length > 0 ? kept : row;
203
+ });
204
+ }
205
+ const limit = limitNote(options.requestedLimit, envelope.data.length, envelope.has_more);
206
+ if (limit.warning)
207
+ warnings.push(limit.warning);
208
+ return {
209
+ ...envelope,
210
+ data,
211
+ ...(limit.applied !== undefined ? { limit_applied: limit.applied } : {}),
212
+ ...(options.filterApplied ? { filter_applied: options.filterApplied } : {}),
213
+ ...(warnings.length > 0 ? { warnings } : {}),
214
+ };
215
+ }
216
+ /**
217
+ * E11: the server silently clamps `--limit` (cap) and coerces `0` to its default.
218
+ * Echo what was applied. `applied` is only reported when we can prove it: a full
219
+ * page that still has more rows means the cap is exactly the row count.
220
+ */
221
+ function limitNote(requested, rowCount, hasMore) {
222
+ if (requested === undefined)
223
+ return {};
224
+ if (requested <= 0) {
225
+ return {
226
+ applied: hasMore ? rowCount : undefined,
227
+ warning: {
228
+ code: 'LIMIT_COERCED',
229
+ value: requested,
230
+ hint: '--limit must be >= 1; the server applied its default page size instead. Pass an explicit positive --limit.',
231
+ },
232
+ };
233
+ }
234
+ if (hasMore && rowCount > 0 && rowCount < requested) {
235
+ return {
236
+ applied: rowCount,
237
+ warning: {
238
+ code: 'LIMIT_CLAMPED',
239
+ value: requested,
240
+ hint: `The server returned ${rowCount} rows, its per-page cap, not the ${requested} requested. Follow next_cursor for the rest.`,
241
+ },
242
+ };
243
+ }
244
+ return {};
245
+ }
246
+ /** The text-mode twin of a warning: one `Note:` line a person can act on. */
247
+ function warningLines(warnings) {
248
+ return (warnings ?? []).map((w) => `Note: ${w.hint}`);
249
+ }
250
+ /**
251
+ * Render a shaped list for `--json` (pretty envelope) or `--ndjson` (rows one per
252
+ * line, `_meta` on stderr). Pure; the caller writes the lines.
253
+ */
254
+ function renderListOutput(shaped, ndjson) {
255
+ if (!ndjson)
256
+ return { stdout: [JSON.stringify(shaped, null, 2)], stderr: [] };
257
+ const envelope = shaped;
258
+ if (!envelope || !Array.isArray(envelope.data)) {
259
+ return { stdout: [JSON.stringify(shaped)], stderr: [] };
260
+ }
261
+ const { data, ...meta } = envelope;
262
+ return {
263
+ stdout: data.map((row) => JSON.stringify(row)),
264
+ stderr: [JSON.stringify({ _meta: meta })],
265
+ };
266
+ }
@@ -0,0 +1,36 @@
1
+ import { COMPUTER_DAEMON_LOG_LEVELS, COMPUTER_DAEMON_LOG_LIMITS, type ComputerDaemonLogResult } from '@skrr-ai/data-provider';
2
+ import { type ComputerFileFailure } from './computer-files';
3
+ /**
4
+ * machine-daemon-log.ts — request client for `GET /api/machines/:machineId/daemon-log`
5
+ * (`computer_daemon_log_v1`): the tail of what a machine's daemon logged about
6
+ * itself, so an owner can see why it reconnected, re-registered or failed
7
+ * without reading syslog (which a Dedicated Runtime guest's tenant uid cannot).
8
+ *
9
+ * The daemon serves an in-memory ring of its OWN logger's lines, redacted
10
+ * before they were kept; a `watch` grantee reads it too. Vocabulary, limits
11
+ * and the result shape are owned by `@skrr-ai/data-provider`.
12
+ *
13
+ * ## Inline path literal
14
+ *
15
+ * `domain-api-parity` resolves a command to an endpoint by reading this
16
+ * string; a helper that assembled the URL would read as unreachable.
17
+ */
18
+ export { COMPUTER_DAEMON_LOG_LEVELS, COMPUTER_DAEMON_LOG_LIMITS };
19
+ export type { ComputerDaemonLogResult };
20
+ export interface MachineDaemonLogQuery {
21
+ lines?: number;
22
+ sinceMs?: number;
23
+ level?: (typeof COMPUTER_DAEMON_LOG_LEVELS)[number];
24
+ }
25
+ export declare function getMachineDaemonLog(machineId: string, query?: MachineDaemonLogQuery): Promise<ComputerDaemonLogResult>;
26
+ /** `--since 90s|30m|2h|1d` as milliseconds, bounded by what the daemon will look back. */
27
+ export declare function parseDaemonLogSince(value: string): number;
28
+ /**
29
+ * A failed read as the sentence the command prints. `capability_missing` is the
30
+ * zero state: this machine's daemon predates the log, and the fix is the image.
31
+ * `consent_missing` is a personal machine that has not run `skrr computer allow`.
32
+ */
33
+ export declare function describeDaemonLogFailure(err: unknown, ctx: {
34
+ bin: string;
35
+ leaseId: string;
36
+ }): ComputerFileFailure | null;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMPUTER_DAEMON_LOG_LIMITS = exports.COMPUTER_DAEMON_LOG_LEVELS = void 0;
4
+ exports.getMachineDaemonLog = getMachineDaemonLog;
5
+ exports.parseDaemonLogSince = parseDaemonLogSince;
6
+ exports.describeDaemonLogFailure = describeDaemonLogFailure;
7
+ const data_provider_1 = require("@skrr-ai/data-provider");
8
+ Object.defineProperty(exports, "COMPUTER_DAEMON_LOG_LEVELS", { enumerable: true, get: function () { return data_provider_1.COMPUTER_DAEMON_LOG_LEVELS; } });
9
+ Object.defineProperty(exports, "COMPUTER_DAEMON_LOG_LIMITS", { enumerable: true, get: function () { return data_provider_1.COMPUTER_DAEMON_LOG_LIMITS; } });
10
+ const api_fetch_1 = require("./api-fetch");
11
+ const computer_files_1 = require("./computer-files");
12
+ async function getMachineDaemonLog(machineId, query = {}) {
13
+ const params = new URLSearchParams();
14
+ if (query.lines !== undefined)
15
+ params.set('lines', String(query.lines));
16
+ if (query.sinceMs !== undefined)
17
+ params.set('sinceMs', String(query.sinceMs));
18
+ if (query.level)
19
+ params.set('level', query.level);
20
+ const qs = params.toString();
21
+ const suffix = qs ? `?${qs}` : '';
22
+ return (0, api_fetch_1.apiFetch)(`/api/machines/${encodeURIComponent(machineId)}/daemon-log` + suffix);
23
+ }
24
+ const SINCE_UNIT_MS = {
25
+ s: 1000,
26
+ m: 60_000,
27
+ h: 3_600_000,
28
+ d: 86_400_000,
29
+ };
30
+ /** `--since 90s|30m|2h|1d` as milliseconds, bounded by what the daemon will look back. */
31
+ function parseDaemonLogSince(value) {
32
+ const match = value.trim().match(/^(\d+)([smhd])$/i);
33
+ if (!match) {
34
+ throw new Error(`Invalid --since value: ${value}. Use an age such as 90s, 30m, 2h or 1d.`);
35
+ }
36
+ const ms = Number(match[1]) * SINCE_UNIT_MS[match[2].toLowerCase()];
37
+ if (ms < 1 || ms > data_provider_1.COMPUTER_DAEMON_LOG_LIMITS.maxSinceMs) {
38
+ throw new Error(`--since must be between 1s and ${data_provider_1.COMPUTER_DAEMON_LOG_LIMITS.maxSinceMs / 3_600_000}h; the daemon keeps a short, recent log.`);
39
+ }
40
+ return ms;
41
+ }
42
+ /**
43
+ * A failed read as the sentence the command prints. `capability_missing` is the
44
+ * zero state: this machine's daemon predates the log, and the fix is the image.
45
+ * `consent_missing` is a personal machine that has not run `skrr computer allow`.
46
+ */
47
+ function describeDaemonLogFailure(err, ctx) {
48
+ const refusal = (0, computer_files_1.computerFileRefusalInfo)(err);
49
+ if (refusal?.code === 'capability_missing') {
50
+ return {
51
+ message: `This machine's daemon predates daemon logs, so it has none to show. ` +
52
+ `\`${ctx.bin} machines dedicated update-image ${ctx.leaseId}\` moves the machine onto the current image, which keeps one.`,
53
+ code: 'capability_missing',
54
+ status: refusal.status,
55
+ retryable: false,
56
+ details: refusal.body,
57
+ };
58
+ }
59
+ if (refusal?.code === 'consent_missing') {
60
+ return {
61
+ message: `${refusal.message} The person who uses the machine sets this on it: \`${ctx.bin} computer allow\`.`,
62
+ code: 'consent_missing',
63
+ status: refusal.status,
64
+ retryable: false,
65
+ details: refusal.body,
66
+ };
67
+ }
68
+ if (refusal?.code === 'unauthorized') {
69
+ return {
70
+ message: `${refusal.message} Reading a machine's daemon log needs at least the watch tier — see \`${ctx.bin} machines shares ${ctx.leaseId}\`.`,
71
+ code: 'unauthorized',
72
+ status: refusal.status,
73
+ retryable: false,
74
+ details: refusal.body,
75
+ };
76
+ }
77
+ return (0, computer_files_1.describeComputerFileFailure)(err, ctx);
78
+ }
@@ -18,6 +18,7 @@ const delegated_cli_1 = require("./delegated-cli");
18
18
  const workspace_header_1 = require("./workspace-header");
19
19
  const non_json_response_1 = require("./non-json-response");
20
20
  require("./auth-core-init");
21
+ const rate_limit_retry_1 = require("./rate-limit-retry");
21
22
  // ---------------------------------------------------------------------
22
23
  // Per-process credential override — set by BaseCommand.init().
23
24
  // Pulled out of the closure so test harnesses or long-lived callers
@@ -146,6 +147,8 @@ function createNodeAdapter(opts = {}) {
146
147
  }
147
148
  return u.toString();
148
149
  }
150
+ /** The last 429's `Retry-After`, read off the response of the most recent attempt. */
151
+ let lastRetryAfterMs;
149
152
  async function rawRequest(method, url, body, options, isFormData) {
150
153
  const headers = buildHeaders(options?.headers);
151
154
  let finalBody;
@@ -163,7 +166,10 @@ function createNodeAdapter(opts = {}) {
163
166
  // OSK-12020 — a DPoP-bound hand-off token needs a fresh proof per request
164
167
  // (and per retry: proofs are single-use). No-op for every other token.
165
168
  Object.assign(headers, await (0, dpop_auth_1.dpopHeadersFor)(currentCredential().token, method, finalUrl));
166
- return fetch(finalUrl, { method, headers, body: finalBody });
169
+ // E6: bounded retry on 429 for a GET or an idempotency-keyed write.
170
+ const { response, retryAfterMs } = await (0, rate_limit_retry_1.fetchWithRateLimitRetry)(() => fetch(finalUrl, { method, headers, body: finalBody }), { method, headers });
171
+ lastRetryAfterMs = retryAfterMs;
172
+ return response;
167
173
  }
168
174
  /**
169
175
  * Inner refresh: delegates to `refresh.ts`, the shared CLI refresh
@@ -359,6 +365,9 @@ function createNodeAdapter(opts = {}) {
359
365
  // "which of these requests was mine" is otherwise unanswerable, and a
360
366
  // 409 that belonged to another session was nearly filed as a CLI bug.
361
367
  err.requestId = res.headers.get('x-request-id') || undefined;
368
+ if (res.status === 429 && lastRetryAfterMs !== undefined) {
369
+ err.retryAfterMs = lastRetryAfterMs;
370
+ }
362
371
  throw err;
363
372
  }
364
373
  if (options?.responseType === 'arraybuffer') {
@@ -0,0 +1,12 @@
1
+ export declare const OPEN_REF_KINDS: readonly string[];
2
+ export type OpenTargetErrorCode = 'OPEN_TARGET_EMPTY' | 'OPEN_TARGET_FOREIGN' | 'OPEN_TARGET_UNKNOWN';
3
+ export declare class OpenTargetError extends Error {
4
+ readonly code: OpenTargetErrorCode;
5
+ constructor(message: string, code: OpenTargetErrorCode);
6
+ }
7
+ export type ResolvedOpenTarget = {
8
+ url: string;
9
+ /** Which spelling was given — echoed by `--json` so a script can tell. */
10
+ form: 'url' | 'path' | 'ref' | 'agent';
11
+ };
12
+ export declare function resolveOpenTarget(input: string, baseURL: string): Promise<ResolvedOpenTarget>;