Skip to content

cli: run single-fn files, list multi-fn files, gate AST dump behind --ast#223

Merged
danieljohnmorris merged 3 commits into
mainfrom
fix/cli-default-run
May 13, 2026
Merged

cli: run single-fn files, list multi-fn files, gate AST dump behind --ast#223
danieljohnmorris merged 3 commits into
mainfrom
fix/cli-default-run

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

`ilo file.ilo` with no function name has dumped raw AST JSON since the early days, which is a first-touch surprise the assessment doc has caught at least six times (lines 527, 623, 816, 839, 936, 1045). It looks like silent success: the program ran, here is some output, except none of it is the program's output. Personas burn 1-3 retries before they figure out they need to pass a function name.

New behaviour:

Invocation Before After
`ilo file.ilo` with 1 fn AST JSON runs the fn
`ilo file.ilo` with N fns AST JSON friendly listing, exit 1
`ilo file.ilo func args` runs fn runs fn (unchanged)
`ilo --ast file.ilo` (n/a) AST JSON
`ilo ''` inline-no-func AST JSON AST JSON (preserved, PR #178)

The `--ast` flag works in leading, trailing, or any-position - it is extracted in a pre-scan like the engine flags from PR #175. AST dump still skips verify so partial/exploratory snippets work.

Manifesto framing: every retry costs tokens. The current behaviour costs tokens on first contact and disproportionately hits agents that lean on natural-language intuitions about "how to run a file". This change makes the most common case Just Work and reserves the inspection path for an explicit flag.

Repro

Before:

```
$ ilo file.ilo
{ "declarations": [ ... ] } # looks like success, no fn was run
```

After:

```
$ ilo single-fn.ilo
42 # runs

$ ilo multi-fn.ilo
error: multi-fn.ilo defines multiple functions, please specify one.
available functions:
foo
bar
baz

ilo multi-fn.ilo [args...] run a function
ilo --ast multi-fn.ilo dump the parsed AST as JSON

$ ilo --ast file.ilo
{ "declarations": [ ... ] }
```

What's in the diff

  • c7a50e2 cli: run single-fn files, list multi-fn files, gate AST dump behind --ast - adds `pub ast: bool` to `RunArgs`, threads `ast: false` through every construction site, pre-scans `--ast` from anywhere in argv, replaces the file-AST-dump path with auto-run / friendly listing / declarations-only fallback. Extends the verify-skip predicate so `--ast` skips verify the same way the legacy inline-no-func path does. Updates `print_help`.
  • 52e9f37 tests: cover new ilo file.ilo dispatch and --ast flag - eleven cross-cutting regressions in `tests/regression_cli_default.rs` plus a retarget of the one existing test that asserted the old AST-on-no-args contract.

Test plan

  • `cargo test --release --features cranelift` green (full suite)
  • `cargo fmt --check` clean
  • `cargo clippy --release --features cranelift --all-targets` clean
  • New regressions cover: single-fn auto-run, single-fn auto-run with positional args, multi-fn listing exit code and listed names, multi-fn explicit-fn unchanged, multi-fn explicit-fn with args, `--ast` in leading position, `--ast` in trailing position, `--ast` on inline code, `--ast` does NOT execute the fn, inline-no-func legacy AST dump preserved, empty-file AST dump
  • Existing inline-no-func tests in `tests/eval_inline.rs` still pass (PR main: skip verify errors in inline AST-dump mode #178 contract preserved)
  • Existing CLI flag-placement tests in `tests/cli_run_flag_placement.rs` still pass

Follow-ups

  • The friendly listing currently includes both user functions and any `tool` decls? It only iterates `ast::Decl::Function` so tool-only files still hit the declarations-only AST-dump fallback. Probably fine, could revisit if it surprises users.
  • An `examples/*.ilo` regression of this scenario doesn't fit naturally (the harness invokes engines, not the bare-args CLI dispatcher we changed), so the coverage lives entirely in the new Rust regression test.

…-ast

ilo file.ilo with no func arg used to dump raw AST JSON. New behaviour:
single-fn file auto-runs, multi-fn file prints a friendly listing and
exits 1, AST dump moves behind explicit --ast. Inline-no-func AST dump
(PR #178 contract) preserved for tooling.
Eleven regression tests pinning single-fn auto-run, multi-fn listing,
--ast in leading and trailing positions, --ast on inline code, and the
legacy inline-no-func AST dump. Retarget the one existing test that
asserted the old behaviour at --ast.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 94.91525% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/main.rs 94.82% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

The pre-scan loop strips --ast from argv before the positional mode-flag
match runs, so the dedicated arm here was dead. Removes it.
@danieljohnmorris danieljohnmorris merged commit 6df6050 into main May 13, 2026
5 checks passed
@danieljohnmorris danieljohnmorris deleted the fix/cli-default-run branch May 13, 2026 12:37
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