@bike4mind/cli 0.2.64-worktree-refactor-extract-search-query-builders.21815 → 0.2.64
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/bin/bike4mind-cli.mjs +6 -6
- package/dist/BubblewrapRuntime-BHbtqvLx.mjs +72 -0
- package/dist/ConfigStore-CllM6jOf.mjs +8614 -0
- package/dist/ImageStore-DaKT_Ew8.mjs +202 -0
- package/dist/ProxyManager-Dl2nFk-A.mjs +259 -0
- package/dist/ProxyManager-kiOD1X8-.mjs +3 -0
- package/dist/SandboxOrchestrator-BEW3rqYi.mjs +159 -0
- package/dist/SandboxOrchestrator-CHZgSR3P.mjs +3 -0
- package/dist/SandboxRuntimeAdapter-C1B4t20N.mjs +57 -0
- package/dist/SandboxRuntimeAdapter-D7UAG13n.mjs +3 -0
- package/dist/SeatbeltRuntime-D4m0VOcD.mjs +116 -0
- package/dist/StderrViolationParser-D0afQ3-1.mjs +70 -0
- package/dist/ViolationLogStore-CZl35HcA.mjs +96 -0
- package/dist/bashExecute-BTkdqlSs-5foM20Lb.mjs +466 -0
- package/dist/commands/doctorCommand.mjs +101 -0
- package/dist/commands/headlessCommand.mjs +319 -0
- package/dist/commands/mcpCommand.mjs +218 -0
- package/dist/commands/updateCommand.mjs +40 -0
- package/dist/createFile-yQfh8uvk-I-yM5DxC.mjs +63 -0
- package/dist/deleteFile-DKHfnyny-G3b1Kj2T.mjs +66 -0
- package/dist/globFiles-D1en6joM-8jekiXdX.mjs +100 -0
- package/dist/grepSearch-aMamoBn_-DCJcY8JS.mjs +173 -0
- package/dist/index.mjs +6722 -0
- package/dist/pathValidation-Cgjh5WQO-DiCZTcq6.mjs +63 -0
- package/dist/store-Dw1nZX2Y.mjs +128 -0
- package/dist/store-nZExNOWX.mjs +3 -0
- package/dist/terminalSetup-rmr1P8KF.mjs +254 -0
- package/dist/tools-C6M5aW8W.mjs +20907 -0
- package/dist/treeSitterEngine-DCSXcm_3.mjs +309 -0
- package/dist/types-DBEjF9YS.mjs +59 -0
- package/dist/types-DK3P88Px.mjs +3 -0
- package/dist/updateChecker-Cu9dkHxV.mjs +120 -0
- package/package.json +10 -10
- package/dist/BubblewrapRuntime-PMIOLWKR.js +0 -71
- package/dist/HydrationEngine-YL2HWJ3V.js +0 -9
- package/dist/ImageStore-MMUOUPI2.js +0 -224
- package/dist/ProxyManager-HEB4TLVX.js +0 -7
- package/dist/SandboxOrchestrator-UIJ5GYBB.js +0 -8
- package/dist/SandboxRuntimeAdapter-FQ56MAB2.js +0 -13
- package/dist/SeatbeltRuntime-EE3TTLEP.js +0 -98
- package/dist/StderrViolationParser-7OYPM2DJ.js +0 -59
- package/dist/ViolationLogStore-RIIUVURH.js +0 -104
- package/dist/artifactExtractor-R7DIP2XO.js +0 -180
- package/dist/bashExecute-GLGLD3JD.js +0 -379
- package/dist/chunk-4BIBE3J7.js +0 -48
- package/dist/chunk-5LZS5CVJ.js +0 -161
- package/dist/chunk-BDQBOLYG.js +0 -120
- package/dist/chunk-BPFEGDC7.js +0 -192
- package/dist/chunk-EPIYC3LA.js +0 -13770
- package/dist/chunk-G4ZGEQFT.js +0 -250
- package/dist/chunk-GQGOWACU.js +0 -770
- package/dist/chunk-J6ZBI6TI.js +0 -1079
- package/dist/chunk-JW3JRHH7.js +0 -12433
- package/dist/chunk-KQAMBXAW.js +0 -163
- package/dist/chunk-KUVV2NAB.js +0 -19125
- package/dist/chunk-LTLJRF6I.js +0 -44
- package/dist/chunk-PFBYGCOW.js +0 -449
- package/dist/chunk-QWB6ZYY4.js +0 -48
- package/dist/chunk-SGPRXN4C.js +0 -245
- package/dist/chunk-UZUHPHZC.js +0 -95
- package/dist/chunk-WBE7SQUB.js +0 -241
- package/dist/chunk-Y4WOJJM3.js +0 -147
- package/dist/commands/doctorCommand.js +0 -87
- package/dist/commands/headlessCommand.js +0 -380
- package/dist/commands/mcpCommand.js +0 -203
- package/dist/commands/updateCommand.js +0 -42
- package/dist/create-C4VEEEYR.js +0 -12
- package/dist/createFile-6PSPLW6R.js +0 -71
- package/dist/deleteFile-AUSRLWIK.js +0 -73
- package/dist/formatConverter-5QEJDW24.js +0 -7
- package/dist/globFiles-TSRN64N2.js +0 -120
- package/dist/grepSearch-634XWZOJ.js +0 -216
- package/dist/index.js +0 -6779
- package/dist/llmMarkdownGenerator-Z6NB26TT.js +0 -371
- package/dist/markdownGenerator-SK2ZQQL4.js +0 -269
- package/dist/mementoService-N4IM6QAC.js +0 -12
- package/dist/notificationDeduplicator-HUC53NEW.js +0 -9
- package/dist/src-F4KZCAA2.js +0 -319
- package/dist/src-ISX322I7.js +0 -1101
- package/dist/store-CAB6BV3P.js +0 -11
- package/dist/subtractCredits-D4KEM6VU.js +0 -12
- package/dist/terminalSetup-C5FHMLC3.js +0 -214
- package/dist/treeSitterEngine-4SGFQDY3.js +0 -330
- package/dist/types-KB5NP6T4.js +0 -7
- package/dist/utils-JCHWDM4Z.js +0 -31
package/dist/chunk-Y4WOJJM3.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/store/index.ts
|
|
4
|
-
import { create } from "zustand";
|
|
5
|
-
var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["running", "queued"]);
|
|
6
|
-
function isActiveStatus(status) {
|
|
7
|
-
return ACTIVE_STATUSES.has(status);
|
|
8
|
-
}
|
|
9
|
-
var useCliStore = create((set) => ({
|
|
10
|
-
// Session state
|
|
11
|
-
session: null,
|
|
12
|
-
setSession: (session) => set({ session }),
|
|
13
|
-
addMessage: (message) => set((state) => {
|
|
14
|
-
if (!state.session) return state;
|
|
15
|
-
return {
|
|
16
|
-
session: {
|
|
17
|
-
...state.session,
|
|
18
|
-
messages: [...state.session.messages, message],
|
|
19
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
}),
|
|
23
|
-
// Pending messages
|
|
24
|
-
pendingMessages: [],
|
|
25
|
-
addPendingMessage: (message) => set((state) => ({ pendingMessages: [...state.pendingMessages, message] })),
|
|
26
|
-
updatePendingMessage: (index, message) => set((state) => {
|
|
27
|
-
const updated = [...state.pendingMessages];
|
|
28
|
-
updated[index] = message;
|
|
29
|
-
return { pendingMessages: updated };
|
|
30
|
-
}),
|
|
31
|
-
clearPendingMessages: () => set({ pendingMessages: [] }),
|
|
32
|
-
completePendingMessage: (index, finalMessage) => set((state) => {
|
|
33
|
-
const pending = [...state.pendingMessages];
|
|
34
|
-
pending.splice(index, 1);
|
|
35
|
-
const session = state.session;
|
|
36
|
-
if (!session) return { pendingMessages: pending };
|
|
37
|
-
return {
|
|
38
|
-
pendingMessages: pending,
|
|
39
|
-
session: {
|
|
40
|
-
...session,
|
|
41
|
-
messages: [...session.messages, finalMessage],
|
|
42
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}),
|
|
46
|
-
// UI state
|
|
47
|
-
isThinking: false,
|
|
48
|
-
setIsThinking: (thinking) => set({ isThinking: thinking }),
|
|
49
|
-
// Input state (for Ctrl+C clearing)
|
|
50
|
-
inputValue: "",
|
|
51
|
-
setInputValue: (value) => set({ inputValue: value }),
|
|
52
|
-
clearInput: () => set({ inputValue: "", pastedContent: null, pastedLineCount: 0 }),
|
|
53
|
-
// Paste state
|
|
54
|
-
pastedContent: null,
|
|
55
|
-
pastedLineCount: 0,
|
|
56
|
-
setPastedContent: (content, lineCount) => set({
|
|
57
|
-
pastedContent: content,
|
|
58
|
-
pastedLineCount: lineCount,
|
|
59
|
-
inputValue: content
|
|
60
|
-
}),
|
|
61
|
-
clearPaste: () => set({ pastedContent: null, pastedLineCount: 0, inputValue: "" }),
|
|
62
|
-
// Permission prompt queue
|
|
63
|
-
permissionPrompt: null,
|
|
64
|
-
permissionQueue: [],
|
|
65
|
-
enqueuePermissionPrompt: (prompt) => set((state) => {
|
|
66
|
-
if (!state.permissionPrompt) {
|
|
67
|
-
return { permissionPrompt: prompt };
|
|
68
|
-
}
|
|
69
|
-
return { permissionQueue: [...state.permissionQueue, prompt] };
|
|
70
|
-
}),
|
|
71
|
-
dequeuePermissionPrompt: () => set((state) => {
|
|
72
|
-
const [next, ...rest] = state.permissionQueue;
|
|
73
|
-
return {
|
|
74
|
-
permissionPrompt: next ?? null,
|
|
75
|
-
permissionQueue: rest
|
|
76
|
-
};
|
|
77
|
-
}),
|
|
78
|
-
// User question prompt queue
|
|
79
|
-
userQuestionPrompt: null,
|
|
80
|
-
userQuestionQueue: [],
|
|
81
|
-
enqueueUserQuestionPrompt: (prompt) => set((state) => {
|
|
82
|
-
if (!state.userQuestionPrompt) {
|
|
83
|
-
return { userQuestionPrompt: prompt };
|
|
84
|
-
}
|
|
85
|
-
return { userQuestionQueue: [...state.userQuestionQueue, prompt] };
|
|
86
|
-
}),
|
|
87
|
-
dequeueUserQuestionPrompt: () => set((state) => {
|
|
88
|
-
const [next, ...rest] = state.userQuestionQueue;
|
|
89
|
-
return {
|
|
90
|
-
userQuestionPrompt: next ?? null,
|
|
91
|
-
userQuestionQueue: rest
|
|
92
|
-
};
|
|
93
|
-
}),
|
|
94
|
-
// Config editor
|
|
95
|
-
showConfigEditor: false,
|
|
96
|
-
setShowConfigEditor: (show) => set({ showConfigEditor: show }),
|
|
97
|
-
// MCP viewer
|
|
98
|
-
showMcpViewer: false,
|
|
99
|
-
setShowMcpViewer: (show) => set({ showMcpViewer: show }),
|
|
100
|
-
// Auto-accept edits toggle (Shift+Tab)
|
|
101
|
-
autoAcceptEdits: false,
|
|
102
|
-
toggleAutoAcceptEdits: () => set((state) => ({ autoAcceptEdits: !state.autoAcceptEdits })),
|
|
103
|
-
// Exit handling
|
|
104
|
-
exitRequested: false,
|
|
105
|
-
setExitRequested: (requested) => set({ exitRequested: requested }),
|
|
106
|
-
// Background agents
|
|
107
|
-
backgroundAgents: [],
|
|
108
|
-
upsertBackgroundAgent: (job) => set((state) => {
|
|
109
|
-
const existing = state.backgroundAgents.findIndex((j) => j.id === job.id);
|
|
110
|
-
if (existing >= 0) {
|
|
111
|
-
const updated = [...state.backgroundAgents];
|
|
112
|
-
updated[existing] = job;
|
|
113
|
-
return { backgroundAgents: updated };
|
|
114
|
-
}
|
|
115
|
-
return { backgroundAgents: [...state.backgroundAgents, job] };
|
|
116
|
-
}),
|
|
117
|
-
cleanupCompletedBackgroundAgents: () => set((state) => ({
|
|
118
|
-
backgroundAgents: state.backgroundAgents.filter((j) => isActiveStatus(j.status))
|
|
119
|
-
})),
|
|
120
|
-
// Completed group notifications
|
|
121
|
-
completedGroupNotifications: [],
|
|
122
|
-
addCompletedGroupNotification: (notification, groupDescription) => set((state) => ({
|
|
123
|
-
completedGroupNotifications: [
|
|
124
|
-
...state.completedGroupNotifications,
|
|
125
|
-
{ notification, groupDescription, timestamp: Date.now() }
|
|
126
|
-
]
|
|
127
|
-
})),
|
|
128
|
-
clearCompletedGroupNotifications: () => set({ completedGroupNotifications: [] }),
|
|
129
|
-
// Pending background trigger
|
|
130
|
-
pendingBackgroundTrigger: false,
|
|
131
|
-
setPendingBackgroundTrigger: (pending) => set({ pendingBackgroundTrigger: pending }),
|
|
132
|
-
// Tavern activity log (capped at 200 entries)
|
|
133
|
-
tavernActivityLog: [],
|
|
134
|
-
addTavernLogEntry: (entry) => set((state) => {
|
|
135
|
-
const log = [...state.tavernActivityLog, entry];
|
|
136
|
-
return { tavernActivityLog: log.length > 200 ? log.slice(-200) : log };
|
|
137
|
-
}),
|
|
138
|
-
clearTavernActivityLog: () => set({ tavernActivityLog: [] })
|
|
139
|
-
}));
|
|
140
|
-
var selectActiveBackgroundAgents = (state) => state.backgroundAgents.filter((j) => isActiveStatus(j.status));
|
|
141
|
-
var selectCompletedBackgroundAgents = (state) => state.backgroundAgents.filter((j) => !isActiveStatus(j.status));
|
|
142
|
-
|
|
143
|
-
export {
|
|
144
|
-
useCliStore,
|
|
145
|
-
selectActiveBackgroundAgents,
|
|
146
|
-
selectCompletedBackgroundAgents
|
|
147
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
fetchLatestVersion,
|
|
4
|
-
forceCheckForUpdate,
|
|
5
|
-
package_default
|
|
6
|
-
} from "../chunk-SGPRXN4C.js";
|
|
7
|
-
|
|
8
|
-
// src/commands/doctorCommand.ts
|
|
9
|
-
import { execSync } from "child_process";
|
|
10
|
-
import { existsSync, constants } from "fs";
|
|
11
|
-
import { promises as fsPromises } from "fs";
|
|
12
|
-
import path from "path";
|
|
13
|
-
import { homedir } from "os";
|
|
14
|
-
async function handleDoctorCommand() {
|
|
15
|
-
console.log("B4M CLI Doctor\n");
|
|
16
|
-
console.log("Running diagnostics...\n");
|
|
17
|
-
const results = [];
|
|
18
|
-
const nodeVersion = process.version;
|
|
19
|
-
const nodeMajor = parseInt(nodeVersion.slice(1).split(".")[0], 10);
|
|
20
|
-
if (nodeMajor >= 18) {
|
|
21
|
-
results.push({ name: "Node.js version", status: "pass", message: `${nodeVersion} (>= 18 required)` });
|
|
22
|
-
} else {
|
|
23
|
-
results.push({
|
|
24
|
-
name: "Node.js version",
|
|
25
|
-
status: "fail",
|
|
26
|
-
message: `${nodeVersion} (>= 18 required, please upgrade)`
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
const latestVersion = await fetchLatestVersion();
|
|
30
|
-
if (latestVersion) {
|
|
31
|
-
results.push({ name: "NPM registry", status: "pass", message: `Accessible (latest: v${latestVersion})` });
|
|
32
|
-
} else {
|
|
33
|
-
results.push({ name: "NPM registry", status: "fail", message: "Not accessible \u2014 check your internet connection" });
|
|
34
|
-
}
|
|
35
|
-
const currentVersion = package_default.version;
|
|
36
|
-
const updateResult = await forceCheckForUpdate(currentVersion);
|
|
37
|
-
if (updateResult) {
|
|
38
|
-
if (updateResult.updateAvailable) {
|
|
39
|
-
results.push({
|
|
40
|
-
name: "Version",
|
|
41
|
-
status: "warn",
|
|
42
|
-
message: `v${currentVersion} installed, v${updateResult.latestVersion} available. Run: b4m update`
|
|
43
|
-
});
|
|
44
|
-
} else {
|
|
45
|
-
results.push({ name: "Version", status: "pass", message: `v${currentVersion} (latest)` });
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
const npmPrefix = execSync("npm config get prefix", { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
50
|
-
try {
|
|
51
|
-
await fsPromises.access(npmPrefix, constants.W_OK);
|
|
52
|
-
results.push({ name: "Global npm path", status: "pass", message: `${npmPrefix} (writable)` });
|
|
53
|
-
} catch {
|
|
54
|
-
results.push({
|
|
55
|
-
name: "Global npm path",
|
|
56
|
-
status: "warn",
|
|
57
|
-
message: `${npmPrefix} (not writable \u2014 may need sudo for updates)`
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
} catch {
|
|
61
|
-
results.push({ name: "Global npm path", status: "warn", message: "Could not determine npm prefix" });
|
|
62
|
-
}
|
|
63
|
-
const configFile = path.join(homedir(), ".bike4mind", "config.json");
|
|
64
|
-
if (existsSync(configFile)) {
|
|
65
|
-
results.push({ name: "Config file", status: "pass", message: configFile });
|
|
66
|
-
} else {
|
|
67
|
-
results.push({ name: "Config file", status: "warn", message: `Not found at ${configFile}` });
|
|
68
|
-
}
|
|
69
|
-
console.log("Results:\n");
|
|
70
|
-
for (const result of results) {
|
|
71
|
-
const icon = result.status === "pass" ? "\x1B[32m\u2713\x1B[0m" : result.status === "warn" ? "\x1B[33m!\x1B[0m" : "\x1B[31m\u2717\x1B[0m";
|
|
72
|
-
console.log(` ${icon} ${result.name}: ${result.message}`);
|
|
73
|
-
}
|
|
74
|
-
const failures = results.filter((r) => r.status === "fail");
|
|
75
|
-
const warnings = results.filter((r) => r.status === "warn");
|
|
76
|
-
console.log("");
|
|
77
|
-
if (failures.length > 0) {
|
|
78
|
-
console.log(`${failures.length} issue(s) found.`);
|
|
79
|
-
} else if (warnings.length > 0) {
|
|
80
|
-
console.log(`All checks passed with ${warnings.length} warning(s).`);
|
|
81
|
-
} else {
|
|
82
|
-
console.log("All checks passed.");
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export {
|
|
86
|
-
handleDoctorCommand
|
|
87
|
-
};
|
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
createSandboxRuntime
|
|
4
|
-
} from "../chunk-QWB6ZYY4.js";
|
|
5
|
-
import {
|
|
6
|
-
SandboxOrchestrator
|
|
7
|
-
} from "../chunk-KQAMBXAW.js";
|
|
8
|
-
import {
|
|
9
|
-
ProxyManager
|
|
10
|
-
} from "../chunk-G4ZGEQFT.js";
|
|
11
|
-
import {
|
|
12
|
-
AgentStore,
|
|
13
|
-
ApiClient,
|
|
14
|
-
BackgroundAgentManager,
|
|
15
|
-
CheckpointStore,
|
|
16
|
-
CustomCommandStore,
|
|
17
|
-
McpManager,
|
|
18
|
-
PermissionManager,
|
|
19
|
-
ReActAgent,
|
|
20
|
-
ServerLlmBackend,
|
|
21
|
-
SessionStore,
|
|
22
|
-
SubagentOrchestrator,
|
|
23
|
-
WebSocketConnectionManager,
|
|
24
|
-
WebSocketLlmBackend,
|
|
25
|
-
WebSocketToolExecutor,
|
|
26
|
-
buildCoreSystemPrompt,
|
|
27
|
-
createAgentDelegateTool,
|
|
28
|
-
createBackgroundAgentTools,
|
|
29
|
-
createFindDefinitionTool,
|
|
30
|
-
createGetFileStructureTool,
|
|
31
|
-
createSkillTool,
|
|
32
|
-
createTodoStore,
|
|
33
|
-
createWriteTodosTool,
|
|
34
|
-
generateCliTools,
|
|
35
|
-
getApiUrl,
|
|
36
|
-
isReadOnlyTool,
|
|
37
|
-
loadContextFiles,
|
|
38
|
-
setWebSocketToolExecutor
|
|
39
|
-
} from "../chunk-KUVV2NAB.js";
|
|
40
|
-
import "../chunk-BDQBOLYG.js";
|
|
41
|
-
import "../chunk-WBE7SQUB.js";
|
|
42
|
-
import "../chunk-GQGOWACU.js";
|
|
43
|
-
import "../chunk-LTLJRF6I.js";
|
|
44
|
-
import "../chunk-5LZS5CVJ.js";
|
|
45
|
-
import "../chunk-UZUHPHZC.js";
|
|
46
|
-
import "../chunk-EPIYC3LA.js";
|
|
47
|
-
import "../chunk-PFBYGCOW.js";
|
|
48
|
-
import "../chunk-BPFEGDC7.js";
|
|
49
|
-
import {
|
|
50
|
-
ConfigStore,
|
|
51
|
-
logger
|
|
52
|
-
} from "../chunk-J6ZBI6TI.js";
|
|
53
|
-
import "../chunk-JW3JRHH7.js";
|
|
54
|
-
import {
|
|
55
|
-
DEFAULT_SANDBOX_CONFIG
|
|
56
|
-
} from "../chunk-4BIBE3J7.js";
|
|
57
|
-
|
|
58
|
-
// src/commands/headlessCommand.ts
|
|
59
|
-
import { randomBytes } from "crypto";
|
|
60
|
-
import { v4 as uuidv4 } from "uuid";
|
|
61
|
-
async function readStdin() {
|
|
62
|
-
if (process.stdin.isTTY) {
|
|
63
|
-
return "";
|
|
64
|
-
}
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
const chunks = [];
|
|
67
|
-
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
68
|
-
process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8").trim()));
|
|
69
|
-
process.stdin.on("error", reject);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
var silentLogger = {
|
|
73
|
-
log: () => {
|
|
74
|
-
},
|
|
75
|
-
info: () => {
|
|
76
|
-
},
|
|
77
|
-
warn: () => {
|
|
78
|
-
},
|
|
79
|
-
error: () => {
|
|
80
|
-
},
|
|
81
|
-
debug: () => {
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
async function handleHeadlessCommand(options) {
|
|
85
|
-
const { prompt, outputFormat, dangerouslySkipPermissions, addDirs } = options;
|
|
86
|
-
logger.setVerbose(options.verbose);
|
|
87
|
-
const stdinContent = await readStdin();
|
|
88
|
-
const fullPrompt = stdinContent ? `${prompt}
|
|
89
|
-
|
|
90
|
-
<stdin>
|
|
91
|
-
${stdinContent}
|
|
92
|
-
</stdin>` : prompt;
|
|
93
|
-
const configStore = new ConfigStore();
|
|
94
|
-
const sessionStore = new SessionStore();
|
|
95
|
-
const customCommandStore = new CustomCommandStore();
|
|
96
|
-
try {
|
|
97
|
-
const config = await configStore.load();
|
|
98
|
-
const configDirs = await configStore.getAdditionalDirectories();
|
|
99
|
-
const flagDirs = process.env.B4M_ADDITIONAL_DIRS ? JSON.parse(process.env.B4M_ADDITIONAL_DIRS) : [];
|
|
100
|
-
const additionalDirectories = [.../* @__PURE__ */ new Set([...configDirs, ...flagDirs, ...addDirs])];
|
|
101
|
-
try {
|
|
102
|
-
await customCommandStore.loadCommands();
|
|
103
|
-
} catch {
|
|
104
|
-
}
|
|
105
|
-
const authTokens = await configStore.getAuthTokens();
|
|
106
|
-
if (!authTokens) {
|
|
107
|
-
process.stderr.write("Error: Not authenticated. Run `b4m /login` to authenticate.\n");
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
if (new Date(authTokens.expiresAt) <= /* @__PURE__ */ new Date()) {
|
|
111
|
-
await configStore.clearAuthTokens();
|
|
112
|
-
process.stderr.write("Error: Authentication token expired. Run `b4m /login` to re-authenticate.\n");
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
const apiBaseURL = getApiUrl(config.apiConfig);
|
|
116
|
-
const apiClient = new ApiClient(apiBaseURL, configStore);
|
|
117
|
-
const tokenGetter = async () => {
|
|
118
|
-
const tokens = await configStore.getAuthTokens();
|
|
119
|
-
return tokens?.accessToken ?? null;
|
|
120
|
-
};
|
|
121
|
-
let wsManager = null;
|
|
122
|
-
let llm;
|
|
123
|
-
try {
|
|
124
|
-
const serverConfig = await apiClient.get(
|
|
125
|
-
"/api/settings/serverConfig"
|
|
126
|
-
);
|
|
127
|
-
const wsUrl = serverConfig?.websocketUrl;
|
|
128
|
-
const wsCompletionUrl = serverConfig?.wsCompletionUrl;
|
|
129
|
-
if (wsUrl && wsCompletionUrl) {
|
|
130
|
-
wsManager = new WebSocketConnectionManager(wsUrl, tokenGetter);
|
|
131
|
-
await wsManager.connect();
|
|
132
|
-
const wsToolExecutor = new WebSocketToolExecutor(wsManager, tokenGetter);
|
|
133
|
-
setWebSocketToolExecutor(wsToolExecutor);
|
|
134
|
-
llm = new WebSocketLlmBackend({
|
|
135
|
-
wsManager,
|
|
136
|
-
apiClient,
|
|
137
|
-
model: config.defaultModel,
|
|
138
|
-
tokenGetter,
|
|
139
|
-
wsCompletionUrl
|
|
140
|
-
});
|
|
141
|
-
logger.debug("[headless] Using WebSocket transport");
|
|
142
|
-
} else {
|
|
143
|
-
throw new Error("No websocketUrl or wsCompletionUrl in server config");
|
|
144
|
-
}
|
|
145
|
-
} catch {
|
|
146
|
-
wsManager = null;
|
|
147
|
-
setWebSocketToolExecutor(null);
|
|
148
|
-
llm = new ServerLlmBackend({ apiClient, model: config.defaultModel });
|
|
149
|
-
logger.debug("[headless] Using SSE transport fallback");
|
|
150
|
-
}
|
|
151
|
-
const models = await llm.getModelInfo();
|
|
152
|
-
if (models.length === 0) {
|
|
153
|
-
throw new Error("No models available from server.");
|
|
154
|
-
}
|
|
155
|
-
const modelInfo = models.find((m) => m.id === config.defaultModel) ?? models[0];
|
|
156
|
-
llm.currentModel = modelInfo.id;
|
|
157
|
-
const session = {
|
|
158
|
-
id: uuidv4(),
|
|
159
|
-
name: `Headless ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
160
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
161
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
162
|
-
model: modelInfo.id,
|
|
163
|
-
messages: [],
|
|
164
|
-
metadata: { totalTokens: 0, totalCost: 0, toolCallCount: 0 }
|
|
165
|
-
};
|
|
166
|
-
await logger.initialize(session.id);
|
|
167
|
-
const permissionManager = new PermissionManager(config.trustedTools ?? [], void 0, config.tools.disabled);
|
|
168
|
-
const promptFn = (toolName, _args, _preview) => {
|
|
169
|
-
if (dangerouslySkipPermissions) {
|
|
170
|
-
logger.debug(`[headless] Auto-allowing tool: ${toolName}`);
|
|
171
|
-
return Promise.resolve({ action: "allow-once" });
|
|
172
|
-
}
|
|
173
|
-
process.stderr.write(
|
|
174
|
-
`Warning: Tool "${toolName}" requires permission and was denied. Use --dangerously-skip-permissions to auto-allow tools in headless mode.
|
|
175
|
-
`
|
|
176
|
-
);
|
|
177
|
-
return Promise.resolve({ action: "deny" });
|
|
178
|
-
};
|
|
179
|
-
const userQuestionFn = (_payload) => {
|
|
180
|
-
process.stderr.write(
|
|
181
|
-
"Warning: Agent requested user input; headless mode cannot respond interactively. Answering with empty response.\n"
|
|
182
|
-
);
|
|
183
|
-
return Promise.resolve({ answers: [] });
|
|
184
|
-
};
|
|
185
|
-
const sandboxConfig = config.sandbox ?? DEFAULT_SANDBOX_CONFIG;
|
|
186
|
-
const checkpointProjectDir = configStore.getProjectConfigDir() ?? process.cwd();
|
|
187
|
-
const checkpointStore = new CheckpointStore(checkpointProjectDir);
|
|
188
|
-
const [sandboxRuntime] = await Promise.all([
|
|
189
|
-
createSandboxRuntime(),
|
|
190
|
-
checkpointStore.init(session.id).catch(() => {
|
|
191
|
-
})
|
|
192
|
-
]);
|
|
193
|
-
const proxyManager = new ProxyManager(sandboxConfig.network);
|
|
194
|
-
const sandboxOrchestrator = new SandboxOrchestrator(sandboxConfig, sandboxRuntime, proxyManager);
|
|
195
|
-
permissionManager.setSandboxState(sandboxConfig.mode, sandboxOrchestrator.isActive());
|
|
196
|
-
const agentContext = {
|
|
197
|
-
currentAgent: null,
|
|
198
|
-
observationQueue: []
|
|
199
|
-
};
|
|
200
|
-
const { tools: b4mTools } = await generateCliTools(
|
|
201
|
-
config.userId,
|
|
202
|
-
llm,
|
|
203
|
-
modelInfo.id,
|
|
204
|
-
permissionManager,
|
|
205
|
-
promptFn,
|
|
206
|
-
agentContext,
|
|
207
|
-
configStore,
|
|
208
|
-
apiClient,
|
|
209
|
-
void 0,
|
|
210
|
-
userQuestionFn,
|
|
211
|
-
checkpointStore,
|
|
212
|
-
sandboxOrchestrator,
|
|
213
|
-
additionalDirectories
|
|
214
|
-
);
|
|
215
|
-
const mcpManager = new McpManager(config);
|
|
216
|
-
const projectConfigDir = configStore.getProjectConfigDir();
|
|
217
|
-
const builtinAgentsDir = new URL("../agents/defaults/", import.meta.url).pathname;
|
|
218
|
-
const agentStore = new AgentStore(builtinAgentsDir, projectConfigDir ?? process.cwd());
|
|
219
|
-
const [, , contextResult] = await Promise.all([
|
|
220
|
-
mcpManager.initialize(),
|
|
221
|
-
agentStore.loadAgents(),
|
|
222
|
-
loadContextFiles(projectConfigDir)
|
|
223
|
-
]);
|
|
224
|
-
const mcpTools = mcpManager.getTools();
|
|
225
|
-
const orchestrator = new SubagentOrchestrator({
|
|
226
|
-
userId: config.userId,
|
|
227
|
-
llm,
|
|
228
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
229
|
-
logger: silentLogger,
|
|
230
|
-
// silentLogger satisfies Logger structurally but lacks full type metadata
|
|
231
|
-
permissionManager,
|
|
232
|
-
showPermissionPrompt: promptFn,
|
|
233
|
-
configStore,
|
|
234
|
-
apiClient,
|
|
235
|
-
agentStore,
|
|
236
|
-
customCommandStore,
|
|
237
|
-
enableParallelToolExecution: config.preferences.enableParallelToolExecution === true,
|
|
238
|
-
showUserQuestion: userQuestionFn,
|
|
239
|
-
checkpointStore
|
|
240
|
-
});
|
|
241
|
-
const backgroundManager = new BackgroundAgentManager(orchestrator);
|
|
242
|
-
const agentDelegateTool = createAgentDelegateTool(orchestrator, agentStore, session.id, backgroundManager);
|
|
243
|
-
const backgroundTools = createBackgroundAgentTools(backgroundManager);
|
|
244
|
-
const todoStore = createTodoStore();
|
|
245
|
-
const writeTodosTool = createWriteTodosTool(todoStore);
|
|
246
|
-
const findDefinitionTool = createFindDefinitionTool();
|
|
247
|
-
const getFileStructureTool = createGetFileStructureTool();
|
|
248
|
-
const enableSkillTool = config.preferences.enableSkillTool !== false;
|
|
249
|
-
const skillTool = enableSkillTool ? createSkillTool({ customCommandStore, subagentOrchestrator: orchestrator, sessionId: session.id }) : null;
|
|
250
|
-
const cliTools = [agentDelegateTool, ...backgroundTools, writeTodosTool, findDefinitionTool, getFileStructureTool];
|
|
251
|
-
if (skillTool) cliTools.push(skillTool);
|
|
252
|
-
const allTools = [...b4mTools, ...mcpTools, ...cliTools];
|
|
253
|
-
const systemPrompt = buildCoreSystemPrompt({
|
|
254
|
-
contextContent: contextResult.mergedContent,
|
|
255
|
-
agentStore,
|
|
256
|
-
customCommands: customCommandStore.getAllCommands(),
|
|
257
|
-
enableSkillTool,
|
|
258
|
-
enableDynamicAgentCreation: false,
|
|
259
|
-
additionalDirectories
|
|
260
|
-
});
|
|
261
|
-
const maxIterations = config.preferences.maxIterations === null ? 999999 : config.preferences.maxIterations;
|
|
262
|
-
const agent = new ReActAgent({
|
|
263
|
-
userId: config.userId,
|
|
264
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
265
|
-
logger: silentLogger,
|
|
266
|
-
// silentLogger satisfies Logger structurally but lacks full type metadata
|
|
267
|
-
llm,
|
|
268
|
-
model: modelInfo.id,
|
|
269
|
-
tools: allTools,
|
|
270
|
-
maxIterations,
|
|
271
|
-
maxTokens: config.preferences.maxTokens,
|
|
272
|
-
temperature: config.preferences.temperature,
|
|
273
|
-
systemPrompt
|
|
274
|
-
});
|
|
275
|
-
agentContext.currentAgent = agent;
|
|
276
|
-
agent.observationQueue = agentContext.observationQueue;
|
|
277
|
-
if (outputFormat === "stream-json") {
|
|
278
|
-
const emitNdjson = (obj) => process.stdout.write(JSON.stringify(obj) + "\n");
|
|
279
|
-
agent.on("thought", (step) => {
|
|
280
|
-
emitNdjson({ type: "thought", content: step.content });
|
|
281
|
-
});
|
|
282
|
-
agent.on("action", (step) => {
|
|
283
|
-
emitNdjson({
|
|
284
|
-
type: "action",
|
|
285
|
-
content: step.content,
|
|
286
|
-
toolName: step.metadata?.toolName,
|
|
287
|
-
toolInput: step.metadata?.toolInput
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
agent.on("observation", (step) => {
|
|
291
|
-
emitNdjson({ type: "observation", content: step.content, toolName: step.metadata?.toolName });
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
const turnId = `turn-${randomBytes(4).toString("hex")}`;
|
|
295
|
-
backgroundManager.setCurrentTurn(turnId);
|
|
296
|
-
let result;
|
|
297
|
-
try {
|
|
298
|
-
result = await agent.run(fullPrompt, {
|
|
299
|
-
parallelExecution: config.preferences.enableParallelToolExecution === true,
|
|
300
|
-
isReadOnlyTool
|
|
301
|
-
});
|
|
302
|
-
} finally {
|
|
303
|
-
backgroundManager.setCurrentTurn(null);
|
|
304
|
-
}
|
|
305
|
-
const finalSession = {
|
|
306
|
-
...session,
|
|
307
|
-
messages: [
|
|
308
|
-
{ id: uuidv4(), role: "user", content: fullPrompt, timestamp: (/* @__PURE__ */ new Date()).toISOString() },
|
|
309
|
-
{ id: uuidv4(), role: "assistant", content: result.finalAnswer, timestamp: (/* @__PURE__ */ new Date()).toISOString() }
|
|
310
|
-
],
|
|
311
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
312
|
-
metadata: {
|
|
313
|
-
totalTokens: result.completionInfo.totalTokens,
|
|
314
|
-
totalCost: 0,
|
|
315
|
-
toolCallCount: result.completionInfo.toolCalls
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
await sessionStore.save(finalSession);
|
|
319
|
-
switch (outputFormat) {
|
|
320
|
-
case "text":
|
|
321
|
-
process.stdout.write(result.finalAnswer + "\n");
|
|
322
|
-
break;
|
|
323
|
-
case "json": {
|
|
324
|
-
const jsonResult = {
|
|
325
|
-
result: result.finalAnswer,
|
|
326
|
-
steps: result.steps.map((s) => ({
|
|
327
|
-
type: s.type,
|
|
328
|
-
content: s.content,
|
|
329
|
-
toolName: s.metadata?.toolName,
|
|
330
|
-
toolInput: s.metadata?.toolInput
|
|
331
|
-
})),
|
|
332
|
-
tokenUsage: {
|
|
333
|
-
totalTokens: result.completionInfo.totalTokens,
|
|
334
|
-
inputTokens: result.completionInfo.totalInputTokens,
|
|
335
|
-
outputTokens: result.completionInfo.totalOutputTokens
|
|
336
|
-
},
|
|
337
|
-
iterations: result.completionInfo.iterations,
|
|
338
|
-
toolCalls: result.completionInfo.toolCalls
|
|
339
|
-
};
|
|
340
|
-
process.stdout.write(JSON.stringify(jsonResult, null, 2) + "\n");
|
|
341
|
-
break;
|
|
342
|
-
}
|
|
343
|
-
case "stream-json":
|
|
344
|
-
process.stdout.write(
|
|
345
|
-
JSON.stringify({
|
|
346
|
-
type: "result",
|
|
347
|
-
content: result.finalAnswer,
|
|
348
|
-
tokenUsage: {
|
|
349
|
-
totalTokens: result.completionInfo.totalTokens,
|
|
350
|
-
inputTokens: result.completionInfo.totalInputTokens,
|
|
351
|
-
outputTokens: result.completionInfo.totalOutputTokens
|
|
352
|
-
},
|
|
353
|
-
iterations: result.completionInfo.iterations,
|
|
354
|
-
toolCalls: result.completionInfo.toolCalls
|
|
355
|
-
}) + "\n"
|
|
356
|
-
);
|
|
357
|
-
break;
|
|
358
|
-
}
|
|
359
|
-
await mcpManager.disconnect().catch(() => {
|
|
360
|
-
});
|
|
361
|
-
if (wsManager) wsManager.disconnect();
|
|
362
|
-
setWebSocketToolExecutor(null);
|
|
363
|
-
agent.removeAllListeners();
|
|
364
|
-
process.exit(0);
|
|
365
|
-
} catch (error) {
|
|
366
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
367
|
-
if (outputFormat === "json") {
|
|
368
|
-
process.stdout.write(JSON.stringify({ error: message }) + "\n");
|
|
369
|
-
} else if (outputFormat === "stream-json") {
|
|
370
|
-
process.stdout.write(JSON.stringify({ type: "error", error: message }) + "\n");
|
|
371
|
-
} else {
|
|
372
|
-
process.stderr.write(`Error: ${message}
|
|
373
|
-
`);
|
|
374
|
-
}
|
|
375
|
-
process.exit(1);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
export {
|
|
379
|
-
handleHeadlessCommand
|
|
380
|
-
};
|