Repository navigation
feat(fill): read text from stdin with --text-stdin - #3351
Metehan-Bicer wants to merge 6 commits into
Conversation
fill can take its text from stdin instead of argv so a secret never appears in the CLI's process arguments. The read is bounded to 64 KiB and strips exactly one trailing LF or CRLF; a text argument, a terminal, empty input and invalid UTF-8 are refused with typed reasons that never echo the input. The value goes through the existing sensitivity contract: it is registered as a diagnostics secret in the CLI and daemon scopes, and the daemon keeps it out of recorded actions unless --record-as parameterizes it. While recording is armed the flag needs --record-as or --no-record. Batch steps, MCP tools and env/config defaults cannot set it. Closes callstack#3260
There was a problem hiding this comment.
All reported issues were addressed across 25 files
Reply to a comment to ask cubic a question or push back. It learns from your replies.
View guided diff | Re-trigger cubic
- Mask target parse failures under --text-stdin: a stray positional may be the secret, and the generic target error echoed it. - Keep a leading byte order mark and refuse lone surrogates in string chunks instead of replacing them. - Only refuse batch steps that set textStdin to true. - Clarify help and docs: passing neither --record-as nor --no-record while recording is an error, invalid UTF-8 is refused, and printf %s is the verbatim way to pipe a value. - Tighten tests to assert each case's own input is never echoed.
There was a problem hiding this comment.
All reported issues were addressed across 10 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
- A string stream may split a surrogate pair across chunks, and the per-chunk lone-surrogate check refused valid input. A trailing high surrogate is now held back until the next string chunk; a byte chunk or the end of input still refuses it as invalid UTF-8. - Size a string chunk with Buffer.byteLength before encoding it, so an oversized chunk is refused without being copied first.
4e7597c to
0964704
Compare
|
Would it be simpler to treat Not blocking, and you can take or leave it: the armed-recording refusal and the extended diagnostic-registration predicate are only tested by calling the helpers directly, so one router-level test that sends an armed Two bot threads on CI is green and there are no conflicts. This read of 0964704 is from the code only, and I did not run the CLI or the tests. The earlier live iOS run was at 9d2bc90 and did not show the |
A fill whose text is sensitive (--record-as set or --text-stdin) now decides it through one predicate, isSensitiveFillText, for the response payloads, the recorder skip and diagnostics registration. Without --record-as, the response and result text read [REDACTED] and value-carrying selector candidates are dropped, so an unrecorded or --no-record stdin fill no longer echoes the value in --json output or the client result. An error leaving the router now passes through the request's registered sensitive values, so a backend message that echoes the value after admission is redacted as well.
|
Thanks for the careful read. Addressed in 19d3ffd:
No part of the value is in stdout, and a follow-up One question: |
There was a problem hiding this comment.
All reported issues were addressed across 8 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
- recordAs and textStdin mark fill text as sensitive, but the request boundary only checks that flags is an object. A direct daemon request with textStdin: "true" was read as unmarked, so the value came back in data.text; recordAs: 42 failed later as an UNKNOWN TypeError. Both are now refused as INVALID_ARGS before any device work. - Assert the --no-record response text is exactly [REDACTED].
|
The fixes from the earlier review at 0964704 are in at 68acc36, but one problem remains in the error path. The two earlier cubic-dev-ai threads are addressed at this commit: the malformed
Not blocking, and fine to take or leave: in CI is green, with the single reported check passing, and there are no conflicts. I read the code only and did not run the tests or a live replay. I also did not check whether nested batch steps that carry |
Summary
fillcan now take its text from stdin, so a secret never appears in the CLI's argv:\nor\r\n. A text argument, a TTY, empty input and invalid UTF-8 areINVALID_ARGSwith typed reasons (fill_text_source_conflict,fill_text_stdin_*); no message echoes the input.session.actionsunless--record-asparameterizes it. While recording is armed,--text-stdinneeds--record-asor--no-record(fill_text_stdin_unparameterized_recording). Happy to switch this to recording the step without its text if you prefer.25 files; scope stays within the
fillfamily. Closes #3260.Validation
Tested at 9d2bc90 (includes the review fixes):
pnpm check:affected --runpassed (all runnable checks; device and toolchain lanes are GitHub-authoritative). CI pending.Live run on an iPhone 16 simulator (iOS 18.6, Settings search field): stdin fill succeeded; an armed recording refused it without
--record-asand published${PASSWORD}with it. The value was absent from the daemon log, session events and the.adscript. It still appears in the native XCTest session log, which is #3261 and out of scope here.