Story
As a command-line user, I want xmd run - to execute a complete XMD program
from standard input, so a program-producing command can compose with xmd run
without a temporary file.
Common path
xmd plan "Prepare the release program."| xmd run -
xmd run - reads standard input completely, admits it as one complete root,
and then executes it through the ordinary run profile.
Current gap
Today the run grammar treats - as a file reference. The shared CLI also has
no host-supplied operation for acquiring standard input, and the subprocess
test launcher can send input but cannot close it to deliver EOF. The documented
composition therefore cannot run, and the proposed focused test cannot prove
that it does.
Command grammar
The literal document argument - selects standard input only when the caller
explicitly names the run command. Both xmd run - and xmd run -- - select
stdin. The selection happens from the original command form, not merely from a
parsed configuration that also represents the shorthand run command.
No other spelling acquires standard input:
- bare
xmd - retains the shorthand run grammar and treats - as a file
reference; xmd run --eval - and xmd -e - keep their existing refusal and never read
stdin;- is not an alias for another command; and- a reference such as
-#Section is not the literal stdin argument.
xmd run --help remains generic and reads no input. xmd run - --help selects
and inspects the supplied document, as the existing file and --eval help
forms do, but never executes it.
Host input and root identity
Standard input is a private CLI-host dependency. Each supported runtime
entrypoint supplies one cancellable Effection operation that reads stdin to EOF
once and returns a Result<string>. The shared CLI neither detects a runtime
nor reaches a host stdin global. This operation is not a public component,
syntax form, document capability, or contextual authority that an authored
program can replace.
After a successful read, the CLI constructs the existing
retainedSource("<stdin>", source) root. <stdin> is the stable origin shown in
source positions and diagnostics. The exact supplied source remains part of
the ordinary root binding and durable root import. Do not add a digest member,
a stdin-specific root variant, or another public root-source form: the existing
origin-plus-source identity already distinguishes two supplied programs.
Relative imports and every other relative document operation resolve from the
invocation's contextual working directory. Stdin never pretends to be a file in
that directory. File and --eval roots keep their existing identities and
selection behavior.
Lifecycle and failures
Fixed command grammar selects stdin before the host input operation is called.
The complete input is acquired before document inspection, root-property
resolution, Agent or provider setup, secret-detection announcement, journal
creation, root admission, or document execution. The reader is called exactly
once for one selected stdin root.
A read failure returns this approved diagnostic and exits nonzero:
xmd run could not read a complete document from standard input
It performs none of the later actions above. Cancellation while the reader is
waiting for bytes or EOF tears the reader down completely and admits no root,
creates no journal, and performs no document effect. Cancellation is not
converted into a read failure.
Once acquired, stdin follows the ordinary run lifecycle. Complete structural
preflight finishes before the first document effect, so a malformed construct
after an otherwise valid effect causes no document effect at all. Empty stdin
is the ordinary empty text root: it emits nothing and performs no document
effect.
All ordinary xmd run options, root props, output and return behavior,
journaling, timeout behavior, permission mode, cancellation, and providers
apply after source selection exactly as they do for file and --eval roots.
The run timeout begins at its existing boundary; it does not turn source
acquisition into a second execution lifecycle.
Approved command wording
Generic run help says:
Exactly one root document is required: a path, standard input through `xmd run -`, or one --eval value.
A run with no root says:
xmd run requires a root document — `xmd run <document.md>`, `xmd run -`, or `xmd run --eval '<markdown>'`
The stdin read-failure wording is the fixed sentence in the lifecycle section.
No raw host error, input content, or substituted path is included in it.
Acceptance ownership
This story exclusively owns the Quest's Stdin run case:
- a deterministic producer piped to
xmd run - supplies one complete root,
which executes once; - a later malformed construct prevents an earlier negative-control effect;
- empty stdin emits nothing and performs no document effect;
- a source position reports
<stdin>, and a journaled root import retains the
exact supplied source under that origin; - relative imports resolve from the invocation working directory;
- read failure and actual cancellation reach no inspection, provider, journal,
root admission, or document effect; - explicit and shorthand file roots and
--eval remain unchanged; - bare
xmd -, --eval -, another command's -, and -#Section do not select
stdin; and - generic help does not read stdin, while selected-root help reads and
describes it without execution.
#723 proves the pipe boundary with a deterministic producer and lands before
#724. #724 supplies the source-only xmd plan producer; once both stories are
delivered, their contracts establish the common path without additional #723
work. #723 is not held open for a test that can run only after #724.
Documentation and focused evidence
Update the root-source and CLI execution sections of architecture.md and
specs/executable-mdx-spec.md. Update xmd run --help and README/homepage
command examples that enumerate root inputs, without adding a <Run>
component.
Extend packages/test-support/launch.ts with bounded stdin input that writes
the supplied text and closes stdin, so subprocess tests observe real EOF and
still tear down the child on cancellation. Add the stdin matrix in
packages/cli/tests/stdin-cli.test.ts; keep file and --eval negative controls
in packages/cli/tests/inline-cli.test.ts. Exercise the private host-input
failure and cancellation paths with a controlled provider, and use real CLI
subprocess input for the public pipe, EOF, preflight, empty-input, identity,
working-directory, option, and grammar cases.
Focused feedback evidence:
deno task test \
packages/cli/tests/stdin-cli.test.ts \
packages/cli/tests/inline-cli.test.ts \
packages/cli/tests/cli-help.test.ts \
packages/cli/tests/syntax-cli.test.ts
packages/core/tests/source-position.test.ts is not focused evidence unless
the implementation changes core's canonical source-position shape, which this
contract does not require.
After a feedback commit, run deno task test --changed. Delivery adds a real
stdin/EOF probe to scripts/tests/cli-npm-bin.test.ts, proves the compiled CLI
after deno task build, and waits for required CI. Because this change touches
every runtime entrypoint and the shared subprocess launcher, the ordinary
delivery runtime matrices remain authoritative for Deno, Node, and Bun.
Dependencies and delivery order
Implementation starts from a clean worktree at current main, not from the
unrelated dirty checkout used for this architecture review.
Out of scope
- A
<Run> component or an independent child execution. - Reading stdin through
--eval, a bare xmd - alias, or xmd plan itself. - Treating stdin as a saved file origin.
- A new public stdin API, root-source variant, or digest protocol.
Story
As a command-line user, I want
xmd run -to execute a complete XMD programfrom standard input, so a program-producing command can compose with
xmd runwithout a temporary file.
Common path
xmd run -reads standard input completely, admits it as one complete root,and then executes it through the ordinary run profile.
Current gap
Today the run grammar treats
-as a file reference. The shared CLI also hasno host-supplied operation for acquiring standard input, and the subprocess
test launcher can send input but cannot close it to deliver EOF. The documented
composition therefore cannot run, and the proposed focused test cannot prove
that it does.
Command grammar
The literal document argument
-selects standard input only when the callerexplicitly names the
runcommand. Bothxmd run -andxmd run -- -selectstdin. The selection happens from the original command form, not merely from a
parsed configuration that also represents the shorthand run command.
No other spelling acquires standard input:
xmd -retains the shorthand run grammar and treats-as a filereference;
xmd run --eval -andxmd -e -keep their existing refusal and never readstdin;
-is not an alias for another command; and-#Sectionis not the literal stdin argument.xmd run --helpremains generic and reads no input.xmd run - --helpselectsand inspects the supplied document, as the existing file and
--evalhelpforms do, but never executes it.
Host input and root identity
Standard input is a private CLI-host dependency. Each supported runtime
entrypoint supplies one cancellable Effection operation that reads stdin to EOF
once and returns a
Result<string>. The shared CLI neither detects a runtimenor reaches a host stdin global. This operation is not a public component,
syntax form, document capability, or contextual authority that an authored
program can replace.
After a successful read, the CLI constructs the existing
retainedSource("<stdin>", source)root.<stdin>is the stable origin shown insource positions and diagnostics. The exact supplied source remains part of
the ordinary root binding and durable root import. Do not add a digest member,
a stdin-specific root variant, or another public root-source form: the existing
origin-plus-source identity already distinguishes two supplied programs.
Relative imports and every other relative document operation resolve from the
invocation's contextual working directory. Stdin never pretends to be a file in
that directory. File and
--evalroots keep their existing identities andselection behavior.
Lifecycle and failures
Fixed command grammar selects stdin before the host input operation is called.
The complete input is acquired before document inspection, root-property
resolution, Agent or provider setup, secret-detection announcement, journal
creation, root admission, or document execution. The reader is called exactly
once for one selected stdin root.
A read failure returns this approved diagnostic and exits nonzero:
It performs none of the later actions above. Cancellation while the reader is
waiting for bytes or EOF tears the reader down completely and admits no root,
creates no journal, and performs no document effect. Cancellation is not
converted into a read failure.
Once acquired, stdin follows the ordinary run lifecycle. Complete structural
preflight finishes before the first document effect, so a malformed construct
after an otherwise valid effect causes no document effect at all. Empty stdin
is the ordinary empty text root: it emits nothing and performs no document
effect.
All ordinary
xmd runoptions, root props, output and return behavior,journaling, timeout behavior, permission mode, cancellation, and providers
apply after source selection exactly as they do for file and
--evalroots.The run timeout begins at its existing boundary; it does not turn source
acquisition into a second execution lifecycle.
Approved command wording
Generic run help says:
A run with no root says:
The stdin read-failure wording is the fixed sentence in the lifecycle section.
No raw host error, input content, or substituted path is included in it.
Acceptance ownership
This story exclusively owns the Quest's Stdin run case:
xmd run -supplies one complete root,which executes once;
<stdin>, and a journaled root import retains theexact supplied source under that origin;
root admission, or document effect;
--evalremain unchanged;xmd -,--eval -, another command's-, and-#Sectiondo not selectstdin; and
describes it without execution.
#723 proves the pipe boundary with a deterministic producer and lands before
#724. #724 supplies the source-only
xmd planproducer; once both stories aredelivered, their contracts establish the common path without additional #723
work. #723 is not held open for a test that can run only after #724.
Documentation and focused evidence
Update the root-source and CLI execution sections of
architecture.mdandspecs/executable-mdx-spec.md. Updatexmd run --helpand README/homepagecommand examples that enumerate root inputs, without adding a
<Run>component.
Extend
packages/test-support/launch.tswith bounded stdin input that writesthe supplied text and closes stdin, so subprocess tests observe real EOF and
still tear down the child on cancellation. Add the stdin matrix in
packages/cli/tests/stdin-cli.test.ts; keep file and--evalnegative controlsin
packages/cli/tests/inline-cli.test.ts. Exercise the private host-inputfailure and cancellation paths with a controlled provider, and use real CLI
subprocess input for the public pipe, EOF, preflight, empty-input, identity,
working-directory, option, and grammar cases.
Focused feedback evidence:
deno task test \ packages/cli/tests/stdin-cli.test.ts \ packages/cli/tests/inline-cli.test.ts \ packages/cli/tests/cli-help.test.ts \ packages/cli/tests/syntax-cli.test.tspackages/core/tests/source-position.test.tsis not focused evidence unlessthe implementation changes core's canonical source-position shape, which this
contract does not require.
After a feedback commit, run
deno task test --changed. Delivery adds a realstdin/EOF probe to
scripts/tests/cli-npm-bin.test.ts, proves the compiled CLIafter
deno task build, and waits for required CI. Because this change touchesevery runtime entrypoint and the shared subprocess launcher, the ordinary
delivery runtime matrices remain authoritative for Deno, Node, and Bun.
Dependencies and delivery order
<Plan>with<TestAgent>in Markdown tests #728 supplies deterministic<Plan>execution in Markdown tests.<Plan>emit or capture approved XMD source #722 supplies exact text-producing<Plan>source.<Evaluate>evaluate complete XMD programs #713 may proceed in parallel; its nested complete-program admission does notreplace this CLI root-source path.
xmd run#723 lands before Makexmd planproduce approved XMD source only #724 removes implicit Plan execution.xmd planauthorship observable during and after an invocation #676 remains follow-up work after Makexmd planproduce approved XMD source only #724.Implementation starts from a clean worktree at current
main, not from theunrelated dirty checkout used for this architecture review.
Out of scope
<Run>component or an independent child execution.--eval, a barexmd -alias, orxmd planitself.