monday-cli 0.2.0 → 0.4.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 (479) hide show
  1. package/CHANGELOG.md +675 -2
  2. package/README.md +223 -31
  3. package/dist/api/assets.d.ts +326 -0
  4. package/dist/api/assets.d.ts.map +1 -0
  5. package/dist/api/assets.js +519 -0
  6. package/dist/api/assets.js.map +1 -0
  7. package/dist/api/board-favorites.d.ts +329 -0
  8. package/dist/api/board-favorites.d.ts.map +1 -0
  9. package/dist/api/board-favorites.js +353 -0
  10. package/dist/api/board-favorites.js.map +1 -0
  11. package/dist/api/board-mutation-result.d.ts +9 -5
  12. package/dist/api/board-mutation-result.d.ts.map +1 -1
  13. package/dist/api/board-mutation-result.js +9 -5
  14. package/dist/api/board-mutation-result.js.map +1 -1
  15. package/dist/api/board-relation-validation.d.ts +161 -0
  16. package/dist/api/board-relation-validation.d.ts.map +1 -0
  17. package/dist/api/board-relation-validation.js +317 -0
  18. package/dist/api/board-relation-validation.js.map +1 -0
  19. package/dist/api/cache.d.ts +14 -5
  20. package/dist/api/cache.d.ts.map +1 -1
  21. package/dist/api/cache.js +8 -10
  22. package/dist/api/cache.js.map +1 -1
  23. package/dist/api/column-mapping.js +2 -2
  24. package/dist/api/column-mapping.js.map +1 -1
  25. package/dist/api/column-mutation-result.d.ts +9 -5
  26. package/dist/api/column-mutation-result.d.ts.map +1 -1
  27. package/dist/api/column-mutation-result.js +9 -5
  28. package/dist/api/column-mutation-result.js.map +1 -1
  29. package/dist/api/column-types.d.ts +37 -14
  30. package/dist/api/column-types.d.ts.map +1 -1
  31. package/dist/api/column-types.js +47 -6
  32. package/dist/api/column-types.js.map +1 -1
  33. package/dist/api/column-values.d.ts +234 -31
  34. package/dist/api/column-values.d.ts.map +1 -1
  35. package/dist/api/column-values.js +560 -124
  36. package/dist/api/column-values.js.map +1 -1
  37. package/dist/api/cross-board-search.d.ts +501 -0
  38. package/dist/api/cross-board-search.d.ts.map +1 -0
  39. package/dist/api/cross-board-search.js +547 -0
  40. package/dist/api/cross-board-search.js.map +1 -0
  41. package/dist/api/dev-conventions.d.ts +1038 -0
  42. package/dist/api/dev-conventions.d.ts.map +1 -0
  43. package/dist/api/dev-conventions.js +1556 -0
  44. package/dist/api/dev-conventions.js.map +1 -0
  45. package/dist/api/documents.d.ts +519 -0
  46. package/dist/api/documents.d.ts.map +1 -0
  47. package/dist/api/documents.js +586 -0
  48. package/dist/api/documents.js.map +1 -0
  49. package/dist/api/dry-run.d.ts +32 -5
  50. package/dist/api/dry-run.d.ts.map +1 -1
  51. package/dist/api/dry-run.js +149 -32
  52. package/dist/api/dry-run.js.map +1 -1
  53. package/dist/api/errors.d.ts.map +1 -1
  54. package/dist/api/errors.js +28 -7
  55. package/dist/api/errors.js.map +1 -1
  56. package/dist/api/group-mutation-result.d.ts +9 -5
  57. package/dist/api/group-mutation-result.d.ts.map +1 -1
  58. package/dist/api/group-mutation-result.js +9 -5
  59. package/dist/api/group-mutation-result.js.map +1 -1
  60. package/dist/api/item-history-projection.d.ts +919 -0
  61. package/dist/api/item-history-projection.d.ts.map +1 -0
  62. package/dist/api/item-history-projection.js +1104 -0
  63. package/dist/api/item-history-projection.js.map +1 -0
  64. package/dist/api/item-mutation-execute.d.ts +82 -0
  65. package/dist/api/item-mutation-execute.d.ts.map +1 -0
  66. package/dist/api/item-mutation-execute.js +199 -0
  67. package/dist/api/item-mutation-execute.js.map +1 -0
  68. package/dist/api/item-watch.d.ts +263 -0
  69. package/dist/api/item-watch.d.ts.map +1 -0
  70. package/dist/api/item-watch.js +709 -0
  71. package/dist/api/item-watch.js.map +1 -0
  72. package/dist/api/multipart-transport.d.ts +223 -0
  73. package/dist/api/multipart-transport.d.ts.map +1 -0
  74. package/dist/api/multipart-transport.js +274 -0
  75. package/dist/api/multipart-transport.js.map +1 -0
  76. package/dist/api/notifications.d.ts +156 -0
  77. package/dist/api/notifications.d.ts.map +1 -0
  78. package/dist/api/notifications.js +215 -0
  79. package/dist/api/notifications.js.map +1 -0
  80. package/dist/api/oauth-test-helper.d.ts +64 -0
  81. package/dist/api/oauth-test-helper.d.ts.map +1 -0
  82. package/dist/api/oauth-test-helper.js +179 -0
  83. package/dist/api/oauth-test-helper.js.map +1 -0
  84. package/dist/api/oauth.d.ts +198 -0
  85. package/dist/api/oauth.d.ts.map +1 -0
  86. package/dist/api/oauth.js +471 -0
  87. package/dist/api/oauth.js.map +1 -0
  88. package/dist/api/parallel-dispatch.d.ts +155 -0
  89. package/dist/api/parallel-dispatch.d.ts.map +1 -0
  90. package/dist/api/parallel-dispatch.js +243 -0
  91. package/dist/api/parallel-dispatch.js.map +1 -0
  92. package/dist/api/partial-success-bulk.d.ts +480 -0
  93. package/dist/api/partial-success-bulk.d.ts.map +1 -0
  94. package/dist/api/partial-success-bulk.js +436 -0
  95. package/dist/api/partial-success-bulk.js.map +1 -0
  96. package/dist/api/partial-success-mutation.d.ts +13 -1
  97. package/dist/api/partial-success-mutation.d.ts.map +1 -1
  98. package/dist/api/partial-success-mutation.js +5 -1
  99. package/dist/api/partial-success-mutation.js.map +1 -1
  100. package/dist/api/people.d.ts +54 -1
  101. package/dist/api/people.d.ts.map +1 -1
  102. package/dist/api/people.js +27 -3
  103. package/dist/api/people.js.map +1 -1
  104. package/dist/api/probes.d.ts +487 -0
  105. package/dist/api/probes.d.ts.map +1 -0
  106. package/dist/api/probes.js +881 -0
  107. package/dist/api/probes.js.map +1 -0
  108. package/dist/api/raw-document.d.ts.map +1 -1
  109. package/dist/api/raw-document.js +2 -2
  110. package/dist/api/raw-document.js.map +1 -1
  111. package/dist/api/raw-write.d.ts +12 -4
  112. package/dist/api/raw-write.d.ts.map +1 -1
  113. package/dist/api/raw-write.js +32 -14
  114. package/dist/api/raw-write.js.map +1 -1
  115. package/dist/api/resolution-context.d.ts +23 -11
  116. package/dist/api/resolution-context.d.ts.map +1 -1
  117. package/dist/api/resolution-context.js +53 -12
  118. package/dist/api/resolution-context.js.map +1 -1
  119. package/dist/api/resolution-pass.d.ts +30 -1
  120. package/dist/api/resolution-pass.d.ts.map +1 -1
  121. package/dist/api/resolution-pass.js +36 -1
  122. package/dist/api/resolution-pass.js.map +1 -1
  123. package/dist/api/resolve-client.d.ts +22 -0
  124. package/dist/api/resolve-client.d.ts.map +1 -1
  125. package/dist/api/resolve-client.js +9 -1
  126. package/dist/api/resolve-client.js.map +1 -1
  127. package/dist/api/response-root.d.ts +92 -46
  128. package/dist/api/response-root.d.ts.map +1 -1
  129. package/dist/api/response-root.js +93 -41
  130. package/dist/api/response-root.js.map +1 -1
  131. package/dist/api/tag-directory.d.ts +154 -0
  132. package/dist/api/tag-directory.d.ts.map +1 -0
  133. package/dist/api/tag-directory.js +325 -0
  134. package/dist/api/tag-directory.js.map +1 -0
  135. package/dist/api/time-tracking.d.ts +165 -0
  136. package/dist/api/time-tracking.d.ts.map +1 -0
  137. package/dist/api/time-tracking.js +135 -0
  138. package/dist/api/time-tracking.js.map +1 -0
  139. package/dist/api/transport.js +3 -3
  140. package/dist/api/transport.js.map +1 -1
  141. package/dist/api/usage.d.ts +190 -0
  142. package/dist/api/usage.d.ts.map +1 -0
  143. package/dist/api/usage.js +194 -0
  144. package/dist/api/usage.js.map +1 -0
  145. package/dist/api/users-fan-out-mutation.d.ts.map +1 -1
  146. package/dist/api/users-fan-out-mutation.js +10 -5
  147. package/dist/api/users-fan-out-mutation.js.map +1 -1
  148. package/dist/api/webhooks.d.ts +357 -0
  149. package/dist/api/webhooks.d.ts.map +1 -0
  150. package/dist/api/webhooks.js +333 -0
  151. package/dist/api/webhooks.js.map +1 -0
  152. package/dist/cli/envelope-out.d.ts +18 -1
  153. package/dist/cli/envelope-out.d.ts.map +1 -1
  154. package/dist/cli/envelope-out.js +16 -2
  155. package/dist/cli/envelope-out.js.map +1 -1
  156. package/dist/cli/program.d.ts.map +1 -1
  157. package/dist/cli/program.js +120 -1
  158. package/dist/cli/program.js.map +1 -1
  159. package/dist/cli/run.d.ts +32 -0
  160. package/dist/cli/run.d.ts.map +1 -1
  161. package/dist/cli/run.js +3 -0
  162. package/dist/cli/run.js.map +1 -1
  163. package/dist/commands/account/tags.d.ts +37 -0
  164. package/dist/commands/account/tags.d.ts.map +1 -0
  165. package/dist/commands/account/tags.js +84 -0
  166. package/dist/commands/account/tags.js.map +1 -0
  167. package/dist/commands/auth/login.d.ts +14 -0
  168. package/dist/commands/auth/login.d.ts.map +1 -0
  169. package/dist/commands/auth/login.js +314 -0
  170. package/dist/commands/auth/login.js.map +1 -0
  171. package/dist/commands/auth/logout.d.ts +28 -0
  172. package/dist/commands/auth/logout.d.ts.map +1 -0
  173. package/dist/commands/auth/logout.js +94 -0
  174. package/dist/commands/auth/logout.js.map +1 -0
  175. package/dist/commands/board/archive.d.ts.map +1 -1
  176. package/dist/commands/board/archive.js +14 -14
  177. package/dist/commands/board/archive.js.map +1 -1
  178. package/dist/commands/board/column-create.d.ts +9 -8
  179. package/dist/commands/board/column-create.d.ts.map +1 -1
  180. package/dist/commands/board/column-create.js +61 -51
  181. package/dist/commands/board/column-create.js.map +1 -1
  182. package/dist/commands/board/column-delete.d.ts.map +1 -1
  183. package/dist/commands/board/column-delete.js +15 -16
  184. package/dist/commands/board/column-delete.js.map +1 -1
  185. package/dist/commands/board/column-update.d.ts.map +1 -1
  186. package/dist/commands/board/column-update.js +23 -22
  187. package/dist/commands/board/column-update.js.map +1 -1
  188. package/dist/commands/board/create.d.ts.map +1 -1
  189. package/dist/commands/board/create.js +14 -17
  190. package/dist/commands/board/create.js.map +1 -1
  191. package/dist/commands/board/delete.d.ts.map +1 -1
  192. package/dist/commands/board/delete.js +12 -15
  193. package/dist/commands/board/delete.js.map +1 -1
  194. package/dist/commands/board/describe.d.ts.map +1 -1
  195. package/dist/commands/board/describe.js +30 -0
  196. package/dist/commands/board/describe.js.map +1 -1
  197. package/dist/commands/board/duplicate.d.ts.map +1 -1
  198. package/dist/commands/board/duplicate.js +12 -13
  199. package/dist/commands/board/duplicate.js.map +1 -1
  200. package/dist/commands/board/favorites.d.ts +33 -0
  201. package/dist/commands/board/favorites.d.ts.map +1 -0
  202. package/dist/commands/board/favorites.js +74 -0
  203. package/dist/commands/board/favorites.js.map +1 -0
  204. package/dist/commands/board/find.d.ts +1 -1
  205. package/dist/commands/board/group-archive.d.ts.map +1 -1
  206. package/dist/commands/board/group-archive.js +12 -16
  207. package/dist/commands/board/group-archive.js.map +1 -1
  208. package/dist/commands/board/group-create.d.ts.map +1 -1
  209. package/dist/commands/board/group-create.js +9 -19
  210. package/dist/commands/board/group-create.js.map +1 -1
  211. package/dist/commands/board/group-delete.d.ts.map +1 -1
  212. package/dist/commands/board/group-delete.js +12 -16
  213. package/dist/commands/board/group-delete.js.map +1 -1
  214. package/dist/commands/board/group-duplicate.d.ts.map +1 -1
  215. package/dist/commands/board/group-duplicate.js +12 -16
  216. package/dist/commands/board/group-duplicate.js.map +1 -1
  217. package/dist/commands/board/group-update.d.ts.map +1 -1
  218. package/dist/commands/board/group-update.js +12 -11
  219. package/dist/commands/board/group-update.js.map +1 -1
  220. package/dist/commands/board/list.d.ts +1 -1
  221. package/dist/commands/board/update.d.ts.map +1 -1
  222. package/dist/commands/board/update.js +16 -11
  223. package/dist/commands/board/update.js.map +1 -1
  224. package/dist/commands/cache/list.d.ts +2 -0
  225. package/dist/commands/cache/list.d.ts.map +1 -1
  226. package/dist/commands/cache/list.js +2 -2
  227. package/dist/commands/cache/list.js.map +1 -1
  228. package/dist/commands/completion.d.ts +188 -0
  229. package/dist/commands/completion.d.ts.map +1 -0
  230. package/dist/commands/completion.js +418 -0
  231. package/dist/commands/completion.js.map +1 -0
  232. package/dist/commands/dev/_shared.d.ts +40 -0
  233. package/dist/commands/dev/_shared.d.ts.map +1 -0
  234. package/dist/commands/dev/_shared.js +104 -0
  235. package/dist/commands/dev/_shared.js.map +1 -0
  236. package/dist/commands/dev/configure.d.ts +36 -0
  237. package/dist/commands/dev/configure.d.ts.map +1 -0
  238. package/dist/commands/dev/configure.js +145 -0
  239. package/dist/commands/dev/configure.js.map +1 -0
  240. package/dist/commands/dev/discover.d.ts +34 -0
  241. package/dist/commands/dev/discover.d.ts.map +1 -0
  242. package/dist/commands/dev/discover.js +117 -0
  243. package/dist/commands/dev/discover.js.map +1 -0
  244. package/dist/commands/dev/doctor.d.ts +39 -0
  245. package/dist/commands/dev/doctor.d.ts.map +1 -0
  246. package/dist/commands/dev/doctor.js +91 -0
  247. package/dist/commands/dev/doctor.js.map +1 -0
  248. package/dist/commands/dev/epic/items.d.ts +24 -0
  249. package/dist/commands/dev/epic/items.d.ts.map +1 -0
  250. package/dist/commands/dev/epic/items.js +103 -0
  251. package/dist/commands/dev/epic/items.js.map +1 -0
  252. package/dist/commands/dev/epic/list.d.ts +36 -0
  253. package/dist/commands/dev/epic/list.d.ts.map +1 -0
  254. package/dist/commands/dev/epic/list.js +120 -0
  255. package/dist/commands/dev/epic/list.js.map +1 -0
  256. package/dist/commands/dev/release/list.d.ts +21 -0
  257. package/dist/commands/dev/release/list.d.ts.map +1 -0
  258. package/dist/commands/dev/release/list.js +73 -0
  259. package/dist/commands/dev/release/list.js.map +1 -0
  260. package/dist/commands/dev/sprint/current.d.ts +24 -0
  261. package/dist/commands/dev/sprint/current.d.ts.map +1 -0
  262. package/dist/commands/dev/sprint/current.js +90 -0
  263. package/dist/commands/dev/sprint/current.js.map +1 -0
  264. package/dist/commands/dev/sprint/items.d.ts +34 -0
  265. package/dist/commands/dev/sprint/items.d.ts.map +1 -0
  266. package/dist/commands/dev/sprint/items.js +118 -0
  267. package/dist/commands/dev/sprint/items.js.map +1 -0
  268. package/dist/commands/dev/sprint/list.d.ts +41 -0
  269. package/dist/commands/dev/sprint/list.d.ts.map +1 -0
  270. package/dist/commands/dev/sprint/list.js +104 -0
  271. package/dist/commands/dev/sprint/list.js.map +1 -0
  272. package/dist/commands/dev/task/block.d.ts +29 -0
  273. package/dist/commands/dev/task/block.d.ts.map +1 -0
  274. package/dist/commands/dev/task/block.js +106 -0
  275. package/dist/commands/dev/task/block.js.map +1 -0
  276. package/dist/commands/dev/task/done.d.ts +30 -0
  277. package/dist/commands/dev/task/done.d.ts.map +1 -0
  278. package/dist/commands/dev/task/done.js +113 -0
  279. package/dist/commands/dev/task/done.js.map +1 -0
  280. package/dist/commands/dev/task/list.d.ts +42 -0
  281. package/dist/commands/dev/task/list.d.ts.map +1 -0
  282. package/dist/commands/dev/task/list.js +227 -0
  283. package/dist/commands/dev/task/list.js.map +1 -0
  284. package/dist/commands/dev/task/start.d.ts +29 -0
  285. package/dist/commands/dev/task/start.d.ts.map +1 -0
  286. package/dist/commands/dev/task/start.js +90 -0
  287. package/dist/commands/dev/task/start.js.map +1 -0
  288. package/dist/commands/doc/get.d.ts +46 -0
  289. package/dist/commands/doc/get.d.ts.map +1 -0
  290. package/dist/commands/doc/get.js +95 -0
  291. package/dist/commands/doc/get.js.map +1 -0
  292. package/dist/commands/doc/list.d.ts +83 -0
  293. package/dist/commands/doc/list.d.ts.map +1 -0
  294. package/dist/commands/doc/list.js +248 -0
  295. package/dist/commands/doc/list.js.map +1 -0
  296. package/dist/commands/emit.d.ts.map +1 -1
  297. package/dist/commands/emit.js +5 -3
  298. package/dist/commands/emit.js.map +1 -1
  299. package/dist/commands/index.d.ts.map +1 -1
  300. package/dist/commands/index.js +141 -0
  301. package/dist/commands/index.js.map +1 -1
  302. package/dist/commands/item/archive.d.ts.map +1 -1
  303. package/dist/commands/item/archive.js +11 -0
  304. package/dist/commands/item/archive.js.map +1 -1
  305. package/dist/commands/item/clear.d.ts.map +1 -1
  306. package/dist/commands/item/clear.js +15 -0
  307. package/dist/commands/item/clear.js.map +1 -1
  308. package/dist/commands/item/create.d.ts.map +1 -1
  309. package/dist/commands/item/create.js +41 -8
  310. package/dist/commands/item/create.js.map +1 -1
  311. package/dist/commands/item/delete.d.ts.map +1 -1
  312. package/dist/commands/item/delete.js +11 -0
  313. package/dist/commands/item/delete.js.map +1 -1
  314. package/dist/commands/item/duplicate.d.ts.map +1 -1
  315. package/dist/commands/item/duplicate.js +12 -0
  316. package/dist/commands/item/duplicate.js.map +1 -1
  317. package/dist/commands/item/history.d.ts +60 -0
  318. package/dist/commands/item/history.d.ts.map +1 -0
  319. package/dist/commands/item/history.js +309 -0
  320. package/dist/commands/item/history.js.map +1 -0
  321. package/dist/commands/item/list.d.ts.map +1 -1
  322. package/dist/commands/item/list.js +16 -13
  323. package/dist/commands/item/list.js.map +1 -1
  324. package/dist/commands/item/move.d.ts.map +1 -1
  325. package/dist/commands/item/move.js +41 -7
  326. package/dist/commands/item/move.js.map +1 -1
  327. package/dist/commands/item/search.d.ts +99 -15
  328. package/dist/commands/item/search.d.ts.map +1 -1
  329. package/dist/commands/item/search.js +480 -36
  330. package/dist/commands/item/search.js.map +1 -1
  331. package/dist/commands/item/set.d.ts.map +1 -1
  332. package/dist/commands/item/set.js +52 -8
  333. package/dist/commands/item/set.js.map +1 -1
  334. package/dist/commands/item/time-track/start.d.ts +61 -0
  335. package/dist/commands/item/time-track/start.d.ts.map +1 -0
  336. package/dist/commands/item/time-track/start.js +138 -0
  337. package/dist/commands/item/time-track/start.js.map +1 -0
  338. package/dist/commands/item/time-track/stop.d.ts +32 -0
  339. package/dist/commands/item/time-track/stop.d.ts.map +1 -0
  340. package/dist/commands/item/time-track/stop.js +97 -0
  341. package/dist/commands/item/time-track/stop.js.map +1 -0
  342. package/dist/commands/item/update.d.ts +2 -0
  343. package/dist/commands/item/update.d.ts.map +1 -1
  344. package/dist/commands/item/update.js +164 -113
  345. package/dist/commands/item/update.js.map +1 -1
  346. package/dist/commands/item/upload.d.ts +108 -0
  347. package/dist/commands/item/upload.d.ts.map +1 -0
  348. package/dist/commands/item/upload.js +370 -0
  349. package/dist/commands/item/upload.js.map +1 -0
  350. package/dist/commands/item/upsert.d.ts.map +1 -1
  351. package/dist/commands/item/upsert.js +48 -1
  352. package/dist/commands/item/upsert.js.map +1 -1
  353. package/dist/commands/item/watch.d.ts +90 -0
  354. package/dist/commands/item/watch.d.ts.map +1 -0
  355. package/dist/commands/item/watch.js +342 -0
  356. package/dist/commands/item/watch.js.map +1 -0
  357. package/dist/commands/notification/send.d.ts +60 -0
  358. package/dist/commands/notification/send.d.ts.map +1 -0
  359. package/dist/commands/notification/send.js +147 -0
  360. package/dist/commands/notification/send.js.map +1 -0
  361. package/dist/commands/parse-argv.d.ts.map +1 -1
  362. package/dist/commands/parse-argv.js +14 -4
  363. package/dist/commands/parse-argv.js.map +1 -1
  364. package/dist/commands/raw/index.d.ts.map +1 -1
  365. package/dist/commands/raw/index.js +13 -15
  366. package/dist/commands/raw/index.js.map +1 -1
  367. package/dist/commands/run-by-id-lookup.d.ts.map +1 -1
  368. package/dist/commands/run-by-id-lookup.js +2 -2
  369. package/dist/commands/run-by-id-lookup.js.map +1 -1
  370. package/dist/commands/schema/index.d.ts +2 -0
  371. package/dist/commands/schema/index.d.ts.map +1 -1
  372. package/dist/commands/status.d.ts +120 -0
  373. package/dist/commands/status.d.ts.map +1 -0
  374. package/dist/commands/status.js +365 -0
  375. package/dist/commands/status.js.map +1 -0
  376. package/dist/commands/update/body-source.d.ts.map +1 -1
  377. package/dist/commands/update/body-source.js +2 -2
  378. package/dist/commands/update/body-source.js.map +1 -1
  379. package/dist/commands/update/create.d.ts +2 -3
  380. package/dist/commands/update/create.d.ts.map +1 -1
  381. package/dist/commands/update/create.js +15 -3
  382. package/dist/commands/update/create.js.map +1 -1
  383. package/dist/commands/update/delete.d.ts.map +1 -1
  384. package/dist/commands/update/delete.js +11 -0
  385. package/dist/commands/update/delete.js.map +1 -1
  386. package/dist/commands/update/edit.d.ts.map +1 -1
  387. package/dist/commands/update/edit.js +11 -0
  388. package/dist/commands/update/edit.js.map +1 -1
  389. package/dist/commands/update/list.d.ts.map +1 -1
  390. package/dist/commands/update/list.js +15 -12
  391. package/dist/commands/update/list.js.map +1 -1
  392. package/dist/commands/update/reply.d.ts.map +1 -1
  393. package/dist/commands/update/reply.js +11 -0
  394. package/dist/commands/update/reply.js.map +1 -1
  395. package/dist/commands/update/toggle.d.ts.map +1 -1
  396. package/dist/commands/update/toggle.js +13 -0
  397. package/dist/commands/update/toggle.js.map +1 -1
  398. package/dist/commands/update/upload.d.ts +69 -0
  399. package/dist/commands/update/upload.d.ts.map +1 -0
  400. package/dist/commands/update/upload.js +235 -0
  401. package/dist/commands/update/upload.js.map +1 -0
  402. package/dist/commands/usage.d.ts +58 -0
  403. package/dist/commands/usage.d.ts.map +1 -0
  404. package/dist/commands/usage.js +94 -0
  405. package/dist/commands/usage.js.map +1 -0
  406. package/dist/commands/webhook/create.d.ts +74 -0
  407. package/dist/commands/webhook/create.d.ts.map +1 -0
  408. package/dist/commands/webhook/create.js +150 -0
  409. package/dist/commands/webhook/create.js.map +1 -0
  410. package/dist/commands/webhook/delete.d.ts +46 -0
  411. package/dist/commands/webhook/delete.d.ts.map +1 -0
  412. package/dist/commands/webhook/delete.js +141 -0
  413. package/dist/commands/webhook/delete.js.map +1 -0
  414. package/dist/commands/webhook/list.d.ts +23 -0
  415. package/dist/commands/webhook/list.d.ts.map +1 -0
  416. package/dist/commands/webhook/list.js +68 -0
  417. package/dist/commands/webhook/list.js.map +1 -0
  418. package/dist/commands/workspace/create.d.ts.map +1 -1
  419. package/dist/commands/workspace/create.js +16 -0
  420. package/dist/commands/workspace/create.js.map +1 -1
  421. package/dist/commands/workspace/delete.d.ts.map +1 -1
  422. package/dist/commands/workspace/delete.js +13 -13
  423. package/dist/commands/workspace/delete.js.map +1 -1
  424. package/dist/commands/workspace/list.d.ts +1 -1
  425. package/dist/commands/workspace/update.d.ts.map +1 -1
  426. package/dist/commands/workspace/update.js +15 -15
  427. package/dist/commands/workspace/update.js.map +1 -1
  428. package/dist/config/credentials.d.ts +189 -0
  429. package/dist/config/credentials.d.ts.map +1 -0
  430. package/dist/config/credentials.js +300 -0
  431. package/dist/config/credentials.js.map +1 -0
  432. package/dist/config/profiles.d.ts +125 -0
  433. package/dist/config/profiles.d.ts.map +1 -0
  434. package/dist/config/profiles.js +227 -0
  435. package/dist/config/profiles.js.map +1 -0
  436. package/dist/types/global-flags.d.ts +1 -1
  437. package/dist/types/global-flags.d.ts.map +1 -1
  438. package/dist/types/global-flags.js +28 -16
  439. package/dist/types/global-flags.js.map +1 -1
  440. package/dist/types/ids.d.ts +4 -0
  441. package/dist/types/ids.d.ts.map +1 -1
  442. package/dist/types/ids.js +12 -3
  443. package/dist/types/ids.js.map +1 -1
  444. package/dist/utils/errors.d.ts +57 -3
  445. package/dist/utils/errors.d.ts.map +1 -1
  446. package/dist/utils/errors.js +69 -2
  447. package/dist/utils/errors.js.map +1 -1
  448. package/dist/utils/fs.d.ts +35 -0
  449. package/dist/utils/fs.d.ts.map +1 -0
  450. package/dist/utils/fs.js +36 -0
  451. package/dist/utils/fs.js.map +1 -0
  452. package/dist/utils/json.d.ts +60 -0
  453. package/dist/utils/json.d.ts.map +1 -0
  454. package/dist/utils/json.js +86 -0
  455. package/dist/utils/json.js.map +1 -0
  456. package/dist/utils/mime.d.ts +24 -0
  457. package/dist/utils/mime.d.ts.map +1 -0
  458. package/dist/utils/mime.js +64 -0
  459. package/dist/utils/mime.js.map +1 -0
  460. package/dist/utils/output/envelope.d.ts +30 -0
  461. package/dist/utils/output/envelope.d.ts.map +1 -1
  462. package/dist/utils/output/envelope.js +26 -0
  463. package/dist/utils/output/envelope.js.map +1 -1
  464. package/dist/utils/output/ndjson.d.ts +90 -3
  465. package/dist/utils/output/ndjson.d.ts.map +1 -1
  466. package/dist/utils/output/ndjson.js +33 -0
  467. package/dist/utils/output/ndjson.js.map +1 -1
  468. package/dist/utils/redact.d.ts.map +1 -1
  469. package/dist/utils/redact.js +31 -0
  470. package/dist/utils/redact.js.map +1 -1
  471. package/dist/utils/signal.d.ts +42 -0
  472. package/dist/utils/signal.d.ts.map +1 -0
  473. package/dist/utils/signal.js +45 -0
  474. package/dist/utils/signal.js.map +1 -0
  475. package/package.json +2 -1
  476. package/dist/commands/account/client-helper.d.ts +0 -37
  477. package/dist/commands/account/client-helper.d.ts.map +0 -1
  478. package/dist/commands/account/client-helper.js +0 -55
  479. package/dist/commands/account/client-helper.js.map +0 -1
