diff --git a/DISASMER_PUBLIC_TREE.json b/DISASMER_PUBLIC_TREE.json index 372a315..cf760af 100644 --- a/DISASMER_PUBLIC_TREE.json +++ b/DISASMER_PUBLIC_TREE.json @@ -1,7 +1,7 @@ { "kind": "disasmer-filtered-public-tree", - "source_commit": "d0ea56e226f6a5fa409ab5284d5c4e550afe2f35", - "release_name": "dryrun-d0ea56e226f6", + "source_commit": "133d7b466c2f96c240f559722bc4b557aa94c091", + "release_name": "dryrun-133d7b466c2f", "filtered_out": [ "private/**", "experiments/**", diff --git a/crates/disasmer-cli/src/main.rs b/crates/disasmer-cli/src/main.rs index 6e95a5a..c0b77aa 100644 --- a/crates/disasmer-cli/src/main.rs +++ b/crates/disasmer-cli/src/main.rs @@ -26,7 +26,21 @@ const DOCTOR_COORDINATOR_TIMEOUT: Duration = Duration::from_millis(500); const DEFAULT_ARTIFACT_EXPORT_MAX_BYTES: u64 = 64 * 1024 * 1024; #[derive(Clone, Debug, Parser)] -#[command(name = "disasmer", version, arg_required_else_help = true)] +#[command( + name = "disasmer", + version, + arg_required_else_help = true, + about = "Disasmer distributed Wasm runtime CLI.", + after_help = "Primary workflow: + 1. disasmer login --browser + 2. disasmer project init + 3. disasmer node enroll; disasmer node attach --worker + 4. disasmer run [entry] --project + 5. Debug with VS Code \"Disasmer: Launch Virtual Process\" or disasmer dap + 6. Inspect with disasmer process status, task list, logs, and artifact list + +Use --json on primary commands for scriptable output. Hosted account creation happens in the browser login flow." +)] struct Cli { #[command(subcommand)] command: Commands, @@ -5887,6 +5901,31 @@ mod tests { } } + #[test] + fn top_level_help_exposes_primary_workflow_without_auth() { + let mut command = Cli::command(); + let help = command.render_help().to_string(); + + for expected in [ + "Primary workflow:", + "disasmer login --browser", + "disasmer project init", + "disasmer node enroll", + "disasmer node attach --worker", + "disasmer run [entry] --project ", + "Disasmer: Launch Virtual Process", + "disasmer dap", + "disasmer process status", + "task list", + "logs", + "artifact list", + "--json", + "Hosted account creation happens in the browser login flow.", + ] { + assert!(help.contains(expected), "help output missing {expected}"); + } + } + #[test] fn top_level_logout_alias_removes_only_cli_session_state() { let temp = tempfile::tempdir().unwrap(); diff --git a/scripts/cli-first-contract-smoke.js b/scripts/cli-first-contract-smoke.js index 58b67e8..9c57a1f 100644 --- a/scripts/cli-first-contract-smoke.js +++ b/scripts/cli-first-contract-smoke.js @@ -138,7 +138,8 @@ assert.doesNotMatch( ); for (const [name, pattern] of [ - ["top-level version metadata", /#\[command\(name = "disasmer", version, arg_required_else_help = true\)\]/], + ["top-level version metadata", /#\[command\([\s\S]*name = "disasmer"[\s\S]*version[\s\S]*arg_required_else_help = true[\s\S]*\)\]/], + ["top-level primary workflow help", /after_help = "Primary workflow:[\s\S]*disasmer login --browser[\s\S]*disasmer node attach --worker[\s\S]*Disasmer: Launch Virtual Process[\s\S]*Hosted account creation happens in the browser login flow\."/], ["top-level logout command", /enum Commands[\s\S]*Logout\(AuthLogoutArgs\)[\s\S]*Auth \{/], ["human report renderer", /fn human_report\(value: &Value\) -> String/], ["shared report emitter", /fn emit_report\(report: &T, json_output: bool\) -> Result<\(\)>/], @@ -164,6 +165,7 @@ for (const [name, pattern] of [ for (const [name, pattern] of [ ["CLI parse coverage", /fn cli_first_mvp_command_surface_parses\(\)/], + ["CLI primary workflow help coverage", /fn top_level_help_exposes_primary_workflow_without_auth\(\)/], ["CLI version coverage", /fn top_level_version_is_available\(\)/], ["CLI JSON parse coverage", /fn cli_first_json_mode_parses_for_primary_commands\(\)/], ["CLI human output coverage", /fn human_report_is_text_not_json\(\)/], diff --git a/scripts/cli-output-mode-smoke.js b/scripts/cli-output-mode-smoke.js index 010c56c..0027dce 100644 --- a/scripts/cli-output-mode-smoke.js +++ b/scripts/cli-output-mode-smoke.js @@ -36,6 +36,17 @@ function assertHuman(name, output, requiredPatterns) { } } +const helpHuman = disasmer(["help"]); +assertHuman("help", helpHuman, [ + /Primary workflow:/, + /disasmer login --browser/, + /disasmer project init/, + /disasmer node attach --worker/, + /Disasmer: Launch Virtual Process/, + /Hosted account creation happens in the browser login flow/, + /--json/, +]); + const loginHuman = disasmer(["login", "--coordinator", "https://coord.example.test"]); assertHuman("login", loginHuman, [ /Disasmer login/,