fix(maestro): resolve command wrappers with a shell-aware tokenizer (#199)
command_program/command_tool whitespace-split and only skipped whole wrapper words, so quoted paths broke, sudo -u/env -i/nohup/time/npx --yes/pnpm|yarn --silent dlx/bun x were rejected, and pnpm claude / yarn claude (a package.json script, not `dlx claude`) resolved as a Claude launch. Replace it with a tokenizer that honours quoting and escaping without evaluating any expansion, and per-wrapper option tables (env, sudo, command, nohup, time, npx, pnpm, yarn, bun) that require dlx/x before looking through a package-manager wrapper. Ambiguous shell grammar (pipelines, list operators, redirections, substitution, unterminated quotes) is rejected outright rather than guessed through; command_program still degrades to the naive first word for display, but command_tool returns None. Mirror the same resolver in web/src/toolIcon.ts and add fixtures/command-resolution.json as a parity fixture both test suites assert against.
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { splitCommand, toolIconSvg } from "./toolIcon.js";
|
||||
import commandResolutionFixture from "../../fixtures/command-resolution.json";
|
||||
|
||||
interface CommandResolutionCase {
|
||||
command: string;
|
||||
program: string;
|
||||
tool: string | null;
|
||||
}
|
||||
|
||||
describe("tool icons on the command fragment (docs/SIDEBAR.md)", () => {
|
||||
it("recognises the agents and shells sessions are spawned with", () => {
|
||||
@@ -46,6 +53,14 @@ describe("tool icons on the command fragment (docs/SIDEBAR.md)", () => {
|
||||
expect(splitCommand("").tool).toBeNull();
|
||||
});
|
||||
|
||||
it("resolves every case in the shared command-resolution fixture (#199)", () => {
|
||||
const cases = commandResolutionFixture.cases as CommandResolutionCase[];
|
||||
expect(cases.length).toBeGreaterThan(0);
|
||||
for (const { command, program, tool } of cases) {
|
||||
expect(splitCommand(command), command).toEqual({ tool, program });
|
||||
}
|
||||
});
|
||||
|
||||
it("gives every recognised tool a labelled mark", () => {
|
||||
for (const tool of ["claude", "codex", "opencode", "gemini", "aider", "cursor", "pi", "shell"]) {
|
||||
const svg = toolIconSvg(tool);
|
||||
|
||||
Reference in New Issue
Block a user