@bike4mind/cli 0.2.30-feat-cli-scrollable-command-autocomplete.19203 → 0.2.30-feat-cli-websocket-streaming.19209

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,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-C3K7SH2V.js";
4
+ } from "./chunk-55ZDRTGQ.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
7
7
  var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
@@ -1181,6 +1181,29 @@ var VoiceSessionSendTranscriptAction = z10.object({
1181
1181
  conversationItemId: z10.string(),
1182
1182
  timestamp: z10.coerce.date().optional()
1183
1183
  });
1184
+ var CliCompletionRequestAction = z10.object({
1185
+ action: z10.literal("cli_completion_request"),
1186
+ accessToken: z10.string(),
1187
+ requestId: z10.string().uuid(),
1188
+ model: z10.string(),
1189
+ messages: z10.array(z10.object({
1190
+ role: z10.enum(["user", "assistant", "system"]),
1191
+ content: z10.union([z10.string(), z10.array(z10.unknown())])
1192
+ })),
1193
+ options: z10.object({
1194
+ temperature: z10.number().optional(),
1195
+ maxTokens: z10.number().optional(),
1196
+ stream: z10.boolean().optional(),
1197
+ tools: z10.array(z10.unknown()).optional()
1198
+ }).optional()
1199
+ });
1200
+ var CliToolRequestAction = z10.object({
1201
+ action: z10.literal("cli_tool_request"),
1202
+ accessToken: z10.string(),
1203
+ requestId: z10.string().uuid(),
1204
+ toolName: z10.string(),
1205
+ input: z10.record(z10.unknown())
1206
+ });
1184
1207
  var VoiceSessionEndedAction = z10.object({
1185
1208
  action: z10.literal("voice_session_ended"),
1186
1209
  userId: z10.string(),
@@ -1469,6 +1492,36 @@ var VoiceCreditsExhaustedAction = z10.object({
1469
1492
  creditsUsed: z10.number(),
1470
1493
  clientId: z10.string().optional()
1471
1494
  });
1495
+ var CliCompletionChunkAction = z10.object({
1496
+ action: z10.literal("cli_completion_chunk"),
1497
+ requestId: z10.string(),
1498
+ chunk: z10.object({
1499
+ type: z10.enum(["content", "tool_use"]),
1500
+ text: z10.string(),
1501
+ tools: z10.array(z10.unknown()).optional(),
1502
+ usage: z10.object({
1503
+ inputTokens: z10.number().optional(),
1504
+ outputTokens: z10.number().optional()
1505
+ }).optional(),
1506
+ thinking: z10.array(z10.unknown()).optional()
1507
+ })
1508
+ });
1509
+ var CliCompletionDoneAction = z10.object({
1510
+ action: z10.literal("cli_completion_done"),
1511
+ requestId: z10.string()
1512
+ });
1513
+ var CliCompletionErrorAction = z10.object({
1514
+ action: z10.literal("cli_completion_error"),
1515
+ requestId: z10.string(),
1516
+ error: z10.string()
1517
+ });
1518
+ var CliToolResponseAction = z10.object({
1519
+ action: z10.literal("cli_tool_response"),
1520
+ requestId: z10.string(),
1521
+ success: z10.boolean(),
1522
+ content: z10.unknown().optional(),
1523
+ error: z10.string().optional()
1524
+ });
1472
1525
  var SessionCreatedAction = shareableDocumentSchema.extend({
1473
1526
  action: z10.literal("session.created"),
1474
1527
  id: z10.string(),
@@ -1503,7 +1556,9 @@ var MessageDataToServer = z10.discriminatedUnion("action", [
1503
1556
  DataUnsubscribeRequestAction,
1504
1557
  HeartbeatAction,
1505
1558
  VoiceSessionSendTranscriptAction,
1506
- VoiceSessionEndedAction
1559
+ VoiceSessionEndedAction,
1560
+ CliCompletionRequestAction,
1561
+ CliToolRequestAction
1507
1562
  ]);
1508
1563
  var MessageDataToClient = z10.discriminatedUnion("action", [
1509
1564
  DataSubscriptionUpdateAction,
@@ -1529,7 +1584,11 @@ var MessageDataToClient = z10.discriminatedUnion("action", [
1529
1584
  PiHistoryCompleteAction,
1530
1585
  PiHistoryErrorAction,
1531
1586
  SessionCreatedAction,
1532
- VoiceCreditsExhaustedAction
1587
+ VoiceCreditsExhaustedAction,
1588
+ CliCompletionChunkAction,
1589
+ CliCompletionDoneAction,
1590
+ CliCompletionErrorAction,
1591
+ CliToolResponseAction
1533
1592
  ]);
1534
1593
 
1535
1594
  // ../../b4m-core/packages/common/dist/src/schemas/cliCompletions.js
@@ -8724,6 +8783,8 @@ export {
8724
8783
  DataUnsubscribeRequestAction,
8725
8784
  HeartbeatAction,
8726
8785
  VoiceSessionSendTranscriptAction,
8786
+ CliCompletionRequestAction,
8787
+ CliToolRequestAction,
8727
8788
  VoiceSessionEndedAction,
8728
8789
  DataSubscriptionUpdateAction,
8729
8790
  LLMStatusUpdateAction,
@@ -8748,6 +8809,10 @@ export {
8748
8809
  ImportHistoryJobProgressUpdateAction,
8749
8810
  ResearchModeStreamAction,
8750
8811
  VoiceCreditsExhaustedAction,
8812
+ CliCompletionChunkAction,
8813
+ CliCompletionDoneAction,
8814
+ CliCompletionErrorAction,
8815
+ CliToolResponseAction,
8751
8816
  SessionCreatedAction,
8752
8817
  MessageDataToServer,
8753
8818
  MessageDataToClient,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-5HA4JEOV.js";
5
+ } from "./chunk-PIJR5GZP.js";
6
6
  import {
7
7
  CompletionApiUsageTransaction,
8
8
  GenericCreditDeductTransaction,
@@ -12,7 +12,7 @@ import {
12
12
  TextGenerationUsageTransaction,
13
13
  TransferCreditTransaction,
14
14
  VideoGenerationUsageTransaction
15
- } from "./chunk-C3K7SH2V.js";
15
+ } from "./chunk-55ZDRTGQ.js";
16
16
 
17
17
  // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
18
18
  import { z } from "zod";
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-5HA4JEOV.js";
9
+ } from "./chunk-PIJR5GZP.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-C3K7SH2V.js";
14
+ } from "./chunk-55ZDRTGQ.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
17
17
  import { z } from "zod";
@@ -7,11 +7,11 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-5HA4JEOV.js";
10
+ } from "./chunk-PIJR5GZP.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-C3K7SH2V.js";
14
+ } from "./chunk-55ZDRTGQ.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -16,7 +16,7 @@ import {
16
16
  dayjsConfig_default,
17
17
  extractSnippetMeta,
18
18
  settingsMap
19
- } from "./chunk-C3K7SH2V.js";
19
+ } from "./chunk-55ZDRTGQ.js";
20
20
  import {
21
21
  Logger
22
22
  } from "./chunk-OCYRD7D6.js";
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-B7Z2QQMD.js";
6
- import "./chunk-5HA4JEOV.js";
7
- import "./chunk-C3K7SH2V.js";
5
+ } from "./chunk-PD5RFLGO.js";
6
+ import "./chunk-PIJR5GZP.js";
7
+ import "./chunk-55ZDRTGQ.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  createFabFile,
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  getEffectiveApiKey,
6
6
  getOpenWeatherKey,
