Establish CLI behavior contract#266
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f52648436
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @app.command("help", context_settings=CLI_CONTEXT_SETTINGS) | ||
| def help_command( | ||
| command: list[str] = typer.Argument(None, metavar="[COMMAND]...", help="Command or nested subcommand path"), |
There was a problem hiding this comment.
Bypass project loading for the help command
Because this is registered as an ordinary command, Typer runs the root callback before help_command, so any malformed sidemantic.yaml in the current project makes sidemantic help and sidemantic help info exit with a config error instead of showing help. This breaks the documented equivalence with sidemantic --help exactly when users may need help to recover from a bad config; the help path should avoid project discovery or be handled before the root callback.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 348697de63
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| suffix = source_spec.extensions[0] if source_spec.extensions else ".txt" | ||
| source = temp_root / f"stdin{suffix}" |
There was a problem hiding this comment.
Preserve stdin source extensions for SQL models
When a user streams a native Sidemantic SQL definition, e.g. cat model.sql | sidemantic convert - --from sidemantic --to sidemantic --output -, this always materializes stdin as the first registered extension (.yml). SidemanticAdapter.parse() dispatches SQL handling based on the .sql suffix, so the streamed SQL is parsed as YAML instead and fails with a non-actionable error like 'str' object has no attribute 'get'; stdin conversion should let users select or infer the correct suffix for multi-extension formats.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad184e8bc0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| ) | ||
| else: | ||
| emit_error(e) |
There was a problem hiding this comment.
Honor --debug in validate failures
With the new global --debug contract, sidemantic --debug validate ./models should expose tracebacks for unexpected validation crashes, but this non-JSON exception path still emits a concise error and then exits. If validate_directory() raises due to an internal loader/validator bug, users get the same suppressed traceback as normal mode instead of the debug behavior implemented via fail(e) in the other commands.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a06db680ee
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ctx.invoked_subcommand == "help": | ||
| return |
There was a problem hiding this comment.
Skip project loading for all help paths
When a malformed sidemantic.yaml is present and the user asks for conventional subcommand help such as sidemantic info --help, sidemantic migrate generate -h, or a no-args subgroup help like sidemantic migrate, ctx.invoked_subcommand is the real command/group rather than "help", so the callback still runs ProjectContext.discover() and exits with a config error instead of showing help. This leaves the documented --help/-h help paths unavailable in exactly the recovery scenario this guard is meant to handle; the skip needs to cover Click's help/no-args-help parsing as well as the custom help command.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef92d73424
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| **HTTP API server** (JSON or Arrow): | ||
| ```bash | ||
| uvx --from "sidemantic[api]" sidemantic api-serve --demo --port 4400 --auth-token secret | ||
| uvx --from "sidemantic[api]" sidemantic server api --demo --port 4400 --auth-token-file .secrets/api-token |
There was a problem hiding this comment.
Make the API demo command self-contained
When a user copies this demo command in a fresh checkout, server api now tries to read .secrets/api-token and exits before starting because that file is not created anywhere in the demo instructions. Since the token is optional for local demos, either omit this flag here or add the credential-file creation step so the documented demo remains runnable.
Useful? React with 👍 / 👎.
Establishes a consistent CLI contract across Sidemantic.
Shared downstream extension points live in
sidemantic/cli_contract.py:CLIState,cli_state(),ContractGroup, result and diagnostic emitters, and stream/secret helpers.Inline configuration secrets remain supported. Only direct
--passwordand--auth-tokenarguments are deprecated through 0.x, with removal eligible in 1.0 after a documented release cycle.Known limitations: global
--debugmust precede the subcommand, and multi-file generators cannot write to stdout.