@nimblebrain/synapse 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ABJP7PL4.cjs → chunk-MQNKIR7K.cjs} +51 -18
- package/dist/chunk-MQNKIR7K.cjs.map +1 -0
- package/dist/{chunk-BWSAQV3P.js → chunk-QY4IBJKV.js} +51 -18
- package/dist/chunk-QY4IBJKV.js.map +1 -0
- package/dist/codegen/cli.cjs +1 -1
- package/dist/codegen/cli.js +1 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +40 -4
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +28 -2
- package/dist/react/index.d.ts +28 -2
- package/dist/react/index.js +39 -4
- package/dist/react/index.js.map +1 -1
- package/dist/{server-NNW54YW5.js → server-7BRGSPT3.js} +13 -13
- package/dist/{server-NNW54YW5.js.map → server-7BRGSPT3.js.map} +1 -1
- package/dist/{server-3BDZ5S72.cjs → server-SRE7E3G3.cjs} +13 -13
- package/dist/{server-3BDZ5S72.cjs.map → server-SRE7E3G3.cjs.map} +1 -1
- package/dist/synapse-runtime.iife.global.js +1 -1
- package/dist/{types-BL15lUqi.d.cts → types-CG7zrCn-.d.cts} +45 -3
- package/dist/{types-BL15lUqi.d.ts → types-CG7zrCn-.d.ts} +45 -3
- package/dist/vite/index.cjs +6 -6
- package/dist/vite/index.cjs.map +1 -1
- package/dist/vite/index.js +6 -6
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ABJP7PL4.cjs.map +0 -1
- package/dist/chunk-BWSAQV3P.js.map +0 -1
|
@@ -45,7 +45,7 @@ var KeyboardForwarder = class {
|
|
|
45
45
|
if (this.destroyed) return;
|
|
46
46
|
if (this.shouldForward(event, config)) {
|
|
47
47
|
event.preventDefault();
|
|
48
|
-
transport.send("
|
|
48
|
+
transport.send("synapse/keydown", {
|
|
49
49
|
key: event.key,
|
|
50
50
|
ctrlKey: event.ctrlKey,
|
|
51
51
|
metaKey: event.metaKey,
|
|
@@ -69,7 +69,11 @@ var KeyboardForwarder = class {
|
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
if (event.key === "Escape") return true;
|
|
72
|
-
if (event.ctrlKey || event.metaKey)
|
|
72
|
+
if (event.ctrlKey || event.metaKey) {
|
|
73
|
+
const key = event.key.toLowerCase();
|
|
74
|
+
if (key === "c" || key === "v" || key === "x" || key === "a") return false;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
73
77
|
return false;
|
|
74
78
|
}
|
|
75
79
|
};
|
|
@@ -237,7 +241,7 @@ function createSynapse(options) {
|
|
|
237
241
|
currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };
|
|
238
242
|
for (const cb of themeCallbacks) cb(currentTheme);
|
|
239
243
|
});
|
|
240
|
-
const unsubNbTheme = transport.onMessage("
|
|
244
|
+
const unsubNbTheme = transport.onMessage("synapse/theme-changed", (params) => {
|
|
241
245
|
if (!params) return;
|
|
242
246
|
const mode = params.mode === "dark" || params.mode === "light" ? params.mode : currentTheme.mode;
|
|
243
247
|
const tokens = params.tokens && typeof params.tokens === "object" ? params.tokens : currentTheme.tokens;
|
|
@@ -247,7 +251,7 @@ function createSynapse(options) {
|
|
|
247
251
|
const themeCallbacks = /* @__PURE__ */ new Set();
|
|
248
252
|
const dataCallbacks = /* @__PURE__ */ new Set();
|
|
249
253
|
const actionCallbacks = /* @__PURE__ */ new Set();
|
|
250
|
-
const unsubData = transport.onMessage("
|
|
254
|
+
const unsubData = transport.onMessage("synapse/data-changed", (params) => {
|
|
251
255
|
if (!params) return;
|
|
252
256
|
const event = {
|
|
253
257
|
source: "agent",
|
|
@@ -256,7 +260,7 @@ function createSynapse(options) {
|
|
|
256
260
|
};
|
|
257
261
|
for (const cb of dataCallbacks) cb(event);
|
|
258
262
|
});
|
|
259
|
-
const unsubAction = transport.onMessage("
|
|
263
|
+
const unsubAction = transport.onMessage("synapse/action", (params) => {
|
|
260
264
|
if (!params || typeof params.type !== "string") return;
|
|
261
265
|
const action = {
|
|
262
266
|
type: params.type,
|
|
@@ -311,19 +315,26 @@ function createSynapse(options) {
|
|
|
311
315
|
},
|
|
312
316
|
action(action, params) {
|
|
313
317
|
if (!isNB()) return;
|
|
314
|
-
transport.send("
|
|
318
|
+
transport.send("synapse/action", { action, ...params });
|
|
315
319
|
},
|
|
316
320
|
chat(message, context) {
|
|
317
|
-
|
|
318
|
-
|
|
321
|
+
const textBlock = { type: "text", text: message };
|
|
322
|
+
if (isNB() && context) {
|
|
323
|
+
textBlock._meta = { context };
|
|
324
|
+
}
|
|
325
|
+
transport.send("ui/message", {
|
|
326
|
+
role: "user",
|
|
327
|
+
content: [textBlock]
|
|
328
|
+
});
|
|
319
329
|
},
|
|
320
330
|
setVisibleState(state, summary) {
|
|
321
|
-
if (!isNB()) return;
|
|
322
331
|
if (stateTimer) clearTimeout(stateTimer);
|
|
323
332
|
stateTimer = setTimeout(() => {
|
|
324
|
-
transport.send("ui/
|
|
325
|
-
state,
|
|
326
|
-
...summary !== void 0 && {
|
|
333
|
+
transport.send("ui/update-model-context", {
|
|
334
|
+
structuredContent: state,
|
|
335
|
+
...summary !== void 0 && {
|
|
336
|
+
content: [{ type: "text", text: summary }]
|
|
337
|
+
}
|
|
327
338
|
});
|
|
328
339
|
stateTimer = null;
|
|
329
340
|
}, 250);
|
|
@@ -331,19 +342,41 @@ function createSynapse(options) {
|
|
|
331
342
|
downloadFile(filename, content, mimeType) {
|
|
332
343
|
if (!isNB()) return;
|
|
333
344
|
const data = typeof content === "string" ? content : "[Blob content not serializable]";
|
|
334
|
-
transport.send("
|
|
345
|
+
transport.send("synapse/download-file", {
|
|
335
346
|
data,
|
|
336
347
|
filename,
|
|
337
348
|
mimeType: mimeType ?? "application/octet-stream"
|
|
338
349
|
});
|
|
339
350
|
},
|
|
340
351
|
openLink(url) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
} else {
|
|
352
|
+
transport.send("ui/open-link", { url });
|
|
353
|
+
if (!isNB()) {
|
|
344
354
|
window.open(url, "_blank", "noopener");
|
|
345
355
|
}
|
|
346
356
|
},
|
|
357
|
+
async requestFile(options2) {
|
|
358
|
+
if (!isNB()) {
|
|
359
|
+
throw new Error("requestFile is not supported in this host");
|
|
360
|
+
}
|
|
361
|
+
const result = await transport.request("synapse/request-file", {
|
|
362
|
+
accept: options2?.accept,
|
|
363
|
+
maxSize: options2?.maxSize ?? 26214400,
|
|
364
|
+
multiple: false
|
|
365
|
+
});
|
|
366
|
+
return result ?? null;
|
|
367
|
+
},
|
|
368
|
+
async requestFiles(options2) {
|
|
369
|
+
if (!isNB()) {
|
|
370
|
+
throw new Error("requestFiles is not supported in this host");
|
|
371
|
+
}
|
|
372
|
+
const result = await transport.request("synapse/request-file", {
|
|
373
|
+
accept: options2?.accept,
|
|
374
|
+
maxSize: options2?.maxSize ?? 26214400,
|
|
375
|
+
multiple: true
|
|
376
|
+
});
|
|
377
|
+
if (!result) return [];
|
|
378
|
+
return Array.isArray(result) ? result : [result];
|
|
379
|
+
},
|
|
347
380
|
_onMessage(method, callback) {
|
|
348
381
|
return transport.onMessage(method, callback);
|
|
349
382
|
},
|
|
@@ -369,5 +402,5 @@ function createSynapse(options) {
|
|
|
369
402
|
}
|
|
370
403
|
|
|
371
404
|
exports.createSynapse = createSynapse;
|
|
372
|
-
//# sourceMappingURL=chunk-
|
|
373
|
-
//# sourceMappingURL=chunk-
|
|
405
|
+
//# sourceMappingURL=chunk-MQNKIR7K.cjs.map
|
|
406
|
+
//# sourceMappingURL=chunk-MQNKIR7K.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/detection.ts","../src/keyboard.ts","../src/result-parser.ts","../src/transport.ts","../src/core.ts"],"names":["options"],"mappings":"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","file":"chunk-MQNKIR7K.cjs","sourcesContent":["import type { HostInfo, SynapseTheme } from \"./types\";\n\nconst DEFAULT_THEME: SynapseTheme = {\n mode: \"light\",\n primaryColor: \"#6366f1\",\n tokens: {},\n};\n\n/**\n * Detect the host environment from the ext-apps `ui/initialize` response.\n *\n * Handles missing or malformed fields gracefully — never throws.\n */\nexport function detectHost(initResponse: unknown): HostInfo {\n const resp = initResponse as Record<string, unknown> | null | undefined;\n\n const serverInfo = safeObj(resp?.serverInfo);\n const serverName = typeof serverInfo?.name === \"string\" ? serverInfo.name : \"unknown\";\n\n const protocolVersion =\n typeof resp?.protocolVersion === \"string\" ? resp.protocolVersion : \"unknown\";\n\n const hostContext = safeObj(resp?.hostContext);\n const theme = extractTheme(hostContext?.theme);\n\n return {\n isNimbleBrain: serverName === \"nimblebrain\",\n serverName,\n protocolVersion,\n theme,\n };\n}\n\nfunction extractTheme(raw: unknown): SynapseTheme {\n const obj = safeObj(raw);\n if (!obj) return { ...DEFAULT_THEME };\n\n const mode = obj.mode === \"light\" || obj.mode === \"dark\" ? obj.mode : DEFAULT_THEME.mode;\n\n const primaryColor =\n typeof obj.primaryColor === \"string\" ? obj.primaryColor : DEFAULT_THEME.primaryColor;\n\n const tokens =\n obj.tokens !== null && typeof obj.tokens === \"object\" && !Array.isArray(obj.tokens)\n ? (obj.tokens as Record<string, string>)\n : {};\n\n return { mode, primaryColor, tokens };\n}\n\nfunction safeObj(value: unknown): Record<string, unknown> | undefined {\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n","import type { SynapseTransport } from \"./transport.js\";\nimport type { KeyForwardConfig } from \"./types.js\";\n\n/**\n * Forward keyboard shortcuts from the iframe document to the host.\n *\n * By default, forwards all Ctrl/Cmd+key combos and Escape.\n * Apps can customize via `forwardKeys` config.\n */\nexport class KeyboardForwarder {\n private listener: (event: KeyboardEvent) => void;\n private destroyed = false;\n\n constructor(transport: SynapseTransport, customKeys?: KeyForwardConfig[]) {\n const config = customKeys ?? null; // null = default behavior\n\n this.listener = (event: KeyboardEvent) => {\n if (this.destroyed) return;\n if (this.shouldForward(event, config)) {\n event.preventDefault();\n transport.send(\"synapse/keydown\", {\n key: event.key,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n }\n };\n\n document.addEventListener(\"keydown\", this.listener);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n document.removeEventListener(\"keydown\", this.listener);\n }\n\n private shouldForward(event: KeyboardEvent, config: KeyForwardConfig[] | null): boolean {\n // Empty array = forwarding disabled\n if (config && config.length === 0) return false;\n\n // Custom config: match exactly\n if (config) {\n return config.some(\n (k) =>\n event.key.toLowerCase() === k.key.toLowerCase() &&\n (k.ctrl === undefined || event.ctrlKey === k.ctrl) &&\n (k.meta === undefined || event.metaKey === k.meta) &&\n (k.shift === undefined || event.shiftKey === k.shift) &&\n (k.alt === undefined || event.altKey === k.alt),\n );\n }\n\n // Default: forward all Ctrl/Cmd combos + Escape,\n // EXCEPT clipboard shortcuts (c, v, x, a) which the browser must handle natively.\n if (event.key === \"Escape\") return true;\n if (event.ctrlKey || event.metaKey) {\n const key = event.key.toLowerCase();\n if (key === \"c\" || key === \"v\" || key === \"x\" || key === \"a\") return false;\n return true;\n }\n return false;\n }\n}\n","import type { ToolCallResult } from \"./types.js\";\n\n/**\n * Normalize a raw tool call response into a consistent `ToolCallResult`.\n *\n * Handles three shapes:\n * 1. MCP `CallToolResult` — has a `content` array with typed blocks.\n * 2. Raw JSON object (NimbleBrain bridge) — used as-is.\n * 3. Null / undefined — returns `{ data: null, isError: false }`.\n */\nexport function parseToolResult(raw: unknown): ToolCallResult {\n if (raw == null) {\n return { data: null, isError: false };\n }\n\n if (isCallToolResult(raw)) {\n return parseCallToolResult(raw);\n }\n\n // Raw JSON object — pass through.\n return { data: raw, isError: false };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface McpTextBlock {\n type: \"text\";\n text: string;\n}\n\ninterface McpCallToolResult {\n content: unknown[];\n isError?: boolean;\n}\n\nfunction isCallToolResult(value: unknown): value is McpCallToolResult {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n return Array.isArray((value as Record<string, unknown>).content);\n}\n\nfunction isTextBlock(block: unknown): block is McpTextBlock {\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n return false;\n }\n const obj = block as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\nfunction parseCallToolResult(result: McpCallToolResult): ToolCallResult {\n const isError = result.isError === true;\n const content = result.content;\n\n if (content.length === 0) {\n return { data: null, isError };\n }\n\n const firstText = content.find(isTextBlock);\n\n if (!firstText) {\n // No text blocks — return the full content array so callers can inspect it.\n return { data: content, isError };\n }\n\n // Try to parse JSON from the text block.\n try {\n return { data: JSON.parse(firstText.text), isError };\n } catch {\n // Invalid JSON — return the raw string.\n return { data: firstText.text, isError };\n }\n}\n","import type {\n JsonRpcMessage,\n JsonRpcNotification,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"./types.js\";\n\ntype PendingEntry = {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n};\n\ntype MessageHandler = (params: Record<string, unknown> | undefined) => void;\n\nexport class SynapseTransport {\n private counter = 0;\n private destroyed = false;\n private pending = new Map<string, PendingEntry>();\n private handlers = new Map<string, Set<MessageHandler>>();\n private listener: (event: MessageEvent) => void;\n\n constructor() {\n this.listener = (event: MessageEvent) => this.handleMessage(event);\n window.addEventListener(\"message\", this.listener);\n }\n\n send(method: string, params?: Record<string, unknown>): void {\n if (this.destroyed) return;\n\n const msg: JsonRpcNotification = {\n jsonrpc: \"2.0\",\n method,\n ...(params !== undefined && { params }),\n };\n window.parent.postMessage(msg, \"*\");\n }\n\n request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n if (this.destroyed) {\n return Promise.reject(new Error(\"Transport destroyed\"));\n }\n\n const id = `syn-${++this.counter}`;\n const msg: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n method,\n id,\n ...(params !== undefined && { params }),\n };\n\n return new Promise<unknown>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n window.parent.postMessage(msg, \"*\");\n });\n }\n\n onMessage(method: string, callback: MessageHandler): () => void {\n if (!this.handlers.has(method)) {\n this.handlers.set(method, new Set());\n }\n this.handlers.get(method)?.add(callback);\n\n return () => {\n const set = this.handlers.get(method);\n if (set) {\n set.delete(callback);\n if (set.size === 0) {\n this.handlers.delete(method);\n }\n }\n };\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n window.removeEventListener(\"message\", this.listener);\n\n const error = new Error(\"Transport destroyed\");\n for (const entry of this.pending.values()) {\n entry.reject(error);\n }\n this.pending.clear();\n this.handlers.clear();\n }\n\n private handleMessage(event: MessageEvent): void {\n if (this.destroyed) return;\n\n const data = event.data as JsonRpcMessage;\n if (!data || data.jsonrpc !== \"2.0\") return;\n\n // Response to a pending request\n if (\"id\" in data && data.id && !(\"method\" in data)) {\n const response = data as JsonRpcResponse;\n const entry = this.pending.get(response.id);\n if (!entry) return;\n this.pending.delete(response.id);\n\n if (response.error) {\n const err = new Error(response.error.message);\n (err as any).code = response.error.code;\n (err as any).data = response.error.data;\n entry.reject(err);\n } else {\n entry.resolve(response.result);\n }\n return;\n }\n\n // Incoming notification\n if (\"method\" in data && !(\"id\" in data && data.id)) {\n const notification = data as JsonRpcNotification;\n const set = this.handlers.get(notification.method);\n if (set) {\n for (const handler of set) {\n handler(notification.params);\n }\n }\n }\n }\n}\n","import { detectHost } from \"./detection.js\";\nimport { KeyboardForwarder } from \"./keyboard.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { SynapseTransport } from \"./transport.js\";\nimport type {\n AgentAction,\n DataChangedEvent,\n FileResult,\n HostInfo,\n RequestFileOptions,\n Synapse,\n SynapseOptions,\n SynapseTheme,\n ToolCallResult,\n} from \"./types.js\";\n\n/**\n * Create a Synapse instance.\n *\n * Wraps the ext-apps protocol handshake via `SynapseTransport` and provides\n * a typed, framework-agnostic API for calling tools, reacting to data changes,\n * dispatching actions, and pushing LLM-visible state.\n *\n * In non-NimbleBrain hosts, NB-specific methods degrade to no-ops.\n */\nexport function createSynapse(options: SynapseOptions): Synapse {\n const { name, version, internal = false, forwardKeys } = options;\n\n const transport = new SynapseTransport();\n let hostInfo: HostInfo | null = null;\n let currentTheme: SynapseTheme = {\n mode: \"light\",\n primaryColor: \"#6366f1\",\n tokens: {},\n };\n let destroyed = false;\n\n // --- Debounce for setVisibleState ---\n let stateTimer: ReturnType<typeof setTimeout> | null = null;\n\n // --- Keyboard forwarding ---\n let keyboard: KeyboardForwarder | null = null;\n\n // --- ext-apps handshake ---\n // We send ui/initialize as a JSON-RPC request and wait for the response.\n const ready = transport\n .request(\"ui/initialize\", {\n protocolVersion: \"2026-01-26\",\n clientInfo: { name, version },\n capabilities: {},\n })\n .then((result) => {\n hostInfo = detectHost(result);\n currentTheme = hostInfo.theme;\n\n // Send initialized notification per ext-apps spec\n transport.send(\"ui/notifications/initialized\", {});\n\n // Set up keyboard forwarding after we know the host\n keyboard = new KeyboardForwarder(transport, forwardKeys);\n });\n\n // Listen for theme changes from the host\n const unsubTheme = transport.onMessage(\"ui/notifications/host-context-changed\", (params) => {\n if (!params) return;\n const mode = params.theme === \"dark\" ? \"dark\" : \"light\";\n const tokens =\n params.tokens && typeof params.tokens === \"object\"\n ? (params.tokens as Record<string, string>)\n : currentTheme.tokens;\n currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };\n for (const cb of themeCallbacks) cb(currentTheme);\n });\n\n // Also listen for NB-specific synapse/theme-changed message\n const unsubNbTheme = transport.onMessage(\"synapse/theme-changed\", (params) => {\n if (!params) return;\n const mode =\n params.mode === \"dark\" || params.mode === \"light\" ? params.mode : currentTheme.mode;\n const tokens =\n params.tokens && typeof params.tokens === \"object\"\n ? (params.tokens as Record<string, string>)\n : currentTheme.tokens;\n currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };\n for (const cb of themeCallbacks) cb(currentTheme);\n });\n\n const themeCallbacks = new Set<(theme: SynapseTheme) => void>();\n const dataCallbacks = new Set<(event: DataChangedEvent) => void>();\n const actionCallbacks = new Set<(action: AgentAction) => void>();\n\n // Listen for data change events\n const unsubData = transport.onMessage(\"synapse/data-changed\", (params) => {\n if (!params) return;\n const event: DataChangedEvent = {\n source: \"agent\",\n server: (params.server as string) ?? \"\",\n tool: (params.tool as string) ?? \"\",\n };\n for (const cb of dataCallbacks) cb(event);\n });\n\n // Listen for agent actions (typed, declarative commands from the server)\n const unsubAction = transport.onMessage(\"synapse/action\", (params) => {\n if (!params || typeof params.type !== \"string\") return;\n const action: AgentAction = {\n type: params.type as string,\n payload: (params.payload as Record<string, unknown>) ?? {},\n requiresConfirmation: params.requiresConfirmation === true,\n label: typeof params.label === \"string\" ? params.label : undefined,\n };\n for (const cb of actionCallbacks) cb(action);\n });\n\n const isNB = () => hostInfo?.isNimbleBrain === true;\n\n const synapse: Synapse = {\n get ready() {\n return ready;\n },\n\n get isNimbleBrainHost() {\n return isNB();\n },\n\n get destroyed() {\n return destroyed;\n },\n\n async callTool<TInput = Record<string, unknown>, TOutput = unknown>(\n toolName: string,\n args?: TInput,\n ): Promise<ToolCallResult<TOutput>> {\n const params: Record<string, unknown> = {\n name: toolName,\n arguments: args ?? {},\n };\n // Internal apps can cross-call\n if (internal) {\n params.server = name;\n }\n const raw = await transport.request(\"tools/call\", params);\n return parseToolResult(raw) as ToolCallResult<TOutput>;\n },\n\n onDataChanged(callback: (event: DataChangedEvent) => void): () => void {\n dataCallbacks.add(callback);\n return () => {\n dataCallbacks.delete(callback);\n };\n },\n\n onAction(callback: (action: AgentAction) => void): () => void {\n actionCallbacks.add(callback);\n return () => {\n actionCallbacks.delete(callback);\n };\n },\n\n getTheme(): SynapseTheme {\n return { ...currentTheme };\n },\n\n onThemeChanged(callback: (theme: SynapseTheme) => void): () => void {\n themeCallbacks.add(callback);\n return () => {\n themeCallbacks.delete(callback);\n };\n },\n\n action(action: string, params?: Record<string, unknown>): void {\n if (!isNB()) return;\n transport.send(\"synapse/action\", { action, ...params });\n },\n\n chat(message: string, context?: { action?: string; entity?: string }): void {\n const textBlock: Record<string, unknown> = { type: \"text\", text: message };\n if (isNB() && context) {\n textBlock._meta = { context };\n }\n transport.send(\"ui/message\", {\n role: \"user\",\n content: [textBlock],\n });\n },\n\n setVisibleState(state: Record<string, unknown>, summary?: string): void {\n // Debounce: 250ms\n if (stateTimer) clearTimeout(stateTimer);\n stateTimer = setTimeout(() => {\n transport.send(\"ui/update-model-context\", {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary }],\n }),\n });\n stateTimer = null;\n }, 250);\n },\n\n downloadFile(filename: string, content: string | Blob, mimeType?: string): void {\n if (!isNB()) return;\n const data = typeof content === \"string\" ? content : \"[Blob content not serializable]\";\n transport.send(\"synapse/download-file\", {\n data,\n filename,\n mimeType: mimeType ?? \"application/octet-stream\",\n });\n },\n\n openLink(url: string): void {\n transport.send(\"ui/open-link\", { url });\n if (!isNB()) {\n window.open(url, \"_blank\", \"noopener\");\n }\n },\n\n async requestFile(options?: RequestFileOptions): Promise<FileResult | null> {\n if (!isNB()) {\n throw new Error(\"requestFile is not supported in this host\");\n }\n const result = await transport.request(\"synapse/request-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: false,\n });\n return (result as FileResult) ?? null;\n },\n\n async requestFiles(options?: RequestFileOptions): Promise<FileResult[]> {\n if (!isNB()) {\n throw new Error(\"requestFiles is not supported in this host\");\n }\n const result = await transport.request(\"synapse/request-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: true,\n });\n if (!result) return [];\n return Array.isArray(result) ? (result as FileResult[]) : [result as FileResult];\n },\n\n _onMessage(\n method: string,\n callback: (params: Record<string, unknown> | undefined) => void,\n ): () => void {\n return transport.onMessage(method, callback);\n },\n\n _request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n return transport.request(method, params);\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n\n if (stateTimer) clearTimeout(stateTimer);\n keyboard?.destroy();\n unsubTheme();\n unsubNbTheme();\n unsubData();\n unsubAction();\n themeCallbacks.clear();\n dataCallbacks.clear();\n actionCallbacks.clear();\n transport.destroy();\n },\n };\n\n return synapse;\n}\n"]}
|
|
@@ -43,7 +43,7 @@ var KeyboardForwarder = class {
|
|
|
43
43
|
if (this.destroyed) return;
|
|
44
44
|
if (this.shouldForward(event, config)) {
|
|
45
45
|
event.preventDefault();
|
|
46
|
-
transport.send("
|
|
46
|
+
transport.send("synapse/keydown", {
|
|
47
47
|
key: event.key,
|
|
48
48
|
ctrlKey: event.ctrlKey,
|
|
49
49
|
metaKey: event.metaKey,
|
|
@@ -67,7 +67,11 @@ var KeyboardForwarder = class {
|
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
if (event.key === "Escape") return true;
|
|
70
|
-
if (event.ctrlKey || event.metaKey)
|
|
70
|
+
if (event.ctrlKey || event.metaKey) {
|
|
71
|
+
const key = event.key.toLowerCase();
|
|
72
|
+
if (key === "c" || key === "v" || key === "x" || key === "a") return false;
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
71
75
|
return false;
|
|
72
76
|
}
|
|
73
77
|
};
|
|
@@ -235,7 +239,7 @@ function createSynapse(options) {
|
|
|
235
239
|
currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };
|
|
236
240
|
for (const cb of themeCallbacks) cb(currentTheme);
|
|
237
241
|
});
|
|
238
|
-
const unsubNbTheme = transport.onMessage("
|
|
242
|
+
const unsubNbTheme = transport.onMessage("synapse/theme-changed", (params) => {
|
|
239
243
|
if (!params) return;
|
|
240
244
|
const mode = params.mode === "dark" || params.mode === "light" ? params.mode : currentTheme.mode;
|
|
241
245
|
const tokens = params.tokens && typeof params.tokens === "object" ? params.tokens : currentTheme.tokens;
|
|
@@ -245,7 +249,7 @@ function createSynapse(options) {
|
|
|
245
249
|
const themeCallbacks = /* @__PURE__ */ new Set();
|
|
246
250
|
const dataCallbacks = /* @__PURE__ */ new Set();
|
|
247
251
|
const actionCallbacks = /* @__PURE__ */ new Set();
|
|
248
|
-
const unsubData = transport.onMessage("
|
|
252
|
+
const unsubData = transport.onMessage("synapse/data-changed", (params) => {
|
|
249
253
|
if (!params) return;
|
|
250
254
|
const event = {
|
|
251
255
|
source: "agent",
|
|
@@ -254,7 +258,7 @@ function createSynapse(options) {
|
|
|
254
258
|
};
|
|
255
259
|
for (const cb of dataCallbacks) cb(event);
|
|
256
260
|
});
|
|
257
|
-
const unsubAction = transport.onMessage("
|
|
261
|
+
const unsubAction = transport.onMessage("synapse/action", (params) => {
|
|
258
262
|
if (!params || typeof params.type !== "string") return;
|
|
259
263
|
const action = {
|
|
260
264
|
type: params.type,
|
|
@@ -309,19 +313,26 @@ function createSynapse(options) {
|
|
|
309
313
|
},
|
|
310
314
|
action(action, params) {
|
|
311
315
|
if (!isNB()) return;
|
|
312
|
-
transport.send("
|
|
316
|
+
transport.send("synapse/action", { action, ...params });
|
|
313
317
|
},
|
|
314
318
|
chat(message, context) {
|
|
315
|
-
|
|
316
|
-
|
|
319
|
+
const textBlock = { type: "text", text: message };
|
|
320
|
+
if (isNB() && context) {
|
|
321
|
+
textBlock._meta = { context };
|
|
322
|
+
}
|
|
323
|
+
transport.send("ui/message", {
|
|
324
|
+
role: "user",
|
|
325
|
+
content: [textBlock]
|
|
326
|
+
});
|
|
317
327
|
},
|
|
318
328
|
setVisibleState(state, summary) {
|
|
319
|
-
if (!isNB()) return;
|
|
320
329
|
if (stateTimer) clearTimeout(stateTimer);
|
|
321
330
|
stateTimer = setTimeout(() => {
|
|
322
|
-
transport.send("ui/
|
|
323
|
-
state,
|
|
324
|
-
...summary !== void 0 && {
|
|
331
|
+
transport.send("ui/update-model-context", {
|
|
332
|
+
structuredContent: state,
|
|
333
|
+
...summary !== void 0 && {
|
|
334
|
+
content: [{ type: "text", text: summary }]
|
|
335
|
+
}
|
|
325
336
|
});
|
|
326
337
|
stateTimer = null;
|
|
327
338
|
}, 250);
|
|
@@ -329,19 +340,41 @@ function createSynapse(options) {
|
|
|
329
340
|
downloadFile(filename, content, mimeType) {
|
|
330
341
|
if (!isNB()) return;
|
|
331
342
|
const data = typeof content === "string" ? content : "[Blob content not serializable]";
|
|
332
|
-
transport.send("
|
|
343
|
+
transport.send("synapse/download-file", {
|
|
333
344
|
data,
|
|
334
345
|
filename,
|
|
335
346
|
mimeType: mimeType ?? "application/octet-stream"
|
|
336
347
|
});
|
|
337
348
|
},
|
|
338
349
|
openLink(url) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
} else {
|
|
350
|
+
transport.send("ui/open-link", { url });
|
|
351
|
+
if (!isNB()) {
|
|
342
352
|
window.open(url, "_blank", "noopener");
|
|
343
353
|
}
|
|
344
354
|
},
|
|
355
|
+
async requestFile(options2) {
|
|
356
|
+
if (!isNB()) {
|
|
357
|
+
throw new Error("requestFile is not supported in this host");
|
|
358
|
+
}
|
|
359
|
+
const result = await transport.request("synapse/request-file", {
|
|
360
|
+
accept: options2?.accept,
|
|
361
|
+
maxSize: options2?.maxSize ?? 26214400,
|
|
362
|
+
multiple: false
|
|
363
|
+
});
|
|
364
|
+
return result ?? null;
|
|
365
|
+
},
|
|
366
|
+
async requestFiles(options2) {
|
|
367
|
+
if (!isNB()) {
|
|
368
|
+
throw new Error("requestFiles is not supported in this host");
|
|
369
|
+
}
|
|
370
|
+
const result = await transport.request("synapse/request-file", {
|
|
371
|
+
accept: options2?.accept,
|
|
372
|
+
maxSize: options2?.maxSize ?? 26214400,
|
|
373
|
+
multiple: true
|
|
374
|
+
});
|
|
375
|
+
if (!result) return [];
|
|
376
|
+
return Array.isArray(result) ? result : [result];
|
|
377
|
+
},
|
|
345
378
|
_onMessage(method, callback) {
|
|
346
379
|
return transport.onMessage(method, callback);
|
|
347
380
|
},
|
|
@@ -367,5 +400,5 @@ function createSynapse(options) {
|
|
|
367
400
|
}
|
|
368
401
|
|
|
369
402
|
export { createSynapse };
|
|
370
|
-
//# sourceMappingURL=chunk-
|
|
371
|
-
//# sourceMappingURL=chunk-
|
|
403
|
+
//# sourceMappingURL=chunk-QY4IBJKV.js.map
|
|
404
|
+
//# sourceMappingURL=chunk-QY4IBJKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/detection.ts","../src/keyboard.ts","../src/result-parser.ts","../src/transport.ts","../src/core.ts"],"names":["options"],"mappings":"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","file":"chunk-QY4IBJKV.js","sourcesContent":["import type { HostInfo, SynapseTheme } from \"./types\";\n\nconst DEFAULT_THEME: SynapseTheme = {\n mode: \"light\",\n primaryColor: \"#6366f1\",\n tokens: {},\n};\n\n/**\n * Detect the host environment from the ext-apps `ui/initialize` response.\n *\n * Handles missing or malformed fields gracefully — never throws.\n */\nexport function detectHost(initResponse: unknown): HostInfo {\n const resp = initResponse as Record<string, unknown> | null | undefined;\n\n const serverInfo = safeObj(resp?.serverInfo);\n const serverName = typeof serverInfo?.name === \"string\" ? serverInfo.name : \"unknown\";\n\n const protocolVersion =\n typeof resp?.protocolVersion === \"string\" ? resp.protocolVersion : \"unknown\";\n\n const hostContext = safeObj(resp?.hostContext);\n const theme = extractTheme(hostContext?.theme);\n\n return {\n isNimbleBrain: serverName === \"nimblebrain\",\n serverName,\n protocolVersion,\n theme,\n };\n}\n\nfunction extractTheme(raw: unknown): SynapseTheme {\n const obj = safeObj(raw);\n if (!obj) return { ...DEFAULT_THEME };\n\n const mode = obj.mode === \"light\" || obj.mode === \"dark\" ? obj.mode : DEFAULT_THEME.mode;\n\n const primaryColor =\n typeof obj.primaryColor === \"string\" ? obj.primaryColor : DEFAULT_THEME.primaryColor;\n\n const tokens =\n obj.tokens !== null && typeof obj.tokens === \"object\" && !Array.isArray(obj.tokens)\n ? (obj.tokens as Record<string, string>)\n : {};\n\n return { mode, primaryColor, tokens };\n}\n\nfunction safeObj(value: unknown): Record<string, unknown> | undefined {\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n","import type { SynapseTransport } from \"./transport.js\";\nimport type { KeyForwardConfig } from \"./types.js\";\n\n/**\n * Forward keyboard shortcuts from the iframe document to the host.\n *\n * By default, forwards all Ctrl/Cmd+key combos and Escape.\n * Apps can customize via `forwardKeys` config.\n */\nexport class KeyboardForwarder {\n private listener: (event: KeyboardEvent) => void;\n private destroyed = false;\n\n constructor(transport: SynapseTransport, customKeys?: KeyForwardConfig[]) {\n const config = customKeys ?? null; // null = default behavior\n\n this.listener = (event: KeyboardEvent) => {\n if (this.destroyed) return;\n if (this.shouldForward(event, config)) {\n event.preventDefault();\n transport.send(\"synapse/keydown\", {\n key: event.key,\n ctrlKey: event.ctrlKey,\n metaKey: event.metaKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n });\n }\n };\n\n document.addEventListener(\"keydown\", this.listener);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n document.removeEventListener(\"keydown\", this.listener);\n }\n\n private shouldForward(event: KeyboardEvent, config: KeyForwardConfig[] | null): boolean {\n // Empty array = forwarding disabled\n if (config && config.length === 0) return false;\n\n // Custom config: match exactly\n if (config) {\n return config.some(\n (k) =>\n event.key.toLowerCase() === k.key.toLowerCase() &&\n (k.ctrl === undefined || event.ctrlKey === k.ctrl) &&\n (k.meta === undefined || event.metaKey === k.meta) &&\n (k.shift === undefined || event.shiftKey === k.shift) &&\n (k.alt === undefined || event.altKey === k.alt),\n );\n }\n\n // Default: forward all Ctrl/Cmd combos + Escape,\n // EXCEPT clipboard shortcuts (c, v, x, a) which the browser must handle natively.\n if (event.key === \"Escape\") return true;\n if (event.ctrlKey || event.metaKey) {\n const key = event.key.toLowerCase();\n if (key === \"c\" || key === \"v\" || key === \"x\" || key === \"a\") return false;\n return true;\n }\n return false;\n }\n}\n","import type { ToolCallResult } from \"./types.js\";\n\n/**\n * Normalize a raw tool call response into a consistent `ToolCallResult`.\n *\n * Handles three shapes:\n * 1. MCP `CallToolResult` — has a `content` array with typed blocks.\n * 2. Raw JSON object (NimbleBrain bridge) — used as-is.\n * 3. Null / undefined — returns `{ data: null, isError: false }`.\n */\nexport function parseToolResult(raw: unknown): ToolCallResult {\n if (raw == null) {\n return { data: null, isError: false };\n }\n\n if (isCallToolResult(raw)) {\n return parseCallToolResult(raw);\n }\n\n // Raw JSON object — pass through.\n return { data: raw, isError: false };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\ninterface McpTextBlock {\n type: \"text\";\n text: string;\n}\n\ninterface McpCallToolResult {\n content: unknown[];\n isError?: boolean;\n}\n\nfunction isCallToolResult(value: unknown): value is McpCallToolResult {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n return Array.isArray((value as Record<string, unknown>).content);\n}\n\nfunction isTextBlock(block: unknown): block is McpTextBlock {\n if (block === null || typeof block !== \"object\" || Array.isArray(block)) {\n return false;\n }\n const obj = block as Record<string, unknown>;\n return obj.type === \"text\" && typeof obj.text === \"string\";\n}\n\nfunction parseCallToolResult(result: McpCallToolResult): ToolCallResult {\n const isError = result.isError === true;\n const content = result.content;\n\n if (content.length === 0) {\n return { data: null, isError };\n }\n\n const firstText = content.find(isTextBlock);\n\n if (!firstText) {\n // No text blocks — return the full content array so callers can inspect it.\n return { data: content, isError };\n }\n\n // Try to parse JSON from the text block.\n try {\n return { data: JSON.parse(firstText.text), isError };\n } catch {\n // Invalid JSON — return the raw string.\n return { data: firstText.text, isError };\n }\n}\n","import type {\n JsonRpcMessage,\n JsonRpcNotification,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"./types.js\";\n\ntype PendingEntry = {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n};\n\ntype MessageHandler = (params: Record<string, unknown> | undefined) => void;\n\nexport class SynapseTransport {\n private counter = 0;\n private destroyed = false;\n private pending = new Map<string, PendingEntry>();\n private handlers = new Map<string, Set<MessageHandler>>();\n private listener: (event: MessageEvent) => void;\n\n constructor() {\n this.listener = (event: MessageEvent) => this.handleMessage(event);\n window.addEventListener(\"message\", this.listener);\n }\n\n send(method: string, params?: Record<string, unknown>): void {\n if (this.destroyed) return;\n\n const msg: JsonRpcNotification = {\n jsonrpc: \"2.0\",\n method,\n ...(params !== undefined && { params }),\n };\n window.parent.postMessage(msg, \"*\");\n }\n\n request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n if (this.destroyed) {\n return Promise.reject(new Error(\"Transport destroyed\"));\n }\n\n const id = `syn-${++this.counter}`;\n const msg: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n method,\n id,\n ...(params !== undefined && { params }),\n };\n\n return new Promise<unknown>((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n window.parent.postMessage(msg, \"*\");\n });\n }\n\n onMessage(method: string, callback: MessageHandler): () => void {\n if (!this.handlers.has(method)) {\n this.handlers.set(method, new Set());\n }\n this.handlers.get(method)?.add(callback);\n\n return () => {\n const set = this.handlers.get(method);\n if (set) {\n set.delete(callback);\n if (set.size === 0) {\n this.handlers.delete(method);\n }\n }\n };\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n\n window.removeEventListener(\"message\", this.listener);\n\n const error = new Error(\"Transport destroyed\");\n for (const entry of this.pending.values()) {\n entry.reject(error);\n }\n this.pending.clear();\n this.handlers.clear();\n }\n\n private handleMessage(event: MessageEvent): void {\n if (this.destroyed) return;\n\n const data = event.data as JsonRpcMessage;\n if (!data || data.jsonrpc !== \"2.0\") return;\n\n // Response to a pending request\n if (\"id\" in data && data.id && !(\"method\" in data)) {\n const response = data as JsonRpcResponse;\n const entry = this.pending.get(response.id);\n if (!entry) return;\n this.pending.delete(response.id);\n\n if (response.error) {\n const err = new Error(response.error.message);\n (err as any).code = response.error.code;\n (err as any).data = response.error.data;\n entry.reject(err);\n } else {\n entry.resolve(response.result);\n }\n return;\n }\n\n // Incoming notification\n if (\"method\" in data && !(\"id\" in data && data.id)) {\n const notification = data as JsonRpcNotification;\n const set = this.handlers.get(notification.method);\n if (set) {\n for (const handler of set) {\n handler(notification.params);\n }\n }\n }\n }\n}\n","import { detectHost } from \"./detection.js\";\nimport { KeyboardForwarder } from \"./keyboard.js\";\nimport { parseToolResult } from \"./result-parser.js\";\nimport { SynapseTransport } from \"./transport.js\";\nimport type {\n AgentAction,\n DataChangedEvent,\n FileResult,\n HostInfo,\n RequestFileOptions,\n Synapse,\n SynapseOptions,\n SynapseTheme,\n ToolCallResult,\n} from \"./types.js\";\n\n/**\n * Create a Synapse instance.\n *\n * Wraps the ext-apps protocol handshake via `SynapseTransport` and provides\n * a typed, framework-agnostic API for calling tools, reacting to data changes,\n * dispatching actions, and pushing LLM-visible state.\n *\n * In non-NimbleBrain hosts, NB-specific methods degrade to no-ops.\n */\nexport function createSynapse(options: SynapseOptions): Synapse {\n const { name, version, internal = false, forwardKeys } = options;\n\n const transport = new SynapseTransport();\n let hostInfo: HostInfo | null = null;\n let currentTheme: SynapseTheme = {\n mode: \"light\",\n primaryColor: \"#6366f1\",\n tokens: {},\n };\n let destroyed = false;\n\n // --- Debounce for setVisibleState ---\n let stateTimer: ReturnType<typeof setTimeout> | null = null;\n\n // --- Keyboard forwarding ---\n let keyboard: KeyboardForwarder | null = null;\n\n // --- ext-apps handshake ---\n // We send ui/initialize as a JSON-RPC request and wait for the response.\n const ready = transport\n .request(\"ui/initialize\", {\n protocolVersion: \"2026-01-26\",\n clientInfo: { name, version },\n capabilities: {},\n })\n .then((result) => {\n hostInfo = detectHost(result);\n currentTheme = hostInfo.theme;\n\n // Send initialized notification per ext-apps spec\n transport.send(\"ui/notifications/initialized\", {});\n\n // Set up keyboard forwarding after we know the host\n keyboard = new KeyboardForwarder(transport, forwardKeys);\n });\n\n // Listen for theme changes from the host\n const unsubTheme = transport.onMessage(\"ui/notifications/host-context-changed\", (params) => {\n if (!params) return;\n const mode = params.theme === \"dark\" ? \"dark\" : \"light\";\n const tokens =\n params.tokens && typeof params.tokens === \"object\"\n ? (params.tokens as Record<string, string>)\n : currentTheme.tokens;\n currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };\n for (const cb of themeCallbacks) cb(currentTheme);\n });\n\n // Also listen for NB-specific synapse/theme-changed message\n const unsubNbTheme = transport.onMessage(\"synapse/theme-changed\", (params) => {\n if (!params) return;\n const mode =\n params.mode === \"dark\" || params.mode === \"light\" ? params.mode : currentTheme.mode;\n const tokens =\n params.tokens && typeof params.tokens === \"object\"\n ? (params.tokens as Record<string, string>)\n : currentTheme.tokens;\n currentTheme = { mode, primaryColor: currentTheme.primaryColor, tokens };\n for (const cb of themeCallbacks) cb(currentTheme);\n });\n\n const themeCallbacks = new Set<(theme: SynapseTheme) => void>();\n const dataCallbacks = new Set<(event: DataChangedEvent) => void>();\n const actionCallbacks = new Set<(action: AgentAction) => void>();\n\n // Listen for data change events\n const unsubData = transport.onMessage(\"synapse/data-changed\", (params) => {\n if (!params) return;\n const event: DataChangedEvent = {\n source: \"agent\",\n server: (params.server as string) ?? \"\",\n tool: (params.tool as string) ?? \"\",\n };\n for (const cb of dataCallbacks) cb(event);\n });\n\n // Listen for agent actions (typed, declarative commands from the server)\n const unsubAction = transport.onMessage(\"synapse/action\", (params) => {\n if (!params || typeof params.type !== \"string\") return;\n const action: AgentAction = {\n type: params.type as string,\n payload: (params.payload as Record<string, unknown>) ?? {},\n requiresConfirmation: params.requiresConfirmation === true,\n label: typeof params.label === \"string\" ? params.label : undefined,\n };\n for (const cb of actionCallbacks) cb(action);\n });\n\n const isNB = () => hostInfo?.isNimbleBrain === true;\n\n const synapse: Synapse = {\n get ready() {\n return ready;\n },\n\n get isNimbleBrainHost() {\n return isNB();\n },\n\n get destroyed() {\n return destroyed;\n },\n\n async callTool<TInput = Record<string, unknown>, TOutput = unknown>(\n toolName: string,\n args?: TInput,\n ): Promise<ToolCallResult<TOutput>> {\n const params: Record<string, unknown> = {\n name: toolName,\n arguments: args ?? {},\n };\n // Internal apps can cross-call\n if (internal) {\n params.server = name;\n }\n const raw = await transport.request(\"tools/call\", params);\n return parseToolResult(raw) as ToolCallResult<TOutput>;\n },\n\n onDataChanged(callback: (event: DataChangedEvent) => void): () => void {\n dataCallbacks.add(callback);\n return () => {\n dataCallbacks.delete(callback);\n };\n },\n\n onAction(callback: (action: AgentAction) => void): () => void {\n actionCallbacks.add(callback);\n return () => {\n actionCallbacks.delete(callback);\n };\n },\n\n getTheme(): SynapseTheme {\n return { ...currentTheme };\n },\n\n onThemeChanged(callback: (theme: SynapseTheme) => void): () => void {\n themeCallbacks.add(callback);\n return () => {\n themeCallbacks.delete(callback);\n };\n },\n\n action(action: string, params?: Record<string, unknown>): void {\n if (!isNB()) return;\n transport.send(\"synapse/action\", { action, ...params });\n },\n\n chat(message: string, context?: { action?: string; entity?: string }): void {\n const textBlock: Record<string, unknown> = { type: \"text\", text: message };\n if (isNB() && context) {\n textBlock._meta = { context };\n }\n transport.send(\"ui/message\", {\n role: \"user\",\n content: [textBlock],\n });\n },\n\n setVisibleState(state: Record<string, unknown>, summary?: string): void {\n // Debounce: 250ms\n if (stateTimer) clearTimeout(stateTimer);\n stateTimer = setTimeout(() => {\n transport.send(\"ui/update-model-context\", {\n structuredContent: state,\n ...(summary !== undefined && {\n content: [{ type: \"text\", text: summary }],\n }),\n });\n stateTimer = null;\n }, 250);\n },\n\n downloadFile(filename: string, content: string | Blob, mimeType?: string): void {\n if (!isNB()) return;\n const data = typeof content === \"string\" ? content : \"[Blob content not serializable]\";\n transport.send(\"synapse/download-file\", {\n data,\n filename,\n mimeType: mimeType ?? \"application/octet-stream\",\n });\n },\n\n openLink(url: string): void {\n transport.send(\"ui/open-link\", { url });\n if (!isNB()) {\n window.open(url, \"_blank\", \"noopener\");\n }\n },\n\n async requestFile(options?: RequestFileOptions): Promise<FileResult | null> {\n if (!isNB()) {\n throw new Error(\"requestFile is not supported in this host\");\n }\n const result = await transport.request(\"synapse/request-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: false,\n });\n return (result as FileResult) ?? null;\n },\n\n async requestFiles(options?: RequestFileOptions): Promise<FileResult[]> {\n if (!isNB()) {\n throw new Error(\"requestFiles is not supported in this host\");\n }\n const result = await transport.request(\"synapse/request-file\", {\n accept: options?.accept,\n maxSize: options?.maxSize ?? 26_214_400,\n multiple: true,\n });\n if (!result) return [];\n return Array.isArray(result) ? (result as FileResult[]) : [result as FileResult];\n },\n\n _onMessage(\n method: string,\n callback: (params: Record<string, unknown> | undefined) => void,\n ): () => void {\n return transport.onMessage(method, callback);\n },\n\n _request(method: string, params?: Record<string, unknown>): Promise<unknown> {\n return transport.request(method, params);\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n\n if (stateTimer) clearTimeout(stateTimer);\n keyboard?.destroy();\n unsubTheme();\n unsubNbTheme();\n unsubData();\n unsubAction();\n themeCallbacks.clear();\n dataCallbacks.clear();\n actionCallbacks.clear();\n transport.destroy();\n },\n };\n\n return synapse;\n}\n"]}
|
package/dist/codegen/cli.cjs
CHANGED
|
@@ -58,7 +58,7 @@ async function runCodegen(args2) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
async function runPreview(args2) {
|
|
61
|
-
const { startPreview } = await import('../server-
|
|
61
|
+
const { startPreview } = await import('../server-SRE7E3G3.cjs');
|
|
62
62
|
const flags = parseFlags(args2, ["server", "ui", "server-port", "ui-port", "port"]);
|
|
63
63
|
if (!flags.server || !flags.ui) {
|
|
64
64
|
console.error("Usage:");
|
package/dist/codegen/cli.js
CHANGED
|
@@ -56,7 +56,7 @@ async function runCodegen(args2) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
async function runPreview(args2) {
|
|
59
|
-
const { startPreview } = await import('../server-
|
|
59
|
+
const { startPreview } = await import('../server-7BRGSPT3.js');
|
|
60
60
|
const flags = parseFlags(args2, ["server", "ui", "server-port", "ui-port", "port"]);
|
|
61
61
|
if (!flags.server || !flags.ui) {
|
|
62
62
|
console.error("Usage:");
|
package/dist/codegen/index.d.cts
CHANGED
package/dist/codegen/index.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkMQNKIR7K_cjs = require('./chunk-MQNKIR7K.cjs');
|
|
4
4
|
|
|
5
5
|
// src/store.ts
|
|
6
6
|
function createStore(synapse, config) {
|
|
@@ -28,7 +28,7 @@ function createStore(synapse, config) {
|
|
|
28
28
|
function schedulePersist() {
|
|
29
29
|
if (persistTimer) clearTimeout(persistTimer);
|
|
30
30
|
persistTimer = setTimeout(() => {
|
|
31
|
-
synapse._request("
|
|
31
|
+
synapse._request("synapse/persist-state", {
|
|
32
32
|
state,
|
|
33
33
|
version: config.version
|
|
34
34
|
}).catch(() => {
|
|
@@ -38,7 +38,7 @@ function createStore(synapse, config) {
|
|
|
38
38
|
}
|
|
39
39
|
let unsubStateLoaded;
|
|
40
40
|
if (config.persist) {
|
|
41
|
-
unsubStateLoaded = synapse._onMessage("
|
|
41
|
+
unsubStateLoaded = synapse._onMessage("synapse/state-loaded", (params) => {
|
|
42
42
|
if (!params?.state) return;
|
|
43
43
|
let loaded = params.state;
|
|
44
44
|
const loadedVersion = params.version ?? 1;
|
|
@@ -80,7 +80,7 @@ function createStore(synapse, config) {
|
|
|
80
80
|
|
|
81
81
|
Object.defineProperty(exports, "createSynapse", {
|
|
82
82
|
enumerable: true,
|
|
83
|
-
get: function () { return
|
|
83
|
+
get: function () { return chunkMQNKIR7K_cjs.createSynapse; }
|
|
84
84
|
});
|
|
85
85
|
exports.createStore = createStore;
|
|
86
86
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":";;;;;AASO,SAAS,WAAA,CAMd,SAAkB,MAAA,EAA8E;AAChG,EAAA,IAAI,KAAA,GAAQ,eAAA,CAAgB,MAAA,CAAO,YAAY,CAAA;AAC/C,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAA6B;AACrD,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,YAAA,GAAqD,IAAA;AAGzD,EAAA,MAAM,WAAW,EAAC;AAClB,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AAC7C,IAAC,QAAA,CAAiB,GAAG,CAAA,GAAI,CAAC,OAAA,KAAqB;AAC7C,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAC1C,MAAA,MAAA,EAAO;AAAA,IACT,CAAA;AAAA,EACF;AAEA,EAAA,SAAS,MAAA,GAAe;AACtB,IAAA,KAAA,MAAW,EAAA,IAAM,WAAA,EAAa,EAAA,CAAG,KAAK,CAAA;AACtC,IAAA,IAAI,MAAA,CAAO,gBAAgB,WAAA,EAAY;AACvC,IAAA,IAAI,MAAA,CAAO,SAAS,eAAA,EAAgB;AAAA,EACtC;AAEA,EAAA,SAAS,WAAA,GAAoB;AAC3B,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,SAAA,GAAY,KAAK,CAAA;AACxC,IAAA,OAAA,CAAQ,eAAA,CAAgB,OAA6C,OAAO,CAAA;AAAA,EAC9E;AAEA,EAAA,SAAS,eAAA,GAAwB;AAC/B,IAAA,IAAI,YAAA,eAA2B,YAAY,CAAA;AAC3C,IAAA,YAAA,GAAe,WAAW,MAAM;AAC9B,MAAA,OAAA,CACG,SAAS,
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ActionReducer, Store, StoreConfig, StoreDispatch, Synapse } from \"./types.js\";\n\n/**\n * Create a typed state store with optional persistence and agent visibility.\n *\n * - `persist: true` — state survives iframe reloads via host storage\n * - `visibleToAgent: true` — state is pushed to the LLM context\n * - Both are independent and can be enabled separately\n */\nexport function createStore<\n TState,\n TActions extends Record<string, ActionReducer<TState, any>> = Record<\n string,\n ActionReducer<TState, any>\n >,\n>(synapse: Synapse, config: StoreConfig<TState> & { actions: TActions }): Store<TState, TActions> {\n let state = structuredClone(config.initialState);\n const subscribers = new Set<(state: TState) => void>();\n let destroyed = false;\n let persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Build dispatch object from action reducers\n const dispatch = {} as StoreDispatch<TActions>;\n for (const key of Object.keys(config.actions)) {\n (dispatch as any)[key] = (payload: unknown) => {\n if (destroyed) return;\n state = config.actions[key](state, payload);\n notify();\n };\n }\n\n function notify(): void {\n for (const cb of subscribers) cb(state);\n if (config.visibleToAgent) pushToAgent();\n if (config.persist) schedulePersist();\n }\n\n function pushToAgent(): void {\n const summary = config.summarize?.(state);\n synapse.setVisibleState(state as unknown as Record<string, unknown>, summary);\n }\n\n function schedulePersist(): void {\n if (persistTimer) clearTimeout(persistTimer);\n persistTimer = setTimeout(() => {\n synapse\n ._request(\"synapse/persist-state\", {\n state: state as unknown as Record<string, unknown>,\n version: config.version,\n })\n .catch(() => {\n // Silently ignore persist failures (host may not support it)\n });\n persistTimer = null;\n }, 500);\n }\n\n // Listen for state loaded from host (on init)\n let unsubStateLoaded: (() => void) | undefined;\n if (config.persist) {\n unsubStateLoaded = synapse._onMessage(\"synapse/state-loaded\", (params) => {\n if (!params?.state) return;\n let loaded = params.state as TState;\n const loadedVersion = (params.version as number) ?? 1;\n const currentVersion = config.version ?? 1;\n\n // Run migrations if needed\n if (config.migrations && loadedVersion < currentVersion) {\n const startIdx = loadedVersion - 1;\n for (let i = startIdx; i < config.migrations.length; i++) {\n loaded = config.migrations[i](loaded);\n }\n }\n\n store.hydrate(loaded);\n });\n }\n\n const store: Store<TState, TActions> = {\n getState(): TState {\n return state;\n },\n\n subscribe(callback: (state: TState) => void): () => void {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n\n dispatch,\n\n hydrate(newState: TState): void {\n state = newState;\n for (const cb of subscribers) cb(state);\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (persistTimer) clearTimeout(persistTimer);\n subscribers.clear();\n unsubStateLoaded?.();\n },\n };\n\n return store;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SynapseOptions, a as Synapse, A as ActionReducer, b as StoreConfig, c as Store } from './types-
|
|
2
|
-
export { d as AgentAction, B as BuiltinActionType, D as DataChangedEvent, H as HostInfo, K as KeyForwardConfig, N as NavigatePayload, e as NotifyPayload, f as StateAcknowledgement, g as StoreDispatch, h as SynapseTheme, T as ToolCallResult, i as ToolDefinition, V as VisibleState } from './types-
|
|
1
|
+
import { S as SynapseOptions, a as Synapse, A as ActionReducer, b as StoreConfig, c as Store } from './types-CG7zrCn-.cjs';
|
|
2
|
+
export { d as AgentAction, B as BuiltinActionType, D as DataChangedEvent, F as FileResult, H as HostInfo, K as KeyForwardConfig, N as NavigatePayload, e as NotifyPayload, R as RequestFileOptions, f as StateAcknowledgement, g as StoreDispatch, h as SynapseTheme, T as ToolCallResult, i as ToolDefinition, V as VisibleState } from './types-CG7zrCn-.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create a Synapse instance.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SynapseOptions, a as Synapse, A as ActionReducer, b as StoreConfig, c as Store } from './types-
|
|
2
|
-
export { d as AgentAction, B as BuiltinActionType, D as DataChangedEvent, H as HostInfo, K as KeyForwardConfig, N as NavigatePayload, e as NotifyPayload, f as StateAcknowledgement, g as StoreDispatch, h as SynapseTheme, T as ToolCallResult, i as ToolDefinition, V as VisibleState } from './types-
|
|
1
|
+
import { S as SynapseOptions, a as Synapse, A as ActionReducer, b as StoreConfig, c as Store } from './types-CG7zrCn-.js';
|
|
2
|
+
export { d as AgentAction, B as BuiltinActionType, D as DataChangedEvent, F as FileResult, H as HostInfo, K as KeyForwardConfig, N as NavigatePayload, e as NotifyPayload, R as RequestFileOptions, f as StateAcknowledgement, g as StoreDispatch, h as SynapseTheme, T as ToolCallResult, i as ToolDefinition, V as VisibleState } from './types-CG7zrCn-.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create a Synapse instance.
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createSynapse } from './chunk-
|
|
1
|
+
export { createSynapse } from './chunk-QY4IBJKV.js';
|
|
2
2
|
|
|
3
3
|
// src/store.ts
|
|
4
4
|
function createStore(synapse, config) {
|
|
@@ -26,7 +26,7 @@ function createStore(synapse, config) {
|
|
|
26
26
|
function schedulePersist() {
|
|
27
27
|
if (persistTimer) clearTimeout(persistTimer);
|
|
28
28
|
persistTimer = setTimeout(() => {
|
|
29
|
-
synapse._request("
|
|
29
|
+
synapse._request("synapse/persist-state", {
|
|
30
30
|
state,
|
|
31
31
|
version: config.version
|
|
32
32
|
}).catch(() => {
|
|
@@ -36,7 +36,7 @@ function createStore(synapse, config) {
|
|
|
36
36
|
}
|
|
37
37
|
let unsubStateLoaded;
|
|
38
38
|
if (config.persist) {
|
|
39
|
-
unsubStateLoaded = synapse._onMessage("
|
|
39
|
+
unsubStateLoaded = synapse._onMessage("synapse/state-loaded", (params) => {
|
|
40
40
|
if (!params?.state) return;
|
|
41
41
|
let loaded = params.state;
|
|
42
42
|
const loadedVersion = params.version ?? 1;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":";;;AASO,SAAS,WAAA,CAMd,SAAkB,MAAA,EAA8E;AAChG,EAAA,IAAI,KAAA,GAAQ,eAAA,CAAgB,MAAA,CAAO,YAAY,CAAA;AAC/C,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAA6B;AACrD,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,YAAA,GAAqD,IAAA;AAGzD,EAAA,MAAM,WAAW,EAAC;AAClB,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AAC7C,IAAC,QAAA,CAAiB,GAAG,CAAA,GAAI,CAAC,OAAA,KAAqB;AAC7C,MAAA,IAAI,SAAA,EAAW;AACf,MAAA,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAC1C,MAAA,MAAA,EAAO;AAAA,IACT,CAAA;AAAA,EACF;AAEA,EAAA,SAAS,MAAA,GAAe;AACtB,IAAA,KAAA,MAAW,EAAA,IAAM,WAAA,EAAa,EAAA,CAAG,KAAK,CAAA;AACtC,IAAA,IAAI,MAAA,CAAO,gBAAgB,WAAA,EAAY;AACvC,IAAA,IAAI,MAAA,CAAO,SAAS,eAAA,EAAgB;AAAA,EACtC;AAEA,EAAA,SAAS,WAAA,GAAoB;AAC3B,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,SAAA,GAAY,KAAK,CAAA;AACxC,IAAA,OAAA,CAAQ,eAAA,CAAgB,OAA6C,OAAO,CAAA;AAAA,EAC9E;AAEA,EAAA,SAAS,eAAA,GAAwB;AAC/B,IAAA,IAAI,YAAA,eAA2B,YAAY,CAAA;AAC3C,IAAA,YAAA,GAAe,WAAW,MAAM;AAC9B,MAAA,OAAA,CACG,SAAS,
|
|
1
|
+
{"version":3,"sources":["../src/store.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ActionReducer, Store, StoreConfig, StoreDispatch, Synapse } from \"./types.js\";\n\n/**\n * Create a typed state store with optional persistence and agent visibility.\n *\n * - `persist: true` — state survives iframe reloads via host storage\n * - `visibleToAgent: true` — state is pushed to the LLM context\n * - Both are independent and can be enabled separately\n */\nexport function createStore<\n TState,\n TActions extends Record<string, ActionReducer<TState, any>> = Record<\n string,\n ActionReducer<TState, any>\n >,\n>(synapse: Synapse, config: StoreConfig<TState> & { actions: TActions }): Store<TState, TActions> {\n let state = structuredClone(config.initialState);\n const subscribers = new Set<(state: TState) => void>();\n let destroyed = false;\n let persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n // Build dispatch object from action reducers\n const dispatch = {} as StoreDispatch<TActions>;\n for (const key of Object.keys(config.actions)) {\n (dispatch as any)[key] = (payload: unknown) => {\n if (destroyed) return;\n state = config.actions[key](state, payload);\n notify();\n };\n }\n\n function notify(): void {\n for (const cb of subscribers) cb(state);\n if (config.visibleToAgent) pushToAgent();\n if (config.persist) schedulePersist();\n }\n\n function pushToAgent(): void {\n const summary = config.summarize?.(state);\n synapse.setVisibleState(state as unknown as Record<string, unknown>, summary);\n }\n\n function schedulePersist(): void {\n if (persistTimer) clearTimeout(persistTimer);\n persistTimer = setTimeout(() => {\n synapse\n ._request(\"synapse/persist-state\", {\n state: state as unknown as Record<string, unknown>,\n version: config.version,\n })\n .catch(() => {\n // Silently ignore persist failures (host may not support it)\n });\n persistTimer = null;\n }, 500);\n }\n\n // Listen for state loaded from host (on init)\n let unsubStateLoaded: (() => void) | undefined;\n if (config.persist) {\n unsubStateLoaded = synapse._onMessage(\"synapse/state-loaded\", (params) => {\n if (!params?.state) return;\n let loaded = params.state as TState;\n const loadedVersion = (params.version as number) ?? 1;\n const currentVersion = config.version ?? 1;\n\n // Run migrations if needed\n if (config.migrations && loadedVersion < currentVersion) {\n const startIdx = loadedVersion - 1;\n for (let i = startIdx; i < config.migrations.length; i++) {\n loaded = config.migrations[i](loaded);\n }\n }\n\n store.hydrate(loaded);\n });\n }\n\n const store: Store<TState, TActions> = {\n getState(): TState {\n return state;\n },\n\n subscribe(callback: (state: TState) => void): () => void {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n\n dispatch,\n\n hydrate(newState: TState): void {\n state = newState;\n for (const cb of subscribers) cb(state);\n },\n\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (persistTimer) clearTimeout(persistTimer);\n subscribers.clear();\n unsubStateLoaded?.();\n },\n };\n\n return store;\n}\n"]}
|