@skrr-ai/cli 0.1.110 → 0.1.111

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 (391) hide show
  1. package/bin/run.js +15 -1
  2. package/dist/base-command.d.ts +31 -3
  3. package/dist/base-command.js +136 -22
  4. package/dist/commands/actions/list.js +2 -1
  5. package/dist/commands/agenda/trigger/create.js +1 -1
  6. package/dist/commands/agenda/trigger/list.js +2 -1
  7. package/dist/commands/agent-groups/list.js +2 -1
  8. package/dist/commands/agents/actions/list.js +2 -1
  9. package/dist/commands/agents/always-on/status.js +5 -0
  10. package/dist/commands/agents/chat.js +4 -1
  11. package/dist/commands/agents/duplicate.js +4 -0
  12. package/dist/commands/agents/eval/list.js +2 -1
  13. package/dist/commands/agents/files/list.js +2 -1
  14. package/dist/commands/agents/folders/list.js +2 -1
  15. package/dist/commands/agents/goals/list.js +2 -1
  16. package/dist/commands/agents/intuitions/list.js +8 -5
  17. package/dist/commands/agents/list.d.ts +12 -0
  18. package/dist/commands/agents/list.js +45 -8
  19. package/dist/commands/agents/releases/known-issues/list.js +2 -1
  20. package/dist/commands/agents/releases/list.js +5 -1
  21. package/dist/commands/agents/releases/trusted-publishers/list.js +2 -1
  22. package/dist/commands/agents/roles/list.js +2 -1
  23. package/dist/commands/agents/skills/list.js +2 -1
  24. package/dist/commands/agents/todos/list.js +2 -1
  25. package/dist/commands/agents/triggers/list.js +2 -1
  26. package/dist/commands/api-keys/list.js +2 -1
  27. package/dist/commands/apps/channel.d.ts +20 -0
  28. package/dist/commands/apps/channel.js +64 -0
  29. package/dist/commands/apps/check-draft.d.ts +12 -0
  30. package/dist/commands/apps/check-draft.js +41 -0
  31. package/dist/commands/apps/check.d.ts +42 -0
  32. package/dist/commands/apps/check.js +91 -0
  33. package/dist/commands/apps/create.d.ts +15 -0
  34. package/dist/commands/apps/create.js +59 -0
  35. package/dist/commands/apps/data/put.d.ts +18 -0
  36. package/dist/commands/apps/data/put.js +72 -0
  37. package/dist/commands/apps/data/query.d.ts +20 -0
  38. package/dist/commands/apps/data/query.js +88 -0
  39. package/dist/commands/apps/disclosure.d.ts +16 -0
  40. package/dist/commands/apps/disclosure.js +71 -0
  41. package/dist/commands/apps/file/cat.d.ts +15 -0
  42. package/dist/commands/apps/file/cat.js +50 -0
  43. package/dist/commands/apps/file/ls.d.ts +13 -0
  44. package/dist/commands/apps/file/ls.js +47 -0
  45. package/dist/commands/apps/file/mv.d.ts +15 -0
  46. package/dist/commands/apps/file/mv.js +49 -0
  47. package/dist/commands/apps/file/rm.d.ts +15 -0
  48. package/dist/commands/apps/file/rm.js +53 -0
  49. package/dist/commands/apps/file/write.d.ts +17 -0
  50. package/dist/commands/apps/file/write.js +81 -0
  51. package/dist/commands/apps/install.d.ts +19 -0
  52. package/dist/commands/apps/install.js +136 -0
  53. package/dist/commands/apps/installations/list.d.ts +11 -0
  54. package/dist/commands/apps/installations/list.js +49 -0
  55. package/dist/commands/apps/installations/show.d.ts +12 -0
  56. package/dist/commands/apps/installations/show.js +61 -0
  57. package/dist/commands/apps/layout/set.d.ts +11 -0
  58. package/dist/commands/apps/layout/set.js +125 -0
  59. package/dist/commands/apps/layout/show.d.ts +9 -0
  60. package/dist/commands/apps/layout/show.js +33 -0
  61. package/dist/commands/apps/list.d.ts +10 -0
  62. package/dist/commands/apps/list.js +45 -0
  63. package/dist/commands/apps/logs.d.ts +13 -0
  64. package/dist/commands/apps/logs.js +55 -0
  65. package/dist/commands/apps/preview.d.ts +12 -0
  66. package/dist/commands/apps/preview.js +39 -0
  67. package/dist/commands/apps/publish/propose.d.ts +14 -0
  68. package/dist/commands/apps/publish/propose.js +45 -0
  69. package/dist/commands/apps/pull.d.ts +14 -0
  70. package/dist/commands/apps/pull.js +56 -0
  71. package/dist/commands/apps/push.d.ts +15 -0
  72. package/dist/commands/apps/push.js +75 -0
  73. package/dist/commands/apps/reconsent.d.ts +13 -0
  74. package/dist/commands/apps/reconsent.js +67 -0
  75. package/dist/commands/apps/report.d.ts +20 -0
  76. package/dist/commands/apps/report.js +63 -0
  77. package/dist/commands/apps/resume.d.ts +12 -0
  78. package/dist/commands/apps/resume.js +36 -0
  79. package/dist/commands/apps/settings/set.d.ts +13 -0
  80. package/dist/commands/apps/settings/set.js +54 -0
  81. package/dist/commands/apps/settings/show.d.ts +11 -0
  82. package/dist/commands/apps/settings/show.js +31 -0
  83. package/dist/commands/apps/show.d.ts +12 -0
  84. package/dist/commands/apps/show.js +49 -0
  85. package/dist/commands/apps/suspend.d.ts +12 -0
  86. package/dist/commands/apps/suspend.js +35 -0
  87. package/dist/commands/apps/uninstall.d.ts +13 -0
  88. package/dist/commands/apps/uninstall.js +43 -0
  89. package/dist/commands/apps/upgrade.d.ts +14 -0
  90. package/dist/commands/apps/upgrade.js +49 -0
  91. package/dist/commands/apps/version/create.d.ts +14 -0
  92. package/dist/commands/apps/version/create.js +53 -0
  93. package/dist/commands/apps/version/show.d.ts +12 -0
  94. package/dist/commands/apps/version/show.js +39 -0
  95. package/dist/commands/apps/versions.d.ts +12 -0
  96. package/dist/commands/apps/versions.js +40 -0
  97. package/dist/commands/apps/webhooks/list.d.ts +12 -0
  98. package/dist/commands/apps/webhooks/list.js +47 -0
  99. package/dist/commands/characters/list.js +2 -1
  100. package/dist/commands/chats/files/list.js +2 -1
  101. package/dist/commands/chats/folders/list.js +2 -1
  102. package/dist/commands/chats/list.js +2 -1
  103. package/dist/commands/chats/spaces/list.js +2 -1
  104. package/dist/commands/chats/widgets/list.js +2 -1
  105. package/dist/commands/code/jobs/list.js +4 -1
  106. package/dist/commands/commerce/incidents/list.js +2 -1
  107. package/dist/commands/commitments/accounting.js +3 -0
  108. package/dist/commands/commitments/action-proposals.d.ts +8 -0
  109. package/dist/commands/commitments/action-proposals.js +17 -2
  110. package/dist/commands/commitments/cost.d.ts +11 -0
  111. package/dist/commands/commitments/cost.js +25 -0
  112. package/dist/commands/commitments/create.js +6 -1
  113. package/dist/commands/commitments/endpoints/list.js +2 -1
  114. package/dist/commands/commitments/links/list.js +2 -1
  115. package/dist/commands/commitments/list.js +2 -1
  116. package/dist/commands/commitments/liveness.d.ts +30 -0
  117. package/dist/commands/commitments/liveness.js +22 -5
  118. package/dist/commands/commitments/pack/list.js +2 -1
  119. package/dist/commands/commitments/preflight.js +6 -2
  120. package/dist/commands/commitments/update.js +10 -1
  121. package/dist/commands/compass/list.js +2 -1
  122. package/dist/commands/context.js +7 -1
  123. package/dist/commands/convos/list.js +3 -2
  124. package/dist/commands/dm/list.js +2 -1
  125. package/dist/commands/dm/work.d.ts +19 -0
  126. package/dist/commands/dm/work.js +54 -0
  127. package/dist/commands/feeds/list.js +2 -1
  128. package/dist/commands/followups/list.js +2 -1
  129. package/dist/commands/followups/plans/cancel.d.ts +13 -0
  130. package/dist/commands/followups/plans/cancel.js +26 -0
  131. package/dist/commands/followups/plans/create.d.ts +11 -0
  132. package/dist/commands/followups/plans/create.js +35 -0
  133. package/dist/commands/followups/plans/list.d.ts +13 -0
  134. package/dist/commands/followups/plans/list.js +50 -0
  135. package/dist/commands/followups/plans/observability.d.ts +11 -0
  136. package/dist/commands/followups/plans/observability.js +46 -0
  137. package/dist/commands/followups/plans/revise.d.ts +13 -0
  138. package/dist/commands/followups/plans/revise.js +35 -0
  139. package/dist/commands/followups/plans/show.d.ts +11 -0
  140. package/dist/commands/followups/plans/show.js +32 -0
  141. package/dist/commands/goals/key-results/list.js +2 -1
  142. package/dist/commands/goals/labels/list.js +3 -2
  143. package/dist/commands/goals/list.js +3 -2
  144. package/dist/commands/grants/list.js +2 -1
  145. package/dist/commands/harnesses/grants/list.js +2 -1
  146. package/dist/commands/harnesses/leases/list.js +2 -1
  147. package/dist/commands/harnesses/list.js +10 -1
  148. package/dist/commands/ingress/list.js +2 -1
  149. package/dist/commands/initiatives/list.js +2 -1
  150. package/dist/commands/instruction-blocks/list.js +2 -1
  151. package/dist/commands/instructions/list.js +2 -1
  152. package/dist/commands/integrations/connections/list.js +2 -1
  153. package/dist/commands/integrations/tools/list.js +2 -1
  154. package/dist/commands/labels/list.js +3 -2
  155. package/dist/commands/learning/adapters.d.ts +16 -0
  156. package/dist/commands/learning/adapters.js +44 -0
  157. package/dist/commands/machines/dedicated/list.js +2 -1
  158. package/dist/commands/machines/hosted/list.js +2 -1
  159. package/dist/commands/machines/list.js +2 -1
  160. package/dist/commands/machines/show.js +5 -2
  161. package/dist/commands/measures/list.js +2 -1
  162. package/dist/commands/memory/list.js +2 -1
  163. package/dist/commands/memory/proposals/list.js +2 -1
  164. package/dist/commands/memory/stores/list.js +2 -1
  165. package/dist/commands/memory/topics/list.js +2 -1
  166. package/dist/commands/memory/versions/list.js +2 -1
  167. package/dist/commands/messages/list.js +2 -1
  168. package/dist/commands/northstars/intents/list.js +2 -1
  169. package/dist/commands/northstars/list.js +2 -1
  170. package/dist/commands/northstars/recommendations/list.js +2 -1
  171. package/dist/commands/outbox/list.js +2 -1
  172. package/dist/commands/profiles/list.js +2 -1
  173. package/dist/commands/projects/docs/list.js +8 -1
  174. package/dist/commands/projects/updates/list.js +2 -1
  175. package/dist/commands/proposals/list.js +2 -1
  176. package/dist/commands/requests/comments/list.js +2 -1
  177. package/dist/commands/requests/list.js +2 -1
  178. package/dist/commands/shares/list.js +2 -1
  179. package/dist/commands/shortcuts/list.js +2 -1
  180. package/dist/commands/signals/monitors/list.js +2 -1
  181. package/dist/commands/signals/schemas/list.js +2 -1
  182. package/dist/commands/signals/sources/list.js +2 -1
  183. package/dist/commands/space-directory-views/list.js +2 -1
  184. package/dist/commands/spaces/actions/list.js +4 -3
  185. package/dist/commands/spaces/briefs/list.js +2 -1
  186. package/dist/commands/spaces/cycles/list.js +2 -1
  187. package/dist/commands/spaces/files/folders/list.js +2 -1
  188. package/dist/commands/spaces/files/list.js +3 -2
  189. package/dist/commands/spaces/heartbeats/list.js +3 -2
  190. package/dist/commands/spaces/labels/list.js +3 -2
  191. package/dist/commands/spaces/list.d.ts +3 -18
  192. package/dist/commands/spaces/list.js +28 -35
  193. package/dist/commands/spaces/live/cards/list.js +2 -1
  194. package/dist/commands/spaces/members/list.d.ts +1 -0
  195. package/dist/commands/spaces/members/list.js +4 -1
  196. package/dist/commands/spaces/show.js +2 -2
  197. package/dist/commands/spaces/skills/list.js +6 -2
  198. package/dist/commands/spaces/states/list.js +2 -1
  199. package/dist/commands/spaces/views/list.js +2 -1
  200. package/dist/commands/spaces/widgets/list.js +3 -2
  201. package/dist/commands/spaces/workflow-templates/list.js +2 -1
  202. package/dist/commands/spaces/workflows/fixtures/list.js +2 -1
  203. package/dist/commands/spaces/workflows/list.js +3 -2
  204. package/dist/commands/spaces/workflows/proposals/list.js +2 -1
  205. package/dist/commands/spaces/workflows/triggers/list.js +2 -1
  206. package/dist/commands/store/acquisitions/list.js +2 -1
  207. package/dist/commands/store/admissions/list.js +17 -1
  208. package/dist/commands/store/advisories/list.js +2 -1
  209. package/dist/commands/store/follows/list.js +2 -1
  210. package/dist/commands/store/publishers/domains/list.js +2 -1
  211. package/dist/commands/store/reports/list.js +2 -1
  212. package/dist/commands/subscriptions/list.js +2 -1
  213. package/dist/commands/tasks/actionability.js +7 -30
  214. package/dist/commands/tasks/activity.js +3 -7
  215. package/dist/commands/tasks/approvals/list.js +2 -1
  216. package/dist/commands/tasks/assign.d.ts +1 -0
  217. package/dist/commands/tasks/assign.js +43 -7
  218. package/dist/commands/tasks/attachments/list.js +2 -1
  219. package/dist/commands/tasks/chat/send.js +34 -0
  220. package/dist/commands/tasks/comments/add.js +6 -1
  221. package/dist/commands/tasks/comments/list.js +2 -1
  222. package/dist/commands/tasks/complete.js +26 -2
  223. package/dist/commands/tasks/continue.d.ts +18 -0
  224. package/dist/commands/tasks/continue.js +54 -0
  225. package/dist/commands/tasks/create-tree.d.ts +5 -0
  226. package/dist/commands/tasks/create-tree.js +399 -219
  227. package/dist/commands/tasks/create.d.ts +1 -0
  228. package/dist/commands/tasks/create.js +63 -11
  229. package/dist/commands/tasks/deliverable/add.js +10 -3
  230. package/dist/commands/tasks/deliverable/list.js +2 -1
  231. package/dist/commands/tasks/events/list.js +2 -1
  232. package/dist/commands/tasks/execution-state.d.ts +12 -0
  233. package/dist/commands/tasks/execution-state.js +28 -0
  234. package/dist/commands/tasks/expectations/assess.js +40 -5
  235. package/dist/commands/tasks/guide.d.ts +10 -0
  236. package/dist/commands/tasks/guide.js +20 -0
  237. package/dist/commands/tasks/labels/list.js +2 -1
  238. package/dist/commands/tasks/list.d.ts +19 -0
  239. package/dist/commands/tasks/list.js +97 -4
  240. package/dist/commands/tasks/move.js +10 -2
  241. package/dist/commands/tasks/preflight.d.ts +14 -0
  242. package/dist/commands/tasks/preflight.js +77 -0
  243. package/dist/commands/tasks/resource/list.js +2 -1
  244. package/dist/commands/tasks/result/submit.js +10 -1
  245. package/dist/commands/tasks/review.js +6 -1
  246. package/dist/commands/tasks/revisions.d.ts +2 -0
  247. package/dist/commands/tasks/revisions.js +8 -1
  248. package/dist/commands/tasks/show.js +17 -11
  249. package/dist/commands/tasks/start.d.ts +1 -0
  250. package/dist/commands/tasks/start.js +35 -0
  251. package/dist/commands/tasks/templates/list.js +2 -1
  252. package/dist/commands/tasks/timeline.d.ts +5 -0
  253. package/dist/commands/tasks/timeline.js +9 -1
  254. package/dist/commands/tasks/update.d.ts +1 -0
  255. package/dist/commands/tasks/update.js +25 -2
  256. package/dist/commands/tasks/updates/add.js +6 -1
  257. package/dist/commands/tasks/updates/list.js +2 -1
  258. package/dist/commands/tasks/upsert.d.ts +1 -0
  259. package/dist/commands/tasks/upsert.js +8 -1
  260. package/dist/commands/token/list.js +2 -1
  261. package/dist/commands/tokens/list.js +2 -1
  262. package/dist/commands/tones/list.js +4 -2
  263. package/dist/commands/triggers/list.js +2 -1
  264. package/dist/commands/views/list.js +2 -1
  265. package/dist/commands/webhooks/list.js +2 -1
  266. package/dist/commands/whoami.js +1 -1
  267. package/dist/commands/widgets/list.js +2 -1
  268. package/dist/commands/widgets/save-as-app.d.ts +13 -0
  269. package/dist/commands/widgets/save-as-app.js +65 -0
  270. package/dist/commands/work-views/list.js +2 -1
  271. package/dist/commands/worklog/list.js +2 -1
  272. package/dist/commands/workspaces/list.js +3 -2
  273. package/dist/commands/workspaces/members.d.ts +1 -0
  274. package/dist/commands/workspaces/members.js +5 -2
  275. package/dist/generated/managed-instruction-guides.json +2 -2
  276. package/dist/help.js +7 -0
  277. package/dist/lib/agent-proactive-baseline.d.ts +9 -0
  278. package/dist/lib/agent-proactive-baseline.js +44 -0
  279. package/dist/lib/agentic-stream.d.ts +4 -1
  280. package/dist/lib/agentic-stream.js +29 -4
  281. package/dist/lib/appData.d.ts +75 -0
  282. package/dist/lib/appData.js +274 -0
  283. package/dist/lib/appInstallations.d.ts +117 -0
  284. package/dist/lib/appInstallations.js +960 -0
  285. package/dist/lib/appSettings.d.ts +3 -0
  286. package/dist/lib/appSettings.js +71 -0
  287. package/dist/lib/appWebhooks.d.ts +7 -0
  288. package/dist/lib/appWebhooks.js +59 -0
  289. package/dist/lib/apps-command.d.ts +44 -0
  290. package/dist/lib/apps-command.js +164 -0
  291. package/dist/lib/apps.d.ts +45 -0
  292. package/dist/lib/apps.js +148 -0
  293. package/dist/lib/appsCheck.d.ts +12 -0
  294. package/dist/lib/appsCheck.js +173 -0
  295. package/dist/lib/appsFs.d.ts +58 -0
  296. package/dist/lib/appsFs.js +384 -0
  297. package/dist/lib/auth-failure.d.ts +20 -0
  298. package/dist/lib/auth-failure.js +40 -3
  299. package/dist/lib/cli-installers.d.ts +9 -2
  300. package/dist/lib/command-miss.js +107 -0
  301. package/dist/lib/commitment-loop-status.js +25 -3
  302. package/dist/lib/commitments.d.ts +44 -3
  303. package/dist/lib/commitments.js +107 -9
  304. package/dist/lib/compasses.d.ts +4 -0
  305. package/dist/lib/compasses.js +11 -0
  306. package/dist/lib/daemon-setup.js +7 -7
  307. package/dist/lib/daemonHandoff.js +3 -2
  308. package/dist/lib/dedicated-ssh.d.ts +2 -0
  309. package/dist/lib/dedicated-ssh.js +98 -28
  310. package/dist/lib/json-output.d.ts +33 -0
  311. package/dist/lib/json-output.js +37 -0
  312. package/dist/lib/list-output.d.ts +9 -4
  313. package/dist/lib/list-output.js +36 -9
  314. package/dist/lib/lookbackPlans.d.ts +13 -0
  315. package/dist/lib/lookbackPlans.js +68 -0
  316. package/dist/lib/machines.d.ts +27 -6
  317. package/dist/lib/machines.js +25 -14
  318. package/dist/lib/member-output.d.ts +20 -0
  319. package/dist/lib/member-output.js +57 -0
  320. package/dist/lib/preflight-copy.d.ts +7 -0
  321. package/dist/lib/preflight-copy.js +31 -0
  322. package/dist/lib/roles.d.ts +2 -2
  323. package/dist/lib/task-admission.d.ts +9 -0
  324. package/dist/lib/task-admission.js +35 -0
  325. package/dist/lib/task-batch.d.ts +4 -0
  326. package/dist/lib/task-batch.js +2 -0
  327. package/dist/lib/task-operations.d.ts +25 -0
  328. package/dist/lib/task-operations.js +123 -0
  329. package/dist/lib/task-preflight.d.ts +35 -0
  330. package/dist/lib/task-preflight.js +121 -0
  331. package/dist/lib/task-resource-references.d.ts +23 -0
  332. package/dist/lib/task-resource-references.js +119 -0
  333. package/dist/lib/task-spec-verification.d.ts +42 -0
  334. package/dist/lib/task-spec-verification.js +101 -0
  335. package/dist/lib/task-work.d.ts +11 -0
  336. package/dist/lib/task-work.js +41 -0
  337. package/dist/lib/task-write-attribution.d.ts +26 -0
  338. package/dist/lib/task-write-attribution.js +47 -0
  339. package/dist/lib/tasks.d.ts +13 -0
  340. package/dist/lib/tasks.js +61 -8
  341. package/dist/lib/triggers.d.ts +7 -0
  342. package/dist/lib/triggers.js +54 -4
  343. package/dist/lib/usage-discovery.d.ts +4 -0
  344. package/dist/lib/usage-discovery.js +14 -4
  345. package/dist/lib/widgetApps.d.ts +10 -0
  346. package/dist/lib/widgetApps.js +47 -0
  347. package/dist/lib/widgetStaticScan.js +25 -1
  348. package/dist/lib/workspaces.d.ts +11 -4
  349. package/dist/lib/workspaces.js +7 -3
  350. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +14 -1
  351. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -2
  352. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.d.ts +49 -1
  353. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +26 -0
  354. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.d.ts +118 -0
  355. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonWire.js +614 -0
  356. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.d.ts +2 -0
  357. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refresh.js +15 -2
  358. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.d.ts +5 -0
  359. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/refreshClassification.js +3 -1
  360. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.d.ts +177 -0
  361. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/sessionRevocation.js +484 -0
  362. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.d.ts +11 -0
  363. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/telemetryRedaction.js +46 -7
  364. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.d.ts +232 -0
  365. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/toolApprovalSignature.js +372 -0
  366. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.d.ts +17 -1
  367. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/types.js +12 -1
  368. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +14 -1
  369. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +45 -2
  370. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.d.ts +49 -1
  371. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +24 -0
  372. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.d.ts +118 -0
  373. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonWire.js +608 -0
  374. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.d.ts +2 -0
  375. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refresh.js +15 -2
  376. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.d.ts +5 -0
  377. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/refreshClassification.js +3 -1
  378. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.d.ts +177 -0
  379. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/sessionRevocation.js +472 -0
  380. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.d.ts +11 -0
  381. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/telemetryRedaction.js +44 -6
  382. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.d.ts +232 -0
  383. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/toolApprovalSignature.js +360 -0
  384. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.d.ts +17 -1
  385. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/types.js +12 -1
  386. package/dist/node_modules/@skrr-ai/auth-core/package.json +30 -0
  387. package/dist/node_modules/@skrr-ai/data-provider/index.js +25239 -18730
  388. package/docs/v1/operations.md +52 -0
  389. package/docs/v1/space-search.md +19 -0
  390. package/oclif.manifest.json +4719 -479
  391. package/package.json +23 -2
