CLI (experimental)
@aml-jsx/cli runs an AML workflow source file without a separate application entry point. It loads TypeScript, TSX, or JavaScript through Vite and vite-node, resolves one exported AML value, evaluates it, and prints the result.
What the CLI owns
Section titled “What the CLI owns”The CLI deliberately owns only process-level concerns:
- loading a trusted workflow module;
- applying Vite-style environment files before the module is evaluated;
- selecting the default,
main, or requested named export; - creating an
AmlRuntime, evaluating the exported AML value, and formatting the result; - translating process interruption into runtime cancellation so active resources can be released;
- writing lifecycle and optional trace diagnostics to standard error.
Provider selection and provider-specific options belong in the workflow file. The CLI does not have --agent-provider, --sandbox-provider, model, credential, or Workspace configuration flags.
Run the package
Section titled “Run the package”Install the CLI beside the SDK used by the workflow:
npm install @aml-jsx/sdknpm install --save-dev @aml-jsx/cliRun it through the project-local executable:
npx aml run ./workflow.tsxFrom an AML repository checkout, contributors can build and invoke the workspace copy directly:
npm run build --workspace=@aml-jsx/clinode apps/cli/dist/index.js run ./workflow.tsxWrite a workflow entry
Section titled “Write a workflow entry”Export an AML renderable directly or export a zero-argument function that returns one. The current CLI creates the AmlRuntime; the module does not export a runtime instance.
import { Agent } from "@aml-jsx/sdk"import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing"
const provider = new DeterministicAgentProvider({ name: "cli-example", respond: request => ({ text: `Reviewed: ${request.prompt}` }),})
export default <Agent provider={provider}>README.md</Agent>This credential-free example prints Reviewed: README.md. Replace the deterministic provider with a supported Agent provider when the workflow is ready to call a live model. Keeping provider construction in the module makes the executable workflow self-contained: another runner can import the same tree, inspect its provider construction, or evaluate it with application-owned infrastructure later.
Export resolution
Section titled “Export resolution”The command resolves and executes one export in this order:
- Use the export selected by
--entry, when supplied. - Otherwise use the module’s
defaultexport. - Otherwise call an exported
main()function. - Await a selected function or promise and validate that it resolves to an AML renderable.
A function can build the tree after environment variables have been loaded:
import { Agent, opencodeAgent } from "@aml-jsx/sdk"
export default function ReviewRepository() { const model = process.env.AML_MODEL const OpenCode = opencodeAgent(model ? { model } : {})
return <Agent provider={OpenCode}>Review this repository and list the three highest-risk changes.</Agent>}The workflow file is the positional argument immediately after run. --entry selects an export inside that file; it does not replace the file argument. Select a different named export when one module contains several entry points:
aml run ./workflow.tsx --entry releaseReviewEnvironment loading
Section titled “Environment loading”Before importing the workflow, the CLI reads Vite-style environment files from the directory containing the workflow file—not necessarily the process’s current working directory. The mode is NODE_ENV, or development when NODE_ENV is absent.
project/├── .env.ci # explicit override selected from the current directory└── src/ ├── workflow.tsx ├── .env # workflow-local base values ├── .env.local # workflow-local machine values ├── .env.development └── .env.development.localExisting process environment values win over values in these files. An explicitly selected runtime environment file is applied last and can override both:
aml run ./workflow.tsx --runtime-env-file .env.ciThe option is named --runtime-env-file because modern Node.js interprets --env-file before the AML command receives its arguments. Relative override paths are resolved from the current working directory first, then from the workflow directory.
Run a named workflow in CI
Section titled “Run a named workflow in CI”One module can expose several jobs while keeping provider and environment choices in source. This credential-free example selects one named export and echoes its resolved prompt:
import { Agent } from "@aml-jsx/sdk"import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing"
const provider = new DeterministicAgentProvider({ name: "ci-example", respond: request => ({ text: request.prompt }),})
export const releaseReview = ( <Agent provider={provider}>Review the {process.env.RELEASE_CHANNEL ?? "preview"} release.</Agent>)
export const dependencyReview = <Agent provider={provider}>Review dependency updates.</Agent>Put RELEASE_CHANNEL=stable in src/.env, then apply a job-specific override from the process working directory:
RELEASE_CHANNEL=release-candidatenpx aml run ./src/automation.tsx \ --entry releaseReview \ --runtime-env-file .env.ci \ --json \ --traceThe JSON result containing Review the release-candidate release. is written to standard output. Lifecycle and metadata-only trace events go to standard error; prompt and result content remain redacted unless --capture-content is supplied explicitly.
Source execution
Section titled “Source execution”The CLI intentionally has one compiler path: Vite and vite-node. It creates a one-shot Vite transform environment,
loads the trusted module with source-map support, closes that environment, and then evaluates the selected AML value.
There is no --compiler abstraction. A second loader should only be introduced if native platform evidence demonstrates
a compatibility gap that Vite cannot address.
Output and diagnostics
Section titled “Output and diagnostics”Normal output stays easy to pipe: the resolved workflow result is written to standard output, while run lifecycle and trace diagnostics are written to standard error.
aml run ./workflow.tsx > result.txtUse --json for a machine-readable result envelope containing runId, durationMs, success, and result:
aml run ./workflow.tsx --jsonUse --trace to print metadata-only trace events. Prompt and result content remains redacted unless content capture is requested explicitly:
aml run ./workflow.tsx --traceaml run ./workflow.tsx --trace --capture-content--capture-content is an AML CLI option, not an ACP option or Agent capability. Treat its output as sensitive. It can include prompts, Agent messages and thoughts exposed through ACP, raw Tool activity, plans, structured results, <Tool /> input and output, commands, errors, and filesystem context. See Observability for the complete event and redaction contract.
Interrupting a run
Section titled “Interrupting a run”aml run translates SIGINT (usually Ctrl+C) and SIGTERM into cancellation of the active runtime evaluation. The signal reaches Agent sessions, ACP requests, MCP relays, and Sandbox operations through the evaluation’s AbortSignal. AML then closes active sessions and releases acquired resource scopes before the CLI exits.
The first signal starts graceful cancellation and allows up to 10 seconds for cleanup. When cleanup settles, the CLI exits with the conventional signal status: 130 for SIGINT or 143 for SIGTERM. A second SIGINT or SIGTERM exits immediately instead of continuing to wait. If cleanup has not settled after 10 seconds, the CLI also forces termination with the first signal’s status.
Cleanup follows provider ownership. AML orchestrates cancellation and invokes the acquired lease’s release boundary; the Sandbox provider decides how to stop its platform-specific resources. Local kills tracked process groups, Docker removes its leased container, and disposable remote providers terminate or delete their remote environment. A provider backed by intentionally persistent infrastructure should terminate evaluation-owned executions and release only the evaluation lease, not destroy the shared infrastructure.
Current command reference
Section titled “Current command reference”| Command or option | Behavior |
|---|---|
aml run <file> | Load and evaluate one trusted TS, TSX, or JS workflow module. |
-e, --entry <name> | Select a named export instead of the default export resolution. |
--runtime-env-file <file> | Apply one explicit environment file after Vite-style environment loading. |
--trace | Write metadata-only runtime trace events to standard error. |
--capture-content | Include sensitive trace content and imply --trace. |
--json | Emit a JSON result envelope instead of plain workflow text. |
-h, --help | Show CAC-generated command help. |
-v, --version | Show the CLI package, platform, architecture, and Node versions. |
When to use it
Section titled “When to use it”The experimental CLI is useful for local workflows, repository automation, scheduled jobs with explicit environment injection, and examples that should run without handwritten new AmlRuntime().evaluate(...) glue.
Prefer an application-owned runner when you need to inject runtime defaults, attach custom event sinks, share one runtime configuration across requests, coordinate service shutdown, or expose AML behind an API or queue consumer. Read Deployment for that pattern.