@cadraos/sdk 0.3.14-p46.3 → 0.3.14

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 (52) hide show
  1. package/README.md +104 -53
  2. package/dist/ai-functions/react/index.cjs +176 -0
  3. package/dist/ai-functions/react/index.cjs.map +1 -0
  4. package/dist/ai-functions/react/index.d.cts +129 -0
  5. package/dist/ai-functions/react/index.d.ts +129 -0
  6. package/dist/ai-functions/react/index.js +153 -0
  7. package/dist/ai-functions/react/index.js.map +1 -0
  8. package/dist/ai-functions/server/index.cjs +296 -0
  9. package/dist/ai-functions/server/index.cjs.map +1 -0
  10. package/dist/ai-functions/server/index.d.cts +334 -0
  11. package/dist/ai-functions/server/index.d.ts +334 -0
  12. package/dist/ai-functions/server/index.js +284 -0
  13. package/dist/ai-functions/server/index.js.map +1 -0
  14. package/dist/board-host/index.cjs +217 -129
  15. package/dist/board-host/index.cjs.map +1 -1
  16. package/dist/board-host/index.d.cts +96 -1
  17. package/dist/board-host/index.d.ts +96 -1
  18. package/dist/board-host/index.js +218 -131
  19. package/dist/board-host/index.js.map +1 -1
  20. package/dist/board-host/server/index.d.cts +44 -0
  21. package/dist/board-host/server/index.d.ts +44 -0
  22. package/dist/chat/index.cjs +299 -17
  23. package/dist/chat/index.cjs.map +1 -1
  24. package/dist/chat/index.d.cts +225 -0
  25. package/dist/chat/index.d.ts +225 -0
  26. package/dist/chat/index.js +299 -17
  27. package/dist/chat/index.js.map +1 -1
  28. package/dist/index.cjs +221 -3
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +286 -1
  31. package/dist/index.d.ts +286 -1
  32. package/dist/index.js +215 -4
  33. package/dist/index.js.map +1 -1
  34. package/dist/kanban/engine/index.cjs +774 -683
  35. package/dist/kanban/engine/index.cjs.map +1 -1
  36. package/dist/kanban/engine/index.d.cts +90 -1
  37. package/dist/kanban/engine/index.d.ts +90 -1
  38. package/dist/kanban/engine/index.js +774 -684
  39. package/dist/kanban/engine/index.js.map +1 -1
  40. package/dist/kanban/index.cjs +214 -3
  41. package/dist/kanban/index.cjs.map +1 -1
  42. package/dist/kanban/index.d.cts +252 -0
  43. package/dist/kanban/index.d.ts +252 -0
  44. package/dist/kanban/index.js +214 -3
  45. package/dist/kanban/index.js.map +1 -1
  46. package/dist/teams/index.cjs +214 -3
  47. package/dist/teams/index.cjs.map +1 -1
  48. package/dist/teams/index.d.cts +225 -0
  49. package/dist/teams/index.d.ts +225 -0
  50. package/dist/teams/index.js +214 -3
  51. package/dist/teams/index.js.map +1 -1
  52. package/package.json +21 -1
@@ -319,6 +319,11 @@ interface KanbanCard {
319
319
  configVersion?: number;
320
320
  /** Arbitrary shared context carried across transitions. */
321
321
  sharedContext?: Record<string, unknown>;
322
+ /**
323
+ * p46 (P46-002): the card's id in an external host (a Jira issue key).
324
+ * Absent on native / crm / yobo cards.
325
+ */
326
+ externalRef?: string;
322
327
  /**
323
328
  * Execution UUID of the card's current/last run, if any.
324
329
  *
@@ -381,6 +386,18 @@ interface CreateCardInput {
381
386
  * in the lifecycle's initial lane.
382
387
  */
383
388
  lane?: string;
389
+ /**
390
+ * p46 (P46-002): the card's id in an EXTERNAL host (a Jira issue key, e.g.
391
+ * `CAD-231`). Optional. When set, a card is created at most ONCE per
392
+ * `(boardConfigUuid, externalRef)`: a repeat create returns the existing card
393
+ * and dispatches nothing. Hosts that don't store it simply ignore it.
394
+ */
395
+ externalRef?: string;
396
+ /**
397
+ * p46 (P46-002): opaque host facts stored with the card (Jira `statusId`,
398
+ * `mover`, `detached`, …). Passed through to `adapter.createCard` untouched.
399
+ */
400
+ externalMeta?: Record<string, unknown>;
384
401
  }
