@bike4mind/cli 0.2.11-cli-cancel-pending-message.17327 → 0.2.11-cli-todo-list.17329
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ImageStore-RQZ7OF7P.js → ImageStore-MMUOUPI2.js} +0 -1
- package/dist/{artifactExtractor-BZNU5FMW.js → artifactExtractor-5XROR32D.js} +0 -1
- package/dist/{chunk-DGAIF2QC.js → chunk-6AYWWNXH.js} +1 -1
- package/dist/{chunk-RA3CZOUX.js → chunk-GLQV2QBP.js} +1 -1
- package/dist/{chunk-SQBLLN7K.js → chunk-M4EAFD3H.js} +1 -1
- package/dist/{chunk-AMDXHL6S.js → chunk-OCYRD7D6.js} +1 -1
- package/dist/{chunk-RBZRTCAY.js → chunk-WENSCUXW.js} +1 -1
- package/dist/{create-4KCG4N2U.js → create-AYJ2FUMX.js} +3 -4
- package/dist/{formatConverter-I7EIUVDY.js → formatConverter-5QEJDW24.js} +0 -1
- package/dist/index.js +348 -256
- package/dist/{llmMarkdownGenerator-TUFLBYA3.js → llmMarkdownGenerator-3VB77TGN.js} +0 -1
- package/dist/{markdownGenerator-2WSEU4QD.js → markdownGenerator-6CDF26SR.js} +0 -1
- package/dist/{mementoService-75KFGFQT.js → mementoService-YHQGUY3M.js} +3 -4
- package/dist/{notificationDeduplicator-UW7D75QS.js → notificationDeduplicator-UTHJHMSZ.js} +1 -2
- package/dist/{src-JZRDAJFC.js → src-ROS3BMWE.js} +2 -3
- package/dist/{src-UHKJ3EHY.js → src-VOMQHSNW.js} +0 -1
- package/dist/{subtractCredits-MOVABDWW.js → subtractCredits-EGQGB7MG.js} +3 -4
- package/dist/{utils-JPMDGUBL.js → utils-JCHWDM4Z.js} +0 -1
- package/package.json +7 -6
- package/dist/chunk-PDX44BCA.js +0 -11
|
@@ -160,7 +160,7 @@ var notifyEventLogsToSlack = async ({ event, stage, slackUrl, throttlingSlackUrl
|
|
|
160
160
|
if (!allowedStages.includes(stage))
|
|
161
161
|
return;
|
|
162
162
|
const logEvents = logData.logEvents;
|
|
163
|
-
const { notificationDeduplicator: notificationDeduplicator2 } = await import("./notificationDeduplicator-
|
|
163
|
+
const { notificationDeduplicator: notificationDeduplicator2 } = await import("./notificationDeduplicator-UTHJHMSZ.js");
|
|
164
164
|
for (const logEvent of logEvents) {
|
|
165
165
|
try {
|
|
166
166
|
let message;
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-GLQV2QBP.js";
|
|
6
|
+
import "./chunk-M4EAFD3H.js";
|
|
7
|
+
import "./chunk-OCYRD7D6.js";
|
|
8
8
|
import "./chunk-WCYNJOOX.js";
|
|
9
|
-
import "./chunk-PDX44BCA.js";
|
|
10
9
|
export {
|
|
11
10
|
createFabFile,
|
|
12
11
|
createFabFileSchema
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getEffectiveApiKey,
|
|
5
5
|
getOpenWeatherKey,
|
|
6
6
|
getSerperKey
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-6AYWWNXH.js";
|
|
8
|
+
import "./chunk-WENSCUXW.js";
|
|
9
|
+
import "./chunk-GLQV2QBP.js";
|
|
10
10
|
import {
|
|
11
11
|
BFLImageService,
|
|
12
12
|
BaseStorage,
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
OpenAIBackend,
|
|
16
16
|
OpenAIImageService,
|
|
17
17
|
XAIImageService
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-M4EAFD3H.js";
|
|
19
19
|
import {
|
|
20
20
|
Logger
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-OCYRD7D6.js";
|
|
22
22
|
import "./chunk-BPFEGDC7.js";
|
|
23
23
|
import {
|
|
24
24
|
AiEvents,
|
|
@@ -74,9 +74,6 @@ import {
|
|
|
74
74
|
b4mLLMTools,
|
|
75
75
|
getMcpProviderMetadata
|
|
76
76
|
} from "./chunk-WCYNJOOX.js";
|
|
77
|
-
import {
|
|
78
|
-
__require
|
|
79
|
-
} from "./chunk-PDX44BCA.js";
|
|
80
77
|
|
|
81
78
|
// src/index.tsx
|
|
82
79
|
import React17, { useState as useState8, useEffect as useEffect3, useCallback, useRef as useRef2 } from "react";
|
|
@@ -3376,6 +3373,15 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
3376
3373
|
};
|
|
3377
3374
|
|
|
3378
3375
|
// src/core/prompts.ts
|
|
3376
|
+
var TOOL_GREP_SEARCH = "grep_search";
|
|
3377
|
+
var TOOL_GLOB_FILES = "glob_files";
|
|
3378
|
+
var TOOL_FILE_READ = "file_read";
|
|
3379
|
+
var TOOL_EDIT_LOCAL_FILE = "edit_local_file";
|
|
3380
|
+
var TOOL_CREATE_FILE = "create_file";
|
|
3381
|
+
var TOOL_BASH_EXECUTE = "bash_execute";
|
|
3382
|
+
var TOOL_SUBAGENT_DELEGATE = "subagent_delegate";
|
|
3383
|
+
var TOOL_WRITE_TODOS = "write_todos";
|
|
3384
|
+
var EXPLORE_SUBAGENT_TYPE = "explore";
|
|
3379
3385
|
function buildCoreSystemPrompt(contextSection = "") {
|
|
3380
3386
|
return `You are an autonomous AI assistant with access to tools. Your job is to help users by taking action and solving problems proactively.
|
|
3381
3387
|
|
|
@@ -3387,15 +3393,17 @@ CORE BEHAVIOR:
|
|
|
3387
3393
|
|
|
3388
3394
|
FOR SOFTWARE ENGINEERING TASKS:
|
|
3389
3395
|
When requested to perform tasks like fixing bugs, adding features, refactoring, or explaining code, follow this sequence:
|
|
3390
|
-
1. **Understand:** Think about the user's request and the relevant codebase context. Use '
|
|
3396
|
+
1. **Understand:** Think about the user's request and the relevant codebase context. Use '${TOOL_GREP_SEARCH}' and '${TOOL_GLOB_FILES}' search tools extensively (in parallel if independent) to understand file structures, existing code patterns, and conventions. Use '${TOOL_FILE_READ}' to understand context and validate any assumptions you may have. If you need to read multiple files, you should make multiple parallel calls to '${TOOL_FILE_READ}'.
|
|
3397
|
+
When the task involves **complex refactoring, codebase exploration or system-wide analysis**, your **first and primary action** must be to delegate to the '${EXPLORE_SUBAGENT_TYPE}' agent using the '${TOOL_SUBAGENT_DELEGATE}' tool. Use it to build a comprehensive understanding of the code, its structure, and dependencies. For **simple, targeted searches** (like finding a specific function name, file path, or variable declaration), you should use '${TOOL_GREP_SEARCH}' or '${TOOL_GLOB_FILES}' directly.
|
|
3391
3398
|
2. **Plan:** Build a coherent and grounded (based on the understanding in step 1) plan for how you intend to resolve the user's task. Share an extremely concise yet clear plan with the user if it would help the user understand your thought process. As part of the plan, you should use an iterative development process that includes writing unit tests to verify your changes. Use output logs or debug statements as part of this process to arrive at a solution.
|
|
3392
|
-
|
|
3399
|
+
If '${EXPLORE_SUBAGENT_TYPE}' subagent was used, do not ignore the output of the agent, you must use it as the foundation of your plan. For complex tasks, break them down into smaller, manageable subtasks and use the \`${TOOL_WRITE_TODOS}\` tool to track your progress. Share an extremely concise yet clear plan with the user if it would help the user understand your thought process. As part of the plan, you should use an iterative development process that includes writing unit tests to verify your changes. Use output logs or debug statements as part of this process to arrive at a solution.
|
|
3400
|
+
3. **Implement:** Use the available tools (e.g., '${TOOL_EDIT_LOCAL_FILE}', '${TOOL_CREATE_FILE}', '${TOOL_BASH_EXECUTE}' ...) to act on the plan, strictly adhering to the project's established conventions.
|
|
3393
3401
|
4. **Verify (Tests):** If applicable and feasible, verify the changes using the project's testing procedures. Identify the correct test commands and frameworks by examining 'README' files, build/package configuration (e.g., 'package.json'), or existing test execution patterns. NEVER assume standard test commands. When executing test commands, prefer "run once" or "CI" modes to ensure the command terminates after completion.
|
|
3394
3402
|
5. **Verify (Standards):** VERY IMPORTANT: After making code changes, execute the project-specific build, linting and type-checking commands (e.g., 'tsc', 'npm run lint', 'ruff check .') that you have identified for this project (or obtained from the user). This ensures code quality and adherence to standards.
|
|
3395
3403
|
6. **Finalize:** After all verification passes, consider the task complete. Do not remove or revert any changes or created files (like tests). Await the user's next instruction.
|
|
3396
3404
|
|
|
3397
3405
|
SUBAGENT DELEGATION:
|
|
3398
|
-
- You have access to specialized subagents via the
|
|
3406
|
+
- You have access to specialized subagents via the ${TOOL_SUBAGENT_DELEGATE} tool
|
|
3399
3407
|
- Use subagents for focused exploration, planning, or review tasks:
|
|
3400
3408
|
* explore: Fast read-only codebase search (e.g., "find all auth files", "locate API endpoints")
|
|
3401
3409
|
* plan: Break down complex tasks into actionable steps
|
|
@@ -3411,7 +3419,7 @@ FOR GENERAL TASKS:
|
|
|
3411
3419
|
## Shell tool output token efficiency:
|
|
3412
3420
|
IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION.
|
|
3413
3421
|
|
|
3414
|
-
- Always prefer command flags that reduce output verbosity when using '
|
|
3422
|
+
- Always prefer command flags that reduce output verbosity when using '${TOOL_BASH_EXECUTE}'.
|
|
3415
3423
|
- Aim to minimize tool output tokens while still capturing necessary information.
|
|
3416
3424
|
- If a command is expected to produce a lot of output, use quiet or silent flags where available and appropriate.
|
|
3417
3425
|
- Always consider the trade-off between output verbosity and the need for information. If a command's full output is essential for understanding the result, avoid overly aggressive quieting that might obscure important details.
|
|
@@ -3421,9 +3429,9 @@ IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION.
|
|
|
3421
3429
|
EXAMPLES:
|
|
3422
3430
|
- "what should I wear in Texas?" \u2192 use weather tool for Texas
|
|
3423
3431
|
- "how about Japan?" \u2192 use weather tool for Japan (applying same question from context)
|
|
3424
|
-
- "enhance README" \u2192
|
|
3425
|
-
- "what packages installed?" \u2192
|
|
3426
|
-
- "find all components using React hooks" \u2192
|
|
3432
|
+
- "enhance README" \u2192 ${TOOL_FILE_READ} \u2192 generate \u2192 ${TOOL_EDIT_LOCAL_FILE}
|
|
3433
|
+
- "what packages installed?" \u2192 ${TOOL_GLOB_FILES} "**/package.json" \u2192 ${TOOL_FILE_READ}
|
|
3434
|
+
- "find all components using React hooks" \u2192 ${TOOL_SUBAGENT_DELEGATE}(task="find all components using React hooks", type="explore")
|
|
3427
3435
|
|
|
3428
3436
|
Remember: Use context from previous messages to understand follow-up questions.${contextSection}`;
|
|
3429
3437
|
}
|
|
@@ -8779,98 +8787,80 @@ var createFileTool = {
|
|
|
8779
8787
|
};
|
|
8780
8788
|
|
|
8781
8789
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
|
|
8782
|
-
import {
|
|
8783
|
-
import {
|
|
8790
|
+
import { glob } from "glob";
|
|
8791
|
+
import { stat } from "fs/promises";
|
|
8784
8792
|
import path9 from "path";
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
if (!includeHidden && entry.name.startsWith(".")) {
|
|
8800
|
-
continue;
|
|
8801
|
-
}
|
|
8802
|
-
const relativePath = basePath ? path9.join(basePath, entry.name) : entry.name;
|
|
8803
|
-
const fullPath = path9.join(dir, entry.name);
|
|
8804
|
-
if (matchGlob(relativePath, pattern)) {
|
|
8805
|
-
matches.push(relativePath);
|
|
8806
|
-
}
|
|
8807
|
-
if (entry.isDirectory() && (pattern.includes("**") || pattern.includes("/"))) {
|
|
8808
|
-
const subMatches = await walkDir(fullPath, pattern, includeHidden, maxResults - matches.length, relativePath);
|
|
8809
|
-
matches.push(...subMatches);
|
|
8810
|
-
}
|
|
8811
|
-
}
|
|
8812
|
-
} catch (error) {
|
|
8813
|
-
}
|
|
8814
|
-
return matches;
|
|
8815
|
-
}
|
|
8816
|
-
async function listFiles(params) {
|
|
8817
|
-
const { pattern, cwd: relativeCwd, includeHidden = false, maxResults = 1e3 } = params;
|
|
8793
|
+
var DEFAULT_IGNORE_PATTERNS2 = [
|
|
8794
|
+
"**/node_modules/**",
|
|
8795
|
+
"**/.git/**",
|
|
8796
|
+
"**/dist/**",
|
|
8797
|
+
"**/build/**",
|
|
8798
|
+
"**/.next/**",
|
|
8799
|
+
"**/coverage/**",
|
|
8800
|
+
"**/.turbo/**",
|
|
8801
|
+
"**/.sst/**",
|
|
8802
|
+
"**/*.min.js",
|
|
8803
|
+
"**/*.min.css"
|
|
8804
|
+
];
|
|
8805
|
+
async function findFiles(params) {
|
|
8806
|
+
const { pattern, dir_path, case_sensitive = true, respect_git_ignore = true } = params;
|
|
8818
8807
|
const baseCwd = process.cwd();
|
|
8819
|
-
const
|
|
8820
|
-
if (!
|
|
8821
|
-
throw new Error(`Access denied: Cannot
|
|
8822
|
-
}
|
|
8823
|
-
const
|
|
8808
|
+
const targetDir = dir_path ? path9.resolve(baseCwd, path9.normalize(dir_path)) : baseCwd;
|
|
8809
|
+
if (!targetDir.startsWith(baseCwd)) {
|
|
8810
|
+
throw new Error(`Access denied: Cannot search outside of current working directory`);
|
|
8811
|
+
}
|
|
8812
|
+
const ignorePatterns = respect_git_ignore ? DEFAULT_IGNORE_PATTERNS2 : [];
|
|
8813
|
+
const matches = await glob(pattern, {
|
|
8814
|
+
cwd: targetDir,
|
|
8815
|
+
dot: false,
|
|
8816
|
+
// Don't match hidden files by default
|
|
8817
|
+
ignore: ignorePatterns,
|
|
8818
|
+
absolute: true,
|
|
8819
|
+
nodir: true,
|
|
8820
|
+
// Only return files, not directories
|
|
8821
|
+
nocase: !case_sensitive,
|
|
8822
|
+
// Case-insensitive if requested
|
|
8823
|
+
maxDepth: 20
|
|
8824
|
+
// Reasonable depth limit
|
|
8825
|
+
});
|
|
8824
8826
|
if (matches.length === 0) {
|
|
8825
|
-
return `No files found matching pattern: ${pattern}`;
|
|
8827
|
+
return `No files found matching pattern: ${pattern}${dir_path ? ` in ${dir_path}` : ""}`;
|
|
8826
8828
|
}
|
|
8827
|
-
const
|
|
8828
|
-
for (const
|
|
8829
|
+
const filesWithStats = [];
|
|
8830
|
+
for (const filePath of matches) {
|
|
8829
8831
|
try {
|
|
8830
|
-
const
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
size: stats.size,
|
|
8835
|
-
isDirectory: stats.isDirectory(),
|
|
8836
|
-
modified: stats.mtime.toISOString()
|
|
8832
|
+
const stats = await stat(filePath);
|
|
8833
|
+
filesWithStats.push({
|
|
8834
|
+
path: filePath,
|
|
8835
|
+
mtime: stats.mtimeMs
|
|
8837
8836
|
});
|
|
8838
|
-
} catch
|
|
8837
|
+
} catch {
|
|
8839
8838
|
continue;
|
|
8840
8839
|
}
|
|
8841
8840
|
}
|
|
8842
|
-
|
|
8843
|
-
const
|
|
8844
|
-
|
|
8845
|
-
const
|
|
8846
|
-
` : ""
|
|
8847
|
-
const
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
return `${summary}${cwdInfo}
|
|
8841
|
+
filesWithStats.sort((a, b) => b.mtime - a.mtime);
|
|
8842
|
+
const MAX_RESULTS = 500;
|
|
8843
|
+
const truncated = filesWithStats.length > MAX_RESULTS;
|
|
8844
|
+
const results = truncated ? filesWithStats.slice(0, MAX_RESULTS) : filesWithStats;
|
|
8845
|
+
const summary = `Found ${filesWithStats.length} file(s)${truncated ? ` (showing first ${MAX_RESULTS})` : ""} matching: ${pattern}`;
|
|
8846
|
+
const dirInfo = dir_path ? `
|
|
8847
|
+
Directory: ${dir_path}` : "";
|
|
8848
|
+
const filesList = results.map((file) => path9.relative(baseCwd, file.path)).join("\n");
|
|
8849
|
+
return `${summary}${dirInfo}
|
|
8850
|
+
|
|
8853
8851
|
${filesList}`;
|
|
8854
8852
|
}
|
|
8855
|
-
function formatBytes(bytes) {
|
|
8856
|
-
if (bytes === 0)
|
|
8857
|
-
return "0 B";
|
|
8858
|
-
const k = 1024;
|
|
8859
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
8860
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
8861
|
-
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
|
8862
|
-
}
|
|
8863
8853
|
var globFilesTool = {
|
|
8864
8854
|
name: "glob_files",
|
|
8865
8855
|
implementation: (context) => ({
|
|
8866
8856
|
toolFn: async (value) => {
|
|
8867
8857
|
const params = value;
|
|
8868
|
-
context.logger.info("\u{1F50D} GlobFiles:
|
|
8858
|
+
context.logger.info("\u{1F50D} GlobFiles: Finding files", {
|
|
8869
8859
|
pattern: params.pattern,
|
|
8870
|
-
|
|
8860
|
+
dir_path: params.dir_path || "."
|
|
8871
8861
|
});
|
|
8872
8862
|
try {
|
|
8873
|
-
const result = await
|
|
8863
|
+
const result = await findFiles(params);
|
|
8874
8864
|
context.logger.info("\u2705 GlobFiles: Success");
|
|
8875
8865
|
return result;
|
|
8876
8866
|
} catch (error) {
|
|
@@ -8880,25 +8870,25 @@ var globFilesTool = {
|
|
|
8880
8870
|
},
|
|
8881
8871
|
toolSchema: {
|
|
8882
8872
|
name: "glob_files",
|
|
8883
|
-
description: "
|
|
8873
|
+
description: "Efficiently finds files matching specific glob patterns (e.g., `src/**/*.ts`, `**/*.md`), returning absolute paths sorted by modification time (newest first). Use this to locate files by name or extension when you need to discover or explore files in a project.",
|
|
8884
8874
|
parameters: {
|
|
8885
8875
|
type: "object",
|
|
8886
8876
|
properties: {
|
|
8887
8877
|
pattern: {
|
|
8888
8878
|
type: "string",
|
|
8889
|
-
description: '
|
|
8879
|
+
description: 'The glob pattern to match against file paths. Supports wildcards (*, **), character ranges ([abc]), and brace expansion ({ts,tsx}). Examples: "*.ts" for TypeScript files in current dir, "src/**/*.tsx" for all TSX files in src tree, "**/*.{js,ts}" for all JS/TS files.'
|
|
8890
8880
|
},
|
|
8891
|
-
|
|
8881
|
+
dir_path: {
|
|
8892
8882
|
type: "string",
|
|
8893
|
-
description: "
|
|
8883
|
+
description: "Optional: The absolute path to the directory to search in. If not specified, uses the current working directory. Must be within the current working directory."
|
|
8894
8884
|
},
|
|
8895
|
-
|
|
8885
|
+
case_sensitive: {
|
|
8896
8886
|
type: "boolean",
|
|
8897
|
-
description: "
|
|
8887
|
+
description: "Optional: Whether the pattern matching should be case-sensitive. Defaults to true. Set to false for case-insensitive matching on case-sensitive file systems."
|
|
8898
8888
|
},
|
|
8899
|
-
|
|
8900
|
-
type: "
|
|
8901
|
-
description: "
|
|
8889
|
+
respect_git_ignore: {
|
|
8890
|
+
type: "boolean",
|
|
8891
|
+
description: "Optional: Whether to respect common ignore patterns (node_modules, .git, dist, build, etc.). Defaults to true. Set to false to include all files."
|
|
8902
8892
|
}
|
|
8903
8893
|
},
|
|
8904
8894
|
required: ["pattern"]
|
|
@@ -8908,158 +8898,144 @@ var globFilesTool = {
|
|
|
8908
8898
|
};
|
|
8909
8899
|
|
|
8910
8900
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
|
|
8911
|
-
import {
|
|
8912
|
-
import {
|
|
8901
|
+
import { globStream } from "glob";
|
|
8902
|
+
import { readFile, stat as stat2 } from "fs/promises";
|
|
8913
8903
|
import path10 from "path";
|
|
8914
8904
|
var MAX_FILE_SIZE3 = 10 * 1024 * 1024;
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8905
|
+
var DEFAULT_IGNORE_PATTERNS3 = [
|
|
8906
|
+
"**/node_modules/**",
|
|
8907
|
+
"**/.git/**",
|
|
8908
|
+
"**/dist/**",
|
|
8909
|
+
"**/build/**",
|
|
8910
|
+
"**/.next/**",
|
|
8911
|
+
"**/coverage/**",
|
|
8912
|
+
"**/*.min.js",
|
|
8913
|
+
"**/*.min.css",
|
|
8914
|
+
"**/package-lock.json",
|
|
8915
|
+
"**/pnpm-lock.yaml",
|
|
8916
|
+
"**/yarn.lock"
|
|
8917
|
+
];
|
|
8918
|
+
async function isBinaryFile2(filePath) {
|
|
8922
8919
|
try {
|
|
8923
|
-
const
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
8930
|
-
|
|
8931
|
-
|
|
8932
|
-
const fullPath = path10.join(dir, entry.name);
|
|
8933
|
-
if (matchGlob2(relativePath, pattern)) {
|
|
8934
|
-
matches.push(relativePath);
|
|
8935
|
-
}
|
|
8936
|
-
if (entry.isDirectory() && (pattern.includes("**") || pattern.includes("/"))) {
|
|
8937
|
-
const subMatches = await walkDir2(fullPath, pattern, maxResults - matches.length, relativePath);
|
|
8938
|
-
matches.push(...subMatches);
|
|
8939
|
-
}
|
|
8940
|
-
}
|
|
8941
|
-
} catch (error) {
|
|
8920
|
+
const { openSync, readSync, closeSync } = await import("fs");
|
|
8921
|
+
const buffer = Buffer.alloc(8192);
|
|
8922
|
+
const fd = openSync(filePath, "r");
|
|
8923
|
+
const bytesRead = readSync(fd, buffer, 0, 8192, 0);
|
|
8924
|
+
closeSync(fd);
|
|
8925
|
+
const chunk = buffer.slice(0, bytesRead);
|
|
8926
|
+
return chunk.includes(0);
|
|
8927
|
+
} catch {
|
|
8928
|
+
return true;
|
|
8942
8929
|
}
|
|
8943
|
-
|
|
8930
|
+
}
|
|
8931
|
+
function isPathWithinWorkspace(targetPath, baseCwd) {
|
|
8932
|
+
const resolvedTarget = path10.resolve(targetPath);
|
|
8933
|
+
const resolvedBase = path10.resolve(baseCwd);
|
|
8934
|
+
return resolvedTarget.startsWith(resolvedBase);
|
|
8944
8935
|
}
|
|
8945
8936
|
async function searchFiles2(params) {
|
|
8946
|
-
const { pattern,
|
|
8937
|
+
const { pattern, dir_path, include } = params;
|
|
8947
8938
|
const baseCwd = process.cwd();
|
|
8948
|
-
const
|
|
8949
|
-
if (!
|
|
8950
|
-
throw new Error(`
|
|
8939
|
+
const targetDir = dir_path ? path10.resolve(baseCwd, dir_path) : baseCwd;
|
|
8940
|
+
if (!isPathWithinWorkspace(targetDir, baseCwd)) {
|
|
8941
|
+
throw new Error(`Path validation failed: "${dir_path}" resolves outside the allowed workspace directory`);
|
|
8942
|
+
}
|
|
8943
|
+
try {
|
|
8944
|
+
const stats = await stat2(targetDir);
|
|
8945
|
+
if (!stats.isDirectory()) {
|
|
8946
|
+
throw new Error(`Path is not a directory: ${dir_path}`);
|
|
8947
|
+
}
|
|
8948
|
+
} catch (error) {
|
|
8949
|
+
if (error.code === "ENOENT") {
|
|
8950
|
+
throw new Error(`Path does not exist: ${dir_path}`);
|
|
8951
|
+
}
|
|
8952
|
+
throw error;
|
|
8951
8953
|
}
|
|
8952
8954
|
let searchRegex;
|
|
8953
8955
|
try {
|
|
8954
|
-
|
|
8955
|
-
searchRegex = new RegExp(pattern, flags);
|
|
8956
|
+
searchRegex = new RegExp(pattern, "i");
|
|
8956
8957
|
} catch (error) {
|
|
8957
8958
|
throw new Error(`Invalid regex pattern: ${pattern}`);
|
|
8958
8959
|
}
|
|
8959
|
-
const
|
|
8960
|
-
const
|
|
8961
|
-
|
|
8962
|
-
|
|
8960
|
+
const globPattern = include || "**/*";
|
|
8961
|
+
const filesStream = globStream(globPattern, {
|
|
8962
|
+
cwd: targetDir,
|
|
8963
|
+
dot: false,
|
|
8964
|
+
// Skip hidden files
|
|
8965
|
+
ignore: DEFAULT_IGNORE_PATTERNS3,
|
|
8966
|
+
absolute: true,
|
|
8967
|
+
nodir: true
|
|
8968
|
+
// Only match files, not directories
|
|
8969
|
+
});
|
|
8970
|
+
const allMatches = [];
|
|
8971
|
+
let filesSearched = 0;
|
|
8972
|
+
const maxMatches = 500;
|
|
8973
|
+
for await (const filePath of filesStream) {
|
|
8974
|
+
if (allMatches.length >= maxMatches) {
|
|
8975
|
+
break;
|
|
8976
|
+
}
|
|
8977
|
+
const fileAbsPath = filePath;
|
|
8963
8978
|
try {
|
|
8964
|
-
const stats =
|
|
8965
|
-
if (stats.
|
|
8979
|
+
const stats = await stat2(fileAbsPath);
|
|
8980
|
+
if (stats.size > MAX_FILE_SIZE3) {
|
|
8966
8981
|
continue;
|
|
8967
8982
|
}
|
|
8968
|
-
if (isBinaryFile2(
|
|
8983
|
+
if (await isBinaryFile2(fileAbsPath)) {
|
|
8969
8984
|
continue;
|
|
8970
8985
|
}
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
for (const file of filteredFiles) {
|
|
8982
|
-
if (matches.length >= maxResults) {
|
|
8983
|
-
break;
|
|
8984
|
-
}
|
|
8985
|
-
filesSearched++;
|
|
8986
|
-
const fullPath = path10.join(targetCwd, file);
|
|
8987
|
-
try {
|
|
8988
|
-
const content = readFileSync3(fullPath, "utf-8");
|
|
8989
|
-
const lines = content.split("\n");
|
|
8990
|
-
for (let i = 0; i < lines.length; i++) {
|
|
8991
|
-
if (matches.length >= maxResults) {
|
|
8992
|
-
break;
|
|
8993
|
-
}
|
|
8994
|
-
const line = lines[i];
|
|
8995
|
-
if (searchRegex.test(line)) {
|
|
8996
|
-
const match = {
|
|
8997
|
-
file,
|
|
8998
|
-
line: i + 1,
|
|
8999
|
-
// 1-indexed line numbers
|
|
9000
|
-
content: line.trim()
|
|
9001
|
-
};
|
|
9002
|
-
if (contextLines > 0) {
|
|
9003
|
-
const before = [];
|
|
9004
|
-
const after = [];
|
|
9005
|
-
for (let j = Math.max(0, i - contextLines); j < i; j++) {
|
|
9006
|
-
before.push(lines[j]);
|
|
9007
|
-
}
|
|
9008
|
-
for (let j = i + 1; j <= Math.min(lines.length - 1, i + contextLines); j++) {
|
|
9009
|
-
after.push(lines[j]);
|
|
9010
|
-
}
|
|
9011
|
-
match.context = { before, after };
|
|
9012
|
-
}
|
|
9013
|
-
matches.push(match);
|
|
8986
|
+
filesSearched++;
|
|
8987
|
+
const content = await readFile(fileAbsPath, "utf8");
|
|
8988
|
+
const lines = content.split(/\r?\n/);
|
|
8989
|
+
lines.forEach((line, index) => {
|
|
8990
|
+
if (allMatches.length < maxMatches && searchRegex.test(line)) {
|
|
8991
|
+
allMatches.push({
|
|
8992
|
+
filePath: path10.relative(targetDir, fileAbsPath) || path10.basename(fileAbsPath),
|
|
8993
|
+
lineNumber: index + 1,
|
|
8994
|
+
line
|
|
8995
|
+
});
|
|
9014
8996
|
}
|
|
9015
|
-
|
|
8997
|
+
});
|
|
8998
|
+
} catch (readError) {
|
|
8999
|
+
const errCode = readError.code;
|
|
9000
|
+
if (errCode !== "ENOENT" && errCode !== "EACCES") {
|
|
9001
|
+
console.debug(`Could not read ${fileAbsPath}: ${readError.message}`);
|
|
9016
9002
|
}
|
|
9017
|
-
} catch {
|
|
9018
|
-
continue;
|
|
9019
9003
|
}
|
|
9020
9004
|
}
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9005
|
+
const searchDirDisplay = dir_path || ".";
|
|
9006
|
+
const filterInfo = include ? ` (filter: "${include}")` : "";
|
|
9007
|
+
if (allMatches.length === 0) {
|
|
9008
|
+
return `No matches found for pattern "${pattern}" in "${searchDirDisplay}"${filterInfo}.
|
|
9009
|
+
Searched ${filesSearched} file(s).`;
|
|
9024
9010
|
}
|
|
9025
|
-
const
|
|
9026
|
-
|
|
9011
|
+
const matchesByFile = allMatches.reduce((acc, match) => {
|
|
9012
|
+
if (!acc[match.filePath]) {
|
|
9013
|
+
acc[match.filePath] = [];
|
|
9014
|
+
}
|
|
9015
|
+
acc[match.filePath].push(match);
|
|
9016
|
+
acc[match.filePath].sort((a, b) => a.lineNumber - b.lineNumber);
|
|
9017
|
+
return acc;
|
|
9018
|
+
}, {});
|
|
9019
|
+
const matchCount = allMatches.length;
|
|
9020
|
+
const matchTerm = matchCount === 1 ? "match" : "matches";
|
|
9021
|
+
const truncated = matchCount >= maxMatches;
|
|
9022
|
+
let result = `Found ${matchCount} ${matchTerm}${truncated ? " (truncated)" : ""} for pattern "${pattern}" in "${searchDirDisplay}"${filterInfo}:
|
|
9027
9023
|
`;
|
|
9028
|
-
|
|
9024
|
+
result += `Searched ${filesSearched} file(s)
|
|
9025
|
+
---
|
|
9029
9026
|
`;
|
|
9030
|
-
const
|
|
9031
|
-
`
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
${match.context.before.map((l) => ` ${l}`).join("\n")}`;
|
|
9041
|
-
}
|
|
9042
|
-
if (match.context.after.length > 0) {
|
|
9043
|
-
result = `${result}
|
|
9044
|
-
Context after:
|
|
9045
|
-
${match.context.after.map((l) => ` ${l}`).join("\n")}`;
|
|
9046
|
-
}
|
|
9047
|
-
}
|
|
9048
|
-
return result;
|
|
9049
|
-
}).join("\n");
|
|
9050
|
-
return `${summary}${patternInfo}${cwdInfo}${matchesList}`;
|
|
9051
|
-
}
|
|
9052
|
-
function isBinaryFile2(filePath) {
|
|
9053
|
-
try {
|
|
9054
|
-
const buffer = Buffer.alloc(8192);
|
|
9055
|
-
const fd = __require("fs").openSync(filePath, "r");
|
|
9056
|
-
const bytesRead = __require("fs").readSync(fd, buffer, 0, 8192, 0);
|
|
9057
|
-
__require("fs").closeSync(fd);
|
|
9058
|
-
const chunk = buffer.slice(0, bytesRead);
|
|
9059
|
-
return chunk.includes(0);
|
|
9060
|
-
} catch {
|
|
9061
|
-
return true;
|
|
9027
|
+
for (const filePath in matchesByFile) {
|
|
9028
|
+
result += `File: ${filePath}
|
|
9029
|
+
`;
|
|
9030
|
+
matchesByFile[filePath].forEach((match) => {
|
|
9031
|
+
const trimmedLine = match.line.trim();
|
|
9032
|
+
const displayLine = trimmedLine.length > 200 ? trimmedLine.slice(0, 200) + "..." : trimmedLine;
|
|
9033
|
+
result += `L${match.lineNumber}: ${displayLine}
|
|
9034
|
+
`;
|
|
9035
|
+
});
|
|
9036
|
+
result += "---\n";
|
|
9062
9037
|
}
|
|
9038
|
+
return result.trim();
|
|
9063
9039
|
}
|
|
9064
9040
|
var grepSearchTool = {
|
|
9065
9041
|
name: "grep_search",
|
|
@@ -9068,8 +9044,8 @@ var grepSearchTool = {
|
|
|
9068
9044
|
const params = value;
|
|
9069
9045
|
context.logger.info("\u{1F50D} GrepSearch: Searching files", {
|
|
9070
9046
|
pattern: params.pattern,
|
|
9071
|
-
|
|
9072
|
-
|
|
9047
|
+
dir_path: params.dir_path || ".",
|
|
9048
|
+
include: params.include || "**/*"
|
|
9073
9049
|
});
|
|
9074
9050
|
try {
|
|
9075
9051
|
const result = await searchFiles2(params);
|
|
@@ -9082,33 +9058,21 @@ var grepSearchTool = {
|
|
|
9082
9058
|
},
|
|
9083
9059
|
toolSchema: {
|
|
9084
9060
|
name: "grep_search",
|
|
9085
|
-
description: "
|
|
9061
|
+
description: "Searches for a regular expression pattern within the content of files in a specified directory (or current working directory). Can filter files by a glob pattern. Returns the lines containing matches, along with their file paths and line numbers.",
|
|
9086
9062
|
parameters: {
|
|
9087
9063
|
type: "object",
|
|
9088
9064
|
properties: {
|
|
9089
9065
|
pattern: {
|
|
9090
9066
|
type: "string",
|
|
9091
|
-
description: "
|
|
9067
|
+
description: "The regular expression (regex) pattern to search for within file contents (e.g., 'function\\s+myFunction', 'import\\s+\\{.*\\}\\s+from\\s+.*')."
|
|
9092
9068
|
},
|
|
9093
|
-
|
|
9069
|
+
dir_path: {
|
|
9094
9070
|
type: "string",
|
|
9095
|
-
description:
|
|
9071
|
+
description: "Optional: The absolute path to the directory to search within. If omitted, searches the current working directory."
|
|
9096
9072
|
},
|
|
9097
|
-
|
|
9073
|
+
include: {
|
|
9098
9074
|
type: "string",
|
|
9099
|
-
description: "
|
|
9100
|
-
},
|
|
9101
|
-
caseSensitive: {
|
|
9102
|
-
type: "boolean",
|
|
9103
|
-
description: "Whether the search should be case-sensitive (default: false)"
|
|
9104
|
-
},
|
|
9105
|
-
maxResults: {
|
|
9106
|
-
type: "number",
|
|
9107
|
-
description: "Maximum number of matches to return (default: 100). Prevents overwhelming output."
|
|
9108
|
-
},
|
|
9109
|
-
contextLines: {
|
|
9110
|
-
type: "number",
|
|
9111
|
-
description: "Number of context lines to show before and after each match (default: 0). Similar to grep -C option."
|
|
9075
|
+
description: "Optional: A glob pattern to filter which files are searched (e.g., '*.js', '*.{ts,tsx}', 'src/**'). If omitted, searches all files (respecting potential global ignores)."
|
|
9112
9076
|
}
|
|
9113
9077
|
},
|
|
9114
9078
|
required: ["pattern"]
|
|
@@ -9119,7 +9083,7 @@ var grepSearchTool = {
|
|
|
9119
9083
|
|
|
9120
9084
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
|
|
9121
9085
|
import { promises as fs10 } from "fs";
|
|
9122
|
-
import { existsSync as existsSync6, statSync as
|
|
9086
|
+
import { existsSync as existsSync6, statSync as statSync5 } from "fs";
|
|
9123
9087
|
import path11 from "path";
|
|
9124
9088
|
async function deleteFile(params) {
|
|
9125
9089
|
const { path: filePath, recursive = false } = params;
|
|
@@ -9132,7 +9096,7 @@ async function deleteFile(params) {
|
|
|
9132
9096
|
if (!existsSync6(resolvedPath)) {
|
|
9133
9097
|
throw new Error(`File or directory not found: ${filePath}`);
|
|
9134
9098
|
}
|
|
9135
|
-
const stats =
|
|
9099
|
+
const stats = statSync5(resolvedPath);
|
|
9136
9100
|
const isDirectory = stats.isDirectory();
|
|
9137
9101
|
const size = stats.size;
|
|
9138
9102
|
if (isDirectory && !recursive) {
|
|
@@ -9153,7 +9117,7 @@ var deleteFileTool = {
|
|
|
9153
9117
|
toolFn: async (value) => {
|
|
9154
9118
|
const params = value;
|
|
9155
9119
|
const resolvedPath = path11.resolve(process.cwd(), path11.normalize(params.path));
|
|
9156
|
-
const isDirectory = existsSync6(resolvedPath) &&
|
|
9120
|
+
const isDirectory = existsSync6(resolvedPath) && statSync5(resolvedPath).isDirectory();
|
|
9157
9121
|
context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
|
|
9158
9122
|
path: params.path,
|
|
9159
9123
|
recursive: params.recursive
|
|
@@ -9929,7 +9893,7 @@ var ToolErrorType;
|
|
|
9929
9893
|
|
|
9930
9894
|
// src/utils/diffPreview.ts
|
|
9931
9895
|
import * as Diff from "diff";
|
|
9932
|
-
import { readFile } from "fs/promises";
|
|
9896
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
9933
9897
|
import { existsSync as existsSync8 } from "fs";
|
|
9934
9898
|
async function generateFileDiffPreview(args) {
|
|
9935
9899
|
try {
|
|
@@ -9944,7 +9908,7 @@ ${preview}${hasMore ? `
|
|
|
9944
9908
|
|
|
9945
9909
|
... (${lines2.length - 20} more lines)` : ""}`;
|
|
9946
9910
|
}
|
|
9947
|
-
const currentContent = await
|
|
9911
|
+
const currentContent = await readFile2(args.path, "utf-8");
|
|
9948
9912
|
const patch = Diff.createPatch(
|
|
9949
9913
|
args.path,
|
|
9950
9914
|
currentContent,
|
|
@@ -11768,7 +11732,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
11768
11732
|
// package.json
|
|
11769
11733
|
var package_default = {
|
|
11770
11734
|
name: "@bike4mind/cli",
|
|
11771
|
-
version: "0.2.11-cli-
|
|
11735
|
+
version: "0.2.11-cli-todo-list.17329+bc504ca29",
|
|
11772
11736
|
type: "module",
|
|
11773
11737
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
11774
11738
|
license: "UNLICENSED",
|
|
@@ -11838,6 +11802,7 @@ var package_default = {
|
|
|
11838
11802
|
"eventsource-parser": "^3.0.6",
|
|
11839
11803
|
"file-type": "^18.7.0",
|
|
11840
11804
|
"fuse.js": "^7.1.0",
|
|
11805
|
+
glob: "^13.0.0",
|
|
11841
11806
|
"gray-matter": "^4.0.3",
|
|
11842
11807
|
ink: "^6.5.1",
|
|
11843
11808
|
"ink-select-input": "^6.2.0",
|
|
@@ -11872,10 +11837,10 @@ var package_default = {
|
|
|
11872
11837
|
},
|
|
11873
11838
|
devDependencies: {
|
|
11874
11839
|
"@bike4mind/agents": "0.1.0",
|
|
11875
|
-
"@bike4mind/common": "2.40.1-cli-
|
|
11876
|
-
"@bike4mind/mcp": "1.20.5-cli-
|
|
11877
|
-
"@bike4mind/services": "2.35.1-cli-
|
|
11878
|
-
"@bike4mind/utils": "2.1.5-cli-
|
|
11840
|
+
"@bike4mind/common": "2.40.1-cli-todo-list.17329+bc504ca29",
|
|
11841
|
+
"@bike4mind/mcp": "1.20.5-cli-todo-list.17329+bc504ca29",
|
|
11842
|
+
"@bike4mind/services": "2.35.1-cli-todo-list.17329+bc504ca29",
|
|
11843
|
+
"@bike4mind/utils": "2.1.5-cli-todo-list.17329+bc504ca29",
|
|
11879
11844
|
"@types/better-sqlite3": "^7.6.13",
|
|
11880
11845
|
"@types/diff": "^5.0.9",
|
|
11881
11846
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -11888,7 +11853,7 @@ var package_default = {
|
|
|
11888
11853
|
typescript: "^5.9.3",
|
|
11889
11854
|
vitest: "^3.2.4"
|
|
11890
11855
|
},
|
|
11891
|
-
gitHead: "
|
|
11856
|
+
gitHead: "bc504ca299975846c55f1c16f05f4e7535ce2fda"
|
|
11892
11857
|
};
|
|
11893
11858
|
|
|
11894
11859
|
// src/config/constants.ts
|
|
@@ -12244,6 +12209,131 @@ function createSubagentDelegateTool(orchestrator, parentSessionId) {
|
|
|
12244
12209
|
};
|
|
12245
12210
|
}
|
|
12246
12211
|
|
|
12212
|
+
// src/tools/writeTodosTool.ts
|
|
12213
|
+
var VALID_STATUSES = ["pending", "in_progress", "completed", "cancelled"];
|
|
12214
|
+
function validateTodos(todos) {
|
|
12215
|
+
if (!Array.isArray(todos)) {
|
|
12216
|
+
throw new Error("write_todos: todos must be an array");
|
|
12217
|
+
}
|
|
12218
|
+
if (todos.length === 0) {
|
|
12219
|
+
throw new Error("write_todos: todos array cannot be empty");
|
|
12220
|
+
}
|
|
12221
|
+
let inProgressCount = 0;
|
|
12222
|
+
const validatedTodos = todos.map((item, index) => {
|
|
12223
|
+
if (!item || typeof item !== "object") {
|
|
12224
|
+
throw new Error(`write_todos: item at index ${index} must be an object`);
|
|
12225
|
+
}
|
|
12226
|
+
const { description, status } = item;
|
|
12227
|
+
if (typeof description !== "string" || description.trim() === "") {
|
|
12228
|
+
throw new Error(`write_todos: item at index ${index} must have a non-empty description`);
|
|
12229
|
+
}
|
|
12230
|
+
if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
|
|
12231
|
+
throw new Error(
|
|
12232
|
+
`write_todos: item at index ${index} has invalid status "${status}". Must be one of: ${VALID_STATUSES.join(", ")}`
|
|
12233
|
+
);
|
|
12234
|
+
}
|
|
12235
|
+
if (status === "in_progress") {
|
|
12236
|
+
inProgressCount++;
|
|
12237
|
+
}
|
|
12238
|
+
return {
|
|
12239
|
+
description: description.trim(),
|
|
12240
|
+
status
|
|
12241
|
+
};
|
|
12242
|
+
});
|
|
12243
|
+
if (inProgressCount > 1) {
|
|
12244
|
+
throw new Error(`write_todos: only one task can be 'in_progress' at a time, but found ${inProgressCount}`);
|
|
12245
|
+
}
|
|
12246
|
+
return validatedTodos;
|
|
12247
|
+
}
|
|
12248
|
+
function formatTodosOutput(todos) {
|
|
12249
|
+
const statusEmoji = {
|
|
12250
|
+
pending: "\u2B1C",
|
|
12251
|
+
in_progress: "\u{1F504}",
|
|
12252
|
+
completed: "\u2705",
|
|
12253
|
+
cancelled: "\u274C"
|
|
12254
|
+
};
|
|
12255
|
+
const lines = todos.map((todo, index) => {
|
|
12256
|
+
const emoji = statusEmoji[todo.status];
|
|
12257
|
+
return `${index + 1}. ${emoji} [${todo.status}] ${todo.description}`;
|
|
12258
|
+
});
|
|
12259
|
+
return lines.join("\n");
|
|
12260
|
+
}
|
|
12261
|
+
function createWriteTodosTool(todoStore) {
|
|
12262
|
+
return {
|
|
12263
|
+
toolFn: async (args) => {
|
|
12264
|
+
const params = args;
|
|
12265
|
+
const validatedTodos = validateTodos(params.todos);
|
|
12266
|
+
todoStore.todos = validatedTodos;
|
|
12267
|
+
if (todoStore.onUpdate) {
|
|
12268
|
+
todoStore.onUpdate(validatedTodos);
|
|
12269
|
+
}
|
|
12270
|
+
const output = formatTodosOutput(validatedTodos);
|
|
12271
|
+
return `Todo list updated successfully:
|
|
12272
|
+
|
|
12273
|
+
${output}`;
|
|
12274
|
+
},
|
|
12275
|
+
toolSchema: {
|
|
12276
|
+
name: "write_todos",
|
|
12277
|
+
description: `Create or update a list of subtasks for complex multi-step requests.
|
|
12278
|
+
|
|
12279
|
+
**When to use this tool:**
|
|
12280
|
+
- When handling complex requests that require multiple steps
|
|
12281
|
+
- To break down a large task into smaller, manageable subtasks
|
|
12282
|
+
- To track progress through a multi-step workflow
|
|
12283
|
+
|
|
12284
|
+
**Important guidelines:**
|
|
12285
|
+
- Call this tool early when receiving complex requests
|
|
12286
|
+
- Update the list immediately when starting, completing, or cancelling tasks
|
|
12287
|
+
- Only ONE task should be 'in_progress' at a time
|
|
12288
|
+
- Never batch updates - update as soon as state changes
|
|
12289
|
+
|
|
12290
|
+
**Status values:**
|
|
12291
|
+
- pending: Task not yet started
|
|
12292
|
+
- in_progress: Currently working on this task (only ONE allowed)
|
|
12293
|
+
- completed: Task finished successfully
|
|
12294
|
+
- cancelled: Task will not be completed
|
|
12295
|
+
|
|
12296
|
+
**Example:**
|
|
12297
|
+
If asked to "create a new React component with tests", break it down:
|
|
12298
|
+
1. Create component file \u2192 in_progress
|
|
12299
|
+
2. Add component logic \u2192 pending
|
|
12300
|
+
3. Create test file \u2192 pending
|
|
12301
|
+
4. Write unit tests \u2192 pending`,
|
|
12302
|
+
parameters: {
|
|
12303
|
+
type: "object",
|
|
12304
|
+
properties: {
|
|
12305
|
+
todos: {
|
|
12306
|
+
type: "array",
|
|
12307
|
+
description: "Complete list of todo items. This replaces any existing list. Each item needs a description and status.",
|
|
12308
|
+
items: {
|
|
12309
|
+
type: "object",
|
|
12310
|
+
properties: {
|
|
12311
|
+
description: {
|
|
12312
|
+
type: "string",
|
|
12313
|
+
description: "Clear, concise description of the task"
|
|
12314
|
+
},
|
|
12315
|
+
status: {
|
|
12316
|
+
type: "string",
|
|
12317
|
+
enum: ["pending", "in_progress", "completed", "cancelled"],
|
|
12318
|
+
description: "Current status of the task. Only ONE task can be 'in_progress' at a time."
|
|
12319
|
+
}
|
|
12320
|
+
},
|
|
12321
|
+
required: ["description", "status"]
|
|
12322
|
+
}
|
|
12323
|
+
}
|
|
12324
|
+
},
|
|
12325
|
+
required: ["todos"]
|
|
12326
|
+
}
|
|
12327
|
+
}
|
|
12328
|
+
};
|
|
12329
|
+
}
|
|
12330
|
+
function createTodoStore(onUpdate) {
|
|
12331
|
+
return {
|
|
12332
|
+
todos: [],
|
|
12333
|
+
onUpdate
|
|
12334
|
+
};
|
|
12335
|
+
}
|
|
12336
|
+
|
|
12247
12337
|
// src/index.tsx
|
|
12248
12338
|
process.removeAllListeners("warning");
|
|
12249
12339
|
process.on("warning", (warning) => {
|
|
@@ -12528,7 +12618,9 @@ function CliApp() {
|
|
|
12528
12618
|
subagentConfigs
|
|
12529
12619
|
});
|
|
12530
12620
|
const subagentDelegateTool = createSubagentDelegateTool(orchestrator, newSession.id);
|
|
12531
|
-
const
|
|
12621
|
+
const todoStore = createTodoStore();
|
|
12622
|
+
const writeTodosTool = createWriteTodosTool(todoStore);
|
|
12623
|
+
const allTools = [...b4mTools, ...mcpTools, subagentDelegateTool, writeTodosTool];
|
|
12532
12624
|
console.log(`\u{1F916} Subagent delegation enabled (explore, plan, review)`);
|
|
12533
12625
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
12534
12626
|
const contextResult = await loadContextFiles(projectDir);
|
|
@@ -13008,7 +13100,7 @@ ${output}` : output.trim() || "(no output)",
|
|
|
13008
13100
|
if (!imageStore) {
|
|
13009
13101
|
if (!imageStoreInitPromise.current) {
|
|
13010
13102
|
imageStoreInitPromise.current = (async () => {
|
|
13011
|
-
const { ImageStore: ImageStoreClass } = await import("./ImageStore-
|
|
13103
|
+
const { ImageStore: ImageStoreClass } = await import("./ImageStore-MMUOUPI2.js");
|
|
13012
13104
|
const newImageStore = new ImageStoreClass();
|
|
13013
13105
|
setState((prev) => ({
|
|
13014
13106
|
...prev,
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-6AYWWNXH.js";
|
|
6
|
+
import "./chunk-M4EAFD3H.js";
|
|
7
|
+
import "./chunk-OCYRD7D6.js";
|
|
8
8
|
import "./chunk-WCYNJOOX.js";
|
|
9
|
-
import "./chunk-PDX44BCA.js";
|
|
10
9
|
export {
|
|
11
10
|
findMostSimilarMemento,
|
|
12
11
|
getRelevantMementos
|
|
@@ -120,7 +120,7 @@ import {
|
|
|
120
120
|
validateMermaidSyntax,
|
|
121
121
|
warmUpSettingsCache,
|
|
122
122
|
withRetry
|
|
123
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-M4EAFD3H.js";
|
|
124
124
|
import {
|
|
125
125
|
Logger,
|
|
126
126
|
NotificationDeduplicator,
|
|
@@ -128,9 +128,8 @@ import {
|
|
|
128
128
|
notifyEventLogsToSlack,
|
|
129
129
|
postLowCreditsNotificationToSlack,
|
|
130
130
|
postMessageToSlack
|
|
131
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-OCYRD7D6.js";
|
|
132
132
|
import "./chunk-WCYNJOOX.js";
|
|
133
|
-
import "./chunk-PDX44BCA.js";
|
|
134
133
|
export {
|
|
135
134
|
AWSBackend,
|
|
136
135
|
AdminSettingsCache,
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-WENSCUXW.js";
|
|
6
|
+
import "./chunk-M4EAFD3H.js";
|
|
7
|
+
import "./chunk-OCYRD7D6.js";
|
|
8
8
|
import "./chunk-WCYNJOOX.js";
|
|
9
|
-
import "./chunk-PDX44BCA.js";
|
|
10
9
|
export {
|
|
11
10
|
SubtractCreditsSchema,
|
|
12
11
|
subtractCredits
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.11-cli-
|
|
3
|
+
"version": "0.2.11-cli-todo-list.17329+bc504ca29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"eventsource-parser": "^3.0.6",
|
|
71
71
|
"file-type": "^18.7.0",
|
|
72
72
|
"fuse.js": "^7.1.0",
|
|
73
|
+
"glob": "^13.0.0",
|
|
73
74
|
"gray-matter": "^4.0.3",
|
|
74
75
|
"ink": "^6.5.1",
|
|
75
76
|
"ink-select-input": "^6.2.0",
|
|
@@ -104,10 +105,10 @@
|
|
|
104
105
|
},
|
|
105
106
|
"devDependencies": {
|
|
106
107
|
"@bike4mind/agents": "0.1.0",
|
|
107
|
-
"@bike4mind/common": "2.40.1-cli-
|
|
108
|
-
"@bike4mind/mcp": "1.20.5-cli-
|
|
109
|
-
"@bike4mind/services": "2.35.1-cli-
|
|
110
|
-
"@bike4mind/utils": "2.1.5-cli-
|
|
108
|
+
"@bike4mind/common": "2.40.1-cli-todo-list.17329+bc504ca29",
|
|
109
|
+
"@bike4mind/mcp": "1.20.5-cli-todo-list.17329+bc504ca29",
|
|
110
|
+
"@bike4mind/services": "2.35.1-cli-todo-list.17329+bc504ca29",
|
|
111
|
+
"@bike4mind/utils": "2.1.5-cli-todo-list.17329+bc504ca29",
|
|
111
112
|
"@types/better-sqlite3": "^7.6.13",
|
|
112
113
|
"@types/diff": "^5.0.9",
|
|
113
114
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -120,5 +121,5 @@
|
|
|
120
121
|
"typescript": "^5.9.3",
|
|
121
122
|
"vitest": "^3.2.4"
|
|
122
123
|
},
|
|
123
|
-
"gitHead": "
|
|
124
|
+
"gitHead": "bc504ca299975846c55f1c16f05f4e7535ce2fda"
|
|
124
125
|
}
|
package/dist/chunk-PDX44BCA.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
-
}) : x)(function(x) {
|
|
5
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
__require
|
|
11
|
-
};
|