Files
multica/server
Jiang Bohan 8ca87bd5ff refactor(execenv): scope MUST-stdin mandate back to Codex-only
Followup to #2247: roll back the over-spread of #1795 / #1851. Both PRs
were intended to fix Codex's habit of emitting literal `\n` inside
`--content "..."` (MUL-1467), but the implementation landed strong
"MUST pipe via stdin" / `--description-stdin` directives in the
all-provider Available Commands section AND in the provider-agnostic
`BuildCommentReplyInstructions` helper. That global mandate then broke
non-ASCII bytes for every provider on Windows shells (#2198 / #2236),
because PowerShell 5.1 / cmd.exe re-encode piped HEREDOC bytes through
the active console codepage and silently drop non-representable bytes
as `?`.

Three concrete changes:

- `runtime_config.go` Available Commands: replace the platform-branched
  "MUST pipe via stdin" block with a neutral three-line description of
  the three input modes (`--content`, `--content-stdin`,
  `--content-file`). Same text on every host, no GOOS branch. The
  `--content-file` line still flags the Windows-shell-codepage caveat
  in passing so an agent that picks stdin and lands on Win11 has a
  pointer to file as the safe fallback, but no provider gets a "MUST"
  here anymore.

- `BuildCommentReplyInstructions`: add a `provider` parameter. Codex
  keeps the platform-aware mandate (Windows → file, non-Windows →
  stdin/HEREDOC) — the original MUL-1467 fix lives where it belongs.
  Every other provider gets the lightweight pre-#1795 inline template
  (`--content "..."` with a pointer to stdin/file for richer
  formatting); the CLI's `util.UnescapeBackslashEscapes` still decodes
  `\n` server-side so multi-line inline works on every platform, and
  argv goes through CreateProcessW UTF-16 on Windows so non-ASCII
  survives.

- Plumbing: thread `provider` through `BuildPrompt` →
  `buildCommentPrompt` → `execenv.BuildCommentReplyInstructions`. Sole
  caller is `daemon.runTask`, where `provider` is already in scope.

Test rework:

- `TestInjectRuntimeConfigDirectsMultiLineWritesToStdin` is replaced by
  `TestInjectRuntimeConfigAvailableCommandsIsNeutral`, which sweeps every
  non-Codex provider × every host OS and pins (a) the three-mode menu is
  present, (b) the over-spread substrings (`MUST pipe via stdin`,
  `Agent-authored comments should always pipe content via stdin`,
  `use --description-stdin and pipe a HEREDOC`) are GONE.
- `TestInjectRuntimeConfigWindowsRecommendsContentFile` becomes
  `TestInjectRuntimeConfigCodexWindowsRecommendsContentFile`, scoped to
  the Codex section. Linux Codex still pins `always use --content-stdin
  with a HEREDOC` so the original MUL-1467 protection isn't dropped.
- `TestBuildCommentReplyInstructionsIncludesTriggerID` becomes
  `TestBuildCommentReplyInstructionsCodexLinux` (codex/linux still gets
  stdin) plus a new
  `TestBuildCommentReplyInstructionsNonCodexUsesInline` that sweeps
  claude / opencode / openclaw / hermes / kimi / kiro / cursor / gemini
  on linux / darwin / windows and pins the inline template, with a ban
  on the codex-specific stdin/file substrings.
- `TestBuildCommentReplyInstructionsCodexWindowsUsesContentFile` and
  `TestInjectRuntimeConfigCodexWindowsCommentTriggerHasNoStdin` keep
  the Windows file-first end-to-end pin for codex.
- `BuildPrompt` callers in daemon_test.go updated for the new
  `provider` arg.

Net effect: Windows non-Codex agents (Claude / Opencode / Hermes /
etc.) on Win11 stop getting steered at the broken stdin path entirely;
Codex on Windows stays on `--content-file`; Codex on Linux/macOS keeps
its MUL-1467 protection; every other provider's CLAUDE.md / AGENTS.md
loses the "MUST stdin" mandate it never needed.

Co-authored-by: multica-agent <github@multica.ai>
2026-05-08 16:08:45 +08:00
..