added Maestro Symphony Registration Manifest

This commit is contained in:
Pedram Amini
2026-01-08 06:12:13 -06:00
parent f30d57a28d
commit c862ca5a11
3 changed files with 70 additions and 5 deletions

View File

@@ -1130,6 +1130,47 @@ describe('process IPC handlers', () => {
expect(remoteCommandArg).not.toContain('/opt/homebrew/bin/codex');
});
it('should use sessionCustomPath for SSH remote when user specifies a custom path', async () => {
// When user sets a custom path for a session, that path should be used on the remote
// This allows users to specify the exact binary location on the remote host
const mockAgent = {
id: 'codex',
name: 'Codex',
binaryName: 'codex',
path: '/opt/homebrew/bin/codex', // Local path
requiresPty: false,
};
mockAgentDetector.getAgent.mockResolvedValue(mockAgent);
mockSettingsStore.get.mockImplementation((key, defaultValue) => {
if (key === 'sshRemotes') return [mockSshRemote];
return defaultValue;
});
mockProcessManager.spawn.mockReturnValue({ pid: 12345, success: true });
const handler = handlers.get('process:spawn');
await handler!({} as any, {
sessionId: 'session-1',
toolType: 'codex',
cwd: '/home/devuser/project',
command: '/opt/homebrew/bin/codex',
args: ['exec', '--json'],
sessionCustomPath: '/usr/local/bin/codex', // User's custom path for the remote
sessionSshRemoteConfig: {
enabled: true,
remoteId: 'remote-1',
},
});
const spawnCall = mockProcessManager.spawn.mock.calls[0][0];
expect(spawnCall.command).toBe('ssh');
// Should use the custom path, not binaryName or local path
const remoteCommandArg = spawnCall.args[spawnCall.args.length - 1];
expect(remoteCommandArg).toContain("'/usr/local/bin/codex'");
expect(remoteCommandArg).not.toContain('/opt/homebrew/bin/codex');
});
it('should fall back to config.command when agent.binaryName is not available', async () => {
// Edge case: if agent lookup fails or binaryName is undefined, fall back to command
mockAgentDetector.getAgent.mockResolvedValue(null); // Agent not found

View File

@@ -268,11 +268,12 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
// The cwd is the local project path which may not exist on remote
// Remote should use remoteWorkingDir from SSH config if set
//
// IMPORTANT: For remote execution, use the agent's binaryName (e.g., 'codex', 'claude')
// instead of the locally detected full path (e.g., '/opt/homebrew/bin/codex').
// The remote shell's PATH will resolve the binary correctly. This fixes the issue
// where Maestro would try to execute a local macOS path on a remote Linux host.
const remoteCommand = agent?.binaryName || config.command;
// Determine the command to run on the remote host:
// 1. If user set a session-specific custom path, use that (they configured it for the remote)
// 2. Otherwise, use the agent's binaryName (e.g., 'codex', 'claude') and let
// the remote shell's PATH resolve it. This avoids using local paths like
// '/opt/homebrew/bin/codex' which don't exist on the remote host.
const remoteCommand = config.sessionCustomPath || agent?.binaryName || config.command;
const sshCommand = await buildSshCommand(sshResult.config, {
command: remoteCommand,
args: sshArgs,
@@ -294,6 +295,8 @@ export function registerProcessHandlers(deps: ProcessHandlerDependencies): void
source: sshResult.source,
localCommand: config.command,
remoteCommand: remoteCommand,
customPath: config.sessionCustomPath || null,
hasCustomEnvVars: !!effectiveCustomEnvVars && Object.keys(effectiveCustomEnvVars).length > 0,
sshCommand: `${sshCommand.command} ${sshCommand.args.join(' ')}`,
});
}

21
symphony-registry.json Normal file
View File

@@ -0,0 +1,21 @@
{
"schemaVersion": "1.0",
"lastUpdated": "2025-01-01T00:00:00Z",
"repositories": [
{
"slug": "pedramamini/Maestro",
"name": "Maestro",
"description": "Desktop app for managing multiple AI coding assistants with a keyboard-first interface.",
"url": "https://github.com/pedramamini/Maestro",
"category": "developer-tools",
"tags": ["electron", "ai", "productivity", "typescript"],
"maintainer": {
"name": "Pedram Amini",
"url": "https://github.com/pedramamini"
},
"isActive": true,
"featured": true,
"addedAt": "2025-01-01"
}
]
}