@bike4mind/cli 0.2.10-slack-metrics-admin-dashboard.17277 → 0.2.11-feat-api-key-rate-limiting.17313

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-6EQ62KRQ.js";
4
+ } from "./chunk-S42YW3EI.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
@@ -2,15 +2,16 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-23GLLYOT.js";
5
+ } from "./chunk-BBQI2EAJ.js";
6
6
  import {
7
+ CompletionApiUsageTransaction,
7
8
  GenericCreditDeductTransaction,
8
9
  ImageEditUsageTransaction,
9
10
  ImageGenerationUsageTransaction,
10
11
  RealtimeVoiceUsageTransaction,
11
12
  TextGenerationUsageTransaction,
12
13
  TransferCreditTransaction
13
- } from "./chunk-6EQ62KRQ.js";
14
+ } from "./chunk-S42YW3EI.js";
14
15
 
15
16
  // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
16
17
  import { z } from "zod";
@@ -20,6 +21,7 @@ var SubtractCreditsSchema = z.discriminatedUnion("type", [
20
21
  ImageGenerationUsageTransaction.omit({ createdAt: true, updatedAt: true }),
21
22
  RealtimeVoiceUsageTransaction.omit({ createdAt: true, updatedAt: true }),
22
23
  ImageEditUsageTransaction.omit({ createdAt: true, updatedAt: true }),
24
+ CompletionApiUsageTransaction.omit({ createdAt: true, updatedAt: true }),
23
25
  TransferCreditTransaction.omit({ createdAt: true, updatedAt: true })
24
26
  ]);
25
27
  async function subtractCredits(parameters, { db, creditHolderMethods, skipBalanceUpdate, currentCreditHolder }) {
@@ -63,6 +65,20 @@ async function subtractCredits(parameters, { db, creditHolderMethods, skipBalanc
63
65
  inputTokens: params.inputTokens,
64
66
  outputTokens: params.outputTokens
65
67
  });
68
+ } else if (type === "completion_api_usage") {
69
+ await db.creditTransactions.createTransaction("completion_api_usage", {
70
+ ownerId,
71
+ ownerType,
72
+ credits: -Math.abs(credits),
73
+ // Negative for usage
74
+ description: description || "Completion API usage",
75
+ metadata,
76
+ model: params.model,
77
+ apiKeyId: params.apiKeyId,
78
+ // Optional - present for API key auth, undefined for JWT
79
+ inputTokens: params.inputTokens,
80
+ outputTokens: params.outputTokens
81
+ });
66
82
  } else if (type === "image_generation_usage") {
67
83
  await db.creditTransactions.createTransaction("image_generation_usage", {
68
84
  ownerId,
@@ -16,7 +16,7 @@ import {
16
16
  dayjsConfig_default,
17
17
  extractSnippetMeta,
18
18
  settingsMap
19
- } from "./chunk-6EQ62KRQ.js";
19
+ } from "./chunk-S42YW3EI.js";
20
20
 
21
21
  // ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
22
22
  import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
@@ -672,6 +672,14 @@ var RealtimeVoiceUsageTransaction = BaseCreditTransaction.extend({
672
672
  model: z7.string(),
673
673
  sessionId: z7.string()
674
674
  });
675
+ var CompletionApiUsageTransaction = BaseCreditTransaction.extend({
676
+ type: z7.literal("completion_api_usage"),
677
+ model: z7.string(),
678
+ apiKeyId: z7.string().optional(),
679
+ // Optional - present for API key auth, undefined for JWT
680
+ inputTokens: z7.number(),
681
+ outputTokens: z7.number()
682
+ });
675
683
  var TransferCreditTransaction = BaseCreditTransaction.extend({
676
684
  type: z7.literal("transfer_credit"),
677
685
  recipientId: z7.string(),
@@ -686,6 +694,7 @@ var CreditTransaction = z7.discriminatedUnion("type", [
686
694
  ImageGenerationUsageTransaction,
687
695
  ImageEditUsageTransaction,
688
696
  RealtimeVoiceUsageTransaction,
697
+ CompletionApiUsageTransaction,
689
698
  TransferCreditTransaction,
690
699
  ReceivedCreditTransaction
691
700
  ]);
@@ -700,6 +709,7 @@ var CREDIT_DEDUCT_TRANSACTION_TYPES = [
700
709
  "image_generation_usage",
701
710
  "image_edit_usage",
702
711
  "realtime_voice_usage",
712
+ "completion_api_usage",
703
713
  "transfer_credit",
704
714
  "generic_deduct"
705
715
  ];
@@ -4047,13 +4057,6 @@ var SlackEvents;
4047
4057
  SlackEvents2["SLACK_COMMAND_COMPLETED"] = "Slack Command Completed";
4048
4058
  SlackEvents2["SLACK_MCP_TOOL_INVOKED"] = "Slack MCP Tool Invoked";
4049
4059
  SlackEvents2["SLACK_BULK_OPERATION"] = "Slack Bulk Operation Executed";
4050
- SlackEvents2["COMMAND_PROCESSED"] = "Slack Command Processed";
4051
- SlackEvents2["COMMAND_FAILED"] = "Slack Command Failed";
4052
- SlackEvents2["APP_CREATED"] = "Slack App Created";
4053
- SlackEvents2["WORKSPACE_DEACTIVATED"] = "Slack Workspace Deactivated";
4054
- SlackEvents2["CHANNEL_EXPORT_STARTED"] = "Slack Channel Export Started";
4055
- SlackEvents2["CHANNEL_EXPORT_COMPLETED"] = "Slack Channel Export Completed";
4056
- SlackEvents2["CHANNEL_EXPORT_FAILED"] = "Slack Channel Export Failed";
4057
4060
  })(SlackEvents || (SlackEvents = {}));
4058
4061
 
4059
4062
  // ../../b4m-core/packages/common/dist/src/schemas/team.js
@@ -6005,6 +6008,7 @@ export {
6005
6008
  ImageGenerationUsageTransaction,
6006
6009
  ImageEditUsageTransaction,
6007
6010
  RealtimeVoiceUsageTransaction,
6011
+ CompletionApiUsageTransaction,
6008
6012
  TransferCreditTransaction,
6009
6013
  CreditTransaction,
6010
6014
  CREDIT_ADD_TRANSACTION_TYPES,
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-23GLLYOT.js";
9
+ } from "./chunk-BBQI2EAJ.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-6EQ62KRQ.js";
14
+ } from "./chunk-S42YW3EI.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-23GLLYOT.js";
10
+ } from "./chunk-BBQI2EAJ.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-6EQ62KRQ.js";
14
+ } from "./chunk-S42YW3EI.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-E2VXQGEM.js";
6
- import "./chunk-23GLLYOT.js";
5
+ } from "./chunk-Y5NGQESV.js";
6
+ import "./chunk-BBQI2EAJ.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
- import "./chunk-6EQ62KRQ.js";
8
+ import "./chunk-S42YW3EI.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  createFabFile,
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-TFXE7AI6.js";
8
- import "./chunk-VOOM6DLV.js";
9
- import "./chunk-E2VXQGEM.js";
7
+ } from "./chunk-X5H7N2CY.js";
8
+ import "./chunk-7TW7K6CW.js";
9
+ import "./chunk-Y5NGQESV.js";
10
10
  import {
11
11
  BFLImageService,
12
12
  BaseStorage,
@@ -15,7 +15,7 @@ import {
15
15
  OpenAIBackend,
16
16
  OpenAIImageService,
17
17
  XAIImageService
18
- } from "./chunk-23GLLYOT.js";
18
+ } from "./chunk-BBQI2EAJ.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-AMDXHL6S.js";
@@ -73,7 +73,7 @@ import {
73
73
  XAI_IMAGE_MODELS,
74
74
  b4mLLMTools,
75
75
  getMcpProviderMetadata
76
- } from "./chunk-6EQ62KRQ.js";
76
+ } from "./chunk-S42YW3EI.js";
77
77
  import {
78
78
  __require
79
79
  } from "./chunk-PDX44BCA.js";
