@particle-academy/agent-integrations 0.14.0 → 0.16.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/{chunk-J5KYPEYB.js → chunk-GJSKBUOH.js} +4 -4
- package/dist/chunk-GJSKBUOH.js.map +1 -0
- package/dist/components-shared-whiteboard.cjs +3 -3
- package/dist/components-shared-whiteboard.cjs.map +1 -1
- package/dist/components-shared-whiteboard.js +2 -2
- package/dist/components-shared-whiteboard.js.map +1 -1
- package/dist/index.cjs +64 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -2
- package/dist/index.d.ts +36 -2
- package/dist/index.js +64 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-J5KYPEYB.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ShareControls, AgentCursor, AgentActivityHighlight, AgentPanel } from './chunk-
|
|
1
|
+
import { ShareControls, AgentCursor, AgentActivityHighlight, AgentPanel } from './chunk-GJSKBUOH.js';
|
|
2
2
|
import { createSessionDescriptor, attachSseRelay } from './chunk-CPNOF4HI.js';
|
|
3
3
|
import { attachInProcess } from './chunk-AFUULW5E.js';
|
|
4
4
|
import { registerWhiteboardBridge } from './chunk-3QJSOS7G.js';
|
|
@@ -18,7 +18,7 @@ function SharedWhiteboard({
|
|
|
18
18
|
initialStrokes = [],
|
|
19
19
|
initialViewport = { x: 0, y: 0, zoom: 1 },
|
|
20
20
|
agent = DEFAULT_AGENT,
|
|
21
|
-
shareBaseUrl = "/
|
|
21
|
+
shareBaseUrl = "/agent-relay",
|
|
22
22
|
onRegisterSession,
|
|
23
23
|
showAgentPanel = true,
|
|
24
24
|
showShareControls = true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SharedWhiteboard/SharedWhiteboard.tsx"],"names":[],"mappings":"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","file":"components-shared-whiteboard.js","sourcesContent":["import { type CSSProperties, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n Board,\n StickyNote,\n Connector,\n Shape,\n CursorLayer,\n type StickyNoteItem,\n type ShapeItem,\n type ConnectorItem,\n type Stroke,\n type RemoteCursor,\n type Viewport,\n} from \"@particle-academy/fancy-whiteboard\";\nimport { MicroMcpServer, type Transport } from \"../../mcp/server\";\nimport { attachInProcess, type InProcessTransport } from \"../../mcp/transports/in-process\";\nimport { attachSseRelay, type RelayState, type SseRelayTransport } from \"../../sharing/sse-relay\";\nimport { createSessionDescriptor, type SessionDescriptor } from \"../../sharing/token\";\nimport { registerWhiteboardBridge } from \"../../bridges/whiteboard\";\nimport type { Bridge } from \"../../bridges/types\";\nimport { ShareControls } from \"../ShareControls\";\nimport { AgentPanel, type AgentActivity } from \"../AgentPanel\";\nimport { AgentCursor } from \"../AgentCursor\";\nimport { AgentActivityHighlight } from \"../AgentActivityHighlight\";\n\nexport type SharedWhiteboardProps = {\n /** Initial board contents. */\n initialNotes?: StickyNoteItem[];\n initialShapes?: ShapeItem[];\n initialConnectors?: ConnectorItem[];\n initialStrokes?: Stroke[];\n initialViewport?: Viewport;\n\n /** Agent identity displayed in the panel + cursor. */\n agent?: { id: string; name?: string; color?: string };\n\n /**\n * Where the relay HTTP endpoints live. The host app implements these (see\n * docs/relay-protocol.md). Pass `null` to disable sharing — the board\n * still works locally with the in-process MCP server.\n */\n shareBaseUrl?: string | null;\n\n /**\n * Optional callback to register a new session token with the host's\n * relay broker. Receives `{ session, token }` and should return after\n * registration. Defaults to POSTing JSON to `${shareBaseUrl}/register`.\n */\n onRegisterSession?: (descriptor: SessionDescriptor) => Promise<void>;\n\n /** Show the agent panel. Default true. */\n showAgentPanel?: boolean;\n\n /** Show share controls. Default true. */\n showShareControls?: boolean;\n\n /** Auto-broadcast local edits as `notifications/state_update`. Default true. */\n broadcastEdits?: boolean;\n\n /** Pixel height of the board area. Default 640. */\n height?: number;\n\n /** Header content rendered above the board. */\n header?: ReactNode;\n\n className?: string;\n style?: CSSProperties;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * SharedWhiteboard — drop-in component that bundles every piece of the\n * \"agent-collaborative whiteboard\" UX: board with all primitives, in-page\n * MCP server, share controls, agent panel, presence cursor, activity\n * highlight, and outbound state broadcast.\n *\n * Most apps only need this one component. For deeper customization, swap\n * it for the lower-level primitives (Board, MicroMcpServer, ShareControls).\n */\nexport function SharedWhiteboard({\n initialNotes = [],\n initialShapes = [],\n initialConnectors = [],\n initialStrokes = [],\n initialViewport = { x: 0, y: 0, zoom: 1 },\n agent = DEFAULT_AGENT,\n shareBaseUrl = \"/whiteboard-share\",\n onRegisterSession,\n showAgentPanel = true,\n showShareControls = true,\n broadcastEdits = true,\n height = 640,\n header,\n className,\n style,\n}: SharedWhiteboardProps) {\n // Board state\n const [notes, setNotes] = useState<StickyNoteItem[]>(initialNotes);\n const [shapes, setShapes] = useState<ShapeItem[]>(initialShapes);\n const [connectors, setConnectors] = useState<ConnectorItem[]>(initialConnectors);\n const [strokes, setStrokes] = useState<Stroke[]>(initialStrokes);\n const [viewport, setViewport] = useState<Viewport>(initialViewport);\n const [agentCursor, setAgentCursor] = useState<RemoteCursor | null>(null);\n\n // Agent UX state\n const [activity, setActivity] = useState<AgentActivity[]>([]);\n const [highlight, setHighlight] = useState<{ pulseKey: number; bounds: { x: number; y: number; width: number; height: number } } | null>(null);\n\n const stateRefs = useRef({ notes, shapes, connectors, strokes, viewport });\n useEffect(() => { stateRefs.current = { notes, shapes, connectors, strokes, viewport }; }, [notes, shapes, connectors, strokes, viewport]);\n\n // MCP server + bridge\n const serverRef = useRef<MicroMcpServer | null>(null);\n const inProcRef = useRef<InProcessTransport | null>(null);\n const bridgeRef = useRef<Bridge | null>(null);\n\n useEffect(() => {\n const server = new MicroMcpServer({\n info: { name: \"shared-whiteboard\", version: \"0.2.0\" },\n instructions: \"Collaborative whiteboard. Use whiteboard_* tools to read or modify the board.\",\n });\n bridgeRef.current = registerWhiteboardBridge(server, {\n adapter: {\n getNotes: () => stateRefs.current.notes,\n setNotes: (next) => setNotes(typeof next === \"function\" ? next : () => next),\n getShapes: () => stateRefs.current.shapes,\n setShapes: (next) => setShapes(typeof next === \"function\" ? next : () => next),\n getConnectors: () => stateRefs.current.connectors,\n setConnectors: (next) => setConnectors(typeof next === \"function\" ? next : () => next),\n getStrokes: () => stateRefs.current.strokes,\n setStrokes: (next) => setStrokes(typeof next === \"function\" ? next : () => next),\n getViewport: () => stateRefs.current.viewport,\n setViewport,\n setAgentCursor,\n },\n agent,\n });\n inProcRef.current = attachInProcess(server);\n serverRef.current = server;\n\n // Pulse a highlight whenever a tool call returns a structured id.\n const off = inProcRef.current.onServerMessage((msg: any) => {\n if (msg?.id !== undefined && \"result\" in msg && msg.result?.structuredContent?.id) {\n const id = msg.result.structuredContent.id;\n requestAnimationFrame(() => pulseFor(id));\n }\n });\n return () => {\n off();\n bridgeRef.current?.dispose();\n bridgeRef.current = null;\n if (inProcRef.current) server.detach(inProcRef.current);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const pulseFor = (id: string) => {\n const n = stateRefs.current.notes.find((x) => x.id === id);\n if (n) return setHighlight({ pulseKey: Date.now(), bounds: { x: n.x, y: n.y, width: n.width, height: n.height } });\n const s = stateRefs.current.shapes.find((x) => x.id === id);\n if (s) return setHighlight({ pulseKey: Date.now(), bounds: { x: s.x, y: s.y, width: s.width, height: s.height } });\n };\n\n const log = useCallback((entry: Omit<AgentActivity, \"id\" | \"at\">) => {\n setActivity((all) => [...all.slice(-200), { id: `a_${Date.now()}_${all.length}`, at: Date.now(), ...entry }]);\n }, []);\n\n // Sharing\n const [session, setSession] = useState<SessionDescriptor | null>(null);\n const [relayState, setRelayState] = useState<RelayState>(\"idle\");\n const sseRef = useRef<SseRelayTransport | null>(null);\n const logEsRef = useRef<EventSource | null>(null);\n\n const startShare = async () => {\n if (session || !serverRef.current || !shareBaseUrl) return;\n const desc = createSessionDescriptor();\n\n try {\n if (onRegisterSession) {\n await onRegisterSession(desc);\n } else {\n const csrf = (document.querySelector('meta[name=\"csrf-token\"]') as HTMLMetaElement | null)?.content ?? \"\";\n const reg = await fetch(`${shareBaseUrl}/register`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf, accept: \"application/json\" },\n body: JSON.stringify({ session: desc.id, token: desc.token }),\n });\n if (!reg.ok) throw new Error(`registration failed (HTTP ${reg.status})`);\n }\n } catch (e) {\n log({ kind: \"error\", source: \"share\", text: e instanceof Error ? e.message : String(e) });\n return;\n }\n\n const relay = attachSseRelay(serverRef.current, {\n baseUrl: shareBaseUrl,\n sessionId: desc.id,\n token: desc.token,\n });\n sseRef.current = relay;\n relay.onStateChange(setRelayState);\n\n // Activity log mirror — does NOT call deliverFromRemote (relay does it).\n const es = new EventSource(`${shareBaseUrl}/${desc.id}/events?token=${desc.token}&direction=inbound`);\n es.addEventListener(\"mcp\", (ev: MessageEvent) => {\n try {\n const frame = JSON.parse(ev.data);\n if (frame.method === \"notifications/peer_joined\") {\n // External agent just opened an outbound subscription. Surface it\n // so the human can see \"an agent is connecting\" before any tools\n // arrive. The agent itself should follow up with set_agent_cursor\n // immediately, but in case it doesn't, drop a placeholder cursor\n // at the canvas origin so presence is visible right away.\n setAgentCursor((c) => c ?? { userId: agent.id, name: agent.name, color: agent.color, x: 60, y: 60 });\n log({ kind: \"info\", source: \"presence\", text: `${agent.name ?? \"Agent\"} connected` });\n return;\n }\n if (frame.method === \"notifications/peer_left\") {\n setAgentCursor(null);\n log({ kind: \"info\", source: \"presence\", text: `${agent.name ?? \"Agent\"} disconnected` });\n return;\n }\n if (frame.method === \"notifications/agent_message\") {\n log({ kind: \"message\", source: agent.name ?? \"Agent\", text: String(frame.params?.text ?? \"\") });\n } else if (frame.method === \"notifications/agent_status\") {\n log({ kind: \"info\", source: agent.name ?? \"Agent\", text: String(frame.params?.text ?? \"\") });\n } else if (frame.method?.startsWith(\"notifications/\")) {\n // ignore other notifications in the feed\n } else {\n log({ kind: \"tool\", source: \"remote\", text: `← ${frame.method ?? `id:${frame.id}`}`, detail: frame });\n }\n } catch {\n /* noop */\n }\n });\n logEsRef.current = es;\n\n setSession(desc);\n log({ kind: \"info\", source: \"share\", text: `Sharing started · session ${desc.id}` });\n };\n\n const stopShare = async () => {\n if (!session) return;\n const desc = session;\n setSession(null);\n logEsRef.current?.close();\n logEsRef.current = null;\n if (sseRef.current && serverRef.current) serverRef.current.detach(sseRef.current);\n sseRef.current = null;\n setRelayState(\"closed\");\n if (shareBaseUrl) {\n const csrf = (document.querySelector('meta[name=\"csrf-token\"]') as HTMLMetaElement | null)?.content ?? \"\";\n await fetch(`${shareBaseUrl}/${desc.id}/unregister?token=${encodeURIComponent(desc.token)}`, {\n method: \"POST\",\n headers: { \"x-csrf-token\": csrf, accept: \"application/json\" },\n }).catch(() => {});\n }\n log({ kind: \"info\", source: \"share\", text: \"Sharing stopped.\" });\n };\n\n // Outbound state broadcast — every state change pushes a notification on\n // the relay (capped to ~12 Hz) so external agents see human edits live.\n const lastBroadcastRef = useRef(0);\n useEffect(() => {\n if (!broadcastEdits || !sseRef.current || !session) return;\n const now = Date.now();\n if (now - lastBroadcastRef.current < 80) return;\n lastBroadcastRef.current = now;\n sseRef.current.send({\n jsonrpc: \"2.0\",\n method: \"notifications/state_update\",\n params: { notes, shapes, connectors, viewport, ts: now },\n });\n }, [notes, shapes, connectors, viewport, session, broadcastEdits]);\n\n const handleSubmit = (text: string) => {\n if (!sseRef.current) {\n log({ kind: \"error\", source: \"you\", text: \"Start a shared session first.\" });\n return;\n }\n sseRef.current.send({\n jsonrpc: \"2.0\",\n method: \"notifications/user_message\",\n params: { text, ts: Date.now() },\n });\n log({ kind: \"message\", source: \"You\", text });\n };\n\n // The agent cursor is rendered by <AgentCursor> below — keep it OUT of\n // the cursors array so we don't double-render it via CursorLayer.\n // (CursorLayer is reserved for human participants once relay sync lands.)\n const cursors: RemoteCursor[] = useMemo(() => [], []);\n const statusText = (() => {\n switch (relayState) {\n case \"open\": return \"live\";\n case \"connecting\": return \"connecting…\";\n case \"error\": return \"error\";\n case \"closed\": return \"closed\";\n default: return undefined;\n }\n })();\n\n return (\n <div className={[\"fai-shared-whiteboard\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n {header}\n {showShareControls && shareBaseUrl !== null && (\n <div className=\"fai-shared-whiteboard__controls\">\n <ShareControls session={session} onStart={startShare} onStop={stopShare} status={statusText} />\n </div>\n )}\n <div\n className=\"fai-shared-whiteboard__layout\"\n style={{\n display: \"grid\",\n gap: 16,\n gridTemplateColumns: showAgentPanel ? \"1fr 360px\" : \"1fr\",\n }}\n >\n <div\n className=\"fai-shared-whiteboard__board\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n borderRadius: 12,\n border: \"1px solid #e4e4e7\",\n background:\n \"radial-gradient(circle at 1px 1px, rgba(0,0,0,0.07) 1px, transparent 0)\",\n backgroundSize: \"20px 20px\",\n height,\n }}\n >\n <Board viewport={viewport} onViewportChange={setViewport} style={{ width: \"100%\", height: \"100%\" }}>\n {connectors.map((c) => {\n const a = resolveCenter(c.from, notes, shapes);\n const b = resolveCenter(c.to, notes, shapes);\n if (!a || !b) return null;\n return <Connector key={c.id} from={a} to={b} color={c.color ?? \"#64748b\"} />;\n })}\n {shapes.map((s) => (\n <Shape key={s.id} item={s} onChange={(next) => setShapes((all) => all.map((x) => (x.id === next.id ? next : x)))} />\n ))}\n {notes.map((n) => (\n <StickyNote key={n.id} item={n} onChange={(next) => setNotes((all) => all.map((x) => (x.id === next.id ? next : x)))} />\n ))}\n <CursorLayer cursors={cursors} />\n {agentCursor && (\n <AgentCursor x={agentCursor.x} y={agentCursor.y} name={agentCursor.name} color={agentCursor.color} />\n )}\n {highlight && (\n <AgentActivityHighlight\n x={highlight.bounds.x}\n y={highlight.bounds.y}\n width={highlight.bounds.width}\n height={highlight.bounds.height}\n color={agent.color ?? \"#a855f7\"}\n pulseKey={highlight.pulseKey}\n />\n )}\n </Board>\n </div>\n {showAgentPanel && (\n <div style={{ height }}>\n <AgentPanel\n agent={agent}\n activity={activity}\n onSubmit={handleSubmit}\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction resolveCenter(\n ref: ConnectorItem[\"from\"],\n notes: StickyNoteItem[],\n shapes: ShapeItem[],\n): { x: number; y: number } | null {\n if (typeof ref === \"string\") {\n const n = notes.find((x) => x.id === ref);\n if (n) return { x: n.x + n.width / 2, y: n.y + n.height / 2 };\n const s = shapes.find((x) => x.id === ref);\n if (s) return { x: s.x + s.width / 2, y: s.y + s.height / 2 };\n return null;\n }\n return ref;\n}\n\n// Internal-import safety\ntype _UseTransport = Transport;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/SharedWhiteboard/SharedWhiteboard.tsx"],"names":[],"mappings":"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","file":"components-shared-whiteboard.js","sourcesContent":["import { type CSSProperties, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n Board,\n StickyNote,\n Connector,\n Shape,\n CursorLayer,\n type StickyNoteItem,\n type ShapeItem,\n type ConnectorItem,\n type Stroke,\n type RemoteCursor,\n type Viewport,\n} from \"@particle-academy/fancy-whiteboard\";\nimport { MicroMcpServer, type Transport } from \"../../mcp/server\";\nimport { attachInProcess, type InProcessTransport } from \"../../mcp/transports/in-process\";\nimport { attachSseRelay, type RelayState, type SseRelayTransport } from \"../../sharing/sse-relay\";\nimport { createSessionDescriptor, type SessionDescriptor } from \"../../sharing/token\";\nimport { registerWhiteboardBridge } from \"../../bridges/whiteboard\";\nimport type { Bridge } from \"../../bridges/types\";\nimport { ShareControls } from \"../ShareControls\";\nimport { AgentPanel, type AgentActivity } from \"../AgentPanel\";\nimport { AgentCursor } from \"../AgentCursor\";\nimport { AgentActivityHighlight } from \"../AgentActivityHighlight\";\n\nexport type SharedWhiteboardProps = {\n /** Initial board contents. */\n initialNotes?: StickyNoteItem[];\n initialShapes?: ShapeItem[];\n initialConnectors?: ConnectorItem[];\n initialStrokes?: Stroke[];\n initialViewport?: Viewport;\n\n /** Agent identity displayed in the panel + cursor. */\n agent?: { id: string; name?: string; color?: string };\n\n /**\n * Where the relay HTTP endpoints live. The host app implements these (see\n * docs/relay-protocol.md). Pass `null` to disable sharing — the board\n * still works locally with the in-process MCP server.\n */\n shareBaseUrl?: string | null;\n\n /**\n * Optional callback to register a new session token with the host's\n * relay broker. Receives `{ session, token }` and should return after\n * registration. Defaults to POSTing JSON to `${shareBaseUrl}/register`.\n */\n onRegisterSession?: (descriptor: SessionDescriptor) => Promise<void>;\n\n /** Show the agent panel. Default true. */\n showAgentPanel?: boolean;\n\n /** Show share controls. Default true. */\n showShareControls?: boolean;\n\n /** Auto-broadcast local edits as `notifications/state_update`. Default true. */\n broadcastEdits?: boolean;\n\n /** Pixel height of the board area. Default 640. */\n height?: number;\n\n /** Header content rendered above the board. */\n header?: ReactNode;\n\n className?: string;\n style?: CSSProperties;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\n\n/**\n * SharedWhiteboard — drop-in component that bundles every piece of the\n * \"agent-collaborative whiteboard\" UX: board with all primitives, in-page\n * MCP server, share controls, agent panel, presence cursor, activity\n * highlight, and outbound state broadcast.\n *\n * Most apps only need this one component. For deeper customization, swap\n * it for the lower-level primitives (Board, MicroMcpServer, ShareControls).\n */\nexport function SharedWhiteboard({\n initialNotes = [],\n initialShapes = [],\n initialConnectors = [],\n initialStrokes = [],\n initialViewport = { x: 0, y: 0, zoom: 1 },\n agent = DEFAULT_AGENT,\n shareBaseUrl = \"/agent-relay\",\n onRegisterSession,\n showAgentPanel = true,\n showShareControls = true,\n broadcastEdits = true,\n height = 640,\n header,\n className,\n style,\n}: SharedWhiteboardProps) {\n // Board state\n const [notes, setNotes] = useState<StickyNoteItem[]>(initialNotes);\n const [shapes, setShapes] = useState<ShapeItem[]>(initialShapes);\n const [connectors, setConnectors] = useState<ConnectorItem[]>(initialConnectors);\n const [strokes, setStrokes] = useState<Stroke[]>(initialStrokes);\n const [viewport, setViewport] = useState<Viewport>(initialViewport);\n const [agentCursor, setAgentCursor] = useState<RemoteCursor | null>(null);\n\n // Agent UX state\n const [activity, setActivity] = useState<AgentActivity[]>([]);\n const [highlight, setHighlight] = useState<{ pulseKey: number; bounds: { x: number; y: number; width: number; height: number } } | null>(null);\n\n const stateRefs = useRef({ notes, shapes, connectors, strokes, viewport });\n useEffect(() => { stateRefs.current = { notes, shapes, connectors, strokes, viewport }; }, [notes, shapes, connectors, strokes, viewport]);\n\n // MCP server + bridge\n const serverRef = useRef<MicroMcpServer | null>(null);\n const inProcRef = useRef<InProcessTransport | null>(null);\n const bridgeRef = useRef<Bridge | null>(null);\n\n useEffect(() => {\n const server = new MicroMcpServer({\n info: { name: \"shared-whiteboard\", version: \"0.2.0\" },\n instructions: \"Collaborative whiteboard. Use whiteboard_* tools to read or modify the board.\",\n });\n bridgeRef.current = registerWhiteboardBridge(server, {\n adapter: {\n getNotes: () => stateRefs.current.notes,\n setNotes: (next) => setNotes(typeof next === \"function\" ? next : () => next),\n getShapes: () => stateRefs.current.shapes,\n setShapes: (next) => setShapes(typeof next === \"function\" ? next : () => next),\n getConnectors: () => stateRefs.current.connectors,\n setConnectors: (next) => setConnectors(typeof next === \"function\" ? next : () => next),\n getStrokes: () => stateRefs.current.strokes,\n setStrokes: (next) => setStrokes(typeof next === \"function\" ? next : () => next),\n getViewport: () => stateRefs.current.viewport,\n setViewport,\n setAgentCursor,\n },\n agent,\n });\n inProcRef.current = attachInProcess(server);\n serverRef.current = server;\n\n // Pulse a highlight whenever a tool call returns a structured id.\n const off = inProcRef.current.onServerMessage((msg: any) => {\n if (msg?.id !== undefined && \"result\" in msg && msg.result?.structuredContent?.id) {\n const id = msg.result.structuredContent.id;\n requestAnimationFrame(() => pulseFor(id));\n }\n });\n return () => {\n off();\n bridgeRef.current?.dispose();\n bridgeRef.current = null;\n if (inProcRef.current) server.detach(inProcRef.current);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const pulseFor = (id: string) => {\n const n = stateRefs.current.notes.find((x) => x.id === id);\n if (n) return setHighlight({ pulseKey: Date.now(), bounds: { x: n.x, y: n.y, width: n.width, height: n.height } });\n const s = stateRefs.current.shapes.find((x) => x.id === id);\n if (s) return setHighlight({ pulseKey: Date.now(), bounds: { x: s.x, y: s.y, width: s.width, height: s.height } });\n };\n\n const log = useCallback((entry: Omit<AgentActivity, \"id\" | \"at\">) => {\n setActivity((all) => [...all.slice(-200), { id: `a_${Date.now()}_${all.length}`, at: Date.now(), ...entry }]);\n }, []);\n\n // Sharing\n const [session, setSession] = useState<SessionDescriptor | null>(null);\n const [relayState, setRelayState] = useState<RelayState>(\"idle\");\n const sseRef = useRef<SseRelayTransport | null>(null);\n const logEsRef = useRef<EventSource | null>(null);\n\n const startShare = async () => {\n if (session || !serverRef.current || !shareBaseUrl) return;\n const desc = createSessionDescriptor();\n\n try {\n if (onRegisterSession) {\n await onRegisterSession(desc);\n } else {\n const csrf = (document.querySelector('meta[name=\"csrf-token\"]') as HTMLMetaElement | null)?.content ?? \"\";\n const reg = await fetch(`${shareBaseUrl}/register`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf, accept: \"application/json\" },\n body: JSON.stringify({ session: desc.id, token: desc.token }),\n });\n if (!reg.ok) throw new Error(`registration failed (HTTP ${reg.status})`);\n }\n } catch (e) {\n log({ kind: \"error\", source: \"share\", text: e instanceof Error ? e.message : String(e) });\n return;\n }\n\n const relay = attachSseRelay(serverRef.current, {\n baseUrl: shareBaseUrl,\n sessionId: desc.id,\n token: desc.token,\n });\n sseRef.current = relay;\n relay.onStateChange(setRelayState);\n\n // Activity log mirror — does NOT call deliverFromRemote (relay does it).\n const es = new EventSource(`${shareBaseUrl}/${desc.id}/events?token=${desc.token}&direction=inbound`);\n es.addEventListener(\"mcp\", (ev: MessageEvent) => {\n try {\n const frame = JSON.parse(ev.data);\n if (frame.method === \"notifications/peer_joined\") {\n // External agent just opened an outbound subscription. Surface it\n // so the human can see \"an agent is connecting\" before any tools\n // arrive. The agent itself should follow up with set_agent_cursor\n // immediately, but in case it doesn't, drop a placeholder cursor\n // at the canvas origin so presence is visible right away.\n setAgentCursor((c) => c ?? { userId: agent.id, name: agent.name, color: agent.color, x: 60, y: 60 });\n log({ kind: \"info\", source: \"presence\", text: `${agent.name ?? \"Agent\"} connected` });\n return;\n }\n if (frame.method === \"notifications/peer_left\") {\n setAgentCursor(null);\n log({ kind: \"info\", source: \"presence\", text: `${agent.name ?? \"Agent\"} disconnected` });\n return;\n }\n if (frame.method === \"notifications/agent_message\") {\n log({ kind: \"message\", source: agent.name ?? \"Agent\", text: String(frame.params?.text ?? \"\") });\n } else if (frame.method === \"notifications/agent_status\") {\n log({ kind: \"info\", source: agent.name ?? \"Agent\", text: String(frame.params?.text ?? \"\") });\n } else if (frame.method?.startsWith(\"notifications/\")) {\n // ignore other notifications in the feed\n } else {\n log({ kind: \"tool\", source: \"remote\", text: `← ${frame.method ?? `id:${frame.id}`}`, detail: frame });\n }\n } catch {\n /* noop */\n }\n });\n logEsRef.current = es;\n\n setSession(desc);\n log({ kind: \"info\", source: \"share\", text: `Sharing started · session ${desc.id}` });\n };\n\n const stopShare = async () => {\n if (!session) return;\n const desc = session;\n setSession(null);\n logEsRef.current?.close();\n logEsRef.current = null;\n if (sseRef.current && serverRef.current) serverRef.current.detach(sseRef.current);\n sseRef.current = null;\n setRelayState(\"closed\");\n if (shareBaseUrl) {\n const csrf = (document.querySelector('meta[name=\"csrf-token\"]') as HTMLMetaElement | null)?.content ?? \"\";\n await fetch(`${shareBaseUrl}/${desc.id}/unregister?token=${encodeURIComponent(desc.token)}`, {\n method: \"POST\",\n headers: { \"x-csrf-token\": csrf, accept: \"application/json\" },\n }).catch(() => {});\n }\n log({ kind: \"info\", source: \"share\", text: \"Sharing stopped.\" });\n };\n\n // Outbound state broadcast — every state change pushes a notification on\n // the relay (capped to ~12 Hz) so external agents see human edits live.\n const lastBroadcastRef = useRef(0);\n useEffect(() => {\n if (!broadcastEdits || !sseRef.current || !session) return;\n const now = Date.now();\n if (now - lastBroadcastRef.current < 80) return;\n lastBroadcastRef.current = now;\n sseRef.current.send({\n jsonrpc: \"2.0\",\n method: \"notifications/state_update\",\n params: { notes, shapes, connectors, viewport, ts: now },\n });\n }, [notes, shapes, connectors, viewport, session, broadcastEdits]);\n\n const handleSubmit = (text: string) => {\n if (!sseRef.current) {\n log({ kind: \"error\", source: \"you\", text: \"Start a shared session first.\" });\n return;\n }\n sseRef.current.send({\n jsonrpc: \"2.0\",\n method: \"notifications/user_message\",\n params: { text, ts: Date.now() },\n });\n log({ kind: \"message\", source: \"You\", text });\n };\n\n // The agent cursor is rendered by <AgentCursor> below — keep it OUT of\n // the cursors array so we don't double-render it via CursorLayer.\n // (CursorLayer is reserved for human participants once relay sync lands.)\n const cursors: RemoteCursor[] = useMemo(() => [], []);\n const statusText = (() => {\n switch (relayState) {\n case \"open\": return \"live\";\n case \"connecting\": return \"connecting…\";\n case \"error\": return \"error\";\n case \"closed\": return \"closed\";\n default: return undefined;\n }\n })();\n\n return (\n <div className={[\"fai-shared-whiteboard\", className ?? \"\"].filter(Boolean).join(\" \")} style={style}>\n {header}\n {showShareControls && shareBaseUrl !== null && (\n <div className=\"fai-shared-whiteboard__controls\">\n <ShareControls session={session} onStart={startShare} onStop={stopShare} status={statusText} />\n </div>\n )}\n <div\n className=\"fai-shared-whiteboard__layout\"\n style={{\n display: \"grid\",\n gap: 16,\n gridTemplateColumns: showAgentPanel ? \"1fr 360px\" : \"1fr\",\n }}\n >\n <div\n className=\"fai-shared-whiteboard__board\"\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n borderRadius: 12,\n border: \"1px solid #e4e4e7\",\n background:\n \"radial-gradient(circle at 1px 1px, rgba(0,0,0,0.07) 1px, transparent 0)\",\n backgroundSize: \"20px 20px\",\n height,\n }}\n >\n <Board viewport={viewport} onViewportChange={setViewport} style={{ width: \"100%\", height: \"100%\" }}>\n {connectors.map((c) => {\n const a = resolveCenter(c.from, notes, shapes);\n const b = resolveCenter(c.to, notes, shapes);\n if (!a || !b) return null;\n return <Connector key={c.id} from={a} to={b} color={c.color ?? \"#64748b\"} />;\n })}\n {shapes.map((s) => (\n <Shape key={s.id} item={s} onChange={(next) => setShapes((all) => all.map((x) => (x.id === next.id ? next : x)))} />\n ))}\n {notes.map((n) => (\n <StickyNote key={n.id} item={n} onChange={(next) => setNotes((all) => all.map((x) => (x.id === next.id ? next : x)))} />\n ))}\n <CursorLayer cursors={cursors} />\n {agentCursor && (\n <AgentCursor x={agentCursor.x} y={agentCursor.y} name={agentCursor.name} color={agentCursor.color} />\n )}\n {highlight && (\n <AgentActivityHighlight\n x={highlight.bounds.x}\n y={highlight.bounds.y}\n width={highlight.bounds.width}\n height={highlight.bounds.height}\n color={agent.color ?? \"#a855f7\"}\n pulseKey={highlight.pulseKey}\n />\n )}\n </Board>\n </div>\n {showAgentPanel && (\n <div style={{ height }}>\n <AgentPanel\n agent={agent}\n activity={activity}\n onSubmit={handleSubmit}\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction resolveCenter(\n ref: ConnectorItem[\"from\"],\n notes: StickyNoteItem[],\n shapes: ShapeItem[],\n): { x: number; y: number } | null {\n if (typeof ref === \"string\") {\n const n = notes.find((x) => x.id === ref);\n if (n) return { x: n.x + n.width / 2, y: n.y + n.height / 2 };\n const s = shapes.find((x) => x.id === ref);\n if (s) return { x: s.x + s.width / 2, y: s.y + s.height / 2 };\n return null;\n }\n return ref;\n}\n\n// Internal-import safety\ntype _UseTransport = Transport;\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var fancyAutoCommon = require('@particle-academy/fancy-auto-common');
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var fancySlides = require('@particle-academy/fancy-slides');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var reactDom = require('react-dom');
|
|
7
8
|
|
|
8
9
|
var __defProp = Object.defineProperty;
|
|
9
10
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -2342,12 +2343,13 @@ function registerNavigationBridge(host, options) {
|
|
|
2342
2343
|
},
|
|
2343
2344
|
[],
|
|
2344
2345
|
(args) => {
|
|
2346
|
+
const handle = typeof args.handle === "string" ? args.handle : void 0;
|
|
2345
2347
|
adapter.scrollTo({
|
|
2346
|
-
handle
|
|
2348
|
+
handle,
|
|
2347
2349
|
x: typeof args.x === "number" ? args.x : void 0,
|
|
2348
2350
|
y: typeof args.y === "number" ? args.y : void 0
|
|
2349
2351
|
});
|
|
2350
|
-
return textResult("Scrolled");
|
|
2352
|
+
return textResult("Scrolled", handle ? { handle, rect: adapter.rectFor?.(handle) ?? void 0 } : void 0);
|
|
2351
2353
|
},
|
|
2352
2354
|
() => target("Scroll")
|
|
2353
2355
|
);
|
|
@@ -2374,7 +2376,7 @@ function registerNavigationBridge(host, options) {
|
|
|
2374
2376
|
const handle = String(args.handle ?? "");
|
|
2375
2377
|
const res = adapter.setField(handle, args.value);
|
|
2376
2378
|
if (!res.ok) return errorResult(res.error ?? `Could not set ${handle}`);
|
|
2377
|
-
return textResult(`${handle} \u2190 ${JSON.stringify(args.value)}`, { handle, value: args.value });
|
|
2379
|
+
return textResult(`${handle} \u2190 ${JSON.stringify(args.value)}`, { handle, value: args.value, rect: adapter.rectFor?.(handle) ?? void 0 });
|
|
2378
2380
|
},
|
|
2379
2381
|
(args) => target(`Set ${String(args.handle ?? "")}`, String(args.handle ?? ""))
|
|
2380
2382
|
);
|
|
@@ -2386,13 +2388,14 @@ function registerNavigationBridge(host, options) {
|
|
|
2386
2388
|
async (args) => {
|
|
2387
2389
|
const handle = String(args.handle ?? "");
|
|
2388
2390
|
const action = adapter.describe().actions.find((a) => a.handle === handle);
|
|
2391
|
+
const rect = adapter.rectFor?.(handle) ?? void 0;
|
|
2389
2392
|
if (pendingMode && action?.destructive && adapter.confirm) {
|
|
2390
2393
|
const ok = await adapter.confirm({ action: "click", handle, label: action.label });
|
|
2391
2394
|
if (!ok) return errorResult("Declined by user");
|
|
2392
2395
|
}
|
|
2393
2396
|
const res = adapter.click(handle);
|
|
2394
2397
|
if (!res.ok) return errorResult(res.error ?? `Could not click ${handle}`);
|
|
2395
|
-
return textResult(`Clicked ${handle}`, { handle });
|
|
2398
|
+
return textResult(`Clicked ${handle}`, { handle, rect });
|
|
2396
2399
|
},
|
|
2397
2400
|
(args) => target(`Click ${String(args.handle ?? "")}`, String(args.handle ?? ""))
|
|
2398
2401
|
);
|
|
@@ -2403,13 +2406,14 @@ function registerNavigationBridge(host, options) {
|
|
|
2403
2406
|
["handle"],
|
|
2404
2407
|
async (args) => {
|
|
2405
2408
|
const handle = String(args.handle ?? "");
|
|
2409
|
+
const rect = adapter.rectFor?.(handle) ?? void 0;
|
|
2406
2410
|
if (pendingMode && adapter.confirm) {
|
|
2407
2411
|
const ok = await adapter.confirm({ action: "submit", handle, label: handle });
|
|
2408
2412
|
if (!ok) return errorResult("Declined by user");
|
|
2409
2413
|
}
|
|
2410
2414
|
const res = await adapter.submit(handle);
|
|
2411
2415
|
if (!res.ok) return errorResult(res.error ?? "Submit failed");
|
|
2412
|
-
return textResult(`Submitted ${handle}`, { handle });
|
|
2416
|
+
return textResult(`Submitted ${handle}`, { handle, rect });
|
|
2413
2417
|
},
|
|
2414
2418
|
(args) => target(`Submit ${String(args.handle ?? "")}`, String(args.handle ?? ""))
|
|
2415
2419
|
);
|
|
@@ -2598,7 +2602,7 @@ var USER = { id: "human", name: "You" };
|
|
|
2598
2602
|
function useCoBrowseSession(options) {
|
|
2599
2603
|
const { adapter, extraBridges } = options;
|
|
2600
2604
|
const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
|
|
2601
|
-
const relayBaseUrl = options.relayBaseUrl ?? "/
|
|
2605
|
+
const relayBaseUrl = options.relayBaseUrl ?? "/agent-relay";
|
|
2602
2606
|
const serverRef = react.useRef(null);
|
|
2603
2607
|
const relayRef = react.useRef(null);
|
|
2604
2608
|
const detachInProc = react.useRef(null);
|
|
@@ -3023,8 +3027,8 @@ function CopyBox({ label, value, multiline }) {
|
|
|
3023
3027
|
}
|
|
3024
3028
|
function buildCurlRecipe(session) {
|
|
3025
3029
|
const base = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.host}` : "http://localhost";
|
|
3026
|
-
const inbox = `${base}/
|
|
3027
|
-
const events = `${base}/
|
|
3030
|
+
const inbox = `${base}/agent-relay/${session.id}/inbox?token=${session.token}`;
|
|
3031
|
+
const events = `${base}/agent-relay/${session.id}/events?token=${session.token}`;
|
|
3028
3032
|
return [
|
|
3029
3033
|
`# 1) In one terminal, subscribe to server-pushed frames (SSE)`,
|
|
3030
3034
|
`curl -N "${events}"`,
|
|
@@ -3383,6 +3387,57 @@ function CoBrowsePresence({ session, connectUrl, shareBaseUrl, className }) {
|
|
|
3383
3387
|
] });
|
|
3384
3388
|
}
|
|
3385
3389
|
CoBrowsePresence.displayName = "CoBrowsePresence";
|
|
3390
|
+
function CoBrowseCursorLayer({ active = true, zIndex = 2147483e3 }) {
|
|
3391
|
+
const { latest } = useAgentActivity(void 0, { capacity: 12 });
|
|
3392
|
+
const [cursor, setCursor] = react.useState(
|
|
3393
|
+
null
|
|
3394
|
+
);
|
|
3395
|
+
const [pulse, setPulse] = react.useState(null);
|
|
3396
|
+
react.useEffect(() => {
|
|
3397
|
+
if (!latest || (latest.source ?? "agent") === "user") return;
|
|
3398
|
+
const color = latest.agentColor ?? "#a855f7";
|
|
3399
|
+
const name = latest.agentName ?? "Agent";
|
|
3400
|
+
const status = latest.target?.label ?? latest.action;
|
|
3401
|
+
const rect = latest.meta?.rect;
|
|
3402
|
+
if (rect) {
|
|
3403
|
+
setCursor({ x: rect.x + rect.width / 2, y: rect.y + rect.height / 2, name, color, status });
|
|
3404
|
+
setPulse({ rect, color, key: latest.timestamp });
|
|
3405
|
+
} else {
|
|
3406
|
+
setCursor(
|
|
3407
|
+
(prev) => prev ? { ...prev, status, name, color } : { x: window.innerWidth / 2, y: window.innerHeight / 2, name, color, status }
|
|
3408
|
+
);
|
|
3409
|
+
}
|
|
3410
|
+
}, [latest?.timestamp]);
|
|
3411
|
+
if (!active || !cursor || typeof document === "undefined") return null;
|
|
3412
|
+
return reactDom.createPortal(
|
|
3413
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-co-browse-cursor-layer": "", style: { position: "fixed", inset: 0, pointerEvents: "none", zIndex }, children: [
|
|
3414
|
+
pulse && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3415
|
+
AgentActivityHighlight,
|
|
3416
|
+
{
|
|
3417
|
+
x: pulse.rect.x,
|
|
3418
|
+
y: pulse.rect.y,
|
|
3419
|
+
width: pulse.rect.width,
|
|
3420
|
+
height: pulse.rect.height,
|
|
3421
|
+
color: pulse.color,
|
|
3422
|
+
pulseKey: pulse.key
|
|
3423
|
+
}
|
|
3424
|
+
),
|
|
3425
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3426
|
+
AgentCursor,
|
|
3427
|
+
{
|
|
3428
|
+
x: cursor.x,
|
|
3429
|
+
y: cursor.y,
|
|
3430
|
+
name: cursor.name,
|
|
3431
|
+
color: cursor.color,
|
|
3432
|
+
status: cursor.status,
|
|
3433
|
+
style: { transition: "left .35s cubic-bezier(.22,.61,.36,1), top .35s cubic-bezier(.22,.61,.36,1)" }
|
|
3434
|
+
}
|
|
3435
|
+
)
|
|
3436
|
+
] }),
|
|
3437
|
+
document.body
|
|
3438
|
+
);
|
|
3439
|
+
}
|
|
3440
|
+
CoBrowseCursorLayer.displayName = "CoBrowseCursorLayer";
|
|
3386
3441
|
|
|
3387
3442
|
// src/presence/index.ts
|
|
3388
3443
|
init_registry();
|
|
@@ -3512,6 +3567,7 @@ exports.CLAUDE_CONNECTORS_URL = CLAUDE_CONNECTORS_URL;
|
|
|
3512
3567
|
exports.CONNECTOR_GLYPHS = CONNECTOR_GLYPHS;
|
|
3513
3568
|
exports.CONNECTOR_TARGETS = CONNECTOR_TARGETS;
|
|
3514
3569
|
exports.ClaudeMark = ClaudeMark;
|
|
3570
|
+
exports.CoBrowseCursorLayer = CoBrowseCursorLayer;
|
|
3515
3571
|
exports.CoBrowsePresence = CoBrowsePresence;
|
|
3516
3572
|
exports.ConnectorButtons = ConnectorButtons;
|
|
3517
3573
|
exports.CursorMark = CursorMark;
|