@bike4mind/cli 0.2.24-recent-changes-tool.18468 → 0.2.24-sessions-command-bug-fix.18477

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -183,7 +183,6 @@ export SERPER_API_KEY="your-key-here"
183
183
  - ✅ `current_datetime` - No API key needed
184
184
  - ✅ `prompt_enhancement` - No API key needed
185
185
  - ✅ `bash_execute` - No API key needed
186
- - ✅ `recent_changes` - No API key needed (git-based file search by modification time)
187
186
  - 🔑 `weather_info` - Requires `toolApiKeys.openweather`
188
187
  - 🔑 `web_search` - Requires `toolApiKeys.serper`
189
188
  - 🔑 `deep_research` - Requires `toolApiKeys.serper`
@@ -265,36 +264,6 @@ You can also run any MCP server via npx or custom executables:
265
264
 
266
265
  **Note:** Internal MCP servers must be built and available in the `b4m-core/packages/mcp/dist/src/` directory. The CLI will automatically find them if you're running from the monorepo. For Docker-based servers, ensure Docker is installed and the image is accessible.
267
266
 
268
- ## Git-Aware Code Search
269
-
270
- The CLI includes a `recent_changes` tool that uses git history to find recently modified files. This significantly speeds up debugging by narrowing the search space to recently changed code.
271
-
272
- ### Use Cases
273
-
274
- - **Recent bug debugging:** "I just broke something, can you help fix it?"
275
- - **Understanding feature development:** "What did we change for the new dashboard?"
276
- - **Finding active development areas:** "What are we actively working on?"
277
- - **Code review prep:** "What changed since last release?"
278
-
279
- ### Parameters
280
-
281
- - `since` - Time range to search (default: "7 days ago")
282
- - Examples: "2 hours ago", "3 days ago", "2025-01-01"
283
- - `path` - Filter to specific directory (default: entire repo)
284
- - Examples: "src/components", "apps/client", "**/*.test.ts"
285
- - `limit` - Maximum files to return (default: 50)
286
- - `include_stats` - Show lines added/removed (default: false)
287
-
288
- ### How It Works
289
-
290
- The tool uses `git log` to track file modifications and returns:
291
- - Files sorted by activity (most commits first)
292
- - Commit messages for context
293
- - Optional statistics showing lines changed
294
- - Filtered results based on time and path
295
-
296
- **Performance benefit:** Instead of searching 50+ files (5-10 minutes), find the 3 relevant files in ~30 seconds.
297
-
298
267
  ## Context Files
299
268
 
300
269
  The CLI supports loading project-specific instructions from context files, similar to CLAUDE.md in Claude Code. These files provide persistent instructions that are automatically included in the agent's system prompt.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-37CKEEXO.js";
4
+ } from "./chunk-LOIWIBZT.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;
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-KC235R6G.js";
9
+ } from "./chunk-XFN2ICKP.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-37CKEEXO.js";
14
+ } from "./chunk-LOIWIBZT.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-KC235R6G.js";
10
+ } from "./chunk-XFN2ICKP.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-37CKEEXO.js";
14
+ } from "./chunk-LOIWIBZT.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-KC235R6G.js";
5
+ } from "./chunk-XFN2ICKP.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-37CKEEXO.js";
15
+ } from "./chunk-LOIWIBZT.js";
16
16
 
17
17
  // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
18
18
  import { z } from "zod";
@@ -303,8 +303,17 @@ var b4mLLMTools = z5.enum([
303
303
  "sunrise_sunset",
304
304
  "iss_tracker",
305
305
  "planet_visibility",
306
+ // File operation tools
307
+ "file_read",
308
+ "create_file",
309
+ "edit_local_file",
310
+ "glob_files",
311
+ "grep_search",
312
+ "delete_file",
306
313
  // Knowledge base search
307
- "search_knowledge_base"
314
+ "search_knowledge_base",
315
+ // Shell execution
316
+ "bash_execute"
308
317
  ]);
309
318
  var B4MLLMToolsList = b4mLLMTools.options.map((tool) => tool);
310
319
  var RechartsChartTypeSchema = z5.enum([
@@ -15,7 +15,7 @@ import {
15
15
  dayjsConfig_default,
16
16
  extractSnippetMeta,
17
17
  settingsMap
18
- } from "./chunk-37CKEEXO.js";
18
+ } from "./chunk-LOIWIBZT.js";
19
19
  import {
20
20
  Logger
21
21
  } from "./chunk-OCYRD7D6.js";
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-SWBK52BT.js";
6
- import "./chunk-KC235R6G.js";
7
- import "./chunk-37CKEEXO.js";
5
+ } from "./chunk-GGQZHK5U.js";
6
+ import "./chunk-XFN2ICKP.js";
7
+ import "./chunk-LOIWIBZT.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  createFabFile,
package/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import {
4
4
  getEffectiveApiKey,
5
5
  getOpenWeatherKey,
6
6
  getSerperKey
7
- } from "./chunk-QCZ7HG2D.js";
7
+ } from "./chunk-FV2VQXYX.js";
8
8
  import {
9
9
  ConfigStore
10
10
  } from "./chunk-23T2XGSZ.js";
