@w6w/embed 0.2.0 → 0.2.11

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 (119) hide show
  1. package/dist/{ConfirmModal-RLbZT5_k.js → ConfirmModal-BE-SdX-O.js} +53 -49
  2. package/dist/{ConfirmModal-RLbZT5_k.js.map → ConfirmModal-BE-SdX-O.js.map} +1 -1
  3. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-D6CQLpa_.js} +25 -25
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-D6CQLpa_.js.map} +1 -1
  5. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-YauVdolr.js} +5 -5
  6. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-YauVdolr.js.map} +1 -1
  7. package/dist/{ImportSpecModal-BDQIf6rg.js → ImportSpecModal-B7qd1Km2.js} +3 -3
  8. package/dist/{ImportSpecModal-BDQIf6rg.js.map → ImportSpecModal-B7qd1Km2.js.map} +1 -1
  9. package/dist/ModelRoutesManager-BGESQahw.js +345 -0
  10. package/dist/ModelRoutesManager-BGESQahw.js.map +1 -0
  11. package/dist/WorkflowEditor-CwvmAGp2.js +925 -0
  12. package/dist/WorkflowEditor-CwvmAGp2.js.map +1 -0
  13. package/dist/{apps-1FNUwbGv.js → apps-CboASBKr.js} +14 -14
  14. package/dist/{apps-1FNUwbGv.js.map → apps-CboASBKr.js.map} +1 -1
  15. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  16. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  17. package/dist/chrome/ConfirmModal.d.ts +4 -1
  18. package/dist/chrome/workspace.d.ts +4 -0
  19. package/dist/{coerce-input-BicYr7nc.js → coerce-input-DttlcSdO.js} +70 -58
  20. package/dist/coerce-input-DttlcSdO.js.map +1 -0
  21. package/dist/connections-D7cgXhDS.js +119 -0
  22. package/dist/connections-D7cgXhDS.js.map +1 -0
  23. package/dist/credentials-DaQU3Ca_.js +171 -0
  24. package/dist/credentials-DaQU3Ca_.js.map +1 -0
  25. package/dist/document-sources-UCwe8x77.js +91 -0
  26. package/dist/document-sources-UCwe8x77.js.map +1 -0
  27. package/dist/draft.mjs +1 -1
  28. package/dist/editor/BindingBanner.d.ts +13 -0
  29. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  30. package/dist/editor/EndpointCards.d.ts +4 -1
  31. package/dist/editor/PublishControl.d.ts +19 -0
  32. package/dist/editor/TargetSelector.d.ts +15 -0
  33. package/dist/editor/TargetSelector.types.d.ts +2 -0
  34. package/dist/editor/definition.d.ts +2 -0
  35. package/dist/{editor-apps-BdenSV1o.js → editor-apps-BUZWld-m.js} +5 -5
  36. package/dist/{editor-apps-BdenSV1o.js.map → editor-apps-BUZWld-m.js.map} +1 -1
  37. package/dist/{editor-tools-RxmY5iyi.js → editor-tools-B_Lfx3kw.js} +11 -11
  38. package/dist/editor-tools-B_Lfx3kw.js.map +1 -0
  39. package/dist/editor.mjs +1 -1
  40. package/dist/editors.mjs +769 -622
  41. package/dist/editors.mjs.map +1 -1
  42. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  43. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  44. package/dist/fields-DvS8XZFc.js +21 -0
  45. package/dist/fields-DvS8XZFc.js.map +1 -0
  46. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  47. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  48. package/dist/forms.d.ts +4 -0
  49. package/dist/forms.mjs +611 -212
  50. package/dist/forms.mjs.map +1 -1
  51. package/dist/index.mjs +119 -112
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/lib/binding-problems.d.ts +38 -0
  54. package/dist/lib/code-rail.d.ts +4 -2
  55. package/dist/lib/index.d.ts +1 -0
  56. package/dist/lib/invoke-error.d.ts +1 -0
  57. package/dist/lib/sdk-snippets.d.ts +1 -1
  58. package/dist/lib/target-fields.d.ts +8 -0
  59. package/dist/lib/trigger-preview.d.ts +1 -0
  60. package/dist/lib/workflow-live-run.d.ts +9 -2
  61. package/dist/lib/workflow-nodes.d.ts +5 -0
  62. package/dist/lib/workflow-validity.d.ts +1 -0
  63. package/dist/lib.mjs +72 -70
  64. package/dist/lists/ConnectionDependents.d.ts +31 -0
  65. package/dist/lists/ConnectionDetail.d.ts +4 -1
  66. package/dist/lists/ConnectionList.d.ts +4 -1
  67. package/dist/lists/CredentialDetail.d.ts +15 -0
  68. package/dist/lists/CredentialList.d.ts +14 -0
  69. package/dist/lists/ModelCatalog.d.ts +12 -0
  70. package/dist/lists/ModelUsage.d.ts +12 -0
  71. package/dist/lists.d.ts +8 -0
  72. package/dist/lists.mjs +1322 -604
  73. package/dist/lists.mjs.map +1 -1
  74. package/dist/models-bAayQPJ_.js +270 -0
  75. package/dist/models-bAayQPJ_.js.map +1 -0
  76. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  77. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  78. package/dist/rail.mjs +4 -4
  79. package/dist/repos/agents-studio-agents.d.ts +52 -0
  80. package/dist/repos/agents-studio-assets.d.ts +68 -0
  81. package/dist/repos/connections.d.ts +30 -12
  82. package/dist/repos/credentials.d.ts +83 -0
  83. package/dist/repos/endpoints.d.ts +9 -3
  84. package/dist/repos/fields.d.ts +34 -0
  85. package/dist/repos/functions.d.ts +7 -5
  86. package/dist/repos/index.d.ts +5 -0
  87. package/dist/repos/models.d.ts +289 -0
  88. package/dist/repos.mjs +613 -176
  89. package/dist/repos.mjs.map +1 -1
  90. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  91. package/dist/slug-BVdgiP_L.js.map +1 -0
  92. package/dist/{spec-export-Cf3VQSQS.js → spec-export-CBbloO_n.js} +7 -7
  93. package/dist/{spec-export-Cf3VQSQS.js.map → spec-export-CBbloO_n.js.map} +1 -1
  94. package/dist/{spec-import-CjmxyZDR.js → spec-import-CW6R_Wk1.js} +160 -156
  95. package/dist/spec-import-CW6R_Wk1.js.map +1 -0
  96. package/dist/theme-context-E2ZhlXDX.js +6 -0
  97. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  98. package/dist/theme-context.d.ts +2 -0
  99. package/dist/trigger-preview-DKxfjzUY.js +145 -0
  100. package/dist/trigger-preview-DKxfjzUY.js.map +1 -0
  101. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DsALnSfF.js} +22 -22
  102. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DsALnSfF.js.map} +1 -1
  103. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  104. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  105. package/package.json +1 -1
  106. package/src/styles.css +2 -6
  107. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  108. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  109. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  110. package/dist/connections-CjjYeRqb.js +0 -78
  111. package/dist/connections-CjjYeRqb.js.map +0 -1
  112. package/dist/document-sources-C0grrtdq.js +0 -86
  113. package/dist/document-sources-C0grrtdq.js.map +0 -1
  114. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  115. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  116. package/dist/slug-C4ktDPdy.js.map +0 -1
  117. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  118. package/dist/trigger-preview-VPkrryDl.js +0 -120
  119. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
