minovative-mind-cli 2.5.2 → 2.6.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/README.md +28 -25
- package/dist/commands/chat.js +1 -1
- package/dist/services/agent/inputHandler.d.ts +9 -0
- package/dist/services/agent/inputHandler.js +34 -0
- package/dist/services/agent/slashCommands.js +102 -26
- package/dist/services/agent/syntaxAgent.d.ts +40 -0
- package/dist/services/agent/syntaxAgent.js +237 -23
- package/dist/services/agent/toolLoop.js +10 -1
- package/dist/services/agent/types.d.ts +1 -0
- package/dist/services/agent-tools.d.ts +156 -1
- package/dist/services/agent-tools.js +259 -67
- package/dist/services/agent.d.ts +74 -0
- package/dist/services/agent.js +192 -30
- package/dist/services/ai.d.ts +5 -0
- package/dist/services/ai.js +80 -87
- package/dist/services/chatHistoryService.d.ts +11 -0
- package/dist/services/chatHistoryService.js +20 -1
- package/dist/services/contextAgent.d.ts +1 -1
- package/dist/services/contextAgent.js +9 -29
- package/dist/services/orchestration/investigationAgent.d.ts +2 -1
- package/dist/services/orchestration/investigationAgent.js +7 -2
- package/dist/services/orchestration/investigationOrchestrator.d.ts +1 -1
- package/dist/services/orchestration/investigationOrchestrator.js +13 -2
- package/dist/services/orchestration/orchestrator.js +21 -4
- package/dist/services/orchestration/subAgent.d.ts +2 -1
- package/dist/services/orchestration/subAgent.js +12 -6
- package/dist/utils/analysisRunner.d.ts +27 -4
- package/dist/utils/analysisRunner.js +100 -20
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.js +2 -0
- package/dist/utils/fuzzyMatch.d.ts +32 -0
- package/dist/utils/fuzzyMatch.js +215 -27
- package/dist/utils/localSyntaxValidator.d.ts +2 -2
- package/dist/utils/localSyntaxValidator.js +280 -81
- package/dist/utils/performanceAuditor.d.ts +2 -7
- package/dist/utils/performanceAuditor.js +541 -89
- package/dist/utils/projectStorage.js +9 -0
- package/dist/utils/systemPrompts.d.ts +3 -2
- package/dist/utils/systemPrompts.js +29 -5
- package/oclif.manifest.json +2 -2
- package/package.json +1 -1
|
@@ -67,7 +67,7 @@ export class Orchestrator {
|
|
|
67
67
|
this.bus = new MessageBus(workspaceRoot, conversationId);
|
|
68
68
|
this.locks = new FileLockRegistry();
|
|
69
69
|
let model = getGlobalActiveModel();
|
|
70
|
-
if (model === GEMINI_MODELS.AUTO)
|
|
70
|
+
if (model === GEMINI_MODELS.AUTO || model.includes('claude'))
|
|
71
71
|
model = GEMINI_MODELS.FLASH;
|
|
72
72
|
this.pmChat = new ProxyChatSession(model, PM_SYSTEM_INSTRUCTION, [], {
|
|
73
73
|
maxOutputTokens: MAX_OUTPUT_TOKENS,
|
|
@@ -109,6 +109,7 @@ export class Orchestrator {
|
|
|
109
109
|
.join('\n');
|
|
110
110
|
p.log.step(pc.magenta(`Starting Wave ${wave.depth + 1} (${wave.taskIds.length} tasks):\n${taskDescriptions}`));
|
|
111
111
|
const s = p.spinner();
|
|
112
|
+
this.inputHandler.setSpinner(s);
|
|
112
113
|
s.start(`Executing Wave ${wave.depth + 1}...`);
|
|
113
114
|
const agentStatuses = new Map();
|
|
114
115
|
const updateSpinner = () => {
|
|
@@ -120,6 +121,7 @@ export class Orchestrator {
|
|
|
120
121
|
// Limit to 2 concurrent sub-agents to avoid Vertex AI RESOURCE_EXHAUSTED
|
|
121
122
|
const results = [];
|
|
122
123
|
const MAX_CONCURRENT = 2;
|
|
124
|
+
const toolLogs = [];
|
|
123
125
|
for (let i = 0; i < wave.taskIds.length; i += MAX_CONCURRENT) {
|
|
124
126
|
const chunk = wave.taskIds.slice(i, i + MAX_CONCURRENT);
|
|
125
127
|
const wavePromises = chunk.map((taskId) => {
|
|
@@ -127,15 +129,30 @@ export class Orchestrator {
|
|
|
127
129
|
const globalContext = `Objective:\n${objective}\n\nContext:\n${contextInjection}`;
|
|
128
130
|
agentStatuses.set(taskDef.id, 'Starting...');
|
|
129
131
|
updateSpinner();
|
|
132
|
+
const onToolCall = (msg) => {
|
|
133
|
+
const formattedLog = `${pc.dim(`[${taskDef.id}]`)} ${msg}`;
|
|
134
|
+
toolLogs.push(formattedLog);
|
|
135
|
+
// Keep the spinner running, just update the status message
|
|
136
|
+
agentStatuses.set(taskDef.id, msg);
|
|
137
|
+
updateSpinner();
|
|
138
|
+
};
|
|
130
139
|
return this.dispatchAgent(taskDef, globalContext, signal, (msg) => {
|
|
131
140
|
agentStatuses.set(taskDef.id, msg);
|
|
132
141
|
updateSpinner();
|
|
142
|
+
}, onToolCall).then((res) => {
|
|
143
|
+
agentStatuses.set(taskDef.id, res.success ? '✅ Done' : '❌ Failed');
|
|
144
|
+
updateSpinner();
|
|
145
|
+
return res;
|
|
133
146
|
});
|
|
134
147
|
});
|
|
135
148
|
const chunkResults = await Promise.all(wavePromises);
|
|
136
149
|
results.push(...chunkResults);
|
|
137
150
|
}
|
|
138
|
-
|
|
151
|
+
const successful = results.filter((r) => r.success).length;
|
|
152
|
+
s.stop(`Wave ${wave.depth + 1} completed: ${successful}/${wave.taskIds.length} tasks succeeded`);
|
|
153
|
+
if (toolLogs.length > 0) {
|
|
154
|
+
toolLogs.forEach(log => p.log.step(log));
|
|
155
|
+
}
|
|
139
156
|
// Post-wave evaluation
|
|
140
157
|
const failedCount = results.filter((r) => !r.success).length;
|
|
141
158
|
if (failedCount > 0) {
|
|
@@ -213,9 +230,9 @@ export class Orchestrator {
|
|
|
213
230
|
/**
|
|
214
231
|
* Dispatches a single sub-agent and records its result.
|
|
215
232
|
*/
|
|
216
|
-
async dispatchAgent(taskDef, globalContext, signal, onProgress) {
|
|
233
|
+
async dispatchAgent(taskDef, globalContext, signal, onProgress, onTool) {
|
|
217
234
|
return trackTask(`Sub-Agent: ${taskDef.id}`, async () => {
|
|
218
|
-
const runner = new SubAgentRunner(taskDef.id, taskDef.intent, this.workspaceRoot, this.bus, this.locks, globalContext, onProgress);
|
|
235
|
+
const runner = new SubAgentRunner(taskDef.id, taskDef.intent, this.workspaceRoot, this.bus, this.locks, globalContext, onProgress, onTool);
|
|
219
236
|
const result = await runner.execute(signal);
|
|
220
237
|
// Clean up any stray locks if the agent crashed or stalled
|
|
221
238
|
if (result.crashed) {
|
|
@@ -33,6 +33,7 @@ export declare class SubAgentRunner {
|
|
|
33
33
|
private readonly locks;
|
|
34
34
|
private readonly globalContext;
|
|
35
35
|
private readonly onProgress?;
|
|
36
|
+
private readonly onTool?;
|
|
36
37
|
private chat;
|
|
37
38
|
private lastHeartbeat;
|
|
38
39
|
private creditsUsed;
|
|
@@ -40,7 +41,7 @@ export declare class SubAgentRunner {
|
|
|
40
41
|
private outputTokens;
|
|
41
42
|
/** Max time without a tool call or response before the agent is considered stalled */
|
|
42
43
|
static readonly STALL_TIMEOUT_MS = 300000;
|
|
43
|
-
constructor(taskId: string, intent: string, workspaceRoot: string, bus: MessageBus, locks: FileLockRegistry, globalContext: string, onProgress?: ((msg: string) => void) | undefined);
|
|
44
|
+
constructor(taskId: string, intent: string, workspaceRoot: string, bus: MessageBus, locks: FileLockRegistry, globalContext: string, onProgress?: ((msg: string) => void) | undefined, onTool?: ((msg: string) => void) | undefined);
|
|
44
45
|
/**
|
|
45
46
|
* Constructs the base system instruction for this specific agent.
|
|
46
47
|
*/
|
|
@@ -9,6 +9,7 @@ import { GEMINI_MODELS, MAX_OUTPUT_TOKENS } from '../../utils/config.js';
|
|
|
9
9
|
import { executeScopedTool, getScopedToolDeclarations } from './scopedTools.js';
|
|
10
10
|
import { debugLog } from '../../utils/logger.js';
|
|
11
11
|
import { runWithAgentId } from '../../utils/asyncContext.js';
|
|
12
|
+
import { formatToolCall } from '../agent/toolLoop.js';
|
|
12
13
|
/**
|
|
13
14
|
* Executes a sub-agent task with full health monitoring, tool wrapping,
|
|
14
15
|
* and orchestration integration.
|
|
@@ -21,6 +22,7 @@ export class SubAgentRunner {
|
|
|
21
22
|
locks;
|
|
22
23
|
globalContext;
|
|
23
24
|
onProgress;
|
|
25
|
+
onTool;
|
|
24
26
|
chat;
|
|
25
27
|
lastHeartbeat = Date.now();
|
|
26
28
|
creditsUsed = 0;
|
|
@@ -28,7 +30,7 @@ export class SubAgentRunner {
|
|
|
28
30
|
outputTokens = 0;
|
|
29
31
|
/** Max time without a tool call or response before the agent is considered stalled */
|
|
30
32
|
static STALL_TIMEOUT_MS = 300_000;
|
|
31
|
-
constructor(taskId, intent, workspaceRoot, bus, locks, globalContext, onProgress) {
|
|
33
|
+
constructor(taskId, intent, workspaceRoot, bus, locks, globalContext, onProgress, onTool) {
|
|
32
34
|
this.taskId = taskId;
|
|
33
35
|
this.intent = intent;
|
|
34
36
|
this.workspaceRoot = workspaceRoot;
|
|
@@ -36,6 +38,7 @@ export class SubAgentRunner {
|
|
|
36
38
|
this.locks = locks;
|
|
37
39
|
this.globalContext = globalContext;
|
|
38
40
|
this.onProgress = onProgress;
|
|
41
|
+
this.onTool = onTool;
|
|
39
42
|
let model = getGlobalActiveModel();
|
|
40
43
|
if (model === GEMINI_MODELS.AUTO)
|
|
41
44
|
model = GEMINI_MODELS.FLASH;
|
|
@@ -66,11 +69,11 @@ export class SubAgentRunner {
|
|
|
66
69
|
`1. You are ONE worker in a team. Focus EXCLUSIVELY on your specific objective: "${this.intent}".\n` +
|
|
67
70
|
`2. DO NOT attempt to fulfill the entire original user request in the reference context. Other agents handle other tasks.\n` +
|
|
68
71
|
`3. EXECUTION WORKFLOW:\n` +
|
|
69
|
-
` - Step 1 (
|
|
70
|
-
` - Step 2 (
|
|
71
|
-
` - Step 3 (
|
|
72
|
-
`
|
|
73
|
-
`
|
|
72
|
+
` - Step 1 (Investigate): Use 'grep_search', 'read_file', or 'list_directory' to inspect the codebase as needed.\n` +
|
|
73
|
+
` - Step 2 (Execute): Use 'modify_file' or 'write_file' to implement the required changes.\n` +
|
|
74
|
+
` - Step 3 (Verify): Use 'run_debug_script' or 'run_command' to test your changes if necessary.\n` +
|
|
75
|
+
` - Step 4 (Conclude): Once your specific objective is fully met, stop calling tools and return a text summary of your changes.\n` +
|
|
76
|
+
`4. Coordinate: Use 'read_messages' to check for updates from other agents. Use 'post_message' if you discover breaking changes affecting others.\n` +
|
|
74
77
|
`</critical_guidelines>`);
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
@@ -128,6 +131,9 @@ export class SubAgentRunner {
|
|
|
128
131
|
if (this.onProgress) {
|
|
129
132
|
this.onProgress(`executing ${call.name}...`);
|
|
130
133
|
}
|
|
134
|
+
if (this.onTool) {
|
|
135
|
+
this.onTool(formatToolCall(call.name, call.args));
|
|
136
|
+
}
|
|
131
137
|
debugLog(`SubAgent [${this.taskId}]: Executing tool ${call.name}`);
|
|
132
138
|
let responseData;
|
|
133
139
|
try {
|
|
@@ -3,14 +3,28 @@ export interface EphemeralScriptResult {
|
|
|
3
3
|
stderr: string;
|
|
4
4
|
exitCode: number;
|
|
5
5
|
}
|
|
6
|
-
interface EphemeralScriptOptions {
|
|
7
|
-
/** Execution timeout in milliseconds. Defaults to
|
|
6
|
+
export interface EphemeralScriptOptions {
|
|
7
|
+
/** Execution timeout in milliseconds. Defaults to 60,000 (60s). */
|
|
8
8
|
timeoutMs?: number;
|
|
9
|
-
/** Maximum characters to capture from stdout/stderr. Defaults to
|
|
9
|
+
/** Maximum characters to capture from stdout/stderr. Defaults to 100,000. */
|
|
10
10
|
maxOutputChars?: number;
|
|
11
11
|
/** AbortSignal to cancel execution. */
|
|
12
12
|
abortSignal?: AbortSignal;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Normalizes user/AI provided language string to a standard runtime identifier.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeLanguage(lang: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Detects whether the workspace package.json specifies `"type": "module"`.
|
|
20
|
+
* Returns `'module'` or `'commonjs'`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectWorkspaceModuleType(workspaceRoot: string): Promise<'module' | 'commonjs'>;
|
|
23
|
+
/**
|
|
24
|
+
* Dynamically resolves the appropriate file extension for a script based on workspace configuration,
|
|
25
|
+
* target runtime language, and source code syntax analysis.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveScriptExtension(workspaceRoot: string, language: string, code: string): Promise<string>;
|
|
14
28
|
/**
|
|
15
29
|
* Write a disposable analysis script to a temporary file, execute it using the
|
|
16
30
|
* specified language runtime, capture its output, and guarantee cleanup.
|
|
@@ -26,4 +40,13 @@ interface EphemeralScriptOptions {
|
|
|
26
40
|
* @returns Captured stdout, stderr, and exit code.
|
|
27
41
|
*/
|
|
28
42
|
export declare function runEphemeralScript(workspaceRoot: string, language: string, code: string, options?: EphemeralScriptOptions): Promise<EphemeralScriptResult>;
|
|
29
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Primary entry point for dynamic debug script execution.
|
|
45
|
+
* Accepts code and options, auto-resolving runtime language and script extension.
|
|
46
|
+
*
|
|
47
|
+
* @param workspaceRoot - Path to the root directory of the workspace.
|
|
48
|
+
* @param code - The debug script source code to execute.
|
|
49
|
+
* @param language - Optional runtime language (defaults to 'node').
|
|
50
|
+
* @param options - Execution options (timeoutMs, maxOutputChars, abortSignal).
|
|
51
|
+
*/
|
|
52
|
+
export declare function runDebugScript(workspaceRoot: string, code: string, language?: string | EphemeralScriptOptions, options?: EphemeralScriptOptions): Promise<EphemeralScriptResult>;
|
|
@@ -5,15 +5,76 @@ import { exec } from 'node:child_process';
|
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
import { createHash } from 'node:crypto';
|
|
7
7
|
const execAsync = promisify(exec);
|
|
8
|
-
/**
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
/** Supported language aliases map. */
|
|
9
|
+
const LANGUAGE_ALIASES = {
|
|
10
|
+
js: 'node',
|
|
11
|
+
javascript: 'node',
|
|
12
|
+
node: 'node',
|
|
13
|
+
ts: 'ts-node',
|
|
14
|
+
typescript: 'ts-node',
|
|
15
|
+
'ts-node': 'ts-node',
|
|
16
|
+
py: 'python',
|
|
17
|
+
python: 'python',
|
|
18
|
+
sh: 'bash',
|
|
19
|
+
bash: 'bash',
|
|
20
|
+
go: 'go',
|
|
21
|
+
rs: 'rust',
|
|
22
|
+
rust: 'rust',
|
|
16
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Normalizes user/AI provided language string to a standard runtime identifier.
|
|
26
|
+
*/
|
|
27
|
+
export function normalizeLanguage(lang) {
|
|
28
|
+
const key = lang.toLowerCase().trim();
|
|
29
|
+
return LANGUAGE_ALIASES[key] || key;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Detects whether the workspace package.json specifies `"type": "module"`.
|
|
33
|
+
* Returns `'module'` or `'commonjs'`.
|
|
34
|
+
*/
|
|
35
|
+
export async function detectWorkspaceModuleType(workspaceRoot) {
|
|
36
|
+
try {
|
|
37
|
+
const pkgPath = path.join(workspaceRoot, 'package.json');
|
|
38
|
+
const content = await fs.readFile(pkgPath, 'utf-8');
|
|
39
|
+
const pkg = JSON.parse(content);
|
|
40
|
+
return pkg.type === 'module' ? 'module' : 'commonjs';
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return 'commonjs';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Dynamically resolves the appropriate file extension for a script based on workspace configuration,
|
|
48
|
+
* target runtime language, and source code syntax analysis.
|
|
49
|
+
*/
|
|
50
|
+
export async function resolveScriptExtension(workspaceRoot, language, code) {
|
|
51
|
+
const normLang = normalizeLanguage(language);
|
|
52
|
+
if (normLang === 'node') {
|
|
53
|
+
// Check for explicit CJS syntax markers
|
|
54
|
+
const hasCJS = new RegExp('\\b(require\\s*\\(|module\\.exports|exports\\.)').test(code);
|
|
55
|
+
// Check for explicit ESM syntax markers
|
|
56
|
+
const hasESM = new RegExp('\\b(import\\s+|import\\(|export\\s+|export\\{|export\\s+default)\\b').test(code) || new RegExp('^\\s*await\\s+', 'm').test(code);
|
|
57
|
+
if (hasCJS && !hasESM) {
|
|
58
|
+
return '.cjs';
|
|
59
|
+
}
|
|
60
|
+
if (hasESM && !hasCJS) {
|
|
61
|
+
return '.mjs';
|
|
62
|
+
}
|
|
63
|
+
// If ambiguous or both present, default based on workspace package.json module type
|
|
64
|
+
const moduleType = await detectWorkspaceModuleType(workspaceRoot);
|
|
65
|
+
return moduleType === 'module' ? '.mjs' : '.cjs';
|
|
66
|
+
}
|
|
67
|
+
if (normLang === 'ts-node') {
|
|
68
|
+
return '.ts';
|
|
69
|
+
}
|
|
70
|
+
const defaultExts = {
|
|
71
|
+
python: '.py',
|
|
72
|
+
bash: '.sh',
|
|
73
|
+
go: '.go',
|
|
74
|
+
rust: '.rs',
|
|
75
|
+
};
|
|
76
|
+
return defaultExts[normLang] || '.js';
|
|
77
|
+
}
|
|
17
78
|
/**
|
|
18
79
|
* Generates a deterministic but unique temporary file path for the analysis script.
|
|
19
80
|
* Uses a content hash to prevent collisions when multiple scripts run concurrently.
|
|
@@ -27,7 +88,8 @@ function buildTempPath(code, ext) {
|
|
|
27
88
|
* Returns null for unsupported languages.
|
|
28
89
|
*/
|
|
29
90
|
function buildCommand(language, scriptPath) {
|
|
30
|
-
|
|
91
|
+
const normLang = normalizeLanguage(language);
|
|
92
|
+
switch (normLang) {
|
|
31
93
|
case 'node':
|
|
32
94
|
return `node "${scriptPath}"`;
|
|
33
95
|
case 'ts-node':
|
|
@@ -40,7 +102,7 @@ function buildCommand(language, scriptPath) {
|
|
|
40
102
|
return `go run "${scriptPath}"`;
|
|
41
103
|
case 'rust': {
|
|
42
104
|
const binExt = os.platform() === 'win32' ? '.exe' : '';
|
|
43
|
-
const binPath = scriptPath.replace(
|
|
105
|
+
const binPath = scriptPath.replace(/\.rs$/, binExt);
|
|
44
106
|
return `rustc "${scriptPath}" -o "${binPath}" && "${binPath}"`;
|
|
45
107
|
}
|
|
46
108
|
default:
|
|
@@ -72,24 +134,22 @@ function truncateOutput(text, max) {
|
|
|
72
134
|
export async function runEphemeralScript(workspaceRoot, language, code, options) {
|
|
73
135
|
const timeoutMs = options?.timeoutMs ?? 60_000;
|
|
74
136
|
const maxOutputChars = options?.maxOutputChars ?? 100_000;
|
|
75
|
-
const
|
|
76
|
-
|
|
137
|
+
const normLang = normalizeLanguage(language);
|
|
138
|
+
const ext = await resolveScriptExtension(workspaceRoot, normLang, code);
|
|
139
|
+
const scriptPath = buildTempPath(code, ext);
|
|
140
|
+
const cmd = buildCommand(normLang, scriptPath);
|
|
141
|
+
if (!cmd) {
|
|
77
142
|
return {
|
|
78
143
|
stdout: '',
|
|
79
|
-
stderr: `Unsupported language runtime: "${language}". Supported:
|
|
144
|
+
stderr: `Unsupported language runtime: "${language}". Supported: node, ts-node, python, bash, go, rust`,
|
|
80
145
|
exitCode: 1,
|
|
81
146
|
};
|
|
82
147
|
}
|
|
83
|
-
const scriptPath = buildTempPath(code, ext);
|
|
84
|
-
const cmd = buildCommand(language, scriptPath);
|
|
85
|
-
if (!cmd) {
|
|
86
|
-
return { stdout: '', stderr: `Failed to build command for language: ${language}`, exitCode: 1 };
|
|
87
|
-
}
|
|
88
148
|
// Collect all temp files created so we can clean them up unconditionally
|
|
89
149
|
const tempFiles = [scriptPath];
|
|
90
|
-
if (
|
|
150
|
+
if (normLang === 'rust') {
|
|
91
151
|
const binExt = os.platform() === 'win32' ? '.exe' : '';
|
|
92
|
-
tempFiles.push(scriptPath.replace(
|
|
152
|
+
tempFiles.push(scriptPath.replace(/\.rs$/, binExt));
|
|
93
153
|
}
|
|
94
154
|
try {
|
|
95
155
|
await fs.writeFile(scriptPath, code, 'utf-8');
|
|
@@ -127,3 +187,23 @@ export async function runEphemeralScript(workspaceRoot, language, code, options)
|
|
|
127
187
|
}
|
|
128
188
|
}
|
|
129
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Primary entry point for dynamic debug script execution.
|
|
192
|
+
* Accepts code and options, auto-resolving runtime language and script extension.
|
|
193
|
+
*
|
|
194
|
+
* @param workspaceRoot - Path to the root directory of the workspace.
|
|
195
|
+
* @param code - The debug script source code to execute.
|
|
196
|
+
* @param language - Optional runtime language (defaults to 'node').
|
|
197
|
+
* @param options - Execution options (timeoutMs, maxOutputChars, abortSignal).
|
|
198
|
+
*/
|
|
199
|
+
export async function runDebugScript(workspaceRoot, code, language = 'node', options) {
|
|
200
|
+
let lang = 'node';
|
|
201
|
+
let opts = options;
|
|
202
|
+
if (typeof language === 'string') {
|
|
203
|
+
lang = language;
|
|
204
|
+
}
|
|
205
|
+
else if (typeof language === 'object' && language !== null) {
|
|
206
|
+
opts = language;
|
|
207
|
+
}
|
|
208
|
+
return runEphemeralScript(workspaceRoot, lang, code, opts);
|
|
209
|
+
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -14,7 +14,9 @@ export declare const GITHUB_CLIENT_ID = "Ov23linFYFfjO3JILG7r";
|
|
|
14
14
|
* Supported Gemini AI models.
|
|
15
15
|
*/
|
|
16
16
|
export declare const GEMINI_MODELS: {
|
|
17
|
+
readonly CLAUDE_OPUS: "claude-opus-5";
|
|
17
18
|
readonly PRO: "gemini-3.1-pro-preview";
|
|
19
|
+
readonly CLAUDE_SONNET: "claude-sonnet-5";
|
|
18
20
|
readonly FLASH: "gemini-3.6-flash";
|
|
19
21
|
readonly FLASH_LITE: "gemini-3.5-flash-lite";
|
|
20
22
|
readonly AUTO: "auto";
|
package/dist/utils/config.js
CHANGED
|
@@ -14,7 +14,9 @@ export const GITHUB_CLIENT_ID = 'Ov23linFYFfjO3JILG7r';
|
|
|
14
14
|
* Supported Gemini AI models.
|
|
15
15
|
*/
|
|
16
16
|
export const GEMINI_MODELS = {
|
|
17
|
+
CLAUDE_OPUS: 'claude-opus-5',
|
|
17
18
|
PRO: 'gemini-3.1-pro-preview',
|
|
19
|
+
CLAUDE_SONNET: 'claude-sonnet-5',
|
|
18
20
|
FLASH: 'gemini-3.6-flash',
|
|
19
21
|
FLASH_LITE: 'gemini-3.5-flash-lite',
|
|
20
22
|
AUTO: 'auto',
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
import { ValidationResult } from './localSyntaxValidator.js';
|
|
1
2
|
export interface MatchResult {
|
|
2
3
|
start: number;
|
|
3
4
|
end: number;
|
|
4
5
|
strategy: string;
|
|
5
6
|
}
|
|
7
|
+
export interface PatchBlock {
|
|
8
|
+
search: string;
|
|
9
|
+
replace: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PatchApplicationResult {
|
|
12
|
+
success: boolean;
|
|
13
|
+
content: string;
|
|
14
|
+
appliedBlocks: number;
|
|
15
|
+
failedBlocks: number;
|
|
16
|
+
errors: string[];
|
|
17
|
+
syntaxValidation?: ValidationResult;
|
|
18
|
+
}
|
|
19
|
+
export interface ApplyPatchOptions {
|
|
20
|
+
validateSyntax?: boolean;
|
|
21
|
+
}
|
|
6
22
|
/**
|
|
7
23
|
* Trims each line, collapses multiple spaces/tabs to single space,
|
|
8
24
|
* and normalizes line endings.
|
|
@@ -16,6 +32,22 @@ export declare function levenshteinSimilarity(a: string, b: string): number;
|
|
|
16
32
|
/**
|
|
17
33
|
* Finds the best match for `searchContent` inside `fileContent`.
|
|
18
34
|
* Uses a pipeline of strategies: Exact -> Whitespace-normalized -> Levenshtein.
|
|
35
|
+
* Enforces uniqueness and higher confidence thresholds for non-unique search snippets across repetitive files.
|
|
19
36
|
*/
|
|
20
37
|
export declare function findBestMatch(fileContent: string, searchContent: string): MatchResult | null;
|
|
21
38
|
export declare function applyMatch(fileContent: string, match: MatchResult, replaceContent: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Parses differential patch block string into structured PatchBlock objects.
|
|
41
|
+
* Supports blocks formatted as:
|
|
42
|
+
* <<<<< SEARCH
|
|
43
|
+
* search content
|
|
44
|
+
* =====
|
|
45
|
+
* replace content
|
|
46
|
+
* >>>>> REPLACE
|
|
47
|
+
*/
|
|
48
|
+
export declare function parsePatchBlocks(patchText: string): PatchBlock[];
|
|
49
|
+
/**
|
|
50
|
+
* Applies a sequence of search/replace patch blocks to file content
|
|
51
|
+
* using fuzzy matching, and validates local syntax on the result.
|
|
52
|
+
*/
|
|
53
|
+
export declare function applyPatch(fileContent: string, patchTextOrBlocks: string | PatchBlock[], filePath?: string, options?: ApplyPatchOptions): PatchApplicationResult;
|