Skip to main content

path_cli/
lib.rs

1pub mod artifact;
2mod cache;
3#[cfg(all(feature = "resume-remote", not(target_os = "emscripten")))]
4mod claude_session;
5#[cfg(not(target_os = "emscripten"))]
6mod cmd_auth;
7mod cmd_cache;
8#[cfg(not(target_os = "emscripten"))]
9mod cmd_config;
10mod cmd_derive;
11mod cmd_export;
12mod cmd_haiku;
13mod cmd_import;
14mod cmd_incept;
15mod cmd_kind;
16mod cmd_list;
17mod cmd_merge;
18mod cmd_p;
19mod cmd_p_query;
20#[cfg(not(target_os = "emscripten"))]
21mod cmd_pathbase;
22mod cmd_project;
23mod cmd_query;
24mod cmd_render;
25#[cfg(not(target_os = "emscripten"))]
26pub mod cmd_resume;
27#[cfg(not(target_os = "emscripten"))]
28mod cmd_share;
29#[cfg(not(target_os = "emscripten"))]
30mod cmd_show;
31mod cmd_track;
32mod cmd_validate;
33mod config;
34mod derive;
35#[cfg(not(target_os = "emscripten"))]
36mod fuzzy;
37#[cfg(not(target_os = "emscripten"))]
38pub mod harness;
39mod io;
40pub mod kinds;
41mod providers;
42mod query;
43mod remote;
44mod schema;
45#[cfg(not(target_os = "emscripten"))]
46mod share_config;
47#[cfg(all(not(target_os = "emscripten"), feature = "embedded-picker"))]
48mod skim_picker;
49#[cfg(all(unix, not(target_os = "emscripten"), feature = "resume-remote"))]
50mod ssh;
51mod sync;
52mod term;
53
54use anyhow::Result;
55use clap::{Parser, Subcommand};
56
57#[derive(Parser, Debug)]
58#[command(name = "path", version)]
59#[command(about = "Derive, query, and visualize Toolpath provenance documents")]
60struct Cli {
61    #[command(subcommand)]
62    command: Commands,
63
64    /// Pretty-print JSON output
65    #[arg(long, global = true)]
66    pretty: bool,
67
68    /// Backend for the interactive fuzzy picker used by `share`,
69    /// `resume`, and `p import <provider>`. `auto` (default) uses the
70    /// embedded skim picker and falls back to external `fzf` only when
71    /// skim isn't compiled in; a hint is printed if `fzf` is also on
72    /// PATH. `fzf`/`skim` force one backend and error if it isn't
73    /// available.
74    #[cfg(not(target_os = "emscripten"))]
75    #[arg(long, global = true, value_enum, default_value_t = fuzzy::Picker::Auto)]
76    picker: fuzzy::Picker,
77}
78
79#[derive(Subcommand, Debug)]
80enum Commands {
81    /// Show a single session as a markdown summary (used by fzf preview)
82    #[cfg(not(target_os = "emscripten"))]
83    Show {
84        #[command(subcommand)]
85        source: cmd_show::ShowSource,
86        /// Emit ANSI-styled terminal output instead of raw markdown
87        /// (bold speakers, dim metadata, colored diffs). Used by the
88        /// fzf preview panes.
89        #[arg(long)]
90        ansi: bool,
91    },
92    /// Share an agent session to Pathbase via an interactive picker
93    #[cfg(not(target_os = "emscripten"))]
94    Share {
95        #[command(flatten)]
96        args: cmd_share::ShareArgs,
97    },
98    /// Resume an agent session into the chosen harness, projecting the
99    /// document and exec'ing the harness's resume command.
100    #[cfg(not(target_os = "emscripten"))]
101    Resume {
102        #[command(flatten)]
103        args: cmd_resume::ResumeArgs,
104    },
105    /// Query the local cache: load every step into one JSON array and
106    /// transform it with a jaq (jq) filter
107    Query {
108        #[command(flatten)]
109        args: cmd_query::QueryArgs,
110    },
111    /// List bundled document kinds, or print a kind's schema (the field
112    /// reference for `path query`)
113    Kind {
114        #[command(flatten)]
115        args: cmd_kind::KindArgs,
116    },
117    /// Manage Pathbase credentials for trace uploads
118    #[cfg(not(target_os = "emscripten"))]
119    Auth {
120        #[command(subcommand)]
121        op: cmd_auth::AuthOp,
122    },
123    /// Edit the user configuration (~/.toolpath/config.toml)
124    #[cfg(not(target_os = "emscripten"))]
125    Config {
126        #[command(subcommand)]
127        op: cmd_config::ConfigOp,
128    },
129    /// Plumbing: lower-level operations on documents and sources
130    /// (import, export, cache, list, render, merge, validate, derive,
131    /// project, incept, track, query)
132    P {
133        #[command(subcommand)]
134        command: cmd_p::PCommand,
135    },
136    /// Print a random Toolpath haiku
137    Haiku,
138}
139
140pub fn run() -> Result<()> {
141    let cli = Cli::parse();
142
143    let config = config::Config::load()?;
144
145    #[cfg(not(target_os = "emscripten"))]
146    fuzzy::set_picker_override(cli.picker);
147
148    match cli.command {
149        Commands::Haiku => {
150            cmd_haiku::run();
151            Ok(())
152        }
153        #[cfg(not(target_os = "emscripten"))]
154        Commands::Show { source, ansi } => cmd_show::run(source, ansi, &config),
155        #[cfg(not(target_os = "emscripten"))]
156        Commands::Share { args } => cmd_share::run(args),
157        #[cfg(not(target_os = "emscripten"))]
158        Commands::Resume { args } => {
159            #[cfg(all(unix, feature = "resume-remote"))]
160            if let Some(dest) = args.remote.dest.clone() {
161                return cmd_resume::run_remote(dest, args, &config);
162            }
163            cmd_resume::run(args)
164        }
165        Commands::Query { args } => cmd_query::run(args, cli.pretty, &config),
166        Commands::Kind { args } => cmd_kind::run(args),
167        #[cfg(not(target_os = "emscripten"))]
168        Commands::Auth { op } => cmd_auth::run(op),
169        #[cfg(not(target_os = "emscripten"))]
170        Commands::Config { op } => cmd_config::run(op),
171        Commands::P { command } => cmd_p::run(command, cli.pretty, &config),
172    }
173}