@bike4mind/cli 0.7.0 → 0.8.0
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/{ConfigStore-Bu_plzvP.mjs → ConfigStore-Bj1IOvWn.mjs} +20 -2
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +2 -2
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/index.mjs +46 -17
- package/dist/store-44C_Fvdb.mjs +3 -0
- package/dist/{store-FkY4K-0M.mjs → store-B0ImnWR4.mjs} +11 -2
- package/dist/{tools-DY-JzNoY.mjs → tools-Dg1HL5PO.mjs} +160 -13
- package/dist/{updateChecker-Dn-Ri8zw.mjs → updateChecker-Bbkc_8IL.mjs} +1 -1
- package/package.json +6 -6
- package/dist/store-D2zh6DFz.mjs +0 -3
|
@@ -862,9 +862,27 @@ const GenericCreditDeductTransaction = BaseCreditTransaction.extend({
|
|
|
862
862
|
*/
|
|
863
863
|
userId: z.string().optional(),
|
|
864
864
|
/**
|
|
865
|
-
*
|
|
865
|
+
* Reason/source for the transaction. Use GenericDeductReasons for new callers.
|
|
866
866
|
*/
|
|
867
|
-
reason: z.
|
|
867
|
+
reason: z.enum([
|
|
868
|
+
"dispute_clawback",
|
|
869
|
+
"refund_clawback",
|
|
870
|
+
"payment_failed_clawback",
|
|
871
|
+
"notebook_curation",
|
|
872
|
+
"manual",
|
|
873
|
+
"admin_adjustment",
|
|
874
|
+
"refund_adjustment"
|
|
875
|
+
]).optional(),
|
|
876
|
+
/**
|
|
877
|
+
* Stripe dispute ID — set for dispute clawback transactions.
|
|
878
|
+
* Used for idempotency (unique sparse index prevents duplicate clawbacks).
|
|
879
|
+
*/
|
|
880
|
+
stripeDisputeId: z.string().optional(),
|
|
881
|
+
/**
|
|
882
|
+
* Stripe refund ID — set for refund clawback transactions.
|
|
883
|
+
* Used for idempotency (unique sparse index prevents duplicate clawbacks).
|
|
884
|
+
*/
|
|
885
|
+
stripeRefundId: z.string().optional()
|
|
868
886
|
});
|
|
869
887
|
const TextGenerationUsageTransaction = BaseCreditTransaction.extend({
|
|
870
888
|
type: z.literal("text_generation_usage"),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-
|
|
2
|
+
import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-Bbkc_8IL.mjs";
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
import { constants, existsSync, promises } from "fs";
|
|
5
5
|
import { homedir } from "os";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { n as logger, t as ConfigStore } from "../ConfigStore-
|
|
2
|
+
import { C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, I as generateCliTools, M as loadContextFiles, N as getApiUrl, O as McpManager, Q as CheckpointStore, S as ApiClient, T as FallbackLlmBackend, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, b as createSkillTool, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, m as createCoordinateTaskTool, p as createWriteTodosTool, q as buildSystemPrompt, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, y as SubagentOrchestrator } from "../tools-Dg1HL5PO.mjs";
|
|
3
|
+
import { n as logger, t as ConfigStore } from "../ConfigStore-Bj1IOvWn.mjs";
|
|
4
4
|
import { t as DEFAULT_SANDBOX_CONFIG } from "../types-DBEjF9YS.mjs";
|
|
5
5
|
import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-C1B4t20N.mjs";
|
|
6
6
|
import { t as SandboxOrchestrator } from "../SandboxOrchestrator-BEW3rqYi.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as version, i as forceCheckForUpdate } from "../updateChecker-
|
|
2
|
+
import { a as version, i as forceCheckForUpdate } from "../updateChecker-Bbkc_8IL.mjs";
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
//#region src/commands/updateCommand.ts
|
|
5
5
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-
|
|
3
|
-
import { $ as
|
|
4
|
-
import { Mt as validateNotebookPath$1, g as ChatModels, jt as validateJupyterKernelName, m as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore } from "./ConfigStore-
|
|
5
|
-
import { a as version, t as checkForUpdate } from "./updateChecker-
|
|
2
|
+
import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-B0ImnWR4.mjs";
|
|
3
|
+
import { $ as CommandHistoryStore, A as formatStep, B as DEFAULT_RETRY_CONFIG, C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, G as OllamaBackend, H as clearFeatureModuleTools, I as generateCliTools, J as buildSkillsPromptSection, K as getPlanModeFilePath, L as ALWAYS_DENIED_FOR_AGENTS, M as loadContextFiles, N as getApiUrl, O as McpManager, P as getEnvironmentName, Q as CheckpointStore, R as DEFAULT_AGENT_MODEL, S as ApiClient, T as FallbackLlmBackend, U as registerFeatureModuleTools, V as DEFAULT_THOROUGHNESS, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, a as createBlockerTools, at as mergeCommands, b as createSkillTool, c as createDecisionStore, ct as warmFileCache, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, i as createBlockerStore, it as searchCommands, j as extractCompactInstructions, k as substituteArguments, l as formatDecisionsOutput, m as createCoordinateTaskTool, n as createReviewGateTool, nt as hasFileReferences, o as formatBlockersOutput, ot as formatFileSize, p as createWriteTodosTool, q as buildSystemPrompt, r as formatReviewGatesOutput, rt as processFileReferences, s as createDecisionLogTool, st as searchFiles, t as createReviewGateStore, tt as OAuthClient, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, x as parseAgentConfig, y as SubagentOrchestrator, z as DEFAULT_MAX_ITERATIONS } from "./tools-Dg1HL5PO.mjs";
|
|
4
|
+
import { Mt as validateNotebookPath$1, g as ChatModels, jt as validateJupyterKernelName, m as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore } from "./ConfigStore-Bj1IOvWn.mjs";
|
|
5
|
+
import { a as version, t as checkForUpdate } from "./updateChecker-Bbkc_8IL.mjs";
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
7
7
|
import { Box, Static, Text, render, useApp, useInput } from "ink";
|
|
8
8
|
import { execSync } from "child_process";
|
|
@@ -25,16 +25,19 @@ import { get_encoding } from "tiktoken";
|
|
|
25
25
|
import WsWebSocket from "ws";
|
|
26
26
|
//#region src/components/StatusBar.tsx
|
|
27
27
|
const StatusBar = React.memo(function StatusBar({ sessionName, model, tokenUsage, creditsUsage }) {
|
|
28
|
-
const
|
|
28
|
+
const interactionMode = useCliStore((state) => state.interactionMode);
|
|
29
29
|
return /* @__PURE__ */ React.createElement(Box, {
|
|
30
30
|
flexDirection: "row",
|
|
31
31
|
justifyContent: "space-between",
|
|
32
32
|
width: "100%",
|
|
33
33
|
paddingX: 1
|
|
34
|
-
}, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, sessionName), /* @__PURE__ */ React.createElement(Box, { gap: 2 },
|
|
34
|
+
}, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, sessionName), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, interactionMode === "auto-accept" && /* @__PURE__ */ React.createElement(Text, {
|
|
35
35
|
color: "green",
|
|
36
36
|
bold: true
|
|
37
|
-
}, "AUTO ACCEPT: Edits"),
|
|
37
|
+
}, "AUTO ACCEPT: Edits"), interactionMode === "plan" && /* @__PURE__ */ React.createElement(Text, {
|
|
38
|
+
color: "yellow",
|
|
39
|
+
bold: true
|
|
40
|
+
}, "PLAN MODE"), tokenUsage > 0 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, tokenUsage.toLocaleString(), " tokens"), creditsUsage !== void 0 && creditsUsage > 0 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, creditsUsage.toLocaleString(), " ", creditsUsage === 1 ? "credit" : "credits"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, model)));
|
|
38
41
|
});
|
|
39
42
|
/**
|
|
40
43
|
* Maximum paste size in characters (~500KB) to prevent memory issues
|
|
@@ -1403,7 +1406,7 @@ function ReviewGatePrompt({ description, options, recommendation, onResponse })
|
|
|
1403
1406
|
onChange: setNote,
|
|
1404
1407
|
onSubmit: handleConfirm,
|
|
1405
1408
|
placeholder: "Type a note and press Enter…"
|
|
1406
|
-
}))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, noteMode ? "Type note + Enter to submit, ↑↓ to switch action" : "Press 1-4, y/n, or ↑↓ + Enter")));
|
|
1409
|
+
}))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, noteMode ? note.trim().length === 0 ? "Note required — type a note + Enter to submit, ↑↓ to switch action" : "Type note + Enter to submit, ↑↓ to switch action" : "Press 1-4, y/n, or ↑↓ + Enter")));
|
|
1407
1410
|
}
|
|
1408
1411
|
//#endregion
|
|
1409
1412
|
//#region src/components/ConfigEditor.tsx
|
|
@@ -2048,9 +2051,9 @@ function App({ onMessage, onBackgroundCompletion, onCommand, onBashCommand, onPe
|
|
|
2048
2051
|
setPendingBackgroundTrigger,
|
|
2049
2052
|
onBackgroundCompletion
|
|
2050
2053
|
]);
|
|
2051
|
-
const
|
|
2054
|
+
const cycleInteractionMode = useCliStore((state) => state.cycleInteractionMode);
|
|
2052
2055
|
useInput((_input, key) => {
|
|
2053
|
-
if (key.tab && key.shift)
|
|
2056
|
+
if (key.tab && key.shift) cycleInteractionMode();
|
|
2054
2057
|
});
|
|
2055
2058
|
const [isBashMode, setIsBashMode] = useState(false);
|
|
2056
2059
|
const handleSubmit = React.useCallback(async (input) => {
|
|
@@ -5906,15 +5909,18 @@ function CliApp() {
|
|
|
5906
5909
|
if (contextResult.projectContext) startupLog.push(`📄 Project context: ${contextResult.projectContext.filename}`);
|
|
5907
5910
|
for (const error of contextResult.errors) startupLog.push(`⚠️ Context file error: ${error}`);
|
|
5908
5911
|
const featureModulePrompts = featureRegistry.getSystemPromptSections();
|
|
5909
|
-
const
|
|
5912
|
+
const promptVariant = config.preferences.promptVariant ?? "current";
|
|
5913
|
+
const buildPromptForMode = (mode) => buildSystemPrompt(promptVariant, {
|
|
5910
5914
|
contextContent: contextResult.mergedContent,
|
|
5911
5915
|
agentStore,
|
|
5912
5916
|
customCommands: state.customCommandStore.getAllCommands(),
|
|
5913
5917
|
enableSkillTool,
|
|
5914
5918
|
enableDynamicAgentCreation: config.preferences.enableDynamicAgentCreation === true,
|
|
5915
5919
|
additionalDirectories,
|
|
5916
|
-
featureModulePrompts: featureModulePrompts || void 0
|
|
5920
|
+
featureModulePrompts: featureModulePrompts || void 0,
|
|
5921
|
+
planModeFilePath: mode === "plan" ? getPlanModeFilePath(newSession.id) : void 0
|
|
5917
5922
|
});
|
|
5923
|
+
const cliSystemPrompt = buildPromptForMode(useCliStore.getState().interactionMode);
|
|
5918
5924
|
const maxIterations = config.preferences.maxIterations === null ? 999999 : config.preferences.maxIterations;
|
|
5919
5925
|
const agent = new ReActAgent({
|
|
5920
5926
|
userId: config.userId,
|
|
@@ -5928,6 +5934,14 @@ function CliApp() {
|
|
|
5928
5934
|
systemPrompt: cliSystemPrompt
|
|
5929
5935
|
});
|
|
5930
5936
|
agentContext.currentAgent = agent;
|
|
5937
|
+
const agentInternalContext = agent.context;
|
|
5938
|
+
let lastInteractionMode = useCliStore.getState().interactionMode;
|
|
5939
|
+
useCliStore.subscribe((s) => {
|
|
5940
|
+
if (s.interactionMode === lastInteractionMode) return;
|
|
5941
|
+
lastInteractionMode = s.interactionMode;
|
|
5942
|
+
if (agentContext.currentAgent !== agent) return;
|
|
5943
|
+
agentInternalContext.systemPrompt = buildPromptForMode(s.interactionMode);
|
|
5944
|
+
});
|
|
5931
5945
|
agent.observationQueue = agentContext.observationQueue;
|
|
5932
5946
|
const stepHandler = (step) => {
|
|
5933
5947
|
const { pendingMessages, updatePendingMessage } = useCliStore.getState();
|
|
@@ -7250,7 +7264,6 @@ Multi-line Input:
|
|
|
7250
7264
|
logger.debug("=== New Session Started via /clear ===");
|
|
7251
7265
|
decisionStoreRef.current.decisions = [];
|
|
7252
7266
|
blockerStoreRef.current.blockers = [];
|
|
7253
|
-
reviewGateStoreRef.current.reviewGates = [];
|
|
7254
7267
|
if (state.checkpointStore) state.checkpointStore.setSessionId(newSession.id);
|
|
7255
7268
|
setState((prev) => ({
|
|
7256
7269
|
...prev,
|
|
@@ -7258,6 +7271,17 @@ Multi-line Input:
|
|
|
7258
7271
|
}));
|
|
7259
7272
|
setStoreSession(newSession);
|
|
7260
7273
|
useCliStore.getState().clearPendingMessages();
|
|
7274
|
+
const staleGate = useCliStore.getState().reviewGatePrompt;
|
|
7275
|
+
if (staleGate) {
|
|
7276
|
+
dequeueReviewGatePrompt();
|
|
7277
|
+
staleGate.resolve({
|
|
7278
|
+
decision: "rejected",
|
|
7279
|
+
note: "Session cleared."
|
|
7280
|
+
});
|
|
7281
|
+
}
|
|
7282
|
+
queueMicrotask(() => {
|
|
7283
|
+
reviewGateStoreRef.current.reviewGates = [];
|
|
7284
|
+
});
|
|
7261
7285
|
usageCache = null;
|
|
7262
7286
|
console.log("New session started.");
|
|
7263
7287
|
console.log(`\n📝 Session: ${newSession.name} | 🤖 Model: ${newSession.model} | 📊 Tokens: 0\n`);
|
|
@@ -8071,6 +8095,7 @@ Multi-line Input:
|
|
|
8071
8095
|
const newFeatureTools = newFeatureRegistry.getAllTools();
|
|
8072
8096
|
agentContext.tools = [...baseTools, ...newFeatureTools];
|
|
8073
8097
|
const newFeaturePrompts = newFeatureRegistry.getSystemPromptSections();
|
|
8098
|
+
const planFilePathForRebuild = useCliStore.getState().interactionMode === "plan" && state.session ? getPlanModeFilePath(state.session.id) : void 0;
|
|
8074
8099
|
agentContext.systemPrompt = buildSystemPrompt(updatedConfig.preferences.promptVariant ?? "current", {
|
|
8075
8100
|
contextContent: state.contextContent,
|
|
8076
8101
|
agentStore: state.agentStore || void 0,
|
|
@@ -8078,7 +8103,8 @@ Multi-line Input:
|
|
|
8078
8103
|
enableSkillTool: updatedConfig.preferences.enableSkillTool !== false,
|
|
8079
8104
|
enableDynamicAgentCreation: updatedConfig.preferences.enableDynamicAgentCreation === true,
|
|
8080
8105
|
additionalDirectories: state.additionalDirectories,
|
|
8081
|
-
featureModulePrompts: newFeaturePrompts || void 0
|
|
8106
|
+
featureModulePrompts: newFeaturePrompts || void 0,
|
|
8107
|
+
planModeFilePath: planFilePathForRebuild
|
|
8082
8108
|
});
|
|
8083
8109
|
const moduleNames = newFeatureRegistry.getModuleNames();
|
|
8084
8110
|
if (moduleNames.length > 0) console.error(`\n\x1b[36m🏰 Feature modules hot-reloaded: ${moduleNames.join(", ")}\x1b[0m`);
|
|
@@ -8217,15 +8243,15 @@ Multi-line Input:
|
|
|
8217
8243
|
onUserQuestionResponse: (response, promptId) => {
|
|
8218
8244
|
const currentPrompt = useCliStore.getState().userQuestionPrompt;
|
|
8219
8245
|
if (currentPrompt?.id !== promptId) return;
|
|
8220
|
-
currentPrompt.resolve(response);
|
|
8221
8246
|
dequeueUserQuestionPrompt();
|
|
8247
|
+
currentPrompt.resolve(response);
|
|
8222
8248
|
emitNextAwaitingStatus();
|
|
8223
8249
|
},
|
|
8224
8250
|
onReviewGateResponse: (response, promptId) => {
|
|
8225
8251
|
const currentPrompt = useCliStore.getState().reviewGatePrompt;
|
|
8226
8252
|
if (currentPrompt?.id !== promptId) return;
|
|
8227
|
-
currentPrompt.resolve(response);
|
|
8228
8253
|
dequeueReviewGatePrompt();
|
|
8254
|
+
currentPrompt.resolve(response);
|
|
8229
8255
|
emitNextAwaitingStatus();
|
|
8230
8256
|
}
|
|
8231
8257
|
});
|
|
@@ -8236,6 +8262,9 @@ try {
|
|
|
8236
8262
|
} catch {}
|
|
8237
8263
|
if (import.meta.url.includes("/src/") || process.env.NODE_ENV === "development") logger.debug("🔧 Running in development mode (using TypeScript source)\n");
|
|
8238
8264
|
warmFileCache();
|
|
8239
|
-
render(/* @__PURE__ */ React.createElement(CliApp, null), {
|
|
8265
|
+
render(/* @__PURE__ */ React.createElement(CliApp, null), {
|
|
8266
|
+
exitOnCtrlC: false,
|
|
8267
|
+
alternateScreen: true
|
|
8268
|
+
});
|
|
8240
8269
|
//#endregion
|
|
8241
8270
|
export {};
|
|
@@ -3,6 +3,14 @@ import { create } from "zustand";
|
|
|
3
3
|
//#region src/store/index.ts
|
|
4
4
|
/** Active job statuses (jobs still in progress) */
|
|
5
5
|
const ACTIVE_STATUSES = new Set(["running", "queued"]);
|
|
6
|
+
const INTERACTION_MODE_CYCLE = [
|
|
7
|
+
"normal",
|
|
8
|
+
"auto-accept",
|
|
9
|
+
"plan"
|
|
10
|
+
];
|
|
11
|
+
function nextInteractionMode(current) {
|
|
12
|
+
return INTERACTION_MODE_CYCLE[(INTERACTION_MODE_CYCLE.indexOf(current) + 1) % INTERACTION_MODE_CYCLE.length];
|
|
13
|
+
}
|
|
6
14
|
/** Check if a job status is active (running or queued) */
|
|
7
15
|
function isActiveStatus(status) {
|
|
8
16
|
return ACTIVE_STATUSES.has(status);
|
|
@@ -122,8 +130,9 @@ const useCliStore = create((set) => ({
|
|
|
122
130
|
setShowConfigEditor: (show) => set({ showConfigEditor: show }),
|
|
123
131
|
showMcpViewer: false,
|
|
124
132
|
setShowMcpViewer: (show) => set({ showMcpViewer: show }),
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
interactionMode: "normal",
|
|
134
|
+
cycleInteractionMode: () => set((state) => ({ interactionMode: nextInteractionMode(state.interactionMode) })),
|
|
135
|
+
setInteractionMode: (mode) => set({ interactionMode: mode }),
|
|
127
136
|
exitRequested: false,
|
|
128
137
|
setExitRequested: (requested) => set({ exitRequested: requested }),
|
|
129
138
|
backgroundAgents: [],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as RechartsChartTypeList, A as ImageGenerationUsageTransaction, At as secureParameters, B as NotFoundError, C as FileEvents, Ct as getMcpProviderMetadata, D as GenericCreditAddTransaction, Dt as obfuscateApiKey, E as GenerateImageToolCallSchema, Et as isGPTImageModel, F as KnowledgeType, G as ProfileEvents, H as OpenAIImageGenerationInput, I as LLMEvents, J as PurchaseTransaction, K as ProjectEvents, L as MiscEvents, M as InboxEvents, N as InviteEvents, Nt as CollectionType, O as GenericCreditDeductTransaction, Ot as resolveNavigationIntents, P as InviteType, Q as ReceivedCreditTransaction, R as ModalEvents, S as FeedbackEvents, St as getDataLakeTags, T as GEMINI_IMAGE_MODELS, Tt as isGPTImage2Model, U as Permission, V as OpenAIEmbeddingModel, W as PermissionDeniedError, X as REASONING_SUPPORTED_MODELS, Y as QuestMasterParamsSchema, Z as RealtimeVoiceUsageTransaction, _ as CompletionApiUsageTransaction, _t as VideoModels, a as ApiKeyEvents, at as SessionEvents, b as FIXED_TEMPERATURE_MODELS, bt as b4mLLMTools, c as AppFileEvents, ct as SupportedFabFileMimeTypes, d as BFL_IMAGE_MODELS, dt as TextGenerationUsageTransaction, et as RegInviteEvents, f as BFL_SAFETY_TOLERANCE, ft as ToolUsageTransaction, g as ChatModels, gt as VideoGenerationUsageTransaction, h as ChatCompletionCreateInputSchema, ht as VIDEO_SIZE_CONSTRAINTS, i as AiEvents, it as ResearchTaskType, j as ImageModels, k as ImageEditUsageTransaction, kt as sanitizeTelemetryError, l as ArtifactTypeSchema, lt as TagType, mt as UiNavigationEvents, n as logger, nt as ResearchTaskExecutionType, o as ApiKeyScope, ot as SpeechToTextModels, p as BedrockEmbeddingModel, pt as TransferCreditTransaction, q as PromptMetaZodSchema, r as ALERT_THRESHOLDS, rt as ResearchTaskPeriodicFrequencyType, s as ApiKeyType, st as SubscriptionCreditTransaction, t as ConfigStore, tt as ResearchModeParamsSchema, u as AuthEvents, ut as TaskScheduleHandler, v as DashboardParamsSchema, vt as VoyageAIEmbeddingModel, w as FriendshipEvents, wt as getViewById, x as FavoriteDocumentType, xt as getAccessibleDataLakes, y as ElabsEvents, yt as XAI_IMAGE_MODELS, z as ModelBackend } from "./ConfigStore-
|
|
2
|
+
import { $ as RechartsChartTypeList, A as ImageGenerationUsageTransaction, At as secureParameters, B as NotFoundError, C as FileEvents, Ct as getMcpProviderMetadata, D as GenericCreditAddTransaction, Dt as obfuscateApiKey, E as GenerateImageToolCallSchema, Et as isGPTImageModel, F as KnowledgeType, G as ProfileEvents, H as OpenAIImageGenerationInput, I as LLMEvents, J as PurchaseTransaction, K as ProjectEvents, L as MiscEvents, M as InboxEvents, N as InviteEvents, Nt as CollectionType, O as GenericCreditDeductTransaction, Ot as resolveNavigationIntents, P as InviteType, Q as ReceivedCreditTransaction, R as ModalEvents, S as FeedbackEvents, St as getDataLakeTags, T as GEMINI_IMAGE_MODELS, Tt as isGPTImage2Model, U as Permission, V as OpenAIEmbeddingModel, W as PermissionDeniedError, X as REASONING_SUPPORTED_MODELS, Y as QuestMasterParamsSchema, Z as RealtimeVoiceUsageTransaction, _ as CompletionApiUsageTransaction, _t as VideoModels, a as ApiKeyEvents, at as SessionEvents, b as FIXED_TEMPERATURE_MODELS, bt as b4mLLMTools, c as AppFileEvents, ct as SupportedFabFileMimeTypes, d as BFL_IMAGE_MODELS, dt as TextGenerationUsageTransaction, et as RegInviteEvents, f as BFL_SAFETY_TOLERANCE, ft as ToolUsageTransaction, g as ChatModels, gt as VideoGenerationUsageTransaction, h as ChatCompletionCreateInputSchema, ht as VIDEO_SIZE_CONSTRAINTS, i as AiEvents, it as ResearchTaskType, j as ImageModels, k as ImageEditUsageTransaction, kt as sanitizeTelemetryError, l as ArtifactTypeSchema, lt as TagType, mt as UiNavigationEvents, n as logger, nt as ResearchTaskExecutionType, o as ApiKeyScope, ot as SpeechToTextModels, p as BedrockEmbeddingModel, pt as TransferCreditTransaction, q as PromptMetaZodSchema, r as ALERT_THRESHOLDS, rt as ResearchTaskPeriodicFrequencyType, s as ApiKeyType, st as SubscriptionCreditTransaction, t as ConfigStore, tt as ResearchModeParamsSchema, u as AuthEvents, ut as TaskScheduleHandler, v as DashboardParamsSchema, vt as VoyageAIEmbeddingModel, w as FriendshipEvents, wt as getViewById, x as FavoriteDocumentType, xt as getAccessibleDataLakes, y as ElabsEvents, yt as XAI_IMAGE_MODELS, z as ModelBackend } from "./ConfigStore-Bj1IOvWn.mjs";
|
|
3
3
|
import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
|
|
4
4
|
import { execFile, execFileSync, spawn } from "child_process";
|
|
5
5
|
import { createHash, randomBytes } from "crypto";
|
|
@@ -3023,6 +3023,84 @@ const TOOL_WRITE_TODOS = "write_todos";
|
|
|
3023
3023
|
const TOOL_CREATE_DYNAMIC_AGENT = "create_dynamic_agent";
|
|
3024
3024
|
const EXPLORE_SUBAGENT_TYPE = "explore";
|
|
3025
3025
|
/**
|
|
3026
|
+
* Plan-mode section: tells the model that write tools are blocked and where to put the plan.
|
|
3027
|
+
* Appended dynamically when the user cycles into plan mode via Shift+Tab.
|
|
3028
|
+
*
|
|
3029
|
+
* The phased workflow (understand → clarify → design → present) mirrors Claude Code's
|
|
3030
|
+
* plan-mode prompting: research before designing, ask the user before assuming, and only
|
|
3031
|
+
* write the plan after ambiguities are resolved.
|
|
3032
|
+
*/
|
|
3033
|
+
function buildPlanModePromptSection(planModeFilePath) {
|
|
3034
|
+
return `
|
|
3035
|
+
|
|
3036
|
+
## PLAN MODE ACTIVE
|
|
3037
|
+
|
|
3038
|
+
The user has cycled into plan mode (Shift+Tab). Plan mode restricts WRITING, not READING. You still have a complete read toolkit — use it.
|
|
3039
|
+
|
|
3040
|
+
**Tools available in plan mode (use these aggressively):**
|
|
3041
|
+
- \`grep_search\` — find symbols, strings, patterns across files
|
|
3042
|
+
- \`glob_files\` — list files by pattern (use this instead of \`ls\` / \`find\`)
|
|
3043
|
+
- \`file_read\` — read file contents
|
|
3044
|
+
- \`find_definition\` — locate where a symbol is defined
|
|
3045
|
+
- \`get_file_structure\` — AST overview of a file
|
|
3046
|
+
- \`agent_delegate\` — delegate to read-only subagents (e.g. 'explore', 'plan')
|
|
3047
|
+
- \`ask_user_question\` — ask the user clarifying questions
|
|
3048
|
+
- \`current_datetime\`, \`math_evaluate\`, \`web_search\`, \`web_fetch\` — also fine
|
|
3049
|
+
|
|
3050
|
+
**Tools blocked in plan mode:**
|
|
3051
|
+
- \`bash_execute\`, \`edit_local_file\`, \`create_file\`, \`delete_file\` — and any other tool that mutates state.
|
|
3052
|
+
- Exception: \`create_file\` / \`edit_local_file\` targeting paths under \`${planModeFilePath.replace(/\/plan-[^/]+\.md$/, "/")}\` are allowed (that's where you write the plan).
|
|
3053
|
+
|
|
3054
|
+
**Forbidden responses:**
|
|
3055
|
+
- ❌ "I can't explore the directory because plan mode blocks shell commands."
|
|
3056
|
+
- ❌ "I'd need to run bash to check this."
|
|
3057
|
+
- ❌ Any variant of "plan mode prevents me from researching."
|
|
3058
|
+
- ✅ Instead: use \`glob_files\`, \`grep_search\`, \`file_read\`, or delegate to the \`explore\` subagent. Bash is not the only way to investigate code.
|
|
3059
|
+
|
|
3060
|
+
Ground every claim in files you have actually read. Do not write pseudocode in chat as a substitute for reading the real code.
|
|
3061
|
+
|
|
3062
|
+
Follow this phased workflow. Do not skip phases.
|
|
3063
|
+
|
|
3064
|
+
### Phase 1 — Understand
|
|
3065
|
+
- Read the relevant code before forming opinions. Use grep_search / glob_files / file_read directly for narrow lookups.
|
|
3066
|
+
- For broad or uncertain scope, delegate to the 'explore' subagent via agent_delegate so the main context stays focused.
|
|
3067
|
+
- Identify what already exists vs. what needs to be built. Reuse existing functions and patterns rather than proposing new ones.
|
|
3068
|
+
|
|
3069
|
+
### Phase 2 — Clarify (REQUIRED if anything is ambiguous)
|
|
3070
|
+
- If requirements are unclear, if there are multiple reasonable approaches, or if you would otherwise be guessing about user intent, **call the ask_user_question tool BEFORE writing the plan**.
|
|
3071
|
+
- Ask about: trade-offs the user should pick between, scope (which files / how broad), behavior on edge cases, naming, dependencies you would add.
|
|
3072
|
+
- Do NOT ask "is the plan ready?" or "should I proceed?" — those are decided by the user pressing Shift+Tab. Only ask substantive design questions.
|
|
3073
|
+
- If the request is fully unambiguous, skip this phase. Do not invent questions.
|
|
3074
|
+
|
|
3075
|
+
### Phase 3 — Design
|
|
3076
|
+
- For complex tasks, delegate to the 'plan' subagent via agent_delegate to get a structured implementation plan, then critique its output.
|
|
3077
|
+
- For simple tasks, design directly.
|
|
3078
|
+
|
|
3079
|
+
### Phase 4 — Write the plan
|
|
3080
|
+
Write the plan to \`${planModeFilePath}\` (writes to this path are permitted in plan mode). Build it incrementally — append sections as you research, do not wait until the end. Structure it as:
|
|
3081
|
+
|
|
3082
|
+
\`\`\`markdown
|
|
3083
|
+
## Context
|
|
3084
|
+
Why this change is being made — the problem, what prompted it, the intended outcome.
|
|
3085
|
+
|
|
3086
|
+
## Approach
|
|
3087
|
+
The chosen approach in 1-3 sentences. Mention rejected alternatives only if non-obvious.
|
|
3088
|
+
|
|
3089
|
+
## Files to change
|
|
3090
|
+
- path/to/file.ts — what changes and why
|
|
3091
|
+
- path/to/other.ts — what changes and why
|
|
3092
|
+
|
|
3093
|
+
## Reused existing code
|
|
3094
|
+
- function/module path — how it will be reused
|
|
3095
|
+
|
|
3096
|
+
## Verification
|
|
3097
|
+
How to confirm the change works end-to-end (commands, tests, manual steps).
|
|
3098
|
+
\`\`\`
|
|
3099
|
+
|
|
3100
|
+
### Phase 5 — Hand off
|
|
3101
|
+
Tell the user the plan is ready and where it lives (\`${planModeFilePath}\`). Summarize in 1-2 sentences. Do not ask for approval — the user will press Shift+Tab to exit plan mode and authorize execution.`;
|
|
3102
|
+
}
|
|
3103
|
+
/**
|
|
3026
3104
|
* Build the CLI system prompt with optional project context
|
|
3027
3105
|
* @param contextSection - Optional project-specific context to append (legacy string) or config object
|
|
3028
3106
|
* @param config - Configuration object for building context sections (when first param is string)
|
|
@@ -3034,6 +3112,7 @@ function buildCoreSystemPrompt(contextSection, config) {
|
|
|
3034
3112
|
let dynamicAgentSection = "";
|
|
3035
3113
|
let directoriesSection = "";
|
|
3036
3114
|
let featureModulesSection = "";
|
|
3115
|
+
let planModeSection = "";
|
|
3037
3116
|
if (typeof contextSection === "string") {
|
|
3038
3117
|
projectContextSection = contextSection;
|
|
3039
3118
|
if (config) {
|
|
@@ -3041,6 +3120,7 @@ function buildCoreSystemPrompt(contextSection, config) {
|
|
|
3041
3120
|
if (config.agentStore) agentDirectoryContext = config.agentStore.getDirectoryContext();
|
|
3042
3121
|
if (config.enableDynamicAgentCreation) dynamicAgentSection = buildDynamicAgentPromptSection();
|
|
3043
3122
|
if (config.featureModulePrompts) featureModulesSection = config.featureModulePrompts;
|
|
3123
|
+
if (config.planModeFilePath) planModeSection = buildPlanModePromptSection(config.planModeFilePath);
|
|
3044
3124
|
}
|
|
3045
3125
|
} else if (contextSection && typeof contextSection === "object") {
|
|
3046
3126
|
config = contextSection;
|
|
@@ -3050,6 +3130,7 @@ function buildCoreSystemPrompt(contextSection, config) {
|
|
|
3050
3130
|
if (config.enableDynamicAgentCreation) dynamicAgentSection = buildDynamicAgentPromptSection();
|
|
3051
3131
|
if (config.additionalDirectories && config.additionalDirectories.length > 0) directoriesSection = `\n\n## Additional Allowed Directories\n\nIn addition to the working directory (${process.cwd()}), you have read/write access to these directories:\n${config.additionalDirectories.map((d) => `- ${d}`).join("\n")}\n\nTo access files in additional directories, pass the full path to the 'dir_path' parameter of file tools:\n- ${TOOL_GREP_SEARCH}(pattern="...", dir_path="/path/to/additional/dir")\n- ${TOOL_GLOB_FILES}(pattern="**/*.ts", dir_path="/path/to/additional/dir")\n- ${TOOL_FILE_READ}(path="/path/to/additional/dir/file.ts")\n\nWhen the user asks about content in an additional directory, search there first using the dir_path parameter.`;
|
|
3052
3132
|
if (config.featureModulePrompts) featureModulesSection = config.featureModulePrompts;
|
|
3133
|
+
if (config.planModeFilePath) planModeSection = buildPlanModePromptSection(config.planModeFilePath);
|
|
3053
3134
|
}
|
|
3054
3135
|
return `You are an autonomous AI assistant with access to tools. Your job is to help users by taking action and solving problems proactively.
|
|
3055
3136
|
|
|
@@ -3152,7 +3233,7 @@ You have tools for tracking decisions, blockers, and human review gates during y
|
|
|
3152
3233
|
|
|
3153
3234
|
- request_review_gate: Pause for explicit human approval before crossing a significant decision point — one that affects interpretation, evidence, cost, credentials, platform, or public commitment (e.g., narrowing research scope after synthesis, hard-to-reverse refactors, architectural pivots, dependency swaps). Do NOT use for routine operations or actions already covered by the standard permission system (file edits, bash commands). Treat a rejection as a hard stop — re-plan, do not retry.
|
|
3154
3235
|
|
|
3155
|
-
These tools are lightweight — use them naturally as part of your work, not as a ceremony.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}`;
|
|
3236
|
+
These tools are lightweight — use them naturally as part of your work, not as a ceremony.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}`;
|
|
3156
3237
|
}
|
|
3157
3238
|
/**
|
|
3158
3239
|
* Build the minimal-variant system prompt. Reuses the project context,
|
|
@@ -3165,16 +3246,18 @@ function buildMinimalSystemPrompt(config = {}) {
|
|
|
3165
3246
|
let skillsSection = "";
|
|
3166
3247
|
let directoriesSection = "";
|
|
3167
3248
|
let featureModulesSection = "";
|
|
3249
|
+
let planModeSection = "";
|
|
3168
3250
|
if (config.contextContent) projectContextSection = `\n\n## Project Context\n\nFollow these project-specific instructions:\n\n${config.contextContent}`;
|
|
3169
3251
|
if (config.enableSkillTool !== false && config.customCommands && config.customCommands.length > 0) skillsSection = buildSkillsPromptSection(config.customCommands);
|
|
3170
3252
|
if (config.additionalDirectories && config.additionalDirectories.length > 0) directoriesSection = `\n\n## Additional Allowed Directories\n\nIn addition to the working directory (${process.cwd()}), you have read/write access to these directories:\n${config.additionalDirectories.map((d) => `- ${d}`).join("\n")}\n\nPass full paths to file tools' \`dir_path\` parameter to access these directories.`;
|
|
3171
3253
|
if (config.featureModulePrompts) featureModulesSection = config.featureModulePrompts;
|
|
3254
|
+
if (config.planModeFilePath) planModeSection = buildPlanModePromptSection(config.planModeFilePath);
|
|
3172
3255
|
return `You are an expert coding assistant. You help users by reading files, executing commands, editing code, and writing new files using the tools available to you.
|
|
3173
3256
|
|
|
3174
3257
|
Guidelines:
|
|
3175
3258
|
- Be concise in your responses.
|
|
3176
3259
|
- Show file paths clearly when working with files.
|
|
3177
|
-
- When the task is done, give the user a direct answer — no recap of steps already visible in the tool history.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}`;
|
|
3260
|
+
- When the task is done, give the user a direct answer — no recap of steps already visible in the tool history.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}`;
|
|
3178
3261
|
}
|
|
3179
3262
|
/**
|
|
3180
3263
|
* Pick a system prompt by variant. The dispatch point for the
|
|
@@ -3234,6 +3317,41 @@ You have access to the '${TOOL_CREATE_DYNAMIC_AGENT}' tool, which lets you creat
|
|
|
3234
3317
|
thoroughness: "quick"`;
|
|
3235
3318
|
}
|
|
3236
3319
|
//#endregion
|
|
3320
|
+
//#region src/utils/planMode.ts
|
|
3321
|
+
const PLAN_MODE_DIR = ".b4m-cli/plans";
|
|
3322
|
+
const PATH_TOOLS = new Set([
|
|
3323
|
+
"create_file",
|
|
3324
|
+
"edit_local_file",
|
|
3325
|
+
"delete_file"
|
|
3326
|
+
]);
|
|
3327
|
+
/**
|
|
3328
|
+
* Directory plan-mode artifacts are written to (under the working directory).
|
|
3329
|
+
* Writes to paths under this directory are permitted while plan mode is active.
|
|
3330
|
+
*/
|
|
3331
|
+
function getPlanModeFileDir(cwd = process.cwd()) {
|
|
3332
|
+
return path.resolve(cwd, PLAN_MODE_DIR);
|
|
3333
|
+
}
|
|
3334
|
+
/**
|
|
3335
|
+
* Default plan file for the current session. Sessions can override this if needed.
|
|
3336
|
+
*/
|
|
3337
|
+
function getPlanModeFilePath(sessionId, cwd = process.cwd()) {
|
|
3338
|
+
const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3339
|
+
return path.join(getPlanModeFileDir(cwd), `plan-${safeId}.md`);
|
|
3340
|
+
}
|
|
3341
|
+
/**
|
|
3342
|
+
* Whether a write/edit/delete tool call targets a path inside the plan-mode directory.
|
|
3343
|
+
* Used to allow incremental plan-file writes while plan mode blocks other writes.
|
|
3344
|
+
*/
|
|
3345
|
+
function isWriteTargetingPlanFile(toolName, args, cwd = process.cwd()) {
|
|
3346
|
+
if (!PATH_TOOLS.has(toolName)) return false;
|
|
3347
|
+
const argPath = args?.path;
|
|
3348
|
+
if (typeof argPath !== "string" || argPath.length === 0) return false;
|
|
3349
|
+
const resolved = path.resolve(cwd, argPath);
|
|
3350
|
+
const planDir = getPlanModeFileDir(cwd);
|
|
3351
|
+
const rel = path.relative(planDir, resolved);
|
|
3352
|
+
return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
3353
|
+
}
|
|
3354
|
+
//#endregion
|
|
3237
3355
|
//#region ../../b4m-core/utils/dist/imageGeneration/AIImageService.mjs
|
|
3238
3356
|
/**
|
|
3239
3357
|
* Abstract class for AI Image Service
|
|
@@ -5723,7 +5841,7 @@ z.object({
|
|
|
5723
5841
|
* @see https://platform.openai.com/docs/guides/function-calling
|
|
5724
5842
|
*/
|
|
5725
5843
|
const MAX_GOAL_LENGTH = 1e3;
|
|
5726
|
-
const MAX_DESCRIPTION_LENGTH = 2e3;
|
|
5844
|
+
const MAX_DESCRIPTION_LENGTH$1 = 2e3;
|
|
5727
5845
|
ChatModels.GPT5, ChatModels.GPT5_MINI, ChatModels.GPT5_NANO, ChatModels.GPT5_1, ChatModels.GPT5_2, ChatModels.GPT5_4, ChatModels.GPT5_4_MINI, ChatModels.GPT5_4_NANO, ChatModels.GPT5_5;
|
|
5728
5846
|
/**
|
|
5729
5847
|
* Invokes the image processor Lambda to convert and resize images
|
|
@@ -15204,7 +15322,8 @@ updateUserSchema.extend({
|
|
|
15204
15322
|
note: z.string(),
|
|
15205
15323
|
userName: z.string()
|
|
15206
15324
|
})).optional(),
|
|
15207
|
-
numReferralsAvailable: z.number().optional()
|
|
15325
|
+
numReferralsAvailable: z.number().optional(),
|
|
15326
|
+
disputePending: z.boolean().optional()
|
|
15208
15327
|
});
|
|
15209
15328
|
z.object({
|
|
15210
15329
|
username: z.string(),
|
|
@@ -15907,7 +16026,7 @@ z.object({
|
|
|
15907
16026
|
const questSchema = z.object({
|
|
15908
16027
|
id: z.string(),
|
|
15909
16028
|
title: z.string().min(1).max(255),
|
|
15910
|
-
description: z.string().max(MAX_DESCRIPTION_LENGTH),
|
|
16029
|
+
description: z.string().max(MAX_DESCRIPTION_LENGTH$1),
|
|
15911
16030
|
status: z.enum([
|
|
15912
16031
|
"not_started",
|
|
15913
16032
|
"in_progress",
|
|
@@ -15930,7 +16049,7 @@ const questResourceSchema = z.object({
|
|
|
15930
16049
|
});
|
|
15931
16050
|
z.object({
|
|
15932
16051
|
title: z.string().min(1).max(255),
|
|
15933
|
-
description: z.string().max(MAX_DESCRIPTION_LENGTH).optional(),
|
|
16052
|
+
description: z.string().max(MAX_DESCRIPTION_LENGTH$1).optional(),
|
|
15934
16053
|
goal: z.string().min(1).max(MAX_GOAL_LENGTH),
|
|
15935
16054
|
complexity: z.enum([
|
|
15936
16055
|
"beginner",
|
|
@@ -18970,9 +19089,18 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
18970
19089
|
});
|
|
18971
19090
|
return result;
|
|
18972
19091
|
}
|
|
19092
|
+
const { useCliStore } = await import("./store-44C_Fvdb.mjs");
|
|
19093
|
+
const interactionMode = useCliStore.getState().interactionMode;
|
|
19094
|
+
if (interactionMode === "plan" && !isReadOnlyTool(toolName) && !isWriteTargetingPlanFile(toolName, args)) {
|
|
19095
|
+
const result = `Tool "${toolName}" is blocked while plan mode is active. Plan mode is read-only — research the codebase, then write your plan to a file under ${getPlanModeFileDir()}/. The user will press Shift+Tab to exit plan mode and authorize execution.`;
|
|
19096
|
+
agentContext.observationQueue.push({
|
|
19097
|
+
toolName,
|
|
19098
|
+
result
|
|
19099
|
+
});
|
|
19100
|
+
return result;
|
|
19101
|
+
}
|
|
18973
19102
|
if (!permissionManager.needsPermission(toolName, { isSandboxed })) return executeAndRecord();
|
|
18974
|
-
|
|
18975
|
-
if (useCliStore.getState().autoAcceptEdits) return executeAndRecord();
|
|
19103
|
+
if (interactionMode === "auto-accept") return executeAndRecord();
|
|
18976
19104
|
const response = await showPermissionPrompt(toolName, effectiveArgs, await generateToolPreview(toolName, args, isSandboxed));
|
|
18977
19105
|
if (response.action === "deny") throw new PermissionDeniedError(toolName, args);
|
|
18978
19106
|
if (response.action === "allow-session") permissionManager.trustToolForSession(toolName);
|
|
@@ -23989,6 +24117,10 @@ function createBlockerStore(onUpdate) {
|
|
|
23989
24117
|
}
|
|
23990
24118
|
//#endregion
|
|
23991
24119
|
//#region src/tools/reviewGateTool.ts
|
|
24120
|
+
const MAX_DESCRIPTION_LENGTH = 2e3;
|
|
24121
|
+
const MAX_RECOMMENDATION_LENGTH = 1e3;
|
|
24122
|
+
const MAX_OPTION_LENGTH = 500;
|
|
24123
|
+
const MAX_OPTIONS_COUNT = 10;
|
|
23992
24124
|
/**
|
|
23993
24125
|
* Validate request_review_gate parameters
|
|
23994
24126
|
* @throws Error if validation fails
|
|
@@ -23996,11 +24128,19 @@ function createBlockerStore(onUpdate) {
|
|
|
23996
24128
|
function validateParams(args) {
|
|
23997
24129
|
const params = args;
|
|
23998
24130
|
if (typeof params.description !== "string" || params.description.trim() === "") throw new Error("request_review_gate: description must be a non-empty string");
|
|
24131
|
+
if (params.description.length > MAX_DESCRIPTION_LENGTH) throw new Error(`request_review_gate: description must be ${MAX_DESCRIPTION_LENGTH} characters or fewer`);
|
|
23999
24132
|
if (params.options !== void 0) {
|
|
24000
24133
|
if (!Array.isArray(params.options)) throw new Error("request_review_gate: options must be an array of strings");
|
|
24001
|
-
|
|
24134
|
+
if (params.options.length > MAX_OPTIONS_COUNT) throw new Error(`request_review_gate: options must contain ${MAX_OPTIONS_COUNT} entries or fewer`);
|
|
24135
|
+
for (const opt of params.options) {
|
|
24136
|
+
if (typeof opt !== "string") throw new Error("request_review_gate: each option must be a string");
|
|
24137
|
+
if (opt.length > MAX_OPTION_LENGTH) throw new Error(`request_review_gate: each option must be ${MAX_OPTION_LENGTH} characters or fewer`);
|
|
24138
|
+
}
|
|
24139
|
+
}
|
|
24140
|
+
if (params.recommendation !== void 0) {
|
|
24141
|
+
if (typeof params.recommendation !== "string") throw new Error("request_review_gate: recommendation must be a string");
|
|
24142
|
+
if (params.recommendation.length > MAX_RECOMMENDATION_LENGTH) throw new Error(`request_review_gate: recommendation must be ${MAX_RECOMMENDATION_LENGTH} characters or fewer`);
|
|
24002
24143
|
}
|
|
24003
|
-
if (params.recommendation !== void 0 && typeof params.recommendation !== "string") throw new Error("request_review_gate: recommendation must be a string");
|
|
24004
24144
|
const options = params.options?.map((o) => o.trim()).filter((o) => o.length > 0);
|
|
24005
24145
|
return {
|
|
24006
24146
|
description: params.description.trim(),
|
|
@@ -24015,6 +24155,11 @@ function formatReviewGatesOutput(gates) {
|
|
|
24015
24155
|
if (gates.length === 0) return "No review gates recorded in this session.";
|
|
24016
24156
|
return gates.map((gate, index) => {
|
|
24017
24157
|
const lines = [`${index + 1}. **${gate.description}**`, ` Status: ${gate.status}`];
|
|
24158
|
+
if (gate.recommendation) lines.push(` Recommendation: ${gate.recommendation}`);
|
|
24159
|
+
if (gate.options && gate.options.length > 0) {
|
|
24160
|
+
lines.push(" Options:");
|
|
24161
|
+
for (const opt of gate.options) lines.push(` • ${opt}`);
|
|
24162
|
+
}
|
|
24018
24163
|
if (gate.userNote) lines.push(` Note: ${gate.userNote}`);
|
|
24019
24164
|
const requested = new Date(gate.timestamp).toLocaleTimeString();
|
|
24020
24165
|
lines.push(` Requested at: ${requested}`);
|
|
@@ -24053,7 +24198,9 @@ function createReviewGateTool(store, requestReviewFn) {
|
|
|
24053
24198
|
description: params.description,
|
|
24054
24199
|
status: response.decision,
|
|
24055
24200
|
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24056
|
-
userNote: trimmedNote && trimmedNote.length > 0 ? trimmedNote : void 0
|
|
24201
|
+
userNote: trimmedNote && trimmedNote.length > 0 ? trimmedNote : void 0,
|
|
24202
|
+
options: params.options,
|
|
24203
|
+
recommendation: params.recommendation
|
|
24057
24204
|
};
|
|
24058
24205
|
store.reviewGates.push(entry);
|
|
24059
24206
|
if (store.onUpdate) store.onUpdate(store.reviewGates);
|
|
@@ -24111,4 +24258,4 @@ function createReviewGateStore(onUpdate) {
|
|
|
24111
24258
|
};
|
|
24112
24259
|
}
|
|
24113
24260
|
//#endregion
|
|
24114
|
-
export {
|
|
24261
|
+
export { CommandHistoryStore as $, formatStep as A, DEFAULT_RETRY_CONFIG as B, WebSocketToolExecutor as C, ServerLlmBackend as D, WebSocketLlmBackend as E, PermissionManager as F, OllamaBackend as G, clearFeatureModuleTools as H, generateCliTools as I, buildSkillsPromptSection as J, getPlanModeFilePath as K, ALWAYS_DENIED_FOR_AGENTS as L, loadContextFiles as M, getApiUrl as N, McpManager as O, getEnvironmentName as P, CheckpointStore as Q, DEFAULT_AGENT_MODEL as R, ApiClient as S, FallbackLlmBackend as T, registerFeatureModuleTools as U, DEFAULT_THOROUGHNESS as V, setWebSocketToolExecutor as W, ReActAgent as X, isReadOnlyTool as Y, CustomCommandStore as Z, createAgentDelegateTool as _, createBlockerTools as a, mergeCommands as at, createSkillTool as b, createDecisionStore as c, warmFileCache as ct, createFindDefinitionTool as d, SessionStore as et, createTodoStore as f, BackgroundAgentManager as g, createBackgroundAgentTools as h, createBlockerStore as i, searchCommands as it, extractCompactInstructions as j, substituteArguments as k, formatDecisionsOutput as l, createCoordinateTaskTool as m, createReviewGateTool as n, hasFileReferences as nt, formatBlockersOutput as o, formatFileSize$1 as ot, createWriteTodosTool as p, buildSystemPrompt as q, formatReviewGatesOutput as r, processFileReferences as rt, createDecisionLogTool as s, searchFiles as st, createReviewGateStore as t, OAuthClient as tt, createGetFileStructureTool as u, AgentStore as v, WebSocketConnectionManager as w, parseAgentConfig as x, SubagentOrchestrator as y, DEFAULT_MAX_ITERATIONS as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -118,11 +118,11 @@
|
|
|
118
118
|
"tsx": "^4.21.0",
|
|
119
119
|
"typescript": "^5.9.3",
|
|
120
120
|
"vitest": "^4.1.2",
|
|
121
|
-
"@bike4mind/agents": "0.7.
|
|
122
|
-
"@bike4mind/common": "2.92.
|
|
123
|
-
"@bike4mind/
|
|
124
|
-
"@bike4mind/
|
|
125
|
-
"@bike4mind/
|
|
121
|
+
"@bike4mind/agents": "0.7.1",
|
|
122
|
+
"@bike4mind/common": "2.92.2",
|
|
123
|
+
"@bike4mind/mcp": "1.37.4",
|
|
124
|
+
"@bike4mind/services": "2.79.5",
|
|
125
|
+
"@bike4mind/utils": "2.19.4"
|
|
126
126
|
},
|
|
127
127
|
"optionalDependencies": {
|
|
128
128
|
"@vscode/ripgrep": "^1.17.1"
|
package/dist/store-D2zh6DFz.mjs
DELETED