monday-cli 0.2.0

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 (596) hide show
  1. package/CHANGELOG.md +439 -0
  2. package/LICENSE +21 -0
  3. package/README.md +431 -0
  4. package/dist/api/board-child-finder.d.ts +95 -0
  5. package/dist/api/board-child-finder.d.ts.map +1 -0
  6. package/dist/api/board-child-finder.js +89 -0
  7. package/dist/api/board-child-finder.js.map +1 -0
  8. package/dist/api/board-metadata.d.ts +162 -0
  9. package/dist/api/board-metadata.d.ts.map +1 -0
  10. package/dist/api/board-metadata.js +238 -0
  11. package/dist/api/board-metadata.js.map +1 -0
  12. package/dist/api/board-mutation-invalidation.d.ts +153 -0
  13. package/dist/api/board-mutation-invalidation.d.ts.map +1 -0
  14. package/dist/api/board-mutation-invalidation.js +136 -0
  15. package/dist/api/board-mutation-invalidation.js.map +1 -0
  16. package/dist/api/board-mutation-result.d.ts +97 -0
  17. package/dist/api/board-mutation-result.d.ts.map +1 -0
  18. package/dist/api/board-mutation-result.js +99 -0
  19. package/dist/api/board-mutation-result.js.map +1 -0
  20. package/dist/api/board-projection.d.ts +68 -0
  21. package/dist/api/board-projection.d.ts.map +1 -0
  22. package/dist/api/board-projection.js +79 -0
  23. package/dist/api/board-projection.js.map +1 -0
  24. package/dist/api/cache.d.ts +150 -0
  25. package/dist/api/cache.d.ts.map +1 -0
  26. package/dist/api/cache.js +418 -0
  27. package/dist/api/cache.js.map +1 -0
  28. package/dist/api/client.d.ts +162 -0
  29. package/dist/api/client.d.ts.map +1 -0
  30. package/dist/api/client.js +205 -0
  31. package/dist/api/client.js.map +1 -0
  32. package/dist/api/column-mapping.d.ts +68 -0
  33. package/dist/api/column-mapping.d.ts.map +1 -0
  34. package/dist/api/column-mapping.js +117 -0
  35. package/dist/api/column-mapping.js.map +1 -0
  36. package/dist/api/column-mutation-result.d.ts +136 -0
  37. package/dist/api/column-mutation-result.d.ts.map +1 -0
  38. package/dist/api/column-mutation-result.js +130 -0
  39. package/dist/api/column-mutation-result.js.map +1 -0
  40. package/dist/api/column-types.d.ts +215 -0
  41. package/dist/api/column-types.d.ts.map +1 -0
  42. package/dist/api/column-types.js +195 -0
  43. package/dist/api/column-types.js.map +1 -0
  44. package/dist/api/column-values.d.ts +446 -0
  45. package/dist/api/column-values.d.ts.map +1 -0
  46. package/dist/api/column-values.js +795 -0
  47. package/dist/api/column-values.js.map +1 -0
  48. package/dist/api/columns.d.ts +205 -0
  49. package/dist/api/columns.d.ts.map +1 -0
  50. package/dist/api/columns.js +343 -0
  51. package/dist/api/columns.js.map +1 -0
  52. package/dist/api/complexity.d.ts +90 -0
  53. package/dist/api/complexity.d.ts.map +1 -0
  54. package/dist/api/complexity.js +194 -0
  55. package/dist/api/complexity.js.map +1 -0
  56. package/dist/api/dates.d.ts +150 -0
  57. package/dist/api/dates.d.ts.map +1 -0
  58. package/dist/api/dates.js +490 -0
  59. package/dist/api/dates.js.map +1 -0
  60. package/dist/api/destructive-gate.d.ts +107 -0
  61. package/dist/api/destructive-gate.d.ts.map +1 -0
  62. package/dist/api/destructive-gate.js +19 -0
  63. package/dist/api/destructive-gate.js.map +1 -0
  64. package/dist/api/dry-run.d.ts +338 -0
  65. package/dist/api/dry-run.d.ts.map +1 -0
  66. package/dist/api/dry-run.js +607 -0
  67. package/dist/api/dry-run.js.map +1 -0
  68. package/dist/api/emails.d.ts +60 -0
  69. package/dist/api/emails.d.ts.map +1 -0
  70. package/dist/api/emails.js +113 -0
  71. package/dist/api/emails.js.map +1 -0
  72. package/dist/api/errors.d.ts +82 -0
  73. package/dist/api/errors.d.ts.map +1 -0
  74. package/dist/api/errors.js +434 -0
  75. package/dist/api/errors.js.map +1 -0
  76. package/dist/api/filters.d.ts +198 -0
  77. package/dist/api/filters.d.ts.map +1 -0
  78. package/dist/api/filters.js +328 -0
  79. package/dist/api/filters.js.map +1 -0
  80. package/dist/api/group-color.d.ts +33 -0
  81. package/dist/api/group-color.d.ts.map +1 -0
  82. package/dist/api/group-color.js +80 -0
  83. package/dist/api/group-color.js.map +1 -0
  84. package/dist/api/group-mutation-result.d.ts +150 -0
  85. package/dist/api/group-mutation-result.d.ts.map +1 -0
  86. package/dist/api/group-mutation-result.js +141 -0
  87. package/dist/api/group-mutation-result.js.map +1 -0
  88. package/dist/api/iso-country-codes.d.ts +45 -0
  89. package/dist/api/iso-country-codes.d.ts.map +1 -0
  90. package/dist/api/iso-country-codes.js +71 -0
  91. package/dist/api/iso-country-codes.js.map +1 -0
  92. package/dist/api/item-board-lookup.d.ts +86 -0
  93. package/dist/api/item-board-lookup.d.ts.map +1 -0
  94. package/dist/api/item-board-lookup.js +140 -0
  95. package/dist/api/item-board-lookup.js.map +1 -0
  96. package/dist/api/item-helpers.d.ts +133 -0
  97. package/dist/api/item-helpers.d.ts.map +1 -0
  98. package/dist/api/item-helpers.js +139 -0
  99. package/dist/api/item-helpers.js.map +1 -0
  100. package/dist/api/item-mutation-result.d.ts +60 -0
  101. package/dist/api/item-mutation-result.d.ts.map +1 -0
  102. package/dist/api/item-mutation-result.js +63 -0
  103. package/dist/api/item-mutation-result.js.map +1 -0
  104. package/dist/api/item-projection.d.ts +165 -0
  105. package/dist/api/item-projection.d.ts.map +1 -0
  106. package/dist/api/item-projection.js +235 -0
  107. package/dist/api/item-projection.js.map +1 -0
  108. package/dist/api/item-source-read.d.ts +45 -0
  109. package/dist/api/item-source-read.d.ts.map +1 -0
  110. package/dist/api/item-source-read.js +57 -0
  111. package/dist/api/item-source-read.js.map +1 -0
  112. package/dist/api/items-page-walker.d.ts +126 -0
  113. package/dist/api/items-page-walker.d.ts.map +1 -0
  114. package/dist/api/items-page-walker.js +256 -0
  115. package/dist/api/items-page-walker.js.map +1 -0
  116. package/dist/api/links.d.ts +70 -0
  117. package/dist/api/links.d.ts.map +1 -0
  118. package/dist/api/links.js +128 -0
  119. package/dist/api/links.js.map +1 -0
  120. package/dist/api/me-token.d.ts +52 -0
  121. package/dist/api/me-token.d.ts.map +1 -0
  122. package/dist/api/me-token.js +55 -0
  123. package/dist/api/me-token.js.map +1 -0
  124. package/dist/api/pagination.d.ts +201 -0
  125. package/dist/api/pagination.d.ts.map +1 -0
  126. package/dist/api/pagination.js +223 -0
  127. package/dist/api/pagination.js.map +1 -0
  128. package/dist/api/partial-success-mutation.d.ts +28 -0
  129. package/dist/api/partial-success-mutation.d.ts.map +1 -0
  130. package/dist/api/partial-success-mutation.js +68 -0
  131. package/dist/api/partial-success-mutation.js.map +1 -0
  132. package/dist/api/people.d.ts +182 -0
  133. package/dist/api/people.d.ts.map +1 -0
  134. package/dist/api/people.js +260 -0
  135. package/dist/api/people.js.map +1 -0
  136. package/dist/api/phones.d.ts +74 -0
  137. package/dist/api/phones.d.ts.map +1 -0
  138. package/dist/api/phones.js +167 -0
  139. package/dist/api/phones.js.map +1 -0
  140. package/dist/api/raw-document.d.ts +53 -0
  141. package/dist/api/raw-document.d.ts.map +1 -0
  142. package/dist/api/raw-document.js +177 -0
  143. package/dist/api/raw-document.js.map +1 -0
  144. package/dist/api/raw-write.d.ts +127 -0
  145. package/dist/api/raw-write.d.ts.map +1 -0
  146. package/dist/api/raw-write.js +233 -0
  147. package/dist/api/raw-write.js.map +1 -0
  148. package/dist/api/resolution-context.d.ts +32 -0
  149. package/dist/api/resolution-context.d.ts.map +1 -0
  150. package/dist/api/resolution-context.js +42 -0
  151. package/dist/api/resolution-context.js.map +1 -0
  152. package/dist/api/resolution-pass.d.ts +163 -0
  153. package/dist/api/resolution-pass.d.ts.map +1 -0
  154. package/dist/api/resolution-pass.js +254 -0
  155. package/dist/api/resolution-pass.js.map +1 -0
  156. package/dist/api/resolve-client.d.ts +69 -0
  157. package/dist/api/resolve-client.d.ts.map +1 -0
  158. package/dist/api/resolve-client.js +70 -0
  159. package/dist/api/resolve-client.js.map +1 -0
  160. package/dist/api/resolver-error-fold.d.ts +176 -0
  161. package/dist/api/resolver-error-fold.d.ts.map +1 -0
  162. package/dist/api/resolver-error-fold.js +230 -0
  163. package/dist/api/resolver-error-fold.js.map +1 -0
  164. package/dist/api/resolvers.d.ts +131 -0
  165. package/dist/api/resolvers.d.ts.map +1 -0
  166. package/dist/api/resolvers.js +262 -0
  167. package/dist/api/resolvers.js.map +1 -0
  168. package/dist/api/response-root.d.ts +65 -0
  169. package/dist/api/response-root.d.ts.map +1 -0
  170. package/dist/api/response-root.js +61 -0
  171. package/dist/api/response-root.js.map +1 -0
  172. package/dist/api/retry.d.ts +112 -0
  173. package/dist/api/retry.d.ts.map +1 -0
  174. package/dist/api/retry.js +181 -0
  175. package/dist/api/retry.js.map +1 -0
  176. package/dist/api/set-expression.d.ts +23 -0
  177. package/dist/api/set-expression.d.ts.map +1 -0
  178. package/dist/api/set-expression.js +31 -0
  179. package/dist/api/set-expression.js.map +1 -0
  180. package/dist/api/sort.d.ts +59 -0
  181. package/dist/api/sort.d.ts.map +1 -0
  182. package/dist/api/sort.js +73 -0
  183. package/dist/api/sort.js.map +1 -0
  184. package/dist/api/source-aggregator.d.ts +94 -0
  185. package/dist/api/source-aggregator.d.ts.map +1 -0
  186. package/dist/api/source-aggregator.js +111 -0
  187. package/dist/api/source-aggregator.js.map +1 -0
  188. package/dist/api/transport.d.ts +58 -0
  189. package/dist/api/transport.d.ts.map +1 -0
  190. package/dist/api/transport.js +190 -0
  191. package/dist/api/transport.js.map +1 -0
  192. package/dist/api/update-mutation-result.d.ts +133 -0
  193. package/dist/api/update-mutation-result.d.ts.map +1 -0
  194. package/dist/api/update-mutation-result.js +145 -0
  195. package/dist/api/update-mutation-result.js.map +1 -0
  196. package/dist/api/users-fan-out-mutation.d.ts +124 -0
  197. package/dist/api/users-fan-out-mutation.d.ts.map +1 -0
  198. package/dist/api/users-fan-out-mutation.js +331 -0
  199. package/dist/api/users-fan-out-mutation.js.map +1 -0
  200. package/dist/api/walk-pages.d.ts +91 -0
  201. package/dist/api/walk-pages.d.ts.map +1 -0
  202. package/dist/api/walk-pages.js +84 -0
  203. package/dist/api/walk-pages.js.map +1 -0
  204. package/dist/api/workspace-projection.d.ts +64 -0
  205. package/dist/api/workspace-projection.d.ts.map +1 -0
  206. package/dist/api/workspace-projection.js +83 -0
  207. package/dist/api/workspace-projection.js.map +1 -0
  208. package/dist/cli/envelope-out.d.ts +128 -0
  209. package/dist/cli/envelope-out.d.ts.map +1 -0
  210. package/dist/cli/envelope-out.js +146 -0
  211. package/dist/cli/envelope-out.js.map +1 -0
  212. package/dist/cli/index.d.ts +3 -0
  213. package/dist/cli/index.d.ts.map +1 -0
  214. package/dist/cli/index.js +27 -0
  215. package/dist/cli/index.js.map +1 -0
  216. package/dist/cli/program.d.ts +29 -0
  217. package/dist/cli/program.d.ts.map +1 -0
  218. package/dist/cli/program.js +109 -0
  219. package/dist/cli/program.js.map +1 -0
  220. package/dist/cli/run.d.ts +108 -0
  221. package/dist/cli/run.d.ts.map +1 -0
  222. package/dist/cli/run.js +105 -0
  223. package/dist/cli/run.js.map +1 -0
  224. package/dist/commands/account/client-helper.d.ts +37 -0
  225. package/dist/commands/account/client-helper.d.ts.map +1 -0
  226. package/dist/commands/account/client-helper.js +55 -0
  227. package/dist/commands/account/client-helper.js.map +1 -0
  228. package/dist/commands/account/complexity.d.ts +29 -0
  229. package/dist/commands/account/complexity.d.ts.map +1 -0
  230. package/dist/commands/account/complexity.js +70 -0
  231. package/dist/commands/account/complexity.js.map +1 -0
  232. package/dist/commands/account/info.d.ts +36 -0
  233. package/dist/commands/account/info.d.ts.map +1 -0
  234. package/dist/commands/account/info.js +74 -0
  235. package/dist/commands/account/info.js.map +1 -0
  236. package/dist/commands/account/version.d.ts +44 -0
  237. package/dist/commands/account/version.d.ts.map +1 -0
  238. package/dist/commands/account/version.js +98 -0
  239. package/dist/commands/account/version.js.map +1 -0
  240. package/dist/commands/account/whoami.d.ts +34 -0
  241. package/dist/commands/account/whoami.d.ts.map +1 -0
  242. package/dist/commands/account/whoami.js +77 -0
  243. package/dist/commands/account/whoami.js.map +1 -0
  244. package/dist/commands/board/add-users.d.ts +60 -0
  245. package/dist/commands/board/add-users.d.ts.map +1 -0
  246. package/dist/commands/board/add-users.js +133 -0
  247. package/dist/commands/board/add-users.js.map +1 -0
  248. package/dist/commands/board/archive.d.ts +64 -0
  249. package/dist/commands/board/archive.d.ts.map +1 -0
  250. package/dist/commands/board/archive.js +226 -0
  251. package/dist/commands/board/archive.js.map +1 -0
  252. package/dist/commands/board/column-create.d.ts +146 -0
  253. package/dist/commands/board/column-create.d.ts.map +1 -0
  254. package/dist/commands/board/column-create.js +564 -0
  255. package/dist/commands/board/column-create.js.map +1 -0
  256. package/dist/commands/board/column-delete.d.ts +76 -0
  257. package/dist/commands/board/column-delete.d.ts.map +1 -0
  258. package/dist/commands/board/column-delete.js +224 -0
  259. package/dist/commands/board/column-delete.js.map +1 -0
  260. package/dist/commands/board/column-update.d.ts +92 -0
  261. package/dist/commands/board/column-update.d.ts.map +1 -0
  262. package/dist/commands/board/column-update.js +364 -0
  263. package/dist/commands/board/column-update.js.map +1 -0
  264. package/dist/commands/board/columns.d.ts +30 -0
  265. package/dist/commands/board/columns.d.ts.map +1 -0
  266. package/dist/commands/board/columns.js +102 -0
  267. package/dist/commands/board/columns.js.map +1 -0
  268. package/dist/commands/board/create.d.ts +67 -0
  269. package/dist/commands/board/create.d.ts.map +1 -0
  270. package/dist/commands/board/create.js +226 -0
  271. package/dist/commands/board/create.js.map +1 -0
  272. package/dist/commands/board/delete.d.ts +60 -0
  273. package/dist/commands/board/delete.d.ts.map +1 -0
  274. package/dist/commands/board/delete.js +192 -0
  275. package/dist/commands/board/delete.js.map +1 -0
  276. package/dist/commands/board/describe.d.ts +68 -0
  277. package/dist/commands/board/describe.d.ts.map +1 -0
  278. package/dist/commands/board/describe.js +241 -0
  279. package/dist/commands/board/describe.js.map +1 -0
  280. package/dist/commands/board/doctor.d.ts +108 -0
  281. package/dist/commands/board/doctor.d.ts.map +1 -0
  282. package/dist/commands/board/doctor.js +417 -0
  283. package/dist/commands/board/doctor.js.map +1 -0
  284. package/dist/commands/board/duplicate.d.ts +85 -0
  285. package/dist/commands/board/duplicate.d.ts.map +1 -0
  286. package/dist/commands/board/duplicate.js +281 -0
  287. package/dist/commands/board/duplicate.js.map +1 -0
  288. package/dist/commands/board/find.d.ts +47 -0
  289. package/dist/commands/board/find.d.ts.map +1 -0
  290. package/dist/commands/board/find.js +153 -0
  291. package/dist/commands/board/find.js.map +1 -0
  292. package/dist/commands/board/get.d.ts +41 -0
  293. package/dist/commands/board/get.d.ts.map +1 -0
  294. package/dist/commands/board/get.js +66 -0
  295. package/dist/commands/board/get.js.map +1 -0
  296. package/dist/commands/board/group-archive.d.ts +83 -0
  297. package/dist/commands/board/group-archive.d.ts.map +1 -0
  298. package/dist/commands/board/group-archive.js +264 -0
  299. package/dist/commands/board/group-archive.js.map +1 -0
  300. package/dist/commands/board/group-create.d.ts +118 -0
  301. package/dist/commands/board/group-create.d.ts.map +1 -0
  302. package/dist/commands/board/group-create.js +239 -0
  303. package/dist/commands/board/group-create.js.map +1 -0
  304. package/dist/commands/board/group-delete.d.ts +79 -0
  305. package/dist/commands/board/group-delete.d.ts.map +1 -0
  306. package/dist/commands/board/group-delete.js +222 -0
  307. package/dist/commands/board/group-delete.js.map +1 -0
  308. package/dist/commands/board/group-duplicate.d.ts +70 -0
  309. package/dist/commands/board/group-duplicate.d.ts.map +1 -0
  310. package/dist/commands/board/group-duplicate.js +219 -0
  311. package/dist/commands/board/group-duplicate.js.map +1 -0
  312. package/dist/commands/board/group-update.d.ts +145 -0
  313. package/dist/commands/board/group-update.d.ts.map +1 -0
  314. package/dist/commands/board/group-update.js +341 -0
  315. package/dist/commands/board/group-update.js.map +1 -0
  316. package/dist/commands/board/groups.d.ts +28 -0
  317. package/dist/commands/board/groups.d.ts.map +1 -0
  318. package/dist/commands/board/groups.js +85 -0
  319. package/dist/commands/board/groups.js.map +1 -0
  320. package/dist/commands/board/list.d.ts +39 -0
  321. package/dist/commands/board/list.d.ts.map +1 -0
  322. package/dist/commands/board/list.js +135 -0
  323. package/dist/commands/board/list.js.map +1 -0
  324. package/dist/commands/board/subscribers.d.ts +24 -0
  325. package/dist/commands/board/subscribers.d.ts.map +1 -0
  326. package/dist/commands/board/subscribers.js +89 -0
  327. package/dist/commands/board/subscribers.js.map +1 -0
  328. package/dist/commands/board/update.d.ts +82 -0
  329. package/dist/commands/board/update.d.ts.map +1 -0
  330. package/dist/commands/board/update.js +328 -0
  331. package/dist/commands/board/update.js.map +1 -0
  332. package/dist/commands/cache/clear.d.ts +34 -0
  333. package/dist/commands/cache/clear.d.ts.map +1 -0
  334. package/dist/commands/cache/clear.js +113 -0
  335. package/dist/commands/cache/clear.js.map +1 -0
  336. package/dist/commands/cache/list.d.ts +50 -0
  337. package/dist/commands/cache/list.d.ts.map +1 -0
  338. package/dist/commands/cache/list.js +77 -0
  339. package/dist/commands/cache/list.js.map +1 -0
  340. package/dist/commands/cache/stats.d.ts +22 -0
  341. package/dist/commands/cache/stats.d.ts.map +1 -0
  342. package/dist/commands/cache/stats.js +56 -0
  343. package/dist/commands/cache/stats.js.map +1 -0
  344. package/dist/commands/config/path.d.ts +22 -0
  345. package/dist/commands/config/path.d.ts.map +1 -0
  346. package/dist/commands/config/path.js +74 -0
  347. package/dist/commands/config/path.js.map +1 -0
  348. package/dist/commands/config/show.d.ts +61 -0
  349. package/dist/commands/config/show.d.ts.map +1 -0
  350. package/dist/commands/config/show.js +137 -0
  351. package/dist/commands/config/show.js.map +1 -0
  352. package/dist/commands/emit.d.ts +156 -0
  353. package/dist/commands/emit.d.ts.map +1 -0
  354. package/dist/commands/emit.js +212 -0
  355. package/dist/commands/emit.js.map +1 -0
  356. package/dist/commands/index.d.ts +5 -0
  357. package/dist/commands/index.d.ts.map +1 -0
  358. package/dist/commands/index.js +195 -0
  359. package/dist/commands/index.js.map +1 -0
  360. package/dist/commands/item/archive.d.ts +81 -0
  361. package/dist/commands/item/archive.d.ts.map +1 -0
  362. package/dist/commands/item/archive.js +187 -0
  363. package/dist/commands/item/archive.js.map +1 -0
  364. package/dist/commands/item/clear.d.ts +140 -0
  365. package/dist/commands/item/clear.d.ts.map +1 -0
  366. package/dist/commands/item/clear.js +748 -0
  367. package/dist/commands/item/clear.js.map +1 -0
  368. package/dist/commands/item/create.d.ts +77 -0
  369. package/dist/commands/item/create.d.ts.map +1 -0
  370. package/dist/commands/item/create.js +802 -0
  371. package/dist/commands/item/create.js.map +1 -0
  372. package/dist/commands/item/delete.d.ts +82 -0
  373. package/dist/commands/item/delete.d.ts.map +1 -0
  374. package/dist/commands/item/delete.js +179 -0
  375. package/dist/commands/item/delete.js.map +1 -0
  376. package/dist/commands/item/duplicate.d.ts +117 -0
  377. package/dist/commands/item/duplicate.d.ts.map +1 -0
  378. package/dist/commands/item/duplicate.js +238 -0
  379. package/dist/commands/item/duplicate.js.map +1 -0
  380. package/dist/commands/item/find.d.ts +55 -0
  381. package/dist/commands/item/find.d.ts.map +1 -0
  382. package/dist/commands/item/find.js +231 -0
  383. package/dist/commands/item/find.js.map +1 -0
  384. package/dist/commands/item/get.d.ts +47 -0
  385. package/dist/commands/item/get.d.ts.map +1 -0
  386. package/dist/commands/item/get.js +66 -0
  387. package/dist/commands/item/get.js.map +1 -0
  388. package/dist/commands/item/list.d.ts +73 -0
  389. package/dist/commands/item/list.d.ts.map +1 -0
  390. package/dist/commands/item/list.js +284 -0
  391. package/dist/commands/item/list.js.map +1 -0
  392. package/dist/commands/item/move.d.ts +181 -0
  393. package/dist/commands/item/move.d.ts.map +1 -0
  394. package/dist/commands/item/move.js +560 -0
  395. package/dist/commands/item/move.js.map +1 -0
  396. package/dist/commands/item/search.d.ts +67 -0
  397. package/dist/commands/item/search.d.ts.map +1 -0
  398. package/dist/commands/item/search.js +322 -0
  399. package/dist/commands/item/search.js.map +1 -0
  400. package/dist/commands/item/set.d.ts +88 -0
  401. package/dist/commands/item/set.d.ts.map +1 -0
  402. package/dist/commands/item/set.js +387 -0
  403. package/dist/commands/item/set.js.map +1 -0
  404. package/dist/commands/item/subitems.d.ts +50 -0
  405. package/dist/commands/item/subitems.d.ts.map +1 -0
  406. package/dist/commands/item/subitems.js +86 -0
  407. package/dist/commands/item/subitems.js.map +1 -0
  408. package/dist/commands/item/update.d.ts +99 -0
  409. package/dist/commands/item/update.d.ts.map +1 -0
  410. package/dist/commands/item/update.js +884 -0
  411. package/dist/commands/item/update.js.map +1 -0
  412. package/dist/commands/item/upsert.d.ts +105 -0
  413. package/dist/commands/item/upsert.d.ts.map +1 -0
  414. package/dist/commands/item/upsert.js +998 -0
  415. package/dist/commands/item/upsert.js.map +1 -0
  416. package/dist/commands/parse-argv.d.ts +20 -0
  417. package/dist/commands/parse-argv.d.ts.map +1 -0
  418. package/dist/commands/parse-argv.js +40 -0
  419. package/dist/commands/parse-argv.js.map +1 -0
  420. package/dist/commands/raw/index.d.ts +23 -0
  421. package/dist/commands/raw/index.d.ts.map +1 -0
  422. package/dist/commands/raw/index.js +416 -0
  423. package/dist/commands/raw/index.js.map +1 -0
  424. package/dist/commands/run-by-id-lookup.d.ts +72 -0
  425. package/dist/commands/run-by-id-lookup.d.ts.map +1 -0
  426. package/dist/commands/run-by-id-lookup.js +58 -0
  427. package/dist/commands/run-by-id-lookup.js.map +1 -0
  428. package/dist/commands/schema/index.d.ts +104 -0
  429. package/dist/commands/schema/index.d.ts.map +1 -0
  430. package/dist/commands/schema/index.js +183 -0
  431. package/dist/commands/schema/index.js.map +1 -0
  432. package/dist/commands/types.d.ts +66 -0
  433. package/dist/commands/types.d.ts.map +1 -0
  434. package/dist/commands/types.js +15 -0
  435. package/dist/commands/types.js.map +1 -0
  436. package/dist/commands/update/body-source.d.ts +38 -0
  437. package/dist/commands/update/body-source.d.ts.map +1 -0
  438. package/dist/commands/update/body-source.js +80 -0
  439. package/dist/commands/update/body-source.js.map +1 -0
  440. package/dist/commands/update/clear-all.d.ts +67 -0
  441. package/dist/commands/update/clear-all.d.ts.map +1 -0
  442. package/dist/commands/update/clear-all.js +281 -0
  443. package/dist/commands/update/clear-all.js.map +1 -0
  444. package/dist/commands/update/create.d.ts +51 -0
  445. package/dist/commands/update/create.d.ts.map +1 -0
  446. package/dist/commands/update/create.js +167 -0
  447. package/dist/commands/update/create.js.map +1 -0
  448. package/dist/commands/update/delete.d.ts +53 -0
  449. package/dist/commands/update/delete.d.ts.map +1 -0
  450. package/dist/commands/update/delete.js +148 -0
  451. package/dist/commands/update/delete.js.map +1 -0
  452. package/dist/commands/update/edit.d.ts +37 -0
  453. package/dist/commands/update/edit.d.ts.map +1 -0
  454. package/dist/commands/update/edit.js +129 -0
  455. package/dist/commands/update/edit.js.map +1 -0
  456. package/dist/commands/update/get.d.ts +37 -0
  457. package/dist/commands/update/get.d.ts.map +1 -0
  458. package/dist/commands/update/get.js +92 -0
  459. package/dist/commands/update/get.js.map +1 -0
  460. package/dist/commands/update/like.d.ts +17 -0
  461. package/dist/commands/update/like.d.ts.map +1 -0
  462. package/dist/commands/update/like.js +23 -0
  463. package/dist/commands/update/like.js.map +1 -0
  464. package/dist/commands/update/list.d.ts +58 -0
  465. package/dist/commands/update/list.d.ts.map +1 -0
  466. package/dist/commands/update/list.js +322 -0
  467. package/dist/commands/update/list.js.map +1 -0
  468. package/dist/commands/update/pin.d.ts +17 -0
  469. package/dist/commands/update/pin.d.ts.map +1 -0
  470. package/dist/commands/update/pin.js +23 -0
  471. package/dist/commands/update/pin.js.map +1 -0
  472. package/dist/commands/update/reply.d.ts +47 -0
  473. package/dist/commands/update/reply.d.ts.map +1 -0
  474. package/dist/commands/update/reply.js +149 -0
  475. package/dist/commands/update/reply.js.map +1 -0
  476. package/dist/commands/update/toggle.d.ts +70 -0
  477. package/dist/commands/update/toggle.d.ts.map +1 -0
  478. package/dist/commands/update/toggle.js +118 -0
  479. package/dist/commands/update/toggle.js.map +1 -0
  480. package/dist/commands/update/unlike.d.ts +17 -0
  481. package/dist/commands/update/unlike.d.ts.map +1 -0
  482. package/dist/commands/update/unlike.js +22 -0
  483. package/dist/commands/update/unlike.js.map +1 -0
  484. package/dist/commands/update/unpin.d.ts +17 -0
  485. package/dist/commands/update/unpin.d.ts.map +1 -0
  486. package/dist/commands/update/unpin.js +21 -0
  487. package/dist/commands/update/unpin.js.map +1 -0
  488. package/dist/commands/user/get.d.ts +31 -0
  489. package/dist/commands/user/get.d.ts.map +1 -0
  490. package/dist/commands/user/get.js +81 -0
  491. package/dist/commands/user/get.js.map +1 -0
  492. package/dist/commands/user/list.d.ts +61 -0
  493. package/dist/commands/user/list.d.ts.map +1 -0
  494. package/dist/commands/user/list.js +148 -0
  495. package/dist/commands/user/list.js.map +1 -0
  496. package/dist/commands/user/me.d.ts +17 -0
  497. package/dist/commands/user/me.d.ts.map +1 -0
  498. package/dist/commands/user/me.js +49 -0
  499. package/dist/commands/user/me.js.map +1 -0
  500. package/dist/commands/workspace/add-users.d.ts +76 -0
  501. package/dist/commands/workspace/add-users.d.ts.map +1 -0
  502. package/dist/commands/workspace/add-users.js +154 -0
  503. package/dist/commands/workspace/add-users.js.map +1 -0
  504. package/dist/commands/workspace/create.d.ts +59 -0
  505. package/dist/commands/workspace/create.d.ts.map +1 -0
  506. package/dist/commands/workspace/create.js +163 -0
  507. package/dist/commands/workspace/create.js.map +1 -0
  508. package/dist/commands/workspace/delete.d.ts +67 -0
  509. package/dist/commands/workspace/delete.d.ts.map +1 -0
  510. package/dist/commands/workspace/delete.js +182 -0
  511. package/dist/commands/workspace/delete.js.map +1 -0
  512. package/dist/commands/workspace/folders.d.ts +40 -0
  513. package/dist/commands/workspace/folders.d.ts.map +1 -0
  514. package/dist/commands/workspace/folders.js +124 -0
  515. package/dist/commands/workspace/folders.js.map +1 -0
  516. package/dist/commands/workspace/get.d.ts +35 -0
  517. package/dist/commands/workspace/get.d.ts.map +1 -0
  518. package/dist/commands/workspace/get.js +62 -0
  519. package/dist/commands/workspace/get.js.map +1 -0
  520. package/dist/commands/workspace/list.d.ts +57 -0
  521. package/dist/commands/workspace/list.d.ts.map +1 -0
  522. package/dist/commands/workspace/list.js +125 -0
  523. package/dist/commands/workspace/list.js.map +1 -0
  524. package/dist/commands/workspace/remove-users.d.ts +47 -0
  525. package/dist/commands/workspace/remove-users.d.ts.map +1 -0
  526. package/dist/commands/workspace/remove-users.js +122 -0
  527. package/dist/commands/workspace/remove-users.js.map +1 -0
  528. package/dist/commands/workspace/update.d.ts +68 -0
  529. package/dist/commands/workspace/update.d.ts.map +1 -0
  530. package/dist/commands/workspace/update.js +237 -0
  531. package/dist/commands/workspace/update.js.map +1 -0
  532. package/dist/config/load.d.ts +33 -0
  533. package/dist/config/load.d.ts.map +1 -0
  534. package/dist/config/load.js +81 -0
  535. package/dist/config/load.js.map +1 -0
  536. package/dist/index.d.ts +3 -0
  537. package/dist/index.d.ts.map +1 -0
  538. package/dist/index.js +4 -0
  539. package/dist/index.js.map +1 -0
  540. package/dist/types/global-flags.d.ts +69 -0
  541. package/dist/types/global-flags.d.ts.map +1 -0
  542. package/dist/types/global-flags.js +170 -0
  543. package/dist/types/global-flags.js.map +1 -0
  544. package/dist/types/ids.d.ts +38 -0
  545. package/dist/types/ids.d.ts.map +1 -0
  546. package/dist/types/ids.js +51 -0
  547. package/dist/types/ids.js.map +1 -0
  548. package/dist/types/json.d.ts +60 -0
  549. package/dist/types/json.d.ts.map +1 -0
  550. package/dist/types/json.js +33 -0
  551. package/dist/types/json.js.map +1 -0
  552. package/dist/utils/errors.d.ts +121 -0
  553. package/dist/utils/errors.d.ts.map +1 -0
  554. package/dist/utils/errors.js +264 -0
  555. package/dist/utils/errors.js.map +1 -0
  556. package/dist/utils/logger.d.ts +39 -0
  557. package/dist/utils/logger.d.ts.map +1 -0
  558. package/dist/utils/logger.js +49 -0
  559. package/dist/utils/logger.js.map +1 -0
  560. package/dist/utils/output/envelope.d.ts +140 -0
  561. package/dist/utils/output/envelope.d.ts.map +1 -0
  562. package/dist/utils/output/envelope.js +120 -0
  563. package/dist/utils/output/envelope.js.map +1 -0
  564. package/dist/utils/output/json.d.ts +10 -0
  565. package/dist/utils/output/json.d.ts.map +1 -0
  566. package/dist/utils/output/json.js +12 -0
  567. package/dist/utils/output/json.js.map +1 -0
  568. package/dist/utils/output/ndjson.d.ts +92 -0
  569. package/dist/utils/output/ndjson.d.ts.map +1 -0
  570. package/dist/utils/output/ndjson.js +33 -0
  571. package/dist/utils/output/ndjson.js.map +1 -0
  572. package/dist/utils/output/select.d.ts +22 -0
  573. package/dist/utils/output/select.d.ts.map +1 -0
  574. package/dist/utils/output/select.js +47 -0
  575. package/dist/utils/output/select.js.map +1 -0
  576. package/dist/utils/output/table.d.ts +32 -0
  577. package/dist/utils/output/table.d.ts.map +1 -0
  578. package/dist/utils/output/table.js +133 -0
  579. package/dist/utils/output/table.js.map +1 -0
  580. package/dist/utils/output/text.d.ts +5 -0
  581. package/dist/utils/output/text.d.ts.map +1 -0
  582. package/dist/utils/output/text.js +32 -0
  583. package/dist/utils/output/text.js.map +1 -0
  584. package/dist/utils/parse-boundary.d.ts +53 -0
  585. package/dist/utils/parse-boundary.d.ts.map +1 -0
  586. package/dist/utils/parse-boundary.js +62 -0
  587. package/dist/utils/parse-boundary.js.map +1 -0
  588. package/dist/utils/redact.d.ts +54 -0
  589. package/dist/utils/redact.d.ts.map +1 -0
  590. package/dist/utils/redact.js +154 -0
  591. package/dist/utils/redact.js.map +1 -0
  592. package/dist/utils/request-id.d.ts +17 -0
  593. package/dist/utils/request-id.d.ts.map +1 -0
  594. package/dist/utils/request-id.js +26 -0
  595. package/dist/utils/request-id.js.map +1 -0
  596. package/package.json +87 -0
