From f115981a86191ad189de41308de05a011d5dc298 Mon Sep 17 00:00:00 2001 From: Monalisa Biswal Date: Mon, 12 Oct 2026 18:40:34 -0400 Subject: [PATCH] fix: tell agents to quote the exec separator and avoid cmd /c In Windows PowerShell an unquoted -- is dropped, so fixlab exec printed usage and agents fell back to a cmd /c wrapper that non-interactive sessions deny. Update agent guidance, the dashboard prompt and troubleshooting docs, and add a hint to the usage error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: aa2b2938-9ca6-4b67-a11a-f131b554d603 --- .github/agents/fixlab-autofix.agent.md | 5 ++++- agents/fixlab.md | 5 ++++- bin/structured-command.js | 3 ++- com.github.copilot/agents/fixlab.agent.md | 5 ++++- dashboard/server.js | 2 +- docs/troubleshooting.md | 9 +++++++++ templates/fixlab-autofix.agent.md | 5 ++++- test/dashboard-server.test.js | 1 + test/structured-command.test.js | 6 +++++- 9 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.github/agents/fixlab-autofix.agent.md b/.github/agents/fixlab-autofix.agent.md index 342d110..204ee66 100644 --- a/.github/agents/fixlab-autofix.agent.md +++ b/.github/agents/fixlab-autofix.agent.md @@ -75,7 +75,10 @@ only for information that cannot be established safely from the repository. or create a pull request unless the developer explicitly requests it. Run verbose repository-owned tests, builds, linters, type checks, and package -validation through `fixlab exec --stage -- [args...]`. Keep +validation through `fixlab exec --stage -- [args...]`. In +Windows PowerShell write the separator quoted (`'--'`) because an unquoted `--` +is dropped, and never wrap `fixlab exec` in `cmd /c`; that wrapper is denied in +non-interactive sessions. Keep the compact result in context and inspect its private evidence only when an exact diagnostic is needed. Use `--reuse` only for deterministic local validation with identical command and repository state. Never reuse startup, diff --git a/agents/fixlab.md b/agents/fixlab.md index b440615..d26a326 100644 --- a/agents/fixlab.md +++ b/agents/fixlab.md @@ -51,7 +51,10 @@ instructions provide authoritative commands. 10. Present evidence, skipped gates, and remaining risks. Run verbose repository-owned tests, builds, linters, type checks, and package -validation through `fixlab exec --stage -- [args...]`. Use +validation through `fixlab exec --stage -- [args...]`. In +Windows PowerShell write the separator quoted (`'--'`) because an unquoted `--` +is dropped, and never wrap `fixlab exec` in `cmd /c`; that wrapper is denied in +non-interactive sessions. Use its compact result in agent context and refer to the private evidence path only when an exact diagnostic is needed. Add `--reuse` only for deterministic local validation when the command, arguments, Git state, working directory, profile, diff --git a/bin/structured-command.js b/bin/structured-command.js index d982ac5..5b39a87 100644 --- a/bin/structured-command.js +++ b/bin/structured-command.js @@ -284,7 +284,8 @@ export function parseStructuredCommandArguments( const separator = args.indexOf("--"); if (separator < 0 || separator === args.length - 1) { throw new Error( - "usage: fixlab exec [repository] [--cwd ] [--stage ] [--reuse] [--timeout-seconds ] -- [args...]" + "usage: fixlab exec [repository] [--cwd ] [--stage ] [--reuse] [--timeout-seconds ] -- [args...]\n" + + "hint: in Windows PowerShell an unquoted -- is dropped; write '--' (quoted) and do not wrap the command in cmd /c." ); } diff --git a/com.github.copilot/agents/fixlab.agent.md b/com.github.copilot/agents/fixlab.agent.md index b440615..d26a326 100644 --- a/com.github.copilot/agents/fixlab.agent.md +++ b/com.github.copilot/agents/fixlab.agent.md @@ -51,7 +51,10 @@ instructions provide authoritative commands. 10. Present evidence, skipped gates, and remaining risks. Run verbose repository-owned tests, builds, linters, type checks, and package -validation through `fixlab exec --stage -- [args...]`. Use +validation through `fixlab exec --stage -- [args...]`. In +Windows PowerShell write the separator quoted (`'--'`) because an unquoted `--` +is dropped, and never wrap `fixlab exec` in `cmd /c`; that wrapper is denied in +non-interactive sessions. Use its compact result in agent context and refer to the private evidence path only when an exact diagnostic is needed. Add `--reuse` only for deterministic local validation when the command, arguments, Git state, working directory, profile, diff --git a/dashboard/server.js b/dashboard/server.js index 5237a6b..e3942d5 100644 --- a/dashboard/server.js +++ b/dashboard/server.js @@ -859,7 +859,7 @@ ${branchNamingGuidance} - Autonomously complete the lifecycle without asking the user to direct routine engineering steps. - ${playwrightOnly ? "Skip source diagnosis, separate reproduction, implementation, diff review, and non-browser validation. Mark diagnosis, reproduce, fix, and review skipped with the reason Playwright-only mode was selected." : "Inspect the affected surface, implement the smallest required code when edits are allowed, and self-review the effective diff for correctness, scope, and unrelated changes."} - ${playwrightOnly ? "Run only setup commands strictly required to launch the profile-defined applications and focused Playwright journey. Do not reinstall dependencies that are already available." : "Run the focused repository-owned tests, type-checks, and builds needed for the affected surface and risk. Preserve exact results."} -- Run verbose repository-owned tests, builds, linters, type checks, and package validation through \`fixlab exec --stage -- [args...]\`. Keep its compact result in context and inspect the private evidence path only when an exact diagnostic is needed. +- Run verbose repository-owned tests, builds, linters, type checks, and package validation through \`fixlab exec --stage -- [args...]\`. In Windows PowerShell quote the separator (\`'--'\`) because an unquoted \`--\` is dropped, and never wrap \`fixlab exec\` in \`cmd /c\`; that wrapper is denied in non-interactive sessions. Keep its compact result in context and inspect the private evidence path only when an exact diagnostic is needed. - Add \`--reuse\` only for deterministic local validation when command, arguments, Git state, working directory, profile, and stage are unchanged. Never reuse startup, health, authentication, Playwright or live-environment validation, external-data checks, dependency installation, deployments, or mutating commands. - Do not skip Playwright merely because an unrelated non-browser test, build, or backend startup is failed or blocked. If frontend startup, authentication, safe data, and the selected browser journey are independently ready, run the live-test gate and preserve the other blocker separately. - Use local-stack only for profile-defined application startup and health. Do not mark local-stack failed because a separate test, type-check, lint, or production build reports unrelated baseline diagnostics; preserve that exact validation limitation separately and continue browser execution when startup is healthy. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index e3fcb68..0c63df3 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -12,6 +12,15 @@ repository: fixlab exec --cwd .\frontend --stage test -- npm test ``` +In Windows PowerShell an unquoted `--` is dropped, so `fixlab exec` prints its +usage text instead of running. Quote the separator (`'--'`). Do not wrap the +command in `cmd /c`: the wrapper is denied when no interactive user can approve +it, which blocks the job. + +```powershell +fixlab exec --cwd .\frontend --stage test '--' npm test +``` + The `Evidence:` path is Git-private and contains redacted `stdout.log`, `stderr.log`, and `result.json`. A missing stream file means that stream was empty. The terminal `Context:` line and `result.json.context` report raw and diff --git a/templates/fixlab-autofix.agent.md b/templates/fixlab-autofix.agent.md index 342d110..204ee66 100644 --- a/templates/fixlab-autofix.agent.md +++ b/templates/fixlab-autofix.agent.md @@ -75,7 +75,10 @@ only for information that cannot be established safely from the repository. or create a pull request unless the developer explicitly requests it. Run verbose repository-owned tests, builds, linters, type checks, and package -validation through `fixlab exec --stage -- [args...]`. Keep +validation through `fixlab exec --stage -- [args...]`. In +Windows PowerShell write the separator quoted (`'--'`) because an unquoted `--` +is dropped, and never wrap `fixlab exec` in `cmd /c`; that wrapper is denied in +non-interactive sessions. Keep the compact result in context and inspect its private evidence only when an exact diagnostic is needed. Use `--reuse` only for deterministic local validation with identical command and repository state. Never reuse startup, diff --git a/test/dashboard-server.test.js b/test/dashboard-server.test.js index f4af521..0fa2837 100644 --- a/test/dashboard-server.test.js +++ b/test/dashboard-server.test.js @@ -1171,6 +1171,7 @@ test("dashboard parses complete stage markers and passes a job", async () => { assert.match(receivedPrompt, /commit changes and repository-profile or instruction changes as invalidation boundaries/i); assert.match(receivedPrompt, /do not feed unbounded raw output back into prompts/i); assert.match(receivedPrompt, /fixlab exec --stage /i); + assert.match(receivedPrompt, /never wrap `fixlab exec` in `cmd \/c`/u); assert.match(receivedPrompt, /Never reuse startup, health, authentication/i); assert.match(receivedPrompt, /FIXLAB_STAGE\|stage\|status\|message/); assert.match(receivedPrompt, /FIXLAB_BUG\|id\|outcome\|owner\|summary/); diff --git a/test/structured-command.test.js b/test/structured-command.test.js index 8dad61c..f2ba8bc 100644 --- a/test/structured-command.test.js +++ b/test/structured-command.test.js @@ -318,7 +318,11 @@ test("structured command arguments enforce repository containment", () => { ); assert.throws( () => parseStructuredCommandArguments([repository, process.execPath]), - /usage: fixlab exec/ + /usage: fixlab exec[\s\S]*quoted/u + ); + assert.throws( + () => parseStructuredCommandArguments([repository, process.execPath]), + /do not wrap the command in cmd \/c/u ); assert.throws( () =>