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.
- package/CHANGELOG.md +665 -0
- package/README.md +209 -35
- package/dist/api/column-types.d.ts +81 -19
- package/dist/api/column-types.d.ts.map +1 -1
- package/dist/api/column-types.js +44 -11
- package/dist/api/column-types.js.map +1 -1
- package/dist/api/column-values.d.ts +22 -10
- package/dist/api/column-values.d.ts.map +1 -1
- package/dist/api/column-values.js +50 -20
- package/dist/api/column-values.js.map +1 -1
- package/dist/api/file-column-set.d.ts +613 -0
- package/dist/api/file-column-set.d.ts.map +1 -0
- package/dist/api/file-column-set.js +568 -0
- package/dist/api/file-column-set.js.map +1 -0
- package/dist/api/raw-write.d.ts +38 -17
- package/dist/api/raw-write.d.ts.map +1 -1
- package/dist/api/raw-write.js +62 -25
- package/dist/api/raw-write.js.map +1 -1
- package/dist/api/resolver-error-fold.d.ts +25 -0
- package/dist/api/resolver-error-fold.d.ts.map +1 -1
- package/dist/api/resolver-error-fold.js +56 -0
- package/dist/api/resolver-error-fold.js.map +1 -1
- package/dist/commands/board/column-create.d.ts +13 -3
- package/dist/commands/board/column-create.d.ts.map +1 -1
- package/dist/commands/board/column-create.js +27 -8
- package/dist/commands/board/column-create.js.map +1 -1
- package/dist/commands/item/create.d.ts +24 -8
- package/dist/commands/item/create.d.ts.map +1 -1
- package/dist/commands/item/create.js +601 -44
- package/dist/commands/item/create.js.map +1 -1
- package/dist/commands/item/set.d.ts +33 -3
- package/dist/commands/item/set.d.ts.map +1 -1
- package/dist/commands/item/set.js +193 -15
- package/dist/commands/item/set.js.map +1 -1
- package/dist/commands/item/update.d.ts +203 -3
- package/dist/commands/item/update.d.ts.map +1 -1
- package/dist/commands/item/update.js +1015 -68
- package/dist/commands/item/update.js.map +1 -1
- package/dist/commands/item/upload.d.ts.map +1 -1
- package/dist/commands/item/upload.js +16 -69
- package/dist/commands/item/upload.js.map +1 -1
- package/dist/commands/update/upload.d.ts.map +1 -1
- package/dist/commands/update/upload.js +9 -59
- package/dist/commands/update/upload.js.map +1 -1
- package/dist/utils/file-source.d.ts +93 -0
- package/dist/utils/file-source.d.ts.map +1 -0
- package/dist/utils/file-source.js +140 -0
- package/dist/utils/file-source.js.map +1 -0
- package/package.json +1 -1
|
@@ -23,14 +23,30 @@
|
|
|
23
23
|
* v0.3 because the column-resolution path here assumes the
|
|
24
24
|
* classic auto-generated-subitems-board model.
|
|
25
25
|
*
|
|
26
|
-
* **Single round-trip** (cli-design §5.8 —
|
|
27
|
-
* translated `--set` / `--set-raw`
|
|
28
|
-
* `create_item.column_values` (or
|
|
29
|
-
* parameter via `bundleColumnValues`;
|
|
30
|
-
* to `create_item` +
|
|
31
|
-
* failure. Monday's
|
|
32
|
-
*
|
|
33
|
-
* value fixed.
|
|
26
|
+
* **Single round-trip on the JSON-only path** (cli-design §5.8 —
|
|
27
|
+
* hard exit gate). Every translated non-file `--set` / `--set-raw`
|
|
28
|
+
* value bundles into one `create_item.column_values` (or
|
|
29
|
+
* `create_subitem.column_values`) parameter via `bundleColumnValues`;
|
|
30
|
+
* the CLI does **not** fall back to `create_item` +
|
|
31
|
+
* `change_multiple_column_values` on partial failure. Monday's
|
|
32
|
+
* server-side rejection of any value fails the whole mutation, and
|
|
33
|
+
* no item is created — agents retry with the value fixed.
|
|
34
|
+
*
|
|
35
|
+
* **Two-leg dispatch on the create-time file `--set` carve-out
|
|
36
|
+
* (v0.7-M43 D6 fold).** When any `--set <file-col>=<path>` is
|
|
37
|
+
* present, the action body partitions setEntries (non-file →
|
|
38
|
+
* leg-1's `column_values`; file → leg-2) and routes through
|
|
39
|
+
* `runItemCreateFileDispatch`: leg-1 `create_item` (or
|
|
40
|
+
* `create_subitem`) bundles the non-file column_values atomically;
|
|
41
|
+
* leg-2 `add_file_to_column` attaches the file via M31's multipart
|
|
42
|
+
* wire (reused verbatim through M38's `executeFileColumnSet`). The
|
|
43
|
+
* pair is non-atomic by construction; leg-2 failure surfaces
|
|
44
|
+
* `internal_error` with `details.reason:
|
|
45
|
+
* 'create_then_file_upload_partial_failure'` + `details.cause` +
|
|
46
|
+
* `details.created_item_id` echoing the orphan + a hint directing
|
|
47
|
+
* agents to retry leg-2 only OR rollback via `monday item delete`
|
|
48
|
+
* (cli-design §5.8 orphan-warn atomicity envelope, D1 closure). See
|
|
49
|
+
* `runItemCreateFileDispatch` below for the helper signature.
|
|
34
50
|
*
|
|
35
51
|
* **`--position` / `--relative-to` cross-validation.** Both flags
|
|
36
52
|
* are required together (one without the other → `usage_error`).
|
|
@@ -50,22 +66,46 @@
|
|
|
50
66
|
import { z } from 'zod';
|
|
51
67
|
import { ensureSubcommand } from '../types.js';
|
|
52
68
|
import { emitDryRun, emitMutation } from '../emit.js';
|
|
53
|
-
import { resolveClient } from '../../api/resolve-client.js';
|
|
69
|
+
import { resolveClient, } from '../../api/resolve-client.js';
|
|
54
70
|
import { BoardIdSchema, ItemIdSchema } from '../../types/ids.js';
|
|
55
71
|
import { parseArgv } from '../parse-argv.js';
|
|
56
72
|
import { ApiError, MondayCliError, UsageError } from '../../utils/errors.js';
|
|
57
73
|
import { bundleColumnValues, } from '../../api/column-values.js';
|
|
58
74
|
import { parseSetRawExpression, } from '../../api/raw-write.js';
|
|
59
75
|
import { splitSetExpression } from '../../api/set-expression.js';
|
|
60
|
-
import { buildResolutionContexts } from '../../api/resolution-context.js';
|
|
76
|
+
import { buildResolutionContexts, } from '../../api/resolution-context.js';
|
|
61
77
|
import { lookupItemBoard, lookupItemBoardWithHierarchy, } from '../../api/item-board-lookup.js';
|
|
62
|
-
import { SourceAggregator,
|
|
78
|
+
import { SourceAggregator, mergeCacheAge, mergeSourceWithPreflight, } from '../../api/source-aggregator.js';
|
|
63
79
|
import { resolveAndTranslate } from '../../api/resolution-pass.js';
|
|
64
|
-
import {
|
|
80
|
+
import { executeFileColumnSet, preCheckM38FileDispatch, } from '../../api/file-column-set.js';
|
|
81
|
+
import { foldAndRemap, mergeResolverWarningsIntoError, } from '../../api/resolver-error-fold.js';
|
|
65
82
|
import { planCreate } from '../../api/dry-run.js';
|
|
66
83
|
import { loadBoardMetadata } from '../../api/board-metadata.js';
|
|
67
84
|
import { assertResponseFieldPresent } from '../../api/response-root.js';
|
|
68
85
|
import { unwrapOrThrow } from '../../utils/parse-boundary.js';
|
|
86
|
+
import { precheckLocalFile } from '../../utils/file-source.js';
|
|
87
|
+
import { invalidateBoard } from '../../api/cache.js';
|
|
88
|
+
/**
|
|
89
|
+
* Dedupes resolver warnings by `code + message + details.token`.
|
|
90
|
+
* v0.6-M38 IMPL round-2 P3-1 fix: M38 pre-check + downstream
|
|
91
|
+
* resolveAndTranslate / planCreate can both observe the same
|
|
92
|
+
* `stale_cache_refreshed` / `column_token_collision` warning;
|
|
93
|
+
* dedupe ensures each surfaces exactly once. Same shape as the
|
|
94
|
+
* bulk-update `dedupeWarnings` helper.
|
|
95
|
+
*/
|
|
96
|
+
const dedupeCreateWarnings = (warnings) => {
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const out = [];
|
|
99
|
+
for (const w of warnings) {
|
|
100
|
+
const tokenKey = typeof w.details?.token === 'string' ? w.details.token : '';
|
|
101
|
+
const key = `${w.code}|${w.message}|${tokenKey}`;
|
|
102
|
+
if (seen.has(key))
|
|
103
|
+
continue;
|
|
104
|
+
seen.add(key);
|
|
105
|
+
out.push(w);
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
};
|
|
69
109
|
// ============================================================
|
|
70
110
|
// GraphQL mutations. The parent lookup + relative-to lookup queries
|
|
71
111
|
// live in api/item-board-lookup.ts (R23 lift).
|
|
@@ -420,13 +460,13 @@ const resolveCreateMode = async (inputs) => {
|
|
|
420
460
|
`creation is deferred. Use a classic board ` +
|
|
421
461
|
`(hierarchy_type null/"classic"). v0.3 M28 Decision 11 closure: ` +
|
|
422
462
|
`Monday's sub_items_board carries no subtasks column at API ` +
|
|
423
|
-
`2026-01, so depth-2 subitems have no data-model home — v0.
|
|
463
|
+
`2026-01, so depth-2 subitems have no data-model home — v0.8 ` +
|
|
424
464
|
`picks the feature up if Monday surfaces the capability.`, {
|
|
425
465
|
details: {
|
|
426
466
|
parent_item_id: dispatch.parentItemId,
|
|
427
467
|
parent_board_id: parent.boardId,
|
|
428
468
|
hierarchy_type: parent.hierarchyType,
|
|
429
|
-
deferred_to: 'v0.
|
|
469
|
+
deferred_to: 'v0.8',
|
|
430
470
|
},
|
|
431
471
|
});
|
|
432
472
|
}
|
|
@@ -541,7 +581,7 @@ export const itemCreateCommand = {
|
|
|
541
581
|
const parsed = parseArgv(itemCreateCommand.inputSchema, {
|
|
542
582
|
...opts,
|
|
543
583
|
});
|
|
544
|
-
const { client, globalFlags, apiVersion, toEmit } = resolveClient(ctx, program.opts());
|
|
584
|
+
const { client, globalFlags, apiVersion, multipart, toEmit } = resolveClient(ctx, program.opts());
|
|
545
585
|
const dispatch = validateInputShape(parsed);
|
|
546
586
|
// Argv-parse-time failures fire BEFORE any network call —
|
|
547
587
|
// splits run on pure strings, JSON parse on `--set-raw` runs
|
|
@@ -578,57 +618,177 @@ export const itemCreateCommand = {
|
|
|
578
618
|
? createMode.subitemsBoardId
|
|
579
619
|
: createMode.boardId;
|
|
580
620
|
const { dateResolution, peopleResolution, tagResolution, relationResolution } = buildResolutionContexts({ client, ctx, globalFlags });
|
|
581
|
-
|
|
582
|
-
|
|
621
|
+
// v0.6-M38 / v0.7-M43 D6 closure — create-time file-set
|
|
622
|
+
// dispatch routes through the column-resolution boundary's
|
|
623
|
+
// pre-check. Pre-checks setEntries against the resolved
|
|
624
|
+
// create-mode board (subitems board for subitem create;
|
|
625
|
+
// --board for top-level), then returns one of:
|
|
626
|
+
// - `kind: 'json'` — no file column in `--set` (existing
|
|
627
|
+
// bundled-create path runs below).
|
|
628
|
+
// - `kind: 'file_create'` — clean single-file `--set`
|
|
629
|
+
// entry; branches into the v0.7-M43 two-leg dispatch
|
|
630
|
+
// helper {@link runItemCreateFileDispatch} (carve-out
|
|
631
|
+
// fold from v0.6-M38's permanent rejection).
|
|
632
|
+
// - Throws `usage_error` with
|
|
633
|
+
// `details.reason: 'multi_file_set_unsupported'` on 2+
|
|
634
|
+
// file `--set` entries (universal mutex rule). The
|
|
635
|
+
// `'mixed_file_and_value_sets'` rule is SUPPRESSED on
|
|
636
|
+
// `'item_create'` callShape per the v0.7-M43 D6 mixed-
|
|
637
|
+
// rule asymmetry — `create_item` natively bundles
|
|
638
|
+
// non-file `column_values` atomically into leg-1.
|
|
639
|
+
// `--set-raw <file-col>=<json>` stays at
|
|
640
|
+
// `translateRawColumnValue`'s D3 permanent rejection (the
|
|
641
|
+
// pre-check inspects setEntries only).
|
|
642
|
+
let m38Source;
|
|
643
|
+
let m38CacheAge = null;
|
|
644
|
+
let m38Warnings = [];
|
|
645
|
+
let m38FileCreate;
|
|
646
|
+
if (setEntries.length > 0) {
|
|
647
|
+
const m38 = await preCheckM38FileDispatch({
|
|
583
648
|
client,
|
|
584
|
-
|
|
585
|
-
name: parsed.name,
|
|
649
|
+
boardId: resolveBoardId,
|
|
586
650
|
setEntries,
|
|
587
|
-
|
|
651
|
+
setRawCount: rawEntries.length,
|
|
652
|
+
hasName: true,
|
|
653
|
+
callShape: 'item_create',
|
|
654
|
+
env: ctx.env,
|
|
655
|
+
noCache: globalFlags.noCache,
|
|
656
|
+
});
|
|
657
|
+
m38Source = m38.source;
|
|
658
|
+
m38CacheAge = m38.cacheAgeSeconds;
|
|
659
|
+
m38Warnings = m38.warnings;
|
|
660
|
+
if (m38.kind === 'file_create') {
|
|
661
|
+
m38FileCreate = m38;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
// v0.6-M38 → v0.7-M43 D6 fold — branch into the two-leg
|
|
665
|
+
// dispatch helper. {@link runItemCreateFileDispatch} runs
|
|
666
|
+
// the upfront `precheckLocalFile` + partitions setEntries
|
|
667
|
+
// (non-file → leg-1 `column_values`, file → leg-2
|
|
668
|
+
// `add_file_to_column`) + dispatches leg-1 `create_item`
|
|
669
|
+
// / `create_subitem` then leg-2 `add_file_to_column` under
|
|
670
|
+
// the §5.8 orphan-warn atomicity envelope (D1 closure).
|
|
671
|
+
// Reaching this branch means argv parse + shape validation
|
|
672
|
+
// + duplicate-token check + create-mode resolution + M38
|
|
673
|
+
// pre-check all succeeded.
|
|
674
|
+
if (m38FileCreate !== undefined) {
|
|
675
|
+
await runItemCreateFileDispatch({
|
|
676
|
+
parsed,
|
|
677
|
+
client,
|
|
678
|
+
multipart,
|
|
679
|
+
ctx,
|
|
680
|
+
programOpts: program.opts(),
|
|
681
|
+
apiVersion,
|
|
682
|
+
createMode,
|
|
683
|
+
resolveBoardId,
|
|
684
|
+
setEntries,
|
|
685
|
+
rawEntries,
|
|
686
|
+
m38: m38FileCreate,
|
|
687
|
+
preflightSource: createModeResult.preflightSource,
|
|
688
|
+
preflightCacheAgeSeconds: createModeResult.preflightCacheAgeSeconds,
|
|
689
|
+
metaSource: m38Source,
|
|
690
|
+
metaCacheAgeSeconds: m38CacheAge,
|
|
691
|
+
preflightWarnings: m38Warnings,
|
|
588
692
|
dateResolution,
|
|
589
693
|
peopleResolution,
|
|
590
694
|
tagResolution,
|
|
591
695
|
relationResolution,
|
|
592
|
-
|
|
696
|
+
isDryRun: globalFlags.dryRun,
|
|
593
697
|
noCache: globalFlags.noCache,
|
|
698
|
+
retries: globalFlags.retry,
|
|
699
|
+
toEmit,
|
|
594
700
|
});
|
|
595
|
-
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (globalFlags.dryRun) {
|
|
704
|
+
let result;
|
|
705
|
+
try {
|
|
706
|
+
result = await planCreate({
|
|
707
|
+
client,
|
|
708
|
+
mode: createMode,
|
|
709
|
+
name: parsed.name,
|
|
710
|
+
setEntries,
|
|
711
|
+
...(rawEntries.length === 0 ? {} : { rawEntries }),
|
|
712
|
+
dateResolution,
|
|
713
|
+
peopleResolution,
|
|
714
|
+
tagResolution,
|
|
715
|
+
relationResolution,
|
|
716
|
+
env: ctx.env,
|
|
717
|
+
noCache: globalFlags.noCache,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
catch (err) {
|
|
721
|
+
// Round-3 P3-1 fix: fold M38 pre-check warnings into
|
|
722
|
+
// the failure envelope's `details.resolver_warnings`.
|
|
723
|
+
if (err instanceof MondayCliError && m38Warnings.length > 0) {
|
|
724
|
+
throw mergeResolverWarningsIntoError(err, m38Warnings);
|
|
725
|
+
}
|
|
726
|
+
throw err;
|
|
727
|
+
}
|
|
728
|
+
// Dry-run envelope source folds four legs (Codex M9 P2 #1
|
|
729
|
+
// + v0.6-M38 IMPL round-1 P3-1-equivalent fix):
|
|
596
730
|
// pre-planner network calls (parent lookup + parent-board
|
|
597
|
-
// metadata + --relative-to verification) +
|
|
731
|
+
// metadata + --relative-to verification) + the M38
|
|
732
|
+
// pre-check's column-resolution leg + planCreate's
|
|
598
733
|
// column-resolution legs. `meta.source: "none"` is only
|
|
599
734
|
// accurate when ZERO wire calls fired.
|
|
600
|
-
const dryRunSource = mergeSourceWithPreflight(result.source, createModeResult.preflightSource);
|
|
601
|
-
const dryRunCacheAge = mergeCacheAge(result.cacheAgeSeconds, createModeResult.preflightCacheAgeSeconds);
|
|
735
|
+
const dryRunSource = mergeSourceWithPreflight(mergeSourceWithPreflight(result.source, m38Source), createModeResult.preflightSource);
|
|
736
|
+
const dryRunCacheAge = mergeCacheAge(mergeCacheAge(m38CacheAge, result.cacheAgeSeconds), createModeResult.preflightCacheAgeSeconds);
|
|
737
|
+
// Round-2 P3-1 fix: thread M38 pre-check warnings into
|
|
738
|
+
// the dry-run envelope. Pre-check's `stale_cache_refreshed`
|
|
739
|
+
// / `column_token_collision` survive even though
|
|
740
|
+
// downstream `planCreate`'s resolveAndTranslate cache-hits
|
|
741
|
+
// suppress re-emission. Dedupe inline by code+message+
|
|
742
|
+
// token (small N).
|
|
602
743
|
emitDryRun({
|
|
603
744
|
ctx,
|
|
604
745
|
programOpts: program.opts(),
|
|
605
746
|
plannedChanges: result.plannedChanges,
|
|
606
747
|
source: dryRunSource,
|
|
607
748
|
cacheAgeSeconds: dryRunCacheAge,
|
|
608
|
-
warnings: result.warnings,
|
|
749
|
+
warnings: dedupeCreateWarnings([...m38Warnings, ...result.warnings]),
|
|
609
750
|
apiVersion,
|
|
610
751
|
});
|
|
611
752
|
return;
|
|
612
753
|
}
|
|
613
|
-
// Live create path. Three-pass resolution +
|
|
614
|
-
// through the shared helper (R20 lift), then
|
|
615
|
-
// column_values map and fire the single-
|
|
616
|
-
// per cli-design §5.8.
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
754
|
+
// Live create path (JSON-only). Three-pass resolution +
|
|
755
|
+
// translation through the shared helper (R20 lift), then
|
|
756
|
+
// bundle into one column_values map and fire the single-
|
|
757
|
+
// round-trip mutation per cli-design §5.8. Reaching this
|
|
758
|
+
// block means the v0.7-M43 `file_create` dispatch helper
|
|
759
|
+
// did NOT apply (no file `--set` entries present) — the
|
|
760
|
+
// helper returned above; this remaining path is JSON-only
|
|
761
|
+
// single-round-trip.
|
|
762
|
+
let resolutionResult;
|
|
763
|
+
try {
|
|
764
|
+
resolutionResult = await resolveAndTranslate({
|
|
765
|
+
client,
|
|
766
|
+
boardId: resolveBoardId,
|
|
767
|
+
setEntries,
|
|
768
|
+
rawEntries,
|
|
769
|
+
dateResolution,
|
|
770
|
+
peopleResolution,
|
|
771
|
+
tagResolution,
|
|
772
|
+
relationResolution,
|
|
773
|
+
env: ctx.env,
|
|
774
|
+
noCache: globalFlags.noCache,
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
catch (err) {
|
|
778
|
+
// Round-3 P3-1 fix: fold M38 pre-check warnings into the
|
|
779
|
+
// live failure envelope's `details.resolver_warnings`.
|
|
780
|
+
if (err instanceof MondayCliError && m38Warnings.length > 0) {
|
|
781
|
+
throw mergeResolverWarningsIntoError(err, m38Warnings);
|
|
782
|
+
}
|
|
783
|
+
throw err;
|
|
784
|
+
}
|
|
785
|
+
// Round-2 P3-1 fix: include M38 pre-check warnings.
|
|
786
|
+
// Deduped by code+message+token via the same shape as
|
|
787
|
+
// bulk-update's `dedupeWarnings` helper.
|
|
788
|
+
const collectedWarnings = dedupeCreateWarnings([
|
|
789
|
+
...m38Warnings,
|
|
630
790
|
...resolutionResult.warnings,
|
|
631
|
-
];
|
|
791
|
+
]);
|
|
632
792
|
const resolvedIds = resolutionResult.resolvedIds;
|
|
633
793
|
// Live envelope source aggregates four legs (Codex M9 P2 #1):
|
|
634
794
|
// pre-planner network calls (parent lookup + parent metadata
|
|
@@ -638,6 +798,13 @@ export const itemCreateCommand = {
|
|
|
638
798
|
// planner there can claim 'none' (no wire call); the class
|
|
639
799
|
// shape only handles `EnvelopeSource = 'live'|'cache'|'mixed'`.
|
|
640
800
|
const sourceAgg = new SourceAggregator();
|
|
801
|
+
// v0.6-M38 IMPL round-1 P3-1-equivalent fix: thread the M38
|
|
802
|
+
// pre-check's source/cacheAge into source aggregation so the
|
|
803
|
+
// live envelope's `meta.source` reflects the pre-check wire
|
|
804
|
+
// leg (a `live` BoardMetadata fetch when cache cold).
|
|
805
|
+
if (m38Source !== undefined) {
|
|
806
|
+
sourceAgg.record(m38Source, m38CacheAge);
|
|
807
|
+
}
|
|
641
808
|
if (resolutionResult.source !== undefined) {
|
|
642
809
|
sourceAgg.record(resolutionResult.source, resolutionResult.cacheAgeSeconds);
|
|
643
810
|
}
|
|
@@ -832,4 +999,394 @@ const executeCreateSubitem = async (client, inputs) => {
|
|
|
832
999
|
response,
|
|
833
1000
|
};
|
|
834
1001
|
};
|
|
1002
|
+
/**
|
|
1003
|
+
* Two-leg create-time file dispatch helper. Runs:
|
|
1004
|
+
*
|
|
1005
|
+
* 1. Single upfront {@link precheckLocalFile} on the file `--set`
|
|
1006
|
+
* raw value. Local-only; failure surfaces `usage_error` with
|
|
1007
|
+
* `details.reason: 'file_not_readable'` / `'file_empty'`
|
|
1008
|
+
* BEFORE either wire leg fires (atomicity-before-wire
|
|
1009
|
+
* discipline per cli-design §5.8).
|
|
1010
|
+
* 2. Partitions `inputs.setEntries` by `token`: the entry whose
|
|
1011
|
+
* `token === inputs.m38.token` routes to leg-2; every other
|
|
1012
|
+
* entry routes to leg-1's `column_values`. `inputs.rawEntries`
|
|
1013
|
+
* route to leg-1 verbatim — `--set-raw <file-col>=<json>` is
|
|
1014
|
+
* rejected upstream at `translateRawColumnValue` per D3
|
|
1015
|
+
* permanent rejection, so by this point no raw entry targets
|
|
1016
|
+
* a file column.
|
|
1017
|
+
* 3. **Dry-run branch.** Invokes {@link planCreate} on the
|
|
1018
|
+
* non-file entries (handles resolution + diff cell build),
|
|
1019
|
+
* then appends a synthetic entry-2
|
|
1020
|
+
* `operation: 'add_file_to_column'` carrying `column_id` +
|
|
1021
|
+
* `file_path` (argv-derived) + `filename` + `file_size_bytes`
|
|
1022
|
+
* from the upfront pre-check. Emits both entries together
|
|
1023
|
+
* via `emitDryRun`; no multipart wire round-trip fires.
|
|
1024
|
+
* Entry-2 omits `item_id` (the item doesn't exist yet at
|
|
1025
|
+
* dry-run time).
|
|
1026
|
+
* 4. **Live branch.** `resolveAndTranslate` on the non-file
|
|
1027
|
+
* entries yields the leg-1 `column_values`; leg-1 invokes
|
|
1028
|
+
* `executeCreateItem` / `executeCreateSubitem` depending on
|
|
1029
|
+
* `inputs.createMode.kind`; leg-2 builds a
|
|
1030
|
+
* {@link FileColumnSetEntry} from the pre-check + leg-1's
|
|
1031
|
+
* new item ID and invokes {@link executeFileColumnSet}.
|
|
1032
|
+
* On full success, a single
|
|
1033
|
+
* {@link invalidateBoard} fires (mirroring M38 single-item
|
|
1034
|
+
* + M42 bulk file-dispatch invalidate timing — leg-2
|
|
1035
|
+
* mutates the file column's asset state wire-side).
|
|
1036
|
+
* 5. **Leg-1 failure.** Routes through {@link foldAndRemap} to
|
|
1037
|
+
* surface `column_archived` on cache-served file-column
|
|
1038
|
+
* resolution against an archived column (mirrors the JSON
|
|
1039
|
+
* path's F4 remap above). No orphan handle because no item
|
|
1040
|
+
* was created.
|
|
1041
|
+
* 6. **Leg-2 failure (orphan-warn per D1).** Catches
|
|
1042
|
+
* `MondayCliError`, applies {@link foldAndRemap} to surface
|
|
1043
|
+
* `column_archived` etc., then wraps the remapped error in
|
|
1044
|
+
* a fresh `ApiError('internal_error', ...)` carrying
|
|
1045
|
+
* `details.reason: 'create_then_file_upload_partial_failure'`
|
|
1046
|
+
* + `details.created_item_id` + `details.column_id` +
|
|
1047
|
+
* `details.cause` (JSON projection of the remapped error) +
|
|
1048
|
+
* `details.hint` (retry-leg-2-only / rollback). The board
|
|
1049
|
+
* cache is NOT invalidated on leg-2 failure — leg-1's
|
|
1050
|
+
* `create_item` doesn't affect cached board metadata
|
|
1051
|
+
* (mirrors the JSON-only create path's no-invalidate), and
|
|
1052
|
+
* leg-2 failure means no file mutation occurred wire-side.
|
|
1053
|
+
*/
|
|
1054
|
+
const runItemCreateFileDispatch = async (inputs) => {
|
|
1055
|
+
// 1) Upfront local file pre-check. Atomicity-before-wire per
|
|
1056
|
+
// cli-design §5.8: pre-checks fire BEFORE any wire round-trip
|
|
1057
|
+
// so a bad path surfaces `usage_error` (exit 1) with
|
|
1058
|
+
// `details.reason: 'file_not_readable'` / `'file_empty'`
|
|
1059
|
+
// without burning either wire leg. R-v0.6-NEW-1 4th-consumer
|
|
1060
|
+
// site (M31 upload + M38 single-item + M42 file-bulk + here);
|
|
1061
|
+
// 5-consumer graduation threshold not yet hit.
|
|
1062
|
+
const precheck = await precheckLocalFile(inputs.m38.rawValue);
|
|
1063
|
+
// 2) Partition setEntries: the file entry's `token` matches
|
|
1064
|
+
// `inputs.m38.token` (the pre-check identified it); every
|
|
1065
|
+
// other token goes to leg-1's column_values.
|
|
1066
|
+
const nonFileSetEntries = inputs.setEntries.filter((e) => e.token !== inputs.m38.token);
|
|
1067
|
+
// 3) Dry-run branch — D2 closure. Two `planned_changes` entries
|
|
1068
|
+
// without burning either wire leg. planCreate handles
|
|
1069
|
+
// non-file column resolution + diff cells; entry-2 is built
|
|
1070
|
+
// locally from the pre-check.
|
|
1071
|
+
if (inputs.isDryRun) {
|
|
1072
|
+
let planResult;
|
|
1073
|
+
try {
|
|
1074
|
+
planResult = await planCreate({
|
|
1075
|
+
client: inputs.client,
|
|
1076
|
+
mode: inputs.createMode,
|
|
1077
|
+
name: inputs.parsed.name,
|
|
1078
|
+
setEntries: nonFileSetEntries,
|
|
1079
|
+
...(inputs.rawEntries.length === 0
|
|
1080
|
+
? {}
|
|
1081
|
+
: { rawEntries: inputs.rawEntries }),
|
|
1082
|
+
dateResolution: inputs.dateResolution,
|
|
1083
|
+
peopleResolution: inputs.peopleResolution,
|
|
1084
|
+
tagResolution: inputs.tagResolution,
|
|
1085
|
+
relationResolution: inputs.relationResolution,
|
|
1086
|
+
env: inputs.ctx.env,
|
|
1087
|
+
noCache: inputs.noCache,
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
catch (err) {
|
|
1091
|
+
// Fold M38 pre-check warnings into the dry-run failure
|
|
1092
|
+
// envelope's `details.resolver_warnings`. `mergeResolverWarningsIntoError`
|
|
1093
|
+
// is a no-op on empty `preflightWarnings`, so no length guard
|
|
1094
|
+
// is needed; the JSON path's analogous catch at
|
|
1095
|
+
// `create.ts:944-951` keeps the guard inline for parity with
|
|
1096
|
+
// its older pattern, but the M43 helper collapses it (smaller
|
|
1097
|
+
// branch surface). Non-`MondayCliError` programmer bugs
|
|
1098
|
+
// re-throw unchanged.
|
|
1099
|
+
if (err instanceof MondayCliError) {
|
|
1100
|
+
throw mergeResolverWarningsIntoError(err, inputs.preflightWarnings);
|
|
1101
|
+
}
|
|
1102
|
+
throw err;
|
|
1103
|
+
}
|
|
1104
|
+
// Source aggregates four legs (planner + M38 pre-check +
|
|
1105
|
+
// pre-planner preflight) — mirrors the JSON-path dry-run
|
|
1106
|
+
// aggregation pattern at lines 959-966 above. planCreate may
|
|
1107
|
+
// return `source: 'none'` when its no-set short-circuit fires
|
|
1108
|
+
// (only relevant here if the call had ONLY the file `--set`),
|
|
1109
|
+
// so the standalone `mergeSourceWithPreflight` helper is used
|
|
1110
|
+
// rather than the SourceAggregator class (which doesn't model
|
|
1111
|
+
// 'none').
|
|
1112
|
+
const dryRunSource = mergeSourceWithPreflight(mergeSourceWithPreflight(planResult.source, inputs.metaSource), inputs.preflightSource);
|
|
1113
|
+
const dryRunCacheAge = mergeCacheAge(mergeCacheAge(inputs.metaCacheAgeSeconds, planResult.cacheAgeSeconds), inputs.preflightCacheAgeSeconds);
|
|
1114
|
+
// Entry-2: `add_file_to_column` planned-change. Mirrors M31's
|
|
1115
|
+
// dry-run shape minus `item_id` (the item doesn't exist yet).
|
|
1116
|
+
// `file_path` is the argv-derived raw value per cli-design §6.4;
|
|
1117
|
+
// resolved absolute path lives in pre-check rejections, not in
|
|
1118
|
+
// the success-shaped dry-run envelope.
|
|
1119
|
+
const fileEntry = {
|
|
1120
|
+
operation: 'add_file_to_column',
|
|
1121
|
+
column_id: inputs.m38.columnId,
|
|
1122
|
+
file_path: inputs.m38.rawValue,
|
|
1123
|
+
filename: precheck.filename,
|
|
1124
|
+
file_size_bytes: precheck.fileSizeBytes,
|
|
1125
|
+
};
|
|
1126
|
+
const plannedChanges = [
|
|
1127
|
+
...planResult.plannedChanges,
|
|
1128
|
+
fileEntry,
|
|
1129
|
+
];
|
|
1130
|
+
emitDryRun({
|
|
1131
|
+
ctx: inputs.ctx,
|
|
1132
|
+
programOpts: inputs.programOpts,
|
|
1133
|
+
plannedChanges,
|
|
1134
|
+
source: dryRunSource,
|
|
1135
|
+
cacheAgeSeconds: dryRunCacheAge,
|
|
1136
|
+
warnings: dedupeCreateWarnings([
|
|
1137
|
+
...inputs.preflightWarnings,
|
|
1138
|
+
...planResult.warnings,
|
|
1139
|
+
]),
|
|
1140
|
+
apiVersion: inputs.apiVersion,
|
|
1141
|
+
});
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
// 4) Live branch — leg-1 (create_item / create_subitem) then
|
|
1145
|
+
// leg-2 (add_file_to_column). resolveAndTranslate on non-file
|
|
1146
|
+
// entries yields leg-1's column_values; the M38 pre-check
|
|
1147
|
+
// already warmed the column-resolution cache so this leg
|
|
1148
|
+
// typically hits cache (source folds to `mixed` once leg-1
|
|
1149
|
+
// + leg-2 record `live`).
|
|
1150
|
+
let resolutionResult;
|
|
1151
|
+
try {
|
|
1152
|
+
resolutionResult = await resolveAndTranslate({
|
|
1153
|
+
client: inputs.client,
|
|
1154
|
+
boardId: inputs.resolveBoardId,
|
|
1155
|
+
setEntries: nonFileSetEntries,
|
|
1156
|
+
rawEntries: inputs.rawEntries,
|
|
1157
|
+
dateResolution: inputs.dateResolution,
|
|
1158
|
+
peopleResolution: inputs.peopleResolution,
|
|
1159
|
+
tagResolution: inputs.tagResolution,
|
|
1160
|
+
relationResolution: inputs.relationResolution,
|
|
1161
|
+
env: inputs.ctx.env,
|
|
1162
|
+
noCache: inputs.noCache,
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
catch (err) {
|
|
1166
|
+
// Same shape as the planCreate catch above — collapse the
|
|
1167
|
+
// `&& length > 0` guard (no-op on empty) for a smaller branch
|
|
1168
|
+
// surface than the JSON path's pattern at
|
|
1169
|
+
// `create.ts:1010-1022`.
|
|
1170
|
+
if (err instanceof MondayCliError) {
|
|
1171
|
+
throw mergeResolverWarningsIntoError(err, inputs.preflightWarnings);
|
|
1172
|
+
}
|
|
1173
|
+
throw err;
|
|
1174
|
+
}
|
|
1175
|
+
// Combined warnings: M38 pre-check + resolveAndTranslate. Deduped
|
|
1176
|
+
// by code+message+token (a stale_cache_refreshed seen at pre-check
|
|
1177
|
+
// AND at resolveAndTranslate for the same token collapses to one
|
|
1178
|
+
// entry). Mirrors the JSON path's dedupeCreateWarnings usage.
|
|
1179
|
+
const collectedWarnings = dedupeCreateWarnings([...inputs.preflightWarnings, ...resolutionResult.warnings]);
|
|
1180
|
+
// Source aggregator across every wire leg that fires (or that
|
|
1181
|
+
// already fired upstream). Records preflight + M38 pre-check +
|
|
1182
|
+
// resolveAndTranslate legs; records `'live'` once at the end of
|
|
1183
|
+
// each successful wire mutation (mergeSource is idempotent for a
|
|
1184
|
+
// constant `'live'` second leg so recording leg-1 + leg-2 separately
|
|
1185
|
+
// is byte-equivalent to recording once).
|
|
1186
|
+
const sourceAgg = new SourceAggregator();
|
|
1187
|
+
// Defensive: the helper is entered only when the action body's
|
|
1188
|
+
// `preCheckM38FileDispatch` returned `kind: 'file_create'`, which
|
|
1189
|
+
// guarantees `metaSource` is defined (the M38 pre-check populates
|
|
1190
|
+
// `source` for every entry it resolves). The `undefined` arm is
|
|
1191
|
+
// unreachable from any callable test surface.
|
|
1192
|
+
/* c8 ignore next 3 */
|
|
1193
|
+
if (inputs.metaSource !== undefined) {
|
|
1194
|
+
sourceAgg.record(inputs.metaSource, inputs.metaCacheAgeSeconds);
|
|
1195
|
+
}
|
|
1196
|
+
if (resolutionResult.source !== undefined) {
|
|
1197
|
+
sourceAgg.record(resolutionResult.source, resolutionResult.cacheAgeSeconds);
|
|
1198
|
+
}
|
|
1199
|
+
if (inputs.preflightSource !== undefined) {
|
|
1200
|
+
sourceAgg.record(inputs.preflightSource, inputs.preflightCacheAgeSeconds);
|
|
1201
|
+
}
|
|
1202
|
+
// resolved_ids — file token + non-file tokens. Mirrors §6.4
|
|
1203
|
+
// mutation-envelope shape: `{ <token>: <resolved_column_id> }`
|
|
1204
|
+
// for every `--set` / `--set-raw` the agent supplied.
|
|
1205
|
+
const resolvedIds = {
|
|
1206
|
+
[inputs.m38.token]: inputs.m38.columnId,
|
|
1207
|
+
...resolutionResult.resolvedIds,
|
|
1208
|
+
};
|
|
1209
|
+
// Bundle non-file translated values into leg-1's column_values
|
|
1210
|
+
// parameter. `null` when zero non-file entries (mirrors the JSON
|
|
1211
|
+
// path's "no `--set` values to bundle" treatment — Monday accepts
|
|
1212
|
+
// `column_values: null` distinctly from an empty map).
|
|
1213
|
+
const translated = resolutionResult.translated;
|
|
1214
|
+
const columnValues = translated.length === 0 ? null : bundleColumnValues(translated);
|
|
1215
|
+
// Leg-1: create_item or create_subitem. F4 remap on failure
|
|
1216
|
+
// mirrors the JSON path's catch arm (cache-served resolution +
|
|
1217
|
+
// Monday rejecting as `validation_failed` → check live archived
|
|
1218
|
+
// state). No orphan handle on leg-1 failure because no item was
|
|
1219
|
+
// created.
|
|
1220
|
+
let leg1Result;
|
|
1221
|
+
try {
|
|
1222
|
+
if (inputs.createMode.kind === 'subitem') {
|
|
1223
|
+
leg1Result = await executeCreateSubitem(inputs.client, {
|
|
1224
|
+
parentItemId: inputs.createMode.parentItemId,
|
|
1225
|
+
itemName: inputs.parsed.name,
|
|
1226
|
+
columnValues,
|
|
1227
|
+
createLabelsIfMissing: inputs.parsed.createLabelsIfMissing,
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
else {
|
|
1231
|
+
leg1Result = await executeCreateItem(inputs.client, {
|
|
1232
|
+
boardId: inputs.createMode.boardId,
|
|
1233
|
+
itemName: inputs.parsed.name,
|
|
1234
|
+
groupId: inputs.createMode.groupId,
|
|
1235
|
+
position: inputs.createMode.position,
|
|
1236
|
+
columnValues,
|
|
1237
|
+
createLabelsIfMissing: inputs.parsed.createLabelsIfMissing,
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
catch (err) {
|
|
1242
|
+
if (err instanceof MondayCliError) {
|
|
1243
|
+
throw await foldAndRemap({
|
|
1244
|
+
err,
|
|
1245
|
+
warnings: collectedWarnings,
|
|
1246
|
+
client: inputs.client,
|
|
1247
|
+
boardId: inputs.resolveBoardId,
|
|
1248
|
+
columnIds: translated.map((t) => t.columnId),
|
|
1249
|
+
env: inputs.ctx.env,
|
|
1250
|
+
noCache: inputs.noCache,
|
|
1251
|
+
resolutionSource: resolutionResult.source ?? 'live',
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
// Defensive: every wire fetcher in `src/api/**` raises typed
|
|
1255
|
+
// errors (ApiError / UsageError) which both extend MondayCliError;
|
|
1256
|
+
// a non-typed throw here indicates a programmer bug in the
|
|
1257
|
+
// wire layer, not a Monday-side failure that needs the F4 remap.
|
|
1258
|
+
/* c8 ignore next */
|
|
1259
|
+
throw err;
|
|
1260
|
+
}
|
|
1261
|
+
// Leg-1 fired live; record into the aggregator.
|
|
1262
|
+
sourceAgg.record('live', null);
|
|
1263
|
+
// Leg-2: add_file_to_column via M31's multipart fetcher. On
|
|
1264
|
+
// success, build the create envelope below; on `MondayCliError`,
|
|
1265
|
+
// surface the D1 orphan-warn envelope with the freshly-created
|
|
1266
|
+
// item ID as the recovery handle.
|
|
1267
|
+
const fileEntry = {
|
|
1268
|
+
columnId: inputs.m38.columnId,
|
|
1269
|
+
columnType: 'file',
|
|
1270
|
+
rawValue: inputs.m38.rawValue,
|
|
1271
|
+
filePath: precheck.filePath,
|
|
1272
|
+
filename: precheck.filename,
|
|
1273
|
+
fileSizeBytes: precheck.fileSizeBytes,
|
|
1274
|
+
};
|
|
1275
|
+
try {
|
|
1276
|
+
await executeFileColumnSet({
|
|
1277
|
+
client: inputs.client,
|
|
1278
|
+
multipart: inputs.multipart,
|
|
1279
|
+
itemId: leg1Result.projected.id,
|
|
1280
|
+
entry: fileEntry,
|
|
1281
|
+
signal: inputs.ctx.signal,
|
|
1282
|
+
retries: inputs.retries,
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
catch (err) {
|
|
1286
|
+
if (err instanceof MondayCliError) {
|
|
1287
|
+
// foldAndRemap surfaces `column_archived` for cache-served
|
|
1288
|
+
// file-column resolution against an archived column (cli-
|
|
1289
|
+
// design §6.5 stable-code rule; mirrors M42's file-bulk
|
|
1290
|
+
// fail-fast pattern). The remapped error's code/message
|
|
1291
|
+
// surface in `details.cause` so agents can branch on
|
|
1292
|
+
// leg-2's underlying outcome from the orphan-warn envelope.
|
|
1293
|
+
const remapped = await foldAndRemap({
|
|
1294
|
+
err,
|
|
1295
|
+
warnings: collectedWarnings,
|
|
1296
|
+
client: inputs.client,
|
|
1297
|
+
boardId: inputs.resolveBoardId,
|
|
1298
|
+
columnIds: [inputs.m38.columnId],
|
|
1299
|
+
env: inputs.ctx.env,
|
|
1300
|
+
noCache: inputs.noCache,
|
|
1301
|
+
resolutionSource: inputs.metaSource ?? 'live',
|
|
1302
|
+
});
|
|
1303
|
+
// D1 orphan-warn envelope. Always-internal-error outer
|
|
1304
|
+
// shape; the remapped error embeds as `details.cause` JSON
|
|
1305
|
+
// projection so the agent sees `{code, message, details?}`
|
|
1306
|
+
// for the underlying failure. Error.cause threads the
|
|
1307
|
+
// remapped error for stack debugging in `--debug` mode.
|
|
1308
|
+
const causeProjection = {
|
|
1309
|
+
code: remapped.code,
|
|
1310
|
+
message: remapped.message,
|
|
1311
|
+
};
|
|
1312
|
+
// Defensive: M31's wire-error rewraps (and foldAndRemap) always
|
|
1313
|
+
// populate `details` on the returned error in practice; the
|
|
1314
|
+
// undefined-arm exists only to satisfy the optional shape on
|
|
1315
|
+
// the `MondayCliError` type.
|
|
1316
|
+
/* c8 ignore next 3 */
|
|
1317
|
+
if (remapped.details !== undefined) {
|
|
1318
|
+
causeProjection.details = remapped.details;
|
|
1319
|
+
}
|
|
1320
|
+
const createdItemId = leg1Result.projected.id;
|
|
1321
|
+
throw new ApiError('internal_error', `Item ${createdItemId} was created on board ${inputs.resolveBoardId} ` +
|
|
1322
|
+
`but the file upload to column ${inputs.m38.columnId} failed ` +
|
|
1323
|
+
`(${remapped.code}: ${remapped.message}). The item persists on ` +
|
|
1324
|
+
`Monday; retry the file upload alone with \`monday item set ` +
|
|
1325
|
+
`${createdItemId} <file-col>=<path>\` against the orphan, or roll ` +
|
|
1326
|
+
`back with \`monday item delete ${createdItemId} --yes\`.`, {
|
|
1327
|
+
cause: remapped,
|
|
1328
|
+
details: {
|
|
1329
|
+
reason: 'create_then_file_upload_partial_failure',
|
|
1330
|
+
created_item_id: createdItemId,
|
|
1331
|
+
column_id: inputs.m38.columnId,
|
|
1332
|
+
cause: causeProjection,
|
|
1333
|
+
hint: `the item was created (id ${createdItemId}) but the file ` +
|
|
1334
|
+
`upload failed. Retry leg-2 alone with \`monday item set ` +
|
|
1335
|
+
`${createdItemId} <file-col>=<path>\`; or rollback the ` +
|
|
1336
|
+
`orphan with \`monday item delete ${createdItemId} --yes\` ` +
|
|
1337
|
+
`and re-run the original \`monday item create\` once the ` +
|
|
1338
|
+
`underlying cause is fixed.`,
|
|
1339
|
+
},
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
// Non-CliError programmer bug — re-throw to the runner's catch-
|
|
1343
|
+
// all (surfaces as `internal_error` whole-call). Non-typed
|
|
1344
|
+
// throws indicate broken contract, not a Monday-side failure
|
|
1345
|
+
// that needs the orphan-warn decoration; routing them through
|
|
1346
|
+
// D1's `create_then_file_upload_partial_failure` discriminator
|
|
1347
|
+
// would falsely promise an orphan-recovery path for a programmer
|
|
1348
|
+
// bug.
|
|
1349
|
+
/* c8 ignore next */
|
|
1350
|
+
throw err;
|
|
1351
|
+
}
|
|
1352
|
+
// Leg-2 fired live; record into the aggregator. `'live'` + `'live'`
|
|
1353
|
+
// is idempotent under mergeSource so this is the second authoritative
|
|
1354
|
+
// wire-leg record (leg-1 already recorded).
|
|
1355
|
+
sourceAgg.record('live', null);
|
|
1356
|
+
// Both legs succeeded — single board-cache invalidate before emit
|
|
1357
|
+
// (mirrors M38 single-item + M42 fail-fast file-bulk invalidate
|
|
1358
|
+
// timing; leg-2 mutated the file column's asset state wire-side).
|
|
1359
|
+
// The invalidate fires BEFORE emitMutation so a cache-unlink
|
|
1360
|
+
// failure surfaces through the runner's catch-all rather than
|
|
1361
|
+
// double-emitting after the success envelope already hit stdout.
|
|
1362
|
+
await invalidateBoard(inputs.resolveBoardId, inputs.ctx.env);
|
|
1363
|
+
// Map the resolver warnings into the envelope `warnings` slot.
|
|
1364
|
+
const warnings = collectedWarnings;
|
|
1365
|
+
// Success envelope — `data: ItemCreateOutput` from leg-1's
|
|
1366
|
+
// projection. `toEmit(leg1Result.response)` threads leg-1's
|
|
1367
|
+
// `complexity` + `apiVersion` slots; `sourceAgg.result()`
|
|
1368
|
+
// overrides `source` + `cacheAgeSeconds` so the aggregator's
|
|
1369
|
+
// result (cache + live blended across every leg) is
|
|
1370
|
+
// authoritative. Leg-2's complexity is intentionally NOT folded
|
|
1371
|
+
// — the contract pins leg-1's projection on `data`, and the
|
|
1372
|
+
// envelope's `meta.complexity` is the create mutation's cost
|
|
1373
|
+
// (multipart leg-2 has no GraphQL complexity surface).
|
|
1374
|
+
// The output asset from leg-2 is attached to the item server-
|
|
1375
|
+
// side; agents read it back via `monday item get <iid> --columns
|
|
1376
|
+
// <file-col>` if they need the projection (the file-column
|
|
1377
|
+
// dispatch's `Asset` slot is documented per item upload's
|
|
1378
|
+
// envelope; the v0.7-M43 success envelope keeps the canonical
|
|
1379
|
+
// ItemCreateOutput shape so JSON-path and file-path envelopes
|
|
1380
|
+
// remain byte-equivalent on `data`).
|
|
1381
|
+
emitMutation({
|
|
1382
|
+
ctx: inputs.ctx,
|
|
1383
|
+
data: leg1Result.projected,
|
|
1384
|
+
schema: itemCreateOutputSchema,
|
|
1385
|
+
programOpts: inputs.programOpts,
|
|
1386
|
+
warnings,
|
|
1387
|
+
...inputs.toEmit(leg1Result.response),
|
|
1388
|
+
...sourceAgg.result(),
|
|
1389
|
+
resolvedIds,
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
835
1392
|
//# sourceMappingURL=create.js.map
|