@particle-academy/agent-integrations 0.50.0 → 0.52.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/CHANGELOG.md +91 -0
- package/README.md +69 -0
- package/dist/bridges/artboard.d.cts +3 -3
- package/dist/bridges/artboard.d.ts +3 -3
- package/dist/bridges/catalog.d.cts +3 -3
- package/dist/bridges/catalog.d.ts +3 -3
- package/dist/bridges/charts.d.cts +3 -3
- package/dist/bridges/charts.d.ts +3 -3
- package/dist/bridges/cms.d.cts +3 -3
- package/dist/bridges/cms.d.ts +3 -3
- package/dist/bridges/code.d.cts +3 -3
- package/dist/bridges/code.d.ts +3 -3
- package/dist/bridges/doc.d.cts +3 -3
- package/dist/bridges/doc.d.ts +3 -3
- package/dist/bridges/features.d.cts +3 -3
- package/dist/bridges/features.d.ts +3 -3
- package/dist/bridges/files.d.cts +3 -3
- package/dist/bridges/files.d.ts +3 -3
- package/dist/bridges/flow.d.cts +3 -3
- package/dist/bridges/flow.d.ts +3 -3
- package/dist/bridges/forms.d.cts +55 -10
- package/dist/bridges/forms.d.ts +55 -10
- package/dist/bridges/git.d.cts +3 -3
- package/dist/bridges/git.d.ts +3 -3
- package/dist/bridges/grid.d.cts +3 -3
- package/dist/bridges/grid.d.ts +3 -3
- package/dist/bridges/map.d.cts +3 -3
- package/dist/bridges/map.d.ts +3 -3
- package/dist/bridges/navigation.d.cts +3 -3
- package/dist/bridges/navigation.d.ts +3 -3
- package/dist/bridges/passkeys.d.cts +3 -3
- package/dist/bridges/passkeys.d.ts +3 -3
- package/dist/bridges/scene.d.cts +3 -3
- package/dist/bridges/scene.d.ts +3 -3
- package/dist/bridges/screen-doc.d.cts +3 -3
- package/dist/bridges/screen-doc.d.ts +3 -3
- package/dist/bridges/screens.d.cts +3 -3
- package/dist/bridges/screens.d.ts +3 -3
- package/dist/bridges/sheets.d.cts +3 -3
- package/dist/bridges/sheets.d.ts +3 -3
- package/dist/bridges/slides.d.cts +3 -3
- package/dist/bridges/slides.d.ts +3 -3
- package/dist/bridges/terminal.d.cts +3 -3
- package/dist/bridges/terminal.d.ts +3 -3
- package/dist/bridges/tui.d.cts +2 -2
- package/dist/bridges/tui.d.ts +2 -2
- package/dist/bridges/whiteboard.d.cts +3 -3
- package/dist/bridges/whiteboard.d.ts +3 -3
- package/dist/bridges-artboard.cjs +11 -5
- package/dist/bridges-artboard.cjs.map +1 -1
- package/dist/bridges-artboard.js +6 -4
- package/dist/bridges-artboard.js.map +1 -1
- package/dist/bridges-catalog.cjs +11 -5
- package/dist/bridges-catalog.cjs.map +1 -1
- package/dist/bridges-catalog.js +3 -3
- package/dist/bridges-charts.cjs +11 -5
- package/dist/bridges-charts.cjs.map +1 -1
- package/dist/bridges-charts.js +3 -3
- package/dist/bridges-cms.cjs +11 -5
- package/dist/bridges-cms.cjs.map +1 -1
- package/dist/bridges-cms.js +4 -4
- package/dist/bridges-code.cjs +11 -5
- package/dist/bridges-code.cjs.map +1 -1
- package/dist/bridges-code.js +3 -3
- package/dist/bridges-doc.cjs +11 -5
- package/dist/bridges-doc.cjs.map +1 -1
- package/dist/bridges-doc.js +3 -3
- package/dist/bridges-features.cjs +11 -5
- package/dist/bridges-features.cjs.map +1 -1
- package/dist/bridges-features.js +3 -3
- package/dist/bridges-files.cjs +11 -5
- package/dist/bridges-files.cjs.map +1 -1
- package/dist/bridges-files.js +3 -3
- package/dist/bridges-flow.cjs +11 -5
- package/dist/bridges-flow.cjs.map +1 -1
- package/dist/bridges-flow.js +6 -4
- package/dist/bridges-flow.js.map +1 -1
- package/dist/bridges-forms.cjs +123 -16
- package/dist/bridges-forms.cjs.map +1 -1
- package/dist/bridges-forms.js +4 -3
- package/dist/bridges-git.cjs +10 -5
- package/dist/bridges-git.cjs.map +1 -1
- package/dist/bridges-git.js +3 -3
- package/dist/bridges-grid.cjs +11 -5
- package/dist/bridges-grid.cjs.map +1 -1
- package/dist/bridges-grid.js +3 -3
- package/dist/bridges-map.cjs +11 -5
- package/dist/bridges-map.cjs.map +1 -1
- package/dist/bridges-map.js +3 -3
- package/dist/bridges-navigation.cjs +11 -5
- package/dist/bridges-navigation.cjs.map +1 -1
- package/dist/bridges-navigation.js +3 -3
- package/dist/bridges-passkeys.cjs +11 -5
- package/dist/bridges-passkeys.cjs.map +1 -1
- package/dist/bridges-passkeys.js +3 -3
- package/dist/bridges-scene.cjs +11 -5
- package/dist/bridges-scene.cjs.map +1 -1
- package/dist/bridges-scene.js +3 -3
- package/dist/bridges-screen-doc.cjs +14 -6
- package/dist/bridges-screen-doc.cjs.map +1 -1
- package/dist/bridges-screen-doc.js +4 -4
- package/dist/bridges-screens.cjs +15 -7
- package/dist/bridges-screens.cjs.map +1 -1
- package/dist/bridges-screens.js +4 -3
- package/dist/bridges-sheets.cjs +11 -5
- package/dist/bridges-sheets.cjs.map +1 -1
- package/dist/bridges-sheets.js +3 -3
- package/dist/bridges-slides.cjs +11 -5
- package/dist/bridges-slides.cjs.map +1 -1
- package/dist/bridges-slides.js +3 -3
- package/dist/bridges-terminal.cjs +11 -5
- package/dist/bridges-terminal.cjs.map +1 -1
- package/dist/bridges-terminal.js +3 -3
- package/dist/bridges-tui.cjs +1 -1
- package/dist/bridges-tui.cjs.map +1 -1
- package/dist/bridges-tui.js +2 -2
- package/dist/bridges-whiteboard.cjs +11 -5
- package/dist/bridges-whiteboard.cjs.map +1 -1
- package/dist/bridges-whiteboard.js +3 -3
- package/dist/{chunk-CZV3WUW5.js → chunk-3GFKC6OK.js} +20 -7
- package/dist/chunk-3GFKC6OK.js.map +1 -0
- package/dist/{chunk-JLHVQWOV.js → chunk-6Q3PMT7K.js} +4 -4
- package/dist/chunk-6Q3PMT7K.js.map +1 -0
- package/dist/{chunk-HOZCDDRA.js → chunk-7HHZBPDE.js} +9 -29
- package/dist/chunk-7HHZBPDE.js.map +1 -0
- package/dist/{chunk-VFWFT3OK.js → chunk-AL77RO25.js} +97 -17
- package/dist/chunk-AL77RO25.js.map +1 -0
- package/dist/{chunk-AXWMWYH5.js → chunk-C4AQ2YBW.js} +7 -6
- package/dist/chunk-C4AQ2YBW.js.map +1 -0
- package/dist/{chunk-NH6HUVXQ.js → chunk-CI5ZVHDY.js} +8 -6
- package/dist/chunk-CI5ZVHDY.js.map +1 -0
- package/dist/{chunk-5ZWNCHZS.js → chunk-CKJL5C7A.js} +8 -6
- package/dist/chunk-CKJL5C7A.js.map +1 -0
- package/dist/chunk-DPBAEWB5.js +28 -0
- package/dist/chunk-DPBAEWB5.js.map +1 -0
- package/dist/{chunk-BG3QXNM6.js → chunk-HNVHAY4A.js} +8 -6
- package/dist/chunk-HNVHAY4A.js.map +1 -0
- package/dist/{chunk-5M5ELTHE.js → chunk-KAEPC6N4.js} +8 -6
- package/dist/chunk-KAEPC6N4.js.map +1 -0
- package/dist/{chunk-3WVXAB3D.js → chunk-M423JOQ3.js} +3 -3
- package/dist/{chunk-3WVXAB3D.js.map → chunk-M423JOQ3.js.map} +1 -1
- package/dist/{chunk-SWWJUOCY.js → chunk-MKC633WU.js} +3 -3
- package/dist/{chunk-SWWJUOCY.js.map → chunk-MKC633WU.js.map} +1 -1
- package/dist/{chunk-LQB42OSA.js → chunk-MKJE6V4Z.js} +8 -6
- package/dist/chunk-MKJE6V4Z.js.map +1 -0
- package/dist/{chunk-MIDZWKIF.js → chunk-NB5AQIR2.js} +8 -6
- package/dist/chunk-NB5AQIR2.js.map +1 -0
- package/dist/{chunk-VMRUW4B4.js → chunk-OUUHFR4N.js} +8 -6
- package/dist/chunk-OUUHFR4N.js.map +1 -0
- package/dist/{chunk-FCXSR7I5.js → chunk-P6SJBP5T.js} +8 -6
- package/dist/chunk-P6SJBP5T.js.map +1 -0
- package/dist/{chunk-5JLTXHX6.js → chunk-PMPBI6I3.js} +7 -5
- package/dist/chunk-PMPBI6I3.js.map +1 -0
- package/dist/{chunk-4WVLZ6YP.js → chunk-PV4FZDYX.js} +8 -6
- package/dist/chunk-PV4FZDYX.js.map +1 -0
- package/dist/{chunk-3UUF5KKZ.js → chunk-QEVSNDJW.js} +8 -6
- package/dist/chunk-QEVSNDJW.js.map +1 -0
- package/dist/{chunk-VOCUGTZB.js → chunk-S4DA2UTJ.js} +8 -6
- package/dist/chunk-S4DA2UTJ.js.map +1 -0
- package/dist/{chunk-RVMM4BHK.js → chunk-V6EHKHSF.js} +8 -6
- package/dist/chunk-V6EHKHSF.js.map +1 -0
- package/dist/{chunk-36MKPTVD.js → chunk-VE7TRWZR.js} +8 -6
- package/dist/chunk-VE7TRWZR.js.map +1 -0
- package/dist/{chunk-Z5NL5D4J.js → chunk-VFUKZ6UA.js} +8 -6
- package/dist/chunk-VFUKZ6UA.js.map +1 -0
- package/dist/{chunk-3HVYUMQF.js → chunk-VHB3VE53.js} +8 -6
- package/dist/chunk-VHB3VE53.js.map +1 -0
- package/dist/{chunk-R4XXOGQH.js → chunk-ZDKYKJFH.js} +10 -6
- package/dist/chunk-ZDKYKJFH.js.map +1 -0
- package/dist/components-shared-whiteboard.cjs +29 -10
- package/dist/components-shared-whiteboard.cjs.map +1 -1
- package/dist/components-shared-whiteboard.js +3 -3
- package/dist/dom-navigation/index.d.cts +3 -3
- package/dist/dom-navigation/index.d.ts +3 -3
- package/dist/index.cjs +211 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -26
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.cts +5 -5
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/stdio.d.cts +3 -3
- package/dist/mcp/stdio.d.ts +3 -3
- package/dist/mcp.cjs +18 -5
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/presence/index.d.cts +1 -1
- package/dist/presence/index.d.ts +1 -1
- package/dist/{server-1y0n61R5.d.cts → server-DJJygNo1.d.cts} +2 -2
- package/dist/{server-vq6qVl3T.d.ts → server-Dwo9LOxh.d.ts} +2 -2
- package/dist/sharing/index.d.cts +3 -3
- package/dist/sharing/index.d.ts +3 -3
- package/dist/sheets-adapter.d.cts +3 -3
- package/dist/sheets-adapter.d.ts +3 -3
- package/dist/{tool-host-LYfdPE8u.d.ts → tool-host-BBSaU7IJ.d.cts} +10 -4
- package/dist/{tool-host-D67N2a2h.d.cts → tool-host-BqJRPr_T.d.ts} +10 -4
- package/dist/{types-DP5yQZQU.d.cts → types-D_H2f-wF.d.cts} +1 -1
- package/dist/{types-VX_9je7w.d.ts → types-D_TzdBsK.d.ts} +1 -1
- package/dist/{types-gzIpsUDE.d.cts → types-ITRQFAir.d.cts} +26 -1
- package/dist/{types-gzIpsUDE.d.ts → types-ITRQFAir.d.ts} +26 -1
- package/dist/undo/index.d.cts +2 -2
- package/dist/undo/index.d.ts +2 -2
- package/dist/undo.cjs +7 -3
- package/dist/undo.cjs.map +1 -1
- package/dist/undo.js +3 -3
- package/docs/multi-form-hosts.md +97 -0
- package/package.json +1 -1
- package/dist/chunk-36MKPTVD.js.map +0 -1
- package/dist/chunk-3HVYUMQF.js.map +0 -1
- package/dist/chunk-3UUF5KKZ.js.map +0 -1
- package/dist/chunk-4WVLZ6YP.js.map +0 -1
- package/dist/chunk-5JLTXHX6.js.map +0 -1
- package/dist/chunk-5M5ELTHE.js.map +0 -1
- package/dist/chunk-5ZWNCHZS.js.map +0 -1
- package/dist/chunk-AXWMWYH5.js.map +0 -1
- package/dist/chunk-BG3QXNM6.js.map +0 -1
- package/dist/chunk-CZV3WUW5.js.map +0 -1
- package/dist/chunk-FCXSR7I5.js.map +0 -1
- package/dist/chunk-HOZCDDRA.js.map +0 -1
- package/dist/chunk-JLHVQWOV.js.map +0 -1
- package/dist/chunk-LQB42OSA.js.map +0 -1
- package/dist/chunk-MIDZWKIF.js.map +0 -1
- package/dist/chunk-NH6HUVXQ.js.map +0 -1
- package/dist/chunk-R4XXOGQH.js.map +0 -1
- package/dist/chunk-RVMM4BHK.js.map +0 -1
- package/dist/chunk-VFWFT3OK.js.map +0 -1
- package/dist/chunk-VMRUW4B4.js.map +0 -1
- package/dist/chunk-VOCUGTZB.js.map +0 -1
- package/dist/chunk-Z5NL5D4J.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { M as MicroMcpServer } from './server-
|
|
2
|
-
export { a as McpServerOptions, T as Transport, e as errorResult, r as rpcError, t as textResult } from './server-
|
|
3
|
-
export { T as ToolHost, a as ToolRegistry } from './tool-host-
|
|
1
|
+
import { M as MicroMcpServer } from './server-DJJygNo1.cjs';
|
|
2
|
+
export { a as McpServerOptions, T as Transport, e as errorResult, r as rpcError, t as textResult } from './server-DJJygNo1.cjs';
|
|
3
|
+
export { T as ToolHost, a as ToolRegistry } from './tool-host-BBSaU7IJ.cjs';
|
|
4
4
|
export { InProcessTransport, RelayChannel, RelayTransport, attachInProcess, attachRelay } from './mcp/index.cjs';
|
|
5
|
-
export { C as CallToolResult,
|
|
5
|
+
export { C as CallToolResult, e as ContentBlock, I as InitializeResult, J as JsonObject, d as JsonRpcMessage, f as JsonRpcNotification, g as JsonRpcRequest, h as JsonValue, M as MCP_PROTOCOL_VERSION, R as RegisterToolOptions, c as ServerCapabilities, S as ServerInfo, i as ToolCallContext, T as ToolDefinition, a as ToolHandler } from './types-ITRQFAir.cjs';
|
|
6
6
|
export { HumanPlusDisposition, HumanPlusEvent, HumanPlusEventPage, HumanPlusEventQuery, HumanPlusEventStore, MemoryHumanPlusEventStore, NewHumanPlusEvent } from './human-plus/index.cjs';
|
|
7
7
|
export { TuiBridgeOptions, TuiSurfaceRegistryLike, registerTuiBridge } from './bridges/tui.cjs';
|
|
8
|
-
export { B as Bridge, a as BridgeFactory } from './types-
|
|
8
|
+
export { B as Bridge, a as BridgeFactory } from './types-D_H2f-wF.cjs';
|
|
9
9
|
import { FormFieldDescriptor } from './bridges/forms.cjs';
|
|
10
|
-
export { FormBridgeAdapter, FormBridgeOptions, registerFormBridge } from './bridges/forms.cjs';
|
|
10
|
+
export { FormAdapterCommit, FormAdapterResult, FormBridgeAdapter, FormBridgeOptions, FormConfirmRequest, registerFormBridge } from './bridges/forms.cjs';
|
|
11
11
|
export { SheetsBridgeAdapter, SheetsBridgeOptions, registerSheetsBridge } from './bridges/sheets.cjs';
|
|
12
12
|
export { SheetsAdapterOptions, SheetsCellHighlight, SheetsCellHighlightMap, SheetsHighlightOptions, UseSheetsAdapterResult, WorkbookLike, useSheetsActivityHighlights, useSheetsAdapter } from './sheets-adapter.cjs';
|
|
13
13
|
export { CodeBridgeAdapter, CodeBridgeOptions, registerCodeBridge } from './bridges/code.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { M as MicroMcpServer } from './server-
|
|
2
|
-
export { a as McpServerOptions, T as Transport, e as errorResult, r as rpcError, t as textResult } from './server-
|
|
3
|
-
export { T as ToolHost, a as ToolRegistry } from './tool-host-
|
|
1
|
+
import { M as MicroMcpServer } from './server-Dwo9LOxh.js';
|
|
2
|
+
export { a as McpServerOptions, T as Transport, e as errorResult, r as rpcError, t as textResult } from './server-Dwo9LOxh.js';
|
|
3
|
+
export { T as ToolHost, a as ToolRegistry } from './tool-host-BqJRPr_T.js';
|
|
4
4
|
export { InProcessTransport, RelayChannel, RelayTransport, attachInProcess, attachRelay } from './mcp/index.js';
|
|
5
|
-
export { C as CallToolResult,
|
|
5
|
+
export { C as CallToolResult, e as ContentBlock, I as InitializeResult, J as JsonObject, d as JsonRpcMessage, f as JsonRpcNotification, g as JsonRpcRequest, h as JsonValue, M as MCP_PROTOCOL_VERSION, R as RegisterToolOptions, c as ServerCapabilities, S as ServerInfo, i as ToolCallContext, T as ToolDefinition, a as ToolHandler } from './types-ITRQFAir.js';
|
|
6
6
|
export { HumanPlusDisposition, HumanPlusEvent, HumanPlusEventPage, HumanPlusEventQuery, HumanPlusEventStore, MemoryHumanPlusEventStore, NewHumanPlusEvent } from './human-plus/index.js';
|
|
7
7
|
export { TuiBridgeOptions, TuiSurfaceRegistryLike, registerTuiBridge } from './bridges/tui.js';
|
|
8
|
-
export { B as Bridge, a as BridgeFactory } from './types-
|
|
8
|
+
export { B as Bridge, a as BridgeFactory } from './types-D_TzdBsK.js';
|
|
9
9
|
import { FormFieldDescriptor } from './bridges/forms.js';
|
|
10
|
-
export { FormBridgeAdapter, FormBridgeOptions, registerFormBridge } from './bridges/forms.js';
|
|
10
|
+
export { FormAdapterCommit, FormAdapterResult, FormBridgeAdapter, FormBridgeOptions, FormConfirmRequest, registerFormBridge } from './bridges/forms.js';
|
|
11
11
|
export { SheetsBridgeAdapter, SheetsBridgeOptions, registerSheetsBridge } from './bridges/sheets.js';
|
|
12
12
|
export { SheetsAdapterOptions, SheetsCellHighlight, SheetsCellHighlightMap, SheetsHighlightOptions, UseSheetsAdapterResult, WorkbookLike, useSheetsActivityHighlights, useSheetsAdapter } from './sheets-adapter.js';
|
|
13
13
|
export { CodeBridgeAdapter, CodeBridgeOptions, registerCodeBridge } from './bridges/code.js';
|
package/dist/index.js
CHANGED
|
@@ -4,45 +4,46 @@ import './chunk-IJ6JX5VC.js';
|
|
|
4
4
|
import { createSessionDescriptor, attachSseRelay } from './chunk-6TZ5IBRN.js';
|
|
5
5
|
export { SseRelayTransport, attachSseRelay, buildShareConfig, buildShareUrl, createSessionDescriptor, describeSession, readSessionFromUrl } from './chunk-6TZ5IBRN.js';
|
|
6
6
|
export { attachHeuristicsSink, mapActivityToEvent as mapActivityToHeuristicsEvent } from './chunk-7R6RMROL.js';
|
|
7
|
-
export { useUndoStack } from './chunk-
|
|
8
|
-
export { registerTuiBridge } from './chunk-
|
|
7
|
+
export { useUndoStack } from './chunk-M423JOQ3.js';
|
|
8
|
+
export { registerTuiBridge } from './chunk-6Q3PMT7K.js';
|
|
9
9
|
import { useAgentActivity } from './chunk-UCKJAUBY.js';
|
|
10
10
|
export { useAgentActivity, useAgentActivityForScreen } from './chunk-UCKJAUBY.js';
|
|
11
|
-
import { registerNavigationBridge } from './chunk-
|
|
12
|
-
export { registerNavigationBridge } from './chunk-
|
|
11
|
+
import { registerNavigationBridge } from './chunk-HNVHAY4A.js';
|
|
12
|
+
export { registerNavigationBridge } from './chunk-HNVHAY4A.js';
|
|
13
13
|
export { MemoryHumanPlusEventStore } from './chunk-PMI4C5S4.js';
|
|
14
14
|
export { useSheetsActivityHighlights, useSheetsAdapter } from './chunk-KHKSQEMC.js';
|
|
15
15
|
import { ConnectorButtons } from './chunk-5HNTNIWY.js';
|
|
16
16
|
export { CLAUDE_CONNECTORS_URL, CONNECTOR_GLYPHS, CONNECTOR_TARGETS, ClaudeMark, ConnectorButtons, CursorMark, DesktopMark, VscodeMark, WrenchMark, buildCursorDeeplink, buildManualConfig, buildManualConfigSnippet, buildVscodeDeeplink, connectorHref, encodeBase64Json, slugifyServerName } from './chunk-5HNTNIWY.js';
|
|
17
17
|
export { DEFAULT_MCPB_ENTRY_POINT, MCPB_MANIFEST_VERSION, MCPB_MIN_NODE, buildMcpbManifest, buildMcpbProxyStub } from './chunk-GO2Y6H6U.js';
|
|
18
|
-
export { registerGitBridge } from './chunk-
|
|
19
|
-
export { registerFilesBridge } from './chunk-
|
|
20
|
-
export { registerTerminalBridge } from './chunk-
|
|
21
|
-
export { registerCatalogBridge } from './chunk-
|
|
22
|
-
export { registerFeaturesBridge } from './chunk-
|
|
23
|
-
export { PASSKEY_BRIDGE_TOOLS, registerPasskeyBridge } from './chunk-
|
|
24
|
-
export { cmsReducer, registerCmsBridge } from './chunk-
|
|
25
|
-
export { registerCodeBridge } from './chunk-
|
|
26
|
-
export { registerChartsBridge } from './chunk-
|
|
27
|
-
export { registerGridBridge } from './chunk-
|
|
28
|
-
export { registerSceneBridge } from './chunk-
|
|
29
|
-
export { registerScreensBridge } from './chunk-
|
|
30
|
-
export { SCREEN_TEXT_NODE_TYPE, registerScreenDocBridge } from './chunk-
|
|
31
|
-
export { registerDocBridge } from './chunk-
|
|
32
|
-
export { registerSlidesBridge } from './chunk-
|
|
33
|
-
export { registerMapBridge } from './chunk-
|
|
18
|
+
export { registerGitBridge } from './chunk-C4AQ2YBW.js';
|
|
19
|
+
export { registerFilesBridge } from './chunk-VFUKZ6UA.js';
|
|
20
|
+
export { registerTerminalBridge } from './chunk-CKJL5C7A.js';
|
|
21
|
+
export { registerCatalogBridge } from './chunk-CI5ZVHDY.js';
|
|
22
|
+
export { registerFeaturesBridge } from './chunk-KAEPC6N4.js';
|
|
23
|
+
export { PASSKEY_BRIDGE_TOOLS, registerPasskeyBridge } from './chunk-PV4FZDYX.js';
|
|
24
|
+
export { cmsReducer, registerCmsBridge } from './chunk-MKC633WU.js';
|
|
25
|
+
export { registerCodeBridge } from './chunk-P6SJBP5T.js';
|
|
26
|
+
export { registerChartsBridge } from './chunk-VE7TRWZR.js';
|
|
27
|
+
export { registerGridBridge } from './chunk-NB5AQIR2.js';
|
|
28
|
+
export { registerSceneBridge } from './chunk-V6EHKHSF.js';
|
|
29
|
+
export { registerScreensBridge } from './chunk-7HHZBPDE.js';
|
|
30
|
+
export { SCREEN_TEXT_NODE_TYPE, registerScreenDocBridge } from './chunk-PMPBI6I3.js';
|
|
31
|
+
export { registerDocBridge } from './chunk-VHB3VE53.js';
|
|
32
|
+
export { registerSlidesBridge } from './chunk-OUUHFR4N.js';
|
|
33
|
+
export { registerMapBridge } from './chunk-QEVSNDJW.js';
|
|
34
34
|
export { RelayTransport, attachRelay } from './chunk-G6N2TQVO.js';
|
|
35
35
|
import { attachInProcess } from './chunk-AFUULW5E.js';
|
|
36
36
|
export { InProcessTransport, attachInProcess } from './chunk-AFUULW5E.js';
|
|
37
|
-
import { registerFormBridge } from './chunk-
|
|
38
|
-
export { registerFormBridge } from './chunk-
|
|
39
|
-
|
|
40
|
-
export {
|
|
37
|
+
import { registerFormBridge } from './chunk-AL77RO25.js';
|
|
38
|
+
export { registerFormBridge } from './chunk-AL77RO25.js';
|
|
39
|
+
import './chunk-DPBAEWB5.js';
|
|
40
|
+
export { registerSheetsBridge } from './chunk-S4DA2UTJ.js';
|
|
41
|
+
export { clearStack as clearUndoStack, ensureUndoToolsRegistered, pushUndoEntry, readHistory as readUndoHistory, redoOne, registerUndoTools, resetAllUndoStacks, undoOne } from './chunk-ZDKYKJFH.js';
|
|
41
42
|
export { wrapToolWithActivity } from './chunk-2VENWGLZ.js';
|
|
42
43
|
import { emitActivity, onActivity } from './chunk-C3TYI5TJ.js';
|
|
43
44
|
export { emitActivity, onActivity, readActivityHistory, resetActivityRegistry } from './chunk-C3TYI5TJ.js';
|
|
44
|
-
import { MicroMcpServer } from './chunk-
|
|
45
|
-
export { MCP_PROTOCOL_VERSION, MicroMcpServer, ToolRegistry, errorResult, rpcError, textResult } from './chunk-
|
|
45
|
+
import { MicroMcpServer } from './chunk-3GFKC6OK.js';
|
|
46
|
+
export { MCP_PROTOCOL_VERSION, MicroMcpServer, ToolRegistry, errorResult, rpcError, textResult } from './chunk-3GFKC6OK.js';
|
|
46
47
|
import { useRef, useState, useEffect, useCallback, useMemo } from 'react';
|
|
47
48
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
48
49
|
import { createPortal } from 'react-dom';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sharing/bridge-contributions.ts","../src/sharing/use-co-browse-session.ts","../src/components/BridgedForm/BridgedForm.tsx","../src/components/ScreensActivityBridge/ScreensActivityBridge.tsx","../src/components/CoBrowsePresence/CoBrowsePresence.tsx","../src/components/CoBrowseCursorLayer/CoBrowseCursorLayer.tsx","../src/components/SimulateUsersButton/SimulateUsersButton.tsx"],"names":["useRef","useEffect","useMemo","jsx","LIFECYCLE_ACTIONS","useState","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type { MicroMcpServer } from \"../mcp/server\";\n\n/**\n * A page's contribution to the shared tool surface.\n *\n * Return the disposer that withdraws it — typically the `Bridge`'s own\n * `dispose`, or the function `registerTool` returns. Returning nothing is\n * allowed (the original `extraBridges` was typed that way) but means the\n * contribution can never be withdrawn.\n */\nexport type BridgeContribution = (server: MicroMcpServer) => (() => void) | void;\n\n/**\n * The registry behind **\"site tools always; page tools while mounted\"**.\n *\n * `useCoBrowseSession` already had an `extraBridges` hook and already called it.\n * What that shape could not express is a tool surface that CHANGES under the\n * agent mid-session, because the callback is invoked exactly once while the\n * server is being built:\n *\n * - a page that mounts later never gets a chance to contribute;\n * - a page that unmounts cannot withdraw, so the agent keeps a tool aimed at\n * a surface that is gone and only finds out by calling it.\n *\n * Both are silent. Nothing errors; the agent just never sees the tools, or sees\n * dead ones. So contributions live in a registry that is applied when a server\n * appears, re-applied if it is replaced, and withdrawn when the page unmounts —\n * rather than a callback captured at construction.\n *\n * Withdrawal needs no notification machinery of its own: a bridge's disposer\n * unregisters its tools, `ToolRegistry` fires `onToolsChanged`, and\n * `MicroMcpServer` broadcasts `notifications/tools/list_changed`. That was\n * verified before this was written — a grep for `unregisterTool` reads as\n * \"nothing unregisters\", which is a false negative, because bridges use the\n * disposer `registerTool` returns.\n */\nexport class BridgeContributions {\n private readonly contributions = new Map<symbol, BridgeContribution>();\n private readonly applied = new Map<symbol, () => void>();\n private server: MicroMcpServer | null = null;\n\n /**\n * Contribute bridges for as long as the returned disposer is uncalled.\n *\n * Applies immediately when a server is already live, and is held for the next\n * one otherwise — so a page need not know whether sharing has started.\n */\n add(contribute: BridgeContribution): () => void {\n const key = Symbol(\"bridge-contribution\");\n this.contributions.set(key, contribute);\n if (this.server) this.apply(key, contribute, this.server);\n\n return () => {\n this.contributions.delete(key);\n this.withdraw(key);\n };\n }\n\n /** Attach a server and apply every live contribution to it. */\n bind(server: MicroMcpServer): void {\n if (this.server === server) return;\n if (this.server) this.unbind();\n this.server = server;\n for (const [key, contribute] of this.contributions) this.apply(key, contribute, server);\n }\n\n /**\n * Detach the current server, withdrawing what was applied to it. Contributions\n * themselves are KEPT: a session can be stopped and restarted under a page\n * that never unmounted, and its tools must come back rather than silently\n * vanish.\n */\n unbind(): void {\n for (const key of [...this.applied.keys()]) this.withdraw(key);\n this.server = null;\n }\n\n private apply(key: symbol, contribute: BridgeContribution, server: MicroMcpServer): void {\n const dispose = contribute(server);\n if (typeof dispose === \"function\") this.applied.set(key, dispose);\n }\n\n private withdraw(key: symbol): void {\n const dispose = this.applied.get(key);\n this.applied.delete(key);\n dispose?.();\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { MicroMcpServer } from \"../mcp/server\";\nimport { attachInProcess } from \"../mcp/transports\";\nimport { attachSseRelay, type RelayState, type SseRelayTransport } from \"./sse-relay\";\nimport { createSessionDescriptor, type SessionDescriptor } from \"./token\";\nimport { emitActivity } from \"../presence/registry\";\nimport type { AgentActivityEvent } from \"../presence/types\";\nimport { registerNavigationBridge, type NavigationBridgeAdapter } from \"../bridges/navigation\";\nimport { BridgeContributions, type BridgeContribution } from \"./bridge-contributions\";\n\n/** A thing the human did, surfaced so the connected agent stays aware. */\nexport type CoBrowseUserEvent =\n | { kind: \"navigation\"; url: string; title?: string; revision?: number }\n | { kind: \"scroll\"; y: number; revision?: number }\n | { kind: \"form\"; handle: string; value?: unknown; masked?: boolean; revision?: number }\n | { kind: \"click\"; handle: string; label?: string; revision?: number };\n\nexport type UseCoBrowseSessionOptions = {\n /**\n * The navigation adapter (Inertia + DOM in the sandbox). MUST be stable —\n * its methods should read live state via refs, since the bridge captures it\n * once on mount. Memoize it.\n */\n adapter: NavigationBridgeAdapter;\n /** Identity for the agent's presence (cursor/log color + name). */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Which activity events this session forwards to its agent.\n *\n * Only needed when a page runs MORE THAN ONE session — site co-browse plus\n * the agent playground, say. The activity bus is global to the page, so\n * without a filter each relay forwards the other's traffic and every agent\n * sees every other agent's navigations.\n *\n * Omitted forwards everything, which is right for the single-session case.\n */\n activityFilter?: (event: AgentActivityEvent) => boolean;\n /** Relay base path. Default \"/agent-relay\" (the generic frame broker). */\n relayBaseUrl?: string;\n /** MCP server info advertised to the agent. */\n info?: { name: string; version: string; instructions?: string };\n /**\n * Register extra bridges (forms/screens/…) on the same server, once, at\n * construction.\n *\n * For a surface that comes and goes with navigation use\n * {@link CoBrowseSession.contributeBridges} instead: this callback fires\n * exactly once while the server is built, so a page mounted afterwards can\n * never contribute through it, and one that unmounts can never withdraw.\n */\n extraBridges?: (server: MicroMcpServer) => void;\n /** CSRF token for the relay register/unregister POSTs. */\n csrfToken?: () => string | null | undefined;\n /** Stage submit + destructive clicks for human confirm. Default true. */\n pendingMode?: boolean;\n};\n\nexport type CoBrowseSession = {\n server: MicroMcpServer | null;\n /**\n * Contribute bridges for as long as the returned disposer is uncalled —\n * \"site tools always; page tools while mounted\".\n *\n * Call it from a page's mount effect and return its disposer:\n *\n * ```tsx\n * useEffect(() => contributeBridges((server) =>\n * registerArtboardBridge(server, { adapter }).dispose), []);\n * ```\n *\n * Safe to call before sharing starts — the contribution is applied to the\n * server as soon as one exists, and re-applied if the session is restarted.\n */\n contributeBridges: (contribute: BridgeContribution) => () => void;\n session: SessionDescriptor | null;\n relayState: RelayState;\n /**\n * True once at least one remote agent is actually attached to the session.\n *\n * Distinct from `relayState === \"open\"`, which only says the BROWSER reached\n * the relay — true the moment sharing starts, before the link has been handed\n * to anyone. A UI that keys \"Agent is driving\" off the relay state therefore\n * announces a driver who does not exist, and stays silent when a real one\n * arrives.\n */\n agentConnected: boolean;\n /** How many remote agents are attached (0 when nobody has joined). */\n agentCount: number;\n startShare: () => Promise<void>;\n stopShare: () => void;\n /**\n * Report a human action so the connected agent is notified. Emits a\n * `source:\"user\"` activity event, which the SSE relay forwards to the agent\n * as a `notifications/agent_activity` frame.\n */\n observeUser: (event: CoBrowseUserEvent) => void;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst USER = { id: \"human\", name: \"You\" };\n\n/**\n * Site-wide co-browsing session: one persistent in-page `MicroMcpServer` running\n * the navigation bridge, joinable by an external agent over the relay. Mount it\n * once at the app root; render `<CoBrowsePresence>` to show the agent + a Stop\n * control. The host wires `observeUser(...)` to navigation/scroll/form listeners\n * so the agent sees what the human does.\n */\nexport function useCoBrowseSession(options: UseCoBrowseSessionOptions): CoBrowseSession {\n const { adapter, extraBridges } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const relayBaseUrl = options.relayBaseUrl ?? \"/agent-relay\";\n\n const serverRef = useRef<MicroMcpServer | null>(null);\n // Survives re-renders AND server rebuilds: a page's contribution outlives any\n // one session, which is the entire reason this is not a captured callback.\n const contributionsRef = useRef<BridgeContributions>(null as unknown as BridgeContributions);\n if (!contributionsRef.current) contributionsRef.current = new BridgeContributions();\n const relayRef = useRef<SseRelayTransport | null>(null);\n const detachInProc = useRef<(() => void) | null>(null);\n const disposeBridge = useRef<(() => void) | null>(null);\n\n const [session, setSession] = useState<SessionDescriptor | null>(null);\n const [relayState, setRelayState] = useState<RelayState>(\"idle\");\n const [agentCount, setAgentCount] = useState(0);\n\n // Build the server + bridges once. The adapter is captured here, so it must\n // be stable (its methods read live state).\n useEffect(() => {\n const server = new MicroMcpServer({\n info: options.info ?? { name: \"fancy-co-browse\", version: \"0.1.0\" },\n instructions:\n options.info?.instructions ??\n \"Co-browse with a watching human. Call page_describe first; navigate, scroll, and (with confirm) fill/click via stable handles. You receive notifications/agent_activity for the human's actions (source:\\\"user\\\").\",\n });\n const bridge = registerNavigationBridge(server, { adapter, agent, pendingMode: options.pendingMode });\n extraBridges?.(server);\n // Apply whatever pages are already mounted, and keep the registry attached\n // so later mounts/unmounts add and withdraw live.\n contributionsRef.current.bind(server);\n const inProc = attachInProcess(server);\n detachInProc.current = () => inProc.close();\n disposeBridge.current = bridge.dispose;\n serverRef.current = server;\n\n return () => {\n relayRef.current?.close();\n relayRef.current = null;\n contributionsRef.current.unbind();\n disposeBridge.current?.();\n detachInProc.current?.();\n serverRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const startShare = useCallback(async () => {\n const server = serverRef.current;\n if (!server || relayRef.current) return;\n const descriptor = createSessionDescriptor();\n const csrf = options.csrfToken?.() ?? \"\";\n const response = await fetch(`${relayBaseUrl}/register`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf },\n body: JSON.stringify({ session: descriptor.id, token: descriptor.token }),\n });\n if (!response.ok) {\n throw new Error(`Relay registration failed (${response.status})`);\n }\n // Pass the session's agent identity down so the relay stamps its own\n // connect/disconnect events with it, and so a host that runs a SECOND\n // session (the agent playground alongside site co-browse) has something to\n // scope on. Without an `agent` this behaves exactly as before.\n const relay = attachSseRelay(server, {\n baseUrl: relayBaseUrl,\n sessionId: descriptor.id,\n token: descriptor.token,\n agent: options.agent,\n activityFilter: options.activityFilter,\n });\n relay.onStateChange(setRelayState);\n relay.onPeersChange(setAgentCount);\n relayRef.current = relay;\n setSession(descriptor);\n }, [relayBaseUrl, options]);\n\n const stopShare = useCallback(() => {\n const current = session;\n relayRef.current?.close();\n relayRef.current = null;\n setRelayState(\"idle\");\n setAgentCount(0);\n setSession(null);\n if (current) {\n const csrf = options.csrfToken?.() ?? \"\";\n void fetch(`${relayBaseUrl}/${current.id}/unregister?token=${encodeURIComponent(current.token)}`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf },\n }).catch(() => {});\n }\n }, [relayBaseUrl, options, session]);\n\n const observeUser = useCallback((event: CoBrowseUserEvent) => {\n const label =\n event.kind === \"navigation\"\n ? `You navigated to ${event.url}`\n : event.kind === \"scroll\"\n ? \"You scrolled\"\n : event.kind === \"click\"\n ? `You clicked ${event.label ?? event.handle}`\n : `You edited ${event.handle}${event.masked ? \" (hidden)\" : \"\"}`;\n emitActivity({\n agentId: USER.id,\n agentName: USER.name,\n source: \"user\",\n target: { kind: \"navigation\", label },\n action: `user_${event.kind}`,\n timestamp: Date.now(),\n meta: event as Record<string, unknown>,\n });\n }, []);\n\n // Stable identity: a page passes this straight into a mount effect, so a new\n // function each render would re-register its bridges on every render.\n const contributeBridges = useCallback(\n (contribute: BridgeContribution) => contributionsRef.current.add(contribute),\n [],\n );\n\n return {\n server: serverRef.current,\n contributeBridges,\n session,\n relayState,\n agentConnected: agentCount > 0,\n agentCount,\n startShare,\n stopShare,\n observeUser,\n };\n}\n","import { type ReactNode, useEffect, useMemo, useRef } from \"react\";\nimport type { MicroMcpServer } from \"../../mcp/server\";\nimport { registerFormBridge, type FormBridgeAdapter, type FormFieldDescriptor } from \"../../bridges/forms\";\n\nexport type BridgedFormProps = {\n /** Stable id for this form. Used by agents in `form_*` tool calls. */\n id: string;\n /** Human title (also surfaced as the bridge title). */\n title?: string;\n /** Optional fancy-screens screen id this form lives in. */\n screenId?: string;\n /** Field descriptors — drives the agent-facing schema. */\n fields: FormFieldDescriptor[];\n /** Controlled values. */\n values: Record<string, unknown>;\n /** Setter — hosts pass their setState. */\n onChange: (next: Record<string, unknown>) => void;\n /** Optional submit handler. */\n onSubmit?: () => Promise<{ ok: boolean; values?: Record<string, unknown>; error?: string }>;\n /** The MicroMcpServer the bridge registers against. Pass null/undefined\n * to render without a bridge (useful for stories / non-shared use). */\n server?: MicroMcpServer | null;\n /** Identity used in activity events. */\n agent?: { id: string; name?: string; color?: string };\n children: ReactNode;\n};\n\n/**\n * BridgedForm — wraps a react-fancy form (or any controlled inputs)\n * with a `registerFormBridge` lifecycle. Children render the actual form\n * using `values` + `onChange`; this component only manages the bridge.\n *\n * Hosts use it like:\n *\n * <BridgedForm id=\"signup\" fields={...} values={values} onChange={setValues} server={server}>\n * <Field><Input value={values.email} onValueChange={(v) => onChange({ ...values, email: v })} /></Field>\n * ...\n * </BridgedForm>\n *\n * Agents can then call form_describe, form_set_value, form_submit, etc.\n */\nexport function BridgedForm({\n id,\n title,\n screenId,\n fields,\n values,\n onChange,\n onSubmit,\n server,\n agent,\n children,\n}: BridgedFormProps) {\n // Refs so the adapter sees fresh values without re-installing the bridge.\n const valuesRef = useRef(values);\n const onChangeRef = useRef(onChange);\n const fieldsRef = useRef(fields);\n const submitRef = useRef(onSubmit);\n useEffect(() => { valuesRef.current = values; }, [values]);\n useEffect(() => { onChangeRef.current = onChange; }, [onChange]);\n useEffect(() => { fieldsRef.current = fields; }, [fields]);\n useEffect(() => { submitRef.current = onSubmit; }, [onSubmit]);\n\n const focusElement = (name: string) => {\n if (typeof document === \"undefined\") return;\n const el = document.querySelector(`[data-form-id=\"${id}\"] [name=\"${name}\"]`) as HTMLElement | null;\n el?.focus();\n };\n\n const adapter = useMemo<FormBridgeAdapter>(() => ({\n id,\n title,\n screenId,\n getFields: () => fieldsRef.current,\n getValue: (name) => valuesRef.current[name],\n getValues: () => ({ ...valuesRef.current }),\n setValue: (name, v) => onChangeRef.current({ ...valuesRef.current, [name]: v }),\n setValues: (next) => onChangeRef.current({ ...valuesRef.current, ...next }),\n focus: focusElement,\n submit: async () => {\n if (!submitRef.current) {\n return { ok: true, values: { ...valuesRef.current } };\n }\n return submitRef.current();\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }), [id, title, screenId]);\n\n useEffect(() => {\n if (!server) return;\n const bridge = registerFormBridge(server, { adapter, agent });\n return () => bridge.dispose();\n }, [server, adapter, agent]);\n\n return <div data-form-id={id}>{children}</div>;\n}\n","import { useEffect } from \"react\";\nimport { onActivity } from \"../../presence/registry\";\n\n/**\n * Loose shape of the fancy-screens system context — kept here so this\n * component doesn't hard-import `@particle-academy/fancy-screens`.\n */\ntype ScreenSystemLike = {\n registry: Map<string, { id: string; agentActivity?: unknown }>;\n updateScreen: (id: string, patch: { agentActivity?: unknown }) => void;\n};\n\nexport type ScreensActivityBridgeProps = {\n /** The value returned by `useScreenSystem()` from fancy-screens. */\n system: ScreenSystemLike;\n /** ms to wait after the last activity before clearing the screen's badge. Default 1500. */\n fadeMs?: number;\n};\n\n/**\n * ScreensActivityBridge — subscribe to the in-process activity registry\n * and patch each event into the matching screen's `agentActivity` field.\n * Fade-out clears the badge after `fadeMs`.\n *\n * Use it once near the root of your app, ABOVE every <Screen>:\n *\n * const system = useScreenSystem();\n * <>\n * <ScreensActivityBridge system={system} />\n * <Screen id=\"dashboard\">…</Screen>\n * <Screen id=\"form\">…</Screen>\n * </>\n *\n * Renders nothing; pure side-effect component.\n */\nexport function ScreensActivityBridge({ system, fadeMs = 1500 }: ScreensActivityBridgeProps) {\n useEffect(() => {\n const fadeTimers = new Map<string, ReturnType<typeof setTimeout>>();\n const off = onActivity((event) => {\n const screenId = event.target.screenId;\n if (!screenId) return;\n // Only patch screens that are currently registered.\n if (!system.registry.has(screenId)) return;\n const activity = {\n agentId: event.agentId,\n agentName: event.agentName,\n agentColor: event.agentColor,\n action: event.action,\n timestamp: event.timestamp,\n elementId: event.target.elementId,\n label: event.target.label,\n };\n system.updateScreen(screenId, { agentActivity: activity });\n const prev = fadeTimers.get(screenId);\n if (prev) clearTimeout(prev);\n fadeTimers.set(\n screenId,\n setTimeout(() => {\n system.updateScreen(screenId, { agentActivity: null });\n fadeTimers.delete(screenId);\n }, event.ttlMs ?? fadeMs),\n );\n });\n return () => {\n off();\n for (const t of fadeTimers.values()) clearTimeout(t);\n };\n }, [system, fadeMs]);\n return null;\n}\n","import { useMemo } from \"react\";\nimport { useAgentActivity } from \"../../presence/use-agent-activity\";\nimport { ShareControls } from \"../ShareControls/ShareControls\";\nimport { ConnectorButtons } from \"../../connectors/ConnectorButtons\";\nimport type { AgentActivity } from \"../AgentPanel\";\nimport type { AgentActivityEvent } from \"../../presence/types\";\nimport type { CoBrowseSession } from \"../../sharing/use-co-browse-session\";\n\nexport type CoBrowsePresenceProps = {\n /** The session from `useCoBrowseSession`. */\n session: CoBrowseSession;\n /** Public MCP/connect URL shown to the user (for ConnectorButtons), optional. */\n connectUrl?: string;\n /** Base URL used to build the shareable session link. */\n shareBaseUrl?: string;\n className?: string;\n};\n\n/** Lifecycle chatter — real to the session, but not something the agent *did*. */\nconst LIFECYCLE_ACTIONS = new Set([\"agent_connected\", \"agent_disconnected\"]);\n\n/**\n * The human's view of a site-wide co-browsing session: a \"Let an agent drive\"\n * starter, the share/connect surface until an agent arrives, a live log of what\n * it is doing once one has, and a Stop / take-back-control button.\n *\n * Staged-action confirms are rendered by the HOST (via the navigation adapter's\n * `confirm`), so this component stays presentation-only.\n */\nexport function CoBrowsePresence({ session, connectUrl, shareBaseUrl, className }: CoBrowsePresenceProps) {\n const { events } = useAgentActivity(undefined, { capacity: 40 });\n const lastAgentAction = [...events]\n .reverse()\n .find((e) => (e.source ?? \"agent\") !== \"user\" && !LIFECYCLE_ACTIONS.has(e.action));\n\n // Whether an agent is HERE, not whether the browser reached the relay. The\n // latter is true the instant sharing starts, so keying the badge on it told\n // every human \"Agent is driving\" before they had handed the link to anyone.\n const connected = session.agentConnected;\n\n const activity = useMemo(() => events.map(toPanelActivity), [events]);\n\n if (!session.session) {\n return (\n <div className={className} data-co-browse-presence=\"idle\">\n <button type=\"button\" onClick={() => void session.startShare()} data-co-browse-start>\n Let an agent drive\n </button>\n </div>\n );\n }\n\n return (\n <div className={className} data-co-browse-presence={connected ? \"connected\" : \"waiting\"}>\n <div data-co-browse-bar>\n <span data-co-browse-dot data-state={session.relayState} />\n <span data-co-browse-status>\n {connected ? \"Agent is driving\" : `Waiting for an agent… (${session.relayState})`}\n </span>\n {lastAgentAction && <span data-co-browse-last>{lastAgentAction.target?.label ?? lastAgentAction.action}</span>}\n <button type=\"button\" onClick={session.stopShare} data-co-browse-stop>\n Stop\n </button>\n </div>\n\n <ShareControls\n session={session.session}\n onStart={() => void session.startShare()}\n onStop={session.stopShare}\n status={session.relayState}\n agentConnected={connected}\n activity={activity}\n shareBaseUrl={shareBaseUrl}\n />\n\n {connectUrl && <ConnectorButtons serverName=\"Fancy UI co-browse\" mcpUrl={connectUrl} />}\n </div>\n );\n}\n\n/**\n * Presence event → the `AgentActivity` row `<ShareControls>` / `<AgentPanel>`\n * render. One shape for both, so a host already collecting presence needs no\n * second stream.\n */\nfunction toPanelActivity(event: AgentActivityEvent): AgentActivity {\n const who = (event.source ?? \"agent\") === \"user\" ? \"You\" : (event.agentName ?? \"Agent\");\n return {\n id: `${event.timestamp}-${event.action}-${event.target?.elementId ?? event.target?.label ?? \"\"}`,\n at: event.timestamp,\n kind: LIFECYCLE_ACTIONS.has(event.action) ? \"info\" : \"tool\",\n source: who,\n text: event.target?.label ?? event.action,\n detail: event.meta,\n };\n}\n\nCoBrowsePresence.displayName = \"CoBrowsePresence\";\n","import { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useAgentActivity } from \"../../presence/use-agent-activity\";\nimport { AgentCursor } from \"../AgentCursor/AgentCursor\";\nimport { AgentActivityHighlight } from \"../AgentActivityHighlight/AgentActivityHighlight\";\n\ntype Rect = { x: number; y: number; width: number; height: number };\n\nconst CURSOR_EDGE_INSET = 24;\nconst FLUID_CURSOR_SPEED_PX_PER_SECOND = 1_050;\nconst MIN_GLIDE_MS = 240;\nconst MAX_GLIDE_MS = 1_200;\n\nexport function visibleCursorPoint(rect: Rect, viewport: { width: number; height: number }) {\n const x = rect.x + rect.width / 2;\n const y = rect.y + rect.height / 2;\n return {\n x: Math.min(Math.max(x, CURSOR_EDGE_INSET), Math.max(CURSOR_EDGE_INSET, viewport.width - CURSOR_EDGE_INSET)),\n y: Math.min(Math.max(y, CURSOR_EDGE_INSET), Math.max(CURSOR_EDGE_INSET, viewport.height - CURSOR_EDGE_INSET)),\n };\n}\n\nexport function fluidGlideDuration(from: { x: number; y: number } | null, to: { x: number; y: number }) {\n if (!from) return 0;\n const distance = Math.hypot(to.x - from.x, to.y - from.y);\n return Math.round(Math.min(MAX_GLIDE_MS, Math.max(MIN_GLIDE_MS, (distance / FLUID_CURSOR_SPEED_PX_PER_SECOND) * 1_000)));\n}\n\nexport type CoBrowseCursorLayerProps = {\n /** Render the overlay only while a session is live. Default true. */\n active?: boolean;\n /** Stacking order of the overlay. Default just under the max. */\n zIndex?: number;\n /**\n * Retire the cursor after this long without a tool call. Default 15s;\n * `0` keeps it on screen indefinitely.\n *\n * A cursor that sits still is not neutral — it reads as \"the agent is\n * broken\", which is worse than showing nothing. Continuous presence belongs\n * in the activity log; the cursor is for *motion*.\n */\n idleAfterMs?: number;\n};\n\n/**\n * Session lifecycle chatter. Real events, but nothing the agent DID — so they\n * must never conjure a cursor. `agent_connected` used to, parking a motionless\n * pointer captioned \"Agent connected\" in the middle of the viewport for a\n * session in which the agent had not yet made a single tool call.\n */\nconst LIFECYCLE_ACTIONS = new Set([\"agent_connected\", \"agent_disconnected\"]);\n\n/**\n * Page-wide agent presence for co-browsing — the missing \"all actors present\"\n * half of Human+ UX. A fixed, click-through overlay (portaled to <body>) that\n * shows the connected agent as a live cursor + pings/highlights the element it\n * just acted on, gliding between targets. Same visual language as the whiteboard\n * demo's agent cursor, but mapped from the navigation bridge's STABLE HANDLES\n * (the agent has no real mouse) — each tool reports the acted element's viewport\n * rect in `meta.rect` (see `NavigationBridgeAdapter.rectFor`).\n *\n * Mount it once near the app root (e.g. in your CoBrowseProvider), gated on an\n * active session. SSR-safe: renders null on the server / until the first action.\n */\nexport function CoBrowseCursorLayer({\n active = true,\n zIndex = 2147483000,\n idleAfterMs = 15_000,\n}: CoBrowseCursorLayerProps) {\n const { latest } = useAgentActivity(undefined, { capacity: 12 });\n const [cursor, setCursor] = useState<{ x: number; y: number; name: string; color: string; status?: string; glideMs: number } | null>(\n null,\n );\n const [pulse, setPulse] = useState<{ rect: Rect; color: string; key: number } | null>(null);\n // Timestamp of the last real tool call — the only thing that keeps the cursor\n // alive. Deliberately NOT bumped by lifecycle events, so a relay client\n // reconnecting every call can't hold a stale pointer on screen forever.\n const [lastActionAt, setLastActionAt] = useState(0);\n\n useEffect(() => {\n if (!latest || (latest.source ?? \"agent\") === \"user\") return;\n if (LIFECYCLE_ACTIONS.has(latest.action)) {\n // Connecting is not acting. Relay clients may also be intentionally\n // short-lived (one process per MCP call), so a disconnect is not the end\n // of the session either — if a cursor is already on screen from real work,\n // leave it and just say so. What we must NOT do is create one: an agent\n // that has connected and done nothing has nowhere to point.\n setCursor((prev) => (prev ? { ...prev, status: \"Standing by\", glideMs: 0 } : null));\n setPulse(null);\n return;\n }\n setLastActionAt(latest.timestamp);\n const color = latest.agentColor ?? \"#a855f7\";\n const name = latest.agentName ?? \"Agent\";\n const status = latest.target?.label ?? latest.action;\n const rect = (latest.meta as { rect?: Rect } | undefined)?.rect;\n if (rect) {\n // Keep off-screen targets represented at the nearest viewport edge, then\n // glide at a distance-aware pace that a watching human can comfortably\n // follow. This is presence, not a teleport animation.\n const target = visibleCursorPoint(rect, { width: window.innerWidth, height: window.innerHeight });\n const reduceMotion = window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n setCursor((prev) => ({\n ...target,\n name,\n color,\n status,\n glideMs: reduceMotion ? 0 : fluidGlideDuration(prev, target),\n }));\n setPulse({ rect, color, key: latest.timestamp });\n } else {\n // nav / scroll — no element. Keep (or first-show, at viewport center) the\n // cursor so the agent stays visibly present; just refresh its caption.\n setCursor((prev) =>\n prev\n ? { ...prev, status, name, color }\n : { x: window.innerWidth / 2, y: window.innerHeight / 2, name, color, status, glideMs: 0 },\n );\n }\n }, [latest?.timestamp]);\n\n // Retire the cursor once the agent goes quiet. Presence that never changes\n // stops being information — the human reads a frozen pointer as a hung agent,\n // and the activity log is where \"still connected\" is supposed to live.\n useEffect(() => {\n if (!idleAfterMs || !lastActionAt) return;\n const timer = setTimeout(() => {\n setCursor(null);\n setPulse(null);\n }, idleAfterMs);\n return () => clearTimeout(timer);\n }, [lastActionAt, idleAfterMs]);\n\n if (!active || !cursor || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div data-co-browse-cursor-layer=\"\" style={{ position: \"fixed\", inset: 0, pointerEvents: \"none\", zIndex }}>\n {pulse && (\n <AgentActivityHighlight\n x={pulse.rect.x}\n y={pulse.rect.y}\n width={pulse.rect.width}\n height={pulse.rect.height}\n color={pulse.color}\n pulseKey={pulse.key}\n />\n )}\n <AgentCursor\n x={cursor.x}\n y={cursor.y}\n name={cursor.name}\n color={cursor.color}\n status={cursor.status}\n style={{\n transition: cursor.glideMs\n ? `left ${cursor.glideMs}ms cubic-bezier(.22,.61,.36,1), top ${cursor.glideMs}ms cubic-bezier(.22,.61,.36,1)`\n : \"none\",\n }}\n />\n </div>,\n document.body,\n );\n}\n\nCoBrowseCursorLayer.displayName = \"CoBrowseCursorLayer\";\n","import { type CSSProperties, useState } from \"react\";\n\nexport type SimulateUsersButtonProps = {\n /** Endpoint that injects the fake active users. Default `/active-users/simulate`. */\n endpoint?: string;\n /** How many fake users to simulate (sent as `count`). Default `10`. */\n count?: number;\n /** Button label. Default `Simulate {count} active users`. */\n label?: string;\n /**\n * CSRF token sent as `X-CSRF-TOKEN`. If omitted, falls back to a\n * `<meta name=\"csrf-token\">` on the page (the Laravel default).\n */\n csrfToken?: string;\n /** Called after a successful trigger. */\n onTriggered?: () => void;\n /** Called if the request fails. */\n onError?: (error: unknown) => void;\n className?: string;\n style?: CSSProperties;\n};\n\nfunction resolveCsrf(explicit?: string): string | undefined {\n if (explicit) return explicit;\n if (typeof document === \"undefined\") return undefined;\n return document.querySelector<HTMLMetaElement>('meta[name=\"csrf-token\"]')?.content;\n}\n\n/**\n * A button that asks the host to inject N **fake** active users (injected\n * dummies, not real accounts) so the live ActiveUser stream / presence overlay\n * has something to animate in a demo. POSTs `{ count }` to `endpoint`.\n *\n * Self-contained (inline styles, no react-fancy dependency) so it drops into any\n * host. The fakes + their staggered activity are produced server-side; this\n * button only triggers them.\n */\nexport function SimulateUsersButton({\n endpoint = \"/active-users/simulate\",\n count = 10,\n label,\n csrfToken,\n onTriggered,\n onError,\n className,\n style,\n}: SimulateUsersButtonProps) {\n const [busy, setBusy] = useState(false);\n\n async function trigger() {\n if (busy) return;\n setBusy(true);\n try {\n const token = resolveCsrf(csrfToken);\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Requested-With\": \"XMLHttpRequest\",\n ...(token ? { \"X-CSRF-TOKEN\": token } : {}),\n },\n credentials: \"same-origin\",\n body: JSON.stringify({ count }),\n });\n if (!res.ok) throw new Error(`Simulate request failed: ${res.status}`);\n onTriggered?.();\n } catch (err) {\n onError?.(err);\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <button\n type=\"button\"\n data-fai-simulate-users=\"\"\n className={[\"fai-simulate-users\", className ?? \"\"].filter(Boolean).join(\" \")}\n onClick={trigger}\n disabled={busy}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"8px 14px\",\n borderRadius: 8,\n border: \"1px solid rgba(139,92,246,0.4)\",\n background: busy ? \"rgba(139,92,246,0.15)\" : \"rgba(139,92,246,0.1)\",\n color: \"#7c3aed\",\n font: \"inherit\",\n fontSize: 13,\n fontWeight: 500,\n cursor: busy ? \"progress\" : \"pointer\",\n opacity: busy ? 0.7 : 1,\n ...style,\n }}\n >\n <span aria-hidden>{busy ? \"⏳\" : \"✨\"}</span>\n {label ?? `Simulate ${count} active users`}\n </button>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/sharing/bridge-contributions.ts","../src/sharing/use-co-browse-session.ts","../src/components/BridgedForm/BridgedForm.tsx","../src/components/ScreensActivityBridge/ScreensActivityBridge.tsx","../src/components/CoBrowsePresence/CoBrowsePresence.tsx","../src/components/CoBrowseCursorLayer/CoBrowseCursorLayer.tsx","../src/components/SimulateUsersButton/SimulateUsersButton.tsx"],"names":["useRef","useEffect","useMemo","jsx","LIFECYCLE_ACTIONS","useState","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["import type { MicroMcpServer } from \"../mcp/server\";\n\n/**\n * A page's contribution to the shared tool surface.\n *\n * Return the disposer that withdraws it — typically the `Bridge`'s own\n * `dispose`, or the function `registerTool` returns. Returning nothing is\n * allowed (the original `extraBridges` was typed that way) but means the\n * contribution can never be withdrawn.\n */\nexport type BridgeContribution = (server: MicroMcpServer) => (() => void) | void;\n\n/**\n * The registry behind **\"site tools always; page tools while mounted\"**.\n *\n * `useCoBrowseSession` already had an `extraBridges` hook and already called it.\n * What that shape could not express is a tool surface that CHANGES under the\n * agent mid-session, because the callback is invoked exactly once while the\n * server is being built:\n *\n * - a page that mounts later never gets a chance to contribute;\n * - a page that unmounts cannot withdraw, so the agent keeps a tool aimed at\n * a surface that is gone and only finds out by calling it.\n *\n * Both are silent. Nothing errors; the agent just never sees the tools, or sees\n * dead ones. So contributions live in a registry that is applied when a server\n * appears, re-applied if it is replaced, and withdrawn when the page unmounts —\n * rather than a callback captured at construction.\n *\n * Withdrawal needs no notification machinery of its own: a bridge's disposer\n * unregisters its tools, `ToolRegistry` fires `onToolsChanged`, and\n * `MicroMcpServer` broadcasts `notifications/tools/list_changed`. That was\n * verified before this was written — a grep for `unregisterTool` reads as\n * \"nothing unregisters\", which is a false negative, because bridges use the\n * disposer `registerTool` returns.\n */\nexport class BridgeContributions {\n private readonly contributions = new Map<symbol, BridgeContribution>();\n private readonly applied = new Map<symbol, () => void>();\n private server: MicroMcpServer | null = null;\n\n /**\n * Contribute bridges for as long as the returned disposer is uncalled.\n *\n * Applies immediately when a server is already live, and is held for the next\n * one otherwise — so a page need not know whether sharing has started.\n */\n add(contribute: BridgeContribution): () => void {\n const key = Symbol(\"bridge-contribution\");\n this.contributions.set(key, contribute);\n if (this.server) this.apply(key, contribute, this.server);\n\n return () => {\n this.contributions.delete(key);\n this.withdraw(key);\n };\n }\n\n /** Attach a server and apply every live contribution to it. */\n bind(server: MicroMcpServer): void {\n if (this.server === server) return;\n if (this.server) this.unbind();\n this.server = server;\n for (const [key, contribute] of this.contributions) this.apply(key, contribute, server);\n }\n\n /**\n * Detach the current server, withdrawing what was applied to it. Contributions\n * themselves are KEPT: a session can be stopped and restarted under a page\n * that never unmounted, and its tools must come back rather than silently\n * vanish.\n */\n unbind(): void {\n for (const key of [...this.applied.keys()]) this.withdraw(key);\n this.server = null;\n }\n\n private apply(key: symbol, contribute: BridgeContribution, server: MicroMcpServer): void {\n const dispose = contribute(server);\n if (typeof dispose === \"function\") this.applied.set(key, dispose);\n }\n\n private withdraw(key: symbol): void {\n const dispose = this.applied.get(key);\n this.applied.delete(key);\n dispose?.();\n }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { MicroMcpServer } from \"../mcp/server\";\nimport { attachInProcess } from \"../mcp/transports\";\nimport { attachSseRelay, type RelayState, type SseRelayTransport } from \"./sse-relay\";\nimport { createSessionDescriptor, type SessionDescriptor } from \"./token\";\nimport { emitActivity } from \"../presence/registry\";\nimport type { AgentActivityEvent } from \"../presence/types\";\nimport { registerNavigationBridge, type NavigationBridgeAdapter } from \"../bridges/navigation\";\nimport { BridgeContributions, type BridgeContribution } from \"./bridge-contributions\";\n\n/** A thing the human did, surfaced so the connected agent stays aware. */\nexport type CoBrowseUserEvent =\n | { kind: \"navigation\"; url: string; title?: string; revision?: number }\n | { kind: \"scroll\"; y: number; revision?: number }\n | { kind: \"form\"; handle: string; value?: unknown; masked?: boolean; revision?: number }\n | { kind: \"click\"; handle: string; label?: string; revision?: number };\n\nexport type UseCoBrowseSessionOptions = {\n /**\n * The navigation adapter (Inertia + DOM in the sandbox). MUST be stable —\n * its methods should read live state via refs, since the bridge captures it\n * once on mount. Memoize it.\n */\n adapter: NavigationBridgeAdapter;\n /** Identity for the agent's presence (cursor/log color + name). */\n agent?: { id: string; name?: string; color?: string };\n /**\n * Which activity events this session forwards to its agent.\n *\n * Only needed when a page runs MORE THAN ONE session — site co-browse plus\n * the agent playground, say. The activity bus is global to the page, so\n * without a filter each relay forwards the other's traffic and every agent\n * sees every other agent's navigations.\n *\n * Omitted forwards everything, which is right for the single-session case.\n */\n activityFilter?: (event: AgentActivityEvent) => boolean;\n /** Relay base path. Default \"/agent-relay\" (the generic frame broker). */\n relayBaseUrl?: string;\n /** MCP server info advertised to the agent. */\n info?: { name: string; version: string; instructions?: string };\n /**\n * Register extra bridges (forms/screens/…) on the same server, once, at\n * construction.\n *\n * For a surface that comes and goes with navigation use\n * {@link CoBrowseSession.contributeBridges} instead: this callback fires\n * exactly once while the server is built, so a page mounted afterwards can\n * never contribute through it, and one that unmounts can never withdraw.\n */\n extraBridges?: (server: MicroMcpServer) => void;\n /** CSRF token for the relay register/unregister POSTs. */\n csrfToken?: () => string | null | undefined;\n /** Stage submit + destructive clicks for human confirm. Default true. */\n pendingMode?: boolean;\n};\n\nexport type CoBrowseSession = {\n server: MicroMcpServer | null;\n /**\n * Contribute bridges for as long as the returned disposer is uncalled —\n * \"site tools always; page tools while mounted\".\n *\n * Call it from a page's mount effect and return its disposer:\n *\n * ```tsx\n * useEffect(() => contributeBridges((server) =>\n * registerArtboardBridge(server, { adapter }).dispose), []);\n * ```\n *\n * Safe to call before sharing starts — the contribution is applied to the\n * server as soon as one exists, and re-applied if the session is restarted.\n */\n contributeBridges: (contribute: BridgeContribution) => () => void;\n session: SessionDescriptor | null;\n relayState: RelayState;\n /**\n * True once at least one remote agent is actually attached to the session.\n *\n * Distinct from `relayState === \"open\"`, which only says the BROWSER reached\n * the relay — true the moment sharing starts, before the link has been handed\n * to anyone. A UI that keys \"Agent is driving\" off the relay state therefore\n * announces a driver who does not exist, and stays silent when a real one\n * arrives.\n */\n agentConnected: boolean;\n /** How many remote agents are attached (0 when nobody has joined). */\n agentCount: number;\n startShare: () => Promise<void>;\n stopShare: () => void;\n /**\n * Report a human action so the connected agent is notified. Emits a\n * `source:\"user\"` activity event, which the SSE relay forwards to the agent\n * as a `notifications/agent_activity` frame.\n */\n observeUser: (event: CoBrowseUserEvent) => void;\n};\n\nconst DEFAULT_AGENT = { id: \"agent\", name: \"Agent\", color: \"#a855f7\" };\nconst USER = { id: \"human\", name: \"You\" };\n\n/**\n * Site-wide co-browsing session: one persistent in-page `MicroMcpServer` running\n * the navigation bridge, joinable by an external agent over the relay. Mount it\n * once at the app root; render `<CoBrowsePresence>` to show the agent + a Stop\n * control. The host wires `observeUser(...)` to navigation/scroll/form listeners\n * so the agent sees what the human does.\n */\nexport function useCoBrowseSession(options: UseCoBrowseSessionOptions): CoBrowseSession {\n const { adapter, extraBridges } = options;\n const agent = { ...DEFAULT_AGENT, ...(options.agent ?? {}) };\n const relayBaseUrl = options.relayBaseUrl ?? \"/agent-relay\";\n\n const serverRef = useRef<MicroMcpServer | null>(null);\n // Survives re-renders AND server rebuilds: a page's contribution outlives any\n // one session, which is the entire reason this is not a captured callback.\n const contributionsRef = useRef<BridgeContributions>(null as unknown as BridgeContributions);\n if (!contributionsRef.current) contributionsRef.current = new BridgeContributions();\n const relayRef = useRef<SseRelayTransport | null>(null);\n const detachInProc = useRef<(() => void) | null>(null);\n const disposeBridge = useRef<(() => void) | null>(null);\n\n const [session, setSession] = useState<SessionDescriptor | null>(null);\n const [relayState, setRelayState] = useState<RelayState>(\"idle\");\n const [agentCount, setAgentCount] = useState(0);\n\n // Build the server + bridges once. The adapter is captured here, so it must\n // be stable (its methods read live state).\n useEffect(() => {\n const server = new MicroMcpServer({\n info: options.info ?? { name: \"fancy-co-browse\", version: \"0.1.0\" },\n instructions:\n options.info?.instructions ??\n \"Co-browse with a watching human. Call page_describe first; navigate, scroll, and (with confirm) fill/click via stable handles. You receive notifications/agent_activity for the human's actions (source:\\\"user\\\").\",\n });\n const bridge = registerNavigationBridge(server, { adapter, agent, pendingMode: options.pendingMode });\n extraBridges?.(server);\n // Apply whatever pages are already mounted, and keep the registry attached\n // so later mounts/unmounts add and withdraw live.\n contributionsRef.current.bind(server);\n const inProc = attachInProcess(server);\n detachInProc.current = () => inProc.close();\n disposeBridge.current = bridge.dispose;\n serverRef.current = server;\n\n return () => {\n relayRef.current?.close();\n relayRef.current = null;\n contributionsRef.current.unbind();\n disposeBridge.current?.();\n detachInProc.current?.();\n serverRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const startShare = useCallback(async () => {\n const server = serverRef.current;\n if (!server || relayRef.current) return;\n const descriptor = createSessionDescriptor();\n const csrf = options.csrfToken?.() ?? \"\";\n const response = await fetch(`${relayBaseUrl}/register`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf },\n body: JSON.stringify({ session: descriptor.id, token: descriptor.token }),\n });\n if (!response.ok) {\n throw new Error(`Relay registration failed (${response.status})`);\n }\n // Pass the session's agent identity down so the relay stamps its own\n // connect/disconnect events with it, and so a host that runs a SECOND\n // session (the agent playground alongside site co-browse) has something to\n // scope on. Without an `agent` this behaves exactly as before.\n const relay = attachSseRelay(server, {\n baseUrl: relayBaseUrl,\n sessionId: descriptor.id,\n token: descriptor.token,\n agent: options.agent,\n activityFilter: options.activityFilter,\n });\n relay.onStateChange(setRelayState);\n relay.onPeersChange(setAgentCount);\n relayRef.current = relay;\n setSession(descriptor);\n }, [relayBaseUrl, options]);\n\n const stopShare = useCallback(() => {\n const current = session;\n relayRef.current?.close();\n relayRef.current = null;\n setRelayState(\"idle\");\n setAgentCount(0);\n setSession(null);\n if (current) {\n const csrf = options.csrfToken?.() ?? \"\";\n void fetch(`${relayBaseUrl}/${current.id}/unregister?token=${encodeURIComponent(current.token)}`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"x-csrf-token\": csrf },\n }).catch(() => {});\n }\n }, [relayBaseUrl, options, session]);\n\n const observeUser = useCallback((event: CoBrowseUserEvent) => {\n const label =\n event.kind === \"navigation\"\n ? `You navigated to ${event.url}`\n : event.kind === \"scroll\"\n ? \"You scrolled\"\n : event.kind === \"click\"\n ? `You clicked ${event.label ?? event.handle}`\n : `You edited ${event.handle}${event.masked ? \" (hidden)\" : \"\"}`;\n emitActivity({\n agentId: USER.id,\n agentName: USER.name,\n source: \"user\",\n target: { kind: \"navigation\", label },\n action: `user_${event.kind}`,\n timestamp: Date.now(),\n meta: event as Record<string, unknown>,\n });\n }, []);\n\n // Stable identity: a page passes this straight into a mount effect, so a new\n // function each render would re-register its bridges on every render.\n const contributeBridges = useCallback(\n (contribute: BridgeContribution) => contributionsRef.current.add(contribute),\n [],\n );\n\n return {\n server: serverRef.current,\n contributeBridges,\n session,\n relayState,\n agentConnected: agentCount > 0,\n agentCount,\n startShare,\n stopShare,\n observeUser,\n };\n}\n","import { type ReactNode, useEffect, useMemo, useRef } from \"react\";\nimport type { MicroMcpServer } from \"../../mcp/server\";\nimport { registerFormBridge, type FormBridgeAdapter, type FormFieldDescriptor } from \"../../bridges/forms\";\n\nexport type BridgedFormProps = {\n /** Stable id for this form. Used by agents in `form_*` tool calls. */\n id: string;\n /** Human title (also surfaced as the bridge title). */\n title?: string;\n /** Optional fancy-screens screen id this form lives in. */\n screenId?: string;\n /** Field descriptors — drives the agent-facing schema. */\n fields: FormFieldDescriptor[];\n /** Controlled values. */\n values: Record<string, unknown>;\n /** Setter — hosts pass their setState. */\n onChange: (next: Record<string, unknown>) => void;\n /** Optional submit handler. */\n onSubmit?: () => Promise<{ ok: boolean; values?: Record<string, unknown>; error?: string }>;\n /** The MicroMcpServer the bridge registers against. Pass null/undefined\n * to render without a bridge (useful for stories / non-shared use). */\n server?: MicroMcpServer | null;\n /** Identity used in activity events. */\n agent?: { id: string; name?: string; color?: string };\n children: ReactNode;\n};\n\n/**\n * BridgedForm — wraps a react-fancy form (or any controlled inputs)\n * with a `registerFormBridge` lifecycle. Children render the actual form\n * using `values` + `onChange`; this component only manages the bridge.\n *\n * Hosts use it like:\n *\n * <BridgedForm id=\"signup\" fields={...} values={values} onChange={setValues} server={server}>\n * <Field><Input value={values.email} onValueChange={(v) => onChange({ ...values, email: v })} /></Field>\n * ...\n * </BridgedForm>\n *\n * Agents can then call form_describe, form_set_value, form_submit, etc.\n */\nexport function BridgedForm({\n id,\n title,\n screenId,\n fields,\n values,\n onChange,\n onSubmit,\n server,\n agent,\n children,\n}: BridgedFormProps) {\n // Refs so the adapter sees fresh values without re-installing the bridge.\n const valuesRef = useRef(values);\n const onChangeRef = useRef(onChange);\n const fieldsRef = useRef(fields);\n const submitRef = useRef(onSubmit);\n useEffect(() => { valuesRef.current = values; }, [values]);\n useEffect(() => { onChangeRef.current = onChange; }, [onChange]);\n useEffect(() => { fieldsRef.current = fields; }, [fields]);\n useEffect(() => { submitRef.current = onSubmit; }, [onSubmit]);\n\n const focusElement = (name: string) => {\n if (typeof document === \"undefined\") return;\n const el = document.querySelector(`[data-form-id=\"${id}\"] [name=\"${name}\"]`) as HTMLElement | null;\n el?.focus();\n };\n\n const adapter = useMemo<FormBridgeAdapter>(() => ({\n id,\n title,\n screenId,\n getFields: () => fieldsRef.current,\n getValue: (name) => valuesRef.current[name],\n getValues: () => ({ ...valuesRef.current }),\n setValue: (name, v) => onChangeRef.current({ ...valuesRef.current, [name]: v }),\n setValues: (next) => onChangeRef.current({ ...valuesRef.current, ...next }),\n focus: focusElement,\n submit: async () => {\n if (!submitRef.current) {\n return { ok: true, values: { ...valuesRef.current } };\n }\n return submitRef.current();\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }), [id, title, screenId]);\n\n useEffect(() => {\n if (!server) return;\n const bridge = registerFormBridge(server, { adapter, agent });\n return () => bridge.dispose();\n }, [server, adapter, agent]);\n\n return <div data-form-id={id}>{children}</div>;\n}\n","import { useEffect } from \"react\";\nimport { onActivity } from \"../../presence/registry\";\n\n/**\n * Loose shape of the fancy-screens system context — kept here so this\n * component doesn't hard-import `@particle-academy/fancy-screens`.\n */\ntype ScreenSystemLike = {\n registry: Map<string, { id: string; agentActivity?: unknown }>;\n updateScreen: (id: string, patch: { agentActivity?: unknown }) => void;\n};\n\nexport type ScreensActivityBridgeProps = {\n /** The value returned by `useScreenSystem()` from fancy-screens. */\n system: ScreenSystemLike;\n /** ms to wait after the last activity before clearing the screen's badge. Default 1500. */\n fadeMs?: number;\n};\n\n/**\n * ScreensActivityBridge — subscribe to the in-process activity registry\n * and patch each event into the matching screen's `agentActivity` field.\n * Fade-out clears the badge after `fadeMs`.\n *\n * Use it once near the root of your app, ABOVE every <Screen>:\n *\n * const system = useScreenSystem();\n * <>\n * <ScreensActivityBridge system={system} />\n * <Screen id=\"dashboard\">…</Screen>\n * <Screen id=\"form\">…</Screen>\n * </>\n *\n * Renders nothing; pure side-effect component.\n */\nexport function ScreensActivityBridge({ system, fadeMs = 1500 }: ScreensActivityBridgeProps) {\n useEffect(() => {\n const fadeTimers = new Map<string, ReturnType<typeof setTimeout>>();\n const off = onActivity((event) => {\n const screenId = event.target.screenId;\n if (!screenId) return;\n // Only patch screens that are currently registered.\n if (!system.registry.has(screenId)) return;\n const activity = {\n agentId: event.agentId,\n agentName: event.agentName,\n agentColor: event.agentColor,\n action: event.action,\n timestamp: event.timestamp,\n elementId: event.target.elementId,\n label: event.target.label,\n };\n system.updateScreen(screenId, { agentActivity: activity });\n const prev = fadeTimers.get(screenId);\n if (prev) clearTimeout(prev);\n fadeTimers.set(\n screenId,\n setTimeout(() => {\n system.updateScreen(screenId, { agentActivity: null });\n fadeTimers.delete(screenId);\n }, event.ttlMs ?? fadeMs),\n );\n });\n return () => {\n off();\n for (const t of fadeTimers.values()) clearTimeout(t);\n };\n }, [system, fadeMs]);\n return null;\n}\n","import { useMemo } from \"react\";\nimport { useAgentActivity } from \"../../presence/use-agent-activity\";\nimport { ShareControls } from \"../ShareControls/ShareControls\";\nimport { ConnectorButtons } from \"../../connectors/ConnectorButtons\";\nimport type { AgentActivity } from \"../AgentPanel\";\nimport type { AgentActivityEvent } from \"../../presence/types\";\nimport type { CoBrowseSession } from \"../../sharing/use-co-browse-session\";\n\nexport type CoBrowsePresenceProps = {\n /** The session from `useCoBrowseSession`. */\n session: CoBrowseSession;\n /** Public MCP/connect URL shown to the user (for ConnectorButtons), optional. */\n connectUrl?: string;\n /** Base URL used to build the shareable session link. */\n shareBaseUrl?: string;\n className?: string;\n};\n\n/** Lifecycle chatter — real to the session, but not something the agent *did*. */\nconst LIFECYCLE_ACTIONS = new Set([\"agent_connected\", \"agent_disconnected\"]);\n\n/**\n * The human's view of a site-wide co-browsing session: a \"Let an agent drive\"\n * starter, the share/connect surface until an agent arrives, a live log of what\n * it is doing once one has, and a Stop / take-back-control button.\n *\n * Staged-action confirms are rendered by the HOST (via the navigation adapter's\n * `confirm`), so this component stays presentation-only.\n */\nexport function CoBrowsePresence({ session, connectUrl, shareBaseUrl, className }: CoBrowsePresenceProps) {\n const { events } = useAgentActivity(undefined, { capacity: 40 });\n const lastAgentAction = [...events]\n .reverse()\n .find((e) => (e.source ?? \"agent\") !== \"user\" && !LIFECYCLE_ACTIONS.has(e.action));\n\n // Whether an agent is HERE, not whether the browser reached the relay. The\n // latter is true the instant sharing starts, so keying the badge on it told\n // every human \"Agent is driving\" before they had handed the link to anyone.\n const connected = session.agentConnected;\n\n const activity = useMemo(() => events.map(toPanelActivity), [events]);\n\n if (!session.session) {\n return (\n <div className={className} data-co-browse-presence=\"idle\">\n <button type=\"button\" onClick={() => void session.startShare()} data-co-browse-start>\n Let an agent drive\n </button>\n </div>\n );\n }\n\n return (\n <div className={className} data-co-browse-presence={connected ? \"connected\" : \"waiting\"}>\n <div data-co-browse-bar>\n <span data-co-browse-dot data-state={session.relayState} />\n <span data-co-browse-status>\n {connected ? \"Agent is driving\" : `Waiting for an agent… (${session.relayState})`}\n </span>\n {lastAgentAction && <span data-co-browse-last>{lastAgentAction.target?.label ?? lastAgentAction.action}</span>}\n <button type=\"button\" onClick={session.stopShare} data-co-browse-stop>\n Stop\n </button>\n </div>\n\n <ShareControls\n session={session.session}\n onStart={() => void session.startShare()}\n onStop={session.stopShare}\n status={session.relayState}\n agentConnected={connected}\n activity={activity}\n shareBaseUrl={shareBaseUrl}\n />\n\n {connectUrl && <ConnectorButtons serverName=\"Fancy UI co-browse\" mcpUrl={connectUrl} />}\n </div>\n );\n}\n\n/**\n * Presence event → the `AgentActivity` row `<ShareControls>` / `<AgentPanel>`\n * render. One shape for both, so a host already collecting presence needs no\n * second stream.\n */\nfunction toPanelActivity(event: AgentActivityEvent): AgentActivity {\n const who = (event.source ?? \"agent\") === \"user\" ? \"You\" : (event.agentName ?? \"Agent\");\n return {\n id: `${event.timestamp}-${event.action}-${event.target?.elementId ?? event.target?.label ?? \"\"}`,\n at: event.timestamp,\n kind: LIFECYCLE_ACTIONS.has(event.action) ? \"info\" : \"tool\",\n source: who,\n text: event.target?.label ?? event.action,\n detail: event.meta,\n };\n}\n\nCoBrowsePresence.displayName = \"CoBrowsePresence\";\n","import { useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useAgentActivity } from \"../../presence/use-agent-activity\";\nimport { AgentCursor } from \"../AgentCursor/AgentCursor\";\nimport { AgentActivityHighlight } from \"../AgentActivityHighlight/AgentActivityHighlight\";\n\ntype Rect = { x: number; y: number; width: number; height: number };\n\nconst CURSOR_EDGE_INSET = 24;\nconst FLUID_CURSOR_SPEED_PX_PER_SECOND = 1_050;\nconst MIN_GLIDE_MS = 240;\nconst MAX_GLIDE_MS = 1_200;\n\nexport function visibleCursorPoint(rect: Rect, viewport: { width: number; height: number }) {\n const x = rect.x + rect.width / 2;\n const y = rect.y + rect.height / 2;\n return {\n x: Math.min(Math.max(x, CURSOR_EDGE_INSET), Math.max(CURSOR_EDGE_INSET, viewport.width - CURSOR_EDGE_INSET)),\n y: Math.min(Math.max(y, CURSOR_EDGE_INSET), Math.max(CURSOR_EDGE_INSET, viewport.height - CURSOR_EDGE_INSET)),\n };\n}\n\nexport function fluidGlideDuration(from: { x: number; y: number } | null, to: { x: number; y: number }) {\n if (!from) return 0;\n const distance = Math.hypot(to.x - from.x, to.y - from.y);\n return Math.round(Math.min(MAX_GLIDE_MS, Math.max(MIN_GLIDE_MS, (distance / FLUID_CURSOR_SPEED_PX_PER_SECOND) * 1_000)));\n}\n\nexport type CoBrowseCursorLayerProps = {\n /** Render the overlay only while a session is live. Default true. */\n active?: boolean;\n /** Stacking order of the overlay. Default just under the max. */\n zIndex?: number;\n /**\n * Retire the cursor after this long without a tool call. Default 15s;\n * `0` keeps it on screen indefinitely.\n *\n * A cursor that sits still is not neutral — it reads as \"the agent is\n * broken\", which is worse than showing nothing. Continuous presence belongs\n * in the activity log; the cursor is for *motion*.\n */\n idleAfterMs?: number;\n};\n\n/**\n * Session lifecycle chatter. Real events, but nothing the agent DID — so they\n * must never conjure a cursor. `agent_connected` used to, parking a motionless\n * pointer captioned \"Agent connected\" in the middle of the viewport for a\n * session in which the agent had not yet made a single tool call.\n */\nconst LIFECYCLE_ACTIONS = new Set([\"agent_connected\", \"agent_disconnected\"]);\n\n/**\n * Page-wide agent presence for co-browsing — the missing \"all actors present\"\n * half of Human+ UX. A fixed, click-through overlay (portaled to <body>) that\n * shows the connected agent as a live cursor + pings/highlights the element it\n * just acted on, gliding between targets. Same visual language as the whiteboard\n * demo's agent cursor, but mapped from the navigation bridge's STABLE HANDLES\n * (the agent has no real mouse) — each tool reports the acted element's viewport\n * rect in `meta.rect` (see `NavigationBridgeAdapter.rectFor`).\n *\n * Mount it once near the app root (e.g. in your CoBrowseProvider), gated on an\n * active session. SSR-safe: renders null on the server / until the first action.\n */\nexport function CoBrowseCursorLayer({\n active = true,\n zIndex = 2147483000,\n idleAfterMs = 15_000,\n}: CoBrowseCursorLayerProps) {\n const { latest } = useAgentActivity(undefined, { capacity: 12 });\n const [cursor, setCursor] = useState<{ x: number; y: number; name: string; color: string; status?: string; glideMs: number } | null>(\n null,\n );\n const [pulse, setPulse] = useState<{ rect: Rect; color: string; key: number } | null>(null);\n // Timestamp of the last real tool call — the only thing that keeps the cursor\n // alive. Deliberately NOT bumped by lifecycle events, so a relay client\n // reconnecting every call can't hold a stale pointer on screen forever.\n const [lastActionAt, setLastActionAt] = useState(0);\n\n useEffect(() => {\n if (!latest || (latest.source ?? \"agent\") === \"user\") return;\n if (LIFECYCLE_ACTIONS.has(latest.action)) {\n // Connecting is not acting. Relay clients may also be intentionally\n // short-lived (one process per MCP call), so a disconnect is not the end\n // of the session either — if a cursor is already on screen from real work,\n // leave it and just say so. What we must NOT do is create one: an agent\n // that has connected and done nothing has nowhere to point.\n setCursor((prev) => (prev ? { ...prev, status: \"Standing by\", glideMs: 0 } : null));\n setPulse(null);\n return;\n }\n setLastActionAt(latest.timestamp);\n const color = latest.agentColor ?? \"#a855f7\";\n const name = latest.agentName ?? \"Agent\";\n const status = latest.target?.label ?? latest.action;\n const rect = (latest.meta as { rect?: Rect } | undefined)?.rect;\n if (rect) {\n // Keep off-screen targets represented at the nearest viewport edge, then\n // glide at a distance-aware pace that a watching human can comfortably\n // follow. This is presence, not a teleport animation.\n const target = visibleCursorPoint(rect, { width: window.innerWidth, height: window.innerHeight });\n const reduceMotion = window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n setCursor((prev) => ({\n ...target,\n name,\n color,\n status,\n glideMs: reduceMotion ? 0 : fluidGlideDuration(prev, target),\n }));\n setPulse({ rect, color, key: latest.timestamp });\n } else {\n // nav / scroll — no element. Keep (or first-show, at viewport center) the\n // cursor so the agent stays visibly present; just refresh its caption.\n setCursor((prev) =>\n prev\n ? { ...prev, status, name, color }\n : { x: window.innerWidth / 2, y: window.innerHeight / 2, name, color, status, glideMs: 0 },\n );\n }\n }, [latest?.timestamp]);\n\n // Retire the cursor once the agent goes quiet. Presence that never changes\n // stops being information — the human reads a frozen pointer as a hung agent,\n // and the activity log is where \"still connected\" is supposed to live.\n useEffect(() => {\n if (!idleAfterMs || !lastActionAt) return;\n const timer = setTimeout(() => {\n setCursor(null);\n setPulse(null);\n }, idleAfterMs);\n return () => clearTimeout(timer);\n }, [lastActionAt, idleAfterMs]);\n\n if (!active || !cursor || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div data-co-browse-cursor-layer=\"\" style={{ position: \"fixed\", inset: 0, pointerEvents: \"none\", zIndex }}>\n {pulse && (\n <AgentActivityHighlight\n x={pulse.rect.x}\n y={pulse.rect.y}\n width={pulse.rect.width}\n height={pulse.rect.height}\n color={pulse.color}\n pulseKey={pulse.key}\n />\n )}\n <AgentCursor\n x={cursor.x}\n y={cursor.y}\n name={cursor.name}\n color={cursor.color}\n status={cursor.status}\n style={{\n transition: cursor.glideMs\n ? `left ${cursor.glideMs}ms cubic-bezier(.22,.61,.36,1), top ${cursor.glideMs}ms cubic-bezier(.22,.61,.36,1)`\n : \"none\",\n }}\n />\n </div>,\n document.body,\n );\n}\n\nCoBrowseCursorLayer.displayName = \"CoBrowseCursorLayer\";\n","import { type CSSProperties, useState } from \"react\";\n\nexport type SimulateUsersButtonProps = {\n /** Endpoint that injects the fake active users. Default `/active-users/simulate`. */\n endpoint?: string;\n /** How many fake users to simulate (sent as `count`). Default `10`. */\n count?: number;\n /** Button label. Default `Simulate {count} active users`. */\n label?: string;\n /**\n * CSRF token sent as `X-CSRF-TOKEN`. If omitted, falls back to a\n * `<meta name=\"csrf-token\">` on the page (the Laravel default).\n */\n csrfToken?: string;\n /** Called after a successful trigger. */\n onTriggered?: () => void;\n /** Called if the request fails. */\n onError?: (error: unknown) => void;\n className?: string;\n style?: CSSProperties;\n};\n\nfunction resolveCsrf(explicit?: string): string | undefined {\n if (explicit) return explicit;\n if (typeof document === \"undefined\") return undefined;\n return document.querySelector<HTMLMetaElement>('meta[name=\"csrf-token\"]')?.content;\n}\n\n/**\n * A button that asks the host to inject N **fake** active users (injected\n * dummies, not real accounts) so the live ActiveUser stream / presence overlay\n * has something to animate in a demo. POSTs `{ count }` to `endpoint`.\n *\n * Self-contained (inline styles, no react-fancy dependency) so it drops into any\n * host. The fakes + their staggered activity are produced server-side; this\n * button only triggers them.\n */\nexport function SimulateUsersButton({\n endpoint = \"/active-users/simulate\",\n count = 10,\n label,\n csrfToken,\n onTriggered,\n onError,\n className,\n style,\n}: SimulateUsersButtonProps) {\n const [busy, setBusy] = useState(false);\n\n async function trigger() {\n if (busy) return;\n setBusy(true);\n try {\n const token = resolveCsrf(csrfToken);\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Requested-With\": \"XMLHttpRequest\",\n ...(token ? { \"X-CSRF-TOKEN\": token } : {}),\n },\n credentials: \"same-origin\",\n body: JSON.stringify({ count }),\n });\n if (!res.ok) throw new Error(`Simulate request failed: ${res.status}`);\n onTriggered?.();\n } catch (err) {\n onError?.(err);\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <button\n type=\"button\"\n data-fai-simulate-users=\"\"\n className={[\"fai-simulate-users\", className ?? \"\"].filter(Boolean).join(\" \")}\n onClick={trigger}\n disabled={busy}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"8px 14px\",\n borderRadius: 8,\n border: \"1px solid rgba(139,92,246,0.4)\",\n background: busy ? \"rgba(139,92,246,0.15)\" : \"rgba(139,92,246,0.1)\",\n color: \"#7c3aed\",\n font: \"inherit\",\n fontSize: 13,\n fontWeight: 500,\n cursor: busy ? \"progress\" : \"pointer\",\n opacity: busy ? 0.7 : 1,\n ...style,\n }}\n >\n <span aria-hidden>{busy ? \"⏳\" : \"✨\"}</span>\n {label ?? `Simulate ${count} active users`}\n </button>\n );\n}\n"]}
|
package/dist/mcp/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { T as Transport, M as MicroMcpServer } from '../server-
|
|
2
|
-
export { a as McpServerOptions, e as errorResult, r as rpcError, t as textResult } from '../server-
|
|
3
|
-
import {
|
|
4
|
-
export { C as CallToolResult,
|
|
5
|
-
import '../tool-host-
|
|
1
|
+
import { T as Transport, M as MicroMcpServer } from '../server-DJJygNo1.cjs';
|
|
2
|
+
export { a as McpServerOptions, e as errorResult, r as rpcError, t as textResult } from '../server-DJJygNo1.cjs';
|
|
3
|
+
import { d as JsonRpcMessage } from '../types-ITRQFAir.cjs';
|
|
4
|
+
export { C as CallToolResult, e as ContentBlock, I as InitializeResult, j as JSONRPC_INTERNAL_ERROR, k as JSONRPC_INVALID_PARAMS, l as JSONRPC_INVALID_REQUEST, m as JSONRPC_METHOD_NOT_FOUND, n as JSONRPC_PARSE_ERROR, J as JsonObject, o as JsonRpcError, p as JsonRpcId, f as JsonRpcNotification, g as JsonRpcRequest, q as JsonRpcSuccess, h as JsonValue, M as MCP_PROTOCOL_VERSION, R as RegisterToolOptions, b as RegisteredTool, c as ServerCapabilities, S as ServerInfo, r as ToolAnnotations, i as ToolCallContext, T as ToolDefinition, a as ToolHandler, s as ToolInputSchema } from '../types-ITRQFAir.cjs';
|
|
5
|
+
import '../tool-host-BBSaU7IJ.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* InProcessTransport — direct function-call wiring between an in-page MCP
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { T as Transport, M as MicroMcpServer } from '../server-
|
|
2
|
-
export { a as McpServerOptions, e as errorResult, r as rpcError, t as textResult } from '../server-
|
|
3
|
-
import {
|
|
4
|
-
export { C as CallToolResult,
|
|
5
|
-
import '../tool-host-
|
|
1
|
+
import { T as Transport, M as MicroMcpServer } from '../server-Dwo9LOxh.js';
|
|
2
|
+
export { a as McpServerOptions, e as errorResult, r as rpcError, t as textResult } from '../server-Dwo9LOxh.js';
|
|
3
|
+
import { d as JsonRpcMessage } from '../types-ITRQFAir.js';
|
|
4
|
+
export { C as CallToolResult, e as ContentBlock, I as InitializeResult, j as JSONRPC_INTERNAL_ERROR, k as JSONRPC_INVALID_PARAMS, l as JSONRPC_INVALID_REQUEST, m as JSONRPC_METHOD_NOT_FOUND, n as JSONRPC_PARSE_ERROR, J as JsonObject, o as JsonRpcError, p as JsonRpcId, f as JsonRpcNotification, g as JsonRpcRequest, q as JsonRpcSuccess, h as JsonValue, M as MCP_PROTOCOL_VERSION, R as RegisterToolOptions, b as RegisteredTool, c as ServerCapabilities, S as ServerInfo, r as ToolAnnotations, i as ToolCallContext, T as ToolDefinition, a as ToolHandler, s as ToolInputSchema } from '../types-ITRQFAir.js';
|
|
5
|
+
import '../tool-host-BqJRPr_T.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* InProcessTransport — direct function-call wiring between an in-page MCP
|
package/dist/mcp/stdio.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as Transport, M as MicroMcpServer } from '../server-
|
|
2
|
-
import {
|
|
3
|
-
import '../tool-host-
|
|
1
|
+
import { T as Transport, M as MicroMcpServer } from '../server-DJJygNo1.cjs';
|
|
2
|
+
import { d as JsonRpcMessage } from '../types-ITRQFAir.cjs';
|
|
3
|
+
import '../tool-host-BBSaU7IJ.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* StdioTransport — newline-delimited JSON-RPC over a byte stream pair.
|
package/dist/mcp/stdio.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { T as Transport, M as MicroMcpServer } from '../server-
|
|
2
|
-
import {
|
|
3
|
-
import '../tool-host-
|
|
1
|
+
import { T as Transport, M as MicroMcpServer } from '../server-Dwo9LOxh.js';
|
|
2
|
+
import { d as JsonRpcMessage } from '../types-ITRQFAir.js';
|
|
3
|
+
import '../tool-host-BqJRPr_T.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* StdioTransport — newline-delimited JSON-RPC over a byte stream pair.
|
package/dist/mcp.cjs
CHANGED
|
@@ -28,13 +28,23 @@ var ToolRegistry = class {
|
|
|
28
28
|
*/
|
|
29
29
|
this.withdrawn = /* @__PURE__ */ new Set();
|
|
30
30
|
}
|
|
31
|
-
registerTool(definition, handler) {
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
registerTool(definition, handler, options = {}) {
|
|
32
|
+
const name = definition.name;
|
|
33
|
+
const { owner, replace = false } = options;
|
|
34
|
+
const held = this.tools.get(name);
|
|
35
|
+
if (held && !replace && (owner === void 0 || held.owner !== owner)) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Tool "${name}" is already registered by ${describeOwner(held.owner)}; ${describeOwner(owner)} cannot register it too. Two registrants for one name would leave the first one listed but unreachable. Give one of them a different tool name, dispose the first registration, or pass { replace: true } to take the name over deliberately.`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
const record = owner === void 0 ? { definition, handler } : { definition, handler, owner };
|
|
41
|
+
this.tools.set(name, record);
|
|
42
|
+
this.withdrawn.delete(name);
|
|
34
43
|
this.onToolsChanged();
|
|
35
44
|
return () => {
|
|
36
|
-
if (this.tools.
|
|
37
|
-
this.
|
|
45
|
+
if (this.tools.get(name) === record) {
|
|
46
|
+
this.tools.delete(name);
|
|
47
|
+
this.withdrawn.add(name);
|
|
38
48
|
this.onToolsChanged();
|
|
39
49
|
}
|
|
40
50
|
};
|
|
@@ -63,6 +73,9 @@ var ToolRegistry = class {
|
|
|
63
73
|
onToolsChanged() {
|
|
64
74
|
}
|
|
65
75
|
};
|
|
76
|
+
function describeOwner(owner) {
|
|
77
|
+
return owner === void 0 ? "an unnamed registrant (pass { owner } to registerTool to identify it)" : `"${owner}"`;
|
|
78
|
+
}
|
|
66
79
|
|
|
67
80
|
// src/mcp/server.ts
|
|
68
81
|
var MicroMcpServer = class extends ToolRegistry {
|