@@ -0,0 +1,91 @@
1
+ import { parse as l } from "yaml";
2
+ function u(n) {
3
+ if (!n) return !1;
4
+ switch (n.kind) {
5
+ case "function":
6
+ case "endpoint":
7
+ case "workflow":
8
+ return !0;
9
+ // A bare connection has no snippet; only the action page (which names one) does.
10
+ case "connection":
11
+ return !!n.action;
12
+ default:
13
+ return !1;
14
+ }
15
+ }
16
+ function f(n) {
17
+ if (!n) return null;
18
+ switch (n.kind) {
19
+ case "function":
20
+ return { kind: "function", id: n.id, key: n.key, inputs: n.inputs, alias: n.alias };
21
+ case "endpoint":
22
+ return {
23
+ kind: "endpoint",
24
+ id: n.id,
25
+ key: n.key,
26
+ invokeUrl: n.invokeUrl,
27
+ invokeUrlByKey: n.invokeUrlByKey,
28
+ urlForm: n.urlForm,
29
+ alias: n.alias,
30
+ inputs: n.inputs
31
+ };
32
+ case "workflow":
33
+ return { kind: "workflow", id: n.id, displayName: n.label, key: n.key };
34
+ case "connection":
35
+ return n.action ? { kind: "connection", id: n.id, action: n.action, params: n.params } : null;
36
+ default:
37
+ return null;
38
+ }
39
+ }
40
+ function k({
41
+ resource: n,
42
+ target: e,
43
+ hasAdapter: r
44
+ }) {
45
+ return (e.kind === "function" || e.kind === "workflow") && e.kind === n.kind && e.id === n.id ? r ? "warn" : "block" : "allow";
46
+ }
47
+ function t(n) {
48
+ let e;
49
+ if (n.format === "json")
50
+ try {
51
+ e = JSON.parse(n.content);
52
+ } catch {
53
+ return null;
54
+ }
55
+ else if (n.format === "yaml")
56
+ try {
57
+ e = l(n.content);
58
+ } catch {
59
+ return null;
60
+ }
61
+ else
62
+ return null;
63
+ return typeof e != "object" || e === null || Array.isArray(e) ? null : e;
64
+ }
65
+ function d(n) {
66
+ return n.map((e) => {
67
+ const r = t(e);
68
+ if (!r) return { key: e.key };
69
+ const i = Object.keys(r);
70
+ return i.length > 0 ? { key: e.key, fields: i.map((o) => ({ key: o })) } : { key: e.key };
71
+ });
72
+ }
73
+ function c(n) {
74
+ const e = {};
75
+ for (const r of n) {
76
+ e[`documents.${r.key}`] = r.content;
77
+ const i = t(r);
78
+ if (i)
79
+ for (const [o, a] of Object.entries(i))
80
+ e[`documents.${r.key}.${o}`] = a;
81
+ }
82
+ return e;
83
+ }
84
+ export {
85
+ c as d,
86
+ k as e,
87
+ u as i,
88
+ d as p,
89
+ f as t
90
+ };
91
+ //# sourceMappingURL=document-sources-UCwe8x77.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-sources-UCwe8x77.js","sources":["../src/lib/code-rail.ts","../src/lib/error-handler-self.ts","../src/lib/document-sources.ts"],"sourcesContent":["/**\n * Pure decisions behind the right rail's Code tool (`src/ui/rail/CodeTool.tsx`).\n * Split out so `node --test` can gate them directly — mirrors\n * `src/lib/alias-rail.ts`'s own reason for existing: `node --test` throws\n * `ERR_UNKNOWN_FILE_EXTENSION` on any `@w6w/ui`-adjacent import, and\n * `src/ui/workspace.tsx` sits one hop from that barrel through `Layout.tsx`'s\n * import graph. So this module declares its own structural mirror of\n * `WorkspaceCallable` instead of importing it.\n */\nimport type { SnippetCallable, SnippetInput } from \"./sdk-snippets.ts\";\n\n/** Structural mirror of T2.1.2's widened `WorkspaceCallable` (`src/ui/workspace.tsx`). */\nexport type RailCallable =\n | { kind: \"function\"; id: string; key?: string; inputs?: readonly SnippetInput[]; alias?: string }\n | {\n kind: \"endpoint\";\n id: string;\n key?: string;\n invokeUrl?: string;\n invokeUrlByKey?: string;\n urlForm?: \"id\" | \"key\";\n alias?: string;\n inputs?: readonly SnippetInput[];\n }\n | { kind: \"workflow\"; id: string; label?: string; key?: string }\n | { kind: \"connection\"; id: string; action?: string; params?: readonly SnippetInput[] }\n | null;\n\n/**\n * Is a \"Call from code\" panel meaningful for this context? Mirrors\n * `alias-rail.ts`'s `targetForCallable` fail-closed shape exactly (its own\n * comment: *\"'connection' and no resource at all both fail closed to null —\n * house style\"*) — a bare `\"connection\"` (no `action`) and `null` both answer `false`.\n */\nexport function isAvailable(ctx: RailCallable): boolean {\n if (!ctx) return false;\n switch (ctx.kind) {\n case \"function\":\n case \"endpoint\":\n case \"workflow\":\n return true;\n // A bare connection has no snippet; only the action page (which names one) does.\n case \"connection\":\n return !!ctx.action;\n default:\n return false;\n }\n}\n\n/**\n * The widened-union -> `SnippetCallable` conversion `CodeTool.Panel` hands to\n * `CallFromCodeBody`. `null` for a context this tool has no snippet for\n * (a connection without an `action`, or no resource at all) — defensive, since `isAvailable`\n * already keeps the tool off the strip for those.\n *\n * The one easy-to-miss field: `WorkspaceCallable`'s `label` maps to\n * `SnippetCallable`'s `workflow` arm's `displayName` — NOT the same field\n * name. A naive `{...ctx}` spread compiles (both optional) but silently\n * drops the label everywhere it matters, never caught by `tsc`.\n */\nexport function toSnippetCallable(ctx: RailCallable): SnippetCallable | null {\n if (!ctx) return null;\n switch (ctx.kind) {\n case \"function\":\n return { kind: \"function\", id: ctx.id, key: ctx.key, inputs: ctx.inputs, alias: ctx.alias };\n case \"endpoint\":\n return {\n kind: \"endpoint\",\n id: ctx.id,\n key: ctx.key,\n invokeUrl: ctx.invokeUrl,\n invokeUrlByKey: ctx.invokeUrlByKey,\n urlForm: ctx.urlForm,\n alias: ctx.alias,\n inputs: ctx.inputs,\n };\n case \"workflow\":\n return { kind: \"workflow\", id: ctx.id, displayName: ctx.label, key: ctx.key };\n case \"connection\":\n return ctx.action\n ? { kind: \"connection\", id: ctx.id, action: ctx.action, params: ctx.params }\n : null;\n default:\n return null;\n }\n}\n","/**\n * The authoring-time half of the error-handler recursion guard. The server\n * compares resolved values at dispatch time; this small, pure decision keeps\n * the rail from creating the known-identical no-adapter case in the first\n * place without losing an adapter imported or authored elsewhere.\n */\nexport type ErrorHandlerSelfDecision = \"allow\" | \"warn\" | \"block\";\n\nexport interface ErrorHandlerSelfInput {\n resource: { kind: string; id: string };\n target: { kind: string; id: string };\n hasAdapter: boolean;\n}\n\n/**\n * Only Function and Workflow targets can re-enter the currently edited\n * resource. Actions are always allowed. A self-target with no adapter passes\n * the failed input through unchanged, so it is refused; an adapter is kept\n * and called out because only the runtime can determine its resolved values.\n */\nexport function errorHandlerSelfDecision({\n resource,\n target,\n hasAdapter,\n}: ErrorHandlerSelfInput): ErrorHandlerSelfDecision {\n const selfTarget =\n (target.kind === \"function\" || target.kind === \"workflow\") &&\n target.kind === resource.kind &&\n target.id === resource.id;\n if (!selfTarget) return \"allow\";\n return hasAdapter ? \"warn\" : \"block\";\n}\n","/**\n * Pure `Doc[]` → `ExpressionOptions` projections for the ƒx picker's\n * Documents group — extracted out of `ExpressionScope.tsx` so studio's\n * Node-native `test:unit` runner (globbed to `src/lib/__tests__/`,\n * `src/api/__tests__/` and `src/repos/__tests__/` only — `.ai/PLANNER.md`\n * fact 10) can reach it. No React, no import from `src/ui/` — `@w6w/ui`'s\n * `ExpressionDocumentSource` interface is not imported either (it is not\n * exported from `@w6w/ui`'s barrel, D-P3): the object literals returned below\n * are structurally identical to it, so TypeScript carries the shape without a\n * type import.\n *\n * ## The gate — mirrors the engine's own, bit-for-bit\n *\n * A document contributes field data **iff**: `doc.format === \"json\"` AND\n * `JSON.parse(doc.content)` succeeds into a plain object, OR\n * `doc.format === \"yaml\"` AND npm `yaml`'s `parse(doc.content)` succeeds into\n * a plain object — where *plain object* means\n * `typeof v === \"object\" && v !== null && !Array.isArray(v)`. This mirrors\n * the engine's own gate (`documentsSeed` /\n * `packages/server/packages/api/run-seed.ts`, read-only, out of scope)\n * bit-for-bit for each format: `format === \"json\"` or `format === \"yaml\"`,\n * then a `try/catch` parse, falling back to the raw content string on either\n * a non-matching format or a throw. Reproduced here so the picker never\n * offers a ref the run scope itself would refuse to resolve\n * (`render_ref_unresolved`) — `text`/`markdown`/`html` documents, and a\n * `json`/`yaml` document whose parse throws or yields a non-plain-object, are\n * excluded.\n *\n * The two parsers are not identical for every input — `@std/yaml` (server,\n * `{ schema: \"core\" }`) and npm `yaml` (here) diverge on tab-indented content\n * and on an unresolvable custom tag (`!!js/function`), both accepted, tested\n * debt (D-3). Every other input, including a plain JSON object (JSON is a\n * subset of YAML), agrees between the two.\n *\n * Field keys are enumerated RAW and UNFILTERED by {@link projectDocumentSources}\n * — arbitrary user-authored JSON keys (which can contain `.`/`{`/`}`/\n * whitespace) reach the modal; `isRefSafeKey` filters them exactly once, at\n * the modal's render site (`ExpressionEditorModal.tsx`), never here\n * (`building-blocks.md`: \"enumerate raw at the source, filter once at the\n * single render site\").\n */\nimport type { Doc } from \"@w6w/sdk\";\nimport { parse as parseYaml } from \"yaml\";\n\n/** One document's contribution to `ExpressionOptions.documents` — structurally\n * identical to `@w6w/ui`'s (unexported) `ExpressionDocumentSource`. */\nexport interface DocumentSource {\n key: string;\n fields?: { key: string }[];\n}\n\n/**\n * `doc`'s parsed content when the gate holds, else `null`. The one place both\n * functions below apply the gate, so they cannot silently disagree on it.\n */\nfunction gatedFields(doc: Doc): Record<string, unknown> | null {\n let parsed: unknown;\n if (doc.format === \"json\") {\n try {\n parsed = JSON.parse(doc.content);\n } catch {\n return null;\n }\n } else if (doc.format === \"yaml\") {\n try {\n parsed = parseYaml(doc.content);\n } catch {\n return null;\n }\n } else {\n return null;\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return null;\n return parsed as Record<string, unknown>;\n}\n\n/**\n * The `ExpressionOptions.documents` array: `{ key }` for every document, plus\n * `fields` (raw, unfiltered top-level keys) when the gate holds AND the\n * parsed object has at least one key. `fields` is OMITTED (not `[]`) both\n * when the gate fails and when it holds but yields zero keys — a consumer\n * must be able to tell \"nothing declared\" from \"declared none\".\n */\nexport function projectDocumentSources(docs: Doc[]): DocumentSource[] {\n return docs.map((d) => {\n const parsed = gatedFields(d);\n if (!parsed) return { key: d.key };\n const keys = Object.keys(parsed);\n return keys.length > 0 ? { key: d.key, fields: keys.map((key) => ({ key })) } : { key: d.key };\n });\n}\n\n/**\n * The `sampleValues` entries the ƒx Result preview substitutes for document\n * refs: `documents.<key>` → the document's raw content, for every document\n * (unconditional, exactly as before this project), PLUS `documents.<key>.<field>`\n * → the field's own parsed value, for the gated set only. Without the second\n * half, every field ref this project newly makes pickable would preview as\n * the empty string (`renderResult` does an exact flat-key lookup).\n */\nexport function documentSampleValues(docs: Doc[]): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const d of docs) {\n out[`documents.${d.key}`] = d.content;\n const parsed = gatedFields(d);\n if (!parsed) continue;\n for (const [key, value] of Object.entries(parsed)) {\n out[`documents.${d.key}.${key}`] = value;\n }\n }\n return out;\n}\n"],"names":["isAvailable","ctx","toSnippetCallable","errorHandlerSelfDecision","resource","target","hasAdapter","gatedFields","doc","parsed","parseYaml","projectDocumentSources","docs","d","keys","key","documentSampleValues","out","value"],"mappings":";AAkCO,SAASA,EAAYC,GAA4B;AACtD,MAAI,CAACA,EAAK,QAAO;AACjB,UAAQA,EAAI,MAAA;AAAA,IACV,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA;AAAA,IAET,KAAK;AACH,aAAO,CAAC,CAACA,EAAI;AAAA,IACf;AACE,aAAO;AAAA,EAAA;AAEb;AAaO,SAASC,EAAkBD,GAA2C;AAC3E,MAAI,CAACA,EAAK,QAAO;AACjB,UAAQA,EAAI,MAAA;AAAA,IACV,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,IAAIA,EAAI,IAAI,KAAKA,EAAI,KAAK,QAAQA,EAAI,QAAQ,OAAOA,EAAI,MAAA;AAAA,IACtF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAIA,EAAI;AAAA,QACR,KAAKA,EAAI;AAAA,QACT,WAAWA,EAAI;AAAA,QACf,gBAAgBA,EAAI;AAAA,QACpB,SAASA,EAAI;AAAA,QACb,OAAOA,EAAI;AAAA,QACX,QAAQA,EAAI;AAAA,MAAA;AAAA,IAEhB,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,IAAIA,EAAI,IAAI,aAAaA,EAAI,OAAO,KAAKA,EAAI,IAAA;AAAA,IAC1E,KAAK;AACH,aAAOA,EAAI,SACP,EAAE,MAAM,cAAc,IAAIA,EAAI,IAAI,QAAQA,EAAI,QAAQ,QAAQA,EAAI,WAClE;AAAA,IACN;AACE,aAAO;AAAA,EAAA;AAEb;ACjEO,SAASE,EAAyB;AAAA,EACvC,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AACF,GAAoD;AAKlD,UAHGD,EAAO,SAAS,cAAcA,EAAO,SAAS,eAC/CA,EAAO,SAASD,EAAS,QACzBC,EAAO,OAAOD,EAAS,KAElBE,IAAa,SAAS,UADL;AAE1B;ACwBA,SAASC,EAAYC,GAA0C;AAC7D,MAAIC;AACJ,MAAID,EAAI,WAAW;AACjB,QAAI;AACF,MAAAC,IAAS,KAAK,MAAMD,EAAI,OAAO;AAAA,IACjC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,WACSA,EAAI,WAAW;AACxB,QAAI;AACF,MAAAC,IAASC,EAAUF,EAAI,OAAO;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA;AAEA,WAAO;AAET,SAAI,OAAOC,KAAW,YAAYA,MAAW,QAAQ,MAAM,QAAQA,CAAM,IAAU,OAC5EA;AACT;AASO,SAASE,EAAuBC,GAA+B;AACpE,SAAOA,EAAK,IAAI,CAACC,MAAM;AACrB,UAAMJ,IAASF,EAAYM,CAAC;AAC5B,QAAI,CAACJ,EAAQ,QAAO,EAAE,KAAKI,EAAE,IAAA;AAC7B,UAAMC,IAAO,OAAO,KAAKL,CAAM;AAC/B,WAAOK,EAAK,SAAS,IAAI,EAAE,KAAKD,EAAE,KAAK,QAAQC,EAAK,IAAI,CAACC,OAAS,EAAE,KAAAA,IAAM,EAAA,IAAM,EAAE,KAAKF,EAAE,IAAA;AAAA,EAC3F,CAAC;AACH;AAUO,SAASG,EAAqBJ,GAAsC;AACzE,QAAMK,IAA+B,CAAA;AACrC,aAAWJ,KAAKD,GAAM;AACpB,IAAAK,EAAI,aAAaJ,EAAE,GAAG,EAAE,IAAIA,EAAE;AAC9B,UAAMJ,IAASF,EAAYM,CAAC;AAC5B,QAAKJ;AACL,iBAAW,CAACM,GAAKG,CAAK,KAAK,OAAO,QAAQT,CAAM;AAC9C,QAAAQ,EAAI,aAAaJ,EAAE,GAAG,IAAIE,CAAG,EAAE,IAAIG;AAAA,EAEvC;AACA,SAAOD;AACT;"}
package/dist/draft.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { A as a, c as s, i as t, n as o, r as i, u } from "./use-workflow-draft-DzAyUeA6.js";
3
3
  import { E as n, u as l } from "./client-context-CX61Bgw-.js";
