@w6w/embed 0.2.1 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConfirmModal-RLbZT5_k.js → ConfirmModal-BE-SdX-O.js} +53 -49
- package/dist/{ConfirmModal-RLbZT5_k.js.map → ConfirmModal-BE-SdX-O.js.map} +1 -1
- package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-D6CQLpa_.js} +25 -25
- package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-D6CQLpa_.js.map} +1 -1
- package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-YauVdolr.js} +5 -5
- package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-YauVdolr.js.map} +1 -1
- package/dist/{ImportSpecModal-BDQIf6rg.js → ImportSpecModal-B7qd1Km2.js} +3 -3
- package/dist/{ImportSpecModal-BDQIf6rg.js.map → ImportSpecModal-B7qd1Km2.js.map} +1 -1
- package/dist/ModelRoutesManager-BGESQahw.js +345 -0
- package/dist/ModelRoutesManager-BGESQahw.js.map +1 -0
- package/dist/WorkflowEditor-CwvmAGp2.js +925 -0
- package/dist/WorkflowEditor-CwvmAGp2.js.map +1 -0
- package/dist/{apps-1FNUwbGv.js → apps-CboASBKr.js} +14 -14
- package/dist/{apps-1FNUwbGv.js.map → apps-CboASBKr.js.map} +1 -1
- 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/workspace.d.ts +4 -0
- package/dist/{coerce-input-BicYr7nc.js → coerce-input-DttlcSdO.js} +70 -58
- package/dist/coerce-input-DttlcSdO.js.map +1 -0
- package/dist/connections-D7cgXhDS.js +119 -0
- package/dist/connections-D7cgXhDS.js.map +1 -0
- package/dist/credentials-DaQU3Ca_.js +171 -0
- package/dist/credentials-DaQU3Ca_.js.map +1 -0
- package/dist/document-sources-UCwe8x77.js +91 -0
- package/dist/document-sources-UCwe8x77.js.map +1 -0
- package/dist/draft.mjs +1 -1
- 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/TargetSelector.d.ts +15 -0
- package/dist/editor/TargetSelector.types.d.ts +2 -0
- package/dist/editor/definition.d.ts +2 -0
- package/dist/{editor-apps-BdenSV1o.js → editor-apps-BUZWld-m.js} +5 -5
- package/dist/{editor-apps-BdenSV1o.js.map → editor-apps-BUZWld-m.js.map} +1 -1
- package/dist/{editor-tools-RxmY5iyi.js → editor-tools-B_Lfx3kw.js} +11 -11
- package/dist/editor-tools-B_Lfx3kw.js.map +1 -0
- package/dist/editor.mjs +1 -1
- package/dist/editors.mjs +768 -621
- 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/index.mjs +119 -112
- package/dist/index.mjs.map +1 -1
- package/dist/lib/binding-problems.d.ts +38 -0
- package/dist/lib/code-rail.d.ts +4 -2
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/invoke-error.d.ts +1 -0
- package/dist/lib/sdk-snippets.d.ts +1 -1
- package/dist/lib/target-fields.d.ts +8 -0
- package/dist/lib/trigger-preview.d.ts +1 -0
- package/dist/lib/workflow-live-run.d.ts +9 -2
- package/dist/lib/workflow-nodes.d.ts +5 -0
- package/dist/lib/workflow-validity.d.ts +1 -0
- package/dist/lib.mjs +72 -70
- 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/ModelCatalog.d.ts +12 -0
- package/dist/lists/ModelUsage.d.ts +12 -0
- package/dist/lists.d.ts +8 -0
- package/dist/lists.mjs +1322 -604
- 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.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/credentials.d.ts +83 -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/index.d.ts +5 -0
- package/dist/repos/models.d.ts +289 -0
- package/dist/repos.mjs +613 -176
- package/dist/repos.mjs.map +1 -1
- 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-CBbloO_n.js} +7 -7
- package/dist/{spec-export-Cf3VQSQS.js.map → spec-export-CBbloO_n.js.map} +1 -1
- package/dist/{spec-import-CjmxyZDR.js → spec-import-CW6R_Wk1.js} +160 -156
- package/dist/spec-import-CW6R_Wk1.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/trigger-preview-DKxfjzUY.js +145 -0
- package/dist/trigger-preview-DKxfjzUY.js.map +1 -0
- package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DsALnSfF.js} +22 -22
- package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DsALnSfF.js.map} +1 -1
- 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/package.json +1 -1
- package/src/styles.css +2 -6
- package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
- package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
- 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-tools-RxmY5iyi.js.map +0 -1
- package/dist/endpoints-B2ynbZo-.js.map +0 -1
- package/dist/slug-C4ktDPdy.js.map +0 -1
- package/dist/spec-import-CjmxyZDR.js.map +0 -1
- package/dist/trigger-preview-VPkrryDl.js +0 -120
- package/dist/trigger-preview-VPkrryDl.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec-import-CjmxyZDR.js","sources":["../src/lib/workflow-live-run.ts","../src/lib/history-query.ts","../src/lib/workflow-poll.ts","../src/repos/workflows.ts","../src/repos/documents.ts","../src/repos/spec-import.ts"],"sourcesContent":["/**\n * Pure decision layer for the visual editor's live Run/Stop feature (T2.1.1,\n * A7). Every judgment call this feature makes that is NOT layout — is a run\n * in flight? should polling continue? is the canvas editable right now? what\n * should the Run button say and is it disabled? how does a cancel failure\n * get handled? how does a `RunState`'s steps map to the execution log\n * panel's rows, and what error does each row and the run show? what `input`\n * does the header Run send? — lives here as plain functions of (run state) -> result,\n * with no `.tsx` import and no React import, so `node --test` can load this\n * module directly. Same mechanical reason `workflow-poll.ts` and\n * `repos/reliability-uptime.ts` exist as separate `.ts` modules — read\n * `workflow-poll.ts`'s own header. `WorkflowsPage.tsx` calls these functions\n * rather than restating the conditions inline.\n */\nimport { type RunStatus, isTerminalRunStatus } from \"@w6w/sdk\";\n\nexport type { RunStatus };\n\n/**\n * The five states a workflow step's execution can be in — a thin LOCAL copy\n * of `@w6w/ui`'s `StepStatus` (itself a thin local copy of the engine's\n * `StepStatus` — see `run-visuals.ts`'s own header in `packages/ui`, the\n * same house idiom). `@w6w/sdk/console`'s `RunState.steps` is deliberately\n * typed `Record<string, unknown>` — opaque pass-through, by that module's\n * own documented design — so the real per-step shape has to be re-stated\n * here rather than imported.\n */\nexport type StepStatus = \"pending\" | \"running\" | \"succeeded\" | \"failed\" | \"skipped\";\n\n/** The per-step metadata (which app/version/action/connection ran) — one\n * local structural copy of the pinned `StepMeta`. A `type` alias, not an\n * `interface`, so it stays assignable to index-signature types. */\nexport type StepMetaLike = {\n app: string;\n version: string;\n action: string;\n connectionId: string | null;\n};\n\n/** The slice of a `StepExecution` this module reads, to build one\n * `ExecutionLogPanel` row. */\nexport interface StepExecutionLike {\n status: StepStatus;\n startedAt?: string;\n finishedAt?: string;\n input?: unknown;\n output?: unknown;\n /** `StepExecution.error` — a `StepError` on `failed` per rfcs/workflow.md\n * §StepExecution, but read as `unknown` because `RunState.steps` is opaque\n * on the wire; {@link toLogError} normalises whatever actually arrives. */\n error?: unknown;\n /** Recorded metadata; absent (or null) for steps that recorded none. */\n meta?: StepMetaLike | null;\n}\n\n/** A step or run error, as the run log panel renders it — field-for-field\n * `@w6w/ui`'s `ExecutionLogError` (rfcs/workflow.md §StepError's\n * `code`/`message`/`phase`/`retryable`), restated locally for the same reason\n * as {@link ExecutionLogStepLike} below. `message` is never empty. */\nexport interface LogErrorLike {\n code?: string;\n message: string;\n phase?: string;\n retryable?: boolean;\n}\n\n/** One `RunState.stepErrors` entry the panel shows at run level — field-for-field\n * `@w6w/ui`'s `ExecutionLogRecordedError`, restated locally (see above). */\nexport interface RecordedLogErrorLike {\n stepId: string;\n label?: string;\n error: LogErrorLike;\n}\n\n/** The slice of a `RunState` {@link runLevelErrors} reads. */\nexport interface RunErrorSourceLike {\n status?: string;\n error?: unknown;\n stepErrors?: ReadonlyArray<{ stepId: string; error: unknown }>;\n}\n\n/** The slice of a saved step-test fixture (`StepTest`) {@link latestFixtureInput}\n * reads — `with` is what the trigger's Test tab invokes it with. */\nexport interface StepTestFixtureLike {\n with?: unknown;\n}\n\n/** The row-level fallback for a `failed` step that carries no `error` at all. */\nexport const STEP_FAILED_NO_REASON = \"Step failed without reporting a reason.\";\n\n/** The run-level fallback for a `failed` run where nothing carries a reason. */\nexport const RUN_FAILED_NO_REASON = \"Run failed without reporting a reason.\";\n\n/** One `ExecutionLogPanel` row — field-for-field `@w6w/ui`'s\n * `ExecutionLogStep`, restated locally for the same reason as\n * {@link StepExecutionLike} above (no runtime dependency on `@w6w/ui`,\n * which this module must not import — see the file header). */\nexport interface ExecutionLogStepLike {\n id: string;\n status: StepStatus;\n startedAt?: string;\n finishedAt?: string;\n input?: unknown;\n output?: unknown;\n error?: LogErrorLike;\n meta?: StepMetaLike;\n}\n\n/** How a cancel-request failure should be handled (A6). */\nexport type CancelErrorOutcome = \"reconcile\" | \"surface\";\n\n/**\n * A2/M1 — the `refetchInterval` decision: keep polling (`true`) until the\n * run's status is terminal (`false`), including while no run has answered\n * yet (`status === undefined` — the very first poll hasn't landed, or no run\n * is active at all).\n */\nexport function shouldContinuePolling(status: RunStatus | undefined): boolean {\n return status === undefined || !isTerminalRunStatus(status);\n}\n\n/**\n * A4/M2/M3 — is a run currently \"in flight\" from this page's point of view?\n * `true` only while the poll has a live, non-terminal status AND the poll\n * itself hasn't given up/errored — a failed poll unlocks the canvas exactly\n * like reaching a real terminal status does (A4's own named failure case: \"a\n * canvas that stays locked after a cancel\"). Drives the canvas's `readOnly`\n * prop, the Stop button's visibility, and the Run button's disabled state —\n * one function, three call sites, so they can never drift out of sync with\n * each other.\n */\nexport function isRunInFlight(status: RunStatus | undefined, pollFailed: boolean): boolean {\n if (pollFailed) return false;\n if (status === undefined) return false;\n return !isTerminalRunStatus(status);\n}\n\n/** A1/A6 — what the Run button should read right now. */\nexport function runButtonLabel(status: RunStatus | undefined, pollFailed: boolean): string {\n if (!isRunInFlight(status, pollFailed)) return \"Run\";\n return status === \"queued\" ? \"Queued…\" : \"Running…\";\n}\n\n/**\n * A6/M6 — classify a `cancel()` failure. `run_not_cancelable` (409) means\n * the run already reached a terminal state before the cancel request landed\n * — not a user-facing error, just reconcile to whatever the next poll\n * reports. Everything else (`unknown_run`, a network failure, …) is a real\n * failure the page's existing error affordance must show.\n */\nexport function classifyCancelError(code: string): CancelErrorOutcome {\n return code === \"run_not_cancelable\" ? \"reconcile\" : \"surface\";\n}\n\n/**\n * G5 — map a `RunState`'s opaque `steps` record onto `ExecutionLogPanel`'s\n * row shape, in the record's own key order (the order the server checkpoints\n * steps in, so it already reads as execution order). `ExecutionLogPanel`'s\n * own contract is \"never re-sorted\" (`ExecutionLogPanel.tsx`'s header), so\n * this function must not reorder either.\n */\nexport function mapRunStateToLogSteps(\n steps: Record<string, StepExecutionLike> | undefined,\n): ExecutionLogStepLike[] {\n if (!steps) return [];\n return Object.entries(steps).map(([id, step]) => ({\n id,\n status: step.status,\n startedAt: step.startedAt,\n finishedAt: step.finishedAt,\n input: step.input,\n output: step.output,\n ...(step.meta !== undefined && step.meta !== null ? { meta: step.meta } : {}),\n ...rowError(step),\n }));\n}\n\n/** The `error` key for one row — present ONLY when the step reports an error\n * or is `failed` (then with {@link STEP_FAILED_NO_REASON}), so a healthy row\n * keeps exactly the shape it had before errors were carried. */\nfunction rowError(step: StepExecutionLike): { error?: LogErrorLike } {\n const error = toLogError(step.error);\n if (error) return { error };\n if (step.status === \"failed\") return { error: { message: STEP_FAILED_NO_REASON } };\n return {};\n}\n\n/**\n * Normalise whatever a step or run reported as its error into the panel's\n * {@link LogErrorLike}. `null`/`undefined` mean \"no error\". A non-empty string\n * is the message. An object contributes `code` (string), `message` (its own\n * non-empty `message`, else a non-empty `code`, else its JSON), `phase`\n * (string) and `retryable` (boolean). Anything else is stringified. The\n * returned `message` is never empty.\n */\nexport function toLogError(raw: unknown): LogErrorLike | undefined {\n if (raw === null || raw === undefined) return undefined;\n if (typeof raw === \"string\" && raw !== \"\") return { message: raw };\n if (typeof raw === \"object\") {\n const o = raw as Record<string, unknown>;\n const code = typeof o.code === \"string\" ? o.code : undefined;\n const message =\n typeof o.message === \"string\" && o.message !== \"\" ? o.message : code || safeJson(raw);\n return {\n ...(code !== undefined ? { code } : {}),\n message: message || \"Unknown error.\",\n ...(typeof o.phase === \"string\" ? { phase: o.phase } : {}),\n ...(typeof o.retryable === \"boolean\" ? { retryable: o.retryable } : {}),\n };\n }\n return { message: String(raw) || \"Unknown error.\" };\n}\n\n/** `JSON.stringify` that answers `\"\"` instead of throwing (a cycle, a BigInt)\n * or returning `undefined` (a `toJSON` that yields nothing). */\nfunction safeJson(raw: unknown): string {\n try {\n return JSON.stringify(raw) ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n/**\n * The run-level half of the run log: `RunState.error` as `runError`, plus the\n * `RunState.stepErrors` entries whose step has NO row already carrying an\n * error (a `continue-record` failure is usually also on its own row — showing\n * it twice would read as two failures), in their given order. A row showing\n * only {@link STEP_FAILED_NO_REASON} does not count as carrying an error here,\n * so the reason recorded for that step is still surfaced. A `failed` run where\n * nothing — run, rows or surfaced step errors — carries a reason gets\n * {@link RUN_FAILED_NO_REASON}. `runError` is omitted when it duplicates a\n * row's error (equal `message` and equal `code`), since the step failure that\n * stopped the run is already shown on its row. It is likewise omitted when it\n * duplicates a surfaced `stepErrors` entry's error, by the same equality.\n * Keys are omitted when empty.\n */\nexport function runLevelErrors(\n run: RunErrorSourceLike | undefined,\n rows: ReadonlyArray<ExecutionLogStepLike>,\n): { runError?: LogErrorLike; stepErrors?: RecordedLogErrorLike[] } {\n if (!run) return {};\n const carried = new Set(rows.filter((r) => r.error !== undefined).map((r) => r.id));\n const reasoned = new Set(\n rows\n .filter((r) => r.error !== undefined && r.error.message !== STEP_FAILED_NO_REASON)\n .map((r) => r.id),\n );\n const stepErrors = (run.stepErrors ?? [])\n .filter((e) => !reasoned.has(e.stepId))\n .map((e) => ({\n stepId: e.stepId,\n error: toLogError(e.error) ?? { message: STEP_FAILED_NO_REASON },\n }));\n const own = toLogError(run.error);\n const sameAsOwn = (e: LogErrorLike | undefined) =>\n own !== undefined && e?.message === own.message && e?.code === own.code;\n const shown = rows.some((r) => sameAsOwn(r.error)) || stepErrors.some((e) => sameAsOwn(e.error));\n let runError = shown ? undefined : own;\n if (!runError && run.status === \"failed\" && carried.size === 0 && stepErrors.length === 0) {\n runError = { message: RUN_FAILED_NO_REASON };\n }\n return {\n ...(runError ? { runError } : {}),\n ...(stepErrors.length > 0 ? { stepErrors } : {}),\n };\n}\n\n/**\n * The header Run's `input`: the LAST saved fixture's `with` (`listStepTests`\n * answers oldest-first — the same \"last is latest\" reading\n * `@w6w/ui`'s `TriggerFillForm` seeds from), when it is a plain object.\n * Sent verbatim — `{type:\"expr\",…}` values included.\n */\nexport function latestFixtureInput(\n tests: ReadonlyArray<StepTestFixtureLike> | undefined,\n): Record<string, unknown> | undefined {\n const last = tests?.[tests.length - 1]?.with;\n if (last === null || typeof last !== \"object\" || Array.isArray(last)) return undefined;\n return last as Record<string, unknown>;\n}\n\n/**\n * Resolve the header Run's `input` for the manual trigger `triggerStepId`.\n * No trigger id → `undefined` without fetching. A fetch that throws or\n * rejects → `undefined`: a missing fixture never blocks the run. Fetched at\n * click time on purpose — a cached `stepTestsKey` query can be stale, since\n * saving a fixture does not invalidate it.\n */\nexport async function resolveHeaderRunInput(\n triggerStepId: string | undefined,\n list: (stepId: string) => Promise<ReadonlyArray<StepTestFixtureLike> | undefined>,\n): Promise<Record<string, unknown> | undefined> {\n if (!triggerStepId) return undefined;\n try {\n return latestFixtureInput(await list(triggerStepId));\n } catch {\n return undefined;\n }\n}\n","// Run: node --test src/lib/__tests__/history-query.test.ts (Node 24, type-stripped)\n//\n// T2.3.1 — the pure data layer behind the project-wide and per-callable\n// History page (T2.4.1) and the Function/Endpoint/Workflow header's History\n// button (T2.4.2). Everything that is a judgment call rather than React\n// plumbing lives here: how a URL's search string becomes a `HistoryFilters`\n// (and back), how a filter set becomes the wire's own query params, the\n// query keys every hook in `repos/history.ts` shares, and how a summary row\n// is expanded into a full detail view for one of the three callable kinds.\n//\n// Zero runtime imports other than `./workflow-live-run.ts` (A1) — every other\n// import here is `import type`, erased at build time, so `node --test` can\n// load this module directly with no React, no SDK runtime, no JSX. The one\n// runtime import reuses `mapRunStateToLogSteps`, the same step mapper the\n// visual editor's live-run overlay already uses, so a workflow's historical\n// detail view renders steps identically to its live one.\n//\n// The wire shape (`ExecutionKind`, `ExecutionStatus`, `ExecutionSummary`,\n// `ExecutionStats`) is pinned verbatim against T2.1.1's own contract — do not\n// drift it; T2.4.1/T2.4.2 are written against this file's exports exactly.\n\nimport type { W6WClient } from \"@w6w/sdk\";\nimport { type StepExecutionLike, mapRunStateToLogSteps } from \"./workflow-live-run.ts\";\n\n// ── wire types (pinned, identical to T2.1.1 §Wire) ──────────────────────\n\nexport type ExecutionKind = \"function\" | \"endpoint\" | \"workflow\";\nexport type ExecutionStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"canceled\";\n\nexport interface ExecutionSummary {\n id: string;\n kind: ExecutionKind;\n callableId: string;\n callableName: string;\n status: ExecutionStatus;\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n workflowRunId: string | null;\n}\n\nexport interface ExecutionStats {\n total: number;\n succeeded: number;\n failed: number;\n canceled: number;\n inFlight: number;\n successRate: number | null;\n avgDurationMs: number | null;\n}\n\n// ── scope + filters ───────────────────────────────────────────────────────\n\n/** Either the project-wide view or one callable's own history — mutually\n * exclusive, never both, mirroring the wire's own `project`|`callable`\n * params (exactly one). */\nexport type HistoryScope = { project: string } | { callable: string };\n\n/** Everything the History page's filter chrome can set, already parsed out\n * of the URL. `status`/`kind` are `\"\"` for \"any\"; `from`/`to` are the\n * `YYYY-MM-DD` the date pickers hand back, or `\"\"` for unset; `offset` is\n * always a non-negative integer (0 for \"first page\"). */\nexport interface HistoryFilters {\n status: ExecutionStatus | \"\";\n kind: ExecutionKind | \"\";\n from: string;\n to: string;\n q: string;\n offset: number;\n}\n\nexport const EMPTY_HISTORY_FILTERS: HistoryFilters = {\n status: \"\",\n kind: \"\",\n from: \"\",\n to: \"\",\n q: \"\",\n offset: 0,\n};\n\nexport const HISTORY_PAGE_SIZE = 25;\n\nconst VALID_STATUSES: ReadonlySet<string> = new Set([\n \"queued\",\n \"running\",\n \"succeeded\",\n \"failed\",\n \"canceled\",\n]);\nconst VALID_KINDS: ReadonlySet<string> = new Set([\"function\", \"endpoint\", \"workflow\"]);\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** True when `YYYY-MM-DD` names a real calendar day (`2026-02-30` rolls into\n * March through `new Date`, so a round-trip comparison rejects it). */\nfunction isRealDate(s: string): boolean {\n if (!DATE_RE.test(s)) return false;\n const { y, m, d } = dateParts(s);\n const dt = new Date(y, m - 1, d);\n return dt.getFullYear() === y && dt.getMonth() === m - 1 && dt.getDate() === d;\n}\n\n/** Parse a validated `YYYY-MM-DD` string into its three numeric parts. */\nfunction dateParts(value: string): { y: number; m: number; d: number } {\n const [y, m, d] = value.split(\"-\").map(Number);\n return { y, m, d };\n}\n\n/**\n * URL search string → `HistoryFilters`. An unrecognised `status`/`kind`, a\n * `from`/`to` not matching `YYYY-MM-DD`, or a non-integer/negative `offset`\n * all fall back to their empty/zero default rather than carrying a bogus\n * value forward into a request — a stale or hand-edited URL degrades to \"no\n * filter\" instead of erroring.\n */\nexport function filtersFromSearch(search: string): HistoryFilters {\n const params = new URLSearchParams(search);\n const status = params.get(\"status\") ?? \"\";\n const kind = params.get(\"kind\") ?? \"\";\n const from = params.get(\"from\") ?? \"\";\n const to = params.get(\"to\") ?? \"\";\n const q = params.get(\"q\") ?? \"\";\n const offsetRaw = params.get(\"offset\");\n let offset = 0;\n if (offsetRaw !== null) {\n const n = Number(offsetRaw);\n if (Number.isInteger(n) && n >= 0) offset = n;\n }\n return {\n status: VALID_STATUSES.has(status) ? (status as ExecutionStatus) : \"\",\n kind: VALID_KINDS.has(kind) ? (kind as ExecutionKind) : \"\",\n from: isRealDate(from) ? from : \"\",\n to: isRealDate(to) ? to : \"\",\n q,\n offset,\n };\n}\n\n/**\n * `HistoryFilters` → URL search string. `\"\"` when every field is at its\n * default, else a leading-`?` string with only the non-default fields, in\n * the pinned key order `status,kind,from,to,q,offset` (so two renders of the\n * same filters always produce byte-identical URLs — stable for bookmarking\n * and for `filtersFromSearch` round-tripping).\n */\nexport function filtersToSearch(f: HistoryFilters): string {\n const params = new URLSearchParams();\n if (f.status !== \"\") params.set(\"status\", f.status);\n if (f.kind !== \"\") params.set(\"kind\", f.kind);\n if (f.from !== \"\") params.set(\"from\", f.from);\n if (f.to !== \"\") params.set(\"to\", f.to);\n if (f.q !== \"\") params.set(\"q\", f.q);\n if (f.offset > 0) params.set(\"offset\", String(f.offset));\n const s = params.toString();\n return s === \"\" ? \"\" : `?${s}`;\n}\n\n/**\n * `HistoryFilters` + a scope → the wire's own query params (D3/pinned rules).\n * `kind` is sent only for a project scope with a non-empty kind — a\n * per-callable view already knows its one kind, and the server's `kind`\n * param is project-mode-only. `from`/`to` are expanded from the picked\n * calendar day into the half-open `[from, to)` ISO instant range the wire\n * wants — `to` is the NEXT day's midnight so the picked day itself is fully\n * inclusive. `q` is trimmed and omitted when blank (server-side id/name\n * search, D3 — never a payload scan). Paging params are added only when\n * `opts.paged`: `limit` always (defaulting to `HISTORY_PAGE_SIZE`), `offset`\n * only when it would change anything (`> 0`).\n */\nexport function historyRequestQuery(\n scope: HistoryScope,\n f: HistoryFilters,\n opts: { paged: boolean; limit?: number },\n): Record<string, string> {\n const query: Record<string, string> = {};\n\n if (\"project\" in scope) {\n query.project = scope.project;\n if (f.kind !== \"\") query.kind = f.kind;\n } else {\n query.callable = scope.callable;\n }\n\n if (f.status !== \"\") query.status = f.status;\n\n if (f.from !== \"\" && isRealDate(f.from)) {\n const { y, m, d } = dateParts(f.from);\n query.from = new Date(y, m - 1, d).toISOString();\n }\n if (f.to !== \"\" && isRealDate(f.to)) {\n const { y, m, d } = dateParts(f.to);\n query.to = new Date(y, m - 1, d + 1).toISOString();\n }\n\n const q = f.q.trim();\n if (q !== \"\") query.q = q;\n\n if (opts.paged) {\n query.limit = String(opts.limit ?? HISTORY_PAGE_SIZE);\n if (f.offset > 0) query.offset = String(f.offset);\n }\n\n return query;\n}\n\n// ── cache keys (ship from here, never from a caller — mirrors `repos/dashboard.ts`) ──\n\n/**\n * Every key this domain reads or invalidates. `list`/`stats` carry the full\n * scope and filters object so two distinct filter sets never collide on the\n * same cache entry (and the identical pair always do) — react-query's own\n * structural key hashing does the rest.\n */\nexport const historyKeys = {\n root: [\"history\"] as const,\n list(scope: HistoryScope, f: HistoryFilters, limit: number): readonly unknown[] {\n return [\"history\", \"list\", scope, f, limit];\n },\n stats(scope: HistoryScope, f: HistoryFilters): readonly unknown[] {\n return [\"history\", \"stats\", scope, f];\n },\n exists(callableId: string): readonly [\"history\", \"exists\", string] {\n return [\"history\", \"exists\", callableId];\n },\n detail(kind: ExecutionKind, id: string): readonly [\"history\", \"detail\", ExecutionKind, string] {\n return [\"history\", \"detail\", kind, id];\n },\n};\n\n// ── fetchers ─────────────────────────────────────────────────────────────\n\n/** `GET /history` — paged. */\nexport function getHistory(\n client: W6WClient,\n scope: HistoryScope,\n f: HistoryFilters,\n limit: number = HISTORY_PAGE_SIZE,\n): Promise<{ executions: ExecutionSummary[]; hasMore: boolean }> {\n return client\n .request<{ executions: ExecutionSummary[]; hasMore: boolean }>({\n method: \"GET\",\n path: \"/history\",\n query: historyRequestQuery(scope, f, { paged: true, limit }),\n })\n .then((response) => response.body);\n}\n\n/** `GET /history/stats` — unpaged (no `limit`/`offset`). */\nexport function getHistoryStats(\n client: W6WClient,\n scope: HistoryScope,\n f: HistoryFilters,\n): Promise<ExecutionStats> {\n return client\n .request<{ stats: ExecutionStats }>({\n method: \"GET\",\n path: \"/history/stats\",\n query: historyRequestQuery(scope, f, { paged: false }),\n })\n .then((response) => response.body.stats);\n}\n\n/** One execution's full detail — the shape `ExecutionDetail` (`@w6w/ui`,\n * T2.2.2) renders. `steps` is present only for a workflow run; a\n * function/endpoint invocation has none. */\nexport interface ExecutionDetailData {\n id: string;\n kind: ExecutionKind;\n callableName: string;\n status: ExecutionStatus;\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n input?: unknown;\n output?: unknown;\n error?: unknown;\n steps?: Array<{\n id: string;\n status: \"pending\" | \"running\" | \"succeeded\" | \"failed\" | \"skipped\";\n startedAt?: string;\n finishedAt?: string;\n input?: unknown;\n output?: unknown;\n }>;\n}\n\n/** The `GET /invocations/:id` response body's shape this module reads\n * (context notes: server `db/repos/invocations.ts` `InvocationRow`). */\ninterface InvocationDetailBody {\n status: ExecutionStatus;\n input?: unknown;\n output?: unknown;\n error?: unknown;\n durationMs: number | null;\n startedAt: string;\n finishedAt: string | null;\n}\n\n/**\n * Expand a list row into its full detail. Function/Endpoint invocations are\n * synchronous calls recorded one row per call (`.claude/docs/invocations.md`)\n * — `GET /invocations/:id` by the escape-hatch `client.request` (no typed SDK\n * method exists for this internal route, same reasoning as\n * `repos/callables.ts`'s `archiveCallable`/`deleteCallable` split; A1: no\n * other runtime import needed). A workflow run instead reuses\n * `client.console.workflows.getRun` (`repos/workflows.ts`'s own\n * `getRunState`) — its `variables` become the detail's `input`, and its\n * opaque `steps` map through the SAME `mapRunStateToLogSteps` the live-run\n * overlay uses, so a historical run's step list renders identically to a\n * live one. `callableName` always comes from the summary — neither read\n * carries a human-readable callable name of its own.\n */\nexport async function getExecutionDetail(\n client: W6WClient,\n summary: ExecutionSummary,\n): Promise<ExecutionDetailData> {\n if (summary.kind === \"workflow\") {\n const run = await client.console.workflows.getRun(summary.id);\n return {\n id: summary.id,\n kind: \"workflow\",\n callableName: summary.callableName,\n status: run.status,\n startedAt: summary.startedAt,\n finishedAt: summary.finishedAt,\n durationMs: summary.durationMs,\n input: run.variables,\n output: run.output,\n error: run.error,\n steps: mapRunStateToLogSteps(run.steps as Record<string, StepExecutionLike> | undefined),\n };\n }\n\n const response = await client.request<{ invocation: InvocationDetailBody }>({\n method: \"GET\",\n path: `/invocations/${encodeURIComponent(summary.id)}`,\n });\n const invocation = response.body.invocation;\n return {\n id: summary.id,\n kind: summary.kind,\n callableName: summary.callableName,\n status: invocation.status,\n startedAt: invocation.startedAt,\n finishedAt: invocation.finishedAt,\n durationMs: invocation.durationMs,\n input: invocation.input,\n output: invocation.output,\n error: invocation.error,\n };\n}\n","/**\n * The run-polling loop, split out of `api/client.ts`'s original `runWorkflow`\n * into its own PURE module — for the SAME mechanical reason\n * `repos/reliability-uptime.ts` exists (read that file's own header comment in\n * full): a `.ts` module that would otherwise transitively import\n * `../api/apiClient.tsx` (a `.tsx` file Node's type-stripping cannot load at\n * all) must be split out to stay reachable by `node --test`.\n *\n * Ported field-for-field from `api/client.ts`'s original `runWorkflow` (same\n * 500 ms interval, same 600-iteration cap, same \"one more fetch after the\n * loop\" shape) — the ONLY change is the injected `getRun`/`sleep` parameters,\n * which is what makes this loop testable on a fake clock instead of a real\n * 5-minute wait. See `../repos/workflows.ts` for the caller.\n */\nimport type { RunState } from \"@w6w/sdk/console\";\n\nconst TERMINAL = new Set([\"succeeded\", \"failed\", \"canceled\"]);\n\nfunction realSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Poll `getRun` until the run reaches a terminal status, or 600 polls (~5\n * minutes at the default 500ms interval) elapse — whichever comes first.\n * Ported verbatim from `api/client.ts`'s `runWorkflow`; see\n * `../repos/workflows.ts` for the caller.\n */\nexport async function pollRunToTerminal(\n getRun: () => Promise<RunState>,\n sleep: (ms: number) => Promise<void> = realSleep,\n): Promise<RunState> {\n for (let i = 0; i < 600; i++) {\n const run = await getRun();\n if (TERMINAL.has(run.status)) return run;\n await sleep(500);\n }\n return getRun();\n}\n","import {\n type UseMutationResult,\n useMutation,\n useQuery,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport type { W6WClient, WorkflowRunResult } from \"@w6w/sdk\";\nimport type { RunState } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport { historyKeys } from \"../lib/history-query.ts\";\nimport { shouldContinuePolling } from \"../lib/workflow-live-run.ts\";\nimport { pollRunToTerminal } from \"../lib/workflow-poll.ts\";\n\nexport type { RunState, RunSummary } from \"@w6w/sdk/console\";\nexport type { WorkflowStatus, WorkflowSummary } from \"@w6w/sdk\";\n\n// `project` distinguishes a project-scoped entry (WorkflowsPage.tsx) from the\n// unscoped one (TargetSelector.tsx, SubscriptionsPage.tsx) — genuinely DIFFERENT\n// queries (not a spelling split to unify like T2.2.2's appActions fix). Keep them\n// as distinct cache entries.\nexport const workflowsKey = (project?: string) => [\"workflows\", project] as const;\n\nexport function listWorkflows(client: W6WClient, project?: string) {\n return client.workflows.list({ project });\n}\n\nexport function useWorkflowsQuery(project?: string, enabled = true) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: workflowsKey(project),\n queryFn: () => listWorkflows(apiClient, project),\n enabled,\n });\n}\n\nexport const workflowKey = (id: string) => [\"workflow\", id] as const;\n\nexport function getWorkflow(client: W6WClient, id: string) {\n return client.workflows.get(id);\n}\n\nexport function useWorkflowQuery(id: string, enabled = true) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: workflowKey(id),\n queryFn: () => getWorkflow(apiClient, id),\n enabled,\n });\n}\n\n/**\n * A missing `project` here is not \"unscoped\" the way a read can legitimately\n * be — the write would silently land in the account's default project\n * instead of the one the caller is looking at. Both mutations refuse rather\n * than risk that; `WorkflowsPage.tsx`'s own `projectId != null` gate on\n * `useWorkflowsQuery` should mean `project` is always set by the time either\n * of these can actually be invoked from the UI, but the guard costs nothing.\n */\nexport function useCreateWorkflowMutation(project?: string) {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (definition: unknown) => {\n if (!project) return Promise.reject(new Error(\"No project selected yet.\"));\n return apiClient.console.workflows.upsert(definition, { project });\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"workflows\"] }),\n });\n}\n\nexport function useSaveWorkflowMutation(project?: string) {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { definition: unknown; ifUnmodifiedSince: string | null }) => {\n if (!project) return Promise.reject(new Error(\"No project selected yet.\"));\n return apiClient.console.workflows.upsert(vars.definition, {\n project,\n ifUnmodifiedSince: vars.ifUnmodifiedSince,\n });\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"workflows\"] }),\n });\n}\n\nexport function useArchiveWorkflowMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => apiClient.workflows.archive(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"workflows\"] }),\n });\n}\n\nexport function useDeleteWorkflowMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (id: string) => apiClient.workflows.delete(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"workflows\"] }),\n });\n}\n\nexport const runsKey = (workflowId: string) => [\"runs\", workflowId] as const;\n\nexport function useRunsQuery(workflowId: string) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: runsKey(workflowId),\n queryFn: () => apiClient.console.workflows.listRuns(workflowId),\n });\n}\n\n/**\n * Start a run and poll it to a terminal state.\n *\n * `input` is the run's START PAYLOAD, and it is a different thing from\n * `variables`: the server hands it to the entry `@w6w/trigger` node as that\n * node's own output, which is what makes `{{ steps.<trigger>.output.<field> }}`\n * resolve in a real run. Omitted, that node outputs `{}` and every reference to\n * a trigger field resolves to the empty string — the failure mode filed as\n * `.ai/projects/backlog/26-07-29-01-trigger-run-payload.md`, where a step tests\n * green and then does nothing in production. `variables` seeds `vars.*` and\n * reaches the trigger node not at all.\n *\n * Goes through the typed `client.workflows.run()` with\n * `allowUnpublished: true`: this call site always runs the STORED draft, and\n * the server exempts a caller that sets the flag from the publish gate\n * (`packages/api/run-workflow.ts`'s `enqueueRun`). The SDK's result is the flat\n * run body, so the `runId` used to poll comes off `res.runId`.\n */\nexport function runWorkflow(\n client: W6WClient,\n id: string,\n variables: Record<string, unknown>,\n input?: Record<string, unknown>,\n): Promise<RunState> {\n return client.workflows\n .run(id, { variables, input, allowUnpublished: true })\n .then((res) => pollRunToTerminal(() => client.console.workflows.getRun(res.runId)));\n}\n\nexport function useRunWorkflowMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: {\n id: string;\n variables: Record<string, unknown>;\n input?: Record<string, unknown>;\n }) => runWorkflow(apiClient, vars.id, vars.variables, vars.input),\n onSuccess: (_res, vars) => qc.invalidateQueries({ queryKey: runsKey(vars.id) }),\n onSettled: () => qc.invalidateQueries({ queryKey: historyKeys.root }),\n });\n}\n\n/**\n * Run a Workflow SYNCHRONOUSLY — the `W6WApi.runWorkflow` facade member's\n * backing function (the Workflows tab's Test stage, D-11/D-15(c)). A sibling\n * of {@link runWorkflow}, NOT a replacement: that function's enqueue-then-poll\n * shape is the studio-wide \"Run this workflow\" action and stays exactly as it\n * is. This one instead sends `wait: true` on the SAME base `client.workflows\n * .run` call already published (`?wait=true` — the server polls internally,\n * up to its own timeout) — zero new server code, and no second poll loop:\n * there is no `pollRunToTerminal` here at all. `terminal`/`httpStatus` on the\n * result distinguish \"finished in time\" (`200`) from \"still going when the\n * server's own wait timed out\" (`202`, a legitimate outcome, not an error).\n */\nexport function runWorkflowSync(\n client: W6WClient,\n id: string,\n variables: Record<string, unknown>,\n input?: Record<string, unknown>,\n): Promise<WorkflowRunResult> {\n return client.workflows.run(id, { variables, input, wait: true });\n}\n\n/**\n * T2.1.1 — the ENQUEUE half only: starts a run and returns its handle\n * immediately, without polling it to terminal. A genuine sibling of\n * {@link runWorkflow}, NOT a replacement — that function's \"enqueue, then\n * block to a terminal result\" shape is what `WorkflowDetailPage.tsx`'s \"Run\n * now\" panel is built on and stays exactly as it is. This one is for a host\n * that wants the `runId` right away so it can poll it live itself (the\n * visual editor's canvas + execution log panel) — see {@link useLiveRunQuery}.\n *\n * Like {@link runWorkflow}, this calls `client.workflows.run()` with\n * `allowUnpublished: true` unconditionally. Only `{ runId }` is returned, so\n * callers keep reading `runId` off the resolved value exactly as before.\n */\nexport function startWorkflowRun(\n client: W6WClient,\n id: string,\n variables: Record<string, unknown>,\n input?: Record<string, unknown>,\n) {\n return client.workflows\n .run(id, { variables, input, allowUnpublished: true })\n .then((res) => ({ runId: res.runId }));\n}\n\nexport function useStartRunMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: {\n id: string;\n variables: Record<string, unknown>;\n input?: Record<string, unknown>;\n }) => startWorkflowRun(apiClient, vars.id, vars.variables, vars.input),\n onSuccess: (_res, vars) => qc.invalidateQueries({ queryKey: runsKey(vars.id) }),\n onSettled: () => qc.invalidateQueries({ queryKey: historyKeys.root }),\n });\n}\n\n/** What `client.workflows.cancel` resolves to. Named here because the SDK's root entry does not\n * export its `WorkflowCancelResult`: an inferred return type would name it and `vite-plugin-dts`\n * would skip this whole file (TS2742), leaving every `./repos` declaration out of the tarball. */\nexport type WorkflowCancelResult = Awaited<ReturnType<W6WClient[\"workflows\"][\"cancel\"]>>;\n\n/**\n * T2.1.1/A6 — cancel a queued or running run. `client.workflows.cancel`\n * itself never claims the run has stopped (its own doc comment: a `202`\n * means the request was RECORDED, not that the run finished) — the caller\n * keeps polling {@link useLiveRunQuery} until the run actually reaches a\n * terminal status. See `../lib/workflow-live-run.ts`'s `classifyCancelError`\n * for how a `409 run_not_cancelable` (the run beat the cancel to the finish\n * line) is told apart from a real failure.\n */\nexport function cancelWorkflowRun(client: W6WClient, runId: string): Promise<WorkflowCancelResult> {\n return client.workflows.cancel(runId);\n}\n\nexport function useCancelRunMutation(): UseMutationResult<WorkflowCancelResult, Error, string> {\n const apiClient = useEmbedClient();\n return useMutation({\n mutationFn: (runId: string) => cancelWorkflowRun(apiClient, runId),\n });\n}\n\n/** The single-shot half of {@link useLiveRunQuery} — a thin, directly\n * testable wrapper around `client.console.workflows.getRun`, so the polling\n * config below can be pinned without needing to render a hook. */\nexport function getRunState(client: W6WClient, runId: string): Promise<RunState> {\n return client.console.workflows.getRun(runId);\n}\n\n/** Query key for one run's live state — distinct from {@link runsKey}, which\n * is the workflow's run LIST. */\nexport const runStateKey = (runId: string) => [\"run\", runId] as const;\n\n/**\n * T2.1.1/A2/A3 — poll one run's live state at a fixed 500ms interval,\n * stopping once it reaches a terminal status ({@link shouldContinuePolling},\n * `../lib/workflow-live-run.ts`). A genuine sibling of `pollRunToTerminal`\n * (`../lib/workflow-poll.ts`) using the SAME underlying SDK call\n * (`client.console.workflows.getRun`), but publishing every intermediate\n * `RunState` to its caller via TanStack Query's own `data` — unlike\n * `pollRunToTerminal`, which discards every non-terminal result and hands\n * back only the last one. `runId === null` disables the query entirely (no\n * run started yet, or the page navigated to a different workflow).\n */\nexport function useLiveRunQuery(runId: string | null) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: runStateKey(runId ?? \"\"),\n queryFn: () => getRunState(apiClient, runId as string),\n enabled: runId != null,\n refetchInterval: (query) => (shouldContinuePolling(query.state.data?.status) ? 500 : false),\n });\n}\n","/**\n * The `documents` domain repo — wraps `@w6w/sdk`'s `client.documents.*` in\n * react-query (HITL-6). `QueryClientProvider` (`main.tsx`) stays the actual\n * cache; this module only centralizes the query-key factory and the\n * `queryFn`/`mutationFn` pairs so every page reads documents the same way.\n *\n * Documents are project-scoped (`documents.ts`'s `DocumentOptions.project`);\n * every mutation here invalidates the unscoped `[\"documents\"]` key, which\n * prefix-matches every project-scoped query key produced by\n * {@linkcode documentsKey} — the same invalidation shape `DocumentsPage.tsx`\n * used before this migration.\n */\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { path, type Doc, type DocumentCreateInput, type DocumentPatch } from \"@w6w/sdk\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n\n/**\n * T1.1.1's wire shape for one document, pinned here ahead of that node\n * merging (this node is dispatched speculatively against it — see this\n * task's contract). `shared` and the six `source*`/`syncedAt` fields are all\n * additive over the SDK's own `Doc`, so a locally-created document simply\n * carries them as `null` (or `false` for `shared`) rather than omitting\n * them. Do not rename a field — the server produces these names verbatim.\n */\nexport interface DocWithProvenance extends Doc {\n shared: boolean;\n /** \"owner/name\" of the bound repository this document was pulled from. */\n sourceRepo: string | null;\n /** Repo-relative file path the document was pulled from. */\n sourcePath: string | null;\n /** The pulled file's content hash — NOT a commit SHA. */\n sourceSha: string | null;\n /** The repository's HEAD commit SHA at pull time — NOT a content hash. */\n sourceRefSha: string | null;\n /** Web link to the file; may be absent even when the rest of provenance is set. */\n sourceUrl: string | null;\n /** ISO-8601. Stamped at the document's last actual change, not at every sync. */\n syncedAt: string | null;\n}\n\n/**\n * Which provenance state `DocumentDetailPage.tsx`'s \"Source\" card should\n * render for `doc`. `shared` (not `sourceRepo`) is the gate: a shared\n * document whose provenance columns haven't been stamped yet (any document\n * synced before this feature shipped, until its next real-content sync —\n * tier-1 \"unchanged\" syncs never restamp provenance) is still shared, and\n * must say so, distinct from a genuinely private document.\n *\n * - `\"private\"` — `doc.shared` is false. No card.\n * - `\"pending\"` — shared, but `sourceRepo` hasn't been stamped yet.\n * - `\"synced\"` — shared, with full provenance available.\n */\nexport function documentProvenanceState(doc: DocWithProvenance): \"private\" | \"pending\" | \"synced\" {\n if (!doc.shared) return \"private\";\n return doc.sourceRepo == null ? \"pending\" : \"synced\";\n}\n\n/** Query key for a documents list, optionally scoped to a project. */\nexport function documentsKey(projectId?: string) {\n return [\"documents\", projectId] as const;\n}\n\n/**\n * Query key for a single document, scoped to a project (mirrors\n * {@linkcode useDocumentsQuery}'s fix at :72-79/:80-87 below — `projectId`\n * belongs in the key itself, not just the `queryFn`, so a render where the\n * key was cached under `projectId === undefined` genuinely changes key once\n * `ProjectContext` resolves the real one, instead of reusing the same cache\n * entry — and its `retry: false` wrong-project 404 — forever). Still sits\n * under the bare `[\"documents\"]` prefix every mutation below invalidates, so\n * an edit/delete refreshes this page too — `\"detail\"` keeps it from\n * colliding with {@linkcode documentsKey}'s own `[\"documents\", projectId]`\n * shape.\n */\nexport function documentKey(id: string, projectId?: string) {\n return [\"documents\", \"detail\", id, projectId] as const;\n}\n\n/**\n * A single document by id, cast to {@link DocWithProvenance} (D-5): the SDK's\n * `Doc` doesn't model T1.1.1's provenance fields yet, and this repo is not\n * the place to fork or extend `@w6w/sdk` (D-4). The `project` option is\n * passed exactly as {@linkcode useDocumentsQuery} passes it — a document in a\n * non-default project 404s without it. `enabled` defaults `true` to preserve\n * that unscoped fallback for a caller that genuinely wants it — same as\n * {@linkcode useDocumentsQuery}'s own `enabled` doc comment below — a\n * project-scoped page should instead pass `enabled: projectId != null` so it\n * never queries (and never renders) against the wrong project while\n * `ProjectContext`'s own project list is still resolving.\n */\nexport function useDocumentQuery(id: string, projectId?: string, enabled = true) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: documentKey(id, projectId),\n queryFn: async () =>\n (await apiClient.documents.get(id, { project: projectId })) as DocWithProvenance,\n enabled,\n });\n}\n\n/**\n * The current project's documents (or the tenant default when unscoped).\n * `enabled` defaults `true` to preserve that unscoped fallback for a caller\n * that genuinely wants it — a project-scoped page should instead pass\n * `enabled: projectId != null` so it never queries (and never renders)\n * against the wrong project while `ProjectContext`'s own project list is\n * still resolving.\n */\nexport function useDocumentsQuery(projectId?: string, enabled = true) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: documentsKey(projectId),\n // Cast to DocWithProvenance[], same as useDocumentQuery above: the wire\n // response already carries `shared`/`source*`/`syncedAt` (repo.list()\n // serializes every document the same way repo.get() does), but the SDK's\n // own `Doc` type doesn't declare them yet (D-5). Without this cast,\n // DocumentsPage.tsx's list rows have no type-visible way to branch on\n // `d.shared` the way DocumentDetailPage.tsx already does.\n queryFn: async () =>\n (await apiClient.documents.list({ project: projectId })) as DocWithProvenance[],\n enabled,\n });\n}\n\nexport function useCreateDocumentMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { input: DocumentCreateInput; project?: string }) =>\n apiClient.documents.create(vars.input, { project: vars.project }),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"documents\"] }),\n });\n}\n\nexport function useUpdateDocumentMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; patch: DocumentPatch; project?: string }) =>\n apiClient.documents.update(vars.id, vars.patch, { project: vars.project }),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"documents\"] }),\n });\n}\n\nexport function useDeleteDocumentMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; project?: string }) =>\n apiClient.documents.delete(vars.id, { project: vars.project }),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"documents\"] }),\n });\n}\n\n/**\n * Re-pulls a shared document from its bound repository (\"Sync\" button, T2.1.4)\n * — `POST /documents/:id/sync` (T3.1.1). No SDK method exists for this route\n * yet (D-4/D-5), so this goes through `apiClient.request()` directly, same\n * escape hatch `repo-sync.ts`'s `useSyncRepoNowMutation` uses. The document\n * routes are project-scoped by QUERY param, not a path segment (unlike\n * `repo-binding`'s `/projects/:id/...` shape), so `project` travels in\n * `query`, mirroring {@linkcode useDocumentQuery}'s own `{ project: … }` use.\n */\nexport function useSyncDocumentMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { id: string; project?: string }) =>\n apiClient.request<{ document: DocWithProvenance }>({\n method: \"POST\",\n path: path`/documents/${vars.id}/sync`,\n query: { project: vars.project },\n }),\n onSuccess: () => qc.invalidateQueries({ queryKey: [\"documents\"] }),\n });\n}\n","/**\n * The `/spec/import` repo (T3.2.1). A NEW file, deliberately kept out of\n * `repos/functions.ts` / `repos/endpoints.ts` (T3.1.1 owns both) so the two\n * nodes never collide on the same file.\n *\n * **Every operation here goes through `W6WClient.request<T>()`, never\n * `apiClient.console.*`.** `T2.1.2`'s `inputs.touch` has no\n * `packages/wrappers` entry — there is no SDK method for this route — so\n * `request()` is the client's public escape hatch, exactly as\n * `repos/vars.ts`'s own docblock explains for the same reason.\n *\n * The posted `document` is forwarded to the server VERBATIM: this module\n * shapes nothing, validates nothing, and — this is the mechanism pin note 1\n * of the contract states from the side a wrong implementation must break —\n * never falls back to the sibling whole-definition save mutation\n * `FunctionIdentityModal.tsx` uses, on any response. `/spec/import` is where\n * the server-side sealed-secret walker lives (T2.1.2 §B runs\n * `assertNoSecretEnvelopes` over the WHOLE supplied body before any write);\n * a \"helpful\" fallback to that other write path would route a pasted\n * document straight around that check.\n *\n * T1.2.1 generalizes this over all three kinds: `onSuccess` invalidates the\n * ONE list key the imported document's own kind reads (`result.kind`, which\n * the server always echoes), never an unconditional `functionsKey`. The\n * decision of which key that is lives in `../lib/spec-import-invalidation.ts`\n * (a pure, `node --test`-loadable module). The three list keys are INJECTED by the host\n * (`listKeys`): Studio's `functionsKey`/`endpointsKey` live in its own `repos/callables`.\n */\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n type SpecImportListKeys,\n invalidateImportedCallable,\n} from \"../lib/spec-import-invalidation.ts\";\n\n/**\n * Mirrors `T2.1.1`'s `SpecDocument` (`T2.1.1.contract.md:134-141`): the\n * portable document a `GET /<kind>/:id/spec` export produces and this\n * route consumes. Not a bare `FunctionDef` — connection/var references ride\n * as re-bindable `rebind` entries, never live ids.\n */\nexport interface SpecImportDocument {\n specVersion: string;\n kind: \"function\" | \"endpoint\" | \"workflow\";\n callable: Record<string, unknown>;\n rebind: unknown[];\n}\n\n/** One reference site's outcome (T2.1.2 §E's `SpecImportReferenceReport`). */\nexport interface SpecImportReferenceReport {\n path: string;\n kind: string;\n resolved: boolean;\n /** Present only when `resolved` is `true`. */\n boundTo?: string;\n /** Present only when `resolved` is `false`. */\n reason?: string;\n}\n\n/** The `201` body `POST /spec/import` returns (T2.1.2 §E). */\nexport interface SpecImportResult {\n kind: \"function\" | \"endpoint\" | \"workflow\";\n callable: { id: string; key?: string; name?: string };\n references: SpecImportReferenceReport[];\n}\n\n/**\n * `POST /spec/import`. Success is always `201` — including a partially\n * resolved import (T2.1.2 §E: \"report, never fail silently\"). This mutation\n * resolves on ANY `201`; branching on `references.every(r => r.resolved)` is\n * the caller's job (A5), never this repo's.\n *\n * `project` is the caller's current project — only the workflow arm reads it\n * (`listKeys.workflowsKey(project)`), but every caller passes it uniformly rather than branching on kind itself; see\n * `../lib/spec-import-invalidation.ts` for why the key differs by kind.\n */\nexport function useImportSpecMutation(project: string | undefined, listKeys: SpecImportListKeys) {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: async (document: Record<string, unknown>) => {\n const res = await apiClient.request<SpecImportResult>({\n method: \"POST\",\n path: \"/spec/import\",\n body: document,\n });\n return res.body;\n },\n // A row exists in every `201` outcome (T2.1.2 §E creates it even when\n // some references stayed unresolved), so the list is stale either way —\n // but ONLY the list the imported kind actually belongs to (AC-3): the\n // unconditional `functionsKey` this used to invalidate left an imported\n // Endpoint or Workflow's own list stale while pointlessly invalidating\n // Functions.\n onSuccess: (result) => invalidateImportedCallable(qc, result.kind, listKeys, project),\n });\n}\n"],"names":["STEP_FAILED_NO_REASON","RUN_FAILED_NO_REASON","shouldContinuePolling","status","isTerminalRunStatus","isRunInFlight","pollFailed","runButtonLabel","classifyCancelError","code","mapRunStateToLogSteps","steps","id","step","rowError","error","toLogError","raw","o","message","safeJson","runLevelErrors","run","rows","carried","r","reasoned","stepErrors","e","own","sameAsOwn","runError","latestFixtureInput","tests","last","_a","resolveHeaderRunInput","triggerStepId","list","EMPTY_HISTORY_FILTERS","HISTORY_PAGE_SIZE","VALID_STATUSES","VALID_KINDS","DATE_RE","isRealDate","s","y","m","d","dateParts","dt","value","filtersFromSearch","search","params","kind","from","to","q","offsetRaw","offset","n","filtersToSearch","f","historyRequestQuery","scope","opts","query","historyKeys","limit","callableId","getHistory","client","response","getHistoryStats","getExecutionDetail","summary","invocation","TERMINAL","realSleep","ms","resolve","pollRunToTerminal","getRun","sleep","i","workflowsKey","project","listWorkflows","useWorkflowsQuery","enabled","apiClient","useEmbedClient","useQuery","workflowKey","getWorkflow","useWorkflowQuery","useCreateWorkflowMutation","qc","useQueryClient","useMutation","definition","useSaveWorkflowMutation","vars","useArchiveWorkflowMutation","useDeleteWorkflowMutation","runsKey","workflowId","useRunsQuery","runWorkflow","variables","input","res","useRunWorkflowMutation","_res","runWorkflowSync","startWorkflowRun","useStartRunMutation","cancelWorkflowRun","runId","useCancelRunMutation","getRunState","runStateKey","useLiveRunQuery","documentProvenanceState","doc","documentsKey","projectId","documentKey","useDocumentQuery","useDocumentsQuery","useCreateDocumentMutation","useUpdateDocumentMutation","useDeleteDocumentMutation","useSyncDocumentMutation","path","useImportSpecMutation","listKeys","document","result","invalidateImportedCallable"],"mappings":"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"}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
function f(r, e) {
|
|
2
|
-
const t = r.uses;
|
|
3
|
-
if (t != null && t.function) return null;
|
|
4
|
-
if (!(t != null && t.app) || !(t != null && t.action)) return "target missing";
|
|
5
|
-
const n = e.actionParamsByKey[`${t.app}::${t.action}`] ?? [], i = r.with ?? {};
|
|
6
|
-
return e.requiredParamsFilled(n, i) ? t.app in e.appsById && e.isTestRequired(e.appsById[t.app]) && !e.testStatus[r.id] ? "saved test" : null : "required params";
|
|
7
|
-
}
|
|
8
|
-
function d(r, e) {
|
|
9
|
-
return f(r, e) === null;
|
|
10
|
-
}
|
|
11
|
-
function c(r, e) {
|
|
12
|
-
return e.hasTrigger ? (r.steps ?? []).every((t) => d(t, e)) : !1;
|
|
13
|
-
}
|
|
14
|
-
function k(r, e) {
|
|
15
|
-
if (!e.hasTrigger) return "no trigger step";
|
|
16
|
-
for (const t of r.steps ?? []) {
|
|
17
|
-
const n = f(t, e);
|
|
18
|
-
if (n) return `${t.id}: ${n}`;
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
const p = /* @__PURE__ */ new Set(["string", "number", "boolean", "object", "array"]);
|
|
23
|
-
function g(r) {
|
|
24
|
-
if (!Array.isArray(r)) return [];
|
|
25
|
-
const e = [];
|
|
26
|
-
for (const t of r) {
|
|
27
|
-
if (typeof t != "object" || t === null || Array.isArray(t)) continue;
|
|
28
|
-
const n = t, i = { key: typeof n.key == "string" ? n.key : "" };
|
|
29
|
-
typeof n.type == "string" && p.has(n.type) && (i.type = n.type), typeof n.required == "boolean" && (i.required = n.required), n.default !== void 0 && (i.default = n.default), e.push(i);
|
|
30
|
-
}
|
|
31
|
-
return e;
|
|
32
|
-
}
|
|
33
|
-
function h(r) {
|
|
34
|
-
if (r.length !== 0)
|
|
35
|
-
return r.map((e) => {
|
|
36
|
-
const t = { key: e.key };
|
|
37
|
-
return e.type !== void 0 && (t.type = e.type), e.required && (t.required = !0), e.default !== void 0 && (t.default = e.default), t;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function v(r) {
|
|
41
|
-
const e = /* @__PURE__ */ new Set(), t = [];
|
|
42
|
-
return r.forEach((n, i) => {
|
|
43
|
-
e.has(n.key) ? t.push(i) : e.add(n.key);
|
|
44
|
-
}), t;
|
|
45
|
-
}
|
|
46
|
-
function m(r, e, t) {
|
|
47
|
-
const n = /* @__PURE__ */ new Set(), i = [];
|
|
48
|
-
for (const o of [...r.slice(0, e).map((a) => a.key), ...t])
|
|
49
|
-
o === "" || n.has(o) || (n.add(o), i.push(o));
|
|
50
|
-
return i;
|
|
51
|
-
}
|
|
52
|
-
function y(r) {
|
|
53
|
-
return typeof r == "object" && r !== null && !Array.isArray(r) && r.type === "expr" && Array.isArray(r.parts);
|
|
54
|
-
}
|
|
55
|
-
function b(r) {
|
|
56
|
-
const e = [], t = [];
|
|
57
|
-
for (const n of r)
|
|
58
|
-
if (n.key.trim() !== "") {
|
|
59
|
-
if (y(n.default)) {
|
|
60
|
-
e.push({ key: n.key, type: n.type, required: !1 }), t.push(n.key);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
e.push({ key: n.key, type: n.type, default: n.default, required: n.required });
|
|
64
|
-
}
|
|
65
|
-
return { fields: e, computed: t };
|
|
66
|
-
}
|
|
67
|
-
function A(r) {
|
|
68
|
-
return r === "active" || r === "archived" ? r : "draft";
|
|
69
|
-
}
|
|
70
|
-
function S(r) {
|
|
71
|
-
const e = r;
|
|
72
|
-
return {
|
|
73
|
-
autoSave: (e == null ? void 0 : e.autoSave) !== !1,
|
|
74
|
-
savePosition: (e == null ? void 0 : e.savePosition) !== !1
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
function q(r, e, t) {
|
|
78
|
-
const i = { ...typeof r == "object" && r !== null && !Array.isArray(r) ? r : void 0 };
|
|
79
|
-
return t ? delete i[e] : i[e] = !1, Object.keys(i).length === 0 ? void 0 : i;
|
|
80
|
-
}
|
|
81
|
-
function w(r, e) {
|
|
82
|
-
var i, o;
|
|
83
|
-
const t = r.steps ?? [], n = [];
|
|
84
|
-
for (const a of t) {
|
|
85
|
-
const s = (i = a.uses) == null ? void 0 : i.app;
|
|
86
|
-
if (!s || !e.isManualTrigger(s)) continue;
|
|
87
|
-
const l = e.asFieldDefs((o = a.with) == null ? void 0 : o.fields).filter((u) => typeof u.key == "string" && u.key.trim() !== "");
|
|
88
|
-
n.push({ id: a.id, label: a.displayName ?? a.id, fields: l });
|
|
89
|
-
}
|
|
90
|
-
return n;
|
|
91
|
-
}
|
|
92
|
-
function F(r) {
|
|
93
|
-
const e = {};
|
|
94
|
-
for (const t of (r == null ? void 0 : r.fields) ?? [])
|
|
95
|
-
if (!(typeof t.key != "string" || t.key.trim() === "")) {
|
|
96
|
-
if (t.default !== void 0) {
|
|
97
|
-
e[t.key] = t.default;
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
e[t.key] = t.type === "number" ? 0 : t.type === "boolean" ? !1 : "";
|
|
101
|
-
}
|
|
102
|
-
return e;
|
|
103
|
-
}
|
|
104
|
-
export {
|
|
105
|
-
y as a,
|
|
106
|
-
g as b,
|
|
107
|
-
A as c,
|
|
108
|
-
v as d,
|
|
109
|
-
b as e,
|
|
110
|
-
w as f,
|
|
111
|
-
m as g,
|
|
112
|
-
q as h,
|
|
113
|
-
k as i,
|
|
114
|
-
S as r,
|
|
115
|
-
d as s,
|
|
116
|
-
F as t,
|
|
117
|
-
h as v,
|
|
118
|
-
c as w
|
|
119
|
-
};
|
|
120
|
-
//# sourceMappingURL=trigger-preview-VPkrryDl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trigger-preview-VPkrryDl.js","sources":["../src/lib/workflow-validity.ts","../src/lib/workflow-variables.ts","../src/lib/workflow-settings.ts","../src/lib/trigger-preview.ts"],"sourcesContent":["/**\n * The publish-time validity gate (`logs/decisions.jsonl` row 9, verbatim):\n *\n * > a step is valid iff (app+action set, or function id set) and all its\n * > required params are filled (reuse `requiredParamsFilled`,\n * > `StepBuilderModal.tsx:577-590`) and, where `testRequired` is set for the\n * > app, its saved test has passed. The workflow is valid iff a trigger exists\n * > and every step is valid. Graph well-formedness (orphaned/unreachable\n * > nodes, dangling edges) is explicitly OUT of scope for this project.\n *\n * Pure and testable by design: `WorkflowsPage.tsx` is JSX, which Node 24's\n * type-stripping cannot parse, so nothing in it can be loaded by `node --test`\n * (same shape as `src/lib/workflow-save.ts` + its `.test.ts`). This module\n * cannot import `@w6w/ui`/`@w6w/ui/flow` either way: `@w6w/ui`'s\n * `package.json` `exports[\".\"]` resolves to raw `./src/index.ts`, which\n * re-exports `StepBuilderModal.tsx` — a `.tsx` file — so `node --test` throws\n * `ERR_UNKNOWN_FILE_EXTENSION` the moment anything here imports it. Instead,\n * the two functions the pinned predicate reuses\n * (`requiredParamsFilled`/`isTestRequired`) are **caller-injected** on\n * `ValidityContext` — `WorkflowsPage.tsx` (unaffected by the JSX constraint)\n * imports the real ones from `@w6w/ui` and passes them in. Same for \"a\n * trigger exists\": that reads a graph STEP whose `INTERNAL_NODES` entry has\n * `group === \"trigger\"` (`@w6w/ui/flow`), never the workflow's top-level\n * `trigger` field (`rfcs/workflow.md:114`, \"Absent means manual-only\" — always\n * present, so it can't gate anything) — so `hasTrigger` is caller-computed too.\n *\n * `ActionParamLike`/`WorkflowStepLike`/`WorkflowLike` below are this file's\n * own minimal local types (see `rfcs/workflow.md` §\"Step\" for the real shape,\n * `rfcs/function.md` for the `uses.function` arm).\n */\n\n/** A declared action/internal-node param, just enough of it for this gate. */\nexport interface ActionParamLike {\n key: string;\n type: string;\n required?: boolean;\n default?: unknown;\n children?: ActionParamLike[];\n}\n\n/** A workflow graph step, just enough of it for this gate. */\nexport interface WorkflowStepLike {\n id: string;\n uses?: {\n app?: string;\n action?: string;\n /** The \"or a function id\" arm (`rfcs/function.md:49,260`) — `Step.uses.function`. */\n function?: string;\n };\n with?: Record<string, unknown>;\n}\n\n/** A workflow definition, just enough of it for this gate. */\nexport interface WorkflowLike {\n steps?: WorkflowStepLike[];\n /**\n * Present on real definitions, never read here — graph well-formedness\n * (orphaned/unreachable nodes, dangling edges) is explicitly out of scope\n * for the publish gate (`logs/decisions.jsonl` row 9).\n */\n edges?: unknown;\n}\n\n/**\n * Everything `stepValid`/`workflowValid`/`invalidReason` need that this pure\n * module cannot compute or import itself — see the module docstring for why\n * each field is caller-built rather than derived in here.\n */\nexport interface ValidityContext {\n /** Does the graph contain a step whose (app, action) is a trigger node? */\n hasTrigger: boolean;\n /** Declared params for a step's target, keyed `` `${app}::${action}` ``. */\n actionParamsByKey: Record<string, ActionParamLike[]>;\n /** The fetched apps list, keyed by app id — only a key present here is test-gated. */\n appsById: Record<string, unknown>;\n /** Whether the given step id has a saved test that last ran successfully. */\n testStatus: Record<string, boolean>;\n /** `@w6w/ui`'s `requiredParamsFilled`, injected (see module docstring). */\n requiredParamsFilled: (params: ActionParamLike[], values: Record<string, unknown>) => boolean;\n /** `@w6w/ui`'s `isTestRequired`, injected (see module docstring). */\n isTestRequired: (app: unknown) => boolean;\n}\n\n/** Which of the pinned predicate's checks a step fails, or `null` when it's valid. */\ntype StepFailure = \"target missing\" | \"required params\" | \"saved test\";\n\n/**\n * The single place the pinned predicate's branching lives — `stepValid` and\n * `invalidReason` both read this rather than re-deriving the same checks.\n */\nfunction stepFailure(step: WorkflowStepLike, ctx: ValidityContext): StepFailure | null {\n const uses = step.uses;\n // A function-targeted step is valid on presence alone (T5.1.1 owns a\n // Function's own runnability separately — not duplicated here).\n if (uses?.function) return null;\n if (!uses?.app || !uses?.action) return \"target missing\";\n const params = ctx.actionParamsByKey[`${uses.app}::${uses.action}`] ?? [];\n const values = step.with ?? {};\n if (!ctx.requiredParamsFilled(params, values)) return \"required params\";\n // The testRequired/saved-test branch applies only when `uses.app` is a real,\n // fetched app — an internal/trigger/control step's app is never a key in\n // `appsById`, so it is never gated on a saved test.\n if (uses.app in ctx.appsById && ctx.isTestRequired(ctx.appsById[uses.app])) {\n if (!ctx.testStatus[step.id]) return \"saved test\";\n }\n return null;\n}\n\n/** Is this one step valid, per the pinned predicate? */\nexport function stepValid(step: WorkflowStepLike, ctx: ValidityContext): boolean {\n return stepFailure(step, ctx) === null;\n}\n\n/**\n * Is the whole workflow valid? A trigger step must exist and every step must\n * be individually valid — nothing about graph well-formedness (this never\n * reads `workflow.edges`, even when present).\n */\nexport function workflowValid(workflow: WorkflowLike, ctx: ValidityContext): boolean {\n if (!ctx.hasTrigger) return false;\n return (workflow.steps ?? []).every((step) => stepValid(step, ctx));\n}\n\n/**\n * `null` when the workflow is valid; otherwise names the cause — `\"no trigger\n * step\"`, or the id of the first invalid step in declared order plus which\n * check it fails.\n */\nexport function invalidReason(workflow: WorkflowLike, ctx: ValidityContext): string | null {\n if (!ctx.hasTrigger) return \"no trigger step\";\n for (const step of workflow.steps ?? []) {\n const failure = stepFailure(step, ctx);\n if (failure) return `${step.id}: ${failure}`;\n }\n return null;\n}\n","/**\n * The pure decisions behind a workflow's `variables` list (T1.1.5) — the\n * Variables tab's authoring surface and the run page's generated-form\n * projection. `variables` rides inside the workflow **definition**\n * (`w6w-workflow/packages/types/mod.ts:170`), the same JSON document that\n * already carries `steps`, so there is no column, no migration and no server\n * change behind it.\n *\n * Pure, React-free, `.ts`, **no value import of `@w6w/ui`** — studio's\n * `test:unit` is a bare `node --test` with no jsx loader\n * (`studio/package.json:17`), so a value import of the barrel (which\n * re-exports `.tsx`) kills the test. Same shape as `workflow-settings.ts`'s\n * reader/writer discipline and `input-seeding.ts`'s pure-module docstring\n * rule.\n *\n * The row type is defined **locally**, structurally identical to\n * `WorkflowVariable` (`w6w-workflow/packages/types/mod.ts:40-45`: `key`,\n * `type?`, `required?`, `default?`), so no cast is needed at the `.tsx`\n * boundary in either direction.\n */\n\n/** One row of a workflow's declared `variables` list. */\nexport interface WorkflowVariableRow {\n key: string;\n type?: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n required?: boolean;\n default?: unknown;\n}\n\n/** The declared type union `WorkflowVariable.type` accepts. */\nconst VARIABLE_TYPES = new Set([\"string\", \"number\", \"boolean\", \"object\", \"array\"]);\n\n/**\n * Read a workflow definition's `variables` field as an array of rows.\n *\n * Takes `unknown` because the source is `JSON.parse`d and the `</>` editor\n * lets an author type anything: a non-array reads as no variables, and a\n * non-object array entry is dropped rather than crashing the tab. **Never\n * sorts, never de-dups, never re-orders** — declaration order *is*\n * resolution order (D-5) and `resolveVariables` iterates the array in order\n * (`w6w-workflow/packages/engine/src/run.ts:70-83`), so two rows sharing a\n * key both survive, in the order they were declared.\n */\nexport function readVariables(raw: unknown): WorkflowVariableRow[] {\n if (!Array.isArray(raw)) return [];\n const out: WorkflowVariableRow[] = [];\n for (const entry of raw) {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) continue;\n const e = entry as Record<string, unknown>;\n const row: WorkflowVariableRow = { key: typeof e.key === \"string\" ? e.key : \"\" };\n if (typeof e.type === \"string\" && VARIABLE_TYPES.has(e.type)) {\n row.type = e.type as WorkflowVariableRow[\"type\"];\n }\n if (typeof e.required === \"boolean\") row.required = e.required;\n if (e.default !== undefined) row.default = e.default;\n out.push(row);\n }\n return out;\n}\n\n/**\n * The rows ready to write back into the definition's `variables` field.\n *\n * Mirrors `workflow-settings.ts`'s \"default written as absent\" rule, but here\n * it applies to a row's **optional flags, not the value**: `required` is\n * omitted when `false` and `type` is omitted when unset, so opening the tab\n * and touching nothing does not rewrite a legacy definition into\n * `{required:false,type:undefined}` rows. `default` is user data and is kept\n * **verbatim** — including `false`, `0`, `\"\"` and `null` — never dropped as\n * an optimisation (a \"drop falsy\" implementation would lose a `false`\n * default, which is exactly the case the tests pin).\n *\n * Returns `undefined` for an empty array (never `[]`) so the caller\n * (`patchMeta`, via `JSON.stringify`) drops the key entirely — which matters\n * beyond hygiene here: `draftFromWorkflowVariables`\n * (`server/packages/api/mcp/tool-schema.ts:310-326`) treats `undefined` and\n * `length === 0` identically (pass-through), so `[]` and absent already agree\n * on the wire; this just keeps the definition itself from growing an empty\n * `\"variables\": []` on the first open of the tab.\n */\nexport function variablesForSave(rows: WorkflowVariableRow[]): WorkflowVariableRow[] | undefined {\n if (rows.length === 0) return undefined;\n return rows.map((r) => {\n const out: WorkflowVariableRow = { key: r.key };\n if (r.type !== undefined) out.type = r.type;\n if (r.required) out.required = true;\n if (r.default !== undefined) out.default = r.default;\n return out;\n });\n}\n\n/**\n * Every index whose `key` repeats an earlier row's key. `resolveVariables`\n * writes `vars[v.key]` in a loop with no duplicate check (`run.ts:74-80`), so\n * a later row silently wins — this is informational only (the tab marks the\n * row; nothing here blocks a save), never de-duping or rejecting.\n */\nexport function duplicateKeyIndexes(rows: WorkflowVariableRow[]): number[] {\n const seen = new Set<string>();\n const out: number[] = [];\n rows.forEach((r, i) => {\n if (seen.has(r.key)) out.push(i);\n else seen.add(r.key);\n });\n return out;\n}\n\n/**\n * The `vars.*` names to offer row `index`'s expression rail: the keys of\n * rows **strictly above** it, then `projectVars`, deduped, with blanks\n * dropped. Declaration order is resolution order (D-5), so a row can only\n * reference a variable declared earlier than itself — offering a row at or\n * below `index` would suggest a forward reference the engine rejects\n * (T2.1.1). This is the offered rail only; it is not validation.\n */\nexport function varsRailFor(\n rows: WorkflowVariableRow[],\n index: number,\n projectVars: string[],\n): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const k of [...rows.slice(0, index).map((r) => r.key), ...projectVars]) {\n if (k === \"\" || seen.has(k)) continue;\n seen.add(k);\n out.push(k);\n }\n return out;\n}\n\n/** `true` if `v` is an `ExprValue` envelope — the two-key check `@w6w/ui`'s\n * `isExprValue` (`ui/src/types.ts:301-309`) makes, re-implemented locally\n * because this module cannot import `@w6w/ui` at value level (see the\n * module docstring). Mirrors `trigger-preview.ts:102-119`'s sanctioned\n * pattern for the same constraint — this is not duplication. */\nexport function isExprDefault(v: unknown): boolean {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !Array.isArray(v) &&\n (v as { type?: unknown }).type === \"expr\" &&\n Array.isArray((v as { parts?: unknown }).parts)\n );\n}\n\n/** One field the run page's generated form fills — structurally assignable\n * to `@w6w/ui/flow`'s `TriggerFieldDef` (all fields optional) with no cast. */\nexport interface RunFormField {\n key: string;\n type?: WorkflowVariableRow[\"type\"];\n default?: unknown;\n required?: boolean;\n}\n\n/**\n * Project a workflow's declared variables into the run page's form fields.\n *\n * A row whose `default` is an `ExprValue` envelope is a server-side\n * computation (its value is resolved at run time, not authored on the\n * client), so it is emitted with **`default` dropped and `required: false`**\n * — never as a value `ui`'s `seedValues` would `String(...)` the envelope\n * into — and its key is listed in `computed` so the host can label the field\n * \"computed at run time\" and post nothing for it. A row with a blank/missing\n * key is dropped, mirroring `@w6w/ui`'s `fieldsToParams`, which does the same\n * before turning field definitions into a fillable form.\n */\nexport function runFormFields(rows: WorkflowVariableRow[]): {\n fields: RunFormField[];\n computed: string[];\n} {\n const fields: RunFormField[] = [];\n const computed: string[] = [];\n for (const r of rows) {\n if (r.key.trim() === \"\") continue;\n if (isExprDefault(r.default)) {\n fields.push({ key: r.key, type: r.type, required: false });\n computed.push(r.key);\n continue;\n }\n fields.push({ key: r.key, type: r.type, default: r.default, required: r.required });\n }\n return { fields, computed };\n}\n","/**\n * The two pure decisions behind a workflow's authoring settings\n * (`rfcs/workflow.md` — \"Amendment — 2026-07-29: authoring presentation\").\n *\n * `settings` rides inside the workflow **definition** — the same JSON document\n * that already carries `steps` — so there is no column, no migration and no\n * server change behind it. What needs pinning is not the storage but the two\n * readings that can silently corrupt a definition, and both live here rather\n * than in `WorkflowsPage.tsx` so they are executable: that file is JSX, which\n * Node 24's type-stripping cannot parse, so nothing in it can be loaded by\n * `node --test`. Same shape as `src/lib/workflow-save.ts` + its `.test.ts`.\n */\nimport type { WorkflowStatus } from \"@w6w/sdk\";\n\n/**\n * Read a workflow definition's `status` field as the real three-state value.\n *\n * `WorkflowsPage.tsx` used to coerce this with `status === \"active\" ? \"active\" :\n * \"draft\"` — a two-way ternary that silently collapsed a freshly-archived\n * workflow back down to `\"draft\"`, which would have reproduced the same bug one\n * layer up in the archive/delete button-swap (an archived workflow would render\n * Archive again instead of Delete). `unknown` because the source is parsed JSON,\n * not a validated value — anything that isn't exactly `\"active\"` or `\"archived\"`\n * reads as `\"draft\"`, same fallback the old coercion used for a missing/garbage\n * status.\n */\nexport function readWorkflowStatus(status: unknown): WorkflowStatus {\n if (status === \"active\" || status === \"archived\") return status;\n return \"draft\";\n}\n\n/** Authoring presentation for one workflow. Declarative only — the engine ignores it. */\nexport type WorkflowSettings = {\n /** Persist edits without an explicit save. Omitted ⇒ **true**. */\n autoSave?: boolean;\n /** Persist step coordinates and `viewport` on save. Omitted ⇒ **true**. */\n savePosition?: boolean;\n /** The canvas camera, written by the editor — never by the settings modal. */\n viewport?: { x: number; y: number; zoom: number };\n};\n\n/** Both flags resolved against their defaults. */\nexport type EffectiveWorkflowSettings = {\n autoSave: boolean;\n savePosition: boolean;\n};\n\n/**\n * The effective flags for a workflow, applying the **true-by-default** rule.\n *\n * ⚠️ Both flags are `true` when omitted. That is deliberately *unlike* the house\n * convention `ports` and `onError` follow, where an absent field reproduces\n * prior behaviour: here the product requires both features on by default, so an\n * absent `settings` object means auto-save **on** and positions **persisted**.\n * The RFC states it three ways and names `?? false` as a contradiction. Only an\n * explicit `false` turns a feature off — hence `!== false`, which also refuses\n * to read `null`, `0` or `\"false\"` out of a hand-edited definition as \"off\".\n *\n * Takes `unknown` because the caller's source is parsed JSON, not a validated\n * value; every non-object reads as \"no flags set\", i.e. both on.\n */\nexport function readSettings(settings: unknown): EffectiveWorkflowSettings {\n const s = settings as WorkflowSettings | undefined;\n return {\n autoSave: s?.autoSave !== false,\n savePosition: s?.savePosition !== false,\n };\n}\n\n/**\n * Set one flag, returning the `settings` object to store.\n *\n * Two rules, both about *not* writing more than was asked:\n *\n * 1. **The default is written as absent.** `true` deletes the key instead of\n * storing `autoSave: true` (the same idiom as an omitted `onError: \"fail\"`).\n * Otherwise merely opening this modal on a legacy workflow and toggling\n * something back would rewrite the definition of every workflow ever\n * authored — and with auto-save on, that write happens by itself.\n * 2. **Everything else survives verbatim**, `viewport` above all: it is the\n * author's saved camera, written by the editor, and a whole-object replace\n * here would silently discard it on the next toggle.\n *\n * Returns `undefined` when nothing is left to store, so the caller drops the\n * key entirely rather than persisting an empty object.\n *\n * The input is `unknown` for the same reason `readSettings`' is — it comes straight\n * out of `JSON.parse`, and the `</>` editor in the very same header lets an author\n * write `\"settings\": \"hello\"`. Spreading that would persist `{\"0\":\"h\",\"1\":\"e\",…}`,\n * and with auto-save on the rewrite would repeat on a debounce, without anyone\n * clicking anything. So anything that is not a plain object reads as \"no flags\n * set\", exactly as it does in `readSettings`.\n */\nexport function writeSetting(\n settings: unknown,\n key: \"autoSave\" | \"savePosition\",\n value: boolean,\n): WorkflowSettings | undefined {\n const prev: WorkflowSettings | undefined =\n typeof settings === \"object\" && settings !== null && !Array.isArray(settings)\n ? (settings as WorkflowSettings)\n : undefined;\n // The copy is load-bearing: a debounced saver keeps payloads across ticks, so a\n // function that mutated `prev` in place would leave a \"has this actually changed?\"\n // comparison looking at one object twice. Never simplify this to `prev ?? {}`.\n const next: WorkflowSettings = { ...prev };\n if (value) delete next[key];\n else next[key] = false;\n return Object.keys(next).length === 0 ? undefined : next;\n}\n","/**\n * \"Call from code\" trigger preview (T2.2.1, HITL-2/HITL-4 pinned):\n *\n * > one tab per MANUAL (`@w6w/trigger`) trigger step, in declared order,\n * > labelled `step.displayName ?? step.id`. Webhook/scheduler steps are\n * > excluded — they declare named params, never a generic `fields` array.\n *\n * Pure and testable by design, same shape as `workflow-validity.ts`:\n * `WorkflowDetailPage.tsx`/`WorkflowsPage.tsx` are JSX, which Node 24's\n * type-stripping cannot parse, so nothing in it can be loaded by\n * `node --test`. This module cannot import `@w6w/ui`/`@w6w/ui/flow` either\n * way (`ERR_UNKNOWN_FILE_EXTENSION` — see `workflow-validity.ts`'s docstring).\n * Instead, \"is this step a MANUAL trigger\" and \"read a trigger's declared\n * `fields`\" are **caller-injected** on `TriggerPreviewContext` —\n * `WorkflowsPage.tsx`/`WorkflowDetailPage.tsx` import the real\n * `TRIGGER_APP`/`asFieldDefs` from `@w6w/ui/flow` and pass them in. This file\n * contains no `@w6w/*` app-id string literal.\n *\n * Deliberately narrower than `@w6w/ui/flow`'s own `isTriggerApp`, which also\n * matches `@w6w/webhook`/`@w6w/scheduler` (all three are \"entry nodes\" for the\n * canvas). Those two kinds declare named params, not a generic `fields`\n * array, so they cannot be previewed the same way — the injected predicate a\n * caller supplies here is expected to be the MANUAL-only check\n * (`app === TRIGGER_APP`), not the broader `isTriggerApp`.\n */\n\n/** One field a trigger declares — just enough of `@w6w/ui/flow`'s\n * `TriggerFieldDef` for this preview (structurally compatible, not imported). */\nexport interface TriggerPreviewFieldDef {\n key?: string;\n type?: string;\n required?: boolean;\n default?: unknown;\n}\n\n/** A workflow graph step, just enough of it for this preview. */\nexport interface WorkflowStepLike {\n id: string;\n /** Human-facing step name, when the author set one. Falls back to `id`. */\n displayName?: string;\n uses?: { app?: string; action?: string };\n with?: Record<string, unknown>;\n}\n\n/** A workflow definition, just enough of it for this preview. */\nexport interface WorkflowLike {\n steps?: WorkflowStepLike[];\n}\n\n/**\n * Everything `triggerPreviews` needs that this pure module cannot compute or\n * import itself — see the module docstring for why each field is\n * caller-injected rather than derived in here.\n */\nexport interface TriggerPreviewContext {\n /** Is this step's `uses.app` a MANUAL trigger (`@w6w/trigger`)? Webhook and\n * scheduler steps must answer `false` here even though they are also\n * \"entry nodes\" — they have no generic `fields` array to preview. */\n isManualTrigger: (app: string) => boolean;\n /** `@w6w/ui/flow`'s `asFieldDefs`, injected — reads a step's `with.fields`\n * param value as an array of field definitions. */\n asFieldDefs: (fields: unknown) => TriggerPreviewFieldDef[];\n}\n\n/** One manual trigger's declared fields, ready for the modal's picker. */\nexport interface TriggerPreview {\n id: string;\n /** `step.displayName ?? step.id`. */\n label: string;\n fields: TriggerPreviewFieldDef[];\n}\n\n/**\n * One `TriggerPreview` per manual trigger step in `workflow.steps`, in\n * declared order. Non-manual steps (including webhook/scheduler entry nodes)\n * are excluded. A field with a missing/blank `key` is dropped — mirrors\n * `@w6w/ui/flow`'s `fieldsToParams`, which does the same before turning\n * `TriggerFieldDef[]` into a fillable form.\n */\nexport function triggerPreviews(\n workflow: WorkflowLike,\n ctx: TriggerPreviewContext,\n): TriggerPreview[] {\n const steps = workflow.steps ?? [];\n const previews: TriggerPreview[] = [];\n for (const step of steps) {\n const app = step.uses?.app;\n if (!app || !ctx.isManualTrigger(app)) continue;\n const fields = ctx\n .asFieldDefs(step.with?.fields)\n .filter((f) => typeof f.key === \"string\" && f.key.trim() !== \"\");\n previews.push({ id: step.id, label: step.displayName ?? step.id, fields });\n }\n return previews;\n}\n\n/**\n * A start-payload skeleton for one manual trigger — every declared field at its\n * declared default, so the Run panel opens with the shape the workflow actually\n * expects instead of an empty object the author has to reconstruct by hand.\n *\n * Mirrors `@w6w/ui/flow`'s `seedValues` (which this module cannot import — see\n * the header): an explicit `default` wins; otherwise the empty value for the\n * declared type. Unknown types fall to `\"\"`, matching that function.\n *\n * `undefined` in → `{}`, so a caller can pass a still-loading preview.\n */\nexport function triggerInputSeed(preview: TriggerPreview | undefined): Record<string, unknown> {\n const seed: Record<string, unknown> = {};\n for (const f of preview?.fields ?? []) {\n if (typeof f.key !== \"string\" || f.key.trim() === \"\") continue;\n if (f.default !== undefined) {\n seed[f.key] = f.default;\n continue;\n }\n seed[f.key] = f.type === \"number\" ? 0 : f.type === \"boolean\" ? false : \"\";\n }\n return seed;\n}\n"],"names":["stepFailure","step","ctx","uses","params","values","stepValid","workflowValid","workflow","invalidReason","failure","VARIABLE_TYPES","readVariables","raw","out","entry","e","row","variablesForSave","rows","r","duplicateKeyIndexes","seen","varsRailFor","index","projectVars","k","isExprDefault","v","runFormFields","fields","computed","readWorkflowStatus","status","readSettings","settings","s","writeSetting","key","value","next","triggerPreviews","_a","_b","steps","previews","app","f","triggerInputSeed","preview","seed"],"mappings":"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"}
|