Skip to main content

harn_cli/cli/
mod.rs

1//! Top-level clap definition for the `harn` CLI.
2//!
3//! Per-subcommand arg structs live in their own modules under
4//! `crates/harn-cli/src/cli/`. The `Cli` and `Command` enum here only
5//! reference types via `pub(crate) use ...` re-exports so external
6//! consumers can keep using `crate::cli::TypeName` unchanged.
7//!
8//! Some variants of subcommand enums are reached only by destructuring
9//! the parent (`SubCommand::Foo(args) => ...`) and are never referenced
10//! by name from outside this module. Those types stay private to their
11//! per-subcommand module and are accessed through their parent enum.
12
13mod bench;
14mod check;
15mod completions;
16mod config_cmd;
17mod connect;
18mod connector;
19mod contracts;
20mod crystallize;
21mod demo;
22mod dev;
23mod doctor;
24mod dump;
25mod eval;
26mod explain;
27mod fix;
28mod flow;
29mod init;
30mod lint_fmt;
31mod local;
32mod mcp;
33mod merge_captain;
34mod models;
35mod orchestrator;
36mod pack;
37mod package;
38mod persona;
39mod playground;
40mod portal;
41mod precompile;
42mod profile;
43mod provider;
44mod providers;
45mod quickstart;
46mod routes;
47mod run;
48mod runs;
49mod serve;
50mod session;
51mod skill;
52mod skills;
53mod supervisor;
54mod test;
55mod test_bench;
56mod time;
57mod tool;
58mod trace;
59mod trigger;
60mod trust;
61mod try_cmd;
62mod upgrade;
63mod util;
64mod verify;
65mod viz;
66mod watch;
67mod workflow;
68
69pub(crate) use bench::{BenchArgs, BenchCommand, BenchReplayArgs};
70pub(crate) use check::{CheckArgs, CheckOutputFormat};
71pub(crate) use completions::{CompletionShell, CompletionsArgs};
72pub(crate) use config_cmd::{ConfigArgs, ConfigCommand, ConfigInspectArgs, ConfigValidateArgs};
73pub(crate) use connect::{
74    ConnectApiKeyArgs, ConnectArgs, ConnectCommand, ConnectGenericArgs, ConnectGithubArgs,
75    ConnectLinearArgs, ConnectOAuthArgs, ConnectSetupPlanArgs, ConnectStatusArgs,
76};
77pub(crate) use connector::{
78    ConnectorArgs, ConnectorCheckArgs, ConnectorCommand, ConnectorTestArgs,
79};
80pub(crate) use contracts::{
81    ContractsArgs, ContractsBundleArgs, ContractsCommand, ContractsHostCapabilitiesArgs,
82    ContractsOutputArgs,
83};
84pub(crate) use crystallize::{
85    CrystallizeArgs, CrystallizeCommand, CrystallizeIngestArgs, CrystallizeShadowArgs,
86    CrystallizeValidateArgs,
87};
88pub(crate) use demo::DemoArgs;
89pub(crate) use dev::DevArgs;
90pub(crate) use doctor::DoctorArgs;
91pub(crate) use dump::{
92    DumpConnectorMatrixArgs, DumpHighlightKeywordsArgs, DumpProtocolArtifactsArgs,
93    DumpTriggerQuickrefArgs,
94};
95pub use eval::{
96    EvalArgs, EvalCommand, EvalPromptArgs, EvalPromptMode, EvalPromptOutput, EvalToolCallsArgs,
97    EvalToolCallsCommand, EvalToolCallsRegressionArgs,
98};
99pub(crate) use explain::ExplainArgs;
100pub(crate) use fix::FixArgs;
101pub(crate) use flow::{
102    FlowArchivistCommand, FlowArchivistScanArgs, FlowArgs, FlowCommand, FlowReplayAuditArgs,
103    FlowShipCommand, FlowShipWatchArgs,
104};
105pub(crate) use init::{InitArgs, NewArgs, ProjectTemplate};
106pub(crate) use lint_fmt::{FmtArgs, PathTargetsArgs};
107pub(crate) use local::{
108    LocalArgs, LocalCommand, LocalListArgs, LocalProfileArgs, LocalStatusArgs, LocalStopArgs,
109    LocalSwitchArgs,
110};
111pub(crate) use mcp::{McpArgs, McpCommand, McpLoginArgs, McpServeArgs, McpServerRefArgs};
112pub(crate) use merge_captain::{
113    MergeCaptainArgs, MergeCaptainAuditArgs, MergeCaptainAuditFormat, MergeCaptainBackendKind,
114    MergeCaptainCommand, MergeCaptainIterateArgs, MergeCaptainIterateFormat,
115    MergeCaptainLadderArgs, MergeCaptainLadderFormat, MergeCaptainMockCleanupArgs,
116    MergeCaptainMockCommand, MergeCaptainMockInitArgs, MergeCaptainMockServeArgs,
117    MergeCaptainMockStatusArgs, MergeCaptainMockStepArgs, MergeCaptainRunArgs,
118};
119pub(crate) use models::{
120    ModelRecommendArgs, ModelsArgs, ModelsCommand, ModelsInstallArgs, ModelsListArgs,
121    ModelsTestArgs,
122};
123pub(crate) use orchestrator::{
124    OrchestratorArgs, OrchestratorCommand, OrchestratorDeployArgs, OrchestratorDeployProvider,
125    OrchestratorDlqArgs, OrchestratorFireArgs, OrchestratorInspectArgs, OrchestratorLocalArgs,
126    OrchestratorLogFormat, OrchestratorQueueArgs, OrchestratorQueueCommand,
127    OrchestratorQueueDrainArgs, OrchestratorQueueLsArgs, OrchestratorQueuePurgeArgs,
128    OrchestratorRecoverArgs, OrchestratorReloadArgs, OrchestratorReplayArgs,
129    OrchestratorReplayOracleArgs, OrchestratorResumeArgs, OrchestratorServeArgs,
130    OrchestratorStatsArgs, OrchestratorTenantArgs, OrchestratorTenantCommand,
131    OrchestratorTenantCreateArgs, OrchestratorTenantDeleteArgs, OrchestratorTenantLsArgs,
132    OrchestratorTenantSuspendArgs,
133};
134pub use pack::PackArgs;
135pub(crate) use package::{
136    AddArgs, InstallArgs, PackageArgs, PackageArtifactsCommand, PackageCacheCommand,
137    PackageCommand, PublishArgs, RemoveArgs, UpdateArgs,
138};
139pub(crate) use persona::{
140    PersonaArgs, PersonaCheckArgs, PersonaCommand, PersonaControlArgs, PersonaDoctorArgs,
141    PersonaInspectArgs, PersonaListArgs, PersonaNewArgs, PersonaSpendArgs, PersonaStatusArgs,
142    PersonaSupervisionCommand, PersonaSupervisionTailArgs, PersonaTemplateKind, PersonaTickArgs,
143    PersonaTriggerArgs,
144};
145pub(crate) use playground::PlaygroundArgs;
146pub(crate) use portal::PortalArgs;
147pub use precompile::PrecompileArgs;
148pub(crate) use profile::ProfileArgs;
149pub(crate) use provider::{
150    ModelInfoArgs, ProviderCatalogArgs, ProviderProbeArgs, ProviderReadyArgs,
151    ProviderToolProbeArgs, ProviderToolProbeModeArg,
152};
153pub(crate) use providers::{
154    ProvidersArgs, ProvidersCommand, ProvidersExportArgs, ProvidersRefreshArgs,
155    ProvidersValidateArgs,
156};
157pub(crate) use quickstart::QuickstartArgs;
158pub(crate) use routes::RoutesArgs;
159pub(crate) use run::RunArgs;
160pub(crate) use runs::{ReplayArgs, RunsArgs, RunsCommand};
161pub(crate) use serve::{
162    A2aServeArgs, ApiServeArgs, McpServeTransport, ServeAcpArgs, ServeArgs, ServeCommand,
163    ServeMcpArgs, ServeTlsMode,
164};
165pub(crate) use session::{
166    SessionArgs, SessionCommand, SessionExportArgs, SessionImportArgs, SessionSchemaArgs,
167    SessionValidateArgs,
168};
169pub(crate) use skill::{
170    SkillArgs, SkillCommand, SkillEndorseArgs, SkillKeyCommand, SkillKeyGenerateArgs,
171    SkillSignArgs, SkillTrustAddArgs, SkillTrustCommand, SkillTrustListArgs, SkillVerifyArgs,
172    SkillWhoSignedArgs,
173};
174pub(crate) use skills::{
175    SkillsArgs, SkillsCommand, SkillsDumpArgs, SkillsGetArgs, SkillsInspectArgs, SkillsInstallArgs,
176    SkillsListArgs, SkillsMatchArgs, SkillsNewArgs, SkillsResolvedArgs,
177};
178pub(crate) use supervisor::{
179    SupervisorArgs, SupervisorCommand, SupervisorDlqCommand, SupervisorDlqListArgs,
180    SupervisorDlqReplayArgs, SupervisorFireArgs, SupervisorInspectArgs, SupervisorListArgs,
181    SupervisorPauseArgs, SupervisorRecoverArgs, SupervisorReplayArgs, SupervisorResumeArgs,
182    SupervisorStartArgs, SupervisorStopArgs,
183};
184pub(crate) use test::TestArgs;
185pub(crate) use test_bench::{
186    TestBenchArgs, TestBenchCommand, TestBenchExportAnnotationsArgs, TestBenchFidelityArgs,
187    TestBenchReplayArgs, TestBenchRunArgs, TestBenchValidateAnnotationsArgs,
188};
189pub(crate) use time::{TimeArgs, TimeCommand, TimeRunArgs};
190pub(crate) use tool::{ToolArgs, ToolCommand, ToolNewArgs};
191pub(crate) use trace::{TraceArgs, TraceCommand, TraceImportArgs};
192pub(crate) use trigger::{TriggerArgs, TriggerCancelArgs, TriggerCommand, TriggerReplayArgs};
193pub(crate) use try_cmd::TryArgs;
194pub(crate) use upgrade::UpgradeArgs;
195// `TrustOutcomeArg` / `TrustTierArg` are referenced from the cli
196// parser tests only; they're matched via destructuring elsewhere.
197#[allow(unused_imports)]
198pub(crate) use trust::{
199    TrustArgs, TrustCommand, TrustExportArgs, TrustOutcomeArg, TrustQueryArgs, TrustTierArg,
200    TrustVerifyChainArgs,
201};
202pub(crate) use verify::VerifyArgs;
203pub(crate) use viz::VizArgs;
204pub(crate) use watch::WatchArgs;
205pub(crate) use workflow::{
206    WorkflowArgs, WorkflowCommand, WorkflowFunctionToolsArgs, WorkflowNestedCeilingArgs,
207    WorkflowPatchApplyArgs, WorkflowPatchCommand, WorkflowPatchPreviewArgs,
208    WorkflowPatchValidateArgs,
209};
210
211use clap::{Parser, Subcommand};
212
213#[derive(Debug, Parser)]
214#[command(
215    name = "harn",
216    about = "The agent harness language",
217    version,
218    disable_help_subcommand = false,
219    arg_required_else_help = true
220)]
221pub(crate) struct Cli {
222    /// Emit the JSON-schema catalog for every `harn` subcommand that
223    /// exposes a structured `--json` envelope. Pair with
224    /// `--command <name>` to print just one entry.
225    #[arg(long = "json-schemas", global = false)]
226    pub json_schemas: bool,
227
228    /// When combined with `--json-schemas`, restrict the catalog to a
229    /// single command name (e.g. `--command run`).
230    #[arg(
231        long = "command",
232        requires = "json_schemas",
233        value_name = "COMMAND",
234        global = false
235    )]
236    pub schema_command: Option<String>,
237
238    #[command(subcommand)]
239    pub command: Option<Command>,
240}
241
242#[derive(Debug, Subcommand)]
243pub(crate) enum Command {
244    /// Execute a .harn file or an inline expression.
245    #[command(long_about = "\
246Execute a .harn file or an inline expression.
247
248USAGE
249    harn run script.harn
250    harn run -e 'println(\"hello\")'
251    harn run script.harn -- arg1 arg2   (script reads `argv` as list<string>)
252
253CONCURRENCY
254    Harn supports first-class concurrency primitives:
255      - spawn { ... }         — launch a task, return a handle
256      - parallel each LIST    — concurrent map
257      - parallel settle LIST  — concurrent map, collect Ok/Err
258      - parallel N            — N-way fan-out
259      - with { max_concurrent: N }  — cap in-flight workers
260      - channels, retry, select
261    https://harnlang.com/concurrency.html
262
263LLM THROTTLING
264    Providers can be rate-limited via `rpm:` in harn.toml / providers.toml
265    or via `HARN_RATE_LIMIT_<PROVIDER>=N`. Rate limits control throughput
266    (RPM); `max_concurrent` on `parallel` caps simultaneous in-flight jobs.
267
268SCRIPTING
269    LLM-readable one-pager: https://harnlang.com/docs/llm/harn-quickref.html
270    Human cheatsheet:       https://harnlang.com/scripting-cheatsheet.html
271    Full docs:              https://harnlang.com/
272")]
273    Run(RunArgs),
274    /// Type-check .harn files or directories without executing them.
275    Check(CheckArgs),
276    /// Inspect, validate, and emit schemas for layered Harn runtime config.
277    Config(ConfigArgs),
278    /// Explain a diagnostic. Pass a stable `HARN-<CAT>-<NNN>` code
279    /// (optionally with `--json` for the structured envelope), or the
280    /// legacy `--invariant <NAME> <FUNCTION> <FILE>` form to walk the
281    /// control-flow path behind a Harn invariant violation.
282    Explain(ExplainArgs),
283    /// Plan or apply repair-bearing diagnostics under an explicit safety ceiling.
284    Fix(FixArgs),
285    /// Export machine-readable Harn contracts and bundle manifests.
286    Contracts(ContractsArgs),
287    /// Lint .harn files or directories for common issues.
288    Lint(PathTargetsArgs),
289    /// Format .harn files or directories.
290    Fmt(FmtArgs),
291    /// Run user tests or the conformance suite.
292    Test(TestArgs),
293    /// Run a .harn script under a hermetic testbench (paused clock,
294    /// optional LLM/process tapes, fs overlay, deny-by-default network).
295    #[command(name = "test-bench")]
296    TestBench(TestBenchArgs),
297    /// Instrument a wrapped subcommand with phase-level wall-clock
298    /// timing (parse, typecheck, bytecode compile + cache hit/miss,
299    /// run setup, run main) plus per-LLM-call and per-tool-call
300    /// latency. Pair with `--json` for an agent-readable envelope.
301    Time(TimeArgs),
302    /// Scaffold a new project with harn.toml.
303    Init(InitArgs),
304    /// Scaffold a new project, package, or connector from a starter template.
305    New(NewArgs),
306    /// Diagnose the local Harn environment: toolchain version, configured
307    /// LLM providers and credentials, MCP server reachability, file
308    /// permissions on `~/.harn`, and project manifest health. Reports
309    /// each check as ok/warn/fail with a suggested fix.
310    Doctor(DoctorArgs),
311    /// Configure a starter Harn project and LLM provider settings.
312    Quickstart(QuickstartArgs),
313    /// Run a bundled offline demo scenario to see Harn in action without
314    /// API keys. `harn demo` lists scenarios; `harn demo <id>` runs one.
315    Demo(DemoArgs),
316    /// Register outbound connector resources with a provider.
317    Connect(Box<ConnectArgs>),
318    /// Validate pure-Harn connector packages against the connector contract.
319    Connector(ConnectorArgs),
320    /// Serve a Harn workflow over a transport adapter.
321    Serve(ServeArgs),
322    /// Manage remote MCP OAuth credentials and status.
323    Mcp(McpArgs),
324    /// Watch a .harn file and re-run it on changes.
325    Watch(WatchArgs),
326    /// Watch a Harn project and re-typecheck only the modules whose
327    /// public interface fingerprint actually changed.
328    ///
329    /// USAGE
330    ///     harn dev --watch [<root>]
331    ///     harn dev --watch --json
332    ///     harn dev --watch --with-tests
333    ///
334    /// On each file change, the changed module's interface fingerprint
335    /// (BLAKE3 of types + signatures + `pub import` re-exports) is
336    /// recomputed. If it matches the previous fingerprint, only that
337    /// module is re-checked. If it changed, every transitive importer
338    /// is invalidated and re-checked. `--with-tests` extends the loop
339    /// to also re-run `test_*` / `@test`-attributed pipelines in
340    /// every invalidated module.
341    Dev(DevArgs),
342    /// Launch the local Harn observability portal.
343    Portal(PortalArgs),
344    /// Replay and inspect historical trigger dispatches from the event log.
345    Trigger(TriggerArgs),
346    /// Statically enumerate declared trigger routes and their requirements.
347    Routes(RoutesArgs),
348    /// Inspect Harn Flow atom, slice, and predicate audit state.
349    Flow(FlowArgs),
350    /// Validate, preview, and run portable workflow bundles.
351    Workflow(WorkflowArgs),
352    /// Control local durable workflow automations for trusted hosts.
353    Supervisor(SupervisorArgs),
354    /// Import third-party eval traces into replayable Harn fixtures.
355    Trace(TraceArgs),
356    /// Mine repeated traces into a reviewable deterministic Harn workflow candidate.
357    Crystallize(CrystallizeArgs),
358    /// Query and manage trust-graph autonomy state.
359    Trust(TrustArgs),
360    /// Alias for `harn trust`. Query and verify trust-graph autonomy state.
361    #[command(name = "trust-graph")]
362    TrustGraph(TrustArgs),
363    /// Verify a signed Harn provenance receipt.
364    Verify(VerifyArgs),
365    /// Print shell completion script to stdout.
366    Completions(CompletionsArgs),
367    /// Start the orchestrator process that hosts triggers and connector dispatch.
368    Orchestrator(OrchestratorArgs),
369    /// Run a pipeline against a Harn-native host module for fast iteration.
370    Playground(PlaygroundArgs),
371    /// Inspect persisted workflow run records.
372    Runs(RunsArgs),
373    /// Export, import, and validate portable Harn session bundles.
374    Session(SessionArgs),
375    /// Replay a persisted workflow run record.
376    Replay(ReplayArgs),
377    /// Evaluate a run record, run directory, or eval manifest.
378    Eval(EvalArgs),
379    /// Start the interactive REPL.
380    Repl,
381    /// Benchmark a .harn pipeline over repeated runs.
382    Bench(BenchArgs),
383    /// Pre-compile `.harn` sources into the content-addressed bytecode
384    /// cache so cold-start `harn run` for the same source skips parse
385    /// and compile and goes straight to bytecode load.
386    ///
387    /// `harn precompile path/` walks the directory and compiles every
388    /// `.harn` file; `harn precompile script.harn` compiles a single
389    /// file. Artifacts are written adjacent to each source as
390    /// `<name>.harnbc` by default; pass `--out DIR` to redirect them
391    /// into a sibling tree.
392    Precompile(PrecompileArgs),
393    /// Build a signed-ready `.harnpack` run bundle from a Harn entrypoint.
394    ///
395    /// `harn pack <entrypoint>` walks the entrypoint's transitive imports,
396    /// precompiles every module, snapshots the provider catalog and
397    /// stdlib pin, generates a minimal SBOM, and emits a deterministic
398    /// tar.zst container under `<entrypoint>.harnpack` (or `--out`).
399    ///
400    /// `--upgrade <old.harnpack>` reads an existing bundle (v1 or v2) and
401    /// re-emits it under the v2 manifest, preserving the prior bundle's
402    /// workflow graph, triggers, and prompt capsules.
403    ///
404    /// Signing (E6.3) and richer SBOM enumeration (E6.4) land in
405    /// follow-ups; today the bundle ships unsigned with a stdlib-pin SBOM.
406    Pack(PackArgs),
407    /// Render a .harn file as a Mermaid workflow graph.
408    Viz(VizArgs),
409    /// Install dependencies declared in harn.toml.
410    Install(InstallArgs),
411    /// Add a dependency to harn.toml.
412    Add(AddArgs),
413    /// Refresh one or more dependency lock entries.
414    Update(UpdateArgs),
415    /// Remove a dependency from harn.toml and harn.lock.
416    Remove(RemoveArgs),
417    /// Resolve dependencies and write harn.lock without materializing packages.
418    Lock,
419    /// Manage Harn package caches and integrity verification.
420    Package(PackageArgs),
421    /// Prepare a package manifest and bundle for publication. Validates
422    /// `harn.toml` and produces a publishable archive locally; remote
423    /// registry submission is not yet implemented (the resulting
424    /// archive can be installed via `harn add <repo-or-path>` in the
425    /// meantime).
426    Publish(PublishArgs),
427    /// List and inspect durable agent persona manifests.
428    Persona(PersonaArgs),
429    /// Merge Captain transcript oracle and audit (#1013).
430    #[command(name = "merge-captain")]
431    MergeCaptain(MergeCaptainArgs),
432    /// Print resolved metadata for a model alias or model id as JSON.
433    ModelInfo(ModelInfoArgs),
434    /// List, install, recommend, and test configured LLM models.
435    Models(ModelsArgs),
436    /// Manage local LLM runtime lifecycle: enumerate, switch, and stop
437    /// Ollama, llama.cpp, MLX, and other OpenAI-compatible local servers.
438    Local(LocalArgs),
439    /// Validate and generate provider/model catalog artifacts.
440    Providers(ProvidersArgs),
441    /// Print the provider/model catalog Harn loaded as JSON.
442    ProviderCatalog(ProviderCatalogArgs),
443    /// Probe a provider's /models endpoint and optionally verify a served model.
444    ProviderReady(ProviderReadyArgs),
445    /// Snapshot a provider: readiness, served models, loaded models with
446    /// memory/context details. Designed for eval pipelines that need a
447    /// stable telemetry envelope per provider.
448    ProviderProbe(ProviderProbeArgs),
449    /// Run one-tool provider conformance and classify native/text fallback.
450    ProviderToolProbe(ProviderToolProbeArgs),
451    /// One-shot agent_loop with a prompt. Routes through the configured
452    /// provider (or `HARN_LLM_PROVIDER=mock` for offline use).
453    #[command(name = "try")]
454    Try(TryArgs),
455    /// Manage and inspect Harn skills (list/get/dump for the embedded
456    /// corpus; resolved/inspect/match/install/new for FS-resolved skills).
457    Skills(SkillsArgs),
458    /// Manage skill provenance: keys, signatures, verification, and trust policy.
459    Skill(SkillArgs),
460    /// Scaffold and inspect Harn-native custom tools.
461    Tool(ToolArgs),
462    /// Print the decorated version banner.
463    Version,
464    /// Download and atomically replace the running `harn` binary with
465    /// the latest published GitHub release (or a specific tag via
466    /// `--version`). Verifies the archive against the release's
467    /// `SHA256SUMS` manifest before installing.
468    Upgrade(UpgradeArgs),
469    /// Regenerate docs/theme/harn-keywords.js from the live lexer + stdlib sets.
470    ///
471    /// Dev-only. Hidden from `--help` — invoke via
472    /// `cargo run -p harn-cli -- dump-highlight-keywords` or the
473    /// `make gen-highlight` target.
474    #[command(hide = true, name = "dump-highlight-keywords")]
475    DumpHighlightKeywords(DumpHighlightKeywordsArgs),
476    /// Regenerate docs/llm/harn-triggers-quickref.md from the live trigger provider catalog.
477    ///
478    /// Dev-only. Hidden from `--help` — invoke via
479    /// `cargo run -p harn-cli -- dump-trigger-quickref` or the
480    /// `make gen-trigger-quickref` target.
481    #[command(hide = true, name = "dump-trigger-quickref")]
482    DumpTriggerQuickref(DumpTriggerQuickrefArgs),
483    /// Regenerate docs/src/connectors/parity-matrix.md from connector package manifests.
484    ///
485    /// Dev-only. Hidden from `--help` — invoke via
486    /// `cargo run -p harn-cli -- dump-connector-matrix` or the
487    /// `make gen-connector-matrix` target.
488    #[command(hide = true, name = "dump-connector-matrix")]
489    DumpConnectorMatrix(DumpConnectorMatrixArgs),
490    /// Regenerate Harn protocol schemas and TypeScript/Swift bindings.
491    ///
492    /// Dev-only. Hidden from `--help` — invoke via
493    /// `cargo run -p harn-cli -- dump-protocol-artifacts` or the
494    /// `make gen-protocol-artifacts` target.
495    #[command(hide = true, name = "dump-protocol-artifacts")]
496    DumpProtocolArtifacts(DumpProtocolArtifactsArgs),
497}
498
499#[cfg(test)]
500mod tests;