7
7
  getSerperKey
8
- } from "./chunk-65DLNQY2.js";
8
+ } from "./chunk-NRQSEF3E.js";
9
9
  import "./chunk-RUI6HNLO.js";
10
10
  import {
11
11
  ConfigStore,
@@ -15,8 +15,8 @@ import {
15
15
  selectActiveBackgroundAgents,
16
16
  useCliStore
17
17
  } from "./chunk-TVW4ZESU.js";
18
- import "./chunk-BYLWQZ5S.js";
19
- import "./chunk-B7Z2QQMD.js";
18
+ import "./chunk-EAFOBAEJ.js";
19
+ import "./chunk-PD5RFLGO.js";
20
20
  import {
21
21
  BFLImageService,
22
22
  BaseStorage,
@@ -28,7 +28,7 @@ import {
28
28
  OpenAIBackend,
29
29
  OpenAIImageService,
30
30
  XAIImageService
31
- } from "./chunk-5HA4JEOV.js";
31
+ } from "./chunk-PIJR5GZP.js";
32
32
  import {
33
33
  AiEvents,
34
34
  ApiKeyEvents,
@@ -84,7 +84,7 @@ import {
84
84
  XAI_IMAGE_MODELS,
85
85
  b4mLLMTools,
86
86
  getMcpProviderMetadata
87
- } from "./chunk-C3K7SH2V.js";
87
+ } from "./chunk-55ZDRTGQ.js";
88
88
  import {
89
89
  Logger
90
90
  } from "./chunk-OCYRD7D6.js";
@@ -94,7 +94,7 @@ import React21, { useState as useState10, useEffect as useEffect7, useCallback a
94
94
  import { render, Box as Box20, Text as Text20, useApp, useInput as useInput9 } from "ink";
95
95
  import { execSync } from "child_process";
96
96
  import { randomBytes as randomBytes5 } from "crypto";
97
- import { v4 as uuidv411 } from "uuid";
97
+ import { v4 as uuidv413 } from "uuid";
98
98
 
99
99
  // src/components/App.tsx
100
100
  import React15, { useState as useState6, useEffect as useEffect5 } from "react";
@@ -316,23 +316,9 @@ function CommandAutocomplete({ commands, selectedIndex }) {
316
316
  if (commands.length === 0) {
317
317
  return /* @__PURE__ */ React3.createElement(Box2, { marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "No matching commands"));
318
318
  }
319
- const VIEWPORT_SIZE = 6;
320
- const totalCommands = commands.length;
321
- let startIndex = 0;
322
- let endIndex = Math.min(VIEWPORT_SIZE, totalCommands);
323
- if (totalCommands > VIEWPORT_SIZE) {
324
- const halfViewport = Math.floor(VIEWPORT_SIZE / 2);
325
- startIndex = Math.max(0, selectedIndex - halfViewport);
326
- endIndex = Math.min(totalCommands, startIndex + VIEWPORT_SIZE);
327
- if (endIndex === totalCommands) {
328
- startIndex = Math.max(0, totalCommands - VIEWPORT_SIZE);
329
- }
330
- }
331
- const visibleCommands = commands.slice(startIndex, endIndex);
332
- return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, totalCommands === 1 ? "1 command" : `${totalCommands} commands`, totalCommands > VIEWPORT_SIZE && ` (${selectedIndex + 1}/${totalCommands})`, " \u2022 Use \u2191\u2193 to navigate, Enter to select")), visibleCommands.map((cmd, viewportIndex) => {
333
- const actualIndex = startIndex + viewportIndex;
319
+ return /* @__PURE__ */ React3.createElement(Box2, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, /* @__PURE__ */ React3.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, commands.length === 1 ? "1 command" : `${commands.length} commands`, " \u2022 Use \u2191\u2193 to navigate, Enter to select")), commands.map((cmd, index) => {
334
320
  const args = cmd.args ? ` ${cmd.args}` : "";
335
- const isSelected = actualIndex === selectedIndex;
321
+ const isSelected = index === selectedIndex;
336
322
  const sourceIcon = cmd.source === "global" ? "\u{1F3E0} " : cmd.source === "project" ? "\u{1F4C1} " : cmd.source === "built-in" ? "\u{1F527} " : "";
337
323
  return /* @__PURE__ */ React3.createElement(Box2, { key: cmd.name, marginLeft: 1 }, /* @__PURE__ */ React3.createElement(Text3, { color: isSelected ? "cyan" : void 0, bold: isSelected }, isSelected ? "\u25B8 " : " ", sourceIcon, "/", cmd.name, args, " - ", cmd.description));
338
324
  }));
@@ -12495,6 +12481,10 @@ var ServerToolExecutor = class {
12495
12481
  };
12496
12482
 
12497
12483
  // src/llm/ToolRouter.ts
12484
+ var wsToolExecutor = null;
12485
+ function setWebSocketToolExecutor(executor) {
12486
+ wsToolExecutor = executor;
12487
+ }
12498
12488
  var SERVER_TOOLS = ["weather_info", "web_search", "web_fetch"];
12499
12489
  var LOCAL_TOOLS = [
12500
12490
  "file_read",
@@ -12517,7 +12507,15 @@ function isLocalTool(toolName) {
12517
12507
  }
12518
12508
  async function executeTool(toolName, input, apiClient, localToolFn) {
12519
12509
  if (isServerTool(toolName)) {
12520
- logger.debug(`[ToolRouter] Routing ${toolName} to server`);
12510
+ if (wsToolExecutor) {
12511
+ logger.debug(`[ToolRouter] Routing ${toolName} to server via WebSocket`);
12512
+ const result = await wsToolExecutor.execute(toolName, input);
12513
+ if (!result.success) {
12514
+ return `Error executing ${toolName}: ${result.error || "Tool execution failed"}`;
12515
+ }
12516
+ return typeof result.content === "string" ? result.content : JSON.stringify(result.content ?? "");
12517
+ }
12518
+ logger.debug(`[ToolRouter] Routing ${toolName} to server via HTTP`);
12521
12519
  const executor = new ServerToolExecutor(apiClient);
12522
12520
  return await executor.executeTool(toolName, input);
12523
12521
  } else if (isLocalTool(toolName)) {
@@ -14479,6 +14477,173 @@ var ServerLlmBackend = class {
14479
14477
  }
14480
14478
  };
14481
14479
 
14480
+ // src/llm/WebSocketLlmBackend.ts
14481
+ import { v4 as uuidv411 } from "uuid";
14482
+ function stripThinkingBlocks2(text) {
14483
+ return text.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
14484
+ }
14485
+ var WebSocketLlmBackend = class {
14486
+ constructor(options) {
14487
+ this.wsManager = options.wsManager;
14488
+ this.apiClient = options.apiClient;
14489
+ this.currentModel = options.model;
14490
+ this.tokenGetter = options.tokenGetter;
14491
+ this.wsCompletionUrl = options.wsCompletionUrl;
14492
+ }
14493
+ /**
14494
+ * Send completion request via HTTP POST, receive streaming response via WebSocket.
14495
+ * Collects all streamed chunks, then calls callback once at completion
14496
+ * with the full accumulated content.
14497
+ */
14498
+ async complete(model, messages, options, callback) {
14499
+ logger.debug(`[WebSocketLlmBackend] Starting complete() with model: ${model}`);
14500
+ if (options.abortSignal?.aborted) {
14501
+ logger.debug("[WebSocketLlmBackend] Request aborted before start");
14502
+ return;
14503
+ }
14504
+ if (!this.wsManager.isConnected) {
14505
+ throw new Error("WebSocket is not connected");
14506
+ }
14507
+ const requestId = uuidv411();
14508
+ return new Promise((resolve3, reject) => {
14509
+ const isVerbose = process.env.B4M_VERBOSE === "1";
14510
+ const isUltraVerbose = process.env.B4M_DEBUG_STREAM === "1";
14511
+ const streamLogger = new StreamLogger(logger, "WebSocketLlmBackend", isVerbose, isUltraVerbose);
14512
+ streamLogger.streamStart();
14513
+ let eventCount = 0;
14514
+ let accumulatedText = "";
14515
+ let lastUsageInfo = {};
14516
+ let toolsUsed = [];
14517
+ let thinkingBlocks = [];
14518
+ let settled = false;
14519
+ const settle = (action) => {
14520
+ if (settled) return;
14521
+ settled = true;
14522
+ this.wsManager.offRequest(requestId);
14523
+ this.wsManager.offDisconnect(onDisconnect);
14524
+ action();
14525
+ };
14526
+ const settleResolve = () => settle(() => resolve3());
14527
+ const settleReject = (err) => settle(() => reject(err));
14528
+ const onDisconnect = () => {
14529
+ logger.debug("[WebSocketLlmBackend] Connection dropped during completion");
14530
+ settleReject(new Error("WebSocket connection lost during completion"));
14531
+ };
14532
+ this.wsManager.onDisconnect(onDisconnect);
14533
+ if (options.abortSignal) {
14534
+ if (options.abortSignal.aborted) {
14535
+ settleResolve();
14536
+ return;
14537
+ }
14538
+ options.abortSignal.addEventListener(
14539
+ "abort",
14540
+ () => {
14541
+ logger.debug("[WebSocketLlmBackend] Abort signal received");
14542
+ settleResolve();
14543
+ },
14544
+ { once: true }
14545
+ );
14546
+ }
14547
+ const updateUsage = (usage) => {
14548
+ if (usage) {
14549
+ lastUsageInfo = { inputTokens: usage.inputTokens, outputTokens: usage.outputTokens };
14550
+ }
14551
+ };
14552
+ this.wsManager.onRequest(requestId, (message) => {
14553
+ if (options.abortSignal?.aborted) return;
14554
+ const action = message.action;
14555
+ if (action === "cli_completion_chunk") {
14556
+ eventCount++;
14557
+ const chunk = message.chunk;
14558
+ streamLogger.onEvent(eventCount, JSON.stringify(chunk));
14559
+ const textChunk = chunk.text || "";
14560
+ if (textChunk) accumulatedText += textChunk;
14561
+ updateUsage(chunk.usage);
14562
+ if (chunk.type === "content") {
14563
+ streamLogger.onContent(eventCount, textChunk, accumulatedText);
14564
+ } else if (chunk.type === "tool_use") {
14565
+ streamLogger.onCriticalEvent(eventCount, "TOOL_USE", `tools: ${chunk.tools?.length}`);
14566
+ if (chunk.tools && chunk.tools.length > 0) toolsUsed = chunk.tools;
14567
+ if (chunk.thinking && chunk.thinking.length > 0) thinkingBlocks = chunk.thinking;
14568
+ }
14569
+ } else if (action === "cli_completion_done") {
14570
+ streamLogger.streamComplete(accumulatedText);
14571
+ const cleanedText = stripThinkingBlocks2(accumulatedText);
14572
+ if (!cleanedText && toolsUsed.length === 0) {
14573
+ settleResolve();
14574
+ return;
14575
+ }
14576
+ const info = {
14577
+ ...lastUsageInfo,
14578
+ ...toolsUsed.length > 0 && { toolsUsed },
14579
+ ...thinkingBlocks.length > 0 && { thinking: thinkingBlocks }
14580
+ };
14581
+ callback([cleanedText], info).then(() => settleResolve()).catch((err) => settleReject(err));
14582
+ } else if (action === "cli_completion_error") {
14583
+ const errorMsg = message.error || "Server error";
14584
+ streamLogger.onCriticalEvent(eventCount, "ERROR", errorMsg);
14585
+ settleReject(new Error(errorMsg));
14586
+ }
14587
+ });
14588
+ const axiosInstance = this.apiClient.getAxiosInstance();
14589
+ axiosInstance.post(
14590
+ this.wsCompletionUrl,
14591
+ {
14592
+ requestId,
14593
+ model,
14594
+ messages,
14595
+ options: {
14596
+ temperature: options.temperature,
14597
+ maxTokens: options.maxTokens,
14598
+ stream: true,
14599
+ tools: options.tools || []
14600
+ }
14601
+ },
14602
+ { signal: options.abortSignal }
14603
+ ).catch((err) => {
14604
+ const msg = err instanceof Error ? err.message : String(err);
14605
+ settleReject(new Error(`HTTP request failed: ${msg}`));
14606
+ });
14607
+ });
14608
+ }
14609
+ /**
14610
+ * Get available models from server (REST call, not streaming).
14611
+ * Delegates to ApiClient -- same as ServerLlmBackend.
14612
+ */
14613
+ async getModelInfo() {
14614
+ try {
14615
+ logger.debug("[WebSocketLlmBackend] Fetching models from /api/models");
14616
+ const response = await this.apiClient.get("/api/models");
14617
+ if (!response || typeof response !== "object" || !Array.isArray(response.models)) {
14618
+ logger.warn("[WebSocketLlmBackend] Invalid API response format, using fallback models");
14619
+ return this.getFallbackModels();
14620
+ }
14621
+ const filteredModels = response.models.filter(
14622
+ (model) => model.type === "text" && model.supportsTools === true
14623
+ );
14624
+ if (filteredModels.length === 0) {
14625
+ logger.warn("[WebSocketLlmBackend] No CLI-compatible models found, using fallback");
14626
+ return this.getFallbackModels();
14627
+ }
14628
+ logger.debug(`[WebSocketLlmBackend] Loaded ${filteredModels.length} models`);
14629
+ return filteredModels;
14630
+ } catch (error) {
14631
+ logger.warn(
14632
+ `[WebSocketLlmBackend] Failed to fetch models: ${error instanceof Error ? error.message : String(error)}`
14633
+ );
14634
+ return this.getFallbackModels();
14635
+ }
14636
+ }
14637
+ getFallbackModels() {
14638
+ return [
14639
+ { id: "claude-sonnet-4-5-20250929", name: "Claude 4.5 Sonnet" },
14640
+ { id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku" },
14641
+ { id: "gpt-4o", name: "GPT-4o" },
14642
+ { id: "gpt-4o-mini", name: "GPT-4o Mini" }
14643
+ ];
14644
+ }
14645
+ };
14646
+
14482
14647
  // src/llm/NotifyingLlmBackend.ts
14483
14648
  var NotifyingLlmBackend = class {
14484
14649
  constructor(inner, backgroundManager) {
@@ -14513,6 +14678,253 @@ Please acknowledge these background agent results and incorporate them into your
14513
14678
  }
14514
14679
  };
14515
14680
 
14681
+ // src/ws/WebSocketConnectionManager.ts
14682
+ var WebSocketConnectionManager = class {
14683
+ constructor(wsUrl, getToken) {
14684
+ this.ws = null;
14685
+ this.heartbeatInterval = null;
14686
+ this.reconnectAttempts = 0;
14687
+ this.maxReconnectDelay = 3e4;
14688
+ this.handlers = /* @__PURE__ */ new Map();
14689
+ this.disconnectHandlers = /* @__PURE__ */ new Set();
14690
+ this.reconnectTimer = null;
14691
+ this.connected = false;
14692
+ this.connecting = false;
14693
+ this.closed = false;
14694
+ this.wsUrl = wsUrl;
14695
+ this.getToken = getToken;
14696
+ }
14697
+ /**
14698
+ * Connect to the WebSocket server.
14699
+ * Resolves when connection is established, rejects on failure.
14700
+ */
14701
+ async connect() {
14702
+ if (this.connected || this.connecting) return;
14703
+ this.connecting = true;
14704
+ const token = await this.getToken();
14705
+ if (!token) {
14706
+ this.connecting = false;
14707
+ throw new Error("No access token available for WebSocket connection");
14708
+ }
14709
+ return new Promise((resolve3, reject) => {
14710
+ logger.debug(`[WS] Connecting to ${this.wsUrl}...`);
14711
+ this.ws = new WebSocket(this.wsUrl, [`access_token.${token}`]);
14712
+ this.ws.onopen = () => {
14713
+ logger.debug("[WS] Connected");
14714
+ this.connected = true;
14715
+ this.connecting = false;
14716
+ this.reconnectAttempts = 0;
14717
+ this.startHeartbeat();
14718
+ resolve3();
14719
+ };
14720
+ this.ws.onmessage = (event) => {
14721
+ try {
14722
+ const data = typeof event.data === "string" ? event.data : event.data.toString();
14723
+ const message = JSON.parse(data);
14724
+ const requestId = message.requestId;
14725
+ if (requestId && this.handlers.has(requestId)) {
14726
+ this.handlers.get(requestId)(message);
14727
+ } else {
14728
+ logger.debug(`[WS] Unhandled message: ${message.action || "unknown"}`);
14729
+ }
14730
+ } catch (err) {
14731
+ logger.debug(`[WS] Failed to parse message: ${err}`);
14732
+ }
14733
+ };
14734
+ this.ws.onclose = () => {
14735
+ logger.debug("[WS] Connection closed");
14736
+ this.cleanup();
14737
+ this.notifyDisconnect();
14738
+ if (!this.closed) {
14739
+ this.scheduleReconnect();
14740
+ }
14741
+ };
14742
+ this.ws.onerror = (err) => {
14743
+ logger.debug(`[WS] Error: ${err}`);
14744
+ if (this.connecting) {
14745
+ this.connecting = false;
14746
+ this.connected = false;
14747
+ reject(new Error("WebSocket connection failed"));
14748
+ }
14749
+ };
14750
+ });
14751
+ }
14752
+ /** Whether the connection is currently established */
14753
+ get isConnected() {
14754
+ return this.connected;
14755
+ }
14756
+ /**
14757
+ * Send a JSON message over the WebSocket connection.
14758
+ */
14759
+ send(data) {
14760
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
14761
+ throw new Error("WebSocket is not connected");
14762
+ }
14763
+ const payload = JSON.stringify(data);
14764
+ const sizeKB = (payload.length / 1024).toFixed(1);
14765
+ logger.debug(`[WS] Sending ${sizeKB} KB (action: ${data.action})`);
14766
+ if (payload.length > 32e3) {
14767
+ logger.warn(`[WS] Payload ${sizeKB} KB exceeds API Gateway 32 KB frame limit \u2014 connection will be closed`);
14768
+ }
14769
+ this.ws.send(payload);
14770
+ }
14771
+ /**
14772
+ * Register a handler for messages matching a specific requestId.
14773
+ */
14774
+ onRequest(requestId, handler) {
14775
+ this.handlers.set(requestId, handler);
14776
+ }
14777
+ /**
14778
+ * Remove a handler for a specific requestId.
14779
+ */
14780
+ offRequest(requestId) {
14781
+ this.handlers.delete(requestId);
14782
+ }
14783
+ /**
14784
+ * Register a handler that fires when the connection drops.
14785
+ */
14786
+ onDisconnect(handler) {
14787
+ this.disconnectHandlers.add(handler);
14788
+ }
14789
+ /**
14790
+ * Remove a disconnect handler.
14791
+ */
14792
+ offDisconnect(handler) {
14793
+ this.disconnectHandlers.delete(handler);
14794
+ }
14795
+ /**
14796
+ * Close the connection and stop all heartbeat/reconnect logic.
14797
+ */
14798
+ disconnect() {
14799
+ this.closed = true;
14800
+ this.cleanup();
14801
+ if (this.ws) {
14802
+ this.ws.close();
14803
+ this.ws = null;
14804
+ }
14805
+ this.handlers.clear();
14806
+ this.disconnectHandlers.clear();
14807
+ }
14808
+ startHeartbeat() {
14809
+ this.stopHeartbeat();
14810
+ this.heartbeatInterval = setInterval(
14811
+ () => {
14812
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
14813
+ this.ws.send(JSON.stringify({ action: "heartbeat" }));
14814
+ logger.debug("[WS] Heartbeat sent");
14815
+ }
14816
+ },
14817
+ 5 * 60 * 1e3
14818
+ );
14819
+ }
14820
+ stopHeartbeat() {
14821
+ if (this.heartbeatInterval) {
14822
+ clearInterval(this.heartbeatInterval);
14823
+ this.heartbeatInterval = null;
14824
+ }
14825
+ }
14826
+ cleanup() {
14827
+ this.connected = false;
14828
+ this.connecting = false;
14829
+ this.stopHeartbeat();
14830
+ if (this.reconnectTimer) {
14831
+ clearTimeout(this.reconnectTimer);
14832
+ this.reconnectTimer = null;
14833
+ }
14834
+ }
14835
+ notifyDisconnect() {
14836
+ for (const handler of this.disconnectHandlers) {
14837
+ try {
14838
+ handler();
14839
+ } catch {
14840
+ }
14841
+ }
14842
+ }
14843
+ scheduleReconnect() {
14844
+ if (this.closed) return;
14845
+ this.reconnectAttempts++;
14846
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts - 1), this.maxReconnectDelay);
14847
+ logger.debug(`[WS] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
14848
+ this.reconnectTimer = setTimeout(async () => {
14849
+ this.reconnectTimer = null;
14850
+ if (this.closed) return;
14851
+ try {
14852
+ await this.connect();
14853
+ } catch {
14854
+ logger.debug("[WS] Reconnection failed");
14855
+ }
14856
+ }, delay);
14857
+ }
14858
+ };
14859
+
14860
+ // src/ws/WebSocketToolExecutor.ts
14861
+ import { v4 as uuidv412 } from "uuid";
14862
+ var WebSocketToolExecutor = class {
14863
+ constructor(wsManager, tokenGetter) {
14864
+ this.wsManager = wsManager;
14865
+ this.tokenGetter = tokenGetter;
14866
+ }
14867
+ /**
14868
+ * Execute a server-side tool via WebSocket.
14869
+ * Returns the tool result or throws on error.
14870
+ */
14871
+ async execute(toolName, input, abortSignal) {
14872
+ if (!this.wsManager.isConnected) {
14873
+ throw new Error("WebSocket is not connected");
14874
+ }
14875
+ const token = await this.tokenGetter();
14876
+ if (!token) {
14877
+ throw new Error("No access token available");
14878
+ }
14879
+ const requestId = uuidv412();
14880
+ return new Promise((resolve3, reject) => {
14881
+ let settled = false;
14882
+ const settle = (action) => {
14883
+ if (settled) return;
14884
+ settled = true;
14885
+ this.wsManager.offRequest(requestId);
14886
+ this.wsManager.offDisconnect(onDisconnect);
14887
+ action();
14888
+ };
14889
+ const settleResolve = (result) => settle(() => resolve3(result));
14890
+ const settleReject = (err) => settle(() => reject(err));
14891
+ const onDisconnect = () => {
14892
+ settleReject(new Error("WebSocket connection lost during tool execution"));
14893
+ };
14894
+ this.wsManager.onDisconnect(onDisconnect);
14895
+ if (abortSignal) {
14896
+ if (abortSignal.aborted) {
14897
+ settleReject(new Error("Tool execution aborted"));
14898
+ return;
14899
+ }
14900
+ abortSignal.addEventListener("abort", () => settleReject(new Error("Tool execution aborted")), {
14901
+ once: true
14902
+ });
14903
+ }
14904
+ this.wsManager.onRequest(requestId, (message) => {
14905
+ if (message.action === "cli_tool_response") {
14906
+ settleResolve({
14907
+ success: message.success,
14908
+ content: message.content,
14909
+ error: message.error
14910
+ });
14911
+ }
14912
+ });
14913
+ try {
14914
+ this.wsManager.send({
14915
+ action: "cli_tool_request",
14916
+ accessToken: token,
14917
+ requestId,
14918
+ toolName,
14919
+ input
14920
+ });
14921
+ } catch (err) {
14922
+ settleReject(err instanceof Error ? err : new Error(String(err)));
14923
+ }
14924
+ });
14925
+ }
14926
+ };
14927
+
14516
14928
  // src/auth/ApiClient.ts
14517
14929
  import axios11 from "axios";
14518
14930
  var ApiClient = class {
@@ -14650,7 +15062,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
14650
15062
  // package.json
14651
15063
  var package_default = {
14652
15064
  name: "@bike4mind/cli",
14653
- version: "0.2.30-feat-cli-scrollable-command-autocomplete.19203+b74387251",
15065
+ version: "0.2.30-feat-cli-websocket-streaming.19209+64d4459aa",
14654
15066
  type: "module",
14655
15067
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
14656
15068
  license: "UNLICENSED",
@@ -14761,10 +15173,10 @@ var package_default = {
14761
15173
  },
14762
15174
  devDependencies: {
14763
15175
  "@bike4mind/agents": "0.1.0",
14764
- "@bike4mind/common": "2.51.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
14765
- "@bike4mind/mcp": "1.30.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
14766
- "@bike4mind/services": "2.49.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
14767
- "@bike4mind/utils": "2.6.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
15176
+ "@bike4mind/common": "2.51.1-feat-cli-websocket-streaming.19209+64d4459aa",
15177
+ "@bike4mind/mcp": "1.30.1-feat-cli-websocket-streaming.19209+64d4459aa",
15178
+ "@bike4mind/services": "2.49.1-feat-cli-websocket-streaming.19209+64d4459aa",
15179
+ "@bike4mind/utils": "2.6.1-feat-cli-websocket-streaming.19209+64d4459aa",
14768
15180
  "@types/better-sqlite3": "^7.6.13",
14769
15181
  "@types/diff": "^5.0.9",
14770
15182
  "@types/jsonwebtoken": "^9.0.4",
@@ -14785,7 +15197,7 @@ var package_default = {
14785
15197
  optionalDependencies: {
14786
15198
  "@vscode/ripgrep": "^1.17.0"
14787
15199
  },
14788
- gitHead: "b74387251e07e79e94b8720e6d4b1c8e16bde324"
15200
+ gitHead: "64d4459aaf9c9ba124dac6513d470113295bd1d1"
14789
15201
  };
14790
15202
 
14791
15203
  // src/config/constants.ts
@@ -16564,7 +16976,8 @@ function CliApp() {
16564
16976
  agentStore: null,
16565
16977
  abortController: null,
16566
16978
  contextContent: "",
16567
- backgroundManager: null
16979
+ backgroundManager: null,
16980
+ wsManager: null
16568
16981
  });
16569
16982
  const [isInitialized, setIsInitialized] = useState10(false);
16570
16983
  const [initError, setInitError] = useState10(null);
@@ -16592,6 +17005,10 @@ function CliApp() {
16592
17005
  })
16593
17006
  );
16594
17007
  }
17008
+ if (state.wsManager) {
17009
+ state.wsManager.disconnect();
17010
+ setWebSocketToolExecutor(null);
17011
+ }
16595
17012
  if (state.agent) {
16596
17013
  state.agent.removeAllListeners();
16597
17014
  }
@@ -16610,7 +17027,7 @@ function CliApp() {
16610
17027
  setTimeout(() => {
16611
17028
  process.exit(0);
16612
17029
  }, 100);
16613
- }, [state.session, state.sessionStore, state.mcpManager, state.agent, state.imageStore]);
17030
+ }, [state.session, state.sessionStore, state.mcpManager, state.agent, state.imageStore, state.wsManager]);
16614
17031
  useInput9((input, key) => {
16615
17032
  if (key.escape) {
16616
17033
  if (state.abortController) {
@@ -16680,7 +17097,7 @@ function CliApp() {
16680
17097
  if (!isAuthenticated) {
16681
17098
  console.log("\u2139\uFE0F AI features disabled. Available commands: /login, /help, /config\n");
16682
17099
  const minimalSession = {
16683
- id: uuidv411(),
17100
+ id: uuidv413(),
16684
17101
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
16685
17102
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
16686
17103
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -16708,10 +17125,45 @@ function CliApp() {
16708
17125
  console.log(`\u{1F30D} API Environment: ${envName} (${apiBaseURL})`);
16709
17126
  }
16710
17127
  const apiClient = new ApiClient(apiBaseURL, state.configStore);
16711
- const llm = new ServerLlmBackend({
16712
- apiClient,
16713
- model: config.defaultModel
16714
- });
17128
+ const tokenGetter = async () => {
17129
+ const tokens = await state.configStore.getAuthTokens();
17130
+ return tokens?.accessToken ?? null;
17131
+ };
17132
+ let wsManager = null;
17133
+ let llm;
17134
+ try {
17135
+ const serverConfig = await apiClient.get(
17136
+ "/api/settings/serverConfig"
17137
+ );
17138
+ const wsUrl = serverConfig?.websocketUrl;
17139
+ const wsCompletionUrl = serverConfig?.wsCompletionUrl;
17140
+ if (wsUrl && wsCompletionUrl) {
17141
+ wsManager = new WebSocketConnectionManager(wsUrl, tokenGetter);
17142
+ await wsManager.connect();
17143
+ const wsToolExecutor2 = new WebSocketToolExecutor(wsManager, tokenGetter);
17144
+ setWebSocketToolExecutor(wsToolExecutor2);
17145
+ llm = new WebSocketLlmBackend({
17146
+ wsManager,
17147
+ apiClient,
17148
+ model: config.defaultModel,
17149
+ tokenGetter,
17150
+ wsCompletionUrl
17151
+ });
17152
+ logger.debug("\u{1F50C} Using WebSocket transport (bypasses CloudFront timeout)");
17153
+ } else {
17154
+ throw new Error("No websocketUrl or wsCompletionUrl in server config");
17155
+ }
17156
+ } catch (wsError) {
17157
+ logger.debug(
17158
+ `[WS] WebSocket unavailable, using SSE fallback: ${wsError instanceof Error ? wsError.message : String(wsError)}`
17159
+ );
17160
+ wsManager = null;
17161
+ setWebSocketToolExecutor(null);
17162
+ llm = new ServerLlmBackend({
17163
+ apiClient,
17164
+ model: config.defaultModel
17165
+ });
17166
+ }
16715
17167
  const models = await llm.getModelInfo();
16716
17168
  if (models.length === 0) {
16717
17169
  throw new Error("No models available from server.");
@@ -16724,7 +17176,7 @@ function CliApp() {
16724
17176
  }
16725
17177
  llm.currentModel = modelInfo.id;
16726
17178
  const newSession = {
16727
- id: uuidv411(),
17179
+ id: uuidv413(),
16728
17180
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
16729
17181
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
16730
17182
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -16938,8 +17390,10 @@ function CliApp() {
16938
17390
  // Store agent store for agent management commands
16939
17391
  contextContent: contextResult.mergedContent,
16940
17392
  // Store raw context for compact instructions
16941
- backgroundManager
17393
+ backgroundManager,
16942
17394
  // Store for grouped notification turn tracking
17395
+ wsManager
17396
+ // WebSocket connection manager (null if using SSE fallback)
16943
17397
  }));
16944
17398
  setStoreSession(newSession);
16945
17399
  const bannerLines = [
@@ -17034,13 +17488,13 @@ function CliApp() {
17034
17488
  messageContent = multimodalMessage.content;
17035
17489
  }
17036
17490
  const userMessage = {
17037
- id: uuidv411(),
17491
+ id: uuidv413(),
17038
17492
  role: "user",
17039
17493
  content: userMessageContent,
17040
17494
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
17041
17495
  };
17042
17496
  const pendingAssistantMessage = {
17043
- id: uuidv411(),
17497
+ id: uuidv413(),
17044
17498
  role: "assistant",
17045
17499
  content: "...",
17046
17500
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -17253,13 +17707,13 @@ function CliApp() {
17253
17707
  userMessageContent = message;
17254
17708
  }
17255
17709
  const userMessage = {
17256
- id: uuidv411(),
17710
+ id: uuidv413(),
17257
17711
  role: "user",
17258
17712
  content: userMessageContent,
17259
17713
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
17260
17714
  };
17261
17715
  const pendingAssistantMessage = {
17262
- id: uuidv411(),
17716
+ id: uuidv413(),
17263
17717
  role: "assistant",
17264
17718
  content: "...",
17265
17719
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -17339,7 +17793,7 @@ function CliApp() {
17339
17793
  const currentSession = useCliStore.getState().session;
17340
17794
  if (currentSession) {
17341
17795
  const cancelMessage = {
17342
- id: uuidv411(),
17796
+ id: uuidv413(),
17343
17797
  role: "assistant",
17344
17798
  content: "\u26A0\uFE0F Operation cancelled by user",
17345
17799
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -17384,7 +17838,7 @@ function CliApp() {
17384
17838
  setState((prev) => ({ ...prev, abortController }));
17385
17839
  try {
17386
17840
  const pendingAssistantMessage = {
17387
- id: uuidv411(),
17841
+ id: uuidv413(),
17388
17842
  role: "assistant",
17389
17843
  content: "...",
17390
17844
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -17412,7 +17866,7 @@ function CliApp() {
17412
17866
  const currentSession = useCliStore.getState().session;
17413
17867
  if (!currentSession) return;
17414
17868
  const continuationMessage = {
17415
- id: uuidv411(),
17869
+ id: uuidv413(),
17416
17870
  role: "assistant",
17417
17871
  content: "---\n\n**Background Agent Results:**\n\n" + result.finalAnswer,
17418
17872
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -17473,13 +17927,13 @@ function CliApp() {
17473
17927
  isError = true;
17474
17928
  }
17475
17929
  const userMessage = {
17476
- id: uuidv411(),
17930
+ id: uuidv413(),
17477
17931
  role: "user",
17478
17932
  content: `$ ${command}`,
17479
17933
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
17480
17934
  };
17481
17935
  const assistantMessage = {
17482
- id: uuidv411(),
17936
+ id: uuidv413(),
17483
17937
  role: "assistant",
17484
17938
  content: isError ? `\u274C Error:
17485
17939
  ${output}` : output.trim() || "(no output)",
@@ -17948,7 +18402,7 @@ Keyboard Shortcuts:
17948
18402
  console.clear();
17949
18403
  const model = state.session?.model || state.config?.defaultModel || "claude-sonnet";
17950
18404
  const newSession = {
17951
- id: uuidv411(),
18405
+ id: uuidv413(),
17952
18406
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
17953
18407
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
17954
18408
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -18453,9 +18907,9 @@ No usage data available for the last ${USAGE_DAYS} days.`);
18453
18907
  return { ...prev, config: updatedConfig };
18454
18908
  });
