mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
`cli list_projects` with no arguments blocked forever whenever fd 0 was a pipe nobody closes: an ssh session's stdin, or a Node child_process.spawn parent that never calls stdin.end(). That is the #1359 deadlock again. The #1359 gate only skipped the stdin read for a tool whose schema declares NO properties; #1181 then gave list_projects optional paging properties, and the read came back for exactly the callers #1359 fixed. It showed up as a 25-minute stall in the Windows smoke's Phase 1b over ssh, and it is the same in v0.11.0. The gate now asks what stdin is (terminal, regular file, or stream) and what the tool needs: - terminal: never read (unchanged); - no properties: never read (unchanged); - optional properties only: a regular file (`cli list_projects < args.json`) is read, since a file always reaches EOF; a stream is not, and the call runs with `{}` exactly as an interactive one does; - any required property: file or stream, the documented `echo '<json>' | cli <tool>` channel, unchanged; the bare call cannot succeed without it. Only list_projects is optional-only today; the other 16 tools all require an argument. Piping JSON into list_projects is no longer read; flags, --args-file and `< file` still are. Proof (macOS, the release-tree binary vs this one, isolated runtime dirs): - held-open pipe: `list_projects` hung until killed at 20 s -> returns in 0.4 s; - `list_projects < args.json` ({"format":"json"}): JSON on both; - `printf '{"project":"nope"}' | cli index_status`: same "project not found" on both. Tests: the #1359 schema seam now takes the stdin kind; new cli_optional_argument_tool_never_reads_stream_stdin (fails before: the old gate admitted a stream for list_projects) and cli_stdin_kind_classifies_file_and_pipe; the whole-table sweep checks file and stream separately and asserts it really covers an optional-only tool. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>