@yushaw/sanqian-chat 0.2.15 → 0.2.18

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.
@@ -38,6 +38,9 @@ function createSanqianChatApi() {
38
38
  getSessionResources: () => {
39
39
  return ipcRenderer.sendSync("sanqian-chat:getSessionResourcesSync");
40
40
  },
41
+ fetchSessionResources: (agentId) => {
42
+ return ipcRenderer.invoke("sanqian-chat:fetchSessionResources", agentId ? { agentId } : void 0);
43
+ },
41
44
  onSessionResourceEvent: (callback) => {
42
45
  const handler = (_, event) => {
43
46
  callback(event);
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { ResourceType, HitlInterruptPayload, ContextListItem, HitlResponse, ResourceListOptions, SanqianSDK } from '@yushaw/sanqian-sdk';
2
3
  export { ChatStreamEvent, ContextListItem, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ResourceListOptions, ResourceListResult, ResourceType, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
3
4
 
@@ -434,6 +435,57 @@ type SessionResourceEvent = {
434
435
  type: 'resources_cleared';
435
436
  appName: string;
436
437
  };
438
+ /**
439
+ * Link click event with parsed URL information
440
+ */
441
+ interface LinkClickEvent {
442
+ /** Original href string */
443
+ href: string;
444
+ /** Parsed URL object (undefined if invalid URL) */
445
+ url?: URL;
446
+ /** Original React mouse event */
447
+ originalEvent: React.MouseEvent;
448
+ }
449
+ /**
450
+ * Link handler configuration for custom protocol support
451
+ *
452
+ * Allows third-party apps to handle custom URL schemes (e.g., sanqian-notes://)
453
+ * in chat messages.
454
+ *
455
+ * @example
456
+ * ```tsx
457
+ * <CompactChat
458
+ * linkHandler={{
459
+ * allowedProtocols: ['sanqian-notes:', 'obsidian:'],
460
+ * onLinkClick: (event) => {
461
+ * if (event.href.startsWith('sanqian-notes://')) {
462
+ * // Handle note navigation
463
+ * return true; // Prevent default behavior
464
+ * }
465
+ * return false; // Let default behavior handle it
466
+ * }
467
+ * }}
468
+ * />
469
+ * ```
470
+ */
471
+ interface LinkHandlerConfig {
472
+ /**
473
+ * Additional protocols to allow in markdown links.
474
+ * These will be merged with default protocols ['workspace:', 'download:'].
475
+ * Without this, rehype-harden will strip links with unknown protocols.
476
+ *
477
+ * @example ['sanqian-notes:', 'obsidian:', 'bear:']
478
+ */
479
+ allowedProtocols?: string[];
480
+ /**
481
+ * Callback when a link is clicked.
482
+ *
483
+ * @param event - Link click event with href and parsed URL
484
+ * @returns true if handled (prevents default and legacy onLinkClick),
485
+ * false/void to fall back to legacy onLinkClick prop or browser default
486
+ */
487
+ onLinkClick?: (event: LinkClickEvent) => boolean | void;
488
+ }
437
489
 
438
490
  /**
439
491
  * Chat Adapter Interface
@@ -536,8 +588,10 @@ interface ChatAdapter {
536
588
  }>;
537
589
  /** Subscribe to locale change events */
538
590
  onLocaleChanged?(callback: (locale: string) => void): () => void;
539
- /** Get current session resources from all connected apps */
591
+ /** Get session resources pushed by THIS app (local cache) */
540
592
  getSessionResources?(): StoredSessionResource[];
593
+ /** Fetch session resources from server (optionally filtered by agent) */
594
+ fetchSessionResources?(agentId?: string): Promise<StoredSessionResource[]>;
541
595
  /** Subscribe to session resource events (push/remove) */
542
596
  onSessionResourceEvent?(callback: (event: SessionResourceEvent) => void): () => void;
543
597
  /** Remove a session resource (user action from UI) */
@@ -630,4 +684,4 @@ declare function parseToolCalls(toolCalls: unknown): ToolCall[] | undefined;
630
684
  */
631
685
  declare function mergeConsecutiveAssistantMessages(rawMessages: ApiMessage[]): ChatMessage[];
632
686
 
633
- export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
687
+ export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type LinkClickEvent, type LinkHandlerConfig, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { ResourceType, HitlInterruptPayload, ContextListItem, HitlResponse, ResourceListOptions, SanqianSDK } from '@yushaw/sanqian-sdk';
2
3
  export { ChatStreamEvent, ContextListItem, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ResourceListOptions, ResourceListResult, ResourceType, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
3
4
 
@@ -434,6 +435,57 @@ type SessionResourceEvent = {
434
435
  type: 'resources_cleared';
435
436
  appName: string;
436
437
  };
438
+ /**
439
+ * Link click event with parsed URL information
440
+ */
441
+ interface LinkClickEvent {
442
+ /** Original href string */
443
+ href: string;
444
+ /** Parsed URL object (undefined if invalid URL) */
445
+ url?: URL;
446
+ /** Original React mouse event */
447
+ originalEvent: React.MouseEvent;
448
+ }
449
+ /**
450
+ * Link handler configuration for custom protocol support
451
+ *
452
+ * Allows third-party apps to handle custom URL schemes (e.g., sanqian-notes://)
453
+ * in chat messages.
454
+ *
455
+ * @example
456
+ * ```tsx
457
+ * <CompactChat
458
+ * linkHandler={{
459
+ * allowedProtocols: ['sanqian-notes:', 'obsidian:'],
460
+ * onLinkClick: (event) => {
461
+ * if (event.href.startsWith('sanqian-notes://')) {
462
+ * // Handle note navigation
463
+ * return true; // Prevent default behavior
464
+ * }
465
+ * return false; // Let default behavior handle it
466
+ * }
467
+ * }}
468
+ * />
469
+ * ```
470
+ */
471
+ interface LinkHandlerConfig {
472
+ /**
473
+ * Additional protocols to allow in markdown links.
474
+ * These will be merged with default protocols ['workspace:', 'download:'].
475
+ * Without this, rehype-harden will strip links with unknown protocols.
476
+ *
477
+ * @example ['sanqian-notes:', 'obsidian:', 'bear:']
478
+ */
479
+ allowedProtocols?: string[];
480
+ /**
481
+ * Callback when a link is clicked.
482
+ *
483
+ * @param event - Link click event with href and parsed URL
484
+ * @returns true if handled (prevents default and legacy onLinkClick),
485
+ * false/void to fall back to legacy onLinkClick prop or browser default
486
+ */
487
+ onLinkClick?: (event: LinkClickEvent) => boolean | void;
488
+ }
437
489
 
438
490
  /**
439
491
  * Chat Adapter Interface
@@ -536,8 +588,10 @@ interface ChatAdapter {
536
588
  }>;
537
589
  /** Subscribe to locale change events */
538
590
  onLocaleChanged?(callback: (locale: string) => void): () => void;
539
- /** Get current session resources from all connected apps */
591
+ /** Get session resources pushed by THIS app (local cache) */
540
592
  getSessionResources?(): StoredSessionResource[];
593
+ /** Fetch session resources from server (optionally filtered by agent) */
594
+ fetchSessionResources?(agentId?: string): Promise<StoredSessionResource[]>;
541
595
  /** Subscribe to session resource events (push/remove) */
542
596
  onSessionResourceEvent?(callback: (event: SessionResourceEvent) => void): () => void;
543
597
  /** Remove a session resource (user action from UI) */
@@ -630,4 +684,4 @@ declare function parseToolCalls(toolCalls: unknown): ToolCall[] | undefined;
630
684
  */
631
685
  declare function mergeConsecutiveAssistantMessages(rawMessages: ApiMessage[]): ChatMessage[];
632
686
 
633
- export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
687
+ export { type ApiMessage, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, type ChatMessage, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfigSerializable, type ChatUiStrings, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, type FloatingWindowConfig, type HitlInterruptData, type LinkClickEvent, type LinkHandlerConfig, type Locale, type MessageBlock, type MessageRole, type ResourcePickerItem, type ResourcePickerState, type SdkAdapterConfig, type SendMessage, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, type ToolCall, type ToolCallStatus, type WindowPosition, createChatAdapter, createSdkAdapter, mergeConsecutiveAssistantMessages, parseToolCalls };
@@ -438,15 +438,32 @@ function createSessionResourceMethods(getSdk) {
438
438
  const sdk = getSdk();
439
439
  return sdk?.getSessionResources?.() || [];
440
440
  },
441
+ async fetchSessionResources(agentId) {
442
+ const sdk = getSdk();
443
+ if (!sdk) return [];
444
+ return sdk.fetchSessionResources?.(agentId) ?? [];
445
+ },
441
446
  onSessionResourceEvent(callback) {
442
447
  const sdk = getSdk();
443
448
  if (!sdk) return () => {
444
449
  };
445
- const handler = (resourceId) => {
450
+ const pushHandler = (resource) => {
451
+ callback({ type: "resource_pushed", resource });
452
+ };
453
+ sdk.on("resourcePushed", pushHandler);
454
+ const removeHandler = (resourceId) => {
446
455
  callback({ type: "resource_removed", resourceId, source: "user" });
447
456
  };
448
- sdk.on("resourceRemoved", handler);
449
- return () => sdk.off("resourceRemoved", handler);
457
+ sdk.on("resourceRemoved", removeHandler);
458
+ const clearHandler = (appName) => {
459
+ callback({ type: "resources_cleared", appName });
460
+ };
461
+ sdk.on("resourcesCleared", clearHandler);
462
+ return () => {
463
+ sdk.off("resourcePushed", pushHandler);
464
+ sdk.off("resourceRemoved", removeHandler);
465
+ sdk.off("resourcesCleared", clearHandler);
466
+ };
450
467
  },
451
468
  async removeSessionResource(fullId) {
452
469
  const sdk = getSdk();
@@ -399,15 +399,32 @@ function createSessionResourceMethods(getSdk) {
399
399
  const sdk = getSdk();
400
400
  return sdk?.getSessionResources?.() || [];
401
401
  },
402
+ async fetchSessionResources(agentId) {
403
+ const sdk = getSdk();
404
+ if (!sdk) return [];
405
+ return sdk.fetchSessionResources?.(agentId) ?? [];
406
+ },
402
407
  onSessionResourceEvent(callback) {
403
408
  const sdk = getSdk();
404
409
  if (!sdk) return () => {
405
410
  };
406
- const handler = (resourceId) => {
411
+ const pushHandler = (resource) => {
412
+ callback({ type: "resource_pushed", resource });
413
+ };
414
+ sdk.on("resourcePushed", pushHandler);
415
+ const removeHandler = (resourceId) => {
407
416
  callback({ type: "resource_removed", resourceId, source: "user" });
408
417
  };
409
- sdk.on("resourceRemoved", handler);
410
- return () => sdk.off("resourceRemoved", handler);
418
+ sdk.on("resourceRemoved", removeHandler);
419
+ const clearHandler = (appName) => {
420
+ callback({ type: "resources_cleared", appName });
421
+ };
422
+ sdk.on("resourcesCleared", clearHandler);
423
+ return () => {
424
+ sdk.off("resourcePushed", pushHandler);
425
+ sdk.off("resourceRemoved", removeHandler);
426
+ sdk.off("resourcesCleared", clearHandler);
427
+ };
411
428
  },
412
429
  async removeSessionResource(fullId) {
413
430
  const sdk = getSdk();
@@ -1915,6 +1915,16 @@ var ChatPanel = class {
1915
1915
  return { success: false, error: e instanceof Error ? e.message : "Failed to remove resource" };
1916
1916
  }
1917
1917
  });
1918
+ import_electron2.ipcMain.handle("sanqian-chat:fetchSessionResources", async (_, params) => {
1919
+ try {
1920
+ const sdk = activeInstance2?.getSdk();
1921
+ if (!sdk) return [];
1922
+ return await sdk.fetchSessionResources(params?.agentId);
1923
+ } catch (e) {
1924
+ console.error("Failed to fetch session resources:", e);
1925
+ return [];
1926
+ }
1927
+ });
1918
1928
  import_electron2.ipcMain.handle("chatPanel:getMode", () => {
1919
1929
  return activeInstance2?.getMode() ?? "floating";
1920
1930
  });
@@ -1981,6 +1991,7 @@ var ChatPanel = class {
1981
1991
  import_electron2.ipcMain.removeHandler("sanqian-chat:getResourceList");
1982
1992
  import_electron2.ipcMain.removeAllListeners("sanqian-chat:getSessionResourcesSync");
1983
1993
  import_electron2.ipcMain.removeHandler("sanqian-chat:removeSessionResource");
1994
+ import_electron2.ipcMain.removeHandler("sanqian-chat:fetchSessionResources");
1984
1995
  import_electron2.ipcMain.removeHandler("chatPanel:getMode");
1985
1996
  import_electron2.ipcMain.removeHandler("chatPanel:setMode");
1986
1997
  import_electron2.ipcMain.removeHandler("chatPanel:toggleMode");
@@ -1890,6 +1890,16 @@ var ChatPanel = class {
1890
1890
  return { success: false, error: e instanceof Error ? e.message : "Failed to remove resource" };
1891
1891
  }
1892
1892
  });
1893
+ ipcMain2.handle("sanqian-chat:fetchSessionResources", async (_, params) => {
1894
+ try {
1895
+ const sdk = activeInstance2?.getSdk();
1896
+ if (!sdk) return [];
1897
+ return await sdk.fetchSessionResources(params?.agentId);
1898
+ } catch (e) {
1899
+ console.error("Failed to fetch session resources:", e);
1900
+ return [];
1901
+ }
1902
+ });
1893
1903
  ipcMain2.handle("chatPanel:getMode", () => {
1894
1904
  return activeInstance2?.getMode() ?? "floating";
1895
1905
  });
@@ -1956,6 +1966,7 @@ var ChatPanel = class {
1956
1966
  ipcMain2.removeHandler("sanqian-chat:getResourceList");
1957
1967
  ipcMain2.removeAllListeners("sanqian-chat:getSessionResourcesSync");
1958
1968
  ipcMain2.removeHandler("sanqian-chat:removeSessionResource");
1969
+ ipcMain2.removeHandler("sanqian-chat:fetchSessionResources");
1959
1970
  ipcMain2.removeHandler("chatPanel:getMode");
1960
1971
  ipcMain2.removeHandler("chatPanel:setMode");
1961
1972
  ipcMain2.removeHandler("chatPanel:toggleMode");
@@ -43,6 +43,9 @@ function createSanqianChatApi() {
43
43
  getSessionResources: () => {
44
44
  return import_electron.ipcRenderer.sendSync("sanqian-chat:getSessionResourcesSync");
45
45
  },
46
+ fetchSessionResources: (agentId) => {
47
+ return import_electron.ipcRenderer.invoke("sanqian-chat:fetchSessionResources", agentId ? { agentId } : void 0);
48
+ },
46
49
  onSessionResourceEvent: (callback) => {
47
50
  const handler = (_, event) => {
48
51
  callback(event);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createChatPanelApi,
3
3
  createSanqianChatApi
4
- } from "../chunk-YBHGKM2H.mjs";
4
+ } from "../chunk-27MEXKQU.mjs";
5
5
 
6
6
  // src/preload/entry.ts
7
7
  import { contextBridge } from "electron";
@@ -247,6 +247,7 @@ interface SanqianChatAPI {
247
247
  }>;
248
248
  onLocaleChanged(callback: (locale: string) => void): () => void;
249
249
  getSessionResources(): StoredSessionResource[];
250
+ fetchSessionResources(agentId?: string): Promise<StoredSessionResource[]>;
250
251
  onSessionResourceEvent(callback: (event: SessionResourceEvent) => void): () => void;
251
252
  removeSessionResource(fullId: string): Promise<{
252
253
  success: boolean;
@@ -247,6 +247,7 @@ interface SanqianChatAPI {
247
247
  }>;
248
248
  onLocaleChanged(callback: (locale: string) => void): () => void;
249
249
  getSessionResources(): StoredSessionResource[];
250
+ fetchSessionResources(agentId?: string): Promise<StoredSessionResource[]>;
250
251
  onSessionResourceEvent(callback: (event: SessionResourceEvent) => void): () => void;
251
252
  removeSessionResource(fullId: string): Promise<{
252
253
  success: boolean;
@@ -63,6 +63,9 @@ function createSanqianChatApi() {
63
63
  getSessionResources: () => {
64
64
  return import_electron.ipcRenderer.sendSync("sanqian-chat:getSessionResourcesSync");
65
65
  },
66
+ fetchSessionResources: (agentId) => {
67
+ return import_electron.ipcRenderer.invoke("sanqian-chat:fetchSessionResources", agentId ? { agentId } : void 0);
68
+ },
66
69
  onSessionResourceEvent: (callback) => {
67
70
  const handler = (_, event) => {
68
71
  callback(event);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createChatPanelApi,
3
3
  createSanqianChatApi
4
- } from "../chunk-YBHGKM2H.mjs";
4
+ } from "../chunk-27MEXKQU.mjs";
5
5
  export {
6
6
  createChatPanelApi,
7
7
  createSanqianChatApi
@@ -65,6 +65,9 @@ function createSanqianChatApi() {
65
65
  getSessionResources: () => {
66
66
  return import_electron.ipcRenderer.sendSync("sanqian-chat:getSessionResourcesSync");
67
67
  },
68
+ fetchSessionResources: (agentId) => {
69
+ return import_electron.ipcRenderer.invoke("sanqian-chat:fetchSessionResources", agentId ? { agentId } : void 0);
70
+ },
68
71
  onSessionResourceEvent: (callback) => {
69
72
  const handler = (_, event) => {
70
73
  callback(event);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createChatPanelApi,
3
3
  createSanqianChatApi
4
- } from "../chunk-YBHGKM2H.mjs";
4
+ } from "../chunk-27MEXKQU.mjs";
5
5
  export {
6
6
  createChatPanelApi,
7
7
  createSanqianChatApi
@@ -1,8 +1,8 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactNode, RefObject, CSSProperties } from 'react';
1
3
  import { ResourceType, HitlInterruptPayload, ContextListItem, HitlResponse, ResourceListOptions, SanqianSDK } from '@yushaw/sanqian-sdk';
2
4
  export { ContextListItem, HitlInterruptPayload, HitlInterruptType, HitlResponse, HitlRiskLevel, ResourceListOptions, ResourceListResult, ResourceType, ChatMessage as SdkChatMessage, ConversationDetail as SdkConversationDetail, ConversationInfo as SdkConversationInfo, ToolCall as SdkToolCall } from '@yushaw/sanqian-sdk';
3
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
- import * as react from 'react';
5
- import { ReactNode, RefObject, CSSProperties } from 'react';
6
6
  export { ChatMessage, ChatStreamEvent, SDKConfig, SanqianSDK, ToolDefinition } from '@yushaw/sanqian-sdk/browser';
7
7
 
8
8
  /**
@@ -438,6 +438,57 @@ type SessionResourceEvent = {
438
438
  type: 'resources_cleared';
439
439
  appName: string;
440
440
  };
441
+ /**
442
+ * Link click event with parsed URL information
443
+ */
444
+ interface LinkClickEvent {
445
+ /** Original href string */
446
+ href: string;
447
+ /** Parsed URL object (undefined if invalid URL) */
448
+ url?: URL;
449
+ /** Original React mouse event */
450
+ originalEvent: react__default.MouseEvent;
451
+ }
452
+ /**
453
+ * Link handler configuration for custom protocol support
454
+ *
455
+ * Allows third-party apps to handle custom URL schemes (e.g., sanqian-notes://)
456
+ * in chat messages.
457
+ *
458
+ * @example
459
+ * ```tsx
460
+ * <CompactChat
461
+ * linkHandler={{
462
+ * allowedProtocols: ['sanqian-notes:', 'obsidian:'],
463
+ * onLinkClick: (event) => {
464
+ * if (event.href.startsWith('sanqian-notes://')) {
465
+ * // Handle note navigation
466
+ * return true; // Prevent default behavior
467
+ * }
468
+ * return false; // Let default behavior handle it
469
+ * }
470
+ * }}
471
+ * />
472
+ * ```
473
+ */
474
+ interface LinkHandlerConfig {
475
+ /**
476
+ * Additional protocols to allow in markdown links.
477
+ * These will be merged with default protocols ['workspace:', 'download:'].
478
+ * Without this, rehype-harden will strip links with unknown protocols.
479
+ *
480
+ * @example ['sanqian-notes:', 'obsidian:', 'bear:']
481
+ */
482
+ allowedProtocols?: string[];
483
+ /**
484
+ * Callback when a link is clicked.
485
+ *
486
+ * @param event - Link click event with href and parsed URL
487
+ * @returns true if handled (prevents default and legacy onLinkClick),
488
+ * false/void to fall back to legacy onLinkClick prop or browser default
489
+ */
490
+ onLinkClick?: (event: LinkClickEvent) => boolean | void;
491
+ }
441
492
 
442
493
  /**
443
494
  * Chat Adapter Interface
@@ -540,8 +591,10 @@ interface ChatAdapter {
540
591
  }>;
541
592
  /** Subscribe to locale change events */
542
593
  onLocaleChanged?(callback: (locale: string) => void): () => void;
543
- /** Get current session resources from all connected apps */
594
+ /** Get session resources pushed by THIS app (local cache) */
544
595
  getSessionResources?(): StoredSessionResource[];
596
+ /** Fetch session resources from server (optionally filtered by agent) */
597
+ fetchSessionResources?(agentId?: string): Promise<StoredSessionResource[]>;
545
598
  /** Subscribe to session resource events (push/remove) */
546
599
  onSessionResourceEvent?(callback: (event: SessionResourceEvent) => void): () => void;
547
600
  /** Remove a session resource (user action from UI) */
@@ -1267,6 +1320,27 @@ interface CompactChatProps {
1267
1320
  getErrorMessage?: (errorCode: string) => string;
1268
1321
  /** Use floating window container style (for transparent Electron windows) */
1269
1322
  floating?: boolean;
1323
+ /**
1324
+ * Link handler configuration for custom protocol support.
1325
+ * Allows third-party apps to handle custom URL schemes (e.g., sanqian-notes://)
1326
+ * in chat message content.
1327
+ *
1328
+ * @example
1329
+ * ```tsx
1330
+ * <CompactChat
1331
+ * linkHandler={{
1332
+ * allowedProtocols: ['sanqian-notes:'],
1333
+ * onLinkClick: (event) => {
1334
+ * if (event.href.startsWith('sanqian-notes://')) {
1335
+ * // Handle navigation
1336
+ * return true;
1337
+ * }
1338
+ * }
1339
+ * }}
1340
+ * />
1341
+ * ```
1342
+ */
1343
+ linkHandler?: LinkHandlerConfig;
1270
1344
  }
1271
1345
  declare const CompactChat: react.NamedExoticComponent<CompactChatProps>;
1272
1346
 
@@ -1392,6 +1466,8 @@ interface ResourcePickerProps {
1392
1466
  anchorRef?: React.RefObject<HTMLElement>;
1393
1467
  /** Locale for i18n */
1394
1468
  locale?: 'en' | 'zh';
1469
+ /** Additional class name (for theme support) */
1470
+ className?: string;
1395
1471
  }
1396
1472
  declare const ResourcePicker: react.NamedExoticComponent<ResourcePickerProps>;
1397
1473
 
@@ -1454,6 +1530,8 @@ interface AddResourceButtonProps {
1454
1530
  disabled?: boolean;
1455
1531
  /** Locale */
1456
1532
  locale?: 'en' | 'zh';
1533
+ /** Theme class for dark mode support */
1534
+ themeClass?: string;
1457
1535
  }
1458
1536
  declare const AddResourceButton: react.NamedExoticComponent<AddResourceButtonProps>;
1459
1537
 
@@ -1519,8 +1597,16 @@ interface MarkdownRendererProps {
1519
1597
  children?: ReactNode;
1520
1598
  }>;
1521
1599
  };
1522
- /** Callback when a link is clicked */
1600
+ /**
1601
+ * Callback when a link is clicked (legacy, use linkHandler for new code)
1602
+ * @deprecated Use linkHandler.onLinkClick instead
1603
+ */
1523
1604
  onLinkClick?: (href: string, event: React.MouseEvent) => void;
1605
+ /**
1606
+ * Link handler configuration for custom protocol support.
1607
+ * Allows third-party apps to handle custom URL schemes (e.g., sanqian-notes://)
1608
+ */
1609
+ linkHandler?: LinkHandlerConfig;
1524
1610
  }
1525
1611
  declare const MarkdownRenderer: react.NamedExoticComponent<MarkdownRendererProps>;
1526
1612
 
@@ -1551,4 +1637,4 @@ declare function ensureChatBaseStyles(): void;
1551
1637
  */
1552
1638
  declare function ensureFullChatStyles(): void;
1553
1639
 
1554
- export { AddResourceButton, type AddResourceButtonProps, type AlertAction, AlertBanner, type AlertBannerProps, type AlertConfig, type AlertType, AttachButton, type AttachButtonProps, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, AttachedResourceTags, type AttachedResourceTagsProps, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, ChatInput, type ChatInputHandle, type ChatInputProps, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfig, type ChatUiConfigSerializable, type ChatUiStrings, CompactChat, type CompactChatProps, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, FloatingChat, type FloatingChatProps, type FloatingWindowConfig, HistoryList, type HistoryListProps, HistoryModal, type HistoryModalProps, HitlCard, type HitlCardProps, type HitlInterruptData, I18nProvider, type I18nProviderProps, IntermediateSteps, type IntermediateStepsProps, type Locale, MarkdownRenderer, type MarkdownRendererProps, type MessageBlock, MessageBubble, type MessageBubbleProps, MessageList, type MessageListProps, type MessageRole, ModeToggleButton, type ModeToggleButtonProps, PanelControls, type PanelControlsProps, PanelHeaderButtons, PanelResizer, Resizer, type ResizerProps, type ResolvedTheme, ResourceChip, ResourceChipList, type ResourceChipListProps, type ResourceChipProps, ResourcePicker, type ResourcePickerItem, type ResourcePickerProps, type ResourcePickerState, SanqianChat, SanqianChatMessage, type SanqianChatMessageProps, type SanqianChatProps, SanqianMessageList, type SanqianMessageListHandle, type SanqianMessageListProps, type SdkAdapterConfig, type SendMessage, type SendMessageOptions, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, StreamingTimeline, type StreamingTimelineProps, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThinkingSection, type ThinkingSectionProps, ToolArgumentsDisplay, type ToolArgumentsDisplayProps, type ToolCall, type ToolCallStatus, type Translations, type UseAttachStateReturn, type UseChatOptions, type UseChatPanelReturn, type UseChatReturn, type UseConnectionOptions, type UseConnectionReturn, type UseConversationsOptions, type UseConversationsReturn, type UseFocusPersistenceOptions, type UseResourcePickerOptions, type UseResourcePickerReturn, type WindowPosition, createChatAdapter, createIpcAdapter, createSdkAdapter, ensureChatBaseStyles, ensureFullChatStyles, getTranslations, resolveChatStrings, useAttachState, useChat, useChatPanel, useChatStyles, useConnection, useConversations, useFocusPersistence, useI18n, useIpcUiConfig, useResolvedUiConfig, useResourcePicker, useStandaloneI18n, useStandaloneTheme, useTheme };
1640
+ export { AddResourceButton, type AddResourceButtonProps, type AlertAction, AlertBanner, type AlertBannerProps, type AlertConfig, type AlertType, AttachButton, type AttachButtonProps, type AttachConfig, type AttachPosition, type AttachState, type AttachedResource, AttachedResourceTags, type AttachedResourceTagsProps, type AttachmentMenuItem, type AttachmentMenuItemType, type ChatAdapter, type ChatAdapterConfig, type ChatFontSize, ChatInput, type ChatInputHandle, type ChatInputProps, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatThemeMode, type ChatUiConfig, type ChatUiConfigSerializable, type ChatUiStrings, CompactChat, type CompactChatProps, type ConnectionErrorCode, type ConnectionStatus, type ContextProviderInfo, type ConversationDetail, type ConversationInfo, FloatingChat, type FloatingChatProps, type FloatingWindowConfig, HistoryList, type HistoryListProps, HistoryModal, type HistoryModalProps, HitlCard, type HitlCardProps, type HitlInterruptData, I18nProvider, type I18nProviderProps, IntermediateSteps, type IntermediateStepsProps, type LinkClickEvent, type LinkHandlerConfig, type Locale, MarkdownRenderer, type MarkdownRendererProps, type MessageBlock, MessageBubble, type MessageBubbleProps, MessageList, type MessageListProps, type MessageRole, ModeToggleButton, type ModeToggleButtonProps, PanelControls, type PanelControlsProps, PanelHeaderButtons, PanelResizer, Resizer, type ResizerProps, type ResolvedTheme, ResourceChip, ResourceChipList, type ResourceChipListProps, type ResourceChipProps, ResourcePicker, type ResourcePickerItem, type ResourcePickerProps, type ResourcePickerState, SanqianChat, SanqianChatMessage, type SanqianChatMessageProps, type SanqianChatProps, SanqianMessageList, type SanqianMessageListHandle, type SanqianMessageListProps, type SdkAdapterConfig, type SendMessage, type SendMessageOptions, type SessionResource, type SessionResourceEvent, type StoredSessionResource, type StreamEvent, StreamingTimeline, type StreamingTimelineProps, type ThemeMode, ThemeProvider, type ThemeProviderProps, ThinkingSection, type ThinkingSectionProps, ToolArgumentsDisplay, type ToolArgumentsDisplayProps, type ToolCall, type ToolCallStatus, type Translations, type UseAttachStateReturn, type UseChatOptions, type UseChatPanelReturn, type UseChatReturn, type UseConnectionOptions, type UseConnectionReturn, type UseConversationsOptions, type UseConversationsReturn, type UseFocusPersistenceOptions, type UseResourcePickerOptions, type UseResourcePickerReturn, type WindowPosition, createChatAdapter, createIpcAdapter, createSdkAdapter, ensureChatBaseStyles, ensureFullChatStyles, getTranslations, resolveChatStrings, useAttachState, useChat, useChatPanel, useChatStyles, useConnection, useConversations, useFocusPersistence, useI18n, useIpcUiConfig, useResolvedUiConfig, useResourcePicker, useStandaloneI18n, useStandaloneTheme, useTheme };