11
- import "./chunk-5ACUY24Z.js";
12
- import "./chunk-SWBK52BT.js";
11
+ import "./chunk-JHCQOESZ.js";
12
+ import "./chunk-GGQZHK5U.js";
13
13
  import {
14
14
  BFLImageService,
15
15
  BaseStorage,
@@ -21,7 +21,7 @@ import {
21
21
  OpenAIBackend,
22
22
  OpenAIImageService,
23
23
  XAIImageService
24
- } from "./chunk-KC235R6G.js";
24
+ } from "./chunk-XFN2ICKP.js";
25
25
  import {
26
26
  AiEvents,
27
27
  ApiKeyEvents,
@@ -77,7 +77,7 @@ import {
77
77
  XAI_IMAGE_MODELS,
78
78
  b4mLLMTools,
79
79
  getMcpProviderMetadata
80
- } from "./chunk-37CKEEXO.js";
80
+ } from "./chunk-LOIWIBZT.js";
81
81
  import {
82
82
  Logger
83
83
  } from "./chunk-OCYRD7D6.js";
@@ -1032,7 +1032,7 @@ function InputPrompt({
1032
1032
  setFileSelectedIndex(0);
1033
1033
  }, [filteredFiles]);
1034
1034
  useInput2(
1035
- (_input, key) => {
1035
+ (input, key) => {
1036
1036
  if (fileAutocomplete?.active && filteredFiles.length > 0) {
1037
1037
  if (key.upArrow) {
1038
1038
  setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
@@ -2031,7 +2031,7 @@ import SelectInput4 from "ink-select-input";
2031
2031
  function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
2032
2032
  const [step, setStep] = useState6("selection");
2033
2033
  const [selectedSession, setSelectedSession] = useState6(null);
2034
- useInput6((input, key) => {
2034
+ useInput6((_input, key) => {
2035
2035
  if (key.escape) {
2036
2036
  if (step === "confirmation") {
2037
2037
  setStep("selection");
@@ -2042,12 +2042,29 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
2042
2042
  }
2043
2043
  });
2044
2044
  const hasUnsavedWork = currentSession && currentSession.messages.length > 0;
2045
+ const formatTimeAgo = (timestamp) => {
2046
+ const now = /* @__PURE__ */ new Date();
2047
+ const then = new Date(timestamp);
2048
+ const diffMs = now.getTime() - then.getTime();
2049
+ const diffMins = Math.floor(diffMs / 6e4);
2050
+ const diffHours = Math.floor(diffMs / 36e5);
2051
+ const diffDays = Math.floor(diffMs / 864e5);
2052
+ if (diffMins < 60) {
2053
+ return `${diffMins}m`;
2054
+ } else if (diffHours < 24) {
2055
+ return `${diffHours}h`;
2056
+ } else {
2057
+ return `${diffDays}d`;
2058
+ }
2059
+ };
2045
2060
  const items = sessions.map((session, index) => {
2046
- const messageCount = session.messages.length;
2047
- const lastUpdated = new Date(session.updatedAt).toLocaleString();
2061
+ const userMessages = session.messages.filter((msg) => msg.role === "user");
2062
+ const lastUserMessage = userMessages[userMessages.length - 1];
2063
+ const preview = lastUserMessage ? lastUserMessage.content.slice(0, 50).replace(/\n/g, " ") + (lastUserMessage.content.length > 50 ? "..." : "") : "No messages";
2064
+ const timeAgo = formatTimeAgo(session.updatedAt);
2048
2065
  return {
2049
- label: `[${index + 1}] ${session.name} (${messageCount} msg, ${session.model})
2050
- Last updated: ${lastUpdated}`,
2066
+ key: session.id,
2067
+ label: `[${index + 1}] ${preview} (${timeAgo})`,
2051
2068
  value: session
2052
2069
  };
2053
2070
  });
@@ -2287,6 +2304,9 @@ var SessionStore = class {
2287
2304
  * Save a session to disk
2288
2305
  */
2289
2306
  async save(session) {
2307
+ if (session.messages.length === 0) {
2308
+ throw new Error("Cannot save session with no messages");
2309
+ }
2290
2310
  await this.init();
2291
2311
  const filePath = path3.join(this.basePath, `${session.id}.json`);
2292
2312
  try {
@@ -2329,13 +2349,14 @@ var SessionStore = class {
2329
2349
  }
2330
2350
  /**
2331
2351
  * List all saved sessions
2352
+ * @param limit - Optional limit on number of sessions to return (returns most recent)
2332
2353
  */
2333
- async list() {
2354
+ async list(limit) {
2334
2355
  await this.init();
2335
2356
  try {
2336
2357
  const files = await fs3.readdir(this.basePath);
2337
2358
  const jsonFiles = files.filter((f) => f.endsWith(".json"));
2338
- const sessions = await Promise.all(
2359
+ const sessionsWithFiles = await Promise.all(
2339
2360
  jsonFiles.map(async (file) => {
2340
2361
  const filePath = path3.join(this.basePath, file);
2341
2362
  const data = await fs3.readFile(filePath, "utf-8");
@@ -2346,10 +2367,23 @@ var SessionStore = class {
2346
2367
  }
2347
2368
  return msg;
2348
2369
  });
2349
- return session;
2370
+ return { session, filePath };
2350
2371
  })
2351
2372
  );
2352
- return sessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
2373
+ const validSessions = [];
2374
+ for (const { session, filePath } of sessionsWithFiles) {
2375
+ if (session.messages.length === 0) {
2376
+ try {
2377
+ await fs3.unlink(filePath);
2378
+ } catch (error) {
2379
+ console.error(`Failed to delete empty session ${session.id}:`, error);
2380
+ }
2381
+ } else {
2382
+ validSessions.push(session);
2383
+ }
2384
+ }
2385
+ const sorted = validSessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
2386
+ return limit ? sorted.slice(0, limit) : sorted;
2353
2387
  } catch (error) {
2354
2388
  console.error("Failed to list sessions:", error);
2355
2389
  return [];
@@ -5585,15 +5619,6 @@ var llmAnalysisResponseSchema = z136.object({
5585
5619
  suggestedTags: z136.array(z136.string()).default([])
5586
5620
  });
5587
5621
 
5588
- // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
5589
- import { z as z138 } from "zod";
5590
-
5591
- // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
5592
- import { fromZodError } from "zod-validation-error";
5593
-
5594
- // ../../b4m-core/packages/services/dist/src/llm/tools/toolManager.js
5595
- var BUILT_IN_TOOL_SET = new Set(b4mLLMTools.options);
5596
-
5597
5622
  // ../../b4m-core/packages/services/dist/src/llm/tools/ToolCacheManager.js
5598
5623
  var DEFAULT_CONFIG = {
5599
5624
  ttl: 5 * 60 * 1e3,
@@ -9955,343 +9980,8 @@ var editLocalFileTool = {
9955
9980
  })
9956
9981
  };
9957
9982
 
9958
- // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/recentChanges/index.js
9959
- import { spawn as spawn2 } from "child_process";
9960
- var DEFAULT_SINCE = "7 days ago";
9961
- var DEFAULT_LIMIT = 50;
9962
- var DEFAULT_INCLUDE_STATS = false;
9963
- function parseStatusLine(line) {
9964
- const results = [];
9965
- if (line.length < 4)
9966
- return results;
9967
- const indexStatus = line[0];
9968
- const workTreeStatus = line[1];
9969
- const filePath = line.slice(3);
9970
- const typeMap = {
9971
- M: "modified",
9972
- A: "added",
9973
- D: "deleted",
9974
- R: "renamed",
9975
- C: "copied"
9976
- };
9977
- if (indexStatus !== " " && indexStatus !== "?") {
9978
- results.push({
9979
- path: filePath,
9980
- status: "staged",
9981
- type: typeMap[indexStatus] || "modified"
9982
- });
9983
- }
9984
- if (workTreeStatus !== " " && workTreeStatus !== "?") {
9985
- results.push({
9986
- path: filePath,
9987
- status: "unstaged",
9988
- type: typeMap[workTreeStatus] || "modified"
9989
- });
9990
- }
9991
- if (indexStatus === "?" && workTreeStatus === "?") {
9992
- results.push({
9993
- path: filePath,
9994
- status: "untracked",
9995
- type: "added"
9996
- });
9997
- }
9998
- return results;
9999
- }
10000
- async function getWorkingTreeChanges(filterPath) {
10001
- const args = ["status", "--porcelain"];
10002
- if (filterPath) {
10003
- args.push("--", filterPath);
10004
- }
10005
- return new Promise((resolve3) => {
10006
- const proc = spawn2("git", args, {
10007
- cwd: process.cwd(),
10008
- stdio: ["ignore", "pipe", "pipe"]
10009
- });
10010
- let stdout = "";
10011
- proc.stdout.on("data", (data) => {
10012
- stdout += data.toString();
10013
- });
10014
- proc.on("close", (exitCode) => {
10015
- if (exitCode !== 0) {
10016
- resolve3([]);
10017
- return;
10018
- }
10019
- const files = stdout.split("\n").filter((line) => line.length > 0).flatMap(parseStatusLine);
10020
- resolve3(files);
10021
- });
10022
- proc.on("error", () => {
10023
- resolve3([]);
10024
- });
10025
- });
10026
- }
10027
- async function getRecentChanges(params) {
10028
- const { since = DEFAULT_SINCE, path: filterPath, limit = DEFAULT_LIMIT, include_stats = DEFAULT_INCLUDE_STATS } = params;
10029
- const args = ["log", `--since=${since}`, "--name-only", "--pretty=format:"];
10030
- if (filterPath) {
10031
- args.push("--", filterPath);
10032
- }
10033
- return new Promise((resolve3) => {
10034
- const proc = spawn2("git", args, {
10035
- cwd: process.cwd(),
10036
- stdio: ["ignore", "pipe", "pipe"]
10037
- });
10038
- let stdout = "";
10039
- let stderr = "";
10040
- proc.stdout.on("data", (data) => {
10041
- stdout += data.toString();
10042
- });
10043
- proc.stderr.on("data", (data) => {
10044
- stderr += data.toString();
10045
- });
10046
- proc.on("close", async (exitCode) => {
10047
- const workingTree = await getWorkingTreeChanges(filterPath);
10048
- if (exitCode !== 0) {
10049
- resolve3({
10050
- files: [],
10051
- workingTree,
10052
- timeRange: since,
10053
- totalFiles: 0,
10054
- error: stderr || "Git command failed"
10055
- });
10056
- return;
10057
- }
10058
- const files = stdout.split("\n").filter((line) => line.trim().length > 0).reduce((acc, filePath) => {
10059
- const existing = acc.find((f) => f.path === filePath);
10060
- if (existing) {
10061
- existing.changes++;
10062
- } else {
10063
- acc.push({ path: filePath, changes: 1 });
10064
- }
10065
- return acc;
10066
- }, []);
10067
- files.sort((a, b) => b.changes - a.changes);
10068
- const limitedFiles = files.slice(0, limit);
10069
- if (include_stats && limitedFiles.length > 0) {
10070
- const filesWithStats = await getFileStats(limitedFiles, since, filterPath);
10071
- resolve3({
10072
- files: filesWithStats,
10073
- workingTree,
10074
- timeRange: since,
10075
- totalFiles: files.length
10076
- });
10077
- } else {
10078
- resolve3({
10079
- files: limitedFiles,
10080
- workingTree,
10081
- timeRange: since,
10082
- totalFiles: files.length
10083
- });
10084
- }
10085
- });
10086
- proc.on("error", async (error) => {
10087
- const workingTree = await getWorkingTreeChanges(filterPath);
10088
- resolve3({
10089
- files: [],
10090
- workingTree,
10091
- timeRange: since,
10092
- totalFiles: 0,
10093
- error: `Failed to execute git command: ${error.message}`
10094
- });
10095
- });
10096
- });
10097
- }
10098
- async function getFileStats(files, since, filterPath) {
10099
- const args = ["log", `--since=${since}`, "--numstat", "--pretty=format:"];
10100
- if (filterPath) {
10101
- args.push("--", filterPath);
10102
- }
10103
- return new Promise((resolve3) => {
10104
- const proc = spawn2("git", args, {
10105
- cwd: process.cwd(),
10106
- stdio: ["ignore", "pipe", "pipe"]
10107
- });
10108
- let stdout = "";
10109
- proc.stdout.on("data", (data) => {
10110
- stdout += data.toString();
10111
- });
10112
- proc.on("close", () => {
10113
- const stats = /* @__PURE__ */ new Map();
10114
- stdout.split("\n").forEach((line) => {
10115
- const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
10116
- if (match) {
10117
- const [, additions, deletions, filePath] = match;
10118
- const existing = stats.get(filePath);
10119
- if (existing) {
10120
- existing.additions += parseInt(additions, 10);
10121
- existing.deletions += parseInt(deletions, 10);
10122
- } else {
10123
- stats.set(filePath, {
10124
- additions: parseInt(additions, 10),
10125
- deletions: parseInt(deletions, 10)
10126
- });
10127
- }
10128
- }
10129
- });
10130
- const result = files.map((file) => {
10131
- const stat3 = stats.get(file.path);
10132
- if (stat3) {
10133
- return { ...file, ...stat3 };
10134
- }
10135
- return file;
10136
- });
10137
- resolve3(result);
10138
- });
10139
- proc.on("error", () => {
10140
- resolve3(files);
10141
- });
10142
- });
10143
- }
10144
- function formatResult2(result) {
10145
- const parts = [];
10146
- if (result.error) {
10147
- parts.push(`Error: ${result.error}`);
10148
- parts.push("");
10149
- parts.push("Make sure you are running this command in a git repository.");
10150
- if (result.workingTree.length > 0) {
10151
- parts.push("");
10152
- parts.push(formatWorkingTree(result.workingTree));
10153
- }
10154
- return parts.join("\n");
10155
- }
10156
- if (result.workingTree.length > 0) {
10157
- parts.push(formatWorkingTree(result.workingTree));
10158
- parts.push("");
10159
- }
10160
- parts.push(`Recently committed files (${result.timeRange}):`);
10161
- parts.push("");
10162
- if (result.files.length === 0) {
10163
- parts.push("No files changed in this time period.");
10164
- } else {
10165
- result.files.forEach((file, index) => {
10166
- const stats = file.additions !== void 0 && file.deletions !== void 0 ? ` (+${file.additions}/-${file.deletions})` : "";
10167
- parts.push(`${index + 1}. ${file.path} (${file.changes} commits)${stats}`);
10168
- });
10169
- if (result.totalFiles > result.files.length) {
10170
- parts.push("");
10171
- parts.push(`Showing ${result.files.length} of ${result.totalFiles} changed files.`);
10172
- parts.push(`Use the 'limit' parameter to see more files.`);
10173
- }
10174
- }
10175
- return parts.join("\n");
10176
- }
10177
- function formatWorkingTree(workingTree) {
10178
- const parts = [];
10179
- const staged = workingTree.filter((f) => f.status === "staged");
10180
- const unstaged = workingTree.filter((f) => f.status === "unstaged");
10181
- const untracked = workingTree.filter((f) => f.status === "untracked");
10182
- parts.push("Working tree changes:");
10183
- if (staged.length > 0) {
10184
- parts.push("");
10185
- parts.push(` Staged (${staged.length}):`);
10186
- staged.forEach((f) => parts.push(` ${f.type}: ${f.path}`));
10187
- }
10188
- if (unstaged.length > 0) {
10189
- parts.push("");
10190
- parts.push(` Unstaged (${unstaged.length}):`);
10191
- unstaged.forEach((f) => parts.push(` ${f.type}: ${f.path}`));
10192
- }
10193
- if (untracked.length > 0) {
10194
- parts.push("");
10195
- parts.push(` Untracked (${untracked.length}):`);
10196
- untracked.forEach((f) => parts.push(` ${f.path}`));
10197
- }
10198
- return parts.join("\n");
10199
- }
10200
- var recentChangesTool = {
10201
- name: "recent_changes",
10202
- implementation: (context) => ({
10203
- toolFn: async (value) => {
10204
- const params = value;
10205
- context.logger.info("RecentChanges: Getting recently changed files", {
10206
- since: params.since || DEFAULT_SINCE,
10207
- path: params.path || "all",
10208
- limit: params.limit || DEFAULT_LIMIT,
10209
- include_stats: params.include_stats || DEFAULT_INCLUDE_STATS
10210
- });
10211
- if (context.onStart) {
10212
- await context.onStart("recent_changes", {
10213
- since: params.since,
10214
- path: params.path
10215
- });
10216
- }
10217
- try {
10218
- const result = await getRecentChanges(params);
10219
- const formattedResult = formatResult2(result);
10220
- context.logger.info("RecentChanges: Retrieved file changes", {
10221
- totalFiles: result.totalFiles,
10222
- displayedFiles: result.files.length,
10223
- error: result.error
10224
- });
10225
- if (context.onFinish) {
10226
- await context.onFinish("recent_changes", {
10227
- totalFiles: result.totalFiles,
10228
- displayedFiles: result.files.length
10229
- });
10230
- }
10231
- return formattedResult;
10232
- } catch (error) {
10233
- context.logger.error("RecentChanges: Failed to get changes", error);
10234
- if (context.onFinish) {
10235
- await context.onFinish("recent_changes", {
10236
- error: error instanceof Error ? error.message : "Unknown error"
10237
- });
10238
- }
10239
- throw error;
10240
- }
10241
- },
10242
- toolSchema: {
10243
- name: "recent_changes",
10244
- description: `Get a list of recently changed files in the git repository, including uncommitted working tree changes (staged, unstaged, and untracked files) plus committed changes sorted by activity. This tool is extremely useful for:
10245
-
10246
- - **Debugging recent issues**: "Something broke after my last commit" \u2192 See exactly what changed
10247
- - **Understanding active development**: "What are we working on?" \u2192 See most active files and current work-in-progress
10248
- - **Code review preparation**: "What changed since last release?" \u2192 Get comprehensive file list
10249
- - **Feature context**: "What files are part of the new dashboard?" \u2192 Filter by path
10250
- - **Current work-in-progress**: See staged, unstaged, and untracked files alongside commit history
10251
-
10252
- The tool combines git status (working tree) with git log (commit history) to give a complete picture of recent activity. Working tree changes are shown first, followed by committed files ranked by number of commits (most active first).
10253
-
10254
- **Time Range Examples:**
10255
- - "7 days ago" (default)
10256
- - "2 hours ago"
10257
- - "3 weeks ago"
10258
- - "2025-01-01"
10259
- - "yesterday"
10260
-
10261
- **Path Filter Examples:**
10262
- - "src/components" - Only files in components directory
10263
- - "apps/client" - Only client app files
10264
- - "**/*.test.ts" - Only test files (use glob patterns)
10265
-
10266
- **Performance:** Very fast (< 1 second) since it only queries git metadata, not file contents.`,
10267
- parameters: {
10268
- type: "object",
10269
- properties: {
10270
- since: {
10271
- type: "string",
10272
- description: 'Time range for changes (default: "7 days ago"). Examples: "2 hours ago", "3 weeks ago", "2025-01-01", "yesterday".'
10273
- },
10274
- path: {
10275
- type: "string",
10276
- description: 'Optional path filter to limit results to specific directory or pattern. Examples: "src/components", "apps/client", "**/*.test.ts".'
10277
- },
10278
- limit: {
10279
- type: "number",
10280
- description: "Maximum number of files to return (default: 50). Files are sorted by activity (most commits first)."
10281
- },
10282
- include_stats: {
10283
- type: "boolean",
10284
- description: "Include lines added/removed statistics for each file (default: false). Note: This makes the command slightly slower."
10285
- }
10286
- },
10287
- required: []
10288
- }
10289
- }
10290
- })
10291
- };
10292
-
10293
9983
  // ../../b4m-core/packages/services/dist/src/llm/tools/index.js
10294
- var b4mTools = {
9984
+ var tools = {
10295
9985
  dice_roll: diceRollTool,
10296
9986
  weather_info: weatherTool,
10297
9987
  image_generation: imageGenerationTool,
@@ -10314,23 +10004,18 @@ var b4mTools = {
10314
10004
  sunrise_sunset: sunriseSunsetTool,
10315
10005
  iss_tracker: issTrackerTool,
10316
10006
  planet_visibility: planetVisibilityTool,
10317
- // Knowledge base search
10318
- search_knowledge_base: knowledgeBaseSearchTool
10319
- };
10320
- var cliOnlyTools = {
10321
- // File operation tools
10322
10007
  file_read: fileReadTool,
10323
10008
  create_file: createFileTool,
10324
10009
  edit_local_file: editLocalFileTool,
10325
10010
  glob_files: globFilesTool,
10326
10011
  grep_search: grepSearchTool,
10327
10012
  delete_file: deleteFileTool,
10013
+ // Knowledge base search
10014
+ search_knowledge_base: knowledgeBaseSearchTool,
10328
10015
  // Shell execution
10329
- bash_execute: bashExecuteTool,
10330
- // Git operations
10331
- recent_changes: recentChangesTool
10016
+ bash_execute: bashExecuteTool
10332
10017
  };
10333
- var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, tools = b4mTools) => {
10018
+ var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model) => {
10334
10019
  const context = {
10335
10020
  userId,
10336
10021
  user,
@@ -10351,9 +10036,9 @@ var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorag
10351
10036
  };
10352
10037
  var ATLASSIAN_RECONNECT_MESSAGE = "\u26A0\uFE0F Your Atlassian connection has expired.\n\nPlease reconnect your Atlassian account in Settings > Connected Apps to continue using Confluence and Jira tools.";
10353
10038
  var generateMcpTools = async (mcpData) => {
10354
- let tools;
10039
+ let tools2;
10355
10040
  try {
10356
- tools = await mcpData.getTools();
10041
+ tools2 = await mcpData.getTools();
10357
10042
  } catch (error) {
10358
10043
  const errorName = error instanceof Error ? error.name : "";
10359
10044
  if (errorName === "AtlassianReconnectRequiredError") {
@@ -10362,12 +10047,12 @@ var generateMcpTools = async (mcpData) => {
10362
10047
  }
10363
10048
  throw error;
10364
10049
  }
10365
- const toolList = Array.isArray(tools) ? tools : tools?.tools || [];
10366
- if (!Array.isArray(tools)) {
10367
- console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(tools));
10050
+ const toolList = Array.isArray(tools2) ? tools2 : tools2?.tools || [];
10051
+ if (!Array.isArray(tools2)) {
10052
+ console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(tools2));
10368
10053
  }
10369
10054
  if (!Array.isArray(toolList)) {
10370
- throw new Error(`Expected getTools() to return an array, but got ${typeof tools}`);
10055
+ throw new Error(`Expected getTools() to return an array, but got ${typeof tools2}`);
10371
10056
  }
10372
10057
  const result = toolList.map((item) => {
10373
10058
  const { name: originalToolName, ...rest } = item;
@@ -10437,16 +10122,8 @@ var generateMcpTools = async (mcpData) => {
10437
10122
  import throttle2 from "lodash/throttle.js";
10438
10123
 
10439
10124
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionFeatures.js
10125
+ import { z as z138 } from "zod";
10440
10126
  import uniq4 from "lodash/uniq.js";
10441
-
10442
- // ../../b4m-core/packages/services/dist/src/llm/StatusManager.js
10443
- import throttle from "lodash/throttle.js";
10444
-
10445
- // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionProcess.js
10446
- var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true";
10447
- var questSaveMutex = new Mutex();
10448
-
10449
- // ../../b4m-core/packages/services/dist/src/llm/ChatCompletion.js
10450
10127
  var QuestStartBodySchema = z138.object({
10451
10128
  userId: z138.string(),
10452
10129
  sessionId: z138.string(),
@@ -10488,6 +10165,19 @@ var QuestStartBodySchema = z138.object({
10488
10165
  timezone: z138.string().optional()
10489
10166
  });
10490
10167
 
10168
+ // ../../b4m-core/packages/services/dist/src/llm/StatusManager.js
10169
+ import throttle from "lodash/throttle.js";
10170
+
10171
+ // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionProcess.js
10172
+ var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true";
10173
+ var questSaveMutex = new Mutex();
10174
+
10175
+ // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionInvoke.js
10176
+ import { fromZodError } from "zod-validation-error";
10177
+
10178
+ // ../../b4m-core/packages/services/dist/src/llm/tools/toolManager.js
10179
+ var BUILT_IN_TOOL_SET = new Set(b4mLLMTools.options);
10180
+
10491
10181
  // ../../b4m-core/packages/services/dist/src/llm/ImageGeneration.js
10492
10182
  import axios8 from "axios";
10493
10183
  import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
@@ -10701,8 +10391,7 @@ var LOCAL_TOOLS = [
10701
10391
  "dice_roll",
10702
10392
  "math_evaluate",
10703
10393
  "current_datetime",
10704
- "bash_execute",
10705
- "recent_changes"
10394
+ "bash_execute"
10706
10395
  ];
10707
10396
  function isServerTool(toolName) {
10708
10397
  return SERVER_TOOLS.includes(toolName);
@@ -10728,11 +10417,11 @@ async function executeTool(toolName, input, apiClient, localToolFn) {
10728
10417
  }
10729
10418
 
10730
10419
  // src/utils/shellRunner.ts
10731
- import { spawn as spawn3 } from "child_process";
10420
+ import { spawn as spawn2 } from "child_process";
10732
10421
  async function runShellCommand(options) {
10733
10422
  const { command, cwd, timeoutMs, env, stdin } = options;
10734
10423
  return new Promise((resolve3) => {
10735
- const child = spawn3("bash", ["-c", command], {
10424
+ const child = spawn2("bash", ["-c", command], {
10736
10425
  cwd,
10737
10426
  env,
10738
10427
  stdio: ["pipe", "pipe", "pipe"]
@@ -11155,21 +10844,37 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
11155
10844
  adminSettings: mockAdminSettings
11156
10845
  }
11157
10846
  };
11158
- const enabledB4mToolNames = [
10847
+ const toolConfig = {
11159
10848
  // Local-only tools (no external API keys needed)
11160
- "dice_roll",
11161
- "math_evaluate",
11162
- "current_datetime",
11163
- "prompt_enhancement",
10849
+ dice_roll: {},
10850
+ math_evaluate: {},
10851
+ current_datetime: {},
10852
+ prompt_enhancement: {},
10853
+ // File operation tools (CLI-specific, local execution)
10854
+ file_read: {},
10855
+ create_file: {},
10856
+ edit_local_file: {},
10857
+ glob_files: {},
10858
+ grep_search: {},
10859
+ delete_file: {},
10860
+ // Shell execution (always requires permission)
10861
+ bash_execute: {},
11164
10862
  // Server-side tools (executed via /api/ai/v1/tools Lambda)
11165
- "weather_info",
11166
- "web_search",
11167
- "web_fetch"
11168
- ];
11169
- const filteredB4mTools = Object.fromEntries(
11170
- enabledB4mToolNames.filter((name) => name in b4mTools).map((name) => [name, b4mTools[name]])
11171
- );
11172
- const tools_to_generate = { ...filteredB4mTools, ...cliOnlyTools };
10863
+ // Routed by ToolRouter to use B4M company API keys
10864
+ weather_info: {},
10865
+ web_search: {},
10866
+ web_fetch: {}
10867
+ // Disable web-only tools
10868
+ // blog_publish: undefined,
10869
+ // blog_edit: undefined,
10870
+ // blog_draft: undefined,
10871
+ // image_generation: undefined,
10872
+ // edit_image: undefined,
10873
+ // mermaid_chart: undefined,
10874
+ // recharts: undefined,
10875
+ // edit_file: undefined,
10876
+ // deep_research: undefined,
10877
+ };
11173
10878
  const toolsMap = generateTools(
11174
10879
  userId,
11175
10880
  user,
@@ -11182,18 +10887,17 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
11182
10887
  onStart,
11183
10888
  onFinish,
11184
10889
  llm,
11185
- {},
11186
- model,
11187
- tools_to_generate
10890
+ toolConfig,
10891
+ model
11188
10892
  );
11189
- let tools = Object.entries(toolsMap).map(
10893
+ let tools2 = Object.entries(toolsMap).filter(([key]) => toolConfig[key] !== void 0).map(
11190
10894
  ([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient)
11191
10895
  );
11192
10896
  if (toolFilter) {
11193
10897
  const { allowedTools, deniedTools } = toolFilter;
11194
10898
  const normalizedAllowed = allowedTools?.map(normalizeToolName);
11195
10899
  const normalizedDenied = deniedTools?.map(normalizeToolName);
11196
- tools = tools.filter((tool) => {
10900
+ tools2 = tools2.filter((tool) => {
11197
10901
  const toolName = tool.toolSchema.name;
11198
10902
  if (normalizedDenied && normalizedDenied.includes(toolName)) {
11199
10903
  return false;
@@ -11204,7 +10908,7 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
11204
10908
  return true;
11205
10909
  });
11206
10910
  }
11207
- return { tools, agentContext };
10911
+ return { tools: tools2, agentContext };
11208
10912
  }
11209
10913
 
11210
10914
  // src/config/toolSafety.ts
@@ -11643,9 +11347,9 @@ var TokenCounter = class {
11643
11347
  * Count tokens in tool schemas.
11644
11348
  * Tool schemas are sent as part of the API call and consume context.
11645
11349
  */
11646
- countToolSchemaTokens(tools) {
11647
- if (tools.length === 0) return 0;
11648
- const schemaText = tools.map(
11350
+ countToolSchemaTokens(tools2) {
11351
+ if (tools2.length === 0) return 0;
11352
+ const schemaText = tools2.map(
11649
11353
  ({ toolSchema }) => `Tool: ${toolSchema.name}
11650
11354
  Description: ${toolSchema.description}
11651
11355
  Parameters: ${JSON.stringify(toolSchema.parameters)}`
@@ -11947,14 +11651,14 @@ var McpManager = class {
11947
11651
  getTools: async () => client.tools,
11948
11652
  callTool: async (name, args) => client.callTool(name, args)
11949
11653
  };
11950
- const tools = await generateMcpTools(mcpData);
11654
+ const tools2 = await generateMcpTools(mcpData);
11951
11655
  this.servers.set(serverConfig.name, {
11952
11656
  name: serverConfig.name,
11953
11657
  client,
11954
- tools
11658
+ tools: tools2
11955
11659
  });
11956
11660
  this.connectionStates.set(serverConfig.name, "connected");
11957
- logger.debug(`\u2705 Connected to ${serverConfig.name} (${tools.length} tools)`);
11661
+ logger.debug(`\u2705 Connected to ${serverConfig.name} (${tools2.length} tools)`);
11958
11662
  } catch (error) {
11959
11663
  this.connectionStates.set(serverConfig.name, "failed");
11960
11664
  logger.debug(`\u274C Failed to connect to ${serverConfig.name}: ${error}`);
@@ -12839,7 +12543,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
12839
12543
  // package.json
12840
12544
  var package_default = {
12841
12545
  name: "@bike4mind/cli",
12842
- version: "0.2.24-recent-changes-tool.18468+3dfc3fcea",
12546
+ version: "0.2.24-sessions-command-bug-fix.18477+04624b930",
12843
12547
  type: "module",
12844
12548
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
12845
12549
  license: "UNLICENSED",
@@ -12947,10 +12651,10 @@ var package_default = {
12947
12651
  },
12948
12652
  devDependencies: {
12949
12653
  "@bike4mind/agents": "0.1.0",
12950
- "@bike4mind/common": "2.47.1-recent-changes-tool.18468+3dfc3fcea",
12951
- "@bike4mind/mcp": "1.27.1-recent-changes-tool.18468+3dfc3fcea",
12952
- "@bike4mind/services": "2.45.1-recent-changes-tool.18468+3dfc3fcea",
12953
- "@bike4mind/utils": "2.3.3-recent-changes-tool.18468+3dfc3fcea",
12654
+ "@bike4mind/common": "2.47.1-sessions-command-bug-fix.18477+04624b930",
12655
+ "@bike4mind/mcp": "1.27.1-sessions-command-bug-fix.18477+04624b930",
12656
+ "@bike4mind/services": "2.45.1-sessions-command-bug-fix.18477+04624b930",
12657
+ "@bike4mind/utils": "2.3.3-sessions-command-bug-fix.18477+04624b930",
12954
12658
  "@types/better-sqlite3": "^7.6.13",
12955
12659
  "@types/diff": "^5.0.9",
12956
12660
  "@types/jsonwebtoken": "^9.0.4",
@@ -12967,7 +12671,7 @@ var package_default = {
12967
12671
  optionalDependencies: {
12968
12672
  "@vscode/ripgrep": "^1.17.0"
12969
12673
  },
12970
- gitHead: "3dfc3fcea60259000ed1bfe1ad362f3137f9725c"
12674
+ gitHead: "04624b930f0d41ba258c04002f4047fe0b249a29"
12971
12675
  };
12972
12676
 
12973
12677
  // src/config/constants.ts
@@ -14250,7 +13954,7 @@ function CliApp() {
14250
13954
  currentAgent: null,
14251
13955
  observationQueue: []
14252
13956
  };
14253
- const { tools: b4mTools2 } = generateCliTools(
13957
+ const { tools: b4mTools } = generateCliTools(
14254
13958
  config.userId,
14255
13959
  llm,
14256
13960
  modelInfo.id,
@@ -14260,7 +13964,7 @@ function CliApp() {
14260
13964
  state.configStore,
14261
13965
  apiClient
14262
13966
  );
14263
- console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
13967
+ console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
14264
13968
  const mcpManager = new McpManager(config);
14265
13969
  await mcpManager.initialize();
14266
13970
  const mcpTools = mcpManager.getTools();
@@ -14301,7 +14005,7 @@ function CliApp() {
14301
14005
  if (skillTool) {
14302
14006
  cliTools.push(skillTool);
14303
14007
  }
14304
- const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
14008
+ const allTools = [...b4mTools, ...mcpTools, ...cliTools];
14305
14009
  console.log(`\u{1F4C2} Working directory: ${process.cwd()}`);
14306
14010
  console.log(`\u{1F916} Subagent delegation enabled (explore, plan, review)`);
14307
14011
  if (skillTool) {
@@ -14311,7 +14015,7 @@ function CliApp() {
14311
14015
  }
14312
14016
  }
14313
14017
  logger.debug(
14314
- `Total tools available to agent: ${allTools.length} (${b4mTools2.length} B4M + ${mcpTools.length} MCP + ${cliTools.length} CLI)`
14018
+ `Total tools available to agent: ${allTools.length} (${b4mTools.length} B4M + ${mcpTools.length} MCP + ${cliTools.length} CLI)`
14315
14019
  );
14316
14020
  const projectDir = state.configStore.getProjectConfigDir();
14317
14021
  const contextResult = await loadContextFiles(projectDir);
@@ -14990,13 +14694,17 @@ Custom Commands:
14990
14694
  console.log("No active session to save");
14991
14695
  return;
14992
14696
  }
14697
+ if (state.session.messages.length === 0) {
14698
+ console.log("\u274C Cannot save session with no messages");
14699
+ return;
14700
+ }
14993
14701
  const sessionName = args.join(" ") || state.session.name;
14994
14702
  state.session.name = sessionName;
14995
14703
  await state.sessionStore.save(state.session);
14996
14704
  console.log(`\u2705 Session saved as "${sessionName}"`);
14997
14705
  break;
14998
14706
  case "sessions": {
14999
- const sessions = await state.sessionStore.list();
14707
+ const sessions = await state.sessionStore.list(20);
15000
14708
  if (sessions.length === 0) {
15001
14709
  console.log("\n\u{1F4DA} No saved sessions found.");
15002
14710
  console.log("\u{1F4A1} Use /save <name> to save your current session.\n");
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-37CKEEXO.js";
4
+ } from "./chunk-LOIWIBZT.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-37CKEEXO.js";
4
+ } from "./chunk-LOIWIBZT.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-QCZ7HG2D.js";
6
- import "./chunk-KC235R6G.js";
7
- import "./chunk-37CKEEXO.js";
5
+ } from "./chunk-FV2VQXYX.js";
6
+ import "./chunk-XFN2ICKP.js";
7
+ import "./chunk-LOIWIBZT.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  findMostSimilarMemento,
@@ -132,8 +132,8 @@ import {
132
132
  validateMermaidSyntax,
133
133
  warmUpSettingsCache,
134
134
  withRetry
135
- } from "./chunk-KC235R6G.js";
136
- import "./chunk-37CKEEXO.js";
135
+ } from "./chunk-XFN2ICKP.js";
136
+ import "./chunk-LOIWIBZT.js";
137
137
  import {
138
138
  Logger,
139
139
  NotificationDeduplicator,
@@ -333,7 +333,7 @@ import {
333
333
  validateReactArtifactV2,
334
334
  validateSvgArtifactV2,
335
335
  wikiMarkupToAdf
336
- } from "./chunk-37CKEEXO.js";
336
+ } from "./chunk-LOIWIBZT.js";
337
337
  export {
338
338
  ALL_IMAGE_MODELS,
339
339
  ALL_IMAGE_SIZES,
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  SubtractCreditsSchema,
4
4
  subtractCredits
5
- } from "./chunk-5ACUY24Z.js";
6
- import "./chunk-KC235R6G.js";
7
- import "./chunk-37CKEEXO.js";
5
+ } from "./chunk-JHCQOESZ.js";
6
+ import "./chunk-XFN2ICKP.js";
7
+ import "./chunk-LOIWIBZT.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.24-recent-changes-tool.18468+3dfc3fcea",
3
+ "version": "0.2.24-sessions-command-bug-fix.18477+04624b930",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -108,10 +108,10 @@
108
108
  },
109
109
  "devDependencies": {
110
110
  "@bike4mind/agents": "0.1.0",
111
- "@bike4mind/common": "2.47.1-recent-changes-tool.18468+3dfc3fcea",
112
- "@bike4mind/mcp": "1.27.1-recent-changes-tool.18468+3dfc3fcea",
113
- "@bike4mind/services": "2.45.1-recent-changes-tool.18468+3dfc3fcea",
114
- "@bike4mind/utils": "2.3.3-recent-changes-tool.18468+3dfc3fcea",
111
+ "@bike4mind/common": "2.47.1-sessions-command-bug-fix.18477+04624b930",
112
+ "@bike4mind/mcp": "1.27.1-sessions-command-bug-fix.18477+04624b930",
113
+ "@bike4mind/services": "2.45.1-sessions-command-bug-fix.18477+04624b930",
114
+ "@bike4mind/utils": "2.3.3-sessions-command-bug-fix.18477+04624b930",
115
115
  "@types/better-sqlite3": "^7.6.13",
116
116
  "@types/diff": "^5.0.9",
117
117
  "@types/jsonwebtoken": "^9.0.4",
@@ -128,5 +128,5 @@
128
128
  "optionalDependencies": {
129
129
  "@vscode/ripgrep": "^1.17.0"
130
130
  },
131
- "gitHead": "3dfc3fcea60259000ed1bfe1ad362f3137f9725c"
131
+ "gitHead": "04624b930f0d41ba258c04002f4047fe0b249a29"
132
132
  }