Skip to content

fix(cli): flush stream-json output - #1919

Closed
hogeheer499-commits wants to merge 2 commits into
MoonshotAI:mainfrom
hogeheer499-commits:agent/fix-stream-json-backpressure-1897
Closed

fix(cli): flush stream-json output#1919
hogeheer499-commits wants to merge 2 commits into
MoonshotAI:mainfrom
hogeheer499-commits:agent/fix-stream-json-backpressure-1897

Conversation

@hogeheer499-commits

@hogeheer499-commits hogeheer499-commits commented Jul 19, 2026

Copy link
Copy Markdown

Related Issue

Resolves #1897

The stream-JSON writers in headless mode ignored the return value of stdout.write(). With a slow or piped consumer, the final assistant message or resume hint could still be buffered when signal cleanup called process.exit().

Both headless runners now track backpressured writes and wait for drain before ordinary completion. That wait uses the existing bounded stdio timeout, so a consumer that stops reading cannot hang a completed command indefinitely. Signal cleanup restores session permissions and closes runtime resources before giving pending output its bounded flush window.

The regression tests cover delayed and permanently stalled drains, ordinary writes, resume hints, signal shutdown, permission restoration, and both headless engines. On current main I ran the full CLI suite (2,384 passing, 5 skipped), package typecheck, type-aware lint, changeset validation, and git diff --check.

This includes a patch changeset for @moonshot-ai/kimi-code. The stream-JSON interface itself has not changed, so no documentation update is needed.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 092fac8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@hogeheer499-commits
hogeheer499-commits force-pushed the agent/fix-stream-json-backpressure-1897 branch from 5d32ece to 35beeb1 Compare July 19, 2026 11:38
@hogeheer499-commits
hogeheer499-commits marked this pull request as ready for review July 21, 2026 20:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35beeb15e1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/cli/run-prompt.ts Outdated
const cleanupPromptRun = async (): Promise<void> => {
const pending = (cleanupPromise ??= (async () => {
removeTerminationCleanup?.();
await drainPromptOutput(stdout);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run permission cleanup even if stdout is wedged

When a SIGINT/SIGTERM arrives while --output-format stream-json stdout is backpressured and the pipe does not drain within PROMPT_CLEANUP_TIMEOUT_MS, cleanup times out at this first await and restorePromptSessionPermission()/harness.close() never run before installPromptTerminationCleanup() calls process.exit(). For resumed sessions that were forced to auto, that can leave the stored permission mode changed after an interrupted print run; wait for stdout with its own bounded best effort or move it after the required state cleanup. The v2 cleanup has the same ordering.

Useful? React with 👍 / 👎.

Comment thread apps/kimi-code/src/cli/run-prompt.ts Outdated
);
}
writeResumeHint(session.id, outputFormat, stdout, stderr);
await drainPromptOutput(stdout);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound the completion drain before returning

When --output-format stream-json writes enough data to make stdout.write() return false and the downstream pipe stays open but stops reading, this await never resolves. Because main.ts only calls finalizeHeadlessRun() after runPrompt() resolves, the existing bounded stdio drain/force-exit backstop is never reached, so a completed headless command can hang indefinitely instead of exiting after the configured stdio timeout. The v2 runner has the same unbounded await at run-v2-print.ts.

Useful? React with 👍 / 👎.

@hogeheer499-commits
hogeheer499-commits force-pushed the agent/fix-stream-json-backpressure-1897 branch from 35beeb1 to 092fac8 Compare July 22, 2026 16:00
@hogeheer499-commits

Copy link
Copy Markdown
Author

Closing this to avoid keeping two implementations in review now that #2170 covers the same buffered-output shutdown path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant