monday-cli 0.5.0 → 0.7.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 (49) hide show
  1. package/CHANGELOG.md +665 -0
  2. package/README.md +209 -35
  3. package/dist/api/column-types.d.ts +81 -19
  4. package/dist/api/column-types.d.ts.map +1 -1
  5. package/dist/api/column-types.js +44 -11
  6. package/dist/api/column-types.js.map +1 -1
  7. package/dist/api/column-values.d.ts +22 -10
  8. package/dist/api/column-values.d.ts.map +1 -1
  9. package/dist/api/column-values.js +50 -20
  10. package/dist/api/column-values.js.map +1 -1
  11. package/dist/api/file-column-set.d.ts +613 -0
  12. package/dist/api/file-column-set.d.ts.map +1 -0
  13. package/dist/api/file-column-set.js +568 -0
  14. package/dist/api/file-column-set.js.map +1 -0
  15. package/dist/api/raw-write.d.ts +38 -17
  16. package/dist/api/raw-write.d.ts.map +1 -1
  17. package/dist/api/raw-write.js +62 -25
  18. package/dist/api/raw-write.js.map +1 -1
  19. package/dist/api/resolver-error-fold.d.ts +25 -0
  20. package/dist/api/resolver-error-fold.d.ts.map +1 -1
  21. package/dist/api/resolver-error-fold.js +56 -0
  22. package/dist/api/resolver-error-fold.js.map +1 -1
  23. package/dist/commands/board/column-create.d.ts +13 -3
  24. package/dist/commands/board/column-create.d.ts.map +1 -1
  25. package/dist/commands/board/column-create.js +27 -8
  26. package/dist/commands/board/column-create.js.map +1 -1
  27. package/dist/commands/item/create.d.ts +24 -8
  28. package/dist/commands/item/create.d.ts.map +1 -1
  29. package/dist/commands/item/create.js +601 -44
  30. package/dist/commands/item/create.js.map +1 -1
  31. package/dist/commands/item/set.d.ts +33 -3
  32. package/dist/commands/item/set.d.ts.map +1 -1
  33. package/dist/commands/item/set.js +193 -15
  34. package/dist/commands/item/set.js.map +1 -1
  35. package/dist/commands/item/update.d.ts +203 -3
  36. package/dist/commands/item/update.d.ts.map +1 -1
  37. package/dist/commands/item/update.js +1015 -68
  38. package/dist/commands/item/update.js.map +1 -1
  39. package/dist/commands/item/upload.d.ts.map +1 -1
  40. package/dist/commands/item/upload.js +16 -69
  41. package/dist/commands/item/upload.js.map +1 -1
  42. package/dist/commands/update/upload.d.ts.map +1 -1
  43. package/dist/commands/update/upload.js +9 -59
  44. package/dist/commands/update/upload.js.map +1 -1
  45. package/dist/utils/file-source.d.ts +93 -0
  46. package/dist/utils/file-source.d.ts.map +1 -0
  47. package/dist/utils/file-source.js +140 -0
  48. package/dist/utils/file-source.js.map +1 -0
  49. package/package.json +1 -1
@@ -0,0 +1,568 @@
1
+ /**
2
+ * Files-shaped friendly `--set` dispatch (`cli-design.md` §5.3
3
+ * writer-expansion roadmap "files" row + §13 v0.6 entry,
4
+ * `v0.6-plan.md` §3 M38).
5
+ *
6
+ * **Status: runtime bodies shipped at v0.6-M38 IMPL.** The dispatch
7
+ * type signatures + the per-mutex-rejection error shape + the
8
+ * fetcher wrapping M31's `addFileToColumn` all landed at pre-flight;
9
+ * IMPL swaps the c8-ignored stub bodies for runtime logic. No new
10
+ * wire fetcher (M38 reuses the v0.4-M31 multipart wire verbatim);
11
+ * no new transport seam.
12
+ *
13
+ * **Wire surface.** Zero net change. When `monday item set <iid>
14
+ * <file-col>=<path>` OR `monday item update <iid> --set
15
+ * <file-col>=<path>` resolves to a `file`-typed column, the
16
+ * command action body branches OFF the standard JSON-translator
17
+ * path INTO M31's multipart `addFileToColumn` fetcher via
18
+ * `executeFileColumnSet` below. The translator
19
+ * (`translateColumnValueAsync` in `column-values.ts`) stays
20
+ * JSON-output-shaped for the 13 existing writable types — the
21
+ * file-column dispatch is a SIBLING leg routed at the command
22
+ * action body level, NOT a new payload format inside the
23
+ * translator union.
24
+ *
25
+ * **Why a sibling leg, not a translator widening.** Three reasons
26
+ * pin the design (cli-design §5.3 step 4 + step 5 prose):
27
+ *
28
+ * 1. The wire surface is fundamentally different — multipart
29
+ * `add_file_to_column` vs JSON `change_column_value` /
30
+ * `change_multiple_column_values`. Folding the file payload
31
+ * into `ColumnValuePayload` would require a `format: 'file'`
32
+ * union variant that `selectMutation` can't bundle into the
33
+ * multi-mutation (each `add_file_to_column` is a single
34
+ * per-column multipart round-trip; bundling N file uploads
35
+ * into one mutation isn't a Monday wire shape).
36
+ * 2. The atomicity contract differs — the 13 existing types
37
+ * bundle atomically via `change_multiple_column_values` when
38
+ * ≥2 columns target the same item. File-column writes are
39
+ * single-column-per-call only on Monday's wire; mixing a
40
+ * file-column `--set` with any value `--set` / `--set-raw` /
41
+ * `--name` in the same call would force a multi-leg dispatch
42
+ * that breaks the existing atomicity guarantee. M38 enforces
43
+ * single-file-only via the mutex rules below (D2 closure) —
44
+ * the existing atomicity contract stays intact.
45
+ * 3. The translator's input contract is "value-string-to-JSON-
46
+ * payload" — file columns take a file path, not a value
47
+ * string. Path validation + `fs.stat` + `fs.access(R_OK)` +
48
+ * Blob construction don't fit the translator's pure-function
49
+ * shape; routing the path through the sibling leg keeps each
50
+ * helper focused.
51
+ *
52
+ * **Reuse from v0.4-M31.** The wire dispatch reuses
53
+ * `addFileToColumn` from `src/api/assets.ts` verbatim — same
54
+ * `MultipartTransport.request(...)` round-trip, same `withRetry`
55
+ * shape, same `file_too_large` rewrap-inside-retry-thunk pattern
56
+ * (R-v0.4-W2 axis 7 "non-retryable rewrap placement" carries
57
+ * through safely-by-construction since the dispatch goes through
58
+ * the existing fetcher rather than a re-implementation).
59
+ *
60
+ * **Consumer counts post v0.6-M38 IMPL close** (runtime bodies
61
+ * shipped at `e749931` + the R-v0.6-NEW-1 lift at `3c2a9b0`;
62
+ * pre-flight stubs collapsed):
63
+ *
64
+ * - `addFileToColumn` (M31): 2 consumers (M31's `item upload`
65
+ * action body + M38's `executeFileColumnSet` runtime body).
66
+ * - `MultipartTransport` via `ResolvedClient.multipart`: 2
67
+ * consumers (the same test seam pattern; M31's two upload
68
+ * verbs + M38's dispatch share the slot).
69
+ * - `sniffContentType` from `src/utils/mime.ts`: 2 consumers
70
+ * post-lift (M31's `item upload` + M31's `update upload` —
71
+ * both via {@link buildBlobFromPath}; M38 routes through
72
+ * `buildBlobFromPath` rather than calling `sniffContentType`
73
+ * directly).
74
+ * - **R-v0.6-NEW-1 SHIPPED at IMPL kickoff**: the file-pre-check
75
+ * + Blob-construction pattern lifted to `src/utils/file-source
76
+ * .ts` (`precheckLocalFile` + `buildBlobFromPath` — 3 consumers
77
+ * post-lift: M31's `item upload`, M31's `update upload`, M38's
78
+ * `executeFileColumnSet`).
79
+ *
80
+ * **Mutex rules (D2 closure).** Enforced at the column-resolution
81
+ * boundary (parse-time can't know — column types only resolve
82
+ * after metadata loads). When any resolved column has `type ===
83
+ * 'file'`:
84
+ *
85
+ * - Exactly ONE file `--set` entry allowed per call (single-
86
+ * file scope; multi-file dispatch defers to v0.7.x — Monday's
87
+ * `add_file_to_column` is single-column per call on the wire
88
+ * regardless of how many items the dispatch fans out across,
89
+ * so this rule is universal).
90
+ * - NO other value `--set` / `--set-raw` / `--name` flags
91
+ * allowed (mixing would force non-atomic multi-leg dispatch
92
+ * across the multipart + JSON wire surfaces).
93
+ * - Bulk `item update --where ... --set <file-col>=<path>` —
94
+ * **CARVED OUT at v0.7-M42** (D5 fold). At v0.6-M38 this was
95
+ * REJECTED with `'file_set_on_bulk_unsupported'`; v0.7-M42's
96
+ * pre-flight contract diff returns
97
+ * `{ kind: 'file_bulk', columnId, rawValue }` from
98
+ * {@link enforceSingleFileColumnSet} on the clean dispatch
99
+ * path so the action body can branch into the per-item
100
+ * multipart fan-out. Multi-file / mixed mutex rules STILL
101
+ * apply on bulk (those are universal).
102
+ * - `item create --set <file-col>=<path>` — **CARVED OUT at
103
+ * v0.7-M43** (D6 fold). At v0.6-M38 this was REJECTED with
104
+ * `'file_set_on_create_unsupported'`; v0.7-M43's pre-flight
105
+ * contract diff returns
106
+ * `{ kind: 'file_create', columnId, rawValue }` from
107
+ * {@link enforceSingleFileColumnSet} on the clean dispatch
108
+ * path so the action body can branch into the two-leg
109
+ * dispatch (`create_item` then `add_file_to_column`).
110
+ * Multi-file mutex rule STILL applies on create (universal).
111
+ * The mixed rule is callShape-aware: on `'item_create'` the
112
+ * `--name` arm + non-file value `--set` / `--set-raw` arms
113
+ * are SUPPRESSED (leg-1 `create_item` natively bundles
114
+ * `column_values` atomically + `item_name` is required on
115
+ * create); the D3 `--set-raw <file-col>=<json>` rejection
116
+ * at `raw-write.ts:translateRawColumnValue` stays in force
117
+ * (separate enforcement layer).
118
+ *
119
+ * Rejection surfaces share the `usage_error.details.reason`
120
+ * discriminator pattern from M14 / M27 / M31:
121
+ *
122
+ * - `'mixed_file_and_value_sets'` — file `--set` + any value
123
+ * `--set` / `--set-raw` / `--name` in same call. Applies on
124
+ * single-item AND bulk call shapes (universal mutex rule).
125
+ * - `'multi_file_set_unsupported'` — 2+ file `--set` entries
126
+ * in same call. Applies on single-item AND bulk call shapes
127
+ * (universal mutex rule).
128
+ * - `'file_set_on_bulk_unsupported'` — **NO LONGER SURFACES**
129
+ * at v0.7-M42 onwards. Historical reference only; the
130
+ * discriminator literal stays reserved across the codebase
131
+ * (do not reuse for a different rejection reason).
132
+ * - `'file_set_on_create_unsupported'` — **NO LONGER SURFACES**
133
+ * at v0.7-M43 onwards. Historical reference only; the
134
+ * discriminator literal stays reserved across the codebase
135
+ * (do not reuse for a different rejection reason).
136
+ *
137
+ * **D3 closure — `--set-raw <file-col>=<json>` STAYS REJECTED.**
138
+ * Files have no JSON wire shape Monday's `change_column_value`
139
+ * accepts; the escape-hatch contract "user supplies the JSON
140
+ * `change_column_value` accepts" doesn't compose with the
141
+ * multipart wire. The existing rejection at
142
+ * `raw-write.ts:translateRawColumnValue` stays unchanged; the
143
+ * prose enumerates every shipped friendly write path (v0.6-M38
144
+ * single-item, v0.7-M42 bulk, v0.7-M43 create-time, v0.4-M31
145
+ * verb-shaped upload) so agents reading the `--set-raw`
146
+ * rejection see the full set of working alternatives rather
147
+ * than just the M38 single-item form.
148
+ *
149
+ * **D7 closure — `<path>='-'` stdin support OUT OF SCOPE.**
150
+ * Mirrors M31 `monday item upload`'s rejection rationale — no
151
+ * clean `--filename` companion shape pinned for `--set
152
+ * <file-col>=-` syntax (stdin reads byte-anonymously; the
153
+ * filename is the load-bearing handle for Monday's wire
154
+ * `Asset.name` slot). Carry-forward candidate for v0.7.x once a
155
+ * `--filename` companion shape is pinned.
156
+ *
157
+ * **No new ERROR_CODE (D8 closure; registry stays at 29).** All
158
+ * M38-specific rejections route through existing `usage_error`
159
+ * with `details.reason` discrimination.
160
+ *
161
+ * **R-NEW-41 4th supporting site filed at M38 pre-flight.** The
162
+ * `--set` syntax is type-uniform from the agent's view
163
+ * (`<col>=<value>`), but for file columns the value is a path
164
+ * and the dispatch transitions silently from JSON to multipart at
165
+ * the translator boundary. The asymmetry is at the AGENT-INPUT
166
+ * boundary, NOT at the wire boundary (M31's multipart-vs-JSON
167
+ * asymmetry #3 is wire-boundary-only). See `docs/architecture.md`
168
+ * "Wire-vs-CLI semantics documentation conventions" for the
169
+ * canonical cross-link.
170
+ */
171
+ import { z } from 'zod';
172
+ import { ApiError } from '../utils/errors.js';
173
+ import { buildBlobFromPath } from '../utils/file-source.js';
174
+ import { addFileToColumn, assetSchema } from './assets.js';
175
+ import { resolveColumnWithRefresh } from './columns.js';
176
+ import { foldResolverWarningsIntoError } from './resolver-error-fold.js';
177
+ import { buildColumnArchivedError } from './resolution-pass.js';
178
+ import { mergeSource, mergeCacheAge } from './source-aggregator.js';
179
+ /**
180
+ * Output envelope shape for the file-column `--set` dispatch leg.
181
+ * Mirrors `itemUploadOutputSchema` from `src/api/assets.ts` so the
182
+ * envelope shape is byte-equivalent to M31 `monday item upload` for
183
+ * an agent reading the result — the dispatch source differs
184
+ * (`monday item set` / `monday item update` vs `monday item upload`)
185
+ * but the envelope payload structure is identical.
186
+ *
187
+ * The `operation` slot pins `'add_file_to_column'` literally
188
+ * (mirroring M31's envelope discriminator); agents reading
189
+ * `data.operation` can branch uniformly on the wire mutation
190
+ * regardless of which CLI verb routed there.
191
+ */
192
+ export const fileColumnSetOutputSchema = z
193
+ .object({
194
+ operation: z.literal('add_file_to_column'),
195
+ item_id: z.string().min(1),
196
+ column_id: z.string().min(1),
197
+ filename: z.string().min(1),
198
+ file_size_bytes: z.number().int().nonnegative(),
199
+ asset: assetSchema,
200
+ })
201
+ .strict();
202
+ /**
203
+ * Reads the local file at `inputs.entry.filePath`, constructs a Blob
204
+ * via {@link buildBlobFromPath} (with `Content-Type` sniffed from the
205
+ * filename), and dispatches the multipart upload through M31's
206
+ * {@link addFileToColumn} fetcher (cli-design §5.3 step 5 + the
207
+ * module docstring above pin the load-bearing design).
208
+ *
209
+ * **Status: runtime body shipped at v0.6-M38 IMPL.** Wraps M31's
210
+ * fetcher verbatim — same `operationName: 'AddFileToColumn'`, same
211
+ * `withRetry(...)` retry semantics, same rewrap-inside-retry-thunk
212
+ * pattern for `file_too_large` (R-v0.4-W2 axis 7 carries through
213
+ * safely-by-construction since the dispatch goes through the
214
+ * existing fetcher rather than a re-implementation).
215
+ *
216
+ * The action-body caller (in `item set` / `item update`) is
217
+ * responsible for:
218
+ *
219
+ * 1. Parsing argv + collecting `--set` / `--set-raw` / `--name`
220
+ * entries.
221
+ * 2. Resolving columns via `resolveColumnWithRefresh`.
222
+ * 3. Calling {@link enforceSingleFileColumnSet} to detect the
223
+ * file-column dispatch leg + enforce the mutex rules.
224
+ * 4. Running {@link precheckLocalFile} from
225
+ * `src/utils/file-source.ts` on the agent-supplied path to
226
+ * build a {@link FileColumnSetEntry} (the precheck surfaces
227
+ * `usage_error.details.reason: 'file_not_readable'` /
228
+ * `'file_empty'` before any wire activity per the M31
229
+ * ordering invariant).
230
+ * 5. Calling this fetcher for the wire dispatch.
231
+ * 6. Emitting the envelope per `fileColumnSetOutputSchema`
232
+ * (mirrors M31 `item upload` envelope verbatim).
233
+ */
234
+ export const executeFileColumnSet = async (inputs) => {
235
+ const blob = await buildBlobFromPath({
236
+ filePath: inputs.entry.filePath,
237
+ filename: inputs.entry.filename,
238
+ fileSizeBytes: inputs.entry.fileSizeBytes,
239
+ });
240
+ const result = await addFileToColumn({
241
+ client: inputs.client,
242
+ multipart: inputs.multipart,
243
+ itemId: inputs.itemId,
244
+ columnId: inputs.entry.columnId,
245
+ file: blob,
246
+ filename: inputs.entry.filename,
247
+ signal: inputs.signal,
248
+ retries: inputs.retries,
249
+ });
250
+ return {
251
+ asset: result.asset,
252
+ source: 'live',
253
+ cacheAgeSeconds: null,
254
+ complexity: result.complexity,
255
+ };
256
+ };
257
+ /**
258
+ * Iterates `inputs.setEntries`, identifies entries with
259
+ * `columnType === 'file'`, applies the mutex rules per D2 / D5 / D6
260
+ * closures, and returns either `{ kind: 'json' }` (no file entries),
261
+ * `{ kind: 'file', columnId, rawValue }` (clean dispatch path), or
262
+ * throws `ApiError('usage_error', ...)` on a mutex violation.
263
+ *
264
+ * Mutex priority (ratified at M38 pre-flight; updated at v0.7-M42
265
+ * + v0.7-M43 pre-flights to fold the D5 bulk + D6 create carve-outs):
266
+ *
267
+ * 1. **callShape gate — NONE remaining post-v0.7-M43** — both
268
+ * `'item_update_bulk'` (D5 fold at v0.7-M42) and `'item_create'`
269
+ * (D6 fold at v0.7-M43) short-circuit-throws have been removed.
270
+ * Every callShape falls through to the universal multi-file
271
+ * gate + a callShape-aware mixed gate, then returns a per-
272
+ * callShape `kind` on the clean path.
273
+ * 2. **multi-file leg** — 2+ file `--set` entries (any callShape)
274
+ * surface `'multi_file_set_unsupported'`. Universal rule:
275
+ * Monday's `add_file_to_column` is single-column per call on
276
+ * the wire regardless of fan-out shape.
277
+ * 3. **mixed leg** — 1 file `--set` + any value `--set` /
278
+ * `--set-raw` / `--name` surfaces `'mixed_file_and_value_sets'`
279
+ * on `'item_set'` / `'item_update_single'` / `'item_update_bulk'`.
280
+ * Universal rule on those callShapes: mixing forces non-atomic
281
+ * multi-leg dispatch across the multipart + JSON wire surfaces.
282
+ * **SUPPRESSED on `'item_create'`** per v0.7-M43 D6 mixed-rule
283
+ * asymmetry — `create_item` natively bundles non-file
284
+ * `column_values` atomically into leg-1, and `--name` is
285
+ * required on create.
286
+ * 4. **clean leg** — 1 file `--set`, no mutex violation:
287
+ * - `'item_update_single'` / `'item_set'` → return
288
+ * `{ kind: 'file', columnId, rawValue }` for downstream
289
+ * {@link precheckLocalFile} + {@link executeFileColumnSet}
290
+ * (M38 path; unchanged).
291
+ * - `'item_update_bulk'` → return `{ kind: 'file_bulk',
292
+ * columnId, rawValue }` for the action body's per-item
293
+ * multipart fan-out (v0.7-M42 D5 carve-out fold).
294
+ * - `'item_create'` → return `{ kind: 'file_create', columnId,
295
+ * rawValue }` for the action body's two-leg `create_item`
296
+ * then `add_file_to_column` helper (v0.7-M43 D6 carve-out
297
+ * fold).
298
+ *
299
+ * The function is sync + pure. No I/O. Path validation lives at a
300
+ * SEPARATE step (`precheckLocalFile` from `src/utils/file-source.ts`)
301
+ * that the caller runs AFTER this function returns a `kind: 'file'`
302
+ * result.
303
+ */
304
+ export const enforceSingleFileColumnSet = (inputs) => {
305
+ const fileSetEntries = inputs.setEntries.filter((e) => e.columnType === 'file');
306
+ if (fileSetEntries.length === 0) {
307
+ return { kind: 'json' };
308
+ }
309
+ // callShape gate — NO callShape short-circuits at this layer
310
+ // post v0.7-M43. The v0.6-M38 `'item_create'` short-circuit-throw
311
+ // (`'file_set_on_create_unsupported'`) FOLDED at v0.7-M43 (D6):
312
+ // create-time file `--set` falls through to the universal multi-
313
+ // file gate + a callShape-aware mixed gate, then returns
314
+ // `{ kind: 'file_create', ... }` on the clean path. The discriminator
315
+ // literal `'file_set_on_create_unsupported'` stays RESERVED in
316
+ // docstrings + regression-guard tests; do not re-introduce it as a
317
+ // runtime rejection without a fresh contract decision. (Parallels
318
+ // the v0.7-M42 fold of `'file_set_on_bulk_unsupported'` for
319
+ // `'item_update_bulk'`.)
320
+ // Multi-file leg (D2 multi). 2+ file `--set` entries on any
321
+ // callShape — applies universally (single-item AND bulk) because
322
+ // Monday's `add_file_to_column` is single-column per call on the
323
+ // wire regardless of how many items the dispatch fans out across.
324
+ // Multi-file dispatch carries forward as a v0.7.x candidate.
325
+ if (fileSetEntries.length > 1) {
326
+ throw new ApiError('usage_error', `Multi-file \`--set <file-col>=<path>\` is not supported ` +
327
+ `(${String(fileSetEntries.length)} file \`--set\` entries ` +
328
+ `detected; deferred to v0.7.x per cli-design §5.3 + v0.6-plan ` +
329
+ `§3 M38 D2 closure — carry-forward from v0.6 unchanged at ` +
330
+ `v0.7-M42). Monday's \`add_file_to_column\` mutation is ` +
331
+ `single-column per call on the wire; multi-file dispatch + ` +
332
+ `concurrent multipart over the shared transport carry design ` +
333
+ `dimensions worth their own milestone. Pass exactly one ` +
334
+ `\`--set <file-col>=<path>\` per call; for multiple uploads, ` +
335
+ `run separate calls.`, {
336
+ details: {
337
+ reason: 'multi_file_set_unsupported',
338
+ file_count: fileSetEntries.length,
339
+ file_column_ids: fileSetEntries.map((e) => e.columnId),
340
+ deferred_to: 'v0.7.x',
341
+ hint: 'pass exactly one `--set <file-col>=<path>` per call; ' +
342
+ 'run separate calls for multiple file uploads.',
343
+ },
344
+ });
345
+ }
346
+ // Mixed leg (D2). 1 file `--set` + any value `--set` / `--set-raw`
347
+ // / `--name` — surfaces because Monday's wire has no atomic combo
348
+ // of multipart `add_file_to_column` + JSON `change_column_value` /
349
+ // `change_multiple_column_values` (mixing forces non-atomic
350
+ // multi-leg dispatch that breaks the §5.3 atomicity contract).
351
+ //
352
+ // v0.7-M43 callShape carve-out (D6 mixed-rule asymmetry): on
353
+ // `'item_create'` the two-leg dispatch (`create_item` with bundled
354
+ // non-file column_values then `add_file_to_column`) absorbs the
355
+ // mixed scenarios into leg-1 atomicity for the non-file values +
356
+ // leg-2 atomicity for the file. `--name` is REQUIRED on create
357
+ // (not an opt-in rename like on update), so the universal `hasName`
358
+ // arm would auto-reject every M43 path; suppress on `'item_create'`.
359
+ // Non-file value `--set` + `--set-raw` entries are ALSO allowed on
360
+ // create-time mixed (they bundle into leg-1's `column_values`); the
361
+ // separate D3 `--set-raw <file-col>=<json>` rejection still applies
362
+ // at `raw-write.ts:translateRawColumnValue` for `file`-typed raw
363
+ // tokens, so the action-body path stays safe. The non-create
364
+ // callShapes ('item_set' / 'item_update_single' / 'item_update_bulk')
365
+ // keep the universal mixed rule unchanged.
366
+ const nonFileSetCount = inputs.setEntries.length - fileSetEntries.length;
367
+ const setRawCount = inputs.setRawEntries.length;
368
+ const mixedApplies = inputs.callShape !== 'item_create' &&
369
+ (nonFileSetCount > 0 || setRawCount > 0 || inputs.hasName);
370
+ if (mixedApplies) {
371
+ const fe = fileSetEntries[0];
372
+ /* c8 ignore next 3 */
373
+ if (fe === undefined) {
374
+ throw new ApiError('internal_error', 'enforceSingleFileColumnSet: file entry narrowing failed (mixed)');
375
+ }
376
+ throw new ApiError('usage_error', `Mixing a file \`--set <file-col>=<path>\` with value \`--set\` / ` +
377
+ `\`--set-raw\` / \`--name\` in the same call is not supported at ` +
378
+ `v0.6-M38 (per cli-design §5.3 + v0.6-plan §3 M38 D2 closure). ` +
379
+ `Monday's wire has no atomic combo of multipart ` +
380
+ `\`add_file_to_column\` + JSON \`change_column_value\` / ` +
381
+ `\`change_multiple_column_values\`; mixing would force a non-` +
382
+ `atomic multi-leg dispatch that breaks the existing atomicity ` +
383
+ `contract. Run the file dispatch in its own call.`, {
384
+ details: {
385
+ reason: 'mixed_file_and_value_sets',
386
+ column_id: fe.columnId,
387
+ non_file_set_count: nonFileSetCount,
388
+ set_raw_count: setRawCount,
389
+ has_name: inputs.hasName,
390
+ hint: 'run the file `--set` alone (e.g., `monday item set <iid> ' +
391
+ '<file-col>=<path>`); apply value writes / rename in a ' +
392
+ 'separate call (e.g., `monday item update <iid> --set ' +
393
+ 'status=Done --name "..."`).',
394
+ },
395
+ });
396
+ }
397
+ // Clean dispatch leg. Single file `--set`, no mutex violation.
398
+ // Discriminators:
399
+ // - `'item_update_single'` / `'item_set'` → `kind: 'file'`
400
+ // (M38 single-item path; unchanged).
401
+ // - `'item_update_bulk'` → `kind: 'file_bulk'` (v0.7-M42 D5
402
+ // carve-out fold; action body's per-item multipart fan-out).
403
+ // - `'item_create'` → `kind: 'file_create'` (v0.7-M43 D6
404
+ // carve-out fold; action body's two-leg `create_item` then
405
+ // `add_file_to_column` dispatch with orphan-warn atomicity
406
+ // envelope per D1 closure).
407
+ const fe = fileSetEntries[0];
408
+ /* c8 ignore next 3 */
409
+ if (fe === undefined) {
410
+ throw new ApiError('internal_error', 'enforceSingleFileColumnSet: file entry narrowing failed (clean)');
411
+ }
412
+ if (inputs.callShape === 'item_update_bulk') {
413
+ return { kind: 'file_bulk', columnId: fe.columnId, rawValue: fe.rawValue };
414
+ }
415
+ if (inputs.callShape === 'item_create') {
416
+ return { kind: 'file_create', columnId: fe.columnId, rawValue: fe.rawValue };
417
+ }
418
+ return { kind: 'file', columnId: fe.columnId, rawValue: fe.rawValue };
419
+ };
420
+ /**
421
+ * Resolves `setEntries` column types and runs the v0.6-M38 mutex
422
+ * check (per cli-design §5.3 step 5 "File-column dispatch leg —
423
+ * mutex rules"). The discipline: **enforce mutex at the column-
424
+ * resolution boundary**, not at the translator-rejection boundary.
425
+ * Pre-flight P2-1 + IMPL round-1 P2-2 both surfaced the
426
+ * translator-order-dependent priority drift that this resolution-
427
+ * boundary check fixes.
428
+ *
429
+ * **Why the pre-check fires at the action-body level rather than
430
+ * inside `resolveAndTranslate`.** The shared resolver helper is
431
+ * used by 5 sites (item set, item update single + bulk, item
432
+ * create); the M38 dispatch only applies to 3 (item update single
433
+ * + bulk + item create — item set has its own column resolution at
434
+ * the action body level for the single-positional shape). Folding
435
+ * M38 dispatch into `resolveAndTranslate` would couple the
436
+ * resolver helper to the file-dispatch leg; the action-body level
437
+ * pre-check keeps `resolveAndTranslate` translator-only.
438
+ *
439
+ * **Discriminating friendly `--set` vs `--set-raw`** — the
440
+ * pre-check operates on setEntries only. `--set-raw <file-col>=<json>`
441
+ * rejections come from `translateRawColumnValue` (D3 permanent
442
+ * rejection); the pre-check returns `kind: 'json'` for `--set-raw`
443
+ * file paths and the standard path's `resolveAndTranslate` /
444
+ * `planChanges` then surfaces the D3 `unsupported_column_type`
445
+ * rejection. The pre-check NEVER hijacks `--set-raw` paths into
446
+ * M38 dispatch.
447
+ *
448
+ * **Source aggregation contract.** Each resolveColumnWithRefresh
449
+ * call returns its own `source` / `cacheAgeSeconds`; the pre-check
450
+ * aggregates across `setEntries`. On the `'json'` branch the
451
+ * downstream `resolveAndTranslate` will re-resolve setEntries
452
+ * (cache hit) and produce another aggregation leg — the action
453
+ * body merges both aggregations so the final envelope reflects
454
+ * every wire / cache leg that fired. The `meta.source` of a
455
+ * non-file path with a single `--set` may surface as `'mixed'`
456
+ * (live pre-check + cache downstream) rather than `'live'`; this
457
+ * is correct per §6.1 source-aggregation rules — the second leg
458
+ * IS a cache hit.
459
+ */
460
+ export const preCheckM38FileDispatch = async (inputs) => {
461
+ const resolved = [];
462
+ let aggregateSource;
463
+ let aggregateCacheAge = null;
464
+ const warnings = [];
465
+ for (const entry of inputs.setEntries) {
466
+ const r = await resolveColumnWithRefresh({
467
+ client: inputs.client,
468
+ boardId: inputs.boardId,
469
+ token: entry.token,
470
+ includeArchived: true,
471
+ ...(inputs.env === undefined ? {} : { env: inputs.env }),
472
+ ...(inputs.noCache === undefined ? {} : { noCache: inputs.noCache }),
473
+ });
474
+ aggregateSource = mergeSource(aggregateSource, r.source);
475
+ aggregateCacheAge = mergeCacheAge(aggregateCacheAge, r.cacheAgeSeconds);
476
+ warnings.push(...r.warnings);
477
+ // Archived-column guard (mirrors `resolveAndTranslate`'s
478
+ // pass-(a) check). `includeArchived: true` above surfaces
479
+ // archived columns via the resolver rather than dropping them;
480
+ // the M38 dispatch must reject archived file columns with the
481
+ // stable `column_archived` error so agents key on the canonical
482
+ // shape regardless of write path. Round-2 P2-1 surfacing event:
483
+ // without this guard, `--set <archived_file_col>=<path>` on
484
+ // item update / create reached the M38 dispatch (emitting a
485
+ // successful file `planned_change` on dry-run, or local
486
+ // precheck + multipart dispatch on live) instead of the
487
+ // `column_archived` rejection.
488
+ if (r.match.column.archived === true) {
489
+ throw foldResolverWarningsIntoError(buildColumnArchivedError({
490
+ columnId: r.match.column.id,
491
+ columnTitle: r.match.column.title,
492
+ columnType: r.match.column.type,
493
+ boardId: inputs.boardId,
494
+ }), warnings);
495
+ }
496
+ resolved.push({
497
+ columnId: r.match.column.id,
498
+ columnType: r.match.column.type,
499
+ rawValue: entry.value,
500
+ token: entry.token,
501
+ });
502
+ }
503
+ // Synthesize setRawEntries inputs from the count — only length
504
+ // matters for the mutex check; columnId / columnType slots are
505
+ // unused on the mixed-set discriminator path.
506
+ const setRawEntries = Array.from({ length: inputs.setRawCount }, () => ({ columnId: '', columnType: '' }));
507
+ const enforcement = enforceSingleFileColumnSet({
508
+ callShape: inputs.callShape,
509
+ setEntries: resolved.map((r) => ({
510
+ columnId: r.columnId,
511
+ columnType: r.columnType,
512
+ rawValue: r.rawValue,
513
+ })),
514
+ setRawEntries,
515
+ hasName: inputs.hasName,
516
+ });
517
+ if (enforcement.kind === 'json') {
518
+ return {
519
+ kind: 'json',
520
+ warnings,
521
+ source: aggregateSource,
522
+ cacheAgeSeconds: aggregateCacheAge,
523
+ };
524
+ }
525
+ // enforcement.kind is `'file'` (single-item) OR `'file_bulk'`
526
+ // (v0.7-M42 D5 carve-out fold). Find the matching resolved entry
527
+ // for the file-column token (echo into resolved_ids downstream).
528
+ const fileResolved = resolved.find((r) => r.columnType === 'file' &&
529
+ r.columnId === enforcement.columnId &&
530
+ r.rawValue === enforcement.rawValue);
531
+ /* c8 ignore next 5 — defensive: enforcement returned the same
532
+ entry the pre-check passed in; the find must succeed. */
533
+ if (fileResolved === undefined) {
534
+ throw new ApiError('internal_error', 'preCheckM38FileDispatch: file entry not found in resolved set after enforcement');
535
+ }
536
+ if (enforcement.kind === 'file_bulk') {
537
+ return {
538
+ kind: 'file_bulk',
539
+ columnId: enforcement.columnId,
540
+ rawValue: enforcement.rawValue,
541
+ token: fileResolved.token,
542
+ warnings,
543
+ source: aggregateSource,
544
+ cacheAgeSeconds: aggregateCacheAge,
545
+ };
546
+ }
547
+ if (enforcement.kind === 'file_create') {
548
+ return {
549
+ kind: 'file_create',
550
+ columnId: enforcement.columnId,
551
+ rawValue: enforcement.rawValue,
552
+ token: fileResolved.token,
553
+ warnings,
554
+ source: aggregateSource,
555
+ cacheAgeSeconds: aggregateCacheAge,
556
+ };
557
+ }
558
+ return {
559
+ kind: 'file',
560
+ columnId: enforcement.columnId,
561
+ rawValue: enforcement.rawValue,
562
+ token: fileResolved.token,
563
+ warnings,
564
+ source: aggregateSource,
565
+ cacheAgeSeconds: aggregateCacheAge,
566
+ };
567
+ };
568
+ //# sourceMappingURL=file-column-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-column-set.js","sourceRoot":"","sources":["../../src/api/file-column-set.ts"],"names":[],"mappings":"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"}
@@ -22,12 +22,24 @@
22
22
  * from CLI-time to Monday-time with no new information.
23
23
  * * **`files`-shaped** (`file`, anything else where Monday
24
24
  * uses `add_file_to_column` rather than `change_column_value`)
25
- * → `unsupported_column_type` with `deferred_to: "v0.6"`.
26
- * The `--set-raw` payload reaches `change_column_value` /
27
- * `change_multiple_column_values` only; files-shaped types
28
- * can't be written through that wire surface. Hint points
29
- * at `monday item upload` (v0.4-M31 the verb-shaped
30
- * alternative path).
25
+ * → `unsupported_column_type` rejection STAYS per D3
26
+ * closure (permanent). The `--set-raw` payload reaches
27
+ * `change_column_value` / `change_multiple_column_values`
28
+ * only; files-shaped types can't be written through that
29
+ * wire surface (Monday's wire has no JSON-shape for
30
+ * `change_column_value` on file columns). The friendly
31
+ * `--set <file-col>=<path>` form ships across three
32
+ * shipped paths (v0.6-M38 single-item + v0.7-M42 bulk +
33
+ * v0.4-M31 verb-shaped upload — all dispatching into the
34
+ * multipart wire at the command action body) but keeps
35
+ * `--set-raw` rejected — the escape-hatch contract
36
+ * "user supplies JSON `change_column_value` accepts"
37
+ * doesn't compose with multipart. Hint enumerates every
38
+ * shipped multipart write path: v0.6-M38 single-item
39
+ * friendly `--set` form on `monday item set` + `monday
40
+ * item update <iid>`; v0.7-M42 bulk friendly `--set`
41
+ * form on `monday item update --where ...` (per-item
42
+ * fan-out); v0.4-M31 verb-shaped `monday item upload`.
31
43
  * Otherwise builds a `TranslatedColumnValue` with `payload:
32
44
  * { format: 'rich', value: <parsed> }` so the existing
33
45
  * `selectMutation` dispatcher handles it uniformly.
@@ -101,17 +113,26 @@ export declare const parseSetRawExpression: (raw: string) => ParsedSetRawExpress
101
113
  * - **Read-only-forever** → `unsupported_column_type` with
102
114
  * `read_only: true`. Monday computes these server-side; no
103
115
  * payload (raw or friendly) is ever accepted.
104
- * - **`files`-shaped** → `unsupported_column_type` with
105
- * `deferred_to: "v0.6"`. Monday writes via `add_file_to_column`
106
- * (multipart upload), not `change_column_value`; the raw
107
- * payload can't reach the right wire surface. Hint points at
108
- * `monday item upload` (shipped v0.4-M31; multipart wire the
109
- * alternative path agents should use today). The `deferred_to`
110
- * slot tracks the `--set-raw <file-col>=<json>` form
111
- * specifically; v0.4 shipped the verb-shaped path; v0.5 didn't
112
- * pick up the raw-payload-into-multipart-wire wiring either
113
- * (no escape-hatch-to-multipart dispatch landed); slot slipped
114
- * from v0.5 to v0.6 at v0.5 release-prep.
116
+ * - **`files`-shaped** → `unsupported_column_type` rejection
117
+ * STAYS per D3 closure (permanent). Monday writes via
118
+ * `add_file_to_column` (multipart upload), not
119
+ * `change_column_value`; the raw payload can't reach the
120
+ * right wire surface (Monday's wire has no JSON-shape for
121
+ * `change_column_value` on file columns). The friendly
122
+ * `--set <file-col>=<path>` form ships across four paths
123
+ * reaching the multipart wire: v0.6-M38 single-item friendly
124
+ * (`monday item set` + `monday item update <iid>`); v0.7-M42
125
+ * bulk friendly (`monday item update --where ...` per-item
126
+ * fan-out under `--concurrency` / `--continue-on-error`);
127
+ * v0.7-M43 create-time friendly (`monday item create --set
128
+ * <file-col>=<path>` two-leg `create_item` + `add_file_to_
129
+ * column` dispatch under the §5.8 orphan-warn atomicity
130
+ * envelope); v0.4-M31 verb-shaped (`monday item upload <iid>
131
+ * --column <col> <file>`). The escape-hatch contract "user
132
+ * supplies JSON `change_column_value` accepts" doesn't
133
+ * compose with multipart, so `--set-raw <file-col>=<json>`
134
+ * stays rejected regardless. Hint enumerates every shipped
135
+ * path.
115
136
  *
116
137
  * Anything else (writable + tentative-slipped + future where the API
117
138
  * accepts `change_column_value`) is accepted — the user took the
@@ -1 +1 @@
1
- {"version":3,"file":"raw-write.d.ts","sourceRoot":"","sources":["../../src/api/raw-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,sBA+DnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACtD,OAAO,UAAU,EACjB,SAAS,MAAM,KACd,qBAwEF,CAAC;AAsBF,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"raw-write.d.ts","sourceRoot":"","sources":["../../src/api/raw-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,sBA+DnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,uBAAuB,GAClC,QAAQ;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACtD,OAAO,UAAU,EACjB,SAAS,MAAM,KACd,qBAwFF,CAAC;AAsBF,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}