@yushaw/sanqian-chat 0.2.4 → 0.2.6

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.
@@ -1,6 +1,6 @@
1
1
  import * as _yushaw_sanqian_sdk from '@yushaw/sanqian-sdk';
2
2
  import { SanqianSDK } from '@yushaw/sanqian-sdk';
3
- import { BrowserWindow } from 'electron';
3
+ import { BrowserWindow, WebContents } from 'electron';
4
4
 
5
5
  /**
6
6
  * @yushaw/sanqian-chat Main - Facade Types
@@ -368,6 +368,12 @@ interface ChatUiStrings {
368
368
  hitlInputRequest: string;
369
369
  hitlApprovalRequired: string;
370
370
  hitlInputRequired: string;
371
+ attachWindow: string;
372
+ detachWindow: string;
373
+ floatWindow: string;
374
+ embedWindow: string;
375
+ collapseSidebar: string;
376
+ history: string;
371
377
  }
372
378
  type ChatThemeMode = 'light' | 'dark' | 'auto';
373
379
  type ChatFontSize = 'small' | 'normal' | 'large' | 'extra-large';
@@ -406,6 +412,153 @@ interface FloatingWindowConfig {
406
412
  /** Optional full path for window state file */
407
413
  windowStatePath?: string;
408
414
  }
415
+ type ChatPanelMode = 'embedded' | 'floating';
416
+ type ChatPanelPosition = 'right' | 'left';
417
+ type AttachState = 'attached' | 'detached' | 'unavailable';
418
+ type AttachPosition = 'right' | 'left' | 'top' | 'bottom';
419
+ /**
420
+ * Window attachment configuration for floating mode
421
+ */
422
+ interface AttachConfig {
423
+ /**
424
+ * Target window to attach to (BrowserWindow instance)
425
+ */
426
+ window: unknown;
427
+ /**
428
+ * Attach position relative to target window
429
+ * @default 'right'
430
+ */
431
+ position?: AttachPosition;
432
+ /**
433
+ * Gap between windows (px)
434
+ * @default 0
435
+ */
436
+ gap?: number;
437
+ /**
438
+ * Sync height/width with target window
439
+ * @default true
440
+ */
441
+ syncSize?: boolean;
442
+ /**
443
+ * Behavior when target window is minimized
444
+ * @default 'hide'
445
+ */
446
+ onMinimize?: 'hide' | 'detach' | 'minimize';
447
+ /**
448
+ * Behavior when target window is closed
449
+ * @default 'hide'
450
+ */
451
+ onClose?: 'hide' | 'destroy';
452
+ /**
453
+ * Allow user to drag and detach
454
+ * @default true
455
+ */
456
+ allowDetach?: boolean;
457
+ /**
458
+ * Allow re-attach when dragged near target edge
459
+ * @default true
460
+ */
461
+ allowReattach?: boolean;
462
+ /**
463
+ * Distance threshold for re-attach (px)
464
+ * @default 20
465
+ */
466
+ reattachThreshold?: number;
467
+ }
468
+ /**
469
+ * ChatPanel configuration
470
+ */
471
+ interface ChatPanelConfig {
472
+ /**
473
+ * Host window (BaseWindow supports embedded, BrowserWindow floating only)
474
+ */
475
+ hostWindow: unknown;
476
+ /**
477
+ * Host window's main content view (required for embedded mode)
478
+ */
479
+ hostMainView?: unknown;
480
+ /**
481
+ * Initial mode
482
+ * @default 'embedded'
483
+ */
484
+ initialMode?: ChatPanelMode;
485
+ /**
486
+ * Embed position
487
+ * @default 'right'
488
+ */
489
+ position?: ChatPanelPosition;
490
+ /**
491
+ * Panel width
492
+ * @default 360
493
+ */
494
+ width?: number;
495
+ /**
496
+ * Minimum width
497
+ * @default 240
498
+ */
499
+ minWidth?: number;
500
+ /**
501
+ * Minimum host content width when showing panel.
502
+ * If window is too narrow, expand it to ensure main content has this width.
503
+ * Set to 0 to disable auto-expand.
504
+ * @default 0
505
+ */
506
+ minHostContentWidth?: number;
507
+ /**
508
+ * Allow resize
509
+ * @default true
510
+ */
511
+ resizable?: boolean;
512
+ /**
513
+ * Preload script path
514
+ */
515
+ preloadPath: string;
516
+ /**
517
+ * Renderer HTML path or URL
518
+ */
519
+ rendererPath: string;
520
+ /**
521
+ * Dev mode - load URL instead of file
522
+ */
523
+ devMode?: boolean;
524
+ /**
525
+ * SDK client getter
526
+ */
527
+ getClient: () => unknown;
528
+ /**
529
+ * Agent ID getter
530
+ */
531
+ getAgentId: () => string | null;
532
+ /**
533
+ * Layout change callback (for host app to adjust main content)
534
+ */
535
+ onLayoutChange?: (layout: {
536
+ mainWidth: number;
537
+ chatWidth: number;
538
+ chatVisible: boolean;
539
+ }) => void;
540
+ /**
541
+ * Shortcut configuration
542
+ */
543
+ shortcuts?: {
544
+ /** Toggle show/hide, false to disable */
545
+ toggle?: string | false;
546
+ /** Toggle mode, false to disable */
547
+ toggleMode?: string | false;
548
+ };
549
+ /**
550
+ * Floating window attach configuration
551
+ */
552
+ attach?: AttachConfig;
553
+ /**
554
+ * State persistence key
555
+ */
556
+ stateKey?: string;
557
+ /**
558
+ * UI config for renderer
559
+ */
560
+ uiConfig?: ChatUiConfigSerializable;
561
+ }
409
562
 
