pi-mono/packages/coding-agent/src/core
robopipi[bot] 36be9c612e
fix(coding-agent): decode pi.exec output across UTF-8 chunk boundaries (#11326)
`execCommand()` (the function behind `pi.exec()`) decoded each stdout
and stderr chunk on its own with `data.toString()`. When a multi-byte
UTF-8 character was split across two pipe chunks, each half was turned
into U+FFFD, so the result was corrupted. For example, `"你好"` came back
as `"���好"` while the command still exited with code 0.

This change gives stdout and stderr each their own
`StringDecoder("utf8")`. A decoder holds back incomplete bytes until the
rest of the character arrives. Both decoders are flushed with `end()`
before the promise resolves, on both the success path and the error
path. `waitForChildProcess()` can resolve without a stream `end` event,
so the decoders are flushed there and not in an `end` handler. The
return shape, exit codes, and kill behavior are unchanged.

**Testing**
- Added a regression test to `packages/coding-agent/test/exec.test.ts`.
The child process splits `"你好"` across two writes on both stdout and
stderr. The test fails without the fix and passes with it: `node
../../node_modules/vitest/dist/cli.js --run test/exec.test.ts` reports 3
passed.
- `npm run check` passes.
- Reproduction from the issue: a child that writes the first byte of
`"你好"` and then the rest 100 ms later. Before the fix the result was
`{"stdout":"���好",...}`. After the fix it is
`{"stdout":"你好","stderr":"","code":0,"killed":false}`.

Fixes #11312

Requested by @davidbrai

---------

Co-authored-by: triagent <triagent@localhost>
Co-authored-by: David Brailovsky <davidbrai@gmail.com>
2026-10-23 14:47:34 +02:00
..
compaction fix(coding-agent): apply /compact instructions to split-turn prefix summary 2026-10-21 12:42:17 +02:00
export-html fix(coding-agent): render HTML export for sessions deeper than the call stack 2026-10-22 20:51:38 +02:00
extensions feat(coding-agent): add messageId and timestamp to markdown transformer context 2026-10-22 20:49:38 +02:00
tools fix(coding-agent): grep tool ignores ripgrep config via --no-config 2026-10-21 22:19:03 +02:00
agent-session-runtime.ts fix(coding-agent): save new session file at the first user message 2026-09-25 16:27:51 +02:00
agent-session-services.ts feat(coding-agent): Virtual models (#10035) 2026-09-28 23:30:45 +02:00
agent-session.ts fix(coding-agent): recovery omits tool results with the truncated tool call 2026-10-21 22:44:44 +02:00
auth-guidance.ts chore(ts): use source import extensions 2026-05-20 00:04:03 +02:00
auth-storage.ts fix(coding-agent): retry transient Windows EPERM when acquiring auth lock 2026-10-12 16:14:55 +02:00
bash-executor.ts fix(coding-agent): strip ANSI sequences split across user bash output chunks 2026-10-07 15:02:59 +02:00
bug-report-upload.ts feat(coding-agent): add bug reporting 2026-09-19 17:55:49 +02:00
bug-report.ts feat(ai,coding-agent): add alternative sign in for the openai provider 2026-09-29 17:16:15 +02:00
cache-stats.ts feat(coding-agent): add prompt cache warming (#9668) 2026-09-19 21:18:15 +02:00
cache-warmer.ts fix(coding-agent): skip late cache warming refreshes 2026-09-20 15:53:22 +02:00
client-identity.ts fix(ai,agent,coding-agent,durable): client identity follow-ups 2026-10-21 11:18:16 +00:00
crash-log.ts refactor(coding-agent): resolve built-in extensions as builtin:<name> paths (#10159) 2026-09-29 10:51:01 +02:00
defaults.ts fix(coding-agent): keep model and thinking level changes session scoped (#8356) 2026-08-19 16:48:29 +02:00
diagnostics.ts refactor(coding-agent): unify SkillWarning and ResourceDiagnostic 2026-01-24 00:45:01 +01:00
event-bus.ts Fix event bus async error handling, clear pending messages on session switch, improve SDK docs 2026-01-04 22:04:50 +01:00
exec.ts fix(coding-agent): decode pi.exec output across UTF-8 chunk boundaries (#11326) 2026-10-23 14:47:34 +02:00
experimental.ts feat(coding-agent): prefer strict sampling for built-in tools by default 2026-09-05 23:54:20 +02:00
footer-data-provider.ts docs(coding-agent): clarify custom footer usage APIs (#8482) 2026-08-23 23:34:08 +02:00
http-dispatcher.ts fix(coding-agent): tunnel proxied HTTP requests 2026-09-02 09:23:23 +02:00
index.ts fix(coding-agent): keep prompt and tool state across context handlers (#9846) 2026-09-21 17:14:22 +02:00
key-id-schema.ts feat(coding-agent): publish configuration schemas (#9880) 2026-10-08 10:01:17 +02:00
keybindings-schema.ts feat(coding-agent): publish configuration schemas (#9880) 2026-10-08 10:01:17 +02:00
keybindings.ts feat(coding-agent): publish configuration schemas (#9880) 2026-10-08 10:01:17 +02:00
mcp-servers.ts fix(coding-agent): keep MCP tools with --tools, add tool patterns and --no-mcp 2026-10-05 17:21:55 +02:00
messages.ts Mid conversation system messages (#9548) 2026-09-16 15:54:07 +02:00
model-config.ts docs(ai,coding-agent): generate models.json reference from schemas (#11038) 2026-10-16 21:53:00 +01:00
model-registry.ts feat(coding-agent): add models.generateImages() to codemode 2026-10-01 16:50:29 +02:00
model-resolver.ts fix(ai,coding-agent): drop models retired upstream 2026-10-21 10:10:55 +02:00
model-runtime.ts fix(ai,agent,coding-agent,durable): client identity follow-ups 2026-10-21 11:18:16 +00:00
models-store.ts fix(coding-agent): normalize UTF-8 BOMs in text inputs 2026-08-19 14:11:02 +02:00
nested-tool-calls.ts feat: record response, tool execution, and durable task times 2026-10-06 19:28:54 +02:00
output-guard.ts fix(coding-agent): retry RPC stdout backpressure 2026-05-24 22:59:35 +02:00
package-manager.ts fix(coding-agent): start when a configured package fails to install (#11304) 2026-10-23 12:27:45 +02:00
pi-manifest.ts fix(coding-agent): normalize UTF-8 BOMs in text inputs 2026-08-19 14:11:02 +02:00
project-trust.ts feat(coding-agent): publish configuration schemas (#9880) 2026-10-08 10:01:17 +02:00
prompt-templates.ts fix(coding-agent): keep empty quoted prompt template arguments 2026-10-14 15:35:39 +02:00
provider-composer.ts feat(ai,coding-agent): image input for System One classifiers 2026-10-21 23:53:47 +02:00
radius.ts feat(coding-agent): offer Radius sign-in and MCP setup in /login 2026-10-01 15:12:24 +02:00
remote-catalog-provider.ts feat(ai,coding-agent): list only the OpenRouter models a key may use (#10672) 2026-10-12 10:17:40 +02:00
resolve-config-value.ts fix(coding-agent): run legacy WSL bash commands via stdin 2026-06-19 15:08:25 +02:00
resource-loader.ts fix(coding-agent): start when a configured package fails to install (#11304) 2026-10-23 12:27:45 +02:00
runtime-credentials.ts fix(coding-agent): make model refresh cancellation caller-owned 2026-08-04 00:03:52 +02:00
sdk.ts fix(ai,agent,coding-agent,durable): client identity follow-ups 2026-10-21 11:18:16 +00:00
session-cwd.ts fix(coding-agent): handle missing session cwd 2026-04-05 21:24:32 +02:00
session-export.ts feat(coding-agent): add bug reporting 2026-09-19 17:55:49 +02:00
session-manager.ts fix(tui,coding-agent): reduce render cost of theme changes and streaming 2026-09-29 08:23:46 +02:00
settings-defaults.ts feat(coding-agent): configure session share destination 2026-10-13 15:41:13 +02:00
settings-diagnostics.ts fix(coding-agent): report settings diagnostic paths 2026-08-19 13:07:53 +02:00
settings-manager.ts feat(coding-agent): configure session share destination 2026-10-13 15:41:13 +02:00
settings-schema.ts feat(coding-agent): configure session share destination 2026-10-13 15:41:13 +02:00
skills.ts fix(coding-agent): keep hidden tools out of prompt rules and skills hint 2026-10-05 18:50:17 +02:00
slash-commands.ts feat(coding-agent): configure session share destination 2026-10-13 15:41:13 +02:00
source-info.ts refactor(coding-agent): resolve built-in extensions as builtin:<name> paths (#10159) 2026-09-29 10:51:01 +02:00
system-prompt.ts fix(coding-agent): keep hidden tools out of prompt rules and skills hint 2026-10-05 18:50:17 +02:00
telemetry.ts chore(ts): use source import extensions 2026-05-20 00:04:03 +02:00
timings.ts fix(coding-agent): preserve extension timing measurements 2026-06-25 02:07:32 -05:00
trust-manager.ts feat(coding-agent): codemode and MCP 2026-09-29 09:12:50 +02:00
usage-totals.ts feat(ai): add totalFromProvider flag to usage cost (#11178) 2026-10-22 09:02:01 +02:00
virtual-models.ts fix(coding-agent): resolve branch model selection with one catalog lookup 2026-09-30 14:20:03 +02:00