@skrr-ai/cli 0.1.92 → 0.1.94

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 (323) 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/operating-plan.d.ts +11 -0
  10. package/dist/commands/agents/operating-plan.js +54 -0
  11. package/dist/commands/agents/roles/example.d.ts +11 -0
  12. package/dist/commands/agents/roles/example.js +30 -0
  13. package/dist/commands/{commitments/mode.d.ts → agents/roles/export.d.ts} +5 -5
  14. package/dist/commands/agents/roles/export.js +81 -0
  15. package/dist/commands/agents/roles/install.d.ts +12 -0
  16. package/dist/commands/agents/roles/install.js +48 -0
  17. package/dist/commands/agents/roles/list.d.ts +11 -0
  18. package/dist/commands/agents/roles/list.js +36 -0
  19. package/dist/commands/agents/roles/preview.d.ts +14 -0
  20. package/dist/commands/agents/roles/preview.js +49 -0
  21. package/dist/commands/agents/roles/withdraw.d.ts +13 -0
  22. package/dist/commands/agents/roles/withdraw.js +43 -0
  23. package/dist/commands/agents/share.d.ts +27 -0
  24. package/dist/commands/agents/share.js +100 -0
  25. package/dist/commands/agents/vanity.d.ts +21 -0
  26. package/dist/commands/agents/vanity.js +77 -0
  27. package/dist/commands/agents/visibility.d.ts +21 -1
  28. package/dist/commands/agents/visibility.js +112 -0
  29. package/dist/commands/commands.d.ts +1 -0
  30. package/dist/commands/commands.js +22 -9
  31. package/dist/commands/commitments/{autonomy-requests → cadence-requests}/decide.d.ts +5 -7
  32. package/dist/commands/commitments/{autonomy-requests → cadence-requests}/decide.js +13 -15
  33. package/dist/commands/commitments/cost.d.ts +1 -1
  34. package/dist/commands/commitments/cost.js +1 -1
  35. package/dist/commands/commitments/create.d.ts +0 -7
  36. package/dist/commands/commitments/create.js +9 -98
  37. package/dist/commands/commitments/delivery.js +3 -21
  38. package/dist/commands/commitments/doctor.js +28 -27
  39. package/dist/commands/commitments/effective-policy.js +5 -36
  40. package/dist/commands/commitments/evaluations.d.ts +15 -0
  41. package/dist/commands/commitments/evaluations.js +54 -0
  42. package/dist/commands/commitments/pack/activate.d.ts +11 -0
  43. package/dist/commands/commitments/pack/activate.js +22 -0
  44. package/dist/commands/commitments/pack/bind.js +1 -1
  45. package/dist/commands/commitments/remediate.js +2 -5
  46. package/dist/commands/commitments/show.js +1 -1
  47. package/dist/commands/commitments/update.js +9 -9
  48. package/dist/commands/commitments/wake-capabilities.d.ts +1 -3
  49. package/dist/commands/commitments/wake-capabilities.js +5 -21
  50. package/dist/commands/earnings/attributions.d.ts +17 -0
  51. package/dist/commands/earnings/attributions.js +82 -0
  52. package/dist/commands/earnings/index.js +2 -1
  53. package/dist/commands/generate-recovery-code.js +4 -3
  54. package/dist/commands/github/allow-tools.d.ts +1 -0
  55. package/dist/commands/github/app/install.d.ts +1 -0
  56. package/dist/commands/github/app/status.d.ts +1 -0
  57. package/dist/commands/github/connect.d.ts +1 -0
  58. package/dist/commands/github/connections.d.ts +1 -0
  59. package/dist/commands/github/disconnect.d.ts +1 -0
  60. package/dist/commands/github/finalize.d.ts +1 -0
  61. package/dist/commands/github/reconnect.d.ts +1 -0
  62. package/dist/commands/github/run.d.ts +1 -0
  63. package/dist/commands/github/tools.d.ts +1 -0
  64. package/dist/commands/integrations/connections/connect.d.ts +1 -0
  65. package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
  66. package/dist/commands/integrations/connections/finalize.d.ts +1 -0
  67. package/dist/commands/integrations/connections/list.d.ts +1 -0
  68. package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
  69. package/dist/commands/integrations/execute.d.ts +1 -0
  70. package/dist/commands/integrations/search.d.ts +1 -0
  71. package/dist/commands/integrations/toolkits.d.ts +1 -0
  72. package/dist/commands/integrations/tools/allow.d.ts +1 -0
  73. package/dist/commands/integrations/tools/list.d.ts +1 -0
  74. package/dist/commands/login.js +12 -0
  75. package/dist/commands/machines/dedicated/logs.d.ts +19 -0
  76. package/dist/commands/machines/dedicated/logs.js +103 -0
  77. package/dist/commands/machines/dedicated/power/set.js +1 -1
  78. package/dist/commands/open.d.ts +24 -0
  79. package/dist/commands/open.js +74 -0
  80. package/dist/commands/projects/archive.d.ts +1 -0
  81. package/dist/commands/projects/archive.js +23 -0
  82. package/dist/commands/projects/delete.d.ts +1 -0
  83. package/dist/commands/projects/delete.js +23 -0
  84. package/dist/commands/projects/list.d.ts +3 -0
  85. package/dist/commands/projects/list.js +12 -2
  86. package/dist/commands/spaces/actions/add.js +4 -3
  87. package/dist/commands/spaces/actions/available.js +3 -2
  88. package/dist/commands/spaces/actions/list.js +5 -4
  89. package/dist/commands/spaces/actions/replace.js +6 -5
  90. package/dist/commands/spaces/archive.js +3 -2
  91. package/dist/commands/spaces/auto-executor/preview.js +4 -3
  92. package/dist/commands/spaces/auto-executor/run.js +4 -3
  93. package/dist/commands/spaces/auto-executor/runs.js +3 -2
  94. package/dist/commands/spaces/auto-executor/update.js +4 -3
  95. package/dist/commands/spaces/bootstrap.js +3 -2
  96. package/dist/commands/spaces/briefs/delete.js +3 -2
  97. package/dist/commands/spaces/briefs/get.js +3 -2
  98. package/dist/commands/spaces/briefs/list.js +3 -2
  99. package/dist/commands/spaces/briefs/set.js +5 -4
  100. package/dist/commands/spaces/capacity.js +5 -4
  101. package/dist/commands/spaces/conversations.js +3 -2
  102. package/dist/commands/spaces/cycles/create.js +3 -2
  103. package/dist/commands/spaces/cycles/graph.js +2 -1
  104. package/dist/commands/spaces/cycles/list.js +3 -2
  105. package/dist/commands/spaces/cycles/settings.js +4 -3
  106. package/dist/commands/spaces/cycles/show.js +3 -2
  107. package/dist/commands/spaces/cycles/update.js +3 -2
  108. package/dist/commands/spaces/delete.js +4 -3
  109. package/dist/commands/spaces/expertise-suggestions.js +4 -3
  110. package/dist/commands/spaces/files/delete.js +3 -2
  111. package/dist/commands/spaces/files/folders/create.js +3 -2
  112. package/dist/commands/spaces/files/folders/delete.js +3 -2
  113. package/dist/commands/spaces/files/folders/list.js +3 -2
  114. package/dist/commands/spaces/files/folders/update.js +3 -2
  115. package/dist/commands/spaces/files/list.js +3 -2
  116. package/dist/commands/spaces/files/move.js +3 -2
  117. package/dist/commands/spaces/files/rename.js +3 -2
  118. package/dist/commands/spaces/files/upload.js +6 -5
  119. package/dist/commands/spaces/github-automations/set.js +3 -2
  120. package/dist/commands/spaces/github-automations/show.js +3 -2
  121. package/dist/commands/spaces/goals.js +2 -1
  122. package/dist/commands/spaces/heartbeats/create.js +4 -3
  123. package/dist/commands/spaces/heartbeats/delete.js +4 -3
  124. package/dist/commands/spaces/heartbeats/list.js +4 -3
  125. package/dist/commands/spaces/heartbeats/status.js +3 -2
  126. package/dist/commands/spaces/heartbeats/update.js +4 -3
  127. package/dist/commands/spaces/insights.js +5 -4
  128. package/dist/commands/spaces/labels/add.js +4 -3
  129. package/dist/commands/spaces/labels/list.js +2 -1
  130. package/dist/commands/spaces/labels/remove.js +4 -3
  131. package/dist/commands/spaces/list.d.ts +3 -0
  132. package/dist/commands/spaces/list.js +11 -2
  133. package/dist/commands/spaces/live/cards/create.js +3 -2
  134. package/dist/commands/spaces/live/cards/list.js +3 -2
  135. package/dist/commands/spaces/live/cards/reorder.js +7 -2
  136. package/dist/commands/spaces/live/scene.js +4 -3
  137. package/dist/commands/spaces/members/add.js +7 -6
  138. package/dist/commands/spaces/members/list.js +4 -3
  139. package/dist/commands/spaces/members/remove.js +7 -6
  140. package/dist/commands/spaces/move.js +3 -2
  141. package/dist/commands/spaces/pin.js +5 -4
  142. package/dist/commands/spaces/preferences/show.js +4 -3
  143. package/dist/commands/spaces/preferences/tabs.js +4 -3
  144. package/dist/commands/spaces/revisions.js +3 -2
  145. package/dist/commands/spaces/room/ensure.js +5 -4
  146. package/dist/commands/spaces/room/messages.js +3 -2
  147. package/dist/commands/spaces/room/show.js +5 -4
  148. package/dist/commands/spaces/skills/add.js +4 -3
  149. package/dist/commands/spaces/skills/list.js +3 -2
  150. package/dist/commands/spaces/skills/pin.js +4 -3
  151. package/dist/commands/spaces/skills/remove.js +4 -3
  152. package/dist/commands/spaces/snapshot.js +3 -2
  153. package/dist/commands/spaces/states/archive.js +3 -2
  154. package/dist/commands/spaces/states/create.js +3 -2
  155. package/dist/commands/spaces/states/list.js +3 -2
  156. package/dist/commands/spaces/states/reorder.js +2 -1
  157. package/dist/commands/spaces/states/update.js +3 -2
  158. package/dist/commands/spaces/summary.js +4 -3
  159. package/dist/commands/spaces/tasks.d.ts +3 -0
  160. package/dist/commands/spaces/tasks.js +14 -3
  161. package/dist/commands/spaces/triggers/delete.js +5 -4
  162. package/dist/commands/spaces/triggers/set.js +4 -3
  163. package/dist/commands/spaces/triggers/show.js +4 -3
  164. package/dist/commands/spaces/unarchive.js +3 -2
  165. package/dist/commands/spaces/update.js +5 -4
  166. package/dist/commands/spaces/views/create.js +3 -2
  167. package/dist/commands/spaces/views/list.js +3 -2
  168. package/dist/commands/spaces/views/reorder.js +6 -3
  169. package/dist/commands/spaces/views/subscribe.js +2 -1
  170. package/dist/commands/spaces/views/subscriptions.js +1 -0
  171. package/dist/commands/spaces/views/unsubscribe.js +2 -1
  172. package/dist/commands/spaces/widgets/add.js +4 -3
  173. package/dist/commands/spaces/widgets/list.js +3 -2
  174. package/dist/commands/spaces/widgets/remove.js +5 -4
  175. package/dist/commands/spaces/work-graph.js +2 -1
  176. package/dist/commands/store/install.d.ts +1 -1
  177. package/dist/commands/store/install.js +24 -8
  178. package/dist/commands/store/show.d.ts +25 -0
  179. package/dist/commands/store/show.js +203 -0
  180. package/dist/commands/store/stats.d.ts +33 -0
  181. package/dist/commands/store/stats.js +258 -0
  182. package/dist/commands/tasks/actions/attach.js +1 -1
  183. package/dist/commands/tasks/actions/detach.js +4 -3
  184. package/dist/commands/tasks/activity.js +3 -2
  185. package/dist/commands/tasks/ancestors.js +2 -1
  186. package/dist/commands/tasks/approvals/create.js +2 -1
  187. package/dist/commands/tasks/approvals/delete.js +3 -2
  188. package/dist/commands/tasks/approvals/list.js +5 -4
  189. package/dist/commands/tasks/approvals/resolve.js +2 -1
  190. package/dist/commands/tasks/archive.js +3 -2
  191. package/dist/commands/tasks/assign.js +4 -3
  192. package/dist/commands/tasks/attachments/delete.js +3 -2
  193. package/dist/commands/tasks/attachments/download.d.ts +1 -0
  194. package/dist/commands/tasks/attachments/download.js +20 -1
  195. package/dist/commands/tasks/attachments/list.js +2 -1
  196. package/dist/commands/tasks/attachments/set-role.js +2 -1
  197. package/dist/commands/tasks/attachments/upload.js +2 -1
  198. package/dist/commands/tasks/bulk-update.d.ts +1 -0
  199. package/dist/commands/tasks/bulk-update.js +106 -15
  200. package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
  201. package/dist/commands/tasks/cancel-cascade.js +13 -3
  202. package/dist/commands/tasks/cascade-status.js +2 -1
  203. package/dist/commands/tasks/checkout.js +3 -2
  204. package/dist/commands/tasks/children.js +2 -1
  205. package/dist/commands/tasks/comments/add.js +7 -6
  206. package/dist/commands/tasks/comments/anchor.js +8 -7
  207. package/dist/commands/tasks/comments/delete.js +3 -2
  208. package/dist/commands/tasks/comments/list.js +2 -1
  209. package/dist/commands/tasks/comments/reopen.js +3 -2
  210. package/dist/commands/tasks/comments/resolve.js +3 -2
  211. package/dist/commands/tasks/create-tree.d.ts +63 -0
  212. package/dist/commands/tasks/create-tree.js +197 -4
  213. package/dist/commands/tasks/delete.js +5 -4
  214. package/dist/commands/tasks/descendants.js +2 -1
  215. package/dist/commands/tasks/dri-plan.js +3 -2
  216. package/dist/commands/tasks/dri-run.js +3 -2
  217. package/dist/commands/tasks/dri-status.js +2 -1
  218. package/dist/commands/tasks/duplicate-pipeline.js +2 -1
  219. package/dist/commands/tasks/execution-summary.js +2 -1
  220. package/dist/commands/tasks/execution-timeline.js +2 -1
  221. package/dist/commands/tasks/fork.js +1 -0
  222. package/dist/commands/tasks/forward.js +4 -3
  223. package/dist/commands/tasks/handover.js +1 -0
  224. package/dist/commands/tasks/interrupt.js +3 -2
  225. package/dist/commands/tasks/labels/attach.js +4 -3
  226. package/dist/commands/tasks/labels/detach.js +4 -3
  227. package/dist/commands/tasks/labels/suggest.js +5 -4
  228. package/dist/commands/tasks/list.d.ts +27 -1
  229. package/dist/commands/tasks/list.js +101 -3
  230. package/dist/commands/tasks/move.js +4 -3
  231. package/dist/commands/tasks/output.js +6 -5
  232. package/dist/commands/tasks/pause-schedule.js +3 -2
  233. package/dist/commands/tasks/promote.js +1 -0
  234. package/dist/commands/tasks/prompt-log.js +2 -1
  235. package/dist/commands/tasks/release.js +5 -4
  236. package/dist/commands/tasks/remind.js +2 -1
  237. package/dist/commands/tasks/replay.js +3 -2
  238. package/dist/commands/tasks/report.js +1 -0
  239. package/dist/commands/tasks/resume-schedule.js +3 -2
  240. package/dist/commands/tasks/retry-schedule.js +3 -2
  241. package/dist/commands/tasks/retry.js +10 -9
  242. package/dist/commands/tasks/revisions.js +2 -1
  243. package/dist/commands/tasks/runs.js +6 -5
  244. package/dist/commands/tasks/schedule.js +3 -2
  245. package/dist/commands/tasks/self-schedule.js +6 -5
  246. package/dist/commands/tasks/skills/pin.js +3 -2
  247. package/dist/commands/tasks/skills/unpin.js +3 -2
  248. package/dist/commands/tasks/snooze.js +6 -5
  249. package/dist/commands/tasks/start-all.js +5 -4
  250. package/dist/commands/tasks/subscribe.js +1 -0
  251. package/dist/commands/tasks/tags/add.js +4 -3
  252. package/dist/commands/tasks/tags/remove.js +4 -3
  253. package/dist/commands/tasks/timeline.js +3 -2
  254. package/dist/commands/tasks/today.d.ts +4 -1
  255. package/dist/commands/tasks/today.js +12 -2
  256. package/dist/commands/tasks/transcript.js +6 -5
  257. package/dist/commands/tasks/unschedule.js +3 -2
  258. package/dist/commands/tasks/unsnooze.js +3 -2
  259. package/dist/commands/tasks/unsubscribe.js +2 -1
  260. package/dist/commands/tasks/update.js +5 -4
  261. package/dist/commands/tasks/wait.js +5 -4
  262. package/dist/lib/agent-distribution.d.ts +37 -0
  263. package/dist/lib/agent-distribution.js +63 -0
  264. package/dist/lib/agent-ref.d.ts +69 -0
  265. package/dist/lib/agent-ref.js +168 -0
  266. package/dist/lib/api-fetch.d.ts +2 -0
  267. package/dist/lib/api-fetch.js +14 -3
  268. package/dist/lib/command-hygiene.d.ts +13 -0
  269. package/dist/lib/command-hygiene.js +62 -2
  270. package/dist/lib/commitment-product.d.ts +0 -6
  271. package/dist/lib/commitment-product.js +1 -30
  272. package/dist/lib/commitments.d.ts +9 -45
  273. package/dist/lib/commitments.js +24 -95
  274. package/dist/lib/dedicated-power.d.ts +5 -0
  275. package/dist/lib/dedicated-power.js +30 -2
  276. package/dist/lib/dry-run-plans.d.ts +50 -0
  277. package/dist/lib/dry-run-plans.js +85 -0
  278. package/dist/lib/json-output.d.ts +31 -0
  279. package/dist/lib/json-output.js +78 -0
  280. package/dist/lib/list-output.d.ts +75 -0
  281. package/dist/lib/list-output.js +266 -0
  282. package/dist/lib/machine-daemon-log.d.ts +36 -0
  283. package/dist/lib/machine-daemon-log.js +78 -0
  284. package/dist/lib/node-adapter.js +10 -1
  285. package/dist/lib/northstars.js +1 -1
  286. package/dist/lib/open-target.d.ts +12 -0
  287. package/dist/lib/open-target.js +108 -0
  288. package/dist/lib/rate-limit-retry.d.ts +45 -0
  289. package/dist/lib/rate-limit-retry.js +88 -0
  290. package/dist/lib/roles.d.ts +98 -0
  291. package/dist/lib/roles.js +45 -0
  292. package/dist/lib/store-listing.d.ts +45 -0
  293. package/dist/lib/store-listing.js +186 -0
  294. package/dist/lib/task-batch.d.ts +67 -0
  295. package/dist/lib/task-batch.js +227 -0
  296. package/dist/lib/terminal-qr.d.ts +55 -0
  297. package/dist/lib/terminal-qr.js +119 -0
  298. package/dist/lib/web-url.d.ts +11 -0
  299. package/dist/lib/web-url.js +24 -0
  300. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/commitmentExecutionContract.d.ts +45 -0
  301. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/commitmentExecutionContract.js +550 -0
  302. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
  303. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
  304. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionPermissionAuthority.d.ts +7 -44
  305. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionPermissionAuthority.js +8 -47
  306. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/commitmentExecutionContract.d.ts +45 -0
  307. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/commitmentExecutionContract.js +545 -0
  308. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
  309. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
  310. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionPermissionAuthority.d.ts +7 -44
  311. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionPermissionAuthority.js +8 -47
  312. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  313. package/dist/node_modules/@skrr-ai/data-provider/index.js +7285 -6673
  314. package/dist/node_modules/@skrr-ai/data-provider/package.json +2 -2
  315. package/oclif.manifest.json +35937 -26820
  316. package/package.json +6 -2
  317. package/dist/commands/commitments/autonomy.d.ts +0 -30
  318. package/dist/commands/commitments/autonomy.js +0 -67
  319. package/dist/commands/commitments/mode.js +0 -58
  320. package/dist/commands/commitments/pack/promote.d.ts +0 -19
  321. package/dist/commands/commitments/pack/promote.js +0 -46
  322. package/dist/commands/commitments/pack/shadow.d.ts +0 -20
  323. package/dist/commands/commitments/pack/shadow.js +0 -42
