Skip to content

fix(shell): resolve bash timeout hang when daemon inherits stdio pipes - #10

Merged
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:haozhe/timeout-bugfix
May 25, 2026
Merged

fix(shell): resolve bash timeout hang when daemon inherits stdio pipes#10
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:haozhe/timeout-bugfix

Conversation

@sailist

@sailist sailist commented May 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes a bug where the Bash tool'''s timeout would not take effect when a command spawned a detached daemon process that inherited stdio pipes. The agent would hang indefinitely because the process exit promise waited for stdio streams to close, which never happened while the daemon held the pipe file descriptors open.


1. Destroy stdio streams on abort in BashTool

Problem: When a Bash command spawned a detached daemon that inherited stdout/stderr pipes, aborting the shell command did not release those pipes. The daemon kept the file descriptors open, preventing the close event from firing and causing the agent to hang indefinitely.

What was done:

  • Explicitly destroy proc.stdout and proc.stderr in the abort handler inside BashTool to forcibly close the stdio pipes.

2. Use exit instead of close in LocalProcess

Problem: child.on('\''close'\'') waits for all stdio streams to close before resolving the exit promise. If a detached daemon inherits stdio pipes, the close event never fires.

What was done:

  • Changed the event listener from close to exit in LocalProcess so the exit promise resolves as soon as the child process itself terminates, regardless of stdio stream state.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked the related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@sailist

sailist commented May 25, 2026

Copy link
Copy Markdown
Collaborator Author

@codex

@sailist
sailist force-pushed the haozhe/timeout-bugfix branch from 055a1ca to 7183e78 Compare May 25, 2026 07:42
- destroy stdout/stderr on abort to release stdio pipes held by detached daemons\n- use `exit` instead of `close` event to resolve exit promise
@sailist
sailist force-pushed the haozhe/timeout-bugfix branch from 7183e78 to cf73f1f Compare May 25, 2026 07:44
@sailist
sailist merged commit 67d3cb8 into MoonshotAI:main May 25, 2026
4 checks passed
wintrover added a commit to wintrover/kimy that referenced this pull request Jun 29, 2026
- kimy wrapper: move hash writes after smoke test (MoonshotAI#1)
- kimy wrapper: add public/ to web hash inputs (MoonshotAI#3)
- kimy wrapper: widen vis hash to include config files (MoonshotAI#4)
- kimy wrapper: move lockfile from /tmp to ~/.kimy/bin (MoonshotAI#5)
- kimy wrapper: use explicit package list for native hash (MoonshotAI#7)
- 01-bundle.mjs: skip vis-asset build when already done (MoonshotAI#2)
- justfile: sync deploy with new wrapper, add deploy-full (MoonshotAI#9,MoonshotAI#10,MoonshotAI#11)
- flake.nix: add unpin guidance to nixpkgs comment (MoonshotAI#12)
asdshuaishuai pushed a commit to d2rabbit/kimi-code that referenced this pull request Jul 21, 2026
…onshotAI#10)

The mention machinery existed but had four UX gaps that made it feel
broken:

1. **Empty query returned nothing.** Typing '@' alone wouldn't show any
   suggestions because searchMention short-circuited on falsy query.
   Now an empty query is treated as 'give me the default ranking' and
   the daemon's searchFiles returns a sensible default (recent / popular
   files). The user sees a populated menu the moment they hit @.

2. **Stale async overwrites.** Typing fast fired several searchFiles
   requests; the slowest one would land last and clobber the right
   answer. Added an incrementing sequence id — only the response matching
   the current seq is committed to mentionResults.

3. **mentionIndex past end of new list.** When a new search returned a
   shorter list, the old mentionIndex could point past the end. An
   $effect now resets mentionIndex to 0 whenever mentionResults changes.

4. **insertMention was fragile.** The previous implementation used
   lastIndexOf('@') without verifying the token between @ and cursor was
   still the same — typing a stray @ somewhere else in the textarea and
   then mentioning a file could insert the path at the wrong spot. Now
   we check the slice between the candidate @ and the cursor: if it
   contains whitespace we bail without modifying text. The caret is also
   moved to just after the inserted trailing space so the user can
   immediately keep typing.

5. **Mouse / keyboard were not synced.** Hovering a mention-item with
   the mouse now updates mentionIndex, so the next Enter key press
   picks the visually highlighted item. Each item also has role=option
   and aria-selected for screen-reader parity.

6. **File vs folder icon.** Items whose path ends with '/' or kind is
   'dir' get a folder icon; everything else gets file-text.

svelte-check 0 errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants