@usecrow/client 0.1.42 → 0.1.44

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/index.js CHANGED
@@ -1,816 +1,78 @@
1
- import { C as A, W as R } from "./workflowExecutor-ijFlX3nx.js";
2
- class _ {
3
- constructor() {
4
- this.state = {
5
- token: null,
6
- metadata: {},
7
- isVerified: !1
8
- }, this.listeners = /* @__PURE__ */ new Set();
9
- }
10
- /**
11
- * Identify the current user with a JWT token
12
- */
13
- identify(e) {
14
- const { token: t, ...s } = e;
15
- this.state = {
16
- token: t,
17
- metadata: s,
18
- isVerified: !1
19
- // Will be set when server confirms
20
- }, this.notify(), console.log("[Crow] User identified");
21
- }
22
- /**
23
- * Update verification status (called when server confirms)
24
- */
25
- setVerified(e) {
26
- this.state = { ...this.state, isVerified: e }, this.notify();
27
- }
28
- /**
29
- * Reset user identity (call on logout)
30
- */
31
- reset() {
32
- this.state = {
33
- token: null,
34
- metadata: {},
35
- isVerified: !1
36
- }, this.notify(), console.log("[Crow] User reset");
37
- }
38
- /**
39
- * Get current identity token
40
- */
41
- getToken() {
42
- return this.state.token;
43
- }
44
- /**
45
- * Get current identity state
46
- */
47
- getState() {
48
- return { ...this.state };
49
- }
50
- /**
51
- * Check if user is identified
52
- */
53
- isIdentified() {
54
- return this.state.token !== null;
55
- }
56
- /**
57
- * Check if user is verified
58
- */
59
- isVerified() {
60
- return this.state.isVerified;
61
- }
62
- /**
63
- * Subscribe to identity changes
64
- */
65
- subscribe(e) {
66
- return this.listeners.add(e), () => this.listeners.delete(e);
67
- }
68
- notify() {
69
- const e = this.getState();
70
- for (const t of this.listeners)
71
- t(e);
72
- }
73
- }
74
- class k {
75
- constructor() {
76
- this.handlers = {};
77
- }
78
- /**
79
- * Register client-side tool handlers
80
- */
81
- register(e) {
82
- for (const [t, s] of Object.entries(e))
83
- typeof s == "function" ? (this.handlers[t] = s, console.log(`[Crow] Registered client tool: ${t}`)) : console.warn(`[Crow] Skipping ${t}: handler is not a function`);
84
- }
85
- /**
86
- * Unregister a tool handler
87
- */
88
- unregister(e) {
89
- delete this.handlers[e], console.log(`[Crow] Unregistered client tool: ${e}`);
90
- }
91
- /**
92
- * Check if a tool is registered
93
- */
94
- has(e) {
95
- return e in this.handlers;
96
- }
97
- /**
98
- * Get all registered tool names
99
- */
100
- getRegisteredTools() {
101
- return Object.keys(this.handlers);
102
- }
103
- /**
104
- * Execute a client-side tool
105
- */
106
- async execute(e, t) {
107
- const s = this.handlers[e];
108
- if (!s)
109
- return console.warn(`[Crow] No handler registered for tool: ${e}`), {
110
- status: "error",
111
- error: `No handler registered for tool: ${e}`
112
- };
113
- try {
114
- console.log(`[Crow] Executing client tool: ${e}`, t);
115
- const r = await s(t);
116
- return console.log(`[Crow] Tool ${e} completed:`, r), r;
117
- } catch (r) {
118
- const n = r instanceof Error ? r.message : String(r);
119
- return console.error(`[Crow] Tool ${e} failed:`, r), {
120
- status: "error",
121
- error: n
122
- };
123
- }
124
- }
125
- }
126
- const v = "crow_conv_";
127
- class C {
128
- constructor(e, t) {
129
- this.currentId = null, this.productId = e, this.apiUrl = t, this.currentId = this.loadFromStorage();
130
- }
131
- /**
132
- * Get localStorage key for this product
133
- */
134
- getStorageKey() {
135
- return `${v}${this.productId}`;
136
- }
137
- /**
138
- * Load conversation ID from localStorage
139
- */
140
- loadFromStorage() {
141
- try {
142
- return localStorage.getItem(this.getStorageKey());
143
- } catch {
144
- return null;
145
- }
146
- }
147
- /**
148
- * Save conversation ID to localStorage
149
- */
150
- saveToStorage(e) {
151
- try {
152
- localStorage.setItem(this.getStorageKey(), e);
153
- } catch {
154
- }
155
- }
156
- /**
157
- * Clear conversation ID from localStorage
158
- */
159
- clearStorage() {
160
- try {
161
- localStorage.removeItem(this.getStorageKey());
162
- } catch {
163
- }
164
- }
165
- /**
166
- * Get current conversation ID
167
- */
168
- getCurrentId() {
169
- return this.currentId;
170
- }
171
- /**
172
- * Set current conversation ID
173
- */
174
- setCurrentId(e) {
175
- this.currentId = e, e ? this.saveToStorage(e) : this.clearStorage();
176
- }
177
- /**
178
- * Check if there's a restored conversation
179
- */
180
- hasRestoredConversation() {
181
- return this.currentId !== null;
182
- }
183
- /**
184
- * Clear current conversation (start new)
185
- */
186
- clear() {
187
- this.currentId = null, this.clearStorage();
188
- }
189
- /**
190
- * Fetch list of conversations for verified user
191
- */
192
- async getConversations(e) {
193
- try {
194
- const t = await fetch(
195
- `${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`
196
- );
197
- if (!t.ok)
198
- throw new Error(`HTTP error: ${t.status}`);
199
- return (await t.json()).conversations || [];
200
- } catch (t) {
201
- return console.error("[Crow] Failed to load conversations:", t), [];
202
- }
203
- }
204
- /**
205
- * Load conversation history for verified user
206
- */
207
- async loadHistory(e, t) {
208
- try {
209
- const s = await fetch(
210
- `${this.apiUrl}/api/chat/conversations/${e}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`
211
- );
212
- if (!s.ok)
213
- throw new Error(`HTTP error: ${s.status}`);
214
- const r = await s.json();
215
- return this.parseHistoryMessages(r.messages || []);
216
- } catch (s) {
217
- return console.error("[Crow] Failed to load conversation history:", s), [];
218
- }
219
- }
220
- /**
221
- * Load conversation history for anonymous user
222
- */
223
- async loadAnonymousHistory(e) {
224
- try {
225
- const t = await fetch(
226
- `${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`
227
- );
228
- if (!t.ok)
229
- throw new Error(`HTTP error: ${t.status}`);
230
- const s = await t.json();
231
- return this.parseHistoryMessages(s.messages || []);
232
- } catch (t) {
233
- return console.error("[Crow] Failed to load anonymous conversation history:", t), [];
234
- }
235
- }
236
- /**
237
- * Parse history messages from API format
238
- */
239
- parseHistoryMessages(e) {
240
- return e.filter((t) => t.role !== "tool" && !t.content.startsWith("[Client Tool Result:")).map((t, s) => ({
241
- id: `history-${s}`,
242
- content: this.parseContent(t.content),
243
- role: t.role === "assistant" ? "assistant" : "user",
244
- timestamp: /* @__PURE__ */ new Date()
245
- }));
246
- }
247
- /**
248
- * Parse structured content (with thinking/text blocks) and extract just text
249
- */
250
- parseContent(e) {
251
- try {
252
- const t = JSON.parse(e);
253
- if (Array.isArray(t)) {
254
- const s = t.find(
255
- (r) => r.type === "text"
256
- );
257
- return (s == null ? void 0 : s.text) || e;
258
- }
259
- } catch {
260
- }
261
- if (e.includes("'type': 'text'")) {
262
- const t = e.match(
263
- /\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/
264
- );
265
- if (t)
266
- return t[1].replace(/\\n/g, `
267
- `).replace(/\\'/g, "'");
268
- }
269
- return e;
270
- }
271
- }
272
- function b(o) {
273
- if (o === "[DONE]")
274
- return { type: "done" };
275
- try {
276
- const e = JSON.parse(o);
277
- switch (e.type) {
278
- case "verification_status":
279
- return {
280
- type: "verification_status",
281
- isVerified: e.is_verified === !0
282
- };
283
- case "conversation_id":
284
- return {
285
- type: "conversation_id",
286
- conversationId: e.conversation_id
287
- };
288
- case "thinking":
289
- return e.status === "complete" ? { type: "thinking_complete" } : null;
290
- case "thinking_token":
291
- return {
292
- type: "thinking",
293
- content: e.content || ""
294
- };
295
- case "content":
296
- return {
297
- type: "content",
298
- text: e.content || "",
299
- accumulated: ""
300
- // Will be set by caller
301
- };
302
- case "citations":
303
- return {
304
- type: "citations",
305
- citations: e.citations
306
- };
307
- case "error":
308
- return {
309
- type: "error",
310
- message: e.message || "Unknown error"
311
- };
312
- case "tool_call_start":
313
- return {
314
- type: "tool_call_start",
315
- toolName: e.tool_name,
316
- displayName: e.display_name || void 0,
317
- arguments: e.arguments || {}
318
- };
319
- case "tool_call_complete":
320
- return {
321
- type: "tool_call_complete",
322
- toolName: e.tool_name,
323
- displayName: e.display_name || void 0,
324
- success: e.success
325
- };
326
- case "client_tool_call":
327
- return {
328
- type: "client_tool_call",
329
- toolName: e.tool_name,
330
- displayName: e.display_name || void 0,
331
- arguments: e.arguments || {}
332
- };
333
- case "tool_consent_required":
334
- return {
335
- type: "tool_consent_required",
336
- toolName: e.tool_name,
337
- displayName: e.display_name || void 0,
338
- arguments: e.arguments || {}
339
- };
340
- case "workflow_started":
341
- return {
342
- type: "workflow_started",
343
- name: e.name,
344
- todos: e.todos
345
- };
346
- case "todo_updated":
347
- return {
348
- type: "workflow_todo_updated",
349
- todoId: e.id,
350
- status: e.status
351
- };
352
- case "workflow_ended":
353
- return { type: "workflow_ended" };
354
- case "workflow_complete_prompt":
355
- return { type: "workflow_complete_prompt" };
356
- default:
357
- return null;
358
- }
359
- } catch {
360
- return console.error("[Crow] Failed to parse SSE data:", o), null;
361
- }
362
- }
363
- function* I(o) {
364
- const e = o.split(`
365
- `);
366
- for (const t of e)
367
- t.startsWith("data: ") && (yield t.slice(6).trim());
368
- }
369
- async function* M(o, e) {
370
- var n;
371
- const t = (n = o.body) == null ? void 0 : n.getReader();
372
- if (!t)
373
- throw new Error("Response body is not readable");
374
- const s = new TextDecoder();
375
- let r = "";
376
- try {
377
- for (; ; ) {
378
- if (e != null && e.aborted) {
379
- t.cancel();
380
- return;
381
- }
382
- const { done: i, value: d } = await t.read();
383
- if (i) break;
384
- const h = s.decode(d);
385
- for (const u of I(h)) {
386
- const l = b(u);
387
- if (l && (l.type === "content" ? (r += l.text, yield { ...l, accumulated: r }) : yield l, l.type === "done"))
388
- return;
389
- }
390
- }
391
- } finally {
392
- t.releaseLock();
393
- }
394
- }
395
- async function S() {
396
- var o;
397
- try {
398
- const e = document.title, t = window.location.href, s = window.location.pathname, r = (((o = document.body) == null ? void 0 : o.innerText) || "").slice(0, 2e3).trim();
399
- return {
400
- status: "success",
401
- data: {
402
- title: e,
403
- url: t,
404
- pathname: s,
405
- visibleText: r
406
- }
407
- };
408
- } catch (e) {
409
- return {
410
- status: "error",
411
- error: e instanceof Error ? e.message : "Failed to read screen"
412
- };
413
- }
414
- }
415
- const w = {
416
- whatsOnScreen: S
417
- }, T = Object.keys(w), $ = "https://api.usecrow.org", E = "claude-sonnet-4-20250514";
418
- class x {
419
- constructor(e) {
420
- this.context = {}, this.abortController = null, this.callbacks = {}, this._messages = [], this.messageListeners = /* @__PURE__ */ new Set(), this._isLoading = !1, this.loadingListeners = /* @__PURE__ */ new Set(), this.config = {
421
- productId: e.productId,
422
- apiUrl: e.apiUrl || $,
423
- model: e.model || E
424
- }, this.identity = new _(), this.tools = new k(), this.conversations = new C(
425
- this.config.productId,
426
- this.config.apiUrl
427
- ), this.tools.register(w), console.log("[Crow] Default tools registered:", T.join(", ")), this.identity.subscribe((t) => {
428
- var s, r;
429
- (r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, t.isVerified);
430
- });
431
- }
432
- // ============================================================================
433
- // Configuration
434
- // ============================================================================
435
- /**
436
- * Get current product ID
437
- */
438
- get productId() {
439
- return this.config.productId;
440
- }
441
- /**
442
- * Get current API URL
443
- */
444
- get apiUrl() {
445
- return this.config.apiUrl;
446
- }
447
- /**
448
- * Get/set current model
449
- */
450
- get model() {
451
- return this.config.model;
452
- }
453
- set model(e) {
454
- this.config.model = e;
455
- }
456
- // ============================================================================
457
- // Event Callbacks
458
- // ============================================================================
459
- /**
460
- * Register event callbacks
461
- */
462
- on(e) {
463
- this.callbacks = { ...this.callbacks, ...e };
464
- }
465
- // ============================================================================
466
- // Identity
467
- // ============================================================================
468
- /**
469
- * Identify the current user with a JWT token
470
- */
471
- identify(e) {
472
- this.identity.identify(e);
473
- }
474
- /**
475
- * Reset user identity (call on logout)
476
- */
477
- resetUser() {
478
- this.identity.reset(), this.clearMessages();
479
- }
480
- /**
481
- * Check if user is identified
482
- */
483
- isIdentified() {
484
- return this.identity.isIdentified();
485
- }
486
- /**
487
- * Check if user is verified by server
488
- */
489
- isVerified() {
490
- return this.identity.isVerified();
491
- }
492
- // ============================================================================
493
- // Tools
494
- // ============================================================================
495
- /**
496
- * Register client-side tool handlers
497
- */
498
- registerTools(e) {
499
- this.tools.register(e);
500
- }
501
- /**
502
- * Unregister a tool handler
503
- */
504
- unregisterTool(e) {
505
- this.tools.unregister(e);
506
- }
507
- /**
508
- * Get list of registered tool names
509
- */
510
- getRegisteredTools() {
511
- return this.tools.getRegisteredTools();
512
- }
513
- // ============================================================================
514
- // Context
515
- // ============================================================================
516
- /**
517
- * Set context data to be sent with messages
518
- */
519
- setContext(e) {
520
- this.context = { ...this.context, ...e };
521
- }
522
- /**
523
- * Clear context data
524
- */
525
- clearContext() {
526
- this.context = {};
527
- }
528
- // ============================================================================
529
- // Messages
530
- // ============================================================================
531
- /**
532
- * Get current messages
533
- */
534
- get messages() {
535
- return [...this._messages];
536
- }
537
- /**
538
- * Check if currently loading/streaming
539
- */
540
- get isLoading() {
541
- return this._isLoading;
542
- }
543
- /**
544
- * Subscribe to message changes
545
- */
546
- onMessages(e) {
547
- return this.messageListeners.add(e), () => this.messageListeners.delete(e);
548
- }
549
- /**
550
- * Subscribe to loading state changes
551
- */
552
- onLoading(e) {
553
- return this.loadingListeners.add(e), () => this.loadingListeners.delete(e);
554
- }
555
- /**
556
- * Clear all messages and start new conversation
557
- */
558
- clearMessages() {
559
- this._messages = [], this.conversations.clear(), this.notifyMessages();
560
- }
561
- /**
562
- * Load messages from history
563
- */
564
- loadMessages(e) {
565
- this._messages = e, this.notifyMessages();
566
- }
567
- notifyMessages() {
568
- const e = this.messages;
569
- for (const t of this.messageListeners)
570
- t(e);
571
- }
572
- setLoading(e) {
573
- this._isLoading = e;
574
- for (const t of this.loadingListeners)
575
- t(e);
576
- }
577
- addMessage(e) {
578
- var t, s;
579
- this._messages = [...this._messages, e], this.notifyMessages(), (s = (t = this.callbacks).onMessage) == null || s.call(t, e);
580
- }
581
- updateMessage(e, t) {
582
- var s, r;
583
- this._messages = this._messages.map(
584
- (n) => n.id === e ? { ...n, ...t } : n
585
- ), this.notifyMessages(), (r = (s = this.callbacks).onMessageUpdate) == null || r.call(s, e, t);
586
- }
587
- generateMessageId(e) {
588
- return `${e}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
589
- }
590
- // ============================================================================
591
- // Conversations
592
- // ============================================================================
593
- /**
594
- * Get current conversation ID
595
- */
596
- get conversationId() {
597
- return this.conversations.getCurrentId();
598
- }
599
- /**
600
- * Set current conversation ID
601
- */
602
- set conversationId(e) {
603
- this.conversations.setCurrentId(e);
604
- }
605
- /**
606
- * Get list of conversations for verified user
607
- */
608
- async getConversations() {
609
- const e = this.identity.getToken();
610
- return e ? this.conversations.getConversations(e) : (console.warn("[Crow] Cannot get conversations: user not identified"), []);
611
- }
612
- /**
613
- * Load conversation history
614
- */
615
- async loadHistory(e) {
616
- const t = this.identity.getToken();
617
- return t ? this.conversations.loadHistory(e, t) : this.conversations.loadAnonymousHistory(e);
618
- }
619
- /**
620
- * Switch to a different conversation
621
- */
622
- async switchConversation(e) {
623
- const t = await this.loadHistory(e);
624
- this.conversations.setCurrentId(e), this.loadMessages(t);
625
- }
626
- // ============================================================================
627
- // Messaging
628
- // ============================================================================
629
- /**
630
- * Send a message and receive streaming response
631
- * Returns an async generator of stream events
632
- */
633
- async *sendMessage(e) {
634
- var i, d, h, u, l, g, f, p, y, m;
635
- if (!e.trim())
636
- return;
637
- const t = this.generateMessageId("user");
638
- this.addMessage({
639
- id: t,
640
- content: e,
641
- role: "user",
642
- timestamp: /* @__PURE__ */ new Date()
643
- });
644
- const s = this.generateMessageId("assistant");
645
- this.addMessage({
646
- id: s,
647
- content: "",
648
- role: "assistant",
649
- timestamp: /* @__PURE__ */ new Date()
650
- }), this.setLoading(!0), this.abortController = new AbortController();
651
- let r = "", n = "";
652
- try {
653
- const c = await fetch(`${this.config.apiUrl}/api/chat/message`, {
654
- method: "POST",
655
- headers: { "Content-Type": "application/json" },
656
- body: JSON.stringify({
657
- product_id: this.config.productId,
658
- message: e,
659
- conversation_id: this.conversations.getCurrentId(),
660
- identity_token: this.identity.getToken(),
661
- model: this.config.model,
662
- context: Object.keys(this.context).length > 0 ? this.context : void 0
663
- }),
664
- signal: this.abortController.signal
665
- });
666
- if (!c.ok)
667
- throw new Error(`HTTP error: ${c.status}`);
668
- for await (const a of M(c, this.abortController.signal)) {
669
- switch (a.type) {
670
- case "content":
671
- r = a.accumulated, this.updateMessage(s, { content: r });
672
- break;
673
- case "thinking":
674
- n += a.content, this.updateMessage(s, { thinking: n });
675
- break;
676
- case "thinking_complete":
677
- this.updateMessage(s, { thinkingComplete: !0 });
678
- break;
679
- case "citations":
680
- this.updateMessage(s, { citations: a.citations });
681
- break;
682
- case "verification_status":
683
- this.identity.setVerified(a.isVerified);
684
- break;
685
- case "conversation_id":
686
- this.conversations.setCurrentId(a.conversationId);
687
- break;
688
- case "client_tool_call":
689
- await this.tools.execute(a.toolName, a.arguments), (d = (i = this.callbacks).onToolCall) == null || d.call(i, a);
690
- break;
691
- case "tool_call_start":
692
- case "tool_call_complete":
693
- (u = (h = this.callbacks).onToolCall) == null || u.call(h, a);
694
- break;
695
- case "workflow_started":
696
- case "workflow_todo_updated":
697
- case "workflow_ended":
698
- case "workflow_complete_prompt":
699
- (g = (l = this.callbacks).onWorkflow) == null || g.call(l, a);
700
- break;
701
- case "error":
702
- this.updateMessage(s, { content: a.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(a.message));
703
- break;
704
- }
705
- yield a;
706
- }
707
- } catch (c) {
708
- if (c instanceof Error && c.name === "AbortError") {
709
- r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((a) => a.id !== s), this.notifyMessages());
710
- return;
711
- }
712
- console.error("[Crow] Error:", c), this.updateMessage(s, {
713
- content: "Sorry, I encountered an error. Please try again."
714
- }), (m = (y = this.callbacks).onError) == null || m.call(y, c instanceof Error ? c : new Error(String(c)));
715
- } finally {
716
- this.setLoading(!1), this.abortController = null;
717
- }
718
- }
719
- /**
720
- * Send a message and wait for complete response (non-streaming)
721
- */
722
- async send(e) {
723
- let t = null;
724
- for await (const r of this.sendMessage(e))
725
- if (r.type === "done")
726
- break;
727
- const s = this.messages;
728
- return s.length > 0 && (t = s[s.length - 1], t.role === "assistant") ? t : null;
729
- }
730
- /**
731
- * Stop current generation
732
- */
733
- stop() {
734
- this.abortController && (this.abortController.abort(), this.setLoading(!1));
735
- }
736
- // ============================================================================
737
- // Cleanup
738
- // ============================================================================
739
- /**
740
- * Destroy the client and clean up resources
741
- */
742
- destroy() {
743
- this.stop(), this.messageListeners.clear(), this.loadingListeners.clear();
744
- }
745
- }
746
- function L(o, e, t) {
747
- const s = o.find(
748
- (n) => n.name.toLowerCase() === e.toLowerCase()
1
+ import { ConversationManager as g, CrowClient as f, DEFAULT_TOOLS as m, DEFAULT_TOOL_NAMES as v, IdentityManager as w, ToolManager as h, createLocalStorageAdapter as S, createMemoryStorageAdapter as T, parseSSEChunk as _, parseSSEData as A, streamResponse as C } from "./index.native.js";
2
+ import { C as L, W as y } from "./workflowExecutor-ijFlX3nx.js";
3
+ function l(n, s, a) {
4
+ const e = n.find(
5
+ (t) => t.name.toLowerCase() === s.toLowerCase()
749
6
  );
750
- if (!s) return null;
751
- let r = s.path;
752
- if (t)
753
- for (const [n, i] of Object.entries(t))
754
- r = r.replace(`:${n}`, String(i));
755
- return r;
7
+ if (!e) return null;
8
+ let o = e.path;
9
+ if (a)
10
+ for (const [t, r] of Object.entries(a))
11
+ o = o.replace(`:${t}`, String(r));
12
+ return o;
756
13
  }
757
- function U(o, e) {
758
- return async (t) => {
14
+ function c(n, s) {
15
+ return async (a) => {
759
16
  try {
760
- const s = t.page, r = t.params, n = t.url;
761
- let i = null;
762
- if (s) {
763
- if (i = L(o, s, r), !i)
17
+ const e = a.page, o = a.params, t = a.url;
18
+ let r = null;
19
+ if (e) {
20
+ if (r = l(n, e, o), !r)
764
21
  return {
765
22
  status: "error",
766
- error: `Unknown page: "${s}". Available pages: ${o.map((h) => h.name).join(", ")}`
23
+ error: `Unknown page: "${e}". Available pages: ${n.map((u) => u.name).join(", ")}`
767
24
  };
768
- } else if (n)
769
- i = n;
25
+ } else if (t)
26
+ r = t;
770
27
  else
771
28
  return {
772
29
  status: "error",
773
30
  error: 'Either "page" or "url" parameter is required'
774
31
  };
775
- const d = i.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
776
- return d ? {
32
+ const i = r.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
33
+ return i ? {
777
34
  status: "error",
778
- error: `Missing parameters: ${d.join(", ")}. Please provide values for these parameters.`
779
- } : e ? (e(i), {
35
+ error: `Missing parameters: ${i.join(", ")}. Please provide values for these parameters.`
36
+ } : s ? (s(r), {
780
37
  status: "success",
781
38
  data: {
782
- navigated_to: i,
783
- page: s || void 0,
39
+ navigated_to: r,
40
+ page: e || void 0,
784
41
  method: "spa_router"
785
42
  }
786
- }) : (window.location.href = i, {
43
+ }) : typeof window < "u" ? (window.location.href = r, {
787
44
  status: "success",
788
45
  data: {
789
- navigated_to: i,
790
- page: s || void 0,
46
+ navigated_to: r,
47
+ page: e || void 0,
791
48
  method: "full_navigation"
792
49
  }
793
- });
794
- } catch (s) {
50
+ }) : {
51
+ status: "error",
52
+ error: "No navigateFn provided and window.location is unavailable (non-browser runtime). Pass a navigateFn to createNavigateToPageTool."
53
+ };
54
+ } catch (e) {
795
55
  return {
796
56
  status: "error",
797
- error: String(s)
57
+ error: String(e)
798
58
  };
799
59
  }
800
60
  };
801
61
  }
802
62
  export {
803
- C as ConversationManager,
804
- A as CrowBrowserUse,
805
- x as CrowClient,
806
- w as DEFAULT_TOOLS,
807
- T as DEFAULT_TOOL_NAMES,
808
- _ as IdentityManager,
809
- k as ToolManager,
810
- R as WorkflowExecutor,
811
- U as createNavigateToPageTool,
812
- I as parseSSEChunk,
813
- b as parseSSEData,
814
- L as resolveRoute,
815
- M as streamResponse
63
+ g as ConversationManager,
64
+ L as CrowBrowserUse,
65
+ f as CrowClient,
66
+ m as DEFAULT_TOOLS,
67
+ v as DEFAULT_TOOL_NAMES,
68
+ w as IdentityManager,
69
+ h as ToolManager,
70
+ y as WorkflowExecutor,
71
+ S as createLocalStorageAdapter,
72
+ T as createMemoryStorageAdapter,
73
+ c as createNavigateToPageTool,
74
+ _ as parseSSEChunk,
75
+ A as parseSSEData,
76
+ l as resolveRoute,
77
+ C as streamResponse
816
78
  };