mirror of
https://github.com/jlengrand/Maestro.git
synced 2026-03-10 08:31:19 +00:00
fix(windows): stabilize local and SSH execution for wizard and sessions
- Use full agent path (claude.exe) on Windows to avoid shell:true which breaks stdin piping for stream-json input mode - Fix SSH condition to check enabled flag, not just config existence - Pass sessionSshRemoteConfig through inline wizard to enable remote execution - Add synopsis SSH inheritance from parent session as backend workaround Fixes local wizard crashing with exit code 1 and SSH sessions incorrectly using local paths when SSH was disabled.
This commit is contained in:
65
BUILDING_WINDOWS.md
Normal file
65
BUILDING_WINDOWS.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Building and Running on Windows
|
||||||
|
|
||||||
|
This guide provides instructions for setting up your environment and running the Maestro application on a Windows machine.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before you begin, ensure you have the following installed:
|
||||||
|
|
||||||
|
* **Node.js:** Version 22 or later.
|
||||||
|
* **Python:** Version 3 or later.
|
||||||
|
|
||||||
|
Additionally, you will need the Visual Studio Build Tools to compile native Node.js modules used in this project.
|
||||||
|
|
||||||
|
### Installing Visual Studio Build Tools
|
||||||
|
|
||||||
|
1. **Download the Build Tools:**
|
||||||
|
* Go to the [Visual Studio Downloads page](https://my.visualstudio.com/Downloads?q=Visual%20Studio%202022).
|
||||||
|
* You may need to log in with a Microsoft account.
|
||||||
|
* Download the **Build Tools for Visual Studio 2022**.
|
||||||
|
|
||||||
|
2. **Run the Installer:**
|
||||||
|
* When the installer launches, you will be prompted to select workloads.
|
||||||
|
* Check the box for **Desktop development with C++**.
|
||||||
|
* Proceed with the installation.
|
||||||
|
|
||||||
|
3. **Verify the Setup:**
|
||||||
|
* After the installation is complete, open a PowerShell terminal in the project root.
|
||||||
|
* Run `npm ci` to install dependencies. If you have already run `npm install`, you can run `npx electron-rebuild` to rebuild the native modules.
|
||||||
|
|
||||||
|
## Running the Application in Development Mode
|
||||||
|
|
||||||
|
There are two ways to run the application in development mode on Windows: using the provided script or by running the steps manually.
|
||||||
|
|
||||||
|
### Using the Development Script (Recommended)
|
||||||
|
|
||||||
|
The easiest way to start the development environment is to use the `dev:win` npm script. This script automates the entire process.
|
||||||
|
|
||||||
|
Open a PowerShell terminal and run:
|
||||||
|
```powershell
|
||||||
|
npm run dev:win
|
||||||
|
```
|
||||||
|
|
||||||
|
This will handle all the necessary build steps and launch the application.
|
||||||
|
|
||||||
|
### Manual Steps
|
||||||
|
|
||||||
|
If you encounter issues with the `dev:win` script or prefer to run the steps manually, follow this procedure.
|
||||||
|
|
||||||
|
1. **Build the application:**
|
||||||
|
```powershell
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Start the Vite renderer:**
|
||||||
|
```powershell
|
||||||
|
npm run dev:renderer
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Start the Electron main process:**
|
||||||
|
Open a **new** PowerShell terminal and run the following command:
|
||||||
|
```powershell
|
||||||
|
npm run build:prompts; npx tsc -p tsconfig.main.json; $env:NODE_ENV='development'; npx electron .
|
||||||
|
```
|
||||||
|
|
||||||
|
This will launch the application in development mode with hot-reloading for the renderer.
|
||||||
@@ -423,6 +423,7 @@ function setupIpcHandlers() {
|
|||||||
agentConfigsStore,
|
agentConfigsStore,
|
||||||
settingsStore: store,
|
settingsStore: store,
|
||||||
getMainWindow: () => mainWindow,
|
getMainWindow: () => mainWindow,
|
||||||
|
sessionsStore,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Persistence operations - extracted to src/main/ipc/handlers/persistence.ts
|
// Persistence operations - extracted to src/main/ipc/handlers/persistence.ts
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ export function registerAllHandlers(deps: HandlerDependencies): void {
|
|||||||
agentConfigsStore: deps.agentConfigsStore,
|
agentConfigsStore: deps.agentConfigsStore,
|
||||||
settingsStore: deps.settingsStore,
|
settingsStore: deps.settingsStore,
|
||||||
getMainWindow: deps.getMainWindow,
|
getMainWindow: deps.getMainWindow,
|
||||||
|
sessionsStore: deps.sessionsStore,
|
||||||
});
|
});
|
||||||
registerPersistenceHandlers({
|
registerPersistenceHandlers({
|
||||||
settingsStore: deps.settingsStore,
|
settingsStore: deps.settingsStore,
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ export interface ProcessHandlerDependencies {
|
|||||||
agentConfigsStore: Store<AgentConfigsData>;
|
agentConfigsStore: Store<AgentConfigsData>;
|
||||||
settingsStore: Store<MaestroSettings>;
|
settingsStore: Store<MaestroSettings>;
|
||||||
getMainWindow: () => BrowserWindow | null;
|
getMainWindow: () => BrowserWindow | null;
|
||||||
|
sessionsStore: Store<{ sessions: any[] }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +67,7 @@ export interface ProcessHandlerDependencies {
|
|||||||
* - runCommand: Execute a single command and capture output
|
* - runCommand: Execute a single command and capture output
|
||||||
*/
|
*/
|
||||||
export function registerProcessHandlers(deps: ProcessHandlerDependencies): void {
|
export function registerProcessHandlers(deps: ProcessHandlerDependencies): void {
|
||||||
const { getProcessManager, getAgentDetector, agentConfigsStore, settingsStore, getMainWindow } =
|
const { getProcessManager, getAgentDetector, agentConfigsStore, settingsStore, getMainWindow, sessionsStore } =
|
||||||
deps;
|
deps;
|
||||||
|
|
||||||
// Spawn a new process for a session
|
// Spawn a new process for a session
|
||||||
@@ -108,6 +109,26 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
|
|||||||
const processManager = requireProcessManager(getProcessManager);
|
const processManager = requireProcessManager(getProcessManager);
|
||||||
const agentDetector = requireDependency(getAgentDetector, 'Agent detector');
|
const agentDetector = requireDependency(getAgentDetector, 'Agent detector');
|
||||||
|
|
||||||
|
// Synopsis SSH Fix: If this is a synopsis session and it's missing SSH config,
|
||||||
|
// try to inherit it from the parent session. This is a backend workaround for
|
||||||
|
// a suspected frontend state issue where the remote config isn't passed.
|
||||||
|
const synopsisMatch = config.sessionId.match(/^(.+)-synopsis-\d+$/);
|
||||||
|
if (synopsisMatch && (!config.sessionSshRemoteConfig || !config.sessionSshRemoteConfig.enabled)) {
|
||||||
|
const originalSessionId = synopsisMatch[1];
|
||||||
|
const sessions = sessionsStore.get('sessions', []);
|
||||||
|
const originalSession = sessions.find(s => s.id === originalSessionId);
|
||||||
|
|
||||||
|
if (originalSession && originalSession.sessionSshRemoteConfig?.enabled) {
|
||||||
|
const sshConfig = originalSession.sessionSshRemoteConfig;
|
||||||
|
config.sessionSshRemoteConfig = sshConfig;
|
||||||
|
logger.info(`Inferred SSH config for synopsis session from parent session`, LOG_CONTEXT, {
|
||||||
|
sessionId: config.sessionId,
|
||||||
|
originalSessionId: originalSessionId,
|
||||||
|
sshRemoteId: sshConfig.remoteId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get agent definition to access config options and argument builders
|
// Get agent definition to access config options and argument builders
|
||||||
const agent = await agentDetector.getAgent(config.toolType);
|
const agent = await agentDetector.getAgent(config.toolType);
|
||||||
// Use INFO level on Windows for better visibility in logs
|
// Use INFO level on Windows for better visibility in logs
|
||||||
@@ -245,6 +266,13 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
|
|||||||
// ========================================================================
|
// ========================================================================
|
||||||
// Command Resolution: Apply session-level custom path override if set
|
// Command Resolution: Apply session-level custom path override if set
|
||||||
// This allows users to override the detected agent path per-session
|
// This allows users to override the detected agent path per-session
|
||||||
|
//
|
||||||
|
// WINDOWS FIX: On Windows, prefer the resolved agent path with .exe extension
|
||||||
|
// to avoid using shell:true in ProcessManager. When shell:true is used,
|
||||||
|
// stdin piping through cmd.exe is unreliable - data written to stdin may not
|
||||||
|
// be forwarded to the child process. This breaks stream-json input mode.
|
||||||
|
// By using the full path with .exe extension, ProcessManager will spawn
|
||||||
|
// the process directly without cmd.exe wrapper, ensuring stdin works correctly.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
let commandToSpawn = config.sessionCustomPath || config.command;
|
let commandToSpawn = config.sessionCustomPath || config.command;
|
||||||
let argsToSpawn = finalArgs;
|
let argsToSpawn = finalArgs;
|
||||||
@@ -254,6 +282,20 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
|
|||||||
customPath: config.sessionCustomPath,
|
customPath: config.sessionCustomPath,
|
||||||
originalCommand: config.command,
|
originalCommand: config.command,
|
||||||
});
|
});
|
||||||
|
} else if (isWindows && agent?.path && !config.sessionSshRemoteConfig?.enabled) {
|
||||||
|
// On Windows LOCAL execution, use the full resolved agent path if it ends with .exe or .com
|
||||||
|
// This avoids ProcessManager setting shell:true for extensionless commands,
|
||||||
|
// which breaks stdin piping (needed for stream-json input mode)
|
||||||
|
// NOTE: Skip this for SSH sessions - SSH uses the remote agent path, not local
|
||||||
|
const pathExt = require('path').extname(agent.path).toLowerCase();
|
||||||
|
if (pathExt === '.exe' || pathExt === '.com') {
|
||||||
|
commandToSpawn = agent.path;
|
||||||
|
logger.debug(`Using full agent path on Windows to avoid shell wrapper`, LOG_CONTEXT, {
|
||||||
|
originalCommand: config.command,
|
||||||
|
resolvedPath: agent.path,
|
||||||
|
reason: 'stdin-reliability',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
@@ -271,10 +313,11 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
|
|||||||
toolType: config.toolType,
|
toolType: config.toolType,
|
||||||
isTerminal: config.toolType === 'terminal',
|
isTerminal: config.toolType === 'terminal',
|
||||||
hasSessionSshRemoteConfig: !!config.sessionSshRemoteConfig,
|
hasSessionSshRemoteConfig: !!config.sessionSshRemoteConfig,
|
||||||
willUseSsh: config.toolType !== 'terminal' && !!config.sessionSshRemoteConfig,
|
sshEnabled: config.sessionSshRemoteConfig?.enabled,
|
||||||
|
willUseSsh: config.toolType !== 'terminal' && config.sessionSshRemoteConfig?.enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (config.toolType !== 'terminal' && config.sessionSshRemoteConfig) {
|
if (config.toolType !== 'terminal' && config.sessionSshRemoteConfig?.enabled) {
|
||||||
// Session-level SSH config provided - resolve and use it
|
// Session-level SSH config provided - resolve and use it
|
||||||
logger.info(`Using session-level SSH config`, LOG_CONTEXT, {
|
logger.info(`Using session-level SSH config`, LOG_CONTEXT, {
|
||||||
sessionId: config.sessionId,
|
sessionId: config.sessionId,
|
||||||
|
|||||||
@@ -6325,8 +6325,8 @@ You are taking over this conversation. Based on the context above, provide a bri
|
|||||||
customArgs: activeSession.customArgs,
|
customArgs: activeSession.customArgs,
|
||||||
customEnvVars: activeSession.customEnvVars,
|
customEnvVars: activeSession.customEnvVars,
|
||||||
customModel: activeSession.customModel,
|
customModel: activeSession.customModel,
|
||||||
customContextWindow: activeSession.customContextWindow,
|
customContextWindow: activeSession.customContextWindow,,
|
||||||
sessionSshRemoteConfig: activeSession.sessionSshRemoteConfig,
|
sessionSshRemoteConfig: activeSession.sessionSshRemoteConfig,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -6507,7 +6507,8 @@ You are taking over this conversation. Based on the context above, provide a bri
|
|||||||
activeSession.name, // Session/project name
|
activeSession.name, // Session/project name
|
||||||
activeTab.id, // Tab ID for per-tab isolation
|
activeTab.id, // Tab ID for per-tab isolation
|
||||||
activeSession.id, // Session ID for playbook creation
|
activeSession.id, // Session ID for playbook creation
|
||||||
activeSession.autoRunFolderPath // User-configured Auto Run folder path (if set)
|
activeSession.autoRunFolderPath, // User-configured Auto Run folder path (if set)
|
||||||
|
activeSession.sessionSshRemoteConfig // SSH remote config for remote execution
|
||||||
);
|
);
|
||||||
|
|
||||||
// Rename the tab to "Wizard" immediately when wizard starts
|
// Rename the tab to "Wizard" immediately when wizard starts
|
||||||
@@ -6589,7 +6590,8 @@ You are taking over this conversation. Based on the context above, provide a bri
|
|||||||
activeSession.name,
|
activeSession.name,
|
||||||
newTab.id,
|
newTab.id,
|
||||||
activeSession.id,
|
activeSession.id,
|
||||||
activeSession.autoRunFolderPath // User-configured Auto Run folder path (if set)
|
activeSession.autoRunFolderPath, // User-configured Auto Run folder path (if set)
|
||||||
|
activeSession.sessionSshRemoteConfig // SSH remote config for remote execution
|
||||||
);
|
);
|
||||||
|
|
||||||
// Show a system log entry
|
// Show a system log entry
|
||||||
|
|||||||
@@ -1098,8 +1098,8 @@ class PhaseGenerator {
|
|||||||
agentCommand: agent.command,
|
agentCommand: agent.command,
|
||||||
argsCount: argsForSpawn.length,
|
argsCount: argsForSpawn.length,
|
||||||
promptLength: prompt.length,
|
promptLength: prompt.length,
|
||||||
hasRemoteSsh: !!config.sessionSshRemoteConfig?.enabled,
|
hasRemoteSsh: !!config.sshRemoteConfig?.enabled,
|
||||||
remoteId: config.sessionSshRemoteConfig?.remoteId || null,
|
remoteId: config.sshRemoteConfig?.remoteId || null,
|
||||||
});
|
});
|
||||||
window.maestro.process
|
window.maestro.process
|
||||||
.spawn({
|
.spawn({
|
||||||
|
|||||||
1
src/renderer/global.d.ts
vendored
1
src/renderer/global.d.ts
vendored
@@ -80,6 +80,7 @@ interface AgentConfig {
|
|||||||
binaryName?: string;
|
binaryName?: string;
|
||||||
available: boolean;
|
available: boolean;
|
||||||
path?: string;
|
path?: string;
|
||||||
|
customPath?: string;
|
||||||
command: string;
|
command: string;
|
||||||
args?: string[];
|
args?: string[];
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
|
|||||||
@@ -143,6 +143,12 @@ export interface InlineWizardState {
|
|||||||
subfolderPath: string | null;
|
subfolderPath: string | null;
|
||||||
/** User-configured Auto Run folder path (overrides default projectPath/Auto Run Docs) */
|
/** User-configured Auto Run folder path (overrides default projectPath/Auto Run Docs) */
|
||||||
autoRunFolderPath: string | null;
|
autoRunFolderPath: string | null;
|
||||||
|
/** SSH remote configuration (for remote execution) */
|
||||||
|
sessionSshRemoteConfig?: {
|
||||||
|
enabled: boolean;
|
||||||
|
remoteId: string | null;
|
||||||
|
workingDirOverride?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,6 +205,7 @@ export interface UseInlineWizardReturn {
|
|||||||
* @param tabId - The tab ID to associate the wizard with
|
* @param tabId - The tab ID to associate the wizard with
|
||||||
* @param sessionId - The session ID for playbook creation
|
* @param sessionId - The session ID for playbook creation
|
||||||
* @param autoRunFolderPath - User-configured Auto Run folder path (if set, overrides default projectPath/Auto Run Docs)
|
* @param autoRunFolderPath - User-configured Auto Run folder path (if set, overrides default projectPath/Auto Run Docs)
|
||||||
|
* @param sessionSshRemoteConfig - SSH remote configuration (for remote execution)
|
||||||
*/
|
*/
|
||||||
startWizard: (
|
startWizard: (
|
||||||
naturalLanguageInput?: string,
|
naturalLanguageInput?: string,
|
||||||
@@ -208,7 +215,12 @@ export interface UseInlineWizardReturn {
|
|||||||
sessionName?: string,
|
sessionName?: string,
|
||||||
tabId?: string,
|
tabId?: string,
|
||||||
sessionId?: string,
|
sessionId?: string,
|
||||||
autoRunFolderPath?: string
|
autoRunFolderPath?: string,
|
||||||
|
sessionSshRemoteConfig?: {
|
||||||
|
enabled: boolean;
|
||||||
|
remoteId: string | null;
|
||||||
|
workingDirOverride?: string;
|
||||||
|
}
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
/** End the wizard and restore previous UI state */
|
/** End the wizard and restore previous UI state */
|
||||||
endWizard: () => Promise<PreviousUIState | null>;
|
endWizard: () => Promise<PreviousUIState | null>;
|
||||||
@@ -450,7 +462,12 @@ export function useInlineWizard(): UseInlineWizardReturn {
|
|||||||
sessionName?: string,
|
sessionName?: string,
|
||||||
tabId?: string,
|
tabId?: string,
|
||||||
sessionId?: string,
|
sessionId?: string,
|
||||||
configuredAutoRunFolderPath?: string
|
configuredAutoRunFolderPath?: string,
|
||||||
|
sessionSshRemoteConfig?: {
|
||||||
|
enabled: boolean;
|
||||||
|
remoteId: string | null;
|
||||||
|
workingDirOverride?: string;
|
||||||
|
}
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
// Tab ID is required for per-tab wizard management
|
// Tab ID is required for per-tab wizard management
|
||||||
const effectiveTabId = tabId || 'default';
|
const effectiveTabId = tabId || 'default';
|
||||||
@@ -506,6 +523,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
|
|||||||
subfolderName: null,
|
subfolderName: null,
|
||||||
subfolderPath: null,
|
subfolderPath: null,
|
||||||
autoRunFolderPath: effectiveAutoRunFolderPath,
|
autoRunFolderPath: effectiveAutoRunFolderPath,
|
||||||
|
sessionSshRemoteConfig,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -574,6 +592,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
|
|||||||
goal: goal || undefined,
|
goal: goal || undefined,
|
||||||
existingDocs: docsWithContent.length > 0 ? docsWithContent : undefined,
|
existingDocs: docsWithContent.length > 0 ? docsWithContent : undefined,
|
||||||
autoRunFolderPath: effectiveAutoRunFolderPath,
|
autoRunFolderPath: effectiveAutoRunFolderPath,
|
||||||
|
sessionSshRemoteConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Store conversation session per-tab
|
// Store conversation session per-tab
|
||||||
@@ -708,6 +727,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
|
|||||||
goal: currentState.goal || undefined,
|
goal: currentState.goal || undefined,
|
||||||
existingDocs: undefined,
|
existingDocs: undefined,
|
||||||
autoRunFolderPath: effectiveAutoRunFolderPath,
|
autoRunFolderPath: effectiveAutoRunFolderPath,
|
||||||
|
sessionSshRemoteConfig: currentState.sessionSshRemoteConfig,
|
||||||
});
|
});
|
||||||
conversationSessionsMap.current.set(tabId, session);
|
conversationSessionsMap.current.set(tabId, session);
|
||||||
// Update mode to 'new' since we're proceeding with a new plan
|
// Update mode to 'new' since we're proceeding with a new plan
|
||||||
@@ -888,6 +908,7 @@ export function useInlineWizard(): UseInlineWizardReturn {
|
|||||||
goal: currentState.goal || undefined,
|
goal: currentState.goal || undefined,
|
||||||
existingDocs: undefined, // Will be loaded separately if needed
|
existingDocs: undefined, // Will be loaded separately if needed
|
||||||
autoRunFolderPath: effectiveAutoRunFolderPath,
|
autoRunFolderPath: effectiveAutoRunFolderPath,
|
||||||
|
sessionSshRemoteConfig: currentState.sessionSshRemoteConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
conversationSessionsMap.current.set(tabId, session);
|
conversationSessionsMap.current.set(tabId, session);
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ export interface InlineWizardConversationConfig {
|
|||||||
existingDocs?: ExistingDocument[];
|
existingDocs?: ExistingDocument[];
|
||||||
/** Auto Run folder path */
|
/** Auto Run folder path */
|
||||||
autoRunFolderPath?: string;
|
autoRunFolderPath?: string;
|
||||||
|
/** SSH remote configuration (for remote execution) */
|
||||||
|
sessionSshRemoteConfig?: {
|
||||||
|
enabled: boolean;
|
||||||
|
remoteId: string | null;
|
||||||
|
workingDirOverride?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,6 +114,12 @@ export interface InlineWizardConversationSession {
|
|||||||
systemPrompt: string;
|
systemPrompt: string;
|
||||||
/** Whether the session is active */
|
/** Whether the session is active */
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
|
/** SSH remote configuration (for remote execution) */
|
||||||
|
sessionSshRemoteConfig?: {
|
||||||
|
enabled: boolean;
|
||||||
|
remoteId: string | null;
|
||||||
|
workingDirOverride?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -250,6 +262,8 @@ export function startInlineWizardConversation(
|
|||||||
projectName: config.projectName,
|
projectName: config.projectName,
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
// Only pass SSH config if it is explicitly enabled to prevent false positives in process manager
|
||||||
|
sessionSshRemoteConfig: config.sessionSshRemoteConfig?.enabled ? config.sessionSshRemoteConfig : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,6 +453,7 @@ function buildArgsForAgent(agent: any): string[] {
|
|||||||
// The agent can read files to understand the project, but cannot write/edit
|
// The agent can read files to understand the project, but cannot write/edit
|
||||||
// This ensures the wizard conversation phase doesn't make code changes
|
// This ensures the wizard conversation phase doesn't make code changes
|
||||||
if (!args.includes('--allowedTools')) {
|
if (!args.includes('--allowedTools')) {
|
||||||
|
// Split tools into separate arguments for better cross-platform compatibility (especially Windows)
|
||||||
args.push('--allowedTools', 'Read', 'Glob', 'Grep', 'LS');
|
args.push('--allowedTools', 'Read', 'Glob', 'Grep', 'LS');
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
@@ -648,6 +663,8 @@ export async function sendWizardMessage(
|
|||||||
command: agent.command,
|
command: agent.command,
|
||||||
args: argsForSpawn,
|
args: argsForSpawn,
|
||||||
prompt: fullPrompt,
|
prompt: fullPrompt,
|
||||||
|
// Pass SSH config for remote execution
|
||||||
|
sessionSshRemoteConfig: session.sessionSshRemoteConfig,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
callbacks?.onReceiving?.();
|
callbacks?.onReceiving?.();
|
||||||
|
|||||||
Reference in New Issue
Block a user