monday-cli 0.3.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 (107) hide show
  1. package/CHANGELOG.md +351 -0
  2. package/README.md +130 -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 +11 -7
  8. package/dist/api/column-types.d.ts.map +1 -1
  9. package/dist/api/column-types.js +5 -3
  10. package/dist/api/column-types.js.map +1 -1
  11. package/dist/api/column-values.d.ts +7 -1
  12. package/dist/api/column-values.d.ts.map +1 -1
  13. package/dist/api/column-values.js +15 -6
  14. package/dist/api/column-values.js.map +1 -1
  15. package/dist/api/documents.d.ts +519 -0
  16. package/dist/api/documents.d.ts.map +1 -0
  17. package/dist/api/documents.js +586 -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 +12 -4
  40. package/dist/api/raw-write.d.ts.map +1 -1
  41. package/dist/api/raw-write.js +21 -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/cli/run.d.ts +20 -0
  48. package/dist/cli/run.d.ts.map +1 -1
  49. package/dist/cli/run.js +1 -0
  50. package/dist/cli/run.js.map +1 -1
  51. package/dist/commands/board/column-create.d.ts +6 -5
  52. package/dist/commands/board/column-create.d.ts.map +1 -1
  53. package/dist/commands/board/column-create.js +9 -6
  54. package/dist/commands/board/column-create.js.map +1 -1
  55. package/dist/commands/completion.d.ts +188 -0
  56. package/dist/commands/completion.d.ts.map +1 -0
  57. package/dist/commands/completion.js +418 -0
  58. package/dist/commands/completion.js.map +1 -0
  59. package/dist/commands/doc/get.d.ts +46 -0
  60. package/dist/commands/doc/get.d.ts.map +1 -0
  61. package/dist/commands/doc/get.js +95 -0
  62. package/dist/commands/doc/get.js.map +1 -0
  63. package/dist/commands/doc/list.d.ts +83 -0
  64. package/dist/commands/doc/list.d.ts.map +1 -0
  65. package/dist/commands/doc/list.js +248 -0
  66. package/dist/commands/doc/list.js.map +1 -0
  67. package/dist/commands/index.d.ts.map +1 -1
  68. package/dist/commands/index.js +46 -0
  69. package/dist/commands/index.js.map +1 -1
  70. package/dist/commands/item/create.js +2 -2
  71. package/dist/commands/item/update.d.ts +1 -0
  72. package/dist/commands/item/update.d.ts.map +1 -1
  73. package/dist/commands/item/update.js +61 -0
  74. package/dist/commands/item/update.js.map +1 -1
  75. package/dist/commands/item/upload.d.ts +108 -0
  76. package/dist/commands/item/upload.d.ts.map +1 -0
  77. package/dist/commands/item/upload.js +370 -0
  78. package/dist/commands/item/upload.js.map +1 -0
  79. package/dist/commands/item/watch.d.ts +90 -0
  80. package/dist/commands/item/watch.d.ts.map +1 -0
  81. package/dist/commands/item/watch.js +342 -0
  82. package/dist/commands/item/watch.js.map +1 -0
  83. package/dist/commands/update/upload.d.ts +69 -0
  84. package/dist/commands/update/upload.d.ts.map +1 -0
  85. package/dist/commands/update/upload.js +235 -0
  86. package/dist/commands/update/upload.js.map +1 -0
  87. package/dist/types/ids.d.ts +2 -0
  88. package/dist/types/ids.d.ts.map +1 -1
  89. package/dist/types/ids.js +9 -2
  90. package/dist/types/ids.js.map +1 -1
  91. package/dist/utils/mime.d.ts +24 -0
  92. package/dist/utils/mime.d.ts.map +1 -0
  93. package/dist/utils/mime.js +64 -0
  94. package/dist/utils/mime.js.map +1 -0
  95. package/dist/utils/output/envelope.d.ts +30 -0
  96. package/dist/utils/output/envelope.d.ts.map +1 -1
  97. package/dist/utils/output/envelope.js +26 -0
  98. package/dist/utils/output/envelope.js.map +1 -1
  99. package/dist/utils/output/ndjson.d.ts +25 -0
  100. package/dist/utils/output/ndjson.d.ts.map +1 -1
  101. package/dist/utils/output/ndjson.js +12 -0
  102. package/dist/utils/output/ndjson.js.map +1 -1
  103. package/dist/utils/signal.d.ts +42 -0
  104. package/dist/utils/signal.d.ts.map +1 -0
  105. package/dist/utils/signal.js +45 -0
  106. package/dist/utils/signal.js.map +1 -0
  107. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,357 @@ 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.4.0] - 2026-05-14 — Operational features: long-poll watch, parallel bulk, asset upload, workdocs reads, shell completion