@@ -0,0 +1,998 @@
1
+ /**
2
+ * `monday item upsert --board <bid> --name <n> --match-by <col>[,<col>...]
3
+ * [--set <col>=<val>]... [--set-raw <col>=<json>]... [--dry-run]`
4
+ * (`cli-design.md` §4.3 line 529, §5.8 + §6.4 + §6.5,
5
+ * `v0.2-plan.md` §3 M12).
6
+ *
7
+ * The idempotency-cluster verb. **0 matches** → branches to
8
+ * `create_item` (M9 wire surface). **1 match** → branches to the v0.1
9
+ * `item update` shape (synthetic `name` key bundled into
10
+ * `change_multiple_column_values` per §5.3 step 5; or
11
+ * `change_simple_column_value(column_id: "name")` when `--name` is the
12
+ * only diff). **2+ matches** → fails with `ambiguous_match` carrying
13
+ * `details.candidates: [{id, name}, ...]` capped at 10. The mutation
14
+ * envelope's `data.operation: "create_item" | "update_item"` exposes
15
+ * the branch on the success envelope; the dry-run encodes the same
16
+ * via `planned_changes[0].operation`.
17
+ *
18
+ * **Sequential-retry idempotent only** (cli-design §5.8 + §9.1). Two
19
+ * agents observing zero matches at the same instant both branch to
20
+ * `create_item`; the next call from either agent surfaces the
21
+ * duplicate as `ambiguous_match`. Concurrent-write protection via
22
+ * Monday's resource-locking mutations is a v0.4 candidate (cli-design
23
+ * §9.3). Race-mitigation guidance — pick a stable hidden-key column
24
+ * for `--match-by` and tighten the predicate so a duplicate from a
25
+ * race surfaces as `ambiguous_match` on the next call — lives in
26
+ * `--help` and §6.5.
27
+ *
28
+ * **Match-by semantics.** `--match-by <col>[,<col>...]` accepts
29
+ * comma-separated column tokens (resolved via the same column
30
+ * resolver `--set` uses) plus the literal `name` pseudo-token, which
31
+ * matches against the item's `name` field via Monday's `column_id:
32
+ * "name"` filter. Multiple tokens AND-combine — adding a token
33
+ * narrows the match set, so an agent seeing `ambiguous_match` knows
34
+ * widening the predicate by one column is the recovery path. Each
35
+ * column token's match value comes from the corresponding
36
+ * `--set <token>=<value>` (which is **required** for every match-by
37
+ * column token); the `name` token's match value comes from
38
+ * `--name <n>`. `--set-raw <col>=<json>` participates in column
39
+ * updates but **cannot appear in `--match-by`** because the JSON wire
40
+ * shape isn't a filter-comparable scalar — `usage_error` if an agent
41
+ * tries.
42
+ *
43
+ * **Mutation surface reuse, not entry-point reuse.** This module
44
+ * issues the same wire mutations `commands/item/create.ts` and
45
+ * `commands/item/update.ts` issue (CREATE_ITEM_MUTATION,
46
+ * CHANGE_SIMPLE_COLUMN_VALUE_MUTATION, CHANGE_COLUMN_VALUE_MUTATION,
47
+ * CHANGE_MULTIPLE_COLUMN_VALUES_MUTATION); the GraphQL strings are
48
+ * inlined here rather than imported because every existing site
49
+ * declares them locally too (the third-consumer trigger fires at the
50
+ * fourth+ site, not the third — see v0.2-plan §16's lift-on-third-
51
+ * consumer rule). The translator pipeline (`resolveAndTranslate` +
52
+ * `selectMutation` + `bundleColumnValues`) is the shared layer the
53
+ * three commands collapse onto, so the synthetic-`name` bundling +
54
+ * column-archived remap + `name + multi-column` atomicity contracts
55
+ * stay byte-identical across all three verbs.
56
+ *
57
+ * Idempotent: yes (sequential retry — re-running the same args
58
+ * yields the same item, with the second call hitting the update
59
+ * branch).
60
+ */
61
+ import { z } from 'zod';
62
+ import { ensureSubcommand } from '../types.js';
63
+ import { emitDryRun, emitMutation } from '../emit.js';
64
+ import { resolveClient } from '../../api/resolve-client.js';
65
+ import { BoardIdSchema } from '../../types/ids.js';
66
+ import { parseArgv } from '../parse-argv.js';
67
+ import { ApiError, MondayCliError, UsageError } from '../../utils/errors.js';
68
+ import { bundleColumnValues, selectMutation, } from '../../api/column-values.js';
69
+ import { parseSetRawExpression, } from '../../api/raw-write.js';
70
+ import { splitSetExpression, } from '../../api/set-expression.js';
71
+ import { buildResolutionContexts } from '../../api/resolution-context.js';
72
+ import { SourceAggregator, mergeSource, mergeCacheAge, mergeSourceWithPreflight, } from '../../api/source-aggregator.js';
73
+ import { resolveAndTranslate } from '../../api/resolution-pass.js';
74
+ import { foldAndRemap } from '../../api/resolver-error-fold.js';
75
+ import { planChanges, planCreate } from '../../api/dry-run.js';
76
+ import { loadBoardMetadata, refreshBoardMetadata, } from '../../api/board-metadata.js';
77
+ import { buildQueryParams } from '../../api/filters.js';
78
+ import { fetchItemsPage } from '../../api/items-page-walker.js';
79
+ import { ITEM_FIELDS_FRAGMENT, resolveMeFactory, } from '../../api/item-helpers.js';
80
+ import { projectMutationItem } from '../../api/item-mutation-result.js';
81
+ import { projectedItemSchema, } from '../../api/item-projection.js';
82
+ // ============================================================
83
+ // GraphQL — mutation surface (lookup uses the shared
84
+ // `fetchItemsPage` helper from `api/items-page-walker.ts` lifted
85
+ // post-M12 per §18 R34; the helper builds the `boards.items_page`
86
+ // query inline from `operationName` + `itemFields` + `queryParams`,
87
+ // so the lookup mirrors `item update --where`'s wire shape without
88
+ // a per-file GraphQL constant).
89
+ // ============================================================
90
+ /**
91
+ * Match-by lookup uses `fetchItemsPage` directly with `limit: 11` —
92
+ * the 11th item exists only when ≥11 candidates match, which already
93
+ * gives `ambiguous_match` plus 10 capped candidates the §6.5 details
94
+ * schema documents. No `next_items_page` continuation: the planner
95
+ * caps at 10 candidates, so a non-null cursor on the first page
96
+ * is the 2+ signal.
97
+ */
98
+ const UPSERT_LOOKUP_ITEM_FIELDS = `id
99
+ name`;
100
+ const CREATE_ITEM_MUTATION = `
101
+ mutation ItemUpsertCreate(
102
+ $boardId: ID!
103
+ $itemName: String!
104
+ $columnValues: JSON
105
+ $createLabelsIfMissing: Boolean
106
+ ) {
107
+ create_item(
108
+ board_id: $boardId
109
+ item_name: $itemName
110
+ column_values: $columnValues
111
+ create_labels_if_missing: $createLabelsIfMissing
112
+ ) {
113
+ ${ITEM_FIELDS_FRAGMENT}
114
+ }
115
+ }
116
+ `;
117
+ const CHANGE_SIMPLE_COLUMN_VALUE_MUTATION = `
118
+ mutation ItemUpsertSimple(
119
+ $itemId: ID!
120
+ $boardId: ID!
121
+ $columnId: String!
122
+ $value: String!
123
+ $createLabelsIfMissing: Boolean
124
+ ) {
125
+ change_simple_column_value(
126
+ item_id: $itemId
127
+ board_id: $boardId
128
+ column_id: $columnId
129
+ value: $value
130
+ create_labels_if_missing: $createLabelsIfMissing
131
+ ) {
132
+ ${ITEM_FIELDS_FRAGMENT}
133
+ }
134
+ }
135
+ `;
136
+ const CHANGE_COLUMN_VALUE_MUTATION = `
137
+ mutation ItemUpsertRich(
138
+ $itemId: ID!
139
+ $boardId: ID!
140
+ $columnId: String!
141
+ $value: JSON!
142
+ $createLabelsIfMissing: Boolean
143
+ ) {
144
+ change_column_value(
145
+ item_id: $itemId
146
+ board_id: $boardId
147
+ column_id: $columnId
148
+ value: $value
149
+ create_labels_if_missing: $createLabelsIfMissing
150
+ ) {
151
+ ${ITEM_FIELDS_FRAGMENT}
152
+ }
153
+ }
154
+ `;
155
+ const CHANGE_MULTIPLE_COLUMN_VALUES_MUTATION = `
156
+ mutation ItemUpsertMulti(
157
+ $itemId: ID!
158
+ $boardId: ID!
159
+ $columnValues: JSON!
160
+ $createLabelsIfMissing: Boolean
161
+ ) {
162
+ change_multiple_column_values(
163
+ item_id: $itemId
164
+ board_id: $boardId
165
+ column_values: $columnValues
166
+ create_labels_if_missing: $createLabelsIfMissing
167
+ ) {
168
+ ${ITEM_FIELDS_FRAGMENT}
169
+ }
170
+ }
171
+ `;
172
+ // ============================================================
173
+ // Wire response zod schemas (parse-boundary discipline, R18).
174
+ // ============================================================
175
+ const lookupItemSchema = z
176
+ .object({
177
+ id: z.string().min(1),
178
+ name: z.string(),
179
+ })
180
+ .loose();
181
+ // ============================================================
182
+ // Output schema — projected item + operation discriminator.
183
+ // ============================================================
184
+ const operationEnum = z.enum(['create_item', 'update_item']);
185
+ export const itemUpsertOutputSchema = projectedItemSchema.extend({
186
+ /**
187
+ * Branch discriminator per cli-design §6.4 + v0.2-plan §3 M12.
188
+ * `"create_item"` when the lookup found 0 matches; `"update_item"`
189
+ * when it found exactly 1. The slot lives on `data` (rather than
190
+ * `meta`) because v0.1's mutation envelope already keeps
191
+ * operation-shape signals in `data` — `meta` is reserved for
192
+ * cross-verb cache / source / pagination state. Codex round-2 P2.
193
+ */
194
+ operation: operationEnum,
195
+ });
196
+ // ============================================================
197
+ // Input schema + dispatch.
198
+ // ============================================================
199
+ /**
200
+ * The literal pseudo-token `--match-by` accepts to match against the
201
+ * item's `name` field. Case-sensitive — agents need a deterministic
202
+ * token; lowercase `name` is the convention `cli-design.md` §5.8
203
+ * pins. Column tokens that happen to be titled `Name` (capitalised)
204
+ * still resolve through the column resolver per the normal title-
205
+ * resolution rules; this constant is the *pseudo*-column escape.
206
+ */
207
+ const NAME_PSEUDO_TOKEN = 'name';
208
+ const inputSchema = z
209
+ .object({
210
+ board: BoardIdSchema,
211
+ name: z.string().refine((s) => s.trim().length > 0, {
212
+ message: '--name must be non-empty (whitespace-only is rejected)',
213
+ }),
214
+ matchBy: z
215
+ .array(z.string())
216
+ .min(1, '--match-by requires at least one token'),
217
+ set: z.array(z.string()).default([]),
218
+ setRaw: z.array(z.string()).default([]),
219
+ createLabelsIfMissing: z.boolean().optional(),
220
+ })
221
+ .strict();
222
+ /**
223
+ * Splits the comma-separated `--match-by` argv into individual tokens
224
+ * + de-duplicates. Trims whitespace; rejects empty tokens
225
+ * (`--match-by status,,owner` is a usage error, not a silent drop).
226
+ */
227
+ const parseMatchByTokens = (raw) => {
228
+ const tokens = [];
229
+ const seen = new Set();
230
+ for (const r of raw) {
231
+ for (const piece of r.split(',')) {
232
+ const trimmed = piece.trim();
233
+ if (trimmed.length === 0) {
234
+ throw new UsageError('--match-by entries must not be empty (an empty segment between ' +
235
+ 'commas, or a whitespace-only token, was rejected).', { details: { raw } });
236
+ }
237
+ if (seen.has(trimmed)) {
238
+ throw new UsageError(`--match-by tokens must be unique; ${JSON.stringify(trimmed)} ` +
239
+ `appeared more than once.`, { details: { token: trimmed } });
240
+ }
241
+ seen.add(trimmed);
242
+ tokens.push(trimmed);
243
+ }
244
+ }
245
+ return tokens;
246
+ };
247
+ /**
248
+ * Pairs each match-by token with its match value. For the `name`
249
+ * pseudo-token the value is `--name <n>`; for every column token,
250
+ * the value is the corresponding `--set <token>=<value>`. Throws
251
+ * `usage_error` with token-specific guidance when the pairing fails.
252
+ *
253
+ * `--set-raw` entries cannot supply match values — the JSON wire
254
+ * shape isn't a filter-comparable scalar. The check is at parse-
255
+ * boundary (resolution-free), so a malformed match-by pairing fails
256
+ * before any network call.
257
+ */
258
+ const buildMatchByEntries = (inputs) => {
259
+ const entries = [];
260
+ // Index --set entries by token for O(1) lookup. `splitSetExpression`
261
+ // preserves the agent's verbatim token (no normalisation), so the
262
+ // match-by token must be character-equal to the --set token.
263
+ const setByToken = new Map();
264
+ for (const e of inputs.setEntries) {
265
+ setByToken.set(e.token, e);
266
+ }
267
+ for (const token of inputs.tokens) {
268
+ if (token === NAME_PSEUDO_TOKEN) {
269
+ entries.push({ kind: 'name', token: 'name', value: inputs.name });
270
+ continue;
271
+ }
272
+ if (inputs.rawTokens.has(token)) {
273
+ throw new UsageError(`--match-by ${JSON.stringify(token)} cannot be paired with a ` +
274
+ `--set-raw entry; the JSON wire shape isn't a filter-comparable ` +
275
+ `scalar. Pass the same column via --set <token>=<scalar> for ` +
276
+ `match-by, or drop ${JSON.stringify(token)} from --match-by.`, { details: { token } });
277
+ }
278
+ const setEntry = setByToken.get(token);
279
+ if (setEntry === undefined) {
280
+ throw new UsageError(`--match-by ${JSON.stringify(token)} requires a corresponding ` +
281
+ `--set ${token}=<value> (the upsert pulls the match value from ` +
282
+ `--set so the create branch and the lookup share one source of ` +
283
+ `truth). Add --set ${token}=<value>, or drop ` +
284
+ `${JSON.stringify(token)} from --match-by.`, { details: { token } });
285
+ }
286
+ entries.push({ kind: 'column', token, value: setEntry.value });
287
+ }
288
+ return entries;
289
+ };
290
+ /**
291
+ * Resolves the column-token half of `--match-by` against the board's
292
+ * metadata, builds the `query_params.rules` payload, and queries
293
+ * `items_page` once with `limit: 11` so the 0 / 1 / 2+ branch
294
+ * decision needs no second round-trip.
295
+ *
296
+ * Column-token rules go through `buildQueryParams` — the same path
297
+ * `item list --where` and bulk `item update --where` use (note: `item
298
+ * search` parses identical syntax via `buildColumnQueries` but hits
299
+ * Monday's `items_page_by_column_values` endpoint, a different filter
300
+ * shape) — so per-column-type
301
+ * value resolution (the `me` token for people columns, the same
302
+ * cache-miss-refresh + collision-warning collection) inherits
303
+ * automatically. `name` pseudo-tokens skip the column resolver
304
+ * entirely (Monday accepts `column_id: "name"` in `query_params.rules`
305
+ * as a built-in filter against the item's `name` field, no metadata
306
+ * lookup needed) and are prepended to the rules array post-build.
307
+ *
308
+ * **Known v0.2 round-trip limits (cli-design §5.8 caveat).** The
309
+ * lookup leg and the `--set` translator have asymmetric grammars,
310
+ * so only a subset of column kinds round-trip cleanly when the same
311
+ * column appears in both `--match-by` and `--set`:
312
+ *
313
+ * - **People:** only `me` (resolved on both legs). Emails resolve
314
+ * in `--set` but pass verbatim in lookup; raw numeric user IDs
315
+ * are rejected by the people `--set` grammar (cli-design §5.3
316
+ * step 3, M5b deferral).
317
+ * - **Date:** NOT v0.2-safe — Monday's items_page filter requires
318
+ * `compare_value: ["EXACT", "YYYY-MM-DD"]` for date-equals,
319
+ * but `buildQueryParams` emits a bare-ISO `["YYYY-MM-DD"]` (the
320
+ * same shape `item search` / `item update --where` ship). The
321
+ * EXACT-marker lift is a cross-surface v0.3 candidate.
322
+ * - **Status / dropdown:** label text (e.g. `Backlog`) round-trips
323
+ * because Monday's filter compares against the stored label.
324
+ * - **Text / long_text / numbers / item name / external_id-shaped
325
+ * hidden text:** verbatim pass-through on both legs.
326
+ * - **Link / email / phone (rich pipe grammar):** the friendly
327
+ * `<scalar>|<text>` write parses to `{url, text}` / `{email,
328
+ * text}` / `{phone, country}` but the lookup leg sends the
329
+ * literal pipe string — best-effort only.
330
+ *
331
+ * The recommended canonical pattern is a stable hidden text /
332
+ * external_id column as the synthetic key. Email→ID, numeric-user-
333
+ * ID acceptance, relative-date resolution, and the date EXACT-
334
+ * marker lift are v0.3 cross-surface follow-ups (would lift `item
335
+ * search` and `item update --where` simultaneously).
336
+ */
337
+ const lookupMatches = async (inputs) => {
338
+ // Split into name + column tokens. Column tokens go through the
339
+ // shared filter pipeline; name tokens contribute a literal
340
+ // `column_id: "name"` rule prepended to the resulting rules array.
341
+ const columnEntries = inputs.matchBy.filter((e) => e.kind === 'column');
342
+ const nameEntries = inputs.matchBy.filter((e) => e.kind === 'name');
343
+ // Convert column match-by entries to `--where`-shaped strings and
344
+ // hand to the shared filter pipeline. `splitSetExpression` and
345
+ // `parseWhereSyntax` both split on first `=`, so a value containing
346
+ // `=` round-trips correctly.
347
+ const whereClauses = columnEntries.map((e) => `${e.token}=${e.value}`);
348
+ const filterResult = await buildQueryParams({
349
+ metadata: inputs.metadata,
350
+ resolveMe: resolveMeFactory(inputs.client),
351
+ whereClauses,
352
+ filterJson: undefined,
353
+ ...(inputs.onColumnNotFound === undefined
354
+ ? {}
355
+ : { onColumnNotFound: inputs.onColumnNotFound }),
356
+ });
357
+ // Prepend the `name` pseudo-token rules. Monday accepts
358
+ // `column_id: "name"` in `query_params.rules` as a built-in filter
359
+ // against the item's `name` field — no column resolution needed.
360
+ const nameRules = nameEntries.map((e) => ({
361
+ column_id: 'name',
362
+ operator: 'any_of',
363
+ compare_value: [e.value],
364
+ }));
365
+ const columnRules = filterResult.queryParams?.rules ?? [];
366
+ const rules = [...nameRules, ...columnRules];
367
+ const lookup = await fetchItemsPage({
368
+ client: inputs.client,
369
+ operationName: 'ItemUpsertLookup',
370
+ boardId: inputs.boardId,
371
+ limit: 11,
372
+ queryParams: { rules },
373
+ itemFields: UPSERT_LOOKUP_ITEM_FIELDS,
374
+ itemSchema: lookupItemSchema,
375
+ });
376
+ return {
377
+ items: lookup.data.items,
378
+ hasMore: lookup.data.cursor !== null,
379
+ // Filter pipeline returns `Warning` shape; resolver-warning
380
+ // codes (`column_token_collision`, `stale_cache_refreshed`)
381
+ // structurally widen to ResolverWarning cleanly.
382
+ warnings: filterResult.warnings,
383
+ refreshed: filterResult.refreshed,
384
+ metadata: inputs.metadata,
385
+ };
386
+ };
387
+ const decideBranch = (inputs) => {
388
+ const items = inputs.lookup.items;
389
+ // 0 matches → create branch only when the page is definitively
390
+ // empty (cursor null). An empty page with a non-null cursor is a
391
+ // Monday API anomaly (the items_page contract returns `cursor:
392
+ // null` when no more pages exist) — we can't prove there are zero
393
+ // matches, so fail-closed with internal_error rather than create
394
+ // a duplicate. Codex round-1 F3.
395
+ if (items.length === 0) {
396
+ if (inputs.lookup.hasMore) {
397
+ throw new ApiError('internal_error', `item upsert lookup returned an empty page with a non-null cursor on board ${inputs.boardId}; ` +
398
+ `Monday's items_page contract returns cursor: null when no more matches exist. ` +
399
+ `Refusing to create-or-update without a definitive 0/1/2+ count. ` +
400
+ `Re-run; if the issue persists, file a bug.`, {
401
+ details: {
402
+ board_id: inputs.boardId,
403
+ match_by: inputs.matchBy.map((e) => e.token),
404
+ },
405
+ });
406
+ }
407
+ return { kind: 'create' };
408
+ }
409
+ if (items.length === 1 && !inputs.lookup.hasMore) {
410
+ // c8 ignore — defensive: items.length === 1 narrowing guarantees
411
+ // items[0] is non-undefined.
412
+ const only = items[0];
413
+ /* c8 ignore next 3 */
414
+ if (only === undefined) {
415
+ throw new ApiError('internal_error', 'decideBranch: empty single match');
416
+ }
417
+ return { kind: 'update', itemId: only.id };
418
+ }
419
+ // 2+ matches OR (1 match AND `cursor !== null` → at least 2 across
420
+ // pages). cli-design §6.5 caps the candidates display at 10.
421
+ const candidates = items
422
+ .slice(0, 10)
423
+ .map((i) => ({ id: i.id, name: i.name }));
424
+ const matchValues = {};
425
+ for (const e of inputs.matchBy) {
426
+ matchValues[e.token] = e.value;
427
+ }
428
+ const error = new ApiError('ambiguous_match', `item upsert matched ${String(items.length)} item(s) on board ${inputs.boardId} ` +
429
+ `with the supplied --match-by; pick a tighter predicate (add another ` +
430
+ `--match-by column, or use a stable hidden-key column) so the next ` +
431
+ `call resolves to a single item.`, {
432
+ details: {
433
+ board_id: inputs.boardId,
434
+ match_by: inputs.matchBy.map((e) => e.token),
435
+ match_values: matchValues,
436
+ matched_count: items.length,
437
+ candidates,
438
+ },
439
+ });
440
+ return { kind: 'ambiguous', error };
441
+ };
442
+ const executeCreate = async (inputs) => {
443
+ const response = await inputs.client.raw(CREATE_ITEM_MUTATION, {
444
+ boardId: inputs.boardId,
445
+ itemName: inputs.itemName,
446
+ columnValues: inputs.columnValues,
447
+ createLabelsIfMissing: inputs.createLabelsIfMissing ?? false,
448
+ }, { operationName: 'ItemUpsertCreate' });
449
+ return {
450
+ projected: projectMutationItem({
451
+ raw: response.data.create_item,
452
+ // create_item returns a fresh ID; we don't have one to project
453
+ // against, so the helper falls back to its own check. Pass empty
454
+ // string to indicate "no expected ID" — projectMutationItem
455
+ // surfaces internal_error if Monday returned a null payload.
456
+ itemId: '',
457
+ errorCode: 'internal_error',
458
+ errorMessage: 'Monday returned no item payload from create_item during upsert.',
459
+ }),
460
+ response,
461
+ };
462
+ };
463
+ const executeUpdate = async (inputs) => {
464
+ const labelsFlag = inputs.createLabelsIfMissing ?? false;
465
+ if (inputs.mutation.kind === 'change_simple_column_value') {
466
+ const response = await inputs.client.raw(CHANGE_SIMPLE_COLUMN_VALUE_MUTATION, {
467
+ itemId: inputs.itemId,
468
+ boardId: inputs.boardId,
469
+ columnId: inputs.mutation.columnId,
470
+ value: inputs.mutation.value,
471
+ createLabelsIfMissing: labelsFlag,
472
+ }, { operationName: 'ItemUpsertSimple' });
473
+ return {
474
+ projected: projectMutationItem({
475
+ raw: response.data.change_simple_column_value,
476
+ itemId: inputs.itemId,
477
+ errorCode: 'internal_error',
478
+ errorMessage: `Monday returned no item payload from the mutation for id ${inputs.itemId}.`,
479
+ }),
480
+ response,
481
+ };
482
+ }
483
+ /* c8 ignore start — defensive: in upsert's update branch the
484
+ synthetic `name` translated value always joins the array, so the
485
+ one-rich-only (single-entry rich) shape that selectMutation maps
486
+ to `change_column_value` is unreachable: 0 user --set entries +
487
+ name = 1 simple entry → `change_simple_column_value`; 1+ user
488
+ --set entries + name = 2+ entries → `change_multiple_column_
489
+ values`. The branch is kept exhaustive so a future shape change
490
+ (e.g. dropping the synthetic name on a no-rename code path) can
491
+ opt back in without re-deriving the mutation dispatch. */
492
+ if (inputs.mutation.kind === 'change_column_value') {
493
+ const response = await inputs.client.raw(CHANGE_COLUMN_VALUE_MUTATION, {
494
+ itemId: inputs.itemId,
495
+ boardId: inputs.boardId,
496
+ columnId: inputs.mutation.columnId,
497
+ value: inputs.mutation.value,
498
+ createLabelsIfMissing: labelsFlag,
499
+ }, { operationName: 'ItemUpsertRich' });
500
+ return {
501
+ projected: projectMutationItem({
502
+ raw: response.data.change_column_value,
503
+ itemId: inputs.itemId,
504
+ errorCode: 'internal_error',
505
+ errorMessage: `Monday returned no item payload from the mutation for id ${inputs.itemId}.`,
506
+ }),
507
+ response,
508
+ };
509
+ }
510
+ /* c8 ignore stop */
511
+ // change_multiple_column_values — multi-`--set` or `--set + --name`.
512
+ const response = await inputs.client.raw(CHANGE_MULTIPLE_COLUMN_VALUES_MUTATION, {
513
+ itemId: inputs.itemId,
514
+ boardId: inputs.boardId,
515
+ columnValues: inputs.mutation.columnValues,
516
+ createLabelsIfMissing: labelsFlag,
517
+ }, { operationName: 'ItemUpsertMulti' });
518
+ return {
519
+ projected: projectMutationItem({
520
+ raw: response.data.change_multiple_column_values,
521
+ itemId: inputs.itemId,
522
+ errorCode: 'internal_error',
523
+ errorMessage: `Monday returned no item payload from the mutation for id ${inputs.itemId}.`,
524
+ }),
525
+ response,
526
+ };
527
+ };
528
+ // ============================================================
529
+ // Main command export.
530
+ // ============================================================
531
+ export const itemUpsertCommand = {
532
+ name: 'item.upsert',
533
+ summary: 'Create-or-update an item by --match-by predicate (idempotent)',
534
+ examples: [
535
+ 'monday item upsert --board 67890 --name "Refactor login" --match-by name --set status=Backlog',
536
+ 'monday item upsert --board 67890 --name "Refactor login" --match-by external_id --set external_id=ABC-123 --set status=Backlog',
537
+ 'monday item upsert --board 67890 --name "Refactor login" --match-by name,owner --set owner=me --set status=Backlog',
538
+ 'monday item upsert --board 67890 --name "Refactor login" --match-by name,priority --set priority=High --set status=Backlog',
539
+ 'monday item upsert --board 67890 --name "Refactor login" --match-by name --set status=Backlog --dry-run --json',
540
+ ],
541
+ // Sequential-retry idempotent — see file header + cli-design §5.8.
542
+ // The CommandModule flag is a coarse boolean; the nuanced contract
543
+ // lives in --help / docs / §9.1.
544
+ idempotent: true,
545
+ inputSchema,
546
+ outputSchema: itemUpsertOutputSchema,
547
+ attach: (program, ctx) => {
548
+ const noun = ensureSubcommand(program, 'item', 'Item commands');
549
+ noun
550
+ .command('upsert')
551
+ .description(itemUpsertCommand.summary)
552
+ .requiredOption('--board <bid>', 'board ID (required)')
553
+ .requiredOption('--name <n>', 'item name (required, non-empty)')
554
+ .requiredOption('--match-by <list>', 'comma-separated match tokens (column tokens + literal `name`)', (value, prev) => [...prev, value], [])
555
+ .option('--set <expr>', 'repeatable <col>=<val>. Required for every non-`name` --match-by token.', (value, prev) => [...prev, value], [])
556
+ .option('--set-raw <expr>', 'repeatable <col>=<json> raw write (column updates only — cannot appear in --match-by)', (value, prev) => [...prev, value], [])
557
+ .option('--create-labels-if-missing', 'auto-create unknown status / dropdown labels (Monday flag)')
558
+ .addHelpText('after', [
559
+ '',
560
+ 'Examples:',
561
+ ...itemUpsertCommand.examples.map((e) => ` ${e}`),
562
+ '',
563
+ 'Race-mitigation note: upsert is sequential-retry idempotent only.',
564
+ 'Two concurrent agents observing zero matches both branch to',
565
+ 'create_item; the next call surfaces the duplicate as',
566
+ 'ambiguous_match. Pick a stable hidden-key column for --match-by',
567
+ 'so race-induced duplicates are recoverable.',
568
+ '',
569
+ 'Match-value caveats (per column kind). The lookup leg and the',
570
+ '--set translator have asymmetric grammars in v0.2, so only a',
571
+ 'subset of column kinds round-trip cleanly when used in both',
572
+ '--match-by and --set:',
573
+ '',
574
+ ' Always safe (verbatim pass-through on both legs):',
575
+ ' - name (the item-name pseudo-token)',
576
+ ' - text / long_text',
577
+ ' - numbers',
578
+ ' - external_id-shaped hidden text',
579
+ ' Safe via label-text:',
580
+ ' - status / dropdown (pass the label name, not the index)',
581
+ ' Restricted to one value:',
582
+ ' - people: only `me` round-trips. Emails work in --set but',
583
+ ' pass verbatim in lookup (duplicate); raw numeric user',
584
+ ' IDs are rejected by the --set grammar (cli-design §5.3).',
585
+ ' Not v0.2-safe:',
586
+ ' - date: Monday items_page requires an EXACT marker plus',
587
+ ' YYYY-MM-DD for date-equals comparisons; the lookup leg',
588
+ ' sends bare ISO, so an upsert against a date column',
589
+ ' duplicates on rerun.',
590
+ ' - link / email / phone: the rich `scalar|text` write',
591
+ ' grammar produces a `{url,text}` / `{email,text}` /',
592
+ ' `{phone,country}` payload that the bare-string filter',
593
+ ' compare cannot match against.',
594
+ '',
595
+ 'Recommended canonical pattern: stable hidden text /',
596
+ 'external_id column as the synthetic key. Email->ID,',
597
+ 'numeric-user-ID acceptance, relative-date resolution, and',
598
+ 'the date EXACT-marker lift are v0.3 cross-surface follow-ups',
599
+ '(would also lift `item search` and `item update --where`).',
600
+ '',
601
+ ].join('\n'))
602
+ .action(async (opts) => {
603
+ const parsed = parseArgv(itemUpsertCommand.inputSchema, opts);
604
+ const { client, globalFlags, apiVersion, toEmit } = resolveClient(ctx, program.opts());
605
+ // Argv-parse-time failures fire BEFORE any network call.
606
+ // Splits + JSON parse run on pure strings; surfacing here
607
+ // means a malformed --set / --set-raw / --match-by fails fast
608
+ // without burning a board-metadata fetch + lookup round-trip.
609
+ // Same fail-fast invariant as item update / item create.
610
+ const setEntries = parsed.set.map(splitSetExpression);
611
+ const rawEntries = parsed.setRaw.map(parseSetRawExpression);
612
+ const matchByTokens = parseMatchByTokens(parsed.matchBy);
613
+ const rawTokens = new Set(rawEntries.map((r) => r.token));
614
+ const matchByEntries = buildMatchByEntries({
615
+ tokens: matchByTokens,
616
+ setEntries,
617
+ rawTokens,
618
+ name: parsed.name,
619
+ });
620
+ // Load board metadata once — every leg (lookup, dry-run /
621
+ // live mutation, column resolver) consumes the same view.
622
+ const meta = await loadBoardMetadata({
623
+ client,
624
+ boardId: parsed.board,
625
+ env: ctx.env,
626
+ noCache: globalFlags.noCache,
627
+ });
628
+ const onColumnNotFound = meta.source === 'cache'
629
+ ? async () => {
630
+ const refreshed = await refreshBoardMetadata({
631
+ client,
632
+ boardId: parsed.board,
633
+ env: ctx.env,
634
+ });
635
+ return refreshed.metadata;
636
+ }
637
+ : undefined;
638
+ // Lookup leg — match-by → items_page rules → 0/1/2+ branch.
639
+ const lookup = await lookupMatches({
640
+ client,
641
+ boardId: parsed.board,
642
+ metadata: meta.metadata,
643
+ matchBy: matchByEntries,
644
+ onColumnNotFound,
645
+ });
646
+ const decision = decideBranch({
647
+ lookup,
648
+ boardId: parsed.board,
649
+ matchBy: matchByEntries,
650
+ });
651
+ if (decision.kind === 'ambiguous') {
652
+ throw decision.error;
653
+ }
654
+ const sourceAgg = new SourceAggregator({
655
+ source: meta.source,
656
+ cacheAgeSeconds: meta.cacheAgeSeconds,
657
+ });
658
+ // Lookup is always live (items_page never caches); the
659
+ // metadata leg may have been cache-served. The resolver may
660
+ // have refreshed; that's already folded into meta via
661
+ // `mergeSource`-style logic below.
662
+ sourceAgg.record('live', null);
663
+ // Filter-warnings → envelope warnings. The resolver fires
664
+ // collision + stale_cache_refreshed; both surface on the
665
+ // success envelope.
666
+ const lookupWarnings = lookup.warnings;
667
+ const { dateResolution, peopleResolution } = buildResolutionContexts({ client, ctx, globalFlags });
668
+ if (decision.kind === 'create') {
669
+ await runCreateBranch({
670
+ client,
671
+ boardId: parsed.board,
672
+ name: parsed.name,
673
+ setEntries,
674
+ rawEntries,
675
+ createLabelsIfMissing: parsed.createLabelsIfMissing,
676
+ dateResolution,
677
+ peopleResolution,
678
+ env: ctx.env,
679
+ noCache: globalFlags.noCache,
680
+ dryRun: globalFlags.dryRun,
681
+ ctx,
682
+ programOpts: program.opts(),
683
+ apiVersion,
684
+ toEmit,
685
+ sourceAgg,
686
+ lookupWarnings,
687
+ matchBy: matchByEntries,
688
+ });
689
+ return;
690
+ }
691
+ await runUpdateBranch({
692
+ client,
693
+ boardId: parsed.board,
694
+ itemId: decision.itemId,
695
+ name: parsed.name,
696
+ setEntries,
697
+ rawEntries,
698
+ createLabelsIfMissing: parsed.createLabelsIfMissing,
699
+ dateResolution,
700
+ peopleResolution,
701
+ env: ctx.env,
702
+ noCache: globalFlags.noCache,
703
+ dryRun: globalFlags.dryRun,
704
+ ctx,
705
+ programOpts: program.opts(),
706
+ apiVersion,
707
+ toEmit,
708
+ sourceAgg,
709
+ lookupWarnings,
710
+ matchBy: matchByEntries,
711
+ });
712
+ });
713
+ },
714
+ };
715
+ const matchByTokenList = (matchBy) => matchBy.map((e) => e.token);
716
+ const runCreateBranch = async (inputs) => {
717
+ if (inputs.dryRun) {
718
+ // Reuse the M9 dry-run engine so the diff cells match `item
719
+ // create` byte-for-byte; then post-process the planned change to
720
+ // hoist `name` + add the upsert-specific match_by / matched_count
721
+ // echoes per cli-design §6.4 upsert shape.
722
+ const result = await planCreate({
723
+ client: inputs.client,
724
+ mode: { kind: 'item', boardId: inputs.boardId },
725
+ name: inputs.name,
726
+ setEntries: inputs.setEntries,
727
+ ...(inputs.rawEntries.length === 0
728
+ ? {}
729
+ : { rawEntries: inputs.rawEntries }),
730
+ dateResolution: inputs.dateResolution,
731
+ peopleResolution: inputs.peopleResolution,
732
+ env: inputs.env,
733
+ noCache: inputs.noCache,
734
+ });
735
+ const plan = result.plannedChanges[0];
736
+ /* c8 ignore next 6 — defensive: planCreate returns exactly one
737
+ PlannedChange for an item create; the index guard exists for
738
+ narrowing only. */
739
+ if (plan === undefined) {
740
+ throw new ApiError('internal_error', 'upsert create-branch dry-run: planCreate returned zero plannedChanges');
741
+ }
742
+ const planned = {
743
+ operation: 'create_item',
744
+ board_id: plan.board_id,
745
+ name: plan.name,
746
+ resolved_ids: plan.resolved_ids,
747
+ diff: plan.diff,
748
+ match_by: matchByTokenList(inputs.matchBy),
749
+ matched_count: 0,
750
+ };
751
+ // Fold the upsert preflight legs (metadata + lookup) into the
752
+ // dry-run source — `meta.source` must reflect EVERY wire leg that
753
+ // fired, not just planCreate's. The metadata leg may be cache or
754
+ // live; the lookup is always live (items_page never caches), so
755
+ // the aggregate is at minimum 'live' (or 'mixed' if metadata
756
+ // hit cache). Codex round-1 F2.
757
+ const preflight = inputs.sourceAgg.result();
758
+ const dryRunSource = mergeSourceWithPreflight(result.source, preflight.source);
759
+ const dryRunCacheAge = mergeCacheAge(result.cacheAgeSeconds, preflight.cacheAgeSeconds);
760
+ emitDryRun({
761
+ ctx: inputs.ctx,
762
+ programOpts: inputs.programOpts,
763
+ plannedChanges: [planned],
764
+ source: dryRunSource,
765
+ cacheAgeSeconds: dryRunCacheAge,
766
+ warnings: [...inputs.lookupWarnings, ...result.warnings],
767
+ apiVersion: inputs.apiVersion,
768
+ });
769
+ return;
770
+ }
771
+ // Live create branch — three-pass resolution, bundle into
772
+ // column_values, single round-trip create_item.
773
+ const resolutionResult = await resolveAndTranslate({
774
+ client: inputs.client,
775
+ boardId: inputs.boardId,
776
+ setEntries: inputs.setEntries,
777
+ rawEntries: inputs.rawEntries,
778
+ dateResolution: inputs.dateResolution,
779
+ peopleResolution: inputs.peopleResolution,
780
+ env: inputs.env,
781
+ noCache: inputs.noCache,
782
+ });
783
+ const collectedWarnings = [
784
+ ...resolutionResult.warnings,
785
+ ];
786
+ const resolvedIds = resolutionResult.resolvedIds;
787
+ if (resolutionResult.source !== undefined) {
788
+ inputs.sourceAgg.record(resolutionResult.source, resolutionResult.cacheAgeSeconds);
789
+ }
790
+ const translated = resolutionResult.translated;
791
+ const columnValues = translated.length === 0 ? null : bundleColumnValues(translated);
792
+ let mutationResult;
793
+ try {
794
+ mutationResult = await executeCreate({
795
+ client: inputs.client,
796
+ boardId: inputs.boardId,
797
+ itemName: inputs.name,
798
+ columnValues,
799
+ createLabelsIfMissing: inputs.createLabelsIfMissing,
800
+ });
801
+ }
802
+ catch (err) {
803
+ /* c8 ignore next 24 — the false arm of `instanceof MondayCliError`
804
+ only fires for raw JS-runtime errors (TypeError, RangeError);
805
+ defensive across all four mutation surfaces (create / update /
806
+ clear / upsert), pattern proven via foldAndRemap unit tests. */
807
+ if (err instanceof MondayCliError) {
808
+ // Same column-archived remap shape `item create` uses (M9 P1).
809
+ // Cache-sourced resolution + Monday rejecting as
810
+ // validation_failed → check live archived state. Pass every
811
+ // translated column id (M5b finding #3) so multi-`--set` cases
812
+ // where a later target is archived still remap.
813
+ throw await foldAndRemap({
814
+ err,
815
+ warnings: [
816
+ ...inputs.lookupWarnings.flatMap((w) => w.code === 'column_token_collision' ||
817
+ w.code === 'stale_cache_refreshed'
818
+ ? [w]
819
+ : []),
820
+ ...collectedWarnings,
821
+ ],
822
+ client: inputs.client,
823
+ boardId: inputs.boardId,
824
+ columnIds: translated.map((t) => t.columnId),
825
+ env: inputs.env,
826
+ noCache: inputs.noCache,
827
+ // Defensive fallback: resolveAndTranslate returns a defined
828
+ // source whenever any --set / --set-raw leg fires. The
829
+ // fallback covers the contrived empty-resolution case.
830
+ resolutionSource: resolutionResult.source ?? 'live',
831
+ });
832
+ }
833
+ throw err;
834
+ }
835
+ // Mutation leg fires live; record so cache-served metadata + live
836
+ // wire calls collapses to `mixed`. Mirrors `item create`'s tail
837
+ // record pattern.
838
+ inputs.sourceAgg.record('live', null);
839
+ const data = {
840
+ ...mutationResult.projected,
841
+ operation: 'create_item',
842
+ };
843
+ emitMutation({
844
+ ctx: inputs.ctx,
845
+ data,
846
+ schema: itemUpsertCommand.outputSchema,
847
+ programOpts: inputs.programOpts,
848
+ warnings: [...inputs.lookupWarnings, ...collectedWarnings],
849
+ ...inputs.toEmit(mutationResult.response),
850
+ ...inputs.sourceAgg.result(),
851
+ resolvedIds,
852
+ });
853
+ };
854
+ const runUpdateBranch = async (inputs) => {
855
+ if (inputs.dryRun) {
856
+ // Reuse the M5b dry-run engine. planChanges produces the
857
+ // `change_*` wire-name on the resulting plannedChange; we
858
+ // override to the verb-level `update_item` per cli-design §6.4
859
+ // upsert shape and add the M12 echoes.
860
+ const result = await planChanges({
861
+ client: inputs.client,
862
+ boardId: inputs.boardId,
863
+ itemId: inputs.itemId,
864
+ setEntries: inputs.setEntries,
865
+ ...(inputs.rawEntries.length === 0
866
+ ? {}
867
+ : { rawEntries: inputs.rawEntries }),
868
+ nameChange: inputs.name,
869
+ dateResolution: inputs.dateResolution,
870
+ peopleResolution: inputs.peopleResolution,
871
+ env: inputs.env,
872
+ noCache: inputs.noCache,
873
+ });
874
+ const plan = result.plannedChanges[0];
875
+ /* c8 ignore next 6 — defensive: planChanges returns exactly one
876
+ PlannedChange for a single-item plan; the guard exists for
877
+ narrowing only. */
878
+ if (plan === undefined) {
879
+ throw new ApiError('internal_error', 'upsert update-branch dry-run: planChanges returned zero plannedChanges');
880
+ }
881
+ const planned = {
882
+ operation: 'update_item',
883
+ board_id: plan.board_id,
884
+ item_id: plan.item_id,
885
+ name: inputs.name,
886
+ resolved_ids: plan.resolved_ids,
887
+ diff: plan.diff,
888
+ match_by: matchByTokenList(inputs.matchBy),
889
+ matched_count: 1,
890
+ };
891
+ // Fold the upsert preflight legs (metadata + lookup) into the
892
+ // dry-run source. planChanges' source is always `'live' |
893
+ // 'cache' | 'mixed'` (no `'none'` arm — it always reads the
894
+ // item state); use mergeSource directly. Codex round-1 F2.
895
+ const preflight = inputs.sourceAgg.result();
896
+ const dryRunSource = mergeSource(preflight.source, result.source);
897
+ const dryRunCacheAge = mergeCacheAge(result.cacheAgeSeconds, preflight.cacheAgeSeconds);
898
+ emitDryRun({
899
+ ctx: inputs.ctx,
900
+ programOpts: inputs.programOpts,
901
+ plannedChanges: [planned],
902
+ source: dryRunSource,
903
+ cacheAgeSeconds: dryRunCacheAge,
904
+ warnings: [...inputs.lookupWarnings, ...result.warnings],
905
+ apiVersion: inputs.apiVersion,
906
+ });
907
+ return;
908
+ }
909
+ // Live update branch — three-pass resolution, then
910
+ // selectMutation + execute. Mirrors item update's single-item path
911
+ // verbatim (Codex round-4 P2: same wire shape, same atomicity).
912
+ const resolutionResult = await resolveAndTranslate({
913
+ client: inputs.client,
914
+ boardId: inputs.boardId,
915
+ setEntries: inputs.setEntries,
916
+ rawEntries: inputs.rawEntries,
917
+ dateResolution: inputs.dateResolution,
918
+ peopleResolution: inputs.peopleResolution,
919
+ env: inputs.env,
920
+ noCache: inputs.noCache,
921
+ });
922
+ const collectedWarnings = [
923
+ ...resolutionResult.warnings,
924
+ ];
925
+ const resolvedIds = resolutionResult.resolvedIds;
926
+ if (resolutionResult.source !== undefined) {
927
+ inputs.sourceAgg.record(resolutionResult.source, resolutionResult.cacheAgeSeconds);
928
+ }
929
+ const translated = resolutionResult.translated;
930
+ // Synthetic name key — same shape item update's single path uses.
931
+ // selectMutation handles bundling: name-only → simple; name + cols
932
+ // (or ≥2 cols) → multi.
933
+ const allTranslated = [
934
+ {
935
+ columnId: 'name',
936
+ columnType: 'text',
937
+ rawInput: inputs.name,
938
+ payload: { format: 'simple', value: inputs.name },
939
+ resolvedFrom: null,
940
+ peopleResolution: null,
941
+ },
942
+ ...translated,
943
+ ];
944
+ let mutationResult;
945
+ try {
946
+ const mutation = selectMutation(allTranslated);
947
+ mutationResult = await executeUpdate({
948
+ client: inputs.client,
949
+ mutation,
950
+ itemId: inputs.itemId,
951
+ boardId: inputs.boardId,
952
+ createLabelsIfMissing: inputs.createLabelsIfMissing,
953
+ });
954
+ }
955
+ catch (err) {
956
+ /* c8 ignore next 21 — the false arm of `instanceof MondayCliError`
957
+ only fires for raw JS-runtime errors; defensive across all four
958
+ mutation surfaces. Pattern proven via foldAndRemap unit tests. */
959
+ if (err instanceof MondayCliError) {
960
+ throw await foldAndRemap({
961
+ err,
962
+ warnings: [
963
+ ...inputs.lookupWarnings.flatMap((w) => w.code === 'column_token_collision' ||
964
+ w.code === 'stale_cache_refreshed'
965
+ ? [w]
966
+ : []),
967
+ ...collectedWarnings,
968
+ ],
969
+ client: inputs.client,
970
+ boardId: inputs.boardId,
971
+ columnIds: translated.map((t) => t.columnId),
972
+ env: inputs.env,
973
+ noCache: inputs.noCache,
974
+ // Defensive fallback: resolveAndTranslate returns a defined
975
+ // source whenever any --set / --set-raw leg fires; covers the
976
+ // --name-only update path failing, a contrived edge case.
977
+ resolutionSource: resolutionResult.source ?? 'live',
978
+ });
979
+ }
980
+ throw err;
981
+ }
982
+ inputs.sourceAgg.record('live', null);
983
+ const data = {
984
+ ...mutationResult.projected,
985
+ operation: 'update_item',
986
+ };
987
+ emitMutation({
988
+ ctx: inputs.ctx,
989
+ data,
990
+ schema: itemUpsertCommand.outputSchema,
991
+ programOpts: inputs.programOpts,
992
+ warnings: [...inputs.lookupWarnings, ...collectedWarnings],
993
+ ...inputs.toEmit(mutationResult.response),
994
+ ...inputs.sourceAgg.result(),
995
+ resolvedIds,
996
+ });
997
+ };
998
+ //# sourceMappingURL=upsert.js.map