fix(auto-recall): thread parsed STDIN through the hook-dispatch path#61
Open
hobostay wants to merge 1 commit into
Open
fix(auto-recall): thread parsed STDIN through the hook-dispatch path#61hobostay wants to merge 1 commit into
hobostay wants to merge 1 commit into
Conversation
autoRecall() read process.stdin itself (via readStdin). The hook dispatcher (hook-dispatch-cli.ts) already reads STDIN once, parses it, and fans the parsed object out to every handler — so by the time the auto-recall handler ran, process.stdin was drained and autoRecall() saw "no STDIN data" and returned immediately. The PostToolUse hooks that ship today all go through `teamai hook-dispatch` (legacy `teamai auto-recall --stdin` entries are removed by cleanupLegacyHooks), so auto-recall never fired in production. The handler even carried a TODO noting it "can't easily pipe stdin to the function" and worked around it by capturing stdout — but never fed it data. Fix (resolves that TODO): - Extract the HookInput construction from readStdin into a pure parseHookInput(data) so callers that already hold the parsed JSON can build the input without touching the stream. - autoRecall(input?) accepts an optional pre-parsed input; the legacy `teamai auto-recall --stdin` command path still falls back to readStdin. - The handler now parseHookInput(stdin)s the dispatcher's object and passes it to autoRecall(input) instead of calling it with no args. Added a regression test that executes the auto-recall handler and asserts autoRecall receives a correctly-parsed input (toolName/toolInput/toolOutput/ sessionId). It fails on the old handler (`expected undefined to be defined` — autoRecall was called with no args). The legacy direct command and all existing auto-recall tests are unchanged. `npm test` 1441 passed; `tsc --noEmit` clean. Co-Authored-By: Claude <noreply@anthropic.com>
|
I noticed this PR currently has conflicts with the base branch, and GitHub marks it as not mergeable. Could you please sync with the latest main and resolve the conflicts first? I can continue the review/merge after that. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Auto-recall never fires when invoked through the hook dispatcher — i.e. in every real installation.
autoRecall()readsprocess.stdinitself, butteamai hook-dispatch(the only hook command injected today) reads STDIN once, parses it, and passes the parsed object to each handler. By the time the auto-recall handler runs,process.stdinis drained, soautoRecall()sees "no STDIN data" and returns immediately.The handler's own code documented this as a known limitation:
The
teamai auto-recall --stdindirect command still works (it owns the stream), butcleanupLegacyHooksremoves those legacy entries, so the live PostToolUse path goes throughhook-dispatch→ broken.Fix (resolves the TODO)
HookInputconstruction out ofreadStdininto a pureparseHookInput(data), so a caller that already holds the parsed JSON can build the input without touching the stream.autoRecall(input?)accepts an optional pre-parsed input; the legacy direct command still falls back toreadStdin()— unchanged.parseHookInput(stdin)s the dispatcher's object and passes it toautoRecall(input).The existing stdout-intercept capture is retained (and is sound:
log.debugis off by default andautoUpvoteonly useslog.debug/log.error-to-stderr, so theadditionalContextJSON is the last stdout write).Tests
hook-handlers.test.tsthat executes the auto-recall handler with a realistic PostToolUse STDIN object and assertsautoRecallis called with a correctly-parsed input (toolName/toolInput/toolOutput/sessionId). It fails on the old handler (expected undefined to be defined—autoRecallwas invoked with no arguments).importOriginalin the module mock so the realparseHookInputruns (onlyautoRecallis stubbed).auto-recall/hook-dispatchtests are unchanged.npm test→ 1441 passed;tsc --noEmit→ clean.Co-Authored-By: Claude noreply@anthropic.com