@@ -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') {
@@ -148,7 +148,7 @@ function renderNorthstar(status, log) {
148
148
  id: commitment.id,
149
149
  title: String(commitment.title ?? ''),
150
150
  status: String(commitment.status ?? ''),
151
- health: String(commitment.state?.health ?? 'unknown'),
151
+ health: String(commitment.assessment?.label ?? 'Outcome unknown'),
152
152
  tier: String(commitment.priority?.tier ?? '—'),
153
153
  })), [
154
154
  { key: 'id', header: 'COMMITMENT' },
@@ -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>;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenTargetError = exports.OPEN_REF_KINDS = void 0;
4
+ exports.resolveOpenTarget = resolveOpenTarget;
5
+ const data_provider_1 = require("@skrr-ai/data-provider");
6
+ const agent_ref_1 = require("./agent-ref");
7
+ const web_url_1 = require("./web-url");
8
+ /**
9
+ * What `skrr open <target>` accepts, resolved to one absolute web URL.
10
+ *
11
+ * - a skrr web URL (`https://skrr.ai/a/agent_abc`) — opened as given, after
12
+ * checking it is first-party;
13
+ * - a site path (`/spaces/sp_1/tasks`) — on the configured deployment;
14
+ * - a typed reference (`space:sp_1`, `listing:agent_abc`) — through the
15
+ * CLI's one route table, `web-url.ts`, so no route is spelled here;
16
+ * - an agent reference `resolveAgentRef` understands that is not already a
17
+ * web URL (`skrr://agent/<id>`, `agent_abc`) — opened at its public
18
+ * listing, keeping any attribution it carried.
19
+ *
20
+ * A foreign host is refused rather than opened. `skrr open` is also run by
21
+ * coding agents, and a command that opens whatever URL it is handed would turn
22
+ * "open this skrr link" into "open any link" for anything that can put text in
23
+ * front of one. WHETHER a URL is first-party is data-provider's
24
+ * `inspectSkrrLink` (the shared link parser) over the CLI's host list, never a
25
+ * host comparison of our own.
26
+ */
27
+ /** Kind words a typed reference may use, mapped to the route table's refs. */
28
+ const REF_KINDS = {
29
+ space: (id) => ({ kind: 'space', spaceId: id }),
30
+ task: (id) => ({ kind: 'task', taskId: id }),
31
+ goal: (id) => ({ kind: 'goal', goalId: id }),
32
+ commitment: (id) => ({ kind: 'commitment', commitmentId: id }),
33
+ northstar: (id) => ({ kind: 'northstar', northstarId: id }),
34
+ // The owner's workspace for an agent you hold. To open a published agent's
35
+ // public page — the address you hand to someone else — use `listing:`.
36
+ agent: (id) => ({ kind: 'agent', agentId: id }),
37
+ listing: (id) => ({ kind: 'storeListing', agentId: id }),
38
+ conversation: (id) => ({ kind: 'conversation', conversationId: id }),
39
+ group: (id) => ({ kind: 'groupChat', groupChatId: id }),
40
+ machine: (id) => ({ kind: 'machine', machineId: id }),
41
+ harness: (id) => ({ kind: 'harness', harnessId: id }),
42
+ template: (id) => ({ kind: 'spaceTemplate', templateId: id }),
43
+ };
44
+ exports.OPEN_REF_KINDS = Object.freeze(Object.keys(REF_KINDS));
45
+ class OpenTargetError extends Error {
46
+ code;
47
+ constructor(message, code) {
48
+ super(message);
49
+ this.code = code;
50
+ this.name = 'OpenTargetError';
51
+ }
52
+ }
53
+ exports.OpenTargetError = OpenTargetError;
54
+ /** An agent reference that is not a web URL: an app-scheme link, `@handle/…`, or an `agent_` id. */
55
+ function looksLikeAgentRef(value) {
56
+ return (/^[a-z][a-z0-9+.-]*:\/\//i.test(value) ||
57
+ value.startsWith('@') ||
58
+ /^agent_[A-Za-z0-9_-]+$/.test(value));
59
+ }
60
+ async function resolveOpenTarget(input, baseURL) {
61
+ const value = String(input ?? '').trim();
62
+ if (!value) {
63
+ throw new OpenTargetError(`Name what to open: a ${data_provider_1.BRAND.displayName} URL, a /path, or <kind>:<id>.`, 'OPEN_TARGET_EMPTY');
64
+ }
65
+ if (/^https?:\/\//i.test(value)) {
66
+ let parsed;
67
+ try {
68
+ parsed = new URL(value);
69
+ }
70
+ catch {
71
+ throw new OpenTargetError(`"${value}" is not a valid URL.`, 'OPEN_TARGET_UNKNOWN');
72
+ }
73
+ if (!(0, data_provider_1.inspectSkrrLink)(value, { firstPartyHosts: (0, agent_ref_1.cliFirstPartyHosts)(baseURL) })) {
74
+ throw new OpenTargetError(`${parsed.host} is not a ${data_provider_1.BRAND.displayName} web address, so it was not opened.`, 'OPEN_TARGET_FOREIGN');
75
+ }
76
+ return { url: parsed.toString(), form: 'url' };
77
+ }
78
+ if (value.startsWith('/')) {
79
+ // `//host/...` is a protocol-relative URL to ANOTHER host, not a path.
80
+ if (value.startsWith('//')) {
81
+ throw new OpenTargetError(`"${value}" is not a site path.`, 'OPEN_TARGET_UNKNOWN');
82
+ }
83
+ return { url: new URL(value, `${(0, web_url_1.webOrigin)(baseURL)}/`).toString(), form: 'path' };
84
+ }
85
+ const ref = /^([a-z]+):(.+)$/i.exec(value);
86
+ const build = ref ? REF_KINDS[ref[1].toLowerCase()] : undefined;
87
+ if (ref && build) {
88
+ const url = (0, web_url_1.webUrl)(baseURL, build(ref[2].trim()));
89
+ if (url)
90
+ return { url, form: 'ref' };
91
+ }
92
+ if (looksLikeAgentRef(value)) {
93
+ try {
94
+ const agent = await (0, agent_ref_1.resolveAgentRef)(value, { baseURL });
95
+ return { url: (0, agent_ref_1.attributedListingUrl)(baseURL, agent), form: 'agent' };
96
+ }
97
+ catch (err) {
98
+ if (!(err instanceof agent_ref_1.AgentRefError))
99
+ throw err;
100
+ // A foreign scheme or an unresolvable vanity link says so in its own words.
101
+ if (err.code !== 'AGENT_REF_UNSUPPORTED') {
102
+ throw new OpenTargetError(err.message, err.code === 'AGENT_REF_FOREIGN' ? 'OPEN_TARGET_FOREIGN' : 'OPEN_TARGET_UNKNOWN');
103
+ }
104
+ }
105
+ }
106
+ throw new OpenTargetError(`"${value}" is not something \`skrr open\` understands. Pass a ${data_provider_1.BRAND.displayName} URL, a site path ` +
107
+ `(/spaces/<id>), or <kind>:<id> where kind is one of: ${exports.OPEN_REF_KINDS.join(', ')}.`, 'OPEN_TARGET_UNKNOWN');
108
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Bounded retry on HTTP 429 (agent-surface audit E6).
3
+ *
4
+ * The API limits writes per USER (task create is 200/min), so N agents under one
5
+ * account share one bucket, and the server already says when to come back
6
+ * (`Retry-After`, `standardHeaders: true`). Until now both transports treated a
7
+ * 429 as terminal, so a burst of keyed creates failed on the first refusal.
8
+ *
9
+ * Retried only when replay is provably safe: a GET, or a write that carries an
10
+ * `X-Idempotency-Key` (every `request.ts` / adapter write does). A 429 means the
11
+ * request was refused before it ran, so the key is belt and braces.
12
+ *
13
+ * Bounded twice: at most `maxRetries` extra attempts and a per-wait ceiling, so
14
+ * a stuck limiter costs a script seconds, not minutes. `SKRR_RATE_LIMIT_RETRIES=0`
15
+ * turns it off.
16
+ */
17
+ export declare const DEFAULT_MAX_RATE_LIMIT_RETRIES = 2;
18
+ export declare const MAX_RATE_LIMIT_WAIT_MS = 10000;
19
+ /** `Retry-After` is delta-seconds or an HTTP-date; both become milliseconds. */
20
+ export declare function parseRetryAfterMs(value: string | null | undefined, now?: number): number | undefined;
21
+ /**
22
+ * Wait before retry number `attempt` (0-based): the server's `Retry-After` when
23
+ * given, else exponential from 500 ms, plus 0-25% jitter so a fleet released
24
+ * together does not come back together. Clamped to the ceiling.
25
+ */
26
+ export declare function rateLimitWaitMs(attempt: number, retryAfterMs: number | undefined, random?: () => number): number;
27
+ export declare function maxRateLimitRetries(env?: NodeJS.ProcessEnv): number;
28
+ export declare function isRateLimitRetrySafe(method: string, headers: Record<string, string> | undefined): boolean;
29
+ export interface RateLimitRetryOptions {
30
+ method: string;
31
+ headers?: Record<string, string>;
32
+ signal?: AbortSignal;
33
+ sleep?: (ms: number) => Promise<void>;
34
+ random?: () => number;
35
+ maxRetries?: number;
36
+ }
37
+ /**
38
+ * Run `attemptFetch` and, on a 429 for a replay-safe request, wait and run it
39
+ * again. Returns the last response, with `retryAfterMs` of the final 429 (so the
40
+ * caller can surface it) when retries ran out.
41
+ */
42
+ export declare function fetchWithRateLimitRetry(attemptFetch: () => Promise<Response>, options: RateLimitRetryOptions): Promise<{
43
+ response: Response;
44
+ retryAfterMs?: number;
45
+ }>;