385
402
  /**
386
403
  * Who performed a transition / stage-run (server-engine side).
@@ -498,6 +515,23 @@ interface ApplyTransitionInput {
498
515
  contextPatch?: Record<string, unknown>;
499
516
  /** Execution UUID to stamp on the card (handler advances). */
500
517
  executionUuid?: string;
518
+ /**
519
+ * p46 (P46-002, F8): set ONLY by `engine.hostMove` (a move the external host
520
+ * made — e.g. a Jira drag mirrored by the sync). A host-aware adapter, inside
521
+ * the same card lock as the `fromLane` CAS, (1) refuses the move with a
522
+ * `HostFenceError` while the card has any `host.*` op `pending` (D19 — never
523
+ * mistake our own half-done move for a human one), (2) writes `externalMeta`,
524
+ * then (3) moves. Adapters that don't know it ignore it (optional, additive).
525
+ */
526
+ hostObservation?: {
527
+ externalMeta?: Record<string, unknown>;
528
+ /**
529
+ * ISO time the host state was READ. The fence also refuses the move when a
530
+ * `host.*` op for the card settled (done/failed) after this instant — the
531
+ * read may predate our own write landing in the host.
532
+ */
533
+ observedAt?: string;
534
+ };
501
535
  }
502
536
 
503
537
  /**
@@ -682,6 +716,16 @@ interface KanbanStorageAdapter {
682
716
  * config and passes it as `initialLane`.
683
717
  */
684
718
  createCard(input: CreateCardServerInput): Promise<KanbanCard>;
719
+ /**
720
+ * p46 (P46-002) OPTIONAL: the card with this `externalRef` on this board, or
721
+ * null. When present, `engine.createCard({externalRef})` looks it up first and
722
+ * returns an existing card WITHOUT dispatching (exactly-once create per issue
723
+ * key). A host that stores `externalRef` SHOULD also make `createCard` itself
724
+ * idempotent on `(boardConfigUuid, externalRef)` (unique index + `ON CONFLICT
725
+ * DO NOTHING` → return the existing row) for the lookup/insert race. Hosts
726
+ * without external refs (crm/yobo) omit it.
727
+ */
728
+ getCardByExternalRef?(boardConfigUuid: string, externalRef: string): Promise<KanbanCard | null>;
685
729
  /**
686
730
  * Patch a card's mutable fields.
687
731
  */
@@ -1368,6 +1412,57 @@ interface BoardHostMappingProps {
1368
1412
  }
1369
1413
  declare function BoardHostMapping({ boardConfigUuid, adapter: adapterProp, onSaved, onError, }: BoardHostMappingProps): react_jsx_runtime.JSX.Element;
1370
1414
 
