@w6w/embed 0.2.0 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/{ConfirmModal-RLbZT5_k.js → ConfirmModal-BE-SdX-O.js} +53 -49
  2. package/dist/{ConfirmModal-RLbZT5_k.js.map → ConfirmModal-BE-SdX-O.js.map} +1 -1
  3. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-D6CQLpa_.js} +25 -25
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-D6CQLpa_.js.map} +1 -1
  5. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-YauVdolr.js} +5 -5
  6. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-YauVdolr.js.map} +1 -1
  7. package/dist/{ImportSpecModal-BDQIf6rg.js → ImportSpecModal-B7qd1Km2.js} +3 -3
  8. package/dist/{ImportSpecModal-BDQIf6rg.js.map → ImportSpecModal-B7qd1Km2.js.map} +1 -1
  9. package/dist/ModelRoutesManager-BGESQahw.js +345 -0
  10. package/dist/ModelRoutesManager-BGESQahw.js.map +1 -0
  11. package/dist/WorkflowEditor-CwvmAGp2.js +925 -0
  12. package/dist/WorkflowEditor-CwvmAGp2.js.map +1 -0
  13. package/dist/{apps-1FNUwbGv.js → apps-CboASBKr.js} +14 -14
  14. package/dist/{apps-1FNUwbGv.js.map → apps-CboASBKr.js.map} +1 -1
  15. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  16. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  17. package/dist/chrome/ConfirmModal.d.ts +4 -1
  18. package/dist/chrome/workspace.d.ts +4 -0
  19. package/dist/{coerce-input-BicYr7nc.js → coerce-input-DttlcSdO.js} +70 -58
  20. package/dist/coerce-input-DttlcSdO.js.map +1 -0
  21. package/dist/connections-D7cgXhDS.js +119 -0
  22. package/dist/connections-D7cgXhDS.js.map +1 -0
  23. package/dist/credentials-DaQU3Ca_.js +171 -0
  24. package/dist/credentials-DaQU3Ca_.js.map +1 -0
  25. package/dist/document-sources-UCwe8x77.js +91 -0
  26. package/dist/document-sources-UCwe8x77.js.map +1 -0
  27. package/dist/draft.mjs +1 -1
  28. package/dist/editor/BindingBanner.d.ts +13 -0
  29. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  30. package/dist/editor/EndpointCards.d.ts +4 -1
  31. package/dist/editor/PublishControl.d.ts +19 -0
  32. package/dist/editor/TargetSelector.d.ts +15 -0
  33. package/dist/editor/TargetSelector.types.d.ts +2 -0
  34. package/dist/editor/definition.d.ts +2 -0
  35. package/dist/{editor-apps-BdenSV1o.js → editor-apps-BUZWld-m.js} +5 -5
  36. package/dist/{editor-apps-BdenSV1o.js.map → editor-apps-BUZWld-m.js.map} +1 -1
  37. package/dist/{editor-tools-RxmY5iyi.js → editor-tools-B_Lfx3kw.js} +11 -11
  38. package/dist/editor-tools-B_Lfx3kw.js.map +1 -0
  39. package/dist/editor.mjs +1 -1
  40. package/dist/editors.mjs +769 -622
  41. package/dist/editors.mjs.map +1 -1
  42. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  43. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  44. package/dist/fields-DvS8XZFc.js +21 -0
  45. package/dist/fields-DvS8XZFc.js.map +1 -0
  46. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  47. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  48. package/dist/forms.d.ts +4 -0
  49. package/dist/forms.mjs +611 -212
  50. package/dist/forms.mjs.map +1 -1
  51. package/dist/index.mjs +119 -112
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/lib/binding-problems.d.ts +38 -0
  54. package/dist/lib/code-rail.d.ts +4 -2
  55. package/dist/lib/index.d.ts +1 -0
  56. package/dist/lib/invoke-error.d.ts +1 -0
  57. package/dist/lib/sdk-snippets.d.ts +1 -1
  58. package/dist/lib/target-fields.d.ts +8 -0
  59. package/dist/lib/trigger-preview.d.ts +1 -0
  60. package/dist/lib/workflow-live-run.d.ts +9 -2
  61. package/dist/lib/workflow-nodes.d.ts +5 -0
  62. package/dist/lib/workflow-validity.d.ts +1 -0
  63. package/dist/lib.mjs +72 -70
  64. package/dist/lists/ConnectionDependents.d.ts +31 -0
  65. package/dist/lists/ConnectionDetail.d.ts +4 -1
  66. package/dist/lists/ConnectionList.d.ts +4 -1
  67. package/dist/lists/CredentialDetail.d.ts +15 -0
  68. package/dist/lists/CredentialList.d.ts +14 -0
  69. package/dist/lists/ModelCatalog.d.ts +12 -0
  70. package/dist/lists/ModelUsage.d.ts +12 -0
  71. package/dist/lists.d.ts +8 -0
  72. package/dist/lists.mjs +1322 -604
  73. package/dist/lists.mjs.map +1 -1
  74. package/dist/models-bAayQPJ_.js +270 -0
  75. package/dist/models-bAayQPJ_.js.map +1 -0
  76. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  77. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  78. package/dist/rail.mjs +4 -4
  79. package/dist/repos/agents-studio-agents.d.ts +52 -0
  80. package/dist/repos/agents-studio-assets.d.ts +68 -0
  81. package/dist/repos/connections.d.ts +30 -12
  82. package/dist/repos/credentials.d.ts +83 -0
  83. package/dist/repos/endpoints.d.ts +9 -3
  84. package/dist/repos/fields.d.ts +34 -0
  85. package/dist/repos/functions.d.ts +7 -5
  86. package/dist/repos/index.d.ts +5 -0
  87. package/dist/repos/models.d.ts +289 -0
  88. package/dist/repos.mjs +613 -176
  89. package/dist/repos.mjs.map +1 -1
  90. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  91. package/dist/slug-BVdgiP_L.js.map +1 -0
  92. package/dist/{spec-export-Cf3VQSQS.js → spec-export-CBbloO_n.js} +7 -7
  93. package/dist/{spec-export-Cf3VQSQS.js.map → spec-export-CBbloO_n.js.map} +1 -1
  94. package/dist/{spec-import-CjmxyZDR.js → spec-import-CW6R_Wk1.js} +160 -156
  95. package/dist/spec-import-CW6R_Wk1.js.map +1 -0
  96. package/dist/theme-context-E2ZhlXDX.js +6 -0
  97. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  98. package/dist/theme-context.d.ts +2 -0
  99. package/dist/trigger-preview-DKxfjzUY.js +145 -0
  100. package/dist/trigger-preview-DKxfjzUY.js.map +1 -0
  101. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DsALnSfF.js} +22 -22
  102. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DsALnSfF.js.map} +1 -1
  103. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  104. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  105. package/package.json +1 -1
  106. package/src/styles.css +2 -6
  107. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  108. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  109. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  110. package/dist/connections-CjjYeRqb.js +0 -78
  111. package/dist/connections-CjjYeRqb.js.map +0 -1
  112. package/dist/document-sources-C0grrtdq.js +0 -86
  113. package/dist/document-sources-C0grrtdq.js.map +0 -1
  114. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  115. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  116. package/dist/slug-C4ktDPdy.js.map +0 -1
  117. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  118. package/dist/trigger-preview-VPkrryDl.js +0 -120
  119. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor-tools-RxmY5iyi.js","sources":["../src/chrome/workspace.tsx","../src/chrome/RightRail.tsx","../src/rail/ExpressionScope.tsx","../src/rail/CodeTool.tsx","../src/rail/rail-env.tsx","../src/rail/ErrorHandlingTool.tsx","../src/lib/tag-editor.ts","../src/chrome/TagEditor.tsx","../src/chrome/CallableSettingsModal.tsx","../src/chrome/VersionHistoryModal.tsx","../src/chrome/DangerZone.tsx","../src/rail/settings-sections.tsx","../src/rail/SettingsTool.tsx","../src/rail/editor-tools.ts"],"sourcesContent":["import type { CallablePolicy, SnippetInput, TriggerPreview } from \"@w6w/embed/lib\";\n/**\n * `WorkspaceContext` — what resource (if any) the currently-viewed page has\n * open. The right rail (`chrome/RightRail.tsx`) and every registered\n * `RailTool`'s `Panel` read this via `useWorkspaceCallable`; a page publishes\n * into it via `useWorkspace`.\n *\n * Route-scoped, not root-scoped — mirrors `ProjectContext.tsx`'s precedent\n * (the only other context in this codebase deliberately scoped below the app\n * root): mounted around `Layout()`'s own returned tree (`components/Layout.tsx`),\n * next to its only reader, the rail.\n *\n * The publish idiom (compute a value during render, `useEffect` keyed on a\n * stable serialization of it, clear on unmount) mirrors the shape of the\n * human's uncommitted `src/ui/useDocumentTitle.ts` — copied here as a\n * PATTERN, never imported: that file is one of this project's 23 uncommitted\n * human files and a merged branch cannot depend on it.\n */\nimport { type ReactNode, createContext, useContext, useEffect, useMemo, useState } from \"react\";\n\n/**\n * T2.1.2: widened to a discriminated union, one arm per kind — every new\n * field OPTIONAL, no new required member, so every existing producer keeps\n * compiling and behaving identically (`{kind, id}` alone still satisfies any\n * arm). The extra fields are what `CodeTool`'s snippet panel needs per kind\n * (mirrors `lib/sdk-snippets.ts`'s `SnippetCallable`, field-for-field where\n * the names match — see `lib/code-rail.ts`'s `toSnippetCallable` for the one\n * field that doesn't, `label` -> `displayName`).\n */\nexport type WorkspaceCallable =\n | {\n kind: \"function\";\n id: string;\n label?: string;\n key?: string;\n inputs?: readonly SnippetInput[];\n alias?: string;\n /**\n * The Function's / Endpoint's run-level error policy and its writer, published by an\n * editor that owns the definition buffer (`useCallableDraft`) so the rail's Error handling\n * tool edits and saves THAT buffer (pending edits ride along) instead of racing it. Same\n * ⚠️ as the workflow arm: `onPolicyChange` MUST be referentially stable\n * (`useCallableDraft`'s is).\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | {\n kind: \"endpoint\";\n id: string;\n label?: string;\n key?: string;\n invokeUrl?: string;\n invokeUrlByKey?: string;\n urlForm?: \"id\" | \"key\";\n alias?: string;\n inputs?: readonly SnippetInput[];\n /**\n * The Function's / Endpoint's run-level error policy and its writer, published by an\n * editor that owns the definition buffer (`useCallableDraft`) so the rail's Error handling\n * tool edits and saves THAT buffer (pending edits ride along) instead of racing it. Same\n * ⚠️ as the workflow arm: `onPolicyChange` MUST be referentially stable\n * (`useCallableDraft`'s is).\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | {\n kind: \"workflow\";\n id: string;\n label?: string;\n key?: string;\n triggers?: TriggerPreview[];\n /**\n * The workflow's run-level error policy, and the writer that applies it\n * (core Workflow RFC — *Amendment — 2026-08-21: the run-level error\n * handler*). Published ONLY by the page that owns the definition buffer\n * — the canvas editor — so the rail's Error handling tool edits the same\n * text the editor is about to save instead of racing it over the wire.\n * `ErrorHandlingTool` is the only reader; see `lib/settings-rail.ts`'s\n * `isAvailable` for why the tool hides itself when they are absent.\n *\n * ⚠️ `onPolicyChange` MUST be referentially stable across renders (a\n * `useCallback` reading through a ref). `useWorkspace` keys its publish\n * effect on `JSON.stringify(resource)`, which drops functions — so the\n * stored callback is whichever one was current when some OTHER field\n * last changed, and a closure that captured stale editor state would\n * write stale bytes.\n */\n policy?: CallablePolicy;\n onPolicyChange?: (policy: CallablePolicy) => void;\n }\n | { kind: \"connection\"; id: string; label?: string }\n | null;\n\n/** Derived from {@link WorkspaceCallable}, never redeclared — the arm a\n * `RailTool.isAvailable`/route wrapper narrows on. */\nexport type WorkspaceKind = Exclude<WorkspaceCallable, null>[\"kind\"];\n\ninterface WorkspaceContextValue {\n resource: WorkspaceCallable;\n /** Publishes the OVERRIDE slot; `null` clears it, which restores the provider's `base`. */\n setCallable: (resource: WorkspaceCallable) => void;\n}\n\nconst WorkspaceContext = createContext<WorkspaceContextValue | null>(null);\n\n/**\n * Two layers: `base` (a prop — the host-owned `{kind, id}` a `<CallableWorkspace>` publishes) and\n * an override (what a mounted page publishes with `useWorkspace`). The override wins while it is\n * set; when its publisher unmounts it is cleared and the base is shown again — never empty. With no\n * `base` (Studio's layout, the editor's own nested provider) the behaviour is exactly the old\n * single-slot one: override or `null`.\n */\nexport function WorkspaceProvider({\n children,\n base = null,\n}: { children: ReactNode; base?: WorkspaceCallable }) {\n const [override, setCallable] = useState<WorkspaceCallable>(null);\n const resource = override ?? base;\n const value = useMemo(() => ({ resource, setCallable }), [resource]);\n return <WorkspaceContext.Provider value={value}>{children}</WorkspaceContext.Provider>;\n}\n\n/** Non-throwing probe: is there an enclosing {@link WorkspaceProvider}? */\nexport function useHasWorkspace(): boolean {\n return useContext(WorkspaceContext) !== null;\n}\n\n/** Publisher. Compute during render, effect-write, clear on unmount. */\nexport function useWorkspace(resource: WorkspaceCallable): void {\n const ctx = useContext(WorkspaceContext);\n if (!ctx) throw new Error(\"useWorkspace must be used within <WorkspaceProvider>\");\n const { setCallable } = ctx;\n // A stable serialization, not `resource` itself: a fresh object literal on\n // every render of the calling page (e.g. `{kind:\"workflow\", id}` rebuilt\n // each render) must not re-fire this effect every render — only a genuine\n // change to some field's VALUE should. T2.1.2: widened from a bespoke\n // `kind:id:label` template to a full `JSON.stringify` once the union grew\n // per-kind fields (`key`/`invokeUrl`/`invokeUrlByKey`/`urlForm`/`inputs`/\n // `triggers`) a caller can update after its first publish — e.g. the\n // Endpoint editor's id/key URL-form toggle or a picked tenant domain, both\n // of which change nothing about kind/id/label. A template keyed on\n // kind/id/label alone would miss those and leave `CodeTool`'s panel showing\n // the value from the FIRST render forever (same content -> same string ->\n // no re-fire, so this preserves the original's intent exactly, just over\n // every field instead of three of them).\n const key = resource ? JSON.stringify(resource) : \"\";\n // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on the stable serialized `key`, not `resource`'s object identity — see the comment above.\n useEffect(() => {\n setCallable(resource);\n return () => setCallable(null);\n }, [key, setCallable]);\n}\n\n/** Reader — used by the rail and by every tool `Panel`. Throws outside the provider. */\nexport function useWorkspaceCallable(): WorkspaceCallable {\n const ctx = useContext(WorkspaceContext);\n if (!ctx) throw new Error(\"useWorkspaceCallable must be used within <WorkspaceProvider>\");\n return ctx.resource;\n}\n","import { restoreRailState } from \"@w6w/embed/lib\";\n/**\n * Third `.workspace` grid column: a 48px strip of the tools it is handed plus, when one is open,\n * its panel. Iterates `tools` with a single `.map` — never a per-tool JSX branch — so adding a\n * tool is a registry append in the host (Studio: `StudioRightRail`), nothing here changes.\n */\nimport { type ComponentType, useEffect, useState } from \"react\";\nimport { type WorkspaceCallable, useWorkspaceCallable } from \"./workspace.tsx\";\n\nexport interface RailTool {\n /** Stable; used as the persisted `activeTool`. */\n id: string;\n /** Strip tooltip + panel heading. */\n title: string;\n /** The strip glyph, as a component — built-in tools render a 16×16 `<Icon name=\"…\" />`\n * from `@w6w/ui`'s shared set; a tool may bring its own glyph instead. A component,\n * not an `IconName`, so this seam never narrows to the shared set. */\n Icon: ComponentType;\n isAvailable(ctx: WorkspaceCallable): boolean;\n /** Panel renders its own heading when it includes section actions. */\n rendersHeading?: boolean;\n Panel: ComponentType<{ ctx: WorkspaceCallable }>;\n}\n\ninterface RailState {\n open: boolean;\n activeTool: string | null;\n}\n\nconst CLOSED: RailState = { open: false, activeTool: null };\n\n/**\n * T4.1.1/A2: every mount starts CLOSED, unconditionally — `open` is no\n * longer read out of storage at all (D-I0-2). `restoreRailState`\n * (`../lib/rail-settings.ts`) only ever returns `activeTool`; its return\n * type has no `open` member, so a pre-existing `{\"open\":true,…}` value\n * written before this task has nothing here to reopen the rail with.\n */\nfunction readStoredState(key: string): RailState {\n if (typeof localStorage === \"undefined\") return CLOSED;\n const raw = localStorage.getItem(key);\n const { activeTool } = restoreRailState(raw);\n return { open: false, activeTool };\n}\n\n/** Presentational: the strip + (when open) the active tool's panel. Shared by\n * the persisted and not-yet-persistable (pin 12) render paths below. */\nfunction RailShell({\n tools,\n ctx,\n state,\n onToggle,\n}: {\n tools: readonly RailTool[];\n ctx: WorkspaceCallable;\n state: RailState;\n onToggle: (id: string) => void;\n}) {\n const activeTool = state.open ? (tools.find((t) => t.id === state.activeTool) ?? null) : null;\n return (\n <aside className=\"right-rail\">\n <div className=\"right-rail-strip\">\n {tools.map((tool) => (\n <button\n key={tool.id}\n type=\"button\"\n data-testid={`rail-tool-${tool.id}`}\n className={`right-rail-tool-btn${activeTool?.id === tool.id ? \" active\" : \"\"}`}\n title={tool.title}\n aria-label={tool.title}\n aria-pressed={activeTool?.id === tool.id}\n onClick={() => onToggle(tool.id)}\n >\n <tool.Icon />\n </button>\n ))}\n </div>\n {activeTool && (\n <div className=\"right-rail-panel\" data-testid={`rail-panel-${activeTool.id}`}>\n {!activeTool.rendersHeading && (\n <div className=\"right-rail-panel-head\">\n <h3>{activeTool.title}</h3>\n </div>\n )}\n <activeTool.Panel ctx={ctx} />\n </div>\n )}\n </aside>\n );\n}\n\n/** Owns the persisted open/activeTool state. Split out from `RightRail` and\n * `key`ed on `storageKey` (pin 11/12): `currentProject` resolves from a\n * query, so a `useState` initializer that ran before it resolved would read\n * `w6w.rail.undefined.undefined`. `RightRail` renders this component only\n * once `storageKey` is non-null, and `key={storageKey}` forces a fresh\n * mount — and so a fresh synchronous read of the RESOLVED key — whenever the\n * account/project changes. */\nfunction PersistedRail({\n storageKey,\n tools,\n ctx,\n}: {\n storageKey: string;\n tools: readonly RailTool[];\n ctx: WorkspaceCallable;\n}) {\n const [state, setState] = useState<RailState>(() => readStoredState(storageKey));\n\n // A2: only `activeTool` is ever persisted — `open` is never written to\n // storage (D-I0-2), so a fresh mount always starts closed regardless of\n // whether the rail happened to be open when the tab last closed.\n useEffect(() => {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(storageKey, JSON.stringify({ activeTool: state.activeTool }));\n }, [storageKey, state.activeTool]);\n\n function onToggle(id: string) {\n setState((prev) =>\n prev.open && prev.activeTool === id\n ? { open: false, activeTool: id }\n : { open: true, activeTool: id },\n );\n }\n\n return <RailShell tools={tools} ctx={ctx} state={state} onToggle={onToggle} />;\n}\n\n/** `storageKey === null`: no key to persist under yet (pin 12) — the strip renders closed and\n * nothing is written to localStorage. No available tool ⇒ no rail element at all (C/D-C3). */\nexport function RightRail({\n tools,\n storageKey,\n}: {\n tools: readonly RailTool[];\n storageKey: string | null;\n}) {\n const ctx = useWorkspaceCallable();\n const available = tools.filter((t) => t.isAvailable(ctx));\n if (available.length === 0) return null;\n if (storageKey === null) {\n return <RailShell tools={available} ctx={ctx} state={CLOSED} onToggle={() => {}} />;\n }\n return <PersistedRail key={storageKey} storageKey={storageKey} tools={available} ctx={ctx} />;\n}\n","import { type ExpressionOptions, ExpressionOptionsProvider } from \"@w6w/ui\";\nimport type { ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport { documentSampleValues, projectDocumentSources } from \"../lib/document-sources.ts\";\n/**\n * The APP-LEVEL contribution to the ƒx expression scope — the rail every\n * expression editor starts from (Studio binds `project` to its `ProjectContext`; an embedder\n * passes its own, `null` disabling the project-scoped queries), wherever it is opened.\n *\n * ## Why this is a provider and not a hook each page calls\n *\n * The scope used to travel as an `exprOptions` PROP: each page built the same\n * ~40-line object and handed it to the one or two components it happened to\n * think of. Two things went wrong with that, and both are user-visible:\n *\n * 1. **A field the prop had not reached opened an empty editor.** On a\n * Function's Implementation card, the `ƒx` toggle on a mapping row offered\n * no variables, no secrets and no inputs — while the very same editor,\n * reached through that card's \"Change\" button, offered all of them,\n * because only the modal had been wrapped in a provider.\n * 2. **Five pages carried a copy of the same object.** `FunctionsPage`,\n * `EndpointsPage`, `AliasesPage`, `WorkflowsPage` and the connection\n * tester each restated vars, secrets, documents, `sampleValues`,\n * `sealSecret`, `createVar` and `createSecret` — because the only way to\n * add one page-specific key (`inputs`) was to restate the rest alongside\n * it.\n *\n * Mounted ONCE, inside `ProjectProvider` and around `Layout`, this fixes both:\n * every route inherits it, and a page contributes only what is genuinely its\n * own by nesting a second `ExpressionOptionsProvider` (which LAYERS — see that\n * component's own doc). A page's `inputs` therefore cannot reach a sibling\n * route or a region above it; navigating away drops it with the subtree.\n *\n * ## What belongs here, and what does not\n *\n * Here: anything true for the whole **project** — its variables, its secret\n * NAMES, its document keys, the sample values the Result pane previews against,\n * and the three host callbacks the picker's \"+ Add\"/seal affordances need.\n *\n * Not here: anything that is only true inside one editor. A Function's declared\n * `inputs`, an Endpoint's declared `input`, the upstream `steps` leading to one\n * workflow node — those are contributed by the page or the region that knows\n * about them, and must not be visible anywhere else.\n *\n * `ui` components stay pure (they never fetch): this is the host side, and only\n * names/refs cross the boundary — secret plaintext never reaches the client.\n */\nimport {\n useCreateSecretMutation,\n useCreateVarMutation,\n useDocumentsQuery,\n useSealSecret,\n useSecretsQuery,\n useVarsQuery,\n} from \"../repos/index.ts\";\n\n/**\n * The current project's expression sources, as an `ExpressionOptions`.\n *\n * Exported because a surface that renders OUTSIDE `ProjectExpressionScope` —\n * or one that needs the values themselves rather than the context — can still\n * build the same object. Inside the scope, prefer inheriting it.\n */\nexport function useProjectExpressionOptions(project: string | null): ExpressionOptions {\n const projectId = project;\n\n // Vars/secrets are subject-scoped (no project param on the secret list); the\n // vault list is masked name-only summaries, so nothing secret reaches the\n // client. Documents are project-scoped.\n const varsQuery = useVarsQuery(projectId ?? undefined, projectId != null);\n const secretsQuery = useSecretsQuery();\n const documentsQuery = useDocumentsQuery(projectId ?? undefined, projectId != null);\n const sealSecretFn = useSealSecret();\n // \"+ Add\" (T1.2.4): both mutations already invalidate the exact key their\n // `useQuery` reads (repos/vars.ts, repos/vault.ts), so a create's success\n // alone refreshes the rail — no refetch(), no local list state.\n const createVarMut = useCreateVarMutation();\n const createSecretMut = useCreateSecretMutation();\n\n return useMemo(\n () => ({\n vars: (varsQuery.data ?? []).map((v) => v.name),\n secrets: (secretsQuery.data ?? []).map((s) => s.name),\n // `document-sources.ts` owns the `format === \"json\"` gate and the raw\n // field enumeration — no parsing, no gate logic, and no filtering here\n // (A5c); `isRefSafeKey` filtering happens once, downstream, at the\n // modal's render site.\n documents: projectDocumentSources(documentsQuery.data ?? []),\n // Real project values so the ƒx Result preview substitutes them for\n // `vars.<name>` / `documents.<key>` / `documents.<key>.<field>` refs\n // instead of the raw template.\n sampleValues: {\n ...Object.fromEntries((varsQuery.data ?? []).map((v) => [`vars.${v.name}`, v.value])),\n ...documentSampleValues(documentsQuery.data ?? []),\n },\n sealSecret: sealSecretFn,\n // A created var carries the SAME project the read above carried (B3) —\n // it must land in the project whose rail asked for it. `type: \"string\"`\n // is pinned (a string type's `raw` passes through untouched) — the modal\n // has no type field.\n createVar: (input: { name: string; value: string; description?: string }) =>\n createVarMut\n .mutateAsync({\n input: {\n name: input.name,\n type: \"string\",\n value: input.value,\n description: input.description,\n },\n project: projectId ?? undefined,\n })\n .then(() => undefined),\n // Secrets carry NO project (B4) — `vault_secrets` has no `project`\n // column and the routes read no `?project=`. Plaintext in, the server\n // encrypts; the resolved value is referenced nowhere (B5).\n createSecret: (input: { name: string; value: string; description?: string }) =>\n createSecretMut\n .mutateAsync({ name: input.name, value: input.value, description: input.description })\n .then(() => undefined),\n }),\n [\n varsQuery.data,\n secretsQuery.data,\n documentsQuery.data,\n sealSecretFn,\n createVarMut.mutateAsync,\n createSecretMut.mutateAsync,\n projectId,\n ],\n );\n}\n\n/**\n * Provide the current project's expression sources to every route below.\n *\n * Mount once, inside `ProjectProvider` (it reads the active project) and around\n * `Layout` (so every page inherits). It contributes no `inputs` and no `steps`\n * on purpose — see the module doc.\n */\nexport function ProjectExpressionScope({\n project,\n children,\n}: {\n project: string | null;\n children: ReactNode;\n}) {\n const options = useProjectExpressionOptions(project);\n return <ExpressionOptionsProvider value={options}>{children}</ExpressionOptionsProvider>;\n}\n","import { Icon } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport {\n CallFromCodeBody,\n type SnippetTabId,\n snippetTabsFor,\n} from \"../chrome/CallFromCodeButton.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { isAvailable, toSnippetCallable } from \"../lib/code-rail.ts\";\nimport { unavailableReason } from \"../lib/sdk-snippets.ts\";\n/**\n * The Code tool — the right rail's second registered client of T3.1.1's\n * registry seam (`src/ui/railTools.ts`), and T2.1.2's \"use code\" move: the\n * page-header \"Call from code\" button on Functions/Endpoints/Workflow-detail/\n * the flow-editor canvas becomes this strip icon + panel instead.\n *\n * The two pure decisions — is a snippet meaningful for this context, and\n * what `SnippetCallable` it converts to — live in `./../lib/code-rail.ts` so\n * `node --test` can gate them. This module owns presentation only.\n *\n * The panel is a LANGUAGE PICKER, not a snippet. It used to render\n * `CallFromCodeBody` inline, and a snippet is not readable in a ~395px\n * column: it scrolled sideways, and wrapping it (the first fix) turned the\n * CLI snippet's deliberate `\\`-continuations into what reads as separate\n * commands. Both are symptoms of the same thing — the snippet needs width the\n * rail does not have.\n *\n * So the rail shows one icon per language the resource can be called in, and\n * each opens the full-width modal ALREADY ON THAT LANGUAGE: one click to the\n * thing you came for, rather than open-then-hunt-for-the-tab. The set of\n * languages comes from `snippetTabsFor`, the same filter the modal's own tab\n * strip applies, so the rail can never offer a language the modal would not.\n */\n\nfunction CodePanel({ ctx }: { ctx: WorkspaceCallable }) {\n // Which language the modal opens on, or `null` for closed. ONE piece of\n // state, not an `open` flag beside a `tab`: the two can never disagree, and\n // \"closed\" cannot carry a stale language into the next open.\n const [openTab, setOpenTab] = useState<SnippetTabId | null>(null);\n const snippetCallable = toSnippetCallable(ctx);\n // Defensive: `isAvailable` already keeps this tool off the strip for a\n // `ctx` this can't build a snippet for — mirrors `SettingsTool.tsx`'s own\n // note about `Panel` still needing to handle a ctx `isAvailable` would\n // have excluded (a persisted `activeTool` plus an in-app transition to a\n // non-publishing route can still render this Panel).\n if (!snippetCallable) return null;\n const triggers = ctx?.kind === \"workflow\" ? ctx.triggers : undefined;\n const tabs = snippetTabsFor(snippetCallable);\n\n // No languages means no snippet at all — say why, rather than draw an empty\n // row of icons. Same sentence the body itself would have shown.\n if (tabs.length === 0) return <p className=\"muted\">{unavailableReason(snippetCallable)}</p>;\n\n return (\n <div>\n {/* A LANGUAGE PICKER, not a snippet.\n\n The rail's panel is ~395px wide, and a snippet rendered into it was\n unreadable at that width — first because it scrolled sideways, then,\n once wrapped, because a wrapped shell command reads as two commands.\n Neither is fixable in 395px: the snippet needs the room.\n\n So the panel stops trying to show one. It shows the languages this\n resource can be called in, and each opens the full-width modal\n ALREADY ON THAT LANGUAGE — one click to the thing you came for,\n instead of open-then-hunt-for-the-tab. The languages come from\n `snippetTabsFor`, so a resource with no public URL simply has no curl\n icon rather than an icon that opens an empty tab.\n\n Still not the double-chrome `CallFromCodeButton.tsx`'s header warns\n about: that trap was wrapping the rail's own panel in a modal by\n DEFAULT. The panel is its own content here; the modal is opt-in. */}\n <p className=\"muted small\" style={{ marginTop: 0 }}>\n Call this from:\n </p>\n <div className=\"rail-code-langs\">\n {tabs.map(({ id, label, icon }) => (\n <button\n key={id}\n type=\"button\"\n className=\"rail-code-lang\"\n data-testid={`rail-code-lang-${id}`}\n title={`Show the ${label} snippet`}\n aria-label={`Show the ${label} snippet`}\n onClick={() => setOpenTab(id)}\n >\n <Icon name={icon} size={20} />\n <span>{label}</span>\n </button>\n ))}\n </div>\n\n {/* Conditionally rendered, so each open MOUNTS the body afresh and\n `initialTab` seeds it again — picking Python, closing, then picking\n Node lands on Node. A body kept mounted would keep the first pick. */}\n {openTab !== null && (\n <Modal title=\"Call from code\" wide onClose={() => setOpenTab(null)}>\n <div style={{ height: 450 }}>\n <CallFromCodeBody resource={snippetCallable} triggers={triggers} initialTab={openTab} />\n </div>\n </Modal>\n )}\n </div>\n );\n}\n\nfunction CodeToolIcon() {\n return <Icon name=\"code\" />;\n}\n\nexport const codeTool: RailTool = {\n id: \"code\",\n title: \"Code\",\n Icon: CodeToolIcon,\n isAvailable: (ctx) => isAvailable(ctx),\n Panel: CodePanel,\n};\n","/**\n * The rail's host environment — the two things a rail tool needs from the host that it cannot\n * own: which project the surface is looking at, and how to move the host somewhere after a\n * rail action (archive / delete land on the list; an import opens the imported row).\n *\n * Studio binds both to its router and `ProjectContext`; an embedder binds them to its own. A\n * rail tool never imports a router: it calls `onNavigate` with a target and the host decides what\n * that means. The default (no provider mounted) is inert — no project, navigation ignored — so a\n * tool rendered outside a provider cannot save into the wrong project or throw.\n *\n * `project` is passed through to every write VERBATIM; `null` means \"no project\", on which the\n * package hooks refuse to save (never a fallback to the account default, C/D-C2).\n */\nimport { type ReactNode, createContext, useContext } from \"react\";\nimport type { SpecImportKind } from \"../lib/spec-import-invalidation.ts\";\n\n/** Where the host should go after a rail action. */\nexport type RailNavigation =\n | { type: \"list\" }\n | { type: \"imported\"; kind: SpecImportKind; id: string };\n\nexport interface RailEnv {\n project: string | null;\n onNavigate(to: RailNavigation): void;\n}\n\nconst DEFAULT_ENV: RailEnv = { project: null, onNavigate: () => {} };\n\nconst RailEnvContext = createContext<RailEnv>(DEFAULT_ENV);\n\nexport function RailEnvProvider({\n project,\n onNavigate,\n children,\n}: RailEnv & { children: ReactNode }) {\n return (\n <RailEnvContext.Provider value={{ project, onNavigate }}>{children}</RailEnvContext.Provider>\n );\n}\n\nexport function useRailEnv(): RailEnv {\n return useContext(RailEnvContext);\n}\n","import { ApiError } from \"@w6w/sdk\";\n/**\n * The Error handling tool — the right rail's tool for choosing **what runs when a call fails**.\n *\n * It is a BUTTON, not a form. Clicking it opens the F-2.0 picker modal (`StepBuilderModal`) with\n * its Functions and Workflows tabs, and the pick becomes the resource's `reroute.target`. All\n * three handler shapes are offered: an app Action, a Function, or a Workflow.\n *\n * This module owns two things:\n * - `ErrorHandlerSection` — the shared body (picker, handler label lookup, self-decision,\n * retry / reroute fields and the inline error). It calls no definition query and no save\n * mutation: the caller hands in the `policy` it read and an `onPersist` that writes.\n * - `errorHandlingTool` — the registry entry for all three kinds. A Workflow, and a Function /\n * Endpoint whose editor published `ctx.onPolicyChange`, hand the policy back to the surface\n * that owns the definition buffer, which folds it into the JSON it is already saving (the\n * rail makes zero writes — racing an editor's own save is not an option, see\n * `lib/settings-rail.ts`'s `isAvailable`). A Function / Endpoint with NO published writer\n * reads the cached record (`callableRecord`) and read-modify-writes the whole definition\n * (`definitionWithPolicy`) through the guarded save with that record's `updatedAt`.\n *\n * For a Workflow this is the handler for the RUN AS A WHOLE (core Workflow RFC — *Amendment —\n * 2026-08-21: the run-level error handler*), which is a different question from a step's own\n * `onError` on the canvas and from an `Edge.when: \"error\"`. `retry` IS authored here, through\n * `@w6w/ui`'s `RetryPolicyFields` (core Workflow RFC R-2, \"one retry shape everywhere\").\n */\nimport { type BuiltStep, Icon, RetryPolicyFields, StepBuilderModal } from \"@w6w/ui\";\nimport { useEffect, useState } from \"react\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { callableRecord } from \"../lib/callable-record.ts\";\nimport { errorHandlerSelfDecision } from \"../lib/error-handler-self.ts\";\nimport {\n type CallablePolicy,\n isAvailable as isSettingsRailAvailable,\n policyFromDefinition,\n} from \"../lib/settings-rail.ts\";\nimport { definitionWithPolicy } from \"../lib/settings-rail.ts\";\nimport { useEndpointQuery, useGuardedSaveEndpointMutation } from \"../repos/endpoints.ts\";\nimport {\n useFunctionQuery,\n useFunctionsQuery,\n useGuardedSaveFunctionMutation,\n} from \"../repos/functions.ts\";\nimport { useWorkflowsQuery } from \"../repos/workflows.ts\";\nimport { useRailEnv } from \"./rail-env.tsx\";\n\n/**\n * `@w6w/ui/flow`'s `CALL_APP`, restated: a VALUE import from the flow subpath would put the whole\n * canvas on the editor's eager path (the editor loads it with a dynamic `import()` only). A test\n * (`workflow-editor.test.ts`) pins the two spellings equal.\n */\nexport const CALL_APP = \"@w6w/call\";\n\ntype ErrorHandlerTarget = NonNullable<NonNullable<CallablePolicy[\"reroute\"]>[\"target\"]>;\n\nexport type ErrorHandlerKind = \"function\" | \"endpoint\" | \"workflow\";\n\n/** The id a handler target names, whichever of the three arms it is. */\nfunction refOf(target: ErrorHandlerTarget | undefined): string {\n if (!target) return \"\";\n if (target.kind === \"workflow\") return target.workflow;\n if (target.kind === \"function\") return target.function;\n return `${target.uses.app}/${target.uses.action}`;\n}\n\n/** The noun shown under a bound handler. */\nfunction nounOf(target: ErrorHandlerTarget | undefined): string {\n if (target?.kind === \"workflow\") return \"Workflow (asynchronous)\";\n if (target?.kind === \"function\") return \"Function (synchronous)\";\n return \"App action (synchronous)\";\n}\n\nexport interface ErrorHandlerSectionProps {\n kind: ErrorHandlerKind;\n id: string;\n /** The policy as currently stored (already read off the definition or buffer). */\n policy: CallablePolicy;\n /** The definition (or buffer) the policy was read from is present. */\n ready: boolean;\n saving: boolean;\n /** Write a whole new policy. `onError` shows a refusal inline. */\n onPersist(next: CallablePolicy, onError: (message: string) => void): void;\n}\n\nexport function ErrorHandlerSection({\n kind,\n id,\n policy,\n ready,\n saving,\n onPersist,\n}: ErrorHandlerSectionProps) {\n // Name the bound handler rather than showing a bare id. Both lists are already cached by the\n // picker itself, so this costs no extra round-trip in the common case.\n const functionsQuery = useFunctionsQuery(true);\n // The editor's project (RailEnv, as the Settings tool reads it), never the provider's default:\n // a project-less list would go out as the provider's project, not the one being edited.\n const { project } = useRailEnv();\n const workflowsQuery = useWorkflowsQuery(project ?? undefined, true);\n\n const [pickerOpen, setPickerOpen] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const target = policy.reroute?.target;\n const ref = refOf(target);\n const selfDecision = target\n ? errorHandlerSelfDecision({\n resource: { kind, id },\n target: { kind: target.kind, id: ref },\n hasAdapter: policy.reroute?.with !== undefined,\n })\n : \"allow\";\n const label =\n target?.kind === \"workflow\"\n ? (workflowsQuery.data?.find((w) => w.id === ref)?.displayName ?? undefined)\n : (() => {\n const fn = functionsQuery.data?.find((f) => f.id === ref);\n return fn ? fn.displayName || fn.key : undefined;\n })();\n\n // The rail remains mounted while its resource changes. A refusal belonging to the previous\n // resource must not obscure the current policy.\n useEffect(() => {\n if (id && kind) setError(null);\n }, [id, kind]);\n\n /** Persist a whole new policy — the one write path, shared by pick and clear. */\n function persist(next: CallablePolicy) {\n setError(null);\n onPersist(next, setError);\n }\n\n /**\n * The picker's `onAdd`. Two shapes reach here, because all three handler arms are offered:\n * - a callable → `{ uses: {app: \"@w6w/call\", …}, with: {targetKind, targetId} }`\n * - an action → `{ uses: {app, action, connection}, with }`\n * A graph-only internal node (`@w6w/script`, `@w6w/control`, …) is refused — `appsOnly` means no\n * such tab is rendered, but a `BuiltStep` is a wide type and a silent mis-write would be\n * invisible.\n */\n function pickHandler(built: BuiltStep) {\n let nextTarget: ErrorHandlerTarget;\n if (built.uses.app === CALL_APP) {\n const w = (built.with ?? {}) as { targetKind?: unknown; targetId?: unknown };\n const nextId = typeof w.targetId === \"string\" ? w.targetId : \"\";\n if (!nextId) return;\n nextTarget =\n w.targetKind === \"workflow\"\n ? { kind: \"workflow\", workflow: nextId }\n : { kind: \"function\", function: nextId };\n } else if (!built.uses.app.startsWith(\"@w6w/\")) {\n // The app arm. `with` is the action's own param map, straight from the picker's Configure\n // stage — it is `ActionTarget.with`, which `error-handler.ts` reads in preference to the\n // general `reroute.with`.\n nextTarget = {\n kind: \"action\",\n uses: {\n app: built.uses.app,\n action: built.uses.action,\n connection: built.uses.connection ?? undefined,\n },\n ...(built.with ? { with: built.with } : {}),\n };\n } else {\n return;\n }\n const nextDecision = errorHandlerSelfDecision({\n resource: { kind, id },\n target: { kind: nextTarget.kind, id: refOf(nextTarget) },\n hasAdapter: policy.reroute?.with !== undefined,\n });\n if (nextDecision === \"block\") {\n setError(\n \"This handler would call itself with the same inputs and can loop forever. Choose another handler or keep a differing imported adapter.\",\n );\n setPickerOpen(false);\n return;\n }\n // Preserve `reroute.with` if one was already authored elsewhere — this tool changes WHICH\n // handler runs, never the mapping onto it.\n persist({ ...policy, reroute: { ...policy.reroute, target: nextTarget } });\n setPickerOpen(false);\n }\n\n if (!ready && !saving) {\n return <p className=\"muted small\">Loading…</p>;\n }\n\n return (\n <div className=\"w6w-stack\" data-testid=\"rail-errorhandling-body\">\n {/* Retries run BEFORE the handler below, so the section renders first. */}\n <section data-testid=\"rail-retry-section\">\n <RetryPolicyFields\n value={policy.retry}\n onChange={(next) => persist({ ...policy, retry: next })}\n readOnly={saving}\n target={kind}\n />\n {kind === \"workflow\" && (\n <p className=\"muted small\" data-testid=\"rail-retry-run-warning\">\n Retrying re-runs the whole workflow from its first step, so steps that already succeeded\n run again. For a step that must not repeat (a send or a charge), set retry on that step\n instead.\n </p>\n )}\n </section>\n\n <p className=\"muted small\">\n {kind === \"workflow\"\n ? \"What runs when this workflow's run fails, after every step's own retry is spent.\"\n : \"What runs when this call fails, after retry (if any) is exhausted.\"}\n </p>\n\n {ref ? (\n <div className=\"row\" style={{ alignItems: \"center\", gap: 8 }}>\n <span className=\"list-main\">\n <strong>{label ?? ref}</strong> <code className=\"muted\">{ref}</code>\n <span className=\"muted small block\">{nounOf(target)}</span>\n </span>\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-errorhandling-change\"\n disabled={saving}\n onClick={() => setPickerOpen(true)}\n >\n Change\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n className=\"btn\"\n data-testid=\"rail-errorhandling-choose\"\n disabled={saving}\n onClick={() => setPickerOpen(true)}\n >\n + Choose what runs on failure\n </button>\n )}\n\n {ref && (\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-errorhandling-clear\"\n disabled={saving}\n onClick={() => persist({ ...policy, reroute: undefined })}\n >\n Remove handler\n </button>\n )}\n\n {selfDecision === \"warn\" && (\n <div className=\"result error\" data-testid=\"rail-errorhandling-self-caution\">\n This handler targets itself. Its imported input adapter is preserved; the server will\n refuse it if it resolves to the failed call's same inputs.\n </div>\n )}\n\n {error && (\n <div className=\"error\" data-testid=\"rail-errorhandling-error\">\n {error}\n </div>\n )}\n\n {pickerOpen && (\n <StepBuilderModal\n appsOnly\n callables={[\"function\", \"workflow\"] as const}\n title=\"Choose what runs on failure\"\n onClose={() => setPickerOpen(false)}\n onAdd={pickHandler}\n />\n )}\n </div>\n );\n}\n\n/**\n * The buffer arm: policy read off the host's buffer (`ctx.policy`), written back through\n * `ctx.onPolicyChange`. A workflow's only arm; a function / endpoint's when an editor owns the\n * buffer.\n */\nfunction BufferErrorHandlingPanel({ ctx }: { ctx: Exclude<WorkspaceCallable, null> }) {\n const policy = \"policy\" in ctx ? ctx.policy : undefined;\n const onPolicyChange = \"onPolicyChange\" in ctx ? ctx.onPolicyChange : undefined;\n return (\n <ErrorHandlerSection\n kind={ctx.kind as ErrorHandlerKind}\n id={ctx.id}\n policy={policy ? policyFromDefinition(policy) : {}}\n ready={Boolean(onPolicyChange)}\n saving={false}\n onPersist={(next) => onPolicyChange?.(next)}\n />\n );\n}\n\n/** The cache arm: a function / endpoint with no published writer saves from the cached record. */\nfunction CachedErrorHandlingPanel({ id, kind }: { id: string; kind: \"function\" | \"endpoint\" }) {\n const fnQuery = useFunctionQuery(id, kind === \"function\");\n const epQuery = useEndpointQuery(id, kind === \"endpoint\");\n const saveFnMut = useGuardedSaveFunctionMutation();\n const saveEpMut = useGuardedSaveEndpointMutation();\n\n const record = callableRecord(kind, kind === \"function\" ? fnQuery.data : epQuery.data);\n const saving = kind === \"function\" ? saveFnMut.isPending : saveEpMut.isPending;\n\n return (\n <ErrorHandlerSection\n kind={kind}\n id={id}\n policy={record ? policyFromDefinition(record.definition) : {}}\n ready={Boolean(record)}\n saving={saving}\n onPersist={(next, onError) => {\n if (!record) return;\n const vars = {\n definition: definitionWithPolicy(record.definition, next),\n ifUnmodifiedSince: record.updatedAt,\n };\n const settled = {\n onError: (e: unknown) => onError(e instanceof ApiError ? e.message : String(e)),\n };\n if (kind === \"function\") saveFnMut.mutate(vars, settled);\n else saveEpMut.mutate(vars, settled);\n }}\n />\n );\n}\n\nfunction ErrorHandlingPanel({ ctx }: { ctx: WorkspaceCallable }) {\n // Defensive: a persisted `activeTool` can render this Panel with a ctx this tool has no handler\n // for.\n if (ctx?.kind !== \"workflow\" && ctx?.kind !== \"function\" && ctx?.kind !== \"endpoint\") {\n return null;\n }\n if (ctx.kind === \"workflow\" || typeof ctx.onPolicyChange === \"function\") {\n return <BufferErrorHandlingPanel ctx={ctx} />;\n }\n return <CachedErrorHandlingPanel id={ctx.id} kind={ctx.kind} />;\n}\n\nfunction ErrorHandlingToolIcon() {\n return <Icon name=\"warning\" />;\n}\n\nexport const errorHandlingTool: RailTool = {\n id: \"error-handling\",\n title: \"Error handling\",\n Icon: ErrorHandlingToolIcon,\n isAvailable: (ctx) => isSettingsRailAvailable(ctx),\n Panel: ErrorHandlingPanel,\n};\n","/**\n * Pure decision logic behind `../components/TagEditor.tsx` — kept out of the\n * component so `node --test` can exercise it directly\n * (`__tests__/tag-editor.test.ts`) without touching React, mirroring\n * `alias-rail.ts`/`rail-settings.ts`'s own split. Carries over the retiring\n * `WorkflowsPage.tsx`'s retired tags-editing modal's data contract verbatim:\n * `string[]`, trim, dedupe-on-add, drop empties.\n */\n\n/**\n * Applies a chip input's freeform text to the committed tag list. Called on\n * every change to the trailing, not-yet-committed input — `typed` is always\n * the FULL current value of just that one input, which resets to `\"\"` after\n * a commit, so a single keystroke never carries more than the one character\n * just typed.\n *\n * A comma anywhere in `typed` is the commit signal: every comma-delimited\n * segment is trimmed and, if non-empty and not already present, appended as\n * a chip — in order, regardless of whether it sits before or after the last\n * comma. That is what makes both shapes work from the one rule: typing\n * `\"alpha,\"` one character at a time commits `\"alpha\"` the moment the comma\n * lands, and pasting `\"a,b,c\"` in one go (no trailing comma at all) still\n * commits all three, because nothing here treats \"the last segment\" as\n * special. The returned `typed` is always `\"\"` once a comma triggered a\n * commit. With no comma present at all, nothing commits and `typed` passes\n * through unchanged, so the caller can just store it as the next draft.\n */\nexport function commitTag(tags: string[], typed: string): { tags: string[]; typed: string } {\n if (!typed.includes(\",\")) return { tags, typed };\n let next = tags;\n for (const raw of typed.split(\",\")) {\n const t = raw.trim();\n if (t && !next.includes(t)) next = [...next, t];\n }\n return { tags: next, typed: \"\" };\n}\n\n/**\n * Removes exactly one tag by VALUE, never by position — a list carrying both\n * a tag and a second tag that merely contains it as a prefix (`[\"ab\", \"b\"]`)\n * only ever loses the exact match.\n */\nexport function removeTag(tags: string[], tag: string): string[] {\n return tags.filter((t) => t !== tag);\n}\n","import { IconButton } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { commitTag, removeTag } from \"../lib/tag-editor.ts\";\n\n/**\n * A chip input for a workflow's free-form tags: type text, `,` commits the\n * typed value as a chip (or paste a whole comma-separated list to commit\n * several at once — `../lib/tag-editor.ts`'s `commitTag`), each chip carries\n * an `×` to remove it, and a still-typable tail follows the chips — one\n * control, not a stacked input-above-list.\n *\n * Built fresh (T2.2.1) rather than extended from the retiring\n * `WorkflowsPage.tsx` tags-editing modal: that component was a submit-button\n * \"Add\" form with its own inline add/remove branching, a different\n * interaction shape from a comma-commits chip editor. The shared data\n * contract (trim, dedupe-on-add, drop empties) now lives in\n * `../lib/tag-editor.ts`'s\n * `commitTag`/`removeTag`, so this component holds no branching of its own —\n * it only calls them and renders the result. Controlled, mirroring\n * `InputListEditor.tsx`'s shape: the caller owns `tags`, this component owns\n * only the not-yet-committed typed tail.\n */\nexport interface TagEditorProps {\n tags: string[];\n onChange: (next: string[]) => void;\n}\n\nexport function TagEditor({ tags, onChange }: TagEditorProps) {\n const [typed, setTyped] = useState(\"\");\n\n function handleTypedChange(value: string) {\n const result = commitTag(tags, value);\n setTyped(result.typed);\n if (result.tags !== tags) onChange(result.tags);\n }\n\n return (\n <div className=\"tag-list\" data-testid=\"tag-editor\">\n {tags.map((t) => (\n <span key={t} className=\"tag removable\">\n {t}\n <IconButton\n danger\n icon=\"close\"\n label={`Remove tag ${t}`}\n title={`Remove ${t}`}\n onClick={() => onChange(removeTag(tags, t))}\n />\n </span>\n ))}\n <input\n type=\"text\"\n value={typed}\n placeholder=\"Add a tag…\"\n aria-label=\"New tag\"\n onChange={(e) => handleTypedChange(e.target.value)}\n />\n </div>\n );\n}\n","import { filterKeyInput, isEndpointKey } from \"@w6w/embed/lib\";\n/**\n * Unified settings modal for editing name, key, and tags (workflow only)\n * in a single dialog. Replaces separate Edit Key and Edit Tags modals.\n * Supports Function, Endpoint, and Workflow kinds.\n *\n * T4.2.1: every kind-shaped decision this component used to make inline — may\n * the key be typed at all, does this kind store tags, which placeholder goes in\n * which field — now comes from `CALLABLE_DESCRIPTORS[kind].settings`\n * (`lib/callable-descriptors.ts`). There is deliberately **no `kind ===` left in\n * this file**: a fourth kind, or a copy change, is an edit to the descriptor\n * table and to nothing else. The rendered output is byte-identical to before —\n * same labels, same placeholders, same hint sentence, same conditional Tags\n * section.\n */\nimport { descriptorFor } from \"@w6w/embed/repos\";\nimport { ApiError } from \"@w6w/sdk\";\nimport { useEnterSubmit } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { Modal } from \"./Modal.tsx\";\nimport { TagEditor } from \"./TagEditor.tsx\";\n\ninterface CallableSettingsModalProps {\n kind: \"function\" | \"endpoint\" | \"workflow\";\n id: string;\n initial: {\n displayName: string;\n key: string | null;\n tags?: string[]; // workflow only\n };\n onSave: (data: {\n displayName: string;\n key: string | null;\n tags?: string[];\n }) => Promise<void>;\n onClose: () => void;\n}\n\nexport function CallableSettingsModal(props: CallableSettingsModalProps) {\n // The one kind lookup this component makes. `settings` then answers every\n // per-kind question below, including which of the three `initial` fields this\n // kind even has.\n const settings = descriptorFor(props.kind).settings;\n const { initial } = props;\n const [displayName, setDisplayName] = useState(initial.displayName);\n const [key, setKey] = useState(initial.key ?? \"\");\n const [tags, setTags] = useState<string[]>(initial.tags ?? []);\n const [isSaving, setIsSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const displayNameChanged = displayName !== initial.displayName;\n const keyChanged = key !== (initial.key ?? \"\");\n const tagsChanged =\n settings.hasTags && JSON.stringify(tags) !== JSON.stringify(initial.tags ?? []);\n const isDirty = displayNameChanged || keyChanged || tagsChanged;\n\n // Key can be edited for function/workflow only (not endpoint)\n const canEditKey = settings.canEditKey;\n const keyGrammarOk = key === \"\" || isEndpointKey(key);\n const canSubmit = isDirty && keyGrammarOk && !isSaving;\n\n async function handleSave() {\n if (!canSubmit) return;\n setError(null);\n setIsSaving(true);\n try {\n await props.onSave({\n displayName: displayName.trim(),\n key: canEditKey && keyChanged ? key : initial.key,\n tags: settings.hasTags ? tags : undefined,\n });\n props.onClose();\n } catch (e) {\n setError(e instanceof ApiError ? e.message : String(e));\n } finally {\n setIsSaving(false);\n }\n }\n\n const enterSubmit = useEnterSubmit(handleSave, { enabled: canSubmit });\n\n return (\n <Modal title=\"Edit settings\" onClose={props.onClose}>\n <div className=\"modal-body\">\n <label className=\"field\">\n <span>Name</span>\n <input\n type=\"text\"\n value={displayName}\n onChange={(e) => setDisplayName(e.target.value)}\n placeholder={settings.namePlaceholder}\n autoFocus\n {...enterSubmit}\n />\n </label>\n\n {canEditKey && (\n <label className=\"field\">\n <span>Key</span>\n <input\n type=\"text\"\n value={key}\n onChange={(e) => setKey(filterKeyInput(e.target.value))}\n placeholder={settings.keyPlaceholder}\n {...enterSubmit}\n />\n <span className=\"muted small\">\n Lowercase, kebab-case, 3–39 characters.\n {settings.keyHintSuffix}\n </span>\n </label>\n )}\n\n {settings.hasTags && (\n <div>\n <p className=\"muted small\" style={{ marginBottom: \"8px\" }}>\n Tags\n </p>\n <TagEditor tags={tags} onChange={setTags} />\n </div>\n )}\n\n {error && <div className=\"error\">{error}</div>}\n </div>\n\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"btn\" disabled={!canSubmit} onClick={handleSave}>\n {isSaving ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </Modal>\n );\n}\n","import {\n type VersionsKind,\n useInvokeVersionMutation,\n useRevertMutation,\n useVersionQuery,\n} from \"@w6w/embed/repos\";\nimport { ApiError } from \"@w6w/sdk\";\nimport { CodeBlock } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { ConfirmModal } from \"./ConfirmModal.tsx\";\nimport { Modal } from \"./Modal.tsx\";\n\n/**\n * P2's `<collection>-version-*` testid scheme, spelled out literally per kind rather than built\n * by string interpolation — mirrors `ImportSpecModal.tsx`'s own `TESTIDS` reasoning: this file's\n * own kind arms stay the exact byte strings a page-guard suite would assert against, verifiable\n * by a plain substring search rather than only by running the browser suite.\n */\nconst TESTIDS: Record<\n VersionsKind,\n {\n json: string;\n error: string;\n revertButton: string;\n invokeButton: string;\n invokeJson: string;\n invokeError: string;\n }\n> = {\n function: {\n json: \"functions-version-json\",\n error: \"functions-version-error\",\n revertButton: \"functions-version-revert\",\n invokeButton: \"functions-version-invoke\",\n invokeJson: \"functions-version-invoke-json\",\n invokeError: \"functions-version-invoke-error\",\n },\n workflow: {\n json: \"workflows-version-json\",\n error: \"workflows-version-error\",\n revertButton: \"workflows-version-revert\",\n invokeButton: \"workflows-version-invoke\",\n invokeJson: \"workflows-version-invoke-json\",\n invokeError: \"workflows-version-invoke-error\",\n },\n endpoint: {\n json: \"endpoints-version-json\",\n error: \"endpoints-version-error\",\n revertButton: \"endpoints-version-revert\",\n invokeButton: \"endpoints-version-invoke\",\n invokeJson: \"endpoints-version-invoke-json\",\n invokeError: \"endpoints-version-invoke-error\",\n },\n};\n\n/**\n * Version viewer for Function/Workflow/Endpoint (T3.1.1, extended by T5.3.1): one\n * kind-parametrized component, mirroring `ImportSpecModal.tsx:12-46`'s established shape (a\n * `kind` prop plus per-kind `TESTIDS`, one component mounted from more than one place rather than\n * three near-copies). This project mounts it from `SettingsTool.tsx` only — the component\n * boundary exists so a second mount point later costs one line.\n *\n * Renders the version's own read-only definition through the same two primitives\n * `SettingsTool.tsx`'s existing Export modal already uses — the studio-local `Modal` and\n * `@w6w/ui`'s `CodeBlock` — plus, since T5.3.1, two live actions:\n *\n * - **\"Revert to this version\"** — confirmed via the studio-local `ConfirmModal` (P2-D4:\n * `./ConfirmModal.tsx`, never `@w6w/ui`'s), rendered as a SIBLING of `<Modal>` in\n * the returned fragment, never nested inside it. Overwrites the LIVE resource's `definition`\n * with this version's content, preserving its `key`/address (HITL-4's pinned default).\n * - **\"Invoke this version\"** — one click, NO confirm (ruling #12: an invoke is a call, not a\n * write to the resource, and the LIVE invoke action it mirrors carries no confirm either). Runs\n * this version's own archived definition, never the live one, and renders the response body\n * inline via `CodeBlock`, or a failure inline via the `ApiError` idiom (never a thrown error, a\n * blank modal, or a browser dialog).\n *\n * Both actions read `kind`/`id`/`versionNumber` from props, and both mutations are fresh\n * `useMutation` instances scoped to this component instance — since `SettingsTool.tsx`'s\n * `openVersion` gate fully unmounts/remounts this component per version rather than swapping\n * props on a surviving instance, any prior invoke result or error is gone the moment a different\n * version is opened.\n *\n * Amendments #5/#6 (project.md, Phase 2) supersede the earlier pin that made both of the above\n * out of scope (HITL-2's \"invocation always runs the live definition\"; Amendment #5's \"restore is\n * out of scope, not even a disabled button\").\n */\nexport function VersionHistoryModal(props: {\n kind: VersionsKind;\n id: string;\n versionNumber: number;\n onClose: () => void;\n}) {\n const { kind, id, versionNumber } = props;\n const testids = TESTIDS[kind];\n // Always enabled: this component only ever mounts once a specific version has been picked\n // (the caller renders it conditionally), mirroring the Export modal's own \"mounted while open\"\n // gate rather than re-deriving a second `enabled` flag here.\n const versionQuery = useVersionQuery(kind, id, versionNumber, true);\n const revertMut = useRevertMutation(kind);\n const invokeMut = useInvokeVersionMutation(kind);\n const [confirmingRevert, setConfirmingRevert] = useState(false);\n\n return (\n <>\n <Modal title={`Version ${versionNumber}`} onClose={props.onClose} wide>\n <div className=\"modal-body\">\n {versionQuery.isLoading ? (\n <p className=\"muted small\">Loading…</p>\n ) : versionQuery.isError ? (\n <div className=\"error\" data-testid={testids.error}>\n {versionQuery.error instanceof Error\n ? versionQuery.error.message\n : String(versionQuery.error)}\n </div>\n ) : versionQuery.data ? (\n <div data-testid={testids.json}>\n <CodeBlock\n code={JSON.stringify(versionQuery.data.definition, null, 2)}\n language=\"json\"\n maxHeight=\"420px\"\n copyable\n />\n </div>\n ) : null}\n\n {invokeMut.data !== undefined && (\n <div data-testid={testids.invokeJson}>\n <CodeBlock\n code={JSON.stringify(invokeMut.data, null, 2)}\n language=\"json\"\n maxHeight=\"240px\"\n copyable\n />\n </div>\n )}\n {invokeMut.isError && (\n <div className=\"error\" data-testid={testids.invokeError}>\n {invokeMut.error instanceof ApiError\n ? invokeMut.error.message\n : String(invokeMut.error)}\n </div>\n )}\n </div>\n\n <div className=\"modal-actions\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid={testids.invokeButton}\n disabled={invokeMut.isPending}\n onClick={() => invokeMut.mutate({ id, versionNumber })}\n >\n {invokeMut.isPending ? \"Invoking…\" : \"Invoke this version\"}\n </button>\n <button\n type=\"button\"\n className=\"btn danger\"\n data-testid={testids.revertButton}\n disabled={revertMut.isPending}\n onClick={() => setConfirmingRevert(true)}\n >\n {revertMut.isPending ? \"Reverting…\" : \"Revert to this version\"}\n </button>\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Close\n </button>\n </div>\n </Modal>\n {confirmingRevert && (\n <ConfirmModal\n title=\"Revert to this version\"\n message={`Revert to version ${versionNumber}? This restores its content onto the resource's current draft; the resource's key and address stay unchanged.`}\n confirmLabel=\"Revert\"\n destructive\n onConfirm={() => {\n setConfirmingRevert(false);\n revertMut.mutate({ id, versionNumber });\n }}\n onClose={() => setConfirmingRevert(false)}\n />\n )}\n </>\n );\n}\n","/**\n * T4.1.1/A3: the rail Settings panel's bottom \"danger zone\" — Archive (until\n * archived) then Delete, behind a visibly red confirmation panel — extracted\n * out of `src/ui/rail/SettingsTool.tsx` so Function, Endpoint and Workflow\n * render the EXACT same markup instead of three near-identical branches.\n * T1.3.1 had already moved all three kinds' Archive/Delete into one file, but\n * left them as three separate JSX arms that had drifted out of sync — only\n * Workflow's delete copy said the deletion was permanent (A5). This\n * extraction is what stops a fourth kind (or a future edit to one arm) from\n * silently reintroducing that gap: per-kind variance arrives entirely as\n * props, and there is exactly one archive-vs-delete branch to read.\n *\n * Presentational only, mirroring `@w6w/ui`'s own `DeleteButton` (HITL-1,\n * binding there): takes plain `onClick` callbacks, never an `onConfirm` and\n * never renders a confirm dialog itself — the caller (`SettingsTool.tsx`)\n * owns the `ConfirmModal`s and the archive/delete mutations, exactly as it\n * did before this extraction.\n *\n * A4: `DeleteButton`'s own `label` prop renders as `title`/`aria-label`\n * ONLY, never visible text (`packages/ui/src/components/IconButton.tsx`) —\n * so the visible word \"Delete\" here is this component's OWN sibling\n * `<span>`, not something passed through to `DeleteButton`.\n */\nimport { DeleteButton } from \"@w6w/ui\";\n\nexport interface DangerZoneProps {\n /** Whether the resource is archived yet. `true` renders Delete; `false`\n * renders Archive. Every kind has an archive-before-delete step as of\n * T4.1.1 (Function/Endpoint newly, Workflow already did). */\n archived: boolean;\n /** Accessible name for the Delete icon button — `title`/`aria-label` only\n * (`IconButton.tsx`), e.g. \"Delete this function\". */\n deleteLabel: string;\n /** `data-testid` for the Delete control. Kind-specific — page guards key\n * on these directly (e.g. `delete-function`, `wf-settings-delete`). */\n deleteTestId: string;\n /** `data-testid` for the Archive control. Kind-specific. */\n archiveTestId: string;\n onRequestDelete: () => void;\n onRequestArchive: () => void;\n deleteError: string | null;\n archiveError: string | null;\n}\n\nexport function DangerZone(props: DangerZoneProps) {\n const {\n archived,\n deleteLabel,\n deleteTestId,\n archiveTestId,\n onRequestDelete,\n onRequestArchive,\n deleteError,\n archiveError,\n } = props;\n return (\n <div className=\"rail-danger-zone rail-danger-zone--panel\" data-testid=\"rail-danger-zone-panel\">\n {/* A2/M4's kill: mutually exclusive, never both rendered — Delete only\n once archived, Archive otherwise. */}\n {archived ? (\n <span className=\"rail-danger-zone-delete\">\n <DeleteButton label={deleteLabel} data-testid={deleteTestId} onClick={onRequestDelete} />\n <span>Delete</span>\n </span>\n ) : (\n <button\n type=\"button\"\n className=\"btn danger\"\n data-testid={archiveTestId}\n onClick={onRequestArchive}\n >\n Archive\n </button>\n )}\n {deleteError && (\n <div className=\"error\" data-testid=\"rail-delete-error\">\n {deleteError}\n </div>\n )}\n {archiveError && (\n <div className=\"error\" data-testid=\"rail-archive-error\">\n {archiveError}\n </div>\n )}\n </div>\n );\n}\n","/**\n * The presentational sections of the rail Settings panel, rendered by EVERY arm — the workflow\n * and function/endpoint arms in `./SettingsTool.tsx` — so the markup, test ids and copy exist\n * exactly once.\n *\n * Every section takes data and callbacks as props. There is no query or mutation hook in this\n * file: the arms own their data access (through `../repos/*`). `useState`-free too — open/close state lives in the arm, so a\n * section is a pure function of its props.\n *\n * Moved verbatim from the pre-split `SettingsPanel`: the `rail-meta` definition-list grid, the\n * version-history link + Publish/Enable block and its \"All versions\" list modal (kept as two\n * separate open states in the arm — see `SettingsTool.tsx`), the Export/Edit JSON/Import chooser\n * shell, and the Delete/Archive danger zone with its per-kind confirm copy.\n */\nimport { ConfirmModal, EditButton, Icon, IconButton } from \"@w6w/ui\";\nimport type { ReactNode } from \"react\";\nimport { DangerZone } from \"../chrome/DangerZone.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailSettingsKind } from \"../lib/rail-settings.ts\";\nimport type { VersionSummary, VersionsEnvelope } from \"../repos/versions.ts\";\n\n/** The three kinds the Settings panel renders for. */\nexport type SettingsKind = Extract<RailSettingsKind, \"function\" | \"endpoint\" | \"workflow\">;\n\n/** Heading row: the title and the \"Edit settings\" trigger for the unified settings modal. */\nexport function SettingsHeading(props: { onEdit: () => void }) {\n return (\n <div className=\"right-rail-panel-head rail-settings-head\">\n <h3>Settings</h3>\n <EditButton label=\"Edit settings\" data-testid=\"rail-settings-edit\" onClick={props.onEdit} />\n </div>\n );\n}\n\n/**\n * id + key + updated (+ tags, workflow only) — and nothing else. No createdAt, ever. A two-column\n * label/value GRID (`dl`/`dt`/`dd`); `.rail-meta-list` is the rail-scoped grid and there is\n * deliberately no global `dl`/`dt`/`dd` rule.\n */\nexport function MetadataSection(props: {\n id: string;\n displayName: string;\n /** `metadataFieldsForKind(kind)`. */\n fields: ReadonlyArray<\"id\" | \"key\" | \"updatedAt\">;\n /** The already-cached list row (carries key/updatedAt); `undefined` until the list loads. */\n row: { key?: string | null; updatedAt: string } | undefined;\n /** Workflow only: the tag chips. `undefined` hides the row (function/endpoint). */\n tags?: readonly string[];\n}) {\n const { id, displayName, fields, row, tags } = props;\n return (\n <div className=\"rail-meta\">\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n }}\n >\n <dl className=\"rail-meta-list\">\n {displayName && (\n <>\n <dt>Name</dt>\n <dd data-testid=\"rail-meta-name\">\n <code>{displayName}</code>\n </dd>\n </>\n )}\n <dt>ID</dt>\n <dd data-testid=\"rail-meta-id\">\n <code>{id}</code>\n </dd>\n {fields.includes(\"key\") && row && (\n <>\n <dt>Key</dt>\n <dd data-testid=\"rail-meta-key\">\n <code>{row.key || \"unset\"}</code>\n </dd>\n </>\n )}\n {fields.includes(\"updatedAt\") && row && (\n <>\n <dt>Updated</dt>\n <dd data-testid=\"rail-meta-updated\" data-value={row.updatedAt}>\n {new Date(row.updatedAt).toLocaleString()}\n </dd>\n </>\n )}\n {tags !== undefined && row && (\n <>\n <dt>Tags</dt>\n <dd data-testid=\"rail-meta-tags\">\n {tags.length > 0\n ? tags.map((t) => (\n <span key={t} className=\"tag\">\n {t}\n </span>\n ))\n : \"No tags\"}\n </dd>\n </>\n )}\n </dl>\n </div>\n </div>\n );\n}\n\n/**\n * A5: one icon opens the combined Export/Edit JSON/Import chooser. Nothing here grows with the\n * size of the resource's definition — the definition renders in neither vessel here, only inside\n * a modal.\n */\nexport function SpecActionsTrigger(props: { onOpen: () => void }) {\n return (\n <div className=\"rail-spec-actions\">\n <IconButton\n icon=\"file-text\"\n label=\"Export, edit, or import\"\n data-testid=\"rail-spec-actions-open\"\n onClick={props.onOpen}\n />\n </div>\n );\n}\n\n/**\n * The chooser shell: Import always (it creates a NEW resource and navigates to it, never an\n * in-place replacement), plus a slot an arm fills with extra definition actions (the\n * function/endpoint arm adds Export + Edit JSON). Picking an item closes THIS modal and opens that\n * item's own — nothing is ever nested inside this one's body.\n */\nexport function SpecChooserModal(props: {\n kind: SettingsKind;\n /** Extra definition actions, rendered above the Import row. */\n children?: ReactNode;\n onImport: () => void;\n onClose: () => void;\n}) {\n const { kind, children, onImport, onClose } = props;\n return (\n <Modal title=\"Definition\" onClose={onClose}>\n <div className=\"modal-body\">\n {children}\n <p className=\"muted small\">\n Import a spec document to create a NEW {kind} and navigate to it — this does not replace\n the {kind} you have open.\n </p>\n <div className=\"rail-spec-menu-row\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-spec-import\"\n onClick={onImport}\n >\n Import\n </button>\n </div>\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={onClose}>\n Close\n </button>\n </div>\n </Modal>\n );\n}\n\n/**\n * Version history (A4): a link-styled icon, ALWAYS enabled (\"no earlier versions\" is an empty\n * state INSIDE the list modal, never a disabled control). Once opened (`open`), the un-carded\n * \"Published: vN\" line and Publish / Enable-Disable stay in the main panel.\n */\nexport function VersionSection(props: {\n open: boolean;\n versions: VersionsEnvelope | undefined;\n publishing: boolean;\n togglingEnabled: boolean;\n publishError: string | null;\n enableError: string | null;\n onShow: () => void;\n onPublish: () => void;\n onToggleEnabled: () => void;\n}) {\n const { open, versions } = props;\n return (\n <div className=\"rail-version-section\">\n <button\n type=\"button\"\n className=\"rail-link-icon\"\n data-testid=\"rail-history-show\"\n aria-label=\"Version history\"\n title=\"Version history\"\n onClick={props.onShow}\n >\n <Icon name=\"clock\" size={14} />\n <span>Version history</span>\n </button>\n {open && (\n <>\n <p className=\"muted small\" data-testid=\"rail-version-published\">\n {versions?.currentPublishedVersion != null\n ? `Published: v${versions.currentPublishedVersion}`\n : \"Never published\"}\n </p>\n <div className=\"rail-version-actions\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-publish\"\n disabled={props.publishing}\n onClick={props.onPublish}\n >\n {props.publishing ? \"Publishing…\" : \"Publish\"}\n </button>{\" \"}\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-enable-toggle\"\n disabled={props.togglingEnabled || versions === undefined}\n onClick={props.onToggleEnabled}\n >\n {props.togglingEnabled ? \"Saving…\" : versions?.enabled ? \"Disable\" : \"Enable\"}\n </button>\n </div>\n {props.publishError && (\n <div className=\"error\" data-testid=\"rail-publish-error\">\n {props.publishError}\n </div>\n )}\n {props.enableError && (\n <div className=\"error\" data-testid=\"rail-enable-error\">\n {props.enableError}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n/**\n * The \"All versions\" list modal — deliberately NOT titled \"Version history\" (which would share\n * the `Version …` aria-label prefix the per-version detail viewer's own dialogs use).\n */\nexport function VersionListModal(props: {\n loading: boolean;\n versions: readonly VersionSummary[] | undefined;\n onSelect: (versionNumber: number) => void;\n onClose: () => void;\n}) {\n const { loading, versions } = props;\n return (\n <Modal title=\"All versions\" onClose={props.onClose} wide>\n <div className=\"modal-body\">\n {loading && <p className=\"muted small\">Loading…</p>}\n {versions?.length === 0 && <p className=\"muted small\">No versions yet.</p>}\n {versions && versions.length > 0 && (\n <ul className=\"list\">\n {versions.map((v) => (\n <li key={v.versionNumber} className=\"selectable\">\n <button\n type=\"button\"\n className=\"row-select\"\n data-testid=\"rail-version-row\"\n onClick={() => props.onSelect(v.versionNumber)}\n >\n <div className=\"list-main\">\n <code>v{v.versionNumber}</code>{\" \"}\n {v.isCurrentPublished && (\n <span className=\"badge\" data-testid=\"rail-version-current\">\n Published\n </span>\n )}\n <div className=\"muted small\">{new Date(v.createdAt).toLocaleString()}</div>\n </div>\n </button>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={props.onClose}>\n Done\n </button>\n </div>\n </Modal>\n );\n}\n\nconst DANGER_COPY: Record<\n SettingsKind,\n {\n deleteTitle: string;\n deleteMessage: string;\n archiveTitle: string;\n archiveMessage: string;\n deleteLabel: string;\n deleteTestId: string;\n archiveTestId: string;\n }\n> = {\n function: {\n deleteTitle: \"Delete function\",\n deleteMessage:\n \"Delete this function permanently? Any endpoint, workflow, or call pointing to it will start failing with a not-found error the next time it runs, and this cannot be undone.\",\n archiveTitle: \"Archive function\",\n archiveMessage:\n \"Archive this function? It stops being invocable and can no longer be edited. Archiving is one-way — there is no unarchive — and only an archived function can be deleted.\",\n deleteLabel: \"Delete this function\",\n deleteTestId: \"delete-function\",\n archiveTestId: \"archive-function\",\n },\n endpoint: {\n deleteTitle: \"Delete endpoint\",\n deleteMessage:\n \"Delete this endpoint permanently? Any alias, workflow, or call pointing to it will start failing with a not-found error the next time it runs, and this cannot be undone.\",\n archiveTitle: \"Archive endpoint\",\n archiveMessage:\n \"Archive this endpoint? It stops being invocable and can no longer be edited. Archiving is one-way — there is no unarchive — and only an archived endpoint can be deleted.\",\n deleteLabel: \"Delete this endpoint\",\n deleteTestId: \"delete-endpoint\",\n archiveTestId: \"archive-endpoint\",\n },\n workflow: {\n deleteTitle: \"Delete workflow\",\n deleteMessage:\n \"Delete this workflow permanently? Its run history is discarded immediately via cascading deletes and cannot be recovered.\",\n archiveTitle: \"Archive workflow\",\n archiveMessage:\n \"Archive this workflow? It stops running and can no longer be published. Archiving is one-way — there is no unarchive — and only an archived workflow can be deleted.\",\n deleteLabel: \"Delete this workflow\",\n deleteTestId: \"wf-settings-delete\",\n archiveTestId: \"wf-settings-archive\",\n },\n};\n\n/**\n * The bottom \"danger zone\": Archive (until archived) then Delete, with the two confirm modals.\n * Per-kind variance (copy, test ids) is the table above; the caller owns the mutations and the\n * confirm/error state, and renders this only when `hasDelete(kind)`.\n */\nexport function SettingsDangerZone(props: {\n kind: SettingsKind;\n archived: boolean;\n deleteConfirming: boolean;\n archiveConfirming: boolean;\n deleteError: string | null;\n archiveError: string | null;\n onRequestDelete: () => void;\n onRequestArchive: () => void;\n onConfirmDelete: () => void;\n onConfirmArchive: () => void;\n onCloseDelete: () => void;\n onCloseArchive: () => void;\n}) {\n const copy = DANGER_COPY[props.kind];\n return (\n <>\n <DangerZone\n archived={props.archived}\n deleteLabel={copy.deleteLabel}\n deleteTestId={copy.deleteTestId}\n archiveTestId={copy.archiveTestId}\n onRequestDelete={props.onRequestDelete}\n onRequestArchive={props.onRequestArchive}\n deleteError={props.deleteError}\n archiveError={props.archiveError}\n />\n {props.deleteConfirming && (\n <ConfirmModal\n title={copy.deleteTitle}\n message={copy.deleteMessage}\n confirmLabel=\"Delete\"\n onConfirm={props.onConfirmDelete}\n onClose={props.onCloseDelete}\n />\n )}\n {props.archiveConfirming && (\n <ConfirmModal\n title={copy.archiveTitle}\n message={copy.archiveMessage}\n confirmLabel=\"Archive\"\n onConfirm={props.onConfirmArchive}\n onClose={props.onCloseArchive}\n />\n )}\n </>\n );\n}\n","/**\n * The Settings rail tool — what a resource's right-rail Settings panel does, owned by the package\n * so `<WorkflowEditor>`, a host's `<CallableRail>` and Studio's own rail all render ONE tool:\n * `settingsTool` is a stateful shell (it owns the three open flags) that dispatches by kind to\n * `WorkflowSettingsPanel` or `CallableSettingsPanel` (function / endpoint). Both render the same\n * presentational sections (`./settings-sections.tsx`).\n *\n * Workflow arm, unchanged:\n * - metadata (name / id / key / tags) read off the cached workflow list row;\n * - the unified settings modal saves the WHOLE stored definition (`useWorkflowQuery`'s\n * `workflow`, `displayName` / `key` / `tags` replaced) with `ifUnmodifiedSince` from that\n * query's `updatedAt`, and `project` passed VERBATIM — `useSaveWorkflowMutation` refuses\n * without one, because an unscoped write would silently relocate the workflow into the\n * account's default project (C/D-C2). A 409/400 renders inline, never a thrown error;\n * - the Import chooser → `ImportSpecModal` (creates a NEW workflow and opens it);\n * - version history / Publish / Enable are gated on the section's OWN open state, so opening\n * the panel issues zero `/versions` requests;\n * - Archive → Delete. Both land on the list via `onNavigate({ type: \"list\" })`.\n *\n * Function / endpoint arm: the same sections over `../repos/functions.ts` / `endpoints.ts`, plus\n * Export (`useSpecQuery`, gated on the export modal being open) and Edit JSON. Every write built\n * from a cached definition takes the definition from `callableRecord(kind, query.data)` — the ONE\n * strip of `valid` / `updatedAt` — and saves through the guarded hook with the stale-write token\n * OF THE RECORD THE WRITTEN TEXT CAME FROM: the name/key modal uses the current record's\n * `updatedAt`; Edit JSON uses the token captured when its text was seeded (`openEdit`), never one\n * read at save time over older text (that would silently overwrite a write that landed meanwhile).\n * A refusal (409 `function_stale` / `endpoint_stale`, 400…) renders inline and is never retried.\n *\n * Host seams: `project` and `onNavigate` arrive as props on the arms, and the `settingsTool` Panel\n * reads them from `useRailEnv()` (`./rail-env.tsx`). Archive / delete land on the list through\n * `onNavigate({ type: \"list\" })`; an import opens `{ type: \"imported\", kind, id }`. No router, no\n * `client.console`, no module-scope browser globals.\n *\n * ⚠️ The strip id is `\"settings\"`; `activeTool` is persisted.\n */\nimport { ApiError } from \"@w6w/sdk\";\nimport { CodeBlock, Icon, JsonEditor } from \"@w6w/ui\";\nimport { useState } from \"react\";\nimport { CallableSettingsModal } from \"../chrome/CallableSettingsModal.tsx\";\nimport { ImportSpecModal } from \"../chrome/ImportSpecModal.tsx\";\nimport { Modal } from \"../chrome/Modal.tsx\";\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport { VersionHistoryModal } from \"../chrome/VersionHistoryModal.tsx\";\nimport type { WorkspaceCallable } from \"../chrome/workspace.tsx\";\nimport { callableRecord } from \"../lib/callable-record.ts\";\nimport {\n evaluateEdit,\n hasDefinitionActions,\n hasDelete,\n hasVersionHistory,\n metadataFieldsForKind,\n specCollectionForKind,\n} from \"../lib/rail-settings.ts\";\nimport {\n endpointsKey,\n useArchiveEndpointMutation,\n useDeleteEndpointMutation,\n useEndpointQuery,\n useEndpointsQuery,\n useGuardedSaveEndpointMutation,\n} from \"../repos/endpoints.ts\";\nimport {\n functionsKey,\n useArchiveFunctionMutation,\n useDeleteFunctionMutation,\n useFunctionQuery,\n useFunctionsQuery,\n useGuardedSaveFunctionMutation,\n} from \"../repos/functions.ts\";\nimport { useSpecQuery } from \"../repos/spec-export.ts\";\nimport {\n type VersionsKind,\n usePublishMutation,\n useSetEnabledMutation,\n useVersionsQuery,\n} from \"../repos/versions.ts\";\nimport {\n useArchiveWorkflowMutation,\n useDeleteWorkflowMutation,\n useSaveWorkflowMutation,\n useWorkflowQuery,\n useWorkflowsQuery,\n workflowsKey,\n} from \"../repos/workflows.ts\";\nimport { type RailNavigation, useRailEnv } from \"./rail-env.tsx\";\nimport {\n MetadataSection,\n SettingsDangerZone,\n SettingsHeading,\n SpecActionsTrigger,\n SpecChooserModal,\n VersionListModal,\n VersionSection,\n} from \"./settings-sections.tsx\";\n\n/** The Import modal's three list keys — the repos' own exports, never literals. */\nconst IMPORT_LIST_KEYS = { functionsKey, endpointsKey, workflowsKey };\n\n/**\n * The three open flags a Settings panel shows: the Name/Key/Tags modal, the history section, and\n * the version list modal. They are OWNED BY THE CALLER (a stateful shell above every kind's arm),\n * not by the arm: a rail that stays mounted across a kind change (function -> workflow ->\n * endpoint) swaps arm component types, and state held in the arm would be remounted away,\n * closing an open modal. Lifting them keeps the modal open exactly as the pre-split single\n * component did.\n */\nexport type SettingsOpenState = {\n editingSettings: boolean;\n setEditingSettings: (v: boolean) => void;\n historyOpen: boolean;\n setHistoryOpen: (v: boolean) => void;\n versionListOpen: boolean;\n setVersionListOpen: (v: boolean) => void;\n};\n\nexport function WorkflowSettingsPanel({\n ctx,\n project,\n onNavigate,\n open,\n}: {\n ctx: WorkspaceCallable;\n project: string | null;\n onNavigate: (to: RailNavigation) => void;\n open: SettingsOpenState;\n}) {\n const {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n } = open;\n const workflowsQuery = useWorkflowsQuery(project ?? undefined);\n const isWorkflow = ctx?.kind === \"workflow\";\n const id = ctx?.id ?? \"\";\n\n // The Key / Tags / Name save needs the WHOLE stored definition (never a `{id,key}` stub) plus\n // the `updatedAt` precondition — both come from this query.\n const wfDefQuery = useWorkflowQuery(id, isWorkflow);\n // MUST carry the current project, verbatim: the hook refuses a missing one (no default).\n const saveWfMut = useSaveWorkflowMutation(project ?? undefined);\n const archiveWfMut = useArchiveWorkflowMutation();\n const deleteWfMut = useDeleteWorkflowMutation();\n\n const [specMenuOpen, setSpecMenuOpen] = useState(false);\n const [importing, setImporting] = useState(false);\n const [deleteConfirming, setDeleteConfirming] = useState(false);\n const [archiveConfirming, setArchiveConfirming] = useState(false);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const [archiveError, setArchiveError] = useState<string | null>(null);\n\n // `versionListOpen` is DELIBERATELY separate from `historyOpen` (both arrive via `open`): a\n // native `<dialog>` opened via `showModal()` makes the rest of the page inert, so sharing one\n // boolean would hide Publish/Enable-Disable the moment the list modal closes. The entry icon\n // sets both true; only the list modal's own close clears `versionListOpen`.\n // Gated on the section's OWN open state: opening this panel issues zero `/versions` requests.\n const versionsQuery = useVersionsQuery(\"workflow\", id, historyOpen && isWorkflow);\n const publishMut = usePublishMutation(\"workflow\");\n const setEnabledMut = useSetEnabledMutation(\"workflow\");\n const [publishError, setPublishError] = useState<string | null>(null);\n const [enableError, setEnableError] = useState<string | null>(null);\n // Keyed by resource id: falls back to closed the instant `ctx.id` no longer matches, so a\n // transition never carries a stale version from a DIFFERENT resource.\n const [openVersion, setOpenVersion] = useState<{ id: string; versionNumber: number } | null>(\n null,\n );\n\n if (!ctx || ctx.kind !== \"workflow\") {\n return <p className=\"muted small\">Open a workflow to see its settings.</p>;\n }\n\n const listRow = workflowsQuery.data?.find((w) => w.id === ctx.id);\n const displayName =\n listRow && typeof (listRow as { displayName?: unknown }).displayName === \"string\"\n ? (listRow as { displayName: string }).displayName\n : \"\";\n const tags = (listRow as { tags?: string[] } | undefined)?.tags ?? [];\n const archived = (listRow as { status?: string } | undefined)?.status === \"archived\";\n\n function onDelete() {\n setDeleteError(null);\n deleteWfMut.mutate(id, {\n onSuccess: () => {\n setDeleteConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setDeleteConfirming(false);\n setDeleteError(e instanceof ApiError ? e.message : String(e));\n },\n });\n }\n\n function onArchive() {\n setArchiveError(null);\n archiveWfMut.mutate(id, {\n onSuccess: () => {\n setArchiveConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setArchiveConfirming(false);\n setArchiveError(e instanceof ApiError ? e.message : String(e));\n },\n });\n }\n\n return (\n <div className=\"rail-settings-panel\">\n <SettingsHeading onEdit={() => setEditingSettings(true)} />\n <MetadataSection\n id={ctx.id}\n displayName={displayName}\n fields={metadataFieldsForKind(\"workflow\")}\n row={listRow}\n tags={tags}\n />\n\n <SpecActionsTrigger onOpen={() => setSpecMenuOpen(true)} />\n\n <VersionSection\n open={historyOpen}\n versions={versionsQuery.data}\n publishing={publishMut.isPending}\n togglingEnabled={setEnabledMut.isPending}\n publishError={publishError}\n enableError={enableError}\n onShow={() => {\n setHistoryOpen(true);\n setVersionListOpen(true);\n }}\n onPublish={() => {\n setPublishError(null);\n publishMut.mutate(id, {\n onError: (e) => setPublishError(e instanceof ApiError ? e.message : String(e)),\n });\n }}\n onToggleEnabled={() => {\n setEnableError(null);\n setEnabledMut.mutate(\n { id, enabled: !versionsQuery.data?.enabled },\n { onError: (e) => setEnableError(e instanceof ApiError ? e.message : String(e)) },\n );\n }}\n />\n\n {versionListOpen && (\n <VersionListModal\n loading={versionsQuery.isLoading}\n versions={versionsQuery.data?.versions}\n onSelect={(versionNumber) => setOpenVersion({ id, versionNumber })}\n onClose={() => setVersionListOpen(false)}\n />\n )}\n\n {openVersion && openVersion.id === id && (\n <VersionHistoryModal\n kind=\"workflow\"\n id={id}\n versionNumber={openVersion.versionNumber}\n onClose={() => setOpenVersion(null)}\n />\n )}\n\n {specMenuOpen && (\n <SpecChooserModal\n kind=\"workflow\"\n onClose={() => setSpecMenuOpen(false)}\n onImport={() => {\n setSpecMenuOpen(false);\n setImporting(true);\n }}\n />\n )}\n\n {/* Unified settings modal for name, key, and tags. */}\n {editingSettings && listRow && (\n <CallableSettingsModal\n // `key={id}` remounts (not merely re-renders) when an in-app navigation swaps the rail\n // to a different resource while this modal is open — the modal's `useState`\n // initializers never re-run on a prop change, so without it a save would mix the first\n // resource's stale fields with the new `id`.\n key={id}\n kind=\"workflow\"\n id={id}\n initial={{\n displayName,\n key: (listRow as { key?: string | null }).key ?? null,\n tags,\n }}\n onSave={async (data) => {\n if (!wfDefQuery.data) throw new Error(\"Unable to save settings\");\n const stored = wfDefQuery.data;\n return new Promise((resolve, reject) => {\n const updated: Record<string, unknown> = {\n ...stored.workflow,\n displayName: data.displayName,\n };\n if (data.key !== undefined) {\n updated.key = data.key;\n }\n if (data.tags !== undefined) {\n updated.tags = data.tags;\n }\n saveWfMut.mutate(\n { definition: updated, ifUnmodifiedSince: stored.updatedAt },\n { onSuccess: () => resolve(), onError: reject },\n );\n });\n }}\n onClose={() => setEditingSettings(false)}\n />\n )}\n\n <SettingsDangerZone\n kind=\"workflow\"\n archived={archived}\n deleteConfirming={deleteConfirming}\n archiveConfirming={archiveConfirming}\n deleteError={deleteError}\n archiveError={archiveError}\n onRequestDelete={() => setDeleteConfirming(true)}\n onRequestArchive={() => setArchiveConfirming(true)}\n onConfirmDelete={onDelete}\n onConfirmArchive={onArchive}\n onCloseDelete={() => setDeleteConfirming(false)}\n onCloseArchive={() => setArchiveConfirming(false)}\n />\n\n {importing && (\n <ImportSpecModal\n kind=\"workflow\"\n project={project ?? undefined}\n listKeys={IMPORT_LIST_KEYS}\n onOpenImported={(kind, newId) => onNavigate({ type: \"imported\", kind, id: newId })}\n onClose={() => setImporting(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * Stateful shell: owns the three open flags ABOVE every arm and passes them down. The kind branch\n * picks a component TYPE (so each arm's data hooks stay per-kind), and an arm remounts on a kind\n * change — but the modal / version-list flags live here, so they survive the swap (rail guards\n * K6/V6).\n */\nfunction SettingsToolPanel({ ctx }: { ctx: WorkspaceCallable }) {\n const { project, onNavigate } = useRailEnv();\n const [editingSettings, setEditingSettings] = useState(false);\n const [historyOpen, setHistoryOpen] = useState(false);\n const [versionListOpen, setVersionListOpen] = useState(false);\n const open: SettingsOpenState = {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n };\n return ctx?.kind === \"workflow\" ? (\n <WorkflowSettingsPanel ctx={ctx} project={project} onNavigate={onNavigate} open={open} />\n ) : (\n <CallableSettingsPanel ctx={ctx} project={project} onNavigate={onNavigate} open={open} />\n );\n}\n\nexport function CallableSettingsPanel({\n ctx,\n project,\n onNavigate,\n open,\n}: {\n ctx: WorkspaceCallable;\n project: string | null;\n onNavigate: (to: RailNavigation) => void;\n open: SettingsOpenState;\n}) {\n const {\n editingSettings,\n setEditingSettings,\n historyOpen,\n setHistoryOpen,\n versionListOpen,\n setVersionListOpen,\n } = open;\n const kind0 = ctx?.kind;\n const endpointsQuery = useEndpointsQuery(kind0 === \"endpoint\");\n const functionsQuery = useFunctionsQuery(kind0 === \"function\");\n\n const [editing, setEditing] = useState(false);\n const [editText, setEditText] = useState(\"\");\n const [editError, setEditError] = useState<string | null>(null);\n // The stale-write token of the record `editText` was seeded from (`openEdit`). Read at SAVE time\n // it would guard text seeded from an older copy with a newer token — a silent overwrite.\n const [editToken, setEditToken] = useState<string | null>(null);\n // A5: one chooser icon opens ONE combined Modal (Export + Edit JSON +\n // Import); picking an item there closes the chooser and opens THAT item's\n // own modal as a sibling — never nested inside the chooser's own body.\n const [specMenuOpen, setSpecMenuOpen] = useState(false);\n const [exporting, setExporting] = useState(false);\n const [importing, setImporting] = useState(false);\n const [deleteConfirming, setDeleteConfirming] = useState(false);\n const [archiveConfirming, setArchiveConfirming] = useState(false);\n const [deleteError, setDeleteError] = useState<string | null>(null);\n const [archiveError, setArchiveError] = useState<string | null>(null);\n\n // Gated on `ctx.kind` alone, never additionally on the edit modal being\n // open — ST6's post-save freshness proof needs the `[\"function\", id]` cache\n // entry to exist before the save happens.\n const fnDefQuery = useFunctionQuery(ctx?.id ?? \"\", ctx?.kind === \"function\");\n const epDefQuery = useEndpointQuery(ctx?.id ?? \"\", ctx?.kind === \"endpoint\");\n const saveFnMut = useGuardedSaveFunctionMutation();\n const saveEpMut = useGuardedSaveEndpointMutation();\n const deleteFnMut = useDeleteFunctionMutation();\n const deleteEpMut = useDeleteEndpointMutation();\n // A7: Function/Endpoint have the archive-before-delete step too.\n const archiveFnMut = useArchiveFunctionMutation();\n const archiveEpMut = useArchiveEndpointMutation();\n // Gated on the export modal's own open state, so opening this panel issues\n // zero `/spec` requests. `specCollectionForKind` returns `null` for\n // `workflow`/`connection`, which disables the query regardless of `exporting`.\n const specCollection = ctx ? specCollectionForKind(ctx.kind) : null;\n const specQuery = useSpecQuery(specCollection, ctx?.id ?? \"\", exporting);\n\n // ── The History section ─────────────────────────────────────────────────\n // `null` for a kind with no version history (`connection`).\n const versionsKind: VersionsKind | null =\n ctx && hasVersionHistory(ctx.kind) ? (ctx.kind as VersionsKind) : null;\n // Gated on the section's OWN open state (`historyOpen`): never fires on mount.\n const versionsQuery = useVersionsQuery(versionsKind, ctx?.id ?? \"\", historyOpen);\n // `usePublishMutation`/`useSetEnabledMutation` need a fixed, non-null kind\n // per hook instance; the fallback is never reached by an actual request —\n // the buttons that call `.mutate` only render inside the\n // `hasVersionHistory(ctx.kind)`-gated block.\n const publishMut = usePublishMutation(versionsKind ?? \"function\");\n const setEnabledMut = useSetEnabledMutation(versionsKind ?? \"function\");\n const [publishError, setPublishError] = useState<string | null>(null);\n const [enableError, setEnableError] = useState<string | null>(null);\n // Keyed by resource id: falls back to closed the instant `ctx.id` no longer\n // matches, so a kind/id transition (V6) never carries a stale version.\n const [openVersion, setOpenVersion] = useState<{ id: string; versionNumber: number } | null>(\n null,\n );\n\n // `isAvailable` already keeps this tool off the strip for a `ctx` this has\n // no settings for — but a persisted `activeTool` plus an in-app transition\n // to a non-publishing route can still render this Panel with `ctx === null`\n // (or a `connection`). The rail must never blank out or crash.\n if (!ctx || (ctx.kind !== \"function\" && ctx.kind !== \"endpoint\")) {\n return (\n <p className=\"muted small\">Open a workflow, function, or endpoint to see its settings.</p>\n );\n }\n\n const kind = ctx.kind;\n const id = ctx.id;\n const listRow =\n kind === \"function\"\n ? functionsQuery.data?.find((f) => f.id === id)\n : endpointsQuery.data?.find((e) => e.id === id);\n // The cached record split ONCE (`callableRecord`): the editable definition (no `valid` /\n // `updatedAt`) and the stale-write token it was read with.\n const record = callableRecord(kind, kind === \"function\" ? fnDefQuery.data : epDefQuery.data);\n const def = record?.definition ?? null;\n // Display name (the human-readable label shown in the list)\n const displayName = listRow\n ? typeof (listRow as { displayName?: unknown }).displayName === \"string\"\n ? (listRow as { displayName: string }).displayName\n : \"\"\n : \"\";\n\n const defJson = def ? JSON.stringify(def, null, 2) : \"\";\n\n function openEdit() {\n setEditError(null);\n setEditText(defJson);\n setEditToken(record?.updatedAt ?? null);\n setEditing(true);\n }\n\n const editEval = def\n ? evaluateEdit(editText, { id: String(def.id), key: String(def.key) })\n : { parsed: null, blockedReason: \"No definition loaded yet.\" };\n const savingDef = kind === \"function\" ? saveFnMut.isPending : saveEpMut.isPending;\n\n function onSaveEdit() {\n if (!editEval.parsed || editEval.blockedReason) return;\n setEditError(null);\n const onSettled = {\n onSuccess: () => setEditing(false),\n onError: (e: unknown) => setEditError(e instanceof ApiError ? e.message : String(e)),\n };\n const vars = { definition: editEval.parsed, ifUnmodifiedSince: editToken };\n if (kind === \"function\") {\n saveFnMut.mutate(vars, onSettled);\n } else {\n saveEpMut.mutate(vars, onSettled);\n }\n }\n\n // ── Delete/Archive — the bottom \"danger zone\" ────────────────────────────\n // Function/Endpoint signal \"already archived\" via the `archivedAt` column.\n const archived = (listRow as { archivedAt?: string | null } | undefined)?.archivedAt != null;\n\n function onDelete() {\n setDeleteError(null);\n const onSettled = {\n onSuccess: () => {\n setDeleteConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setDeleteConfirming(false);\n setDeleteError(e instanceof ApiError ? e.message : String(e));\n },\n };\n if (kind === \"function\") deleteFnMut.mutate(id, onSettled);\n else deleteEpMut.mutate(id, onSettled);\n }\n\n // A1/D-I0-1: archive reuses `onDelete`'s land-on-the-list idiom.\n function onArchive() {\n setArchiveError(null);\n const onSettled = {\n onSuccess: () => {\n setArchiveConfirming(false);\n onNavigate({ type: \"list\" });\n },\n onError: (e: unknown) => {\n setArchiveConfirming(false);\n setArchiveError(e instanceof ApiError ? e.message : String(e));\n },\n };\n if (kind === \"function\") archiveFnMut.mutate(id, onSettled);\n else archiveEpMut.mutate(id, onSettled);\n }\n\n return (\n <div className=\"rail-settings-panel\">\n <SettingsHeading onEdit={() => setEditingSettings(true)} />\n <MetadataSection\n id={id}\n displayName={displayName}\n fields={metadataFieldsForKind(kind)}\n row={listRow}\n />\n\n {hasDefinitionActions(kind) && <SpecActionsTrigger onOpen={() => setSpecMenuOpen(true)} />}\n\n {hasVersionHistory(kind) && (\n <VersionSection\n open={historyOpen}\n versions={versionsQuery.data}\n publishing={publishMut.isPending}\n togglingEnabled={setEnabledMut.isPending}\n publishError={publishError}\n enableError={enableError}\n onShow={() => {\n setHistoryOpen(true);\n setVersionListOpen(true);\n }}\n onPublish={() => {\n setPublishError(null);\n publishMut.mutate(id, {\n onError: (e) => setPublishError(e instanceof ApiError ? e.message : String(e)),\n });\n }}\n onToggleEnabled={() => {\n setEnableError(null);\n setEnabledMut.mutate(\n { id, enabled: !versionsQuery.data?.enabled },\n { onError: (e) => setEnableError(e instanceof ApiError ? e.message : String(e)) },\n );\n }}\n />\n )}\n\n {versionListOpen && (\n <VersionListModal\n loading={versionsQuery.isLoading}\n versions={versionsQuery.data?.versions}\n onSelect={(versionNumber) => setOpenVersion({ id, versionNumber })}\n onClose={() => setVersionListOpen(false)}\n />\n )}\n\n {openVersion && openVersion.id === id && (\n <VersionHistoryModal\n kind={kind}\n id={id}\n versionNumber={openVersion.versionNumber}\n onClose={() => setOpenVersion(null)}\n />\n )}\n\n {/* The chooser — Export + Edit JSON (function/endpoint only, PL-2) fill\n the shell's slot; Import is the shell's own. */}\n {specMenuOpen && (\n <SpecChooserModal\n kind={kind}\n onClose={() => setSpecMenuOpen(false)}\n onImport={() => {\n setSpecMenuOpen(false);\n setImporting(true);\n }}\n >\n {hasDefinitionActions(kind) && (\n <>\n <p className=\"muted small\">\n Export a portable definition — the same shape Import accepts — or Edit JSON to\n change what's stored directly.\n </p>\n <div className=\"rail-spec-menu-row\">\n <button\n type=\"button\"\n className=\"btn ghost\"\n data-testid=\"rail-spec-export\"\n onClick={() => {\n setSpecMenuOpen(false);\n setExporting(true);\n }}\n >\n Export\n </button>{\" \"}\n <button\n type=\"button\"\n className=\"btn ghost\"\n disabled={!def}\n data-testid=\"rail-json-edit\"\n onClick={() => {\n setSpecMenuOpen(false);\n openEdit();\n }}\n >\n Edit JSON\n </button>\n </div>\n </>\n )}\n </SpecChooserModal>\n )}\n\n {/* Export — a read-only modal carrying the `/spec` route's `spec` field\n verbatim, via `@w6w/ui`'s `CodeBlock`, never a second editable text\n box. The request fires only while this modal is open. */}\n {exporting && (\n <Modal title=\"Export spec document\" onClose={() => setExporting(false)} wide>\n <div className=\"modal-body\">\n {specQuery.isLoading ? (\n <p className=\"muted small\">Loading…</p>\n ) : specQuery.isError ? (\n <div className=\"error\" data-testid=\"rail-spec-error\">\n {specQuery.error instanceof Error\n ? specQuery.error.message\n : String(specQuery.error)}\n </div>\n ) : specQuery.data ? (\n <div data-testid=\"rail-spec-json\">\n <CodeBlock\n code={JSON.stringify(specQuery.data, null, 2)}\n language=\"json\"\n maxHeight=\"420px\"\n copyable\n />\n </div>\n ) : null}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={() => setExporting(false)}>\n Close\n </button>\n </div>\n </Modal>\n )}\n\n {/* Self-contained — Save lives inside this modal, mirroring\n `WorkflowDetailPage.tsx`'s read-only card, never `WorkflowsPage.tsx`'s\n Save-less `showJson` modal. */}\n {editing && (\n <Modal title=\"Edit definition\" onClose={() => setEditing(false)} wide>\n <div className=\"modal-body\">\n <JsonEditor\n value={editText}\n onChange={setEditText}\n minHeight=\"320px\"\n aria-label=\"Edit definition JSON\"\n />\n {editEval.blockedReason && (\n <p className=\"muted small\" data-testid=\"rail-edit-reason\">\n {editEval.blockedReason}\n </p>\n )}\n {editError && <div className=\"error\">{editError}</div>}\n </div>\n <div className=\"modal-actions\">\n <button type=\"button\" className=\"btn ghost\" onClick={() => setEditing(false)}>\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"btn\"\n disabled={editEval.blockedReason !== null || savingDef}\n data-testid=\"rail-json-save\"\n onClick={onSaveEdit}\n >\n {savingDef ? \"Saving…\" : \"Save\"}\n </button>\n </div>\n </Modal>\n )}\n\n {/* Unified settings modal for name and key. */}\n {editingSettings && listRow && (\n <CallableSettingsModal\n // `key={id}` forces a remount (not a re-render) when an in-app\n // navigation swaps the rail to a different resource while this modal\n // is open — the modal's `useState` initializers never re-run on a\n // prop change, so a save would mix stale fields with the new `id`.\n key={id}\n kind={kind}\n id={id}\n initial={{\n displayName,\n key: (listRow as { key?: string | null }).key ?? null,\n tags: [],\n }}\n onSave={async (data) => {\n if (!record) throw new Error(\"Unable to save settings\");\n // Definition AND token from the same record, read now: the text written is this\n // record's own fields plus the modal's edits.\n const base = record.definition;\n const edited =\n kind === \"function\"\n ? // `canEditKey: true` for function (`callable-descriptors.ts`): `data.key` must\n // reach the server (the modal falls back to `initial.key` when unchanged).\n { ...base, displayName: data.displayName, key: data.key ?? base.key }\n : { ...base, displayName: data.displayName };\n const vars = { definition: edited, ifUnmodifiedSince: record.updatedAt };\n return new Promise((resolve, reject) => {\n const settled = { onSuccess: () => resolve(), onError: reject };\n if (kind === \"function\") saveFnMut.mutate(vars, settled);\n else saveEpMut.mutate(vars, settled);\n });\n }}\n onClose={() => setEditingSettings(false)}\n />\n )}\n\n {hasDelete(kind) && (\n <SettingsDangerZone\n kind={kind}\n archived={archived}\n deleteConfirming={deleteConfirming}\n archiveConfirming={archiveConfirming}\n deleteError={deleteError}\n archiveError={archiveError}\n onRequestDelete={() => setDeleteConfirming(true)}\n onRequestArchive={() => setArchiveConfirming(true)}\n onConfirmDelete={onDelete}\n onConfirmArchive={onArchive}\n onCloseDelete={() => setDeleteConfirming(false)}\n onCloseArchive={() => setArchiveConfirming(false)}\n />\n )}\n\n {importing && (\n <ImportSpecModal\n kind={kind}\n project={project ?? undefined}\n listKeys={IMPORT_LIST_KEYS}\n onOpenImported={(k, newId) => onNavigate({ type: \"imported\", kind: k, id: newId })}\n onClose={() => setImporting(false)}\n />\n )}\n </div>\n );\n}\n\nfunction SettingsToolIcon() {\n return <Icon name=\"settings\" />;\n}\n\n/** The package's Settings tool — workflow, function and endpoint. */\nexport const settingsTool: RailTool = {\n id: \"settings\",\n title: \"Settings\",\n rendersHeading: true,\n Icon: SettingsToolIcon,\n isAvailable: (ctx) =>\n ctx?.kind === \"workflow\" || ctx?.kind === \"function\" || ctx?.kind === \"endpoint\",\n Panel: SettingsToolPanel,\n};\n","/**\n * The rail tools `<WorkflowEditor>`, `<CallableRail>` and Studio's rail mount, in display order.\n * Each serves workflow, function and endpoint resources (`isAvailable` decides per context); the\n * Aliases tool is deliberately absent (alias management is Studio-only). Reachable from the `chrome` subpath, never from the package root barrel — the\n * Error handling tool pulls in `@w6w/ui/flow`.\n */\nimport type { RailTool } from \"../chrome/RightRail.tsx\";\nimport { codeTool } from \"./CodeTool.tsx\";\nimport { errorHandlingTool } from \"./ErrorHandlingTool.tsx\";\nimport { settingsTool } from \"./SettingsTool.tsx\";\n\nexport const editorRailTools: readonly RailTool[] = [settingsTool, codeTool, errorHandlingTool];\n"],"names":["WorkspaceContext","createContext","WorkspaceProvider","children","base","override","setCallable","useState","resource","value","useMemo","jsx","useHasWorkspace","useContext","useWorkspace","ctx","key","useEffect","useWorkspaceCallable","CLOSED","readStoredState","raw","activeTool","restoreRailState","RailShell","tools","state","onToggle","t","jsxs","tool","PersistedRail","storageKey","setState","id","prev","RightRail","available","useProjectExpressionOptions","project","projectId","varsQuery","useVarsQuery","secretsQuery","useSecretsQuery","documentsQuery","useDocumentsQuery","sealSecretFn","useSealSecret","createVarMut","useCreateVarMutation","createSecretMut","useCreateSecretMutation","v","s","projectDocumentSources","documentSampleValues","input","ProjectExpressionScope","options","ExpressionOptionsProvider","CodePanel","openTab","setOpenTab","snippetCallable","toSnippetCallable","triggers","tabs","snippetTabsFor","unavailableReason","label","icon","Icon","Modal","CallFromCodeBody","CodeToolIcon","codeTool","isAvailable","DEFAULT_ENV","RailEnvContext","RailEnvProvider","onNavigate","useRailEnv","CALL_APP","refOf","target","nounOf","ErrorHandlerSection","kind","policy","ready","saving","onPersist","functionsQuery","useFunctionsQuery","workflowsQuery","useWorkflowsQuery","pickerOpen","setPickerOpen","error","setError","_a","ref","selfDecision","errorHandlerSelfDecision","_b","_d","_c","w","fn","f","persist","next","pickHandler","built","nextTarget","nextId","RetryPolicyFields","StepBuilderModal","BufferErrorHandlingPanel","onPolicyChange","policyFromDefinition","CachedErrorHandlingPanel","fnQuery","useFunctionQuery","epQuery","useEndpointQuery","saveFnMut","useGuardedSaveFunctionMutation","saveEpMut","useGuardedSaveEndpointMutation","record","callableRecord","onError","vars","definitionWithPolicy","settled","e","ApiError","ErrorHandlingPanel","ErrorHandlingToolIcon","errorHandlingTool","isSettingsRailAvailable","commitTag","tags","typed","removeTag","tag","TagEditor","onChange","setTyped","handleTypedChange","result","IconButton","CallableSettingsModal","props","settings","descriptorFor","initial","displayName","setDisplayName","setKey","setTags","isSaving","setIsSaving","displayNameChanged","keyChanged","tagsChanged","isDirty","canEditKey","keyGrammarOk","isEndpointKey","canSubmit","handleSave","enterSubmit","useEnterSubmit","filterKeyInput","TESTIDS","VersionHistoryModal","versionNumber","testids","versionQuery","useVersionQuery","revertMut","useRevertMutation","invokeMut","useInvokeVersionMutation","confirmingRevert","setConfirmingRevert","Fragment","CodeBlock","ConfirmModal","DangerZone","archived","deleteLabel","deleteTestId","archiveTestId","onRequestDelete","onRequestArchive","deleteError","archiveError","DeleteButton","SettingsHeading","EditButton","MetadataSection","fields","row","SpecActionsTrigger","SpecChooserModal","onImport","onClose","VersionSection","open","versions","VersionListModal","loading","DANGER_COPY","SettingsDangerZone","copy","IMPORT_LIST_KEYS","functionsKey","endpointsKey","workflowsKey","WorkflowSettingsPanel","editingSettings","setEditingSettings","historyOpen","setHistoryOpen","versionListOpen","setVersionListOpen","isWorkflow","wfDefQuery","useWorkflowQuery","saveWfMut","useSaveWorkflowMutation","archiveWfMut","useArchiveWorkflowMutation","deleteWfMut","useDeleteWorkflowMutation","specMenuOpen","setSpecMenuOpen","importing","setImporting","deleteConfirming","setDeleteConfirming","archiveConfirming","setArchiveConfirming","setDeleteError","setArchiveError","versionsQuery","useVersionsQuery","publishMut","usePublishMutation","setEnabledMut","useSetEnabledMutation","publishError","setPublishError","enableError","setEnableError","openVersion","setOpenVersion","listRow","onDelete","onArchive","metadataFieldsForKind","data","stored","resolve","reject","updated","ImportSpecModal","newId","SettingsToolPanel","CallableSettingsPanel","kind0","endpointsQuery","useEndpointsQuery","editing","setEditing","editText","setEditText","editError","setEditError","editToken","setEditToken","exporting","setExporting","fnDefQuery","epDefQuery","deleteFnMut","useDeleteFunctionMutation","deleteEpMut","useDeleteEndpointMutation","archiveFnMut","useArchiveFunctionMutation","archiveEpMut","useArchiveEndpointMutation","specCollection","specCollectionForKind","specQuery","useSpecQuery","versionsKind","hasVersionHistory","def","defJson","openEdit","editEval","evaluateEdit","savingDef","onSaveEdit","onSettled","hasDefinitionActions","JsonEditor","hasDelete","k","SettingsToolIcon","settingsTool","editorRailTools"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"endpoints-B2ynbZo-.js","sources":["../src/lib/new-id.ts","../src/lib/callable-descriptors.ts","../src/repos/functions.ts","../src/repos/endpoints.ts"],"sourcesContent":["/**\n * Platform id minter (studio copy). Algorithm is byte-identical to the server's\n * `packages/ids/ids.ts`: alphabet base62, drop byte b >= 248 (largest multiple of 62\n * that fits a byte), keep ALPHABET[b % 62]. No modulo bias.\n */\n\nexport const ID_ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\n/** Largest multiple of 62 <= 256; bytes at or above it are rejected. */\nconst REJECT_AT = 248;\n\n/** Byte source seam; defaults to `crypto.getRandomValues`. */\nexport type ByteSource = (n: number) => Uint8Array;\n\nconst defaultBytes: ByteSource = (n) => crypto.getRandomValues(new Uint8Array(n));\n\n/** `<prefix>_<len chars of base62>`. */\nexport function newId(prefix: string, len = 16, bytes: ByteSource = defaultBytes): string {\n let out = \"\";\n while (out.length < len) {\n for (const b of bytes(Math.max(len - out.length, 8))) {\n if (b >= REJECT_AT) continue;\n out += ID_ALPHABET[b % 62];\n if (out.length === len) break;\n }\n }\n return `${prefix}_${out}`;\n}\n","/**\n * `CALLABLE_DESCRIPTORS` — the ONE place the three resource kinds' chrome copy,\n * their Settings-modal behaviour and their id minting are named (T4.2.1,\n * `building-blocks.F3.md` §F-3).\n *\n * Before this file, every \"is this a workflow?\" branch lived inline at its call\n * site: `CallableSettingsModal.tsx` carried seven `kind ===` conditionals for\n * three different questions (may the key be edited? does this kind have tags?\n * which placeholder does the name field use?), and each list page repeated the\n * same title/description/empty-state/`data-testid` literals. A fourth kind — or\n * a rename — meant finding them all by hand.\n *\n * **Data only, never JSX.** A `Descriptor` holds strings, booleans and the one\n * id prefix; the kind-specific *editor body* stays React code in its own page\n * (`src/pages/FunctionsPage.tsx`), because this file is `.ts` and is loaded by\n * `node --test` (`.tsx` cannot be — `package.json`'s `test:unit` glob), exactly\n * the constraint `src/lib/save-invalidation.ts` and `src/lib/alias-rail.ts`\n * document for themselves. So `kind ===` moves OUT of the modal and the pages\n * and INTO a total `Record`, never into a render function.\n *\n * The wire plumbing these descriptors describe — collection segment, query keys,\n * the SDK call per kind — lives one layer down, in `src/repos/callables.ts`,\n * which owns its own total `Record` per kind (mirroring `src/repos/versions.ts`'s\n * `COLLECTION_PATH`). `callable-descriptors.test.ts` asserts the two tables name\n * the same three kinds and the same three collections, so they cannot drift.\n */\nimport type { CallableKind } from \"./callable-kind.ts\";\nimport { newId } from \"./new-id.ts\";\n\nexport type { CallableKind };\n\n/** The Settings modal's own per-kind behaviour (T4.2.1's formalization of the\n * seven `kind ===` conditionals `CallableSettingsModal.tsx` used to carry). */\nexport interface CallableSettingsDescriptor {\n /** May the `key` be typed here at all? Function/Workflow yes, Endpoint no\n * (`rfcs/endpoint.md` — an Endpoint's address is its identity). */\n canEditKey: boolean;\n /** Does this kind store tags? Workflow only. */\n hasTags: boolean;\n /** Placeholder for the Name field. */\n namePlaceholder: string;\n /** Placeholder for the Key field (read only when {@link canEditKey}). */\n keyPlaceholder: string;\n /** Appended to the shared \"Lowercase, kebab-case, 3–39 characters.\" hint —\n * `\"\"` for a kind that cannot unset its key, the \"Leave empty to unset.\"\n * sentence for the one that can. */\n keyHintSuffix: string;\n}\n\n/** The editor chrome's own per-kind copy. */\nexport interface CallableEditorDescriptor {\n /** The back control's label, e.g. `\"← Functions\"`. */\n backLabel: string;\n /** Heading fallback while the definition is still hydrating. */\n newTitle: string;\n /** Rendered in place of the form when the hydration GET 404s. */\n notFoundTitle: string;\n /** The Save button's idle label. */\n saveLabel: string;\n}\n\nexport interface CallableDescriptor {\n kind: CallableKind;\n /** The list page's `<h2>`, and the editor document title's second segment. */\n listTitle: string;\n /** The list page's explanatory paragraph. */\n listDescription: string;\n /** The empty-state paragraph (verbatim, including its typographic quotes). */\n emptyCopy: string;\n /** The create button's label, e.g. `\"+ New function\"`. */\n newLabel: string;\n /** The synthetic id's own prefix — `fn_…`/`ep_…`/`wf_…`, never user-edited. */\n newIdPrefix: string;\n /** `data-testid` of the list's Import affordance. */\n importOpenTestId: string;\n /** `data-testid` of the list's \"Show archived\" checkbox. */\n showArchivedTestId: string;\n /** `data-testid` of a row's \"archived\" badge. */\n archivedBadgeTestId: string;\n /** The row button's `title` tooltip (T4.2.3 — replaces the shared template literal\n * `` `Open this ${kind} in the editor.` ``, since Workflow's own row opens the visual editor,\n * not \"the editor\"). */\n openRowTitle: string;\n editor: CallableEditorDescriptor;\n settings: CallableSettingsDescriptor;\n}\n\n/**\n * The three kinds, every arm named explicitly — a total `Record<CallableKind,\n * …>`, so a fourth kind fails to compile here rather than silently rendering\n * another kind's copy (the same reasoning `COLLECTION_PATH` gives in\n * `src/repos/versions.ts`).\n *\n * Only the `function` arm is consumed today: Endpoints and Workflows keep their\n * own pages until T4.2.2/T4.2.3. Their arms are filled from those pages'\n * current literals so the later nodes are a deletion, not a re-derivation.\n */\nexport const CALLABLE_DESCRIPTORS: Record<CallableKind, CallableDescriptor> = {\n function: {\n kind: \"function\",\n listTitle: \"Functions\",\n listDescription:\n 'A Function is a reusable, vendor-abstracted operation — \"Send Email\", \"Create Contact\" — ' +\n \"with a stable interface bound to one swappable app action. Switch provider by \" +\n \"re-binding; callers never change.\",\n emptyCopy:\n \"None yet — click “New function” to create one, or “Import” to bring in a spec document.\",\n newLabel: \"+ New function\",\n newIdPrefix: \"fn\",\n importOpenTestId: \"functions-import-open\",\n showArchivedTestId: \"functions-show-archived\",\n archivedBadgeTestId: \"function-archived\",\n openRowTitle: \"Open this function in the editor.\",\n editor: {\n backLabel: \"← Functions\",\n newTitle: \"New function\",\n notFoundTitle: \"Function not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: true,\n hasTags: false,\n namePlaceholder: \"Send Email\",\n keyPlaceholder: \"send-email\",\n keyHintSuffix: \"\",\n },\n },\n endpoint: {\n kind: \"endpoint\",\n listTitle: \"Endpoints\",\n listDescription:\n \"An Endpoint is a named, stable entry point that dispatches to one app action, Function, \" +\n \"or Workflow. Callers bind to the Endpoint; the target behind it can change — promote an \" +\n \"action to a Function or a Workflow, or re-bind it — without breaking a single caller.\",\n emptyCopy: \"None yet — click “New endpoint” to create one.\",\n newLabel: \"+ New endpoint\",\n newIdPrefix: \"ep\",\n importOpenTestId: \"endpoints-import-open\",\n showArchivedTestId: \"endpoints-show-archived\",\n archivedBadgeTestId: \"endpoint-archived\",\n openRowTitle: \"Open this endpoint in the editor.\",\n editor: {\n backLabel: \"← Endpoints\",\n newTitle: \"New endpoint\",\n notFoundTitle: \"Endpoint not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: false,\n hasTags: false,\n namePlaceholder: \"My endpoint\",\n keyPlaceholder: \"send-email\",\n keyHintSuffix: \"\",\n },\n },\n workflow: {\n kind: \"workflow\",\n listTitle: \"Workflows\",\n listDescription:\n \"A Workflow is a durable, multi-step run: each step calls an app action, a Function, or \" +\n \"another Workflow, and a run keeps its own state, history and error handling.\",\n emptyCopy: \"None yet — click “New workflow” to create one.\",\n newLabel: \"+ New workflow\",\n newIdPrefix: \"wf\",\n importOpenTestId: \"workflows-import-open\",\n showArchivedTestId: \"workflows-show-archived\",\n archivedBadgeTestId: \"workflow-archived\",\n openRowTitle: \"Open this workflow in the visual editor.\",\n editor: {\n backLabel: \"← Workflows\",\n newTitle: \"New workflow\",\n notFoundTitle: \"Workflow not found\",\n saveLabel: \"Save\",\n },\n settings: {\n canEditKey: true,\n hasTags: true,\n namePlaceholder: \"My workflow\",\n keyPlaceholder: \"unset\",\n keyHintSuffix: \" Leave empty to unset.\",\n },\n },\n};\n\n/** Look a descriptor up by kind. A plain index, never a `switch`: the `Record`\n * above already made every arm total. */\nexport function descriptorFor(kind: CallableKind): CallableDescriptor {\n return CALLABLE_DESCRIPTORS[kind];\n}\n\n/**\n * A fresh synthetic id for a create-modal's first POST — `fn_<uuid>` for a\n * Function (verbatim the `newFunctionId` `FunctionsPage.tsx` used to hold),\n * `ep_`/`wf_` for the other two, whose pages mint the same shapes today. The\n * prefix comes from the descriptor, so \"which kind is this?\" is answered by the\n * same table that answers every other kind question.\n */\nexport function newCallableId(kind: CallableKind): string {\n return newId(descriptorFor(kind).newIdPrefix);\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { type W6WClient, isFunctionRun } from \"@w6w/sdk\";\nimport type { FunctionSummary as SdkFunctionSummary } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n/**\n * The Function-bound facade over the kind-parametrised repo (`src/repos/callables.ts`, T4.2.1).\n *\n * Everything here that is not Function-specific is one line delegating to `callables.ts` with\n * `\"function\"` bound in — the list/get queries, the save mutation, archive and delete — so the\n * Function arm of every kind-wide behaviour has exactly ONE implementation to fix. What stays is\n * what only a Function has: the `manifestVersion: \"2\"` literal, the SDK's Function type re-exports,\n * the `valid`-carrying summary widening, and the run-plane invoke (`client.run`, `isFunctionRun`)\n * that no other kind's page uses.\n *\n * The delegations keep their original names and call shapes on purpose: `ui/rail/SettingsTool.tsx`,\n * `ui/rail/AliasesTool.tsx`, `ui/rail/ErrorHandlingTool.tsx`, `components/TargetSelector.tsx`,\n * `components/FunctionIdentityModal.tsx` and `api/w6wApiFacade.tsx` all import from here, and this\n * node moves no behaviour — only where the code lives.\n */\nimport { callableKey } from \"../lib/callable-kind.ts\";\nimport { invalidateSavedCallable } from \"../lib/save-invalidation.ts\";\nimport {\n callableListKey,\n useArchiveCallableMutation,\n useCallableListQuery,\n useCallableQuery,\n useDeleteCallableMutation,\n useSaveCallableMutation,\n} from \"./callables.ts\";\n\nexport type {\n FunctionDef,\n FunctionImpl,\n FunctionInput,\n FunctionOutputField,\n} from \"@w6w/sdk/console\";\n\n/** A Function list row — the SDK's own summary (it carries `archivedAt` since W-12). */\nexport type FunctionSummary = SdkFunctionSummary;\n\n/** The list key {@link useFunctionsQuery} reads — `callables.ts`'s own\n * `callableListKey(\"function\")`, kept as a named export because\n * `lib/spec-import-invalidation.ts` invalidates it by value. */\nexport const functionsKey = callableListKey(\"function\");\n\n/** Function definitions carry `manifestVersion: \"2\"` - the one literal, shared\n * by the editor's blank draft and the create modal's first POST. */\nexport const FUNCTION_MANIFEST_VERSION = \"2\";\n\nexport function listFunctions(client: W6WClient) {\n return client.console.functions.list();\n}\n\nexport function useFunctionsQuery(enabled = true) {\n return useCallableListQuery<FunctionSummary>(\"function\", enabled);\n}\n\nexport const functionKey = (id: string) => callableKey(\"function\", id);\n\n/** The Function arm's own reader: the SDK's typed `get`, whose `{...function, valid}` splice is\n * what `FunctionEditor` hydrates its draft from (pin 5 — the server computes `valid`; studio\n * never reimplements the check). */\nexport function getFunction(client: W6WClient, id: string) {\n return client.console.functions.get(id);\n}\n\nexport function useFunctionQuery(id: string, enabled = true) {\n return useCallableQuery<Awaited<ReturnType<typeof getFunction>>>(\"function\", id, enabled);\n}\n\nexport function useSaveFunctionMutation() {\n return useSaveCallableMutation(\"function\");\n}\n\n/**\n * The GUARDED Function save: `console.functions.upsert(definition, {ifUnmodifiedSince})`, so a\n * save made from a stale copy answers `409 function_stale` instead of overwriting the newer one.\n * `ifUnmodifiedSince` is REQUIRED in the variables (pass `null` to opt out explicitly) so a call\n * site cannot forget the token; it is the `updatedAt` of the copy the definition was edited from\n * (`callableRecord(\"function\", …).updatedAt`). Same invalidation as {@link useSaveFunctionMutation}\n * (list + the saved resource's key); resolves `{id, key, updatedAt}`. Additive: the unguarded\n * hook's `mutate(definition)` shape is unchanged.\n */\nexport function useGuardedSaveFunctionMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { definition: unknown; ifUnmodifiedSince: string | null }) =>\n apiClient.console.functions.upsert(vars.definition as never, {\n ifUnmodifiedSince: vars.ifUnmodifiedSince,\n }),\n onSuccess: (saved) => invalidateSavedCallable(qc, functionsKey, functionKey(saved.id)),\n });\n}\n\n/**\n * One test invoke's result: the Function's own output, plus the platform's\n * record of the attempt.\n *\n * The two are kept apart rather than merged because they answer different\n * questions, and merging them is what the invocation envelope exists to stop:\n * a vendor payload reading `{\"statusCode\": 202}` is SendGrid describing its own\n * request, while `status` here is whether w6w considered the call a success.\n * The frame fields are optional — an older server sends only the output.\n */\nexport interface FunctionInvokeResult {\n output: unknown;\n invocationId?: string;\n status?: string;\n durationMs?: number;\n}\n\n/**\n * `fn_…` ids are already URN-shaped, so the base dispatcher resolves them\n * directly — no id translation. `isFunctionRun` narrows the open\n * `RunEnvelope`; a `fn_…` URN can only ever resolve to the `function` arm\n * server-side, so the `else` branch is defensive, not a real code path.\n */\nexport function invokeFunction(\n client: W6WClient,\n id: string,\n inputs: Record<string, unknown>,\n): Promise<FunctionInvokeResult> {\n return client.run({ urn: id, payload: inputs }).then((env) => {\n if (!isFunctionRun(env)) {\n throw new Error(`expected a function-kind run envelope for \"${id}\", got \"${env.kind}\"`);\n }\n return {\n output: env.output,\n invocationId: env.invocationId,\n status: env.status,\n durationMs: env.durationMs,\n };\n });\n}\n\nexport function useInvokeFunctionMutation() {\n const apiClient = useEmbedClient();\n return useMutation({\n mutationFn: (vars: { id: string; inputs: Record<string, unknown> }) =>\n invokeFunction(apiClient, vars.id, vars.inputs),\n });\n}\n\n/**\n * T4.1.1/A7/D-I0-7: `POST /functions/:id/archive`, `DELETE /functions/:id` — the Function arm of\n * `callables.ts`'s generic pair (the plain `apiClient.request()` escape hatch, NOT a typed\n * `@w6w/sdk` method, which would drag `packages/wrappers` into this task's scope for two internal\n * routes). Both invalidate `functionsKey`, so the list's `archivedAt` refreshes and the rail's\n * Delete control appears in Archive's place.\n */\nexport function useArchiveFunctionMutation() {\n return useArchiveCallableMutation(\"function\");\n}\n\nexport function useDeleteFunctionMutation() {\n return useDeleteCallableMutation(\"function\");\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport type { W6WClient } from \"@w6w/sdk\";\nimport type {\n EndpointDef as SdkEndpointDef,\n EndpointSummary as SdkEndpointSummary,\n EndpointTarget as SdkEndpointTarget,\n} from \"@w6w/sdk/console\";\n/**\n * The Endpoint-bound facade over the kind-parametrised repo (`src/repos/callables.ts`, T4.2.2).\n *\n * Everything here that is not Endpoint-specific is one line delegating to `callables.ts` with\n * `\"endpoint\"` bound in — the list/get queries, archive and delete — so the Endpoint arm of every\n * kind-wide behaviour has exactly ONE implementation to fix (the shape `repos/functions.ts` took in\n * T4.2.1, and the \"keep the facade's exports\" rule that module documents). What stays is what only\n * an Endpoint has: the `manifestVersion: \"2\"` literal, the SDK's Endpoint type re-exports, the\n * `status`/`incomplete`/`archivedAt`-carrying summary widening with its one reader\n * {@link isEndpointDraft}, the server-rendered `invokeUrls[]` widening, the synchronous invoke\n * (`client.console.endpoints.invoke`), and the SAVE — whose 201 carries those `invokeUrls[]` back to\n * the editor's URL card, which is why its `mutationFn` is the one arm the generic `saveCallable`\n * cannot serve.\n *\n * The delegations keep their original names and call shapes on purpose: `ui/rail/SettingsTool.tsx`,\n * `ui/rail/AliasesTool.tsx`, `ui/rail/ErrorHandlingTool.tsx`, `components/TargetSelector.tsx`,\n * `components/EndpointIdentityModal.tsx`, `repos/versions.ts` (the revert arm's `endpointKey`) and\n * `repos/spec-import.ts` (`endpointsKey`) all import from here, and this node moves no behaviour —\n * only where the code lives. The two key exports stay byte-identical because both are the builders\n * `callables.ts` already documents as frozen (`[\"endpoints\"]`, `[\"endpoint\", id]`).\n */\nimport { callableKey } from \"../lib/callable-kind.ts\";\nimport { invalidateSavedCallable } from \"../lib/save-invalidation.ts\";\n\nexport type {\n ActionTarget,\n CallableRef,\n CallableOnError,\n ErrorHandlerTarget,\n EndpointAuthMode,\n EndpointInput,\n EndpointInvokeResult,\n EndpointSecurity,\n EndpointTarget,\n ErrorReroute,\n Exposure,\n RetryPolicy,\n} from \"@w6w/sdk/console\";\nexport { SECRET_MASK } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n callableListKey,\n useArchiveCallableMutation,\n useCallableListQuery,\n useCallableQuery,\n useDeleteCallableMutation,\n} from \"./callables.ts\";\n\n/** An Endpoint's OWN target: the alias-only `endpoint` arm excluded, mirroring the\n * server fence in admin/endpoints.ts's validateDefinition. Aliases use the full union\n * (`EndpointTarget`, re-exported above verbatim). */\nexport type EndpointOwnTarget = Exclude<SdkEndpointTarget, { kind: \"endpoint\" }>;\nexport type EndpointDef = Omit<SdkEndpointDef, \"target\"> & { target: EndpointOwnTarget };\n\n/**\n * One entry of the `invokeUrls[]` array the server renders on `GET\n * /endpoints/:id` and the `POST /endpoints` 201 (T3.4.1, `admin/endpoints.ts`'s\n * `InvokeUrlEntry` — the shapes are kept in sync by hand, not shared, because\n * `@w6w/sdk` does not type this field yet: it is server-fresh and\n * `packages/wrappers` publishes in lockstep at one `VERSION` across four\n * languages, outside this project's boundary (HITL-10). `entries[0]` is always\n * the platform entry; every entry after it is one of the tenant's domains.\n * `default` mirrors the tenant's stored default domain and, since D-S1\n * (intake T-0.2), it is what CHOOSES the open-on entry: absent an\n * in-session pick, the URL card opens on whichever entry carries it,\n * falling back to `entries[0]` only when no entry does. `resolves` is a\n * static host comparison the server already made; the client never\n * re-derives it.\n */\nexport interface InvokeUrlOption {\n domain: string;\n default: boolean;\n url: string;\n urlByKey?: string;\n resolves: boolean;\n}\n\n/** The two SDK-typed URL fields, widened with the untyped `invokeUrls[]`\n * array — the ONE seam `getEndpoint`, the save mutation and the editor's own\n * 201 read all widen through, so `EndpointsPage.tsx` never casts. */\ntype WithInvokeUrls = {\n invokeUrl: string;\n invokeUrlByKey?: string;\n invokeUrls?: InvokeUrlOption[];\n};\n\n/** An Endpoint list row — the SDK's own summary (`status`, `incomplete` and `archivedAt` are\n * on it since W-12), read for draft-ness only through {@link isEndpointDraft}. */\nexport type EndpointSummary = SdkEndpointSummary;\n\n/** Is this row a draft — not authorised to dispatch (HITL-7/HITL-8,\n * `rfcs/endpoint.md` § Amendment — 2026-08-14b)? Prefers the server's `status`\n * field (`!== \"ready\"`), falling back to the older `incomplete` boolean only\n * when `status` is absent (a server that has not shipped it yet). The sole\n * reader of both fields in studio; every \"unfinished\" UI decision (the\n * list's tag, and any future one) calls this rather than reading either\n * field inline. */\nexport function isEndpointDraft(ep: Pick<EndpointSummary, \"status\" | \"incomplete\">): boolean {\n return ep.status !== undefined ? ep.status !== \"ready\" : ep.incomplete === true;\n}\n\n/** Endpoint definitions carry `manifestVersion: \"2\"` — the one literal, shared\n * by the editor's blank draft and the create modal's first POST. */\nexport const ENDPOINT_MANIFEST_VERSION = \"2\";\n\n/** The list key {@link useEndpointsQuery} reads — `callables.ts`'s own\n * `callableListKey(\"endpoint\")` (byte-identical `[\"endpoints\"]`), kept as a named export because\n * `repos/spec-import.ts` invalidates it by value. */\nexport const endpointsKey = callableListKey(\"endpoint\");\n\nexport function useEndpointsQuery(enabled = true) {\n return useCallableListQuery<EndpointSummary>(\"endpoint\", enabled);\n}\n\n/** Fetch one Endpoint. Widens the SDK's return once — the server sends\n * `invokeUrls[]` (T3.4.1) that `@w6w/sdk`'s typed `get()` does not know about\n * yet; see {@link WithInvokeUrls}. */\nexport function getEndpoint(\n client: W6WClient,\n id: string,\n): Promise<{ endpoint: EndpointDef } & WithInvokeUrls> {\n return client.console.endpoints.get(id) as Promise<{ endpoint: EndpointDef } & WithInvokeUrls>;\n}\n\n/** The single-resource key — `callables.ts`'s own `callableKey(\"endpoint\", id)` (byte-identical\n * `[\"endpoint\", id]`), kept as a named export because `repos/versions.ts`'s revert arm invalidates\n * it by value. */\nexport const endpointKey = (id: string) => callableKey(\"endpoint\", id);\n\n/** `TargetSelector`'s `endpoint` arm needs one Endpoint's own `input` contract\n * to project into fields — mirrors `useFunctionQuery`/`useWorkflowQuery`\n * (`repos/functions.ts`/`repos/workflows.ts`) exactly. */\nexport function useEndpointQuery(id: string, enabled = true) {\n return useCallableQuery<Awaited<ReturnType<typeof getEndpoint>>>(\"endpoint\", id, enabled);\n}\n\n/**\n * The Endpoint arm's SAVE — the one delegated name whose `mutationFn` is NOT `callables.ts`'s\n * `saveCallable`: that helper normalises every kind's success envelope down to `{id, key}` for the\n * invalidation below, while this kind's 201 also carries the fresh server-rendered `invokeUrl`/\n * `invokeUrlByKey`/`invokeUrls[]` the editor's URL card renders from (`onSaveSuccess` in\n * `EndpointsPage.tsx`). Its KEYS and its invalidation, though, are the generic pair's — so the\n * \"which keys does an Endpoint save refresh\" answer still has one home.\n */\nexport function useSaveEndpointMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n // Same widening as `getEndpoint` — the save's 201 carries `invokeUrls[]` too.\n mutationFn: (definition: unknown) =>\n apiClient.console.endpoints.upsert(definition as never) as Promise<\n { endpoint: { id: string; key: string } } & WithInvokeUrls\n >,\n onSuccess: (saved) => invalidateSavedCallable(qc, endpointsKey, endpointKey(saved.endpoint.id)),\n });\n}\n\n/**\n * The GUARDED Endpoint save: `console.endpoints.upsert(definition, {ifUnmodifiedSince})`, so a\n * save from a stale copy answers `409 endpoint_stale`. Variables and invalidation as\n * {@link useSaveEndpointMutation}'s, plus the required token (`null` opts out explicitly; it is\n * `callableRecord(\"endpoint\", …).updatedAt`, the envelope's TOP-LEVEL `updatedAt`). Resolves the\n * verbatim upsert body (`{endpoint:{id,key}, invokeUrl, …, updatedAt}`). Additive: the unguarded\n * hook's `mutate(definition)` shape is unchanged.\n */\nexport function useGuardedSaveEndpointMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (vars: { definition: unknown; ifUnmodifiedSince: string | null }) =>\n apiClient.console.endpoints.upsert(vars.definition as never, {\n ifUnmodifiedSince: vars.ifUnmodifiedSince,\n }) as Promise<{ endpoint: { id: string; key: string }; updatedAt: string } & WithInvokeUrls>,\n onSuccess: (saved) => invalidateSavedCallable(qc, endpointsKey, endpointKey(saved.endpoint.id)),\n });\n}\n\nexport function invokeEndpoint(client: W6WClient, id: string, input: Record<string, unknown>) {\n return client.console.endpoints.invoke(id, input);\n}\n\nexport function useInvokeEndpointMutation() {\n const apiClient = useEmbedClient();\n return useMutation({\n mutationFn: (vars: { id: string; input: Record<string, unknown> }) =>\n invokeEndpoint(apiClient, vars.id, vars.input),\n });\n}\n\n/**\n * T4.1.1/A7/D-I0-7: `POST /endpoints/:id/archive` — the Endpoint arm of `callables.ts`'s generic\n * pair (the plain `apiClient.request()` escape hatch, NOT a typed `@w6w/sdk` method, which would\n * drag `packages/wrappers` into this task's scope for one internal route). Invalidates\n * `endpointsKey`, so the list's `archivedAt` refreshes and the rail's Delete control appears in\n * Archive's place.\n */\nexport function useArchiveEndpointMutation() {\n return useArchiveCallableMutation(\"endpoint\");\n}\n\n/** `DELETE /endpoints/:id` — the Endpoint arm of the same generic pair. */\nexport function useDeleteEndpointMutation() {\n return useDeleteCallableMutation(\"endpoint\");\n}\n"],"names":["ID_ALPHABET","REJECT_AT","defaultBytes","newId","prefix","len","bytes","out","b","CALLABLE_DESCRIPTORS","descriptorFor","kind","newCallableId","functionsKey","callableListKey","FUNCTION_MANIFEST_VERSION","listFunctions","client","useFunctionsQuery","enabled","useCallableListQuery","functionKey","id","callableKey","getFunction","useFunctionQuery","useCallableQuery","useSaveFunctionMutation","useSaveCallableMutation","useGuardedSaveFunctionMutation","apiClient","useEmbedClient","qc","useQueryClient","useMutation","vars","saved","invalidateSavedCallable","invokeFunction","inputs","env","isFunctionRun","useInvokeFunctionMutation","useArchiveFunctionMutation","useArchiveCallableMutation","useDeleteFunctionMutation","useDeleteCallableMutation","isEndpointDraft","ep","ENDPOINT_MANIFEST_VERSION","endpointsKey","useEndpointsQuery","getEndpoint","endpointKey","useEndpointQuery","useSaveEndpointMutation","definition","useGuardedSaveEndpointMutation","invokeEndpoint","input","useInvokeEndpointMutation","useArchiveEndpointMutation","useDeleteEndpointMutation"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"slug-C4ktDPdy.js","sources":["../src/lib/sdk-snippets.ts","../src/lib/slug.ts"],"sourcesContent":["/**\n * Node/CLI call snippets for a studio resource — \"how do I do this from code?\"\n *\n * Pure string builders over the wrapper contract at `packages/wrappers`\n * (`endpoints.json` + `docs/endpoints.md`). Nothing here fetches, and nothing\n * here invents an operation: every snippet emitted maps to an operation the\n * contract lists as `status: required, serverImplemented: true`, using the exact\n * symbol its `naming.ts` / `naming.cli` field pins. If an operation is not in\n * the contract there is no snippet for it — a copyable example of a method that\n * does not exist is worse than no example.\n *\n * The surface at contract v0.3.0, and what each studio page can therefore show:\n *\n * | Resource | Node | CLI | Python | curl |\n * |-----------|-------------------------------------|------------------------------|--------|------|\n * | Workflow | `client.workflows.run(id, opts?)` | `w6w workflows run <id>` | `client.workflows.run(id, ...)` | `curl … /workflows/{id}/run?wait=true` |\n * | Function | `client.functions.run(name, {payload})` | `w6w functions run <name>` | `client.functions.run(name, payload=...)` | `curl … /functions/{name}/invoke` |\n * | Endpoint | `client.endpoints.run(name, {payload})` | `w6w endpoints run <name>` | `client.endpoints.run(name, payload=...)` | `curl … <server-rendered URL>` |\n * | Connection | `client.run({urn, action, payload})` | `w6w run <urn> --action` | `client.run(urn, action=..., payload=...)` | — |\n * | Var | `client.vars.getByName(name)` | `w6w vars get-by-name <n>` | `client.vars.get_by_name(name)` | — |\n * | Document | `client.documents.getByKey(key)` | `w6w documents get-by-key` | `client.documents.get_by_key(key)` | — |\n *\n * There is a fourth, contract-free arm: a raw-HTTP (`curl`) snippet, for the\n * three kinds a caller reaches through a fixed route — Function and Workflow\n * against the `$W6W_BASE_URL` env placeholder (the same one the node/cli/python\n * arms already tell the reader to export), and Endpoint against the URL the\n * SERVER rendered, handed in on the resource. It maps to no wrapper operation\n * on purpose — the three wrapper arms reach a Function or Endpoint through\n * `run`, which takes a URN and not a URL, so raw HTTP is the only place a\n * literal route (or, for an Endpoint, the id-form / key-form URL toggle) can\n * even be shown. An Endpoint's URL is used VERBATIM: nothing here concatenates\n * a host, a path or a slug onto it. Connection, Var and Document have no\n * fixed single-resource route to curl against, so they carry no `curl` arm.\n *\n * **Functions and Endpoints have their own namespaces** as of `@w6w/sdk` 0.6.0\n * (contract 0.3.0): `functions.run(name, {payload})` and\n * `endpoints.run(name, {payload})`, with the NAME FIRST and the same slot\n * accepting either the resource's key or its `fn_…`/`ep_…` id — the two shapes\n * cannot collide, so nothing is tagged. This module used to emit\n * `client.run({urn: \"fn:send-email\"})`, a kind smuggled into a string because\n * the field was one string; that form is gone.\n *\n * **One form per kind, always.** An earlier version rendered\n * `client.run({urn: alias})` for a resource that carried an alias, which put\n * two different call styles side by side for two Functions. `key` is required\n * on every Function and Endpoint server-side, so the namespace call always\n * works and the alias form was never the only way in. An alias is a SECOND\n * address with its own rail (`alias-rail.ts`); it is not advertised here,\n * because the answer to \"how do I call this Function?\" should not change shape\n * depending on whether someone aliased it. See {@link addressName}.\n *\n * `isUrnAddressable` still gates every arm: an id without its kind prefix is\n * not addressable by `run`, so the snippet is withheld rather than emitting a\n * call that cannot work.\n */\n\nimport type { TriggerPreviewFieldDef } from \"./trigger-preview.ts\";\n\n/**\n * One declared input of a Function or Endpoint, as a snippet needs it.\n *\n * A BARE STRING is treated as REQUIRED. That is the shape this file took before\n * it knew about optionality, when every input rendered active — so a caller that\n * only has keys keeps its existing output rather than silently having every\n * field commented out.\n */\nexport type SnippetInput = string | { key: string; required?: boolean };\n\n/** Normalized, so the renderers below never branch on the union. */\ninterface ResolvedInput {\n key: string;\n required: boolean;\n}\n\n/** What the caller is looking at. Mirrors the four runnable URN arms plus assets. */\nexport type SnippetCallable =\n | { kind: \"workflow\"; id: string; displayName?: string; key?: string; alias?: string }\n | { kind: \"function\"; id: string; key?: string; inputs?: readonly SnippetInput[]; alias?: string }\n /**\n * An Endpoint. `invokeUrl` / `invokeUrlByKey` are the two SERVER-rendered\n * forms of its public address, passed straight through from the endpoints\n * envelope; `urlForm` is which of them the page currently has selected, so a\n * raw-HTTP sample follows the toggle the reader can see. All three are\n * optional — an Endpoint with no URL in hand simply gets no HTTP snippet.\n * `inputs` are the target's input parameter keys, resolved from the Function\n * or Workflow the Endpoint dispatches to.\n */\n | {\n kind: \"endpoint\";\n id: string;\n key?: string;\n invokeUrl?: string;\n invokeUrlByKey?: string;\n urlForm?: \"id\" | \"key\";\n alias?: string;\n inputs?: readonly SnippetInput[];\n }\n /** One app action, invoked through a connection — the `conn_` URN arm. */\n | { kind: \"connection\"; id: string; action: string; params?: string[] }\n | { kind: \"var\"; name: string }\n | { kind: \"document\"; key: string };\n\nexport interface Snippet {\n /** Runnable TypeScript against `@w6w/sdk`. */\n node: string;\n /** A single `w6w …` invocation. */\n cli: string;\n /** Runnable Python against `w6w` (PyPI). */\n python: string;\n /**\n * A raw-HTTP (`curl`) call against the resource's own public URL — OPTIONAL,\n * and emitted only where such a URL exists and was handed in (today: an\n * Endpoint). Optional rather than required so the other five `case` arms of\n * {@link buildSnippet} are untouched, and so the tab strip can render only\n * the tabs a built snippet actually carries.\n */\n curl?: string;\n /** The contract operation this maps to, shown so the snippet is checkable. */\n operation: string;\n}\n\n/**\n * The URN prefixes `POST /run` resolves. Kept as data rather than inlined so\n * the gate below and the docs above cannot drift apart.\n */\nconst RUNNABLE_PREFIXES = [\"conn_\", \"fn_\", \"wf_\", \"ep_\"] as const;\n\n/**\n * Can this id be passed to `client.run({urn})` at all?\n *\n * Ids are host-issued and carry a kind prefix (rfcs/function.md §id — \"host-issued\n * opaque id (`fn_…`)\"), but the create routes do not *enforce* it, so a\n * hand-authored id can reach the database without one. Such a resource is\n * reachable through the studio and through its own `/invoke` route, but NOT\n * through the URN operation the wrappers expose — and a snippet is a promise\n * that the code in it runs.\n */\nexport function isUrnAddressable(id: string): boolean {\n return RUNNABLE_PREFIXES.some((p) => id.startsWith(p));\n}\n\n/**\n * The three kinds `POST /run` addresses by URN and that can carry an alias.\n */\ntype AddressableCallable = Extract<SnippetCallable, { kind: \"workflow\" | \"function\" | \"endpoint\" }>;\n\n/**\n * The name a snippet addresses a resource by: its own `key`, falling back to\n * the opaque id when it somehow has none.\n *\n * ONE FORM, ALWAYS — `functions.run(name)` / `endpoints.run(name)`. An earlier\n * version branched to `client.run({urn: alias})` when the resource carried an\n * alias, which rendered two different call styles for two Functions side by\n * side. That inconsistency bought nothing: `key` is REQUIRED on every Function\n * and Endpoint server-side (`admin/functions.ts`: \"`key` is required\"), so the\n * namespace call always works and the alias form was never the only way in.\n *\n * An alias is a SECOND address, not a substitute for the first, and it has its\n * own rail (`alias-rail.ts`) on the page where it belongs. It is deliberately\n * not advertised here: this snippet answers \"how do I call this Function?\",\n * and the answer should not change shape depending on whether someone happened\n * to alias it.\n *\n * `key` is optional on the type rather than on the wire — a row that predates\n * the requirement can still reach the studio — so the id fallback stays.\n */\nfunction addressName(resource: AddressableCallable): string {\n const key = (resource as { key?: string }).key?.trim();\n return key && key.length > 0 ? key : resource.id;\n}\n\n/** Single-quoted shell literal — `'` closed, escaped, reopened. */\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n\n/**\n * Past this many characters a one-line command is harder to read than a\n * continued one. Chosen so the common `w6w run <urn> --action <a>` stays on one\n * line and only a real payload pushes it over.\n */\nconst CLI_WRAP_AT = 72;\n\n/**\n * Assemble a CLI command, breaking it across lines with `\\` when it is long.\n *\n * A single-line `w6w run conn_… --action … --payload '{\"a\":\"<a>\",\"b\":\"<b>\"}'`\n * runs off the edge of the panel, so the reader scrolls sideways to find out\n * what the flags even are. Continued, each flag is its own line and the shape\n * of the call is visible at a glance:\n *\n * w6w run conn_c19f4db6 \\\n * --action message-post \\\n * --payload '{\"channel\":\"<channel>\"}'\n *\n * `\\`-newline is the POSIX continuation, so the wrapped form pastes into\n * bash/zsh **and copies as one command** — the text is identical to what the\n * shell sees. (It is not `cmd.exe` syntax; the snippets already assume a POSIX\n * shell for their single-quoting.)\n *\n * Short commands are left alone: breaking `w6w vars get-by-name x` across two\n * lines makes it less readable, not more.\n *\n * @param head the command and its positional argument(s), never split\n * @param flags one `--flag value` (or bare `--flag`) per entry\n */\nfunction cliCommand(head: string, ...flags: string[]): string {\n const parts = [head, ...flags].filter((p) => p.length > 0);\n const oneLine = parts.join(\" \");\n if (flags.length === 0 || oneLine.length <= CLI_WRAP_AT) return oneLine;\n return parts.join(\" \\\\\\n \");\n}\n\n/** Normalize the caller's input list. A bare key is required — see {@link SnippetInput}. */\nfunction resolveInputs(inputs: readonly SnippetInput[] | undefined): ResolvedInput[] {\n if (!inputs || inputs.length === 0) return [];\n return inputs\n .map((i) =>\n typeof i === \"string\"\n ? { key: i, required: true }\n : {\n key: i.key,\n // Only an explicit `true` is required — an undeclared flag means the\n // Function did not mark it, which is exactly what optional means.\n required: i.required === true,\n },\n )\n .filter((i) => typeof i.key === \"string\" && i.key.trim() !== \"\");\n}\n\n/**\n * A sample payload for a Function's declared inputs, so the snippet shows the\n * shape rather than an empty object the reader has to go and look up.\n * Values are placeholders — this is an example, not a saved request.\n *\n * `requiredOnly` is for the comment-less lanes (JSON has no comments), which\n * carry the required fields and name the optional ones in trailing shell\n * comments instead — the same D-4 split the workflow arm already makes.\n */\nfunction samplePayload(\n inputs: readonly SnippetInput[] | undefined,\n requiredOnly = false,\n): Record<string, string> {\n const resolved = resolveInputs(inputs);\n const used = requiredOnly ? resolved.filter((i) => i.required) : resolved;\n return Object.fromEntries(used.map((i) => [i.key, `<${i.key}>`]));\n}\n\n/**\n * The payload object rendered as SOURCE, with optional inputs commented out —\n * the same active/commented rule {@link nodeInputBlock} applies to a trigger's\n * fields, so both halves of this file read alike.\n *\n * EVERY line ends with a comma, active or commented. A JS object literal\n * tolerates the trailing one, and without it uncommenting the last optional\n * field would leave the line above it without a separator — a paste that no\n * longer parses, produced by doing exactly what the comment invites.\n */\nfunction payloadSource(\n inputs: readonly SnippetInput[] | undefined,\n opts: { indent: string; comment: string; compact?: boolean },\n): string {\n const resolved = resolveInputs(inputs);\n if (resolved.length === 0) return \"{}\";\n // Python's payload is a one-liner today, and stays one when there is nothing\n // to comment: the multi-line form exists to carry the `#` lines, so growing\n // it for a Function whose inputs are all required would be churn in every\n // snippet to serve the minority that needs it.\n if (opts.compact && resolved.every((i) => i.required)) {\n return JSON.stringify(Object.fromEntries(resolved.map((i) => [i.key, `<${i.key}>`])));\n }\n const lines = resolved.map(({ key, required }) => {\n const member = `${JSON.stringify(key)}: ${JSON.stringify(`<${key}>`)},`;\n return required ? `${opts.indent} ${member}` : `${opts.indent} ${opts.comment} ${member}`;\n });\n return `{\\n${lines.join(\"\\n\")}\\n${opts.indent}}`;\n}\n\n/**\n * Trailing `# optional: <key>` lines for the lanes that cannot carry a comment\n * INSIDE the payload (CLI and curl both pass JSON). Appended after the command,\n * and none of them ends with a backslash, so the block still pastes and runs as\n * one command. Mirrors `cliWorkflowCommand`/`curlWorkflowCommand`.\n */\nfunction optionalNotes(inputs: readonly SnippetInput[] | undefined): string {\n return resolveInputs(inputs)\n .filter((i) => !i.required)\n .map((i) => `\\n# optional: ${i.key}`)\n .join(\"\");\n}\n\n/**\n * A trigger field with no declared/blank `key` is dropped — mirrors\n * `trigger-preview.ts`'s own `triggerPreviews()` (and `@w6w/ui/flow`'s\n * `fieldsToParams`), which do the same before turning field defs into\n * anything fillable. Declared order is preserved.\n */\nfunction usableTriggerFields(\n fields: readonly TriggerPreviewFieldDef[] | undefined,\n): TriggerPreviewFieldDef[] {\n if (!fields) return [];\n return fields.filter((f) => typeof f.key === \"string\" && f.key.trim() !== \"\");\n}\n\n/**\n * The D-3 placeholder VALUE for a trigger field's declared `type`. The domain\n * is closed at four values — `trigger-fields.ts`'s `fieldWidget()` collapses\n * anything else to `\"string\"` — so this mirrors that collapse rather than\n * re-deriving it. The `\"<key>\"` form mirrors `samplePayload()`'s own\n * convention, so both arms of this file stay idiomatic.\n */\nfunction fieldPlaceholderValue(\n type: string | undefined,\n key: string,\n): string | number | boolean | Record<string, never> {\n if (type === \"number\") return 0;\n if (type === \"boolean\") return false;\n if (type === \"json\") return {};\n return `<${key}>`;\n}\n\n/**\n * The placeholder rendered as SOURCE CODE for one lane. Only the boolean\n * literal differs between Python (`False`) and Node/JSON (`false`) — a\n * shared `JSON.stringify` across all three lanes would emit `false` into\n * Python and raise `NameError` the moment the pasted snippet runs, which is\n * why this branches on `python` rather than reusing one formatter.\n */\nfunction fieldSourceLiteral(type: string | undefined, key: string, python: boolean): string {\n const value = fieldPlaceholderValue(type, key);\n if (typeof value === \"boolean\") return python ? \"False\" : \"false\";\n return JSON.stringify(value);\n}\n\n/**\n * The trigger's `input` object rendered into the Node call — required fields\n * active, optional fields commented out with `//` (D-3/D-4). `\"\"` when there\n * is nothing to show, so the caller can splice it straight after `wait: true,`\n * without leaving a dangling empty block.\n */\nfunction nodeInputBlock(fields: readonly TriggerPreviewFieldDef[]): string {\n if (fields.length === 0) return \"\";\n const lines = fields.map((f) => {\n // A field key is free text (`packages/ui/src/flow-types.ts:340`, no\n // validation) — `first-name`, `2fa`, `api key` are all reachable. A bare\n // object member (`first-name: ...`) is not valid TypeScript; quoting the\n // key with `JSON.stringify` (the same shape `:311`'s payload already\n // uses) is correct for every key by construction, so nothing here has to\n // decide what counts as a \"safe\" identifier.\n const member = `${JSON.stringify(f.key)}: ${fieldSourceLiteral(f.type, f.key as string, false)},`;\n return f.required === true ? ` ${member}` : ` // ${member}`;\n });\n return `\n input: {\n${lines.join(\"\\n\")}\n },`;\n}\n\n/**\n * The whole `client.workflows.run(...)` call expression for Python — not just\n * the `input=` block, because the no-fields case keeps the existing\n * single-line call rather than growing an empty `input={}`. Same active/\n * commented rule as `nodeInputBlock()`, `#` in place of `//`.\n */\nfunction pythonWorkflowCall(id: string, fields: readonly TriggerPreviewFieldDef[]): string {\n const idLiteral = JSON.stringify(id);\n if (fields.length === 0) return `client.workflows.run(${idLiteral}, wait=True)`;\n const lines = fields.map((f) => {\n const member = `\"${f.key}\": ${fieldSourceLiteral(f.type, f.key as string, true)},`;\n return f.required === true ? ` ${member}` : ` # ${member}`;\n });\n return `client.workflows.run(\n ${idLiteral},\n wait=True,\n input={\n${lines.join(\"\\n\")}\n },\n)`;\n}\n\n/**\n * The CLI arm of the same rule (D-4): JSON admits no comments, so\n * `--input '<json>'` carries the REQUIRED fields only, and each optional\n * field's key is instead named in a trailing `#` shell-comment line. Those\n * lines are appended after `cliCommand()` returns and none of them ends\n * with `\\`, so the whole block — command plus comments — still pastes and\n * runs as one command.\n */\nfunction cliWorkflowCommand(id: string, fields: readonly TriggerPreviewFieldDef[]): string {\n if (fields.length === 0) return cliCommand(`w6w workflows run ${id}`, \"--wait\");\n const required = fields.filter((f) => f.required === true);\n const optional = fields.filter((f) => f.required !== true);\n const payload = Object.fromEntries(\n required.map((f) => [f.key as string, fieldPlaceholderValue(f.type, f.key as string)]),\n );\n let cmd = cliCommand(\n `w6w workflows run ${id}`,\n \"--wait\",\n `--input ${shellQuote(JSON.stringify(payload))}`,\n );\n for (const f of optional) {\n cmd += `\\n# optional: ${f.key} (${f.type ?? \"string\"})`;\n }\n return cmd;\n}\n\n/**\n * The lines every Node snippet opens with. `extra` names any additional symbol\n * the body uses — the import list has to be complete or the snippet does not\n * compile when pasted, which is the one thing a copyable example must not do.\n */\nfunction nodePreamble(...extra: string[]): string {\n const symbols = [\"W6WClient\", ...extra].join(\", \");\n return `import { ${symbols} } from \"@w6w/sdk\";\n\n// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.\nconst client = new W6WClient();`;\n}\n\n/**\n * The lines every Python snippet opens with. Mirrors `nodePreamble()`:\n * `extra` names any additional symbol the body uses (a discriminator\n * free-function), and the import list has to be complete or the snippet does\n * not run when pasted.\n */\nfunction pythonPreamble(...extra: string[]): string {\n const symbols = [\"Client\", ...extra].join(\", \");\n return `from w6w import ${symbols}\n\n# Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.\nclient = Client()`;\n}\n\n/**\n * The two header lines and the `-d` line every curl arm shares — the \"one\n * body builder, not three\" the three curl arms below are built on. `urlToken`\n * is the URL already rendered as a shell token: `\"$W6W_BASE_URL/…\"`\n * double-quoted so the env var expands (the function/workflow arms), or\n * `shellQuote`d (the endpoint arm, whose URL is a server-rendered literal\n * that may carry an operator-typed `'`). The auth header is DOUBLE-quoted so\n * `$W6W_TOKEN` expands on paste; `content-type` keeps single quotes (nothing\n * in it expands); `-d`'s JSON body is always `shellQuote`d — double-quoting\n * it would let the shell eat its own `\"` characters.\n */\nfunction curlBody(urlToken: string, data: unknown): string {\n return `curl -X POST ${urlToken} \\\\\n -H \"authorization: Bearer $W6W_TOKEN\" \\\\\n -H 'content-type: application/json' \\\\\n -d ${shellQuote(JSON.stringify(data))}`;\n}\n\n/**\n * A raw-HTTP call against a URL the SERVER rendered (the Endpoint arm).\n *\n * `url` is spliced in verbatim (through the same `shellQuote` every other shell\n * literal in this file uses) — this function has no notion of a host, a path, an\n * account or a key, and must never grow one: the whole point of the id/key\n * toggle is that both strings arrive fully formed from the server.\n * `payload` is the optional data payload to send with the request.\n */\nfunction curlCommand(url: string, payload?: Record<string, string>): string {\n return curlBody(shellQuote(url), payload ?? {});\n}\n\n/**\n * The name-addressed arm: `POST $W6W_BASE_URL/{group}/{name}/invoke`.\n *\n * `bodyKey` is a parameter because the wire is inconsistent where the SDK is\n * not — a Function takes `inputs`, an Endpoint takes `input`. The wrappers\n * spell both `payload`; raw HTTP cannot, so the caller passes the real one and\n * this helper never guesses.\n *\n * `name` is percent-encoded: it lands in a URL path, and a key that predates\n * the kebab-slug grammar may still contain something that needs escaping.\n */\nfunction curlInvokeCommand(\n group: \"functions\" | \"endpoints\",\n name: string,\n bodyKey: \"inputs\" | \"input\",\n payload: Record<string, string>,\n): string {\n const url = `\"$W6W_BASE_URL/${group}/${encodeURIComponent(name)}/invoke\"`;\n return curlBody(url, { [bodyKey]: payload });\n}\n\n/**\n * The Workflow arm: `POST /workflows/{id}/run?wait=true` — same route as the\n * node/cli/python lanes' `wait: true` / `--wait`. Mirrors `cliWorkflowCommand`\n * (D-3/D-4): required trigger fields are active JSON, optional ones are named\n * in a trailing `#` comment line each (JSON admits no comments), and a\n * trigger with no usable fields emits a bare `{}` body and no trailer.\n */\nfunction curlWorkflowCommand(id: string, fields: readonly TriggerPreviewFieldDef[]): string {\n const url = `\"$W6W_BASE_URL/workflows/${id}/run?wait=true\"`;\n if (fields.length === 0) return curlBody(url, {});\n const required = fields.filter((f) => f.required === true);\n const optional = fields.filter((f) => f.required !== true);\n const payload = Object.fromEntries(\n required.map((f) => [f.key as string, fieldPlaceholderValue(f.type, f.key as string)]),\n );\n let cmd = curlBody(url, { input: payload });\n for (const f of optional) {\n cmd += `\\n# optional: ${f.key} (${f.type ?? \"string\"})`;\n }\n return cmd;\n}\n\n/**\n * Build the Node + CLI snippet for one resource, or `null` when the contract\n * has no operation for it (today: a function or endpoint whose id carries no\n * runnable prefix).\n */\nexport function buildSnippet(\n resource: SnippetCallable,\n triggerFields?: readonly TriggerPreviewFieldDef[],\n): Snippet | null {\n switch (resource.kind) {\n case \"workflow\": {\n if (!isUrnAddressable(resource.id)) return null;\n const name = addressName(resource);\n const fields = usableTriggerFields(triggerFields);\n return {\n operation: \"workflows.run — POST /workflows/{idOrKey}/run\",\n node: `${nodePreamble()}\n\n// \\`wait: true\\` blocks until the run reaches a terminal state.\n// Omit it and you get \\`{ runId, status: \"queued\" }\\` back immediately.\nconst result = await client.workflows.run(${JSON.stringify(name)}, {\n wait: true,${nodeInputBlock(fields)}\n});\n\nconsole.log(result.status, result.runId);`,\n cli: cliWorkflowCommand(name, fields),\n python: `${pythonPreamble()}\n\n# \\`wait=True\\` blocks until the run reaches a terminal state.\n# Omit it and you get \\`WorkflowRunResult(status=\"queued\", ...)\\` back immediately.\nresult = ${pythonWorkflowCall(name, fields)}\n\nprint(result.status, result.runId)`,\n curl: curlWorkflowCommand(name, fields),\n };\n }\n\n case \"function\": {\n if (!isUrnAddressable(resource.id)) return null;\n const name = addressName(resource);\n // JSON carries no comments, so the CLI/curl lanes take the REQUIRED\n // inputs and name the optional ones underneath; Node and Python render\n // every input and comment the optional ones out in place.\n const payload = samplePayload(resource.inputs, true);\n const payloadJson = JSON.stringify(payload);\n const notes = optionalNotes(resource.inputs);\n const payloadBlock = payloadSource(resource.inputs, { indent: \" \", comment: \"//\" });\n const pythonPayload = payloadSource(resource.inputs, {\n indent: \"\",\n comment: \"#\",\n compact: true,\n });\n return {\n operation: \"functions.run — POST /functions/{idOrKey}/invoke\",\n node: `${nodePreamble()}\n\n// The name is the first argument, and it may be the Function's key or its\n// \\`fn_…\\` id — one slot takes either. Returns the OUTPUT directly: the kind is\n// settled by the method, so there is no envelope to narrow.\nconst output = await client.functions.run(${JSON.stringify(name)}, {\n payload: ${payloadBlock},\n});\n\nconsole.log(output);`,\n cli:\n cliCommand(`w6w functions run ${name}`, `--payload ${shellQuote(payloadJson)}`) + notes,\n python: `${pythonPreamble()}\n\n# The name is the first argument — the Function's key or its \\`fn_…\\` id.\noutput = client.functions.run(${JSON.stringify(name)}, payload=${pythonPayload})\n\nprint(output)`,\n curl: curlInvokeCommand(\"functions\", name, \"inputs\", payload) + notes,\n };\n }\n\n case \"endpoint\": {\n if (!isUrnAddressable(resource.id)) return null;\n // Which of the two server-rendered URLs the raw-HTTP arm shows. The\n // absence of a URL altogether means no `curl` snippet at all, rather than\n // a plausible-looking one built here.\n const httpUrl =\n resource.urlForm === \"key\" && resource.invokeUrlByKey\n ? resource.invokeUrlByKey\n : resource.invokeUrl;\n const name = addressName(resource);\n const payload = samplePayload(resource.inputs, true);\n const payloadJson = JSON.stringify(payload);\n const notes = optionalNotes(resource.inputs);\n const payloadBlock = payloadSource(resource.inputs, { indent: \" \", comment: \"//\" });\n const pythonPayload = payloadSource(resource.inputs, {\n indent: \"\",\n comment: \"#\",\n compact: true,\n });\n return {\n operation: \"endpoints.run — POST /endpoints/{idOrKey}/invoke\",\n node: `${nodePreamble()}\n\n// The name is the first argument — the Endpoint's key or its \\`ep_…\\` id. Unlike\n// \\`functions.run\\` this returns the ENVELOPE: an Endpoint dispatches to an app\n// action, a Function or a Workflow, and only \\`kind\\` says which answered.\nconst envelope = await client.endpoints.run(${JSON.stringify(name)}, {\n payload: ${payloadBlock},\n});\n\nconsole.log(envelope.kind, envelope);`,\n cli:\n cliCommand(`w6w endpoints run ${name}`, `--payload ${shellQuote(payloadJson)}`) + notes,\n python: `${pythonPreamble()}\n\n# The name is the first argument — the Endpoint's key or its \\`ep_…\\` id.\nenvelope = client.endpoints.run(${JSON.stringify(name)}, payload=${pythonPayload})\n\nprint(envelope[\"kind\"], envelope)`,\n ...(typeof httpUrl === \"string\" && httpUrl !== \"\"\n ? { curl: curlCommand(httpUrl, payload) + notes }\n : {}),\n };\n }\n\n case \"connection\": {\n if (!isUrnAddressable(resource.id)) return null;\n const payload = samplePayload(resource.params);\n return {\n operation: \"run — POST /run\",\n node: `${nodePreamble(\"isActionRun\")}\n\n// An app action runs through the CONNECTION that authenticates it, so the URN\n// is the connection id and \\`action\\` names the action on its app. This is the\n// one arm where \\`action\\` is required — a workflow, function or endpoint URN\n// has no action to name.\nconst envelope = await client.run({\n urn: ${JSON.stringify(resource.id)},\n action: ${JSON.stringify(resource.action)},\n payload: ${JSON.stringify(payload, null, 2).replaceAll(\"\\n\", \"\\n \")},\n});\n\nif (isActionRun(envelope)) console.log(envelope.value);`,\n cli: cliCommand(\n `w6w run ${resource.id}`,\n `--action ${resource.action}`,\n `--payload ${shellQuote(JSON.stringify(payload))}`,\n ),\n python: `${pythonPreamble(\"is_action_run\")}\n\n# An app action runs through the CONNECTION that authenticates it, so the URN\n# is the connection id and \\`action\\` names the action on its app. This is the\n# one arm where \\`action\\` is required — a workflow, function or endpoint URN\n# has no action to name.\nenvelope = client.run(\n ${JSON.stringify(resource.id)},\n action=${JSON.stringify(resource.action)},\n payload=${JSON.stringify(payload)},\n)\n\nif is_action_run(envelope):\n print(envelope[\"value\"])`,\n };\n }\n\n case \"var\":\n return {\n operation: \"vars.getByName — GET /vars/by-name/{name}\",\n node: `${nodePreamble()}\n\nconst variable = await client.vars.getByName(${JSON.stringify(resource.name)});\nconsole.log(variable.value);`,\n cli: `w6w vars get-by-name ${resource.name}`,\n python: `${pythonPreamble()}\n\nvariable = client.vars.get_by_name(${JSON.stringify(resource.name)})\nprint(variable.value)`,\n };\n\n case \"document\":\n return {\n operation: \"documents.getByKey — GET /documents/by-key/{key}\",\n node: `${nodePreamble()}\n\nconst doc = await client.documents.getByKey(${JSON.stringify(resource.key)});\nconsole.log(doc.content);`,\n cli: `w6w documents get-by-key ${shellQuote(resource.key)}`,\n python: `${pythonPreamble()}\n\ndoc = client.documents.get_by_key(${JSON.stringify(resource.key)})\nprint(doc.content)`,\n };\n }\n}\n\n/** Why no snippet exists, phrased for the reader rather than for a log. */\nexport function unavailableReason(resource: SnippetCallable): string {\n if (\n (resource.kind === \"function\" ||\n resource.kind === \"endpoint\" ||\n resource.kind === \"workflow\") &&\n !isUrnAddressable(resource.id)\n ) {\n return `This ${resource.kind}'s id (${resource.id}) has no \\`${\n resource.kind === \"workflow\" ? \"wf_\" : resource.kind === \"function\" ? \"fn_\" : \"ep_\"\n }\\` prefix, so it cannot be addressed by URN. The SDK and CLI reach ${resource.kind}s through \\`run\\`, which resolves a URN by that prefix — re-create it with a host-issued id to call it from code.`;\n }\n return \"The client libraries do not expose an operation for this yet.\";\n}\n","/**\n * Slug rules — the ONE place in `studio/src` that owns one.\n *\n * Two rules live here and they are deliberately NOT the same rule:\n *\n * · `slugify()` turns a human display name into a machine key. It is the\n * fallback the Endpoint and Function editors use when the operator leaves\n * `key` blank, and it is permissive on purpose: whatever it returns is a\n * legal resource key, digits-first and two characters included.\n * · `ACCOUNT_SLUG_RE` / `isValidAccountSlug()` decide whether a string is a\n * legal ACCOUNT slug — the account segment a key-form invoke URL is\n * addressed by. That rule is stricter: it must start with a letter and run to\n * at least three characters, so `2024-team` and `ab` are both perfectly good\n * keys and both invalid account slugs.\n *\n * The regex is exported rather than re-typed by each caller. A second copy is\n * exactly how a form comes to accept a value the server rejects, so the literal\n * appears in this file and nowhere else in `src/`.\n *\n * Why `src/lib` and why this module imports nothing: `src/lib/*.ts` is the only\n * place studio's `node --test` suite can reach. A rule living inside a `.tsx`\n * page cannot be unit-tested at all (Node's type-stripping does not parse JSX),\n * and a `src/lib` module that imports `@w6w/ui` throws\n * `ERR_UNKNOWN_FILE_EXTENSION` under the same runner because the barrel\n * re-exports `.tsx`. Same constraint documented at\n * `src/lib/workflow-validity.ts:11-20`.\n */\n\n/** Kebab-case a display name into a machine key (the fallback when key is blank). */\nexport function slugify(s: string): string {\n return s\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\n/**\n * A legal account slug: lowercase, opens with a LETTER, then two or more\n * letters/digits/hyphens — three characters minimum.\n *\n * Note this is NOT the server's `tenants.ts` `SLUG_RE`\n * (`/^[a-z0-9][a-z0-9_-]*$/`), which governs tenant ids and is a different,\n * more permissive rule. Do not merge the two.\n */\nexport const ACCOUNT_SLUG_RE = /^[a-z][a-z0-9-]{2,}$/;\n\n/** Does `s` satisfy {@link ACCOUNT_SLUG_RE}? */\nexport function isValidAccountSlug(s: string): boolean {\n return ACCOUNT_SLUG_RE.test(s);\n}\n\n/**\n * A legal Endpoint `key` — mirrors the server's rule VERBATIM, not\n * {@link ACCOUNT_SLUG_RE} above: that one is `{2,}` with no 39-character cap\n * and encodes neither the `--` rule nor the trailing-`-` rule, so a form that\n * validated a key with it would accept a value the server rejects.\n *\n * Source of truth: `packages/server/packages/bll/accounts.ts:72`\n * (`ACCOUNT_SLUG_RE = /^[a-z][a-z0-9-]{2,38}$/`) + `:216-218` (`isAccountSlug`),\n * reached from `packages/server/packages/api/invoke-address.ts:55-57`\n * (`isEndpointKey = isAccountSlug`). There is no reserved-word check on an\n * Endpoint key server-side — `isAccountSlug` only, never\n * `RESERVED_ACCOUNT_SLUGS` — so none is added here either.\n */\nexport function isEndpointKey(s: string): boolean {\n return /^[a-z][a-z0-9-]{2,38}$/.test(s) && !s.includes(\"--\") && !s.endsWith(\"-\");\n}\n\n/**\n * Filters a keystroke into a key input down to what {@link isEndpointKey}'s\n * grammar can ever accept: lowercase letters, digits, hyphens — nothing\n * else, capped at the grammar's own 39-character ceiling. A space or any\n * other disallowed character is dropped outright rather than folded into a\n * `-` ({@link slugify}'s job, for the one-time displayName-to-key fallback —\n * this is a LIVE filter on a field the operator is typing directly into, so\n * silently substituting a different character would be its own surprise).\n * Positional rules the grammar also enforces (must START with a letter, no\n * `--`, no trailing `-`) are left to {@link isEndpointKey} at Save time —\n * blocking those mid-keystroke would refuse a caller who is one keystroke\n * away from a valid value (e.g. typing `\"2\"` before backspacing to start\n * over).\n */\nexport function filterKeyInput(raw: string): string {\n return raw\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"\")\n .slice(0, 39);\n}\n"],"names":["RUNNABLE_PREFIXES","isUrnAddressable","id","p","addressName","resource","_a","key","shellQuote","value","CLI_WRAP_AT","cliCommand","head","flags","parts","oneLine","resolveInputs","inputs","i","samplePayload","requiredOnly","resolved","used","payloadSource","opts","required","member","optionalNotes","usableTriggerFields","fields","f","fieldPlaceholderValue","type","fieldSourceLiteral","python","nodeInputBlock","pythonWorkflowCall","idLiteral","lines","cliWorkflowCommand","optional","payload","cmd","nodePreamble","extra","pythonPreamble","curlBody","urlToken","data","curlCommand","url","curlInvokeCommand","group","name","bodyKey","curlWorkflowCommand","buildSnippet","triggerFields","payloadJson","notes","payloadBlock","pythonPayload","httpUrl","unavailableReason","slugify","s","ACCOUNT_SLUG_RE","isValidAccountSlug","isEndpointKey","filterKeyInput","raw"],"mappings":"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"}