Commit Graph

5 Commits

Author SHA1 Message Date
Bohan Jiang
d964d37f97 Revert "fix(cli): add --content-file / --description-file for non-ASCII on Wi…" (#2252)
This reverts commit 9650788709.
2026-05-08 12:04:03 +08:00
Bohan Jiang
9650788709 fix(cli): add --content-file / --description-file for non-ASCII on Windows (#2247)
* fix(cli): add --content-file / --description-file for non-ASCII on Windows

Windows PowerShell 5.1 (the Win11 default) and cmd.exe re-encode HEREDOC
content through the active console codepage before piping it to a child
process. Characters the codepage cannot represent are silently replaced
with `?`, so agents on Chinese Win11 hosts emitting `--content-stdin` /
`--description-stdin` HEREDOCs land all of their Chinese as `?` in the
issue body and comments. The daemon log shows the original Chinese
correctly because slog writes to a file directly, so the regression
hides until the user opens the issue page.

Add a `--content-file <path>` / `--description-file <path>` source to
`resolveTextFlag`: the CLI reads the file straight off disk, preserves
UTF-8 bytes verbatim, and skips the shell entirely. The runtime config
injected into AGENTS.md / CLAUDE.md now surfaces this as the canonical
Windows fallback when the daemon host runs on Windows; non-Windows hosts
keep the existing stdin/HEREDOC guidance untouched.

Closes #2198, #2236.

Co-authored-by: multica-agent <github@multica.ai>

* fix(execenv): route every Windows-host stdin directive at --content-file

GPT-Boy on PR #2247 caught that the previous patch only inserted a Windows
fallback into the Available Commands section. Two later prompt surfaces
still hard-coded `--content-stdin` and overrode it for the agent:

- The Codex-specific paragraph in `buildMetaSkillContent`, which always
  said "always use `--content-stdin` with a HEREDOC".
- `BuildCommentReplyInstructions`, which is re-emitted on every turn for
  comment-triggered tasks (both via the AGENTS.md/CLAUDE.md workflow and
  the daemon's per-turn prompt) and mandated the same HEREDOC pipe.

On Windows hosts we now branch both surfaces to a file-based template:
the agent writes the body to a UTF-8 file with its file-write tool and
posts via `--content-file <path>`. Non-Windows hosts keep the existing
stdin/HEREDOC guidance untouched.

Tests:

- `TestBuildCommentReplyInstructionsWindowsUsesContentFile` pins the
  Windows / non-Windows reply-instruction text directly.
- `TestInjectRuntimeConfigWindowsCommentTriggerHasNoStdin` asserts that
  the end-to-end CLAUDE.md / AGENTS.md surface for a comment-triggered
  Windows task has no remaining `--content-stdin` directive that could
  override the Windows fallback (covers Claude + Codex providers).

Co-authored-by: multica-agent <github@multica.ai>

* fix(execenv): make Windows comment block file-first, pin tests by GOOS

GPT-Boy's second review on PR #2247 flagged two follow-up blockers:

1. The Windows comment/description block in `buildMetaSkillContent` was
   "stdin first, file caveat appended" — agents on Windows still saw
   "Agent-authored comments should always pipe content via stdin" /
   "MUST pipe via stdin" / `--description-stdin` directives before
   reaching the Windows fallback, so the contradicting instruction was
   live in the same prompt. Rewrite the entire Available Commands
   bullet for Windows hosts as file-first: the headline line names
   `--content-file`, the bulleted rules name `--content-file` /
   `--description-file`, and stdin only appears in anti-prescriptive
   "do NOT pipe via …" prose.

2. The existing non-Windows tests (TestBuildCommentReplyInstructions
   IncludesTriggerID, TestInjectRuntimeConfigDirectsMultiLineWritesToStdin,
   TestInjectRuntimeConfigCodexEmphasizesStdinForFormattedComments,
   TestInjectRuntimeConfigCommentTriggerUsesHelper) all depended on
   `runtimeGOOS` defaulting to non-Windows; they would silently fail on
   a Windows test runner. Pin them to `runtimeGOOS = "linux"` via
   save+restore and drop t.Parallel so they don't race with the
   GOOS-mutating Windows tests.

Test additions:

- TestInjectRuntimeConfigWindowsRecommendsContentFile now asserts the
  Windows AGENTS.md does NOT contain prescriptive stdin phrasings
  (`MUST pipe via stdin`, `use --description-stdin and pipe a HEREDOC`,
  `<<'COMMENT'`, `Agent-authored comments should always pipe content via
  stdin`, `always use --content-stdin`) on top of the file-first
  positive assertions. The ban list pins prescriptive substrings, not
  bare flag names, so anti-prescriptive prose like "do NOT pipe via
  --content-stdin" doesn't trip the ban.
- TestInjectRuntimeConfigWindowsCommentTriggerHasNoStdin gets the same
  expanded ban list across the Available Commands, Codex paragraph,
  and per-turn reply template surfaces.
- The non-Windows side of TestInjectRuntimeConfigWindowsRecommendsContentFile
  pins that the Linux stdin/HEREDOC contract is still in place, so a
  future refactor can't accidentally move every host to file-first.

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: multica-agent <github@multica.ai>
2026-05-08 12:01:19 +08:00
devv-eve
365e84b920 fix(execenv): prefer stdin for formatted comment replies (#1851)
Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
2026-04-29 17:12:04 +08:00
devv-eve
9587a577e2 fix: guide codex multiline comments (#1795)
Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
2026-04-28 19:33:45 +08:00
Bohan Jiang
951f51408a fix(agent/comments): prevent resumed sessions from reusing stale --parent UUID (#1374)
* fix(agent/comments): re-emit trigger comment id every turn + server-side parent_id guard

Resumed Claude sessions keep prior turns' tool calls in context, so a
comment-triggered task could reuse the PREVIOUS turn's --parent UUID
instead of the current trigger's. The reply landed in the wrong thread
(MUL-1125): backend stored exactly what the agent sent, but the agent
pulled a stale UUID from its own conversation memory.

Two layers of defense:

1. Extract BuildCommentReplyInstructions so daemon.buildCommentPrompt
   and execenv.InjectRuntimeConfig emit the same "use this exact
   --parent, do not reuse values from previous turns" block. The
   per-turn prompt now carries the current TriggerCommentID, which it
   previously relied on CLAUDE.md for (and CLAUDE.md isn't re-read
   mid-session).

2. Handler-side guard in CreateComment: when an agent posts from inside
   a comment-triggered task (X-Agent-ID + X-Task-ID, task has
   TriggerCommentID), require parent_id == task.TriggerCommentID or
   return 409. Assignment-triggered tasks are untouched.

* fix(agent/comments): scope parent_id guard to the task's own issue

Two issues from CI + GPT-Boy's review:

1. Guard was too broad: the CLI stamps X-Task-ID on every request, so an
   agent legitimately commenting on a different issue while its current
   task was comment-triggered would get 409'd with the wrong issue's
   trigger comment id. Narrow the guard to fire only when the request's
   issue matches the task's own issue — cross-issue agent activity
   stays unblocked.

2. The integration test tried to insert a second queued task for the
   same (agent, issue), which hits the idx_one_pending_task_per_issue_agent
   unique index. Replace the assignment-triggered-task sub-case with a
   cross-issue regression test (the scenario we now need to cover anyway):
   post on issue B while X-Task-ID points at a comment-triggered task on
   issue A, expect 201.
2026-04-20 15:56:16 +08:00