@@ -82,7 +82,7 @@ import {
82
82
  import React17, { useState as useState8, useEffect as useEffect3, useCallback, useRef as useRef2 } from "react";
83
83
  import { render, Box as Box16, Text as Text16, useApp, useInput as useInput6 } from "ink";
84
84
  import { execSync } from "child_process";
85
- import { v4 as uuidv49 } from "uuid";
85
+ import { v4 as uuidv410 } from "uuid";
86
86
 
87
87
  // src/components/App.tsx
88
88
  import React11, { useState as useState4 } from "react";
@@ -1523,7 +1523,7 @@ ${errorBlock}`;
1523
1523
  onSave: onSaveConfig,
1524
1524
  onClose: () => setShowConfigEditor(false)
1525
1525
  }
1526
- )) : permissionPrompt ? /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(
1526
+ )) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Static, { items: messages }, (message) => /* @__PURE__ */ React11.createElement(Box10, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message }))), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, pendingMessages.map((message) => /* @__PURE__ */ React11.createElement(Box10, { key: message.id, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message })))), permissionPrompt && /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(
1527
1527
  PermissionPrompt,
1528
1528
  {
1529
1529
  toolName: permissionPrompt.toolName,
@@ -1532,7 +1532,7 @@ ${errorBlock}`;
1532
1532
  canBeTrusted: permissionPrompt.canBeTrusted,
1533
1533
  onResponse: onPermissionResponse
1534
1534
  }
1535
- )) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Static, { items: messages }, (message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `${message.timestamp}-${message.role}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message }))), /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column" }, pendingMessages.map((message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: `pending-${message.timestamp}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React11.createElement(MessageItem, { message })))), /* @__PURE__ */ React11.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React11.createElement(Box10, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React11.createElement(Box10, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React11.createElement(
1535
+ )), !permissionPrompt && /* @__PURE__ */ React11.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React11.createElement(Box10, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React11.createElement(Box10, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React11.createElement(
1536
1536
  InputPrompt,
1537
1537
  {
1538
1538
  onSubmit: handleSubmit,
@@ -1932,6 +1932,7 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
1932
1932
  import { promises as fs3 } from "fs";
1933
1933
  import path3 from "path";
1934
1934
  import { homedir } from "os";
1935
+ import { v4 as uuidv4 } from "uuid";
1935
1936
  var SessionStore = class {
1936
1937
  constructor(basePath) {
1937
1938
  this.basePath = basePath || path3.join(homedir(), ".bike4mind", "sessions");
@@ -1967,7 +1968,14 @@ var SessionStore = class {
1967
1968
  const filePath = path3.join(this.basePath, `${id}.json`);
1968
1969
  try {
1969
1970
  const data = await fs3.readFile(filePath, "utf-8");
1970
- return JSON.parse(data);
1971
+ const session = JSON.parse(data);
1972
+ session.messages = session.messages.map((msg) => {
1973
+ if (!msg.id) {
1974
+ return { ...msg, id: uuidv4() };
1975
+ }
1976
+ return msg;
1977
+ });
1978
+ return session;
1971
1979
  } catch (error) {
1972
1980
  if (error.code === "ENOENT") {
1973
1981
  return null;
@@ -1996,7 +2004,14 @@ var SessionStore = class {
1996
2004
  jsonFiles.map(async (file) => {
1997
2005
  const filePath = path3.join(this.basePath, file);
1998
2006
  const data = await fs3.readFile(filePath, "utf-8");
1999
- return JSON.parse(data);
2007
+ const session = JSON.parse(data);
2008
+ session.messages = session.messages.map((msg) => {
2009
+ if (!msg.id) {
2010
+ return { ...msg, id: uuidv4() };
2011
+ }
2012
+ return msg;
2013
+ });
2014
+ return session;
2000
2015
  })
2001
2016
  );
2002
2017
  return sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
@@ -2050,7 +2065,7 @@ var SessionStore = class {
2050
2065
  import { promises as fs4, existsSync as existsSync3 } from "fs";
2051
2066
  import path4 from "path";
2052
2067
  import { homedir as homedir2 } from "os";
2053
- import { v4 as uuidv4 } from "uuid";
2068
+ import { v4 as uuidv42 } from "uuid";
2054
2069
  import { z } from "zod";
2055
2070
  var AuthTokensSchema = z.object({
2056
2071
  accessToken: z.string(),
@@ -2144,7 +2159,7 @@ var ProjectLocalConfigSchema = z.object({
2144
2159
  });
2145
2160
  var DEFAULT_CONFIG = {
2146
2161
  version: "0.1.0",
2147
- userId: uuidv4(),
2162
+ userId: uuidv42(),
2148
2163
  defaultModel: "claude-sonnet-4-5-20250929",
2149
2164
  toolApiKeys: {
2150
2165
  openweather: void 0,
@@ -2426,7 +2441,7 @@ var ConfigStore = class {
2426
2441
  * Reset configuration to defaults
2427
2442
  */
2428
2443
  async reset() {
2429
- this.config = { ...DEFAULT_CONFIG, userId: uuidv4() };
2444
+ this.config = { ...DEFAULT_CONFIG, userId: uuidv42() };
2430
2445
  await this.save();
2431
2446
  return this.config;
2432
2447
  }
@@ -4336,7 +4351,7 @@ var listFabFilesSchema = z86.object({
4336
4351
 
4337
4352
  // ../../b4m-core/packages/services/dist/src/fabFileService/update.js
4338
4353
  import mime from "mime-types";
4339
- import { v4 as uuidv42 } from "uuid";
4354
+ import { v4 as uuidv43 } from "uuid";
4340
4355
  import { z as z87 } from "zod";
4341
4356
  var updateFabFileSchema = z87.object({
4342
4357
  id: z87.string(),
@@ -4457,7 +4472,7 @@ var editFabFileSchema = z98.object({
4457
4472
 
4458
4473
  // ../../b4m-core/packages/services/dist/src/fabFileService/applyEdit.js
4459
4474
  import mime2 from "mime-types";
4460
- import { v4 as uuidv43 } from "uuid";
4475
+ import { v4 as uuidv44 } from "uuid";
4461
4476
  import { z as z99 } from "zod";
4462
4477
  var applyEditSchema = z99.object({
4463
4478
  id: z99.string(),
@@ -5285,7 +5300,7 @@ import { toFile } from "openai/uploads";
5285
5300
  import { Readable } from "stream";
5286
5301
  import { TranscribeClient, StartTranscriptionJobCommand, GetTranscriptionJobCommand, LanguageCode, MediaFormat } from "@aws-sdk/client-transcribe";
5287
5302
  import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand } from "@aws-sdk/client-s3";
5288
- import { v4 as uuidv44 } from "uuid";
5303
+ import { v4 as uuidv45 } from "uuid";
5289
5304
 
5290
5305
  // ../../b4m-core/packages/services/dist/src/emailIngestionService/processIngestedEmail.js
5291
5306
  import { randomUUID as randomUUID5 } from "crypto";
@@ -5446,7 +5461,7 @@ var weatherTool = {
5446
5461
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/imageGeneration/index.js
5447
5462
  import axios6 from "axios";
5448
5463
  import { fileTypeFromBuffer as fileTypeFromBuffer2 } from "file-type";
5449
- import { v4 as uuidv45 } from "uuid";
5464
+ import { v4 as uuidv46 } from "uuid";
5450
5465
  async function downloadImage(url) {
5451
5466
  if (url.startsWith("data:image/")) {
5452
5467
  const base64Data = url.split(",")[1];
@@ -5460,7 +5475,7 @@ async function processAndStoreImages(images, context) {
5460
5475
  return Promise.all(images.map(async (image) => {
5461
5476
  const buffer = await downloadImage(image);
5462
5477
  const fileType = await fileTypeFromBuffer2(buffer);
5463
- const filename = `${uuidv45()}.${fileType?.ext}`;
5478
+ const filename = `${uuidv46()}.${fileType?.ext}`;
5464
5479
  const path16 = await context.imageGenerateStorage.upload(buffer, filename, {});
5465
5480
  return path16;
5466
5481
  }));
@@ -6629,7 +6644,7 @@ Return only the edited content without any markdown code blocks or explanations.
6629
6644
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/imageEdit/index.js
6630
6645
  import axios7 from "axios";
6631
6646
  import { fileTypeFromBuffer as fileTypeFromBuffer3 } from "file-type";
6632
- import { v4 as uuidv46 } from "uuid";
6647
+ import { v4 as uuidv47 } from "uuid";
6633
6648
  async function downloadImage2(url) {
6634
6649
  if (url.startsWith("data:image/")) {
6635
6650
  const base64Data = url.split(",")[1];
@@ -6673,7 +6688,7 @@ async function getImageFromFileId(fileId, context) {
6673
6688
  async function processAndStoreImage(imageUrl, context) {
6674
6689
  const buffer = await downloadImage2(imageUrl);
6675
6690
  const fileType = await fileTypeFromBuffer3(buffer);
6676
- const filename = `${uuidv46()}.${fileType?.ext}`;
6691
+ const filename = `${uuidv47()}.${fileType?.ext}`;
6677
6692
  const path16 = await context.imageGenerateStorage.upload(buffer, filename, {});
6678
6693
  return path16;
6679
6694
  }
@@ -8579,7 +8594,8 @@ var fileReadTool = {
8579
8594
  return content;
8580
8595
  } catch (error) {
8581
8596
  context.logger.error("\u274C FileRead: Failed", error);
8582
- throw error;
8597
+ const errorMessage = error instanceof Error ? error.message : String(error);
8598
+ return `Error reading file: ${errorMessage}`;
8583
8599
  }
8584
8600
  },
8585
8601
  toolSchema: {
@@ -9649,7 +9665,7 @@ var QuestStartBodySchema = z139.object({
9649
9665
  // ../../b4m-core/packages/services/dist/src/llm/ImageGeneration.js
9650
9666
  import axios8 from "axios";
9651
9667
  import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
9652
- import { v4 as uuidv47 } from "uuid";
9668
+ import { v4 as uuidv48 } from "uuid";
9653
9669
  import { z as z140 } from "zod";
9654
9670
  import { fromZodError as fromZodError2 } from "zod-validation-error";
9655
9671
  var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
@@ -9670,7 +9686,7 @@ var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
9670
9686
  // ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
9671
9687
  import axios9 from "axios";
9672
9688
  import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
9673
- import { v4 as uuidv48 } from "uuid";
9689
+ import { v4 as uuidv49 } from "uuid";
9674
9690
  import { z as z141 } from "zod";
9675
9691
  import { fromZodError as fromZodError3 } from "zod-validation-error";
9676
9692
  var ImageEditBodySchema = OpenAIImageGenerationInput.extend({
@@ -10224,7 +10240,31 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
10224
10240
  }
10225
10241
  };
10226
10242
  }
10227
- function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient) {
10243
+ var TOOL_NAME_MAPPING = {
10244
+ // Claude Code -> B4M
10245
+ read: "file_read",
10246
+ write: "create_file",
10247
+ edit: "edit_file",
10248
+ delete: "delete_file",
10249
+ glob: "glob_files",
10250
+ grep: "grep_search",
10251
+ bash: "bash_execute",
10252
+ // B4M -> Claude Code (reverse mapping)
10253
+ file_read: "read",
10254
+ create_file: "write",
10255
+ edit_file: "edit",
10256
+ delete_file: "delete",
10257
+ glob_files: "glob",
10258
+ grep_search: "grep",
10259
+ bash_execute: "bash"
10260
+ };
10261
+ function normalizeToolName(toolName) {
10262
+ if (toolName.includes("_")) {
10263
+ return toolName;
10264
+ }
10265
+ return TOOL_NAME_MAPPING[toolName] || toolName;
10266
+ }
10267
+ function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient, toolFilter) {
10228
10268
  const logger2 = new CliLogger();
10229
10269
  const storage = new NoOpStorage();
10230
10270
  const user = {
@@ -10294,9 +10334,24 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
10294
10334
  toolConfig,
10295
10335
  model
10296
10336
  );
10297
- const tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
10337
+ let tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
10298
10338
  ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient)
10299
10339
  );
10340
+ if (toolFilter) {
10341
+ const { allowedTools, deniedTools } = toolFilter;
10342
+ const normalizedAllowed = allowedTools?.map(normalizeToolName);
10343
+ const normalizedDenied = deniedTools?.map(normalizeToolName);
10344
+ tools2 = tools2.filter((tool) => {
10345
+ const toolName = tool.toolSchema.name;
10346
+ if (normalizedDenied && normalizedDenied.includes(toolName)) {
10347
+ return false;
10348
+ }
10349
+ if (normalizedAllowed && normalizedAllowed.length > 0) {
10350
+ return normalizedAllowed.includes(toolName);
10351
+ }
10352
+ return true;
10353
+ });
10354
+ }
10300
10355
  return { tools: tools2, agentContext };
10301
10356
  }
10302
10357
 
@@ -11472,7 +11527,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
11472
11527
  // package.json
11473
11528
  var package_default = {
11474
11529
  name: "@bike4mind/cli",
11475
- version: "0.2.10-slack-metrics-admin-dashboard.17277+8887342ab",
11530
+ version: "0.2.11-feat-api-key-rate-limiting.17313+25a7242a0",
11476
11531
  type: "module",
11477
11532
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
11478
11533
  license: "UNLICENSED",
@@ -11576,10 +11631,10 @@ var package_default = {
11576
11631
  },
11577
11632
  devDependencies: {
11578
11633
  "@bike4mind/agents": "0.1.0",
11579
- "@bike4mind/common": "2.39.1-slack-metrics-admin-dashboard.17277+8887342ab",
11580
- "@bike4mind/mcp": "1.20.4-slack-metrics-admin-dashboard.17277+8887342ab",
11581
- "@bike4mind/services": "2.34.2-slack-metrics-admin-dashboard.17277+8887342ab",
11582
- "@bike4mind/utils": "2.1.4-slack-metrics-admin-dashboard.17277+8887342ab",
11634
+ "@bike4mind/common": "2.40.1-feat-api-key-rate-limiting.17313+25a7242a0",
11635
+ "@bike4mind/mcp": "1.20.5-feat-api-key-rate-limiting.17313+25a7242a0",
11636
+ "@bike4mind/services": "2.35.1-feat-api-key-rate-limiting.17313+25a7242a0",
11637
+ "@bike4mind/utils": "2.1.5-feat-api-key-rate-limiting.17313+25a7242a0",
11583
11638
  "@types/better-sqlite3": "^7.6.13",
11584
11639
  "@types/diff": "^5.0.9",
11585
11640
  "@types/jsonwebtoken": "^9.0.4",
@@ -11592,7 +11647,7 @@ var package_default = {
11592
11647
  typescript: "^5.9.3",
11593
11648
  vitest: "^3.2.4"
11594
11649
  },
11595
- gitHead: "8887342ab75fec0c6122cc7ddae61f5da01dc164"
11650
+ gitHead: "25a7242a0331435d440bf50f5e7f355eeb388ec9"
11596
11651
  };
11597
11652
 
11598
11653
  // src/config/constants.ts
@@ -11600,6 +11655,353 @@ var USAGE_DAYS = 30;
11600
11655
  var MODEL_NAME_COLUMN_WIDTH = 18;
11601
11656
  var USAGE_CACHE_TTL = 5 * 60 * 1e3;
11602
11657
 
11658
+ // src/agents/SubagentOrchestrator.ts
11659
+ var SubagentOrchestrator = class {
11660
+ constructor(deps) {
11661
+ this.beforeRunCallback = null;
11662
+ this.afterRunCallback = null;
11663
+ this.deps = deps;
11664
+ }
11665
+ /**
11666
+ * Set a callback to be invoked before each subagent.run()
11667
+ * Use this to subscribe to agent events (e.g., subagent.on('action', handler))
11668
+ */
11669
+ setBeforeRunCallback(callback) {
11670
+ this.beforeRunCallback = callback;
11671
+ }
11672
+ /**
11673
+ * Set a callback to be invoked after each subagent.run()
11674
+ * Use this to unsubscribe from agent events (e.g., subagent.off('action', handler))
11675
+ */
11676
+ setAfterRunCallback(callback) {
11677
+ this.afterRunCallback = callback;
11678
+ }
11679
+ /**
11680
+ * Delegate a task to a specialized subagent
11681
+ *
11682
+ * @param options - Configuration for subagent execution
11683
+ * @returns Subagent result with summary
11684
+ */
11685
+ async delegateToSubagent(options) {
11686
+ const { task, type, thoroughness, parentSessionId, config: configOverride } = options;
11687
+ const baseConfig = this.deps.subagentConfigs.get(type);
11688
+ if (!baseConfig) {
11689
+ throw new Error(`No configuration found for subagent type: ${type}`);
11690
+ }
11691
+ const config = {
11692
+ ...baseConfig,
11693
+ ...configOverride,
11694
+ type
11695
+ };
11696
+ const model = config.model || "claude-3-5-haiku-20241022";
11697
+ const maxIterations = this.getMaxIterations(config, thoroughness);
11698
+ const toolFilter = {
11699
+ allowedTools: config.allowedTools,
11700
+ deniedTools: config.deniedTools
11701
+ };
11702
+ const agentContext = {
11703
+ currentAgent: null,
11704
+ observationQueue: []
11705
+ };
11706
+ const { tools: tools2, agentContext: updatedContext } = generateCliTools(
11707
+ this.deps.userId,
11708
+ this.deps.llm,
11709
+ model,
11710
+ this.deps.permissionManager,
11711
+ this.deps.showPermissionPrompt,
11712
+ agentContext,
11713
+ this.deps.configStore,
11714
+ this.deps.apiClient,
11715
+ toolFilter
11716
+ );
11717
+ this.deps.logger.debug(`Spawning ${type} subagent with ${tools2.length} tools, thoroughness: ${thoroughness}`);
11718
+ const subagent = new ReActAgent({
11719
+ userId: this.deps.userId,
11720
+ logger: this.deps.logger,
11721
+ llm: this.deps.llm,
11722
+ model,
11723
+ tools: tools2,
11724
+ maxIterations,
11725
+ systemPrompt: config.systemPrompt || this.getDefaultSystemPrompt(type)
11726
+ });
11727
+ updatedContext.currentAgent = subagent;
11728
+ if (this.beforeRunCallback) {
11729
+ this.beforeRunCallback(subagent, type);
11730
+ }
11731
+ const startTime = Date.now();
11732
+ const result = await subagent.run(task, {
11733
+ maxIterations
11734
+ });
11735
+ const duration = Date.now() - startTime;
11736
+ if (this.afterRunCallback) {
11737
+ this.afterRunCallback(subagent, type);
11738
+ }
11739
+ this.deps.logger.debug(
11740
+ `Subagent completed in ${duration}ms, ${result.completionInfo.iterations} iterations, ${result.completionInfo.totalTokens} tokens`
11741
+ );
11742
+ const summary = this.summarizeResult(result, type);
11743
+ const subagentResult = {
11744
+ ...result,
11745
+ subagentType: type,
11746
+ thoroughness,
11747
+ summary,
11748
+ parentSessionId
11749
+ };
11750
+ return subagentResult;
11751
+ }
11752
+ /**
11753
+ * Get max iterations based on thoroughness and config
11754
+ */
11755
+ getMaxIterations(config, thoroughness) {
11756
+ const defaults = {
11757
+ quick: 2,
11758
+ medium: 5,
11759
+ very_thorough: 10
11760
+ };
11761
+ const configIterations = config.maxIterations || defaults;
11762
+ return configIterations[thoroughness];
11763
+ }
11764
+ /**
11765
+ * Get default system prompt for subagent type
11766
+ */
11767
+ getDefaultSystemPrompt(type) {
11768
+ switch (type) {
11769
+ case "explore":
11770
+ return `You are a code exploration specialist. Your job is to search and analyze codebases efficiently.
11771
+
11772
+ Focus on:
11773
+ - Finding relevant files and functions
11774
+ - Understanding code structure and patterns
11775
+ - Providing clear, concise summaries
11776
+
11777
+ You have read-only access. Use file_read, grep_search, and glob_files to explore.
11778
+
11779
+ When you find what you're looking for, provide a clear summary including:
11780
+ 1. What you found (files, functions, patterns)
11781
+ 2. Key insights or observations
11782
+ 3. Relevant code locations
11783
+
11784
+ Be thorough but concise. Your summary will be used by the main agent.`;
11785
+ case "plan":
11786
+ return `You are a task planning specialist. Your job is to break down complex tasks into clear, actionable steps.
11787
+
11788
+ Focus on:
11789
+ - Identifying dependencies and blockers
11790
+ - Creating logical sequence of steps
11791
+ - Estimating scope and priorities
11792
+
11793
+ Provide a structured plan that the main agent can execute.`;
11794
+ case "review":
11795
+ return `You are a code review specialist. Your job is to analyze code quality and identify issues.
11796
+
11797
+ Focus on:
11798
+ - Code quality and best practices
11799
+ - Potential bugs and edge cases
11800
+ - Performance and security considerations
11801
+
11802
+ Provide actionable feedback with specific file and line references.`;
11803
+ default:
11804
+ return "You are a helpful AI assistant.";
11805
+ }
11806
+ }
11807
+ /**
11808
+ * Summarize subagent result for parent agent
11809
+ */
11810
+ summarizeResult(result, type) {
11811
+ const { finalAnswer, steps, completionInfo } = result;
11812
+ const toolCalls = steps.filter((s) => s.type === "action");
11813
+ const filesRead = toolCalls.filter((s) => s.metadata?.toolName === "file_read").length;
11814
+ const searches = toolCalls.filter((s) => s.metadata?.toolName === "grep_search").length;
11815
+ const globs = toolCalls.filter((s) => s.metadata?.toolName === "glob_files").length;
11816
+ let summary = `**${type.charAt(0).toUpperCase() + type.slice(1)} Subagent Results**
11817
+
11818
+ `;
11819
+ summary += `*Execution: ${completionInfo.iterations} iterations, ${completionInfo.toolCalls} tool calls*
11820
+
11821
+ `;
11822
+ if (type === "explore") {
11823
+ summary += `*Exploration: ${filesRead} files read, ${searches} searches, ${globs} glob patterns*
11824
+
11825
+ `;
11826
+ }
11827
+ const maxLength = 1e3;
11828
+ if (finalAnswer.length > maxLength) {
11829
+ summary += finalAnswer.slice(0, maxLength) + "\n\n...(truncated)";
11830
+ } else {
11831
+ summary += finalAnswer;
11832
+ }
11833
+ return summary;
11834
+ }
11835
+ };
11836
+
11837
+ // src/agents/configs.ts
11838
+ var EXPLORE_CONFIG = {
11839
+ type: "explore",
11840
+ model: "claude-3-5-haiku-20241022",
11841
+ systemPrompt: `You are a code exploration specialist. Your job is to search and analyze codebases efficiently.
11842
+
11843
+ Focus on:
11844
+ - Finding relevant files and functions
11845
+ - Understanding code structure and patterns
11846
+ - Providing clear, concise summaries
11847
+
11848
+ You have read-only access. Use file_read, grep_search, and glob_files to explore.
11849
+
11850
+ When you find what you're looking for, provide a clear summary including:
11851
+ 1. What you found (files, functions, patterns)
11852
+ 2. Key insights or observations
11853
+ 3. Relevant code locations
11854
+
11855
+ Be thorough but concise. Your summary will be used by the main agent.`,
11856
+ allowedTools: [
11857
+ "file_read",
11858
+ "grep_search",
11859
+ "glob_files",
11860
+ "bash_execute",
11861
+ // Only for read-only commands like ls, cat, find
11862
+ "current_datetime",
11863
+ "math_evaluate"
11864
+ ],
11865
+ deniedTools: [
11866
+ "create_file",
11867
+ "edit_file",
11868
+ "delete_file",
11869
+ "web_search",
11870
+ "weather_info",
11871
+ "blog_publish",
11872
+ "blog_edit",
11873
+ "blog_draft"
11874
+ ],
11875
+ maxIterations: {
11876
+ quick: 2,
11877
+ medium: 5,
11878
+ very_thorough: 10
11879
+ },
11880
+ defaultThoroughness: "medium"
11881
+ };
11882
+ var PLAN_CONFIG = {
11883
+ type: "plan",
11884
+ model: "claude-3-5-haiku-20241022",
11885
+ systemPrompt: `You are a task planning specialist. Your job is to break down complex tasks into clear, actionable steps.
11886
+
11887
+ Focus on:
11888
+ - Identifying dependencies and blockers
11889
+ - Creating logical sequence of steps
11890
+ - Estimating scope and priorities
11891
+
11892
+ You can explore the codebase to understand the current architecture before planning.
11893
+
11894
+ Provide a structured plan that the main agent can execute.`,
11895
+ allowedTools: ["file_read", "grep_search", "glob_files", "bash_execute", "current_datetime", "math_evaluate"],
11896
+ deniedTools: ["create_file", "edit_file", "delete_file", "web_search", "weather_info"],
11897
+ maxIterations: {
11898
+ quick: 3,
11899
+ medium: 7,
11900
+ very_thorough: 12
11901
+ },
11902
+ defaultThoroughness: "medium"
11903
+ };
11904
+ var REVIEW_CONFIG = {
11905
+ type: "review",
11906
+ model: "claude-sonnet-4-5-20250929",
11907
+ // Use latest Sonnet for better reasoning
11908
+ systemPrompt: `You are a code review specialist. Your job is to analyze code quality and identify issues.
11909
+
11910
+ Focus on:
11911
+ - Code quality and best practices
11912
+ - Potential bugs and edge cases
11913
+ - Performance and security considerations
11914
+
11915
+ You have read-only access to analyze code.
11916
+
11917
+ Provide actionable feedback with specific file and line references.`,
11918
+ allowedTools: ["file_read", "grep_search", "glob_files", "bash_execute", "current_datetime"],
11919
+ deniedTools: ["create_file", "edit_file", "delete_file", "web_search", "weather_info"],
11920
+ maxIterations: {
11921
+ quick: 3,
11922
+ medium: 8,
11923
+ very_thorough: 15
11924
+ },
11925
+ defaultThoroughness: "medium"
11926
+ };
11927
+ function getDefaultSubagentConfigs() {
11928
+ return /* @__PURE__ */ new Map([
11929
+ ["explore", EXPLORE_CONFIG],
11930
+ ["plan", PLAN_CONFIG],
11931
+ ["review", REVIEW_CONFIG]
11932
+ ]);
11933
+ }
11934
+
11935
+ // src/agents/delegateTool.ts
11936
+ function createSubagentDelegateTool(orchestrator, parentSessionId) {
11937
+ return {
11938
+ toolFn: async (args) => {
11939
+ const params = args;
11940
+ if (!params.task) {
11941
+ throw new Error("subagent_delegate: task parameter is required");
11942
+ }
11943
+ if (!params.type) {
11944
+ throw new Error("subagent_delegate: type parameter is required");
11945
+ }
11946
+ const thoroughness = params.thoroughness || "medium";
11947
+ const type = params.type;
11948
+ const result = await orchestrator.delegateToSubagent({
11949
+ task: params.task,
11950
+ type,
11951
+ thoroughness,
11952
+ parentSessionId
11953
+ });
11954
+ return result.summary;
11955
+ },
11956
+ toolSchema: {
11957
+ name: "subagent_delegate",
11958
+ description: `Delegate a task to a specialized subagent for focused work.
11959
+
11960
+ **When to use this tool:**
11961
+ - **Explore**: When you need to search through the codebase, find files, or understand code structure (read-only)
11962
+ - **Plan**: When you need to break down a complex task into actionable steps
11963
+ - **Review**: When you need to analyze code quality and identify potential issues
11964
+
11965
+ **Benefits:**
11966
+ - Keeps main conversation focused and clean
11967
+ - Uses specialized prompts optimized for each task type
11968
+ - Faster execution with appropriate models (Haiku for explore/plan, Sonnet for review)
11969
+
11970
+ **Example uses:**
11971
+ - "Find all files that use the authentication system" \u2192 explore
11972
+ - "Search for components that handle user input" \u2192 explore
11973
+ - "Break down implementing a new feature into steps" \u2192 plan
11974
+ - "Review this module for potential bugs" \u2192 review`,
11975
+ parameters: {
11976
+ type: "object",
11977
+ properties: {
11978
+ task: {
11979
+ type: "string",
11980
+ description: "Clear description of what you want the subagent to do. Be specific about what you're looking for or what needs to be accomplished."
11981
+ },
11982
+ type: {
11983
+ type: "string",
11984
+ enum: ["explore", "plan", "review"],
11985
+ description: `Type of subagent to use:
11986
+ - explore: Read-only codebase exploration and search (fast, uses Haiku)
11987
+ - plan: Task breakdown and planning (uses Haiku)
11988
+ - review: Code quality analysis and review (uses Sonnet for better reasoning)`
11989
+ },
11990
+ thoroughness: {
11991
+ type: "string",
11992
+ enum: ["quick", "medium", "very_thorough"],
11993
+ description: `How thoroughly to execute:
11994
+ - quick: Fast lookup, 1-2 iterations
11995
+ - medium: Balanced exploration, 3-5 iterations (default)
11996
+ - very_thorough: Comprehensive analysis, 8-10 iterations`
11997
+ }
11998
+ },
11999
+ required: ["task", "type"]
12000
+ }
12001
+ }
12002
+ };
12003
+ }
12004
+
11603
12005
  // src/index.tsx
11604
12006
  process.removeAllListeners("warning");
11605
12007
  process.on("warning", (warning) => {
@@ -11730,7 +12132,7 @@ function CliApp() {
11730
12132
  if (!isAuthenticated) {
11731
12133
  console.log("\u2139\uFE0F AI features disabled. Available commands: /login, /help, /config\n");
11732
12134
  const minimalSession = {
11733
- id: uuidv49(),
12135
+ id: uuidv410(),
11734
12136
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
11735
12137
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
11736
12138
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -11774,7 +12176,7 @@ function CliApp() {
11774
12176
  }
11775
12177
  llm.currentModel = modelInfo.id;
11776
12178
  const newSession = {
11777
- id: uuidv49(),
12179
+ id: uuidv410(),
11778
12180
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
11779
12181
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
11780
12182
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -11847,7 +12249,34 @@ function CliApp() {
11847
12249
  console.log(` \u{1F4E1} ${serverName}: ${count} tool(s)`);
11848
12250
  });
11849
12251
  }
11850
- const allTools = [...b4mTools, ...mcpTools];
12252
+ const subagentConfigs = getDefaultSubagentConfigs();
12253
+ if (config.subagents) {
12254
+ if (config.subagents.explore) {
12255
+ const currentConfig = subagentConfigs.get("explore");
12256
+ subagentConfigs.set("explore", { ...currentConfig, ...config.subagents.explore });
12257
+ }
12258
+ if (config.subagents.plan) {
12259
+ const currentConfig = subagentConfigs.get("plan");
12260
+ subagentConfigs.set("plan", { ...currentConfig, ...config.subagents.plan });
12261
+ }
12262
+ if (config.subagents.review) {
12263
+ const currentConfig = subagentConfigs.get("review");
12264
+ subagentConfigs.set("review", { ...currentConfig, ...config.subagents.review });
12265
+ }
12266
+ }
12267
+ const orchestrator = new SubagentOrchestrator({
12268
+ userId: config.userId,
12269
+ llm,
12270
+ logger: silentLogger,
12271
+ permissionManager,
12272
+ showPermissionPrompt: promptFn,
12273
+ configStore: state.configStore,
12274
+ apiClient,
12275
+ subagentConfigs
12276
+ });
12277
+ const subagentDelegateTool = createSubagentDelegateTool(orchestrator, newSession.id);
12278
+ const allTools = [...b4mTools, ...mcpTools, subagentDelegateTool];
12279
+ console.log(`\u{1F916} Subagent delegation enabled (explore, plan, review)`);
11851
12280
  const projectDir = state.configStore.getProjectConfigDir();
11852
12281
  const contextResult = await loadContextFiles(projectDir);
11853
12282
  if (contextResult.globalContext) {
@@ -11884,6 +12313,15 @@ FOR CODING TASKS:
11884
12313
  - When searching for code: Use grep_search or glob_files to find relevant files
11885
12314
  - Permission system will ask for approval before any file writes
11886
12315
 
12316
+ SUBAGENT DELEGATION:
12317
+ - You have access to specialized subagents via the subagent_delegate tool
12318
+ - Use subagents for focused exploration, planning, or review tasks:
12319
+ * explore: Fast read-only codebase search (e.g., "find all auth files", "locate API endpoints")
12320
+ * plan: Break down complex tasks into actionable steps
12321
+ * review: Analyze code quality and identify issues
12322
+ - Subagents keep the main conversation clean and run faster with optimized models
12323
+ - Delegate when you need to search extensively or analyze code structure
12324
+
11887
12325
  FOR GENERAL TASKS:
11888
12326
  - Use available tools to get information (weather, web search, calculations, etc.)
11889
12327
  - When user asks follow-up questions, use conversation context to understand what they're referring to
@@ -11894,6 +12332,7 @@ EXAMPLES:
11894
12332
  - "how about Japan?" \u2192 use weather tool for Japan (applying same question from context)
11895
12333
  - "enhance README" \u2192 file_read \u2192 generate \u2192 create_file
11896
12334
  - "what packages installed?" \u2192 glob_files "**/package.json" \u2192 file_read
12335
+ - "find all components using React hooks" \u2192 subagent_delegate(task="find all components using React hooks", type="explore")
11897
12336
 
11898
12337
  Remember: Use context from previous messages to understand follow-up questions.${contextSection}`;
11899
12338
  const maxIterations = config.preferences.maxIterations === null ? 999999 : config.preferences.maxIterations;
@@ -11910,6 +12349,27 @@ Remember: Use context from previous messages to understand follow-up questions.$
11910
12349
  });
11911
12350
  agentContext.currentAgent = agent;
11912
12351
  agent.observationQueue = agentContext.observationQueue;
12352
+ const stepHandler = (step) => {
12353
+ const { pendingMessages, updatePendingMessage } = useCliStore.getState();
12354
+ const lastIdx = pendingMessages.length - 1;
12355
+ if (lastIdx >= 0 && pendingMessages[lastIdx].role === "assistant") {
12356
+ const existingSteps = pendingMessages[lastIdx].metadata?.steps || [];
12357
+ updatePendingMessage(lastIdx, {
12358
+ ...pendingMessages[lastIdx],
12359
+ metadata: {
12360
+ ...pendingMessages[lastIdx].metadata,
12361
+ steps: [...existingSteps, step]
12362
+ }
12363
+ });
12364
+ }
12365
+ };
12366
+ agent.on("action", stepHandler);
12367
+ orchestrator.setBeforeRunCallback((subagent, _subagentType) => {
12368
+ subagent.on("action", stepHandler);
12369
+ });
12370
+ orchestrator.setAfterRunCallback((subagent, _subagentType) => {
12371
+ subagent.off("action", stepHandler);
12372
+ });
11913
12373
  setState((prev) => ({
11914
12374
  ...prev,
11915
12375
  session: newSession,
@@ -11983,11 +12443,13 @@ Remember: Use context from previous messages to understand follow-up questions.$
11983
12443
  messageContent = multimodalMessage.content;
11984
12444
  }
11985
12445
  const userMessage = {
12446
+ id: uuidv410(),
11986
12447
  role: "user",
11987
12448
  content: userMessageContent,
11988
12449
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11989
12450
  };
11990
12451
  const pendingAssistantMessage = {
12452
+ id: uuidv410(),
11991
12453
  role: "assistant",
11992
12454
  content: "...",
11993
12455
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12018,7 +12480,10 @@ Remember: Use context from previous messages to understand follow-up questions.$
12018
12480
  const currentSession = useCliStore.getState().session;
12019
12481
  if (!currentSession) return;
12020
12482
  const updatedMessages = [...currentSession.messages];
12483
+ const lastMessage = updatedMessages[updatedMessages.length - 1];
12021
12484
  updatedMessages[updatedMessages.length - 1] = {
12485
+ id: lastMessage.id,
12486
+ // Preserve the original message ID
12022
12487
  role: "assistant",
12023
12488
  content: result.finalAnswer,
12024
12489
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12108,22 +12573,6 @@ Remember: Use context from previous messages to understand follow-up questions.$
12108
12573
  return;
12109
12574
  }
12110
12575
  useCliStore.getState().setIsThinking(true);
12111
- const currentSteps = [];
12112
- const stepHandler = (step) => {
12113
- currentSteps.push(step);
12114
- const { pendingMessages, updatePendingMessage } = useCliStore.getState();
12115
- const lastIdx = pendingMessages.length - 1;
12116
- if (lastIdx >= 0 && pendingMessages[lastIdx].role === "assistant") {
12117
- updatePendingMessage(lastIdx, {
12118
- ...pendingMessages[lastIdx],
12119
- metadata: {
12120
- ...pendingMessages[lastIdx].metadata,
12121
- steps: [...currentSteps]
12122
- }
12123
- });
12124
- }
12125
- };
12126
- state.agent.on("action", stepHandler);
12127
12576
  try {
12128
12577
  let messageContent = message;
12129
12578
  let userMessageContent = message;
@@ -12133,11 +12582,13 @@ Remember: Use context from previous messages to understand follow-up questions.$
12133
12582
  userMessageContent = message;
12134
12583
  }
12135
12584
  const userMessage = {
12585
+ id: uuidv410(),
12136
12586
  role: "user",
12137
12587
  content: userMessageContent,
12138
12588
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
12139
12589
  };
12140
12590
  const pendingAssistantMessage = {
12591
+ id: uuidv410(),
12141
12592
  role: "assistant",
12142
12593
  content: "...",
12143
12594
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -12167,6 +12618,8 @@ Remember: Use context from previous messages to understand follow-up questions.$
12167
12618
  }
12168
12619
  const successfulToolCalls = result.steps.filter((s) => s.type === "observation").length;
12169
12620
  const finalAssistantMessage = {
12621
+ id: pendingAssistantMessage.id,
12622
+ // Preserve the original message ID
12170
12623
  role: "assistant",
12171
12624
  content: result.finalAnswer,
12172
12625
  timestamp: pendingAssistantMessage.timestamp,
@@ -12205,8 +12658,6 @@ Remember: Use context from previous messages to understand follow-up questions.$
12205
12658
  }
12206
12659
  }
12207
12660
  console.error("Error processing message:", error);
12208
- } finally {
12209
- state.agent.off("action", stepHandler);
12210
12661
  }
12211
12662
  };
12212
12663
  const handleBashCommand = useCallback(
@@ -12228,11 +12679,13 @@ Remember: Use context from previous messages to understand follow-up questions.$
12228
12679
  isError = true;
12229
12680
  }
12230
12681
  const userMessage = {
12682
+ id: uuidv410(),
12231
12683
  role: "user",
12232
12684
  content: `$ ${command}`,
12233
12685
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
12234
12686
  };
12235
12687
  const assistantMessage = {
12688
+ id: uuidv410(),
12236
12689
  role: "assistant",
12237
12690
  content: isError ? `\u274C Error:
12238
12691
  ${output}` : output.trim() || "(no output)",
@@ -12643,7 +13096,7 @@ Custom Commands:
12643
13096
  console.clear();
12644
13097
  const model = state.session?.model || state.config?.defaultModel || "claude-sonnet";
12645
13098
  const newSession = {
12646
- id: uuidv49(),
13099
+ id: uuidv410(),
12647
13100
  name: `Session ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
12648
13101
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
12649
13102
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-6EQ62KRQ.js";
4
+ } from "./chunk-S42YW3EI.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/llmMarkdownGenerator.js
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-6EQ62KRQ.js";
4
+ } from "./chunk-S42YW3EI.js";
5
5
  import "./chunk-PDX44BCA.js";
6
6
 
7
7
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/markdownGenerator.js
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  findMostSimilarMemento,
4
4
  getRelevantMementos
5
- } from "./chunk-TFXE7AI6.js";
6
- import "./chunk-23GLLYOT.js";
5
+ } from "./chunk-X5H7N2CY.js";
6
+ import "./chunk-BBQI2EAJ.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
- import "./chunk-6EQ62KRQ.js";
8
+ import "./chunk-S42YW3EI.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  findMostSimilarMemento,
@@ -40,6 +40,7 @@ import {
40
40
  CitableSourceSchema,
41
41
  ClaudeArtifactMimeTypes,
42
42
  CollectionType,
43
+ CompletionApiUsageTransaction,
43
44
  CompletionRequestSchema,
44
45
  ConfluenceApi,
45
46
  CreateFabFileRequestInput,
@@ -293,7 +294,7 @@ import {
293
294
  validateQuestMasterArtifactV2,
294
295
  validateReactArtifactV2,
295
296
  validateSvgArtifactV2
296
- } from "./chunk-6EQ62KRQ.js";
297
+ } from "./chunk-S42YW3EI.js";
297
298
  import "./chunk-PDX44BCA.js";
298
299
  export {
299
300
  ALL_IMAGE_MODELS,
@@ -336,6 +337,7 @@ export {
336
337
  CitableSourceSchema,
337
338
  ClaudeArtifactMimeTypes,
338
339
  CollectionType,
340
+ CompletionApiUsageTransaction,
339
341
  CompletionRequestSchema,
340
342
  ConfluenceApi,
341
343
  CreateFabFileRequestInput,
@@ -120,7 +120,7 @@ import {
120
120
  validateMermaidSyntax,
121
121
  warmUpSettingsCache,
122
122
  withRetry
123
- } from "./chunk-23GLLYOT.js";
123
+ } from "./chunk-BBQI2EAJ.js";
124
124
  import {
125
125
  Logger,
126
126
  NotificationDeduplicator,
@@ -129,7 +129,7 @@ import {
129
129
  postLowCreditsNotificationToSlack,
130
130
  postMessageToSlack
131
131
  } from "./chunk-AMDXHL6S.js";
132
- import "./chunk-6EQ62KRQ.js";
132
+ import "./chunk-S42YW3EI.js";
133
133
  import "./chunk-PDX44BCA.js";
134
134
  export {
135
135
  AWSBackend,
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  SubtractCreditsSchema,
4
4
  subtractCredits
5
- } from "./chunk-VOOM6DLV.js";
6
- import "./chunk-23GLLYOT.js";
5
+ } from "./chunk-7TW7K6CW.js";
6
+ import "./chunk-BBQI2EAJ.js";
7
7
  import "./chunk-AMDXHL6S.js";
8
- import "./chunk-6EQ62KRQ.js";
8
+ import "./chunk-S42YW3EI.js";
9
9
  import "./chunk-PDX44BCA.js";
10
10
  export {
11
11
  SubtractCreditsSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.10-slack-metrics-admin-dashboard.17277+8887342ab",
3
+ "version": "0.2.11-feat-api-key-rate-limiting.17313+25a7242a0",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -104,10 +104,10 @@
104
104
  },
105
105
  "devDependencies": {
106
106
  "@bike4mind/agents": "0.1.0",
107
- "@bike4mind/common": "2.39.1-slack-metrics-admin-dashboard.17277+8887342ab",
108
- "@bike4mind/mcp": "1.20.4-slack-metrics-admin-dashboard.17277+8887342ab",
109
- "@bike4mind/services": "2.34.2-slack-metrics-admin-dashboard.17277+8887342ab",
110
- "@bike4mind/utils": "2.1.4-slack-metrics-admin-dashboard.17277+8887342ab",
107
+ "@bike4mind/common": "2.40.1-feat-api-key-rate-limiting.17313+25a7242a0",
108
+ "@bike4mind/mcp": "1.20.5-feat-api-key-rate-limiting.17313+25a7242a0",
109
+ "@bike4mind/services": "2.35.1-feat-api-key-rate-limiting.17313+25a7242a0",
110
+ "@bike4mind/utils": "2.1.5-feat-api-key-rate-limiting.17313+25a7242a0",
111
111
  "@types/better-sqlite3": "^7.6.13",
112
112
  "@types/diff": "^5.0.9",
113
113
  "@types/jsonwebtoken": "^9.0.4",
@@ -120,5 +120,5 @@
120
120
  "typescript": "^5.9.3",
121
121
  "vitest": "^3.2.4"
122
122
  },
123
- "gitHead": "8887342ab75fec0c6122cc7ddae61f5da01dc164"
123
+ "gitHead": "25a7242a0331435d440bf50f5e7f355eeb388ec9"
124
124
  }