Replace output.args.command and output.args.prompt direct assignments
with replaceToolArgs() in non-interactive-env, prometheus-md-only,
and sisyphus-junior-notepad hooks.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Closes#3607.
## Root cause
On Windows, `detectCommandShellType()` fell through to `detectShellType()`
for two common environments and incorrectly returned `"unix"`:
1. **SHELL points at a Unix-shaped path** (e.g. Git Bash sets
`SHELL=/usr/bin/bash` on a fresh Windows install).
The `detectWindowsShellType(process.env.SHELL)` probe didn't recognize
`bash` as a Windows shell, so the function fell through and
`detectShellType()` returned `"unix"`.
2. **MSYSTEM is set but SHELL is not** (Git Bash leaves MSYSTEM permanently
set system-wide even when the active shell is PowerShell).
The fall-through path returned `"unix"` via the MSYSTEM check.
In both cases, the hook then prepended `export KEY=val;` to git commands,
which PowerShell rejects with:
`export : 无法将"export"项识别为 cmdlet...`
OpenCode on Windows runs the bash tool through a Windows shell
(PowerShell by default, cmd as the user-overridable fallback), regardless
of MSYSTEM or a Unix-shaped SHELL set by Git Bash — so the env prefix
must use Windows-compatible syntax.
## Fix
`detectCommandShellType()` now short-circuits on `process.platform === "win32"`:
- If `SHELL` points at a recognized Windows shell (`cmd.exe`, `powershell.exe`,
`pwsh.exe`), return that.
- If `SHELL` and `MSYSTEM` are both unset, fall back to `ComSpec` then to cmd.
- Otherwise, default to PowerShell — matching what OpenCode actually spawns.
`detectShellType()` is unchanged; other callers (including non-Windows
platforms) are unaffected.
## Test changes
Three pre-existing tests encoded the buggy behavior as expected behavior
and have been updated to assert the new PowerShell syntax with a
`(#3607)` marker and a comment explaining why a Unix-shaped SHELL on
win32 must still resolve to PowerShell. WSL is not affected because in
WSL `process.platform === "linux"`, not `"win32"`.
- `src/hooks/non-interactive-env/`: 24 tests pass / 0 fail
- `bunx tsc --noEmit`: clean
## Note on issue thread
The sisyphus-bot triage comment on #3607 framed this as a policy choice
between (A) forcing Windows env-prefix syntax and (B) resolving against
the OpenCode-configured shell. This PR implements option (A) as the
minimal surgical fix; option (B) remains a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hardcoded platform check forced PowerShell env syntax on Windows
regardless of the actual shell. Replaced with detectShellType() so
Git Bash, WSL, and similar environments use unix prefixes while
native PowerShell continues to get powershell prefixes.
🤖 Generated with OhMyOpenCode assistance
https://github.com/code-yeongyu/oh-my-opencode
The non-interactive-env hook hardcoded shellType as 'unix', causing
'export' syntax to be used on Windows PowerShell where it doesn't work.
This caused sub-agent infinite loops on Windows as git commands would
fail with 'export: The term export is not recognized' and retry forever.
Fix: use the existing detectShellType() function which correctly detects
PowerShell (via PSModulePath), csh, cmd (win32 fallback), and unix shells.
Updated tests to verify platform-aware shell syntax selection.
Closes#3000
The non-interactive-env hook was prepending environment variables without checking
if the prefix was already applied to the command, causing duplication when multiple
git commands were executed in sequence.
This fix adds an idempotent check: if the command already starts with the env prefix,
the hook returns early without modification. This maintains the non-interactive behavior
while ensuring the operation is idempotent across multiple tool executions.