@w6w/embed 0.2.1 → 0.2.19
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/README.md +22 -5
- package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
- package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
- package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
- package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
- package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
- package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
- package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
- package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
- package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
- package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
- package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
- package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
- package/dist/apps-ItBvnWX3.js +92 -0
- package/dist/apps-ItBvnWX3.js.map +1 -0
- package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
- package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
- package/dist/chrome/ConfirmModal.d.ts +4 -1
- package/dist/chrome/DangerZone.d.ts +4 -3
- package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
- package/dist/chrome/JsonToggle.d.ts +29 -20
- package/dist/chrome/Modal.d.ts +3 -1
- package/dist/chrome/RightRail.d.ts +6 -1
- package/dist/chrome/VersionHistoryModal.d.ts +2 -0
- package/dist/chrome/index.d.ts +1 -0
- package/dist/chrome/workspace.d.ts +36 -1
- package/dist/coerce-input-DFJ4n_wc.js +150 -0
- package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
- package/dist/connections-CzsCyIxY.js +119 -0
- package/dist/connections-CzsCyIxY.js.map +1 -0
- package/dist/credentials-Cn92LGhJ.js +171 -0
- package/dist/credentials-Cn92LGhJ.js.map +1 -0
- package/dist/data-stores-UeQvwVCa.js +170 -0
- package/dist/data-stores-UeQvwVCa.js.map +1 -0
- package/dist/document-sources-DNmBojx6.js +169 -0
- package/dist/document-sources-DNmBojx6.js.map +1 -0
- package/dist/draft/use-workflow-draft.d.ts +2 -0
- package/dist/draft.mjs +2 -2
- package/dist/editor/BindingBanner.d.ts +13 -0
- package/dist/editor/CallableEditorFrame.d.ts +7 -0
- package/dist/editor/EndpointCards.d.ts +4 -1
- package/dist/editor/PublishControl.d.ts +19 -0
- package/dist/editor/PublishTooltip.d.ts +7 -0
- package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
- package/dist/editor/StartingStateModal.d.ts +14 -0
- package/dist/editor/TargetSelector.d.ts +15 -0
- package/dist/editor/TargetSelector.types.d.ts +2 -0
- package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
- package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
- package/dist/editor/definition.d.ts +6 -0
- package/dist/editor/json-apply.d.ts +29 -0
- package/dist/editor/step-problems-feed.d.ts +5 -0
- package/dist/editor/types.d.ts +2 -2
- package/dist/editor-apps-DkkC7wOQ.js +152 -0
- package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
- package/dist/editor-tools-BR27RGto.js +1683 -0
- package/dist/editor-tools-BR27RGto.js.map +1 -0
- package/dist/editor.mjs +1 -1
- package/dist/editors.mjs +855 -650
- package/dist/editors.mjs.map +1 -1
- package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
- package/dist/endpoints-DSRo1Lc5.js.map +1 -0
- package/dist/fields-DvS8XZFc.js +21 -0
- package/dist/fields-DvS8XZFc.js.map +1 -0
- package/dist/forms/ModelBudgetsManager.d.ts +9 -0
- package/dist/forms/ModelRoutesManager.d.ts +14 -0
- package/dist/forms.d.ts +4 -0
- package/dist/forms.mjs +611 -212
- package/dist/forms.mjs.map +1 -1
- package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
- package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
- package/dist/index.mjs +154 -117
- package/dist/index.mjs.map +1 -1
- package/dist/lib/binding-problems.d.ts +42 -0
- package/dist/lib/code-rail.d.ts +4 -2
- package/dist/lib/history-query.d.ts +45 -0
- package/dist/lib/import-bindings.d.ts +89 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/invoke-error.d.ts +1 -0
- package/dist/lib/rail-settings.d.ts +1 -1
- package/dist/lib/sdk-snippets.d.ts +1 -1
- package/dist/lib/setup-incomplete.d.ts +22 -0
- package/dist/lib/starting-data.d.ts +31 -0
- package/dist/lib/state-panel.d.ts +29 -0
- package/dist/lib/target-fields.d.ts +11 -15
- package/dist/lib/trigger-preview.d.ts +1 -0
- package/dist/lib/workflow-live-run.d.ts +93 -8
- package/dist/lib/workflow-nodes.d.ts +5 -0
- package/dist/lib/workflow-validity.d.ts +65 -16
- package/dist/lib/workflow-variables.d.ts +1 -1
- package/dist/lib/workflow-version.d.ts +2 -0
- package/dist/lib.mjs +86 -69
- package/dist/lists/ConnectionDependents.d.ts +31 -0
- package/dist/lists/ConnectionDetail.d.ts +4 -1
- package/dist/lists/ConnectionList.d.ts +4 -1
- package/dist/lists/CredentialDetail.d.ts +15 -0
- package/dist/lists/CredentialList.d.ts +14 -0
- package/dist/lists/DataStoreList.d.ts +17 -0
- package/dist/lists/DataStoreView.d.ts +19 -0
- package/dist/lists/Logs.d.ts +19 -0
- package/dist/lists/ModelCatalog.d.ts +12 -0
- package/dist/lists/ModelUsage.d.ts +12 -0
- package/dist/lists.d.ts +14 -0
- package/dist/lists.mjs +1766 -609
- package/dist/lists.mjs.map +1 -1
- package/dist/models-bAayQPJ_.js +270 -0
- package/dist/models-bAayQPJ_.js.map +1 -0
- package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
- package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
- package/dist/rail/ConnectionsTool.d.ts +2 -0
- package/dist/rail/HistoryTool.d.ts +2 -0
- package/dist/rail/StartingStateTool.d.ts +2 -0
- package/dist/rail/settings-sections.d.ts +4 -1
- package/dist/rail.mjs +4 -4
- package/dist/repos/agents-studio-agents.d.ts +52 -0
- package/dist/repos/agents-studio-assets.d.ts +68 -0
- package/dist/repos/connections.d.ts +30 -12
- package/dist/repos/constants.d.ts +12 -0
- package/dist/repos/credentials.d.ts +83 -0
- package/dist/repos/data-stores.d.ts +84 -0
- package/dist/repos/endpoints.d.ts +9 -3
- package/dist/repos/fields.d.ts +34 -0
- package/dist/repos/functions.d.ts +7 -5
- package/dist/repos/history.d.ts +9 -0
- package/dist/repos/index.d.ts +7 -0
- package/dist/repos/models.d.ts +289 -0
- package/dist/repos/spec-export.d.ts +3 -3
- package/dist/repos/spec-import.d.ts +30 -1
- package/dist/repos/step-tests.d.ts +2 -0
- package/dist/repos/webhook-listen.d.ts +35 -0
- package/dist/repos/workflows.d.ts +105 -2
- package/dist/repos.mjs +655 -176
- package/dist/repos.mjs.map +1 -1
- package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
- package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
- package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
- package/dist/slug-BVdgiP_L.js.map +1 -0
- package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
- package/dist/spec-export-DGy5ijps.js.map +1 -0
- package/dist/spec-import-SWOonsNr.js +116 -0
- package/dist/spec-import-SWOonsNr.js.map +1 -0
- package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
- package/dist/step-tests-B4E4W3ly.js.map +1 -0
- package/dist/theme-context-E2ZhlXDX.js +6 -0
- package/dist/theme-context-E2ZhlXDX.js.map +1 -0
- package/dist/theme-context.d.ts +2 -0
- package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
- package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
- package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
- package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
- package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
- package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
- package/dist/workflows-BZN4Hyz1.js +623 -0
- package/dist/workflows-BZN4Hyz1.js.map +1 -0
- package/package.json +3 -2
- package/src/styles.css +155 -7
- package/dist/ConfirmModal-RLbZT5_k.js +0 -181
- package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
- package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
- package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
- package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
- package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
- package/dist/apps-1FNUwbGv.js +0 -77
- package/dist/apps-1FNUwbGv.js.map +0 -1
- package/dist/coerce-input-BicYr7nc.js +0 -139
- package/dist/coerce-input-BicYr7nc.js.map +0 -1
- package/dist/connections-CjjYeRqb.js +0 -78
- package/dist/connections-CjjYeRqb.js.map +0 -1
- package/dist/document-sources-C0grrtdq.js +0 -86
- package/dist/document-sources-C0grrtdq.js.map +0 -1
- package/dist/editor-apps-BdenSV1o.js +0 -95
- package/dist/editor-apps-BdenSV1o.js.map +0 -1
- package/dist/editor-tools-RxmY5iyi.js +0 -1279
- package/dist/editor-tools-RxmY5iyi.js.map +0 -1
- package/dist/endpoints-B2ynbZo-.js.map +0 -1
- package/dist/rail-settings-XYGToh00.js.map +0 -1
- package/dist/slug-C4ktDPdy.js.map +0 -1
- package/dist/spec-export-Cf3VQSQS.js.map +0 -1
- package/dist/spec-import-CjmxyZDR.js +0 -465
- package/dist/spec-import-CjmxyZDR.js.map +0 -1
- package/dist/step-tests-CivICmTq.js.map +0 -1
- package/dist/trigger-preview-VPkrryDl.js +0 -120
- package/dist/trigger-preview-VPkrryDl.js.map +0 -1
- package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
- package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowEditor-DlbVv6Fs.js","sources":["../src/chrome/ExecutionProfileHeader.tsx","../src/chrome/history-open-run.ts","../src/chrome/HistoryModal.tsx","../src/chrome/HistoryButton.tsx","../src/chrome/JsonToggle.tsx","../src/editor/EditorShell.tsx","../src/editor/WorkflowSettingsModal.tsx","../src/editor/definition.ts","../src/editor/WorkflowEditor.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\n\n/**\n * `ExecutionProfileHeader` — the ONE editor header every execution profile's\n * editor mounts (T3.1.1, `building-blocks.md` §Profile building blocks\n * §Mirror).\n *\n * Extracted verbatim from `WorkflowsPage.tsx`'s full-bleed editor head, which\n * is the presentation of record: back control, title, actions. Two hosts use\n * it with two title CONFIGURATIONS, never two headers:\n * - `WorkflowsPage.tsx` — an inline-editable, controlled name input\n * (`editable: true`); back clears the `?edit=` search param; the action row\n * (run / stop / publish / JSON / settings) stays host-owned and arrives as\n * `actions`.\n * - `CallablePage.tsx`'s `CallableEditorChrome` — a Function/Endpoint\n * read-only heading (`editable: false`) with the `incomplete` badge passed\n * as `titleAdornment`, and the host's own JSON toggle then Save button as\n * `actions`.\n *\n * Presentation only: no query, mutation or navigation logic lives here — every\n * callback (`onBack`, `onChange`, `onBlur`) and every node in the action row is\n * the host's, mirroring the `ConnectionHeader.tsx` action-slot precedent.\n *\n * The rendered DOM of the Workflow editor's header is byte-for-byte what it\n * was before the extraction (`wf-fullbleed-head` / `wf-back-btn` /\n * `wf-title-input` / `wf-head-actions`, every `data-testid`, the `aria-label`\n * and the attribute order), which is what `styles.css`'s\n * `.wf-fullbleed-head input.wf-title-input` ancestor specificity and the\n * workflow header screenshot guard both depend on.\n */\n\n/** The editable title variant: the Workflow editor's inline-editable name. */\nexport interface EditableProfileTitle {\n /** The controlled value. */\n value: string;\n /** Called with the new text on every keystroke. */\n onChange: (next: string) => void;\n /** Called when the field loses focus — the Workflow host saves here. */\n onBlur: () => void;\n /** Shown while the value is empty; also the field's minimum sizing basis. */\n placeholder: string;\n /** The `maxLength` the input carries. */\n maxLength: number;\n /** The input's accessible name. */\n ariaLabel: string;\n}\n\n/** The read-only title variant: a Function/Endpoint editor's heading text. */\nexport interface ReadOnlyProfileTitle {\n value: string;\n}\n\n/** Which title the host mounts. The discriminant is `editable`. */\nexport type ExecutionProfileTitle =\n | ({ editable: true } & EditableProfileTitle)\n | ({ editable: false } & ReadOnlyProfileTitle);\n\n/**\n * The editable title field itself. Extracted so the input's own JSX — and the\n * `size` expression `src/lib/__tests__/workflow-title-size.test.ts` extracts\n * and RUNS — lives in one readable place. `size` is capped at the literal 80\n * (the same cap `maxLength` carries on the workflow host), independently of\n * `maxLength`: a name longer than 80 characters can only ever come from the\n * server, so `maxLength` alone would leave a pre-existing long name overflowing\n * its header.\n */\nfunction EditableTitle({ title }: { title: EditableProfileTitle }) {\n const { value, placeholder, maxLength, ariaLabel, onChange, onBlur } = title;\n return (\n <input\n className=\"wf-title-input\"\n value={value}\n placeholder={placeholder}\n maxLength={maxLength}\n size={Math.min(Math.max(value.length, placeholder.length), 80)}\n aria-label={ariaLabel}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n />\n );\n}\n\nexport interface ExecutionProfileHeaderProps {\n /** The back control's click handler — host-owned (the Workflow host clears\n * `?edit=`; `CallableEditorChrome` navigates to the kind's listing). */\n onBack: () => void;\n /** The back control's visible text — host-owned copy (`\"← Workflows\"`,\n * `descriptor.editor.backLabel`). */\n backLabel: string;\n /** Editable (Workflow) or read-only (Function/Endpoint) title. */\n title: ExecutionProfileTitle;\n /** Rendered immediately after a read-only title — the `incomplete` badge. */\n titleAdornment?: ReactNode;\n /** The host's action row (buttons only; this component owns the wrapper). */\n actions: ReactNode;\n}\n\nexport function ExecutionProfileHeader({\n onBack,\n backLabel,\n title,\n titleAdornment,\n actions,\n}: ExecutionProfileHeaderProps) {\n return (\n <div className=\"wf-fullbleed-head\">\n <button\n type=\"button\"\n className=\"muted wf-back-btn\"\n data-testid=\"wf-editor-back\"\n onClick={onBack}\n >\n {backLabel}\n </button>\n {title.editable ? (\n <EditableTitle title={title} />\n ) : (\n <h2 className=\"exec-profile-title\">\n {title.value} {titleAdornment}\n </h2>\n )}\n <div className=\"wf-head-actions\" style={{ marginLeft: \"auto\" }}>\n {actions}\n </div>\n </div>\n );\n}\n","import type { CallableKind, ExecutionSummary } from \"../repos/index.ts\";\n\n/**\n * The open-in-editor decision for a History view: only a workflow run has an editor to open, and\n * only when the host supplied `onOpenRun`. The handler closes the modal BEFORE handing the run id\n * to the host (the host's navigation then lands on an unobscured page).\n */\nexport function historyOpenRun(\n kind: CallableKind,\n onOpenRun: ((runId: string) => void) | undefined,\n onClose: () => void,\n): ((execution: ExecutionSummary) => void) | undefined {\n if (kind !== \"workflow\" || onOpenRun === undefined) return undefined;\n return (execution) => {\n onClose();\n onOpenRun(execution.id);\n };\n}\n","/**\n * `HistoryModal` (R-2 / T3.2.1) — the callable's own execution history,\n * opened as a full-page modal OVER the profile instead of away from it: the\n * route and the URL never change, so the editor underneath (unsaved edits,\n * canvas position, selected node) stays exactly as the author left it.\n * Mounted by `HistoryButton` in place of the navigation it used to do.\n *\n * `@w6w/ui`'s `Modal` at `size=\"full\"` (a near-fullscreen work surface,\n * `ui/src/components/Modal.tsx:12`) wraps `HistoryView`, scoped to this one\n * callable (`{ callable: id }`) with `showKind={false}` — a per-callable\n * view already knows its own kind. Filters are LOCAL state, starting empty\n * every time the modal opens, and are never written to the URL (HB10):\n * bookmarking a filtered view only makes sense for the standalone History\n * page, which still owns the URL-backed form.\n *\n * Closeable by ✕ (the `headerRight` button below), Esc (the real `Modal`'s\n * own `cancel` handling) or its backdrop click — all three funnel through\n * the same `onClose`, so the caller's \"focus returns to the History button\"\n * behaviour (`HistoryButton.tsx`) covers every dismissal path.\n *\n * \"Open in visual editor\" only ever applies to a workflow run, and every\n * execution this modal lists already belongs to THIS callable — its scope\n * is `{ callable: id }`, never project-wide — so there is no \"other\n * workflow\" branch to handle here (that one only exists on the project-wide\n * History page, which `HistoryPage.tsx` still owns). Closes the modal and\n * seeds `?run=` on the SAME route; `WorkflowsPage`'s own `[editId, runParam]`\n * effect (T2.4.2 HB7) is what opens the run overlay in place.\n */\nimport { type CallableKind, EMPTY_HISTORY_FILTERS, type HistoryFilters } from \"@w6w/embed/repos\";\nimport { IconButton, Modal } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { HistoryView } from \"./HistoryView.tsx\";\nimport { historyOpenRun } from \"./history-open-run.ts\";\n\nexport interface HistoryModalProps {\n kind: CallableKind;\n id: string;\n onClose: () => void;\n /** Open a workflow run in the host's editor; absent ⇒ no open-in-editor affordance. */\n onOpenRun?: (runId: string) => void;\n}\n\nexport function HistoryModal(props: HistoryModalProps) {\n const { kind, id, onClose, onOpenRun } = props;\n const [filters, setFilters] = useState<HistoryFilters>(EMPTY_HISTORY_FILTERS);\n\n const onOpenInEditor = historyOpenRun(kind, onOpenRun, onClose);\n\n return (\n <Modal\n size=\"full\"\n title=\"History\"\n subtitle={id}\n onClose={onClose}\n headerRight={<IconButton icon=\"close\" label=\"Close\" onClick={onClose} />}\n >\n <div className=\"w6w-modal-body\">\n <HistoryView\n scope={{ callable: id }}\n showKind={false}\n filters={filters}\n onFiltersChange={setFilters}\n onOpenInEditor={onOpenInEditor}\n />\n </div>\n </Modal>\n );\n}\n","/**\n * The History affordance in the Function/Endpoint/Workflow editor headers\n * (T2.4.2, reworked by T3.2.1/R-2) — one icon button that opens the\n * callable's own execution history as a full-page modal OVER the profile\n * (`HistoryModal.tsx`) instead of navigating away from it, and refuses to\n * open while that callable has never executed.\n *\n * \"Has it ever executed?\" is `repos/history.ts`'s `useHasExecutedQuery` — the\n * cheap one-row `GET /history?callable=<id>&limit=1` existence probe (D1:\n * caller-scoped, exactly the rows its own History page lists). `hasExecuted`\n * reads `false` while that probe is in flight or has failed, so the button's\n * disabled state can never claim history that isn't there — the same \"no\n * false yes\" rule the hook's own docblock states.\n *\n * FAIL CLOSED WHEN THE ANSWER IS UNREADABLE. The hook assumes the envelope\n * (`{executions, hasMore}`) and dereferences `executions` directly, so a\n * response that is JSON but not that envelope — a bare `[]`, which several\n * older page-guard harnesses return from their catch-all for any unmodelled\n * `GET` — throws DURING RENDER. An uncaught render throw unmounts the whole\n * editor, so a header icon would be able to take the page down. The boundary\n * below keeps that failure inside this component and renders the same button\n * in its disabled state: no history is claimed, no modal is opened, and the\n * editor survives. The envelope-vs-array mismatch itself belongs to T2.3.1's\n * file (`src/repos/history.ts`), which this node must not edit.\n *\n * Chrome is `@w6w/ui`'s `IconButton` — the same borderless glyph-only control\n * `JsonToggle.tsx`'s `JsonToggleButton` renders, so the two header icon buttons\n * read as one family. The glyph is that component's `icon=\"history\"` (T2; the\n * local `HistoryIcon` hand-drawn SVG is gone), named `history` in the shared\n * set because it is the same drawing the left rail's History entry uses.\n *\n * Focus handling (R-2's \"closing it puts the user back exactly where they\n * were\"): the button keeps a ref to its own DOM node and refocuses it the\n * moment the modal reports `onClose`, regardless of which of the modal's own\n * three dismiss paths (✕, Esc, backdrop) fired it.\n */\nimport { type CallableKind, useHasExecutedQuery } from \"@w6w/embed/repos\";\nimport { IconButton } from \"@w6w/ui\";\nimport { Component, type ReactNode, type Ref, useEffect, useRef, useState } from \"react\";\nimport { HistoryModal } from \"./HistoryModal.tsx\";\n\nexport interface HistoryButtonProps {\n kind: CallableKind;\n id: string;\n /** Forwarded to the modal; see `HistoryModalProps.onOpenRun`. */\n onOpenRun?: (runId: string) => void;\n}\n\n/** The chrome itself, shared by the live button and the fail-closed fallback —\n * the fallback must be the SAME control (same test id, same name, same\n * glyph), only disabled, or a caller could tell the two apart by shape. */\nfunction HistoryButtonChrome({\n hasExecuted,\n onClick,\n buttonRef,\n}: {\n hasExecuted: boolean;\n onClick: () => void;\n buttonRef?: Ref<HTMLButtonElement>;\n}) {\n return (\n <IconButton\n ref={buttonRef}\n icon=\"history\"\n data-testid=\"history-button\"\n label=\"Execution history\"\n title={hasExecuted ? \"Execution history\" : \"No executions yet\"}\n disabled={!hasExecuted}\n onClick={onClick}\n />\n );\n}\n\n/** The probe's own render — the only thing that reads the query. Kept separate\n * so a throw from the hook lands on the boundary, not on the page. */\nfunction HistoryButtonProbe({ kind, id, onOpenRun }: HistoryButtonProps) {\n const { hasExecuted } = useHasExecutedQuery(id);\n const [open, setOpen] = useState(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n // Tracks the PREVIOUS `open` so the effect below only fires the moment the\n // modal actually goes from open to closed — never on first mount.\n const wasOpen = useRef(false);\n\n // Deferred to an effect (runs after the modal's `<dialog>` is gone from the\n // DOM) rather than called straight from `onClose`: while the native dialog\n // is still the top-layer modal, it traps focus, so a `.focus()` call fired\n // DURING its own `cancel`/dismiss handling can be silently ignored. Waiting\n // for the post-commit effect sidesteps that race for all three dismiss\n // paths (✕, Esc, backdrop) alike.\n useEffect(() => {\n if (wasOpen.current && !open) buttonRef.current?.focus();\n wasOpen.current = open;\n }, [open]);\n\n return (\n <>\n <HistoryButtonChrome\n hasExecuted={hasExecuted}\n buttonRef={buttonRef}\n onClick={() => setOpen(true)}\n />\n {open && (\n <HistoryModal kind={kind} id={id} onClose={() => setOpen(false)} onOpenRun={onOpenRun} />\n )}\n </>\n );\n}\n\n/** Last-resort boundary: an unreadable history answer disables the button\n * instead of unmounting the editor that hosts it. The fallback's `onClick` can\n * never fire (the button is disabled), so it does not need the router. */\nclass HistoryProbeBoundary extends Component<{ children: ReactNode }, { failed: boolean }> {\n state = { failed: false };\n\n static getDerivedStateFromError(): { failed: boolean } {\n return { failed: true };\n }\n\n componentDidCatch(error: unknown): void {\n console.error(\"history probe answer was unreadable; disabling the button\", error);\n }\n\n render(): ReactNode {\n if (this.state.failed) return <HistoryButtonChrome hasExecuted={false} onClick={() => {}} />;\n return this.props.children;\n }\n}\n\nexport function HistoryButton(props: HistoryButtonProps) {\n return (\n <HistoryProbeBoundary>\n <HistoryButtonProbe {...props} />\n </HistoryProbeBoundary>\n );\n}\n","import { IconButton, JsonEditor } from \"@w6w/ui\";\nimport { Modal } from \"./Modal.tsx\";\n\nexport type JsonToggleMode = \"synced\" | \"disconnected\";\n\n/** The header icon button: `IconButton` with the set's `json` glyph — the\n * curly-brace icon, distinct from the `code` `</>` \"Call from code\" icon\n * beside it, so the two stop reading as the same button. The local\n * `JsonIcon` SVG this file used to carry is now `icon=\"json\"` in the shared\n * set. */\nexport function JsonToggleButton(props: { onClick: () => void }) {\n return <IconButton icon=\"json\" onClick={props.onClick} label=\"Edit raw JSON definition\" />;\n}\n\nexport interface JsonToggleProps {\n /** Parent-owned; render nothing when false. */\n open: boolean;\n onClose: () => void;\n /** Modal title. */\n title: string;\n mode: JsonToggleMode;\n /** Parent-owned text; the component keeps NO copy of it. */\n value: string;\n /** Every JsonEditor change, both modes. */\n onChange: (text: string) => void;\n /** JsonEditor's, error ?? null. */\n onValidityChange?: (v: { valid: boolean; error: string | null }) => void;\n /** When non-null: \"Invalid JSON — {invalidReason}\" (Workflow's existing line). */\n invalidReason?: string | null;\n /** Evaluated on `value` every render; non-null → shown in\n * <p className=\"muted small\" data-testid=\"json-toggle-reason\">. */\n guard?: (text: string) => string | null;\n /** disconnected only. */\n onSave?: () => void;\n /** disconnected only. */\n saving?: boolean;\n /** disconnected only; rendered as <div className=\"error\"> inside the dialog. */\n error?: string | null;\n /** JsonEditor aria-label. */\n editorLabel: string;\n}\n\n/**\n * The JSON⇄editor toggle's chrome — the header icon button's dialog, extracted\n * verbatim from `WorkflowsPage.tsx`'s raw-JSON modal (T2.1.1 D-2) so a second\n * host can reuse it in `mode=\"disconnected\"` (T2.1.2). Wraps `@w6w/ui`'s\n * `JsonEditor` and studio's own `Modal` (not `@w6w/ui`'s) — both existing\n * JSON-toggle-shaped precedents in this repo use studio's `Modal`.\n *\n * The component holds NO copy of `value`: every render shows exactly what the\n * parent hands it, which is what keeps a reopened dialog free of a stale\n * snapshot from the previous time it was open.\n */\nexport function JsonToggle(props: JsonToggleProps): JSX.Element | null {\n const {\n open,\n onClose,\n title,\n mode,\n value,\n onChange,\n onValidityChange,\n invalidReason,\n guard,\n onSave,\n saving,\n error,\n editorLabel,\n } = props;\n if (!open) return null;\n\n const guardReason = guard?.(value) ?? null;\n\n return (\n <Modal title={title} onClose={onClose} wide>\n <div className=\"modal-body\">\n <p className=\"muted small\">\n {mode === \"synced\" ? (\n <>\n Edit the raw definition (<code>manifestVersion: \"2\"</code>). Changes sync live to the\n visual editor.\n </>\n ) : (\n \"Save replaces the stored definition.\"\n )}\n </p>\n <JsonEditor\n value={value}\n onChange={onChange}\n onValidityChange={({ valid, error: err }) =>\n onValidityChange?.({ valid, error: err ?? null })\n }\n minHeight=\"420px\"\n aria-label={editorLabel}\n />\n {guardReason && (\n <p className=\"muted small\" data-testid=\"json-toggle-reason\">\n {guardReason}\n </p>\n )}\n {invalidReason && <div className=\"muted small\">Invalid JSON — {invalidReason}</div>}\n {error && <div className=\"error\">{error}</div>}\n </div>\n <div className=\"modal-actions\">\n {mode === \"synced\" ? (\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Done\n </button>\n ) : (\n <>\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"btn\"\n data-testid=\"json-toggle-save\"\n disabled={guardReason != null || Boolean(saving)}\n onClick={onSave}\n >\n {saving ? \"Saving…\" : \"Save\"}\n </button>\n </>\n )}\n </div>\n </Modal>\n );\n}\n","/**\n * The editor frame shared by every callable editor: the rail environment, the project expression\n * scope, and (unless `rail={false}`) the workspace + `RightRail`. `WorkflowEditor` uses it; the\n * Function and Endpoint editors reuse it rather than re-inlining the providers.\n *\n * - `rail` omitted / `true`: its OWN nested `WorkspaceProvider` plus a `RightRail` — the editor's\n * rail, and the nested provider is what keeps a host's outer rail empty.\n * - `rail={false}`: no `RightRail`. Inside a `<CallableWorkspace>` the editor publishes into that\n * workspace; with none it mounts its own provider (no rail) so it can still publish and edit.\n */\nimport type { ReactNode } from \"react\";\nimport { type RailTool, RightRail } from \"../chrome/RightRail.tsx\";\nimport { WorkspaceProvider, useHasWorkspace } from \"../chrome/workspace.tsx\";\nimport { ProjectExpressionScope } from \"../rail/ExpressionScope.tsx\";\nimport { editorRailTools } from \"../rail/editor-tools.ts\";\nimport { RailEnvProvider, type RailNavigation } from \"../rail/rail-env.tsx\";\n\nexport interface EditorShellProps {\n /** Resolved project (`null` = none; tools refuse to save). */\n project: string | null;\n onNavigate: (to: RailNavigation) => void;\n /** Default `true`. `false`: render no rail; publish into the enclosing workspace if any. */\n rail?: boolean;\n /** Persisted-rail key; `null` = not yet persistable. */\n storageKey: string | null;\n /** Default {@link editorRailTools}. */\n tools?: readonly RailTool[];\n children: ReactNode;\n}\n\nexport function EditorShell({\n project,\n onNavigate,\n rail = true,\n storageKey,\n tools = editorRailTools,\n children,\n}: EditorShellProps): ReactNode {\n const enclosed = useHasWorkspace();\n const body = (\n <RailEnvProvider project={project} onNavigate={onNavigate}>\n <ProjectExpressionScope project={project}>\n {children}\n {rail && <RightRail tools={tools} storageKey={storageKey} />}\n </ProjectExpressionScope>\n </RailEnvProvider>\n );\n // Own provider when the rail is ours, or when there is no workspace to publish into.\n return rail || !enclosed ? <WorkspaceProvider>{body}</WorkspaceProvider> : body;\n}\n","import {\n type ExprValue,\n ExpressionInput,\n ExpressionOptionsProvider,\n IconButton,\n type SecretValue,\n useExpressionOptions,\n} from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { type WorkflowVariableRow, duplicateKeyIndexes, varsRailFor } from \"../lib/index.ts\";\n\n/** The settings modal's two tabs — General is always the one it opens on. */\nconst SETTINGS_TABS = [\"general\", \"variables\"] as const;\ntype SettingsTab = (typeof SETTINGS_TABS)[number];\n\n/** The `WorkflowVariable.type` union a row's type `<select>` offers. */\nconst VARIABLE_TYPES = [\"string\", \"number\", \"boolean\", \"object\", \"array\"] as const;\n\n/**\n * Per-workflow authoring settings (General) plus the Variables tab (T1.1.5) —\n * the workflow's declared `variables` list, its public input schema (HITL-5).\n * Both General flags are on unless the workflow says otherwise and persist\n * immediately (`saveMeta`, via `onChange`); every Variables edit instead goes\n * through the auto-saver (`onVariablesChange` → `patchMeta`, never an\n * immediate save — see the module docstring's Save path decision).\n */\nexport function WorkflowSettingsModal(props: {\n autoSave: boolean;\n savePosition: boolean;\n variables: WorkflowVariableRow[];\n onClose: () => void;\n onChange: (key: \"autoSave\" | \"savePosition\", value: boolean) => void;\n onVariablesChange: (next: WorkflowVariableRow[]) => void;\n}) {\n const { autoSave, savePosition, variables, onClose, onChange, onVariablesChange } = props;\n // The project's variable names, inherited from the app shell — the base list\n // `varsRailFor` narrows per row below.\n const inheritedVars = useExpressionOptions().vars ?? [];\n const [tab, setTab] = useState<SettingsTab>(\"general\");\n\n function addVariable() {\n onVariablesChange([...variables, { key: \"\" }]);\n }\n function updateVariable(i: number, next: Partial<WorkflowVariableRow>) {\n onVariablesChange(variables.map((v, idx) => (idx === i ? { ...v, ...next } : v)));\n }\n function removeVariable(i: number) {\n onVariablesChange(variables.filter((_, idx) => idx !== i));\n }\n const dupIndexes = duplicateKeyIndexes(variables);\n\n return (\n <Modal title=\"Workflow settings\" onClose={onClose} wide>\n <div className=\"w6w-subtabs\">\n <button\n type=\"button\"\n className={`w6w-subtab${tab === \"general\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"general\")}\n >\n General\n </button>\n <button\n type=\"button\"\n className={`w6w-subtab${tab === \"variables\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"variables\")}\n >\n Variables\n </button>\n </div>\n\n {tab === \"general\" ? (\n <>\n <div className=\"modal-body\">\n <p className=\"muted small\">\n These settings belong to the workflow, so everyone who opens it gets the same\n behaviour. Both are on unless you turn them off; each change saves straight away.\n </p>\n <label\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"var(--w6w-sp-2)\",\n cursor: \"pointer\",\n }}\n title=\"Save edits as you make them, without pressing Save.\"\n >\n <input\n type=\"checkbox\"\n checked={autoSave}\n onChange={(e) => onChange(\"autoSave\", e.target.checked)}\n />\n <span className=\"muted small\">Auto-save edits</span>\n </label>\n <label\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"var(--w6w-sp-2)\",\n cursor: \"pointer\",\n }}\n title=\"Keep the arrangement of the canvas — where each step sits, and the view you left it at.\"\n >\n <input\n type=\"checkbox\"\n checked={savePosition}\n onChange={(e) => onChange(\"savePosition\", e.target.checked)}\n />\n <span className=\"muted small\">Save step positions and canvas view</span>\n </label>\n </div>\n <div className=\"modal-actions\">\n {/* T1.3.1: Archive/Delete moved to the right rail's Settings tool\n — one consistent Settings surface, same archive-before-delete\n lifecycle, only relocated (D-I0.1-1). See\n `SettingsTool.tsx`'s own module docstring. */}\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Done\n </button>\n </div>\n </>\n ) : (\n <>\n <div className=\"modal-body\">\n {/* HITL-5: declaring a variable flips this workflow's generated MCP\n tool from a pass-through schema to a declared one — say so. */}\n <p className=\"muted small\">\n Declaring variables here defines this workflow's <strong>public input schema</strong>:\n API and AI (MCP) callers then see exactly these inputs. With none declared, they may\n send anything.\n </p>\n <div className=\"row\" style={{ justifyContent: \"space-between\", alignItems: \"center\" }}>\n <span className=\"muted small\">\n {variables.length === 0\n ? \"No variables declared.\"\n : `${variables.length} variable${variables.length === 1 ? \"\" : \"s\"} declared.`}\n </span>\n <button type=\"button\" className=\"btn ghost\" onClick={addVariable}>\n + Add variable\n </button>\n </div>\n {variables.length > 0 && (\n <ul className=\"list\" data-testid=\"workflow-variables-list\">\n {variables.map((v, i) => (\n <li\n // biome-ignore lint/suspicious/noArrayIndexKey: rows are positional and reorderable\n key={i}\n style={{\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: \"var(--w6w-sp-1)\",\n }}\n >\n <div className=\"row\" style={{ alignItems: \"center\", gap: \"var(--w6w-sp-2)\" }}>\n <input\n type=\"text\"\n value={v.key}\n placeholder=\"key\"\n aria-label=\"Variable key\"\n onChange={(e) => updateVariable(i, { key: e.target.value })}\n />\n <select\n value={v.type ?? \"\"}\n aria-label=\"Variable type\"\n onChange={(e) =>\n updateVariable(i, {\n type: (e.target.value || undefined) as WorkflowVariableRow[\"type\"],\n })\n }\n >\n <option value=\"\">(unset)</option>\n {VARIABLE_TYPES.map((t) => (\n <option key={t} value={t}>\n {t}\n </option>\n ))}\n </select>\n <label\n className=\"row\"\n style={{ gap: \"var(--w6w-sp-1)\", alignItems: \"center\" }}\n >\n <input\n type=\"checkbox\"\n checked={v.required ?? false}\n onChange={(e) => updateVariable(i, { required: e.target.checked })}\n />\n <span className=\"muted small\">required</span>\n </label>\n {/* Narrow `vars` for THIS row only: a variable's default\n may reference the variables declared above it, never\n itself or the ones below. Only that one key is\n contributed — secrets, documents, sample values and the\n callbacks come through from the app shell untouched,\n because the provider layers rather than replaces. */}\n <ExpressionOptionsProvider\n value={{ vars: varsRailFor(variables, i, inheritedVars) }}\n >\n <ExpressionInput\n // Re-key on the list's shape (not just `i`): ExpressionInput\n // seeds its parts once on mount and never again, so when a\n // row is removed and later rows shift up an index, React\n // must remount the widget rather than reuse the instance —\n // otherwise the surviving cell keeps showing the previous\n // occupant's default (see ExpressionInput.tsx:56-57).\n key={`${variables.length}:${i}`}\n value={v.default as ExprValue | string | SecretValue | undefined}\n onChange={(next) => updateVariable(i, { default: next })}\n placeholder=\"default\"\n aria-label=\"Variable default\"\n />\n </ExpressionOptionsProvider>\n <IconButton\n danger\n icon=\"close\"\n label={`Remove variable ${v.key || i + 1}`}\n onClick={() => removeVariable(i)}\n />\n </div>\n {dupIndexes.includes(i) && (\n <span className=\"muted small\" data-testid=\"variable-duplicate\">\n Duplicate key — a later row with the same name wins.\n </span>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Done\n </button>\n </div>\n </>\n )}\n </Modal>\n );\n}\n","import type { WorkflowStatus } from \"@w6w/sdk\";\nimport type { CallablePolicy, WorkflowSettings, WorkflowVariableRow } from \"../lib/index.ts\";\n\nexport type Parsed = Record<string, unknown> & {\n id?: string;\n name?: string;\n /** D-1: nullable, no backfill; `undefined` when the field is absent from\n * the text entirely — both mean \"no key\" to {@link workflowKeyEditAllowed}\n * (D-3). The rail's Key control (`SettingsTool.tsx`) is the only place\n * this is ever ASSIGNED; this page only ever reads it back. */\n key?: string | null;\n steps?: unknown[];\n status?: WorkflowStatus;\n tags?: string[];\n /** Authoring presentation — rides in the definition, no column of its own. */\n settings?: WorkflowSettings;\n /** Declared public input schema (T1.1.5) — see `workflow-variables.ts`. */\n variables?: WorkflowVariableRow[];\n /**\n * The RUN-level error policy (core Workflow RFC — *Amendment — 2026-08-21:\n * the run-level error handler*). Authored from the right rail's Error\n * handling tool, which this page hands a writer to rather than letting it\n * save independently — see the `useWorkspace` call below.\n */\n retry?: CallablePolicy[\"retry\"];\n onError?: CallablePolicy[\"onError\"];\n reroute?: CallablePolicy[\"reroute\"];\n};\n\n/** Workflow ids: start alphanumeric, then word chars / dots / dashes. */\nexport const ID_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\n\n/** Placeholder + minimum sizing basis for the inline title field. */\nexport const TITLE_PLACEHOLDER = \"Untitled workflow\";\n","import { useQueries } from \"@tanstack/react-query\";\nimport { ApiError } from \"@w6w/sdk\";\nimport {\n ExecutionLogPanel,\n IconButton,\n isTestRequired,\n requiredParamsFilled,\n useW6WApi,\n} from \"@w6w/ui\";\nimport type { InternalNodeDef } from \"@w6w/ui/flow\";\nimport {\n type ReactNode,\n Suspense,\n lazy,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ExecutionProfileHeader } from \"../chrome/ExecutionProfileHeader.tsx\";\nimport { HistoryButton } from \"../chrome/HistoryButton.tsx\";\nimport { JsonToggle, JsonToggleButton } from \"../chrome/JsonToggle.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport { useWorkspace } from \"../chrome/workspace.tsx\";\nimport { useEmbedClient, useWorkflowDraft } from \"../draft/index.ts\";\nimport {\n type ActionParamLike,\n type CallablePolicy,\n type TriggerPreview,\n type TriggerPreviewFieldDef,\n type ValidityContext,\n type WorkflowLike,\n type WorkflowStepLike,\n definitionWithPolicy,\n invalidReason,\n policyFromDefinition,\n readSettings,\n readVariables,\n triggerPreviews,\n variablesForSave,\n workflowKeyEditAllowed,\n workflowValid,\n writeSetting,\n} from \"../lib/index.ts\";\nimport { useEditorProject } from \"../project-context.ts\";\nimport type { RailNavigation } from \"../rail/rail-env.tsx\";\nimport {\n classifyCancelError,\n isRunInFlight,\n listStepTests,\n mapRunStateToLogSteps,\n resolveHeaderRunInput,\n runButtonLabel,\n runLevelErrors,\n stepTestsKey,\n useCancelRunMutation,\n useLiveRunQuery,\n usePublishMutation,\n useStartRunMutation,\n useVersionsQuery,\n} from \"../repos/index.ts\";\nimport { EditorShell } from \"./EditorShell.tsx\";\nimport { WorkflowSettingsModal } from \"./WorkflowSettingsModal.tsx\";\nimport { ID_RE, type Parsed, TITLE_PLACEHOLDER } from \"./definition.ts\";\nimport { appActionsKey, useEditorApps } from \"./editor-apps.ts\";\nimport type {\n WorkflowEditorNavigation,\n WorkflowEditorProps,\n WorkflowEditorSlots,\n} from \"./types.ts\";\n\n// The visual editor is code-split — its @xyflow/react payload only loads when\n// the editor is actually open.\nconst WorkflowFlowEditor = lazy(() =>\n import(\"@w6w/ui/flow\").then((m) => ({ default: m.WorkflowFlowEditor })),\n);\n\nfunction EditorBody(props: {\n workflowId: string;\n project: string | null;\n initialRunId?: string;\n onNavigate: (to: WorkflowEditorNavigation) => void;\n slots?: WorkflowEditorSlots;\n}) {\n const { workflowId, project, initialRunId, onNavigate, slots } = props;\n const apiClient = useEmbedClient();\n const api = useW6WApi();\n const [valid, setValid] = useState(true);\n const [validityError, setValidityError] = useState<string | null>(null);\n // Page-level errors only (run, publish, create); the draft's own load/save errors come from\n // `useWorkflowDraft` (`draftError` below).\n const [error, setError] = useState<string | null>(null);\n const [showJson, setShowJson] = useState(false);\n const [showSettings, setShowSettings] = useState(false);\n const [reloading, setReloading] = useState(false);\n\n // D-3/P4: the key the SERVER most recently sent for the row the buffer is showing — what\n // `workflowKeyEditAllowed` compares the parsed text's own `key` against. `undefined` = nothing\n // loaded yet (refuses unconditionally). Captured whenever the buffer equals the server's copy\n // (load, 409 reload, and after a save), never while it holds unsaved edits. State, not a ref:\n // the guard below must change identity for the draft to re-evaluate it.\n const [loadedKey, setLoadedKey] = useState<string | null | undefined>(undefined);\n // Injected into the draft (the hook is headless — these are Studio's own rules).\n // `autoSave` and the publish-validity reason both depend on the parsed text, which the hook\n // itself produces, so they ride refs assigned after the call (one render of lag at most).\n const autoSaveRef = useRef(true);\n const publishReasonRef = useRef<(def: unknown) => string | null>(() => null);\n const saveGuard = useCallback(\n (def: unknown): string | null => {\n const d = def as Parsed;\n if (!ID_RE.test(typeof d.id === \"string\" ? d.id : \"\")) return \"Invalid workflow id.\";\n // D-3/P4: the rail's Key control is the only place a key is ever assigned — this JSON\n // editor must refuse to save a definition whose `key` differs from what was loaded. Folded\n // into the draft's save gate (never a separate `disabled` on the Save button): auto-save\n // reads the same gate, so a guard on the button alone would be bypassed by typing.\n return workflowKeyEditAllowed(loadedKey, d.key).reason;\n },\n [loadedKey],\n );\n // Load, buffer, save, auto-save, flush-on-hide/unmount and the 409 all live in the hook\n // (`../draft`). The project is `useEditorProject`'s answer (prop, else the provider's): with\n // none, the hook refuses to save (`saveBlockedReason`) rather than let the server pick the\n // account default.\n const draft = useWorkflowDraft({\n workflowId,\n project,\n autoSave: autoSaveRef.current,\n // The expression editor holds uncommitted parts in its own local state until its Save\n // button, so saving from under it would persist a workflow without the expression the user\n // is looking at. Read at fire time (opening it changes neither the buffer nor `canSave`).\n canAutoSave: () => !document.querySelector(\".w6w-exprmodal\"),\n saveGuard,\n publishBlockedReason: (def) => publishReasonRef.current(def),\n });\n const json = draft.json;\n const parsed = draft.parsed as Parsed | null;\n const canSave = draft.canSave;\n const dirty = draft.dirty;\n\n // Capture the server's key whenever the buffer equals the server's copy (never while it holds\n // unsaved edits), and forget it while a workflow is loading or failed to load.\n useEffect(() => {\n if (draft.loading || draft.loadError !== null) {\n setLoadedKey(undefined);\n return;\n }\n if (!draft.dirty && parsed) setLoadedKey((parsed.key as string | null | undefined) ?? null);\n }, [draft.loading, draft.loadError, draft.dirty, parsed]);\n\n // \"Keep editing\" dismisses the 409 modal; the draft stays stale (it refuses to save into the\n // conflict) until the author reloads.\n const [staleDismissed, setStaleDismissed] = useState(false);\n useEffect(() => {\n if (!draft.stale) setStaleDismissed(false);\n }, [draft.stale]);\n\n // The \"Saved.\" marker: a save finished without error since the last one began.\n const [saved, setSaved] = useState(false);\n const wasSaving = useRef(false);\n useEffect(() => {\n if (draft.saving) setSaved(false);\n else if (wasSaving.current && draft.error === null) setSaved(true);\n wasSaving.current = draft.saving;\n }, [draft.saving, draft.error]);\n\n // T2.1.1: the run this canvas is currently showing, if any. Reset inside\n // the `workflowId` load effect below, so a run from a previously open\n // workflow never bleeds into a different one's canvas.\n const [activeRunId, setActiveRunId] = useState<string | null>(null);\n\n // Names offered by each step field's expression picker (task 3.2). The vault\n // No project-scope memo here any more. The ƒx rail's vars, secrets,\n // documents, sample values and \"+ Add\"/seal callbacks are INHERITED from\n // `ProjectExpressionScope` (`App.tsx`); `WorkflowFlowEditor` and the settings\n // modal below both read them from context. What this page's editor\n // contributes on top — the upstream `steps` for one node, and the narrowed\n // `vars` rail for a variable's own default row — is added where it is known,\n // not restated here. See `ui/ExpressionScope.tsx`.\n\n // ── T2.1.1: Run/Stop in the visual editor — live poll, canvas feedback, ──\n // ── log panel, read-only lock. See building-blocks.md §G3/§G4/§G6/§5. ────\n const startRunMut = useStartRunMutation();\n const cancelRunMut = useCancelRunMutation();\n const runQuery = useLiveRunQuery(activeRunId);\n const runStatus = runQuery.data?.status;\n const runPollFailed = runQuery.isError;\n const runInFlight = isRunInFlight(runStatus, runPollFailed);\n // 26-10-04-01-fixes I-1: the run log's rows (each carrying its step's error)\n // and the run-level `error`/`stepErrors` the rows don't already show —\n // mapped once per render, shared by the panel's three props.\n const runLogSteps = mapRunStateToLogSteps(\n runQuery.data?.steps as unknown as Parameters<typeof mapRunStateToLogSteps>[0],\n );\n const runLogErrors = runLevelErrors(runQuery.data, runLogSteps);\n // Header Run fetches the trigger's saved fixture before starting the run;\n // the ref guards re-entry synchronously (a second click can land before the\n // re-render that disables the button), the state disables the button.\n const runStartingRef = useRef(false);\n const [runStarting, setRunStarting] = useState(false);\n\n // ── T2.4.2: `?run=<runId>` — the History page's \"Open in visual editor\" ──\n // A workflow run's History row links to `workflows/<id>?run=<runId>`, and\n // THIS editor is what that link opens. The run plumbing above already\n // renders a terminal run exactly like a live one (`useLiveRunQuery` stops\n // polling on a terminal status by itself), so seeding `activeRunId` from the\n // URL is the whole feature — nothing about the poll, the canvas, the\n // read-only lock or the log panel moves.\n //\n // Declared AFTER the `workflowId` load effect on purpose: that effect resets\n // `activeRunId` for the row it is opening, and effects run in declaration\n // order, so on a mount the URL's run wins. Keyed on `[workflowId, initialRunId]`\n // rather than on mount alone, so an in-app transition to `?run=…` while the\n // editor stays mounted (`history.pushState` + `popstate`) still opens the\n // panel.\n // T2.1.1: a run belongs to the row that started it — the draft's load (formerly this page's\n // `workflowId` effect) reset it; declared BEFORE the `?run=` seed below so the URL's run still wins.\n // biome-ignore lint/correctness/useExhaustiveDependencies: `workflowId` is the trigger, not a value read\n useEffect(() => {\n setActiveRunId(null);\n }, [workflowId]);\n // biome-ignore lint/correctness/useExhaustiveDependencies: `workflowId`'s own value is never read below — it exists solely to re-seed the URL's run when the OPEN WORKFLOW changes, not as a value this closure needs (same retrigger-dependency shape as `api/w6wApiFacade.tsx`).\n useEffect(() => {\n if (initialRunId) setActiveRunId(initialRunId);\n }, [workflowId, initialRunId]);\n\n // The run id alone is not enough: a stale or hand-edited `?run=` can name a\n // run belonging to a DIFFERENT workflow, and painting that run's steps on\n // this canvas would be a lie. `RunState` carries its own `workflowId`, so the\n // first answer that names another workflow drops the run instead of\n // rendering it.\n useEffect(() => {\n if (runQuery.data && runQuery.data.workflowId !== workflowId) setActiveRunId(null);\n }, [runQuery.data, workflowId]);\n\n /**\n * T2.1.5: run `action` only once the buffer is saved. `blocked` shows its reason in the banner;\n * `failed` is already surfaced by the draft itself (banner, or the 409 modal via `draft.stale`).\n */\n async function runAfterFlush(action: () => Promise<unknown>) {\n try {\n const r = await draft.flushThen(action);\n if (!r.ok && r.outcome.status === \"blocked\") setError(r.outcome.reason);\n } catch (e) {\n setError(e instanceof ApiError ? e.message : String(e));\n }\n }\n\n async function onRunClick() {\n if (!workflowId || runInFlight || runStartingRef.current) return;\n setError(null);\n runStartingRef.current = true;\n setRunStarting(true);\n try {\n // 26-10-04-01-fixes I-1 (pinned): the manual trigger's latest saved Test-tab\n // values become the run's `input`, verbatim; no fixture (or no trigger,\n // or a failed fetch) sends no `input` key, exactly as before.\n const input = await resolveHeaderRunInput(triggerPreviewList?.[0]?.id, (stepId) =>\n listStepTests(apiClient, workflowId, stepId),\n );\n // T2.1.5 (R-27): the stored row is what runs, so an unsaved edit is saved FIRST. A refused\n // flush (`blocked` reason / `failed` save) never starts the run.\n await runAfterFlush(() =>\n startRunMut\n .mutateAsync({\n id: workflowId,\n variables: {},\n ...(input ? { input } : {}),\n })\n .then((res) => setActiveRunId(res.runId)),\n );\n } finally {\n runStartingRef.current = false;\n setRunStarting(false);\n }\n }\n\n function onStopClick() {\n if (!activeRunId) return;\n cancelRunMut.mutate(activeRunId, {\n onError: (e) => {\n const code = e instanceof ApiError ? e.code : \"\";\n // A `409 run_not_cancelable` means the run already finished before the\n // cancel request landed — reconcile via the next poll, no error banner.\n if (classifyCancelError(code) === \"surface\") {\n setError(e instanceof ApiError ? e.message : String(e));\n }\n },\n });\n // T1.1.1 A1: ask the server to cancel, but reset the LOCAL run state now —\n // the cancel is cooperative (heartbeat-driven) and may land long after the\n // click, so waiting for a poll to observe a terminal status would leave the\n // canvas greyed out in front of the user who just pressed Stop. The request\n // above still goes out, and `onError` still classifies the 409.\n setActiveRunId(null);\n }\n\n /** Replace the editor's contents with the server's copy and re-arm the token. */\n async function reloadFromServer() {\n setReloading(true);\n try {\n await draft.reload();\n setValid(true);\n setValidityError(null);\n setError(null);\n } finally {\n setReloading(false);\n }\n }\n\n // Page-level errors win; the draft's own load/save failure shows otherwise. A 409 is the\n // modal's business, not the banner's.\n const draftFailure = draft.stale ? null : (draft.error ?? draft.loadError);\n const bannerError =\n error ??\n (draftFailure === null\n ? null\n : draftFailure instanceof Error\n ? draftFailure.message\n : String(draftFailure));\n\n // Parse for the visual view + meta fields — the draft already parses (memoized) per edit.\n const flowUsable = parsed !== null && Array.isArray(parsed.steps);\n\n const displayName = (parsed?.displayName as string) ?? \"\";\n // Both flags are ON for a workflow that declares no `settings` — see readSettings.\n const settings = readSettings(parsed?.settings);\n // The Variables tab's rows (T1.1.5) — declaring the workflow's public input\n // schema (HITL-5). `useMemo` because `varsRailFor` runs once per row on\n // every render otherwise.\n const variables = useMemo(() => readVariables(parsed?.variables), [parsed?.variables]);\n // Visible only once something has actually loaded AND the parsed text is\n // real JSON — never flashes \"Workflow not loaded yet\" on a fresh mount\n // before the initial fetch resolves.\n const keyEdit = workflowKeyEditAllowed(loadedKey, parsed?.key);\n const keyGuardReason =\n parsed !== null && loadedKey !== undefined && !keyEdit.allowed ? keyEdit.reason : null;\n\n // ── Publish-time validity gate (T4.2.1) ──────────────────────────────────\n const steps = useMemo<WorkflowStepLike[]>(\n () => (Array.isArray(parsed?.steps) ? (parsed.steps as WorkflowStepLike[]) : []),\n [parsed],\n );\n\n // `INTERNAL_NODES`/`isInternalApp`/`internalNodeParams` resolve from the SAME\n // `import(\"@w6w/ui/flow\")` the canvas's `lazy()` above already triggers (a\n // module-cache hit, not a second bundle) — only needed while the editor is\n // open, same as the canvas itself. Defaults to \"nothing resolved yet\", which\n // fails `hasTrigger`/`actionParamsByKey` closed (invalid) until it lands.\n const [flowHelpers, setFlowHelpers] = useState<{\n internalNodes: InternalNodeDef[];\n isInternalApp: (app: string) => boolean;\n internalNodeParams: (app: string, action: string) => ActionParamLike[];\n // \"Call from code\" trigger preview (T2.2.1) — `TRIGGER_APP`/`asFieldDefs`\n // resolve from the SAME import, no second dynamic import.\n isManualTrigger: (app: string) => boolean;\n asFieldDefs: (fields: unknown) => TriggerPreviewFieldDef[];\n } | null>(null);\n useEffect(() => {\n let canceled = false;\n import(\"@w6w/ui/flow\").then((m) => {\n if (canceled) return;\n setFlowHelpers({\n internalNodes: m.INTERNAL_NODES,\n isInternalApp: m.isInternalApp,\n internalNodeParams: m.internalNodeParams,\n isManualTrigger: (app) => app === m.TRIGGER_APP,\n asFieldDefs: m.asFieldDefs,\n });\n });\n return () => {\n canceled = true;\n };\n }, []);\n\n // \"Call from code\" trigger preview (T2.2.1, HITL-2/HITL-4 pinned): the\n // modal's per-trigger field picker, derived from the SAME `steps` above —\n // no new fetch, no new query key.\n const triggerPreviewList = useMemo<TriggerPreview[] | undefined>(() => {\n if (!flowHelpers) return undefined;\n return triggerPreviews(\n { steps },\n {\n isManualTrigger: flowHelpers.isManualTrigger,\n asFieldDefs: flowHelpers.asFieldDefs,\n },\n );\n }, [flowHelpers, steps]);\n\n // \"A trigger exists\" means a graph STEP whose (app, action) is a trigger\n // node (an `INTERNAL_NODES` entry with `group: \"trigger\"`) — not the\n // workflow's top-level `trigger` field, which `blankDefinition` always\n // seeds and so is truthy unconditionally (rfcs/workflow.md:114).\n const hasTrigger = useMemo(() => {\n if (!flowHelpers) return false;\n const triggerKeys = new Set(\n flowHelpers.internalNodes\n .filter((n) => n.group === \"trigger\")\n .map((n) => `${n.app}::${n.action}`),\n );\n return steps.some((s) => {\n const { app, action } = s.uses ?? {};\n return !!app && !!action && triggerKeys.has(`${app}::${action}`);\n });\n }, [flowHelpers, steps]);\n\n // Unique third-party (non-internal) app ids across the graph, batch-fetched\n // once each — mirrors the per-step fetch WorkflowFlowEditor already does\n // (WorkflowFlowEditor.tsx:~1432), hoisted to page level and de-duplicated.\n const thirdPartyAppIds = useMemo(() => {\n if (!flowHelpers) return [];\n const ids = new Set<string>();\n for (const s of steps) {\n const { app, action } = s.uses ?? {};\n if (app && action && !flowHelpers.isInternalApp(app)) ids.add(app);\n }\n return [...ids];\n }, [flowHelpers, steps]);\n // Registered apps, so the visual editor can render each action node with its\n // owning app's icon, display name, and version — bounded to the ids this\n // graph actually references (src/apps provider, T3.1.2).\n const { byId: fetchedAppsById } = useEditorApps(thirdPartyAppIds);\n const appsList = useMemo(() => [...fetchedAppsById.values()], [fetchedAppsById]);\n const appActionsQueries = useQueries({\n queries: thirdPartyAppIds.map((appId) => ({\n queryKey: appActionsKey(appId),\n queryFn: () => api.getAppActions(appId),\n })),\n });\n\n // Declared params for every step's target, internal (sync) or third-party\n // (fetched above) — keyed `${app}::${action}`, one entry per unique target.\n const actionParamsByKey = useMemo(() => {\n const out: Record<string, ActionParamLike[]> = {};\n if (!flowHelpers) return out;\n for (const s of steps) {\n const { app, action } = s.uses ?? {};\n if (!app || !action) continue;\n const key = `${app}::${action}`;\n if (key in out) continue;\n if (flowHelpers.isInternalApp(app)) {\n out[key] = flowHelpers.internalNodeParams(app, action);\n } else {\n const idx = thirdPartyAppIds.indexOf(app);\n const fetched = idx >= 0 ? appActionsQueries[idx]?.data : undefined;\n out[key] = fetched?.find((a) => a.key === action)?.params ?? [];\n }\n }\n return out;\n }, [flowHelpers, steps, thirdPartyAppIds, appActionsQueries]);\n\n const appsById = useMemo(() => {\n const out: Record<string, unknown> = {};\n for (const [id, a] of fetchedAppsById) out[id] = a;\n return out;\n }, [fetchedAppsById]);\n\n // Only a step whose app is BOTH a real fetched app AND opts into\n // testRequired needs a `listStepTests` fetch — an internal/trigger/control\n // step's app is never a key in `appsById`, so it is never gated.\n const testGatedSteps = useMemo(\n () =>\n steps.filter((s) => {\n const app = s.uses?.app;\n return !!app && app in appsById && isTestRequired(appsById[app]);\n }),\n [steps, appsById],\n );\n const stepTestsQueries = useQueries({\n queries: testGatedSteps.map((s) => ({\n queryKey: stepTestsKey(workflowId, s.id),\n queryFn: () => listStepTests(apiClient, workflowId, s.id),\n enabled: !!workflowId,\n })),\n });\n const testStatus = useMemo(() => {\n const out: Record<string, boolean> = {};\n testGatedSteps.forEach((s, i) => {\n out[s.id] = !!stepTestsQueries[i]?.data?.some((t) => t.lastRunStatus === \"succeeded\");\n });\n return out;\n }, [testGatedSteps, stepTestsQueries]);\n\n // T3.1.1: the Publish button's own published-state, gated the same shape\n // as `stepTestsQueries` above (`!!workflowId`) — never on mount\n // alone. Shares its cache entry with the Settings rail's own History\n // section (same `[\"versions\", \"workflow\", id]` key), so either surface's\n // Publish click refreshes both without a reload.\n const versionsQuery = useVersionsQuery(\"workflow\", workflowId, !!workflowId);\n const publishMut = usePublishMutation(\"workflow\");\n\n const validityCtx = useMemo<ValidityContext>(\n () => ({\n hasTrigger,\n actionParamsByKey,\n appsById,\n testStatus,\n requiredParamsFilled,\n isTestRequired,\n }),\n [hasTrigger, actionParamsByKey, appsById, testStatus],\n );\n const workflowIsValid =\n parsed !== null && workflowValid(parsed as unknown as WorkflowLike, validityCtx);\n const publishInvalidReason =\n parsed !== null ? invalidReason(parsed as unknown as WorkflowLike, validityCtx) : null;\n\n publishReasonRef.current = (def) =>\n def !== null && typeof def === \"object\"\n ? invalidReason(def as unknown as WorkflowLike, validityCtx)\n : null;\n autoSaveRef.current = settings.autoSave;\n\n /** Patch top-level workflow fields, keeping the JSON text as source of truth. */\n function patchMeta(patch: Partial<Parsed>) {\n if (!parsed) return;\n const next: Parsed = { ...parsed, ...patch };\n draft.setJson(JSON.stringify(next, null, 2));\n }\n\n /** Patch top-level fields and persist immediately (for publish/tags edits). */\n function saveMeta(patch: Partial<Parsed>) {\n if (!parsed) return;\n const next: Parsed = { ...parsed, ...patch };\n setError(null);\n void draft.commit(JSON.stringify(next, null, 2));\n }\n\n // The rail's `onPolicyChange` must be referentially stable (see the `useWorkspace` call\n // below) and therefore cannot close over `parsed`/`draft` directly: it reads the live\n // definition and the draft's `commit` through refs.\n const parsedRef = useRef(parsed);\n parsedRef.current = parsed;\n const commitRef = useRef(draft.commit);\n commitRef.current = draft.commit;\n const saveNowRef = useRef(draft.saveNow);\n saveNowRef.current = draft.saveNow;\n\n // Cmd/Ctrl+S saves while the visual editor is open (mirrors the project\n // switcher's keydown effect in components/Layout.tsx: one guarded document\n // listener, symmetric cleanup).\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.altKey || !(e.metaKey || e.ctrlKey) || e.key.toLowerCase() !== \"s\") return;\n // Suppress the browser's Save Page dialog on every match, including the\n // paths below that decline to save.\n e.preventDefault();\n // The expression editor holds uncommitted parts in its own local state\n // until its Save button, so saving from under it would persist a workflow\n // without the expression the user is looking at.\n if (document.querySelector(\".w6w-exprmodal\")) return;\n if (!canSave) return;\n saveNowRef.current();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [canSave]);\n\n // T2.1.2: publishes into the right rail's Code/Aliases tools — called on\n // EVERY render, into the `WorkspaceProvider` the outer `WorkflowEditor` mounts.\n //\n // The `policy`/`onPolicyChange` pair is the right rail's Error handling tool\n // (core Workflow RFC — *Amendment — 2026-08-21: the run-level error\n // handler*). The rail does NOT save a workflow itself: this page owns the\n // definition buffer and the draft saves it, so a second writer over the wire\n // would race the canvas and one side's edit would vanish. Handing the rail a\n // writer instead makes its Save fold into the very same JSON text.\n const wfPolicy = useMemo<CallablePolicy>(\n () => (parsed ? policyFromDefinition(parsed) : {}),\n [parsed],\n );\n // Referentially STABLE, as `workspace.tsx` requires: `useWorkspace` keys its\n // publish effect on `JSON.stringify(resource)`, which drops functions, so a\n // callback rebuilt per render would be stored once and then go stale. It\n // reads the current definition through `parsedRef` — always the live value,\n // never a captured one. Persists immediately, exactly like `saveMeta`'s\n // publish/tags edits.\n const onPolicyChange = useCallback((policy: CallablePolicy) => {\n const current = parsedRef.current;\n if (!current) return;\n const next = definitionWithPolicy(current, policy);\n setError(null);\n void commitRef.current(JSON.stringify(next, null, 2));\n }, []);\n\n useWorkspace({\n kind: \"workflow\",\n id: workflowId,\n label: displayName,\n key: parsed?.key ?? undefined,\n triggers: triggerPreviewList,\n policy: wfPolicy,\n onPolicyChange,\n });\n\n return (\n <div className=\"wf-fullbleed\" style={{ height: \"100%\", minWidth: 0, flex: 1 }}>\n {/* T3.1.1: the header itself is `ExecutionProfileHeader` — the SAME\n component a Function/Endpoint editor mounts through\n `CallableEditorChrome`. Everything below is host business: the\n back control (A8, updated by T4.1.1: the editor is its own route\n now, so \"back\" navigates to the LISTING — the sibling params it was\n opened with are kept, since they are the author's), the controlled\n name field that persists on blur, and the action row. */}\n {slots?.header ?? (\n <ExecutionProfileHeader\n onBack={() => onNavigate({ type: \"list\" })}\n backLabel={slots?.backLabel ?? \"← Workflows\"}\n title={{\n editable: true,\n value: displayName,\n placeholder: TITLE_PLACEHOLDER,\n maxLength: 80,\n ariaLabel: \"Workflow name\",\n onChange: (next) => patchMeta({ displayName: next }),\n onBlur: () => {\n if (canSave) draft.saveNow();\n },\n }}\n actions={\n <>\n <IconButton\n icon=\"play\"\n label={runButtonLabel(runStatus, runPollFailed)}\n data-testid=\"wf-run-start\"\n onClick={onRunClick}\n disabled={!workflowId || runInFlight || runStarting || startRunMut.isPending}\n />\n {runInFlight && (\n <IconButton\n icon=\"stop\"\n label=\"Stop this run\"\n data-testid=\"wf-run-stop\"\n onClick={onStopClick}\n disabled={cancelRunMut.isPending}\n />\n )}\n <button\n type=\"button\"\n className={`btn ghost wf-publish${versionsQuery.data?.currentPublishedVersion != null ? \" active\" : \"\"}`}\n data-testid=\"wf-publish\"\n onClick={() => {\n if (!workflowId) return;\n setError(null);\n void runAfterFlush(() => publishMut.mutateAsync(workflowId));\n }}\n disabled={project === null || !canSave || !workflowIsValid || publishMut.isPending}\n title={\n canSave && !workflowIsValid\n ? (publishInvalidReason ?? \"Workflow is not valid\")\n : versionsQuery.data?.currentPublishedVersion != null\n ? \"Published — click to publish a new version\"\n : \"Never published — click to publish\"\n }\n >\n {publishMut.isPending\n ? \"Publishing…\"\n : versionsQuery.data?.currentPublishedVersion != null\n ? \"● Published\"\n : \"Publish\"}\n </button>\n <HistoryButton\n kind=\"workflow\"\n id={workflowId}\n onOpenRun={(runId) => {\n setActiveRunId(runId);\n onNavigate({ type: \"run\", id: workflowId, runId });\n }}\n />\n <JsonToggleButton onClick={() => setShowJson(true)} />\n {/* T2.1.2: \"Call from code\" moved to the right rail's Code tool —\n see the `useWorkspace` call above (this closes the prior\n project's HITL-1: the flow editor now publishes, since the\n gate is the editor's own mount, not the route wrapper that could\n never see this component's route param). */}\n <IconButton\n icon=\"settings\"\n label=\"Workflow settings\"\n onClick={() => setShowSettings(true)}\n />\n {slots?.headerActions}\n </>\n }\n />\n )}\n <div className=\"wf-fullbleed-canvas\">\n <div className=\"wf-run-area\">\n <div className=\"wf-run-canvas\">\n <Suspense fallback={<p className=\"muted\">Loading visual editor…</p>}>\n {flowUsable && parsed ? (\n <WorkflowFlowEditor\n // The parsed cast is safe: onChange only receives shapes we produced.\n value={parsed as unknown as Parameters<typeof WorkflowFlowEditor>[0][\"value\"]}\n onChange={(next) => {\n draft.setJson(JSON.stringify(next, null, 2));\n setValid(true);\n setValidityError(null);\n // T1.1.1 A2.1: an edit to the graph — a canvas edit or a\n // step-config commit from `StepEditModal`, both of which\n // arrive here — means the run this canvas was showing is\n // no longer the thing the author is looking at.\n setActiveRunId(null);\n }}\n apps={appsList}\n project={project ?? undefined}\n height=\"100%\"\n // A4: locked while the run this canvas is showing is still\n // in flight, unlocked again on every terminal status AND\n // when the poll itself gives up or errors.\n readOnly={runInFlight}\n // L-3b: re-frame the graph when the run-log panel docks\n // beside it and again when it leaves — keyed on the panel\n // being MOUNTED (`activeRunId`, same condition as the\n // `wf-run-log` block below), not on `runInFlight` (the\n // panel stays after a terminal status) nor on the run's\n // data (changes every poll tick).\n fitViewKey={activeRunId !== null}\n // A3: each intermediate RunState reaches the canvas as it\n // arrives — the cast crosses the same opaque-`steps`\n // boundary `getRunState`'s own callers already cross (the\n // SDK's console `RunState.steps` is `Record<string,\n // unknown>` on purpose; the server's real per-step shape\n // structurally satisfies `ui`'s narrower `RunState`).\n runState={\n runQuery.data as unknown as Parameters<typeof WorkflowFlowEditor>[0][\"runState\"]\n }\n // T1.1.1 A3: a step test starts → the run this canvas was\n // showing is no longer the thing under test, so drop it on\n // the click rather than waiting for the test's result.\n onTestRun={() => setActiveRunId(null)}\n />\n ) : json === \"\" ? (\n <p className=\"muted\">Loading…</p>\n ) : (\n <p className=\"muted\">Fix the JSON to render the visual editor.</p>\n )}\n </Suspense>\n </div>\n {activeRunId && (\n <div className=\"wf-run-log\" data-testid=\"wf-run-log\">\n <ExecutionLogPanel\n steps={runLogSteps}\n runError={runLogErrors.runError}\n stepErrors={runLogErrors.stepErrors}\n // T1.1.1 A4: the one explicit \"I'm done looking at this run\"\n // control — same lever as Stop, so it must work in the empty\n // branch too (the panel renders its head there as well).\n onDismiss={() => setActiveRunId(null)}\n />\n </div>\n )}\n </div>\n </div>\n {project === null && (\n <div role=\"alert\" className=\"error\" data-testid=\"wf-project-required\">\n No project selected — pass a <code>project</code> prop (or set the provider's project) to\n edit and save this workflow.\n </div>\n )}\n <div className=\"wf-fullbleed-foot\">\n <div className=\"row\" style={{ flexWrap: \"wrap\", alignItems: \"center\" }}>\n {/* Auto-save does not remove this button (it is the escape hatch when\n `autoSave` is off, and the only legible signal of save state when it\n is on): it flushes the pending window now, and greys out once the\n canvas matches the server. */}\n <button\n type=\"button\"\n className=\"btn\"\n disabled={project === null || !canSave || !dirty}\n onClick={draft.saveNow}\n >\n {draft.saving ? \"Saving…\" : \"Save\"}\n </button>\n {saved && <span className=\"ok\">Saved.</span>}\n </div>\n {bannerError && <div className=\"error\">{bannerError}</div>}\n {keyGuardReason && (\n <div className=\"error\" data-testid=\"wf-key-guard\">\n {keyGuardReason}\n </div>\n )}\n </div>\n\n <JsonToggle\n open={showJson}\n onClose={() => setShowJson(false)}\n title={`JSON — ${(parsed?.displayName as string) || \"workflow\"}`}\n mode=\"synced\"\n value={json}\n onChange={(next) => {\n draft.setJson(next);\n // T1.1.1 A2.2 (D-2): the raw-JSON surface is an edit surface\n // too, so it clears the shown run the same way the canvas does.\n setActiveRunId(null);\n }}\n onValidityChange={({ valid: v, error: err }) => {\n setValid(v);\n setValidityError(err);\n }}\n invalidReason={!valid ? validityError : null}\n editorLabel=\"Workflow definition JSON\"\n />\n\n {draft.stale && !staleDismissed && (\n <Modal title=\"This workflow changed on the server\" onClose={() => setStaleDismissed(true)}>\n <div className=\"modal-body\">\n <p className=\"muted small\">\n Someone else — another tab, another session — saved this workflow after you opened it.\n Your save was refused rather than applied, so their work is still intact.\n </p>\n <p className=\"muted small\">\n <strong>Reload from server</strong> replaces what is on this canvas with the saved\n copy; anything you changed here and have not saved is lost.{\" \"}\n <strong>Keep editing</strong> leaves your version exactly as it is — but every save\n will be refused the same way until you reload, so copy out anything you need first.\n </p>\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={() => setStaleDismissed(true)}>\n Keep editing\n </button>\n <button type=\"button\" className=\"btn\" disabled={reloading} onClick={reloadFromServer}>\n {reloading ? \"Reloading…\" : \"Reload from server\"}\n </button>\n </div>\n </Modal>\n )}\n\n {showSettings && (\n <WorkflowSettingsModal\n autoSave={settings.autoSave}\n savePosition={settings.savePosition}\n variables={variables}\n onClose={() => setShowSettings(false)}\n onChange={(key, value) =>\n saveMeta({ settings: writeSetting(parsed?.settings, key, value) })\n }\n onVariablesChange={(next) => patchMeta({ variables: variablesForSave(next) })}\n />\n )}\n </div>\n );\n}\n\nconst NOOP = (): void => {};\n\n/**\n * The managed workflow editor. The outermost element is `.w6w-embed-root` (pinned for the embed\n * stylesheet); everything the editor renders — header, canvas, modals, rail — stays a descendant of\n * it, and nothing goes through a portal. It fills its host container (`height: 100%`), so the host\n * decides how tall the editor is.\n *\n * `useEditorProject(props.project)` is the ONLY project source: it feeds the draft, the expression\n * scope, the rail environment and the canvas. `null` (no project) refuses — see `EditorBody`.\n */\nexport function WorkflowEditor(props: WorkflowEditorProps): ReactNode {\n const { workflowId, initialRunId, onNavigate = NOOP, slots } = props;\n const project = useEditorProject(props.project);\n const railNavigate = useCallback(\n (to: RailNavigation) => {\n if (to.type === \"list\") onNavigate({ type: \"list\" });\n else if (to.kind === \"workflow\") onNavigate({ type: \"workflow\", id: to.id });\n },\n [onNavigate],\n );\n return (\n <div\n className=\"w6w-embed-root\"\n style={{ display: \"flex\", width: \"100%\", height: \"100%\", minHeight: 0 }}\n >\n <EditorShell\n project={project}\n onNavigate={railNavigate}\n rail={props.rail}\n storageKey={project === null ? null : `w6w.rail.embed.${project}`}\n >\n <EditorBody\n workflowId={workflowId}\n project={project}\n initialRunId={initialRunId}\n onNavigate={onNavigate}\n slots={slots}\n />\n </EditorShell>\n </div>\n );\n}\n"],"names":["EditableTitle","title","value","placeholder","maxLength","ariaLabel","onChange","onBlur","jsx","e","ExecutionProfileHeader","onBack","backLabel","titleAdornment","actions","jsxs","historyOpenRun","kind","onOpenRun","onClose","execution","HistoryModal","props","id","filters","setFilters","useState","EMPTY_HISTORY_FILTERS","onOpenInEditor","Modal","IconButton","HistoryView","HistoryButtonChrome","hasExecuted","onClick","buttonRef","HistoryButtonProbe","useHasExecutedQuery","open","setOpen","useRef","wasOpen","useEffect","_a","Fragment","HistoryProbeBoundary","Component","__publicField","error","HistoryButton","JsonToggleButton","JsonToggle","mode","onValidityChange","invalidReason","guard","onSave","saving","editorLabel","guardReason","JsonEditor","valid","err","EditorShell","project","onNavigate","rail","storageKey","tools","editorRailTools","children","enclosed","useHasWorkspace","body","RailEnvProvider","ProjectExpressionScope","RightRail","WorkspaceProvider","VARIABLE_TYPES","WorkflowSettingsModal","autoSave","savePosition","variables","onVariablesChange","inheritedVars","useExpressionOptions","tab","setTab","addVariable","updateVariable","i","next","v","idx","removeVariable","_","dupIndexes","duplicateKeyIndexes","t","ExpressionOptionsProvider","varsRailFor","ExpressionInput","ID_RE","TITLE_PLACEHOLDER","WorkflowFlowEditor","lazy","m","EditorBody","workflowId","initialRunId","slots","apiClient","useEmbedClient","api","useW6WApi","setValid","validityError","setValidityError","setError","showJson","setShowJson","showSettings","setShowSettings","reloading","setReloading","loadedKey","setLoadedKey","autoSaveRef","publishReasonRef","saveGuard","useCallback","def","d","workflowKeyEditAllowed","draft","useWorkflowDraft","json","parsed","canSave","dirty","staleDismissed","setStaleDismissed","saved","setSaved","wasSaving","activeRunId","setActiveRunId","startRunMut","useStartRunMutation","cancelRunMut","useCancelRunMutation","runQuery","useLiveRunQuery","runStatus","runPollFailed","runInFlight","isRunInFlight","runLogSteps","mapRunStateToLogSteps","_b","runLogErrors","runLevelErrors","runStartingRef","runStarting","setRunStarting","runAfterFlush","action","r","ApiError","onRunClick","input","resolveHeaderRunInput","triggerPreviewList","stepId","listStepTests","res","onStopClick","code","classifyCancelError","reloadFromServer","draftFailure","bannerError","flowUsable","displayName","settings","readSettings","useMemo","readVariables","keyEdit","keyGuardReason","steps","flowHelpers","setFlowHelpers","canceled","app","triggerPreviews","hasTrigger","triggerKeys","s","thirdPartyAppIds","ids","fetchedAppsById","useEditorApps","appsList","appActionsQueries","useQueries","appId","appActionsKey","actionParamsByKey","out","key","fetched","a","appsById","testGatedSteps","isTestRequired","stepTestsQueries","stepTestsKey","testStatus","versionsQuery","useVersionsQuery","publishMut","usePublishMutation","validityCtx","requiredParamsFilled","workflowIsValid","workflowValid","publishInvalidReason","patchMeta","patch","saveMeta","parsedRef","commitRef","saveNowRef","onKey","wfPolicy","policyFromDefinition","onPolicyChange","policy","current","definitionWithPolicy","useWorkspace","runButtonLabel","_c","_d","_e","runId","Suspense","ExecutionLogPanel","writeSetting","variablesForSave","NOOP","WorkflowEditor","useEditorProject","railNavigate","to"],"mappings":"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"}
|
package/dist/apps-1FNUwbGv.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { useQuery as s, keepPreviousData as p } from "@tanstack/react-query";
|
|
2
|
-
import { u } from "./client-context-CX61Bgw-.js";
|
|
3
|
-
import { H as l, h as y, m as o, i as a, E as q, j as d } from "./spec-import-CjmxyZDR.js";
|
|
4
|
-
const c = { project: "" };
|
|
5
|
-
function F(e, t, n = l) {
|
|
6
|
-
const i = u();
|
|
7
|
-
return s({
|
|
8
|
-
queryKey: o.list(e ?? c, t, n),
|
|
9
|
-
queryFn: () => a(i, e, t, n),
|
|
10
|
-
enabled: e !== null,
|
|
11
|
-
placeholderData: p
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
function Q(e, t) {
|
|
15
|
-
const n = u();
|
|
16
|
-
return s({
|
|
17
|
-
queryKey: o.stats(e ?? c, t),
|
|
18
|
-
queryFn: () => d(n, e, t),
|
|
19
|
-
enabled: e !== null
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
function S(e) {
|
|
23
|
-
var i, r;
|
|
24
|
-
const t = u(), n = s({
|
|
25
|
-
queryKey: o.exists(e),
|
|
26
|
-
queryFn: () => a(t, { callable: e }, q, 1)
|
|
27
|
-
});
|
|
28
|
-
return {
|
|
29
|
-
hasExecuted: (((r = (i = n.data) == null ? void 0 : i.executions) == null ? void 0 : r.length) ?? 0) > 0,
|
|
30
|
-
isLoading: n.isLoading
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function h(e) {
|
|
34
|
-
const t = u();
|
|
35
|
-
return s({
|
|
36
|
-
queryKey: o.detail((e == null ? void 0 : e.kind) ?? "function", (e == null ? void 0 : e.id) ?? ""),
|
|
37
|
-
queryFn: () => y(t, e),
|
|
38
|
-
enabled: e !== null
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
const f = (e) => ["app-actions", e];
|
|
42
|
-
function g(e, t) {
|
|
43
|
-
return e.console.apps.getActions(t);
|
|
44
|
-
}
|
|
45
|
-
function C(e, t = !0) {
|
|
46
|
-
const n = u();
|
|
47
|
-
return s({
|
|
48
|
-
queryKey: f(e),
|
|
49
|
-
queryFn: () => g(n, e),
|
|
50
|
-
enabled: t
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
const E = (e) => ["app", e];
|
|
54
|
-
function A(e, t) {
|
|
55
|
-
return e.console.apps.get(t);
|
|
56
|
-
}
|
|
57
|
-
function b(e, t = !0) {
|
|
58
|
-
const n = u();
|
|
59
|
-
return s({
|
|
60
|
-
queryKey: E(e ?? ""),
|
|
61
|
-
queryFn: () => A(n, e),
|
|
62
|
-
enabled: t
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
export {
|
|
66
|
-
f as a,
|
|
67
|
-
E as b,
|
|
68
|
-
g as c,
|
|
69
|
-
b as d,
|
|
70
|
-
h as e,
|
|
71
|
-
S as f,
|
|
72
|
-
A as g,
|
|
73
|
-
F as h,
|
|
74
|
-
Q as i,
|
|
75
|
-
C as u
|
|
76
|
-
};
|
|
77
|
-
//# sourceMappingURL=apps-1FNUwbGv.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apps-1FNUwbGv.js","sources":["../src/repos/history.ts","../src/repos/apps.ts"],"sourcesContent":["/**\n * The `history` domain repo (T2.3.1) — thin react-query hooks over\n * `lib/history-query.ts`'s pure fetchers, mirroring `./dashboard.ts`'s\n * shape exactly: the query keys ship from the pure module, not from here or\n * from a caller; every hook is `useEmbedClient()` + one `useQuery`.\n *\n * `lib/history-query.ts` carries every judgment call (URL⇄filter mapping,\n * request params, cache keys, fetchers, detail mapping) so it stays loadable\n * by `node --test`; this file adds nothing but React wiring on top of it.\n */\nimport { keepPreviousData, useQuery } from \"@tanstack/react-query\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n EMPTY_HISTORY_FILTERS,\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n getExecutionDetail,\n getHistory,\n getHistoryStats,\n historyKeys,\n} from \"../lib/history-query.ts\";\n\n/** A placeholder scope to key a disabled query by — never fetched, since\n * `enabled` gates on the real (possibly `null`) scope, matching\n * `repos/workflows.ts`'s `useLiveRunQuery(runId ?? \"\")` idiom. */\nconst NO_SCOPE: HistoryScope = { project: \"\" };\n\n/** The project-wide or per-callable execution list, one page at a time.\n * Disabled while `scope` is `null` (no project/callable selected yet).\n * `placeholderData: keepPreviousData` keeps the previous page's rows on\n * screen while a filter/page change is in flight, instead of flashing to\n * an empty list. */\nexport function useHistoryQuery(\n scope: HistoryScope | null,\n f: HistoryFilters,\n limit: number = HISTORY_PAGE_SIZE,\n) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.list(scope ?? NO_SCOPE, f, limit),\n queryFn: () => getHistory(apiClient, scope as HistoryScope, f, limit),\n enabled: scope !== null,\n placeholderData: keepPreviousData,\n });\n}\n\n/** The aggregate stats card above the list — same scope/filters, no paging.\n * Disabled while `scope` is `null`. */\nexport function useHistoryStatsQuery(scope: HistoryScope | null, f: HistoryFilters) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.stats(scope ?? NO_SCOPE, f),\n queryFn: () => getHistoryStats(apiClient, scope as HistoryScope, f),\n enabled: scope !== null,\n });\n}\n\n/** \"Has this callable ever been executed?\" — the cheap existence probe the\n * header's History button uses to decide its disabled state (one row,\n * every filter at its default). `hasExecuted` reads `false` while loading\n * or on error — never a false \"yes\". */\nexport function useHasExecutedQuery(callableId: string): {\n hasExecuted: boolean;\n isLoading: boolean;\n} {\n const apiClient = useEmbedClient();\n const query = useQuery({\n queryKey: historyKeys.exists(callableId),\n queryFn: () => getHistory(apiClient, { callable: callableId }, EMPTY_HISTORY_FILTERS, 1),\n });\n return {\n hasExecuted: (query.data?.executions?.length ?? 0) > 0,\n isLoading: query.isLoading,\n };\n}\n\n/** One execution's full detail, opened from a list row. Disabled while\n * `summary` is `null` (no row selected). */\nexport function useExecutionDetailQuery(summary: ExecutionSummary | null) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.detail(summary?.kind ?? \"function\", summary?.id ?? \"\"),\n queryFn: () => getExecutionDetail(apiClient, summary as ExecutionSummary),\n enabled: summary !== null,\n });\n}\n","/**\n * The per-app Actions repo — what the Target selector and the canvas's step pickers read.\n *\n * Moved from Studio's `repos/apps.ts` (B-3a); the Studio file re-exports these names. The client\n * comes from `useEmbedClient()`. `GET /apps/:id` through `client.console.apps.getActions` is the\n * same payload the W6WApi adapter serves the canvas, and the key is byte-identical to the one\n * the editor and `WorkflowsPage` compose by hand, so every reader shares one cache entry.\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { W6WClient } from \"@w6w/sdk\";\nimport type { ActionDef, AppDetail } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n\nexport const appActionsKey = (id: string) => [\"app-actions\", id] as const;\n\nexport function getAppActions(client: W6WClient, id: string): Promise<ActionDef[]> {\n return client.console.apps.getActions(id);\n}\n\n/** `enabled` defaults to `true`; a selector passes `app !== \"\"` so an empty app issues nothing. */\nexport function useAppActionsQuery(id: string, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appActionsKey(id),\n queryFn: () => getAppActions(client, id),\n enabled,\n });\n}\n\n// ── app (detail) ─────────────────────────────────────────────────────────\n\nexport const appKey = (id: string) => [\"app\", id] as const;\n\nexport function getApp(client: W6WClient, id: string): Promise<AppDetail> {\n return client.console.apps.get(id);\n}\n\n/**\n * `id` accepts `string | undefined`: a detail view's app id is `undefined` until its own\n * connection query resolves, so the caller passes `enabled` (its `!!id` guard) instead of\n * `!`-asserting.\n */\nexport function useAppQuery(id: string | undefined, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appKey(id ?? \"\"),\n queryFn: () => getApp(client, id as string),\n enabled,\n });\n}\n"],"names":["NO_SCOPE","useHistoryQuery","scope","f","limit","HISTORY_PAGE_SIZE","apiClient","useEmbedClient","useQuery","historyKeys","getHistory","keepPreviousData","useHistoryStatsQuery","getHistoryStats","useHasExecutedQuery","callableId","query","EMPTY_HISTORY_FILTERS","_b","_a","useExecutionDetailQuery","summary","getExecutionDetail","appActionsKey","id","getAppActions","client","useAppActionsQuery","enabled","appKey","getApp","useAppQuery"],"mappings":";;;AA2BA,MAAMA,IAAyB,EAAE,SAAS,GAAA;AAOnC,SAASC,EACdC,GACAC,GACAC,IAAgBC,GAChB;AACA,QAAMC,IAAYC,EAAA;AAClB,SAAOC,EAAS;AAAA,IACd,UAAUC,EAAY,KAAKP,KAASF,GAAUG,GAAGC,CAAK;AAAA,IACtD,SAAS,MAAMM,EAAWJ,GAAWJ,GAAuBC,GAAGC,CAAK;AAAA,IACpE,SAASF,MAAU;AAAA,IACnB,iBAAiBS;AAAA,EAAA,CAClB;AACH;AAIO,SAASC,EAAqBV,GAA4BC,GAAmB;AAClF,QAAMG,IAAYC,EAAA;AAClB,SAAOC,EAAS;AAAA,IACd,UAAUC,EAAY,MAAMP,KAASF,GAAUG,CAAC;AAAA,IAChD,SAAS,MAAMU,EAAgBP,GAAWJ,GAAuBC,CAAC;AAAA,IAClE,SAASD,MAAU;AAAA,EAAA,CACpB;AACH;AAMO,SAASY,EAAoBC,GAGlC;;AACA,QAAMT,IAAYC,EAAA,GACZS,IAAQR,EAAS;AAAA,IACrB,UAAUC,EAAY,OAAOM,CAAU;AAAA,IACvC,SAAS,MAAML,EAAWJ,GAAW,EAAE,UAAUS,EAAA,GAAcE,GAAuB,CAAC;AAAA,EAAA,CACxF;AACD,SAAO;AAAA,IACL,gBAAcC,KAAAC,IAAAH,EAAM,SAAN,gBAAAG,EAAY,eAAZ,gBAAAD,EAAwB,WAAU,KAAK;AAAA,IACrD,WAAWF,EAAM;AAAA,EAAA;AAErB;AAIO,SAASI,EAAwBC,GAAkC;AACxE,QAAMf,IAAYC,EAAA;AAClB,SAAOC,EAAS;AAAA,IACd,UAAUC,EAAY,QAAOY,KAAA,gBAAAA,EAAS,SAAQ,aAAYA,KAAA,gBAAAA,EAAS,OAAM,EAAE;AAAA,IAC3E,SAAS,MAAMC,EAAmBhB,GAAWe,CAA2B;AAAA,IACxE,SAASA,MAAY;AAAA,EAAA,CACtB;AACH;AC1EO,MAAME,IAAgB,CAACC,MAAe,CAAC,eAAeA,CAAE;AAExD,SAASC,EAAcC,GAAmBF,GAAkC;AACjF,SAAOE,EAAO,QAAQ,KAAK,WAAWF,CAAE;AAC1C;AAGO,SAASG,EAAmBH,GAAYI,IAAU,IAAM;AAC7D,QAAMF,IAASnB,EAAA;AACf,SAAOC,EAAS;AAAA,IACd,UAAUe,EAAcC,CAAE;AAAA,IAC1B,SAAS,MAAMC,EAAcC,GAAQF,CAAE;AAAA,IACvC,SAAAI;AAAA,EAAA,CACD;AACH;AAIO,MAAMC,IAAS,CAACL,MAAe,CAAC,OAAOA,CAAE;AAEzC,SAASM,EAAOJ,GAAmBF,GAAgC;AACxE,SAAOE,EAAO,QAAQ,KAAK,IAAIF,CAAE;AACnC;AAOO,SAASO,EAAYP,GAAwBI,IAAU,IAAM;AAClE,QAAMF,IAASnB,EAAA;AACf,SAAOC,EAAS;AAAA,IACd,UAAUqB,EAAOL,KAAM,EAAE;AAAA,IACzB,SAAS,MAAMM,EAAOJ,GAAQF,CAAY;AAAA,IAC1C,SAAAI;AAAA,EAAA,CACD;AACH;"}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
function y(n) {
|
|
2
|
-
return n.kind === "action" ? "" : n.kind === "endpoint" ? n.endpoint : n.kind === "function" ? n.function : n.workflow;
|
|
3
|
-
}
|
|
4
|
-
function q(n) {
|
|
5
|
-
return n.kind === "action" ? !!(n.uses.app && n.uses.action) : !!y(n);
|
|
6
|
-
}
|
|
7
|
-
function I(n) {
|
|
8
|
-
return n ? n.kind === "function" ? { kind: "function", function: n.function } : n.kind === "workflow" ? { kind: "workflow", workflow: n.workflow } : { kind: "action", uses: n.uses, with: n.with } : { kind: "action", uses: { app: "", action: "", connection: null }, with: {} };
|
|
9
|
-
}
|
|
10
|
-
function F(n) {
|
|
11
|
-
return n.kind === "action" ? { uses: n.uses, with: n.with ?? {} } : { ...n, with: {} };
|
|
12
|
-
}
|
|
13
|
-
function g(n) {
|
|
14
|
-
return n.map((e) => {
|
|
15
|
-
const t = {
|
|
16
|
-
key: e.key,
|
|
17
|
-
label: e.label ?? e.key,
|
|
18
|
-
type: e.type ?? "string",
|
|
19
|
-
required: e.required,
|
|
20
|
-
default: e.default
|
|
21
|
-
};
|
|
22
|
-
return e.showIf !== void 0 && (t.showIf = e.showIf), t;
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
function S(n, e) {
|
|
26
|
-
var u, s;
|
|
27
|
-
const t = Array.isArray(n == null ? void 0 : n.steps) ? n.steps : [], i = /* @__PURE__ */ new Set(), r = [];
|
|
28
|
-
for (const o of t) {
|
|
29
|
-
const c = (u = o == null ? void 0 : o.uses) == null ? void 0 : u.app;
|
|
30
|
-
if (typeof c != "string" || !e.isTriggerApp(c)) continue;
|
|
31
|
-
const p = e.asFieldDefs((s = o == null ? void 0 : o.with) == null ? void 0 : s.fields);
|
|
32
|
-
for (const d of p) {
|
|
33
|
-
const f = d.key;
|
|
34
|
-
typeof f != "string" || f.trim() === "" || i.has(f) || (i.add(f), r.push({ key: f, label: f, type: d.type ?? "string", required: d.required }));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return r;
|
|
38
|
-
}
|
|
39
|
-
const h = ["string", "text", "number", "boolean", "json", "secret"];
|
|
40
|
-
function T(n) {
|
|
41
|
-
return n.rows.length === 0 && !n.touched;
|
|
42
|
-
}
|
|
43
|
-
function k(n) {
|
|
44
|
-
return h.includes(n) ? n : "string";
|
|
45
|
-
}
|
|
46
|
-
function N(n, e) {
|
|
47
|
-
const t = new Set(n.map((r) => r.key)), i = [];
|
|
48
|
-
for (const r of e) {
|
|
49
|
-
const u = r.key;
|
|
50
|
-
typeof u != "string" || u.trim() === "" || t.has(u) || (t.add(u), i.push({
|
|
51
|
-
key: u,
|
|
52
|
-
label: r.label ?? u,
|
|
53
|
-
type: k(r.type),
|
|
54
|
-
required: !!r.required
|
|
55
|
-
}));
|
|
56
|
-
}
|
|
57
|
-
return i.length === 0 ? n : [...n, ...i];
|
|
58
|
-
}
|
|
59
|
-
function m(n, e) {
|
|
60
|
-
const t = n.showIf;
|
|
61
|
-
if (!t) return !0;
|
|
62
|
-
const i = e(t.field);
|
|
63
|
-
return t.equals !== void 0 ? i === t.equals : t.in ? t.in.some((r) => r === i) : t.notIn ? !t.notIn.some((r) => r === i) : t.truthy !== void 0 ? t.truthy ? !!i : !i : !0;
|
|
64
|
-
}
|
|
65
|
-
function b(n) {
|
|
66
|
-
return n == null ? !1 : typeof n == "string" ? n.trim() !== "" : !0;
|
|
67
|
-
}
|
|
68
|
-
function a(n, e, t) {
|
|
69
|
-
const i = new Set(n.map((s) => s.key)), r = (s) => {
|
|
70
|
-
var o;
|
|
71
|
-
return (t == null ? void 0 : t[s]) !== void 0 ? t[s] : (o = e.find((c) => c.key === s)) == null ? void 0 : o.default;
|
|
72
|
-
}, u = [];
|
|
73
|
-
for (const s of e) {
|
|
74
|
-
if (!s.required) continue;
|
|
75
|
-
const o = s.key;
|
|
76
|
-
typeof o != "string" || o.trim() === "" || i.has(o) || u.includes(o) || m(s, r) && (b(s.default) || u.push(o));
|
|
77
|
-
}
|
|
78
|
-
return u;
|
|
79
|
-
}
|
|
80
|
-
function j(n, e) {
|
|
81
|
-
if (!(e.emptyMeansPassthrough && n.length === 0))
|
|
82
|
-
return n;
|
|
83
|
-
}
|
|
84
|
-
function w(n) {
|
|
85
|
-
return n == null ? !1 : typeof n == "string" ? n.trim() !== "" : typeof n == "object" && "type" in n && n.type === "expr" ? !0 : typeof n == "object";
|
|
86
|
-
}
|
|
87
|
-
function l(n) {
|
|
88
|
-
const e = [];
|
|
89
|
-
for (const t of Object.keys(n))
|
|
90
|
-
w(n[t]) && e.push({ key: t, label: t, type: "string" });
|
|
91
|
-
return e;
|
|
92
|
-
}
|
|
93
|
-
function v(n) {
|
|
94
|
-
const { target: e, rows: t, fields: i } = n;
|
|
95
|
-
return e.kind === "action" ? e.with === void 0 ? [] : a(l(e.with), i, e.with) : t.length === 0 ? [] : a(t, i);
|
|
96
|
-
}
|
|
97
|
-
function A(n) {
|
|
98
|
-
return n.impl ? a(
|
|
99
|
-
l(n.impl.with ?? {}),
|
|
100
|
-
n.fields,
|
|
101
|
-
n.impl.with ?? {}
|
|
102
|
-
) : n.fields.filter((e) => e.required).map((e) => e.key);
|
|
103
|
-
}
|
|
104
|
-
function B(n, e) {
|
|
105
|
-
if (e !== "")
|
|
106
|
-
switch (n) {
|
|
107
|
-
case "number": {
|
|
108
|
-
const t = Number(e);
|
|
109
|
-
return Number.isNaN(t) ? e : t;
|
|
110
|
-
}
|
|
111
|
-
case "boolean":
|
|
112
|
-
return e === "true";
|
|
113
|
-
case "json":
|
|
114
|
-
try {
|
|
115
|
-
return JSON.parse(e);
|
|
116
|
-
} catch {
|
|
117
|
-
return e;
|
|
118
|
-
}
|
|
119
|
-
default:
|
|
120
|
-
return e;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
export {
|
|
124
|
-
h as I,
|
|
125
|
-
j as a,
|
|
126
|
-
y as b,
|
|
127
|
-
B as c,
|
|
128
|
-
F as d,
|
|
129
|
-
A as e,
|
|
130
|
-
S as f,
|
|
131
|
-
a as g,
|
|
132
|
-
I as i,
|
|
133
|
-
N as m,
|
|
134
|
-
g as p,
|
|
135
|
-
T as s,
|
|
136
|
-
q as t,
|
|
137
|
-
v as u
|
|
138
|
-
};
|
|
139
|
-
//# sourceMappingURL=coerce-input-BicYr7nc.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"coerce-input-BicYr7nc.js","sources":["../src/lib/target-fields.ts","../src/lib/input-seeding.ts","../src/lib/input-coverage.ts","../src/lib/coerce-input.ts"],"sourcesContent":["/**\n * Pure helpers shared by `TargetSelector`'s three arms (rfcs/endpoint.md\n * :339-347 — `EndpointTarget = CallableRef | ActionTarget`) and by\n * `EndpointsPage`'s save gate.\n *\n * Pure and testable by design, mirroring `workflow-validity.ts`'s shape:\n * `@w6w/ui`'s `package.json` `exports[\".\"]` resolves to raw `./src/index.ts`,\n * which re-exports `.tsx` files, so `node --test` throws\n * `ERR_UNKNOWN_FILE_EXTENSION` the moment anything here imports `@w6w/ui` or\n * `@w6w/ui/flow` — even type-only. So this module declares its own local\n * structural (`*Like`) types instead of importing the real ones from\n * `../api/types.ts`, and `isTriggerApp`/`asFieldDefs` (the workflow arm's only\n * dependency on `@w6w/ui/flow`) are **caller-injected** — `TargetSelector.tsx`\n * (unaffected by the JSX constraint) imports the real ones and passes them in.\n */\n\n/** The four arms `EndpointTarget` can take; a Function's `impl` takes the\n * first three (D-8) — `\"endpoint\"` is alias-only, never legal for `Fn.impl`. */\nexport type TargetKind = \"action\" | \"function\" | \"workflow\" | \"endpoint\";\n\n/** The `action` arm — same `{ uses, with }` shape a Function's `impl` carries. */\nexport interface ActionTargetLike {\n kind: \"action\";\n uses: { app: string; action: string; connection?: string | null };\n with?: Record<string, unknown>;\n}\n\n/** The `function`/`workflow` arms — a bare ref, one hop to a CallableRef. */\nexport type CallableTargetLike =\n | { kind: \"function\"; function: string }\n | { kind: \"workflow\"; workflow: string };\n\n/** The `endpoint` arm — a bare ref to another Endpoint. Alias-only (plan.md\n * §2a): legal for `AliasDef.target`, never for an Endpoint's own `target`\n * (the server refuses it — `admin/endpoints.ts`'s `validateDefinition`). */\nexport interface EndpointRefTargetLike {\n kind: \"endpoint\";\n endpoint: string;\n}\n\n/** The full local mirror of `EndpointTarget` this module operates on. */\nexport type TargetLike = ActionTargetLike | CallableTargetLike | EndpointRefTargetLike;\n\n/**\n * The action arm of a Function's `impl` — today's `FunctionImplLike` shape,\n * plus the two fields D-8 adds: `kind?: \"action\"` (absent means \"action\",\n * unchanged for every Function stored before the union existed) and\n * `outputMap?` (mirrors the action arm's own adapter-out pass, already on\n * `FnActionImpl`/`FunctionActionImpl`).\n */\nexport interface ActionImplLike {\n kind?: \"action\";\n uses: { app: string; action: string; connection?: string | null };\n with?: Record<string, unknown>;\n outputMap?: Record<string, unknown>;\n}\n\n/**\n * A Function's `impl` (D-8, `rfcs/function.md` as amended by TC2) — bound to\n * one app Action, or to another Function/Workflow via `CallableTargetLike`\n * (reused verbatim, never a fourth local mirror), intersected with the same\n * `with`/`outputMap` adapter pair the action arm carries — field-for-field\n * `FnCallableImpl = CallableRef & {with?; outputMap?}` (TC2's pinned type).\n */\nexport type FunctionImplLike =\n | ActionImplLike\n | (CallableTargetLike & { with?: Record<string, unknown>; outputMap?: Record<string, unknown> });\n\n/** A declared action/function param, just enough of it for the projector. */\nexport interface ParamLike {\n key: string;\n label?: string;\n type?: string;\n required?: boolean;\n default?: unknown;\n showIf?: ShowIfPredicate;\n}\n\n/** Visibility predicate — mirroring ActionParam.showIf from @w6w/ui. */\nexport interface ShowIfPredicate {\n field: string;\n equals?: unknown;\n in?: unknown[];\n notIn?: unknown[];\n truthy?: boolean;\n}\n\n/** One field of a manual/webhook trigger's `with.fields` (`@w6w/ui/flow`'s `TriggerFieldDef`). */\nexport interface TriggerFieldDefLike {\n key?: string;\n type?: string;\n default?: unknown;\n required?: boolean;\n}\n\n/** A workflow graph step, just enough of it for the trigger-field union (A6). */\nexport interface WorkflowStepLike {\n uses?: { app?: string };\n with?: Record<string, unknown>;\n}\n\n/** A workflow definition, just enough of it for the trigger-field union. */\nexport interface WorkflowLike {\n steps?: unknown;\n}\n\n/** Everything `fieldsFromWorkflow` needs from `@w6w/ui/flow` but cannot import itself. */\nexport interface WorkflowFieldCtx {\n /** `@w6w/ui/flow`'s `isTriggerApp`, injected by the JSX caller. */\n isTriggerApp: (app: string) => boolean;\n /** `@w6w/ui/flow`'s `asFieldDefs`, injected by the JSX caller. */\n asFieldDefs: (fields: unknown) => TriggerFieldDefLike[];\n}\n\n/** One field of the normalized list `TargetSelector` resolves to (A5). */\nexport interface TargetField {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n default?: unknown;\n showIf?: ShowIfPredicate;\n}\n\n/** One row of an input-contract list (`FunctionInput`/`EndpointInput`'s common shape). */\nexport interface InputRowLike {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n}\n\n/** The concrete ref (`fn_…` / `wf_…` / `ep_…`) a CallableRef/endpoint target\n * currently points at, `\"\"` for `action`. */\nexport function targetRef(target: TargetLike): string {\n if (target.kind === \"action\") return \"\";\n if (target.kind === \"endpoint\") return target.endpoint;\n return target.kind === \"function\" ? target.function : target.workflow;\n}\n\n/** Is the target fully chosen? An action needs both halves of its `uses` pair (A9). */\nexport function targetIsBound(target: TargetLike): boolean {\n if (target.kind === \"action\") return Boolean(target.uses.app && target.uses.action);\n return Boolean(targetRef(target));\n}\n\n/**\n * Adapt a Function's `impl` into the shape `TargetSelector` consumes (D-8):\n * an action impl to the `action` arm exactly as before; a CallableRef impl maps\n * its `kind`/`function`|`workflow` across UNCHANGED — deliberately dropping\n * `with`/`outputMap`, which `TargetLike`'s CallableRef arm has no slot for (they\n * survive on `draft.impl` itself; `targetToImpl` restores a default `with` on\n * the way back, so `implToTarget(targetToImpl(x))` round-trips `x`). An\n * absent impl still yields the empty action target.\n */\nexport function implToTarget(\n impl: FunctionImplLike | undefined,\n): ActionTargetLike | CallableTargetLike {\n // Draft functions have no impl yet; return an empty target\n if (!impl) {\n return { kind: \"action\", uses: { app: \"\", action: \"\", connection: null }, with: {} };\n }\n if (impl.kind === \"function\") return { kind: \"function\", function: impl.function };\n if (impl.kind === \"workflow\") return { kind: \"workflow\", workflow: impl.workflow };\n return { kind: \"action\", uses: impl.uses, with: impl.with };\n}\n\n/**\n * Inverse of {@link implToTarget}, over the widened D-8 domain. Never yields\n * `with: undefined` on EITHER arm — A10: `invoke-function.ts`'s\n * `resolveWith(impl.with, …)` call is unconditional and shared by both arms\n * (the CallableRef arm has its own `with` adapter pass onto the callee's inputs,\n * unlike `uncoveredForEndpoint`'s P3), so an unmapped `with` must still be\n * `{}`, not absent, on a CallableRef impl too.\n */\nexport function targetToImpl(target: ActionTargetLike | CallableTargetLike): FunctionImplLike {\n if (target.kind === \"action\") {\n return { uses: target.uses, with: target.with ?? {} };\n }\n return { ...target, with: {} };\n}\n\n/** Project a list of action/function params into the normalized `TargetField[]` (A5). */\nexport function paramsToFields(params: ParamLike[]): TargetField[] {\n return params.map((p) => {\n const field: TargetField = {\n key: p.key,\n label: p.label ?? p.key,\n type: p.type ?? \"string\",\n required: p.required,\n default: p.default,\n };\n if (p.showIf !== undefined) {\n field.showIf = p.showIf;\n }\n return field;\n });\n}\n\n/**\n * A6: project every manual/webhook-trigger step's `with.fields` from a raw\n * workflow graph into the union of `TargetField`s, keyed by `key`, first\n * occurrence wins, order stable (planner D-2: the server broadcasts one\n * `input` object to every trigger identically). A webhook/scheduler step that\n * declares `methods`/`auth` but no `fields` contributes nothing — by reading\n * `with.fields`, not a special case. Unnamed/blank keys are skipped. `default`\n * is not carried for this arm (A5). A missing/garbage graph, or one whose\n * `isTriggerApp` predicate matches nothing, yields `[]` — never a throw.\n */\nexport function fieldsFromWorkflow(\n workflow: WorkflowLike | null | undefined,\n ctx: WorkflowFieldCtx,\n): TargetField[] {\n const steps = Array.isArray(workflow?.steps) ? (workflow.steps as WorkflowStepLike[]) : [];\n const seen = new Set<string>();\n const out: TargetField[] = [];\n for (const step of steps) {\n const app = step?.uses?.app;\n if (typeof app !== \"string\" || !ctx.isTriggerApp(app)) continue;\n const defs = ctx.asFieldDefs(step?.with?.fields);\n for (const def of defs) {\n const key = def.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || seen.has(key)) continue;\n seen.add(key);\n out.push({ key, label: key, type: def.type ?? \"string\", required: def.required });\n }\n }\n return out;\n}\n","/**\n * The seeding/coverage logic behind the shared `InputListEditor` (T3.2.1):\n * filling a Function/Endpoint's declared input list from the picked target's\n * resolved fields (`TargetSelector`'s A5/A7, `target-fields.ts`), and\n * flagging what a later target change no longer covers.\n *\n * **The policy (HITL-1, pinned).** Seed only when the input list is empty\n * AND the user has not touched it; once touched (any add/update/remove via\n * the row editor), a later target change never rewrites the list — it only\n * flags the required keys the new target no longer covers. This is the only\n * policy that cannot destroy typed work, and the flag is what T3.2.2's save\n * gate consumes.\n *\n * **Supersedes `target-fields.ts`'s `seedRowsFromFields`** — T3.1.1's\n * declared v1 stopgap (seed-a-wholly-empty-list-once, no touched/merge\n * concept). That symbol is deleted from `target-fields.ts`, not duplicated;\n * this module is its one home.\n *\n * **The pass-through guard** (the finding most likely to cause a silent\n * regression): the server dispatches an Endpoint's `action` arm on\n * `target.with === undefined` (`invoke-endpoint.ts:136-143`) — `{}` is\n * truthy, so an empty `with` does NOT pass through. `EndpointDef.input` (the\n * declared list this module seeds) is a SEPARATE field the server never\n * reads for dispatch at all, but the round-trip must still agree:\n * {@link inputsForSave} returns `undefined` (never `[]`) for an empty,\n * pass-through-mode list, so a previously authored pass-through Endpoint\n * opens and re-saves unchanged. A Function has no pass-through mode —\n * `emptyMeansPassthrough: false` never returns `undefined`, matching\n * `FunctionDef.inputs`'s non-nullable wire type (`draft.inputs.map` would\n * throw on `undefined`).\n *\n * Pure, React-free, `.ts`, no value import of `@w6w/ui` — mirrors\n * `workflow-validity.ts`/`target-fields.ts`'s shape so `node --test` can\n * load it directly (`@w6w/ui`'s barrel re-exports `.tsx`, which Node's\n * type-stripping cannot parse). `INPUT_TYPES` lives here rather than in\n * `InputListEditor.tsx` because this module's own seeding logic needs it.\n */\n\nimport type { TargetField } from \"./target-fields.ts\";\n\n/** The input-row types the two builders offer (`ActionParam`'s subset). */\nexport const INPUT_TYPES = [\"string\", \"text\", \"number\", \"boolean\", \"json\", \"secret\"] as const;\n\n/**\n * One row of an input-contract list — `FunctionInput`/`EndpointInput`'s\n * common shape (`../api/types.ts`), mirrored locally so this pure module\n * never imports a value from a `.tsx`-reexporting barrel. Structurally\n * identical to both wire types, so a page's `draft.inputs`/`draft.input`\n * needs no cast at the `InputListEditor` boundary in either direction.\n */\nexport interface InputRow {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n default?: unknown;\n hint?: string;\n}\n\n/**\n * Is there a wholly empty, still-untouched list to seed? Any manual edit —\n * add, update or remove, via the row editor's own `onChange` — makes the\n * list the user's forever after (HITL-1); the seeding effect itself must\n * never be what sets `touched`.\n */\nexport function shouldSeed(args: { rows: InputRow[]; touched: boolean }): boolean {\n return args.rows.length === 0 && !args.touched;\n}\n\n/**\n * `type` is the field's own type when {@link INPUT_TYPES} declares it,\n * otherwise `\"string\"` — an unlisted type (`section`, `select`, …) would\n * otherwise render a `<select>` with no matching `<option>` and silently\n * change the value.\n */\nfunction normalizeType(type: string): string {\n return (INPUT_TYPES as readonly string[]).includes(type) ? type : \"string\";\n}\n\n/**\n * `rows` plus one appended row per `fields` key not already present, in\n * field order. **Never modifies or removes an existing row, never\n * re-orders.** A seeded row is\n * `{ key, label: field.label ?? field.key, type, required: Boolean(field.required) }`\n * and nothing else — `default`/`hint` are deliberately not copied, because\n * the row editor cannot show or remove them and they would become invisible\n * state on the saved definition. Fields with a missing/blank key are\n * skipped; a duplicate key (in `fields`, or already present in `rows`)\n * seeds once.\n */\nexport function mergeSeed(rows: InputRow[], fields: TargetField[]): InputRow[] {\n const seen = new Set(rows.map((r) => r.key));\n const appended: InputRow[] = [];\n for (const field of fields) {\n const key = field.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || seen.has(key)) continue;\n seen.add(key);\n appended.push({\n key,\n label: field.label ?? key,\n type: normalizeType(field.type),\n required: Boolean(field.required),\n });\n }\n return appended.length === 0 ? rows : [...rows, ...appended];\n}\n\n/**\n * Is `field` visible under the given effective-value lookup?\n * Implements `packages/ui/src/ParamsForm.tsx:20-29`'s `isParamVisible`\n * predicate, honouring all four arms (`equals`, `in`, `notIn`, `truthy`).\n */\nfunction isFieldVisible(field: TargetField, effective: (key: string) => unknown): boolean {\n const c = field.showIf;\n if (!c) return true;\n const v = effective(c.field);\n if (c.equals !== undefined) return v === c.equals;\n if (c.in) return c.in.some((x) => x === v);\n if (c.notIn) return !c.notIn.some((x) => x === v);\n if (c.truthy !== undefined) return c.truthy ? !!v : !v;\n return true;\n}\n\n/**\n * Does `default` satisfy \"usable\"? A usable default can stand in for an\n * explicitly mapped value — `false` and `0` are usable, `undefined`/`null`\n * and whitespace-only strings are not.\n * Implements the `v === undefined || v === null` / `v.trim() !== \"\"`\n * rejection from `packages/ui/src/StepBuilderModal.tsx:706-707`.\n */\nfunction hasUsableDefault(d: unknown): boolean {\n if (d === undefined || d === null) return false;\n if (typeof d === \"string\") return d.trim() !== \"\";\n return true;\n}\n\n/**\n * The required field keys `fields` declares that no row in `rows` covers,\n * in field order — what a target change leaves for the operator to notice\n * once the list is the user's (HITL-1) and can no longer be auto-filled.\n * Informational here: T3.2.2's save gate is what turns this into a block,\n * and imports this same predicate rather than forking a second copy of it.\n *\n * Skips a required field that is currently hidden by its own `showIf` or\n * that declares a usable `default` — mirroring\n * `packages/ui/src/StepBuilderModal.tsx:686-711`'s `requiredParamsFilled`.\n * `values` is the `with` mapping; omitting it leaves existing callers'\n * behaviour unchanged apart from the two new skips.\n */\nexport function uncoveredRequiredKeys(\n rows: InputRow[],\n fields: TargetField[],\n values?: Record<string, unknown>,\n): string[] {\n const covered = new Set(rows.map((r) => r.key));\n const effective = (key: string) =>\n values?.[key] !== undefined ? values[key] : fields.find((f) => f.key === key)?.default;\n const out: string[] = [];\n for (const field of fields) {\n if (!field.required) continue;\n const key = field.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || covered.has(key) || out.includes(key)) {\n continue;\n }\n if (!isFieldVisible(field, effective)) continue;\n if (hasUsableDefault(field.default)) continue;\n out.push(key);\n }\n return out;\n}\n\n/**\n * The write-back both pages route their input list through (see the module\n * docstring's pass-through guard). The overloads let a call site that\n * passes the literal `emptyMeansPassthrough: false` (every Function save)\n * keep a non-nullable return type at compile time, matching\n * `FunctionDef.inputs`'s wire shape without a cast.\n */\nexport function inputsForSave(rows: InputRow[], opts: { emptyMeansPassthrough: false }): InputRow[];\nexport function inputsForSave(\n rows: InputRow[],\n opts: { emptyMeansPassthrough: boolean },\n): InputRow[] | undefined;\nexport function inputsForSave(\n rows: InputRow[],\n opts: { emptyMeansPassthrough: boolean },\n): InputRow[] | undefined {\n if (opts.emptyMeansPassthrough && rows.length === 0) return undefined;\n return rows;\n}\n","/**\n * The **save gate**'s arm dispatch (T3.2.2): given a picked target, decide\n * *which* key set counts as \"feeding\" its required fields — and when the\n * question does not apply at all — then hand the actual set difference to\n * {@link uncoveredRequiredKeys}.\n *\n * **This module deliberately owns no coverage rule of its own.**\n * `uncoveredRequiredKeys` lives in `./input-seeding.ts` because T3.2.1's\n * `InputListEditor` *renders* the uncovered-required flag from it. Two copies\n * of one coverage rule would drift, and the user would see a flag with no\n * block or a block with no flag. Everything below is dispatch: pick the\n * covered set, or skip.\n *\n * ## The five cases, each anchored to the line that decides it at runtime\n *\n * | # | case | gate |\n * |---|---|---|\n * | P1 | Endpoint, `action` arm, `target.with === undefined` | **skipped** — pass-through |\n * | P2 | Endpoint, `action` arm, `target.with` is an object (**incl. `{}`**) | required params must be non-blank cells of `with` |\n * | P3 | Endpoint, `function`/`workflow` arm, declared `input` list empty | **skipped** — no `with` mechanism exists on these arms |\n * | P4 | Endpoint, `function`/`workflow` arm, declared list non-empty | required target keys must appear as declared row keys |\n * | P5 | **Function**, always | required params must be non-blank cells of `impl.with` |\n *\n * P1 is `=== undefined` **only**. `bll/invoke-endpoint.ts:136-143` dispatches\n * `target.with ? resolveWith(…) : input.input`, and `{}` is truthy — so an\n * empty object does **not** pass through, and treating it as if it did would\n * ship exactly the unfed-required-field bug this gate exists to block. The\n * consequence, stated rather than fixed: `EndpointsPage`'s picker writes\n * `with: built.with ?? {}`, so an action-arm **pass-through Endpoint can no\n * longer be authored through the UI at all** — it can only be opened and\n * re-saved. That was already true server-side before this gate existed\n * (`FOLLOWUPS.md`).\n *\n * P1/P2 key on `target.with` and **never** on the declared list. That matters\n * because T3.2.1 made a deliberately emptied Endpoint list save `input`\n * *absent* rather than `[]` — so \"emptied\" and \"never declared\" are\n * indistinguishable on the wire, and a gate that read pass-through off the\n * list's emptiness would misread one for the other. P3's skip is justified by\n * the *absence of a `with` mechanism* on the callable arms, where the payload\n * always passes through by key identity, not by the list being empty.\n *\n * P5 has no skip: `bll/invoke-function.ts:101-107` calls\n * `resolveWith(impl.with, …)` unconditionally, so a Function has no\n * pass-through mode. With **no action chosen** the field list is empty and\n * coverage is vacuously satisfied, which is what preserves the deliberate\n * save-gate asymmetry — `FunctionsPage` stays saveable incomplete (its\n * `valid`/incomplete badge is the signal), while `EndpointsPage` keeps its\n * separate `targetIsBound` term.\n *\n * ## Known limitation — this gate is CLIENT-SIDE ONLY\n *\n * A determined API caller can still `POST /functions` or `POST /endpoints`\n * with a malformed definition. Both server `validateDefinition`s are\n * structural only (`api/functions.ts:26-37` checks the *types* of\n * `impl.uses.app`/`action`; `api/endpoints.ts:109-154` checks `target.kind`\n * plus its ref/uses fields and the `exposure.security` shape) — neither\n * invokes anything nor looks at coverage, so a dangling ref or an unmapped\n * required param stores fine and fails only at invoke time. Closing that is a\n * server-side write, a boundary expansion out of scope for this node; it is\n * stated here rather than papered over.\n *\n * Pure, React-free, `.ts`, no import of `@w6w/ui` — directly or transitively.\n * `./target-fields.ts`, `./input-seeding.ts` and `./with-mapping.ts` are all\n * `@w6w/ui`-free by the same design (`workflow-validity.ts`'s header explains\n * the wall: the barrel re-exports `.tsx`, which `node --test` cannot parse).\n * The normalized field list therefore arrives as a plain array parameter,\n * resolved by the caller — `TargetSelector`'s `onResolved` — exactly as\n * `workflow-validity.ts:69`'s injected `ValidityContext` does.\n */\n\nimport { type InputRow, uncoveredRequiredKeys } from \"./input-seeding.ts\";\nimport type { FunctionImplLike, TargetField, TargetLike } from \"./target-fields.ts\";\n\n/**\n * Check if a `with` mapping value is considered \"fed\" (non-empty).\n * A cell is \"fed\" when it contains a non-empty value:\n * - ExprValue objects are always considered fed (they have meaningful content)\n * - Strings are fed if non-blank after trimming\n * - Everything else (null, undefined, empty string) is not fed\n */\nfunction isFedValue(v: unknown): boolean {\n if (v == null) return false;\n if (typeof v === \"string\") return v.trim() !== \"\";\n if (typeof v === \"object\" && \"type\" in v && v.type === \"expr\") return true;\n // Legacy `{ \"$\": path }` format or any other object is considered fed\n return typeof v === \"object\";\n}\n\n/**\n * The mapping cells that actually feed something, shaped as the covered rows\n * {@link uncoveredRequiredKeys} diffs against. A cell is \"fed\" when it\n * contains a non-empty value — a whitespace-only literal maps nothing, and\n * `updateWith` deletes a cleared key outright.\n */\nfunction coveredRowsFromWith(withBlock: Record<string, unknown>): InputRow[] {\n const rows: InputRow[] = [];\n for (const key of Object.keys(withBlock)) {\n if (!isFedValue(withBlock[key])) continue;\n rows.push({ key, label: key, type: \"string\" });\n }\n return rows;\n}\n\n/**\n * The required target-field keys an Endpoint does **not** feed — P1–P4 above.\n * Empty means saveable as far as coverage is concerned; `EndpointsPage`'s own\n * `targetIsBound`/`key` terms are separate and survive unchanged.\n *\n * `fields` is the target's normalized field list as `TargetSelector` resolved\n * it. While a target's detail is still loading it is `[]`, so the gate is\n * vacuous until the fields arrive — this fails **open**, deliberately: an\n * unresolvable target (a deleted app, a failed fetch) must never trap an\n * author in a form they cannot save.\n */\nexport function uncoveredForEndpoint(args: {\n target: TargetLike;\n rows: InputRow[];\n fields: TargetField[];\n}): string[] {\n const { target, rows, fields } = args;\n if (target.kind === \"action\") {\n if (target.with === undefined) return []; // P1 — pass-through, nothing to check\n return uncoveredRequiredKeys(coveredRowsFromWith(target.with), fields, target.with); // P2\n }\n if (rows.length === 0) return []; // P3 — the callable arms have no `with` mechanism\n return uncoveredRequiredKeys(rows, fields); // P4 — key-name identity\n}\n\n/**\n * The required action-param keys a Function's `impl.with` does not map — P5.\n * No skip arm: a Function has no pass-through mode. An unbound Function\n * resolves to an empty `fields`, so this returns `[]` and the Functions save\n * gate keeps allowing a deliberately incomplete save.\n */\nexport function uncoveredForFunction(args: {\n impl: FunctionImplLike | undefined;\n fields: TargetField[];\n}): string[] {\n // Draft functions have no impl yet; no fields are covered\n if (!args.impl) {\n return args.fields.filter((f) => f.required).map((f) => f.key);\n }\n return uncoveredRequiredKeys(\n coveredRowsFromWith(args.impl.with ?? {}),\n args.fields,\n args.impl.with ?? {},\n );\n}\n","/**\n * Coerce a text field's value to the canonical input's declared type, for a callable's test-invoke\n * form. Empty ⇒ undefined (the field is omitted from the payload). Unparseable `number`/`json` text\n * is passed through raw, so the server's own validation names the problem.\n */\nexport function coerceInput(type: string, raw: string): unknown {\n if (raw === \"\") return undefined;\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case \"boolean\":\n return raw === \"true\";\n case \"json\":\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n default:\n return raw;\n }\n}\n"],"names":["targetRef","target","targetIsBound","implToTarget","impl","targetToImpl","paramsToFields","params","p","field","fieldsFromWorkflow","workflow","ctx","_a","_b","steps","seen","out","step","app","defs","def","key","INPUT_TYPES","shouldSeed","args","normalizeType","type","mergeSeed","rows","fields","appended","isFieldVisible","effective","c","v","x","hasUsableDefault","d","uncoveredRequiredKeys","values","covered","r","f","inputsForSave","opts","isFedValue","coveredRowsFromWith","withBlock","uncoveredForEndpoint","uncoveredForFunction","coerceInput","raw","n"],"mappings":"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"}
|