410
563
  /**
411
564
  * FloatingWindow - Main process module for floating chat window
@@ -468,4 +621,222 @@ declare class FloatingWindow {
468
621
  getWindow(): BrowserWindow | null;
469
622
  }
470
623
 
471
- export { type AppAgentConfig, type AppClientEvent, type AppClientEventHandlers, type AppConfig, type AppContextData, type AppContextListItem, type AppContextProvider, type AppEmbeddingConfig, type AppJsonSchemaProperty, type AppToolDefinition, type ChatUiConfigSerializable, FloatingWindow, type FloatingWindowConfig, type FloatingWindowOptions, SanqianAppClient, type WindowPosition };
624
+ /**
625
+ * ChatPanel - Core class for embedded + floating chat panel
626
+ *
627
+ * Manages two modes:
628
+ * - Embedded: WebContentsView inside host BaseWindow
629
+ * - Floating: Independent BrowserWindow with WebContentsView
630
+ *
631
+ * Both modes share the same webContents, allowing runtime switching
632
+ * without losing state.
633
+ *
634
+ * REQUIRES: Electron >= 30.0.0 (for BaseWindow and WebContentsView APIs)
635
+ */
636
+
637
+ declare class ChatPanel {
638
+ private webContents;
639
+ private config;
640
+ private mode;
641
+ private visible;
642
+ private currentWidth;
643
+ private embeddedWidth;
644
+ private floatingWidth;
645
+ private floatingHeight;
646
+ private floatingX?;
647
+ private floatingY?;
648
+ private embeddedModeAvailable;
649
+ private embeddedView;
650
+ private floatingWindow;
651
+ private floatingView;
652
+ private registeredShortcuts;
653
+ private stateSaveTimer;
654
+ private activeStreams;
655
+ constructor(config: ChatPanelConfig);
656
+ private hostResizeHandler;
657
+ private setupHostWindowListeners;
658
+ private cleanupHostWindowListeners;
659
+ /**
660
+ * Handle window resize - update layout
661
+ */
662
+ private handleResponsiveResize;
663
+ /**
664
+ * Show panel
665
+ */
666
+ show(): void;
667
+ /**
668
+ * Hide panel
669
+ */
670
+ hide(): void;
671
+ /**
672
+ * Toggle visibility
673
+ */
674
+ toggle(): void;
675
+ /**
676
+ * Get current mode
677
+ */
678
+ getMode(): ChatPanelMode;
679
+ /**
680
+ * Set mode
681
+ */
682
+ setMode(mode: ChatPanelMode): void;
683
+ /**
684
+ * Toggle mode
685
+ */
686
+ toggleMode(): ChatPanelMode;
687
+ /**
688
+ * Check if visible
689
+ */
690
+ isVisible(): boolean;
691
+ /**
692
+ * Set width with optional animation
693
+ */
694
+ setWidth(width: number, animate?: boolean): void;
695
+ /**
696
+ * Called when resize drag ends - update window min width constraint
697
+ */
698
+ onResizeEnd(): void;
699
+ /**
700
+ * Animate width change smoothly
701
+ */
702
+ private animateWidth;
703
+ /**
704
+ * Get width
705
+ */
706
+ getWidth(): number;
707
+ /**
708
+ * Get attach state (for floating mode)
709
+ * Note: Attachment feature not implemented yet - see FloatingWindow.ts for reference
710
+ */
711
+ getAttachState(): AttachState;
712
+ /**
713
+ * Toggle attach state
714
+ * Note: Attachment feature not implemented yet - see FloatingWindow.ts for reference
715
+ */
716
+ toggleAttach(): AttachState;
717
+ /**
718
+ * Get webContents (for IPC)
719
+ */
720
+ getWebContents(): WebContents;
721
+ /**
722
+ * Destroy panel
723
+ */
724
+ destroy(): void;
725
+ private normalizeConfig;
726
+ private checkEmbeddedModeAvailable;
727
+ private determineInitialMode;
728
+ private initWebContents;
729
+ private showEmbedded;
730
+ /**
731
+ * Update host window minimum width constraint based on chat panel visibility.
732
+ * When chat is visible: minWidth = minHostContentWidth + chatWidth
733
+ * When chat is hidden: minWidth = minHostContentWidth
734
+ */
735
+ private updateHostWindowMinWidth;
736
+ /**
737
+ * Expand host window to the right if main content area would be too narrow.
738
+ * If expansion would exceed screen bounds, shift window left as needed.
739
+ */
740
+ private expandHostWindowIfNeeded;
741
+ private hideEmbedded;
742
+ private updateEmbeddedLayout;
743
+ private updateHostLayoutForHidden;
744
+ private createFloatingWindow;
745
+ private showFloating;
746
+ private hideFloating;
747
+ private updateFloatingViewBounds;
748
+ private positionFloatingWindow;
749
+ private getHostWindowBounds;
750
+ private sharedView;
751
+ private getOrCreateSharedView;
752
+ private switchToEmbedded;
753
+ private switchToFloating;
754
+ private notifyVisibilityChange;
755
+ private notifyModeChange;
756
+ private setupShortcuts;
757
+ private getStatePath;
758
+ private loadState;
759
+ private scheduleSaveState;
760
+ private saveState;
761
+ private getSdk;
762
+ private setupIpcHandlers;
763
+ private cleanupIpcHandlers;
764
+ }
765
+
766
+ /**
767
+ * WindowAttachment - Manages floating window attachment to a target window
768
+ *
769
+ * Handles:
770
+ * - Position sync when target window moves/resizes
771
+ * - Minimize/maximize/fullscreen handling
772
+ * - Drag detach and reattach detection
773
+ * - Windows Aero Snap workaround (polling)
774
+ */
775
+
776
+ declare class WindowAttachment {
777
+ private chatWindow;
778
+ private config;
779
+ private state;
780
+ private pollTimer;
781
+ private reattachHandler;
782
+ private onStateChangeCallback?;
783
+ private updatePending;
784
+ constructor(chatWindow: BrowserWindow, config: AttachConfig);
785
+ /**
786
+ * Start attachment listeners
787
+ */
788
+ attach(): void;
789
+ /**
790
+ * Stop attachment listeners
791
+ */
792
+ detach(): void;
793
+ /**
794
+ * Update chat window position to match target
795
+ */
796
+ updatePosition(): void;
797
+ /**
798
+ * Set state change callback
799
+ */
800
+ onStateChange(callback: (state: AttachState) => void): void;
801
+ /**
802
+ * Toggle attach state
803
+ */
804
+ toggle(): AttachState;
805
+ /**
806
+ * Manual detach
807
+ */
808
+ manualDetach(): void;
809
+ /**
810
+ * Manual attach
811
+ */
812
+ manualAttach(): void;
813
+ /**
814
+ * Get current attach state
815
+ */
816
+ get isAttached(): boolean;
817
+ /**
818
+ * Get current position
819
+ */
820
+ get position(): AttachPosition;
821
+ private normalizeConfig;
822
+ private throttledUpdatePosition;
823
+ private calculateAttachedBounds;
824
+ private constrainToScreen;
825
+ private notifyStateChange;
826
+ private handleTargetMinimize;
827
+ private handleTargetRestore;
828
+ private handleTargetMaximize;
829
+ private handleTargetUnmaximize;
830
+ private handleTargetEnterFullScreen;
831
+ private handleTargetLeaveFullScreen;
832
+ private handleTargetClose;
833
+ private handleTargetClosed;
834
+ private handleChatMove;
835
+ private onDetached;
836
+ private startReattachListener;
837
+ private stopReattachListener;
838
+ private startPolling;
839
+ private stopPolling;
840
+ }
841
+
842
+ export { type AppAgentConfig, type AppClientEvent, type AppClientEventHandlers, type AppConfig, type AppContextData, type AppContextListItem, type AppContextProvider, type AppEmbeddingConfig, type AppJsonSchemaProperty, type AppToolDefinition, type AttachConfig, type AttachPosition, type AttachState, ChatPanel, type ChatPanelConfig, type ChatPanelMode, type ChatPanelPosition, type ChatUiConfigSerializable, FloatingWindow, type FloatingWindowConfig, type FloatingWindowOptions, SanqianAppClient, WindowAttachment, type WindowPosition };