11
+
12
+ The "agents can drive long-running workflows + multipart wire +
13
+ shell completion" milestone — v0.3's "drive a real backlog"
14
+ foundation gains long-poll item activity streaming (NDJSON), bounded
15
+ parallel bulk dispatch, the first multipart wire surface (asset
16
+ uploads), Monday workdocs reads, and per-shell completion script
17
+ generation. **No breaking changes vs `0.3.0` — every v0.4 surface
18
+ is additive.** Built incrementally across M29–M33.
19
+
20
+ ### Breaking changes vs `0.3.0`
21
+
22
+ **None.** Every command, error code, envelope key, and warning
23
+ shape shipped in v0.3.0 is preserved byte-for-byte. v0.4 only adds.
24
+
25
+ ### Surface
26
+
27
+ **~101 commands shipped (was ~95 in v0.3).** Six new verbs +
28
+ one orthogonal flag extension on an existing verb. The new noun
29
+ namespaces are `doc` (workdocs reads) and `completion` (CLI-
30
+ internal, shell completion script generator).
31
+
32
+ **Long-poll item activity streaming (M29) — `monday item watch
33
+ <iid>`.** Long-polls Monday's `boards.activity_logs(item_ids:)`
34
+ with a polling cadence floor of `MIN_WATCH_INTERVAL_MS` (1000ms)
35
+ and emits one NDJSON event record per emitted activity-log row
36
+ plus a trailing `{"_meta": {...}}` record carrying the seven
37
+ M29-specific session counters flat under `_meta`:
38
+ `events_emitted`, `polls_made`, `failed_polls`,
39
+ `last_seen_event_id`, `circuit_broken_at`, `exit_reason`,
40
+ `watch_duration_seconds` (plus the standard meta keys + a
41
+ `warnings: [...]` slot accumulating `poll_failed` /
42
+ `circuit_breaker_armed` warnings). Modes: `--once` drains backlog
43
+ and exits without polling further; `--max-events <N>` /
44
+ `--max-duration <duration>` ceilings exit cleanly with the matching
45
+ `exit_reason`; `--since <event-id>` looks up the event's
46
+ `created_at` once and starts the loop from there; `--include
47
+ <kind>` filter narrows emitted events (v0.5+ may extend with
48
+ comment polling via `--include update_posted` once Monday's
49
+ `activity_logs` surfaces those). SIGINT drains gracefully + exits
50
+ 130. Circuit-breaker trips after 5 consecutive `complexity_exceeded`
51
+ polls (emits an `exit_reason: circuit_broken` trailer + a §6.5
52
+ failure envelope on stderr + exit code 2; a successful poll between
53
+ failures resets the consecutive counter). Walker-side
54
+ `entity === 'pulse'` filter drops board-scoped rows per Decision 2
55
+ closure.
56
+
57
+ **Parallel bulk dispatch (M30) — `monday item update --where ...
58
+ --concurrency <N>`.** Extends the M25 partial-success bulk path
59
+ with bounded parallel dispatch via a new `--concurrency <N>` flag
60
+ (range 1..32; default 1). `--concurrency 1` routes through
61
+ `dispatchSequential` (byte-equivalent to the M25 default);
62
+ `--concurrency > 1` routes through `dispatchParallel` (semaphore-
63
+ bounded worker pool). The envelope is byte-equivalent across both
64
+ paths — `--concurrency` is a dispatch-mode flag, not a contract
65
+ extension. **Input-order preservation**: `data.results[]` lists
66
+ per-target outcomes in the original matched-item order regardless
67
+ of completion order, so agents can correlate `results[i]` ↔
68
+ `matched_items[i]` deterministically. `--concurrency` is mutually
69
+ exclusive with the single-item shape (rejected with `usage_error`
70
+ at `validateInputShape` before any network call) and requires
71
+ `--continue-on-error` on the bulk shape (the fail-fast bulk path
72
+ keeps its v0.1 envelope).
73
+
74
+ **Asset uploads (M31) — `monday item upload` + `monday update
75
+ upload`.** First multipart wire surface (`add_file_to_column` /
76
+ `add_file_to_update`). Per-verb shapes:
77
+
78
+ - `monday item upload <iid> --column <col> <file>` uploads the
79
+ local file as a Monday asset attached to the named column on
80
+ the item. Column type is validated against the writable-files
81
+ allowlist (`file` only at v0.4 — Monday's `add_file_to_column`
82
+ doesn't generalise to other types).
83
+ - `monday update upload <update-id> <file>` uploads the local
84
+ file as an asset attached to a Monday "update" (comment).
85
+
86
+ Both verbs do a JSON-leg pre-read (item-board lookup + board
87
+ metadata for column resolution, or update lookup) followed by
88
+ the multipart `add_file_to_*` mutation. The success envelope
89
+ carries Monday's full `Asset` projection (`id`, `name`, `url`,
90
+ `public_url`, `file_extension`, `file_size`, `uploaded_by`, etc.).
91
+ Pre-checks: `file_not_readable` (ENOENT or directory), `file_empty`
92
+ (zero-byte). `file_too_large` rewrap on Monday's
93
+ `FILE_SIZE_LIMIT_EXCEEDED` (non-retryable; the underlying
94
+ multipart wire is retryable, but the file-size error isn't —
95
+ M31 IMPL round-1 P2-1 closure). MIME content-type sniffed via the
96
+ new lifted `src/utils/mime.ts` (R-NEW-NEW shipped at M31 IMPL —
97
+ 2-consumer trigger ahead of v0.4-plan §22's typical 3-consumer
98
+ threshold). `--dry-run` previews the planned change envelope
99
+ without firing the multipart wire (file path + filename +
100
+ file_size_bytes echoed; argv path preserved verbatim for relative
101
+ inputs per the R-class round-2/round-3 closure). Uploads are
102
+ **non-idempotent**: each successful call mints a fresh `Asset`
103
+ ID — re-running uploads the file a second time. Agents needing
104
+ register-once dedupe pre-read `Item.assets` / `Update.assets`
105
+ (read-side `item assets` / `update assets` verbs deferred to
106
+ v0.4.x per M31 Decision D6). Cache invalidation fires single-leg
107
+ on item-upload success (the parent item's board metadata cache
108
+ invalidates per §8); update-upload doesn't touch board metadata
109
+ so there's no invalidation step.
110
+
111
+ **Monday workdocs reads (M32) — `monday doc list [--workspace
112
+ <wid>,...] [--order-by <created_at|used_at>] [--limit <n>]
113
+ [--page <n>]` + `monday doc get <did>`.** First read-only access
114
+ to Monday's workdocs surface (`Query.docs(...)`). `doc list` is
115
+ paginated via page/limit (no cursor on Monday's workdocs surface);
116
+ defaults to `--limit 25 --page 1`; range 1..100. `--workspace
117
+ <wid>,...` accepts a comma-separated `WorkspaceId` list and maps
118
+ to wire `workspace_ids: [ID]` — Monday silently drops inaccessible
119
+ IDs (best-effort, no resolver warning). `--order-by <created_at|
120
+ used_at>` is a closed 2-value enum; both sort `desc` server-side.
121
+ `doc list` emits a wrapped record envelope: `data:
122
+ { documents: [...], page, limit, returned_count, has_more }`
123
+ where `has_more === (returned_count === limit)` (Monday's wire
124
+ has no `total_count` slot). `doc get <did>` emits the direct-
125
+ unwrap `data: <Document with blocks>` shape; empty `docs: []` →
126
+ `not_found` with `details.doc_id` per D8 closure (Monday returns
127
+ empty when the doc doesn't exist OR is inaccessible — single
128
+ error code per the closure). `DocId` joins the brand registry
129
+ (`src/types/ids.ts`) as the 9th brand. **The full workdocs CRUD
130
+ mutation surface (9 mutations: `create_doc` / `update_doc_name`
131
+ / `delete_doc` / `duplicate_doc` / `import_doc_from_html` /
132
+ `add_content_to_doc_from_markdown` / `create_doc_block` /
133
+ `update_doc_block` / `delete_doc_block`) is deferred to v0.5 per
134
+ D8 closure** — each mutation has enough surface area to warrant
135
+ its own milestone cluster.
136
+
137
+ **Shell completion (M33) — `monday completion <bash|zsh|fish>`.**
138
+ First raw-bytes-carve-out verb (cli-design §3.1 #2). The default
139
+ mode emits the install-time script bytes on stdout regardless of
140
+ TTY/pipe context — `monday completion bash >> ~/.bashrc` writes
141
+ the bash script to bashrc as a sourceable file. The `--json` /
142
+ `--output json` / `MONDAY_OUTPUT=json` paths opt INTO the §6
143
+ envelope with `data: { shell, script }` + `meta.source: "none"`
144
+ (CLI-internal verb — no Monday wire call, no cache, no auth
145
+ requirement). `--table` / `--output table` / `--output text` /
146
+ `--output ndjson` reject with `usage_error` at the parse boundary
147
+ (only `--json` and `--table` are global shorthand flags per
148
+ cli-design §4.4). Per-shell scripts are hand-rolled templates
149
+ (commander 14.0.3 ships **no** built-in completion machinery,
150
+ verified by empirical probe at M33 pre-flight) generated by
151
+ walking the registered command tree at runtime so agents adding a
152
+ new verb get completion for free. ERROR_CODES count stays at 29
153
+ per D4 closure. No new runtime dependency added per cli-design §1
154
+ "minimum deps".
155
+
156
+ ### Output contract additions
157
+
158
+ **No new stable error codes — registry stays at 29.** Every v0.4
159
+ milestone closed the new-error-code question NEGATIVE: M29 routes
160
+ poll failures through the existing `complexity_exceeded` /
161
+ `rate_limited` / `network_error` codes (the trailer's
162
+ `exit_reason: circuit_broken` is an envelope-level discriminator,
163
+ not a `error.code`); M30 routes per-item failures through the M25
164
+ codes (`column_archived` / `validation_failed` / etc.); M31 routes
165
+ file-IO pre-checks through `usage_error.details.reason` discriminator
166
+ (`file_not_readable` / `file_empty` / `file_too_large`); M32
167
+ routes empty-array `doc get` through the existing `not_found`; M33
168
+ routes invalid shells through `usage_error` from the `parseArgv`
169
+ boundary.
170
+
171
+ **New NDJSON trailer shape** (M29 — `monday item watch`). NDJSON-
172
+ streaming verbs emit a final `{"_meta": {...}}` record carrying the
173
+ seven M29-specific session counters flat alongside the standard
174
+ meta keys (per cli-design §6.3 trailer contract). Pinned by the
175
+ envelope-snapshot suite + dedicated per-command suite.
176
+
177
+ **New wrapped-paginated-record envelope** (M32 — `monday doc
178
+ list`). `data: { documents, page, limit, returned_count, has_more
179
+ }` carries the pagination wrapper alongside the projection list.
180
+ Mirrors the M22 `monday usage` wrapped-record shape but on a
181
+ read-paginated surface. R-NEW-74 watch-item tracks the
182
+ `kind: 'record'` candidate for a future `emitSuccess` shape
183
+ extension (`emit.ts` ships only `kind: 'single' | 'collection'`
184
+ today; `'single'` does double-duty for wrapped records). JSON
185
+ output works correctly today; the watch-item fires only on a
186
+ table-UX complaint + 3rd consumer.
187
+
188
+ **New raw-bytes-default verb** (M33 — `monday completion`). First
189
+ verb whose default stdout payload is NOT a §6 envelope. The
190
+ carve-out at cli-design §3.1 #2 enumerates the rule: raw-bytes
191
+ mode is opt-out (`--json` / `--output json` / `MONDAY_OUTPUT=json`
192
+ opts INTO the envelope). The §6 envelope shape on the opt-in path
193
+ is byte-identical to other CLI-internal verbs:
194
+ `data: { shell, script }` + `meta.source: "none"`.
195
+
196
+ **New multipart-mutation planned-change envelope** (M31 —
197
+ `item upload --dry-run` + `update upload --dry-run`). The
198
+ `planned_changes[]` entry shape extends the standard dry-run
199
+ envelope with multipart-specific slots: `operation:
200
+ "add_file_to_column"` / `"add_file_to_update"`, `file_path`,
201
+ `filename`, `file_size_bytes`, plus the standard `item_id` /
202
+ `column_id` (or `update_id`) keys.
203
+
204
+ ### Upgrade notes
205
+
206
+ - **`unsupported_column_type` `deferred_to: "v0.4"` slips to
207
+ `"v0.5"`** for the files-shaped category (`file` column type via
208
+ `--set` / `--set-raw`). v0.4-M31 shipped the verb-shaped path
209
+ (`monday item upload`) — that's the alternative path agents
210
+ should use today — but NOT the friendly `--set
211
+ <file-col>=<path>` / `--set-raw <file-col>=<json>` form (which
212
+ would need a separate dispatch from the translator boundary
213
+ into the multipart wire). Agents that previously caught the
214
+ v0.3.0 envelope's `deferred_to: "v0.4"` for the files-shaped
215
+ reject path should update their comparison to `"v0.5"`; the
216
+ `error.code: "unsupported_column_type"` + the hint pointing at
217
+ `monday item upload` are unchanged. **The hint is the load-
218
+ bearing routing surface — agents key off the hint, not the
219
+ `deferred_to` value.**
220
+ - **Multi-level subitem creation slips from `"v0.4"` → `"v0.5"`.**
221
+ Originally slipped from v0.3 → v0.4 at v0.3-M28 audit. v0.4
222
+ didn't pick it up — Monday's `sub_items_board` carries no
223
+ `subtasks` column at API `2026-01`, so depth-2 subitems still
224
+ have no data-model home. Single-level subitems (`item create
225
+ --parent <iid>` against classic boards) continue to work
226
+ byte-identically. The `error.code: "usage_error"` +
227
+ `details.hierarchy_type: "multi_level"` keys are unchanged.
228
+ - **Cross-board `item move` value-overrides slip from `"v0.4"` →
229
+ `"v0.5"`.** Originally v0.3-M11-targeted, slipped to v0.4 at
230
+ v0.3-M28 audit, slipped to v0.5 at v0.4 release-prep. Monday's
231
+ `ColumnMappingInput` still carries no value slot; supporting it
232
+ 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.4 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.4"` → `"v0.5"`.**
238
+ The `cross_board_truncated` warning's `details.hint` continues
239
+ to recommend narrowing via `--workspace` / `--favorites` /
240
+ `--max-boards`; v0.5 may pick the resumable surface up if
241
+ per-board cursor-lifetime under aggregation gets a clean design.
242
+ - **Stable error-code registry stays at 29.** Existing codes'
243
+ shapes are unchanged across v0.3 → v0.4.
244
+ - **`--concurrency <N>` is a new global-ish flag on bulk
245
+ `item update`.** Default `1` preserves the M25 sequential
246
+ envelope byte-for-byte; agents only opt INTO parallel dispatch
247
+ by passing the flag.
248
+ - **`monday auth login` placeholder-guard unchanged.** The verb
249
+ is still registered and still surfaces `usage_error.details.
250
+ reason: oauth_unregistered` pointing at `MONDAY_API_TOKEN`
251
+ (unchanged from v0.3.0). The OAuth deferral revisits in v0.4.x
252
+ / v0.5 contingent on user demand.
253
+
254
+ ### Internals worth highlighting
255
+
256
+ - **First multipart wire surface (M31)** introduces a new
257
+ transport seam (`MultipartTransport`) alongside the JSON
258
+ `transport` slot in `ResolvedClient`. Test seam mirrors the
259
+ JSON path's pattern (`ctx.multipart` injection wins;
260
+ production builds fresh via `createMultipartTransport(...)`).
261
+ The `add_file_to_column` / `add_file_to_update` fetchers share
262
+ an inline `dispatchMultipartOnce` helper + an inline retry-
263
+ thunk rewrap pattern for the non-retryable file_too_large case
264
+ (the wrap-vs-thunk placement is invariant — round-1 P2-1
265
+ closure). Codex pre-pre-flight checklist R-v0.4-W2 ratified
266
+ for "new transport seam" milestones.
267
+
268
+ - **R-class refactors shipped during v0.4.** R-NEW-41 (asymmetric
269
+ wire-vs-CLI semantics documentation pattern) shipped at M31
270
+ pre-flight as a new `docs/architecture.md` "Wire-vs-CLI
271
+ semantics documentation conventions" section enumerating the
272
+ three documented asymmetries (M27 webhook.config wire-typing
273
+ + M27 NotificationTargetType + M31 multipart-vs-JSON
274
+ transport). R-NEW-NEW `sniffContentType` lift to
275
+ `src/utils/mime.ts` (M31 IMPL — 2-consumer trigger ahead of
276
+ the typical 3-consumer threshold; coverage from integration
277
+ tests alone would have failed the branches floor). R-NEW-56
278
+ ratified for the 3rd consecutive IMPL milestone (cross-doc
279
+ grep at IMPL kickoff catches prose-drift surface ahead of
280
+ Codex review). R-NEW-58 ratified via positive case at M31
281
+ + negative case at M32. R-NEW-72 (cross-doc grep after every
282
+ contract-flipping Codex fix-up) graduated to a permanent
283
+ CLAUDE.md "Workflow rules" entry at M33 IMPL close. R-NEW-75
284
+ (5-dimension candidate-selection framework) graduated at the
285
+ post-M33 candidate-selection session that picked release-prep
286
+ over team writers. Full register with shipped commit SHAs +
287
+ consumer counts lives in [`docs/v0.4-plan.md`](./docs/v0.4-plan.md) §22.
288
+
289
+ - **Empirical probes** ratified across every novel v0.4 surface:
290
+ M29 `activity_logs` polling shape, M31 multipart `add_file_to_*`
291
+ wire, M32 `Query.docs(...)` filter + ordering enum + pagination
292
+ shape, M33 commander capability check (returned ZERO hits,
293
+ flipping the cli-design §13 entry from "via commander" to
294
+ "hand-rolled templates" before any pre-flight contract claim
295
+ could drift). R-NEW-77 (CLI-internal milestone empirical-probe-
296
+ slot equivalent) filed at M33 pre-flight as a 1-consumer
297
+ watch-item.
298
+
299
+ - **Two-AI review** (cli-design pre-flight + implementation
300
+ review) ran for every milestone M29–M33. M30 IMPL took 5
301
+ rounds to converge (the lesson driving R-NEW-56's pre-IMPL
302
+ cross-doc grep + R-NEW-72's post-fix-up grep). M31 took 7
303
+ pre-flight rounds (two distinct surface classes plus
304
+ substantive transport-seam gaps at rounds 6-7) + 3 IMPL rounds.
305
+ M32 / M33 each converged in 3 IMPL rounds. The cumulative
306
+ finding count + per-milestone Codex-round breakdown lives in
307
+ the per-milestone post-mortems in
308
+ [`docs/v0.4-plan.md`](./docs/v0.4-plan.md) §3 + §13–§15.
309
+
310
+ ### Tests + quality gates
311
+
312
+ - **3634 unit/integration + E2E tests** at v0.4.0 (+1 skipped;
313
+ was 3249+1 ≈ 3250 in v0.3.0; ~385 new tests across M29–M33 +
314
+ the v0.4 release-prep envelope-snapshot refresh). All green on
315
+ Node 22 + 24.
316
+ - **Coverage at 99.26 / 96.33 / 99.34 / 99.53** (statements /
317
+ branches / functions / lines) against the floor 95 / 95.45 / 95
318
+ / 95. Branches margin **0.88pp** at v0.4.0 (was 0.95pp at
319
+ v0.3.0; the v0.4 surface introduced novel branch-heavy areas
320
+ like M29's circuit-breaker progression + M30's parallel
321
+ dispatcher, both of which carry full integration-test coverage
322
+ but eat margin). Floor unchanged across v0.3.0 → v0.4.0.
323
+ - **Envelope-snapshot suite refreshed** for v0.4 surfaces — adds
324
+ 11 snapshots covering item watch (NDJSON trailer shape),
325
+ doc list (wrapped record), doc get (direct unwrap + D8
326
+ not_found), completion bash/zsh/fish --json (raw-bytes-carve-
327
+ out envelope opt-in), completion --table + invalid-shell
328
+ rejections. Item upload / update upload pinned by the per-
329
+ command suites (multipart transport scaffolding stays out
330
+ of the envelope-snapshot suite per the v0.3-M28 cross-board /
331
+ dev precedent). `--concurrency` envelope byte-equivalent to
332
+ the existing M25 sequential snapshot — pinned by the per-
333
+ command bulk suite.
334
+ - **Five test layers held**: unit, integration (in-process
335
+ `FixtureTransport` + `MultipartFixtureTransport`), E2E
336
+ (subprocess against fixture server), envelope-shape snapshot
337
+ suite, published-tarball E2E.
338
+
339
+ ### Documentation
340
+
341
+ - **[`docs/v0.4-plan.md`](./docs/v0.4-plan.md)** new — the v0.4
342
+ active plan with M29–M33 milestones, decisions log, R-class
343
+ register (R-NEW-44 through R-NEW-81), per-milestone post-
344
+ mortems (§3 + §13–§15 + §22).
345
+ - **[`docs/cli-design.md`](./docs/cli-design.md)** §4.3 grew six
346
+ new verb entries; §3.1 #2 raw-bytes carve-out documented; §13
347
+ v0.4 entry closed out + the v0.5 frame pinned (team writers +
348
+ doc CRUD mutation surface deferred to v0.5).
349
+ - **[`docs/architecture.md`](./docs/architecture.md)** gained
350
+ the "Wire-vs-CLI semantics documentation conventions" section
351
+ (R-NEW-41 shipped at M31 pre-flight).
352
+ - **[`docs/output-shapes.md`](./docs/output-shapes.md)** — every
353
+ shipped v0.4 command has a per-section data shape entry,
354
+ snapshot-backed.
355
+ - **README.md** quickstart expanded with v0.4 examples (`monday
356
+ completion`, `monday item watch`, `monday item upload`,
357
+ `--concurrency`, `monday doc list/get`).
358
+
359
+ [0.4.0]: https://github.com/Firer/monday-cli/releases/tag/v0.4.0
360
+
10
361
  ## [0.3.0] - 2026-05-13 — Monday Dev + multi-profile + diagnostics + outbound writes
11
362
 
12
363
  The "agent can drive a real backlog with a real workflow" milestone —
package/README.md CHANGED
@@ -49,41 +49,71 @@ Requires **Node.js ≥ 22**.
49
49
  # Get one at https://<your-org>.monday.com/admin/integrations/api
50
50
  #
51
51
  # OAuth login (`monday auth login`) is registered but deferred in
52
- # v0.3.0 — the verb surfaces a clear `usage_error.details.reason:
52
+ # v0.4.0 — the verb surfaces a clear `usage_error.details.reason:
53
53
  # oauth_unregistered` pointing here. Authenticate via the env var.
54
54
  export MONDAY_API_TOKEN="<your-token>"
55
55
 
56
56
  # 2. Smoke test — confirm the token works.
57
57
  monday account whoami --json
58
58
 
59
- # 3. Is everything wired up? (v0.3 diagnostics cluster)
60
- monday status --json # 7-probe DNS/TCP/TLS/auth/cache matrix
61
- monday usage --json # remaining daily Monday API operations
59
+ # 3. Install shell completion (v0.4-M33 bash / zsh / fish).
60
+ # The default mode emits raw script bytes on stdout (so the redirect
61
+ # works); `--json` opts INTO the §6 envelope.
62
+ monday completion bash >> ~/.bashrc # or .zshrc / config.fish
62
63
 
63
- # 4. List a board's items (replace 12345 with your board ID)
64
+ # 4. Is everything wired up? (v0.3 diagnostics cluster)
65
+ monday status --json # 7-probe DNS/TCP/TLS/auth/cache matrix
66
+ monday usage --json # remaining daily Monday API operations
67
+
68
+ # 5. List a board's items (replace 12345 with your board ID)
64
69
  monday item list --board 12345 --json
65
70
 
66
- # 5. File a new task (v0.2)
71
+ # 6. File a new task (v0.2)
67
72
  monday item create --board 12345 --name "Refactor login" \
68
73
  --set status=Backlog --set 'Due date'=+1w --json
69
74
 
70
- # 6. Find-or-create with idempotent matching (v0.2)
71
- # Re-running with the same args is safe 0/1/2+ matches route to
72
- # create / update / `ambiguous_match` (one of the 29 stable error codes).
75
+ # 7. Long-poll for activity on an item (v0.4-M29 — NDJSON stream).
76
+ # Per-event NDJSON record + a `{"_meta": {...}}` trailer carrying
77
+ # the session counters. Use `--once` to drain backlog without
78
+ # polling further; SIGINT (Ctrl-C) drains gracefully and exits 130.
79
+ monday item watch 67890 --once # or --max-events 50 --max-duration 1h
80
+
81
+ # 8. Upload a file to a column or update (v0.4-M31 — multipart wire).
82
+ # `add_file_to_column` for item columns; `add_file_to_update` for
83
+ # comment attachments. Both surface `--dry-run` for an envelope
84
+ # preview without the multipart round-trip.
85
+ monday item upload 67890 --column 'Attachments' ./screenshot.png --json
86
+ monday update upload <update-id> ./diagram.png --json
87
+
88
+ # 9. Parallel partial-success bulk updates (v0.4-M30).
89
+ # `--concurrency <N>` (range 1..32) opts into parallel dispatch on
90
+ # the M25 partial-success path. Envelope is byte-equivalent to the
91
+ # sequential `--concurrency 1` default; input order is preserved
92
+ # in `data.results[]` regardless of completion order.
93
+ monday item update --where status=Backlog --set status='Working on it' \
94
+ --board 12345 --yes --continue-on-error --concurrency 4 --json
95
+
96
+ # 10. Browse the workdocs surface (v0.4-M32 — read-only at v0.4).
97
+ monday doc list --workspace 5 --order-by used_at --limit 10 --json
98
+ monday doc get 88001 --json # full Document with blocks
99
+
100
+ # 11. Find-or-create with idempotent matching (v0.2)
101
+ # Re-running with the same args is safe — 0/1/2+ matches route to
102
+ # create / update / `ambiguous_match` (one of the 29 stable error codes).
73
103
  monday item upsert --board 12345 --name "Refactor login" \
74
104
  --match-by name --set status='Working on it' --json
75
105
 
76
- # 7. Move a ticket forward, then comment on it
106
+ # 12. Move a ticket forward, then comment on it
77
107
  monday item set 67890 status=Done --json
78
108
  monday update create 67890 --body "Shipped in PR #1234" --json
79
109
 
80
- # 8. Monday Dev convention layer (v0.3 — sprint/epic/release/task)
81
- # First-time setup auto-detects boards by Monday's stock template names.
82
- monday dev discover --apply --json # writes ~/.monday-cli/config.toml
83
- monday dev sprint current --json # the active sprint
84
- monday dev task list --mine --json # my open tasks
110
+ # 13. Monday Dev convention layer (v0.3 — sprint/epic/release/task)
111
+ # First-time setup auto-detects boards by Monday's stock template names.
112
+ monday dev discover --apply --json # writes ~/.monday-cli/config.toml
113
+ monday dev sprint current --json # the active sprint
114
+ monday dev task list --mine --json # my open tasks
85
115
 
86
- # 9. Outbound writes (v0.3 — webhooks + notifications)
116
+ # 14. Outbound writes (v0.3 — webhooks + notifications)
87
117
  monday webhook list 12345 --json
88
118
  monday notification send --user 7 --target 67890 \
89
119
  --target-type item --text "PTAL" --json
@@ -152,7 +182,7 @@ Every JSON response uses the same universal envelope:
152
182
  "meta": {
153
183
  "schema_version": "1",
154
184
  "api_version": "2026-01",
155
- "cli_version": "0.3.0",
185
+ "cli_version": "0.4.0",
156
186
  "request_id": "0e6f1a7b-...",
157
187
  "source": "live",
158
188
  "cache_age_seconds": null,
@@ -252,7 +282,27 @@ See [`.env.example`](./.env.example) for all supported variables
252
282
 
253
283
  ## Scope
254
284
 
255
- **v0.3.0 (current — `monday-cli@0.3.0` on npm):**
285
+ **v0.4.0 (current — `monday-cli@0.4.0` on npm):**
286
+ the v0.3 surface PLUS long-poll item activity streaming
287
+ (`monday item watch <iid>` — NDJSON), parallel bulk dispatch
288
+ (`monday item update --where ... --concurrency <N>`), asset uploads
289
+ (`monday item upload` / `monday update upload` — multipart wire),
290
+ Monday workdocs reads (`monday doc list` / `monday doc get` — full
291
+ workdocs CRUD mutation surface deferred to v0.5), and shell
292
+ completion (`monday completion bash|zsh|fish`). **No breaking
293
+ changes vs v0.3.0** — every v0.4 surface is additive. Built
294
+ incrementally across M29–M33. See [CHANGELOG.md](./CHANGELOG.md)
295
+ for the full per-milestone release notes.
296
+
297
+ **OAuth deferral (unchanged from v0.3.0).** `monday auth login` is
298
+ registered but the canonical Monday OAuth app is not registered in
299
+ v0.4.0; the verb surfaces a clear `usage_error.details.reason:
300
+ oauth_unregistered` pointing at `MONDAY_API_TOKEN`. Multi-profile
301
+ config + per-profile credentials cache work fully against API
302
+ tokens; OAuth registration revisits in v0.4.x / v0.5 contingent on
303
+ user demand.
304
+
305
+ **v0.3.0 (the previous release):**
256
306
  the v0.2 mutating core PLUS the Monday Dev convention layer
257
307
  (`monday dev` namespace — sprint / epic / release / task workflow
258
308
  shortcuts on top of standard board CRUD), multi-profile auth
@@ -266,17 +316,8 @@ outbound writes (`monday webhook list/create/delete` +
266
316
  (`tags`, `board_relation`, `dependency`) closing the v0.2
267
317
  tentative-row carryover. **No breaking changes vs v0.2.0** — every
268
318
  v0.3 surface is additive. Built incrementally across M19–M28.
269
- See [CHANGELOG.md](./CHANGELOG.md) for the full per-milestone
270
- release notes.
271
-
272
- **OAuth deferral.** `monday auth login` is registered but the
273
- canonical Monday OAuth app is not registered in v0.3.0; the verb
274
- surfaces a clear `usage_error.details.reason: oauth_unregistered`
275
- pointing at `MONDAY_API_TOKEN`. Multi-profile config + per-profile
276
- credentials cache work fully against API tokens; OAuth registration
277
- revisits in v0.3.x / v0.4 contingent on user demand.
278
319
 
279
- **v0.2.0 (the previous release):**
320
+ **v0.2.0 (the prior release):**
280
321
  the v0.1 read-only core + safe-mutations surface PLUS the full
281
322
  mutation surface (item lifecycle, update mutations, workspace
282
323
  lifecycle, board lifecycle, board columns + groups). Built
@@ -461,15 +502,66 @@ row `tags`, `board_relation`, `dependency`.
461
502
  deferred out of v0.3 per Decision 11 (Monday's `sub_items_board`
462
503
  carries no `subtasks` column at API `2026-01`).
463
504
 
464
- **v0.4:** `monday item watch`, `--concurrency` bulk parallelism,
465
- asset uploads, multi-level subitems if Monday's data model
466
- surfaces them.
505
+ **What v0.4 added (M29–M33; full per-milestone narrative in
506
+ [CHANGELOG.md](./CHANGELOG.md)):**
507
+
508
+ - **M29** — `monday item watch <iid>` long-polls `boards.activity_
509
+ logs(item_ids:)` for per-item event streaming. NDJSON output:
510
+ one event record per emitted activity-log row + a trailing
511
+ `{"_meta": {...}}` record carrying the seven session counters
512
+ (`events_emitted` / `polls_made` / `failed_polls` /
513
+ `last_seen_event_id` / `circuit_broken_at` / `exit_reason` /
514
+ `watch_duration_seconds`). `--once` drains backlog and exits
515
+ without polling further; `--max-events` / `--max-duration`
516
+ ceilings exit cleanly; SIGINT drains gracefully + exits 130.
517
+ Circuit-breaker trips after 5 consecutive `complexity_exceeded`
518
+ polls.
519
+ - **M30** — `monday item update --where ... --concurrency <N>`
520
+ (range 1..32; default 1) opts into bounded parallel dispatch on
521
+ the M25 partial-success path. Envelope is byte-equivalent to the
522
+ sequential default; input order is preserved in `data.results[]`
523
+ regardless of completion order. `--concurrency 1` routes through
524
+ `dispatchSequential`; `> 1` routes through `dispatchParallel`.
525
+ - **M31** — `monday item upload <iid> --column <col> <file>` +
526
+ `monday update upload <update-id> <file>` ship the first multipart
527
+ wire surface (`add_file_to_column` / `add_file_to_update`). Both
528
+ surface `--dry-run` for a planned-change envelope preview without
529
+ the multipart round-trip. Uploads are non-idempotent (each
530
+ successful call mints a fresh `Asset` ID); cache invalidation
531
+ fires single-leg on success. Read-side `item assets` / `update
532
+ assets` verbs deferred to v0.4.x per M31 Decision D6.
533
+ - **M32** — `monday doc list [--workspace <wid>,...] [--order-by
534
+ <created_at|used_at>] [--limit <n>] [--page <n>]` + `monday doc
535
+ get <did>` ship read-only access to Monday's workdocs surface
536
+ (`Query.docs(...)`). Page/limit pagination (no cursor on this
537
+ Monday surface). The full workdocs CRUD mutation surface (9
538
+ mutations: `create_doc` / `update_doc_name` / `delete_doc` /
539
+ `duplicate_doc` / `import_doc_from_html` / `add_content_to_doc_
540
+ from_markdown` / `create_doc_block` / `update_doc_block` /
541
+ `delete_doc_block`) is deferred to v0.5.
542
+ - **M33** — `monday completion <bash|zsh|fish>` ships shell
543
+ completion script generation. The default mode emits raw script
544
+ bytes on stdout regardless of TTY/pipe context (so `monday
545
+ completion bash >> ~/.bashrc` works as a sourceable file —
546
+ cli-design §3.1 #2 raw-bytes carve-out); `--json` opts INTO the
547
+ §6 envelope with `data: { shell, script }`. Hand-rolled per-shell
548
+ templates (commander 14.0.3 ships no built-in completion
549
+ machinery, verified by empirical probe at M33 pre-flight).
550
+
551
+ **v0.5 (next):** `team` writers (deferred from v0.4-M34 at the
552
+ post-v0.4-M33 candidate-selection session), Monday workdocs CRUD
553
+ mutation surface (9 mutations deferred at v0.4-M32 D8 closure),
554
+ multi-level subitems remain conditional on Monday's data model
555
+ surfacing them, cross-board `item move` value-overrides (slipped
556
+ from v0.4 at v0.4 release-prep — Monday's `ColumnMappingInput`
557
+ carries no value slot), and resumable cross-board cursor pagination
558
+ (slipped from v0.4 — per-board cursor-lifetime under aggregation
559
+ needs design work).
467
560
 
468
561
  See [`docs/cli-design.md`](./docs/cli-design.md) §13 for the
469
- full roadmap, [`docs/v0.3-plan.md`](./docs/v0.3-plan.md) for the
470
- v0.3 milestone history, and
471
- [`docs/v0.2-plan.md`](./docs/v0.2-plan.md) for the v0.2 milestone
472
- history.
562
+ full roadmap, [`docs/v0.4-plan.md`](./docs/v0.4-plan.md) for the
563
+ v0.4 milestone history, [`docs/v0.3-plan.md`](./docs/v0.3-plan.md)
564
+ for v0.3, and [`docs/v0.2-plan.md`](./docs/v0.2-plan.md) for v0.2.
473
565
 
474
566
  See [CHANGELOG.md](./CHANGELOG.md) for the per-release contract.
475
567
 
@@ -513,7 +605,9 @@ The full dev workflow + how to add a new command is in
513
605
  - **No `any`** (lint-enforced).
514
606
  - **Parse at every boundary** with zod.
515
607
  - **Mock at the network boundary, not internal modules.**
516
- - **Branch coverage 95%+ floor** (v0.3 ratcheted from 94% see
608
+ - **Branch coverage 95.45% floor** for branches; 95% floor for
609
+ statements / functions / lines (v0.3-M22 ratcheted branches
610
+ from 94% via an OAuth coverage-push session — see
517
611
  `vitest.config.ts`).
518
612
  - **Atomic commits, Conventional Commits.**
519
613