monday-cli 0.3.0 → 0.5.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 (198) hide show
  1. package/CHANGELOG.md +719 -0
  2. package/README.md +208 -36
  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/column-types.d.ts +13 -7
  8. package/dist/api/column-types.d.ts.map +1 -1
  9. package/dist/api/column-types.js +7 -3
  10. package/dist/api/column-types.js.map +1 -1
  11. package/dist/api/column-values.d.ts +8 -1
  12. package/dist/api/column-values.d.ts.map +1 -1
  13. package/dist/api/column-values.js +16 -6
  14. package/dist/api/column-values.js.map +1 -1
  15. package/dist/api/documents.d.ts +1652 -0
  16. package/dist/api/documents.d.ts.map +1 -0
  17. package/dist/api/documents.js +2411 -0
  18. package/dist/api/documents.js.map +1 -0
  19. package/dist/api/item-watch.d.ts +263 -0
  20. package/dist/api/item-watch.d.ts.map +1 -0
  21. package/dist/api/item-watch.js +709 -0
  22. package/dist/api/item-watch.js.map +1 -0
  23. package/dist/api/multipart-transport.d.ts +223 -0
  24. package/dist/api/multipart-transport.d.ts.map +1 -0
  25. package/dist/api/multipart-transport.js +274 -0
  26. package/dist/api/multipart-transport.js.map +1 -0
  27. package/dist/api/parallel-dispatch.d.ts +155 -0
  28. package/dist/api/parallel-dispatch.d.ts.map +1 -0
  29. package/dist/api/parallel-dispatch.js +243 -0
  30. package/dist/api/parallel-dispatch.js.map +1 -0
  31. package/dist/api/partial-success-bulk.d.ts +118 -60
  32. package/dist/api/partial-success-bulk.d.ts.map +1 -1
  33. package/dist/api/partial-success-bulk.js +137 -79
  34. package/dist/api/partial-success-bulk.js.map +1 -1
  35. package/dist/api/partial-success-mutation.d.ts +13 -1
  36. package/dist/api/partial-success-mutation.d.ts.map +1 -1
  37. package/dist/api/partial-success-mutation.js +5 -1
  38. package/dist/api/partial-success-mutation.js.map +1 -1
  39. package/dist/api/raw-write.d.ts +13 -4
  40. package/dist/api/raw-write.d.ts.map +1 -1
  41. package/dist/api/raw-write.js +22 -11
  42. package/dist/api/raw-write.js.map +1 -1
  43. package/dist/api/resolve-client.d.ts +11 -0
  44. package/dist/api/resolve-client.d.ts.map +1 -1
  45. package/dist/api/resolve-client.js +9 -1
  46. package/dist/api/resolve-client.js.map +1 -1
  47. package/dist/api/teams.d.ts +657 -0
  48. package/dist/api/teams.d.ts.map +1 -0
  49. package/dist/api/teams.js +880 -0
  50. package/dist/api/teams.js.map +1 -0
  51. package/dist/cli/run.d.ts +20 -0
  52. package/dist/cli/run.d.ts.map +1 -1
  53. package/dist/cli/run.js +1 -0
  54. package/dist/cli/run.js.map +1 -1
  55. package/dist/commands/board/column-create.d.ts +6 -5
  56. package/dist/commands/board/column-create.d.ts.map +1 -1
  57. package/dist/commands/board/column-create.js +9 -6
  58. package/dist/commands/board/column-create.js.map +1 -1
  59. package/dist/commands/completion.d.ts +188 -0
  60. package/dist/commands/completion.d.ts.map +1 -0
  61. package/dist/commands/completion.js +418 -0
  62. package/dist/commands/completion.js.map +1 -0
  63. package/dist/commands/doc/append-markdown.d.ts +117 -0
  64. package/dist/commands/doc/append-markdown.d.ts.map +1 -0
  65. package/dist/commands/doc/append-markdown.js +253 -0
  66. package/dist/commands/doc/append-markdown.js.map +1 -0
  67. package/dist/commands/doc/block-create.d.ts +114 -0
  68. package/dist/commands/doc/block-create.d.ts.map +1 -0
  69. package/dist/commands/doc/block-create.js +206 -0
  70. package/dist/commands/doc/block-create.js.map +1 -0
  71. package/dist/commands/doc/block-delete.d.ts +72 -0
  72. package/dist/commands/doc/block-delete.d.ts.map +1 -0
  73. package/dist/commands/doc/block-delete.js +161 -0
  74. package/dist/commands/doc/block-delete.js.map +1 -0
  75. package/dist/commands/doc/block-update.d.ts +75 -0
  76. package/dist/commands/doc/block-update.d.ts.map +1 -0
  77. package/dist/commands/doc/block-update.js +162 -0
  78. package/dist/commands/doc/block-update.js.map +1 -0
  79. package/dist/commands/doc/create-in-workspace.d.ts +76 -0
  80. package/dist/commands/doc/create-in-workspace.d.ts.map +1 -0
  81. package/dist/commands/doc/create-in-workspace.js +164 -0
  82. package/dist/commands/doc/create-in-workspace.js.map +1 -0
  83. package/dist/commands/doc/create-on-column.d.ts +71 -0
  84. package/dist/commands/doc/create-on-column.d.ts.map +1 -0
  85. package/dist/commands/doc/create-on-column.js +146 -0
  86. package/dist/commands/doc/create-on-column.js.map +1 -0
  87. package/dist/commands/doc/delete.d.ts +68 -0
  88. package/dist/commands/doc/delete.d.ts.map +1 -0
  89. package/dist/commands/doc/delete.js +146 -0
  90. package/dist/commands/doc/delete.js.map +1 -0
  91. package/dist/commands/doc/duplicate.d.ts +101 -0
  92. package/dist/commands/doc/duplicate.d.ts.map +1 -0
  93. package/dist/commands/doc/duplicate.js +191 -0
  94. package/dist/commands/doc/duplicate.js.map +1 -0
  95. package/dist/commands/doc/get.d.ts +46 -0
  96. package/dist/commands/doc/get.d.ts.map +1 -0
  97. package/dist/commands/doc/get.js +95 -0
  98. package/dist/commands/doc/get.js.map +1 -0
  99. package/dist/commands/doc/import-html.d.ts +125 -0
  100. package/dist/commands/doc/import-html.d.ts.map +1 -0
  101. package/dist/commands/doc/import-html.js +273 -0
  102. package/dist/commands/doc/import-html.js.map +1 -0
  103. package/dist/commands/doc/list.d.ts +86 -0
  104. package/dist/commands/doc/list.d.ts.map +1 -0
  105. package/dist/commands/doc/list.js +217 -0
  106. package/dist/commands/doc/list.js.map +1 -0
  107. package/dist/commands/doc/rename.d.ts +60 -0
  108. package/dist/commands/doc/rename.d.ts.map +1 -0
  109. package/dist/commands/doc/rename.js +135 -0
  110. package/dist/commands/doc/rename.js.map +1 -0
  111. package/dist/commands/index.d.ts.map +1 -1
  112. package/dist/commands/index.js +162 -0
  113. package/dist/commands/index.js.map +1 -1
  114. package/dist/commands/item/create.js +2 -2
  115. package/dist/commands/item/update.d.ts +1 -0
  116. package/dist/commands/item/update.d.ts.map +1 -1
  117. package/dist/commands/item/update.js +61 -0
  118. package/dist/commands/item/update.js.map +1 -1
  119. package/dist/commands/item/upload.d.ts +108 -0
  120. package/dist/commands/item/upload.d.ts.map +1 -0
  121. package/dist/commands/item/upload.js +370 -0
  122. package/dist/commands/item/upload.js.map +1 -0
  123. package/dist/commands/item/watch.d.ts +90 -0
  124. package/dist/commands/item/watch.d.ts.map +1 -0
  125. package/dist/commands/item/watch.js +342 -0
  126. package/dist/commands/item/watch.js.map +1 -0
  127. package/dist/commands/update/create.d.ts.map +1 -1
  128. package/dist/commands/update/create.js +6 -4
  129. package/dist/commands/update/create.js.map +1 -1
  130. package/dist/commands/update/edit.d.ts +4 -2
  131. package/dist/commands/update/edit.d.ts.map +1 -1
  132. package/dist/commands/update/edit.js +10 -6
  133. package/dist/commands/update/edit.js.map +1 -1
  134. package/dist/commands/update/reply.d.ts +4 -2
  135. package/dist/commands/update/reply.d.ts.map +1 -1
  136. package/dist/commands/update/reply.js +10 -6
  137. package/dist/commands/update/reply.js.map +1 -1
  138. package/dist/commands/update/upload.d.ts +69 -0
  139. package/dist/commands/update/upload.d.ts.map +1 -0
  140. package/dist/commands/update/upload.js +235 -0
  141. package/dist/commands/update/upload.js.map +1 -0
  142. package/dist/commands/user/_team-membership.d.ts +10 -0
  143. package/dist/commands/user/_team-membership.d.ts.map +1 -0
  144. package/dist/commands/user/_team-membership.js +88 -0
  145. package/dist/commands/user/_team-membership.js.map +1 -0
  146. package/dist/commands/user/team-add-members.d.ts +81 -0
  147. package/dist/commands/user/team-add-members.d.ts.map +1 -0
  148. package/dist/commands/user/team-add-members.js +186 -0
  149. package/dist/commands/user/team-add-members.js.map +1 -0
  150. package/dist/commands/user/team-create.d.ts +82 -0
  151. package/dist/commands/user/team-create.d.ts.map +1 -0
  152. package/dist/commands/user/team-create.js +206 -0
  153. package/dist/commands/user/team-create.js.map +1 -0
  154. package/dist/commands/user/team-delete.d.ts +56 -0
  155. package/dist/commands/user/team-delete.d.ts.map +1 -0
  156. package/dist/commands/user/team-delete.js +137 -0
  157. package/dist/commands/user/team-delete.js.map +1 -0
  158. package/dist/commands/user/team-get.d.ts +41 -0
  159. package/dist/commands/user/team-get.d.ts.map +1 -0
  160. package/dist/commands/user/team-get.js +87 -0
  161. package/dist/commands/user/team-get.js.map +1 -0
  162. package/dist/commands/user/team-list.d.ts +39 -0
  163. package/dist/commands/user/team-list.d.ts.map +1 -0
  164. package/dist/commands/user/team-list.js +90 -0
  165. package/dist/commands/user/team-list.js.map +1 -0
  166. package/dist/commands/user/team-remove-members.d.ts +71 -0
  167. package/dist/commands/user/team-remove-members.d.ts.map +1 -0
  168. package/dist/commands/user/team-remove-members.js +176 -0
  169. package/dist/commands/user/team-remove-members.js.map +1 -0
  170. package/dist/types/ids.d.ts +8 -0
  171. package/dist/types/ids.d.ts.map +1 -1
  172. package/dist/types/ids.js +53 -5
  173. package/dist/types/ids.js.map +1 -1
  174. package/dist/utils/mime.d.ts +24 -0
  175. package/dist/utils/mime.d.ts.map +1 -0
  176. package/dist/utils/mime.js +64 -0
  177. package/dist/utils/mime.js.map +1 -0
  178. package/dist/utils/output/envelope.d.ts +30 -0
  179. package/dist/utils/output/envelope.d.ts.map +1 -1
  180. package/dist/utils/output/envelope.js +26 -0
  181. package/dist/utils/output/envelope.js.map +1 -1
  182. package/dist/utils/output/ndjson.d.ts +25 -0
  183. package/dist/utils/output/ndjson.d.ts.map +1 -1
  184. package/dist/utils/output/ndjson.js +12 -0
  185. package/dist/utils/output/ndjson.js.map +1 -1
  186. package/dist/utils/parse-brand-list.d.ts +95 -0
  187. package/dist/utils/parse-brand-list.d.ts.map +1 -0
  188. package/dist/utils/parse-brand-list.js +96 -0
  189. package/dist/utils/parse-brand-list.js.map +1 -0
  190. package/dist/utils/signal.d.ts +42 -0
  191. package/dist/utils/signal.d.ts.map +1 -0
  192. package/dist/utils/signal.js +45 -0
  193. package/dist/utils/signal.js.map +1 -0
  194. package/dist/utils/source-content.d.ts +93 -0
  195. package/dist/utils/source-content.d.ts.map +1 -0
  196. package/dist/utils/source-content.js +120 -0
  197. package/dist/utils/source-content.js.map +1 -0
  198. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,725 @@ output envelope (`{ ok, data, meta, ... }`) and 29 stable error