18455
18909
  if (modelChanged && state.agent) {
18456
- const llm = state.agent.context.llm;
18457
- if (llm) {
18458
- llm.currentModel = updatedConfig.defaultModel;
18910
+ const backend = state.agent.context.llm;
18911
+ if (backend) {
18912
+ backend.currentModel = updatedConfig.defaultModel;
18459
18913
  }
18460
18914
  }
18461
18915
  };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-C3K7SH2V.js";
4
+ } from "./chunk-55ZDRTGQ.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/llmMarkdownGenerator.js
7
7
  var DEFAULT_OPTIONS = {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-C3K7SH2V.js";
4
+ } from "./chunk-55ZDRTGQ.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/markdownGenerator.js
7
7
  var DEFAULT_OPTIONS = {
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  findMostSimilarMemento,
4
4
  getRelevantMementos
5
- } from "./chunk-65DLNQY2.js";
6
- import "./chunk-5HA4JEOV.js";
7
- import "./chunk-C3K7SH2V.js";
5
+ } from "./chunk-NRQSEF3E.js";
6
+ import "./chunk-PIJR5GZP.js";
7
+ import "./chunk-55ZDRTGQ.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  findMostSimilarMemento,
@@ -41,6 +41,12 @@ import {
41
41
  ChatModels,
42
42
  CitableSourceSchema,
43
43
  ClaudeArtifactMimeTypes,
44
+ CliCompletionChunkAction,
45
+ CliCompletionDoneAction,
46
+ CliCompletionErrorAction,
47
+ CliCompletionRequestAction,
48
+ CliToolRequestAction,
49
+ CliToolResponseAction,
44
50
  CollectionType,
45
51
  CompletionApiUsageTransaction,
46
52
  CompletionRequestSchema,
@@ -419,7 +425,7 @@ import {
419
425
  validateReactArtifactV2,
420
426
  validateSvgArtifactV2,
421
427
  wikiMarkupToAdf
422
- } from "./chunk-C3K7SH2V.js";
428
+ } from "./chunk-55ZDRTGQ.js";
423
429
  export {
424
430
  ALL_IMAGE_MODELS,
425
431
  ALL_IMAGE_SIZES,
@@ -463,6 +469,12 @@ export {
463
469
  ChatModels,
464
470
  CitableSourceSchema,
465
471
  ClaudeArtifactMimeTypes,
472
+ CliCompletionChunkAction,
473
+ CliCompletionDoneAction,
474
+ CliCompletionErrorAction,
475
+ CliCompletionRequestAction,
476
+ CliToolRequestAction,
477
+ CliToolResponseAction,
466
478
  CollectionType,
467
479
  CompletionApiUsageTransaction,
468
480
  CompletionRequestSchema,
@@ -134,12 +134,12 @@ import {
134
134
  validateMermaidSyntax,
135
135
  warmUpSettingsCache,
136
136
  withRetry
137
- } from "./chunk-5HA4JEOV.js";
137
+ } from "./chunk-PIJR5GZP.js";
138
138
  import {
139
139
  buildRateLimitLogEntry,
140
140
  isNearLimit,
141
141
  parseRateLimitHeaders
142
- } from "./chunk-C3K7SH2V.js";
142
+ } from "./chunk-55ZDRTGQ.js";
143
143
  import {
144
144
  Logger,
145
145
  NotificationDeduplicator,
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  SubtractCreditsSchema,
4
4
  subtractCredits
5
- } from "./chunk-BYLWQZ5S.js";
6
- import "./chunk-5HA4JEOV.js";
7
- import "./chunk-C3K7SH2V.js";
5
+ } from "./chunk-EAFOBAEJ.js";
6
+ import "./chunk-PIJR5GZP.js";
7
+ import "./chunk-55ZDRTGQ.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  SubtractCreditsSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.30-feat-cli-scrollable-command-autocomplete.19203+b74387251",
3
+ "version": "0.2.30-feat-cli-websocket-streaming.19209+64d4459aa",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -111,10 +111,10 @@
111
111
  },