4
4
  import { D as E, c, u as d } from "./draft-registry-YF0tqNN0.js";
5
- import { u as p, a as x, b as S } from "./use-callable-draft-zHLpcr-b.js";
5
+ import { u as p, a as x, b as S } from "./use-callable-draft-DsALnSfF.js";
6
6
  export {
7
7
  a as AUTOSAVE_DEBOUNCE_MS,
8
8
  E as DraftRegistryProvider,
@@ -0,0 +1,13 @@
1
+ export interface BindingBannerProps {
2
+ kind: "workflow" | "function" | "endpoint";
3
+ problemCount: number;
4
+ canEnable: boolean;
5
+ onEnable: () => void;
6
+ pending?: boolean;
7
+ }
8
+ /** The one "disabled because a connection is gone" banner all three editors render. */
9
+ export declare function BindingBanner(props: BindingBannerProps): import('react').DetailedReactHTMLElement<{
10
+ role: "alert";
11
+ className: string;
12
+ "data-testid": string;
13
+ }, HTMLElement>;
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CallableKind } from '../lib/callable-kind.ts';
3
+ import { PublishControlProps } from './PublishControl.tsx';
3
4
  import { CallableEditorNavigation, CallableEditorSlots } from './types.ts';
4
5
  export interface CallableEditorFrameProps {
5
6
  /** Which kind's copy (back/save labels, not-found heading) the frame shows. */
@@ -22,6 +23,9 @@ export interface CallableEditorFrameProps {
22
23
  banners?: ReactNode;
23
24
  /** Rendered as the FIRST child of the header action row, before Save (e.g. a JSON toggle). */
24
25
  headerActions?: ReactNode;
26
+ /** The header Publish (save-then-publish). Omitted ⇒ no control; ignored when `slots.header`
27
+ * replaces the header, since the host then owns the run/publish row. */
28
+ publish?: Omit<PublishControlProps, "kind" | "onError">;
25
29
  children: ReactNode;
26
30
  }
27
31
  /**
@@ -29,5 +33,8 @@ export interface CallableEditorFrameProps {
29
33
  * `incomplete` badge, Save, the error banner and the body (or the not-found card). Router-free —
30
34
  * it asks the host to navigate through `onNavigate` and sets no document title. It publishes
31
35
  * nothing to the rail workspace either: each editor body does that itself (`useWorkspace`).
36
+ *
37
+ * The body is a `.w6w-card-stack` (@w6w/ui's shared rule): the cards an editor renders are ONE
38
+ * vertical column, so the gap between them comes from that rule and never from the caller.
32
39
  */
33
40
  export declare function CallableEditorFrame(props: CallableEditorFrameProps): import("react").JSX.Element;
@@ -1,3 +1,4 @@
1
+ import { FlushOutcome } from '../draft/use-workflow-draft.ts';
1
2
  import { UrlForm } from '../lib/endpoint-editor.ts';
2
3
  import { EndpointInput, EndpointSecurity, InvokeUrlOption } from '../repos/endpoints.ts';
3
4
  /**
@@ -46,11 +47,13 @@ export declare function SecretField(props: {
46
47
  }): import("react").JSX.Element;
47
48
  /**
48
49
  * Test-invoke panel: one field per declared input, POSTed to /endpoints/:id/invoke. The server
49
- * invokes the STORED definition, so unsaved edits are not what runs. The result is the
50
+ * invokes the STORED draft without publishing (`allowUnpublished`); unsaved edits are saved first
51
+ * via `saveFirst`, so what runs is what the editor shows. The result is the
50
52
  * `kind`-tagged envelope: an Action or Function target answers with an inline `output`; a Workflow
51
53
  * target answers with a `runId` to poll.
52
54
  */
53
55
  export declare function EndpointTestInvoke(props: {
54
56
  id: string;
55
57
  inputs: EndpointInput[];
58
+ saveFirst: () => Promise<FlushOutcome>;
56
59
  }): import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { ReactNode } from 'react';
2
+ import { FlushOutcome } from '../draft/use-workflow-draft.ts';
3
+ import { CallableKind } from '../lib/callable-kind.ts';
4
+ export interface PublishControlProps {
5
+ kind: Extract<CallableKind, "function" | "endpoint">;
6
+ id: string;
7
+ /** The editor's `saveFirst`: publish runs only on `clean | saved`. */
8
+ saveFirst: () => Promise<FlushOutcome>;
9
+ /** The editor's own gate (`!canSave || incomplete`). */
10
+ disabled: boolean;
11
+ /** Where a `blocked` reason or a failed publish shows (the frame's banner). */
12
+ onError: (message: string | null) => void;
13
+ }
14
+ /**
15
+ * The header Publish of the Function and Endpoint editors, a copy of WorkflowEditor's `wf-publish`:
16
+ * `Publish` → `● Published`, save-then-publish. Same versions cache key as the Settings rail, so
17
+ * a publish from either surface refreshes both.
18
+ */
19
+ export declare function PublishControl(props: PublishControlProps): ReactNode;
@@ -1,4 +1,19 @@
1
+ import { ReactNode } from 'react';
1
2
  import { TargetKind, TargetSelectorProps } from './TargetSelector.types.ts';
3
+ /**
4
+ * The disabled-callable banner for a Function/Endpoint whose action target binds a connection the
5
+ * account no longer has (R5). Shares the connections cache entry with `TargetSelector`; returns
6
+ * `null` unless the callable is disabled and (has, or had this mount) a missing binding.
7
+ */
8
+ export declare function useBindingBanner(args: {
9
+ kind: "function" | "endpoint";
10
+ id: string;
11
+ uses: {
12
+ app?: string;
13
+ connection?: string | null;
14
+ } | undefined;
15
+ dirty: boolean;
16
+ }): ReactNode;
2
17
  /**
3
18
  * One `target` picker for both the Functions editor's Implementation card and
4
19
  * the Endpoints editor's Target card (rfcs/endpoint.md:339-347,
@@ -16,6 +16,8 @@ export interface TargetMeta {
16
16
  export interface TargetSelectorProps<K extends TargetKind> {
17
17
  /** Which kinds the caller may construct. A single-element array offers no kind control at all (A2). */
18
18
  allowedKinds: readonly K[];
19
+ /** Callable ids (`fn_…` / `wf_…`) the opened picker never offers - a Function editor passes its own id so it cannot bind itself. */
20
+ excludeCallableIds?: readonly string[];
19
21
  value: TargetValue<NoInfer<K>>;
20
22
  onChange: (next: TargetValue<NoInfer<K>>) => void;
21
23
  /** Fired whenever the picked target resolves to a normalized field list (A5/A7). */
@@ -8,6 +8,8 @@ export type Parsed = Record<string, unknown> & {
8
8
  * (D-3). The rail's Key control (`SettingsTool.tsx`) is the only place
9
9
  * this is ever ASSIGNED; this page only ever reads it back. */
10
10
  key?: string | null;
11
+ nodes?: unknown[];
12
+ /** Legacy name for `nodes`; read via `workflowNodes`. */
11
13
  steps?: unknown[];
12
14
  status?: WorkflowStatus;
13
15
  tags?: string[];
@@ -1,6 +1,6 @@
1
1
  import { jsxs as F, Fragment as N, jsx as f } from "react/jsx-runtime";
2
- import { h as O, i as _, e as R } from "./apps-1FNUwbGv.js";
3
- import { H as g } from "./spec-import-CjmxyZDR.js";
2
+ import { u as O, a as _, b as R } from "./apps-CboASBKr.js";
3
+ import { H as g } from "./spec-import-CW6R_Wk1.js";
4
4
  import { ExecutionStats as j, ExecutionFilters as D, ExecutionList as L, ExecutionDetail as B, useW6WApi as K } from "@w6w/ui";
5
5
  import { useRef as I, useState as S, useEffect as b, useCallback as V, useMemo as W } from "react";
6
6
  import { useQuery as G } from "@tanstack/react-query";
@@ -89,7 +89,7 @@ function st(e) {
89
89
  }
90
90
  export {
91
91
  ot as H,
92
- Z as a,
93
- st as u
92
+ st as a,
93
+ Z as u
94
94
  };
95
- //# sourceMappingURL=editor-apps-BdenSV1o.js.map
95
+ //# sourceMappingURL=editor-apps-BUZWld-m.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-apps-BdenSV1o.js","sources":["../src/chrome/HistoryView.tsx","../src/editor/editor-apps.ts"],"sourcesContent":["/**\n * `HistoryView` — the execution-history view body (T3.2.1, extracted from\n * `HistoryPage.tsx`'s T2.4.1 shape): stats + filters + paged list + the\n * selected execution's detail. Two hosts mount it — `HistoryPage` (the\n * project-wide and per-callable routes, filters URL-backed) and\n * `HistoryModal` (R-2's in-place modal, filters kept in local state) — so\n * this component owns every judgment call about HOW the view behaves, and\n * takes no position on WHERE its filters live: the host hands down\n * `filters` and gets every change back through `onFiltersChange`, exactly\n * the controlled-value shape `filtersToSearch`/`filtersFromSearch` already\n * assume on the URL-backed side.\n *\n * What stays here, same as it was in `HistoryPage` before the extraction:\n * - the search box's text, debounced, so a keystroke does not re-key and\n * re-issue both queries on every character (`onFiltersChange` — and so\n * the host's own write, URL or local state — fires only once typing\n * settles);\n * - which list row is selected, which is not shareable state and resets on\n * every mount;\n * - every filter change but paging snapping the page back to the first\n * (`offset` 0), because a narrowed result set has no meaningful \"page 3\".\n *\n * `onOpenInEditor`, when given, is called with the selected execution ONLY\n * while it is a workflow run (a function/endpoint invocation has no visual\n * editor to open) — the same gate `HistoryPage.tsx` applied inline before\n * this extraction. A host that never passes it (none of today's two do)\n * simply never sees the call.\n */\nimport {\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n useExecutionDetailQuery,\n useHistoryQuery,\n useHistoryStatsQuery,\n} from \"@w6w/embed/repos\";\nimport {\n ExecutionDetail,\n type ExecutionFilterValue,\n ExecutionFilters,\n ExecutionList,\n ExecutionStats,\n} from \"@w6w/ui\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/** How long to wait after the last keystroke before `onFiltersChange` fires\n * with the new `q` (and so before either query re-issues with it). */\nconst SEARCH_DEBOUNCE_MS = 300;\n\nexport interface HistoryViewProps {\n /** `null` ⇒ no scope known yet (the project-wide host, before its project\n * resolves) — both queries stay disabled, mirroring `repos/history.ts`'s\n * own `enabled: scope !== null`. */\n scope: HistoryScope | null;\n /** Project-wide chrome: the Kind filter, and the Callable column on every\n * row. A per-callable host (every callable already knows its own kind)\n * passes `false`. */\n showKind: boolean;\n filters: HistoryFilters;\n onFiltersChange: (next: HistoryFilters) => void;\n onOpenInEditor?: (execution: ExecutionSummary) => void;\n}\n\nexport function HistoryView(props: HistoryViewProps) {\n const { scope, showKind, filters, onFiltersChange, onOpenInEditor } = props;\n\n // The debounce below fires outside any render, so it needs the LATEST\n // filters (a status picked while a `q` write was still pending must\n // survive it) rather than the ones captured when typing started.\n const filtersRef = useRef(filters);\n filtersRef.current = filters;\n\n const [q, setQ] = useState(filters.q);\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [selected, setSelected] = useState<ExecutionSummary | null>(null);\n\n // Keep the search box in step with `filters.q` when IT moves from outside\n // (Back/Forward or a shared link on the URL-backed host). This never\n // fights a keystroke: an outside `q` only changes once typing has\n // settled, by which point `q` already equals it.\n useEffect(() => {\n setQ(filters.q);\n }, [filters.q]);\n\n // Drop a pending debounce on unmount.\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const listQuery = useHistoryQuery(scope, filters);\n const statsQuery = useHistoryStatsQuery(scope, filters);\n const detailQuery = useExecutionDetailQuery(selected);\n\n const executions = listQuery.data?.executions ?? [];\n const offset = filters.offset;\n const hasMore = listQuery.data?.hasMore ?? false;\n\n /** Every filter change but paging reports a fresh filter set and resets\n * the page to the first. */\n const applyFilters = (next: ExecutionFilterValue) => {\n onFiltersChange({ ...next, offset: 0 });\n };\n\n const onChange = (next: ExecutionFilterValue) => {\n if (next.q === q) {\n applyFilters(next);\n return;\n }\n setQ(next.q);\n if (searchTimer.current) clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => {\n searchTimer.current = null;\n onFiltersChange({ ...filtersRef.current, q: next.q, offset: 0 });\n }, SEARCH_DEBOUNCE_MS);\n };\n\n const onPrev = () =>\n onFiltersChange({ ...filters, q, offset: Math.max(0, offset - HISTORY_PAGE_SIZE) });\n const onNext = () => onFiltersChange({ ...filters, q, offset: offset + HISTORY_PAGE_SIZE });\n\n const onSelect = useCallback(\n (executionId: string) => {\n setSelected(executions.find((row) => row.id === executionId) ?? null);\n },\n [executions],\n );\n\n const filterValue: ExecutionFilterValue = {\n status: filters.status,\n kind: filters.kind,\n from: filters.from,\n to: filters.to,\n q,\n };\n\n // A workflow run is the only execution with a visual editor to jump into\n // — a function/endpoint invocation has no such surface.\n const openInEditor =\n selected?.kind === \"workflow\" && onOpenInEditor ? () => onOpenInEditor(selected) : undefined;\n\n return (\n <>\n <ExecutionStats stats={statsQuery.data ?? null} />\n\n <ExecutionFilters showKind={showKind} value={filterValue} onChange={onChange} />\n\n {listQuery.isError && (\n <p className=\"error\" data-testid=\"history-error\">\n Couldn't load execution history.\n </p>\n )}\n\n <ExecutionList\n items={executions}\n showCallable={showKind}\n loading={listQuery.isLoading}\n selectedId={selected?.id ?? null}\n hasPrev={offset > 0}\n hasNext={hasMore}\n onPrev={onPrev}\n onNext={onNext}\n onSelect={onSelect}\n />\n\n {selected && (\n <ExecutionDetail\n execution={detailQuery.data ?? null}\n loading={detailQuery.isLoading}\n errorMessage={detailQuery.isError ? \"This execution is no longer available.\" : undefined}\n onClose={() => setSelected(null)}\n onOpenInEditor={openInEditor}\n />\n )}\n </>\n );\n}\n","/**\n * The canvas's app lookups, through the host-provided `W6WApi` (`useW6WApi()` — in an embed that\n * is `createW6WUiAdapter`'s, in Studio the facade, which delegates to the same store/repo).\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport { type AppSummary, useW6WApi } from \"@w6w/ui\";\nimport { useMemo } from \"react\";\n\n/** The per-app actions query key — the repos export itself (one declaration, no copy). */\nexport { appActionsKey } from \"../repos/apps.ts\";\n\nconst NO_APPS: ReadonlyMap<string, AppSummary> = new Map();\n\n/** A bounded set of app records by id. Empty when the host's API has no `listAppsByIds`. */\nexport function useEditorApps(ids: readonly string[]): { byId: ReadonlyMap<string, AppSummary> } {\n const api = useW6WApi();\n const list = api.listAppsByIds?.bind(api);\n const key = [...ids].sort().join(\",\");\n const q = useQuery({\n queryKey: [\"editor-apps\", key],\n queryFn: ({ signal }) => (list ? list(ids, { signal }) : Promise.resolve([] as AppSummary[])),\n enabled: ids.length > 0 && typeof list === \"function\",\n });\n const data = q.data;\n const byId = useMemo(\n () => (data ? new Map(data.map((a) => [a.id, a] as const)) : NO_APPS),\n [data],\n );\n return { byId };\n}\n\n/**\n * One app record by id, over {@link useEditorApps} (same `/apps` request, same cache entry as the\n * canvas's batch lookup). `undefined` while loading, for an empty id (which issues no request),\n * or when the host's API cannot look apps up by id.\n */\nexport function useEditorApp(id: string): AppSummary | undefined {\n const { byId } = useEditorApps(id ? [id] : []);\n return id ? byId.get(id) : undefined;\n}\n"],"names":["SEARCH_DEBOUNCE_MS","HistoryView","props","scope","showKind","filters","onFiltersChange","onOpenInEditor","filtersRef","useRef","q","setQ","useState","searchTimer","selected","setSelected","useEffect","listQuery","useHistoryQuery","statsQuery","useHistoryStatsQuery","detailQuery","useExecutionDetailQuery","executions","_a","offset","hasMore","_b","applyFilters","next","onChange","onPrev","HISTORY_PAGE_SIZE","onNext","onSelect","useCallback","executionId","row","filterValue","openInEditor","jsxs","Fragment","jsx","ExecutionStats","ExecutionFilters","ExecutionList","ExecutionDetail","NO_APPS","useEditorApps","ids","api","useW6WApi","list","key","data","useQuery","signal","useMemo","a","useEditorApp","id","byId"],"mappings":"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"}
1
+ {"version":3,"file":"editor-apps-BUZWld-m.js","sources":["../src/chrome/HistoryView.tsx","../src/editor/editor-apps.ts"],"sourcesContent":["/**\n * `HistoryView` — the execution-history view body (T3.2.1, extracted from\n * `HistoryPage.tsx`'s T2.4.1 shape): stats + filters + paged list + the\n * selected execution's detail. Two hosts mount it — `HistoryPage` (the\n * project-wide and per-callable routes, filters URL-backed) and\n * `HistoryModal` (R-2's in-place modal, filters kept in local state) — so\n * this component owns every judgment call about HOW the view behaves, and\n * takes no position on WHERE its filters live: the host hands down\n * `filters` and gets every change back through `onFiltersChange`, exactly\n * the controlled-value shape `filtersToSearch`/`filtersFromSearch` already\n * assume on the URL-backed side.\n *\n * What stays here, same as it was in `HistoryPage` before the extraction:\n * - the search box's text, debounced, so a keystroke does not re-key and\n * re-issue both queries on every character (`onFiltersChange` — and so\n * the host's own write, URL or local state — fires only once typing\n * settles);\n * - which list row is selected, which is not shareable state and resets on\n * every mount;\n * - every filter change but paging snapping the page back to the first\n * (`offset` 0), because a narrowed result set has no meaningful \"page 3\".\n *\n * `onOpenInEditor`, when given, is called with the selected execution ONLY\n * while it is a workflow run (a function/endpoint invocation has no visual\n * editor to open) — the same gate `HistoryPage.tsx` applied inline before\n * this extraction. A host that never passes it (none of today's two do)\n * simply never sees the call.\n */\nimport {\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n useExecutionDetailQuery,\n useHistoryQuery,\n useHistoryStatsQuery,\n} from \"@w6w/embed/repos\";\nimport {\n ExecutionDetail,\n type ExecutionFilterValue,\n ExecutionFilters,\n ExecutionList,\n ExecutionStats,\n} from \"@w6w/ui\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n/** How long to wait after the last keystroke before `onFiltersChange` fires\n * with the new `q` (and so before either query re-issues with it). */\nconst SEARCH_DEBOUNCE_MS = 300;\n\nexport interface HistoryViewProps {\n /** `null` ⇒ no scope known yet (the project-wide host, before its project\n * resolves) — both queries stay disabled, mirroring `repos/history.ts`'s\n * own `enabled: scope !== null`. */\n scope: HistoryScope | null;\n /** Project-wide chrome: the Kind filter, and the Callable column on every\n * row. A per-callable host (every callable already knows its own kind)\n * passes `false`. */\n showKind: boolean;\n filters: HistoryFilters;\n onFiltersChange: (next: HistoryFilters) => void;\n onOpenInEditor?: (execution: ExecutionSummary) => void;\n}\n\nexport function HistoryView(props: HistoryViewProps) {\n const { scope, showKind, filters, onFiltersChange, onOpenInEditor } = props;\n\n // The debounce below fires outside any render, so it needs the LATEST\n // filters (a status picked while a `q` write was still pending must\n // survive it) rather than the ones captured when typing started.\n const filtersRef = useRef(filters);\n filtersRef.current = filters;\n\n const [q, setQ] = useState(filters.q);\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [selected, setSelected] = useState<ExecutionSummary | null>(null);\n\n // Keep the search box in step with `filters.q` when IT moves from outside\n // (Back/Forward or a shared link on the URL-backed host). This never\n // fights a keystroke: an outside `q` only changes once typing has\n // settled, by which point `q` already equals it.\n useEffect(() => {\n setQ(filters.q);\n }, [filters.q]);\n\n // Drop a pending debounce on unmount.\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const listQuery = useHistoryQuery(scope, filters);\n const statsQuery = useHistoryStatsQuery(scope, filters);\n const detailQuery = useExecutionDetailQuery(selected);\n\n const executions = listQuery.data?.executions ?? [];\n const offset = filters.offset;\n const hasMore = listQuery.data?.hasMore ?? false;\n\n /** Every filter change but paging reports a fresh filter set and resets\n * the page to the first. */\n const applyFilters = (next: ExecutionFilterValue) => {\n onFiltersChange({ ...next, offset: 0 });\n };\n\n const onChange = (next: ExecutionFilterValue) => {\n if (next.q === q) {\n applyFilters(next);\n return;\n }\n setQ(next.q);\n if (searchTimer.current) clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => {\n searchTimer.current = null;\n onFiltersChange({ ...filtersRef.current, q: next.q, offset: 0 });\n }, SEARCH_DEBOUNCE_MS);\n };\n\n const onPrev = () =>\n onFiltersChange({ ...filters, q, offset: Math.max(0, offset - HISTORY_PAGE_SIZE) });\n const onNext = () => onFiltersChange({ ...filters, q, offset: offset + HISTORY_PAGE_SIZE });\n\n const onSelect = useCallback(\n (executionId: string) => {\n setSelected(executions.find((row) => row.id === executionId) ?? null);\n },\n [executions],\n );\n\n const filterValue: ExecutionFilterValue = {\n status: filters.status,\n kind: filters.kind,\n from: filters.from,\n to: filters.to,\n q,\n };\n\n // A workflow run is the only execution with a visual editor to jump into\n // — a function/endpoint invocation has no such surface.\n const openInEditor =\n selected?.kind === \"workflow\" && onOpenInEditor ? () => onOpenInEditor(selected) : undefined;\n\n return (\n <>\n <ExecutionStats stats={statsQuery.data ?? null} />\n\n <ExecutionFilters showKind={showKind} value={filterValue} onChange={onChange} />\n\n {listQuery.isError && (\n <p className=\"error\" data-testid=\"history-error\">\n Couldn't load execution history.\n </p>\n )}\n\n <ExecutionList\n items={executions}\n showCallable={showKind}\n loading={listQuery.isLoading}\n selectedId={selected?.id ?? null}\n hasPrev={offset > 0}\n hasNext={hasMore}\n onPrev={onPrev}\n onNext={onNext}\n onSelect={onSelect}\n />\n\n {selected && (\n <ExecutionDetail\n execution={detailQuery.data ?? null}\n loading={detailQuery.isLoading}\n errorMessage={detailQuery.isError ? \"This execution is no longer available.\" : undefined}\n onClose={() => setSelected(null)}\n onOpenInEditor={openInEditor}\n />\n )}\n </>\n );\n}\n","/**\n * The canvas's app lookups, through the host-provided `W6WApi` (`useW6WApi()` — in an embed that\n * is `createW6WUiAdapter`'s, in Studio the facade, which delegates to the same store/repo).\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport { type AppSummary, useW6WApi } from \"@w6w/ui\";\nimport { useMemo } from \"react\";\n\n/** The per-app actions query key — the repos export itself (one declaration, no copy). */\nexport { appActionsKey } from \"../repos/apps.ts\";\n\nconst NO_APPS: ReadonlyMap<string, AppSummary> = new Map();\n\n/** A bounded set of app records by id. Empty when the host's API has no `listAppsByIds`. */\nexport function useEditorApps(ids: readonly string[]): { byId: ReadonlyMap<string, AppSummary> } {\n const api = useW6WApi();\n const list = api.listAppsByIds?.bind(api);\n const key = [...ids].sort().join(\",\");\n const q = useQuery({\n queryKey: [\"editor-apps\", key],\n queryFn: ({ signal }) => (list ? list(ids, { signal }) : Promise.resolve([] as AppSummary[])),\n enabled: ids.length > 0 && typeof list === \"function\",\n });\n const data = q.data;\n const byId = useMemo(\n () => (data ? new Map(data.map((a) => [a.id, a] as const)) : NO_APPS),\n [data],\n );\n return { byId };\n}\n\n/**\n * One app record by id, over {@link useEditorApps} (same `/apps` request, same cache entry as the\n * canvas's batch lookup). `undefined` while loading, for an empty id (which issues no request),\n * or when the host's API cannot look apps up by id.\n */\nexport function useEditorApp(id: string): AppSummary | undefined {\n const { byId } = useEditorApps(id ? [id] : []);\n return id ? byId.get(id) : undefined;\n}\n"],"names":["SEARCH_DEBOUNCE_MS","HistoryView","props","scope","showKind","filters","onFiltersChange","onOpenInEditor","filtersRef","useRef","q","setQ","useState","searchTimer","selected","setSelected","useEffect","listQuery","useHistoryQuery","statsQuery","useHistoryStatsQuery","detailQuery","useExecutionDetailQuery","executions","_a","offset","hasMore","_b","applyFilters","next","onChange","onPrev","HISTORY_PAGE_SIZE","onNext","onSelect","useCallback","executionId","row","filterValue","openInEditor","jsxs","Fragment","jsx","ExecutionStats","ExecutionFilters","ExecutionList","ExecutionDetail","NO_APPS","useEditorApps","ids","api","useW6WApi","list","key","data","useQuery","signal","useMemo","a","useEditorApp","id","byId"],"mappings":"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"}
@@ -2,16 +2,16 @@ import { jsx as n, jsxs as a, Fragment as B } from "react/jsx-runtime";
2
2
  import { r as yn, m as Oe, s as kn, b as Ae, e as wn, h as Pe, a as Nn } from "./rail-settings-XYGToh00.js";
3
3
  import { useContext as de, useState as d, useMemo as Re, useEffect as ge, createContext as Le } from "react";
4
4
  import { ExpressionOptionsProvider as Cn, Icon as x, RetryPolicyFields as En, StepBuilderModal as Sn, IconButton as Qe, useEnterSubmit as Tn, CodeBlock as ve, DeleteButton as An, EditButton as Pn, ConfirmModal as Me, JsonEditor as Mn } from "@w6w/ui";
5
- import { d as Dn, p as In, i as On, t as Rn, e as De } from "./document-sources-C0grrtdq.js";
5
+ import { d as Dn, p as In, i as On, t as Rn, e as De } from "./document-sources-UCwe8x77.js";
6
6
  import { i as Ln, f as Qn, e as jn, b as Vn, u as Wn } from "./vault-BSEWhMYC.js";
7
- import { M as Fn, Y as je, X as Hn, T as Bn, D as Jn, K as $n, _ as Kn } from "./spec-import-CjmxyZDR.js";
8
- import { s as qn, M as K, b as Un, a as zn } from "./ConfirmModal-RLbZT5_k.js";
9
- import { u as _n, i as Gn, f as Yn } from "./slug-C4ktDPdy.js";
7
+ import { P as Fn, Z as je, Y as Hn, V as Bn, J as Jn, N as $n, $ as Kn } from "./spec-import-CW6R_Wk1.js";
8
+ import { s as qn, M as K, b as Un, C as zn } from "./ConfirmModal-BE-SdX-O.js";
9
+ import { u as _n, i as Gn, f as Yn } from "./slug-BVdgiP_L.js";
10
10
  import { ApiError as A } from "@w6w/sdk";
11
11
  import { i as Zn, p as Ve, c as We, d as Xn } from "./settings-rail--GdRMusb.js";
12
- import { s as Fe, q as He, w as Be, v as Je, t as $e, d as xn, a as et, b as nt, r as tt, p as it, o as ot, m as st, u as rt } from "./endpoints-B2ynbZo-.js";
13
- import { I as Ke } from "./ImportSpecModal-BDQIf6rg.js";
14
- import { e as at, b as lt, u as dt, f as qe, a as Ue, c as ze, d as ct } from "./spec-export-Cf3VQSQS.js";
12
+ import { w as Fe, v as He, y as Be, x as Je, b as $e, d as xn, f as et, h as nt, u as tt, t as it, s as ot, r as st, q as rt } from "./endpoints-DSRo1Lc5.js";
13
+ import { I as Ke } from "./ImportSpecModal-B7qd1Km2.js";
14
+ import { e as at, b as lt, u as dt, f as qe, a as Ue, c as ze, d as ct } from "./spec-export-CBbloO_n.js";
15
15
  const ce = Le(null);
16
16
  function Zt({
17
17
  children: e,
@@ -270,7 +270,7 @@ function Xe({
270
270
  ),
271
271
  e === "workflow" && /* @__PURE__ */ n("p", { className: "muted small", "data-testid": "rail-retry-run-warning", children: "Retrying re-runs the whole workflow from its first step, so steps that already succeeded run again. For a step that must not repeat (a send or a charge), set retry on that step instead." })
272
272
  ] }),
273
- /* @__PURE__ */ n("p", { className: "muted small", children: e === "workflow" ? "What runs when this workflow's run fails, after every step's own retry is spent." : "What runs when this call fails, after retry (if any) is exhausted." }),
273
+ /* @__PURE__ */ n("p", { className: "muted small", children: e === "workflow" ? "What runs when this workflow's run fails, after every node's own retry is spent." : "What runs when this call fails, after retry (if any) is exhausted." }),
274
274
  k ? /* @__PURE__ */ a("div", { className: "row", style: { alignItems: "center", gap: 8 }, children: [
275
275
  /* @__PURE__ */ a("span", { className: "list-main", children: [
276
276
  /* @__PURE__ */ n("strong", { children: F ?? k }),
@@ -1271,9 +1271,9 @@ export {
1271
1271
  Zt as W,
1272
1272
  Ze as a,
1273
1273
  ei as b,
1274
- xt as c,
1275
- Xt as d,
1274
+ Xt as c,
1275
+ xt as d,
1276
1276
  ii as e,
1277
1277
  ut as u
1278
1278
  };
1279
- //# sourceMappingURL=editor-tools-RxmY5iyi.js.map
1279
+ //# sourceMappingURL=editor-tools-B_Lfx3kw.js.map