@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
@@ -1,12 +1,89 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unkeyedNodes = unkeyedNodes;
4
+ exports.rerunWarning = rerunWarning;
5
+ exports.derivedTreePrefix = derivedTreePrefix;
6
+ exports.derivedPrefixWarning = derivedPrefixWarning;
7
+ exports.partialFailureResult = partialFailureResult;
3
8
  exports.normalizeTreeRoots = normalizeTreeRoots;
4
9
  exports.planTree = planTree;
5
10
  const core_1 = require("@oclif/core");
11
+ const node_crypto_1 = require("node:crypto");
6
12
  const data_provider_1 = require("@skrr-ai/data-provider");
7
13
  const base_command_1 = require("../../base-command");
8
14
  const prompt_1 = require("../../lib/prompt");
15
+ const task_batch_1 = require("../../lib/task-batch");
9
16
  const tasks_1 = require("../../lib/tasks");
17
+ /**
18
+ * Nodes a re-run could not recognize: no externalKey of their own and no
19
+ * `--external-key-prefix` to derive one. Re-running a partly applied tree
20
+ * creates these twice.
21
+ */
22
+ function unkeyedNodes(planned) {
23
+ return planned
24
+ .filter(({ payload }) => !(typeof payload.externalKey === 'string' && payload.externalKey.trim()))
25
+ .map(({ key }) => key);
26
+ }
27
+ function rerunWarning(planned, prefix) {
28
+ const unkeyed = unkeyedNodes(planned);
29
+ if (unkeyed.length === 0)
30
+ return undefined;
31
+ return {
32
+ code: 'TREE_RERUN_NOT_IDEMPOTENT',
33
+ value: unkeyed,
34
+ hint: `${unkeyed.length} node(s) have no externalKey${prefix ? '' : ' and no --external-key-prefix was given'}, ` +
35
+ 'so re-running this tree after a failure would create them again. Pass --external-key-prefix <stable-prefix> ' +
36
+ '(or an externalKey per node) to make a re-run update instead of duplicate.',
37
+ };
38
+ }
39
+ /**
40
+ * A key prefix derived from the tree itself (its JSON plus the default scope),
41
+ * stable across runs: the same file into the same space always names the same
42
+ * keys. Different content or a different default space is a different prefix.
43
+ */
44
+ function derivedTreePrefix(input, defaults) {
45
+ const digest = (0, node_crypto_1.createHash)('sha256')
46
+ .update((0, data_provider_1.stableJson)({ input, defaults }))
47
+ .digest('hex')
48
+ .slice(0, 12);
49
+ return `tree-${digest}`;
50
+ }
51
+ function derivedPrefixWarning(prefix) {
52
+ return {
53
+ code: 'TREE_PREFIX_DERIVED',
54
+ value: prefix,
55
+ hint: `No --external-key-prefix was given, so nodes are keyed "${prefix}/<tempId>" from the file's content: ` +
56
+ 're-running the same file updates these tasks instead of creating copies. Pass --fresh to create a second copy, ' +
57
+ 'or --external-key-prefix to choose your own keys.',
58
+ };
59
+ }
60
+ /**
61
+ * What a half-applied tree reports (E4). The ids already created are the only
62
+ * way to continue or clean up, and the failing call used to print none of them.
63
+ */
64
+ function partialFailureResult(args) {
65
+ const { results, mapping, failedAt, total, prefix, warnings } = args;
66
+ return {
67
+ object: 'task_create_tree_result',
68
+ ok: false,
69
+ count: results.length,
70
+ total,
71
+ created: results.map((r) => ({
72
+ tempId: r.tempId,
73
+ parentTempId: r.parentTempId,
74
+ id: r.id,
75
+ action: r.action,
76
+ externalKey: r.externalKey,
77
+ title: r.title,
78
+ })),
79
+ mapping,
80
+ failedAt,
81
+ rerun: prefix
82
+ ? 'Safe to re-run the same command: nodes with an externalKey are updated, not duplicated.'
83
+ : 'Re-running creates un-keyed nodes again. Use mapping to continue by hand, or re-run with --external-key-prefix.',
84
+ ...(warnings.length > 0 ? { warnings } : {}),
85
+ };
86
+ }
10
87
  class TasksCreateTree extends base_command_1.BaseCommand {
11
88
  static description = 'Create a task tree from JSON. Use {"nodes":[{"tempId":"root","title":"Task","executionMode":"human","assigneeUserIds":["<user-id>"]}]} to avoid inheriting a Space lead agent.';
12
89
  static examples = [
@@ -23,7 +100,10 @@ class TasksCreateTree extends base_command_1.BaseCommand {
23
100
  }),
24
101
  'dry-run': core_1.Flags.boolean({ description: 'Validate and print the plan without creating tasks' }),
25
102
  'external-key-prefix': core_1.Flags.string({
26
- description: 'Generate externalKey for nodes that omit one; enables idempotent re-runs',
103
+ description: 'Generate externalKey for nodes that omit one; enables idempotent re-runs. Defaults to a prefix derived from the file content (see --fresh)',
104
+ }),
105
+ fresh: core_1.Flags.boolean({
106
+ description: 'Do not derive a key prefix from the file: create a new copy even if this exact file was applied before',
27
107
  }),
28
108
  'default-agent': core_1.Flags.string({
29
109
  description: 'Override the automatic assignee for nodes with no assignee. Use "auto" to inherit the space lead agent; children inherit parent assignees first.',
@@ -49,9 +129,15 @@ class TasksCreateTree extends base_command_1.BaseCommand {
49
129
  this.error(err.message, { exit: 1 });
50
130
  }
51
131
  const topLevelDefaults = normalizeDefaults(input, flags);
132
+ // E4: with no prefix of its own, a tree is keyed from its content, so
133
+ // re-running the same file after a failure updates instead of duplicating.
134
+ const derivedPrefix = flags['external-key-prefix'] || flags.fresh
135
+ ? undefined
136
+ : derivedTreePrefix(input, topLevelDefaults);
137
+ const keyPrefix = flags['external-key-prefix'] ?? derivedPrefix;
52
138
  const planned = planTree(roots, {
53
139
  defaults: topLevelDefaults,
54
- externalKeyPrefix: flags['external-key-prefix'],
140
+ externalKeyPrefix: keyPrefix,
55
141
  });
56
142
  const defaultAgentErrors = [];
57
143
  const defaultAgentResolutions = {};
@@ -142,6 +228,13 @@ class TasksCreateTree extends base_command_1.BaseCommand {
142
228
  object: 'task_create_tree_dry_run',
143
229
  ok: true,
144
230
  count: planned.length,
231
+ ...(() => {
232
+ const dryWarnings = [
233
+ rerunWarning(planned, keyPrefix),
234
+ derivedPrefix ? derivedPrefixWarning(derivedPrefix) : undefined,
235
+ ].filter((w) => w !== undefined);
236
+ return dryWarnings.length > 0 ? { warnings: dryWarnings } : {};
237
+ })(),
145
238
  defaultAgents: defaultAgentResolutions,
146
239
  nodes: planned.map((item) => ({
147
240
  tempId: item.key,
@@ -161,9 +254,49 @@ class TasksCreateTree extends base_command_1.BaseCommand {
161
254
  }
162
255
  return;
163
256
  }
257
+ const treeWarning = rerunWarning(planned, keyPrefix);
258
+ const derivedWarning = derivedPrefix ? derivedPrefixWarning(derivedPrefix) : undefined;
259
+ const warnings = [
260
+ ...(treeWarning ? [treeWarning] : []),
261
+ ...(derivedWarning ? [derivedWarning] : []),
262
+ ];
263
+ if (treeWarning && !flags.json)
264
+ process.stderr.write(`Warning: ${treeWarning.hint}\n`);
265
+ if (derivedWarning && !flags.json)
266
+ process.stderr.write(`Note: ${derivedWarning.hint}\n`);
164
267
  const mapping = {};
165
268
  const results = [];
166
- for (const item of planned) {
269
+ // A half-applied tree reports the ids it did create; the only way back.
270
+ const reportPartial = (item, failure, err) => {
271
+ if (results.length === 0)
272
+ this.handleApiError(err);
273
+ const partial = partialFailureResult({
274
+ results,
275
+ mapping,
276
+ total: planned.length,
277
+ prefix: keyPrefix,
278
+ warnings,
279
+ failedAt: {
280
+ tempId: item.key,
281
+ ...(item.parentKey ? { parentTempId: item.parentKey } : {}),
282
+ title: item.payload.title,
283
+ error: failure,
284
+ },
285
+ });
286
+ if (flags.json) {
287
+ this.log(JSON.stringify(partial, null, 2));
288
+ process.exitCode = partial.failedAt.error.retryable ? 5 : 1;
289
+ this.exit(partial.failedAt.error.retryable ? 5 : 1);
290
+ }
291
+ this.log(`Created ${results.length} of ${planned.length} task(s) before "${item.key}" failed:`);
292
+ for (const [tempId, id] of Object.entries(mapping))
293
+ this.log(`- ${tempId} -> ${id}`);
294
+ this.log(partial.rerun);
295
+ this.handleApiError(err);
296
+ };
297
+ // The serial path: one request per node. Used for updates of existing keyed
298
+ // nodes, and for every create against a server without the batch route.
299
+ const applySerial = async (item) => {
167
300
  const payload = { ...item.payload };
168
301
  if (item.parentKey) {
169
302
  payload.parentId = mapping[item.parentKey];
@@ -197,7 +330,8 @@ class TasksCreateTree extends base_command_1.BaseCommand {
197
330
  }
198
331
  }
199
332
  catch (err) {
200
- this.handleApiError(err);
333
+ reportPartial(item, (0, task_batch_1.describeApiFailure)(err), err);
334
+ return;
201
335
  }
202
336
  const id = (0, tasks_1.taskId)(task);
203
337
  mapping[item.key] = id;
@@ -210,9 +344,68 @@ class TasksCreateTree extends base_command_1.BaseCommand {
210
344
  title: task.title ?? payload.title,
211
345
  task,
212
346
  });
347
+ };
348
+ // New nodes go to POST /api/tasks/batch in chunks. `batchAvailable` flips off
349
+ // the first time the server answers 404/405, and every later node is serial.
350
+ let batchAvailable = true;
351
+ let pending = [];
352
+ const flushPending = async () => {
353
+ const nodes = pending;
354
+ pending = [];
355
+ if (nodes.length === 0)
356
+ return;
357
+ if (batchAvailable) {
358
+ const outcome = await (0, task_batch_1.createNodesViaBatch)(nodes.map((n) => ({ key: n.key, parentKey: n.parentKey, payload: n.payload })), mapping);
359
+ if (outcome.supported) {
360
+ const byKey = new Map(nodes.map((n) => [n.key, n]));
361
+ for (const row of outcome.rows) {
362
+ const node = byKey.get(row.key);
363
+ results.push({
364
+ tempId: row.key,
365
+ parentTempId: node.parentKey,
366
+ id: row.id,
367
+ action: row.status === 'exists' ? 'existing' : 'created',
368
+ externalKey: row.externalKey ?? node.payload.externalKey,
369
+ title: node.payload.title,
370
+ task: {
371
+ id: row.id,
372
+ ...(row.identifier ? { identifier: row.identifier } : {}),
373
+ title: node.payload.title,
374
+ },
375
+ });
376
+ }
377
+ const failure = outcome.failures.find((f) => !f.skipped) ?? outcome.failures[0];
378
+ if (failure) {
379
+ const node = byKey.get(failure.key);
380
+ const err = Object.assign(new Error(failure.error.message), {
381
+ ...(failure.error.status ? { status: failure.error.status } : {}),
382
+ ...(failure.error.code ? { code: failure.error.code } : {}),
383
+ });
384
+ reportPartial(node, failure.error, err);
385
+ }
386
+ return;
387
+ }
388
+ batchAvailable = false;
389
+ }
390
+ for (const node of nodes)
391
+ await applySerial(node);
392
+ };
393
+ for (const item of planned) {
394
+ const existingTask = existingByKey.get(item.key) ?? null;
395
+ if (existingTask) {
396
+ // An update must see its parent's id, and a later create its own parent's.
397
+ await flushPending();
398
+ await applySerial(item);
399
+ }
400
+ else {
401
+ pending.push(item);
402
+ }
213
403
  }
404
+ await flushPending();
214
405
  const summary = {
215
406
  object: 'task_create_tree_result',
407
+ ok: true,
408
+ ...(warnings.length > 0 ? { warnings } : {}),
216
409
  count: results.length,
217
410
  defaultAgents: defaultAgentResolutions,
218
411
  mapping,
@@ -24,9 +24,10 @@ class TasksDelete extends base_command_1.BaseCommand {
24
24
  async run() {
25
25
  this.requireAuth();
26
26
  const { args, flags } = await this.parse(TasksDelete);
27
+ const taskId = await this.resolveEntityRef('task', args.id);
27
28
  let confirmed;
28
29
  try {
29
- confirmed = await (0, prompt_1.confirmDestructive)(`Delete task ${args.id}? This cannot be undone.`, flags.yes);
30
+ confirmed = await (0, prompt_1.confirmDestructive)(`Delete task ${taskId === args.id ? taskId : `${args.id} (${taskId})`}? This cannot be undone.`, flags.yes);
30
31
  }
31
32
  catch (err) {
32
33
  if (err.exit === 7) {
@@ -36,18 +37,18 @@ class TasksDelete extends base_command_1.BaseCommand {
36
37
  }
37
38
  if (!confirmed) {
38
39
  if (flags.json)
39
- return this.log(JSON.stringify({ deleted: false, id: args.id }, null, 2));
40
+ return this.log(JSON.stringify({ deleted: false, id: taskId }, null, 2));
40
41
  this.log('Cancelled.');
41
42
  return;
42
43
  }
43
44
  try {
44
- await data_provider_1.dataService.deleteTask(args.id);
45
+ await data_provider_1.dataService.deleteTask(taskId);
45
46
  }
46
47
  catch (err) {
47
48
  this.handleApiError(err);
48
49
  }
49
50
  if (flags.json)
50
- return this.log(JSON.stringify({ deleted: true, id: args.id }, null, 2));
51
+ return this.log(JSON.stringify({ deleted: true, id: taskId }, null, 2));
51
52
  this.log(`Deleted task ${args.id}`);
52
53
  }
53
54
  }
@@ -22,9 +22,10 @@ class TasksDescendants extends base_command_1.BaseCommand {
22
22
  async run() {
23
23
  this.requireAuth();
24
24
  const { args, flags } = await this.parse(TasksDescendants);
25
+ const taskRef = await this.resolveEntityRef('task', args.id);
25
26
  let response;
26
27
  try {
27
- response = await data_provider_1.dataService.getTaskDescendants(args.id, flags.limit);
28
+ response = await data_provider_1.dataService.getTaskDescendants(taskRef, flags.limit);
28
29
  }
29
30
  catch (err) {
30
31
  this.handleApiError(err);
@@ -18,9 +18,10 @@ class TasksDriPlan extends base_command_1.BaseCommand {
18
18
  async run() {
19
19
  this.requireAuth();
20
20
  const { args, flags } = await this.parse(TasksDriPlan);
21
+ const taskRef = await this.resolveEntityRef('task', args.id);
21
22
  let result;
22
23
  try {
23
- result = await data_provider_1.dataService.startDRIPlan(args.id);
24
+ result = await data_provider_1.dataService.startDRIPlan(taskRef);
24
25
  }
25
26
  catch (err) {
26
27
  this.handleApiError(err);
@@ -29,7 +30,7 @@ class TasksDriPlan extends base_command_1.BaseCommand {
29
30
  this.log(JSON.stringify(result, null, 2));
30
31
  return;
31
32
  }
32
- this.log(`Started DRI plan for task ${args.id}`);
33
+ this.log(`Started DRI plan for task ${taskRef}`);
33
34
  const r = result;
34
35
  if (r.conversationId)
35
36
  this.log(`Conversation: ${r.conversationId}`);
@@ -18,9 +18,10 @@ class TasksDriRun extends base_command_1.BaseCommand {
18
18
  async run() {
19
19
  this.requireAuth();
20
20
  const { args, flags } = await this.parse(TasksDriRun);
21
+ const taskRef = await this.resolveEntityRef('task', args.id);
21
22
  let result;
22
23
  try {
23
- result = await data_provider_1.dataService.startDRIAgent(args.id);
24
+ result = await data_provider_1.dataService.startDRIAgent(taskRef);
24
25
  }
25
26
  catch (err) {
26
27
  this.handleApiError(err);
@@ -29,7 +30,7 @@ class TasksDriRun extends base_command_1.BaseCommand {
29
30
  this.log(JSON.stringify(result, null, 2));
30
31
  return;
31
32
  }
32
- this.log(`Started DRI run for task ${args.id}`);
33
+ this.log(`Started DRI run for task ${taskRef}`);
33
34
  const r = result;
34
35
  if (r.conversationId)
35
36
  this.log(`Conversation: ${r.conversationId}`);
@@ -19,9 +19,10 @@ class TasksDriStatus extends base_command_1.BaseCommand {
19
19
  async run() {
20
20
  this.requireAuth();
21
21
  const { args, flags } = await this.parse(TasksDriStatus);
22
+ const taskRef = await this.resolveEntityRef('task', args.id);
22
23
  let result;
23
24
  try {
24
- result = await data_provider_1.dataService.getDRIStatus(args.id);
25
+ result = await data_provider_1.dataService.getDRIStatus(taskRef);
25
26
  }
26
27
  catch (err) {
27
28
  this.handleApiError(err);
@@ -22,6 +22,7 @@ class TasksDuplicatePipeline extends base_command_1.BaseCommand {
22
22
  async run() {
23
23
  this.requireAuth();
24
24
  const { args, flags } = await this.parse(TasksDuplicatePipeline);
25
+ const taskRef = await this.resolveEntityRef('task', args.id);
25
26
  const data = {};
26
27
  if (flags.title)
27
28
  data.title = flags.title;
@@ -29,7 +30,7 @@ class TasksDuplicatePipeline extends base_command_1.BaseCommand {
29
30
  data.description = flags.description;
30
31
  let result;
31
32
  try {
32
- result = await data_provider_1.dataService.duplicatePipeline(args.id, Object.keys(data).length > 0 ? data : undefined);
33
+ result = await data_provider_1.dataService.duplicatePipeline(taskRef, Object.keys(data).length > 0 ? data : undefined);
33
34
  }
34
35
  catch (err) {
35
36
  this.handleApiError(err);
@@ -51,9 +51,10 @@ class TasksExecutionSummary extends base_command_1.BaseCommand {
51
51
  async run() {
52
52
  this.requireAuth();
53
53
  const { args, flags } = await this.parse(TasksExecutionSummary);
54
+ const taskRef = await this.resolveEntityRef('task', args.id);
54
55
  let result;
55
56
  try {
56
- result = await data_provider_1.dataService.getTaskExecutionSummary(args.id);
57
+ result = await data_provider_1.dataService.getTaskExecutionSummary(taskRef);
57
58
  }
58
59
  catch (err) {
59
60
  this.handleApiError(err);
@@ -22,10 +22,11 @@ class TasksExecutionTimeline extends base_command_1.BaseCommand {
22
22
  async run() {
23
23
  this.requireAuth();
24
24
  const { args, flags } = await this.parse(TasksExecutionTimeline);
25
+ const taskRef = await this.resolveEntityRef('task', args.id);
25
26
  const limit = Math.min(flags.limit, 500);
26
27
  let response;
27
28
  try {
28
- response = await data_provider_1.dataService.getTaskExecutionTimeline(args.id, flags.run, limit);
29
+ response = await data_provider_1.dataService.getTaskExecutionTimeline(taskRef, flags.run, limit);
29
30
  }
30
31
  catch (err) {
31
32
  this.handleApiError(err);
@@ -70,6 +70,7 @@ class TasksFork extends base_command_1.BaseCommand {
70
70
  details: { suggestion: failure.suggestion, context: failure.details },
71
71
  });
72
72
  }
73
+ const taskRef = await this.resolveEntityRef('task', taskIdentity.id);
73
74
  const taskId = taskIdentity.id;
74
75
  // The branch agent is OPTIONAL — a fork onto the same agent on a different
75
76
  // target is the "try it on Codex too" case, and the server derives the
@@ -28,6 +28,7 @@ class TasksForward extends base_command_1.BaseCommand {
28
28
  async run() {
29
29
  this.requireAuth();
30
30
  const { args, flags } = await this.parse(TasksForward);
31
+ const taskRef = await this.resolveEntityRef('task', args.id);
31
32
  // Server dedupes ids, but trimming here keeps the audit log readable.
32
33
  const groupChatIds = Array.from(new Set(flags.to.map((id) => id.trim()).filter(Boolean)));
33
34
  if (groupChatIds.length === 0) {
@@ -35,7 +36,7 @@ class TasksForward extends base_command_1.BaseCommand {
35
36
  }
36
37
  let result;
37
38
  try {
38
- result = await data_provider_1.dataService.forwardTask(args.id, {
39
+ result = await data_provider_1.dataService.forwardTask(taskRef, {
39
40
  groupChatIds,
40
41
  note: flags.note,
41
42
  });
@@ -46,13 +47,13 @@ class TasksForward extends base_command_1.BaseCommand {
46
47
  if (flags.json) {
47
48
  this.log(JSON.stringify({
48
49
  ...result,
49
- url: (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, { id: args.id }),
50
+ url: (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, { id: taskRef }),
50
51
  }, null, 2));
51
52
  return;
52
53
  }
53
54
  const posted = result.posted ?? [];
54
55
  const failed = result.failed ?? [];
55
- this.log(`Forwarded task ${args.id} → ${posted.length} chat(s)`);
56
+ this.log(`Forwarded task ${taskRef} → ${posted.length} chat(s)`);
56
57
  for (const p of posted) {
57
58
  this.log(` posted ${p.groupChatId} (message ${p.messageId})`);
58
59
  }
@@ -99,6 +99,7 @@ class TasksHandover extends base_command_1.BaseCommand {
99
99
  details: { suggestion: failure.suggestion, context: failure.details },
100
100
  });
101
101
  }
102
+ const taskRef = await this.resolveEntityRef('task', taskIdentity.id);
102
103
  const taskId = taskIdentity.id;
103
104
  // ── Target agent: id or name, resolved like `code handover --to`. ──────
104
105
  let agents = [];
@@ -28,11 +28,12 @@ class TasksInterrupt extends base_command_1.BaseCommand {
28
28
  async run() {
29
29
  this.requireAuth();
30
30
  const { args, flags } = await this.parse(TasksInterrupt);
31
+ const taskRef = await this.resolveEntityRef('task', args.id);
31
32
  const body = (flags.reason && flags.reason.trim()) || 'Execution interrupted by user.';
32
33
  let result;
33
34
  try {
34
35
  result = await data_provider_1.dataService.addTaskComment({
35
- taskId: args.id,
36
+ taskId: taskRef,
36
37
  data: { body, interrupt: true },
37
38
  });
38
39
  }
@@ -44,7 +45,7 @@ class TasksInterrupt extends base_command_1.BaseCommand {
44
45
  return;
45
46
  }
46
47
  const c = result;
47
- this.log(`Interrupt sent to task ${args.id} (comment ${c.id ?? c._id ?? '?'})`);
48
+ this.log(`Interrupt sent to task ${taskRef} (comment ${c.id ?? c._id ?? '?'})`);
48
49
  }
49
50
  }
50
51
  exports.default = TasksInterrupt;
@@ -40,6 +40,7 @@ class TasksLabelsAttach extends base_command_1.BaseCommand {
40
40
  async run() {
41
41
  this.requireAuth();
42
42
  const { args, flags } = await this.parse(TasksLabelsAttach);
43
+ const taskRef = await this.resolveEntityRef('task', args.id);
43
44
  const refs = (flags['label-id'] ?? []).map((id) => id.trim()).filter((id) => id.length > 0);
44
45
  if (refs.length === 0) {
45
46
  this.error('At least one --label-id is required.', { exit: 1 });
@@ -74,7 +75,7 @@ class TasksLabelsAttach extends base_command_1.BaseCommand {
74
75
  const nameFor = (id) => nameById?.get(id) ?? id;
75
76
  let current;
76
77
  try {
77
- current = await data_provider_1.dataService.getTask(args.id, { enrich: false });
78
+ current = await data_provider_1.dataService.getTask(taskRef, { enrich: false });
78
79
  }
79
80
  catch (err) {
80
81
  this.handleApiError(err);
@@ -93,7 +94,7 @@ class TasksLabelsAttach extends base_command_1.BaseCommand {
93
94
  let updated;
94
95
  try {
95
96
  updated = await data_provider_1.dataService.updateTask({
96
- taskId: args.id,
97
+ taskId: taskRef,
97
98
  data: { labelIds: merged },
98
99
  });
99
100
  }
@@ -106,7 +107,7 @@ class TasksLabelsAttach extends base_command_1.BaseCommand {
106
107
  }
107
108
  const t = updated;
108
109
  const ref = t.identifier ?? (t.taskNumber ? `#${t.taskNumber}` : '');
109
- this.log(`Attached ${merged.length - existing.length} label(s) to task ${t.id ?? args.id}${ref ? ` (${ref})` : ''} — now: ${merged.map(nameFor).join(', ')}`);
110
+ this.log(`Attached ${merged.length - existing.length} label(s) to task ${t.id ?? taskRef}${ref ? ` (${ref})` : ''} — now: ${merged.map(nameFor).join(', ')}`);
110
111
  }
111
112
  }
112
113
  exports.default = TasksLabelsAttach;
@@ -32,6 +32,7 @@ class TasksLabelsDetach extends base_command_1.BaseCommand {
32
32
  async run() {
33
33
  this.requireAuth();
34
34
  const { args, flags } = await this.parse(TasksLabelsDetach);
35
+ const taskRef = await this.resolveEntityRef('task', args.id);
35
36
  const refs = (flags['label-id'] ?? []).map((id) => id.trim()).filter((id) => id.length > 0);
36
37
  if (refs.length === 0) {
37
38
  this.error('At least one --label-id is required.', { exit: 1 });
@@ -55,7 +56,7 @@ class TasksLabelsDetach extends base_command_1.BaseCommand {
55
56
  const targets = new Set(resolvedTargets);
56
57
  let current;
57
58
  try {
58
- current = await data_provider_1.dataService.getTask(args.id, { enrich: false });
59
+ current = await data_provider_1.dataService.getTask(taskRef, { enrich: false });
59
60
  }
60
61
  catch (err) {
61
62
  this.handleApiError(err);
@@ -71,7 +72,7 @@ class TasksLabelsDetach extends base_command_1.BaseCommand {
71
72
  let updated;
72
73
  try {
73
74
  updated = await data_provider_1.dataService.updateTask({
74
- taskId: args.id,
75
+ taskId: taskRef,
75
76
  data: { labelIds: next },
76
77
  });
77
78
  }
@@ -84,7 +85,7 @@ class TasksLabelsDetach extends base_command_1.BaseCommand {
84
85
  }
85
86
  const t = updated;
86
87
  const ref = t.identifier ?? (t.taskNumber ? `#${t.taskNumber}` : '');
87
- this.log(`Detached ${existing.length - next.length} label(s) from task ${t.id ?? args.id}${ref ? ` (${ref})` : ''} — now: ${next.join(', ') || '(none)'}`);
88
+ this.log(`Detached ${existing.length - next.length} label(s) from task ${t.id ?? taskRef}${ref ? ` (${ref})` : ''} — now: ${next.join(', ') || '(none)'}`);
88
89
  }
89
90
  }
90
91
  exports.default = TasksLabelsDetach;
@@ -31,11 +31,12 @@ class TasksLabelsSuggest extends base_command_1.BaseCommand {
31
31
  async run() {
32
32
  this.requireAuth();
33
33
  const { args, flags } = await this.parse(TasksLabelsSuggest);
34
+ const taskRef = await this.resolveEntityRef('task', args.id);
34
35
  let response;
35
36
  try {
36
37
  // The URL lives in the lib — a command that builds its own `/api/...`
37
38
  // string is invisible to the CLI↔API parity check.
38
- response = await (0, task_extras_1.taskLabelSuggestion)(args.id);
39
+ response = await (0, task_extras_1.taskLabelSuggestion)(taskRef);
39
40
  }
40
41
  catch (err) {
41
42
  this.handleApiError(err);
@@ -47,7 +48,7 @@ class TasksLabelsSuggest extends base_command_1.BaseCommand {
47
48
  const suggestions = (response?.suggestions ?? []).filter((s) => Boolean(s?.id && s?.name));
48
49
  const ref = response?.identifier ? ` (${response.identifier})` : '';
49
50
  if (suggestions.length === 0) {
50
- this.log(`No label suggestions for task ${args.id}${ref} — ` +
51
+ this.log(`No label suggestions for task ${taskRef}${ref} — ` +
51
52
  // The server counts the vocabulary AFTER excluding the labels this
52
53
  // task already wears, so 0 means nothing left to propose, not that
53
54
  // the registry is empty.
@@ -57,13 +58,13 @@ class TasksLabelsSuggest extends base_command_1.BaseCommand {
57
58
  ' "No label" is a correct answer.');
58
59
  return;
59
60
  }
60
- this.log(`Suggested labels for task ${args.id}${ref}:`);
61
+ this.log(`Suggested labels for task ${taskRef}${ref}:`);
61
62
  (0, format_1.renderTable)(suggestions.map((s) => ({ id: s.id, name: s.name })), [
62
63
  { key: 'id', header: 'ID' },
63
64
  { key: 'name', header: 'NAME' },
64
65
  ], (line) => this.log(line));
65
66
  this.log(`A suggestion is a proposal, not a write — attach with ` +
66
- `\`skrr tasks labels attach ${args.id} --label <id>\` if one fits.`);
67
+ `\`skrr tasks labels attach ${taskRef} --label <id>\` if one fits.`);
67
68
  }
68
69
  }
69
70
  exports.default = TasksLabelsSuggest;
@@ -1,6 +1,21 @@
1
1
  import type { TaskListParams } from '@skrr-ai/data-provider';
2
2
  import { BaseCommand } from '../../base-command';
3
+ import { type ListWarning } from '../../lib/list-output';
3
4
  type ListFlags = Record<string, unknown>;
5
+ /**
6
+ * E12: inside an agent session an unfiltered `tasks list --json` returned the
7
+ * first page of EVERYTHING, which in practice was cancelled test tasks. When the
8
+ * caller is an agent (a session agent id in the environment) asking for machine
9
+ * output and has named no state filter of its own, default to open work and SAY
10
+ * so, as data (`filter_applied`) and not only in prose. `--all` is the opt-out;
11
+ * any filter the caller wrote leaves the default off, since they have decided.
12
+ * A person at a terminal is untouched.
13
+ */
14
+ export declare function agentSessionOpenDefault(flags: ListFlags, env?: NodeJS.ProcessEnv): {
15
+ open: true;
16
+ reason: 'agent_session_default';
17
+ hint: string;
18
+ } | undefined;
4
19
  /**
5
20
  * What the zero-row case is allowed to say. The bare `No tasks.` was step 3
6
21
  * of `GETTING_STARTED.md` and named no next step; a new user reading it hit
@@ -31,10 +46,21 @@ export declare function taskRef(t: Record<string, unknown>): string;
31
46
  * the command; this function is deliberately pure for reuse and parity tests.
32
47
  */
33
48
  export declare function buildListParams(flags: ListFlags, assigneeUserId?: string): TaskListParams;
49
+ /**
50
+ * P4: `--status bogus` exits 0 with an empty list, and text mode explains why
51
+ * while `--json` said nothing, so an agent could not tell "no matches" from
52
+ * "invalid filter". Same facts, as data.
53
+ */
54
+ export declare function statusFilterWarnings(flags: ListFlags, rowCount: number): ListWarning[];
34
55
  export default class TasksList extends BaseCommand {
35
56
  static description: string;
36
57
  static examples: string[];
37
58
  static flags: {
59
+ strict: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
60
+ calendar: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
61
+ fields: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
62
+ compact: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
63
+ ndjson: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
38
64
  json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
39
65
  space: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
40
66
  goal: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
@@ -75,7 +101,7 @@ export default class TasksList extends BaseCommand {
75
101
  view: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
76
102
  limit: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
77
103
  cursor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
78
- calendar: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
104
+ all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
79
105
  };
80
106
  run(): Promise<void>;
81
107
  }