7
7
  codes are part of the public contract — the SemVer rules in
8
8
  [`docs/cli-design.md`](./docs/cli-design.md) §6 govern bumps.
9
9
 
10
+ ## [0.5.0] - 2026-05-17 — Team writers + full Monday workdocs CRUD mutation surface
11
+
12
+ The "agents can write to teams + drive the full workdocs surface"
13
+ milestone — v0.4's read-only workdocs + asset-upload foundation
14
+ gains the six team-writer verbs deferred at the post-v0.4-M33
15
+ candidate-selection session and the full Monday workdocs CRUD
16
+ mutation surface deferred at v0.4-M32 D8 closure (10 new doc-
17
+ namespace verbs across doc-level + doc-block + doc-content-import
18
+ clusters). **16 new CLI verbs across 9 wire mutations.** **No
19
+ breaking changes vs `0.4.0` — every v0.5 surface is additive.**
20
+ Built incrementally across M34–M37.
21
+
22
+ ### Breaking changes vs `0.4.0`
23
+
24
+ **None.** Every command, error code, envelope key, and warning
25
+ shape shipped in v0.4.0 is preserved byte-for-byte. v0.5 only adds.
26
+
27
+ ### Surface
28
+
29
+ **~117 commands shipped (was ~101 in v0.4).** 16 new verbs.
30
+ The new noun namespaces are extensions of existing ones — no new
31
+ top-level noun lands at v0.5 (team writers extend `monday user`;
32
+ doc-level + doc-block + doc-content-import extend `monday doc`).
33
+
34
+ **Team writers (M34) — `monday user team-list/get/create/delete/
35
+ add-members/remove-members`.** Six new verbs closing the v0.4-M33
36
+ candidate-selection deferral. The two read verbs (`team-list` /
37
+ `team-get`) project Monday's `Team` shape (`id`, `name`, `picture_url`,
38
+ `users[]`, `owners[]`). The four mutations:
39
+
40
+ - `team-create --name <n> [--users <id>,...] [--guest-team]
41
+ [--allow-empty] [--dry-run]` — backed by `create_team`.
42
+ `--users` resolves to Monday `UserId` list at the parse boundary
43
+ via the new lifted `parseBrandedListArg<T>(raw, brandSchema,
44
+ options)` helper (R-NEW-70 shipped ahead-of-feat at M34
45
+ pre-flight — 4 consumers post-lift).
46
+ - `team-delete <tid> --yes [--dry-run]` — backed by `delete_team`.
47
+ The destructive verb in the cluster; `--yes` gate fires BEFORE
48
+ `resolveClient` per the M10 round-1 P2 invariant.
49
+ - `team-add-members <tid> --users <id>,... [--dry-run]` +
50
+ `team-remove-members <tid> --users <id>,...` — backed by
51
+ `change_team_memberships`. Monday's mutation returns
52
+ `failed_users` + `successful_users` lists (asymmetric — failed
53
+ users carry a User object but no per-user failure reason, so
54
+ the CLI surfaces a generic `membership_failed` message per
55
+ failed record). The new shared `_team-membership.ts:
56
+ projectMembershipResults` helper projects to the universal
57
+ §6.1 `data.results: [{user_id, ok, ...}]` shape with input-
58
+ order preserved + failed-bucket-priority discipline + an
59
+ `internal_error` surface for input users that land in neither
60
+ bucket (wire-shape regression defensive). Lifted at IMPL
61
+ kickoff as a 2-consumer inline lift mirroring M26b's
62
+ `_shared.ts:requireDevBoard` cadence.
63
+
64
+ `team-list` ships flat (Monday's `teams(...)` has no pagination
65
+ on the wire); the two-read-without-pagination shape mirrors
66
+ `monday user list`. The four mutations all surface `--dry-run`
67
+ for planned-change envelopes.
68
+
69
+ **Doc-level CRUD (M35) — `monday doc create-in-workspace/
70
+ create-on-column/rename/delete/duplicate`.** Five verbs, four
71
+ wire mutations (both create variants share `create_doc` per D7's
72
+ mutually-exclusive `board` vs `workspace` split):
73
+
74
+ - `create-in-workspace --workspace <wid> --name <n> [--folder
75
+ <fid>] [--kind public|private|share]` — creates a workspace-
76
+ level doc. Brand: new `DocFolderIdSchema` joins
77
+ `src/types/ids.ts` as the 11th numeric brand.
78
+ - `create-on-column --item <iid> --column <cid>` — creates a
79
+ column-level doc against an existing file-shaped column.
80
+ - `rename <did> --name <n>` — `update_doc_name`.
81
+ - `delete <did> --yes [--dry-run]` — `delete_doc`. Destructive
82
+ gate fires BEFORE `resolveClient` per the M10 invariant.
83
+ - `duplicate <did> [--with-updates] [--dry-run]` — `duplicate_doc`
84
+ (D8 closure dropped `--name <n>` because the wire side has no
85
+ rename slot on duplicate). `--with-updates` copies the source
86
+ doc's comments to the duplicate; new `extractDuplicateDocId`
87
+ helper defensively unwraps the opaque-JSON new-doc-id across
88
+ bare-string / number / record-with-`id` / `doc_id` /
89
+ `new_doc_id` shapes per D9 closure (Monday's `duplicate_doc`
90
+ returns a flat `{ doc_id, success: true }` projection with
91
+ `success` pinned literal-`true` because failure surfaces via
92
+ GraphQL `errors[]` upstream, NOT via a wire-side success flag).
93
+ `--dry-run` previews the planned change envelope without firing
94
+ the wire.
95
+
96
+ D7 / D8 / D9 closures pinned at pre-flight: D7 two CLI verbs over
97
+ one with placement choosers (mirrors v0.4-M31's `monday item
98
+ upload` / `monday update upload` split for the same multipart
99
+ wire path). D8 drops `--name <n>` from duplicate. D9 opaque-JSON
100
+ returns project to flat `{ doc_id, success: true }` per §6.1
101
+ single-record envelope.
102
+
103
+ **Doc-block CRUD (M36) — `monday doc block-create/block-update/
104
+ block-delete`.** Three verbs / three wire mutations. `--type
105
+ <DocBlockContentType>` takes one of 16 enum values (`normal_text`
106
+ / `large_title` / `medium_title` / `small_title` / `quote` /
107
+ `bulleted_list` / `numbered_list` / `check_list` / `code` /
108
+ `divider` / `image` / `video` / `file` / `table` / `layout` /
109
+ `column`) per D10 closure (unknown values reject at the parse
110
+ boundary with `usage_error.details.issues[]` carrying `{path:
111
+ 'type', message}`). `--content <json>` parses via the M27-lifted
112
+ `parseJsonArg` helper (4th + 5th consumers of the helper).
113
+ `block-create` accepts optional `--after <bid>` / `--parent <bid>`
114
+ positioning slots; `block-update` updates the named block's
115
+ content payload; `block-delete --yes` deletes the named block.
116
+ Per-type content payload shapes documented in `docs/output-
117
+ shapes.md` "Per-block content shapes" reference table — 7
118
+ cassette-pinned variants + 9 TBD / inferred variants awaiting
119
+ follow-up cassettes per D11 closure (per-variant payload-shape
120
+ deferral to IMPL cassettes — R-v0.5-NEW-15 watch-item supporting
121
+ instance 2 of 3 ahead of graduation).
122
+
123
+ `DocBlockIdSchema` brand uses `slugIdSchema` (non-empty-string
124
+ base; same shape as `ColumnId` / `GroupId`) because Monday's
125
+ `DocumentBlock.id` is wire `String!`, NOT `ID!` — load-bearing
126
+ distinction from `DocId`'s numeric brand. Snake_case wire arg
127
+ names (`doc_id` / `block_id` / `after_block_id` / `parent_block_id`)
128
+ — Monday's standard cadence, not a new R-NEW-41 supporting site.
129
+
130
+ **Doc-content import (M37) — `monday doc import-html/append-
131
+ markdown`.** Two verbs / two wire mutations. Bulk doc-content
132
+ import in a single wire round-trip (no per-block loop):
133
+
134
+ - `import-html --workspace <wid> (--html <file|-> | --html-string
135
+ <s>) [--folder <fid>] [--kind public|private|share] [--title
136
+ <t>]` — creates a new doc from an HTML payload.
137
+ - `append-markdown <did> (--markdown <file|-> | --markdown-string
138
+ <s>) [--after <bid>]` — appends blocks to an existing doc from
139
+ a markdown payload.
140
+
141
+ Both surface mutex argv sources (file / stdin / inline string)
142
+ backed by the new generic `readSourceContent` helper at
143
+ `src/utils/source-content.ts` (R-v0.5-NEW-18 lifted ahead-of-
144
+ feat at M37 IMPL — widens M13's `readUpdateBody` to parameterise
145
+ on `inlineFlagName` / `fileFlagName` / `verbHint?` / `maxBytes?` /
146
+ `trimTrailingWhitespace?`; 5 consumers post-lift: 3 M13 update
147
+ verbs + 2 M37 doc verbs). 20 unit tests pin the helper's branch
148
+ matrix.
149
+
150
+ D12 closure pins the custom-OBJECT projection (5 branches):
151
+ success → flat envelope; `success: false + populated error` →
152
+ `validation_failed`; `success: false + empty/null error` →
153
+ `internal_error` (wire-regression hint); `success: true +
154
+ missing payload` → `internal_error` (probe descriptions promise
155
+ non-null); EMPTY `block_ids: []` on success → success WITH empty
156
+ array. D13 empirical-probe ran at M37 pre-flight kickoff
157
+ (`scripts/probe/v0.5-m37-size-limits.ts`, 2026-05-17, API
158
+ `2026-01`) + pinned the wire-side rejection threshold between
159
+ 250KB-OK and 500KB-rejected on both surfaces — rejection shape
160
+ is generic `INTERNAL_SERVER_ERROR` (NOT the documented
161
+ `{success: false, error}` envelope path), so the CLI pre-empts
162
+ at parse boundary via `MAX_DOC_IMPORT_PAYLOAD_BYTES = 256_000`
163
+ on the `.refine()` for inline `--html-string` / `--markdown-
164
+ string`.
165
+
166
+ ### Output contract additions
167
+
168
+ **No new stable error codes — registry stays at 29.** Every v0.5
169
+ milestone closed the new-error-code question NEGATIVE: M34
170
+ team mutations route per-user partial-success failures through
171
+ the generic `membership_failed` message (envelope-level per-record
172
+ discriminator, not a top-level code); M35 / M36 / M37 route
173
+ deletes through the existing `not_found`, validation failures
174
+ through the existing `validation_failed`, wire-shape regressions
175
+ through the existing `internal_error`, and parse-boundary
176
+ rejections through the existing `usage_error`.
177
+
178
+ **New per-record partial-success projection** (M34 —
179
+ `team-add-members` + `team-remove-members`). The
180
+ `change_team_memberships` wire mutation returns asymmetric
181
+ `failed_users` + `successful_users` lists; the shared
182
+ `_team-membership.ts:projectMembershipResults` helper projects
183
+ to the universal §6.1 `data.results: [{user_id, ok, ...}]`
184
+ shape with input-order preserved + failed-bucket-priority
185
+ discipline + an `internal_error` surface for input users that
186
+ land in neither bucket (wire-shape regression defensive).
187
+ Mirrors M13's `update clear-all` partial-success cadence but
188
+ with the wire-side asymmetry pinned in the projection.
189
+
190
+ **New custom-OBJECT 5-branch projection** (M37 — `import-html`
191
+ + `append-markdown`). Monday's two new mutations return a
192
+ custom `{success: bool, error?: string}` shape (NOT the
193
+ standard OBJECT-with-id pattern). The CLI projects through the
194
+ 5-branch dispatch pinned at D12 closure (success → flat
195
+ envelope; `success: false + populated error` →
196
+ `validation_failed`; `success: false + empty error` →
197
+ `internal_error` wire-regression hint; `success: true + missing
198
+ payload` → `internal_error`; EMPTY `block_ids: []` on success →
199
+ success WITH empty array). The projection is per-fetcher (no
200
+ shared helper at 2 consumers; R-v0.5-NEW-17 watch-item tracks
201
+ the OBJECT-shape null-payload guard pattern at 9 consumers
202
+ across M34/M35/M36 mutation fetchers but stays UNFILED today
203
+ per the per-consumer divergence rationale).
204
+
205
+ ### Upgrade notes
206
+
207
+ - **`unsupported_column_type` `deferred_to: "v0.5"` slips to
208
+ `"v0.6"`** for the files-shaped category (`file` column type
209
+ via `--set` / `--set-raw`). Originally slipped from v0.4 →
210
+ v0.5 at v0.4 release-prep; v0.5 didn't pick up the friendly /
211
+ raw forms either (the translator boundary still doesn't
212
+ dispatch into the multipart wire). Slipped from v0.5 → v0.6
213
+ at v0.5 release-prep. `monday item upload` (v0.4-M31)
214
+ continues to be the verb-shaped alternative path agents
215
+ should use today; the hint pointing at `monday item upload`
216
+ is unchanged. **The hint is the load-bearing routing surface
217
+ — agents key off the hint, not the `deferred_to` value.**
218
+ - **Multi-level subitem creation slips from `"v0.5"` → `"v0.6"`.**
219
+ Originally slipped from v0.3 → v0.4 → v0.5 across two prior
220
+ release-preps. v0.5 didn't pick it up — Monday's
221
+ `sub_items_board` still carries no `subtasks` column at API
222
+ `2026-01`, so depth-2 subitems still have no data-model home.
223
+ Single-level subitems (`item create --parent <iid>` against
224
+ classic boards) continue to work byte-identically. The
225
+ `error.code: "usage_error"` + `details.hierarchy_type:
226
+ "multi_level"` keys are unchanged.
227
+ - **Cross-board `item move` value-overrides slip from `"v0.5"`
228
+ → `"v0.6"`.** Originally v0.3-M11-targeted, slipped to v0.4
229
+ at v0.3-M28 audit, slipped to v0.5 at v0.4 release-prep,
230
+ slipped to v0.6 at v0.5 release-prep. Monday's
231
+ `ColumnMappingInput` still carries no value slot; supporting
232
+ it would need a non-atomic post-move `change_multiple_column_
233
+ values` with cross-leg partial-failure envelope shapes that
234
+ have no precedent at v0.5 close. Agents needing overrides
235
+ continue to fire `monday item set <iid> <target>=<value>`
236
+ post-move.
237
+ - **Cross-board resumable cursor slips from `"v0.5"` →
238
+ `"v0.6"`.** The `cross_board_truncated` warning's
239
+ `details.hint` continues to recommend narrowing via
240
+ `--workspace` / `--favorites` / `--max-boards`; v0.6 may pick
241
+ the resumable surface up if per-board cursor-lifetime under
242
+ aggregation gets a clean design.
243
+ - **Stable error-code registry stays at 29.** Existing codes'
244
+ shapes are unchanged across v0.4 → v0.5.
245
+ - **Snake_case wire arg names on M36 doc-block surfaces**
246
+ (`doc_id` / `block_id` / `after_block_id` / `parent_block_id`).
247
+ Monday's standard cadence — NOT a new R-NEW-41 supporting
248
+ site. M37 camelCase wire arg names (`workspaceId` / `folderId`
249
+ / `docId` / `afterBlockId`) ARE a 5th R-NEW-41 supporting
250
+ site for the wire-vs-CLI semantics asymmetry section in
251
+ `docs/architecture.md`.
252
+ - **`monday auth login` placeholder-guard unchanged.** The verb
253
+ is still registered and still surfaces `usage_error.details.
254
+ reason: oauth_unregistered` pointing at `MONDAY_API_TOKEN`
255
+ (unchanged from v0.4.0). The OAuth deferral revisits in
256
+ v0.5.x / v0.6 contingent on user demand.
257
+
258
+ ### Internals worth highlighting
259
+
260
+ - **R-class refactors shipped during v0.5.** R-NEW-70
261
+ (`parseBrandedListArg<T>`) shipped ahead-of-feat at v0.5-M34
262
+ pre-flight close (`17c1a54`) — 4 consumers post-lift (doc/list
263
+ `--workspace` + team-create `--users` + team-add-members
264
+ `--users` + team-remove-members `--users`). 18 unit tests pin
265
+ the helper's branch matrix. R-v0.5-NEW-18 (`readSourceContent`)
266
+ shipped at M37 IMPL kickoff (`c431d96`) — widens M13's
267
+ `readUpdateBody` to parameterise on inline / file flag names +
268
+ optional size cap / trim-whitespace; 5 consumers post-lift
269
+ (3 M13 update verbs + 2 M37 doc verbs).
270
+ - **R-class disciplines graduated during v0.5.** R-v0.5-NEW-11
271
+ (per-fetcher null-payload contract decision discipline derived
272
+ from probe-description return-shape promises) graduated at
273
+ M37 pre-flight close (3rd supporting instance — to a permanent
274
+ Codex pre-flight template W{N} audit-point). R-v0.5-NEW-15
275
+ (pre-flight per-variant payload-shape deferral to IMPL
276
+ cassettes) graduated at M37 pre-flight close (3rd supporting
277
+ instance — to a permanent Codex pre-flight template W{N}
278
+ audit-point). R-v0.5-NEW-19 (post-fix-up cross-doc grep
279
+ extension to `src/commands/index.ts` module-import block prose)
280
+ graduated at M37 IMPL close (2nd supporting instance — folded
281
+ into the CLAUDE.md R-NEW-72 "Workflow rules" entry as the
282
+ fourth search path alongside `src/api/*.ts` + `src/commands/
283
+ **/*.ts` + `docs/*.md`). R-v0.5-NEW-9 (round-N parallel-
284
+ fetcher fix-up test parity discipline) graduated at the
285
+ post-M37-close audit (2nd supporting instance — to a
286
+ permanent IMPL-review / pre-flight template W{N} audit-point).
287
+ - **Noun-stem matching for R-NEW-72 grep patterns** ratified at
288
+ v0.5-M37 IMPL rounds 3-5 — use `\b<noun>\b` regex matching
289
+ rather than literal-substring matching to catch all
290
+ inflections in a single pass. Lesson folded into CLAUDE.md
291
+ R-NEW-72 entry: enumerate sibling-site noun-stems before
292
+ grepping; use regex word-boundary matching to catch all
293
+ inflections (e.g., `cassette` / `cassette pin` / `cassette
294
+ pinned` / `cassette pins` collapse under `\bcassette\b`).
295
+ - **Empirical probes** ratified across the v0.5 surface
296
+ introducing novel wire shapes: M34 `change_team_memberships`
297
+ asymmetric bucket containers (probe round-2 surfaced the
298
+ outer-LIST nullability + the missing per-user failure reason
299
+ pinned at IMPL round-1 P2-1); M35 opaque-JSON `duplicate_doc`
300
+ return-shape variance probe (pinned the defensive 5-shape
301
+ unwrap in `extractDuplicateDocId`); M37 `MAX_DOC_IMPORT_
302
+ PAYLOAD_BYTES` size-limit probe at M37 pre-flight (pinned
303
+ the wire-side rejection threshold between 250KB-OK and
304
+ 500KB-rejected on both surfaces). R-NEW-37 W2 (operation-
305
+ name parity) safely-by-construction across all v0.5
306
+ fetchers — verified clean at every Codex IMPL round.
307
+ - **Two-AI review** (cli-design pre-flight + implementation
308
+ review) ran for every v0.5 milestone M34–M37 + skipped on
309
+ the v0.5 release-prep cluster per the **R-NEW-84 carve-out**
310
+ graduated at v0.5-M34 pre-flight (skip Codex review on
311
+ mechanical / process-only / test-side housekeeping clusters
312
+ with zero production `src/**/*.ts` changes). M34 IMPL
313
+ converged in 3 rounds; M35 IMPL converged in 6 rounds (one
314
+ round above the OBJECT-return precedent — driven by the
315
+ opaque-JSON cassette-prose sweep surfacing incrementally as
316
+ the post-fix-up R-NEW-72 grep pattern broadened);
317
+ M36 IMPL converged in 2 rounds (at the LOWER bound of the
318
+ precedent); M37 IMPL converged in 5 rounds (~1 round above
319
+ M36's clean cadence, driven by the custom-OBJECT shape's
320
+ prose surface). The cumulative finding count + per-milestone
321
+ Codex-round breakdown lives in the per-milestone post-
322
+ mortems in [`docs/v0.5-plan.md`](./docs/v0.5-plan.md)
323
+ §11–§14.
324
+
325
+ ### Tests + quality gates
326
+
327
+ - **4054 unit/integration + E2E tests** at v0.5.0 (+1 skipped;
328
+ was 3634+1 at v0.4.0; ~420 new tests across M34–M37). All
329
+ green on Node 22 + 24.
330
+ - **Coverage at 99.29 / 96.45 / 99.45 / 99.55** (statements /
331
+ branches / functions / lines) against the floor 95 / 95.45 /
332
+ 95 / 95. Branches margin **1.00pp** at v0.5.0 (was 0.88pp at
333
+ v0.4.0; +0.12pp recovery — the v0.5 surface's runtime-body
334
+ branches integration-test-cover the c8-ignored stub drops at
335
+ IMPL close cleanly, first v0.5 IMPL milestone (M37) to cross
336
+ the 1.00pp branches margin threshold; the release-prep
337
+ cluster adds no production branches). Floor unchanged across
338
+ v0.4.0 → v0.5.0.
339
+ - **Envelope-snapshot suite** — no refresh needed at release-
340
+ prep; per-milestone close-docs sweeps refreshed snapshots in
341
+ lockstep at each IMPL close (M34 +12 snapshots, M35 +11,
342
+ M36 +6, M37 +0 net — describe-block widening swap only).
343
+ - **Five test layers held**: unit, integration (in-process
344
+ `FixtureTransport` + `MultipartFixtureTransport`), E2E
345
+ (subprocess against fixture server), envelope-shape snapshot
346
+ suite, published-tarball E2E.
347
+
348
+ ### Documentation
349
+
350
+ - **[`docs/v0.5-plan.md`](./docs/v0.5-plan.md)** new — the v0.5
351
+ active plan with M34–M37 milestones, decisions log
352
+ (D1-D13), R-class register (R-v0.5-NEW-1 through
353
+ R-v0.5-NEW-22), per-milestone post-mortems (§11–§14 + §22).
354
+ - **[`docs/cli-design.md`](./docs/cli-design.md)** §4.3 grew
355
+ 16 new verb entries (6 USER team-* rows + 10 DOC rows for
356
+ M35/M36/M37); §13 v0.4 entry's v0.5 deferral list closed
357
+ out + the v0.6 frame pinned (files-shaped friendly + multi-
358
+ level subitems + cross-board move value-overrides + cross-
359
+ board resumable cursor).
360
+ - **[`docs/output-shapes.md`](./docs/output-shapes.md)** —
361
+ M35/M36/M37 verb sections snapshot-backed; M34 team-writer
362
+ sections deferred to v0.5.x as a documentation backfill
363
+ (caught at v0.5 release-prep ToC audit as a v0.5-M34
364
+ close-docs gap; ToC row updated to enumerate the team-*
365
+ verbs, a minimal cross-pointer section landed under
366
+ `### user me` pointing agents at `cli-design.md` §4.3 +
367
+ the per-verb integration tests + envelope-snapshot
368
+ regression suite that pin the team-writer contract surface
369
+ today).
370
+ - **README.md** quickstart expanded with v0.5 examples
371
+ (workdocs CRUD steps demonstrating M35/M36/M37 verbs;
372
+ team-writer steps demonstrating M34). Scope section
373
+ reshaped around v0.5.0 / v0.4.0 / v0.3.0 / v0.2.0 / v0.1.0
374
+ per-version layout.
375
+
376
+ [0.5.0]: https://github.com/Firer/monday-cli/releases/tag/v0.5.0
377
+
378
+ ## [0.4.0] - 2026-05-14 — Operational features: long-poll watch, parallel bulk, asset upload, workdocs reads, shell completion
379
+
380
+ The "agents can drive long-running workflows + multipart wire +
381
+ shell completion" milestone — v0.3's "drive a real backlog"
382
+ foundation gains long-poll item activity streaming (NDJSON), bounded
383
+ parallel bulk dispatch, the first multipart wire surface (asset
384
+ uploads), Monday workdocs reads, and per-shell completion script
385
+ generation. **No breaking changes vs `0.3.0` — every v0.4 surface
386
+ is additive.** Built incrementally across M29–M33.
387
+
388
+ ### Breaking changes vs `0.3.0`
389
+
390
+ **None.** Every command, error code, envelope key, and warning
391
+ shape shipped in v0.3.0 is preserved byte-for-byte. v0.4 only adds.
392
+
393
+ ### Surface
394
+
395
+ **~101 commands shipped (was ~95 in v0.3).** Six new verbs +
396
+ one orthogonal flag extension on an existing verb. The new noun
397
+ namespaces are `doc` (workdocs reads) and `completion` (CLI-
398
+ internal, shell completion script generator).
399
+
400
+ **Long-poll item activity streaming (M29) — `monday item watch
401
+ <iid>`.** Long-polls Monday's `boards.activity_logs(item_ids:)`
402
+ with a polling cadence floor of `MIN_WATCH_INTERVAL_MS` (1000ms)
403
+ and emits one NDJSON event record per emitted activity-log row
404
+ plus a trailing `{"_meta": {...}}` record carrying the seven
405
+ M29-specific session counters flat under `_meta`:
406
+ `events_emitted`, `polls_made`, `failed_polls`,
407
+ `last_seen_event_id`, `circuit_broken_at`, `exit_reason`,
408
+ `watch_duration_seconds` (plus the standard meta keys + a
409
+ `warnings: [...]` slot accumulating `poll_failed` /
410
+ `circuit_breaker_armed` warnings). Modes: `--once` drains backlog
411
+ and exits without polling further; `--max-events <N>` /
412
+ `--max-duration <duration>` ceilings exit cleanly with the matching
413
+ `exit_reason`; `--since <event-id>` looks up the event's
414
+ `created_at` once and starts the loop from there; `--include
415
+ <kind>` filter narrows emitted events (v0.5+ may extend with
416
+ comment polling via `--include update_posted` once Monday's
417
+ `activity_logs` surfaces those). SIGINT drains gracefully + exits
418
+ 130. Circuit-breaker trips after 5 consecutive `complexity_exceeded`
419
+ polls (emits an `exit_reason: circuit_broken` trailer + a §6.5
420
+ failure envelope on stderr + exit code 2; a successful poll between
421
+ failures resets the consecutive counter). Walker-side
422
+ `entity === 'pulse'` filter drops board-scoped rows per Decision 2
423
+ closure.
424
+
425
+ **Parallel bulk dispatch (M30) — `monday item update --where ...
426
+ --concurrency <N>`.** Extends the M25 partial-success bulk path
427
+ with bounded parallel dispatch via a new `--concurrency <N>` flag
428
+ (range 1..32; default 1). `--concurrency 1` routes through
429
+ `dispatchSequential` (byte-equivalent to the M25 default);
430
+ `--concurrency > 1` routes through `dispatchParallel` (semaphore-
431
+ bounded worker pool). The envelope is byte-equivalent across both
432
+ paths — `--concurrency` is a dispatch-mode flag, not a contract
433
+ extension. **Input-order preservation**: `data.results[]` lists
434
+ per-target outcomes in the original matched-item order regardless
435
+ of completion order, so agents can correlate `results[i]` ↔
436
+ `matched_items[i]` deterministically. `--concurrency` is mutually
437
+ exclusive with the single-item shape (rejected with `usage_error`
438
+ at `validateInputShape` before any network call) and requires
439
+ `--continue-on-error` on the bulk shape (the fail-fast bulk path
440
+ keeps its v0.1 envelope).
441
+
442
+ **Asset uploads (M31) — `monday item upload` + `monday update
443
+ upload`.** First multipart wire surface (`add_file_to_column` /
444
+ `add_file_to_update`). Per-verb shapes:
445
+
446
+ - `monday item upload <iid> --column <col> <file>` uploads the
447
+ local file as a Monday asset attached to the named column on
448
+ the item. Column type is validated against the writable-files
449
+ allowlist (`file` only at v0.4 — Monday's `add_file_to_column`
450
+ doesn't generalise to other types).
451
+ - `monday update upload <update-id> <file>` uploads the local
452
+ file as an asset attached to a Monday "update" (comment).
453
+
454
+ Both verbs do a JSON-leg pre-read (item-board lookup + board
455
+ metadata for column resolution, or update lookup) followed by
456
+ the multipart `add_file_to_*` mutation. The success envelope
457
+ carries Monday's full `Asset` projection (`id`, `name`, `url`,
458
+ `public_url`, `file_extension`, `file_size`, `uploaded_by`, etc.).
459
+ Pre-checks: `file_not_readable` (ENOENT or directory), `file_empty`
460
+ (zero-byte). `file_too_large` rewrap on Monday's
461
+ `FILE_SIZE_LIMIT_EXCEEDED` (non-retryable; the underlying
462
+ multipart wire is retryable, but the file-size error isn't —
463
+ M31 IMPL round-1 P2-1 closure). MIME content-type sniffed via the
464
+ new lifted `src/utils/mime.ts` (R-NEW-NEW shipped at M31 IMPL —
465
+ 2-consumer trigger ahead of v0.4-plan §22's typical 3-consumer
466
+ threshold). `--dry-run` previews the planned change envelope
467
+ without firing the multipart wire (file path + filename +
468
+ file_size_bytes echoed; argv path preserved verbatim for relative
469
+ inputs per the R-class round-2/round-3 closure). Uploads are
470
+ **non-idempotent**: each successful call mints a fresh `Asset`
471
+ ID — re-running uploads the file a second time. Agents needing
472
+ register-once dedupe pre-read `Item.assets` / `Update.assets`
473
+ (read-side `item assets` / `update assets` verbs deferred to
474
+ v0.4.x per M31 Decision D6). Cache invalidation fires single-leg
475
+ on item-upload success (the parent item's board metadata cache
476
+ invalidates per §8); update-upload doesn't touch board metadata
477
+ so there's no invalidation step.
478
+
479
+ **Monday workdocs reads (M32) — `monday doc list [--workspace
480
+ <wid>,...] [--order-by <created_at|used_at>] [--limit <n>]
481
+ [--page <n>]` + `monday doc get <did>`.** First read-only access
482
+ to Monday's workdocs surface (`Query.docs(...)`). `doc list` is
483
+ paginated via page/limit (no cursor on Monday's workdocs surface);
484
+ defaults to `--limit 25 --page 1`; range 1..100. `--workspace
485
+ <wid>,...` accepts a comma-separated `WorkspaceId` list and maps
486
+ to wire `workspace_ids: [ID]` — Monday silently drops inaccessible
487
+ IDs (best-effort, no resolver warning). `--order-by <created_at|
488
+ used_at>` is a closed 2-value enum; both sort `desc` server-side.
489
+ `doc list` emits a wrapped record envelope: `data:
490
+ { documents: [...], page, limit, returned_count, has_more }`
491
+ where `has_more === (returned_count === limit)` (Monday's wire
492
+ has no `total_count` slot). `doc get <did>` emits the direct-
493
+ unwrap `data: <Document with blocks>` shape; empty `docs: []` →
494
+ `not_found` with `details.doc_id` per D8 closure (Monday returns
495
+ empty when the doc doesn't exist OR is inaccessible — single
496
+ error code per the closure). `DocId` joins the brand registry
497
+ (`src/types/ids.ts`) as the 9th brand. **The full workdocs CRUD
498
+ mutation surface (9 mutations: `create_doc` / `update_doc_name`
499
+ / `delete_doc` / `duplicate_doc` / `import_doc_from_html` /
500
+ `add_content_to_doc_from_markdown` / `create_doc_block` /
501
+ `update_doc_block` / `delete_doc_block`) is deferred to v0.5 per
502
+ D8 closure** — each mutation has enough surface area to warrant
503
+ its own milestone cluster.
504
+
505
+ **Shell completion (M33) — `monday completion <bash|zsh|fish>`.**
506
+ First raw-bytes-carve-out verb (cli-design §3.1 #2). The default
507
+ mode emits the install-time script bytes on stdout regardless of
508
+ TTY/pipe context — `monday completion bash >> ~/.bashrc` writes
509
+ the bash script to bashrc as a sourceable file. The `--json` /
510
+ `--output json` / `MONDAY_OUTPUT=json` paths opt INTO the §6
511
+ envelope with `data: { shell, script }` + `meta.source: "none"`
512
+ (CLI-internal verb — no Monday wire call, no cache, no auth
513
+ requirement). `--table` / `--output table` / `--output text` /
514
+ `--output ndjson` reject with `usage_error` at the parse boundary
515
+ (only `--json` and `--table` are global shorthand flags per
516
+ cli-design §4.4). Per-shell scripts are hand-rolled templates
517
+ (commander 14.0.3 ships **no** built-in completion machinery,
518
+ verified by empirical probe at M33 pre-flight) generated by
519
+ walking the registered command tree at runtime so agents adding a
520
+ new verb get completion for free. ERROR_CODES count stays at 29
521
+ per D4 closure. No new runtime dependency added per cli-design §1
522
+ "minimum deps".
523
+
524
+ ### Output contract additions
525
+
526
+ **No new stable error codes — registry stays at 29.** Every v0.4
527
+ milestone closed the new-error-code question NEGATIVE: M29 routes
528
+ poll failures through the existing `complexity_exceeded` /
529
+ `rate_limited` / `network_error` codes (the trailer's
530
+ `exit_reason: circuit_broken` is an envelope-level discriminator,
531
+ not a `error.code`); M30 routes per-item failures through the M25
532
+ codes (`column_archived` / `validation_failed` / etc.); M31 routes
533
+ file-IO pre-checks through `usage_error.details.reason` discriminator
534
+ (`file_not_readable` / `file_empty` / `file_too_large`); M32
535
+ routes empty-array `doc get` through the existing `not_found`; M33
536
+ routes invalid shells through `usage_error` from the `parseArgv`
537
+ boundary.
538
+
539
+ **New NDJSON trailer shape** (M29 — `monday item watch`). NDJSON-
540
+ streaming verbs emit a final `{"_meta": {...}}` record carrying the
541
+ seven M29-specific session counters flat alongside the standard
542
+ meta keys (per cli-design §6.3 trailer contract). Pinned by the
543
+ envelope-snapshot suite + dedicated per-command suite.
544
+
545
+ **New wrapped-paginated-record envelope** (M32 — `monday doc
546
+ list`). `data: { documents, page, limit, returned_count, has_more
547
+ }` carries the pagination wrapper alongside the projection list.
548
+ Mirrors the M22 `monday usage` wrapped-record shape but on a
549
+ read-paginated surface. R-NEW-74 watch-item tracks the
550
+ `kind: 'record'` candidate for a future `emitSuccess` shape
551
+ extension (`emit.ts` ships only `kind: 'single' | 'collection'`
552
+ today; `'single'` does double-duty for wrapped records). JSON
553
+ output works correctly today; the watch-item fires only on a
554
+ table-UX complaint + 3rd consumer.
555
+
556
+ **New raw-bytes-default verb** (M33 — `monday completion`). First
557
+ verb whose default stdout payload is NOT a §6 envelope. The
558
+ carve-out at cli-design §3.1 #2 enumerates the rule: raw-bytes
559
+ mode is opt-out (`--json` / `--output json` / `MONDAY_OUTPUT=json`
560
+ opts INTO the envelope). The §6 envelope shape on the opt-in path
561
+ is byte-identical to other CLI-internal verbs:
562
+ `data: { shell, script }` + `meta.source: "none"`.
563
+
564
+ **New multipart-mutation planned-change envelope** (M31 —
565
+ `item upload --dry-run` + `update upload --dry-run`). The
566
+ `planned_changes[]` entry shape extends the standard dry-run
567
+ envelope with multipart-specific slots: `operation:
568
+ "add_file_to_column"` / `"add_file_to_update"`, `file_path`,
569
+ `filename`, `file_size_bytes`, plus the standard `item_id` /
570
+ `column_id` (or `update_id`) keys.
571
+
572
+ ### Upgrade notes
573
+
574
+ - **`unsupported_column_type` `deferred_to: "v0.4"` slips to
575
+ `"v0.5"`** for the files-shaped category (`file` column type via
576
+ `--set` / `--set-raw`). v0.4-M31 shipped the verb-shaped path
577
+ (`monday item upload`) — that's the alternative path agents
578
+ should use today — but NOT the friendly `--set
579
+ <file-col>=<path>` / `--set-raw <file-col>=<json>` form (which
580
+ would need a separate dispatch from the translator boundary
581
+ into the multipart wire). Agents that previously caught the
582
+ v0.3.0 envelope's `deferred_to: "v0.4"` for the files-shaped
583
+ reject path should update their comparison to `"v0.5"`; the
584
+ `error.code: "unsupported_column_type"` + the hint pointing at
585
+ `monday item upload` are unchanged. **The hint is the load-
586
+ bearing routing surface — agents key off the hint, not the
587
+ `deferred_to` value.**
588
+ - **Multi-level subitem creation slips from `"v0.4"` → `"v0.5"`.**
589
+ Originally slipped from v0.3 → v0.4 at v0.3-M28 audit. v0.4
590
+ didn't pick it up — Monday's `sub_items_board` carries no
591
+ `subtasks` column at API `2026-01`, so depth-2 subitems still
592
+ have no data-model home. Single-level subitems (`item create
593
+ --parent <iid>` against classic boards) continue to work
594
+ byte-identically. The `error.code: "usage_error"` +
595
+ `details.hierarchy_type: "multi_level"` keys are unchanged.
596
+ - **Cross-board `item move` value-overrides slip from `"v0.4"` →
597
+ `"v0.5"`.** Originally v0.3-M11-targeted, slipped to v0.4 at
598
+ v0.3-M28 audit, slipped to v0.5 at v0.4 release-prep. Monday's
599
+ `ColumnMappingInput` still carries no value slot; supporting it
600
+ would need a non-atomic post-move `change_multiple_column_
601
+ values` with cross-leg partial-failure envelope shapes that
602
+ have no precedent at v0.4 close. Agents needing overrides
603
+ continue to fire `monday item set <iid> <target>=<value>`
604
+ post-move.
605
+ - **Cross-board resumable cursor slips from `"v0.4"` → `"v0.5"`.**
606
+ The `cross_board_truncated` warning's `details.hint` continues
607
+ to recommend narrowing via `--workspace` / `--favorites` /
608
+ `--max-boards`; v0.5 may pick the resumable surface up if
609
+ per-board cursor-lifetime under aggregation gets a clean design.
610
+ - **Stable error-code registry stays at 29.** Existing codes'
611
+ shapes are unchanged across v0.3 → v0.4.
612
+ - **`--concurrency <N>` is a new global-ish flag on bulk
613
+ `item update`.** Default `1` preserves the M25 sequential
614
+ envelope byte-for-byte; agents only opt INTO parallel dispatch
615
+ by passing the flag.
616
+ - **`monday auth login` placeholder-guard unchanged.** The verb
617
+ is still registered and still surfaces `usage_error.details.
618
+ reason: oauth_unregistered` pointing at `MONDAY_API_TOKEN`
619
+ (unchanged from v0.3.0). The OAuth deferral revisits in v0.4.x
620
+ / v0.5 contingent on user demand.
621
+
622
+ ### Internals worth highlighting
623
+
624
+ - **First multipart wire surface (M31)** introduces a new
625
+ transport seam (`MultipartTransport`) alongside the JSON
626
+ `transport` slot in `ResolvedClient`. Test seam mirrors the
627
+ JSON path's pattern (`ctx.multipart` injection wins;
628
+ production builds fresh via `createMultipartTransport(...)`).
629
+ The `add_file_to_column` / `add_file_to_update` fetchers share
630
+ an inline `dispatchMultipartOnce` helper + an inline retry-
631
+ thunk rewrap pattern for the non-retryable file_too_large case
632
+ (the wrap-vs-thunk placement is invariant — round-1 P2-1
633
+ closure). Codex pre-pre-flight checklist R-v0.4-W2 ratified
634
+ for "new transport seam" milestones.
635
+
636
+ - **R-class refactors shipped during v0.4.** R-NEW-41 (asymmetric
637
+ wire-vs-CLI semantics documentation pattern) shipped at M31
638
+ pre-flight as a new `docs/architecture.md` "Wire-vs-CLI
639
+ semantics documentation conventions" section enumerating the
640
+ three documented asymmetries (M27 webhook.config wire-typing
641
+ + M27 NotificationTargetType + M31 multipart-vs-JSON
642
+ transport). R-NEW-NEW `sniffContentType` lift to
643
+ `src/utils/mime.ts` (M31 IMPL — 2-consumer trigger ahead of
644
+ the typical 3-consumer threshold; coverage from integration
645
+ tests alone would have failed the branches floor). R-NEW-56
646
+ ratified for the 3rd consecutive IMPL milestone (cross-doc
647
+ grep at IMPL kickoff catches prose-drift surface ahead of
648
+ Codex review). R-NEW-58 ratified via positive case at M31
649
+ + negative case at M32. R-NEW-72 (cross-doc grep after every
650
+ contract-flipping Codex fix-up) graduated to a permanent
651
+ CLAUDE.md "Workflow rules" entry at M33 IMPL close. R-NEW-75
652
+ (5-dimension candidate-selection framework) graduated at the
653
+ post-M33 candidate-selection session that picked release-prep
654
+ over team writers. Full register with shipped commit SHAs +
655
+ consumer counts lives in [`docs/v0.4-plan.md`](./docs/v0.4-plan.md) §22.
656
+
657
+ - **Empirical probes** ratified across every novel v0.4 surface:
658
+ M29 `activity_logs` polling shape, M31 multipart `add_file_to_*`
659
+ wire, M32 `Query.docs(...)` filter + ordering enum + pagination
660
+ shape, M33 commander capability check (returned ZERO hits,
661
+ flipping the cli-design §13 entry from "via commander" to
662
+ "hand-rolled templates" before any pre-flight contract claim
663
+ could drift). R-NEW-77 (CLI-internal milestone empirical-probe-
664
+ slot equivalent) filed at M33 pre-flight as a 1-consumer
665
+ watch-item.
666
+
667
+ - **Two-AI review** (cli-design pre-flight + implementation
668
+ review) ran for every milestone M29–M33. M30 IMPL took 5
669
+ rounds to converge (the lesson driving R-NEW-56's pre-IMPL
670
+ cross-doc grep + R-NEW-72's post-fix-up grep). M31 took 7
671
+ pre-flight rounds (two distinct surface classes plus
672
+ substantive transport-seam gaps at rounds 6-7) + 3 IMPL rounds.
673
+ M32 / M33 each converged in 3 IMPL rounds. The cumulative
674
+ finding count + per-milestone Codex-round breakdown lives in
675
+ the per-milestone post-mortems in
676
+ [`docs/v0.4-plan.md`](./docs/v0.4-plan.md) §3 + §13–§15.
677
+
678
+ ### Tests + quality gates
679
+
680
+ - **3634 unit/integration + E2E tests** at v0.4.0 (+1 skipped;
681
+ was 3249+1 ≈ 3250 in v0.3.0; ~385 new tests across M29–M33 +
682
+ the v0.4 release-prep envelope-snapshot refresh). All green on
683
+ Node 22 + 24.
684
+ - **Coverage at 99.26 / 96.33 / 99.34 / 99.53** (statements /
685
+ branches / functions / lines) against the floor 95 / 95.45 / 95
686
+ / 95. Branches margin **0.88pp** at v0.4.0 (was 0.95pp at
687
+ v0.3.0; the v0.4 surface introduced novel branch-heavy areas
688
+ like M29's circuit-breaker progression + M30's parallel
689
+ dispatcher, both of which carry full integration-test coverage
690
+ but eat margin). Floor unchanged across v0.3.0 → v0.4.0.
691
+ - **Envelope-snapshot suite refreshed** for v0.4 surfaces — adds
692
+ 11 snapshots covering item watch (NDJSON trailer shape),
693
+ doc list (wrapped record), doc get (direct unwrap + D8
694
+ not_found), completion bash/zsh/fish --json (raw-bytes-carve-
695
+ out envelope opt-in), completion --table + invalid-shell
696
+ rejections. Item upload / update upload pinned by the per-
697
+ command suites (multipart transport scaffolding stays out
698
+ of the envelope-snapshot suite per the v0.3-M28 cross-board /
699
+ dev precedent). `--concurrency` envelope byte-equivalent to
700
+ the existing M25 sequential snapshot — pinned by the per-
701
+ command bulk suite.
702
+ - **Five test layers held**: unit, integration (in-process
703
+ `FixtureTransport` + `MultipartFixtureTransport`), E2E
704
+ (subprocess against fixture server), envelope-shape snapshot
705
+ suite, published-tarball E2E.
706
+
707
+ ### Documentation
708
+
709
+ - **[`docs/v0.4-plan.md`](./docs/v0.4-plan.md)** new — the v0.4
710
+ active plan with M29–M33 milestones, decisions log, R-class
711
+ register (R-NEW-44 through R-NEW-81), per-milestone post-
712
+ mortems (§3 + §13–§15 + §22).
713
+ - **[`docs/cli-design.md`](./docs/cli-design.md)** §4.3 grew six
714
+ new verb entries; §3.1 #2 raw-bytes carve-out documented; §13
715
+ v0.4 entry closed out + the v0.5 frame pinned (team writers +
716
+ doc CRUD mutation surface deferred to v0.5).
717
+ - **[`docs/architecture.md`](./docs/architecture.md)** gained
718
+ the "Wire-vs-CLI semantics documentation conventions" section
719
+ (R-NEW-41 shipped at M31 pre-flight).
720
+ - **[`docs/output-shapes.md`](./docs/output-shapes.md)** — every
721
+ shipped v0.4 command has a per-section data shape entry,
722
+ snapshot-backed.
723
+ - **README.md** quickstart expanded with v0.4 examples (`monday
724
+ completion`, `monday item watch`, `monday item upload`,
725
+ `--concurrency`, `monday doc list/get`).
726
+
727
+ [0.4.0]: https://github.com/Firer/monday-cli/releases/tag/v0.4.0
728
+
10
729
  ## [0.3.0] - 2026-05-13 — Monday Dev + multi-profile + diagnostics + outbound writes
11
730
 
12
731
  The "agent can drive a real backlog with a real workflow" milestone —