@astermind/cybernetic-chatbot-client 2.2.21 → 2.2.34

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 +1 @@
1
- {"version":3,"file":"CyberneticLocalRAG.d.ts","sourceRoot":"","sources":["../src/CyberneticLocalRAG.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,UAAU,cAAc;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkC;IAEpD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CvD;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsDjD;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;;;;OAKG;IACG,cAAc,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2CpE;;OAEG;IACH,eAAe,IAAI,YAAY;IAa/B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAyB9B;;OAEG;IACH,OAAO,CAAC,UAAU;CAarB"}
1
+ {"version":3,"file":"CyberneticLocalRAG.d.ts","sourceRoot":"","sources":["../src/CyberneticLocalRAG.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,UAAU,cAAc;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkC;IAEpD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDvD;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsDjD;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;;;;OAKG;IACG,cAAc,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2CpE;;OAEG;IACH,eAAe,IAAI,YAAY;IAa/B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAWhB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAyB9B;;OAEG;IACH,OAAO,CAAC,UAAU;CAarB"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Session data structure stored in sessionStorage
3
+ */
4
+ export interface StoredSession {
5
+ /** Session ID from backend API */
6
+ sessionId: string;
7
+ /** Timestamp when session was created/last updated */
8
+ updatedAt: number;
9
+ /** Optional conversation messages for UI restoration */
10
+ messages?: StoredMessage[];
11
+ }
12
+ /**
13
+ * Message structure for conversation history
14
+ */
15
+ export interface StoredMessage {
16
+ /** Unique message ID */
17
+ id: string;
18
+ /** 'user' or 'assistant' */
19
+ role: 'user' | 'assistant';
20
+ /** Message content */
21
+ content: string;
22
+ /** Timestamp */
23
+ timestamp: number;
24
+ /** Whether response was from offline fallback */
25
+ offline?: boolean;
26
+ /** Confidence level of response */
27
+ confidence?: 'high' | 'medium' | 'low' | 'none';
28
+ }
29
+ /**
30
+ * Configuration for session persistence
31
+ */
32
+ export interface SessionStorageConfig {
33
+ /** Enable session persistence (default: true) */
34
+ enabled?: boolean;
35
+ /** Storage key prefix (default: 'astermind_session') */
36
+ storageKey?: string;
37
+ /** Session TTL in milliseconds (default: 30 minutes) */
38
+ sessionTtl?: number;
39
+ /** Persist conversation messages (default: true) */
40
+ persistMessages?: boolean;
41
+ /** Maximum messages to store (default: 50) */
42
+ maxMessages?: number;
43
+ }
44
+ /**
45
+ * Session storage manager for persisting chatbot sessions
46
+ *
47
+ * Uses sessionStorage to maintain conversation continuity across
48
+ * page navigations within the same browser session.
49
+ */
50
+ export declare class CyberneticSessionStorage {
51
+ private config;
52
+ private cachedSession;
53
+ constructor(config?: SessionStorageConfig);
54
+ /**
55
+ * Check if sessionStorage is available
56
+ */
57
+ isAvailable(): boolean;
58
+ /**
59
+ * Get the current session ID (if valid)
60
+ */
61
+ getSessionId(): string | null;
62
+ /**
63
+ * Get the full stored session (if valid)
64
+ */
65
+ getSession(): StoredSession | null;
66
+ /**
67
+ * Save/update session ID
68
+ */
69
+ saveSessionId(sessionId: string): void;
70
+ /**
71
+ * Add a message to the conversation history
72
+ */
73
+ addMessage(message: Omit<StoredMessage, 'id' | 'timestamp'>): void;
74
+ /**
75
+ * Get conversation messages
76
+ */
77
+ getMessages(): StoredMessage[];
78
+ /**
79
+ * Clear the stored session
80
+ */
81
+ clear(): void;
82
+ /**
83
+ * Start a new session (clears existing and optionally sets new ID)
84
+ */
85
+ startNewSession(sessionId?: string): void;
86
+ /**
87
+ * Check if we have a valid stored session
88
+ */
89
+ hasValidSession(): boolean;
90
+ /**
91
+ * Get session info for debugging/status
92
+ */
93
+ getSessionInfo(): {
94
+ hasSession: boolean;
95
+ sessionId: string | null;
96
+ messageCount: number;
97
+ lastUpdated: Date | null;
98
+ ttlRemaining: number | null;
99
+ };
100
+ /**
101
+ * Check if a session is still valid (not expired)
102
+ */
103
+ private isSessionValid;
104
+ /**
105
+ * Load session from sessionStorage
106
+ */
107
+ private loadFromStorage;
108
+ /**
109
+ * Save session to sessionStorage
110
+ */
111
+ private saveToStorage;
112
+ /**
113
+ * Generate a unique message ID
114
+ */
115
+ private generateMessageId;
116
+ }
117
+ //# sourceMappingURL=CyberneticSessionStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberneticSessionStorage.d.ts","sourceRoot":"","sources":["../src/CyberneticSessionStorage.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAUD;;;;;GAKG;AACH,qBAAa,wBAAwB;IACjC,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,CAAC,EAAE,oBAAoB;IASzC;;OAEG;IACH,WAAW,IAAI,OAAO;IAatB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAO7B;;OAEG;IACH,UAAU,IAAI,aAAa,GAAG,IAAI;IAuBlC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IActC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI;IA0BlE;;OAEG;IACH,WAAW,IAAI,aAAa,EAAE;IAO9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAQzC;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;IACH,cAAc,IAAI;QACd,UAAU,EAAE,OAAO,CAAC;QACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;QACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B;IA6BD;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAG5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"CyberneticIntentClassifier.d.ts","sourceRoot":"","sources":["../../src/agentic/CyberneticIntentClassifier.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,oBAAoB,EAIpB,WAAW,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACR,mBAAmB,EACnB,aAAa,EAEb,kBAAkB,EAClB,mBAAmB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAoCzD;;;;;GAKG;AACH,qBAAa,0BAA0B;IACnC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,aAAa,CAAoC;IAEzD,8CAA8C;IAC9C,OAAO,CAAC,gBAAgB,CAAiC;IAEzD;;;;;;OAMG;gBACS,MAAM,EAAE,WAAW,EAAE,MAAM,GAAE,MAAW,EAAE,MAAM,GAAE,MAAW;IAmBzE;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CpB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB;IA6C/C;;OAEG;IACH,OAAO,CAAC,WAAW;IAwLnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgCxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA4BhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgC9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACH,SAAS,IAAI,WAAW;IAMxB;;;;;OAKG;IACG,eAAe,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BrE;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBvD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAiDlC;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,aAAa,IAAI,kBAAkB,EAAE;IAIrC;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAIzC;;OAEG;IACH,SAAS,IAAI,OAAO;IAMpB;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe1C;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAyCnC;;;;OAIG;IACH,cAAc,IAAI,OAAO;IAQzB;;;;;OAKG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzC;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,iBAAiB,IAAI,mBAAmB,EAAE;CAO7C"}
1
+ {"version":3,"file":"CyberneticIntentClassifier.d.ts","sourceRoot":"","sources":["../../src/agentic/CyberneticIntentClassifier.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,oBAAoB,EAIpB,WAAW,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACR,mBAAmB,EACnB,aAAa,EAEb,kBAAkB,EAClB,mBAAmB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAoCzD;;;;;GAKG;AACH,qBAAa,0BAA0B;IACnC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,aAAa,CAAoC;IAEzD,8CAA8C;IAC9C,OAAO,CAAC,gBAAgB,CAAiC;IAEzD;;;;;;OAMG;gBACS,MAAM,EAAE,WAAW,EAAE,MAAM,GAAE,MAAW,EAAE,MAAM,GAAE,MAAW;IAgCzE;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CpB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB;IA6C/C;;OAEG;IACH,OAAO,CAAC,WAAW;IAwLnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgCxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA4BhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAgC9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;OAEG;IACH,SAAS,IAAI,WAAW;IAMxB;;;;;OAKG;IACG,eAAe,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BrE;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBvD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAiDlC;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,aAAa,IAAI,kBAAkB,EAAE;IAIrC;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAIzC;;OAEG;IACH,SAAS,IAAI,OAAO;IAMpB;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe1C;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAyCnC;;;;OAIG;IACH,cAAc,IAAI,OAAO;IAQzB;;;;;OAKG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzC;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,IAAI;IAI9C;;;;OAIG;IACH,iBAAiB,IAAI,mBAAmB,EAAE;CAO7C"}
@@ -6,6 +6,9 @@ import type { AgenticSiteMapEntry, EnhancedSiteMapEntry, MultiSourceSiteMapConfi
6
6
  * 1. Static props (explicit configuration)
7
7
  * 2. Framework auto-discovery (React Router, Vue Router, etc.)
8
8
  * 3. Backend API (tenant-specific sitemaps)
9
+ *
10
+ * Zero-config mode: When agentic is enabled but no siteMapConfig provided,
11
+ * automatically discovers routes using smart defaults.
9
12
  */
10
13
  export declare class SiteMapDiscovery {
11
14
  private config;
@@ -17,6 +20,8 @@ export declare class SiteMapDiscovery {
17
20
  private backendCache;
18
21
  private isInitialized;
19
22
  private initPromise;
23
+ private detectedFramework;
24
+ private popstateHandler;
20
25
  constructor(config: MultiSourceSiteMapConfig, apiUrl: string, apiKey: string);
21
26
  /**
22
27
  * Initialize all sitemap sources
@@ -24,6 +29,42 @@ export declare class SiteMapDiscovery {
24
29
  */
25
30
  initialize(): Promise<void>;
26
31
  private performInitialization;
32
+ /**
33
+ * Wait for DOM to be ready before scanning
34
+ */
35
+ private waitForDOMReady;
36
+ /**
37
+ * Set up popstate listener to re-discover on SPA navigation
38
+ */
39
+ private setupPopstateListener;
40
+ /**
41
+ * Refresh discovery in background without blocking
42
+ */
43
+ private refreshInBackground;
44
+ /**
45
+ * Get localStorage cache key for current origin
46
+ */
47
+ private getCacheKey;
48
+ /**
49
+ * Load discovered entries from localStorage cache
50
+ */
51
+ private loadFromLocalStorage;
52
+ /**
53
+ * Save discovered entries to localStorage cache
54
+ */
55
+ private saveToLocalStorage;
56
+ /**
57
+ * Clear localStorage cache
58
+ */
59
+ clearCache(): void;
60
+ /**
61
+ * Dispose of resources (event listeners, etc.)
62
+ */
63
+ dispose(): void;
64
+ /**
65
+ * Get detected framework name
66
+ */
67
+ getDetectedFramework(): string;
27
68
  /**
28
69
  * Get merged sitemap entries with deduplication
29
70
  */
@@ -59,6 +100,7 @@ export declare class SiteMapDiscovery {
59
100
  private discoverAngularRoutes;
60
101
  /**
61
102
  * Discover routes by scanning DOM navigation elements
103
+ * Uses smart defaults when no selectors provided
62
104
  */
63
105
  private discoverFromDOM;
64
106
  private fetchFromBackend;
@@ -1 +1 @@
1
- {"version":3,"file":"SiteMapDiscovery.d.ts","sourceRoot":"","sources":["../../src/agentic/SiteMapDiscovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,mBAAmB,EACnB,oBAAoB,EAEpB,wBAAwB,EAE3B,MAAM,aAAa,CAAC;AAqBrB;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,cAAc,CAA8B;IAEpD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAA8B;gBAG7C,MAAM,EAAE,wBAAwB,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM;IAYlB;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,qBAAqB;IAgCnC;;OAEG;IACH,gBAAgB,IAAI,oBAAoB,EAAE;IAQ1C;;OAEG;IACH,gBAAgB,IAAI,mBAAmB,EAAE;YAa3B,qBAAqB;IAoEnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAiCvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,eAAe;YA0DT,gBAAgB;IAmE9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,YAAY;IA8DpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,QAAQ,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAQtF"}
1
+ {"version":3,"file":"SiteMapDiscovery.d.ts","sourceRoot":"","sources":["../../src/agentic/SiteMapDiscovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,mBAAmB,EACnB,oBAAoB,EAEpB,wBAAwB,EAE3B,MAAM,aAAa,CAAC;AA4GrB;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,cAAc,CAA8B;IAEpD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,eAAe,CAA6B;gBAGhD,MAAM,EAAE,wBAAwB,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM;IAclB;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,qBAAqB;IAkDnC;;OAEG;YACW,eAAe;IAc7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAa7B;;OAEG;YACW,mBAAmB;IAejC;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAI9B;;OAEG;IACH,gBAAgB,IAAI,oBAAoB,EAAE;IAQ1C;;OAEG;IACH,gBAAgB,IAAI,mBAAmB,EAAE;YAa3B,qBAAqB;IAqEnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAiCvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;;OAGG;IACH,OAAO,CAAC,eAAe;YAgFT,gBAAgB;IAmE9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,YAAY;IA8DpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,QAAQ,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;CAQtF"}
@@ -640,6 +640,10 @@ class CyberneticLocalRAG {
640
640
  // Tokenize and build document frequency
641
641
  const docFreq = new Map();
642
642
  for (const doc of documents) {
643
+ // Skip documents without content
644
+ if (!doc.content) {
645
+ continue;
646
+ }
643
647
  const tokens = this.tokenize(doc.content);
644
648
  const uniqueTokens = new Set(tokens);
645
649
  // Count document frequency
@@ -790,6 +794,9 @@ class CyberneticLocalRAG {
790
794
  * Tokenize text into words
791
795
  */
792
796
  tokenize(text) {
797
+ if (!text || typeof text !== 'string') {
798
+ return [];
799
+ }
793
800
  return text
794
801
  .toLowerCase()
795
802
  .replace(/[^\w\s]/g, ' ')
@@ -2653,6 +2660,68 @@ function loadConfig(options = {}) {
2653
2660
 
2654
2661
  // src/agentic/SiteMapDiscovery.ts
2655
2662
  // Multi-source sitemap discovery and merging for agentic navigation
2663
+ // Zero-config mode: automatically discovers routes on any site
2664
+ // ==================== SMART DEFAULTS ====================
2665
+ /**
2666
+ * Comprehensive default selectors that work on most sites
2667
+ * Covers semantic HTML, common CSS patterns, and framework conventions
2668
+ */
2669
+ const DEFAULT_NAV_SELECTORS = [
2670
+ // Semantic HTML5 navigation
2671
+ 'nav a[href]',
2672
+ '[role="navigation"] a[href]',
2673
+ 'header a[href]',
2674
+ // Common CSS class patterns
2675
+ '.nav a[href]',
2676
+ '.navbar a[href]',
2677
+ '.navigation a[href]',
2678
+ '.sidebar a[href]',
2679
+ '.side-nav a[href]',
2680
+ '.sidenav a[href]',
2681
+ '.menu a[href]',
2682
+ '.main-menu a[href]',
2683
+ '.top-menu a[href]',
2684
+ // Data attributes
2685
+ '[data-nav] a[href]',
2686
+ '[data-menu] a[href]',
2687
+ '[data-navigation] a[href]',
2688
+ // ARIA patterns
2689
+ '[aria-label*="navigation" i] a[href]',
2690
+ '[aria-label*="menu" i] a[href]',
2691
+ // Breadcrumbs
2692
+ '[aria-label*="breadcrumb" i] a[href]',
2693
+ '.breadcrumb a[href]',
2694
+ '.breadcrumbs a[href]',
2695
+ // Generic internal links (fallback - caught last)
2696
+ 'a[href^="/"]',
2697
+ ];
2698
+ /**
2699
+ * Default paths to exclude from discovery
2700
+ * Covers common auth, API, and framework-internal routes
2701
+ */
2702
+ const DEFAULT_EXCLUDE_PATTERNS = [
2703
+ // Authentication routes
2704
+ '/login', '/logout', '/signin', '/signout', '/sign-in', '/sign-out',
2705
+ '/register', '/signup', '/sign-up', '/forgot-password', '/reset-password',
2706
+ '/auth/*', '/oauth/*', '/callback/*', '/sso/*',
2707
+ // API and framework internals
2708
+ '/api/*', '/_next/*', '/_nuxt/*', '/__*',
2709
+ // Special links
2710
+ 'javascript:*', 'mailto:*', 'tel:*', '#*',
2711
+ ];
2712
+ /**
2713
+ * Default maximum number of links to scan from DOM
2714
+ * Prevents performance issues on sites with many links
2715
+ */
2716
+ const DEFAULT_MAX_DOM_LINKS = 200;
2717
+ /**
2718
+ * Default cache TTL for localStorage (5 minutes)
2719
+ */
2720
+ const DEFAULT_CACHE_TTL = 5 * 60 * 1000;
2721
+ /**
2722
+ * Cache version - increment when cache format changes
2723
+ */
2724
+ const CACHE_VERSION = '1';
2656
2725
  /**
2657
2726
  * Multi-source sitemap discovery and management
2658
2727
  *
@@ -2660,6 +2729,9 @@ function loadConfig(options = {}) {
2660
2729
  * 1. Static props (explicit configuration)
2661
2730
  * 2. Framework auto-discovery (React Router, Vue Router, etc.)
2662
2731
  * 3. Backend API (tenant-specific sitemaps)
2732
+ *
2733
+ * Zero-config mode: When agentic is enabled but no siteMapConfig provided,
2734
+ * automatically discovers routes using smart defaults.
2663
2735
  */
2664
2736
  class SiteMapDiscovery {
2665
2737
  constructor(config, apiUrl, apiKey) {
@@ -2669,6 +2741,8 @@ class SiteMapDiscovery {
2669
2741
  this.backendCache = null;
2670
2742
  this.isInitialized = false;
2671
2743
  this.initPromise = null;
2744
+ this.detectedFramework = 'generic';
2745
+ this.popstateHandler = null;
2672
2746
  this.config = config;
2673
2747
  this.apiUrl = apiUrl;
2674
2748
  this.apiKey = apiKey;
@@ -2677,6 +2751,7 @@ class SiteMapDiscovery {
2677
2751
  this.staticEntries = this.enhanceEntries(config.static, 'props');
2678
2752
  }
2679
2753
  }
2754
+ // ==================== INITIALIZATION ====================
2680
2755
  /**
2681
2756
  * Initialize all sitemap sources
2682
2757
  * Call this during widget initialization or first query based on loadStrategy
@@ -2691,8 +2766,19 @@ class SiteMapDiscovery {
2691
2766
  this.isInitialized = true;
2692
2767
  }
2693
2768
  async performInitialization() {
2769
+ // Wait for DOM to be ready before discovery
2770
+ await this.waitForDOMReady();
2771
+ // Try to load from localStorage cache first
2772
+ const cachedEntries = this.loadFromLocalStorage();
2773
+ if (cachedEntries) {
2774
+ this.discoveredEntries = cachedEntries;
2775
+ console.log(`[SiteMapDiscovery] Loaded ${cachedEntries.length} entries from cache`);
2776
+ // Still run discovery in background to refresh cache
2777
+ this.refreshInBackground();
2778
+ return;
2779
+ }
2694
2780
  const tasks = [];
2695
- // Source 2: Framework auto-discovery
2781
+ // Source 2: Framework auto-discovery (enabled by default)
2696
2782
  if (this.config.discovery?.enabled !== false) {
2697
2783
  tasks.push(this.discoverFromFramework());
2698
2784
  }
@@ -2706,6 +2792,8 @@ class SiteMapDiscovery {
2706
2792
  const { entries, source } = result.value;
2707
2793
  if (source === 'discovery') {
2708
2794
  this.discoveredEntries = entries;
2795
+ // Save to localStorage
2796
+ this.saveToLocalStorage(entries);
2709
2797
  }
2710
2798
  else if (source === 'backend') {
2711
2799
  this.backendEntries = entries;
@@ -2715,9 +2803,144 @@ class SiteMapDiscovery {
2715
2803
  console.warn('[SiteMapDiscovery] Source failed:', result.reason);
2716
2804
  }
2717
2805
  }
2806
+ // Set up popstate listener for SPA navigation
2807
+ this.setupPopstateListener();
2718
2808
  const total = this.staticEntries.length + this.discoveredEntries.length + this.backendEntries.length;
2719
2809
  console.log(`[SiteMapDiscovery] Initialized with ${total} total entries (${this.staticEntries.length} static, ${this.discoveredEntries.length} discovered, ${this.backendEntries.length} backend)`);
2720
2810
  }
2811
+ /**
2812
+ * Wait for DOM to be ready before scanning
2813
+ */
2814
+ async waitForDOMReady() {
2815
+ if (typeof document === 'undefined')
2816
+ return;
2817
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
2818
+ // DOM is ready, but give frameworks a microtask to mount
2819
+ await new Promise(resolve => setTimeout(resolve, 0));
2820
+ return;
2821
+ }
2822
+ return new Promise((resolve) => {
2823
+ document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });
2824
+ });
2825
+ }
2826
+ /**
2827
+ * Set up popstate listener to re-discover on SPA navigation
2828
+ */
2829
+ setupPopstateListener() {
2830
+ if (typeof window === 'undefined')
2831
+ return;
2832
+ this.popstateHandler = () => {
2833
+ // Debounce re-discovery
2834
+ setTimeout(() => {
2835
+ this.refreshInBackground();
2836
+ }, 100);
2837
+ };
2838
+ window.addEventListener('popstate', this.popstateHandler);
2839
+ }
2840
+ /**
2841
+ * Refresh discovery in background without blocking
2842
+ */
2843
+ async refreshInBackground() {
2844
+ try {
2845
+ const result = await this.discoverFromFramework();
2846
+ if (result.entries.length > 0) {
2847
+ this.discoveredEntries = result.entries;
2848
+ this.saveToLocalStorage(result.entries);
2849
+ }
2850
+ }
2851
+ catch (error) {
2852
+ // Silent fail for background refresh
2853
+ console.debug('[SiteMapDiscovery] Background refresh failed:', error);
2854
+ }
2855
+ }
2856
+ // ==================== LOCALSTORAGE CACHING ====================
2857
+ /**
2858
+ * Get localStorage cache key for current origin
2859
+ */
2860
+ getCacheKey() {
2861
+ if (typeof window === 'undefined')
2862
+ return 'astermind-sitemap';
2863
+ return `astermind-sitemap-${window.location.origin}`;
2864
+ }
2865
+ /**
2866
+ * Load discovered entries from localStorage cache
2867
+ */
2868
+ loadFromLocalStorage() {
2869
+ if (typeof localStorage === 'undefined')
2870
+ return null;
2871
+ try {
2872
+ const key = this.getCacheKey();
2873
+ const cached = localStorage.getItem(key);
2874
+ if (!cached)
2875
+ return null;
2876
+ const data = JSON.parse(cached);
2877
+ // Check version
2878
+ if (data.version !== CACHE_VERSION) {
2879
+ localStorage.removeItem(key);
2880
+ return null;
2881
+ }
2882
+ // Check TTL
2883
+ const ttl = this.config.discovery?.cacheTtl ?? DEFAULT_CACHE_TTL;
2884
+ if (Date.now() - data.timestamp > ttl) {
2885
+ localStorage.removeItem(key);
2886
+ return null;
2887
+ }
2888
+ this.detectedFramework = data.framework;
2889
+ return data.entries;
2890
+ }
2891
+ catch (error) {
2892
+ console.debug('[SiteMapDiscovery] Failed to load from cache:', error);
2893
+ return null;
2894
+ }
2895
+ }
2896
+ /**
2897
+ * Save discovered entries to localStorage cache
2898
+ */
2899
+ saveToLocalStorage(entries) {
2900
+ if (typeof localStorage === 'undefined')
2901
+ return;
2902
+ if (this.config.discovery?.cacheRoutes === false)
2903
+ return;
2904
+ try {
2905
+ const key = this.getCacheKey();
2906
+ const data = {
2907
+ entries,
2908
+ url: typeof window !== 'undefined' ? window.location.href : '',
2909
+ timestamp: Date.now(),
2910
+ framework: this.detectedFramework,
2911
+ version: CACHE_VERSION
2912
+ };
2913
+ localStorage.setItem(key, JSON.stringify(data));
2914
+ }
2915
+ catch (error) {
2916
+ // localStorage might be full or disabled
2917
+ console.debug('[SiteMapDiscovery] Failed to save to cache:', error);
2918
+ }
2919
+ }
2920
+ /**
2921
+ * Clear localStorage cache
2922
+ */
2923
+ clearCache() {
2924
+ if (typeof localStorage === 'undefined')
2925
+ return;
2926
+ localStorage.removeItem(this.getCacheKey());
2927
+ }
2928
+ // ==================== CLEANUP ====================
2929
+ /**
2930
+ * Dispose of resources (event listeners, etc.)
2931
+ */
2932
+ dispose() {
2933
+ if (this.popstateHandler && typeof window !== 'undefined') {
2934
+ window.removeEventListener('popstate', this.popstateHandler);
2935
+ this.popstateHandler = null;
2936
+ }
2937
+ }
2938
+ /**
2939
+ * Get detected framework name
2940
+ */
2941
+ getDetectedFramework() {
2942
+ return this.detectedFramework;
2943
+ }
2721
2944
  /**
2722
2945
  * Get merged sitemap entries with deduplication
2723
2946
  */
@@ -2744,6 +2967,7 @@ class SiteMapDiscovery {
2744
2967
  try {
2745
2968
  // Detect framework if not specified
2746
2969
  const framework = config.framework || this.detectFramework();
2970
+ this.detectedFramework = framework;
2747
2971
  let routes = [];
2748
2972
  switch (framework) {
2749
2973
  case 'react-router':
@@ -2927,26 +3151,31 @@ class SiteMapDiscovery {
2927
3151
  }
2928
3152
  /**
2929
3153
  * Discover routes by scanning DOM navigation elements
3154
+ * Uses smart defaults when no selectors provided
2930
3155
  */
2931
3156
  discoverFromDOM(selectors) {
2932
3157
  const routes = [];
2933
3158
  if (typeof document === 'undefined')
2934
3159
  return routes;
2935
- const defaultSelectors = [
2936
- 'nav a[href]',
2937
- '[role="navigation"] a[href]',
2938
- '.nav a[href]',
2939
- '.navigation a[href]',
2940
- '.sidebar a[href]',
2941
- '.menu a[href]',
2942
- 'header a[href]'
2943
- ];
2944
- const allSelectors = selectors || defaultSelectors;
3160
+ // Use provided selectors or smart defaults
3161
+ const allSelectors = selectors || DEFAULT_NAV_SELECTORS;
3162
+ // Get max links limit from config or use default
3163
+ const maxLinks = this.config.discovery?.maxDomLinks ?? DEFAULT_MAX_DOM_LINKS;
3164
+ // Get exclude patterns (merge user-provided with defaults)
3165
+ const userExcludes = this.config.discovery?.excludePaths || [];
3166
+ const allExcludes = [...DEFAULT_EXCLUDE_PATTERNS, ...userExcludes];
2945
3167
  const seen = new Set();
3168
+ let linkCount = 0;
2946
3169
  for (const selector of allSelectors) {
3170
+ // Stop if we've hit the limit
3171
+ if (linkCount >= maxLinks)
3172
+ break;
2947
3173
  try {
2948
3174
  const links = document.querySelectorAll(selector);
2949
3175
  for (const link of links) {
3176
+ // Stop if we've hit the limit
3177
+ if (linkCount >= maxLinks)
3178
+ break;
2950
3179
  const href = link.getAttribute('href');
2951
3180
  if (!href)
2952
3181
  continue;
@@ -2955,14 +3184,31 @@ class SiteMapDiscovery {
2955
3184
  continue;
2956
3185
  }
2957
3186
  // Normalize path
2958
- const path = href.startsWith('/') ? href : `/${href}`;
2959
- // Skip duplicates, anchors, and special links
2960
- if (seen.has(path) || path.startsWith('/#') || path === '/' || path.includes('javascript:')) {
2961
- continue;
3187
+ let path = href;
3188
+ if (href.startsWith('http')) {
3189
+ try {
3190
+ path = new URL(href).pathname;
3191
+ }
3192
+ catch {
3193
+ continue;
3194
+ }
3195
+ }
3196
+ else if (!href.startsWith('/')) {
3197
+ path = `/${href}`;
2962
3198
  }
2963
- seen.add(path);
2964
3199
  // Clean path (remove query string and hash)
2965
3200
  const cleanPath = path.split('?')[0].split('#')[0];
3201
+ // Skip duplicates
3202
+ if (seen.has(cleanPath))
3203
+ continue;
3204
+ // Skip root path
3205
+ if (cleanPath === '/')
3206
+ continue;
3207
+ // Skip paths matching exclude patterns
3208
+ if (this.shouldExcludeRoute(cleanPath, allExcludes))
3209
+ continue;
3210
+ seen.add(cleanPath);
3211
+ linkCount++;
2966
3212
  routes.push({
2967
3213
  path: cleanPath,
2968
3214
  name: link.textContent?.trim() || this.pathToName(cleanPath)
@@ -2973,6 +3219,7 @@ class SiteMapDiscovery {
2973
3219
  // Invalid selector - skip
2974
3220
  }
2975
3221
  }
3222
+ console.log(`[SiteMapDiscovery] DOM scan found ${routes.length} routes (limit: ${maxLinks})`);
2976
3223
  return routes;
2977
3224
  }
2978
3225
  // ==================== SOURCE 3: BACKEND API ====================
@@ -3260,9 +3507,18 @@ class CyberneticIntentClassifier {
3260
3507
  this.modalIndex = new Map();
3261
3508
  // Build indexes for fast lookup
3262
3509
  this.buildIndexes();
3263
- // Initialize multi-source sitemap discovery if configured
3264
- if (config.siteMapConfig) {
3265
- this.siteMapDiscovery = new SiteMapDiscovery(config.siteMapConfig, apiUrl, apiKey);
3510
+ // Auto-enable sitemap discovery when agentic is enabled but no explicit config provided
3511
+ // This enables zero-config mode: just set enabled: true and discovery works automatically
3512
+ const siteMapConfig = config.siteMapConfig ?? (config.enabled && !config.siteMap?.length
3513
+ ? { discovery: { enabled: true } }
3514
+ : undefined);
3515
+ // Initialize multi-source sitemap discovery
3516
+ if (siteMapConfig) {
3517
+ this.siteMapDiscovery = new SiteMapDiscovery(siteMapConfig, apiUrl, apiKey);
3518
+ // Log zero-config mode activation
3519
+ if (!config.siteMapConfig && config.enabled) {
3520
+ console.log('[CyberneticIntentClassifier] Zero-config mode: auto-discovery enabled');
3521
+ }
3266
3522
  }
3267
3523
  }
3268
3524
  /**