1415
+ /**
1416
+ * `<LaneMapStep/>` — the lane-map rows (board stage → host state), extracted
1417
+ * from `<BoardHostMapping/>` ② (P46-002-1) so a hosted host (the Jira link
1418
+ * page) reuses the same step.
1419
+ *
1420
+ * - WITHOUT `hostStates`: today's free-text host-state input per lane — the
1421
+ * crm/yobo `<BoardHostMapping/>` path, DOM unchanged.
1422
+ * - WITH `hostStates` (e.g. a Jira board's column statuses): a `<select>` per
1423
+ * lane plus an "Also accepts" multi-select (D17: inbound, any of
1424
+ * `[hostState, ...alsoFrom]` maps to the lane; outbound writes `hostState`).
1425
+ *
1426
+ * Controlled: `value` in, the whole next map out via `onChange`. Zero runtime
1427
+ * deps; plain inline styles.
1428
+ *
1429
+ * @module @cadraos/sdk/board-host
1430
+ */
1431
+
1432
+ /** One lane's host-state binding (`LaneBinding` minus the stage identity). */
1433
+ interface LaneMapEntry {
1434
+ /** The host state a move INTO this lane writes (and reads). */
1435
+ hostState: string;
1436
+ /** Extra host states that also map INTO this lane (inbound only, D17). */
1437
+ alsoFrom?: string[];
1438
+ }
1439
+ /** Lane map keyed by stage `key`. */
1440
+ type LaneMapValue = Record<string, LaneMapEntry>;
1441
+ /** A host state the host offers (e.g. a Jira status: id + display name). */
1442
+ interface HostStateOption {
1443
+ value: string;
1444
+ label: string;
1445
+ }
1446
+ interface LaneMapStepProps {
1447
+ /** Board lanes, in order. */
1448
+ lanes: KanbanLane[];
1449
+ /** Current map (keyed by stage key). */
1450
+ value: LaneMapValue;
1451
+ /** Receives the WHOLE next map. */
1452
+ onChange: (next: LaneMapValue) => void;
1453
+ /** Offered host states → `<select>` mode; absent → free-text mode. */
1454
+ hostStates?: HostStateOption[];
1455
+ /**
1456
+ * Optional per-lane "create if missing" checkbox (the p34 crm/yobo mapping).
1457
+ * Absent → no checkbox.
1458
+ */
1459
+ createIfMissing?: {
1460
+ value: Record<string, boolean>;
1461
+ onChange: (stageKey: string, checked: boolean) => void;
1462
+ };
1463
+ }
1464
+ declare function LaneMapStep({ lanes, value, onChange, hostStates, createIfMissing, }: LaneMapStepProps): React.ReactElement;
1465
+
1371
1466
  interface BoardHostMappingProviderProps {
1372
1467
  /**
1373
1468
  * The session-authed adapter the host injects (wraps the §6b endpoints with
@@ -1450,4 +1545,4 @@ interface DueRef {
1450
1545
  */
1451
1546
  declare function collectDueRefs(lanes: KanbanLane[]): DueRef[];
1452
1547
 
1453
- export { type BoardHostDelegate, BoardHostMapping, type BoardHostMappingAdapter, type BoardHostMapping$1 as BoardHostMappingData, type BoardHostMappingProps, BoardHostMappingProvider, type BoardHostMappingProviderProps, type BoardQueryRunner, type DueRef, type FieldBinding, type LaneBinding, type MappingValidationStatus, type ScopeBinding, WIDGET_IDENTIFIER_PATTERN, collectDueRefs, identifierError, isValidIdentifier, isValidJsonPath, useBoardHostMappingAdapter, useBoardHostMappingAdapterOptional };
1548
+ export { type BoardHostDelegate, BoardHostMapping, type BoardHostMappingAdapter, type BoardHostMapping$1 as BoardHostMappingData, type BoardHostMappingProps, BoardHostMappingProvider, type BoardHostMappingProviderProps, type BoardQueryRunner, type DueRef, type FieldBinding, type HostStateOption, type LaneBinding, type LaneMapEntry, LaneMapStep, type LaneMapStepProps, type LaneMapValue, type MappingValidationStatus, type ScopeBinding, WIDGET_IDENTIFIER_PATTERN, collectDueRefs, identifierError, isValidIdentifier, isValidJsonPath, useBoardHostMappingAdapter, useBoardHostMappingAdapterOptional };
@@ -1,5 +1,5 @@
1
1
  import { createContext, useMemo, useContext, useState, useCallback, useEffect } from 'react';
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
3
 
4
4
  var BoardHostMappingContext = createContext(null);
5
5
  function BoardHostMappingProvider({
@@ -71,86 +71,8 @@ function collectDueRefs(lanes) {
71
71
  }
72
72
  return Array.from(byRef.values());
73
73
  }
74
- var DEFAULT_ORG_COLUMN = "org_id";
75
- function laneStageId(lane) {
76
- return lane.id ?? lane.key;
77
- }
78
- function suggestHostState(lane) {
79
- return lane.label ?? lane.key ?? "";
80
- }
81
- function freshFieldRow(ref, requiresPredicate) {
82
- return {
83
- ref,
84
- kind: requiresPredicate ? "predicate" : "column",
85
- column: "",
86
- path: "",
87
- via: "",
88
- table: "",
89
- name: "",
90
- predicateOnly: requiresPredicate
91
- };
92
- }
93
- function fieldRowFromBinding(b, requiresPredicate) {
94
- const base = freshFieldRow(b.ref, requiresPredicate);
95
- switch (b.kind) {
96
- case "column":
97
- return { ...base, kind: "column", column: b.column };
98
- case "json":
99
- return { ...base, kind: "json", column: b.column, path: b.path };
100
- case "fk":
101
- return { ...base, kind: "fk", via: b.via, table: b.table, column: b.column };
102
- case "predicate":
103
- return { ...base, kind: "predicate", name: b.name };
104
- default:
105
- return base;
106
- }
107
- }
108
- function fieldRowError(row) {
109
- switch (row.kind) {
110
- case "column":
111
- return identifierError(row.column) && `column ${identifierError(row.column)}`;
112
- case "json": {
113
- const colErr = identifierError(row.column);
114
- if (colErr) return `column ${colErr}`;
115
- if (!isValidJsonPath(row.path))
116
- return "path must be dot-separated identifiers";
117
- return null;
118
- }
119
- case "fk": {
120
- const viaErr = identifierError(row.via);
121
- if (viaErr) return `via ${viaErr}`;
122
- const tableErr = identifierError(row.table);
123
- if (tableErr) return `table ${tableErr}`;
124
- const colErr = identifierError(row.column);
125
- if (colErr) return `column ${colErr}`;
126
- return null;
127
- }
128
- case "predicate":
129
- return row.name.length === 0 ? "pick a predicate" : !isValidIdentifier(row.name) ? "predicate name must be a single identifier" : null;
130
- default:
131
- return "unknown kind";
132
- }
133
- }
134
- function rowToBinding(row) {
135
- switch (row.kind) {
136
- case "column":
137
- return { ref: row.ref, kind: "column", column: row.column };
138
- case "json":
139
- return { ref: row.ref, kind: "json", column: row.column, path: row.path };
140
- case "fk":
141
- return {
142
- ref: row.ref,
143
- kind: "fk",
144
- via: row.via,
145
- table: row.table,
146
- column: row.column
147
- };
148
- case "predicate":
149
- return { ref: row.ref, kind: "predicate", name: row.name };
150
- default:
151
- return { ref: row.ref, kind: "column", column: "" };
152
- }
153
- }
74
+
75
+ // src/board-host/widget/styles.ts
154
76
  var S = {
155
77
  card: {
156
78
  background: "#fff",
@@ -232,6 +154,200 @@ var S = {
232
154
  borderRadius: 999
233
155
  }
234
156
  };
157
+ function laneStageId(lane) {
158
+ return lane.id ?? lane.key;
159
+ }
160
+ function withStale(offered, extra) {
161
+ const known = new Set(offered.map((o) => o.value));
162
+ const stale = extra.filter((v) => v && !known.has(v)).map((v) => ({ value: v, label: `${v} (not on the board)` }));
163
+ return [...offered, ...stale];
164
+ }
165
+ function LaneMapStep({
166
+ lanes,
167
+ value,
168
+ onChange,
169
+ hostStates,
170
+ createIfMissing
171
+ }) {
172
+ function setEntry(key, entry) {
173
+ onChange({ ...value, [key]: entry });
174
+ }
175
+ return /* @__PURE__ */ jsx(Fragment, { children: lanes.map((lane) => {
176
+ const entry = value[lane.key];
177
+ const hostState = entry?.hostState ?? "";
178
+ const alsoFrom = entry?.alsoFrom ?? [];
179
+ const mapped = hostState.trim().length > 0;
180
+ return /* @__PURE__ */ jsxs("div", { style: S.lane, children: [
181
+ /* @__PURE__ */ jsxs("span", { children: [
182
+ lane.label,
183
+ /* @__PURE__ */ jsx("small", { style: { display: "block", color: "#98a1ad", fontSize: 11 }, children: laneStageId(lane) })
184
+ ] }),
185
+ /* @__PURE__ */ jsx("span", { style: { color: "#98a1ad", textAlign: "center" }, children: "\u2192" }),
186
+ hostStates ? /* @__PURE__ */ jsxs(
187
+ "select",
188
+ {
189
+ "aria-label": `Host state for ${lane.label}`,
190
+ value: hostState,
191
+ onChange: (e) => {
192
+ const next = e.target.value;
193
+ setEntry(lane.key, {
194
+ hostState: next,
195
+ alsoFrom: alsoFrom.filter((s) => s !== next)
196
+ });
197
+ },
198
+ style: { ...S.input, minWidth: 0, width: "100%" },
199
+ children: [
200
+ /* @__PURE__ */ jsx("option", { value: "", children: "\u2014 host state \u2014" }),
201
+ withStale(hostStates, [hostState]).map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
202
+ ]
203
+ }
204
+ ) : /* @__PURE__ */ jsx(
205
+ "input",
206
+ {
207
+ "aria-label": `Host state for ${lane.label}`,
208
+ value: hostState,
209
+ placeholder: "\u2014 host state \u2014",
210
+ onChange: (e) => {
211
+ setEntry(lane.key, { ...entry, hostState: e.target.value });
212
+ },
213
+ style: { ...S.input, minWidth: 0, width: "100%" }
214
+ }
215
+ ),
216
+ createIfMissing ? /* @__PURE__ */ jsxs(
217
+ "label",
218
+ {
219
+ style: { display: "flex", alignItems: "center", gap: 6, fontSize: 11.5, color: "#6b7480" },
220
+ children: [
221
+ /* @__PURE__ */ jsx(
222
+ "input",
223
+ {
224
+ type: "checkbox",
225
+ "aria-label": `Create lane ${lane.label} if missing`,
226
+ checked: createIfMissing.value[lane.key] ?? false,
227
+ onChange: (e) => createIfMissing.onChange(lane.key, e.target.checked)
228
+ }
229
+ ),
230
+ "create"
231
+ ]
232
+ }
233
+ ) : /* @__PURE__ */ jsx("span", {}),
234
+ hostStates && /* @__PURE__ */ jsxs(
235
+ "label",
236
+ {
237
+ style: {
238
+ gridColumn: "1 / -1",
239
+ display: "flex",
240
+ alignItems: "flex-start",
241
+ gap: 8,
242
+ fontSize: 11.5,
243
+ color: "#6b7480"
244
+ },
245
+ children: [
246
+ "Also accepts",
247
+ /* @__PURE__ */ jsx(
248
+ "select",
249
+ {
250
+ multiple: true,
251
+ "aria-label": `Also accepts for ${lane.label}`,
252
+ value: alsoFrom,
253
+ onChange: (e) => {
254
+ const picked = Array.from(e.target.options).filter((o) => o.selected).map((o) => o.value);
255
+ setEntry(lane.key, { hostState, alsoFrom: picked });
256
+ },
257
+ style: { ...S.input, minWidth: 0, flex: 1 },
258
+ children: withStale(hostStates, alsoFrom).filter((o) => o.value !== hostState).map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
259
+ }
260
+ )
261
+ ]
262
+ }
263
+ ),
264
+ /* @__PURE__ */ jsx(
265
+ "span",
266
+ {
267
+ style: { ...S.st, color: mapped ? "#16a34a" : "#c2710c", gridColumn: "1 / -1", marginTop: 2 },
268
+ children: mapped ? "\u2713 mapped" : "\u26A0 gap \u2014 unmapped lane"
269
+ }
270
+ )
271
+ ] }, lane.key);
272
+ }) });
273
+ }
274
+ var DEFAULT_ORG_COLUMN = "org_id";
275
+ function suggestHostState(lane) {
276
+ return lane.label ?? lane.key ?? "";
277
+ }
278
+ function freshFieldRow(ref, requiresPredicate) {
279
+ return {
280
+ ref,
281
+ kind: requiresPredicate ? "predicate" : "column",
282
+ column: "",
283
+ path: "",
284
+ via: "",
285
+ table: "",
286
+ name: "",
287
+ predicateOnly: requiresPredicate
288
+ };
289
+ }
290
+ function fieldRowFromBinding(b, requiresPredicate) {
291
+ const base = freshFieldRow(b.ref, requiresPredicate);
292
+ switch (b.kind) {
293
+ case "column":
294
+ return { ...base, kind: "column", column: b.column };
295
+ case "json":
296
+ return { ...base, kind: "json", column: b.column, path: b.path };
297
+ case "fk":
298
+ return { ...base, kind: "fk", via: b.via, table: b.table, column: b.column };
299
+ case "predicate":
300
+ return { ...base, kind: "predicate", name: b.name };
301
+ default:
302
+ return base;
303
+ }
304
+ }
305
+ function fieldRowError(row) {
306
+ switch (row.kind) {
307
+ case "column":
308
+ return identifierError(row.column) && `column ${identifierError(row.column)}`;
309
+ case "json": {
310
+ const colErr = identifierError(row.column);
311
+ if (colErr) return `column ${colErr}`;
312
+ if (!isValidJsonPath(row.path))
313
+ return "path must be dot-separated identifiers";
314
+ return null;
315
+ }
316
+ case "fk": {
317
+ const viaErr = identifierError(row.via);
318
+ if (viaErr) return `via ${viaErr}`;
319
+ const tableErr = identifierError(row.table);
320
+ if (tableErr) return `table ${tableErr}`;
321
+ const colErr = identifierError(row.column);
322
+ if (colErr) return `column ${colErr}`;
323
+ return null;
324
+ }
325
+ case "predicate":
326
+ return row.name.length === 0 ? "pick a predicate" : !isValidIdentifier(row.name) ? "predicate name must be a single identifier" : null;
327
+ default:
328
+ return "unknown kind";
329
+ }
330
+ }
331
+ function rowToBinding(row) {
332
+ switch (row.kind) {
333
+ case "column":
334
+ return { ref: row.ref, kind: "column", column: row.column };
335
+ case "json":
336
+ return { ref: row.ref, kind: "json", column: row.column, path: row.path };
337
+ case "fk":
338
+ return {
339
+ ref: row.ref,
340
+ kind: "fk",
341
+ via: row.via,
342
+ table: row.table,
343
+ column: row.column
344
+ };
345
+ case "predicate":
346
+ return { ref: row.ref, kind: "predicate", name: row.name };
347
+ default:
348
+ return { ref: row.ref, kind: "column", column: "" };
349
+ }
350
+ }
235
351
  function statusColors(status) {
236
352
  switch (status) {
237
353
  case "valid":
@@ -590,57 +706,28 @@ function BoardHostMapping({
590
706
  /* @__PURE__ */ jsx("span", { style: S.ttl, children: "Lane map" }),
591
707
  /* @__PURE__ */ jsx("span", { style: { marginLeft: "auto", fontSize: 11, color: "#98a1ad" }, children: "auto-matched by name" })
592
708
  ] }),
593
- lanes.map((lane) => {
594
- const mapped = (laneStates[lane.key] ?? "").trim().length > 0;
595
- return /* @__PURE__ */ jsxs("div", { style: S.lane, children: [
596
- /* @__PURE__ */ jsxs("span", { children: [
597
- lane.label,
598
- /* @__PURE__ */ jsx("small", { style: { display: "block", color: "#98a1ad", fontSize: 11 }, children: laneStageId(lane) })
599
- ] }),
600
- /* @__PURE__ */ jsx("span", { style: { color: "#98a1ad", textAlign: "center" }, children: "\u2192" }),
601
- /* @__PURE__ */ jsx(
602
- "input",
603
- {
604
- "aria-label": `Host state for ${lane.label}`,
605
- value: laneStates[lane.key] ?? "",
606
- placeholder: "\u2014 host state \u2014",
607
- onChange: (e) => {
608
- setLaneStates((s) => ({ ...s, [lane.key]: e.target.value }));
609
- setValidation(null);
610
- },
611
- style: { ...S.input, minWidth: 0, width: "100%" }
612
- }
613
- ),
614
- /* @__PURE__ */ jsxs(
615
- "label",
616
- {
617
- style: { display: "flex", alignItems: "center", gap: 6, fontSize: 11.5, color: "#6b7480" },
618
- children: [
619
- /* @__PURE__ */ jsx(
620
- "input",
621
- {
622
- type: "checkbox",
623
- "aria-label": `Create lane ${lane.label} if missing`,
624
- checked: laneCreate[lane.key] ?? false,
625
- onChange: (e) => {
626
- setLaneCreate((c) => ({ ...c, [lane.key]: e.target.checked }));
627
- setValidation(null);
628
- }
629
- }
630
- ),
631
- "create"
632
- ]
633
- }
709
+ /* @__PURE__ */ jsx(
710
+ LaneMapStep,
711
+ {
712
+ lanes,
713
+ value: Object.fromEntries(
714
+ Object.entries(laneStates).map(([k, hostState]) => [k, { hostState }])
634
715
  ),
635
- /* @__PURE__ */ jsx(
636
- "span",
637
- {
638
- style: { ...S.st, color: mapped ? "#16a34a" : "#c2710c", gridColumn: "1 / -1", marginTop: 2 },
639
- children: mapped ? "\u2713 mapped" : "\u26A0 gap \u2014 unmapped lane"
716
+ onChange: (next) => {
717
+ setLaneStates(
718
+ Object.fromEntries(Object.entries(next).map(([k, e]) => [k, e.hostState]))
719
+ );
720
+ setValidation(null);
721
+ },
722
+ createIfMissing: {
723
+ value: laneCreate,
724
+ onChange: (key, checked) => {
725
+ setLaneCreate((c) => ({ ...c, [key]: checked }));
726
+ setValidation(null);
640
727
  }
641
- )
642
- ] }, lane.key);
643
- })
728
+ }
729
+ }
730
+ )
644
731
  ] }),
645
732
  /* @__PURE__ */ jsxs("section", { style: S.sec, "aria-label": "Field map", children: [
646
733
  /* @__PURE__ */ jsxs("div", { style: S.lbl, children: [
@@ -815,6 +902,6 @@ function BoardHostMapping({
815
902
  ] });
816
903
  }
817
904
 
818
- export { BoardHostMapping, BoardHostMappingProvider, WIDGET_IDENTIFIER_PATTERN, collectDueRefs, identifierError, isValidIdentifier, isValidJsonPath, useBoardHostMappingAdapter, useBoardHostMappingAdapterOptional };
905
+ export { BoardHostMapping, BoardHostMappingProvider, LaneMapStep, WIDGET_IDENTIFIER_PATTERN, collectDueRefs, identifierError, isValidIdentifier, isValidJsonPath, useBoardHostMappingAdapter, useBoardHostMappingAdapterOptional };
819
906
  //# sourceMappingURL=index.js.map
820
907
  //# sourceMappingURL=index.js.map