@@ -0,0 +1,881 @@
1
+ /**
2
+ * Per-probe primitives for the v0.3-M22 `monday status` verb
3
+ * (cli-design §11.5 — Decision 7 closure: probe by default,
4
+ * `--no-probe` opts out).
5
+ *
6
+ * **What `monday status` answers:** "is everything I need to talk to
7
+ * Monday working, without touching account state?" The verb runs
8
+ * a short, deterministic probe matrix:
9
+ *
10
+ * 1. **DNS** — resolve the configured Monday hostname.
11
+ * 2. **TCP** — open a TCP connection to port 443.
12
+ * 3. **TLS** — complete a TLS handshake (cert validity, SNI).
13
+ * 4. **Auth** — issue the cheapest possible GraphQL read
14
+ * (`query { me { id } }`) against the resolved transport.
15
+ * 5. **Cache writability** — verify the local cache directory
16
+ * (`~/.monday-cli/`) exists with mode `0700` and is writable.
17
+ * 6. **Redaction self-test** — pass a known-fixture token through
18
+ * `redact()` and assert the bytes don't appear in the output.
19
+ * 7. **Env-var pickup summary** — local-only; reports which
20
+ * MONDAY_* env vars influenced the run (set/unset, never
21
+ * values). Helps an agent diagnose "why is the wrong profile
22
+ * being selected?" without spelunking dotfiles.
23
+ *
24
+ * **`--no-probe` semantics.** Skips probes 1–4 (the network-touching
25
+ * ones); probes 5–7 still run because they're local-only and don't
26
+ * touch account state. Use case: offline sanity check after rotating
27
+ * credentials, where the agent wants to confirm the cache + redaction
28
+ * + env-var resolution without firing a real Monday API call.
29
+ *
30
+ * **Empirical probe findings (2026-05-10, against `api.monday.com`,
31
+ * API version `2026-01`) — `scripts/probe/m22-status.ts`:**
32
+ *
33
+ * - **401 envelope shape (auth probe).** Status `401`, content-type
34
+ * `application/json; charset=utf-8`, body
35
+ * `{"errors":[{"message":"Not authenticated","extensions":
36
+ * {"code":"NOT_AUTHENTICATED"}}]}`. Identical envelope for
37
+ * missing-`Authorization` and bad-`Authorization`. The auth-probe
38
+ * step maps this verbatim to `unauthorized` (existing error code;
39
+ * NO new code needed for M22).
40
+ * - **`Bearer <token>` prefix DOES work** on `api.monday.com`
41
+ * alongside bare `<token>`. The CLI's `.claude/rules/security.md`
42
+ * rule against the prefix remains precautionary (proxies / logs
43
+ * sometimes split on `Bearer ` differently), not API-enforced.
44
+ *
45
+ * **Why no new ERROR_CODE for probes.** Each probe maps cleanly to
46
+ * an existing code: DNS / TCP / TLS / network failures →
47
+ * `network_error`; 401 → `unauthorized`; cache-writability failure
48
+ * → `config_error`; redaction self-test failure → `internal_error`
49
+ * (a serious bug, not a user-facing condition). Adding a
50
+ * `probe_failed` umbrella would widen the 29-code registry for
51
+ * marginal benefit; each probe's failure mode is best described by
52
+ * the existing semantic-domain code per cli-design §6.5.
53
+ *
54
+ * **Mockable-seam pattern.** Each probe accepts a per-probe seam
55
+ * (`lookupImpl` / `tcpConnectImpl` / `tlsConnectImpl` / `redactImpl`
56
+ * etc.) so tests don't bind real sockets / open real fetch handles /
57
+ * touch real DNS. Mirrors `src/api/transport.ts`'s `fetchImpl?` slot
58
+ * and the M21 `__test_oauth_helper` env seam: production callers
59
+ * leave the slot unset and the runner uses the real stdlib primitive.
60
+ */
61
+ import { randomUUID } from 'node:crypto';
62
+ import { promises as dnsPromises } from 'node:dns';
63
+ import { createConnection } from 'node:net';
64
+ import { connect as tlsConnect } from 'node:tls';
65
+ import { access, constants as fsConstants, stat, unlink, writeFile, } from 'node:fs/promises';
66
+ import { homedir } from 'node:os';
67
+ import { join } from 'node:path';
68
+ import { z } from 'zod';
69
+ import { ApiError, errorCode, errorMessage } from '../utils/errors.js';
70
+ import { formatMode, isENOENT } from '../utils/fs.js';
71
+ import { redact as defaultRedactImpl } from '../utils/redact.js';
72
+ import { collectSecrets } from '../cli/envelope-out.js';
73
+ /**
74
+ * Stable iteration order for the status envelope's `probes` record.
75
+ * Matches the cli-design §11.5 probe-matrix narrative.
76
+ */
77
+ export const STATUS_PROBE_ORDER = [
78
+ 'dns',
79
+ 'tcp',
80
+ 'tls',
81
+ 'auth',
82
+ 'cache_writability',
83
+ 'redaction_self_test',
84
+ 'env_var_pickup',
85
+ ];
86
+ /**
87
+ * The set of probes a `--no-probe` invocation skips (the network
88
+ * touching ones). Local-only probes always run.
89
+ */
90
+ export const NO_PROBE_SKIP_SET = new Set([
91
+ 'dns',
92
+ 'tcp',
93
+ 'tls',
94
+ 'auth',
95
+ ]);
96
+ /**
97
+ * The fixture canary token the redaction self-test scrubs. **Never a
98
+ * real token** — the byte sequence is deliberately distinctive so a
99
+ * leak-test assertion can scan every emitted byte for it.
100
+ */
101
+ export const REDACTION_SELF_TEST_FIXTURE_TOKEN = 'tok-probe-redaction-self-test-DO-NOT-USE';
102
+ /** Default DNS / TCP / TLS host the probe matrix targets. */
103
+ export const DEFAULT_PROBE_HOSTNAME = 'api.monday.com';
104
+ /** Default port for TCP / TLS probes. */
105
+ export const DEFAULT_PROBE_PORT = 443;
106
+ /** Default per-probe timeout (ms). */
107
+ export const DEFAULT_PROBE_TIMEOUT_MS = 5_000;
108
+ /**
109
+ * The MONDAY_* env-var names the env-var-pickup probe summarises.
110
+ * Each entry maps to `{set: boolean}` in the probe's `details` —
111
+ * the **values are never echoed**, only the set/unset signal.
112
+ */
113
+ export const ENV_VAR_PICKUP_KEYS = [
114
+ 'MONDAY_API_TOKEN',
115
+ 'MONDAY_PROFILE',
116
+ 'MONDAY_API_VERSION',
117
+ 'MONDAY_API_URL',
118
+ 'MONDAY_OUTPUT',
119
+ 'MONDAY_REQUEST_TIMEOUT_MS',
120
+ ];
121
+ /**
122
+ * Cache directory name under HOME. Mirrors {@link
123
+ * import('../config/credentials.js').CREDENTIALS_DIR_NAME} verbatim —
124
+ * the cache + credentials share the same `~/.monday-cli/` parent.
125
+ */
126
+ const CACHE_DIR_NAME = '.monday-cli';
127
+ /**
128
+ * Required directory mode for the cache parent. Anything more
129
+ * permissive than `0700` is flagged `mode_insecure`.
130
+ */
131
+ const CACHE_DIR_REQUIRED_MODE_BITS = 0o077;
132
+ /**
133
+ * The 6 redaction-leak contexts cli-design §7.4.3 pins for the
134
+ * canary self-test (Codex M21 P1 ratification). Each entry's path is
135
+ * a stable diagnostic key the probe surfaces under
136
+ * `details.contexts_present`; the canary lives at each one.
137
+ */
138
+ const REDACTION_LEAK_CONTEXT_KEYS = [
139
+ 'error.message',
140
+ 'error.stack',
141
+ 'error.cause.message',
142
+ 'headers.authorization',
143
+ 'url',
144
+ 'debug',
145
+ ];
146
+ /**
147
+ * Coerces `AbortSignal.reason` (typed `any`) into an `Error` for the
148
+ * Promise-reject path. Standardises the abort-bubbling shape so
149
+ * every probe seam rejects with an `Error` per the lint rule
150
+ * `@typescript-eslint/prefer-promise-reject-errors`.
151
+ *
152
+ * Distinct from the shared {@link asError} in `utils/errors.ts`: the
153
+ * shared helper has no fallback parameter and uses `String(err)` as
154
+ * the no-Error fallback, which would render `"undefined"` for the
155
+ * `ctrl.abort()` (no-arg) case. This local variant takes a named
156
+ * fallback string that describes the abort source, useful when
157
+ * `AbortSignal.reason` is undefined.
158
+ */
159
+ const asError = (reason, fallback) => {
160
+ if (reason instanceof Error) {
161
+ return reason;
162
+ }
163
+ /* c8 ignore next — `AbortSignal.reason` is an Error in every code
164
+ path the probes reach (timeout uses `ProbeTimeoutError`; outer
165
+ aborts are wrapped errors). Fallback exists for the unspecified
166
+ `ctrl.abort()` (no-arg) case. */
167
+ return new Error(fallback);
168
+ };
169
+ class ProbeTimeoutError extends Error {
170
+ constructor(probe, timeoutMs) {
171
+ super(`${probe} probe timed out after ${String(timeoutMs)}ms`);
172
+ this.name = 'ProbeTimeoutError';
173
+ }
174
+ }
175
+ /**
176
+ * Builds a single-fire abort controller that fires when EITHER the
177
+ * per-probe deadline elapses OR the outer signal aborts. Each probe
178
+ * threads `abortCtx.signal` into its seam so a timeout cleanly
179
+ * tears down the in-flight socket / fetch handle.
180
+ */
181
+ const createProbeAbortContext = (probe, timeoutMs, outerSignal) => {
182
+ const ctrl = new AbortController();
183
+ let timedOut = false;
184
+ const onOuterAbort = () => {
185
+ ctrl.abort(outerSignal?.reason);
186
+ };
187
+ const timer = setTimeout(() => {
188
+ timedOut = true;
189
+ ctrl.abort(new ProbeTimeoutError(probe, timeoutMs));
190
+ }, timeoutMs);
191
+ if (outerSignal !== undefined) {
192
+ if (outerSignal.aborted) {
193
+ ctrl.abort(outerSignal.reason);
194
+ }
195
+ else {
196
+ outerSignal.addEventListener('abort', onOuterAbort, { once: true });
197
+ }
198
+ }
199
+ return {
200
+ signal: ctrl.signal,
201
+ dispose: () => {
202
+ clearTimeout(timer);
203
+ outerSignal?.removeEventListener('abort', onOuterAbort);
204
+ },
205
+ didTimeout: () => timedOut,
206
+ };
207
+ };
208
+ const ok = (probe, startMs, details) => ({
209
+ kind: 'ok',
210
+ probe,
211
+ elapsed_ms: Date.now() - startMs,
212
+ details,
213
+ });
214
+ const fail = (probe, startMs, reason, message, details) => ({
215
+ kind: 'fail',
216
+ probe,
217
+ elapsed_ms: Date.now() - startMs,
218
+ reason,
219
+ message,
220
+ details,
221
+ });
222
+ // Production-only path: binds to the OS resolver. Unit tests inject
223
+ // a `lookupImpl` seam; integration tests under `--no-probe` skip this
224
+ // path entirely. Real DNS-against-api.monday.com tests would be
225
+ // flaky in CI without a fixture resolver.
226
+ /* c8 ignore start */
227
+ const defaultDnsLookup = async (hostname) => {
228
+ const result = await dnsPromises.lookup(hostname, { all: false });
229
+ return { address: result.address, family: result.family };
230
+ };
231
+ /* c8 ignore stop */
232
+ /**
233
+ * Resolves `inputs.hostname` (default {@link DEFAULT_PROBE_HOSTNAME})
234
+ * via `node:dns/promises.lookup` (or the injected `lookupImpl` test
235
+ * seam). Maps `EAI_NONAME` / `ENOTFOUND` → `not_found`; `EAI_AGAIN`
236
+ * → `temporary_failure`; timeout → `timeout`; anything else →
237
+ * `lookup_failed`.
238
+ */
239
+ export const runDnsProbe = async (inputs = {}) => {
240
+ const hostname = inputs.hostname ?? DEFAULT_PROBE_HOSTNAME;
241
+ const timeoutMs = inputs.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
242
+ // Production path goes through `defaultDnsLookup`; unit tests always
243
+ // inject `lookupImpl` for deterministic + offline coverage.
244
+ /* c8 ignore next */
245
+ const lookupImpl = inputs.lookupImpl ?? defaultDnsLookup;
246
+ const start = Date.now();
247
+ const abortCtx = createProbeAbortContext('dns', timeoutMs, inputs.signal);
248
+ try {
249
+ // `dns.promises.lookup` doesn't accept AbortSignal — race the
250
+ // lookup against the abort signal so the per-probe deadline still
251
+ // bounds the wall-clock cost. The leaked underlying lookup
252
+ // resolves into the void once the OS resolver finishes; not ideal
253
+ // but unavoidable without binding to a different resolver lib.
254
+ const result = await Promise.race([
255
+ lookupImpl(hostname),
256
+ new Promise((_, reject) => {
257
+ if (abortCtx.signal.aborted) {
258
+ reject(asError(abortCtx.signal.reason, 'dns probe aborted'));
259
+ return;
260
+ }
261
+ abortCtx.signal.addEventListener('abort', () => {
262
+ reject(asError(abortCtx.signal.reason, 'dns probe aborted'));
263
+ }, { once: true });
264
+ }),
265
+ ]);
266
+ return ok('dns', start, {
267
+ address: result.address,
268
+ family: result.family,
269
+ });
270
+ }
271
+ catch (err) {
272
+ if (abortCtx.didTimeout()) {
273
+ return fail('dns', start, 'timeout', `dns lookup of ${hostname} timed out`, {
274
+ hostname,
275
+ timeout_ms: timeoutMs,
276
+ });
277
+ }
278
+ const code = errorCode(err);
279
+ if (code === 'ENOTFOUND' || code === 'EAI_NONAME') {
280
+ return fail('dns', start, 'not_found', `host ${hostname} not found`, {
281
+ hostname,
282
+ code,
283
+ });
284
+ }
285
+ if (code === 'EAI_AGAIN') {
286
+ return fail('dns', start, 'temporary_failure', `dns lookup temporarily failed`, {
287
+ hostname,
288
+ code,
289
+ });
290
+ }
291
+ return fail('dns', start, 'lookup_failed', errorMessage(err), {
292
+ hostname,
293
+ ...(code === undefined ? {} : { code }),
294
+ });
295
+ }
296
+ finally {
297
+ abortCtx.dispose();
298
+ }
299
+ };
300
+ // Production-only path: binds a real TCP socket via `node:net`. Unit
301
+ // tests inject a `tcpConnectImpl` seam; integration tests run
302
+ // `--no-probe`. Real-socket test would require an ephemeral
303
+ // localhost listener + a TCP server, brittle vs. the seam-injected
304
+ // per-failure-mode matrix that already covers every reason
305
+ // discriminant.
306
+ /* c8 ignore start */
307
+ const defaultTcpConnect = ({ host, port, signal }) => new Promise((resolve, reject) => {
308
+ const socket = createConnection({ host, port });
309
+ const cleanup = () => {
310
+ socket.removeAllListeners();
311
+ signal.removeEventListener('abort', onAbort);
312
+ socket.destroy();
313
+ };
314
+ const onAbort = () => {
315
+ cleanup();
316
+ reject(asError(signal.reason, 'tcp connect aborted'));
317
+ };
318
+ if (signal.aborted) {
319
+ cleanup();
320
+ reject(asError(signal.reason, 'tcp connect aborted'));
321
+ return;
322
+ }
323
+ signal.addEventListener('abort', onAbort, { once: true });
324
+ socket.once('connect', () => {
325
+ cleanup();
326
+ resolve();
327
+ });
328
+ socket.once('error', (err) => {
329
+ cleanup();
330
+ reject(err);
331
+ });
332
+ });
333
+ /* c8 ignore stop */
334
+ /**
335
+ * Opens a TCP connection to `inputs.hostname:inputs.port` (defaults
336
+ * {@link DEFAULT_PROBE_HOSTNAME} / {@link DEFAULT_PROBE_PORT}) via
337
+ * `node:net.createConnection` (or the injected seam). The socket is
338
+ * destroyed in every exit path; the per-probe deadline aborts the
339
+ * connection via the threaded signal.
340
+ */
341
+ export const runTcpProbe = async (inputs = {}) => {
342
+ const hostname = inputs.hostname ?? DEFAULT_PROBE_HOSTNAME;
343
+ const port = inputs.port ?? DEFAULT_PROBE_PORT;
344
+ const timeoutMs = inputs.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
345
+ // Production path; unit tests inject `tcpConnectImpl`.
346
+ /* c8 ignore next */
347
+ const tcpConnectImpl = inputs.tcpConnectImpl ?? defaultTcpConnect;
348
+ const start = Date.now();
349
+ const abortCtx = createProbeAbortContext('tcp', timeoutMs, inputs.signal);
350
+ try {
351
+ await tcpConnectImpl({ host: hostname, port, signal: abortCtx.signal });
352
+ return ok('tcp', start, { host: hostname, port });
353
+ }
354
+ catch (err) {
355
+ if (abortCtx.didTimeout()) {
356
+ return fail('tcp', start, 'timeout', `tcp connect to ${hostname}:${String(port)} timed out`, { host: hostname, port, timeout_ms: timeoutMs });
357
+ }
358
+ const code = errorCode(err);
359
+ if (code === 'ECONNREFUSED') {
360
+ return fail('tcp', start, 'connection_refused', errorMessage(err), {
361
+ host: hostname,
362
+ port,
363
+ code,
364
+ });
365
+ }
366
+ if (code === 'ECONNRESET') {
367
+ return fail('tcp', start, 'connection_reset', errorMessage(err), {
368
+ host: hostname,
369
+ port,
370
+ code,
371
+ });
372
+ }
373
+ if (code === 'ETIMEDOUT') {
374
+ return fail('tcp', start, 'timeout', errorMessage(err), {
375
+ host: hostname,
376
+ port,
377
+ code,
378
+ timeout_ms: timeoutMs,
379
+ });
380
+ }
381
+ return fail('tcp', start, 'connection_failed', errorMessage(err), {
382
+ host: hostname,
383
+ port,
384
+ ...(code === undefined ? {} : { code }),
385
+ });
386
+ }
387
+ finally {
388
+ abortCtx.dispose();
389
+ }
390
+ };
391
+ // Production-only path: binds a real TLS socket via `node:tls`. Unit
392
+ // tests inject a `tlsConnectImpl` seam; integration tests under
393
+ // `--no-probe` skip this path. A real-cert test would require a
394
+ // disposable TLS server with a self-signed cert, brittle vs. the
395
+ // seam-injected per-failure-mode coverage (cert_expired,
396
+ // cert_untrusted, cert_name_mismatch, etc.).
397
+ /* c8 ignore start */
398
+ const defaultTlsConnect = ({ host, port, signal }) => new Promise((resolve, reject) => {
399
+ const socket = tlsConnect({
400
+ host,
401
+ port,
402
+ servername: host,
403
+ rejectUnauthorized: true,
404
+ });
405
+ const cleanup = () => {
406
+ socket.removeAllListeners();
407
+ signal.removeEventListener('abort', onAbort);
408
+ socket.destroy();
409
+ };
410
+ const onAbort = () => {
411
+ cleanup();
412
+ reject(asError(signal.reason, 'tls handshake aborted'));
413
+ };
414
+ if (signal.aborted) {
415
+ cleanup();
416
+ reject(asError(signal.reason, 'tls handshake aborted'));
417
+ return;
418
+ }
419
+ signal.addEventListener('abort', onAbort, { once: true });
420
+ socket.once('secureConnect', () => {
421
+ const cert = socket.getPeerCertificate();
422
+ cleanup();
423
+ // Node's `getPeerCertificate()` types `subject`/`issuer` as
424
+ // required objects, but the runtime can return an empty `{}`
425
+ // when the peer didn't send a cert (which `rejectUnauthorized`
426
+ // would reject anyway). Narrow defensively via typeof.
427
+ const subjectCn = cert.subject?.CN;
428
+ const issuerCn = cert.issuer?.CN;
429
+ const subject = typeof subjectCn === 'string' && subjectCn.length > 0 ? subjectCn : '<unknown>';
430
+ const issuer = typeof issuerCn === 'string' && issuerCn.length > 0 ? issuerCn : '<unknown>';
431
+ const validTo = typeof cert.valid_to === 'string' ? cert.valid_to : '<unknown>';
432
+ resolve({ subject, issuer, valid_to: validTo });
433
+ });
434
+ socket.once('error', (err) => {
435
+ cleanup();
436
+ reject(err);
437
+ });
438
+ });
439
+ /* c8 ignore stop */
440
+ /**
441
+ * Completes a TLS handshake against `inputs.hostname:inputs.port`
442
+ * with SNI set + cert validation on. Captures the peer cert summary
443
+ * (`subject`/`issuer`/`valid_to`) into `details` on success; maps
444
+ * `CERT_HAS_EXPIRED` → `cert_expired`, `UNABLE_TO_VERIFY_LEAF_SIGNATURE`
445
+ * → `cert_untrusted`, `ERR_TLS_CERT_ALTNAME_INVALID` →
446
+ * `cert_name_mismatch`, anything else → `tls_handshake_failed`.
447
+ */
448
+ export const runTlsProbe = async (inputs = {}) => {
449
+ const hostname = inputs.hostname ?? DEFAULT_PROBE_HOSTNAME;
450
+ const port = inputs.port ?? DEFAULT_PROBE_PORT;
451
+ const timeoutMs = inputs.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
452
+ // Production path; unit tests inject `tlsConnectImpl`.
453
+ /* c8 ignore next */
454
+ const tlsConnectImpl = inputs.tlsConnectImpl ?? defaultTlsConnect;
455
+ const start = Date.now();
456
+ const abortCtx = createProbeAbortContext('tls', timeoutMs, inputs.signal);
457
+ try {
458
+ const cert = await tlsConnectImpl({
459
+ host: hostname,
460
+ port,
461
+ signal: abortCtx.signal,
462
+ });
463
+ return ok('tls', start, {
464
+ subject: cert.subject,
465
+ issuer: cert.issuer,
466
+ valid_to: cert.valid_to,
467
+ });
468
+ }
469
+ catch (err) {
470
+ if (abortCtx.didTimeout()) {
471
+ return fail('tls', start, 'timeout', `tls handshake to ${hostname} timed out`, {
472
+ host: hostname,
473
+ port,
474
+ timeout_ms: timeoutMs,
475
+ });
476
+ }
477
+ const code = errorCode(err);
478
+ if (code === 'CERT_HAS_EXPIRED') {
479
+ return fail('tls', start, 'cert_expired', errorMessage(err), {
480
+ host: hostname,
481
+ port,
482
+ code,
483
+ });
484
+ }
485
+ if (code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {
486
+ return fail('tls', start, 'cert_untrusted', errorMessage(err), {
487
+ host: hostname,
488
+ port,
489
+ code,
490
+ });
491
+ }
492
+ if (code === 'ERR_TLS_CERT_ALTNAME_INVALID') {
493
+ return fail('tls', start, 'cert_name_mismatch', errorMessage(err), {
494
+ host: hostname,
495
+ port,
496
+ code,
497
+ });
498
+ }
499
+ return fail('tls', start, 'tls_handshake_failed', errorMessage(err), {
500
+ host: hostname,
501
+ port,
502
+ ...(code === undefined ? {} : { code }),
503
+ });
504
+ }
505
+ finally {
506
+ abortCtx.dispose();
507
+ }
508
+ };
509
+ /**
510
+ * Issues `query { me { id } }` against the supplied transport. Maps
511
+ * the empirical-probe-confirmed 401 envelope to `unauthorized`;
512
+ * 5xx HTTP status / transport failures (DNS recovery, TCP reset, TLS
513
+ * handshake error mid-flight) to `network_error` per cli-design
514
+ * §11.5.1's per-probe error-code table.
515
+ *
516
+ * The probe's contract is "can we authenticate?", not "can we
517
+ * complete a request budget-wise?". A `complexity_exceeded` from
518
+ * `me { id }` would mean the budget is pathological; the auth probe
519
+ * surfaces it as `auth_failed` rather than mapping into the §11.5.1
520
+ * table's two reasons, so the verb-level envelope reads cleanly.
521
+ */
522
+ export const runAuthProbe = async (inputs) => {
523
+ const timeoutMs = inputs.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
524
+ const start = Date.now();
525
+ const abortCtx = createProbeAbortContext('auth', timeoutMs, inputs.signal);
526
+ try {
527
+ const response = await inputs.transport.request({
528
+ query: 'query MondayStatusAuth { me { id } }',
529
+ operationName: 'MondayStatusAuth',
530
+ signal: abortCtx.signal,
531
+ });
532
+ if (response.status === 401) {
533
+ return fail('auth', start, 'unauthorized', 'Monday returned 401', {
534
+ http_status: 401,
535
+ });
536
+ }
537
+ if (response.status >= 500) {
538
+ return fail('auth', start, 'network_error', `Monday returned HTTP ${String(response.status)}`, { http_status: response.status });
539
+ }
540
+ if (response.status !== 200) {
541
+ return fail('auth', start, 'network_error', `unexpected HTTP status ${String(response.status)} from auth probe`, { http_status: response.status });
542
+ }
543
+ const body = response.body;
544
+ if (typeof body !== 'object' || body === null) {
545
+ return fail('auth', start, 'network_error', 'auth probe response was not a JSON object', { http_status: response.status });
546
+ }
547
+ const bodyRecord = body;
548
+ const errorsField = bodyRecord.errors;
549
+ if (Array.isArray(errorsField) && errorsField.length > 0) {
550
+ // §11.5.1 unauthorized-mapping is "any errors[] entry carries
551
+ // an auth code", not "the first entry". Scan every entry so a
552
+ // mixed-error response (e.g., complexity warning followed by
553
+ // an auth-token expiration) still maps to `unauthorized` — the
554
+ // security-bearing reading wins over the first-error read.
555
+ // Codex M22 W2 ratified.
556
+ const extractCode = (entry) => {
557
+ if (typeof entry !== 'object' || entry === null)
558
+ return undefined;
559
+ const ext = entry.extensions;
560
+ if (typeof ext !== 'object' || ext === null)
561
+ return undefined;
562
+ const code = ext.code;
563
+ return typeof code === 'string' ? code : undefined;
564
+ };
565
+ const extractMessage = (entry) => {
566
+ if (typeof entry !== 'object' || entry === null)
567
+ return undefined;
568
+ const m = entry.message;
569
+ return typeof m === 'string' ? m : undefined;
570
+ };
571
+ const errorsList = errorsField;
572
+ const authEntry = errorsList.find((e) => {
573
+ const code = extractCode(e);
574
+ return code === 'NOT_AUTHENTICATED' || code === 'UNAUTHENTICATED';
575
+ });
576
+ if (authEntry !== undefined) {
577
+ const code = extractCode(authEntry);
578
+ const msg = extractMessage(authEntry) ?? 'auth probe rejected';
579
+ return fail('auth', start, 'unauthorized', msg, {
580
+ http_status: response.status,
581
+ monday_code: code,
582
+ });
583
+ }
584
+ const first = errorsList[0];
585
+ const firstCode = extractCode(first);
586
+ const firstMsg = extractMessage(first) ?? 'auth probe rejected';
587
+ return fail('auth', start, 'auth_failed', firstMsg, {
588
+ http_status: response.status,
589
+ ...(firstCode === undefined ? {} : { monday_code: firstCode }),
590
+ });
591
+ }
592
+ const data = bodyRecord.data;
593
+ /* c8 ignore next 9 — defensive: Monday's GraphQL surface always
594
+ returns `data: {...}` on a 200, and the errors[] branch above
595
+ handles the `data: null` case. This guard exists for hypothetical
596
+ transport shapes that 200-without-data; not reproducible from
597
+ a fixture cassette that returns a valid GraphQL envelope. */
598
+ if (typeof data !== 'object' || data === null) {
599
+ return fail('auth', start, 'network_error', 'auth probe response missing `data`', { http_status: response.status });
600
+ }
601
+ const me = data.me;
602
+ if (typeof me !== 'object' || me === null) {
603
+ return fail('auth', start, 'unauthorized', 'auth probe returned null `me`', {
604
+ http_status: response.status,
605
+ });
606
+ }
607
+ const meId = me.id;
608
+ if (typeof meId !== 'string' || meId.length === 0) {
609
+ return fail('auth', start, 'network_error', 'auth probe response had unexpected `me` shape', { http_status: response.status });
610
+ }
611
+ const details = { me_id: meId };
612
+ if (inputs.apiVersionHint !== undefined) {
613
+ details.api_version = inputs.apiVersionHint;
614
+ }
615
+ return ok('auth', start, details);
616
+ }
617
+ catch (err) {
618
+ if (abortCtx.didTimeout()) {
619
+ return fail('auth', start, 'timeout', 'auth probe timed out', {
620
+ timeout_ms: timeoutMs,
621
+ });
622
+ }
623
+ if (err instanceof ApiError) {
624
+ if (err.code === 'unauthorized') {
625
+ return fail('auth', start, 'unauthorized', err.message, {
626
+ http_status: err.httpStatus ?? 401,
627
+ });
628
+ }
629
+ return fail('auth', start, 'network_error', err.message, {
630
+ ...(err.httpStatus === undefined ? {} : { http_status: err.httpStatus }),
631
+ error_code: err.code,
632
+ });
633
+ }
634
+ return fail('auth', start, 'network_error', errorMessage(err), {});
635
+ }
636
+ finally {
637
+ abortCtx.dispose();
638
+ }
639
+ };
640
+ /**
641
+ * Verifies the local cache directory (`<HOME>/.monday-cli/`) exists,
642
+ * is mode `0700`, and is writable. Stat + access(W_OK) + probe-write
643
+ * (`<dir>/.probe-<rand>`) → delete dance — `access(W_OK)` is advisory
644
+ * on some Unix filesystems, so a probe-write confirms true writability.
645
+ */
646
+ export const runCacheWritabilityProbe = async (inputs) => {
647
+ const home = inputs.home ?? inputs.env.HOME ?? homedir();
648
+ const cacheDir = join(home, CACHE_DIR_NAME);
649
+ const start = Date.now();
650
+ let stats;
651
+ try {
652
+ stats = await stat(cacheDir);
653
+ }
654
+ catch (err) {
655
+ if (isENOENT(err)) {
656
+ return fail('cache_writability', start, 'dir_missing', `cache directory ${cacheDir} does not exist`, {
657
+ path: cacheDir,
658
+ hint: 'run `monday auth login --profile <name>` or any cache-writing command to create it',
659
+ });
660
+ }
661
+ // Non-ENOENT stat failures (EACCES on the parent dir, etc.) aren't
662
+ // reproducible without root or chroot; ENOENT is the only failure
663
+ // mode tests can drive against a tmp dir.
664
+ /* c8 ignore start */
665
+ return fail('cache_writability', start, 'stat_failed', `cannot stat cache directory ${cacheDir}: ${errorMessage(err)}`, { path: cacheDir });
666
+ /* c8 ignore stop */
667
+ }
668
+ if (!stats.isDirectory()) {
669
+ return fail('cache_writability', start, 'not_a_directory', `cache path ${cacheDir} is not a directory`, { path: cacheDir });
670
+ }
671
+ if ((stats.mode & CACHE_DIR_REQUIRED_MODE_BITS) !== 0) {
672
+ return fail('cache_writability', start, 'mode_insecure', `cache directory ${cacheDir} has insecure permissions ${formatMode(stats.mode)}`, {
673
+ path: cacheDir,
674
+ mode: formatMode(stats.mode),
675
+ hint: `run \`chmod 700 ${cacheDir}\` to tighten`,
676
+ });
677
+ }
678
+ try {
679
+ await access(cacheDir, fsConstants.W_OK);
680
+ }
681
+ catch (err) {
682
+ // access(W_OK) failure requires the dir to exist but be non-writable
683
+ // — needs root + ownership manipulation to reproduce against a
684
+ // tmp dir owned by the test user. Production-only.
685
+ /* c8 ignore start */
686
+ return fail('cache_writability', start, 'permission_denied', `cache directory ${cacheDir} is not writable: ${errorMessage(err)}`, { path: cacheDir, mode: formatMode(stats.mode) });
687
+ /* c8 ignore stop */
688
+ }
689
+ const probeFile = join(cacheDir, `.probe-${randomUUID()}`);
690
+ try {
691
+ await writeFile(probeFile, '', { mode: 0o600 });
692
+ }
693
+ catch (err) {
694
+ // writeFile failure when access(W_OK) succeeded is a TOCTOU race
695
+ // (between the access check and the write), filesystem-full, or
696
+ // similar runtime-rare condition. Production-only.
697
+ return fail('cache_writability', start, 'write_failed', `probe write to ${cacheDir} failed: ${errorMessage(err)}`, { path: cacheDir, mode: formatMode(stats.mode) });
698
+ /* c8 ignore stop */
699
+ }
700
+ // Best-effort cleanup; if unlink fails we still succeed because the
701
+ // write succeeded — a leaked probe file is harmless.
702
+ await unlink(probeFile).catch(() => undefined);
703
+ return ok('cache_writability', start, {
704
+ path: cacheDir,
705
+ mode: formatMode(stats.mode),
706
+ });
707
+ };
708
+ /**
709
+ * Folds {@link REDACTION_SELF_TEST_FIXTURE_TOKEN} into
710
+ * `inputs.runtimeSecrets`, runs a sample object (carrying the
711
+ * canary in `error.message`, `error.stack`, a nested
712
+ * `error.cause.message`, a URL, and a lowercase
713
+ * `authorization` header value, plus a mixed-content debug string)
714
+ * through `redact()` with `collectSecrets(env, runtimeSecrets)`, and
715
+ * asserts the canary is absent from every byte of the redacted
716
+ * output. Removes the canary from `runtimeSecrets` before returning
717
+ * so the caller's state is unchanged.
718
+ *
719
+ * Failure here indicates a regression in the redaction layer
720
+ * itself (a serious bug); the probe surfaces `canary_leaked` with
721
+ * `details.contexts_leaked` listing which §7.4.3 enumerated
722
+ * carrier paths still hold the canary.
723
+ */
724
+ export const runRedactionSelfTest = (inputs) => Promise.resolve(runRedactionSelfTestSync(inputs));
725
+ const runRedactionSelfTestSync = (inputs) => {
726
+ const start = Date.now();
727
+ const canary = REDACTION_SELF_TEST_FIXTURE_TOKEN;
728
+ // Production path; the leak-path test injects a tampered redactor.
729
+ /* c8 ignore next */
730
+ const redactImpl = inputs.redactImpl ?? defaultRedactImpl;
731
+ inputs.runtimeSecrets.push(canary);
732
+ try {
733
+ const innerError = new Error(`inner failure carrying ${canary}`);
734
+ const outerError = new Error(`outer failure carrying ${canary}`);
735
+ outerError.cause = innerError;
736
+ const sample = {
737
+ error: {
738
+ message: outerError.message,
739
+ // `Error.stack` is always populated under V8; the fallback is a
740
+ // defensive guard for embedders with custom error constructors.
741
+ /* c8 ignore next */
742
+ stack: outerError.stack ?? '',
743
+ cause: {
744
+ message: innerError.message,
745
+ },
746
+ },
747
+ headers: {
748
+ authorization: canary,
749
+ },
750
+ url: `https://api.monday.com/v2?bogus=${canary}`,
751
+ debug: `auth=${canary} expired`,
752
+ };
753
+ const redacted = redactImpl(sample, {
754
+ secrets: collectSecrets(inputs.env, inputs.runtimeSecrets),
755
+ });
756
+ const serialised = JSON.stringify(redacted);
757
+ if (serialised.includes(canary)) {
758
+ const leakedContexts = [];
759
+ const redactedRecord = redacted;
760
+ const stringAt = (path) => {
761
+ let cur = redactedRecord;
762
+ for (const segment of path) {
763
+ /* c8 ignore next — defensive: paths into the fixture-built
764
+ sample object are always traversable when the redactor is
765
+ identity-mapped; non-object hops only happen when a
766
+ future redactor materially changes the shape. */
767
+ if (typeof cur !== 'object' || cur === null)
768
+ return undefined;
769
+ cur = cur[segment];
770
+ }
771
+ /* c8 ignore next — fixture leaves canary as a string at every
772
+ path; non-string terminals only appear via a rewriting
773
+ redactor. */
774
+ return typeof cur === 'string' ? cur : undefined;
775
+ };
776
+ const checks = [
777
+ { key: 'error.message', path: ['error', 'message'] },
778
+ { key: 'error.stack', path: ['error', 'stack'] },
779
+ { key: 'error.cause.message', path: ['error', 'cause', 'message'] },
780
+ { key: 'headers.authorization', path: ['headers', 'authorization'] },
781
+ { key: 'url', path: ['url'] },
782
+ { key: 'debug', path: ['debug'] },
783
+ ];
784
+ for (const check of checks) {
785
+ const value = stringAt(check.path);
786
+ /* c8 ignore next — `value?.includes(canary)` short-circuits
787
+ on `value === undefined`; defensive false-arm. */
788
+ if (value?.includes(canary) === true) {
789
+ leakedContexts.push(check.key);
790
+ }
791
+ }
792
+ return fail('redaction_self_test', start, 'canary_leaked', 'redaction self-test canary leaked through redact()', {
793
+ fixture_count: REDACTION_LEAK_CONTEXT_KEYS.length,
794
+ contexts_leaked: leakedContexts,
795
+ });
796
+ }
797
+ return ok('redaction_self_test', start, {
798
+ fixture_count: REDACTION_LEAK_CONTEXT_KEYS.length,
799
+ });
800
+ }
801
+ finally {
802
+ const idx = inputs.runtimeSecrets.lastIndexOf(canary);
803
+ // Defensive: we just pushed the canary at the top of the try; the
804
+ // only way idx === -1 is if the test removed it mid-call (which
805
+ // it doesn't). Kept defensive so the splice is safe.
806
+ /* c8 ignore next */
807
+ if (idx !== -1) {
808
+ inputs.runtimeSecrets.splice(idx, 1);
809
+ }
810
+ }
811
+ };
812
+ /**
813
+ * Summarises which of {@link ENV_VAR_PICKUP_KEYS} are set on
814
+ * `inputs.env`. **Values are NEVER included** — an env var's value
815
+ * is potentially a token. Wrapped in a Promise so callers can
816
+ * `Promise.allSettled` the full matrix without special-casing this
817
+ * step.
818
+ */
819
+ export const summariseEnvVarPickup = (inputs) => {
820
+ const start = Date.now();
821
+ const set = {};
822
+ for (const key of ENV_VAR_PICKUP_KEYS) {
823
+ const value = inputs.env[key];
824
+ set[key] = value !== undefined && value.length > 0;
825
+ }
826
+ return Promise.resolve(ok('env_var_pickup', start, { set }));
827
+ };
828
+ /**
829
+ * Schema validating an individual probe result for the
830
+ * `monday status` envelope. Mirrors the runtime
831
+ * {@link ProbeResult} union so the envelope is parse-safe at every
832
+ * emission path (in particular `monday schema` introspection).
833
+ */
834
+ export const probeResultSchema = z.discriminatedUnion('kind', [
835
+ z.object({
836
+ kind: z.literal('ok'),
837
+ probe: z.string().min(1),
838
+ elapsed_ms: z.number().nonnegative(),
839
+ details: z.record(z.string(), z.unknown()),
840
+ }),
841
+ z.object({
842
+ kind: z.literal('fail'),
843
+ probe: z.string().min(1),
844
+ elapsed_ms: z.number().nonnegative(),
845
+ reason: z.string().min(1),
846
+ message: z.string().min(1),
847
+ details: z.record(z.string(), z.unknown()),
848
+ }),
849
+ z.object({
850
+ kind: z.literal('skipped'),
851
+ probe: z.string().min(1),
852
+ reason: z.string().min(1),
853
+ }),
854
+ ]);
855
+ /**
856
+ * Top-level `monday status` envelope-data schema. `probes` requires
857
+ * every {@link STATUS_PROBE_ORDER} entry to be populated (default
858
+ * run AND `--no-probe` run — `--no-probe` emits `ProbeSkipped` slots
859
+ * for the four network probes; local probes still produce real
860
+ * entries). Catchall allows additive future probes (per cli-design
861
+ * §6.1) WITHOUT a schema-version bump; missing-slot drift gets
862
+ * caught at parse time.
863
+ */
864
+ export const statusOutputSchema = z
865
+ .object({
866
+ probes: z
867
+ .object({
868
+ dns: probeResultSchema,
869
+ tcp: probeResultSchema,
870
+ tls: probeResultSchema,
871
+ auth: probeResultSchema,
872
+ cache_writability: probeResultSchema,
873
+ redaction_self_test: probeResultSchema,
874
+ env_var_pickup: probeResultSchema,
875
+ })
876
+ .catchall(probeResultSchema),
877
+ overall: z.enum(['ok', 'degraded', 'down']),
878
+ api_version: z.string().min(1),
879
+ })
880
+ .strict();
881
+ //# sourceMappingURL=probes.js.map