@particle-academy/agent-integrations 0.39.1 → 0.41.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/dist/bridges/files.d.cts +36 -1
- package/dist/bridges/files.d.ts +36 -1
- package/dist/bridges-files.cjs +45 -0
- package/dist/bridges-files.cjs.map +1 -1
- package/dist/bridges-files.js +1 -1
- package/dist/{chunk-JDCB2NMM.js → chunk-6TZ5IBRN.js} +17 -8
- package/dist/chunk-6TZ5IBRN.js.map +1 -0
- package/dist/{chunk-A25E22WW.js → chunk-D756GBMQ.js} +47 -3
- package/dist/chunk-D756GBMQ.js.map +1 -0
- package/dist/{chunk-QYWPCRT2.js → chunk-QDC7MXBH.js} +3 -3
- package/dist/{chunk-QYWPCRT2.js.map → chunk-QDC7MXBH.js.map} +1 -1
- package/dist/components-shared-whiteboard.cjs +15 -6
- package/dist/components-shared-whiteboard.cjs.map +1 -1
- package/dist/components-shared-whiteboard.js +2 -2
- package/dist/index.cjs +66 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/dist/sharing/index.d.cts +28 -0
- package/dist/sharing/index.d.ts +28 -0
- package/dist/sharing.cjs +15 -6
- package/dist/sharing.cjs.map +1 -1
- package/dist/sharing.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-A25E22WW.js.map +0 -1
- package/dist/chunk-JDCB2NMM.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bridges/files.ts"],"names":["p"],"mappings":"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","file":"chunk-D756GBMQ.js","sourcesContent":["// Loose types so this bridge builds standalone without a hard dep on\n// @particle-academy/react-fancy. Hosts using FileBrowser pass its own\n// FileEntry / FileSnapshotNode values straight through — the shapes match.\ntype FileKind = \"file\" | \"dir\";\ntype FileEntry = {\n path: string;\n name: string;\n kind: FileKind;\n size?: number;\n mtime?: string;\n hasChildren?: boolean;\n disabled?: boolean;\n};\ntype FileSnapshotNode = FileEntry & { children?: FileSnapshotNode[] };\n\nimport { textResult, errorResult } from \"../mcp/server\";\nimport type { ToolHost } from \"../mcp/tool-host\";\nimport type { JsonObject } from \"../mcp/types\";\nimport type { Bridge } from \"./types\";\nimport { wrapToolWithActivity } from \"../presence/wrap-tool-with-activity\";\nimport type { AgentTarget as FilesAgentTarget } from \"../presence/types\";\nimport { pushUndoEntry } from \"../undo/undo-stack\";\nimport { ensureUndoToolsRegistered } from \"../undo/undo-tools\";\n\n/**\n * Adapter the host provides — getters/setters over the SAME controlled props it\n * passes to react-fancy's `<FileBrowser>` (`value`/`path`/`expandedPaths`), plus\n * `listChildren` (wire to your `provider.loadChildren` or the loaded cache) and,\n * for snapshot mode, an optional `requestSnapshot`.\n */\nexport type FilesBridgeAdapter = {\n /** Current directory (the `path` prop). */\n getPath: () => string;\n setPath: (path: string) => void;\n /** Selected path(s) — normalize FileBrowser's `value` (string | string[] | null) to an array. */\n getSelection: () => string[];\n setSelection: (paths: string[]) => void;\n /** Expanded folder paths (the `expandedPaths` prop). */\n getExpanded: () => string[];\n setExpanded: (next: string[] | ((prev: string[]) => string[])) => void;\n /** Direct children of a path — wire to `provider.loadChildren` (async) or the loaded/snapshot cache. */\n listChildren: (path: string) => Promise<FileEntry[]> | FileEntry[];\n /** Optional (snapshot mode): fetch/refresh a snapshot subtree so an agent can pull remote state on demand. */\n requestSnapshot?: (path: string, depth?: number) => Promise<FileSnapshotNode[]> | FileSnapshotNode[];\n /**\n * Create a folder. **Supplying this is the opt-in** — `files_create_folder`\n * is registered only when it is present, so an agent cannot be handed a write\n * a host never wired, and the advertised tool list tells the truth about what\n * is possible.\n *\n * Pairs with `FileBrowser`'s `onCreateFolder` (react-fancy 5.18+): the same\n * operation the human has, given to the agent.\n */\n createFolder?: (input: { parentPath: string; name: string }) => Promise<void> | void;\n};\n\nexport type FilesBridgeOptions = {\n adapter: FilesBridgeAdapter;\n /** Identity tagged onto agent-driven actions. */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Optional containment root. When set, every agent-supplied path is checked\n * with {@link assertPathWithinRoot} before it reaches the adapter: a `..`\n * segment or an absolute path outside `root` is rejected. This is a\n * fail-closed, string-level guard (no filesystem access — the bridge runs in\n * the browser). It is NOT sufficient on its own: a host over a real\n * filesystem MUST additionally resolve symlinks/junctions (realpath) and\n * enforce the root, because a link under `root` can still point outside it.\n * When `root` is unset the bridge does no containment and the adapter is\n * SOLELY responsible for sandboxing what `listChildren`/`requestSnapshot` expose.\n */\n root?: string;\n /**\n * Stage writes for human confirmation. Default **true**, matching the\n * catalog bridge's destructive ops.\n *\n * This bridge writes to a filesystem on the strength of a model's output, so\n * the safe mode is the default and turning it off is the deliberate act.\n */\n pendingMode?: boolean;\n /** Host confirm hook for staged writes. Resolves true to proceed. */\n confirm?: (req: { action: string; path: string; label: string }) => Promise<boolean> | boolean;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/** Host default cap on snapshot recursion, so an agent can't request an\n * unbounded deep walk. */\nconst MAX_SNAPSHOT_DEPTH = 8;\n\n/**\n * Fail-closed, filesystem-free path containment. Throws when `path` contains a\n * `..` segment, or is absolute and not within `root`. Relative paths without\n * `..` pass (resolved within root by the host). String-level only — see the\n * `root` docs: hosts over a real fs must ALSO realpath to defeat symlinks.\n */\n/**\n * Why a folder NAME cannot be used, or `null`.\n *\n * `assertPathWithinRoot` inspects the parent path; the name is appended to it\n * afterwards, so `{ parentPath: \"/root\", name: \"../..\" }` clears that check and\n * still escapes. A name containing a separator is not a name.\n */\nexport function invalidFolderName(name: string): string | null {\n const trimmed = name.trim();\n if (trimmed === \"\") return \"A folder name is required.\";\n if (trimmed.includes(\"/\") || trimmed.includes(\"\\\\\")) return \"A folder name may not contain a path separator.\";\n if (trimmed === \".\" || trimmed === \"..\") return \"That folder name is reserved.\";\n return null;\n}\n\nexport function assertPathWithinRoot(root: string, path: string): void {\n const segments = path.replace(/[\\\\/]+/g, \"/\").split(\"/\");\n if (segments.includes(\"..\")) {\n throw new Error(`Path may not contain '..': ${path}`);\n }\n const isAbsolute = /^([A-Za-z]:)?[\\\\/]/.test(path) || /^[A-Za-z]:/.test(path);\n if (isAbsolute) {\n // Strip a trailing slash with `\\/$`, NOT `\\/+$`. The quantified `\\/+$`\n // is a polynomial-ReDoS on paths with many slashes (CodeQL js/polynomial-\n // redos), and the `+` is redundant here: the preceding\n // `.replace(/[\\\\/]+/g, \"/\")` has already collapsed every slash-run to a\n // single `/`, so at most one trailing slash can remain. Non-quantified\n // `\\/$` matches the same input in linear time.\n const norm = (p: string): string => p.replace(/[\\\\/]+/g, \"/\").replace(/\\/$/, \"\").toLowerCase();\n const r = norm(root);\n const p = norm(path);\n if (p !== r && !p.startsWith(r + \"/\")) {\n throw new Error(`Path escapes the configured root: ${path}`);\n }\n }\n}\n\nconst str = (v: unknown, fallback = \"\"): string => (typeof v === \"string\" ? v : fallback);\nconst num = (v: unknown, fallback?: number): number =>\n typeof v === \"number\" && Number.isFinite(v) ? v : fallback ?? 0;\nconst asPaths = (v: unknown): string[] => {\n if (typeof v === \"string\") {\n return [v];\n }\n if (Array.isArray(v)) {\n return v.filter((x): x is string => typeof x === \"string\");\n }\n return [];\n};\n\n/**\n * registerFilesBridge — an MCP tool set over a react-fancy `<FileBrowser>`'s\n * controlled state, so a human and an agent share one file browser. The agent\n * lists a folder's children, navigates, expands/collapses folders, selects\n * entries, and (in snapshot mode) requests a fresh subtree — driving the same\n * `value`/`path`/`expandedPaths` props, no DOM scraping. Every mutation\n * broadcasts AgentActivity (presence) and pushes an undo entry. Mirrors the\n * map / whiteboard / flow bridges in shape.\n *\n * Read-only browse in v1: no content preview (pair with fancy-code's\n * FileViewer) and no write ops (rename/delete/upload) — those arrive later\n * behind a pendingMode-gated iteration.\n */\nexport function registerFilesBridge(host: ToolHost, options: FilesBridgeOptions): Bridge {\n const { adapter } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const pendingMode = options.pendingMode ?? true;\n const disposers: Array<() => void> = [];\n\n // Reject traversal / out-of-root paths before they reach the adapter (no-op\n // when no root is configured — the adapter is then responsible for sandboxing).\n const guard = (path: string): string => {\n if (options.root !== undefined) assertPathWithinRoot(options.root, path);\n return path;\n };\n\n // Register agent_undo / agent_redo / agent_history once per host. Idempotent.\n ensureUndoToolsRegistered(host, { defaultAgentId: agent.id });\n\n const fTarget = (args: any, _result: any): FilesAgentTarget => ({\n kind: \"files\",\n elementId: (args?.path as string | undefined) ?? undefined,\n });\n\n const reg = (\n name: string,\n description: string,\n properties: Record<string, unknown>,\n required: string[],\n handler: (args: JsonObject) => Promise<any> | any,\n resolveTarget?: (args: JsonObject, result: any) => FilesAgentTarget | null,\n ) => {\n const wrapped = async (args: JsonObject) => {\n try {\n return await handler(args);\n } catch (e) {\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n };\n const final = resolveTarget\n ? wrapToolWithActivity(wrapped, {\n toolName: name,\n agent: { id: agent.id, name: agent.name, color: agent.color },\n kind: \"files\",\n resolveTarget: ({ args, result }) => resolveTarget(args, result),\n })\n : wrapped;\n disposers.push(\n host.registerTool(\n {\n name,\n description,\n inputSchema: {\n type: \"object\",\n properties: properties as any,\n required,\n additionalProperties: false,\n },\n },\n final as any,\n ),\n );\n };\n\n // ───────────── Read ─────────────\n\n reg(\n \"files_get_state\",\n \"Get the file browser's current directory, selected path(s), and expanded folders.\",\n {},\n [],\n () => {\n const state = {\n path: adapter.getPath(),\n selected: adapter.getSelection(),\n expanded: adapter.getExpanded(),\n };\n return textResult(JSON.stringify(state, null, 2), state);\n },\n );\n\n reg(\n \"files_list\",\n \"List the direct children of a folder (files + subfolders). Omit `path` for the current directory. Loads lazily from the host's provider/snapshot — never an eager tree walk.\",\n { path: { type: \"string\", description: \"Folder path to list; defaults to the current directory.\" } },\n [],\n async (args) => {\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n const entries = await adapter.listChildren(path);\n const summary = entries.map((e) => ({\n path: e.path,\n name: e.name,\n kind: e.kind,\n ...(e.size !== undefined ? { size: e.size } : {}),\n ...(e.mtime !== undefined ? { mtime: e.mtime } : {}),\n }));\n const text =\n summary.map((e) => `${e.kind === \"dir\" ? \"📁\" : \"📄\"} ${e.path}`).join(\"\\n\") ||\n `(empty: ${path})`;\n return textResult(text, { path, entries: summary });\n },\n );\n\n // ───────────── Navigation ─────────────\n\n reg(\n \"files_navigate\",\n \"Set the current directory (as if the user clicked a breadcrumb or opened a folder).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n const prev = adapter.getPath();\n adapter.setPath(path);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_navigate\",\n label: `Navigated to ${path}`,\n undo: () => adapter.setPath(prev),\n redo: () => adapter.setPath(path),\n });\n return textResult(`Current directory → ${path}`, { path });\n },\n fTarget,\n );\n\n // ───────────── Expansion ─────────────\n\n reg(\n \"files_expand\",\n \"Expand a folder in the tree (loads its children if needed).\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (adapter.getExpanded().includes(path)) {\n return textResult(`${path} already expanded`, { path, expanded: true });\n }\n adapter.setExpanded((prev) => [...prev, path]);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_expand\",\n label: `Expanded ${path}`,\n undo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n redo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n });\n return textResult(`Expanded ${path}`, { path, expanded: true });\n },\n fTarget,\n );\n\n reg(\n \"files_collapse\",\n \"Collapse a folder in the tree.\",\n { path: { type: \"string\" } },\n [\"path\"],\n (args) => {\n const path = guard(str(args.path));\n if (!adapter.getExpanded().includes(path)) {\n return textResult(`${path} already collapsed`, { path, expanded: false });\n }\n adapter.setExpanded((prev) => prev.filter((p) => p !== path));\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_collapse\",\n label: `Collapsed ${path}`,\n undo: () => adapter.setExpanded((prev) => (prev.includes(path) ? prev : [...prev, path])),\n redo: () => adapter.setExpanded((prev) => prev.filter((p) => p !== path)),\n });\n return textResult(`Collapsed ${path}`, { path, expanded: false });\n },\n fTarget,\n );\n\n // ───────────── Selection ─────────────\n\n reg(\n \"files_select\",\n \"Set the selection to the given path(s). Pass a single `path`, or `paths` for a multi-select browser; either empty clears the selection.\",\n {\n path: { type: \"string\", description: \"A single path to select.\" },\n paths: { type: \"array\", items: { type: \"string\" }, description: \"Multiple paths (multi-select browsers).\" },\n },\n [],\n (args) => {\n const next = (args.paths !== undefined ? asPaths(args.paths) : asPaths(args.path)).map(guard);\n const prev = adapter.getSelection();\n adapter.setSelection(next);\n pushUndoEntry(agent.id, {\n timestamp: Date.now(),\n bridgeId: \"files\",\n action: \"files_select\",\n label: next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\",\n undo: () => adapter.setSelection(prev),\n redo: () => adapter.setSelection(next),\n });\n return textResult(next.length ? `Selected ${next.join(\", \")}` : \"Cleared selection\", {\n selected: next,\n });\n },\n fTarget,\n );\n\n // ───────────── Write (staged) ─────────────\n\n if (adapter.createFolder) {\n reg(\n \"files_create_folder\",\n \"Create a folder inside `parentPath`. Staged for human confirmation unless the host disabled pendingMode.\",\n {\n parentPath: { type: \"string\", description: \"Directory to create in; defaults to the current directory.\" },\n name: { type: \"string\", description: \"The new folder's name. A leaf name — no separators.\" },\n confirm: { type: \"boolean\", description: \"Acknowledge a staged write when the host wired no confirm hook.\" },\n },\n [\"name\"],\n async (args) => {\n const parentPath = guard(args.parentPath !== undefined ? str(args.parentPath) : adapter.getPath());\n const name = str(args.name).trim();\n\n const invalid = invalidFolderName(name);\n if (invalid) return errorResult(invalid);\n\n const label = `${parentPath}/${name}`;\n\n if (pendingMode) {\n if (options.confirm) {\n const ok = await options.confirm({ action: \"files_create_folder\", path: label, label });\n if (!ok) return errorResult(`Declined: create folder ${label} (human did not confirm).`);\n } else if (args.confirm !== true) {\n return errorResult(\n `Staged: create folder ${label}. Re-call with confirm:true to proceed.`,\n );\n }\n }\n\n try {\n await adapter.createFolder!({ parentPath, name });\n } catch (e) {\n // The host's filesystem is the authority on what is allowed —\n // permissions, name rules, a race with another writer. Reporting its\n // refusal as success would tell the agent a folder exists that does not.\n return errorResult(e instanceof Error ? e.message : String(e));\n }\n\n return textResult(`Created folder ${label}.`, { parentPath, name, path: label });\n },\n (args) => ({ kind: \"directory\", path: `${str(args.parentPath)}/${str(args.name)}`, label: str(args.name) }),\n );\n }\n\n // ───────────── Snapshot (streamed remote trees) ─────────────\n\n reg(\n \"files_request_snapshot\",\n \"Request a fresh snapshot subtree rooted at `path` (snapshot mode) — e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.\",\n {\n path: { type: \"string\", description: \"Root of the subtree; defaults to the current directory.\" },\n depth: { type: \"number\", description: \"How many levels deep to materialize (host-defined default).\" },\n },\n [],\n async (args) => {\n if (!adapter.requestSnapshot) {\n return errorResult(\"Host did not wire requestSnapshot (snapshot mode not enabled).\");\n }\n const path = guard(args.path !== undefined ? str(args.path) : adapter.getPath());\n // Clamp depth so an agent can't demand an unbounded recursive walk.\n const depth =\n args.depth !== undefined ? Math.max(0, Math.min(MAX_SNAPSHOT_DEPTH, num(args.depth))) : undefined;\n const tree = await adapter.requestSnapshot(path, depth);\n const count = Array.isArray(tree) ? tree.length : 0;\n return textResult(`Snapshot of ${path}: ${count} top-level entr${count === 1 ? \"y\" : \"ies\"}.`, {\n path,\n snapshot: tree,\n });\n },\n fTarget,\n );\n\n return {\n id: \"files\",\n title: \"Files\",\n dispose: () => {\n for (const d of disposers) d();\n },\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildShareUrl, buildShareConfig } from './chunk-
|
|
1
|
+
import { buildShareUrl, buildShareConfig } from './chunk-6TZ5IBRN.js';
|
|
2
2
|
import { useRef, useEffect, useState } from 'react';
|
|
3
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -383,5 +383,5 @@ function buildCurlRecipe(session) {
|
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
export { AgentActivityHighlight, AgentCursor, AgentPanel, ShareControls, buildAgentPrompt };
|
|
386
|
-
//# sourceMappingURL=chunk-
|
|
387
|
-
//# sourceMappingURL=chunk-
|
|
386
|
+
//# sourceMappingURL=chunk-QDC7MXBH.js.map
|
|
387
|
+
//# sourceMappingURL=chunk-QDC7MXBH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/AgentPanel/AgentPanel.tsx","../src/components/AgentCursor/AgentCursor.tsx","../src/components/AgentActivityHighlight/AgentActivityHighlight.tsx","../src/components/ShareControls/ShareControls.tsx"],"names":["jsxs","jsx","useEffect","useState","useRef"],"mappings":"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","file":"chunk-QYWPCRT2.js","sourcesContent":["import { type CSSProperties, type ReactNode, useEffect, useRef } from \"react\";\n\nexport type AgentActivity = {\n id: string;\n /** Wall-clock timestamp; component formats it. */\n at: number;\n /** \"tool\" for MCP tool invocations, \"message\" for chat, \"info\" for status. */\n kind: \"tool\" | \"message\" | \"info\" | \"error\";\n /** Short label, e.g. \"whiteboard_add_sticky\" or \"Agent\". */\n source: string;\n /** Body text. */\n text: string;\n /** Optional structured payload, rendered as collapsed JSON. */\n detail?: unknown;\n\n // ── Tool-call fields. Present when `kind === \"tool\"`; ignored otherwise. ──\n /**\n * The call's arguments. Rendered inline next to the tool name so the feed\n * reads as `tool(args) → result` — the point being that the agent's\n * reasoning is legible AS IT HAPPENS, not reconstructable afterwards from a\n * details pane nobody opens.\n */\n args?: unknown;\n /** What the call returned. */\n result?: unknown;\n /** Round-trip time in ms. Rendered as `· 142ms`. */\n durationMs?: number;\n /**\n * Lifecycle. A row can appear as `pending` the moment a call starts and be\n * replaced by the settled row, which is what makes this a STREAM rather than\n * a log. Defaults to `ok`, or `error` when `kind === \"error\"`.\n */\n status?: \"pending\" | \"ok\" | \"error\";\n};\n\nexport type AgentPanelProps = {\n /** The agent's identity (name + color appears in the header). */\n agent?: { name?: string; color?: string };\n /** Activity stream. Most recent at the end. */\n activity: AgentActivity[];\n /** Optional chat composer — pass an onSubmit to enable. */\n onSubmit?: (message: string) => void;\n /** Disabled while a request is in flight. */\n busy?: boolean;\n /** Right-rail header actions. */\n actions?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentPanel — sidebar showing the agent's identity, a tool-and-chat log,\n * and an optional input composer. Pure presentational: hosts feed it the\n * activity stream from their own state (typically the MCP transport log).\n */\nexport function AgentPanel({ agent, activity, onSubmit, busy, actions, className, style }: AgentPanelProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [activity.length]);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const value = inputRef.current?.value.trim();\n if (!value || !onSubmit) return;\n onSubmit(value);\n if (inputRef.current) inputRef.current.value = \"\";\n };\n\n const color = agent?.color ?? \"#a855f7\";\n const name = agent?.name ?? \"Agent\";\n\n return (\n <div className={[\"fai-panel\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <header className=\"fai-panel__header\">\n <div\n className=\"fai-panel__avatar\"\n style={{ background: color }}\n aria-hidden\n >\n {name.slice(0, 1)}\n </div>\n <div className=\"fai-panel__title\">\n <strong>{name}</strong>\n <span className=\"fai-panel__subtitle\">\n {busy ? \"Working…\" : `${activity.length} event${activity.length === 1 ? \"\" : \"s\"}`}\n </span>\n </div>\n {actions && <div className=\"fai-panel__actions\">{actions}</div>}\n </header>\n\n <div ref={scrollRef} className=\"fai-panel__stream\">\n {activity.length === 0 ? (\n <p className=\"fai-panel__empty\">No activity yet.</p>\n ) : (\n activity.map((a) => <ActivityRow key={a.id} item={a} />)\n )}\n </div>\n\n {onSubmit && (\n <form className=\"fai-panel__composer\" onSubmit={handleSubmit}>\n <textarea\n ref={inputRef}\n className=\"fai-panel__input\"\n placeholder={busy ? \"Working…\" : \"Ask the agent…\"}\n disabled={busy}\n rows={2}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit(e as unknown as React.FormEvent);\n }\n }}\n />\n <button type=\"submit\" className=\"fai-panel__send\" disabled={busy}>\n Send\n </button>\n </form>\n )}\n </div>\n );\n}\n\nfunction ActivityRow({ item }: { item: AgentActivity }) {\n const time = formatTime(item.at);\n const status = item.status ?? (item.kind === \"error\" ? \"error\" : \"ok\");\n const isCall = item.kind === \"tool\" && (item.args !== undefined || item.result !== undefined || item.durationMs !== undefined);\n\n return (\n <div\n className={`fai-row fai-row--${item.kind}${isCall ? ` fai-row--${status}` : \"\"}`}\n data-fai-row=\"\"\n data-kind={item.kind}\n data-status={isCall ? status : undefined}\n >\n <div className=\"fai-row__meta\">\n <span className=\"fai-row__source\">{item.source}</span>\n {isCall && item.args !== undefined && (\n <span className=\"fai-row__args\" data-fai-args=\"\">\n ({inline(item.args)})\n </span>\n )}\n {isCall && item.durationMs !== undefined && (\n <span className=\"fai-row__latency\" data-fai-latency=\"\">\n · {item.durationMs}ms\n </span>\n )}\n <span className=\"fai-row__time\">{time}</span>\n </div>\n {isCall && item.result !== undefined && (\n <div className=\"fai-row__result\" data-fai-result=\"\">\n → {inline(item.result)}\n </div>\n )}\n <div className=\"fai-row__text\">{item.text}</div>\n {item.detail !== undefined && (\n <details className=\"fai-row__detail\">\n <summary>details</summary>\n <pre>{safeJson(item.detail)}</pre>\n </details>\n )}\n </div>\n );\n}\n\n/**\n * One-line rendering of a call's args or result.\n *\n * Truncated hard, because a feed is scanned rather than read: an untruncated\n * result payload pushes every subsequent row off the screen, which costs more\n * than the detail is worth. The full value stays available via `detail`.\n */\nfunction inline(v: unknown, max = 80): string {\n if (typeof v === \"string\") return v.length > max ? `${v.slice(0, max)}…` : v;\n const json = safeJson(v).replace(/\\s+/g, \" \");\n return json.length > max ? `${json.slice(0, max)}…` : json;\n}\n\nfunction formatTime(at: number): string {\n const d = new Date(at);\n const hh = d.getHours().toString().padStart(2, \"0\");\n const mm = d.getMinutes().toString().padStart(2, \"0\");\n const ss = d.getSeconds().toString().padStart(2, \"0\");\n return `${hh}:${mm}:${ss}`;\n}\n\nfunction safeJson(v: unknown): string {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n","import type { CSSProperties } from \"react\";\n\nexport type AgentCursorProps = {\n x: number;\n y: number;\n name?: string;\n color?: string;\n /** Optional caption shown under the name (e.g. current tool). */\n status?: string;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentCursor — on-canvas presence marker for the agent. Drop it inside\n * (or alongside) a fancy-whiteboard <Board> at screen coords matching\n * the agent's reported position.\n */\nexport function AgentCursor({ x, y, name, color = \"#a855f7\", status, className, style }: AgentCursorProps) {\n return (\n <div\n className={[\"fai-cursor\", className ?? \"\"].filter(Boolean).join(\" \")}\n style={{\n position: \"absolute\",\n left: x,\n top: y,\n pointerEvents: \"none\",\n transform: \"translate(-2px, -2px)\",\n ...style,\n }}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" aria-hidden>\n <path\n d=\"M2 2 L2 17 L7 13 L10 19 L12 18 L9 12 L15 12 Z\"\n fill={color}\n stroke=\"white\"\n strokeWidth=\"1.2\"\n />\n </svg>\n {name && (\n <span\n className=\"fai-cursor__tag\"\n style={{ background: color }}\n >\n {name}\n {status ? <em className=\"fai-cursor__status\"> · {status}</em> : null}\n </span>\n )}\n </div>\n );\n}\n","import { type CSSProperties, useEffect, useState } from \"react\";\n\nexport type AgentActivityHighlightProps = {\n /** Bounds of the highlighted item in the parent's coord system. */\n x: number;\n y: number;\n width: number;\n height: number;\n /** Trigger token — change it (e.g. set to Date.now()) to re-fire the pulse. */\n pulseKey?: string | number;\n /** Highlight tint. */\n color?: string;\n /** Pulse duration in ms. Defaults 1200. */\n duration?: number;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentActivityHighlight — short pulsing outline that flashes around an\n * item the agent just touched. Position the parent so this can be placed\n * absolutely matching the item's bounds.\n */\nexport function AgentActivityHighlight({\n x,\n y,\n width,\n height,\n pulseKey,\n color = \"#a855f7\",\n duration = 1200,\n className,\n style,\n}: AgentActivityHighlightProps) {\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n if (pulseKey === undefined) return;\n setVisible(true);\n const t = setTimeout(() => setVisible(false), duration);\n return () => clearTimeout(t);\n }, [pulseKey, duration]);\n\n if (!visible) return null;\n\n return (\n <div\n className={[\"fai-highlight\", className ?? \"\"].filter(Boolean).join(\" \")}\n style={{\n position: \"absolute\",\n left: x - 4,\n top: y - 4,\n width: width + 8,\n height: height + 8,\n borderRadius: 8,\n boxShadow: `0 0 0 2px ${color}, 0 0 16px ${color}66`,\n pointerEvents: \"none\",\n animation: `fai-pulse ${duration}ms ease-out forwards`,\n ...style,\n }}\n />\n );\n}\n","import { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport type { SessionDescriptor } from \"../../sharing/token\";\nimport type { AgentActivity } from \"../AgentPanel\";\nimport { buildShareConfig, buildShareUrl } from \"../../sharing/token\";\n\nexport type ShareControlsProps = {\n /** The active session, or null when not sharing yet. */\n session: SessionDescriptor | null;\n onStart: () => void;\n onStop: () => void;\n /** Optional connection-state badge text. */\n status?: string;\n /**\n * True once an agent has actually connected to the session.\n *\n * Flips the panel from \"here is how to connect\" to \"here is what the agent is\n * doing\" — the paste-this-prompt UI is dead weight the moment it has been\n * pasted, and what the human needs then is visibility.\n */\n agentConnected?: boolean;\n /**\n * What the agent has done, newest last. Reuses `AgentActivity` from\n * `AgentPanel` rather than a second shape, so a host already collecting\n * presence events can pass the same array to both.\n */\n activity?: AgentActivity[];\n /** Override the URL base used in the share URL. */\n shareBaseUrl?: string;\n className?: string;\n style?: CSSProperties;\n};\n\ntype Tab = \"activity\" | \"prompt\" | \"url\" | \"json\" | \"curl\";\n\n/**\n * ShareControls — the host-facing UI for turning sharing on/off and\n * surfacing the resulting connection details (URL / JSON / cURL).\n */\nexport function ShareControls({\n session,\n onStart,\n onStop,\n status,\n agentConnected = false,\n activity,\n shareBaseUrl,\n className,\n style,\n}: ShareControlsProps) {\n const [tab, setTab] = useState<Tab>(\"prompt\");\n\n // Switch to the log the FIRST time an agent connects, then leave the tab\n // alone. Forcing it on every render would fight a human who deliberately went\n // back to copy the URL again — the panel should follow the session, not\n // overrule the person reading it.\n const wasConnected = useRef(false);\n useEffect(() => {\n if (agentConnected && !wasConnected.current) {\n wasConnected.current = true;\n setTab(\"activity\");\n }\n if (!agentConnected) wasConnected.current = false;\n }, [agentConnected]);\n\n if (!session) {\n return (\n <div className={[\"fai-share fai-share--idle\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <button type=\"button\" className=\"fai-share__start\" onClick={onStart}>\n Start shared session\n </button>\n <p className=\"fai-share__hint\">\n Generates a session id + secret token. Hand the <strong>Agent prompt</strong> to an AI agent, share the URL with humans, or give the JSON config to an MCP-capable client.\n </p>\n </div>\n );\n }\n\n const url = buildShareUrl(session, shareBaseUrl);\n const config = buildShareConfig(session);\n const curl = buildCurlRecipe(session);\n const prompt = buildAgentPrompt(url);\n\n return (\n <div className={[\"fai-share fai-share--active\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <div className=\"fai-share__header\">\n <div>\n <strong>Sharing</strong>\n <span className=\"fai-share__id\">\n session <code>{session.id}</code> · token <code>{session.display}…</code>\n </span>\n </div>\n <div className=\"fai-share__header-actions\">\n {status && <span className=\"fai-share__status\">{status}</span>}\n <button type=\"button\" className=\"fai-share__stop\" onClick={onStop}>\n Stop\n </button>\n </div>\n </div>\n\n <div className=\"fai-share__tabs\" role=\"tablist\">\n {agentConnected && (\n <TabButton tab=\"activity\" active={tab} setTab={setTab}>\n Activity\n </TabButton>\n )}\n <TabButton tab=\"prompt\" active={tab} setTab={setTab}>Agent prompt</TabButton>\n <TabButton tab=\"url\" active={tab} setTab={setTab}>URL</TabButton>\n <TabButton tab=\"json\" active={tab} setTab={setTab}>JSON</TabButton>\n <TabButton tab=\"curl\" active={tab} setTab={setTab}>cURL recipe</TabButton>\n </div>\n\n <div className=\"fai-share__panel\">\n {tab === \"activity\" && <ActivityLog activity={activity} />}\n {tab === \"prompt\" && (\n <CopyBox\n label=\"Paste this straight into an AI agent — it connects over MCP, no browser\"\n value={prompt}\n multiline\n />\n )}\n {tab === \"url\" && <CopyBox label=\"Open this URL in another tab to join the session\" value={url} />}\n {tab === \"json\" && (\n <CopyBox\n label=\"Paste into Claude Desktop / Cline MCP server config\"\n value={JSON.stringify(config, null, 2)}\n />\n )}\n {tab === \"curl\" && (\n <CopyBox\n label=\"Connect from a terminal (verifies the relay is reachable)\"\n value={curl}\n multiline\n />\n )}\n </div>\n </div>\n );\n}\n\n/**\n * What the agent has actually done, newest first.\n *\n * The panel used to keep showing the paste-this-prompt UI after the agent was\n * already connected and driving — dead weight at exactly the moment the human\n * needs the opposite: visibility. A connected agent with no visible activity is\n * indistinguishable from a broken one, which is precisely how a stalled session\n * goes unnoticed.\n */\nfunction ActivityLog({ activity }: { activity?: AgentActivity[] }) {\n const entries = (activity ?? []).slice().reverse();\n\n if (entries.length === 0) {\n return (\n <p className=\"fai-share__empty\">\n Connected. Nothing yet — actions appear here as the agent takes them.\n </p>\n );\n }\n\n return (\n <ol className=\"fai-share__activity\" aria-live=\"polite\">\n {entries.map((entry) => (\n <li key={entry.id} className=\"fai-share__activity-row\" data-kind={entry.kind}>\n <time className=\"fai-share__activity-time\" dateTime={new Date(entry.at).toISOString()}>\n {new Date(entry.at).toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n })}\n </time>\n <span className=\"fai-share__activity-source\">{entry.source}</span>\n <span className=\"fai-share__activity-text\">{entry.text}</span>\n </li>\n ))}\n </ol>\n );\n}\n\nfunction TabButton({ tab, active, setTab, children }: { tab: Tab; active: Tab; setTab: (t: Tab) => void; children: React.ReactNode }) {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={tab === active}\n className={`fai-share__tab${tab === active ? \" is-active\" : \"\"}`}\n onClick={() => setTab(tab)}\n >\n {children}\n </button>\n );\n}\n\nfunction CopyBox({ label, value, multiline }: { label: string; value: string; multiline?: boolean }) {\n const [copied, setCopied] = useState(false);\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n // ignore\n }\n };\n return (\n <div>\n <div className=\"fai-share__panel-label\">{label}</div>\n <div className=\"fai-share__copy\">\n <pre className={`fai-share__pre${multiline ? \" is-multi\" : \"\"}`}>{value}</pre>\n <button type=\"button\" className=\"fai-share__copy-btn\" onClick={copy}>\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Build a copy-paste natural-language prompt to hand directly to an AI agent.\n * Agents handed a bare URL tend to try to *open it in a browser* — this spells\n * out that the link is a live MCP co-browsing session it should drive over MCP\n * tools (via the zero-install relay client), never visit.\n */\nexport function buildAgentPrompt(url: string): string {\n return [\n `You're joining a live Human+ co-browsing session on a web app. This is an MCP`,\n `(Model Context Protocol) session — NOT a website to visit. Do NOT open the URL`,\n `in a browser and do NOT use any browser/Playwright tool. You drive the real,`,\n `running app through MCP tools while a human watches and can take over.`,\n ``,\n `Session link (carries the session id + token — treat it as a secret):`,\n ` ${url}`,\n ``,\n `Connect by running the relay client as an MCP server (zero install):`,\n ` npx -y mcp-relay-client \"${url}\"`,\n ``,\n `That exposes the app's own tools (e.g. page_describe, page_read, nav_visit,`,\n `page_click, page_set_field, page_submit, plus surface tools like whiteboard_*).`,\n `Then:`,\n ` 1. Call page_describe first to see the current page and its interactive handles.`,\n ` 2. Act only on the STABLE HANDLES the tools return — never guess DOM selectors.`,\n ` 3. Navigate with nav_visit, type with page_set_field, click with page_click.`,\n ` Submits and destructive clicks are staged for the human to confirm.`,\n ``,\n `If you can't register an MCP server but can run a shell, drive it directly:`,\n ` curl -O https://raw.githubusercontent.com/Particle-Academy/mcp-relay-client/main/connect.sh`,\n ` bash connect.sh \"${url}\" tools`,\n ` bash connect.sh \"${url}\" call page_describe '{}'`,\n ].join(\"\\n\");\n}\n\n/** Build a copy-paste cURL recipe for connecting an external MCP client. */\nfunction buildCurlRecipe(session: SessionDescriptor): string {\n const base =\n typeof window !== \"undefined\"\n ? `${window.location.protocol}//${window.location.host}`\n : \"http://localhost\";\n const inbox = `${base}/agent-relay/${session.id}/inbox?token=${session.token}`;\n const events = `${base}/agent-relay/${session.id}/events?token=${session.token}`;\n return [\n `# 1) In one terminal, subscribe to server-pushed frames (SSE)`,\n `curl -N \"${events}\"`,\n ``,\n `# 2) In another terminal, send an initialize handshake`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}'`,\n ``,\n `# 3) List the tools the bridge exposes`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}'`,\n ``,\n `# 4) Add a sticky note`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"whiteboard_add_sticky\",\"arguments\":{\"x\":300,\"y\":300,\"text\":\"hello from curl\"}}}'`,\n ].join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/AgentPanel/AgentPanel.tsx","../src/components/AgentCursor/AgentCursor.tsx","../src/components/AgentActivityHighlight/AgentActivityHighlight.tsx","../src/components/ShareControls/ShareControls.tsx"],"names":["jsxs","jsx","useEffect","useState","useRef"],"mappings":"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","file":"chunk-QDC7MXBH.js","sourcesContent":["import { type CSSProperties, type ReactNode, useEffect, useRef } from \"react\";\n\nexport type AgentActivity = {\n id: string;\n /** Wall-clock timestamp; component formats it. */\n at: number;\n /** \"tool\" for MCP tool invocations, \"message\" for chat, \"info\" for status. */\n kind: \"tool\" | \"message\" | \"info\" | \"error\";\n /** Short label, e.g. \"whiteboard_add_sticky\" or \"Agent\". */\n source: string;\n /** Body text. */\n text: string;\n /** Optional structured payload, rendered as collapsed JSON. */\n detail?: unknown;\n\n // ── Tool-call fields. Present when `kind === \"tool\"`; ignored otherwise. ──\n /**\n * The call's arguments. Rendered inline next to the tool name so the feed\n * reads as `tool(args) → result` — the point being that the agent's\n * reasoning is legible AS IT HAPPENS, not reconstructable afterwards from a\n * details pane nobody opens.\n */\n args?: unknown;\n /** What the call returned. */\n result?: unknown;\n /** Round-trip time in ms. Rendered as `· 142ms`. */\n durationMs?: number;\n /**\n * Lifecycle. A row can appear as `pending` the moment a call starts and be\n * replaced by the settled row, which is what makes this a STREAM rather than\n * a log. Defaults to `ok`, or `error` when `kind === \"error\"`.\n */\n status?: \"pending\" | \"ok\" | \"error\";\n};\n\nexport type AgentPanelProps = {\n /** The agent's identity (name + color appears in the header). */\n agent?: { name?: string; color?: string };\n /** Activity stream. Most recent at the end. */\n activity: AgentActivity[];\n /** Optional chat composer — pass an onSubmit to enable. */\n onSubmit?: (message: string) => void;\n /** Disabled while a request is in flight. */\n busy?: boolean;\n /** Right-rail header actions. */\n actions?: ReactNode;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentPanel — sidebar showing the agent's identity, a tool-and-chat log,\n * and an optional input composer. Pure presentational: hosts feed it the\n * activity stream from their own state (typically the MCP transport log).\n */\nexport function AgentPanel({ agent, activity, onSubmit, busy, actions, className, style }: AgentPanelProps) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n }, [activity.length]);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const value = inputRef.current?.value.trim();\n if (!value || !onSubmit) return;\n onSubmit(value);\n if (inputRef.current) inputRef.current.value = \"\";\n };\n\n const color = agent?.color ?? \"#a855f7\";\n const name = agent?.name ?? \"Agent\";\n\n return (\n <div className={[\"fai-panel\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <header className=\"fai-panel__header\">\n <div\n className=\"fai-panel__avatar\"\n style={{ background: color }}\n aria-hidden\n >\n {name.slice(0, 1)}\n </div>\n <div className=\"fai-panel__title\">\n <strong>{name}</strong>\n <span className=\"fai-panel__subtitle\">\n {busy ? \"Working…\" : `${activity.length} event${activity.length === 1 ? \"\" : \"s\"}`}\n </span>\n </div>\n {actions && <div className=\"fai-panel__actions\">{actions}</div>}\n </header>\n\n <div ref={scrollRef} className=\"fai-panel__stream\">\n {activity.length === 0 ? (\n <p className=\"fai-panel__empty\">No activity yet.</p>\n ) : (\n activity.map((a) => <ActivityRow key={a.id} item={a} />)\n )}\n </div>\n\n {onSubmit && (\n <form className=\"fai-panel__composer\" onSubmit={handleSubmit}>\n <textarea\n ref={inputRef}\n className=\"fai-panel__input\"\n placeholder={busy ? \"Working…\" : \"Ask the agent…\"}\n disabled={busy}\n rows={2}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit(e as unknown as React.FormEvent);\n }\n }}\n />\n <button type=\"submit\" className=\"fai-panel__send\" disabled={busy}>\n Send\n </button>\n </form>\n )}\n </div>\n );\n}\n\nfunction ActivityRow({ item }: { item: AgentActivity }) {\n const time = formatTime(item.at);\n const status = item.status ?? (item.kind === \"error\" ? \"error\" : \"ok\");\n const isCall = item.kind === \"tool\" && (item.args !== undefined || item.result !== undefined || item.durationMs !== undefined);\n\n return (\n <div\n className={`fai-row fai-row--${item.kind}${isCall ? ` fai-row--${status}` : \"\"}`}\n data-fai-row=\"\"\n data-kind={item.kind}\n data-status={isCall ? status : undefined}\n >\n <div className=\"fai-row__meta\">\n <span className=\"fai-row__source\">{item.source}</span>\n {isCall && item.args !== undefined && (\n <span className=\"fai-row__args\" data-fai-args=\"\">\n ({inline(item.args)})\n </span>\n )}\n {isCall && item.durationMs !== undefined && (\n <span className=\"fai-row__latency\" data-fai-latency=\"\">\n · {item.durationMs}ms\n </span>\n )}\n <span className=\"fai-row__time\">{time}</span>\n </div>\n {isCall && item.result !== undefined && (\n <div className=\"fai-row__result\" data-fai-result=\"\">\n → {inline(item.result)}\n </div>\n )}\n <div className=\"fai-row__text\">{item.text}</div>\n {item.detail !== undefined && (\n <details className=\"fai-row__detail\">\n <summary>details</summary>\n <pre>{safeJson(item.detail)}</pre>\n </details>\n )}\n </div>\n );\n}\n\n/**\n * One-line rendering of a call's args or result.\n *\n * Truncated hard, because a feed is scanned rather than read: an untruncated\n * result payload pushes every subsequent row off the screen, which costs more\n * than the detail is worth. The full value stays available via `detail`.\n */\nfunction inline(v: unknown, max = 80): string {\n if (typeof v === \"string\") return v.length > max ? `${v.slice(0, max)}…` : v;\n const json = safeJson(v).replace(/\\s+/g, \" \");\n return json.length > max ? `${json.slice(0, max)}…` : json;\n}\n\nfunction formatTime(at: number): string {\n const d = new Date(at);\n const hh = d.getHours().toString().padStart(2, \"0\");\n const mm = d.getMinutes().toString().padStart(2, \"0\");\n const ss = d.getSeconds().toString().padStart(2, \"0\");\n return `${hh}:${mm}:${ss}`;\n}\n\nfunction safeJson(v: unknown): string {\n try {\n return JSON.stringify(v, null, 2);\n } catch {\n return String(v);\n }\n}\n","import type { CSSProperties } from \"react\";\n\nexport type AgentCursorProps = {\n x: number;\n y: number;\n name?: string;\n color?: string;\n /** Optional caption shown under the name (e.g. current tool). */\n status?: string;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentCursor — on-canvas presence marker for the agent. Drop it inside\n * (or alongside) a fancy-whiteboard <Board> at screen coords matching\n * the agent's reported position.\n */\nexport function AgentCursor({ x, y, name, color = \"#a855f7\", status, className, style }: AgentCursorProps) {\n return (\n <div\n className={[\"fai-cursor\", className ?? \"\"].filter(Boolean).join(\" \")}\n style={{\n position: \"absolute\",\n left: x,\n top: y,\n pointerEvents: \"none\",\n transform: \"translate(-2px, -2px)\",\n ...style,\n }}\n >\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 22 22\" aria-hidden>\n <path\n d=\"M2 2 L2 17 L7 13 L10 19 L12 18 L9 12 L15 12 Z\"\n fill={color}\n stroke=\"white\"\n strokeWidth=\"1.2\"\n />\n </svg>\n {name && (\n <span\n className=\"fai-cursor__tag\"\n style={{ background: color }}\n >\n {name}\n {status ? <em className=\"fai-cursor__status\"> · {status}</em> : null}\n </span>\n )}\n </div>\n );\n}\n","import { type CSSProperties, useEffect, useState } from \"react\";\n\nexport type AgentActivityHighlightProps = {\n /** Bounds of the highlighted item in the parent's coord system. */\n x: number;\n y: number;\n width: number;\n height: number;\n /** Trigger token — change it (e.g. set to Date.now()) to re-fire the pulse. */\n pulseKey?: string | number;\n /** Highlight tint. */\n color?: string;\n /** Pulse duration in ms. Defaults 1200. */\n duration?: number;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * AgentActivityHighlight — short pulsing outline that flashes around an\n * item the agent just touched. Position the parent so this can be placed\n * absolutely matching the item's bounds.\n */\nexport function AgentActivityHighlight({\n x,\n y,\n width,\n height,\n pulseKey,\n color = \"#a855f7\",\n duration = 1200,\n className,\n style,\n}: AgentActivityHighlightProps) {\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n if (pulseKey === undefined) return;\n setVisible(true);\n const t = setTimeout(() => setVisible(false), duration);\n return () => clearTimeout(t);\n }, [pulseKey, duration]);\n\n if (!visible) return null;\n\n return (\n <div\n className={[\"fai-highlight\", className ?? \"\"].filter(Boolean).join(\" \")}\n style={{\n position: \"absolute\",\n left: x - 4,\n top: y - 4,\n width: width + 8,\n height: height + 8,\n borderRadius: 8,\n boxShadow: `0 0 0 2px ${color}, 0 0 16px ${color}66`,\n pointerEvents: \"none\",\n animation: `fai-pulse ${duration}ms ease-out forwards`,\n ...style,\n }}\n />\n );\n}\n","import { type CSSProperties, useEffect, useRef, useState } from \"react\";\nimport type { SessionDescriptor } from \"../../sharing/token\";\nimport type { AgentActivity } from \"../AgentPanel\";\nimport { buildShareConfig, buildShareUrl } from \"../../sharing/token\";\n\nexport type ShareControlsProps = {\n /** The active session, or null when not sharing yet. */\n session: SessionDescriptor | null;\n onStart: () => void;\n onStop: () => void;\n /** Optional connection-state badge text. */\n status?: string;\n /**\n * True once an agent has actually connected to the session.\n *\n * Flips the panel from \"here is how to connect\" to \"here is what the agent is\n * doing\" — the paste-this-prompt UI is dead weight the moment it has been\n * pasted, and what the human needs then is visibility.\n */\n agentConnected?: boolean;\n /**\n * What the agent has done, newest last. Reuses `AgentActivity` from\n * `AgentPanel` rather than a second shape, so a host already collecting\n * presence events can pass the same array to both.\n */\n activity?: AgentActivity[];\n /** Override the URL base used in the share URL. */\n shareBaseUrl?: string;\n className?: string;\n style?: CSSProperties;\n};\n\ntype Tab = \"activity\" | \"prompt\" | \"url\" | \"json\" | \"curl\";\n\n/**\n * ShareControls — the host-facing UI for turning sharing on/off and\n * surfacing the resulting connection details (URL / JSON / cURL).\n */\nexport function ShareControls({\n session,\n onStart,\n onStop,\n status,\n agentConnected = false,\n activity,\n shareBaseUrl,\n className,\n style,\n}: ShareControlsProps) {\n const [tab, setTab] = useState<Tab>(\"prompt\");\n\n // Switch to the log the FIRST time an agent connects, then leave the tab\n // alone. Forcing it on every render would fight a human who deliberately went\n // back to copy the URL again — the panel should follow the session, not\n // overrule the person reading it.\n const wasConnected = useRef(false);\n useEffect(() => {\n if (agentConnected && !wasConnected.current) {\n wasConnected.current = true;\n setTab(\"activity\");\n }\n if (!agentConnected) wasConnected.current = false;\n }, [agentConnected]);\n\n if (!session) {\n return (\n <div className={[\"fai-share fai-share--idle\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <button type=\"button\" className=\"fai-share__start\" onClick={onStart}>\n Start shared session\n </button>\n <p className=\"fai-share__hint\">\n Generates a session id + secret token. Hand the <strong>Agent prompt</strong> to an AI agent, share the URL with humans, or give the JSON config to an MCP-capable client.\n </p>\n </div>\n );\n }\n\n const url = buildShareUrl(session, shareBaseUrl);\n const config = buildShareConfig(session);\n const curl = buildCurlRecipe(session);\n const prompt = buildAgentPrompt(url);\n\n return (\n <div className={[\"fai-share fai-share--active\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n <div className=\"fai-share__header\">\n <div>\n <strong>Sharing</strong>\n <span className=\"fai-share__id\">\n session <code>{session.id}</code> · token <code>{session.display}…</code>\n </span>\n </div>\n <div className=\"fai-share__header-actions\">\n {status && <span className=\"fai-share__status\">{status}</span>}\n <button type=\"button\" className=\"fai-share__stop\" onClick={onStop}>\n Stop\n </button>\n </div>\n </div>\n\n <div className=\"fai-share__tabs\" role=\"tablist\">\n {agentConnected && (\n <TabButton tab=\"activity\" active={tab} setTab={setTab}>\n Activity\n </TabButton>\n )}\n <TabButton tab=\"prompt\" active={tab} setTab={setTab}>Agent prompt</TabButton>\n <TabButton tab=\"url\" active={tab} setTab={setTab}>URL</TabButton>\n <TabButton tab=\"json\" active={tab} setTab={setTab}>JSON</TabButton>\n <TabButton tab=\"curl\" active={tab} setTab={setTab}>cURL recipe</TabButton>\n </div>\n\n <div className=\"fai-share__panel\">\n {tab === \"activity\" && <ActivityLog activity={activity} />}\n {tab === \"prompt\" && (\n <CopyBox\n label=\"Paste this straight into an AI agent — it connects over MCP, no browser\"\n value={prompt}\n multiline\n />\n )}\n {tab === \"url\" && <CopyBox label=\"Open this URL in another tab to join the session\" value={url} />}\n {tab === \"json\" && (\n <CopyBox\n label=\"Paste into Claude Desktop / Cline MCP server config\"\n value={JSON.stringify(config, null, 2)}\n />\n )}\n {tab === \"curl\" && (\n <CopyBox\n label=\"Connect from a terminal (verifies the relay is reachable)\"\n value={curl}\n multiline\n />\n )}\n </div>\n </div>\n );\n}\n\n/**\n * What the agent has actually done, newest first.\n *\n * The panel used to keep showing the paste-this-prompt UI after the agent was\n * already connected and driving — dead weight at exactly the moment the human\n * needs the opposite: visibility. A connected agent with no visible activity is\n * indistinguishable from a broken one, which is precisely how a stalled session\n * goes unnoticed.\n */\nfunction ActivityLog({ activity }: { activity?: AgentActivity[] }) {\n const entries = (activity ?? []).slice().reverse();\n\n if (entries.length === 0) {\n return (\n <p className=\"fai-share__empty\">\n Connected. Nothing yet — actions appear here as the agent takes them.\n </p>\n );\n }\n\n return (\n <ol className=\"fai-share__activity\" aria-live=\"polite\">\n {entries.map((entry) => (\n <li key={entry.id} className=\"fai-share__activity-row\" data-kind={entry.kind}>\n <time className=\"fai-share__activity-time\" dateTime={new Date(entry.at).toISOString()}>\n {new Date(entry.at).toLocaleTimeString(undefined, {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n })}\n </time>\n <span className=\"fai-share__activity-source\">{entry.source}</span>\n <span className=\"fai-share__activity-text\">{entry.text}</span>\n </li>\n ))}\n </ol>\n );\n}\n\nfunction TabButton({ tab, active, setTab, children }: { tab: Tab; active: Tab; setTab: (t: Tab) => void; children: React.ReactNode }) {\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={tab === active}\n className={`fai-share__tab${tab === active ? \" is-active\" : \"\"}`}\n onClick={() => setTab(tab)}\n >\n {children}\n </button>\n );\n}\n\nfunction CopyBox({ label, value, multiline }: { label: string; value: string; multiline?: boolean }) {\n const [copied, setCopied] = useState(false);\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n } catch {\n // ignore\n }\n };\n return (\n <div>\n <div className=\"fai-share__panel-label\">{label}</div>\n <div className=\"fai-share__copy\">\n <pre className={`fai-share__pre${multiline ? \" is-multi\" : \"\"}`}>{value}</pre>\n <button type=\"button\" className=\"fai-share__copy-btn\" onClick={copy}>\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * Build a copy-paste natural-language prompt to hand directly to an AI agent.\n * Agents handed a bare URL tend to try to *open it in a browser* — this spells\n * out that the link is a live MCP co-browsing session it should drive over MCP\n * tools (via the zero-install relay client), never visit.\n */\nexport function buildAgentPrompt(url: string): string {\n return [\n `You're joining a live Human+ co-browsing session on a web app. This is an MCP`,\n `(Model Context Protocol) session — NOT a website to visit. Do NOT open the URL`,\n `in a browser and do NOT use any browser/Playwright tool. You drive the real,`,\n `running app through MCP tools while a human watches and can take over.`,\n ``,\n `Session link (carries the session id + token — treat it as a secret):`,\n ` ${url}`,\n ``,\n `Connect by running the relay client as an MCP server (zero install):`,\n ` npx -y mcp-relay-client \"${url}\"`,\n ``,\n `That exposes the app's own tools (e.g. page_describe, page_read, nav_visit,`,\n `page_click, page_set_field, page_submit, plus surface tools like whiteboard_*).`,\n `Then:`,\n ` 1. Call page_describe first to see the current page and its interactive handles.`,\n ` 2. Act only on the STABLE HANDLES the tools return — never guess DOM selectors.`,\n ` 3. Navigate with nav_visit, type with page_set_field, click with page_click.`,\n ` Submits and destructive clicks are staged for the human to confirm.`,\n ``,\n `If you can't register an MCP server but can run a shell, drive it directly:`,\n ` curl -O https://raw.githubusercontent.com/Particle-Academy/mcp-relay-client/main/connect.sh`,\n ` bash connect.sh \"${url}\" tools`,\n ` bash connect.sh \"${url}\" call page_describe '{}'`,\n ].join(\"\\n\");\n}\n\n/** Build a copy-paste cURL recipe for connecting an external MCP client. */\nfunction buildCurlRecipe(session: SessionDescriptor): string {\n const base =\n typeof window !== \"undefined\"\n ? `${window.location.protocol}//${window.location.host}`\n : \"http://localhost\";\n const inbox = `${base}/agent-relay/${session.id}/inbox?token=${session.token}`;\n const events = `${base}/agent-relay/${session.id}/events?token=${session.token}`;\n return [\n `# 1) In one terminal, subscribe to server-pushed frames (SSE)`,\n `curl -N \"${events}\"`,\n ``,\n `# 2) In another terminal, send an initialize handshake`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}'`,\n ``,\n `# 3) List the tools the bridge exposes`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\"}'`,\n ``,\n `# 4) Add a sticky note`,\n `curl -X POST \"${inbox}\" \\\\`,\n ` -H 'content-type: application/json' \\\\`,\n ` -d '{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"whiteboard_add_sticky\",\"arguments\":{\"x\":300,\"y\":300,\"text\":\"hello from curl\"}}}'`,\n ].join(\"\\n\");\n}\n"]}
|
|
@@ -407,9 +407,9 @@ var SseRelayTransport = class {
|
|
|
407
407
|
this.peers.add(subscriberId);
|
|
408
408
|
this.notifyPeers();
|
|
409
409
|
fancyAutoCommon.emitActivity({
|
|
410
|
-
agentId: "agent",
|
|
411
|
-
agentName: "Agent",
|
|
412
|
-
agentColor: "#a855f7",
|
|
410
|
+
agentId: this.opts.agent?.id ?? "agent",
|
|
411
|
+
agentName: this.opts.agent?.name ?? "Agent",
|
|
412
|
+
agentColor: this.opts.agent?.color ?? "#a855f7",
|
|
413
413
|
action: "agent_connected",
|
|
414
414
|
timestamp: Date.now(),
|
|
415
415
|
target: { kind: "navigation", label: "Agent connected" },
|
|
@@ -423,9 +423,9 @@ var SseRelayTransport = class {
|
|
|
423
423
|
this.notifyPeers();
|
|
424
424
|
if (this.peers.size === 0) {
|
|
425
425
|
fancyAutoCommon.emitActivity({
|
|
426
|
-
agentId: "agent",
|
|
427
|
-
agentName: "Agent",
|
|
428
|
-
agentColor: "#a855f7",
|
|
426
|
+
agentId: this.opts.agent?.id ?? "agent",
|
|
427
|
+
agentName: this.opts.agent?.name ?? "Agent",
|
|
428
|
+
agentColor: this.opts.agent?.color ?? "#a855f7",
|
|
429
429
|
action: "agent_disconnected",
|
|
430
430
|
timestamp: Date.now(),
|
|
431
431
|
target: { kind: "navigation", label: "Agent disconnected" },
|
|
@@ -448,6 +448,15 @@ function attachSseRelay(server, options) {
|
|
|
448
448
|
transport.start();
|
|
449
449
|
Promise.resolve().then(() => (init_registry(), registry_exports)).then(({ onActivity: onActivity2 }) => {
|
|
450
450
|
const off = onActivity2((event) => {
|
|
451
|
+
if (options.activityFilter) {
|
|
452
|
+
let keep;
|
|
453
|
+
try {
|
|
454
|
+
keep = options.activityFilter(event);
|
|
455
|
+
} catch {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (!keep) return;
|
|
459
|
+
}
|
|
451
460
|
transport.send({
|
|
452
461
|
jsonrpc: "2.0",
|
|
453
462
|
method: "notifications/agent_activity",
|