112
112
  "devDependencies": {
113
113
  "@bike4mind/agents": "0.1.0",
114
- "@bike4mind/common": "2.51.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
115
- "@bike4mind/mcp": "1.30.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
116
- "@bike4mind/services": "2.49.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
117
- "@bike4mind/utils": "2.6.1-feat-cli-scrollable-command-autocomplete.19203+b74387251",
114
+ "@bike4mind/common": "2.51.1-feat-cli-websocket-streaming.19209+64d4459aa",
115
+ "@bike4mind/mcp": "1.30.1-feat-cli-websocket-streaming.19209+64d4459aa",
116
+ "@bike4mind/services": "2.49.1-feat-cli-websocket-streaming.19209+64d4459aa",
117
+ "@bike4mind/utils": "2.6.1-feat-cli-websocket-streaming.19209+64d4459aa",
118
118
  "@types/better-sqlite3": "^7.6.13",
119
119
  "@types/diff": "^5.0.9",
120
120
  "@types/jsonwebtoken": "^9.0.4",
@@ -135,5 +135,5 @@
135
135
  "optionalDependencies": {
136
136
  "@vscode/ripgrep": "^1.17.0"
137
137
  },
138
- "gitHead": "b74387251e07e79e94b8720e6d4b1c8e16bde324"
138
+ "gitHead": "64d4459aaf9c9ba124dac6513d470113295bd1d1"
139
139
  }