@spencerboucher/switchyard 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -7
- package/dist/bridge/pi-model.js +44 -0
- package/dist/bridge/switchyard-bridge.js +24 -2
- package/dist/bridge/switchyard-terminal.js +146 -4
- package/dist/switchyard.mjs +1301 -700
- package/package.json +1 -1
- package/web-dist/assets/AutomationView-BIW_pO0M.js +2 -0
- package/web-dist/assets/AutomationView-BIW_pO0M.js.map +1 -0
- package/web-dist/assets/Badge-BiDp7NKI.js +2 -0
- package/web-dist/assets/Badge-BiDp7NKI.js.map +1 -0
- package/web-dist/assets/InteractionCard-CWxyDv81.js +6 -0
- package/web-dist/assets/InteractionCard-CWxyDv81.js.map +1 -0
- package/web-dist/assets/{Menu-C4GUY_ym.js → Menu-BDt1bxwz.js} +2 -2
- package/web-dist/assets/Menu-BDt1bxwz.js.map +1 -0
- package/web-dist/assets/{SegmentedControl-ChdVilXb.js → SegmentedControl-D-2BCZzd.js} +2 -2
- package/web-dist/assets/{SegmentedControl-ChdVilXb.js.map → SegmentedControl-D-2BCZzd.js.map} +1 -1
- package/web-dist/assets/Tabs-ByiPklAw.js +184 -0
- package/web-dist/assets/Tabs-ByiPklAw.js.map +1 -0
- package/web-dist/assets/TextArea-BYr88SnV.js +2 -0
- package/web-dist/assets/TextArea-BYr88SnV.js.map +1 -0
- package/web-dist/assets/attention-Bya8XHKI.js +2 -0
- package/web-dist/assets/attention-Bya8XHKI.js.map +1 -0
- package/web-dist/assets/automations-DiXKRcnE.js +2 -0
- package/web-dist/assets/automations-DiXKRcnE.js.map +1 -0
- package/web-dist/assets/board-BrLaJwLJ.js +10 -0
- package/web-dist/assets/board-BrLaJwLJ.js.map +1 -0
- package/web-dist/assets/c-Cz4nF6n_.js +1 -0
- package/web-dist/assets/c-SSSlmE39.js +2 -0
- package/web-dist/assets/c-SSSlmE39.js.map +1 -0
- package/web-dist/assets/code-DKLO8bzz.js +11 -0
- package/web-dist/assets/code-DKLO8bzz.js.map +1 -0
- package/web-dist/assets/cpp-Cts1PyIS.js +2 -0
- package/web-dist/assets/cpp-Cts1PyIS.js.map +1 -0
- package/web-dist/assets/cpp-DzjeI0uH.js +1 -0
- package/web-dist/assets/css-BGIxQoYs.js +2 -0
- package/web-dist/assets/css-BGIxQoYs.js.map +1 -0
- package/web-dist/assets/css-DgaLhXQH.js +1 -0
- package/web-dist/assets/describe-DnvH6_fl.js +5 -0
- package/web-dist/assets/describe-DnvH6_fl.js.map +1 -0
- package/web-dist/assets/diff-woXpYk--.js +2 -0
- package/web-dist/assets/diff-woXpYk--.js.map +1 -0
- package/web-dist/assets/dist-BE_V9dwJ.js +56 -0
- package/web-dist/assets/dist-BE_V9dwJ.js.map +1 -0
- package/web-dist/assets/dockerfile-IyjqRm3v.js +2 -0
- package/web-dist/assets/dockerfile-IyjqRm3v.js.map +1 -0
- package/web-dist/assets/enroll-DUDpbJoB.js +2 -0
- package/web-dist/assets/enroll-DUDpbJoB.js.map +1 -0
- package/web-dist/assets/github-dark-C-LZuMrd.js +2 -0
- package/web-dist/assets/github-dark-C-LZuMrd.js.map +1 -0
- package/web-dist/assets/github-light-EUqPIrTm.js +2 -0
- package/web-dist/assets/github-light-EUqPIrTm.js.map +1 -0
- package/web-dist/assets/go-rLFTqkRN.js +2 -0
- package/web-dist/assets/go-rLFTqkRN.js.map +1 -0
- package/web-dist/assets/html-BMn1ogTm.js +2 -0
- package/web-dist/assets/html-BMn1ogTm.js.map +1 -0
- package/web-dist/assets/html-BWDvXlHg.js +1 -0
- package/web-dist/assets/index-DvRcMGEe.css +2 -0
- package/web-dist/assets/index-vIzH1m8u.js +11 -0
- package/web-dist/assets/index-vIzH1m8u.js.map +1 -0
- package/web-dist/assets/java-BtIQNnN0.js +2 -0
- package/web-dist/assets/java-BtIQNnN0.js.map +1 -0
- package/web-dist/assets/java-_ATy9zCa.js +1 -0
- package/web-dist/assets/javascript-BzbQS41l.js +2 -0
- package/web-dist/assets/javascript-BzbQS41l.js.map +1 -0
- package/web-dist/assets/javascript-CpIGwZ_Y.js +1 -0
- package/web-dist/assets/json-qhed-kSA.js +2 -0
- package/web-dist/assets/json-qhed-kSA.js.map +1 -0
- package/web-dist/assets/jsonc-CYpm1nAK.js +2 -0
- package/web-dist/assets/jsonc-CYpm1nAK.js.map +1 -0
- package/web-dist/assets/jsx-C4yDKi0A.js +1 -0
- package/web-dist/assets/jsx-D3KKoC5L.js +2 -0
- package/web-dist/assets/jsx-D3KKoC5L.js.map +1 -0
- package/web-dist/assets/logic-xb-QF00E.js +2 -0
- package/web-dist/assets/logic-xb-QF00E.js.map +1 -0
- package/web-dist/assets/lua-DjuecEsk.js +2 -0
- package/web-dist/assets/lua-DjuecEsk.js.map +1 -0
- package/web-dist/assets/lua-fPRBWD-V.js +1 -0
- package/web-dist/assets/{more-syTnSpW3.js → more-BP5x45cs.js} +2 -2
- package/web-dist/assets/{more-syTnSpW3.js.map → more-BP5x45cs.js.map} +1 -1
- package/web-dist/assets/now--XjJC37b.js +2 -0
- package/web-dist/assets/now--XjJC37b.js.map +1 -0
- package/web-dist/assets/python-gzcpVVnB.js +2 -0
- package/web-dist/assets/python-gzcpVVnB.js.map +1 -0
- package/web-dist/assets/ruby-Bx-U2qjP.js +2 -0
- package/web-dist/assets/ruby-Bx-U2qjP.js.map +1 -0
- package/web-dist/assets/rust-DpiIf5JO.js +2 -0
- package/web-dist/assets/rust-DpiIf5JO.js.map +1 -0
- package/web-dist/assets/scss-8bKmll0B.js +2 -0
- package/web-dist/assets/scss-8bKmll0B.js.map +1 -0
- package/web-dist/assets/send-BKjswHxB.js +2 -0
- package/web-dist/assets/send-BKjswHxB.js.map +1 -0
- package/web-dist/assets/settings-D8T1esWq.js +7 -0
- package/web-dist/assets/settings-D8T1esWq.js.map +1 -0
- package/web-dist/assets/shared-CZ7fcu_B.js +3 -0
- package/web-dist/assets/shared-CZ7fcu_B.js.map +1 -0
- package/web-dist/assets/shellscript-CVTB3cr6.js +1 -0
- package/web-dist/assets/shellscript-CqHdAlCp.js +2 -0
- package/web-dist/assets/shellscript-CqHdAlCp.js.map +1 -0
- package/web-dist/assets/sliders-horizontal-DAoirila.js +2 -0
- package/web-dist/assets/sliders-horizontal-DAoirila.js.map +1 -0
- package/web-dist/assets/sql-CNu3Or2W.js +2 -0
- package/web-dist/assets/sql-CNu3Or2W.js.map +1 -0
- package/web-dist/assets/sql-CfM2IJm3.js +1 -0
- package/web-dist/assets/states--geW2Ntl.js +2 -0
- package/web-dist/assets/states--geW2Ntl.js.map +1 -0
- package/web-dist/assets/swift-CyEgAFGc.js +2 -0
- package/web-dist/assets/swift-CyEgAFGc.js.map +1 -0
- package/web-dist/assets/terminal-login-BJxV78au.js +2 -0
- package/web-dist/assets/terminal-login-BJxV78au.js.map +1 -0
- package/web-dist/assets/toml-CcmNWLt0.js +2 -0
- package/web-dist/assets/toml-CcmNWLt0.js.map +1 -0
- package/web-dist/assets/tsx-BOvsFOI6.js +2 -0
- package/web-dist/assets/tsx-BOvsFOI6.js.map +1 -0
- package/web-dist/assets/tsx-CGosfAUg.js +1 -0
- package/web-dist/assets/typescript-Bb1J8qyy.js +1 -0
- package/web-dist/assets/typescript-j_1H8WHN.js +2 -0
- package/web-dist/assets/typescript-j_1H8WHN.js.map +1 -0
- package/web-dist/assets/useNow-jxdoOC_1.js +2 -0
- package/web-dist/assets/{useNow-BQpDYijR.js.map → useNow-jxdoOC_1.js.map} +1 -1
- package/web-dist/assets/xml-DuKfbPI6.js +1 -0
- package/web-dist/assets/xml-WY0zc4PG.js +2 -0
- package/web-dist/assets/xml-WY0zc4PG.js.map +1 -0
- package/web-dist/assets/yaml-DDA_XMNu.js +1 -0
- package/web-dist/assets/yaml-DijMHRDA.js +2 -0
- package/web-dist/assets/yaml-DijMHRDA.js.map +1 -0
- package/web-dist/index.html +4 -3
- package/web-dist/sw.js +1 -1
- package/web-dist/sw.js.map +1 -1
- package/web-dist/assets/AutomationView-CFohp0SQ.js +0 -2
- package/web-dist/assets/AutomationView-CFohp0SQ.js.map +0 -1
- package/web-dist/assets/InteractionCard-B-xmpTNG.js +0 -4
- package/web-dist/assets/InteractionCard-B-xmpTNG.js.map +0 -1
- package/web-dist/assets/Markdown-jXkvZeRp.js +0 -31
- package/web-dist/assets/Markdown-jXkvZeRp.js.map +0 -1
- package/web-dist/assets/Menu-C4GUY_ym.js.map +0 -1
- package/web-dist/assets/Overlay--v0ur2lj.js +0 -2
- package/web-dist/assets/Overlay--v0ur2lj.js.map +0 -1
- package/web-dist/assets/TextArea-BsQHOQMe.js +0 -2
- package/web-dist/assets/TextArea-BsQHOQMe.js.map +0 -1
- package/web-dist/assets/attention-q6_xlnT4.js +0 -2
- package/web-dist/assets/attention-q6_xlnT4.js.map +0 -1
- package/web-dist/assets/automations-CyA83OAD.js +0 -2
- package/web-dist/assets/automations-CyA83OAD.js.map +0 -1
- package/web-dist/assets/board-BFvNcFhk.js +0 -10
- package/web-dist/assets/board-BFvNcFhk.js.map +0 -1
- package/web-dist/assets/code-DavnmlQN.js +0 -8
- package/web-dist/assets/code-DavnmlQN.js.map +0 -1
- package/web-dist/assets/describe-BirsjlUl.js +0 -5
- package/web-dist/assets/describe-BirsjlUl.js.map +0 -1
- package/web-dist/assets/dist-C-h8FC-n.js +0 -56
- package/web-dist/assets/dist-C-h8FC-n.js.map +0 -1
- package/web-dist/assets/enroll-C7UBC20s.js +0 -2
- package/web-dist/assets/enroll-C7UBC20s.js.map +0 -1
- package/web-dist/assets/index-ByiuDoG0.css +0 -2
- package/web-dist/assets/index-IdzOP9GE.js +0 -11
- package/web-dist/assets/index-IdzOP9GE.js.map +0 -1
- package/web-dist/assets/logic-D_Eq9DMW.js +0 -2
- package/web-dist/assets/logic-D_Eq9DMW.js.map +0 -1
- package/web-dist/assets/now-BqsLS-tK.js +0 -2
- package/web-dist/assets/now-BqsLS-tK.js.map +0 -1
- package/web-dist/assets/settings-DRj7UPtP.js +0 -8
- package/web-dist/assets/settings-DRj7UPtP.js.map +0 -1
- package/web-dist/assets/sliders-horizontal-S3tmwxsP.js +0 -2
- package/web-dist/assets/sliders-horizontal-S3tmwxsP.js.map +0 -1
- package/web-dist/assets/states-DrTQuYXw.js +0 -2
- package/web-dist/assets/states-DrTQuYXw.js.map +0 -1
- package/web-dist/assets/useNow-BQpDYijR.js +0 -2
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionCard-B-xmpTNG.js","names":["createContext","useContext","useMemo","useState","useMemo","useId","_Fragment","useId","useState","useState","_Fragment","__toESM","Link","require_react","createLucideIcon","require_jsx_runtime","isApiError","useSyncStore","apiPost","errorMessage","cn","Button","ErrorState","formatRelative","Check","ChevronRight","CircleX","LoaderCircle","CircleCheck","StatusChip","TextInput","TextArea","Tabs","CodeBlock","TabPanel","Markdown","isFieldVisible","__iconData","FileCode","import_react","IntentContext","useIntent","import_jsx_runtime","ConfirmRenderer","node","disabled","onRespond","busy","stripPrefix","p","HUNK","parseUnifiedDiff","files","file","oldNo","newNo","oldLeft","newLeft","inHunk","consumed","start","f","lines","patch","line","m","l","h","MARKER","GUTTER_BG","DiffView","given","className","showFileHeaders","ref","selectable","onLineClick","marked","isLineMarked","li","fi","initialFormState","out","fields","fieldValue","st","field","vals","visibleFields","values","state","buildValues","v","validateForm","errors","n","chooseSelect","value","chooseSelectOther","toggleMulti","count","max","FormRenderer","setState","attempted","setAttempted","visible","locked","setField","s","name","fs","e","FieldView","id","errId","common","error","onChange","multi","selectedPreview","o","hint","OptionCard","checked","option","onToggle","UINodeRenderer","handlers","parent","hasOwn","content","NodeView","stripUndefined","TONE_TEXT","ListView","c","i","r","cell","ci","ri","SectionView","TabsView","ProgressView","RefView","ActionsView","Children","nodes","Tag","item","prefix","active","setActive","current","t","status","Icon","statusText","pct","refHref","href","refValue","label","onOpenFile","a","onAction","UNSUPPORTED_COPY","DEFAULT_ACTIONS","findActions","found","isUnsupported","unsupportedView","offered","messageMode","runtime","hasInteractive","byLabel","by","InteractionCard","fromProps","upsert","setBusy","setError","alreadyAnswered","setAlreadyAnswered","lastResponse","setLastResponse","acked","setAcked","interaction","pending","unsupported","sessionRuntime","composing","setComposing","message","setMessage","respond","response","res","onAnswered","other","sendMessage","text","UnsupportedBody","readOnlyReason","actionId","view","answered","onSend","onCancelMessage"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/file-code.mjs","../../src/components/intent/context.ts","../../src/components/intent/ConfirmRenderer.tsx","../../src/components/intent/diff.ts","../../src/components/intent/DiffView.tsx","../../src/components/intent/formLogic.ts","../../src/components/intent/FormRenderer.tsx","../../src/components/intent/UINodeRenderer.tsx","../../src/components/intent/unsupported.ts","../../src/components/intent/InteractionCard.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"file-code\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M10 12.5 8 15l2 2.5\", key: \"1tg20x\" }],\n [\"path\", { d: \"m14 12.5 2 2.5-2 2.5\", key: \"yinavb\" }]\n ]\n};\n__iconData.node;\nconst FileCode = createLucideIcon(__iconData);\n\nexport { __iconData, FileCode as default };\n//# sourceMappingURL=file-code.mjs.map\n","import type { InteractionResponse } from \"@switchyard/protocol\";\nimport { createContext, useContext } from \"react\";\n\n/** Handlers available to a rendered UINode tree. */\nexport interface IntentHandlers {\n /** Interaction context: form submit, confirm, cancel and action buttons respond here. */\n onRespond?: (response: InteractionResponse) => void;\n /** Panel/tool-card context: `actions` buttons call this when there is no `onRespond`. */\n onAction?: (actionId: string) => void;\n /** File refs call this when provided (e.g. open in the inspector); otherwise render as text. */\n onOpenFile?: (path: string) => void;\n /** A response is in flight: inputs stay visible, buttons show busy. */\n busy?: boolean;\n /** Read-only (already answered, expired, read-only session). */\n disabled?: boolean;\n}\n\nexport const IntentContext = createContext<IntentHandlers>({});\nexport const useIntent = () => useContext(IntentContext);\n","import type { UINode } from \"@switchyard/protocol\";\nimport { Button } from \"../ui/Button\";\nimport { useIntent } from \"./context\";\nimport { Markdown } from \"./Markdown\";\n\ntype ConfirmNode = Extract<UINode, { t: \"confirm\" }>;\n\n/** Yes/no question; responds `{kind: \"confirm\", confirmed}`. */\nexport function ConfirmRenderer({ node }: { node: ConfirmNode }) {\n const { onRespond, busy, disabled } = useIntent();\n return (\n <div className=\"flex flex-col gap-3\">\n <Markdown text={node.message} />\n {!disabled && (\n <div className=\"flex flex-wrap gap-2\">\n <Button\n variant={node.destructive ? \"danger\" : \"primary\"}\n busy={busy}\n onClick={() => onRespond?.({ kind: \"confirm\", confirmed: true })}\n >\n {node.confirmLabel || \"Confirm\"}\n </Button>\n <Button\n disabled={busy}\n onClick={() => onRespond?.({ kind: \"confirm\", confirmed: false })}\n >\n {node.cancelLabel || \"Cancel\"}\n </Button>\n </div>\n )}\n </div>\n );\n}\n","/** Unified diff parsing for DiffView (pure; tested without a DOM). */\n\nexport type DiffLineKind = \"add\" | \"del\" | \"context\" | \"hunk\" | \"meta\";\n\nexport interface DiffLine {\n kind: DiffLineKind;\n text: string;\n oldLine: number | null;\n newLine: number | null;\n}\n\nexport interface DiffFile {\n /** Display path (new path, or old path for deletions). */\n path: string;\n oldPath: string | null;\n newPath: string | null;\n status: \"modified\" | \"added\" | \"deleted\" | \"renamed\" | \"binary\";\n additions: number;\n deletions: number;\n lines: DiffLine[];\n}\n\nfunction stripPrefix(p: string): string | null {\n const t = p.trim().split(\"\\t\")[0]!;\n if (t === \"/dev/null\") return null;\n return t.replace(/^[ab]\\//, \"\");\n}\n\nconst HUNK = /^@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/;\n\nexport function parseUnifiedDiff(patch: string): DiffFile[] {\n const files: DiffFile[] = [];\n let file: DiffFile | null = null;\n let oldNo = 0;\n let newNo = 0;\n let oldLeft = 0;\n let newLeft = 0;\n let inHunk = false;\n const consumed = () => {\n if (oldLeft <= 0 && newLeft <= 0) inHunk = false;\n };\n const start = (path = \"\"): DiffFile => {\n const f: DiffFile = {\n path,\n oldPath: null,\n newPath: null,\n status: \"modified\",\n additions: 0,\n deletions: 0,\n lines: [],\n };\n files.push(f);\n inHunk = false;\n return f;\n };\n const lines = patch.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n if (lines[lines.length - 1] === \"\") lines.pop();\n for (const line of lines) {\n if (line.startsWith(\"diff --git \")) {\n const m = /^diff --git a\\/(.+?) b\\/(.+)$/.exec(line);\n file = start(m?.[2] ?? \"\");\n if (m) {\n file.oldPath = m[1]!;\n file.newPath = m[2]!;\n }\n continue;\n }\n if (!inHunk && line.startsWith(\"--- \")) {\n if (!file || file.lines.some((l) => l.kind !== \"meta\")) file = start();\n file.oldPath = stripPrefix(line.slice(4));\n if (file.oldPath === null) file.status = \"added\";\n continue;\n }\n if (!inHunk && line.startsWith(\"+++ \") && file) {\n file.newPath = stripPrefix(line.slice(4));\n if (file.newPath === null) file.status = \"deleted\";\n file.path = file.newPath ?? file.oldPath ?? file.path;\n continue;\n }\n const h = HUNK.exec(line);\n if (h) {\n if (!file) file = start();\n oldNo = Number(h[1]);\n newNo = Number(h[3]);\n oldLeft = h[2] === undefined ? 1 : Number(h[2]);\n newLeft = h[4] === undefined ? 1 : Number(h[4]);\n inHunk = oldLeft > 0 || newLeft > 0;\n file.lines.push({ kind: \"hunk\", text: line, oldLine: null, newLine: null });\n continue;\n }\n if (!file) file = start();\n if (inHunk && line.startsWith(\"+\")) {\n file.lines.push({ kind: \"add\", text: line.slice(1), oldLine: null, newLine: newNo++ });\n file.additions++;\n newLeft--;\n consumed();\n } else if (inHunk && line.startsWith(\"-\")) {\n file.lines.push({ kind: \"del\", text: line.slice(1), oldLine: oldNo++, newLine: null });\n file.deletions++;\n oldLeft--;\n consumed();\n } else if (inHunk && (line.startsWith(\" \") || line === \"\")) {\n file.lines.push({\n kind: \"context\",\n text: line.slice(1),\n oldLine: oldNo++,\n newLine: newNo++,\n });\n oldLeft--;\n newLeft--;\n consumed();\n } else if (line.startsWith(\"\\\\\")) {\n file.lines.push({ kind: \"meta\", text: line, oldLine: null, newLine: null });\n } else {\n // Header lines (index, mode, rename, Binary files ...).\n inHunk = false;\n if (line.startsWith(\"new file mode\")) file.status = \"added\";\n else if (line.startsWith(\"deleted file mode\")) file.status = \"deleted\";\n else if (line.startsWith(\"rename from \")) {\n file.status = \"renamed\";\n file.oldPath = line.slice(12);\n } else if (line.startsWith(\"rename to \")) {\n file.status = \"renamed\";\n file.newPath = line.slice(10);\n file.path = file.newPath;\n } else if (line.startsWith(\"Binary files\")) file.status = \"binary\";\n file.lines.push({ kind: \"meta\", text: line, oldLine: null, newLine: null });\n }\n }\n return files;\n}\n","import { useMemo } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { type DiffFile, type DiffLine, parseUnifiedDiff } from \"./diff\";\n\nexport interface DiffLineRef {\n file: string;\n line: DiffLine;\n}\n\nexport interface DiffViewProps {\n /** Unified diff text (one or more files). */\n patch?: string;\n /** Pre-parsed files (alternative to `patch`). */\n files?: DiffFile[];\n /** Show a header per file (default true). */\n showFileHeaders?: boolean;\n /** Enables line selection (e.g. review comments). Called for add/context/del lines. */\n onLineClick?: (ref: DiffLineRef) => void;\n /** Highlight lines (e.g. lines with comments). */\n isLineMarked?: (ref: DiffLineRef) => boolean;\n className?: string;\n}\n\nconst MARKER: Record<DiffLine[\"kind\"], string> = {\n add: \"+\",\n del: \"-\",\n context: \" \",\n hunk: \"\",\n meta: \"\",\n};\n\n/** Opaque gutter backgrounds (the gutter is sticky, so it must cover scrolled text). */\nconst GUTTER_BG: Record<DiffLine[\"kind\"], string> = {\n add: \"bg-diff-add\",\n del: \"bg-diff-del\",\n hunk: \"bg-diff-hunk\",\n context: \"bg-surface\",\n meta: \"bg-surface\",\n};\n\n/**\n * Unified diff with old/new line numbers, +/- text markers (not color alone)\n * and tinted rows. Horizontal scrolling is confined to the diff block, and the line-number\n * gutter is sticky so it stays visible while a long line is scrolled.\n */\nexport function DiffView({\n patch,\n files: given,\n showFileHeaders = true,\n onLineClick,\n isLineMarked,\n className,\n}: DiffViewProps) {\n const files = useMemo(() => given ?? parseUnifiedDiff(patch ?? \"\"), [given, patch]);\n if (files.length === 0) {\n return <p className=\"text-sm text-muted\">No changes.</p>;\n }\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-3\", className)}>\n {files.map((f, fi) => (\n <section\n // biome-ignore lint/suspicious/noArrayIndexKey: files can repeat paths in odd patches\n key={`${f.path}-${fi}`}\n className=\"min-w-0 overflow-hidden rounded-md border border-border\"\n aria-label={`Diff of ${f.path || \"file\"}`}\n >\n {showFileHeaders && (\n <header className=\"flex min-w-0 items-center gap-2 border-b border-border bg-surface-2 px-3 py-1.5 text-sm\">\n <span className=\"min-w-0 flex-1 truncate font-mono\" title={f.path}>\n {f.status === \"renamed\" && f.oldPath ? `${f.oldPath} → ${f.path}` : f.path}\n </span>\n <span className=\"shrink-0 font-mono text-xs\">\n <span className=\"text-success\">\n +{f.additions}\n <span className=\"sr-only\"> added</span>\n </span>{\" \"}\n <span className=\"text-danger\">\n -{f.deletions}\n <span className=\"sr-only\"> deleted</span>\n </span>\n </span>\n </header>\n )}\n {f.status === \"binary\" ? (\n <p className=\"px-3 py-2 text-sm text-muted\">Binary file not shown.</p>\n ) : (\n <div className=\"max-w-full overflow-x-auto overscroll-x-contain\">\n <table className=\"w-full border-collapse font-mono text-xs leading-5\">\n <tbody>\n {f.lines.map((l, li) => {\n const ref = { file: f.path, line: l };\n const selectable =\n !!onLineClick &&\n (l.kind === \"add\" || l.kind === \"del\" || l.kind === \"context\");\n const marked = isLineMarked?.(ref) ?? false;\n return (\n <tr\n // biome-ignore lint/suspicious/noArrayIndexKey: diff lines are positional\n key={li}\n className={cn(\n l.kind === \"add\" && \"bg-diff-add\",\n l.kind === \"del\" && \"bg-diff-del\",\n l.kind === \"hunk\" && \"bg-diff-hunk text-muted\",\n l.kind === \"meta\" && \"text-muted\",\n marked && \"outline outline-1 -outline-offset-1 outline-warning\",\n )}\n >\n <td\n className={cn(\n \"sticky left-0 z-[1] w-[6.25rem] min-w-[6.25rem] select-none whitespace-nowrap p-0\",\n GUTTER_BG[l.kind],\n )}\n >\n <span className=\"flex\">\n <span className=\"w-10 shrink-0 border-r border-border px-1.5 text-right text-subtle tabular-nums\">\n {l.oldLine ?? \"\"}\n </span>\n <span className=\"w-10 shrink-0 border-r border-border px-1.5 text-right text-subtle tabular-nums\">\n {l.newLine ?? \"\"}\n </span>\n <span\n aria-hidden\n className={cn(\n \"w-5 shrink-0 text-center\",\n l.kind === \"add\" && \"text-success\",\n l.kind === \"del\" && \"text-danger\",\n )}\n >\n {MARKER[l.kind]}\n </span>\n {(l.kind === \"add\" || l.kind === \"del\") && (\n <span className=\"sr-only\">\n {l.kind === \"add\" ? \"added\" : \"deleted\"}\n </span>\n )}\n </span>\n </td>\n <td className=\"whitespace-pre pr-3\">\n {selectable ? (\n <button\n type=\"button\"\n data-diff-line={l.newLine ?? l.oldLine ?? undefined}\n // Keyboard focus scrolls the line into view clear of the sticky gutter.\n className=\"block w-full scroll-ml-[6.25rem] cursor-pointer text-left whitespace-pre hover:underline focus-visible:underline\"\n // A pointer click must not scroll the diff sideways (the button spans\n // the whole long line): skip the focus scroll, then focus in place.\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.currentTarget.focus({ preventScroll: true });\n onLineClick?.(ref);\n }}\n aria-label={`Comment on line ${l.newLine ?? l.oldLine}`}\n >\n {l.text || \" \"}\n </button>\n ) : (\n l.text\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </section>\n ))}\n </div>\n );\n}\n","import { type Field, type FormValue, isFieldVisible } from \"@switchyard/protocol\";\n\n/**\n * Pure form state logic for FormRenderer (tested without a DOM).\n *\n * Each field keeps its raw UI state; `buildValues` turns it into the\n * submitted `InteractionResponse` values, omitting hidden fields.\n */\n\nexport interface FieldState {\n /** Selected option values (select: at most one). */\n selected: string[];\n /** \"Other\" chosen (select/multiselect with allowOther). */\n otherChosen: boolean;\n otherText: string;\n /** Text field value. */\n text: string;\n}\n\nexport type FormState = Record<string, FieldState>;\n\nexport function initialFormState(fields: Field[]): FormState {\n const out: FormState = {};\n for (const f of fields) {\n out[f.name] = {\n selected: [],\n otherChosen: false,\n otherText: \"\",\n text: f.kind === \"text\" ? (f.prefill ?? \"\") : \"\",\n };\n }\n return out;\n}\n\n/** The value a field contributes, or undefined when nothing is chosen. */\nexport function fieldValue(field: Field, st: FieldState | undefined): FormValue | undefined {\n if (!st) return undefined;\n switch (field.kind) {\n case \"text\":\n return st.text;\n case \"select\":\n if (st.otherChosen) return { other: st.otherText };\n return st.selected[0];\n case \"multiselect\": {\n const vals = [...st.selected];\n // Multiselect \"other\" text is submitted as an extra entry.\n if (st.otherChosen && st.otherText.trim()) vals.push(st.otherText.trim());\n return vals;\n }\n }\n}\n\n/**\n * Visible fields in order. `showIf` refers to an earlier field, so visibility\n * is evaluated against the values of fields that are themselves visible.\n */\nexport function visibleFields(fields: Field[], state: FormState): Field[] {\n const values: Record<string, FormValue | undefined> = {};\n const out: Field[] = [];\n for (const f of fields) {\n if (!isFieldVisible(f, values)) continue;\n out.push(f);\n values[f.name] = fieldValue(f, state[f.name]);\n }\n return out;\n}\n\n/** Submitted values: visible fields only. */\nexport function buildValues(fields: Field[], state: FormState): Record<string, FormValue> {\n const out: Record<string, FormValue> = {};\n for (const f of visibleFields(fields, state)) {\n const v = fieldValue(f, state[f.name]);\n if (v !== undefined) out[f.name] = v;\n }\n return out;\n}\n\n/** Validation errors keyed by field name (visible fields only). Empty when valid. */\nexport function validateForm(fields: Field[], state: FormState): Record<string, string> {\n const errors: Record<string, string> = {};\n for (const f of visibleFields(fields, state)) {\n const st = state[f.name];\n if (!st) continue;\n if (f.kind === \"select\") {\n if (st.otherChosen) {\n if (!st.otherText.trim()) errors[f.name] = \"Enter a value or choose an option\";\n } else if (st.selected.length === 0) errors[f.name] = \"Choose an option\";\n } else if (f.kind === \"multiselect\") {\n const n = st.selected.length + (st.otherChosen && st.otherText.trim() ? 1 : 0);\n if (st.otherChosen && !st.otherText.trim()) errors[f.name] = \"Enter a value for Other\";\n else if (f.min !== undefined && n < f.min) errors[f.name] = `Choose at least ${f.min}`;\n else if (f.max !== undefined && n > f.max) errors[f.name] = `Choose at most ${f.max}`;\n }\n }\n return errors;\n}\n\n/** Choose an option of a select (clears \"other\"). */\nexport function chooseSelect(st: FieldState, value: string): FieldState {\n return { ...st, selected: [value], otherChosen: false };\n}\n\n/** Choose \"other\" on a select. */\nexport function chooseSelectOther(st: FieldState): FieldState {\n return { ...st, selected: [], otherChosen: true };\n}\n\n/** Toggle a multiselect option, respecting `max` (a toggle past max is ignored). */\nexport function toggleMulti(st: FieldState, value: string, max?: number): FieldState {\n if (st.selected.includes(value)) {\n return { ...st, selected: st.selected.filter((v) => v !== value) };\n }\n const count = st.selected.length + (st.otherChosen ? 1 : 0);\n if (max !== undefined && count >= max) return st;\n return { ...st, selected: [...st.selected, value] };\n}\n","import type { Field, FieldOption, UINode } from \"@switchyard/protocol\";\nimport { Check } from \"lucide-react\";\nimport { useId, useMemo, useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { Button } from \"../ui/Button\";\nimport { TextArea, TextInput } from \"../ui/TextArea\";\nimport { useIntent } from \"./context\";\nimport {\n buildValues,\n chooseSelect,\n chooseSelectOther,\n type FieldState,\n type FormState,\n initialFormState,\n toggleMulti,\n validateForm,\n visibleFields,\n} from \"./formLogic\";\n\ntype FormNode = Extract<UINode, { t: \"form\" }>;\n\nexport interface FormRendererProps {\n node: FormNode;\n className?: string;\n}\n\n/**\n * Structured question form. Selects render as radio cards, multiselects as\n * toggle cards (never comma-separated entry), `allowOther` adds a free-text\n * option, `showIf` hides dependent fields (omitted from the values).\n * Submits `{kind: \"form\", values}` through the IntentContext.\n */\nexport function FormRenderer({ node, className }: FormRendererProps) {\n const { onRespond, busy, disabled } = useIntent();\n const [state, setState] = useState<FormState>(() => initialFormState(node.fields));\n const [attempted, setAttempted] = useState(false);\n const visible = useMemo(() => visibleFields(node.fields, state), [node.fields, state]);\n const errors = useMemo(() => validateForm(node.fields, state), [node.fields, state]);\n const locked = disabled || busy;\n const setField = (name: string, fs: FieldState) => setState((s) => ({ ...s, [name]: fs }));\n\n return (\n <form\n className={cn(\"flex flex-col gap-4\", className)}\n noValidate\n onSubmit={(e) => {\n e.preventDefault();\n setAttempted(true);\n if (Object.keys(errors).length > 0 || locked) return;\n onRespond?.({ kind: \"form\", values: buildValues(node.fields, state) });\n }}\n >\n {visible.map((f) => (\n <FieldView\n key={f.name}\n field={f}\n state={state[f.name]!}\n onChange={(fs) => setField(f.name, fs)}\n error={attempted ? errors[f.name] : undefined}\n disabled={locked}\n />\n ))}\n {!disabled && (\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button type=\"submit\" variant=\"primary\" busy={busy}>\n {node.submitLabel || \"Submit\"}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={busy}\n onClick={() => onRespond?.({ kind: \"cancel\" })}\n >\n {node.cancelLabel || \"Cancel\"}\n </Button>\n {attempted && Object.keys(errors).length > 0 && (\n <span role=\"alert\" className=\"text-sm text-danger\">\n Complete the highlighted fields.\n </span>\n )}\n </div>\n )}\n </form>\n );\n}\n\nfunction FieldView({\n field,\n state,\n onChange,\n error,\n disabled,\n}: {\n field: Field;\n state: FieldState;\n onChange: (s: FieldState) => void;\n error?: string;\n disabled?: boolean;\n}) {\n const id = useId();\n const errId = `${id}-err`;\n if (field.kind === \"text\") {\n const common = {\n id,\n value: state.text,\n placeholder: field.placeholder,\n disabled,\n \"aria-invalid\": !!error || undefined,\n \"aria-describedby\": error ? errId : undefined,\n };\n return (\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor={id} className=\"text-sm font-medium\">\n {field.label}\n </label>\n {field.multiline ? (\n <TextArea\n {...common}\n minRows={3}\n onChange={(e) => onChange({ ...state, text: e.target.value })}\n />\n ) : (\n <TextInput {...common} onChange={(e) => onChange({ ...state, text: e.target.value })} />\n )}\n {error && (\n <p id={errId} className=\"text-sm text-danger\">\n {error}\n </p>\n )}\n </div>\n );\n }\n\n const multi = field.kind === \"multiselect\";\n const selectedPreview =\n !multi && state.selected[0]\n ? field.options.find((o) => o.value === state.selected[0])?.preview\n : undefined;\n const hint =\n multi && (field.min !== undefined || field.max !== undefined)\n ? field.min !== undefined && field.max !== undefined\n ? `Choose ${field.min}–${field.max}`\n : field.min !== undefined\n ? `Choose at least ${field.min}`\n : `Choose up to ${field.max}`\n : multi\n ? \"Choose any\"\n : undefined;\n\n return (\n <fieldset\n className=\"flex min-w-0 flex-col gap-2\"\n aria-describedby={error ? errId : undefined}\n aria-invalid={!!error || undefined}\n >\n <legend className=\"mb-2 text-sm font-medium\">\n {field.label}\n {hint && <span className=\"ml-2 font-normal text-muted\">{hint}</span>}\n </legend>\n <div className=\"grid gap-2\">\n {field.options.map((o) => (\n <OptionCard\n key={o.value}\n name={id}\n option={o}\n multi={multi}\n checked={state.selected.includes(o.value)}\n disabled={disabled}\n onToggle={() =>\n onChange(\n multi\n ? toggleMulti(\n state,\n o.value,\n field.kind === \"multiselect\" ? field.max : undefined,\n )\n : chooseSelect(state, o.value),\n )\n }\n />\n ))}\n {field.allowOther && (\n <OptionCard\n name={id}\n option={{ value: \"__other__\", label: field.allowOther.label || \"Other\" }}\n multi={multi}\n checked={state.otherChosen}\n disabled={disabled}\n onToggle={() =>\n onChange(\n multi ? { ...state, otherChosen: !state.otherChosen } : chooseSelectOther(state),\n )\n }\n />\n )}\n </div>\n {field.allowOther && state.otherChosen && (\n <TextInput\n aria-label={field.allowOther.label || \"Other\"}\n placeholder={field.allowOther.placeholder ?? \"Type your answer\"}\n value={state.otherText}\n disabled={disabled}\n autoFocus\n onChange={(e) => onChange({ ...state, otherText: e.target.value })}\n />\n )}\n {selectedPreview && (\n <pre className=\"max-h-64 max-w-full overflow-auto rounded-md border border-border bg-surface-2 px-3 py-2 text-xs leading-5\">\n {selectedPreview}\n </pre>\n )}\n {error && (\n <p id={errId} className=\"text-sm text-danger\">\n {error}\n </p>\n )}\n </fieldset>\n );\n}\n\nfunction OptionCard({\n name,\n option,\n multi,\n checked,\n disabled,\n onToggle,\n}: {\n name: string;\n option: FieldOption;\n multi: boolean;\n checked: boolean;\n disabled?: boolean;\n onToggle: () => void;\n}) {\n return (\n <label\n className={cn(\n \"tap flex min-w-0 cursor-pointer items-start gap-3 rounded-lg border px-3 py-2.5 text-sm\",\n \"has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-accent\",\n checked ? \"border-accent bg-accent-soft\" : \"border-border bg-surface hover:bg-surface-2\",\n disabled && \"cursor-not-allowed opacity-70\",\n )}\n >\n <input\n type={multi ? \"checkbox\" : \"radio\"}\n name={name}\n value={option.value}\n checked={checked}\n disabled={disabled}\n onChange={onToggle}\n className=\"sr-only\"\n />\n <span\n aria-hidden\n className={cn(\n \"mt-0.5 inline-flex size-4 shrink-0 items-center justify-center border\",\n multi ? \"rounded\" : \"rounded-full\",\n checked ? \"border-accent bg-accent text-accent-fg\" : \"border-border-strong bg-surface\",\n )}\n >\n {checked &&\n (multi ? (\n <Check className=\"size-3\" />\n ) : (\n <span className=\"size-1.5 rounded-full bg-accent-fg\" />\n ))}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block font-medium break-words\">{option.label}</span>\n {option.description && (\n <span className=\"block text-muted break-words\">{option.description}</span>\n )}\n </span>\n </label>\n );\n}\n","import type { UINode, UIRef } from \"@switchyard/protocol\";\nimport { ChevronRight, CircleCheck, CircleX, FileCode, LoaderCircle } from \"lucide-react\";\nimport { useId, useState } from \"react\";\nimport { Link } from \"react-router\";\nimport { cn } from \"../../lib/cn\";\nimport { Button } from \"../ui/Button\";\nimport { TabPanel, Tabs } from \"../ui/Tabs\";\nimport { CodeBlock } from \"./CodeBlock\";\nimport { ConfirmRenderer } from \"./ConfirmRenderer\";\nimport { IntentContext, type IntentHandlers, useIntent } from \"./context\";\nimport { DiffView } from \"./DiffView\";\nimport { FormRenderer } from \"./FormRenderer\";\nimport { Markdown } from \"./Markdown\";\n\nexport interface UINodeRendererProps extends IntentHandlers {\n node: UINode;\n className?: string;\n}\n\n/**\n * Renders a portable UINode tree. Interactive nodes (form, confirm, actions)\n * respond through the handlers given here (or an enclosing IntentContext).\n */\nexport function UINodeRenderer({ node, className, ...handlers }: UINodeRendererProps) {\n const parent = useIntent();\n const hasOwn = Object.values(handlers).some((v) => v !== undefined);\n const content = (\n <div className={cn(\"flex min-w-0 flex-col gap-3\", className)}>\n <NodeView node={node} />\n </div>\n );\n if (!hasOwn) return content;\n return (\n <IntentContext.Provider value={{ ...parent, ...stripUndefined(handlers) }}>\n {content}\n </IntentContext.Provider>\n );\n}\n\nfunction stripUndefined<T extends object>(o: T): Partial<T> {\n return Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n\nconst TONE_TEXT = {\n default: \"text-text\",\n muted: \"text-muted\",\n success: \"text-success\",\n warning: \"text-warning\",\n danger: \"text-danger\",\n} as const;\n\nexport function NodeView({ node }: { node: UINode }) {\n switch (node.t) {\n case \"text\":\n return (\n <p\n className={cn(\n \"text-sm break-words whitespace-pre-wrap\",\n TONE_TEXT[node.tone ?? \"default\"],\n )}\n >\n {node.text}\n </p>\n );\n case \"markdown\":\n return <Markdown text={node.text} />;\n case \"code\":\n return <CodeBlock text={node.text} lang={node.lang} maxHeight=\"24rem\" />;\n case \"diff\":\n return <DiffView patch={node.patch} />;\n case \"list\":\n return <ListView node={node} />;\n case \"table\":\n return (\n <div className=\"max-w-full overflow-x-auto overscroll-x-contain rounded-md border border-border\">\n <table className=\"w-full border-collapse text-sm\">\n <thead className=\"bg-surface-2\">\n <tr>\n {node.columns.map((c, i) => (\n <th\n // biome-ignore lint/suspicious/noArrayIndexKey: columns are positional\n key={i}\n scope=\"col\"\n className=\"border-b border-border px-3 py-1.5 text-left font-medium\"\n >\n {c}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {node.rows.map((r, ri) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: rows are positional\n <tr key={ri} className=\"border-b border-border last:border-b-0\">\n {r.map((cell, ci) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: cells are positional\n <td key={ci} className=\"px-3 py-1.5 align-top break-words\">\n {cell}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n case \"section\":\n return <SectionView node={node} />;\n case \"tabs\":\n return <TabsView node={node} />;\n case \"progress\":\n return <ProgressView node={node} />;\n case \"ref\":\n return <RefView refValue={node.ref} label={node.label} />;\n case \"form\":\n return <FormRenderer node={node} />;\n case \"confirm\":\n return <ConfirmRenderer node={node} />;\n case \"actions\":\n return <ActionsView node={node} />;\n default:\n return null;\n }\n}\n\nfunction Children({ nodes }: { nodes: UINode[] }) {\n return (\n <>\n {nodes.map((n, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: UINode trees have no ids\n <NodeView key={i} node={n} />\n ))}\n </>\n );\n}\n\nfunction ListView({ node }: { node: Extract<UINode, { t: \"list\" }> }) {\n const Tag = node.ordered ? \"ol\" : \"ul\";\n return (\n <Tag\n className={cn(\n \"flex flex-col gap-1.5 pl-5 text-sm\",\n node.ordered ? \"list-decimal\" : \"list-disc\",\n )}\n >\n {node.items.map((item, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: list items are positional\n <li key={i} className=\"min-w-0\">\n <div className=\"flex min-w-0 flex-col gap-2\">\n <NodeView node={item} />\n </div>\n </li>\n ))}\n </Tag>\n );\n}\n\nfunction SectionView({ node }: { node: Extract<UINode, { t: \"section\" }> }) {\n if (node.collapsible) {\n return (\n <details className=\"group min-w-0 rounded-md border border-border\" open>\n <summary className=\"tap flex cursor-pointer list-none items-center gap-1.5 px-3 py-2 text-sm font-medium [&::-webkit-details-marker]:hidden\">\n <ChevronRight\n aria-hidden\n className=\"size-4 shrink-0 transition-transform group-open:rotate-90\"\n />\n {node.title ?? \"Details\"}\n </summary>\n <div className=\"flex min-w-0 flex-col gap-3 border-t border-border px-3 py-2\">\n <Children nodes={node.children} />\n </div>\n </details>\n );\n }\n return (\n <section className=\"flex min-w-0 flex-col gap-2\">\n {node.title && <h3 className=\"text-sm font-semibold\">{node.title}</h3>}\n <Children nodes={node.children} />\n </section>\n );\n}\n\nfunction TabsView({ node }: { node: Extract<UINode, { t: \"tabs\" }> }) {\n const prefix = useId();\n const [active, setActive] = useState(node.tabs[0]?.id ?? \"\");\n const current = node.tabs.find((t) => t.id === active) ?? node.tabs[0];\n if (!current) return null;\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <Tabs\n label=\"Sections\"\n idPrefix={prefix}\n tabs={node.tabs.map((t) => ({ id: t.id, label: t.label }))}\n value={current.id}\n onChange={setActive}\n scrollable\n />\n <TabPanel idPrefix={prefix} id={current.id} className=\"flex min-w-0 flex-col gap-3\">\n <Children nodes={current.children} />\n </TabPanel>\n </div>\n );\n}\n\nfunction ProgressView({ node }: { node: Extract<UINode, { t: \"progress\" }> }) {\n const status = node.status ?? \"running\";\n const Icon = status === \"ok\" ? CircleCheck : status === \"error\" ? CircleX : LoaderCircle;\n const statusText = status === \"ok\" ? \"Done\" : status === \"error\" ? \"Failed\" : \"In progress\";\n const pct = node.value === undefined ? null : Math.round(node.value * 100);\n return (\n <div className=\"flex min-w-0 flex-col gap-1\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Icon\n aria-hidden\n className={cn(\n \"size-4 shrink-0\",\n status === \"ok\" && \"text-success\",\n status === \"error\" && \"text-danger\",\n status === \"running\" && \"animate-spin text-info\",\n )}\n />\n <span className=\"min-w-0 flex-1 truncate\">{node.label}</span>\n <span className=\"shrink-0 text-xs text-muted\">\n {statusText}\n {pct !== null ? ` · ${pct}%` : \"\"}\n </span>\n </div>\n {pct !== null && (\n <div\n role=\"progressbar\"\n aria-label={node.label}\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n className=\"h-1.5 overflow-hidden rounded-full bg-surface-3\"\n >\n <div\n className={cn(\n \"h-full rounded-full\",\n status === \"error\" ? \"bg-danger\" : status === \"ok\" ? \"bg-success\" : \"bg-accent\",\n )}\n style={{ width: `${pct}%` }}\n />\n </div>\n )}\n </div>\n );\n}\n\nexport function refHref(ref: UIRef): string | null {\n switch (ref.kind) {\n case \"session\":\n return `/code/${encodeURIComponent(ref.sessionId)}`;\n case \"task\":\n return `/tasks/${encodeURIComponent(ref.taskId)}`;\n default:\n return null;\n }\n}\n\nfunction RefView({ refValue, label }: { refValue: UIRef; label: string }) {\n const { onOpenFile } = useIntent();\n const href = refHref(refValue);\n if (href) {\n return (\n <Link to={href} className=\"text-sm text-accent underline underline-offset-2\">\n {label}\n </Link>\n );\n }\n if (refValue.kind === \"file\") {\n if (onOpenFile) {\n return (\n <button\n type=\"button\"\n onClick={() => onOpenFile(refValue.path)}\n className=\"inline-flex min-w-0 items-center gap-1 text-left text-sm text-accent underline underline-offset-2\"\n >\n <FileCode aria-hidden className=\"size-4 shrink-0\" />\n <span className=\"truncate\">{label || refValue.path}</span>\n </button>\n );\n }\n return (\n <span\n className=\"inline-flex min-w-0 items-center gap-1 font-mono text-sm\"\n title={refValue.path}\n >\n <FileCode aria-hidden className=\"size-4 shrink-0 text-muted\" />\n <span className=\"truncate\">{label || refValue.path}</span>\n </span>\n );\n }\n if (refValue.kind !== \"native_session\") return <span className=\"text-sm\">{label}</span>;\n return (\n <span className=\"text-sm\" title={refValue.sessionFile}>\n {label} <span className=\"text-muted\">(native Pi session, not imported)</span>\n </span>\n );\n}\n\nfunction ActionsView({ node }: { node: Extract<UINode, { t: \"actions\" }> }) {\n const { onRespond, onAction, busy, disabled } = useIntent();\n if (disabled) return null;\n return (\n <div className=\"flex flex-wrap gap-2\">\n {node.actions.map((a) => (\n <Button\n key={a.id}\n variant={a.tone === \"primary\" ? \"primary\" : a.tone === \"danger\" ? \"danger\" : \"secondary\"}\n disabled={busy || (!onRespond && !onAction)}\n onClick={() => {\n if (onRespond) onRespond({ kind: \"action\", actionId: a.id });\n else onAction?.(a.id);\n }}\n >\n {a.label}\n </Button>\n ))}\n </div>\n );\n}\n","import type { Interaction, UINode } from \"@switchyard/protocol\";\n\n/** What actually happened when an extension opened a terminal-only `ctx.ui.custom()` dialog. */\nexport const UNSUPPORTED_COPY =\n \"An extension opened a terminal-only dialog. In RPC mode Pi gave it no answer, so the extension continued without one.\";\n\nexport interface UnsupportedAction {\n id: \"abort\" | \"message\";\n label: string;\n tone: \"primary\" | \"secondary\" | \"danger\";\n}\n\nconst DEFAULT_ACTIONS: UnsupportedAction[] = [\n { id: \"abort\", label: \"Stop the run\", tone: \"danger\" },\n { id: \"message\", label: \"Send a message to the agent\", tone: \"primary\" },\n];\n\nfunction findActions(node: UINode): Extract<UINode, { t: \"actions\" }> | null {\n if (node.t === \"actions\") return node;\n if (node.t === \"section\") {\n for (const c of node.children) {\n const found = findActions(c);\n if (found) return found;\n }\n }\n return null;\n}\n\nexport interface UnsupportedView {\n /** True until a person chose one of the alternatives. */\n answerable: boolean;\n actions: UnsupportedAction[];\n copy: string;\n}\n\nexport function isUnsupported(i: Interaction): boolean {\n return i.state === \"unsupported\" || i.source.kind === \"unsupported_custom\";\n}\n\n/** The alternatives the host offers for an unsupported dialog (stop the run, message). */\nexport function unsupportedView(i: Interaction): UnsupportedView {\n const node = findActions(i.presentation);\n const offered = (node?.actions ?? [])\n .filter(\n (a): a is typeof a & { id: \"abort\" | \"message\" } => a.id === \"abort\" || a.id === \"message\",\n )\n .map((a) => ({\n id: a.id,\n label: a.label,\n tone: (a.tone === \"default\"\n ? \"secondary\"\n : (a.tone ?? (a.id === \"abort\" ? \"danger\" : \"primary\"))) as UnsupportedAction[\"tone\"],\n }));\n return {\n answerable: i.state === \"unsupported\" && i.resolution === null,\n actions: offered.length > 0 ? offered : DEFAULT_ACTIONS,\n copy: UNSUPPORTED_COPY,\n };\n}\n\n/** A follow-up while Pi is still working queues behind the current turn. */\nexport function messageMode(runtime: string | undefined): \"prompt\" | \"followUp\" {\n return runtime === \"running\" || runtime === \"waiting_input\" ? \"followUp\" : \"prompt\";\n}\n","import type { Interaction, InteractionResponse, UINode } from \"@switchyard/protocol\";\nimport { useState } from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { formatRelative } from \"../../lib/time\";\nimport { apiPost, errorMessage, isApiError } from \"../../sync/api\";\nimport { useSyncStore } from \"../../sync/store\";\nimport { Button } from \"../ui/Button\";\nimport { StatusChip } from \"../ui/StatusChip\";\nimport { ErrorState } from \"../ui/states\";\nimport { TextArea } from \"../ui/TextArea\";\nimport { UINodeRenderer } from \"./UINodeRenderer\";\nimport { isUnsupported, messageMode, unsupportedView } from \"./unsupported\";\n\nexport interface InteractionCardProps {\n interaction: Interaction;\n /** Read-only session or host offline: show the question without answer controls. */\n readOnlyReason?: string | null;\n className?: string;\n /** Called after the coordinator acknowledged an answer. */\n onAnswered?: (interaction: Interaction) => void;\n /** DOM id (the \"Needs your answer\" strip scrolls to it). */\n id?: string;\n}\n\nfunction hasInteractive(node: UINode): boolean {\n switch (node.t) {\n case \"form\":\n case \"confirm\":\n case \"actions\":\n return true;\n case \"list\":\n return node.items.some(hasInteractive);\n case \"section\":\n return node.children.some(hasInteractive);\n case \"tabs\":\n return node.tabs.some((t) => t.children.some(hasInteractive));\n default:\n return false;\n }\n}\n\nfunction byLabel(by: string): string {\n if (by === \"host\") return \"the host\";\n if (by === \"pi\") return \"Pi\";\n return \"a device\";\n}\n\n/**\n * A runtime interaction (extension dialog). Posts the answer with the\n * interaction revision and waits for the acknowledgement; there is no\n * optimistic resolution. A 409 shows \"Already answered: <summary>\".\n */\nexport function InteractionCard({\n interaction: fromProps,\n readOnlyReason,\n className,\n onAnswered,\n id,\n}: InteractionCardProps) {\n const upsert = useSyncStore((s) => s.upsertInteraction);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<unknown>(null);\n const [alreadyAnswered, setAlreadyAnswered] = useState<string | null>(null);\n const [lastResponse, setLastResponse] = useState<InteractionResponse | null>(null);\n // The acknowledged interaction from the answer/409 response, until the prop catches up.\n const [acked, setAcked] = useState<Interaction | null>(null);\n const interaction =\n acked && acked.id === fromProps.id && acked.revision > fromProps.revision ? acked : fromProps;\n\n const pending = interaction.state === \"pending\";\n const unsupported = isUnsupported(interaction);\n const sessionRuntime = useSyncStore((s) => s.sessions[interaction.sessionId]?.runtime);\n const [composing, setComposing] = useState(false);\n const [message, setMessage] = useState(\"\");\n\n const respond = async (response: InteractionResponse): Promise<boolean> => {\n setBusy(true);\n setError(null);\n setLastResponse(response);\n try {\n const res = await apiPost<{ status: string; interaction: Interaction }>(\n `/api/interactions/${encodeURIComponent(interaction.id)}/answer`,\n { revision: interaction.revision, response },\n );\n if (res?.interaction) {\n upsert(res.interaction);\n setAcked(res.interaction);\n onAnswered?.(res.interaction);\n }\n return true;\n } catch (e) {\n if (isApiError(e, \"already_answered\")) {\n const other = (e.details as { interaction?: Interaction } | undefined)?.interaction;\n if (other) {\n upsert(other);\n setAcked(other);\n }\n setAlreadyAnswered(other?.resolution?.summary ?? \"answered on another device\");\n } else {\n setError(e);\n }\n return false;\n } finally {\n setBusy(false);\n }\n };\n\n /** \"Send a message to the agent\": deliver the message first, then record the choice. */\n const sendMessage = async () => {\n const text = message.trim();\n if (!text) return;\n setBusy(true);\n setError(null);\n try {\n await apiPost(`/api/sessions/${encodeURIComponent(interaction.sessionId)}/prompt`, {\n text,\n mode: messageMode(sessionRuntime),\n });\n } catch (e) {\n setError(e);\n setBusy(false);\n return;\n }\n setBusy(false);\n if (await respond({ kind: \"action\", actionId: \"message\" })) {\n setComposing(false);\n setMessage(\"\");\n }\n };\n\n return (\n <article\n id={id}\n aria-label={`Question: ${interaction.title}`}\n className={cn(\n \"flex min-w-0 flex-col gap-3 rounded-lg border bg-surface p-3\",\n pending ? \"border-warning\" : \"border-border\",\n className,\n )}\n >\n <header className=\"flex min-w-0 flex-wrap items-start gap-2\">\n <h3 className=\"min-w-0 flex-1 text-sm font-semibold break-words\">{interaction.title}</h3>\n <StatusChip kind=\"interaction\" value={interaction.state} size=\"sm\" />\n </header>\n\n {alreadyAnswered && (\n <p role=\"status\" className=\"rounded-md bg-surface-2 px-3 py-2 text-sm\">\n Already answered: {alreadyAnswered}\n </p>\n )}\n\n {unsupported ? (\n <UnsupportedBody\n interaction={interaction}\n readOnlyReason={readOnlyReason ?? null}\n busy={busy}\n answered={alreadyAnswered !== null}\n composing={composing}\n message={message}\n setMessage={setMessage}\n onAction={(actionId) => {\n if (actionId === \"message\") setComposing(true);\n else void respond({ kind: \"action\", actionId });\n }}\n onSend={() => void sendMessage()}\n onCancelMessage={() => setComposing(false)}\n />\n ) : pending && !alreadyAnswered ? (\n <>\n {readOnlyReason && <p className=\"text-sm text-muted\">{readOnlyReason}</p>}\n <UINodeRenderer\n node={interaction.presentation}\n onRespond={(r) => void respond(r)}\n busy={busy}\n disabled={!!readOnlyReason}\n />\n {!readOnlyReason && !hasInteractive(interaction.presentation) && (\n <div>\n <Button busy={busy} onClick={() => void respond({ kind: \"cancel\" })}>\n Dismiss\n </Button>\n </div>\n )}\n {busy && (\n <p role=\"status\" className=\"text-sm text-muted\">\n Sending answer… waiting for the host to confirm.\n </p>\n )}\n </>\n ) : alreadyAnswered ? null : interaction.resolution ? (\n <p className=\"text-sm text-muted\">\n {interaction.state === \"resolved\" ? \"Answered\" : \"Closed\"} by{\" \"}\n {byLabel(interaction.resolution.by)} {formatRelative(interaction.resolution.at)}:{\" \"}\n <span className=\"text-text\">{interaction.resolution.summary}</span>\n </p>\n ) : (\n <p className=\"text-sm text-muted\">\n {interaction.state === \"expired\"\n ? \"This question expired before it was answered (Pi closed the dialog).\"\n : \"This question was cancelled.\"}\n </p>\n )}\n\n {error !== null && (\n <ErrorState\n compact\n title=\"Answer not delivered\"\n error={errorMessage(error)}\n onRetry={lastResponse ? () => void respond(lastResponse) : undefined}\n />\n )}\n </article>\n );\n}\n\n/** A terminal-only dialog: what happened, and the alternatives the host offers until one is chosen. */\nfunction UnsupportedBody({\n interaction,\n readOnlyReason,\n busy,\n answered,\n composing,\n message,\n setMessage,\n onAction,\n onSend,\n onCancelMessage,\n}: {\n interaction: Interaction;\n readOnlyReason: string | null;\n busy: boolean;\n answered: boolean;\n composing: boolean;\n message: string;\n setMessage: (t: string) => void;\n onAction: (actionId: \"abort\" | \"message\") => void;\n onSend: () => void;\n onCancelMessage: () => void;\n}) {\n const view = unsupportedView(interaction);\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <p className=\"text-sm text-muted\">{view.copy}</p>\n {interaction.resolution ? (\n <p className=\"text-sm text-muted\">\n Chosen by {byLabel(interaction.resolution.by)} {formatRelative(interaction.resolution.at)}\n : <span className=\"text-text\">{interaction.resolution.summary}</span>\n </p>\n ) : !view.answerable || answered ? null : readOnlyReason ? (\n <p className=\"text-sm text-muted\">{readOnlyReason}</p>\n ) : composing ? (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <TextArea\n aria-label=\"Message to the agent\"\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n rows={3}\n autoFocus\n placeholder=\"Tell the agent what to do instead\"\n />\n <div className=\"flex flex-wrap gap-2\">\n <Button variant=\"primary\" busy={busy} disabled={!message.trim()} onClick={onSend}>\n Send message\n </Button>\n <Button disabled={busy} onClick={onCancelMessage}>\n Cancel\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"flex flex-wrap gap-2\">\n {view.actions.map((a) => (\n <Button\n key={a.id}\n variant={a.tone}\n busy={busy && a.id === \"abort\"}\n disabled={busy}\n onClick={() => onAction(a.id)}\n >\n {a.label}\n </Button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"ignoreList":[0],"mappings":"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"}
|