@@ -11,11 +11,15 @@ exports.normalizeTreeRoots = normalizeTreeRoots;
11
11
  exports.planTree = planTree;
12
12
  const core_1 = require("@oclif/core");
13
13
  const node_crypto_1 = require("node:crypto");
14
+ const node_fs_1 = require("node:fs");
14
15
  const data_provider_1 = require("@skrr-ai/data-provider");
15
16
  const base_command_1 = require("../../base-command");
16
17
  const prompt_1 = require("../../lib/prompt");
17
18
  const task_batch_1 = require("../../lib/task-batch");
18
19
  const write_target_1 = require("../../lib/write-target");
20
+ const json_output_1 = require("../../lib/json-output");
21
+ const web_url_1 = require("../../lib/web-url");
22
+ const task_spec_verification_1 = require("../../lib/task-spec-verification");
19
23
  const tasks_1 = require("../../lib/tasks");
20
24
  /**
21
25
  * Nodes a re-run could not recognize: no externalKey of their own and no
@@ -95,10 +99,12 @@ function partialFailureResult(args) {
95
99
  mapping,
96
100
  failedAt,
97
101
  ...(args.failures ? { failures: args.failures } : {}),
98
- rerun: prefix || args.keyed
99
- ? 'Re-run the same keyed file with --resume to confirm existing IDs and create only missing nodes; --verify lists what exists and what is missing without writing. A submitted write may still finish; stable keys prevent duplicates.'
100
- : 'Re-running creates un-keyed nodes again. Use mapping to continue by hand, or re-run with --external-key-prefix.',
101
- ...(args.next && (prefix || args.keyed) ? { next: args.next } : {}),
102
+ rerun: !prefix && !args.keyed
103
+ ? 'Re-running creates un-keyed nodes again. Use mapping to continue by hand, or re-run with --external-key-prefix.'
104
+ : !failedAt.error.retryable
105
+ ? `Correct the rejected input before retrying: ${failedAt.error.message}. No automatic retry is suggested for this refusal.`
106
+ : 'Re-run the same keyed file with --resume to confirm existing IDs and create only missing nodes; --verify lists what exists and what is missing without writing. A submitted write may still finish; stable keys prevent duplicates.',
107
+ ...(args.next && failedAt.error.retryable && (prefix || args.keyed) ? { next: args.next } : {}),
102
108
  ...(warnings.length > 0 ? { warnings } : {}),
103
109
  };
104
110
  }
@@ -165,7 +171,8 @@ class TasksCreateTree extends base_command_1.BaseCommand {
165
171
  '(a "nodes" array, each node with optional "children"; {"root":{...,"children":[...]}} is accepted too). ' +
166
172
  'Put "me" in assigneeUserIds for yourself and "blockedByTempIds":["<tempId>"] for dependencies. ' +
167
173
  'Setting executionMode human with an explicit assignee avoids inheriting a Space lead agent. ' +
168
- 'Nodes with an externalKey (or under --external-key-prefix) are created once: a re-run, --resume or --verify finds them again.';
174
+ 'Nodes with an externalKey (or under --external-key-prefix) are created once: a re-run, --resume or --verify finds them again. ' +
175
+ 'A nodes array also creates sibling tasks. Use --readback to check declared structured fields after applying, or --verify-spec for a read-only field comparison.';
169
176
  static examples = [
170
177
  '<%= config.bin %> tasks create-tree --from-json tree.json --space <space-id> --json',
171
178
  '<%= config.bin %> tasks create-tree --from-json tree.json --space <space-id> --default-agent auto',
@@ -174,6 +181,8 @@ class TasksCreateTree extends base_command_1.BaseCommand {
174
181
  '<%= config.bin %> tasks create-tree --from-json tree.json --external-key-prefix mine/ --verify --json',
175
182
  '<%= config.bin %> tasks create-tree --from-json tree.json --external-key-prefix mine/ --resume',
176
183
  '<%= config.bin %> tasks create-tree --from-json tree.json --space <space-id> --project OSK-P-1 --expect-target skrr.ai',
184
+ '<%= config.bin %> tasks create-tree --from-json tasks.json --unassigned --readback --json',
185
+ '<%= config.bin %> tasks create-tree --from-json tasks.json --verify-spec --json',
177
186
  ];
178
187
  static flags = {
179
188
  json: core_1.Flags.boolean({ description: 'Output the create-tree result as JSON' }),
@@ -186,8 +195,17 @@ class TasksCreateTree extends base_command_1.BaseCommand {
186
195
  }),
187
196
  verify: core_1.Flags.boolean({
188
197
  description: 'Read-only: report which nodes of this tree already exist (matched by externalKey) and which are missing, and write nothing. Exits 1 when any is missing or cannot be checked.',
189
- exclusive: ['fresh', 'resume', 'dry-run', 'no-batch'],
198
+ exclusive: ['fresh', 'resume', 'dry-run', 'no-batch', 'verify-spec', 'readback'],
190
199
  }),
200
+ 'verify-spec': core_1.Flags.boolean({
201
+ description: 'Read-only: find keyed tasks and compare the declared structured fields, including Expectations, labels and assignment. Rich-text description content is explicitly not compared. Never repairs drift.',
202
+ exclusive: ['fresh', 'resume', 'dry-run', 'no-batch', 'verify', 'readback', 'default-agent'],
203
+ }),
204
+ readback: core_1.Flags.boolean({
205
+ description: 'After applying, reread every confirmed Task and report declared structured-field mismatches and read failures. This checks declarations, not whether Expectations are met. No repair or retry is performed by the readback.',
206
+ exclusive: ['verify', 'verify-spec', 'dry-run'],
207
+ }),
208
+ unassigned: core_1.Flags.boolean({ description: 'Explicitly clear assignees on every node, suppressing session/parent/Space defaults while retaining any declared executor intent. Does not start tasks.', exclusive: ['default-agent'] }),
191
209
  'external-key-prefix': core_1.Flags.string({
192
210
  description: 'Generate externalKey for nodes that omit one; enables idempotent re-runs. Defaults to a prefix derived from the file content (see --fresh)',
193
211
  }),
@@ -214,6 +232,10 @@ class TasksCreateTree extends base_command_1.BaseCommand {
214
232
  async run() {
215
233
  this.requireAuth();
216
234
  const { flags } = await this.parse(TasksCreateTree);
235
+ this.setJsonOperation({ command: 'tasks:create-tree', mode: flags['verify-spec'] || flags.verify ? 'verify' : flags['dry-run'] ? 'dry_run' : 'execute' });
236
+ const unassignmentError = (0, tasks_1.taskUnassignmentFlagError)(flags);
237
+ if (unassignmentError)
238
+ this.failWithCliError({ message: unassignmentError, code: 'TASK_UNASSIGNED_CONFLICT', exit: 2, retryable: false });
217
239
  let input = {};
218
240
  try {
219
241
  input = await (0, prompt_1.readJsonBody)(flags['from-json']);
@@ -264,12 +286,42 @@ class TasksCreateTree extends base_command_1.BaseCommand {
264
286
  const scopes = new Map();
265
287
  for (const item of planned) {
266
288
  try {
289
+ (0, tasks_1.applyExplicitTaskUnassignment)(item.payload, Boolean(flags.unassigned));
290
+ const parentSpace = item.parentKey ? plannedByKey.get(item.parentKey)?.payload.spaceId : undefined;
291
+ if (!item.payload.spaceId && typeof parentSpace === 'string')
292
+ item.payload.spaceId = parentSpace;
293
+ await this.resolveTaskResourceReferences(item.payload);
294
+ if (parentSpace && item.payload.spaceId && parentSpace !== item.payload.spaceId) {
295
+ throw new Error('The Task Space contradicts its planned parent Space; no tasks were written.');
296
+ }
267
297
  scopes.set(item.key, await (0, tasks_1.resolveTaskCreateScope)(item.payload, { parentTaskCache, projectCache }));
268
298
  }
269
299
  catch (err) {
270
300
  defaultAgentErrors.push(`${item.key}: ${err.message}`);
271
301
  }
272
302
  }
303
+ // Validate project references through the same scoped read as `projects show`.
304
+ // A supplied Space must not bypass project validation during a dry run.
305
+ const scopedProjects = new Map();
306
+ for (const item of planned) {
307
+ const { spaceId, projectId } = item.payload;
308
+ if (typeof spaceId !== 'string' || typeof projectId !== 'string')
309
+ continue;
310
+ const cacheKey = JSON.stringify([spaceId, projectId]);
311
+ try {
312
+ if (!scopedProjects.has(cacheKey)) {
313
+ scopedProjects.set(cacheKey, data_provider_1.dataService.getSpaceProject(spaceId, projectId));
314
+ }
315
+ const project = await scopedProjects.get(cacheKey);
316
+ if (!project || typeof project.id !== 'string')
317
+ throw new Error('Project lookup returned no canonical id');
318
+ item.payload.projectId = project.id;
319
+ }
320
+ catch (err) {
321
+ const failure = (0, task_batch_1.describeApiFailure)(err);
322
+ defaultAgentErrors.push(`${item.key}: project '${projectId}' was not found or could not be read in space '${spaceId}': ${failure.message}`);
323
+ }
324
+ }
273
325
  // 2. Which nodes already exist? One bulk read, not one request per node.
274
326
  const lookups = planned
275
327
  .filter((item) => scopes.has(item.key) &&
@@ -299,7 +351,12 @@ class TasksCreateTree extends base_command_1.BaseCommand {
299
351
  existingByKey.set(key, hit?.task ?? null);
300
352
  }
301
353
  }
302
- if (flags.verify) {
354
+ if (flags.verify || flags['verify-spec']) {
355
+ for (const error of defaultAgentErrors) {
356
+ const item = planned.find((node) => error.startsWith(`${node.key}:`));
357
+ if (item)
358
+ unverifiable.push({ tempId: item.key, reason: error });
359
+ }
303
360
  await this.verifyTree(planned, existingByKey, unverifiable, flags);
304
361
  return;
305
362
  }
@@ -355,7 +412,7 @@ class TasksCreateTree extends base_command_1.BaseCommand {
355
412
  if (errors.length > 0) {
356
413
  const result = { object: 'task_create_tree_validation', ok: false, errors, planned };
357
414
  if (flags.json)
358
- this.log(JSON.stringify(result, null, 2));
415
+ this.printJsonOperation(result, { writeState: 'not_attempted' });
359
416
  else
360
417
  this.log(`Create-tree validation failed:\n- ${errors.join('\n- ')}`);
361
418
  this.exit(1);
@@ -367,10 +424,12 @@ class TasksCreateTree extends base_command_1.BaseCommand {
367
424
  // Say so before anything is written, not only inside a dry run (OSK-S-440 #9).
368
425
  const agentAssignment = describeDefaultAgentAssignment(defaultAgentResolutions);
369
426
  const noteworthyAssignment = agentAssignment ? [agentAssignment] : [];
427
+ const target = await this.assertWriteTarget(flags['expect-target'], { preview: flags['dry-run'] });
370
428
  if (flags['dry-run']) {
371
429
  const result = {
372
430
  object: 'task_create_tree_dry_run',
373
431
  ok: true,
432
+ target,
374
433
  count: planned.length,
375
434
  ...(() => {
376
435
  const dryWarnings = [
@@ -393,10 +452,11 @@ class TasksCreateTree extends base_command_1.BaseCommand {
393
452
  externalKey: item.payload.externalKey,
394
453
  action: plannedAction(existingByKey.get(item.key), Boolean(flags.resume)),
395
454
  payload: item.payload,
455
+ assignmentPreview: (0, tasks_1.taskAssignmentPreview)(item.payload),
396
456
  })),
397
457
  };
398
458
  if (flags.json)
399
- this.log(JSON.stringify(result, null, 2));
459
+ this.printJsonOperation(result);
400
460
  else {
401
461
  this.log(`Dry run passed. ${planned.length} task(s) would be created/upserted.`);
402
462
  for (const item of planned) {
@@ -419,99 +479,160 @@ class TasksCreateTree extends base_command_1.BaseCommand {
419
479
  if (agentAssignment && process.stderr.isTTY) {
420
480
  process.stderr.write(`Warning: ${agentAssignment.hint}\n`);
421
481
  }
422
- // Everything above only read. From here a request writes, so say where, and
423
- // honour a caller's `--expect-target` before the first one.
424
- const target = await this.assertWriteTarget(flags['expect-target']);
482
+ // Every preflight passed. Track confirmed and submitted work separately:
483
+ // a request can continue on the server after its client is interrupted.
425
484
  const mapping = {};
426
485
  const results = [];
427
486
  const startedAt = Date.now();
428
487
  let rounds = 0;
429
488
  const next = this.nextCommand(flags);
430
- // A half-applied tree reports the ids it did create; the only way back.
431
- const reportPartial = (item, failure, err, failures) => {
432
- if (results.length === 0 && !failures)
433
- this.handleApiError(err);
434
- const partial = partialFailureResult({
435
- results,
436
- mapping,
437
- total: planned.length,
438
- prefix: keyPrefix,
439
- keyed: unkeyedNodes(planned).length === 0,
440
- warnings,
441
- failures,
442
- next,
443
- failedAt: {
444
- tempId: item.key,
445
- ...(item.parentKey ? { parentTempId: item.parentKey } : {}),
446
- title: item.payload.title,
447
- error: failure,
448
- },
449
- });
450
- if (flags.json) {
451
- this.log(JSON.stringify({ ...partial, target }, null, 2));
452
- process.exitCode = partial.failedAt.error.retryable ? 5 : 1;
453
- this.exit(partial.failedAt.error.retryable ? 5 : 1);
489
+ const submitted = new Set();
490
+ const interrupt = (signal) => {
491
+ const confirmed = Object.keys(mapping).length;
492
+ const unknown = [...submitted].filter((key) => !mapping[key]).length;
493
+ const recovery = unkeyedNodes(planned).length === 0
494
+ ? `Run ${next.replace(/ --resume$/, ' --verify')} to reconcile, then ${next} to continue.`
495
+ : 'Inspect the Space using the mapping before retrying: unkeyed nodes may be duplicated.';
496
+ // Signals can arrive while the network request is pending. Do not wait for
497
+ // it or claim it was cancelled: the server may still complete submitted rows.
498
+ try {
499
+ (0, node_fs_1.writeSync)(2, `Interrupted (${signal}). Confirmed ${confirmed} of ${planned.length}; ${unknown} submitted outcome(s) unknown. The server may still finish submitted writes. ${recovery}\n`);
500
+ if (!flags.json && confirmed > 0)
501
+ (0, node_fs_1.writeSync)(2, `Confirmed mapping: ${JSON.stringify(mapping)}\n`);
502
+ if (flags.json)
503
+ (0, node_fs_1.writeSync)(1, JSON.stringify((0, json_output_1.withCliOperation)({
504
+ object: 'task_create_tree_result', ok: false, interrupted: true, signal,
505
+ total: planned.length, count: confirmed, mapping: { ...mapping }, target,
506
+ summary: { confirmed, unknown, notAttempted: planned.length - confirmed - unknown },
507
+ recovery,
508
+ }, { command: 'tasks:create-tree', mode: 'execute', outcome: 'failed', writeState: 'unknown' }), null, 2) + '\n');
454
509
  }
455
- this.log(`Confirmed ${results.length} of ${planned.length} task(s); stopped at "${item.key}":`);
456
- for (const [tempId, id] of Object.entries(mapping))
457
- this.log(`- ${tempId} -> ${id}`);
458
- this.log(partial.rerun);
459
- if (partial.next)
460
- this.log(`Next: ${partial.next}`);
461
- if (failures) {
462
- for (const row of failures) {
463
- const detail = row.error;
464
- this.log(`- ${String(row.tempId)}: ${String(row.outcome)} — ${detail.message}`);
465
- }
466
- this.exit(failure.retryable ? 5 : 1);
467
- return;
510
+ finally {
511
+ process.exit(signal === 'SIGINT' ? 130 : 143);
468
512
  }
469
- this.handleApiError(err);
470
513
  };
471
- // Blockers a node names by tempId, as the real ids the serial path needs.
472
- const blockerIdsFor = (item) => {
473
- const ids = [];
474
- for (const blockerKey of item.blockerKeys ?? []) {
475
- const id = mapping[blockerKey];
476
- if (!id) {
477
- this.error(`Blocker tempId "${blockerKey}" was not created before "${item.key}"`, {
478
- exit: 1,
479
- });
514
+ const onSigint = () => interrupt('SIGINT');
515
+ const onSigterm = () => interrupt('SIGTERM');
516
+ process.on('SIGINT', onSigint);
517
+ process.on('SIGTERM', onSigterm);
518
+ try {
519
+ // A half-applied tree reports the ids it did create; the only way back.
520
+ const reportPartial = (item, failure, err, failures) => {
521
+ if (failure.code === 'PROJECT_NOT_FOUND') {
522
+ failure = { ...failure, message: `Project '${String(item.payload.projectId)}' was not found in space '${String(item.payload.spaceId)}'. Correct --project or the node's projectId` };
480
523
  }
481
- ids.push(id);
482
- }
483
- return ids;
484
- };
485
- // The serial path: one request per node. Used for updates of existing keyed
486
- // nodes, for every create against a server without the batch route, and for
487
- // everything under --no-batch.
488
- const applySerial = async (item) => {
489
- const payload = { ...item.payload };
490
- if (item.parentKey) {
491
- payload.parentId = mapping[item.parentKey];
492
- if (!payload.parentId) {
493
- this.error(`Parent tempId "${item.parentKey}" was not created before "${item.key}"`, {
494
- exit: 1,
524
+ const failureRows = failures ?? [{
525
+ tempId: item.key,
526
+ externalKey: item.payload.externalKey,
527
+ outcome: !failure.status || failure.status === 408 || failure.status >= 500 ? 'unknown' : 'failed',
528
+ error: failure,
529
+ }];
530
+ const accountedFor = new Set([...Object.keys(mapping), ...failureRows.map((row) => String(row.tempId))]);
531
+ for (const node of planned) {
532
+ if (accountedFor.has(node.key))
533
+ continue;
534
+ failureRows.push({
535
+ tempId: node.key,
536
+ externalKey: node.payload.externalKey,
537
+ outcome: 'not_attempted',
538
+ error: { message: 'Not attempted because an earlier node stopped the tree', retryable: true },
495
539
  });
496
540
  }
497
- }
498
- const blockerIds = blockerIdsFor(item);
499
- let action;
500
- let task;
501
- try {
502
- if (typeof payload.externalKey === 'string' && payload.externalKey.trim()) {
503
- const existingTask = existingByKey.get(item.key) ?? null;
504
- if (existingTask) {
505
- action = 'updated';
506
- const patch = (0, tasks_1.removeUndefinedFields)((0, tasks_1.createPatchFromCreatePayload)(payload));
507
- // Adding is idempotent, so a re-run never duplicates or drops an edge.
508
- if (blockerIds.length > 0)
509
- patch.addBlockedByIds = blockerIds;
510
- task = await data_provider_1.dataService.updateTask({
511
- taskId: (0, tasks_1.taskId)(existingTask),
512
- data: patch,
541
+ const partial = partialFailureResult({
542
+ results,
543
+ mapping,
544
+ total: planned.length,
545
+ prefix: keyPrefix,
546
+ keyed: unkeyedNodes(planned).length === 0,
547
+ warnings,
548
+ failures: failureRows,
549
+ next,
550
+ failedAt: {
551
+ tempId: item.key,
552
+ ...(item.parentKey ? { parentTempId: item.parentKey } : {}),
553
+ title: item.payload.title,
554
+ error: failure,
555
+ },
556
+ });
557
+ if (flags.json) {
558
+ this.printJsonOperation({ ...partial, target }, { outcome: 'failed', writeState: partial.summary.unknown > 0 ? 'unknown' : 'confirmed' });
559
+ process.exitCode = partial.failedAt.error.retryable ? 5 : 1;
560
+ this.exit(partial.failedAt.error.retryable ? 5 : 1);
561
+ }
562
+ this.log(`Confirmed ${results.length} of ${planned.length} task(s); stopped at "${item.key}": ${failure.message}`);
563
+ for (const [tempId, id] of Object.entries(mapping))
564
+ this.log(`- ${tempId} -> ${id}`);
565
+ this.log(partial.rerun);
566
+ if (partial.next)
567
+ this.log(`Next: ${partial.next}`);
568
+ if (failures) {
569
+ for (const row of failures) {
570
+ const detail = row.error;
571
+ this.log(`- ${String(row.tempId)}: ${String(row.outcome)} — ${detail.message}`);
572
+ }
573
+ this.exit(failure.retryable ? 5 : 1);
574
+ return;
575
+ }
576
+ this.handleApiError(err);
577
+ };
578
+ // Blockers a node names by tempId, as the real ids the serial path needs.
579
+ const blockerIdsFor = (item) => {
580
+ const ids = [];
581
+ for (const blockerKey of item.blockerKeys ?? []) {
582
+ const id = mapping[blockerKey];
583
+ if (!id) {
584
+ this.error(`Blocker tempId "${blockerKey}" was not created before "${item.key}"`, {
585
+ exit: 1,
586
+ });
587
+ }
588
+ ids.push(id);
589
+ }
590
+ return ids;
591
+ };
592
+ // The serial path: one request per node. Used for updates of existing keyed
593
+ // nodes, for every create against a server without the batch route, and for
594
+ // everything under --no-batch.
595
+ const applySerial = async (item) => {
596
+ const payload = { ...item.payload };
597
+ if (item.parentKey) {
598
+ payload.parentId = mapping[item.parentKey];
599
+ if (!payload.parentId) {
600
+ this.error(`Parent tempId "${item.parentKey}" was not created before "${item.key}"`, {
601
+ exit: 1,
513
602
  });
514
603
  }
604
+ }
605
+ const blockerIds = blockerIdsFor(item);
606
+ let action;
607
+ let task;
608
+ try {
609
+ submitted.add(item.key);
610
+ if (typeof payload.externalKey === 'string' && payload.externalKey.trim()) {
611
+ const existingTask = existingByKey.get(item.key) ?? null;
612
+ if (existingTask) {
613
+ action = 'updated';
614
+ const patch = (0, tasks_1.removeUndefinedFields)((0, tasks_1.createPatchFromCreatePayload)(payload));
615
+ // Adding is idempotent, so a re-run never duplicates or drops an edge.
616
+ if (blockerIds.length > 0)
617
+ patch.addBlockedByIds = blockerIds;
618
+ task = await data_provider_1.dataService.updateTask({
619
+ taskId: (0, tasks_1.taskId)(existingTask),
620
+ data: patch,
621
+ });
622
+ }
623
+ else {
624
+ action = 'created';
625
+ if (blockerIds.length > 0) {
626
+ payload.blockedByIds = [
627
+ ...new Set([
628
+ ...(payload.blockedByIds ?? []),
629
+ ...blockerIds,
630
+ ]),
631
+ ];
632
+ }
633
+ task = await data_provider_1.dataService.createTask(payload);
634
+ }
635
+ }
515
636
  else {
516
637
  action = 'created';
517
638
  if (blockerIds.length > 0) {
@@ -525,147 +646,183 @@ class TasksCreateTree extends base_command_1.BaseCommand {
525
646
  task = await data_provider_1.dataService.createTask(payload);
526
647
  }
527
648
  }
528
- else {
529
- action = 'created';
530
- if (blockerIds.length > 0) {
531
- payload.blockedByIds = [
532
- ...new Set([
533
- ...(payload.blockedByIds ?? []),
534
- ...blockerIds,
535
- ]),
536
- ];
537
- }
538
- task = await data_provider_1.dataService.createTask(payload);
649
+ catch (err) {
650
+ reportPartial(item, (0, task_batch_1.describeApiFailure)(err), err);
651
+ return;
539
652
  }
540
- }
541
- catch (err) {
542
- reportPartial(item, (0, task_batch_1.describeApiFailure)(err), err);
543
- return;
544
- }
545
- const id = (0, tasks_1.taskId)(task);
546
- mapping[item.key] = id;
547
- results.push({
548
- tempId: item.key,
549
- parentTempId: item.parentKey,
550
- id,
551
- action,
552
- externalKey: payload.externalKey,
553
- title: task.title ?? payload.title,
554
- task,
555
- });
556
- };
557
- // A person watching sees the tree being built; anything capturing output
558
- // sees nothing extra (the answer is the JSON / summary at the end).
559
- const onProgress = process.stderr.isTTY
560
- ? (p) => {
561
- process.stderr.write(p.waiting
562
- ? `Waiting ${Math.max(1, Math.round(p.waiting.ms / 1000))}s before trying again (${p.waiting.reason}); ${p.confirmed} of ${p.total} confirmed.\n`
563
- : `Confirmed ${p.confirmed} of ${p.total} (request ${p.round}, ${Math.round(p.elapsedMs / 1000)}s).\n`);
564
- }
565
- : undefined;
566
- // New nodes go to POST /api/tasks/batch, and the batch is driven until every
567
- // one exists (createNodesViaBatch). `batchAvailable` flips off the first time
568
- // the server answers 404/405, or under --no-batch, and every later node is serial.
569
- let batchAvailable = !flags['no-batch'];
570
- let pending = [];
571
- const flushPending = async () => {
572
- const nodes = pending;
573
- pending = [];
574
- if (nodes.length === 0)
575
- return;
576
- if (batchAvailable) {
577
- const outcome = await (0, task_batch_1.createNodesViaBatch)(nodes.map((n) => ({
578
- key: n.key,
579
- parentKey: n.parentKey,
580
- blockerKeys: n.blockerKeys,
581
- payload: n.payload,
582
- })), mapping, { onProgress });
583
- if (outcome.supported) {
584
- rounds += outcome.rounds;
585
- const byKey = new Map(nodes.map((n) => [n.key, n]));
586
- for (const row of outcome.rows) {
587
- const node = byKey.get(row.key);
588
- results.push({
589
- tempId: row.key,
590
- parentTempId: node.parentKey,
591
- id: row.id,
592
- action: row.status === 'exists' ? 'existing' : 'created',
593
- externalKey: row.externalKey ?? node.payload.externalKey,
594
- title: node.payload.title,
595
- task: {
653
+ const id = (0, tasks_1.taskId)(task);
654
+ mapping[item.key] = id;
655
+ results.push({
656
+ tempId: item.key,
657
+ parentTempId: item.parentKey,
658
+ id,
659
+ action,
660
+ externalKey: payload.externalKey,
661
+ title: task.title ?? payload.title,
662
+ task,
663
+ });
664
+ };
665
+ // A person watching sees the tree being built; anything capturing output
666
+ // sees nothing extra (the answer is the JSON / summary at the end).
667
+ const onProgress = (p) => {
668
+ submitted.clear();
669
+ for (const key of p.unknownKeys ?? [])
670
+ submitted.add(key);
671
+ if (process.stderr.isTTY) {
672
+ process.stderr.write(p.waiting
673
+ ? `Waiting ${Math.max(1, Math.round(p.waiting.ms / 1000))}s before trying again (${p.waiting.reason}); ${p.confirmed} of ${p.total} confirmed.\n`
674
+ : `Confirmed ${p.confirmed} of ${p.total} (request ${p.round}, ${Math.round(p.elapsedMs / 1000)}s).\n`);
675
+ }
676
+ };
677
+ // New nodes go to POST /api/tasks/batch, and the batch is driven until every
678
+ // one exists (createNodesViaBatch). `batchAvailable` flips off the first time
679
+ // the server answers 404/405, or under --no-batch, and every later node is serial.
680
+ let batchAvailable = !flags['no-batch'];
681
+ let pending = [];
682
+ const flushPending = async () => {
683
+ const nodes = pending;
684
+ pending = [];
685
+ if (nodes.length === 0)
686
+ return;
687
+ if (batchAvailable) {
688
+ const outcome = await (0, task_batch_1.createNodesViaBatch)(nodes.map((n) => ({
689
+ key: n.key,
690
+ parentKey: n.parentKey,
691
+ blockerKeys: n.blockerKeys,
692
+ payload: n.payload,
693
+ })), mapping, { onProgress, onSubmit: (nodes) => nodes.forEach((node) => submitted.add(node.key)) });
694
+ if (outcome.supported) {
695
+ rounds += outcome.rounds;
696
+ const byKey = new Map(nodes.map((n) => [n.key, n]));
697
+ for (const row of outcome.rows) {
698
+ const node = byKey.get(row.key);
699
+ results.push({
700
+ tempId: row.key,
701
+ parentTempId: node.parentKey,
596
702
  id: row.id,
597
- ...(row.identifier ? { identifier: row.identifier } : {}),
703
+ action: row.status === 'exists' ? 'existing' : 'created',
704
+ externalKey: row.externalKey ?? node.payload.externalKey,
598
705
  title: node.payload.title,
599
- },
600
- });
706
+ task: {
707
+ id: row.id,
708
+ ...(row.identifier ? { identifier: row.identifier } : {}),
709
+ title: node.payload.title,
710
+ },
711
+ });
712
+ }
713
+ const failure = outcome.failures.find((f) => !f.skipped) ?? outcome.failures[0];
714
+ if (failure) {
715
+ const node = byKey.get(failure.key);
716
+ const err = Object.assign(new Error(failure.error.message), {
717
+ ...(failure.error.status ? { status: failure.error.status } : {}),
718
+ ...(failure.error.code ? { code: failure.error.code } : {}),
719
+ });
720
+ reportPartial(node, failure.error, err, outcome.failures.map((f) => ({
721
+ tempId: f.key,
722
+ outcome: f.outcome ?? (f.skipped ? 'not_attempted' : 'failed'),
723
+ externalKey: f.externalKey ?? byKey.get(f.key)?.payload.externalKey,
724
+ error: f.error,
725
+ })));
726
+ }
727
+ return;
601
728
  }
602
- const failure = outcome.failures.find((f) => !f.skipped) ?? outcome.failures[0];
603
- if (failure) {
604
- const node = byKey.get(failure.key);
605
- const err = Object.assign(new Error(failure.error.message), {
606
- ...(failure.error.status ? { status: failure.error.status } : {}),
607
- ...(failure.error.code ? { code: failure.error.code } : {}),
729
+ batchAvailable = false;
730
+ }
731
+ for (const node of nodes)
732
+ await applySerial(node);
733
+ };
734
+ for (const item of planned) {
735
+ const existingTask = existingByKey.get(item.key) ?? null;
736
+ if (existingTask) {
737
+ // An update must see its parent's id, and a later create its own parent's.
738
+ await flushPending();
739
+ if (flags.resume) {
740
+ const id = (0, tasks_1.taskId)(existingTask);
741
+ mapping[item.key] = id;
742
+ results.push({
743
+ tempId: item.key,
744
+ parentTempId: item.parentKey,
745
+ id,
746
+ action: 'existing',
747
+ externalKey: item.payload.externalKey,
748
+ title: existingTask.title ?? item.payload.title,
749
+ task: existingTask,
608
750
  });
609
- reportPartial(node, failure.error, err, outcome.failures.map((f) => ({
610
- tempId: f.key,
611
- outcome: f.outcome ?? (f.skipped ? 'not_attempted' : 'failed'),
612
- externalKey: f.externalKey ?? byKey.get(f.key)?.payload.externalKey,
613
- error: f.error,
614
- })));
615
751
  }
616
- return;
752
+ else
753
+ await applySerial(item);
617
754
  }
618
- batchAvailable = false;
619
- }
620
- for (const node of nodes)
621
- await applySerial(node);
622
- };
623
- for (const item of planned) {
624
- const existingTask = existingByKey.get(item.key) ?? null;
625
- if (existingTask) {
626
- // An update must see its parent's id, and a later create its own parent's.
627
- await flushPending();
628
- if (flags.resume) {
629
- const id = (0, tasks_1.taskId)(existingTask);
630
- mapping[item.key] = id;
631
- results.push({
632
- tempId: item.key,
633
- parentTempId: item.parentKey,
634
- id,
635
- action: 'existing',
636
- externalKey: item.payload.externalKey,
637
- title: existingTask.title ?? item.payload.title,
638
- task: existingTask,
639
- });
755
+ else {
756
+ pending.push(item);
640
757
  }
641
- else
642
- await applySerial(item);
643
758
  }
644
- else {
645
- pending.push(item);
759
+ await flushPending();
760
+ for (const result of results) {
761
+ result.url = (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, result.task);
646
762
  }
763
+ const verification = flags.readback
764
+ ? await this.readbackSpecifications(planned, mapping)
765
+ : undefined;
766
+ const summary = {
767
+ object: 'task_create_tree_result',
768
+ ok: verification ? verification.ok : true,
769
+ ...(warnings.length > 0 ? { warnings } : {}),
770
+ count: results.length,
771
+ defaultAgents: defaultAgentResolutions,
772
+ target,
773
+ timing: { elapsedMs: Date.now() - startedAt, requests: rounds },
774
+ mapping,
775
+ results,
776
+ ...(verification ? { verification } : {}),
777
+ };
778
+ if (flags.json) {
779
+ this.printJsonOperation(summary, { writeState: 'confirmed' });
780
+ if (verification && !verification.ok)
781
+ this.exit(1);
782
+ return;
783
+ }
784
+ this.log(`Created task tree (${results.length} task(s)).`);
785
+ for (const item of results) {
786
+ const task = item.task;
787
+ this.log(`- ${item.tempId}: ${item.action} ${(0, tasks_1.formatTaskLabel)(task)}`);
788
+ if (item.url)
789
+ this.log(` ${item.url}`);
790
+ }
791
+ if (verification)
792
+ this.printSpecificationSummary(verification);
793
+ if (verification && !verification.ok)
794
+ this.exit(1);
647
795
  }
648
- await flushPending();
649
- const summary = {
650
- object: 'task_create_tree_result',
651
- ok: true,
652
- ...(warnings.length > 0 ? { warnings } : {}),
653
- count: results.length,
654
- defaultAgents: defaultAgentResolutions,
655
- target,
656
- timing: { elapsedMs: Date.now() - startedAt, requests: rounds },
657
- mapping,
658
- results,
659
- };
660
- if (flags.json) {
661
- this.log(JSON.stringify(summary, null, 2));
662
- return;
796
+ finally {
797
+ process.removeListener('SIGINT', onSigint);
798
+ process.removeListener('SIGTERM', onSigterm);
663
799
  }
664
- this.log(`Created task tree (${results.length} task(s)).`);
665
- for (const item of results) {
666
- const task = item.task;
667
- this.log(`- ${item.tempId}: ${item.action} ${(0, tasks_1.formatTaskLabel)(task)}`);
800
+ }
801
+ async readbackSpecifications(planned, mapping) {
802
+ const inputs = planned.map(item => {
803
+ const expected = { ...item.payload };
804
+ if (item.parentKey)
805
+ expected.parentId = mapping[item.parentKey];
806
+ if (item.blockerKeys?.length)
807
+ expected.blockedByIds = [...new Set([
808
+ ...(expected.blockedByIds ?? []),
809
+ ...item.blockerKeys.map(key => mapping[key]),
810
+ ])];
811
+ return { tempId: item.key, id: mapping[item.key], expected };
812
+ });
813
+ return (0, task_spec_verification_1.verifyTaskSpecifications)(inputs, id => data_provider_1.dataService.getTask(id, { enrich: false }));
814
+ }
815
+ printSpecificationSummary(verification) {
816
+ const { summary } = verification;
817
+ this.log(`Structured-field readback: ${summary.matched} match; ${summary.mismatched} differ; ${summary.unavailable} unavailable.`);
818
+ for (const row of verification.results) {
819
+ for (const mismatch of row.mismatches)
820
+ this.log(`- ${row.tempId}: ${mismatch.field} differs`);
821
+ if (row.error)
822
+ this.log(`- ${row.tempId}: cannot read — ${row.error}`);
668
823
  }
824
+ if (summary.withUncheckedFields)
825
+ this.log('Some authored fields are explicitly unchecked; inspect verification.results[].uncheckedFields. No Expectation assessment was performed.');
669
826
  }
670
827
  /**
671
828
  * `--verify`: which nodes of this tree exist, and which do not. Read-only by
@@ -692,6 +849,7 @@ class TasksCreateTree extends base_command_1.BaseCommand {
692
849
  ...(typeof task.identifier === 'string' ? { identifier: task.identifier } : {}),
693
850
  externalKey: item.payload.externalKey,
694
851
  title: task.title ?? item.payload.title,
852
+ url: (0, web_url_1.taskUrlFrom)(this.cliConfig.baseURL, task),
695
853
  });
696
854
  }
697
855
  else {
@@ -703,7 +861,26 @@ class TasksCreateTree extends base_command_1.BaseCommand {
703
861
  });
704
862
  }
705
863
  }
706
- const ok = missing.length === 0 && cannotCheck.size === 0;
864
+ let verification;
865
+ if (flags['verify-spec']) {
866
+ const mapping = Object.fromEntries(existing.map(row => [String(row.tempId), String(row.id)]));
867
+ const checkable = [];
868
+ for (const item of planned) {
869
+ if (!mapping[item.key] || cannotCheck.has(item.key))
870
+ continue;
871
+ const unresolved = [item.parentKey, ...(item.blockerKeys ?? [])].filter(key => key && !mapping[key]);
872
+ if (unresolved.length) {
873
+ cannotCheck.set(item.key, `Cannot resolve related node(s): ${unresolved.join(', ')}`);
874
+ continue;
875
+ }
876
+ // Resolve only explicitly authored names. Read-only verification must
877
+ // not re-derive who a current Space lead would assign today.
878
+ await this.resolveAssigneesInPayload(item.payload);
879
+ checkable.push(item);
880
+ }
881
+ verification = await this.readbackSpecifications(checkable, mapping);
882
+ }
883
+ const ok = missing.length === 0 && cannotCheck.size === 0 && (!verification || verification.ok);
707
884
  const result = {
708
885
  object: 'task_create_tree_verification',
709
886
  ok,
@@ -716,11 +893,12 @@ class TasksCreateTree extends base_command_1.BaseCommand {
716
893
  existing,
717
894
  missing,
718
895
  unverifiable: [...cannotCheck].map(([tempId, reason]) => ({ tempId, reason })),
896
+ ...(verification ? { verification } : {}),
719
897
  target: await this.describeWriteTarget(),
720
898
  ...(missing.length > 0 ? { next: this.nextCommand(flags) } : {}),
721
899
  };
722
900
  if (flags.json) {
723
- this.log(JSON.stringify(result, null, 2));
901
+ this.printJsonOperation(result);
724
902
  }
725
903
  else {
726
904
  this.log(`${existing.length} of ${planned.length} node(s) exist; ${missing.length} missing` +
@@ -732,6 +910,8 @@ class TasksCreateTree extends base_command_1.BaseCommand {
732
910
  this.log(`- cannot check: ${tempId} — ${reason}`);
733
911
  if (result.next)
734
912
  this.log(`Next: ${result.next}`);
913
+ if (verification)
914
+ this.printSpecificationSummary(verification);
735
915
  }
736
916
  if (!ok)
737
917
  this.exit(1);