@nimblebrain/synapse 0.7.0 → 0.9.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 +33 -0
- package/dist/{chunk-WYWKN3YG.cjs → chunk-42JAT6TK.cjs} +27 -14
- package/dist/{chunk-2HKN2A2J.js.map → chunk-42JAT6TK.cjs.map} +1 -1
- package/dist/{chunk-2HKN2A2J.js → chunk-IQYOVYIR.js} +27 -14
- package/dist/chunk-IQYOVYIR.js.map +1 -0
- package/dist/codegen/index.cjs +5 -5
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.js +1 -1
- package/dist/connect.iife.global.js +8 -8
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/react/index.cjs +3 -3
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +1 -1
- package/dist/synapse-runtime.iife.global.js +8 -8
- package/dist/{types-Beo6hjvb.d.cts → types-C9utGXv_.d.cts} +13 -2
- package/dist/{types-Beo6hjvb.d.ts → types-C9utGXv_.d.ts} +13 -2
- package/dist/ui/fonts.cjs +19 -0
- package/dist/ui/fonts.cjs.map +1 -0
- package/dist/ui/fonts.d.cts +30 -0
- package/dist/ui/fonts.d.ts +30 -0
- package/dist/ui/fonts.js +17 -0
- package/dist/ui/fonts.js.map +1 -0
- package/dist/ui/index.cjs +1397 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +415 -0
- package/dist/ui/index.d.ts +415 -0
- package/dist/ui/index.js +1366 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +11 -1
- package/dist/chunk-WYWKN3YG.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ui/tokens.ts","../../src/ui/components/Avatar.tsx","../../src/ui/components/Badge.tsx","../../src/ui/internal/inject-style.ts","../../src/ui/components/Button.tsx","../../src/ui/components/Card.tsx","../../src/ui/components/Drawer.tsx","../../src/ui/primitives.tsx","../../src/ui/typography.tsx","../../src/ui/components/EmptyState.tsx","../../src/ui/components/ListRow.tsx","../../src/ui/components/Pagination.tsx","../../src/ui/components/Prose.tsx","../../src/ui/components/SearchField.tsx","../../src/ui/components/SegmentedControl.tsx","../../src/ui/components/Spinner.tsx","../../src/ui/components/StatusDot.tsx","../../src/ui/components/Table.tsx","../../src/ui/layouts/AppFrame.tsx","../../src/ui/layouts/use-container-width.ts","../../src/ui/layouts/ListDetailLayout.tsx","../../src/ui/layouts/SidebarLayout.tsx"],"names":["jsx","STYLE_ID","RULES","useEffect","TONE","jsxs","Header","Body","Footer","useRef","useState","createContext","useContext","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The token contract for `@nimblebrain/synapse/ui`.\n *\n * Values are NOT brand hexes — they are `var(--token, fallback)` references to\n * the CSS custom properties the host injects into the app iframe (the MCP\n * ext-apps `hostContext.styles.variables`). Because styling resolves through\n * CSS variables, theme changes (including light↔dark) reflect automatically\n * with no React re-render: the host swaps the `:root` vars and every `var()`\n * re-resolves.\n *\n * The fallbacks are deliberately **neutral** (system fonts, neutral grays, a\n * generic blue) — NOT NimbleBrain brand. Brand arrives by injection when the\n * app runs inside the NimbleBrain host; standalone/static renders get a sane\n * unbranded default. This keeps the library host-agnostic.\n *\n * Components import the static `tokens` object and style with CSS `var()`, so\n * theming (incl. light/dark) resolves in CSS with no re-render.\n */\n\nimport type { CSSProperties } from \"react\";\n\n/** Resolved design tokens as CSS `var()` references with neutral fallbacks. */\nexport const tokens = {\n // ── Surfaces ──\n bg: \"var(--color-background-primary, #ffffff)\",\n bgRaised: \"var(--color-background-secondary, #fafafa)\",\n bgSubtle: \"var(--color-background-tertiary, #f3f4f6)\",\n\n // ── Text ──\n fg: \"var(--color-text-primary, #111827)\",\n fgMuted: \"var(--color-text-secondary, #6b7280)\",\n fgFaint: \"var(--color-text-tertiary, #9ca3af)\",\n accent: \"var(--color-text-accent, #2563eb)\",\n accentFg: \"var(--nb-color-accent-foreground, #ffffff)\",\n\n // ── Border / ring ──\n border: \"var(--color-border-primary, #e5e7eb)\",\n borderStrong: \"var(--color-border-secondary, #d1d5db)\",\n ring: \"var(--color-ring-primary, #2563eb)\",\n\n // ── Status / brand semantics ──\n danger: \"var(--nb-color-danger, #dc2626)\",\n success: \"var(--nb-color-success, #059669)\",\n warning: \"var(--nb-color-warning, #f59e0b)\",\n warm: \"var(--nb-color-warm, #d4620a)\",\n warmLight: \"var(--nb-color-warm-light, #fef5ee)\",\n processing: \"var(--nb-color-processing, #7c3aed)\",\n processingLight: \"var(--nb-color-processing-light, #f3eeff)\",\n infoLight: \"var(--nb-color-info-light, #eef4ff)\",\n\n // ── Typography ──\n fontSans: \"var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, sans-serif)\",\n fontMono: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)\",\n fontHeading: \"var(--nb-font-heading, Georgia, 'Times New Roman', serif)\",\n weightNormal: \"var(--font-weight-normal, 400)\",\n weightMedium: \"var(--font-weight-medium, 500)\",\n weightSemibold: \"var(--font-weight-semibold, 600)\",\n weightBold: \"var(--font-weight-bold, 700)\",\n\n // ── Type scale (size + line-height pairs) ──\n textXsSize: \"var(--font-text-xs-size, 0.75rem)\",\n textXsLine: \"var(--font-text-xs-line-height, 1rem)\",\n textSmSize: \"var(--font-text-sm-size, 0.875rem)\",\n textSmLine: \"var(--font-text-sm-line-height, 1.25rem)\",\n textBaseSize: \"var(--font-text-base-size, 1rem)\",\n textBaseLine: \"var(--font-text-base-line-height, 1.5rem)\",\n textLgSize: \"var(--font-text-lg-size, 1.125rem)\",\n textLgLine: \"var(--font-text-lg-line-height, 1.75rem)\",\n headingSmSize: \"var(--font-heading-sm-size, 1.25rem)\",\n headingSmLine: \"var(--font-heading-sm-line-height, 1.75rem)\",\n headingMdSize: \"var(--font-heading-md-size, 1.5rem)\",\n headingMdLine: \"var(--font-heading-md-line-height, 2rem)\",\n headingLgSize: \"var(--font-heading-lg-size, 2rem)\",\n headingLgLine: \"var(--font-heading-lg-line-height, 2.5rem)\",\n\n // ── Radius / border width ──\n radiusXs: \"var(--border-radius-xs, 0.25rem)\",\n radiusSm: \"var(--border-radius-sm, 0.5rem)\",\n radiusMd: \"var(--border-radius-md, 0.75rem)\",\n radiusLg: \"var(--border-radius-lg, 1rem)\",\n radiusXl: \"var(--border-radius-xl, 1.5rem)\",\n borderWidth: \"var(--border-width-regular, 1px)\",\n\n // ── Shadows ──\n shadowHairline: \"var(--shadow-hairline, 0 0 0 1px rgba(0,0,0,0.06))\",\n shadowSm: \"var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.05))\",\n shadowMd: \"var(--shadow-md, 0 4px 6px -1px rgba(0,0,0,0.1))\",\n shadowLg: \"var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1))\",\n} as const;\n\nexport type Tokens = typeof tokens;\n\n/**\n * A style object that also permits CSS custom properties (`--foo`). React's\n * `CSSProperties` rejects custom-property keys; components that set CSS vars\n * inline (for `:hover`/keyframe plumbing) type their style as this, then pass\n * it to `style` (it down-casts cleanly to `CSSProperties`).\n */\nexport type StyleWithVars = CSSProperties & Record<`--${string}`, string | number>;\n\n/** Body text sizes. */\nexport type TextSize = \"xs\" | \"sm\" | \"base\" | \"lg\";\n/** Heading sizes. */\nexport type HeadingSize = \"sm\" | \"md\" | \"lg\";\n\nconst TEXT_SCALE: Record<TextSize, CSSProperties> = {\n xs: { fontSize: tokens.textXsSize, lineHeight: tokens.textXsLine },\n sm: { fontSize: tokens.textSmSize, lineHeight: tokens.textSmLine },\n base: { fontSize: tokens.textBaseSize, lineHeight: tokens.textBaseLine },\n lg: { fontSize: tokens.textLgSize, lineHeight: tokens.textLgLine },\n};\n\nconst HEADING_SCALE: Record<HeadingSize, CSSProperties> = {\n sm: { fontSize: tokens.headingSmSize, lineHeight: tokens.headingSmLine },\n md: { fontSize: tokens.headingMdSize, lineHeight: tokens.headingMdLine },\n lg: { fontSize: tokens.headingLgSize, lineHeight: tokens.headingLgLine },\n};\n\n/** `{ fontSize, lineHeight }` for a body-text level. */\nexport function textStyle(size: TextSize): CSSProperties {\n return TEXT_SCALE[size];\n}\n\n/** `{ fontSize, lineHeight }` for a heading level. */\nexport function headingStyle(size: HeadingSize): CSSProperties {\n return HEADING_SCALE[size];\n}\n","/**\n * Avatar — a circular identity chip. Renders an image when `src` is given,\n * otherwise initials derived from `name` on a subtle tinted background.\n */\n\nimport { type HTMLAttributes, useEffect, useState } from \"react\";\nimport { tokens } from \"../tokens.js\";\n\n/** Up to two initials from a name (\"Jordan Ratner\" → \"JR\", \"mat\" → \"M\"). */\nfunction initialsOf(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n const first = parts[0] ?? \"\";\n if (parts.length === 1) return first.charAt(0).toUpperCase();\n const last = parts[parts.length - 1] ?? \"\";\n return (first.charAt(0) + last.charAt(0)).toUpperCase();\n}\n\ninterface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n /** Name used for initials and the image alt text. */\n name: string;\n /** Optional image URL; falls back to initials when absent or on error. */\n src?: string;\n /** Diameter in px. Default 28. */\n size?: number;\n}\n\nexport function Avatar({ name, src, size = 28, style, ...rest }: AvatarProps) {\n // Fall back to initials if the image fails to load. Reset on `src` change.\n const [failed, setFailed] = useState(false);\n // biome-ignore lint/correctness/useExhaustiveDependencies: reset only when src changes\n useEffect(() => setFailed(false), [src]);\n const showImage = Boolean(src) && !failed;\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n width: size,\n height: size,\n borderRadius: \"50%\",\n overflow: \"hidden\",\n background: tokens.bgSubtle,\n color: tokens.fgMuted,\n fontFamily: tokens.fontSans,\n fontSize: Math.round(size * 0.4),\n fontWeight: tokens.weightSemibold,\n userSelect: \"none\",\n ...style,\n }}\n {...rest}\n >\n {showImage ? (\n <img\n src={src}\n alt={name}\n width={size}\n height={size}\n onError={() => setFailed(true)}\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n />\n ) : (\n initialsOf(name)\n )}\n </span>\n );\n}\n","/**\n * Badge — a small pill for status and priority labels (e.g. MEDIUM/HIGH,\n * open/resolved). Soft tinted background with a same-hue label.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { tokens } from \"../tokens.js\";\n\nexport type BadgeTone =\n | \"neutral\"\n | \"accent\"\n | \"success\"\n | \"warning\"\n | \"danger\"\n | \"processing\"\n | \"warm\";\n\n/** `{ bg, fg }` per tone. Soft tinted background, same-hue label. The status\n * tones have no `*Light` token so their tint is derived from the fg color. */\nconst TONE: Record<BadgeTone, { bg: string; fg: string }> = {\n neutral: { bg: tokens.bgSubtle, fg: tokens.fgMuted },\n accent: { bg: tokens.infoLight, fg: tokens.accent },\n success: { bg: `color-mix(in oklab, ${tokens.success} 14%, transparent)`, fg: tokens.success },\n warning: { bg: `color-mix(in oklab, ${tokens.warning} 14%, transparent)`, fg: tokens.warning },\n danger: { bg: `color-mix(in oklab, ${tokens.danger} 14%, transparent)`, fg: tokens.danger },\n processing: { bg: tokens.processingLight, fg: tokens.processing },\n warm: { bg: tokens.warmLight, fg: tokens.warm },\n};\n\ninterface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n tone?: BadgeTone;\n children?: ReactNode;\n}\n\nexport function Badge({ tone = \"neutral\", style, children, ...rest }: BadgeProps) {\n const { bg, fg } = TONE[tone];\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"0.25rem\",\n padding: \"0.1rem 0.45rem\",\n borderRadius: tokens.radiusXs,\n background: bg,\n color: fg,\n fontFamily: tokens.fontSans,\n fontSize: tokens.textXsSize,\n lineHeight: tokens.textXsLine,\n fontWeight: tokens.weightSemibold,\n letterSpacing: \"0.02em\",\n textTransform: \"uppercase\",\n whiteSpace: \"nowrap\",\n ...style,\n }}\n {...rest}\n >\n {children}\n </span>\n );\n}\n","/**\n * Inject a stylesheet into the document exactly once, keyed by `id`. Used for\n * the few things inline styles can't express — `@keyframes` and `:hover`/\n * `:focus` pseudo-states. SSR-safe (no-ops without `document`) and idempotent.\n */\nexport function ensureStyle(id: string, css: string): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(id)) return;\n const style = document.createElement(\"style\");\n style.id = id;\n style.textContent = css;\n document.head.appendChild(style);\n}\n","/**\n * Button and TextLink. Pseudo-states (`:hover`/`:active`/`:disabled`) live in a\n * once-injected stylesheet that reads token-driven CSS custom properties set\n * inline — so the base values stay token-driven while hover still works.\n */\n\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-button\";\nconst RULES = `\n.nb-btn {\n --nb-btn-bg: transparent;\n --nb-btn-bg-hover: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.4rem;\n border: var(--nb-btn-border, none);\n border-radius: var(--nb-btn-radius);\n background: var(--nb-btn-bg);\n color: var(--nb-btn-fg);\n font-family: var(--nb-btn-font);\n font-weight: var(--nb-btn-weight);\n cursor: pointer;\n transition: background 130ms ease, color 130ms ease, opacity 130ms ease;\n white-space: nowrap;\n}\n.nb-btn:hover { background: var(--nb-btn-bg-hover); }\n.nb-btn:active { transform: translateY(0.5px); }\n.nb-btn:disabled { opacity: 0.5; cursor: default; }\n.nb-btn:disabled:hover { background: var(--nb-btn-bg); }\n.nb-textlink {\n border: none;\n background: none;\n padding: 0;\n cursor: pointer;\n font-family: var(--nb-tl-font);\n color: var(--nb-tl-fg);\n transition: color 130ms ease, opacity 130ms ease;\n}\n.nb-textlink:hover { color: var(--nb-tl-fg-hover); }\n.nb-textlink:disabled { opacity: 0.45; cursor: default; }\n`;\n\ntype Variant = \"primary\" | \"secondary\" | \"ghost\";\ntype Size = \"sm\" | \"md\";\n\nconst SIZE_PAD: Record<Size, string> = {\n sm: \"0.3rem 0.6rem\",\n md: \"0.45rem 0.85rem\",\n};\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: Variant;\n size?: Size;\n children?: ReactNode;\n}\n\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n style,\n className,\n children,\n ...rest\n}: ButtonProps) {\n ensureStyle(STYLE_ID, RULES);\n const vars: Record<`--${string}`, string> = {\n \"--nb-btn-radius\": tokens.radiusSm,\n \"--nb-btn-font\": tokens.fontSans,\n \"--nb-btn-weight\": tokens.weightMedium,\n };\n if (variant === \"primary\") {\n vars[\"--nb-btn-bg\"] = tokens.accent;\n vars[\"--nb-btn-bg-hover\"] = `color-mix(in oklab, ${tokens.accent} 88%, black)`;\n vars[\"--nb-btn-fg\"] = tokens.accentFg;\n } else if (variant === \"secondary\") {\n vars[\"--nb-btn-bg\"] = tokens.bgSubtle;\n vars[\"--nb-btn-bg-hover\"] = tokens.bgRaised;\n vars[\"--nb-btn-fg\"] = tokens.fg;\n vars[\"--nb-btn-border\"] = `${tokens.borderWidth} solid ${tokens.border}`;\n } else {\n vars[\"--nb-btn-bg\"] = \"transparent\";\n vars[\"--nb-btn-bg-hover\"] = tokens.bgSubtle;\n vars[\"--nb-btn-fg\"] = tokens.fg;\n }\n const btnStyle: StyleWithVars = {\n ...vars,\n padding: SIZE_PAD[size],\n fontSize: size === \"sm\" ? tokens.textSmSize : tokens.textBaseSize,\n lineHeight: size === \"sm\" ? tokens.textSmLine : tokens.textBaseLine,\n ...style,\n };\n return (\n <button type=\"button\" className={`nb-btn ${className ?? \"\"}`.trim()} style={btnStyle} {...rest}>\n {children}\n </button>\n );\n}\n\ninterface TextLinkProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Resting tone. Hover always moves toward `accent` (or `danger`). */\n tone?: \"muted\" | \"default\" | \"danger\";\n children?: ReactNode;\n}\n\n/** A chrome-less text button — for back / delete / retry affordances. */\nexport function TextLink({ tone = \"muted\", style, className, children, ...rest }: TextLinkProps) {\n ensureStyle(STYLE_ID, RULES);\n const resting =\n tone === \"danger\" ? tokens.danger : tone === \"default\" ? tokens.fg : tokens.fgMuted;\n const hover = tone === \"danger\" ? tokens.danger : tokens.accent;\n const linkStyle: StyleWithVars = {\n \"--nb-tl-font\": tokens.fontSans,\n \"--nb-tl-fg\": resting,\n \"--nb-tl-fg-hover\": hover,\n fontSize: tokens.textXsSize,\n lineHeight: tokens.textXsLine,\n letterSpacing: \"0.02em\",\n ...style,\n };\n return (\n <button\n type=\"button\"\n className={`nb-textlink ${className ?? \"\"}`.trim()}\n style={linkStyle}\n {...rest}\n >\n {children}\n </button>\n );\n}\n","/**\n * Card — a raised surface with a hairline border. The default container for\n * grouped content (deal cards, task cards, panels). `interactive` adds a hover\n * lift via a once-injected stylesheet (no per-card handlers).\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-card\";\nconst RULES = `\n.nb-card--interactive {\n cursor: pointer;\n transition: box-shadow 140ms ease, border-color 140ms ease;\n}\n.nb-card--interactive:hover {\n box-shadow: var(--nb-card-shadow-hover);\n border-color: var(--nb-card-border-hover);\n}\n`;\n\ninterface CardProps extends HTMLAttributes<HTMLDivElement> {\n /** Inner padding (CSS length or px number). Default `0.875rem`. */\n padding?: number | string;\n /** Lift on hover — for clickable cards. */\n interactive?: boolean;\n children?: ReactNode;\n}\n\nexport function Card({\n padding = \"0.875rem\",\n interactive = false,\n style,\n className,\n children,\n ...rest\n}: CardProps) {\n if (interactive) ensureStyle(STYLE_ID, RULES);\n const cardStyle: StyleWithVars = {\n background: tokens.bgRaised,\n border: `${tokens.borderWidth} solid ${tokens.border}`,\n borderRadius: tokens.radiusMd,\n padding,\n boxShadow: tokens.shadowSm,\n \"--nb-card-shadow-hover\": tokens.shadowMd,\n \"--nb-card-border-hover\": tokens.borderStrong,\n ...style,\n };\n return (\n <div\n className={interactive ? `nb-card--interactive ${className ?? \"\"}`.trim() : className}\n style={cardStyle}\n {...rest}\n >\n {children}\n </div>\n );\n}\n","/**\n * Drawer — an off-canvas overlay panel that slides in from an edge, over a\n * scrim. The general overlay the apps need (e.g. CRM's detail panel).\n *\n * Built on the native `<dialog>` element: `showModal()` gives the focus trap,\n * Escape handling, top-layer stacking, inert background, and scroll behavior\n * for free — no hand-rolled focus management. Controlled via `open`/`onClose`.\n * Escape routes through `onEscape` (defaults to `onClose`); clicking the\n * backdrop calls `onClose`. The slide-in is a CSS keyframe on `[open]`.\n *\n * Compose with the `Header` / `Body` / `Footer` slots, or pass plain children.\n * A multi-level \"panel stack\" (push/pop) is an app concern built on top of this.\n */\n\nimport {\n type DialogHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useRef,\n} from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\ntype Side = \"left\" | \"right\";\n\nconst STYLE_ID = \"nb-synapse-drawer\";\nconst RULES = `\n.nb-drawer {\n margin: 0; padding: 0; border: none; max-width: 92%;\n height: 100%; max-height: 100%; display: flex; flex-direction: column;\n}\n.nb-drawer--right { margin-left: auto; }\n.nb-drawer--left { margin-right: auto; }\n.nb-drawer--right[open] { animation: nb-drawer-in-right 240ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-drawer--left[open] { animation: nb-drawer-in-left 240ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-drawer::backdrop { background: rgba(0, 0, 0, 0.32); }\n.nb-drawer[open]::backdrop { animation: nb-drawer-fade 200ms ease; }\n@keyframes nb-drawer-in-right { from { transform: translateX(100%); } }\n@keyframes nb-drawer-in-left { from { transform: translateX(-100%); } }\n@keyframes nb-drawer-fade { from { opacity: 0; } }\n`;\n\ninterface DrawerProps\n extends Omit<DialogHTMLAttributes<HTMLDialogElement>, \"title\" | \"onCancel\" | \"onClick\"> {\n open: boolean;\n /** Called by the backdrop and the Header close button. */\n onClose: () => void;\n /** Called on Escape. Defaults to `onClose` — override to do something else\n * (e.g. pop one level of a panel stack before closing). */\n onEscape?: () => void;\n side?: Side;\n /** Panel width. Default 480. */\n width?: number | string;\n children?: ReactNode;\n}\n\nfunction DrawerRoot({\n open,\n onClose,\n onEscape,\n side = \"right\",\n width = 480,\n style,\n children,\n ...rest\n}: DrawerProps) {\n ensureStyle(STYLE_ID, RULES);\n const dialogRef = useRef<HTMLDialogElement>(null);\n\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog || typeof dialog.showModal !== \"function\") return;\n if (open && !dialog.open) dialog.showModal();\n else if (!open && dialog.open) dialog.close();\n }, [open]);\n\n const panelStyle: StyleWithVars = {\n width,\n background: tokens.bg,\n color: tokens.fg,\n boxShadow: tokens.shadowLg,\n ...(side === \"right\"\n ? { borderLeft: `${tokens.borderWidth} solid ${tokens.border}` }\n : { borderRight: `${tokens.borderWidth} solid ${tokens.border}` }),\n ...style,\n };\n\n return (\n // biome-ignore lint/a11y/useKeyWithClickEvents: backdrop click is a mouse convenience; the dialog's Escape (onCancel) is the keyboard dismissal path.\n <dialog\n ref={dialogRef}\n className={`nb-drawer nb-drawer--${side}`}\n style={panelStyle}\n onCancel={(e) => {\n e.preventDefault(); // we own dismissal so onEscape can pop a stack\n (onEscape ?? onClose)();\n }}\n onClick={(e) => {\n // A click whose target is the dialog itself is a backdrop click.\n if (e.target === dialogRef.current) onClose();\n }}\n {...rest}\n >\n {children}\n </dialog>\n );\n}\n\ninterface HeaderProps extends HTMLAttributes<HTMLElement> {\n /** Show a close button that calls this. */\n onClose?: () => void;\n children?: ReactNode;\n}\n\nfunction Header({ onClose, style, children, ...rest }: HeaderProps) {\n return (\n <header\n style={{\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.75rem\",\n padding: \"0.875rem 1rem\",\n borderBottom: `${tokens.borderWidth} solid ${tokens.border}`,\n fontFamily: tokens.fontSans,\n fontWeight: tokens.weightSemibold,\n color: tokens.fg,\n ...style,\n }}\n {...rest}\n >\n <div style={{ flex: 1, minWidth: 0 }}>{children}</div>\n {onClose ? <CloseButton onClose={onClose} /> : null}\n </header>\n );\n}\n\nfunction CloseButton({ onClose }: { onClose: () => void }) {\n return (\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={onClose}\n style={{\n flexShrink: 0,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 28,\n height: 28,\n border: \"none\",\n background: \"transparent\",\n color: tokens.fgMuted,\n cursor: \"pointer\",\n borderRadius: tokens.radiusSm,\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <path\n d=\"M4 4l8 8M12 4l-8 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n );\n}\n\nfunction Body({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div style={{ flex: 1, minHeight: 0, overflowY: \"auto\", padding: \"1rem\", ...style }} {...rest}>\n {children}\n </div>\n );\n}\n\nfunction Footer({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n return (\n <footer\n style={{\n flexShrink: 0,\n padding: \"0.75rem 1rem\",\n borderTop: `${tokens.borderWidth} solid ${tokens.border}`,\n ...style,\n }}\n {...rest}\n >\n {children}\n </footer>\n );\n}\n\n/** `Drawer` with `.Header`, `.Body`, `.Footer` slots. */\nexport const Drawer = Object.assign(DrawerRoot, { Header, Body, Footer });\n","/**\n * Layout primitives — the composition atoms. `Stack` (vertical) and `Inline`\n * (horizontal) replace ad-hoc `display:flex` style objects; `Spacer` and\n * `Divider` cover the two other recurring layout needs. Deliberately minimal\n * (no `Box`, no grid system) — the layout scaffolds handle page structure.\n */\n\nimport type { CSSProperties, HTMLAttributes, ReactNode } from \"react\";\nimport { tokens } from \"./tokens.js\";\n\ntype Align = \"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\";\ntype Justify = \"start\" | \"center\" | \"end\" | \"between\" | \"around\";\n\nconst ALIGN: Record<Align, CSSProperties[\"alignItems\"]> = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n stretch: \"stretch\",\n baseline: \"baseline\",\n};\n\nconst JUSTIFY: Record<Justify, CSSProperties[\"justifyContent\"]> = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n around: \"space-around\",\n};\n\ninterface FlexProps extends HTMLAttributes<HTMLDivElement> {\n gap?: number | string;\n align?: Align;\n justify?: Justify;\n wrap?: boolean;\n children?: ReactNode;\n}\n\nfunction flexStyle(\n direction: \"row\" | \"column\",\n { gap, align, justify, wrap }: FlexProps,\n): CSSProperties {\n return {\n display: \"flex\",\n flexDirection: direction,\n gap,\n alignItems: align ? ALIGN[align] : undefined,\n justifyContent: justify ? JUSTIFY[justify] : undefined,\n flexWrap: wrap ? \"wrap\" : undefined,\n };\n}\n\n/** Vertical flex container with `gap`. Defaults to `align: stretch`. */\nexport function Stack({ gap, align, justify, wrap, style, children, ...rest }: FlexProps) {\n return (\n <div style={{ ...flexStyle(\"column\", { gap, align, justify, wrap }), ...style }} {...rest}>\n {children}\n </div>\n );\n}\n\n/** Horizontal flex container with `gap`. Defaults to `align: center`. */\nexport function Inline({\n gap,\n align = \"center\",\n justify,\n wrap,\n style,\n children,\n ...rest\n}: FlexProps) {\n return (\n <div style={{ ...flexStyle(\"row\", { gap, align, justify, wrap }), ...style }} {...rest}>\n {children}\n </div>\n );\n}\n\n/** Flexible gap that pushes siblings apart inside a `Stack`/`Inline`. */\nexport function Spacer({ style, ...rest }: HTMLAttributes<HTMLDivElement>) {\n return <div style={{ flex: 1, ...style }} {...rest} />;\n}\n\ninterface DividerProps extends HTMLAttributes<HTMLDivElement> {\n orientation?: \"horizontal\" | \"vertical\";\n}\n\n/** A hairline rule using the border token. Horizontal by default. Decorative\n * (`aria-hidden`) — it's a visual divider, not a focusable/valued separator. */\nexport function Divider({ orientation = \"horizontal\", style, ...rest }: DividerProps) {\n const isVertical = orientation === \"vertical\";\n return (\n <div\n aria-hidden=\"true\"\n style={{\n flexShrink: 0,\n background: tokens.border,\n ...(isVertical\n ? { width: tokens.borderWidth, alignSelf: \"stretch\" }\n : { height: tokens.borderWidth, width: \"100%\" }),\n ...style,\n }}\n {...rest}\n />\n );\n}\n","/**\n * Typography components bound to the type scale and the sans/heading font\n * slots. `Text` for body copy, `Heading` for display type (uses the heading\n * font — Erode in the NimbleBrain host, a serif fallback elsewhere).\n */\n\nimport type { CSSProperties, ElementType, HTMLAttributes, ReactNode } from \"react\";\nimport { type HeadingSize, headingStyle, type TextSize, textStyle, tokens } from \"./tokens.js\";\n\ntype Tone = \"default\" | \"muted\" | \"faint\" | \"accent\" | \"danger\" | \"success\";\ntype Weight = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\n\nconst TONE: Record<Tone, string> = {\n default: tokens.fg,\n muted: tokens.fgMuted,\n faint: tokens.fgFaint,\n accent: tokens.accent,\n danger: tokens.danger,\n success: tokens.success,\n};\n\nconst WEIGHT: Record<Weight, string> = {\n normal: tokens.weightNormal,\n medium: tokens.weightMedium,\n semibold: tokens.weightSemibold,\n bold: tokens.weightBold,\n};\n\ninterface TextProps extends Omit<HTMLAttributes<HTMLElement>, \"color\"> {\n size?: TextSize;\n weight?: Weight;\n tone?: Tone;\n mono?: boolean;\n /** Single-line ellipsis truncation. */\n truncate?: boolean;\n as?: ElementType;\n children?: ReactNode;\n}\n\n/** Body text. Defaults to base size, normal weight, primary tone, sans font. */\nexport function Text({\n size = \"base\",\n weight = \"normal\",\n tone = \"default\",\n mono = false,\n truncate = false,\n as: As = \"span\",\n style,\n children,\n ...rest\n}: TextProps) {\n const truncation: CSSProperties = truncate\n ? { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }\n : {};\n return (\n <As\n style={{\n margin: 0,\n fontFamily: mono ? tokens.fontMono : tokens.fontSans,\n fontWeight: WEIGHT[weight],\n color: TONE[tone],\n ...textStyle(size),\n ...truncation,\n ...style,\n }}\n {...rest}\n >\n {children}\n </As>\n );\n}\n\ninterface HeadingProps extends Omit<HTMLAttributes<HTMLHeadingElement>, \"color\"> {\n size?: HeadingSize;\n weight?: Weight;\n tone?: Tone;\n as?: ElementType;\n children?: ReactNode;\n}\n\n/** Display heading using the heading font slot. Defaults to md, semibold. */\nexport function Heading({\n size = \"md\",\n weight = \"semibold\",\n tone = \"default\",\n as: As = \"h2\",\n style,\n children,\n ...rest\n}: HeadingProps) {\n return (\n <As\n style={{\n margin: 0,\n fontFamily: tokens.fontHeading,\n fontWeight: WEIGHT[weight],\n color: TONE[tone],\n letterSpacing: \"-0.015em\",\n ...headingStyle(size),\n ...style,\n }}\n {...rest}\n >\n {children}\n </As>\n );\n}\n","/**\n * EmptyState — centered placeholder for empty lists/views. Optional icon,\n * title, description, and an action slot (e.g. a Button).\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Stack } from \"../primitives.js\";\nimport { tokens } from \"../tokens.js\";\nimport { Heading, Text } from \"../typography.js\";\n\ninterface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n icon?: ReactNode;\n title?: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n}\n\nexport function EmptyState({ icon, title, description, action, style, ...rest }: EmptyStateProps) {\n return (\n <Stack\n align=\"center\"\n gap=\"0.5rem\"\n style={{\n textAlign: \"center\",\n padding: \"4rem 1.5rem\",\n color: tokens.fgMuted,\n ...style,\n }}\n {...rest}\n >\n {icon ? <div style={{ color: tokens.fgFaint, marginBottom: \"0.25rem\" }}>{icon}</div> : null}\n {title ? <Heading size=\"sm\">{title}</Heading> : null}\n {description ? (\n <Text size=\"sm\" tone=\"muted\" style={{ maxWidth: 360 }}>\n {description}\n </Text>\n ) : null}\n {action ? <div style={{ marginTop: \"0.75rem\" }}>{action}</div> : null}\n </Stack>\n );\n}\n","/**\n * ListRow — the recurring list item: an optional leading slot (status dot,\n * avatar), a title with optional meta line, and a trailing slot (timestamp,\n * actions). Rounded hover tint, flat at rest — the pattern Research,\n * Conversations, and the Collateral sidebar each re-rolled.\n */\n\nimport type { HTMLAttributes, KeyboardEvent, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-listrow\";\nconst RULES = `\n.nb-listrow { transition: background 140ms ease; }\n.nb-listrow--interactive { cursor: pointer; }\n.nb-listrow--interactive:hover { background: var(--nb-listrow-hover); }\n`;\n\ninterface ListRowProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n title: ReactNode;\n /** Secondary line under the title. */\n meta?: ReactNode;\n /** Leading slot — e.g. a StatusDot or Avatar. */\n leading?: ReactNode;\n /** Trailing slot — e.g. a timestamp or actions. */\n trailing?: ReactNode;\n /** Enables pointer cursor + hover tint. */\n interactive?: boolean;\n}\n\nexport function ListRow({\n title,\n meta,\n leading,\n trailing,\n interactive = false,\n style,\n className,\n ...rest\n}: ListRowProps) {\n ensureStyle(STYLE_ID, RULES);\n const rowStyle: StyleWithVars = {\n \"--nb-listrow-hover\": tokens.bgSubtle,\n display: \"grid\",\n gridTemplateColumns: `${leading ? \"auto \" : \"\"}minmax(0, 1fr)${trailing ? \" auto\" : \"\"}`,\n columnGap: \"0.75rem\",\n alignItems: \"baseline\",\n padding: \"0.65rem 0.75rem\",\n borderRadius: tokens.radiusSm,\n ...style,\n };\n // When interactive, make the row keyboard-operable (matches Table's rows):\n // role=\"button\" + tabIndex, and Enter/Space synthesize the click that drives\n // the consumer's onClick (passed via ...rest). Placed before ...rest so a\n // consumer can still override any of these explicitly.\n const interactiveProps = interactive\n ? {\n role: \"button\",\n tabIndex: 0,\n onKeyDown: (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.currentTarget.click();\n }\n },\n }\n : {};\n return (\n <div\n className={`nb-listrow ${interactive ? \"nb-listrow--interactive\" : \"\"} ${className ?? \"\"}`.trim()}\n style={rowStyle}\n {...interactiveProps}\n {...rest}\n >\n {leading ? <div style={{ alignSelf: \"center\", display: \"flex\" }}>{leading}</div> : null}\n <div style={{ minWidth: 0 }}>\n <div\n style={{\n fontFamily: tokens.fontSans,\n fontSize: tokens.textBaseSize,\n lineHeight: tokens.textBaseLine,\n fontWeight: tokens.weightMedium,\n color: tokens.fg,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {title}\n </div>\n {meta ? (\n <div\n style={{\n marginTop: \"0.15rem\",\n fontFamily: tokens.fontSans,\n fontSize: tokens.textXsSize,\n lineHeight: tokens.textXsLine,\n color: tokens.fgMuted,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {meta}\n </div>\n ) : null}\n </div>\n {trailing ? (\n <div\n style={{\n alignSelf: \"center\",\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"0.5rem\",\n fontSize: tokens.textXsSize,\n color: tokens.fgMuted,\n whiteSpace: \"nowrap\",\n }}\n >\n {trailing}\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * Pagination — chrome-less prev/next text links with a \"page X of Y\" counter.\n * 1-based `page`. Buttons disable at the ends.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { Inline } from \"../primitives.js\";\nimport { tokens } from \"../tokens.js\";\nimport { TextLink } from \"./Button.js\";\n\ninterface PaginationProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** Current page, 1-based. */\n page: number;\n /** Total number of pages. */\n pageCount: number;\n onChange: (page: number) => void;\n}\n\nexport function Pagination({ page, pageCount, onChange, style, ...rest }: PaginationProps) {\n const total = Math.max(1, pageCount);\n const atStart = page <= 1;\n const atEnd = page >= total;\n return (\n <Inline\n justify=\"between\"\n style={{\n fontFamily: tokens.fontSans,\n fontSize: tokens.textXsSize,\n color: tokens.fgMuted,\n letterSpacing: \"0.02em\",\n ...style,\n }}\n {...rest}\n >\n <span style={{ fontVariantNumeric: \"tabular-nums\" }}>\n Page {page} of {total}\n </span>\n <Inline gap=\"1rem\">\n <TextLink disabled={atStart} onClick={() => onChange(page - 1)}>\n ← Prev\n </TextLink>\n <TextLink disabled={atEnd} onClick={() => onChange(page + 1)}>\n Next →\n </TextLink>\n </Inline>\n </Inline>\n );\n}\n","/**\n * Prose — a token-styled container for rendered rich text. It applies the\n * NimbleBrain reading typography (ported from the Research app's markdown\n * element map) to whatever HTML it wraps, via a once-injected scoped\n * stylesheet — so it stays dependency-free.\n *\n * Pass pre-rendered nodes as `children`, or a trusted HTML string as `html`.\n * Bring your own markdown parser (`marked`, `react-markdown`, …) upstream; this\n * owns the *styling*, not the parsing — keeping the SDK free of a parser dep.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-prose\";\nconst RULES = `\n.nb-prose {\n font-family: ${tokens.fontSans};\n font-size: ${tokens.textBaseSize};\n line-height: 1.7;\n color: ${tokens.fg};\n}\n.nb-prose > :first-child { margin-top: 0; }\n.nb-prose > :last-child { margin-bottom: 0; }\n.nb-prose h1, .nb-prose h2 { font-family: ${tokens.fontHeading}; letter-spacing: -0.015em; color: ${tokens.fg}; }\n.nb-prose h1 { font-size: ${tokens.headingMdSize}; line-height: ${tokens.headingMdLine}; margin: 2rem 0 0.75rem; }\n.nb-prose h2 { font-size: ${tokens.headingSmSize}; line-height: ${tokens.headingSmLine}; margin: 1.75rem 0 0.5rem; }\n.nb-prose h3 { font-size: ${tokens.textBaseSize}; font-weight: ${tokens.weightSemibold}; margin: 1.5rem 0 0.35rem; color: ${tokens.fg}; }\n.nb-prose p { margin: 0 0 1rem; }\n.nb-prose ul, .nb-prose ol { margin: 0 0 1rem; padding-left: 1.25rem; }\n.nb-prose li { margin: 0.25rem 0; }\n.nb-prose a { color: ${tokens.accent}; text-decoration: underline; text-underline-offset: 2px; }\n.nb-prose blockquote { margin: 0 0 1rem; padding-left: 1rem; border-left: 2px solid ${tokens.accent}; color: ${tokens.fgMuted}; font-style: italic; }\n.nb-prose code { font-family: ${tokens.fontMono}; font-size: 0.88em; padding: 0.08rem 0.32rem; border-radius: ${tokens.radiusXs}; background: ${tokens.bgSubtle}; }\n.nb-prose pre { font-family: ${tokens.fontMono}; font-size: ${tokens.textSmSize}; line-height: 1.55; margin: 0 0 1.25rem; padding: 0.875rem 1rem; background: ${tokens.bgSubtle}; border-radius: ${tokens.radiusSm}; overflow-x: auto; }\n.nb-prose pre code { padding: 0; background: none; }\n.nb-prose hr { border: none; border-top: 1px solid ${tokens.border}; margin: 2rem 0; }\n.nb-prose strong { font-weight: ${tokens.weightSemibold}; }\n`;\n\ninterface ProseProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"dangerouslySetInnerHTML\"> {\n /** Trusted, pre-sanitized HTML string. */\n html?: string;\n children?: ReactNode;\n}\n\nexport function Prose({ html, children, className, ...rest }: ProseProps) {\n ensureStyle(STYLE_ID, RULES);\n const cls = `nb-prose ${className ?? \"\"}`.trim();\n if (html !== undefined) {\n // biome-ignore lint/security/noDangerouslySetInnerHtml: caller supplies trusted, pre-sanitized HTML by contract.\n return <div className={cls} dangerouslySetInnerHTML={{ __html: html }} {...rest} />;\n }\n return (\n <div className={cls} {...rest}>\n {children}\n </div>\n );\n}\n","/**\n * SearchField — a text input in two postures: `underline` (invisible at rest,\n * reveals an underline on focus — the Research editorial style) and `boxed`\n * (a bordered field). Focus styling lives in a once-injected stylesheet.\n */\n\nimport type { InputHTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-searchfield\";\nconst RULES = `\n.nb-search { font-family: var(--nb-search-font); color: var(--nb-search-fg); outline: none; }\n.nb-search::placeholder { color: var(--nb-search-placeholder); }\n.nb-search--underline {\n border: none;\n border-bottom: 1px solid transparent;\n background: transparent;\n padding: 0.3rem 0.1rem;\n transition: border-color 160ms ease;\n}\n.nb-search--underline:focus { border-bottom-color: var(--nb-search-accent); }\n.nb-search--boxed {\n border: 1px solid var(--nb-search-border);\n border-radius: var(--nb-search-radius);\n background: var(--nb-search-bg);\n padding: 0.4rem 0.6rem;\n transition: border-color 160ms ease, box-shadow 160ms ease;\n}\n.nb-search--boxed:focus {\n border-color: var(--nb-search-accent);\n box-shadow: 0 0 0 3px color-mix(in oklab, var(--nb-search-accent) 18%, transparent);\n}\n`;\n\ninterface SearchFieldProps extends InputHTMLAttributes<HTMLInputElement> {\n variant?: \"underline\" | \"boxed\";\n}\n\nexport function SearchField({\n variant = \"underline\",\n style,\n className,\n type = \"search\",\n ...rest\n}: SearchFieldProps) {\n ensureStyle(STYLE_ID, RULES);\n const fieldStyle: StyleWithVars = {\n \"--nb-search-font\": tokens.fontSans,\n \"--nb-search-fg\": tokens.fg,\n \"--nb-search-placeholder\": tokens.fgFaint,\n \"--nb-search-accent\": tokens.accent,\n \"--nb-search-border\": tokens.border,\n \"--nb-search-bg\": tokens.bgSubtle,\n \"--nb-search-radius\": tokens.radiusSm,\n fontSize: tokens.textSmSize,\n lineHeight: tokens.textSmLine,\n ...style,\n };\n return (\n <input\n type={type}\n className={`nb-search nb-search--${variant} ${className ?? \"\"}`.trim()}\n style={fieldStyle}\n {...rest}\n />\n );\n}\n","/**\n * SegmentedControl — the view-toggle pattern (Board/Table, All/Today/Week).\n * A small set of mutually-exclusive options; the active one gets a raised pill.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-segmented\";\nconst RULES = `\n.nb-seg {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n border-radius: var(--nb-seg-radius);\n background: var(--nb-seg-track);\n}\n.nb-seg__btn {\n border: none;\n background: transparent;\n color: var(--nb-seg-fg);\n font-family: var(--nb-seg-font);\n font-weight: var(--nb-seg-weight);\n padding: 0.25rem 0.7rem;\n border-radius: calc(var(--nb-seg-radius) - 2px);\n cursor: pointer;\n transition: color 130ms ease, background 130ms ease;\n white-space: nowrap;\n}\n.nb-seg__btn:hover:not([aria-pressed=\"true\"]) { color: var(--nb-seg-fg-strong); }\n.nb-seg__btn[aria-pressed=\"true\"] {\n background: var(--nb-seg-active-bg);\n color: var(--nb-seg-fg-strong);\n box-shadow: var(--nb-seg-active-shadow);\n}\n`;\n\ninterface Option<T extends string> {\n label: string;\n value: T;\n}\n\ninterface SegmentedControlProps<T extends string>\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n options: Option<T>[];\n value: T;\n onChange: (value: T) => void;\n}\n\nexport function SegmentedControl<T extends string>({\n options,\n value,\n onChange,\n style,\n className,\n ...rest\n}: SegmentedControlProps<T>) {\n ensureStyle(STYLE_ID, RULES);\n const trackStyle: StyleWithVars = {\n \"--nb-seg-radius\": tokens.radiusSm,\n \"--nb-seg-track\": tokens.bgSubtle,\n \"--nb-seg-fg\": tokens.fgMuted,\n \"--nb-seg-fg-strong\": tokens.fg,\n \"--nb-seg-font\": tokens.fontSans,\n \"--nb-seg-weight\": tokens.weightMedium,\n \"--nb-seg-active-bg\": tokens.bgRaised,\n \"--nb-seg-active-shadow\": tokens.shadowSm,\n fontSize: tokens.textSmSize,\n lineHeight: tokens.textSmLine,\n ...style,\n };\n return (\n // biome-ignore lint/a11y/useSemanticElements: role=\"group\" with aria-label is the correct grouping for a set of toggle buttons; <fieldset> would impose form semantics this control doesn't have.\n <div className={`nb-seg ${className ?? \"\"}`.trim()} role=\"group\" style={trackStyle} {...rest}>\n {options.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n className=\"nb-seg__btn\"\n aria-pressed={opt.value === value}\n onClick={() => onChange(opt.value)}\n >\n {opt.label}\n </button>\n ))}\n </div>\n );\n}\n","/**\n * Spinner — a minimal rotating indicator for inline/button loading states.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-spinner\";\nconst RULES = `\n@keyframes nb-spin { to { transform: rotate(360deg); } }\n.nb-spinner { animation: nb-spin 0.7s linear infinite; }\n@media (prefers-reduced-motion: reduce) { .nb-spinner { animation-duration: 1.6s; } }\n`;\n\ninterface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {\n /** Diameter in px. Default 16. */\n size?: number;\n /** Arc color. Defaults to the accent token. */\n color?: string;\n}\n\nexport function Spinner({ size = 16, color, style, className, ...rest }: SpinnerProps) {\n ensureStyle(STYLE_ID, RULES);\n const spinnerStyle: StyleWithVars = {\n display: \"inline-block\",\n flexShrink: 0,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${tokens.border}`,\n borderTopColor: color ?? tokens.accent,\n boxSizing: \"border-box\",\n ...style,\n };\n return (\n <span\n className={`nb-spinner ${className ?? \"\"}`.trim()}\n role=\"status\"\n aria-label=\"Loading\"\n style={spinnerStyle}\n {...rest}\n />\n );\n}\n","/**\n * StatusDot — a small colored dot for run/task status. The `working` state\n * gets a living ripple-pulse (ported from the Research app), gated on\n * `prefers-reduced-motion`. Same component in list rows and detail headers so\n * status reads identically everywhere.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nexport type Status = \"working\" | \"completed\" | \"failed\" | \"idle\";\n\nconst COLOR: Record<Status, string> = {\n working: tokens.accent,\n completed: tokens.success,\n failed: tokens.danger,\n idle: tokens.fgFaint,\n};\n\nconst STYLE_ID = \"nb-synapse-statusdot\";\nconst KEYFRAMES = `\n@keyframes nb-statusdot-pulse {\n 0% { box-shadow: 0 0 0 0 var(--nb-statusdot-ring); transform: scale(1); }\n 70% { box-shadow: 0 0 0 7px transparent; transform: scale(1.15); }\n 100% { box-shadow: 0 0 0 0 transparent; transform: scale(1); }\n}\n.nb-statusdot--working {\n animation: nb-statusdot-pulse 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n .nb-statusdot--working { animation: none; box-shadow: 0 0 0 2px var(--nb-statusdot-ring); }\n}\n`;\n\ninterface StatusDotProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"color\"> {\n status?: Status;\n /** Override the dot color (any CSS color / token). */\n color?: string;\n /** Diameter in px. Default 8. */\n size?: number;\n}\n\nexport function StatusDot({\n status = \"idle\",\n color,\n size = 8,\n style,\n className,\n ...rest\n}: StatusDotProps) {\n ensureStyle(STYLE_ID, KEYFRAMES);\n const dotColor = color ?? COLOR[status];\n const working = status === \"working\";\n const dotStyle: StyleWithVars = {\n display: \"inline-block\",\n flexShrink: 0,\n width: size,\n height: size,\n borderRadius: \"50%\",\n background: dotColor,\n // Ring color for the pulse keyframe — a faded copy of the dot color.\n \"--nb-statusdot-ring\": `color-mix(in oklab, ${dotColor} 45%, transparent)`,\n ...style,\n };\n return (\n <span\n className={working ? `nb-statusdot--working ${className ?? \"\"}`.trim() : className}\n style={dotStyle}\n {...rest}\n />\n );\n}\n","/**\n * Table — a token-styled data table with declarative columns. For the tabular\n * list surfaces (CRM contacts/deals) that simple `ListRow`s don't fit. Renders\n * a real `<table>` for semantics; header is sticky; rows hover-tint and can be\n * clickable. Sorting / selection / virtualization are deliberately out of v1 —\n * compose `Pagination` for paging.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\ntype Align = \"left\" | \"right\" | \"center\";\n\nexport interface Column<T> {\n /** Stable column id. */\n key: string;\n header: ReactNode;\n /** Cell content for a row. */\n render: (row: T, index: number) => ReactNode;\n align?: Align;\n width?: number | string;\n}\n\ninterface TableProps<T> extends Omit<HTMLAttributes<HTMLTableElement>, \"children\"> {\n data: T[];\n columns: Column<T>[];\n /** Stable key per row. */\n rowKey: (row: T, index: number) => string | number;\n onRowClick?: (row: T, index: number) => void;\n /** Shown when `data` is empty. */\n empty?: ReactNode;\n}\n\nconst STYLE_ID = \"nb-synapse-table\";\nconst RULES = `\n.nb-table { width: 100%; border-collapse: collapse; font-family: var(--nb-table-font); }\n.nb-table th, .nb-table td {\n padding: 0.55rem 0.75rem;\n border-bottom: var(--nb-table-border);\n font-size: var(--nb-table-size); line-height: var(--nb-table-line);\n}\n.nb-table thead th {\n position: sticky; top: 0; z-index: 1;\n background: var(--nb-table-head-bg);\n color: var(--nb-table-muted);\n font-weight: var(--nb-table-semibold);\n font-size: var(--nb-table-xs); text-align: left;\n text-transform: uppercase; letter-spacing: 0.04em;\n}\n.nb-table tbody td { color: var(--nb-table-fg); }\n.nb-table tbody tr.nb-table__row--clickable { cursor: pointer; }\n.nb-table tbody tr.nb-table__row--clickable:hover { background: var(--nb-table-hover); }\n`;\n\nexport function Table<T>({\n data,\n columns,\n rowKey,\n onRowClick,\n empty,\n style,\n className,\n ...rest\n}: TableProps<T>) {\n ensureStyle(STYLE_ID, RULES);\n\n const vars: Record<`--${string}`, string> = {\n \"--nb-table-font\": tokens.fontSans,\n \"--nb-table-fg\": tokens.fg,\n \"--nb-table-muted\": tokens.fgMuted,\n \"--nb-table-head-bg\": tokens.bg,\n \"--nb-table-hover\": tokens.bgSubtle,\n \"--nb-table-border\": `${tokens.borderWidth} solid ${tokens.border}`,\n \"--nb-table-size\": tokens.textSmSize,\n \"--nb-table-line\": tokens.textSmLine,\n \"--nb-table-xs\": tokens.textXsSize,\n \"--nb-table-semibold\": tokens.weightSemibold,\n };\n\n if (data.length === 0 && empty !== undefined) {\n return <>{empty}</>;\n }\n\n const tableStyle: StyleWithVars = { ...vars, ...style };\n\n return (\n <table className={`nb-table ${className ?? \"\"}`.trim()} style={tableStyle} {...rest}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th\n key={col.key}\n scope=\"col\"\n style={{ width: col.width, textAlign: col.align ?? \"left\" }}\n >\n {col.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((row, i) => {\n const clickable = Boolean(onRowClick);\n return (\n <tr\n key={rowKey(row, i)}\n className={clickable ? \"nb-table__row--clickable\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onClick={clickable ? () => onRowClick?.(row, i) : undefined}\n onKeyDown={\n clickable\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onRowClick?.(row, i);\n }\n }\n : undefined\n }\n >\n {columns.map((col) => (\n <td key={col.key} style={{ textAlign: col.align ?? \"left\" }}>\n {col.render(row, i)}\n </td>\n ))}\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n}\n","/**\n * AppFrame — the universal app chrome: a fixed header, a scrollable body, and\n * an optional fixed footer, filling the iframe pane. Every Synapse app uses it;\n * a body layout (SidebarLayout, ListView, …) goes inside `AppFrame.Body`.\n *\n * The `contentWidth` knob is a personality lever: `reading` centers header,\n * body, and footer in a ~760px column (Conversations, Research), while `full`\n * uses the whole pane (CRM, dashboards). Header/body/footer share the same\n * column so the composition reads as one page.\n */\n\nimport {\n type CSSProperties,\n createContext,\n type HTMLAttributes,\n type ReactNode,\n useContext,\n} from \"react\";\nimport { tokens } from \"../tokens.js\";\n\ntype ContentWidth = \"reading\" | \"full\";\nconst READING_MAX = 760;\nconst ContentWidthCtx = createContext<ContentWidth>(\"full\");\n\nfunction columnStyle(width: ContentWidth): CSSProperties {\n return width === \"reading\" ? { maxWidth: READING_MAX, marginInline: \"auto\", width: \"100%\" } : {};\n}\n\ninterface AppFrameProps extends HTMLAttributes<HTMLDivElement> {\n contentWidth?: ContentWidth;\n children?: ReactNode;\n}\n\nfunction AppFrameRoot({ contentWidth = \"full\", style, children, ...rest }: AppFrameProps) {\n return (\n <ContentWidthCtx.Provider value={contentWidth}>\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n minHeight: 0,\n background: tokens.bg,\n color: tokens.fg,\n fontFamily: tokens.fontSans,\n ...style,\n }}\n {...rest}\n >\n {children}\n </div>\n </ContentWidthCtx.Provider>\n );\n}\n\nfunction Header({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n const width = useContext(ContentWidthCtx);\n return (\n <header style={{ flexShrink: 0, padding: \"1.25rem 1.5rem 0.75rem\", ...style }} {...rest}>\n <div style={columnStyle(width)}>{children}</div>\n </header>\n );\n}\n\ninterface BodyProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Host a full-bleed body layout (SidebarLayout, BoardLayout) edge-to-edge:\n * no padding, no reading column, and the body itself doesn't scroll — the\n * layout's panes manage their own scroll. Leave off for plain content\n * (lists, forms), which get the padded reading/full column.\n */\n bleed?: boolean;\n}\n\nfunction Body({ bleed = false, style, children, ...rest }: BodyProps) {\n const width = useContext(ContentWidthCtx);\n if (bleed) {\n return (\n <div\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n ...style,\n }}\n {...rest}\n >\n {children}\n </div>\n );\n }\n return (\n <div style={{ flex: 1, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n <div style={{ ...columnStyle(width), padding: \"0.75rem 1.5rem 1.5rem\" }}>{children}</div>\n </div>\n );\n}\n\nfunction Footer({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n const width = useContext(ContentWidthCtx);\n return (\n <footer\n style={{\n flexShrink: 0,\n padding: \"0.75rem 1.5rem\",\n borderTop: `${tokens.borderWidth} solid ${tokens.border}`,\n ...style,\n }}\n {...rest}\n >\n <div style={columnStyle(width)}>{children}</div>\n </footer>\n );\n}\n\n/** `AppFrame` with `.Header`, `.Body`, `.Footer` slots. */\nexport const AppFrame = Object.assign(AppFrameRoot, { Header, Body, Footer });\n","/**\n * `useBreakpoint` — responsive hook keyed to an element's OWN width, not the\n * device viewport. Synapse apps render in an iframe pane whose width the host\n * controls (fullscreen, split, or a narrow sidebar), so layouts must react to\n * the space they're actually given.\n *\n * Attach the returned `ref` to the element whose width drives the decision.\n * Width is measured synchronously on mount (no first-frame flash) and kept live\n * via `ResizeObserver`. SSR/test-safe: without a DOM/`ResizeObserver` it simply\n * reports `isNarrow: false`.\n */\n\nimport { type RefObject, useLayoutEffect, useRef, useState } from \"react\";\n\nexport function useBreakpoint<T extends HTMLElement = HTMLDivElement>(\n breakpoint: number,\n): { ref: RefObject<T | null>; isNarrow: boolean } {\n const ref = useRef<T>(null);\n const [width, setWidth] = useState<number | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n // Synchronous initial measure — runs before paint, so the first painted\n // frame already reflects the real width. Border-box, matching the observer\n // below (so there's no jump on the first resize if the element has padding).\n setWidth(el.getBoundingClientRect().width);\n if (typeof ResizeObserver === \"undefined\") return;\n const ro = new ResizeObserver((entries) => {\n const entry = entries[0];\n const w = entry?.borderBoxSize?.[0]?.inlineSize ?? entry?.contentRect.width;\n if (typeof w === \"number\") setWidth(w);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n return { ref, isNarrow: width !== null && width < breakpoint };\n}\n","/**\n * ListDetailLayout — a master list beside a detail pane (CRM contacts → record,\n * Research runs → report, conversations → thread). Responsive to the layout's\n * own width: side-by-side when wide; below `breakpoint` it shows one at a time —\n * the list, or the detail when something is `selected`, with a `Back`\n * affordance to return.\n *\n * `selected` is driven by the app's own selection state. Place\n * `<ListDetailLayout.Back />` at the top of `Detail`; it renders only on a\n * narrow pane and calls `onBack`.\n */\n\nimport { createContext, type HTMLAttributes, type ReactNode, useContext } from \"react\";\nimport { TextLink } from \"../components/Button.js\";\nimport { tokens } from \"../tokens.js\";\nimport { useBreakpoint } from \"./use-container-width.js\";\n\ninterface ListDetailState {\n collapsed: boolean;\n selected: boolean;\n listWidth: number | string;\n onBack?: () => void;\n}\n\nconst ListDetailCtx = createContext<ListDetailState | null>(null);\n\n/** Read the list/detail responsive state — for custom back affordances. */\nexport function useListDetail(): ListDetailState {\n const ctx = useContext(ListDetailCtx);\n if (!ctx) throw new Error(\"useListDetail must be used within <ListDetailLayout>\");\n return ctx;\n}\n\ninterface ListDetailLayoutProps extends HTMLAttributes<HTMLDivElement> {\n /** Is a detail open? Drives which pane shows on a narrow layout. */\n selected?: boolean;\n /** Called by `Back` (and custom triggers) to return to the list when narrow. */\n onBack?: () => void;\n /** Master list width when side-by-side. Default 320. */\n listWidth?: number | string;\n /** Collapse to one-at-a-time below this layout width (px). Default 720. */\n breakpoint?: number;\n children?: ReactNode;\n}\n\nfunction ListDetailLayoutRoot({\n selected = false,\n onBack,\n listWidth = 320,\n breakpoint = 720,\n style,\n children,\n ...rest\n}: ListDetailLayoutProps) {\n const { ref, isNarrow } = useBreakpoint<HTMLDivElement>(breakpoint);\n return (\n <ListDetailCtx.Provider value={{ collapsed: isNarrow, selected, listWidth, onBack }}>\n <div\n ref={ref}\n style={{ display: \"flex\", flexDirection: \"row\", height: \"100%\", minHeight: 0, ...style }}\n {...rest}\n >\n {children}\n </div>\n </ListDetailCtx.Provider>\n );\n}\n\nfunction List({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n const { collapsed, selected, listWidth } = useListDetail();\n if (collapsed && selected) return null; // detail has the stage\n const border = `${tokens.borderWidth} solid ${tokens.border}`;\n return (\n <section\n style={{\n overflowY: \"auto\",\n ...(collapsed\n ? { flex: 1, minWidth: 0 }\n : { width: listWidth, flexShrink: 0, borderRight: border }),\n ...style,\n }}\n {...rest}\n >\n {children}\n </section>\n );\n}\n\nfunction Detail({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n const { collapsed, selected } = useListDetail();\n if (collapsed && !selected) return null; // list has the stage\n return (\n <div style={{ flex: 1, minWidth: 0, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n {children}\n </div>\n );\n}\n\ninterface BackProps {\n children?: ReactNode;\n style?: React.CSSProperties;\n}\n\n/** \"← Back\" affordance — renders only on a narrow pane with a detail open. */\nfunction Back({ children, style }: BackProps) {\n const { collapsed, selected, onBack } = useListDetail();\n if (!collapsed || !selected) return null;\n return (\n <TextLink onClick={() => onBack?.()} style={{ marginBottom: \"0.5rem\", ...style }}>\n {children ?? \"← Back\"}\n </TextLink>\n );\n}\n\n/** `ListDetailLayout` with `.List`, `.Detail`, and `.Back` slots. */\nexport const ListDetailLayout = Object.assign(ListDetailLayoutRoot, { List, Detail, Back });\n","/**\n * SidebarLayout — the responsive two-column layout for inside an app pane: a\n * nav/list rail plus main content. It reacts to the layout's OWN width (not the\n * device), and below `breakpoint` collapses one of two ways:\n *\n * - `reflow` (default) — the rail moves to a horizontal strip on top and the\n * content goes full-width. Best for short navs (a settings page's sections).\n * - `drawer` — the rail becomes an off-canvas overlay opened by a `Trigger`.\n * Best for long lists (a document browser) where reflowing would be absurd.\n *\n * Place nav items as flat children of `Sidebar`; it controls direction\n * (column when expanded, row when reflowed). For `drawer`, place a\n * `<SidebarLayout.Trigger />` *inside* the layout (e.g. a toolbar in `Main`) —\n * in v1 the open-state context lives on `SidebarLayout`, so the trigger must be\n * within it, NOT in a sibling `AppFrame.Header`. Or read state via `useSidebar()`.\n * (Header placement would need a hoisted provider — a deliberate later refinement.)\n */\n\nimport {\n type ButtonHTMLAttributes,\n type CSSProperties,\n createContext,\n type HTMLAttributes,\n type ReactNode,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\nimport { useBreakpoint } from \"./use-container-width.js\";\n\ntype CollapseMode = \"reflow\" | \"drawer\";\ntype Side = \"left\" | \"right\";\n\ninterface SidebarState {\n collapsed: boolean;\n mode: CollapseMode;\n side: Side;\n width: number | string;\n open: boolean;\n setOpen: (open: boolean) => void;\n}\n\nconst SidebarCtx = createContext<SidebarState | null>(null);\n\n/** Read the sidebar's responsive state — for custom triggers or nav re-orientation. */\nexport function useSidebar(): SidebarState {\n const ctx = useContext(SidebarCtx);\n if (!ctx) throw new Error(\"useSidebar must be used within <SidebarLayout>\");\n return ctx;\n}\n\nconst STYLE_ID = \"nb-synapse-sidebarlayout\";\n// Distinct class names from the Drawer component (which owns `.nb-drawer`).\nconst RULES = `\n.nb-sidebar-drawer { transition: transform 220ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-sidebar-scrim { animation: nb-sidebar-fade 180ms ease; }\n@keyframes nb-sidebar-fade { from { opacity: 0; } to { opacity: 1; } }\n@media (prefers-reduced-motion: reduce) {\n .nb-sidebar-drawer { transition: none; }\n .nb-sidebar-scrim { animation: none; }\n}\n`;\n\ninterface SidebarLayoutProps extends HTMLAttributes<HTMLDivElement> {\n side?: Side;\n /** Expanded rail / drawer width. Default 240. */\n width?: number | string;\n /** Collapse below this pane width (px). Default 640. */\n breakpoint?: number;\n collapseMode?: CollapseMode;\n children?: ReactNode;\n}\n\nfunction SidebarLayoutRoot({\n side = \"left\",\n width = 240,\n breakpoint = 640,\n collapseMode = \"reflow\",\n style,\n children,\n ...rest\n}: SidebarLayoutProps) {\n const { ref, isNarrow } = useBreakpoint<HTMLDivElement>(breakpoint);\n const [open, setOpen] = useState(false);\n\n // Close the drawer on Escape.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [open]);\n\n // Collapsing back to expanded should drop any open drawer state.\n useEffect(() => {\n if (!isNarrow && open) setOpen(false);\n }, [isNarrow, open]);\n\n const reflowed = isNarrow && collapseMode === \"reflow\";\n const rootStyle: CSSProperties = {\n position: \"relative\",\n display: \"flex\",\n flexDirection: reflowed ? \"column\" : side === \"right\" ? \"row-reverse\" : \"row\",\n height: \"100%\",\n minHeight: 0,\n ...style,\n };\n\n return (\n <SidebarCtx.Provider\n value={{ collapsed: isNarrow, mode: collapseMode, side, width, open, setOpen }}\n >\n <div ref={ref} style={rootStyle} {...rest}>\n {children}\n </div>\n </SidebarCtx.Provider>\n );\n}\n\nfunction Sidebar({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n const { collapsed, mode, side, width, open, setOpen } = useSidebar();\n ensureStyle(STYLE_ID, RULES);\n\n // Expanded: a fixed-width rail beside the content.\n if (!collapsed) {\n const border = `${tokens.borderWidth} solid ${tokens.border}`;\n return (\n <aside\n style={{\n width,\n flexShrink: 0,\n overflowY: \"auto\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"0.125rem\",\n padding: \"0.5rem 0.5rem\",\n ...(side === \"right\" ? { borderLeft: border } : { borderRight: border }),\n ...style,\n }}\n {...rest}\n >\n {children}\n </aside>\n );\n }\n\n // Reflowed: a horizontal strip on top, content below.\n if (mode === \"reflow\") {\n return (\n <aside\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: \"0.25rem\",\n width: \"100%\",\n overflowX: \"auto\",\n padding: \"0.5rem 0.75rem\",\n borderBottom: `${tokens.borderWidth} solid ${tokens.border}`,\n ...style,\n }}\n {...rest}\n >\n {children}\n </aside>\n );\n }\n\n // Drawer: off-canvas overlay + scrim.\n const closed = side === \"right\" ? \"translateX(100%)\" : \"translateX(-100%)\";\n const drawerStyle: StyleWithVars = {\n position: \"absolute\",\n top: 0,\n bottom: 0,\n [side]: 0,\n width,\n maxWidth: \"85%\",\n overflowY: \"auto\",\n background: tokens.bgRaised,\n boxShadow: tokens.shadowLg,\n transform: open ? \"translateX(0)\" : closed,\n zIndex: 11,\n ...(side === \"right\"\n ? { borderLeft: `${tokens.borderWidth} solid ${tokens.border}` }\n : { borderRight: `${tokens.borderWidth} solid ${tokens.border}` }),\n ...style,\n };\n return (\n <>\n {open ? (\n <button\n type=\"button\"\n aria-label=\"Close sidebar\"\n className=\"nb-sidebar-scrim\"\n onClick={() => setOpen(false)}\n style={{\n position: \"absolute\",\n inset: 0,\n border: \"none\",\n padding: 0,\n cursor: \"pointer\",\n background: \"rgba(0,0,0,0.32)\",\n zIndex: 10,\n }}\n />\n ) : null}\n {/* `inert` when closed removes the off-canvas rail from the tab order and\n the a11y tree (vs `aria-hidden`, which leaves focusables reachable). */}\n <aside className=\"nb-sidebar-drawer\" inert={!open} style={drawerStyle} {...rest}>\n {children}\n </aside>\n </>\n );\n}\n\nfunction Main({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div style={{ flex: 1, minWidth: 0, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n {children}\n </div>\n );\n}\n\ninterface TriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** Override the default hamburger glyph. */\n children?: ReactNode;\n}\n\n/**\n * Hamburger that opens the drawer. Renders only when collapsed in `drawer`\n * mode, and only when it can see a `SidebarLayout` context — so it's safe to\n * place anywhere inside the layout subtree (it no-ops elsewhere). Note: in v1\n * the context lives on `SidebarLayout` itself, so the trigger must sit inside\n * it (e.g. a toolbar in `Main`), not in a sibling `AppFrame.Header`.\n */\nfunction Trigger({ children, style, onClick, ...rest }: TriggerProps) {\n const ctx = useContext(SidebarCtx);\n if (!ctx?.collapsed || ctx.mode !== \"drawer\") return null;\n const { open, setOpen } = ctx;\n return (\n <button\n type=\"button\"\n aria-label=\"Toggle sidebar\"\n aria-expanded={open}\n onClick={(e) => {\n setOpen(!open);\n onClick?.(e);\n }}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: 32,\n height: 32,\n border: \"none\",\n background: \"transparent\",\n color: tokens.fg,\n cursor: \"pointer\",\n borderRadius: tokens.radiusSm,\n ...style,\n }}\n {...rest}\n >\n {children ?? (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n <path\n d=\"M2 4.5h14M2 9h14M2 13.5h14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n )}\n </button>\n );\n}\n\n/** `SidebarLayout` with `.Sidebar`, `.Main`, and `.Trigger` slots. */\nexport const SidebarLayout = Object.assign(SidebarLayoutRoot, { Sidebar, Main, Trigger });\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimblebrain/synapse",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Agent-aware app SDK for the MCP ext-apps protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
"import": "./dist/react/index.js",
|
|
15
15
|
"require": "./dist/react/index.cjs"
|
|
16
16
|
},
|
|
17
|
+
"./ui": {
|
|
18
|
+
"types": "./dist/ui/index.d.ts",
|
|
19
|
+
"import": "./dist/ui/index.js",
|
|
20
|
+
"require": "./dist/ui/index.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./ui/fonts": {
|
|
23
|
+
"types": "./dist/ui/fonts.d.ts",
|
|
24
|
+
"import": "./dist/ui/fonts.js",
|
|
25
|
+
"require": "./dist/ui/fonts.cjs"
|
|
26
|
+
},
|
|
17
27
|
"./vite": {
|
|
18
28
|
"types": "./dist/vite/index.d.ts",
|
|
19
29
|
"import": "./dist/vite/index.js",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/content-parser.ts","../src/event-map.ts","../src/resize.ts","../src/result-parser.ts","../src/transport.ts","../src/connect.ts","../src/detection.ts","../src/keyboard.ts","../src/task-handle.ts","../src/core.ts"],"names":["TOOL_RESULT_METHOD","TOOL_INPUT_METHOD","TOOL_INPUT_PARTIAL_METHOD","TOOL_CANCELLED_METHOD","HOST_CONTEXT_CHANGED_METHOD","RESOURCE_TEARDOWN_METHOD","LATEST_PROTOCOL_VERSION","INITIALIZE_METHOD","INITIALIZED_METHOD","OPEN_LINK_METHOD","MESSAGE_METHOD","raw","READ_RESOURCE_METHOD","injectCssVariables","options"],"mappings":"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","file":"chunk-WYWKN3YG.cjs","sourcesContent":["import type { ToolResultData } from \"./types.js\";\n\nexport type { ToolResultData };\n\n/**\n * Parse inbound `ui/notifications/tool-result` notification params into\n * a consistent `ToolResultData` shape.\n *\n * Implements the 5-step parsing algorithm from the RFC:\n * 1. If `params.structuredContent` exists → use it as content.\n * 2. Else if `params.content` is an array of `{type:\"text\", text}` blocks →\n * join the text values and try JSON.parse.\n * 3. Else if `params.content` is a string → try JSON.parse.\n * 4. If JSON.parse fails in steps 2 or 3 → deliver the raw string.\n * 5. Return `{ content, structuredContent, raw }`.\n */\nexport function parseToolResultParams(params: Record<string, unknown> | undefined): ToolResultData {\n const raw = params ?? {};\n const structuredContent = raw.structuredContent ?? null;\n\n // Step 1: If structuredContent exists, use it as content\n if (structuredContent != null) {\n return { content: structuredContent, structuredContent, raw };\n }\n\n const rawContent = raw.content;\n\n // Step 2: If content is array of {type:\"text\", text} blocks, join texts and try JSON.parse\n if (Array.isArray(rawContent)) {\n const texts = rawContent\n .filter(\n (block: unknown) =>\n block != null &&\n typeof block === \"object\" &&\n (block as Record<string, unknown>).type === \"text\" &&\n typeof (block as Record<string, unknown>).text === \"string\",\n )\n .map((block: unknown) => (block as Record<string, unknown>).text as string);\n\n if (texts.length > 0) {\n const joined = texts.join(\"\");\n try {\n return { content: JSON.parse(joined), structuredContent: null, raw };\n } catch {\n return { content: joined, structuredContent: null, raw };\n }\n }\n\n // No text blocks — return raw content array\n return { content: rawContent, structuredContent: null, raw };\n }\n\n // Step 3: If content is string, try JSON.parse\n if (typeof rawContent === \"string\") {\n try {\n return { content: JSON.parse(rawContent), structuredContent: null, raw };\n } catch {\n return { content: rawContent, structuredContent: null, raw };\n }\n }\n\n // Fallback: return content as-is (could be null, object, etc.)\n return { content: rawContent ?? null, structuredContent: null, raw };\n}\n","import {\n HOST_CONTEXT_CHANGED_METHOD,\n RESOURCE_TEARDOWN_METHOD,\n TOOL_CANCELLED_METHOD,\n TOOL_INPUT_METHOD,\n TOOL_INPUT_PARTIAL_METHOD,\n TOOL_RESULT_METHOD,\n} from \"@modelcontextprotocol/ext-apps\";\n\n/**\n * Maps short event names used in App.on() to full MCP method names.\n * Uses canonical constants from @modelcontextprotocol/ext-apps to stay\n * in sync with the spec — if the spec changes a method name, this breaks\n * at compile time, not silently at runtime.\n */\nconst EVENT_MAP: Record<string, string> = {\n \"tool-result\": TOOL_RESULT_METHOD,\n \"tool-input\": TOOL_INPUT_METHOD,\n \"tool-input-partial\": TOOL_INPUT_PARTIAL_METHOD,\n \"tool-cancelled\": TOOL_CANCELLED_METHOD,\n \"theme-changed\": HOST_CONTEXT_CHANGED_METHOD,\n teardown: RESOURCE_TEARDOWN_METHOD,\n};\n\n/**\n * Resolve a short event name to a full MCP method name.\n * Returns the mapped method if found, otherwise passes through as-is.\n */\nexport function resolveEventMethod(name: string): string {\n return EVENT_MAP[name] ?? name;\n}\n","type SendFn = (method: string, params: Record<string, unknown>) => void;\n\ninterface Resizer {\n resize(width?: number, height?: number): void;\n measureAndSend(): void;\n destroy(): void;\n}\n\nexport function createResizer(send: SendFn, autoResize: boolean): Resizer {\n let destroyed = false;\n let observer: ResizeObserver | null = null;\n let rafId: number | null = null;\n\n function measureAndSend(): void {\n if (destroyed) return;\n const width = document.body.scrollWidth;\n const height = document.body.scrollHeight;\n send(\"ui/notifications/size-changed\", { width, height });\n }\n\n function resize(width?: number, height?: number): void {\n if (destroyed) return;\n if (width !== undefined && height !== undefined) {\n send(\"ui/notifications/size-changed\", { width, height });\n } else {\n measureAndSend();\n }\n }\n\n // Auto mode: attach ResizeObserver, debounced at 16ms via requestAnimationFrame\n if (autoResize && typeof ResizeObserver !== \"undefined\") {\n observer = new ResizeObserver(() => {\n if (destroyed) return;\n if (rafId !== null) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n rafId = null;\n measureAndSend();\n });\n });\n observer.observe(document.body);\n }\n\n function destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (rafId !== null) cancelAnimationFrame(rafId);\n observer?.disconnect();\n observer = null;\n }\n\n return { resize, measureAndSend, destroy };\n}\n","import type { ToolCallResult } from \"./types.js\";\n\n/**\n * Normalize a raw tool call response into a consistent `ToolCallResult`.\n *\n * Handles three shapes:\n * 1. MCP `CallToolResult` — has a `content` array with typed blocks.\n * 2. Raw JSON object (NimbleBrain bridge) — used as-is.\n * 3. Null / undefined — returns `{ data: null, isError: false }`.\n *\n * `_meta` on a `CallToolResult` is preserved on the parsed output as a\n * whole-object passthrough — notably `io.modelcontextprotocol/related-task`\n * (`{ taskId }`) for MCP 2025-11-25 task-augmented results, but any other\n * namespaced `_meta` keys propagate for free.\n */\nexport function parseToolResult(raw: unknown): ToolCallResult {\n if (raw == null) {\n return { data: null, isError: false };\n }\n\n if (isCallToolResult(raw)) {\n return parseCallToolResult(raw);\n }\n\n // Raw JSON object — pass through.\n return { data: raw, isError: false };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface McpTextBlock {\n type: \"text\";\n text: string;\n}\n\ninterface McpCallToolResult {\n content: unknown[];\n isError?: boolean;\n _meta?: { [key: string]: unknown };\n}\n\nfunction isCallToolResult(value: unknown): value is McpCallToolResult {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n return Array.isArray((value as Record<string, unknown>).content);\n}\n\nfunction isTextBlock(block: unknown): block is McpTextBlock {\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n return false;\n }\n const obj = block as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\n/**\n * Extract `_meta` as a shallow-copied object if present and object-shaped.\n *\n * Key-preserving by design: every `_meta` entry propagates without\n * selective copying, so future spec additions flow through without code\n * changes. Returns `undefined` when the input has no meaningful `_meta`.\n */\nfunction extractMeta(result: McpCallToolResult): { [key: string]: unknown } | undefined {\n const meta = result._meta;\n if (!meta || typeof meta !== \"object\" || Array.isArray(meta)) return undefined;\n // Shallow spread so mutations on either side don't leak. Preserves the\n // full key set including `io.modelcontextprotocol/related-task`.\n return { ...meta };\n}\n\nfunction parseCallToolResult(result: McpCallToolResult): ToolCallResult {\n const isError = result.isError === true;\n const content = result.content;\n const meta = extractMeta(result);\n\n if (content.length === 0) {\n return { data: null, isError, content, ...(meta && { _meta: meta }) };\n }\n\n const firstText = content.find(isTextBlock);\n\n if (!firstText) {\n // No text blocks — return the full content array so callers can inspect it.\n return { data: content, isError, content, ...(meta && { _meta: meta }) };\n }\n\n // Try to parse JSON from the text block.\n try {\n return { data: JSON.parse(firstText.text), isError, content, ...(meta && { _meta: meta }) };\n } catch {\n // Invalid JSON — return the raw string.\n return { data: firstText.text, isError, content, ...(meta && { _meta: meta }) };\n }\n}\n","import type {\n JsonRpcMessage,\n JsonRpcNotification,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"./types.js\";\n\ntype PendingEntry = {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n};\n\ntype MessageHandler = (params: Record<string, unknown> | undefined) => void;\n\nexport class SynapseTransport {\n private counter = 0;\n private destroyed = false;\n private pending = new Map<string, PendingEntry>();\n private handlers = new Map<string, Set<MessageHandler>>();\n private listener: (event: MessageEvent) => void;\n\n constructor() {\n this.listener = (event: MessageEvent) => this.handleMessage(event);\n window.addEventListener(\"message\", this.listener);\n }\n\n send(method: string, params?: Record<string, unknown>): void {\n if (this.destroyed) return;\n\n const msg: JsonRpcNotification = {\n jsonrpc: \"2.0\",\n method,\n ...(params !== undefined && { params }),\n };\n window.parent.postMessage(msg, \"*\");\n }\n\n request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n if (this.destroyed) {\n return Promise.reject(new Error(\"Transport destroyed\"));\n }\n\n const id = `syn-${++this.counter}`;\n const msg: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n method,\n id,\n ...(params !== undefined && { params }),\n };\n\n return new Promise<unknown>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n window.parent.postMessage(msg, \"*\");\n });\n }\n\n onMessage(method: string, callback: MessageHandler): () => void {\n if (!this.handlers.has(method)) {\n this.handlers.set(method, new Set());\n }\n this.handlers.get(method)?.add(callback);\n\n return () => {\n const set = this.handlers.get(method);\n if (set) {\n set.delete(callback);\n if (set.size === 0) {\n this.handlers.delete(method);\n }\n }\n };\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n window.removeEventListener(\"message\", this.listener);\n\n const error = new Error(\"Transport destroyed\");\n for (const entry of this.pending.values()) {\n entry.reject(error);\n }\n this.pending.clear();\n this.handlers.clear();\n }\n\n private handleMessage(event: MessageEvent): void {\n if (this.destroyed) return;\n\n const data = event.data as JsonRpcMessage;\n if (!data || data.jsonrpc !== \"2.0\") return;\n\n // Response to a pending request\n if (\"id\" in data && data.id && !(\"method\" in data)) {\n const response = data as JsonRpcResponse;\n const entry = this.pending.get(response.id);\n if (!entry) return;\n this.pending.delete(response.id);\n\n if (response.error) {\n const err = new Error(response.error.message);\n (err as any).code = response.error.code;\n (err as any).data = response.error.data;\n entry.reject(err);\n } else {\n entry.resolve(response.result);\n }\n return;\n }\n\n // Incoming notification\n if (\"method\" in data && !(\"id\" in data && data.id)) {\n const notification = data as JsonRpcNotification;\n const set = this.handlers.get(notification.method);\n if (set) {\n for (const handler of set) {\n handler(notification.params);\n }\n }\n }\n }\n}\n","import type {\n McpUiHostContext,\n McpUiHostContextChangedNotification,\n McpUiInitializeRequest,\n McpUiInitializeResult,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps\";\nimport {\n HOST_CONTEXT_CHANGED_METHOD,\n INITIALIZE_METHOD,\n INITIALIZED_METHOD,\n LATEST_PROTOCOL_VERSION,\n MESSAGE_METHOD,\n OPEN_LINK_METHOD,\n TOOL_RESULT_METHOD,\n} from \"@modelcontextprotocol/ext-apps\";\nimport type {\n CallToolRequest,\n ReadResourceRequest,\n ReadResourceResult,\n TextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { parseToolResultParams } from \"./content-parser.js\";\nimport { resolveEventMethod } from \"./event-map.js\";\nimport { createResizer } from \"./resize.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { SynapseTransport } from \"./transport.js\";\nimport type { App, ConnectOptions, Dimensions, Theme, ToolCallResult } from \"./types.js\";\n\n// Derived locally because `@modelcontextprotocol/ext-apps` only exports\n// METHOD constants for ext-apps specific ui/* methods. Typing the literal\n// with the spec's request `method` field still produces a compile error if\n// upstream renames it.\nconst READ_RESOURCE_METHOD: ReadResourceRequest[\"method\"] = \"resources/read\";\n\n/**\n * Connect to a MCP Apps host.\n *\n * Owns the full ext-apps handshake, content parsing, resize management,\n * and event routing. Returns a ready-to-use `App` object.\n */\nexport async function connect(options: ConnectOptions): Promise<App> {\n const { name, version, autoResize = false } = options;\n\n const transport = new SynapseTransport();\n let destroyed = false;\n\n // --- Mutable state ---\n let currentTheme: Theme = { mode: \"light\", tokens: {} };\n let hostInfo: { name: string; version: string } = { name: \"unknown\", version: \"unknown\" };\n let toolInfo: { tool: Record<string, unknown> } | null = null;\n let containerDimensions: Dimensions | null = null;\n\n // --- Event handlers ---\n const handlers = new Map<string, Set<(params: unknown) => void>>();\n\n // --- Step 1: Set up message listener (handled by SynapseTransport constructor) ---\n\n // --- Step 2: Send initial size ---\n const resizer = createResizer((method, params) => transport.send(method, params), autoResize);\n resizer.measureAndSend();\n\n // --- Steps 3-4: Send ui/initialize and wait for response ---\n //\n // `connect()` returns an `App` with no task-augmented call surface, so\n // we don't advertise the `tasks` capability here. Per MCP 2025-11-25,\n // requestors MUST NOT advertise capabilities they can't use — and\n // doing so confuses hosts that allocate state on the strength of the\n // advertisement. If `App` ever grows `callToolAsTask`, re-add the\n // capability here at the same time.\n const initParams: McpUiInitializeRequest[\"params\"] = {\n protocolVersion: LATEST_PROTOCOL_VERSION,\n appInfo: { name, version },\n appCapabilities: {},\n };\n\n const result = (await transport.request(\n INITIALIZE_METHOD,\n initParams as unknown as Record<string, unknown>,\n )) as McpUiInitializeResult | null;\n\n // --- Step 5: Extract theme, hostInfo, toolInfo, containerDimensions ---\n if (result) {\n hostInfo = {\n name: result.hostInfo?.name ?? \"unknown\",\n version: result.hostInfo?.version ?? \"unknown\",\n };\n\n const ctx: McpUiHostContext | undefined = result.hostContext;\n if (ctx) {\n currentTheme = {\n mode: ctx.theme === \"dark\" ? \"dark\" : \"light\",\n tokens:\n ctx.styles?.variables && typeof ctx.styles.variables === \"object\"\n ? (ctx.styles.variables as Record<string, string>)\n : {},\n };\n\n if (ctx.toolInfo && typeof ctx.toolInfo === \"object\") {\n toolInfo = { tool: (ctx.toolInfo.tool as unknown as Record<string, unknown>) ?? {} };\n }\n if (ctx.containerDimensions && typeof ctx.containerDimensions === \"object\") {\n containerDimensions = ctx.containerDimensions as Dimensions;\n }\n\n // Inject host CSS variables into the DOM\n injectCssVariables(ctx.styles?.variables as Record<string, string> | undefined);\n }\n }\n\n // --- Route incoming notifications to registered handlers ---\n\n // Special handling for host-context-changed: update internal theme state\n transport.onMessage(HOST_CONTEXT_CHANGED_METHOD, (params) => {\n if (destroyed || !params) return;\n const ctx = params as Partial<McpUiHostContextChangedNotification[\"params\"]>;\n const mode = ctx.theme === \"dark\" ? \"dark\" : \"light\";\n const variables = ctx.styles?.variables;\n const tokens =\n variables && typeof variables === \"object\"\n ? (variables as Record<string, string>)\n : currentTheme.tokens;\n currentTheme = { mode, tokens };\n injectCssVariables(tokens);\n const set = handlers.get(HOST_CONTEXT_CHANGED_METHOD);\n if (set) {\n for (const handler of set) handler(currentTheme);\n }\n });\n\n // Helper to ensure transport subscription exists for a method\n const subscribedMethods = new Set<string>([HOST_CONTEXT_CHANGED_METHOD]);\n\n function ensureTransportSub(method: string): void {\n if (subscribedMethods.has(method)) return;\n subscribedMethods.add(method);\n\n const isToolResult = method === TOOL_RESULT_METHOD;\n\n transport.onMessage(method, (params) => {\n if (destroyed) return;\n const set = handlers.get(method);\n if (!set) return;\n for (const handler of set) {\n if (isToolResult) {\n handler(parseToolResultParams(params));\n } else {\n handler(params);\n }\n }\n });\n }\n\n // --- Step 6: Pre-register handlers from options.on, then send initialized ---\n if (options.on) {\n for (const [event, handler] of Object.entries(options.on)) {\n if (typeof handler === \"function\") {\n const method = resolveEventMethod(event);\n if (!handlers.has(method)) handlers.set(method, new Set());\n handlers.get(method)?.add(handler);\n ensureTransportSub(method);\n }\n }\n }\n transport.send(INITIALIZED_METHOD, {});\n\n // --- Step 7: Build and return the App object ---\n const app: App = {\n get theme() {\n return { ...currentTheme };\n },\n get hostInfo() {\n return { ...hostInfo };\n },\n get toolInfo() {\n return toolInfo;\n },\n get containerDimensions() {\n return containerDimensions;\n },\n\n on(event: string, handler: (params: any) => void): () => void {\n const method = resolveEventMethod(event);\n\n if (!handlers.has(method)) {\n handlers.set(method, new Set());\n }\n handlers.get(method)?.add(handler);\n ensureTransportSub(method);\n\n return () => {\n const set = handlers.get(method);\n if (set) {\n set.delete(handler);\n if (set.size === 0) handlers.delete(method);\n }\n };\n },\n\n resize(width?: number, height?: number): void {\n resizer.resize(width, height);\n },\n\n openLink(url: string): void {\n if (destroyed) return;\n const params: McpUiOpenLinkRequest[\"params\"] = { url };\n // Spec: ui/open-link is a request (expects a response), not a notification\n transport\n .request(OPEN_LINK_METHOD, params as unknown as Record<string, unknown>)\n .catch(() => {});\n },\n\n updateModelContext(state: Record<string, unknown>, summary?: string): void {\n if (destroyed) return;\n const params: McpUiUpdateModelContextRequest[\"params\"] = {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary } satisfies TextContent],\n }),\n };\n transport.send(\"ui/update-model-context\", params as unknown as Record<string, unknown>);\n },\n\n async callTool(toolName: string, args?: Record<string, unknown>): Promise<ToolCallResult> {\n const params: CallToolRequest[\"params\"] = {\n name: toolName,\n arguments: args ?? {},\n };\n const raw = await transport.request(\n \"tools/call\",\n params as unknown as Record<string, unknown>,\n );\n return parseToolResult(raw);\n },\n\n async readServerResource(params: ReadResourceRequest[\"params\"]): Promise<ReadResourceResult> {\n const raw = await transport.request(\n READ_RESOURCE_METHOD,\n params as unknown as Record<string, unknown>,\n );\n return raw as ReadResourceResult;\n },\n\n sendMessage(text: string, context?: { action?: string; entity?: string }): void {\n if (destroyed) return;\n const textBlock: TextContent = {\n type: \"text\",\n text,\n ...(context && { _meta: { context } }),\n };\n const params: McpUiMessageRequest[\"params\"] = {\n role: \"user\",\n content: [textBlock],\n };\n transport.send(MESSAGE_METHOD, params as unknown as Record<string, unknown>);\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n resizer.destroy();\n handlers.clear();\n transport.destroy();\n },\n };\n\n return app;\n}\n\n// --- Helpers ---\n\n/** Inject CSS custom properties onto :root so widgets inherit host theming. */\nfunction injectCssVariables(vars: Record<string, string> | undefined | null): void {\n if (!vars || typeof vars !== \"object\") return;\n for (const [k, v] of Object.entries(vars)) {\n if (typeof k === \"string\" && typeof v === \"string\") {\n document.documentElement.style.setProperty(k, v);\n }\n }\n}\n","import type { McpUiHostContext, McpUiInitializeResult } from \"@modelcontextprotocol/ext-apps\";\nimport type { HostInfo, SynapseTheme } from \"./types\";\n\nconst DEFAULT_THEME: SynapseTheme = {\n mode: \"light\",\n primaryColor: \"#6366f1\",\n tokens: {},\n};\n\n/**\n * Detect the host environment from the ext-apps `ui/initialize` response.\n *\n * Reports identity only (host name, protocol version). Theme lives in the\n * unified host-context state and is read via `extractTheme(hostContext)`\n * — no parallel `theme` field on `HostInfo`.\n *\n * Handles missing or malformed fields gracefully — never throws.\n */\nexport function detectHost(initResponse: unknown): HostInfo {\n const resp = initResponse as Partial<McpUiInitializeResult> | null | undefined;\n\n const hostName = resp?.hostInfo?.name ?? \"unknown\";\n const protocolVersion = resp?.protocolVersion ?? \"unknown\";\n\n return {\n isNimbleBrain: hostName === \"nimblebrain\",\n serverName: hostName,\n protocolVersion,\n };\n}\n\nexport function extractTheme(ctx: Partial<McpUiHostContext> | undefined): SynapseTheme {\n if (!ctx) return { ...DEFAULT_THEME };\n\n // Spec: theme is a string (\"light\" | \"dark\")\n const mode = ctx.theme === \"light\" || ctx.theme === \"dark\" ? ctx.theme : DEFAULT_THEME.mode;\n\n // Spec: tokens live under styles.variables\n const variables = ctx.styles?.variables;\n const tokens =\n variables && typeof variables === \"object\" && !Array.isArray(variables)\n ? (variables as Record<string, string>)\n : {};\n\n return { mode, primaryColor: DEFAULT_THEME.primaryColor, tokens };\n}\n","import type { SynapseTransport } from \"./transport.js\";\nimport type { KeyForwardConfig } from \"./types.js\";\n\n/**\n * Forward keyboard shortcuts from the iframe document to the host.\n *\n * By default, forwards all Ctrl/Cmd+key combos and Escape.\n * Apps can customize via `forwardKeys` config.\n */\nexport class KeyboardForwarder {\n private listener: (event: KeyboardEvent) => void;\n private destroyed = false;\n\n constructor(transport: SynapseTransport, customKeys?: KeyForwardConfig[]) {\n const config = customKeys ?? null; // null = default behavior\n\n this.listener = (event: KeyboardEvent) => {\n if (this.destroyed) return;\n if (this.shouldForward(event, config)) {\n event.preventDefault();\n transport.send(\"synapse/keydown\", {\n key: event.key,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n }\n };\n\n document.addEventListener(\"keydown\", this.listener);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n document.removeEventListener(\"keydown\", this.listener);\n }\n\n private shouldForward(event: KeyboardEvent, config: KeyForwardConfig[] | null): boolean {\n // Empty array = forwarding disabled\n if (config && config.length === 0) return false;\n\n // Custom config: match exactly\n if (config) {\n return config.some(\n (k) =>\n event.key.toLowerCase() === k.key.toLowerCase() &&\n (k.ctrl === undefined || event.ctrlKey === k.ctrl) &&\n (k.meta === undefined || event.metaKey === k.meta) &&\n (k.shift === undefined || event.shiftKey === k.shift) &&\n (k.alt === undefined || event.altKey === k.alt),\n );\n }\n\n // Default: forward all Ctrl/Cmd combos + Escape,\n // EXCEPT clipboard shortcuts (c, v, x, a) which the browser must handle natively.\n if (event.key === \"Escape\") return true;\n if (event.ctrlKey || event.metaKey) {\n const key = event.key.toLowerCase();\n if (key === \"c\" || key === \"v\" || key === \"x\" || key === \"a\") return false;\n return true;\n }\n return false;\n }\n}\n","import type {\n CallToolRequest,\n CancelTaskRequest,\n CancelTaskResult,\n CreateTaskResult,\n GetTaskPayloadRequest,\n GetTaskPayloadResult,\n GetTaskRequest,\n GetTaskResult,\n Task,\n TaskStatus,\n TaskStatusNotification,\n TaskStatusNotificationParams,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { parseToolResult } from \"./result-parser.js\";\nimport type { SynapseTransport } from \"./transport.js\";\nimport type { CallToolAsTaskOptions, TaskHandle, ToolCallResult } from \"./types.js\";\n\n// -----------------------------------------------------------------------------\n// Spec method constants\n// -----------------------------------------------------------------------------\n//\n// The MCP SDK publishes task-method strings only inside Zod `z.literal(...)`s,\n// not as top-level `*_METHOD` constants. Derive each from its request's\n// `method` type so an upstream rename surfaces here as a compile error\n// (same pattern as `READ_RESOURCE_METHOD` in core.ts / connect.ts).\n//\n// When adding a new method here, also mirror it in `src/_shims/ext-apps.ts`\n// per the IIFE build instructions in CLAUDE.md — the shim must export the\n// same string constants any source file consumes.\n\nexport const TOOLS_CALL_METHOD: CallToolRequest[\"method\"] = \"tools/call\";\nexport const TASKS_GET_METHOD: GetTaskRequest[\"method\"] = \"tasks/get\";\nexport const TASKS_RESULT_METHOD: GetTaskPayloadRequest[\"method\"] = \"tasks/result\";\nexport const TASKS_CANCEL_METHOD: CancelTaskRequest[\"method\"] = \"tasks/cancel\";\nexport const TASKS_STATUS_NOTIFICATION_METHOD: TaskStatusNotification[\"method\"] =\n \"notifications/tasks/status\";\n\n// -----------------------------------------------------------------------------\n// Status router\n// -----------------------------------------------------------------------------\n\n/**\n * Notification fields the spec guarantees on `notifications/tasks/status`.\n * Deliberately narrower than `Task` — the wire notification omits\n * `createdAt`, `lastUpdatedAt`, `ttl`, `pollInterval`. Consumers receive\n * a merged full `Task` via `TaskHandle.onStatus`; the handle is the only\n * party with access to the initial `CreateTaskResult.task` needed to fill\n * the missing fields.\n */\nexport interface TaskStatusUpdate {\n taskId: string;\n status: TaskStatus;\n statusMessage?: string;\n}\n\n/**\n * Per-taskId callback registry. One registry is shared across all\n * `TaskHandle` instances on a given transport so the transport-level\n * `notifications/tasks/status` handler registers exactly once — multiple\n * handles route in-memory by taskId, not by wire subscription.\n */\nexport interface TaskStatusRouter {\n subscribe(taskId: string, cb: (update: TaskStatusUpdate) => void): () => void;\n dispose(): void;\n}\n\nexport function createTaskStatusRouter(transport: SynapseTransport): TaskStatusRouter {\n const listeners = new Map<string, Set<(update: TaskStatusUpdate) => void>>();\n\n // Single transport-level subscription. All per-handle listeners filter\n // in-memory by taskId off this one wire handler.\n const unsub = transport.onMessage(TASKS_STATUS_NOTIFICATION_METHOD, (rawParams) => {\n if (!rawParams) return;\n const params = rawParams as unknown as TaskStatusNotificationParams;\n const taskId = params.taskId;\n if (typeof taskId !== \"string\") return;\n\n const set = listeners.get(taskId);\n if (!set || set.size === 0) return;\n\n // Forward the spec-guaranteed fields verbatim. We deliberately don't\n // fabricate `createdAt`/`lastUpdatedAt`/`ttl` here — the handle merges\n // these from its initial `CreateTaskResult.task` so consumers always\n // see a real Task with no placeholder strings.\n const update: TaskStatusUpdate = {\n taskId: params.taskId,\n status: params.status,\n ...(params.statusMessage !== undefined && { statusMessage: params.statusMessage }),\n };\n\n for (const cb of set) cb(update);\n });\n\n return {\n subscribe(taskId, cb) {\n let set = listeners.get(taskId);\n if (!set) {\n set = new Set();\n listeners.set(taskId, set);\n }\n set.add(cb);\n return () => {\n const s = listeners.get(taskId);\n if (!s) return;\n s.delete(cb);\n if (s.size === 0) listeners.delete(taskId);\n };\n },\n dispose() {\n listeners.clear();\n unsub();\n },\n };\n}\n\n// -----------------------------------------------------------------------------\n// Caller-facing factory\n// -----------------------------------------------------------------------------\n\n/**\n * Dependencies injected into `callToolAsTask`. The call site (in\n * `core.ts`) provides the transport, the shared status router, a factory\n * for the `tools/call` params (so `internal` / `name` handling stays in\n * one place), and the current `_hostTasksCapability` value.\n */\nexport interface CallToolAsTaskDeps {\n transport: SynapseTransport;\n router: TaskStatusRouter;\n /**\n * `null` before the `ui/initialize` handshake resolves, `undefined`\n * afterward if the host did not advertise `tasks`, or the captured\n * capability shape if it did. `callToolAsTask` throws when the nested\n * `requests.tools.call` is not present.\n */\n getHostTasksCapability: () =>\n | { requests?: { tools?: { call?: Record<string, never> } } }\n | undefined\n | null;\n /** App name for `params.server` when `internal: true`. */\n appName: string;\n /** Whether the enclosing Synapse is running in internal-apps mode. */\n internalApp: boolean;\n}\n\nexport async function callToolAsTask<TOutput = unknown>(\n deps: CallToolAsTaskDeps,\n toolName: string,\n args?: unknown,\n options?: CallToolAsTaskOptions,\n): Promise<TaskHandle<TOutput>> {\n const hostTasks = deps.getHostTasksCapability();\n if (!hostTasks?.requests?.tools?.call) {\n throw new Error(\n \"callToolAsTask: host did not advertise tasks.requests.tools.call in its capabilities. \" +\n \"Per MCP 2025-11-25 §, requestors MUST NOT task-augment a tools/call without \" +\n \"matching receiver capability. Fall back to `synapse.callTool`.\",\n );\n }\n\n // Per spec, `task` is an object even when the caller provides no hints —\n // its presence is the signal to the receiver that augmentation is\n // requested. An empty `{}` is valid.\n const taskParam: { ttl?: number } = {};\n if (options?.ttl !== undefined) taskParam.ttl = options.ttl;\n\n // `internal` resolution:\n // - explicit `options.internal === true` → cross-server, add `server`\n // - explicit `options.internal === false` → never add `server`\n // - omitted → inherit from app-level\n // `internal` flag (same\n // semantics as `callTool`)\n const crossServer = options?.internal ?? deps.internalApp;\n\n // Build `tools/call` params. We layer our own shape on the SDK's\n // `CallToolRequest[\"params\"]` via `satisfies` so any rename upstream\n // (`name` → `toolName`, `arguments` → `args`, etc.) trips tsc. The\n // `server` extension is a NimbleBrain bridge convention, not an MCP\n // spec field.\n const callParams = {\n name: toolName,\n arguments: (args as Record<string, unknown> | undefined) ?? {},\n task: taskParam,\n ...(crossServer ? { server: deps.appName } : {}),\n } satisfies CallToolRequest[\"params\"] & { server?: string };\n\n const raw = await deps.transport.request(\n TOOLS_CALL_METHOD,\n callParams as unknown as Record<string, unknown>,\n );\n\n // Spec: task-augmented `tools/call` returns a `CreateTaskResult`. If a\n // receiver that advertised the capability returns a bare\n // `CallToolResult` instead, that's a protocol violation — surface it.\n const createResult = raw as CreateTaskResult | null | undefined;\n const initialTask = createResult?.task;\n if (!initialTask || typeof initialTask !== \"object\" || typeof initialTask.taskId !== \"string\") {\n throw new Error(\n \"callToolAsTask: receiver returned a response without `task` per CreateTaskResult \" +\n \"(expected shape: `{ task: { taskId, status, ... } }`). Receiver may not honor \" +\n \"the advertised tasks capability.\",\n );\n }\n\n const taskId = initialTask.taskId;\n\n // Preserve the Set-semantic dedup contract on `onStatus` (matches\n // `SynapseTransport.onMessage`): registering the same callback twice\n // collapses to one wire subscription, and either returned unsub\n // releases it. Without this, every `onStatus(cb)` would create a\n // fresh wrapper that the router treats as distinct.\n const localCallbacks = new Map<(task: Task) => void, () => void>();\n\n const handle: TaskHandle<TOutput> = {\n task: initialTask,\n\n async result(): Promise<ToolCallResult<TOutput>> {\n const params = { taskId } satisfies GetTaskPayloadRequest[\"params\"];\n const rawResult = await deps.transport.request(\n TASKS_RESULT_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec §: `tasks/result` returns exactly what the non-task\n // response would return. Parse through the shared tool-result\n // parser so `_meta[\"io.modelcontextprotocol/related-task\"]`\n // propagates unchanged (key-preserving spread).\n //\n // Type note: `GetTaskPayloadResult` is a union of result shapes\n // (one per augmentable request type). For `tools/call` tasks,\n // the runtime shape is `CallToolResult`, which `parseToolResult`\n // already handles.\n const typed = rawResult as GetTaskPayloadResult;\n return parseToolResult(typed) as ToolCallResult<TOutput>;\n },\n\n async refresh(): Promise<Task> {\n const params = { taskId } satisfies GetTaskRequest[\"params\"];\n const raw = await deps.transport.request(\n TASKS_GET_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // Per spec, `tasks/get` returns the task shape FLAT (taskId, status,\n // ttl, createdAt, lastUpdatedAt, ... at the top level) — NOT\n // wrapped in a `{ task }` field (unlike `CreateTaskResult`).\n return projectTask(raw as GetTaskResult);\n },\n\n async cancel(): Promise<Task> {\n const params = { taskId } satisfies CancelTaskRequest[\"params\"];\n const raw = await deps.transport.request(\n TASKS_CANCEL_METHOD,\n params as unknown as Record<string, unknown>,\n );\n // `CancelTaskResult` is flat like `GetTaskResult`.\n return projectTask(raw as CancelTaskResult);\n },\n\n onStatus(cb) {\n // Idempotent-in-callback: if the same `cb` is already subscribed,\n // return the existing unsub.\n const existing = localCallbacks.get(cb);\n if (existing) return existing;\n\n // Merge the notification's spec-guaranteed fields (taskId, status,\n // statusMessage) with the handle's initial `CreateTaskResult.task`\n // so the consumer always sees a full valid `Task`. `lastUpdatedAt`\n // is stamped at SDK-receive time (an approximation of the host's\n // update time — the spec doesn't wire the host's timestamp through\n // the notification, so this is the closest signal we have).\n // `createdAt`, `ttl`, `pollInterval` come from the initial task\n // because they don't change over a task's lifetime.\n const wireUnsub = deps.router.subscribe(taskId, (update) => {\n const merged: Task = {\n taskId: update.taskId,\n status: update.status,\n ttl: initialTask.ttl,\n createdAt: initialTask.createdAt,\n lastUpdatedAt: new Date().toISOString(),\n ...(initialTask.pollInterval !== undefined && {\n pollInterval: initialTask.pollInterval,\n }),\n ...(update.statusMessage !== undefined && { statusMessage: update.statusMessage }),\n };\n cb(merged);\n });\n\n const unsub = () => {\n localCallbacks.delete(cb);\n wireUnsub();\n };\n localCallbacks.set(cb, unsub);\n return unsub;\n },\n };\n\n return handle;\n}\n\n// -----------------------------------------------------------------------------\n// Internal helpers\n// -----------------------------------------------------------------------------\n\n/**\n * Project a `GetTaskResult` / `CancelTaskResult` down to the canonical\n * `Task` shape. Both result types are structurally `Task` with an\n * optional `_meta` field on top; we project explicitly so consumers\n * don't see protocol-level `_meta` leaking onto the task state they\n * get back from `refresh()` / `cancel()`.\n *\n * Asymmetry note: `parseToolResult` (for `tools/call` / `tasks/result`\n * payloads) is key-preserving — `_meta` flows through end-to-end, which\n * matters for `io.modelcontextprotocol/related-task` correlation. Here\n * we drop `_meta` because no downstream consumer reads it on `Task` state\n * today. If a host starts stamping useful keys on `tasks/get`/`tasks/cancel`\n * responses, switch to a key-preserving projection.\n */\nfunction projectTask(raw: GetTaskResult | CancelTaskResult): Task {\n return {\n taskId: raw.taskId,\n status: raw.status,\n ttl: raw.ttl,\n createdAt: raw.createdAt,\n lastUpdatedAt: raw.lastUpdatedAt,\n ...(raw.pollInterval !== undefined && { pollInterval: raw.pollInterval }),\n ...(raw.statusMessage !== undefined && { statusMessage: raw.statusMessage }),\n };\n}\n","import type {\n McpUiHostContext,\n McpUiInitializeRequest,\n McpUiInitializeResult,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps\";\nimport {\n HOST_CONTEXT_CHANGED_METHOD,\n INITIALIZE_METHOD,\n INITIALIZED_METHOD,\n LATEST_PROTOCOL_VERSION,\n MESSAGE_METHOD,\n OPEN_LINK_METHOD,\n} from \"@modelcontextprotocol/ext-apps\";\nimport type {\n ReadResourceRequest,\n ReadResourceResult,\n TextContent,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { detectHost, extractTheme } from \"./detection.js\";\nimport { KeyboardForwarder } from \"./keyboard.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { callToolAsTask as callToolAsTaskImpl, createTaskStatusRouter } from \"./task-handle.js\";\nimport { SynapseTransport } from \"./transport.js\";\nimport type {\n AgentAction,\n CallToolAsTaskOptions,\n DataChangedEvent,\n FileResult,\n HostInfo,\n RequestFileOptions,\n Synapse,\n SynapseOptions,\n SynapseTheme,\n TaskHandle,\n TasksCapability,\n ToolCallResult,\n} from \"./types.js\";\n\n// `@modelcontextprotocol/ext-apps` only exports METHOD constants for ext-apps\n// specific ui/* methods, not standard MCP methods. Deriving the constant\n// locally with the spec request's `method` type still fails compilation if\n// upstream renames it.\nconst READ_RESOURCE_METHOD: ReadResourceRequest[\"method\"] = \"resources/read\";\n\n/**\n * Create a Synapse instance.\n *\n * Wraps the ext-apps protocol handshake via `SynapseTransport` and provides\n * a typed, framework-agnostic API for calling tools, reacting to data changes,\n * dispatching actions, and pushing LLM-visible state.\n *\n * In non-NimbleBrain hosts, NB-specific methods degrade to no-ops.\n */\nexport function createSynapse(options: SynapseOptions): Synapse {\n const { name, version, internal = false, forwardKeys } = options;\n\n const transport = new SynapseTransport();\n let hostInfo: HostInfo | null = null;\n // Single source of truth for ext-apps host context. `theme`, `styles`,\n // `displayMode`, `toolInfo` are spec-standardized fields; the open\n // `[key: string]: unknown` lets hosts publish extensions (e.g. NimbleBrain\n // populates a `workspace` field). `getTheme()` and any other typed view\n // is derived from this object — no parallel state.\n let currentHostContext: McpUiHostContext = {};\n // Module-private store for the host's declared `tasks` capability. Kept\n // in the closure (not on Synapse) so `callToolAsTask` reads it without\n // expanding the public surface. `null` before the handshake completes;\n // `undefined` after a handshake where the host did not advertise `tasks`.\n let hostTasksCapability: TasksCapability | undefined | null = null;\n let destroyed = false;\n\n // Shared router for `notifications/tasks/status`. Created eagerly so\n // the transport-level listener registers exactly once — every\n // `TaskHandle.onStatus` subscriber filters off this single wire\n // subscription by taskId. Disposed in `destroy()`.\n const taskStatusRouter = createTaskStatusRouter(transport);\n\n // --- Debounce for setVisibleState ---\n let stateTimer: ReturnType<typeof setTimeout> | null = null;\n\n // --- Keyboard forwarding ---\n let keyboard: KeyboardForwarder | null = null;\n\n // --- ext-apps handshake ---\n //\n // `appCapabilities` is typed as `McpUiAppCapabilities` by the ext-apps\n // spec package, which does not yet model the MCP 2025-11-25 tasks\n // utility. We extend structurally via `TasksCapability` (re-exported\n // from the SDK's `ClientCapabilities.tasks` / `ServerTasksCapability`\n // shape) and `satisfies` the extension so the nested objects match the\n // spec literally — empty objects `{}` as presence flags, NOT booleans.\n const appCapabilities = {\n tasks: {\n cancel: {},\n requests: { tools: { call: {} } },\n } satisfies TasksCapability,\n };\n const initParams: McpUiInitializeRequest[\"params\"] = {\n protocolVersion: LATEST_PROTOCOL_VERSION,\n appInfo: { name, version },\n appCapabilities:\n appCapabilities as unknown as McpUiInitializeRequest[\"params\"][\"appCapabilities\"],\n };\n\n const ready = transport\n .request(INITIALIZE_METHOD, initParams as unknown as Record<string, unknown>)\n .then((result) => {\n hostInfo = detectHost(result);\n currentHostContext = ((result as McpUiInitializeResult | null)?.hostContext ??\n {}) as McpUiHostContext;\n\n // Capture the host's declared `tasks` capability from the init\n // response. The ext-apps `McpUiHostCapabilities` type lacks a\n // `tasks` field (the SDK extension post-dates it), so we read via\n // the result's index signature. `undefined` when absent.\n const initResult = result as McpUiInitializeResult | null;\n const rawTasks = (initResult?.hostCapabilities as Record<string, unknown> | undefined)?.tasks;\n hostTasksCapability =\n rawTasks && typeof rawTasks === \"object\" && !Array.isArray(rawTasks)\n ? (rawTasks as TasksCapability)\n : undefined;\n\n // Inject host CSS variables into :root so plain-CSS styles can consume\n // them via `var(--…)` without needing to read theme.tokens imperatively.\n injectCssVariables(extractTheme(currentHostContext).tokens);\n\n // Notify subscribers so React hooks (useTheme, useHostContext) and\n // custom listeners reflect the handshake-provided context (not just\n // subsequent host-context-changed notifications).\n for (const cb of hostContextCallbacks) cb(currentHostContext);\n\n transport.send(INITIALIZED_METHOD, {});\n\n keyboard = new KeyboardForwarder(transport, forwardKeys);\n });\n\n // Listen for host context changes (ext-apps spec). Notifications carry a\n // full snapshot of the host context, so we replace — never merge.\n const unsubHostContext = transport.onMessage(HOST_CONTEXT_CHANGED_METHOD, (params) => {\n currentHostContext = (params ?? {}) as McpUiHostContext;\n injectCssVariables(extractTheme(currentHostContext).tokens);\n for (const cb of hostContextCallbacks) cb(currentHostContext);\n });\n\n const hostContextCallbacks = new Set<(ctx: McpUiHostContext) => void>();\n const dataCallbacks = new Set<(event: DataChangedEvent) => void>();\n const actionCallbacks = new Set<(action: AgentAction) => void>();\n\n // Listen for data change events\n const unsubData = transport.onMessage(\"synapse/data-changed\", (params) => {\n if (!params) return;\n const event: DataChangedEvent = {\n source: \"agent\",\n server: (params.server as string) ?? \"\",\n tool: (params.tool as string) ?? \"\",\n };\n for (const cb of dataCallbacks) cb(event);\n });\n\n // Listen for agent actions (typed, declarative commands from the server)\n const unsubAction = transport.onMessage(\"synapse/action\", (params) => {\n if (!params || typeof params.type !== \"string\") return;\n const action: AgentAction = {\n type: params.type as string,\n payload: (params.payload as Record<string, unknown>) ?? {},\n requiresConfirmation: params.requiresConfirmation === true,\n label: typeof params.label === \"string\" ? params.label : undefined,\n };\n for (const cb of actionCallbacks) cb(action);\n });\n\n const isNB = () => hostInfo?.isNimbleBrain === true;\n\n const synapse: Synapse = {\n get ready() {\n return ready;\n },\n\n get isNimbleBrainHost() {\n return isNB();\n },\n\n get destroyed() {\n return destroyed;\n },\n\n async callTool<TInput = Record<string, unknown>, TOutput = unknown>(\n toolName: string,\n args?: TInput,\n ): Promise<ToolCallResult<TOutput>> {\n const params: Record<string, unknown> = {\n name: toolName,\n arguments: args ?? {},\n };\n // Internal apps can cross-call\n if (internal) {\n params.server = name;\n }\n const raw = await transport.request(\"tools/call\", params);\n return parseToolResult(raw) as ToolCallResult<TOutput>;\n },\n\n async callToolAsTask<TInput = Record<string, unknown>, TOutput = unknown>(\n toolName: string,\n args?: TInput,\n options?: CallToolAsTaskOptions,\n ): Promise<TaskHandle<TOutput>> {\n return callToolAsTaskImpl<TOutput>(\n {\n transport,\n router: taskStatusRouter,\n getHostTasksCapability: () => hostTasksCapability,\n appName: name,\n internalApp: internal,\n },\n toolName,\n args,\n options,\n );\n },\n\n async readResource(uri: string): Promise<ReadResourceResult> {\n const params: ReadResourceRequest[\"params\"] = { uri };\n const raw = await transport.request(\n READ_RESOURCE_METHOD,\n params as unknown as Record<string, unknown>,\n );\n return raw as ReadResourceResult;\n },\n\n onDataChanged(callback: (event: DataChangedEvent) => void): () => void {\n dataCallbacks.add(callback);\n return () => {\n dataCallbacks.delete(callback);\n };\n },\n\n onAction(callback: (action: AgentAction) => void): () => void {\n actionCallbacks.add(callback);\n return () => {\n actionCallbacks.delete(callback);\n };\n },\n\n getHostContext(): McpUiHostContext {\n return currentHostContext;\n },\n\n onHostContextChanged(callback: (ctx: McpUiHostContext) => void): () => void {\n hostContextCallbacks.add(callback);\n return () => {\n hostContextCallbacks.delete(callback);\n };\n },\n\n getTheme(): SynapseTheme {\n return extractTheme(currentHostContext);\n },\n\n // Selector over `onHostContextChanged`: only fires when the *derived*\n // theme actually changes, so theme subscribers don't see spurious\n // updates when other host-context fields (e.g. workspace) change.\n //\n // Subscriber timing matters:\n // - Subscribed BEFORE handshake: `prev = null` sentinel. The first\n // fire (the handshake dispatch) always invokes the callback,\n // even if the host's theme happens to derive to the default.\n // Otherwise consumers using `onThemeChanged` as their init\n // signal would silently miss it.\n // - Subscribed AFTER handshake: `prev` is pre-seeded with the\n // current derived theme, so a workspace-only `host-context-changed`\n // notification correctly filters as a no-op.\n onThemeChanged(callback: (theme: SynapseTheme) => void): () => void {\n let prev: SynapseTheme | null = hostInfo !== null ? extractTheme(currentHostContext) : null;\n const wrapped = (ctx: McpUiHostContext) => {\n const next = extractTheme(ctx);\n if (prev !== null && themesEqual(prev, next)) return;\n prev = next;\n callback(next);\n };\n hostContextCallbacks.add(wrapped);\n return () => {\n hostContextCallbacks.delete(wrapped);\n };\n },\n\n action(action: string, params?: Record<string, unknown>): void {\n if (!isNB()) return;\n transport.send(\"synapse/action\", { action, ...params });\n },\n\n chat(message: string, context?: { action?: string; entity?: string }): void {\n const textBlock: TextContent = {\n type: \"text\",\n text: message,\n ...(isNB() && context && { _meta: { context } }),\n };\n const params: McpUiMessageRequest[\"params\"] = {\n role: \"user\",\n content: [textBlock],\n };\n transport.send(MESSAGE_METHOD, params as unknown as Record<string, unknown>);\n },\n\n setVisibleState(state: Record<string, unknown>, summary?: string): void {\n // Debounce: 250ms\n if (stateTimer) clearTimeout(stateTimer);\n stateTimer = setTimeout(() => {\n const params: McpUiUpdateModelContextRequest[\"params\"] = {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary } satisfies TextContent],\n }),\n };\n transport.send(\"ui/update-model-context\", params as unknown as Record<string, unknown>);\n stateTimer = null;\n }, 250);\n },\n\n downloadFile(filename: string, content: string | Blob, mimeType?: string): void {\n // Precedence: explicit mimeType arg > Blob's intrinsic type > octet-stream fallback.\n // Empty-string mimeType falls through (a \"\" MIME is effectively \"no type\").\n const resolvedMime =\n mimeType || (content instanceof Blob ? content.type : \"\") || \"application/octet-stream\";\n const blob = content instanceof Blob ? content : new Blob([content], { type: resolvedMime });\n transport.send(\"synapse/download-file\", {\n data: blob,\n filename,\n mimeType: resolvedMime,\n });\n },\n\n openLink(url: string): void {\n const params: McpUiOpenLinkRequest[\"params\"] = { url };\n // Spec: ui/open-link is a request (expects a response), not a notification\n transport\n .request(OPEN_LINK_METHOD, params as unknown as Record<string, unknown>)\n .catch(() => {\n // Fallback: if host doesn't respond, open directly\n window.open(url, \"_blank\", \"noopener\");\n });\n },\n\n async pickFile(options?: RequestFileOptions): Promise<FileResult | null> {\n if (!isNB()) {\n throw new Error(\"pickFile is not supported in this host\");\n }\n const result = await transport.request(\"synapse/pick-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: false,\n });\n return (result as FileResult) ?? null;\n },\n\n async pickFiles(options?: RequestFileOptions): Promise<FileResult[]> {\n if (!isNB()) {\n throw new Error(\"pickFiles is not supported in this host\");\n }\n const result = await transport.request(\"synapse/pick-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: true,\n });\n if (!result) return [];\n return Array.isArray(result) ? (result as FileResult[]) : [result as FileResult];\n },\n\n _onMessage(\n method: string,\n callback: (params: Record<string, unknown> | undefined) => void,\n ): () => void {\n return transport.onMessage(method, callback);\n },\n\n _request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n return transport.request(method, params);\n },\n\n get _hostTasksCapability(): TasksCapability | undefined | null {\n return hostTasksCapability;\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n\n if (stateTimer) clearTimeout(stateTimer);\n keyboard?.destroy();\n unsubHostContext();\n unsubData();\n unsubAction();\n taskStatusRouter.dispose();\n hostContextCallbacks.clear();\n dataCallbacks.clear();\n actionCallbacks.clear();\n transport.destroy();\n },\n };\n\n return synapse;\n}\n\n/** Shallow equality for `SynapseTheme` — used by `onThemeChanged` to filter\n * host-context changes that don't actually move the theme (e.g. a workspace\n * switch that leaves theme/styles untouched). Cheap; tokens are ~40 entries. */\nfunction themesEqual(a: SynapseTheme, b: SynapseTheme): boolean {\n if (a.mode !== b.mode || a.primaryColor !== b.primaryColor) return false;\n const aKeys = Object.keys(a.tokens);\n const bKeys = Object.keys(b.tokens);\n if (aKeys.length !== bKeys.length) return false;\n // Iterating only over `a`'s keys is sufficient: under equal length, any\n // key in `a` missing from `b` reads `b[k] === undefined`, which fails the\n // strict-inequality check. Symmetric difference is covered.\n for (const k of aKeys) {\n if (a.tokens[k] !== b.tokens[k]) return false;\n }\n return true;\n}\n\n/** Inject CSS custom properties onto :root so widgets inherit host theming. */\nfunction injectCssVariables(vars: Record<string, string> | undefined | null): void {\n if (!vars || typeof vars !== \"object\") return;\n if (typeof document === \"undefined\") return;\n for (const [k, v] of Object.entries(vars)) {\n if (typeof k === \"string\" && typeof v === \"string\") {\n document.documentElement.style.setProperty(k, v);\n }\n }\n}\n"]}
|