Skip to content

fix(cli): close each pipe at its read limit, and filters read pasted lists - #54

Merged
ragnorc merged 2 commits into
mainfrom
fix/cli-pipes-close-20261031
Nov 1, 2026
Merged

ragnorc merged 2 commits into
mainfrom
fix/cli-pipes-close-20261031

Conversation

@ragnorc

@ragnorc ragnorc commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Fixes a defect a review found in #52, which is merged, plus two loose ends from it.

Each pipe closes at its read limit (graph_store)

#52 kept a CLI's pipes open after their read limit, because the Take wrappers lived until the run ended. A CLI that wrote more than its limit plus a pipe buffer (for example credentials export with a token over about 128 KiB) then blocked on a full pipe and never exited. The run ran out its timeout instead of being refused at once, holding the CLI turn: the very cost #52 set out to remove. Each read now owns its pipe and closes it at the limit, keeping what it read.

An export answer that fills the bound without its newline is now refused as longer than a token. Before, the CLI stopped by its next write into the closed pipe was reported as a failed export, which pointed at the wrong problem.

A steadier timing test

The test of a program left holding the pipes now sleeps a minute and allows 90 s, so a slow first run fails on the assertion and not on its own timeout. That leaves room for macOS to scan a new script on its first run, which this crate's own docs say can take seconds while builds run.

The "is one of" filter reads lists as cells do (type_table)

The filter's doc says it reads a list as a list cell does, but it kept the comma-only reader when cells began taking JSON in #52. It now uses the same list_texts, so a copied list pasted into a filter works too. While a list is typed as JSON, the value field offers no suggestions: picking one would rewrite the list as plain items and lose its JSON.

Testing

  • cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace (1,167 passed) and the repo checks pass locally, on main 10b7786.
  • cli_tokens::tests::input_a_command_does_not_read_ends_at_its_timeout gains a script that floods its output past the bound. With the pipe held open past the bound, as fix: a CLI run ends with the CLI, and list cells take pasted JSON #52 had it, the test runs out its 60 s timeout and fails (checked).
  • cli_tokens::tests::a_token_is_exported_through_a_pipe exports a 256 KiB token and expects the "longer than a token" refusal. Without the new check it fails (checked).
  • model::tests::list_filters_parse_each_value_with_the_propertys_type gains a pasted JSON list.
  • suggest::tests::a_list_typed_as_json_is_not_completed covers the suggestion rule.

Note

Medium Risk
Changes CLI subprocess I/O and credential export error paths; incorrect pipe closing or token-length checks could break token acquisition or mis-report export failures.

Overview
Follow-up to #52: CLI subprocess handling and “is one of” filter input are tightened so oversized output and list editing behave predictably.

CLI pipe reads (graph_store) — stdout/stderr reads now go through read_into, which closes each pipe once its byte limit is reached. That stops child processes from blocking on a full pipe when they write past the cap (e.g. huge credentials export), so runs fail fast instead of burning the CLI turn until timeout. Exports that fill the token bound without a trailing newline are rejected explicitly as longer than a token, rather than surfacing as a generic failed export after the CLI hits a broken pipe.

Filter lists (type_table) — “Is one of” parsing uses list_texts (same as list cells), so pasted JSON like ["Founder", "Smith, John"] works, not only comma-separated text. While the field starts with [, value suggestions are disabled so picking a suggestion does not rewrite JSON into comma items and lose the paste.

Tests cover flooding stdout past the bound, oversized token export, JSON filter parsing, and the suggestion guard.

Reviewed by Cursor Bugbot for commit 7ba6fef. Bugbot is set up for automated code reviews on this repo. Configure here.

…lists

A review of #52 found that its change kept a CLI's pipes open after
their read limit: the `Take` wrappers lived until the run ended. A CLI
that wrote more than its limit plus a pipe buffer (an oversized token)
then blocked on a full pipe and never exited, so the run ran out the
timeout instead of being refused at once, holding the CLI turn. Each read
now owns its pipe and closes it at the limit, keeping what it read.

The test of a program left holding the pipes sleeps a minute and allows
30 s, with room for macOS to scan a new script on its first run.

The "is one of" filter says it reads a list as a list cell does, but it
kept the comma-only reader when cells took JSON. It now uses the same
`list_texts`, so a copied list pasted into a filter works too.
…uncompleted

An export answer longer than a token fills the read bound without its newline and
is now refused as too long, instead of as whatever the closed pipe made of it. The
leaving-process test gets room to fail on a slow runner without timing out. A filter
list typed as JSON is no longer completed, since a pick would rewrite it as items.
@ragnorc
ragnorc merged commit 2b6ee8d into main Nov 1, 2026
@ragnorc
ragnorc force-pushed the fix/cli-pipes-close-20261031 branch 3 times, most recently from 95892b1 to 7ba6fef Compare November 1, 2026 09:53
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.

1 participant