@bike4mind/cli 0.2.8-feat-cli-session-resume.17148 → 0.2.10-dowgrade-mcp-sdk.17228
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 +48 -0
- package/dist/{artifactExtractor-DNE5C6DY.js → artifactExtractor-JAGU7QRL.js} +1 -1
- package/dist/{chunk-YXHQN7SK.js → chunk-AQBZVAYO.js} +2 -2
- package/dist/{chunk-H6SHASMZ.js → chunk-DJPXSSP4.js} +13 -1
- package/dist/{chunk-DNSBC3LO.js → chunk-GCVIRGIN.js} +1 -1
- package/dist/{chunk-3CCBDIFR.js → chunk-GO75FMLY.js} +2 -2
- package/dist/{chunk-LIRY24M5.js → chunk-VZU4Z7WI.js} +2 -2
- package/dist/{create-PNU64QSF.js → create-ZDOTF7XD.js} +3 -3
- package/dist/index.js +616 -56
- package/dist/{llmMarkdownGenerator-UQXKK2AS.js → llmMarkdownGenerator-LXUGJ7QH.js} +1 -1
- package/dist/{markdownGenerator-FLLZFXMT.js → markdownGenerator-IMDG6OX6.js} +1 -1
- package/dist/{mementoService-LVFQ5XAW.js → mementoService-TURUS3OH.js} +3 -3
- package/dist/{src-OH5AAQEW.js → src-6ZRXGE5J.js} +2 -2
- package/dist/{src-OYQXRLTM.js → src-YNY32ELR.js} +3 -1
- package/dist/{subtractCredits-75VT7HP2.js → subtractCredits-GOVKM3IR.js} +3 -3
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Interactive command-line interface for Bike4Mind with ReAct agents.
|
|
|
10
10
|
- 🛠️ B4M tools + MCP integration
|
|
11
11
|
- 🎨 Rich terminal UI with Ink
|
|
12
12
|
- 🐛 Debug logging with `--verbose` flag
|
|
13
|
+
- 📄 Context file loading (CLAUDE.md, AGENTS.md, AI.md)
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
@@ -160,6 +161,7 @@ export SERPER_API_KEY="your-key-here"
|
|
|
160
161
|
- ✅ `math_evaluate` - No API key needed
|
|
161
162
|
- ✅ `current_datetime` - No API key needed
|
|
162
163
|
- ✅ `prompt_enhancement` - No API key needed
|
|
164
|
+
- ✅ `bash_execute` - No API key needed
|
|
163
165
|
- 🔑 `weather_info` - Requires `toolApiKeys.openweather`
|
|
164
166
|
- 🔑 `web_search` - Requires `toolApiKeys.serper`
|
|
165
167
|
- 🔑 `deep_research` - Requires `toolApiKeys.serper`
|
|
@@ -241,6 +243,51 @@ You can also run any MCP server via npx or custom executables:
|
|
|
241
243
|
|
|
242
244
|
**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.
|
|
243
245
|
|
|
246
|
+
## Context Files
|
|
247
|
+
|
|
248
|
+
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.
|
|
249
|
+
|
|
250
|
+
### Supported Files
|
|
251
|
+
|
|
252
|
+
**Project-level** (in your project directory, checked in priority order):
|
|
253
|
+
1. `CLAUDE.local.md` - Personal/gitignored instructions (highest priority)
|
|
254
|
+
2. `CLAUDE.md` - Project instructions
|
|
255
|
+
3. `AGENTS.md` - Cross-tool standard
|
|
256
|
+
4. `AI.local.md` - Personal/gitignored instructions
|
|
257
|
+
5. `AI.md` - Project instructions
|
|
258
|
+
6. `INSTRUCTIONS.md` - Project instructions (lowest priority)
|
|
259
|
+
|
|
260
|
+
**Global** (in `~/.bike4mind/`):
|
|
261
|
+
1. `AI.local.md` - Personal global instructions
|
|
262
|
+
2. `AI.md` - Global instructions
|
|
263
|
+
|
|
264
|
+
### How It Works
|
|
265
|
+
|
|
266
|
+
- The CLI loads the **first matching file** from each layer (global and project)
|
|
267
|
+
- Project files take precedence over global files
|
|
268
|
+
- `.local.md` variants are intended to be gitignored for personal preferences
|
|
269
|
+
- Files must be under 100KB
|
|
270
|
+
- Symlinks are rejected for security
|
|
271
|
+
|
|
272
|
+
### Example
|
|
273
|
+
|
|
274
|
+
Create a `CLAUDE.md` in your project:
|
|
275
|
+
|
|
276
|
+
```markdown
|
|
277
|
+
# Project Instructions
|
|
278
|
+
|
|
279
|
+
- Always use TypeScript strict mode
|
|
280
|
+
- Prefer functional components with hooks
|
|
281
|
+
- Run tests before committing
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
On startup, you'll see:
|
|
285
|
+
```
|
|
286
|
+
📄 Project context: CLAUDE.md
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The agent will follow these instructions for all interactions in that project.
|
|
290
|
+
|
|
244
291
|
## Session Storage
|
|
245
292
|
|
|
246
293
|
Sessions are saved to `~/.bike4mind/sessions/`
|
|
@@ -338,6 +385,7 @@ Current implementation includes:
|
|
|
338
385
|
✅ B4M tools integration
|
|
339
386
|
✅ MCP tools support
|
|
340
387
|
✅ Debug logging with --verbose flag
|
|
388
|
+
✅ Context file loading (CLAUDE.md, AGENTS.md, AI.md)
|
|
341
389
|
|
|
342
390
|
Coming soon:
|
|
343
391
|
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-GCVIRGIN.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DJPXSSP4.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -230,7 +230,9 @@ var b4mLLMTools = z3.enum([
|
|
|
230
230
|
"create_file",
|
|
231
231
|
"glob_files",
|
|
232
232
|
"grep_search",
|
|
233
|
-
"delete_file"
|
|
233
|
+
"delete_file",
|
|
234
|
+
// Shell execution
|
|
235
|
+
"bash_execute"
|
|
234
236
|
]);
|
|
235
237
|
var B4MLLMToolsList = b4mLLMTools.options.map((tool) => tool);
|
|
236
238
|
var RechartsChartTypeSchema = z3.enum([
|
|
@@ -4038,6 +4040,15 @@ var UserApiKeyEvents;
|
|
|
4038
4040
|
UserApiKeyEvents2["DELETED"] = "User API Key Deleted";
|
|
4039
4041
|
})(UserApiKeyEvents || (UserApiKeyEvents = {}));
|
|
4040
4042
|
|
|
4043
|
+
// ../../b4m-core/packages/common/dist/src/schemas/analytics/events/slack.js
|
|
4044
|
+
var SlackEvents;
|
|
4045
|
+
(function(SlackEvents2) {
|
|
4046
|
+
SlackEvents2["SLACK_COMMAND_RECEIVED"] = "Slack Command Received";
|
|
4047
|
+
SlackEvents2["SLACK_COMMAND_COMPLETED"] = "Slack Command Completed";
|
|
4048
|
+
SlackEvents2["SLACK_MCP_TOOL_INVOKED"] = "Slack MCP Tool Invoked";
|
|
4049
|
+
SlackEvents2["SLACK_BULK_OPERATION"] = "Slack Bulk Operation Executed";
|
|
4050
|
+
})(SlackEvents || (SlackEvents = {}));
|
|
4051
|
+
|
|
4041
4052
|
// ../../b4m-core/packages/common/dist/src/schemas/team.js
|
|
4042
4053
|
import { z as z22 } from "zod";
|
|
4043
4054
|
var InternalTeamMemberSchema = z22.object({
|
|
@@ -6114,6 +6125,7 @@ export {
|
|
|
6114
6125
|
FriendshipEvents,
|
|
6115
6126
|
OrganizationEvents,
|
|
6116
6127
|
UserApiKeyEvents,
|
|
6128
|
+
SlackEvents,
|
|
6117
6129
|
InternalTeamMemberSchema,
|
|
6118
6130
|
InternalTeamMemberListSchema,
|
|
6119
6131
|
PREDEFINED_USER_TAGS,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
dayjsConfig_default,
|
|
17
17
|
extractSnippetMeta,
|
|
18
18
|
settingsMap
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-DJPXSSP4.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";
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
getSettingsByNames,
|
|
7
7
|
obfuscateApiKey,
|
|
8
8
|
secureParameters
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-GCVIRGIN.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DJPXSSP4.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BadRequestError,
|
|
4
4
|
secureParameters
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-GCVIRGIN.js";
|
|
6
6
|
import {
|
|
7
7
|
GenericCreditDeductTransaction,
|
|
8
8
|
ImageEditUsageTransaction,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
RealtimeVoiceUsageTransaction,
|
|
11
11
|
TextGenerationUsageTransaction,
|
|
12
12
|
TransferCreditTransaction
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DJPXSSP4.js";
|
|
14
14
|
|
|
15
15
|
// ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
|
|
16
16
|
import { z } from "zod";
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-AQBZVAYO.js";
|
|
6
|
+
import "./chunk-GCVIRGIN.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-DJPXSSP4.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-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-GO75FMLY.js";
|
|
8
|
+
import "./chunk-VZU4Z7WI.js";
|
|
9
|
+
import "./chunk-AQBZVAYO.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-
|
|
18
|
+
} from "./chunk-GCVIRGIN.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-
|
|
76
|
+
} from "./chunk-DJPXSSP4.js";
|
|
77
77
|
import {
|
|
78
78
|
__require
|
|
79
79
|
} from "./chunk-PDX44BCA.js";
|
|
@@ -85,7 +85,7 @@ import { v4 as uuidv49 } from "uuid";
|
|
|
85
85
|
|
|
86
86
|
// src/components/App.tsx
|
|
87
87
|
import React10 from "react";
|
|
88
|
-
import { Box as Box9, Text as Text9
|
|
88
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
89
89
|
|
|
90
90
|
// src/components/StatusBar.tsx
|
|
91
91
|
import React from "react";
|
|
@@ -742,6 +742,7 @@ function InputPrompt({
|
|
|
742
742
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
743
743
|
const [historyIndex, setHistoryIndex] = useState2(-1);
|
|
744
744
|
const [tempInput, setTempInput] = useState2("");
|
|
745
|
+
const [inputKey, setInputKey] = useState2(0);
|
|
745
746
|
useEffect(() => {
|
|
746
747
|
if (prefillInput) {
|
|
747
748
|
setValue(prefillInput);
|
|
@@ -889,10 +890,11 @@ function InputPrompt({
|
|
|
889
890
|
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: "cyan" }, "> "), /* @__PURE__ */ React5.createElement(
|
|
890
891
|
CustomTextInput,
|
|
891
892
|
{
|
|
893
|
+
key: inputKey,
|
|
892
894
|
value,
|
|
893
895
|
onChange: handleChange,
|
|
894
896
|
onSubmit: handleSubmit,
|
|
895
|
-
placeholder: disabled ? "
|
|
897
|
+
placeholder: disabled ? "" : "Type your message, /help for commands, or @file to reference",
|
|
896
898
|
showCursor: !disabled
|
|
897
899
|
}
|
|
898
900
|
)), shouldShowCommandAutocomplete && /* @__PURE__ */ React5.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }), fileAutocomplete?.active && /* @__PURE__ */ React5.createElement(FileAutocomplete, { files: filteredFiles, selectedIndex: fileSelectedIndex, query: fileAutocomplete.query }));
|
|
@@ -923,6 +925,7 @@ var useCliStore = create((set) => ({
|
|
|
923
925
|
addAgentStep: (step) => set((state) => ({
|
|
924
926
|
agentSteps: [...state.agentSteps, step]
|
|
925
927
|
})),
|
|
928
|
+
setAgentSteps: (steps) => set({ agentSteps: steps }),
|
|
926
929
|
clearAgentSteps: () => set({ agentSteps: [] }),
|
|
927
930
|
// Permission prompt
|
|
928
931
|
permissionPrompt: null,
|
|
@@ -942,7 +945,7 @@ var AgentThinking = React7.memo(function AgentThinking2() {
|
|
|
942
945
|
if (!isThinking) {
|
|
943
946
|
return null;
|
|
944
947
|
}
|
|
945
|
-
return /* @__PURE__ */ React7.createElement(Box6, {
|
|
948
|
+
return /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React7.createElement(ThoughtStream, { steps: agentSteps }));
|
|
946
949
|
});
|
|
947
950
|
|
|
948
951
|
// src/components/PermissionPrompt.tsx
|
|
@@ -1397,7 +1400,7 @@ ${errorBlock}`;
|
|
|
1397
1400
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
1398
1401
|
onResponse: onPermissionResponse
|
|
1399
1402
|
}
|
|
1400
|
-
)) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(
|
|
1403
|
+
)) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column" }, messages.map((message, index) => /* @__PURE__ */ React10.createElement(Box9, { key: `${message.timestamp}-${message.role}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React10.createElement(MessageItem, { message })))), /* @__PURE__ */ React10.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React10.createElement(Box9, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React10.createElement(Box9, { borderStyle: "single", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React10.createElement(
|
|
1401
1404
|
InputPrompt,
|
|
1402
1405
|
{
|
|
1403
1406
|
onSubmit: handleSubmit,
|
|
@@ -1410,7 +1413,8 @@ ${errorBlock}`;
|
|
|
1410
1413
|
))));
|
|
1411
1414
|
}
|
|
1412
1415
|
function MessageItem({ message }) {
|
|
1413
|
-
|
|
1416
|
+
const isUser = message.role === "user";
|
|
1417
|
+
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: isUser ? "cyan" : "green" }, isUser ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1414
1418
|
if (step.type === "thought") {
|
|
1415
1419
|
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
1416
1420
|
}
|
|
@@ -1422,7 +1426,7 @@ function MessageItem({ message }) {
|
|
|
1422
1426
|
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
|
|
1423
1427
|
}
|
|
1424
1428
|
return null;
|
|
1425
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1429
|
+
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: message.metadata?.steps?.length ? 1 : 0 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React10.createElement(Text9, null, message.content)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1426
1430
|
}
|
|
1427
1431
|
|
|
1428
1432
|
// src/components/MessageList.tsx
|
|
@@ -2688,10 +2692,9 @@ ${options.context}` : this.getSystemPrompt()
|
|
|
2688
2692
|
content: query
|
|
2689
2693
|
}
|
|
2690
2694
|
];
|
|
2691
|
-
console.log("[DEBUG ReActAgent] Messages array being sent to LLM:");
|
|
2692
2695
|
messages.forEach((msg, i) => {
|
|
2693
2696
|
const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
2694
|
-
|
|
2697
|
+
this.context.logger.debug(` [${i}] ${msg.role}: ${content.substring(0, 150)}...`);
|
|
2695
2698
|
});
|
|
2696
2699
|
let finalAnswer = "";
|
|
2697
2700
|
let reachedMaxIterations = false;
|
|
@@ -5084,8 +5087,8 @@ async function processAndStoreImages(images, context) {
|
|
|
5084
5087
|
const buffer = await downloadImage(image);
|
|
5085
5088
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
5086
5089
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
5087
|
-
const
|
|
5088
|
-
return
|
|
5090
|
+
const path15 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5091
|
+
return path15;
|
|
5089
5092
|
}));
|
|
5090
5093
|
}
|
|
5091
5094
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -6297,8 +6300,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
6297
6300
|
const buffer = await downloadImage2(imageUrl);
|
|
6298
6301
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
6299
6302
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
6300
|
-
const
|
|
6301
|
-
return
|
|
6303
|
+
const path15 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
6304
|
+
return path15;
|
|
6302
6305
|
}
|
|
6303
6306
|
async function updateQuestAndReturnMarkdown2(storedImagePath, context) {
|
|
6304
6307
|
await context.onFinish?.("edit_image", storedImagePath);
|
|
@@ -8710,6 +8713,381 @@ var deleteFileTool = {
|
|
|
8710
8713
|
})
|
|
8711
8714
|
};
|
|
8712
8715
|
|
|
8716
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/bashExecute/index.js
|
|
8717
|
+
import { spawn } from "child_process";
|
|
8718
|
+
import path11 from "path";
|
|
8719
|
+
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
8720
|
+
var MAX_OUTPUT_SIZE = 100 * 1024;
|
|
8721
|
+
var DANGEROUS_PATTERNS = [
|
|
8722
|
+
// Destructive file operations
|
|
8723
|
+
{
|
|
8724
|
+
pattern: /\brm\s+(-[a-zA-Z]*r[a-zA-Z]*\s+|.*\s+-[a-zA-Z]*r).*\//i,
|
|
8725
|
+
reason: "Recursive delete with path",
|
|
8726
|
+
block: true
|
|
8727
|
+
},
|
|
8728
|
+
{
|
|
8729
|
+
pattern: /\brm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+|.*\s+-[a-zA-Z]*f).*--no-preserve-root/i,
|
|
8730
|
+
reason: "Force delete without preserve root",
|
|
8731
|
+
block: true
|
|
8732
|
+
},
|
|
8733
|
+
{
|
|
8734
|
+
pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+\//i,
|
|
8735
|
+
reason: "Recursive force delete on root paths",
|
|
8736
|
+
block: true
|
|
8737
|
+
},
|
|
8738
|
+
{
|
|
8739
|
+
pattern: /\brm\s+-[a-zA-Z]*f[a-zA-Z]*r[a-zA-Z]*\s+\//i,
|
|
8740
|
+
reason: "Force recursive delete on root paths",
|
|
8741
|
+
block: true
|
|
8742
|
+
},
|
|
8743
|
+
// System-level dangerous commands
|
|
8744
|
+
{ pattern: /\bsudo\b/i, reason: "Elevated privileges (sudo)", block: true },
|
|
8745
|
+
{ pattern: /\bsu\s+(-|root)/i, reason: "Switch to root user", block: true },
|
|
8746
|
+
{ pattern: /\bchmod\s+777\b/i, reason: "Overly permissive chmod", block: false },
|
|
8747
|
+
{ pattern: /\bchown\s+-R\s+root/i, reason: "Recursive chown to root", block: true },
|
|
8748
|
+
// Disk/partition operations
|
|
8749
|
+
{ pattern: /\bmkfs\b/i, reason: "Filesystem creation", block: true },
|
|
8750
|
+
{ pattern: /\bfdisk\b/i, reason: "Disk partitioning", block: true },
|
|
8751
|
+
{ pattern: /\bdd\s+.*of=\/dev\//i, reason: "Direct disk write", block: true },
|
|
8752
|
+
// Network attacks
|
|
8753
|
+
{ pattern: /\b(nc|netcat)\s+.*-e\s+\/bin\/(ba)?sh/i, reason: "Reverse shell attempt", block: true },
|
|
8754
|
+
{ pattern: /\bcurl\s+.*\|\s*(ba)?sh/i, reason: "Piping remote script to shell", block: true },
|
|
8755
|
+
{ pattern: /\bwget\s+.*\|\s*(ba)?sh/i, reason: "Piping remote script to shell", block: true },
|
|
8756
|
+
// Fork bombs and resource exhaustion
|
|
8757
|
+
{ pattern: /:\(\)\s*\{\s*:\|:&\s*\}\s*;/i, reason: "Fork bomb", block: true },
|
|
8758
|
+
{ pattern: /\bwhile\s+true.*do.*done.*&/i, reason: "Infinite loop in background", block: false },
|
|
8759
|
+
// Credential/sensitive data access
|
|
8760
|
+
{ pattern: /\/etc\/shadow/i, reason: "Access to shadow file", block: true },
|
|
8761
|
+
{ pattern: /\/etc\/passwd.*>/i, reason: "Modifying passwd file", block: true },
|
|
8762
|
+
{ pattern: /\baws\s+.*--profile\s+/i, reason: "AWS profile access", block: false },
|
|
8763
|
+
// History/log manipulation
|
|
8764
|
+
{ pattern: /\bhistory\s+-c\b/i, reason: "Clearing shell history", block: false },
|
|
8765
|
+
{ pattern: />\s*\/var\/log\//i, reason: "Overwriting system logs", block: true },
|
|
8766
|
+
// Dangerous redirects
|
|
8767
|
+
{ pattern: />\s*\/dev\/sda/i, reason: "Writing to block device", block: true },
|
|
8768
|
+
{ pattern: />\s*\/dev\/null.*2>&1.*</i, reason: "Potentially hiding output", block: false },
|
|
8769
|
+
// Environment manipulation
|
|
8770
|
+
{ pattern: /\bexport\s+PATH\s*=\s*[^$]/i, reason: "Overwriting PATH", block: false },
|
|
8771
|
+
{ pattern: /\bexport\s+LD_PRELOAD/i, reason: "LD_PRELOAD manipulation", block: true },
|
|
8772
|
+
// Process/system control
|
|
8773
|
+
{ pattern: /\bkill\s+-9\s+(-1|1)\b/i, reason: "Killing all processes", block: true },
|
|
8774
|
+
{ pattern: /\bkillall\s+-9\b/i, reason: "Force killing processes", block: false },
|
|
8775
|
+
{ pattern: /\bshutdown\b/i, reason: "System shutdown", block: true },
|
|
8776
|
+
{ pattern: /\breboot\b/i, reason: "System reboot", block: true },
|
|
8777
|
+
{ pattern: /\binit\s+[06]\b/i, reason: "System runlevel change", block: true }
|
|
8778
|
+
];
|
|
8779
|
+
var SAFE_COMMAND_PREFIXES = [
|
|
8780
|
+
"ls",
|
|
8781
|
+
"cat",
|
|
8782
|
+
"head",
|
|
8783
|
+
"tail",
|
|
8784
|
+
"grep",
|
|
8785
|
+
"find",
|
|
8786
|
+
"echo",
|
|
8787
|
+
"pwd",
|
|
8788
|
+
"whoami",
|
|
8789
|
+
"date",
|
|
8790
|
+
"cal",
|
|
8791
|
+
"wc",
|
|
8792
|
+
"sort",
|
|
8793
|
+
"uniq",
|
|
8794
|
+
"cut",
|
|
8795
|
+
"tr",
|
|
8796
|
+
"sed",
|
|
8797
|
+
"awk",
|
|
8798
|
+
"git",
|
|
8799
|
+
"npm",
|
|
8800
|
+
"pnpm",
|
|
8801
|
+
"yarn",
|
|
8802
|
+
"node",
|
|
8803
|
+
"npx",
|
|
8804
|
+
"tsx",
|
|
8805
|
+
"ts-node",
|
|
8806
|
+
"python",
|
|
8807
|
+
"python3",
|
|
8808
|
+
"pip",
|
|
8809
|
+
"pip3",
|
|
8810
|
+
"docker",
|
|
8811
|
+
"docker-compose",
|
|
8812
|
+
"curl",
|
|
8813
|
+
"wget",
|
|
8814
|
+
// These are safe for fetching, blocked when piped to shell
|
|
8815
|
+
"mkdir",
|
|
8816
|
+
"touch",
|
|
8817
|
+
"cp",
|
|
8818
|
+
"mv",
|
|
8819
|
+
// File operations (still require permission)
|
|
8820
|
+
"which",
|
|
8821
|
+
"whereis",
|
|
8822
|
+
"type",
|
|
8823
|
+
"file",
|
|
8824
|
+
"stat",
|
|
8825
|
+
"env",
|
|
8826
|
+
"printenv",
|
|
8827
|
+
"set",
|
|
8828
|
+
"man",
|
|
8829
|
+
"help",
|
|
8830
|
+
"info",
|
|
8831
|
+
"diff",
|
|
8832
|
+
"comm",
|
|
8833
|
+
"cmp",
|
|
8834
|
+
"tar",
|
|
8835
|
+
"zip",
|
|
8836
|
+
"unzip",
|
|
8837
|
+
"gzip",
|
|
8838
|
+
"gunzip",
|
|
8839
|
+
"ssh",
|
|
8840
|
+
"scp",
|
|
8841
|
+
"rsync",
|
|
8842
|
+
// Network tools
|
|
8843
|
+
"make",
|
|
8844
|
+
"cmake",
|
|
8845
|
+
"cargo",
|
|
8846
|
+
"go",
|
|
8847
|
+
"rustc",
|
|
8848
|
+
"gcc",
|
|
8849
|
+
"g++",
|
|
8850
|
+
// Build tools
|
|
8851
|
+
"jest",
|
|
8852
|
+
"vitest",
|
|
8853
|
+
"mocha",
|
|
8854
|
+
"pytest",
|
|
8855
|
+
// Test runners
|
|
8856
|
+
"eslint",
|
|
8857
|
+
"prettier",
|
|
8858
|
+
"tsc"
|
|
8859
|
+
// Linters/formatters
|
|
8860
|
+
];
|
|
8861
|
+
function checkDangerousPatterns(command) {
|
|
8862
|
+
for (const { pattern, reason, block } of DANGEROUS_PATTERNS) {
|
|
8863
|
+
if (pattern.test(command)) {
|
|
8864
|
+
return { blocked: block, reason };
|
|
8865
|
+
}
|
|
8866
|
+
}
|
|
8867
|
+
return { blocked: false };
|
|
8868
|
+
}
|
|
8869
|
+
function getBaseCommand(command) {
|
|
8870
|
+
const trimmed = command.trim();
|
|
8871
|
+
const match = trimmed.match(/^(\S+)/);
|
|
8872
|
+
return match ? match[1] : "";
|
|
8873
|
+
}
|
|
8874
|
+
function isSafeCommandPrefix(command) {
|
|
8875
|
+
const baseCommand = getBaseCommand(command);
|
|
8876
|
+
return SAFE_COMMAND_PREFIXES.some((safe) => baseCommand === safe || baseCommand.endsWith(`/${safe}`));
|
|
8877
|
+
}
|
|
8878
|
+
async function executeBashCommand(params) {
|
|
8879
|
+
const { command, cwd: relativeCwd, timeout = DEFAULT_TIMEOUT_MS } = params;
|
|
8880
|
+
if (!command || command.trim().length === 0) {
|
|
8881
|
+
return {
|
|
8882
|
+
stdout: "",
|
|
8883
|
+
stderr: "Error: Command cannot be empty",
|
|
8884
|
+
exitCode: 1,
|
|
8885
|
+
timedOut: false,
|
|
8886
|
+
blocked: true,
|
|
8887
|
+
blockedReason: "Empty command"
|
|
8888
|
+
};
|
|
8889
|
+
}
|
|
8890
|
+
const dangerCheck = checkDangerousPatterns(command);
|
|
8891
|
+
if (dangerCheck.blocked) {
|
|
8892
|
+
return {
|
|
8893
|
+
stdout: "",
|
|
8894
|
+
stderr: `Command blocked for safety: ${dangerCheck.reason}`,
|
|
8895
|
+
exitCode: 1,
|
|
8896
|
+
timedOut: false,
|
|
8897
|
+
blocked: true,
|
|
8898
|
+
blockedReason: dangerCheck.reason
|
|
8899
|
+
};
|
|
8900
|
+
}
|
|
8901
|
+
const baseCwd = process.cwd();
|
|
8902
|
+
const targetCwd = relativeCwd ? path11.resolve(baseCwd, relativeCwd) : baseCwd;
|
|
8903
|
+
const effectiveTimeout = Math.min(timeout, 5 * 60 * 1e3);
|
|
8904
|
+
return new Promise((resolve3) => {
|
|
8905
|
+
let stdout = "";
|
|
8906
|
+
let stderr = "";
|
|
8907
|
+
let timedOut = false;
|
|
8908
|
+
const proc = spawn("bash", ["-c", command], {
|
|
8909
|
+
cwd: targetCwd,
|
|
8910
|
+
env: {
|
|
8911
|
+
...process.env,
|
|
8912
|
+
// Prevent color codes that might be hard to read
|
|
8913
|
+
NO_COLOR: "1",
|
|
8914
|
+
FORCE_COLOR: "0"
|
|
8915
|
+
},
|
|
8916
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
8917
|
+
});
|
|
8918
|
+
const timeoutId = setTimeout(() => {
|
|
8919
|
+
timedOut = true;
|
|
8920
|
+
proc.kill("SIGTERM");
|
|
8921
|
+
setTimeout(() => {
|
|
8922
|
+
if (!proc.killed) {
|
|
8923
|
+
proc.kill("SIGKILL");
|
|
8924
|
+
}
|
|
8925
|
+
}, 5e3);
|
|
8926
|
+
}, effectiveTimeout);
|
|
8927
|
+
proc.stdout.on("data", (data) => {
|
|
8928
|
+
if (stdout.length < MAX_OUTPUT_SIZE) {
|
|
8929
|
+
stdout += data.toString();
|
|
8930
|
+
if (stdout.length > MAX_OUTPUT_SIZE) {
|
|
8931
|
+
stdout = stdout.slice(0, MAX_OUTPUT_SIZE) + "\n... [output truncated]";
|
|
8932
|
+
}
|
|
8933
|
+
}
|
|
8934
|
+
});
|
|
8935
|
+
proc.stderr.on("data", (data) => {
|
|
8936
|
+
if (stderr.length < MAX_OUTPUT_SIZE) {
|
|
8937
|
+
stderr += data.toString();
|
|
8938
|
+
if (stderr.length > MAX_OUTPUT_SIZE) {
|
|
8939
|
+
stderr = stderr.slice(0, MAX_OUTPUT_SIZE) + "\n... [output truncated]";
|
|
8940
|
+
}
|
|
8941
|
+
}
|
|
8942
|
+
});
|
|
8943
|
+
proc.on("close", (exitCode) => {
|
|
8944
|
+
clearTimeout(timeoutId);
|
|
8945
|
+
resolve3({
|
|
8946
|
+
stdout: stdout.trim(),
|
|
8947
|
+
stderr: stderr.trim(),
|
|
8948
|
+
exitCode,
|
|
8949
|
+
timedOut,
|
|
8950
|
+
blocked: false
|
|
8951
|
+
});
|
|
8952
|
+
});
|
|
8953
|
+
proc.on("error", (error) => {
|
|
8954
|
+
clearTimeout(timeoutId);
|
|
8955
|
+
resolve3({
|
|
8956
|
+
stdout: "",
|
|
8957
|
+
stderr: `Failed to execute command: ${error.message}`,
|
|
8958
|
+
exitCode: 1,
|
|
8959
|
+
timedOut: false,
|
|
8960
|
+
blocked: false
|
|
8961
|
+
});
|
|
8962
|
+
});
|
|
8963
|
+
});
|
|
8964
|
+
}
|
|
8965
|
+
function formatResult(result, command) {
|
|
8966
|
+
const parts = [];
|
|
8967
|
+
parts.push(`$ ${command}`);
|
|
8968
|
+
parts.push("");
|
|
8969
|
+
if (result.blocked) {
|
|
8970
|
+
parts.push(`BLOCKED: ${result.blockedReason}`);
|
|
8971
|
+
parts.push("");
|
|
8972
|
+
parts.push("This command was blocked for safety reasons.");
|
|
8973
|
+
parts.push("If you believe this is a false positive, please run the command manually.");
|
|
8974
|
+
return parts.join("\n");
|
|
8975
|
+
}
|
|
8976
|
+
if (result.timedOut) {
|
|
8977
|
+
parts.push("WARNING: Command timed out and was terminated.");
|
|
8978
|
+
parts.push("");
|
|
8979
|
+
}
|
|
8980
|
+
if (result.stdout) {
|
|
8981
|
+
parts.push(result.stdout);
|
|
8982
|
+
}
|
|
8983
|
+
if (result.stderr) {
|
|
8984
|
+
if (result.stdout) {
|
|
8985
|
+
parts.push("");
|
|
8986
|
+
}
|
|
8987
|
+
parts.push("STDERR:");
|
|
8988
|
+
parts.push(result.stderr);
|
|
8989
|
+
}
|
|
8990
|
+
if (result.exitCode !== 0 && result.exitCode !== null) {
|
|
8991
|
+
parts.push("");
|
|
8992
|
+
parts.push(`Exit code: ${result.exitCode}`);
|
|
8993
|
+
}
|
|
8994
|
+
if (!result.stdout && !result.stderr && !result.timedOut) {
|
|
8995
|
+
parts.push("(command completed with no output)");
|
|
8996
|
+
}
|
|
8997
|
+
return parts.join("\n");
|
|
8998
|
+
}
|
|
8999
|
+
var bashExecuteTool = {
|
|
9000
|
+
name: "bash_execute",
|
|
9001
|
+
implementation: (context) => ({
|
|
9002
|
+
toolFn: async (value) => {
|
|
9003
|
+
const params = value;
|
|
9004
|
+
const isSafe = isSafeCommandPrefix(params.command);
|
|
9005
|
+
context.logger.info("Bash: Executing command", {
|
|
9006
|
+
command: params.command,
|
|
9007
|
+
cwd: params.cwd || ".",
|
|
9008
|
+
timeout: params.timeout || DEFAULT_TIMEOUT_MS,
|
|
9009
|
+
isSafeCommand: isSafe
|
|
9010
|
+
});
|
|
9011
|
+
if (context.onStart) {
|
|
9012
|
+
await context.onStart("bash_execute", {
|
|
9013
|
+
command: params.command,
|
|
9014
|
+
cwd: params.cwd
|
|
9015
|
+
});
|
|
9016
|
+
}
|
|
9017
|
+
try {
|
|
9018
|
+
const result = await executeBashCommand(params);
|
|
9019
|
+
const formattedResult = formatResult(result, params.command);
|
|
9020
|
+
context.logger.info("Bash: Command completed", {
|
|
9021
|
+
exitCode: result.exitCode,
|
|
9022
|
+
timedOut: result.timedOut,
|
|
9023
|
+
blocked: result.blocked
|
|
9024
|
+
});
|
|
9025
|
+
if (context.onFinish) {
|
|
9026
|
+
await context.onFinish("bash_execute", {
|
|
9027
|
+
command: params.command,
|
|
9028
|
+
exitCode: result.exitCode,
|
|
9029
|
+
blocked: result.blocked
|
|
9030
|
+
});
|
|
9031
|
+
}
|
|
9032
|
+
return formattedResult;
|
|
9033
|
+
} catch (error) {
|
|
9034
|
+
context.logger.error("Bash: Command failed", error);
|
|
9035
|
+
if (context.onFinish) {
|
|
9036
|
+
await context.onFinish("bash_execute", {
|
|
9037
|
+
command: params.command,
|
|
9038
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
9039
|
+
});
|
|
9040
|
+
}
|
|
9041
|
+
throw error;
|
|
9042
|
+
}
|
|
9043
|
+
},
|
|
9044
|
+
toolSchema: {
|
|
9045
|
+
name: "bash_execute",
|
|
9046
|
+
description: `Execute a bash command in the terminal. Use this for running shell commands, scripts, build tools, git operations, and other CLI tasks.
|
|
9047
|
+
|
|
9048
|
+
SAFETY NOTES:
|
|
9049
|
+
- Commands are executed in the current working directory (or specified cwd)
|
|
9050
|
+
- Dangerous commands (sudo, rm -rf /, etc.) are automatically blocked
|
|
9051
|
+
- Commands have a default timeout of 60 seconds (max 5 minutes)
|
|
9052
|
+
- Output is limited to prevent overwhelming responses
|
|
9053
|
+
- This tool ALWAYS requires user permission before execution
|
|
9054
|
+
|
|
9055
|
+
COMMON USE CASES:
|
|
9056
|
+
- Running build commands: npm run build, make, cargo build
|
|
9057
|
+
- Git operations: git status, git log, git diff
|
|
9058
|
+
- Viewing system info: ls, pwd, cat, head, tail
|
|
9059
|
+
- Running tests: npm test, pytest, cargo test
|
|
9060
|
+
- Package management: npm install, pip install
|
|
9061
|
+
- File operations: mkdir, cp, mv (with permission)
|
|
9062
|
+
|
|
9063
|
+
BLOCKED OPERATIONS:
|
|
9064
|
+
- sudo and privilege escalation
|
|
9065
|
+
- Recursive deletes on system paths
|
|
9066
|
+
- Direct disk operations
|
|
9067
|
+
- Fork bombs and resource exhaustion
|
|
9068
|
+
- Piping remote scripts to shell`,
|
|
9069
|
+
parameters: {
|
|
9070
|
+
type: "object",
|
|
9071
|
+
properties: {
|
|
9072
|
+
command: {
|
|
9073
|
+
type: "string",
|
|
9074
|
+
description: "The bash command to execute. Can include pipes, redirects, and chained commands."
|
|
9075
|
+
},
|
|
9076
|
+
cwd: {
|
|
9077
|
+
type: "string",
|
|
9078
|
+
description: "Working directory for the command (optional). Can be relative or absolute path. Defaults to current directory."
|
|
9079
|
+
},
|
|
9080
|
+
timeout: {
|
|
9081
|
+
type: "number",
|
|
9082
|
+
description: "Timeout in milliseconds (optional, default: 60000, max: 300000). Command will be terminated if it exceeds this time."
|
|
9083
|
+
}
|
|
9084
|
+
},
|
|
9085
|
+
required: ["command"]
|
|
9086
|
+
}
|
|
9087
|
+
}
|
|
9088
|
+
})
|
|
9089
|
+
};
|
|
9090
|
+
|
|
8713
9091
|
// ../../b4m-core/packages/services/dist/src/llm/tools/index.js
|
|
8714
9092
|
var tools = {
|
|
8715
9093
|
dice_roll: diceRollTool,
|
|
@@ -8737,7 +9115,9 @@ var tools = {
|
|
|
8737
9115
|
create_file: createFileTool,
|
|
8738
9116
|
glob_files: globFilesTool,
|
|
8739
9117
|
grep_search: grepSearchTool,
|
|
8740
|
-
delete_file: deleteFileTool
|
|
9118
|
+
delete_file: deleteFileTool,
|
|
9119
|
+
// Shell execution
|
|
9120
|
+
bash_execute: bashExecuteTool
|
|
8741
9121
|
};
|
|
8742
9122
|
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model) => {
|
|
8743
9123
|
const context = {
|
|
@@ -9012,7 +9392,7 @@ async function generateFileDeletePreview(args) {
|
|
|
9012
9392
|
if (!existsSync7(args.path)) {
|
|
9013
9393
|
return `[File does not exist: ${args.path}]`;
|
|
9014
9394
|
}
|
|
9015
|
-
const stats = await import("fs/promises").then((
|
|
9395
|
+
const stats = await import("fs/promises").then((fs12) => fs12.stat(args.path));
|
|
9016
9396
|
return `[File will be deleted]
|
|
9017
9397
|
|
|
9018
9398
|
Path: ${args.path}
|
|
@@ -9025,7 +9405,7 @@ Last modified: ${stats.mtime.toLocaleString()}`;
|
|
|
9025
9405
|
|
|
9026
9406
|
// src/utils/Logger.ts
|
|
9027
9407
|
import fs10 from "fs/promises";
|
|
9028
|
-
import
|
|
9408
|
+
import path12 from "path";
|
|
9029
9409
|
import os from "os";
|
|
9030
9410
|
var Logger2 = class _Logger {
|
|
9031
9411
|
constructor() {
|
|
@@ -9048,9 +9428,9 @@ var Logger2 = class _Logger {
|
|
|
9048
9428
|
*/
|
|
9049
9429
|
async initialize(sessionId) {
|
|
9050
9430
|
this.sessionId = sessionId;
|
|
9051
|
-
const debugDir =
|
|
9431
|
+
const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
|
|
9052
9432
|
await fs10.mkdir(debugDir, { recursive: true });
|
|
9053
|
-
this.logFilePath =
|
|
9433
|
+
this.logFilePath = path12.join(debugDir, `${sessionId}.txt`);
|
|
9054
9434
|
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
9055
9435
|
}
|
|
9056
9436
|
/**
|
|
@@ -9260,12 +9640,12 @@ var Logger2 = class _Logger {
|
|
|
9260
9640
|
async cleanupOldLogs() {
|
|
9261
9641
|
if (!this.fileLoggingEnabled) return;
|
|
9262
9642
|
try {
|
|
9263
|
-
const debugDir =
|
|
9643
|
+
const debugDir = path12.join(os.homedir(), ".bike4mind", "debug");
|
|
9264
9644
|
const files = await fs10.readdir(debugDir);
|
|
9265
9645
|
const now = Date.now();
|
|
9266
9646
|
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
9267
9647
|
for (const file of files) {
|
|
9268
|
-
const filePath =
|
|
9648
|
+
const filePath = path12.join(debugDir, file);
|
|
9269
9649
|
const stats = await fs10.stat(filePath);
|
|
9270
9650
|
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
9271
9651
|
await fs10.unlink(filePath);
|
|
@@ -9330,7 +9710,8 @@ var LOCAL_TOOLS = [
|
|
|
9330
9710
|
"edit_file",
|
|
9331
9711
|
"dice_roll",
|
|
9332
9712
|
"math_evaluate",
|
|
9333
|
-
"current_datetime"
|
|
9713
|
+
"current_datetime",
|
|
9714
|
+
"bash_execute"
|
|
9334
9715
|
];
|
|
9335
9716
|
function isServerTool(toolName) {
|
|
9336
9717
|
return SERVER_TOOLS.includes(toolName);
|
|
@@ -9360,21 +9741,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
9360
9741
|
async upload(input, destination, options) {
|
|
9361
9742
|
return `/tmp/${destination}`;
|
|
9362
9743
|
}
|
|
9363
|
-
async download(
|
|
9744
|
+
async download(path15) {
|
|
9364
9745
|
throw new Error("Download not supported in CLI");
|
|
9365
9746
|
}
|
|
9366
|
-
async delete(
|
|
9747
|
+
async delete(path15) {
|
|
9367
9748
|
}
|
|
9368
|
-
async getSignedUrl(
|
|
9369
|
-
return `/tmp/${
|
|
9749
|
+
async getSignedUrl(path15) {
|
|
9750
|
+
return `/tmp/${path15}`;
|
|
9370
9751
|
}
|
|
9371
|
-
getPublicUrl(
|
|
9372
|
-
return `/tmp/${
|
|
9752
|
+
getPublicUrl(path15) {
|
|
9753
|
+
return `/tmp/${path15}`;
|
|
9373
9754
|
}
|
|
9374
|
-
async getPreview(
|
|
9375
|
-
return `/tmp/${
|
|
9755
|
+
async getPreview(path15) {
|
|
9756
|
+
return `/tmp/${path15}`;
|
|
9376
9757
|
}
|
|
9377
|
-
async getMetadata(
|
|
9758
|
+
async getMetadata(path15) {
|
|
9378
9759
|
return { size: 0, contentType: "application/octet-stream" };
|
|
9379
9760
|
}
|
|
9380
9761
|
};
|
|
@@ -9432,6 +9813,10 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
9432
9813
|
} catch (error) {
|
|
9433
9814
|
preview = `[Could not generate preview: ${error instanceof Error ? error.message : "Unknown error"}]`;
|
|
9434
9815
|
}
|
|
9816
|
+
} else if (toolName === "bash_execute" && args?.command) {
|
|
9817
|
+
const cwd = args.cwd ? ` (in ${args.cwd})` : "";
|
|
9818
|
+
const timeout = args.timeout ? ` [timeout: ${args.timeout}ms]` : "";
|
|
9819
|
+
preview = `$ ${args.command}${cwd}${timeout}`;
|
|
9435
9820
|
}
|
|
9436
9821
|
const response = await showPermissionPrompt(toolName, args, preview);
|
|
9437
9822
|
if (response.action === "deny") {
|
|
@@ -9502,6 +9887,8 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
9502
9887
|
glob_files: {},
|
|
9503
9888
|
grep_search: {},
|
|
9504
9889
|
delete_file: {},
|
|
9890
|
+
// Shell execution (always requires permission)
|
|
9891
|
+
bash_execute: {},
|
|
9505
9892
|
// Server-side tools (executed via /api/ai/v1/tools Lambda)
|
|
9506
9893
|
// Routed by ToolRouter to use B4M company API keys
|
|
9507
9894
|
weather_info: {},
|
|
@@ -9567,6 +9954,7 @@ var DEFAULT_TOOL_CATEGORIES = {
|
|
|
9567
9954
|
create_file: "prompt_always",
|
|
9568
9955
|
delete_file: "prompt_always",
|
|
9569
9956
|
shell_execute: "prompt_always",
|
|
9957
|
+
bash_execute: "prompt_always",
|
|
9570
9958
|
git_commit: "prompt_always",
|
|
9571
9959
|
git_push: "prompt_always",
|
|
9572
9960
|
// ===== PROMPT DEFAULT (Repository read tools) =====
|
|
@@ -9728,10 +10116,122 @@ function getEnvironmentName(configApiConfig) {
|
|
|
9728
10116
|
return "Bike4Mind";
|
|
9729
10117
|
}
|
|
9730
10118
|
|
|
10119
|
+
// src/utils/contextLoader.ts
|
|
10120
|
+
import * as fs11 from "fs";
|
|
10121
|
+
import * as path13 from "path";
|
|
10122
|
+
import { homedir as homedir4 } from "os";
|
|
10123
|
+
var CONTEXT_FILE_SIZE_LIMIT = 100 * 1024;
|
|
10124
|
+
var PROJECT_CONTEXT_FILES = [
|
|
10125
|
+
"CLAUDE.local.md",
|
|
10126
|
+
// gitignored, highest priority
|
|
10127
|
+
"CLAUDE.md",
|
|
10128
|
+
"AGENTS.md",
|
|
10129
|
+
// cross-tool standard
|
|
10130
|
+
"AI.local.md",
|
|
10131
|
+
// gitignored
|
|
10132
|
+
"AI.md",
|
|
10133
|
+
"INSTRUCTIONS.md"
|
|
10134
|
+
];
|
|
10135
|
+
var GLOBAL_CONTEXT_FILES = ["AI.local.md", "AI.md"];
|
|
10136
|
+
function formatFileSize2(bytes) {
|
|
10137
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
10138
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
10139
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
10140
|
+
}
|
|
10141
|
+
function tryReadContextFile(dir, filename, source) {
|
|
10142
|
+
const filePath = path13.join(dir, filename);
|
|
10143
|
+
try {
|
|
10144
|
+
const stats = fs11.lstatSync(filePath);
|
|
10145
|
+
if (stats.isDirectory()) {
|
|
10146
|
+
return null;
|
|
10147
|
+
}
|
|
10148
|
+
if (stats.isSymbolicLink()) {
|
|
10149
|
+
return {
|
|
10150
|
+
error: `${source === "global" ? "Global" : "Project"} ${filename} is a symlink (not allowed for security)`
|
|
10151
|
+
};
|
|
10152
|
+
}
|
|
10153
|
+
if (stats.size > CONTEXT_FILE_SIZE_LIMIT) {
|
|
10154
|
+
return {
|
|
10155
|
+
error: `${source === "global" ? "Global" : "Project"} ${filename} exceeds 100KB limit (${formatFileSize2(stats.size)})`
|
|
10156
|
+
};
|
|
10157
|
+
}
|
|
10158
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
10159
|
+
return {
|
|
10160
|
+
filename,
|
|
10161
|
+
content,
|
|
10162
|
+
source,
|
|
10163
|
+
path: filePath
|
|
10164
|
+
};
|
|
10165
|
+
} catch (err) {
|
|
10166
|
+
if (err.code === "ENOENT") {
|
|
10167
|
+
return null;
|
|
10168
|
+
}
|
|
10169
|
+
if (err.code === "EACCES") {
|
|
10170
|
+
return {
|
|
10171
|
+
error: `Cannot read ${source} ${filename}: permission denied`
|
|
10172
|
+
};
|
|
10173
|
+
}
|
|
10174
|
+
return {
|
|
10175
|
+
error: `Cannot read ${source} ${filename}: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
10176
|
+
};
|
|
10177
|
+
}
|
|
10178
|
+
}
|
|
10179
|
+
function findContextFile(dir, candidates, source) {
|
|
10180
|
+
for (const filename of candidates) {
|
|
10181
|
+
const result = tryReadContextFile(dir, filename, source);
|
|
10182
|
+
if (result === null) {
|
|
10183
|
+
continue;
|
|
10184
|
+
}
|
|
10185
|
+
if ("error" in result) {
|
|
10186
|
+
return { result: null, error: result.error };
|
|
10187
|
+
}
|
|
10188
|
+
return { result, error: null };
|
|
10189
|
+
}
|
|
10190
|
+
return { result: null, error: null };
|
|
10191
|
+
}
|
|
10192
|
+
function mergeContextContent(global, project) {
|
|
10193
|
+
if (global && project) {
|
|
10194
|
+
return `${global.content}
|
|
10195
|
+
|
|
10196
|
+
---
|
|
10197
|
+
|
|
10198
|
+
${project.content}`;
|
|
10199
|
+
}
|
|
10200
|
+
if (global) {
|
|
10201
|
+
return global.content;
|
|
10202
|
+
}
|
|
10203
|
+
if (project) {
|
|
10204
|
+
return project.content;
|
|
10205
|
+
}
|
|
10206
|
+
return "";
|
|
10207
|
+
}
|
|
10208
|
+
async function loadContextFiles(projectDir) {
|
|
10209
|
+
const errors = [];
|
|
10210
|
+
const globalDir = path13.join(homedir4(), ".bike4mind");
|
|
10211
|
+
const projectDirectory = projectDir || process.cwd();
|
|
10212
|
+
const [globalResult, projectResult] = await Promise.all([
|
|
10213
|
+
Promise.resolve(findContextFile(globalDir, GLOBAL_CONTEXT_FILES, "global")),
|
|
10214
|
+
Promise.resolve(findContextFile(projectDirectory, PROJECT_CONTEXT_FILES, "project"))
|
|
10215
|
+
]);
|
|
10216
|
+
if (globalResult.error) {
|
|
10217
|
+
errors.push(globalResult.error);
|
|
10218
|
+
}
|
|
10219
|
+
if (projectResult.error) {
|
|
10220
|
+
errors.push(projectResult.error);
|
|
10221
|
+
}
|
|
10222
|
+
const mergedContent = mergeContextContent(globalResult.result, projectResult.result);
|
|
10223
|
+
return {
|
|
10224
|
+
globalContext: globalResult.result,
|
|
10225
|
+
projectContext: projectResult.result,
|
|
10226
|
+
mergedContent,
|
|
10227
|
+
errors
|
|
10228
|
+
};
|
|
10229
|
+
}
|
|
10230
|
+
|
|
9731
10231
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
9732
10232
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
9733
10233
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
9734
|
-
import
|
|
10234
|
+
import path14 from "path";
|
|
9735
10235
|
import { existsSync as existsSync8, readdirSync as readdirSync3 } from "fs";
|
|
9736
10236
|
var MCPClient = class {
|
|
9737
10237
|
// Note: This class handles MCP server communication with repository filtering
|
|
@@ -9772,16 +10272,16 @@ var MCPClient = class {
|
|
|
9772
10272
|
const root = process.env.INIT_CWD || process.cwd();
|
|
9773
10273
|
const candidatePaths = [
|
|
9774
10274
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
9775
|
-
|
|
10275
|
+
path14.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
9776
10276
|
// When running from SST Lambda deployed environment (/var/task)
|
|
9777
|
-
|
|
10277
|
+
path14.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
9778
10278
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
9779
|
-
|
|
10279
|
+
path14.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
9780
10280
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
9781
|
-
|
|
10281
|
+
path14.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
9782
10282
|
// Original paths (backward compatibility)
|
|
9783
|
-
|
|
9784
|
-
|
|
10283
|
+
path14.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
10284
|
+
path14.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
9785
10285
|
];
|
|
9786
10286
|
const serverScriptPath = candidatePaths.find((p) => existsSync8(p));
|
|
9787
10287
|
if (!serverScriptPath) {
|
|
@@ -10585,7 +11085,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
10585
11085
|
// package.json
|
|
10586
11086
|
var package_default = {
|
|
10587
11087
|
name: "@bike4mind/cli",
|
|
10588
|
-
version: "0.2.
|
|
11088
|
+
version: "0.2.10-dowgrade-mcp-sdk.17228+eeed70576",
|
|
10589
11089
|
type: "module",
|
|
10590
11090
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
10591
11091
|
license: "UNLICENSED",
|
|
@@ -10640,7 +11140,7 @@ var package_default = {
|
|
|
10640
11140
|
"@google/generative-ai": "^0.21.0",
|
|
10641
11141
|
"@joplin/turndown-plugin-gfm": "^1.0.62",
|
|
10642
11142
|
"@mendable/firecrawl-js": "^1.29.3",
|
|
10643
|
-
"@modelcontextprotocol/sdk": "
|
|
11143
|
+
"@modelcontextprotocol/sdk": "1.20.1",
|
|
10644
11144
|
"@octokit/rest": "^22.0.0",
|
|
10645
11145
|
"@opensearch-project/opensearch": "2.11.0",
|
|
10646
11146
|
"async-mutex": "^0.5.0",
|
|
@@ -10688,11 +11188,11 @@ var package_default = {
|
|
|
10688
11188
|
},
|
|
10689
11189
|
devDependencies: {
|
|
10690
11190
|
"@bike4mind/agents": "0.1.0",
|
|
10691
|
-
"@bike4mind/common": "2.
|
|
10692
|
-
"@bike4mind/mcp": "1.20.
|
|
10693
|
-
"@bike4mind/services": "2.
|
|
10694
|
-
"@bike4mind/utils": "2.1.
|
|
10695
|
-
"@types/better-sqlite3": "^7.6.
|
|
11191
|
+
"@bike4mind/common": "2.39.1-dowgrade-mcp-sdk.17228+eeed70576",
|
|
11192
|
+
"@bike4mind/mcp": "1.20.4-dowgrade-mcp-sdk.17228+eeed70576",
|
|
11193
|
+
"@bike4mind/services": "2.34.2-dowgrade-mcp-sdk.17228+eeed70576",
|
|
11194
|
+
"@bike4mind/utils": "2.1.4-dowgrade-mcp-sdk.17228+eeed70576",
|
|
11195
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
10696
11196
|
"@types/diff": "^5.0.9",
|
|
10697
11197
|
"@types/jsonwebtoken": "^9.0.4",
|
|
10698
11198
|
"@types/node": "^22.9.0",
|
|
@@ -10704,7 +11204,7 @@ var package_default = {
|
|
|
10704
11204
|
typescript: "^5.9.3",
|
|
10705
11205
|
vitest: "^3.2.4"
|
|
10706
11206
|
},
|
|
10707
|
-
gitHead: "
|
|
11207
|
+
gitHead: "eeed70576ada327d03166880bbd1d1d32f7d4e7c"
|
|
10708
11208
|
};
|
|
10709
11209
|
|
|
10710
11210
|
// src/config/constants.ts
|
|
@@ -10956,6 +11456,24 @@ function CliApp() {
|
|
|
10956
11456
|
}
|
|
10957
11457
|
const allTools = [...b4mTools, ...mcpTools];
|
|
10958
11458
|
console.log(`\u2705 Total: ${allTools.length} tool(s) available`);
|
|
11459
|
+
const projectDir = state.configStore.getProjectConfigDir();
|
|
11460
|
+
const contextResult = await loadContextFiles(projectDir);
|
|
11461
|
+
if (contextResult.globalContext) {
|
|
11462
|
+
console.log(`\u{1F4C4} Global context: ${contextResult.globalContext.filename}`);
|
|
11463
|
+
}
|
|
11464
|
+
if (contextResult.projectContext) {
|
|
11465
|
+
console.log(`\u{1F4C4} Project context: ${contextResult.projectContext.filename}`);
|
|
11466
|
+
}
|
|
11467
|
+
for (const error of contextResult.errors) {
|
|
11468
|
+
console.log(`\u26A0\uFE0F Context file error: ${error}`);
|
|
11469
|
+
}
|
|
11470
|
+
const contextSection = contextResult.mergedContent ? `
|
|
11471
|
+
|
|
11472
|
+
## Project Context
|
|
11473
|
+
|
|
11474
|
+
Follow these project-specific instructions:
|
|
11475
|
+
|
|
11476
|
+
${contextResult.mergedContent}` : "";
|
|
10959
11477
|
const cliSystemPrompt = `You are an autonomous AI assistant with access to tools. Your job is to help users by taking action and solving problems proactively.
|
|
10960
11478
|
|
|
10961
11479
|
CORE BEHAVIOR:
|
|
@@ -10985,7 +11503,7 @@ EXAMPLES:
|
|
|
10985
11503
|
- "enhance README" \u2192 file_read \u2192 generate \u2192 create_file
|
|
10986
11504
|
- "what packages installed?" \u2192 glob_files "**/package.json" \u2192 file_read
|
|
10987
11505
|
|
|
10988
|
-
Remember: Use context from previous messages to understand follow-up questions
|
|
11506
|
+
Remember: Use context from previous messages to understand follow-up questions.${contextSection}`;
|
|
10989
11507
|
const maxIterations = config.preferences.maxIterations === null ? 999999 : config.preferences.maxIterations;
|
|
10990
11508
|
const agent = new ReActAgent({
|
|
10991
11509
|
userId: config.userId,
|
|
@@ -11040,6 +11558,29 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
11040
11558
|
console.log("\u{1F4A1} Run /login to authenticate with your B4M account.\n");
|
|
11041
11559
|
return;
|
|
11042
11560
|
}
|
|
11561
|
+
const currentSteps = [];
|
|
11562
|
+
const stepHandler = (step) => {
|
|
11563
|
+
currentSteps.push(step);
|
|
11564
|
+
const currentSession = useCliStore.getState().session;
|
|
11565
|
+
if (currentSession) {
|
|
11566
|
+
const messages = [...currentSession.messages];
|
|
11567
|
+
const lastMessage = messages[messages.length - 1];
|
|
11568
|
+
if (lastMessage && lastMessage.role === "assistant") {
|
|
11569
|
+
messages[messages.length - 1] = {
|
|
11570
|
+
...lastMessage,
|
|
11571
|
+
metadata: {
|
|
11572
|
+
...lastMessage.metadata,
|
|
11573
|
+
steps: [...currentSteps]
|
|
11574
|
+
}
|
|
11575
|
+
};
|
|
11576
|
+
setStoreSession({
|
|
11577
|
+
...currentSession,
|
|
11578
|
+
messages
|
|
11579
|
+
});
|
|
11580
|
+
}
|
|
11581
|
+
}
|
|
11582
|
+
};
|
|
11583
|
+
state.agent.on("action", stepHandler);
|
|
11043
11584
|
try {
|
|
11044
11585
|
let messageContent = message;
|
|
11045
11586
|
let userMessageContent = message;
|
|
@@ -11053,6 +11594,21 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
11053
11594
|
content: userMessageContent,
|
|
11054
11595
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11055
11596
|
};
|
|
11597
|
+
const pendingAssistantMessage = {
|
|
11598
|
+
role: "assistant",
|
|
11599
|
+
content: "...",
|
|
11600
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11601
|
+
metadata: {
|
|
11602
|
+
steps: []
|
|
11603
|
+
}
|
|
11604
|
+
};
|
|
11605
|
+
const sessionWithMessages = {
|
|
11606
|
+
...state.session,
|
|
11607
|
+
messages: [...state.session.messages, userMessage, pendingAssistantMessage],
|
|
11608
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11609
|
+
};
|
|
11610
|
+
setState((prev) => ({ ...prev, session: sessionWithMessages }));
|
|
11611
|
+
setStoreSession(sessionWithMessages);
|
|
11056
11612
|
const recentMessages = state.session.messages.slice(-20);
|
|
11057
11613
|
const previousMessages = recentMessages.filter((msg) => msg.role === "user" || msg.role === "assistant").map((msg) => ({
|
|
11058
11614
|
role: msg.role,
|
|
@@ -11066,26 +11622,28 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
11066
11622
|
console.log("\n\u26A0\uFE0F Action denied by user\n");
|
|
11067
11623
|
}
|
|
11068
11624
|
const successfulToolCalls = result.steps.filter((s) => s.type === "observation").length;
|
|
11069
|
-
const
|
|
11625
|
+
const currentSession = useCliStore.getState().session;
|
|
11626
|
+
if (!currentSession) return;
|
|
11627
|
+
const finalMessages = [...currentSession.messages];
|
|
11628
|
+
const finalAssistantMessage = {
|
|
11070
11629
|
role: "assistant",
|
|
11071
11630
|
content: result.finalAnswer,
|
|
11072
|
-
timestamp:
|
|
11631
|
+
timestamp: pendingAssistantMessage.timestamp,
|
|
11073
11632
|
metadata: {
|
|
11074
11633
|
tokenUsage: {
|
|
11075
11634
|
prompt: 0,
|
|
11076
|
-
// TODO: Extract from result
|
|
11077
11635
|
completion: 0,
|
|
11078
11636
|
total: result.completionInfo.totalTokens
|
|
11079
11637
|
},
|
|
11080
11638
|
steps: result.steps,
|
|
11081
11639
|
// Complete history: thoughts, actions, observations
|
|
11082
11640
|
permissionDenied
|
|
11083
|
-
// Mark if this ended due to permission denial
|
|
11084
11641
|
}
|
|
11085
11642
|
};
|
|
11643
|
+
finalMessages[finalMessages.length - 1] = finalAssistantMessage;
|
|
11086
11644
|
const updatedSession = {
|
|
11087
|
-
...
|
|
11088
|
-
messages:
|
|
11645
|
+
...currentSession,
|
|
11646
|
+
messages: finalMessages,
|
|
11089
11647
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11090
11648
|
metadata: {
|
|
11091
11649
|
...state.session.metadata,
|
|
@@ -11105,6 +11663,8 @@ Remember: Use context from previous messages to understand follow-up questions.`
|
|
|
11105
11663
|
}
|
|
11106
11664
|
}
|
|
11107
11665
|
console.error("Error processing message:", error);
|
|
11666
|
+
} finally {
|
|
11667
|
+
state.agent.off("action", stepHandler);
|
|
11108
11668
|
}
|
|
11109
11669
|
};
|
|
11110
11670
|
const handleImageDetected = async (imageData) => {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-GO75FMLY.js";
|
|
6
|
+
import "./chunk-GCVIRGIN.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-DJPXSSP4.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
10
10
|
export {
|
|
11
11
|
findMostSimilarMemento,
|
|
@@ -120,7 +120,7 @@ import {
|
|
|
120
120
|
validateMermaidSyntax,
|
|
121
121
|
warmUpSettingsCache,
|
|
122
122
|
withRetry
|
|
123
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-GCVIRGIN.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-
|
|
132
|
+
import "./chunk-DJPXSSP4.js";
|
|
133
133
|
import "./chunk-PDX44BCA.js";
|
|
134
134
|
export {
|
|
135
135
|
AWSBackend,
|
|
@@ -186,6 +186,7 @@ import {
|
|
|
186
186
|
SessionEvents,
|
|
187
187
|
SettingKeySchema,
|
|
188
188
|
SettingTypeSchema,
|
|
189
|
+
SlackEvents,
|
|
189
190
|
SpeechToTextModels,
|
|
190
191
|
SpiderCompleteAction,
|
|
191
192
|
SpiderErrorAction,
|
|
@@ -292,7 +293,7 @@ import {
|
|
|
292
293
|
validateQuestMasterArtifactV2,
|
|
293
294
|
validateReactArtifactV2,
|
|
294
295
|
validateSvgArtifactV2
|
|
295
|
-
} from "./chunk-
|
|
296
|
+
} from "./chunk-DJPXSSP4.js";
|
|
296
297
|
import "./chunk-PDX44BCA.js";
|
|
297
298
|
export {
|
|
298
299
|
ALL_IMAGE_MODELS,
|
|
@@ -481,6 +482,7 @@ export {
|
|
|
481
482
|
SessionEvents,
|
|
482
483
|
SettingKeySchema,
|
|
483
484
|
SettingTypeSchema,
|
|
485
|
+
SlackEvents,
|
|
484
486
|
SpeechToTextModels,
|
|
485
487
|
SpiderCompleteAction,
|
|
486
488
|
SpiderErrorAction,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-VZU4Z7WI.js";
|
|
6
|
+
import "./chunk-GCVIRGIN.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-DJPXSSP4.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.
|
|
3
|
+
"version": "0.2.10-dowgrade-mcp-sdk.17228+eeed70576",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@google/generative-ai": "^0.21.0",
|
|
56
56
|
"@joplin/turndown-plugin-gfm": "^1.0.62",
|
|
57
57
|
"@mendable/firecrawl-js": "^1.29.3",
|
|
58
|
-
"@modelcontextprotocol/sdk": "
|
|
58
|
+
"@modelcontextprotocol/sdk": "1.20.1",
|
|
59
59
|
"@octokit/rest": "^22.0.0",
|
|
60
60
|
"@opensearch-project/opensearch": "2.11.0",
|
|
61
61
|
"async-mutex": "^0.5.0",
|
|
@@ -103,11 +103,11 @@
|
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@bike4mind/agents": "0.1.0",
|
|
106
|
-
"@bike4mind/common": "2.
|
|
107
|
-
"@bike4mind/mcp": "1.20.
|
|
108
|
-
"@bike4mind/services": "2.
|
|
109
|
-
"@bike4mind/utils": "2.1.
|
|
110
|
-
"@types/better-sqlite3": "^7.6.
|
|
106
|
+
"@bike4mind/common": "2.39.1-dowgrade-mcp-sdk.17228+eeed70576",
|
|
107
|
+
"@bike4mind/mcp": "1.20.4-dowgrade-mcp-sdk.17228+eeed70576",
|
|
108
|
+
"@bike4mind/services": "2.34.2-dowgrade-mcp-sdk.17228+eeed70576",
|
|
109
|
+
"@bike4mind/utils": "2.1.4-dowgrade-mcp-sdk.17228+eeed70576",
|
|
110
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
111
111
|
"@types/diff": "^5.0.9",
|
|
112
112
|
"@types/jsonwebtoken": "^9.0.4",
|
|
113
113
|
"@types/node": "^22.9.0",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"typescript": "^5.9.3",
|
|
120
120
|
"vitest": "^3.2.4"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "eeed70576ada327d03166880bbd1d1d32f7d4e7c"
|
|
123
123
|
}
|