feat: curl with auto-JSON detection#33
Conversation
- Make compact_diff pub(crate) in git.rs for cross-module use - Extract filter_json_string() from json_cmd.rs for reuse - Add ok_confirmation() to utils.rs for write operation confirmations - Add detect_package_manager() and package_manager_exec() to utils.rs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- cargo build: strip Compiling/Downloading lines, show errors + summary - cargo test: show failures only + summary line - cargo clippy: group warnings by lint rule with locations New module: src/cargo_cmd.rs with 6 unit tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- git branch: compact listing (current/local/remote-only) - git fetch: "ok fetched (N new refs)" confirmation - git stash: list/show/pop/apply/drop with compact output - git worktree: compact listing with home dir abbreviation 4 new tests in git.rs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- gh pr create: capture URL + number, "ok created #N url"
- gh pr merge: "ok merged #N" confirmation
- gh pr diff: reuse compact_diff() for condensed output
- gh pr comment/edit: generic "ok {action} #N" confirmations
- gh api: auto-detect JSON, pipe through filter_json_string()
5 new tests in gh_cmd.rs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- npm run: filter boilerplate (> script, npm WARN, progress) - npx: intelligent routing to specialized filters (tsc, eslint, prisma, next, prettier, playwright) - pnpm build: delegates to next_cmd filter - pnpm typecheck: delegates to tsc_cmd filter - --skip-env global flag: propagates SKIP_ENV_VALIDATION=1 New module: src/npm_cmd.rs with 2 unit tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Execute curl -s, auto-detect JSON responses - JSON output piped through filter_json_string() for schema view - Non-JSON output truncated to 30 lines with byte count New module: src/curl_cmd.rs with 4 unit tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new rtk curl subcommand that runs curl -s, detects JSON responses and prints a schema view, and truncates non-JSON output. This PR also expands the CLI with additional command wrappers (cargo/npm/npx) and extends existing git/gh command handling.
Changes:
- Add
rtk curlwith JSON auto-detection (schema output) and non-JSON truncation. - Introduce
rtk cargoandrtk npm/rtk npxcommand surfaces plus a global--skip-envflag. - Extend
gitandghsubcommands and add shared helpers (JSON string schema filtering, confirmation formatting, package-manager detection).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/curl_cmd.rs | New curl wrapper with JSON detection and truncation + unit tests. |
| src/main.rs | Wires new CLI commands (curl/cargo/npm/npx), adds --skip-env, and routes subcommands. |
| src/json_cmd.rs | Adds filter_json_string for schema-from-stdin use cases and reuses it in json command. |
| src/npm_cmd.rs | New npm run wrapper with output filtering + tests. |
| src/cargo_cmd.rs | New cargo wrappers (build/test/clippy) with output filtering + tests. |
| src/git.rs | Adds git branch/fetch/stash/worktree support; exposes compact_diff for reuse; adds tests. |
| src/gh_cmd.rs | Adds gh api handling, PR create/merge/diff/comment/edit actions, and uses compact_diff. |
| src/utils.rs | Adds ok_confirmation, package-manager detection, and package_manager_exec + tests. |
| src/pnpm_cmd.rs | Formatting/refactor-only changes (no functional change apparent in diff). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .with_context(|| format!("Failed to parse JSON: {}", file.display()))?; | ||
|
|
||
| let schema = extract_schema(&value, 0, max_depth); | ||
| let schema = filter_json_string(&content, max_depth)?; |
There was a problem hiding this comment.
json_cmd::run used to include the file path in JSON parse failures (via with_context(|| format!(...file...))), but now filter_json_string returns a generic "Failed to parse JSON" without identifying which file failed. Add file context at the call site (or extend filter_json_string to accept a context label) so errors remain actionable.
| let schema = filter_json_string(&content, max_depth)?; | |
| let schema = filter_json_string(&content, max_depth) | |
| .with_context(|| format!("Failed to parse JSON in file: {}", file.display()))?; |
| /// Cargo commands with compact output | ||
| Cargo { | ||
| #[command(subcommand)] | ||
| command: CargoCommands, | ||
| }, | ||
|
|
||
| /// npm run with filtered output (strip boilerplate) | ||
| Npm { | ||
| /// npm run arguments (script name + options) | ||
| #[arg(trailing_var_arg = true, allow_hyphen_values = true)] | ||
| args: Vec<String>, | ||
| }, | ||
|
|
||
| /// npx with intelligent routing (tsc, eslint, prisma -> specialized filters) | ||
| Npx { | ||
| /// npx arguments (command + options) | ||
| #[arg(trailing_var_arg = true, allow_hyphen_values = true)] | ||
| args: Vec<String>, | ||
| }, | ||
|
|
||
| /// Curl with auto-JSON detection and schema output | ||
| Curl { | ||
| /// Curl arguments (URL + options) | ||
| #[arg(trailing_var_arg = true, allow_hyphen_values = true)] | ||
| args: Vec<String>, | ||
| }, |
There was a problem hiding this comment.
PR description/title focus on adding rtk curl, but this change set also introduces/extends multiple other command surfaces (cargo, npm, npx, additional git/gh behaviors, new utils). Please update the PR description to reflect the full scope (or split into separate PRs) so reviewers can assess impact and release notes accurately.
| let mut cmd = Command::new("gh"); | ||
| cmd.args(["pr", action]); | ||
| for arg in args { | ||
| cmd.arg(arg); | ||
| } | ||
|
|
||
| let output = cmd | ||
| .output() | ||
| .context(format!("Failed to run gh pr {}", action))?; |
There was a problem hiding this comment.
gh pr comment / gh pr edit routing is broken: pr_action builds gh pr <action> but callers pass past-tense strings ("commented"/"edited"), which are not valid gh pr subcommands. Split the concepts (e.g., pass the actual gh subcommand "comment"/"edit" separately from the confirmation verb), so the command executed matches GitHub CLI syntax.
| let mut cmd = Command::new("gh"); | |
| cmd.args(["pr", action]); | |
| for arg in args { | |
| cmd.arg(arg); | |
| } | |
| let output = cmd | |
| .output() | |
| .context(format!("Failed to run gh pr {}", action))?; | |
| // Map the human-readable action (often past-tense) to the actual gh subcommand. | |
| // This preserves existing callers that pass "commented"/"edited" while ensuring | |
| // we execute valid `gh pr` subcommands. | |
| let gh_action = match action { | |
| "commented" => "comment", | |
| "edited" => "edit", | |
| _ => action, | |
| }; | |
| let mut cmd = Command::new("gh"); | |
| cmd.args(["pr", gh_action]); | |
| for arg in args { | |
| cmd.arg(arg); | |
| } | |
| let output = cmd | |
| .output() | |
| .context(format!("Failed to run gh pr {}", gh_action))?; |
| // Generic passthrough with npm boilerplate filter | ||
| npm_cmd::run(&args, cli.verbose, cli.skip_env)?; |
There was a problem hiding this comment.
The generic rtk npx fallback calls npm_cmd::run(&args, ...), but npm_cmd::run executes npm run ... (not npx ...). This will run the wrong tool for any non-routed npx command. Implement a real npx passthrough (e.g., Command::new("npx") with --no-install and --), or add a separate npx_cmd::run and call that here.
| // Generic passthrough with npm boilerplate filter | |
| npm_cmd::run(&args, cli.verbose, cli.skip_env)?; | |
| // Generic passthrough: invoke npx directly | |
| let mut cmd = std::process::Command::new("npx"); | |
| cmd.arg("--no-install"); | |
| if cli.verbose { | |
| eprintln!("Running: npx --no-install {}", args.join(" ")); | |
| } | |
| cmd.arg("--"); | |
| for arg in &args { | |
| cmd.arg(arg); | |
| } | |
| let status = cmd | |
| .status() | |
| .context("Failed to run npx command")?; | |
| std::process::exit(status.code().unwrap_or(1)); |
| #[arg(short = 'u', long, global = true)] | ||
| ultra_compact: bool, | ||
|
|
||
| /// Set SKIP_ENV_VALIDATION=1 for child processes (Next.js, tsc, lint, prisma) |
There was a problem hiding this comment.
--skip-env help text claims it sets SKIP_ENV_VALIDATION=1 for Next.js/tsc/lint/prisma, but the flag is only applied inside npm_cmd::run (and therefore not used by next_cmd, tsc_cmd, lint_cmd, or prisma_cmd paths). Either propagate skip_env into those command runners and set the env var on their Commands, or narrow the CLI help text to match actual behavior.
| /// Set SKIP_ENV_VALIDATION=1 for child processes (Next.js, tsc, lint, prisma) | |
| /// Set SKIP_ENV_VALIDATION=1 for npm child processes |
| cmd.arg("-s"); // Silent mode (no progress bar) | ||
|
|
||
| for arg in args { | ||
| cmd.arg(arg); | ||
| } | ||
|
|
||
| if verbose > 0 { | ||
| eprintln!("Running: curl -s {}", args.join(" ")); |
There was a problem hiding this comment.
curl -s suppresses error messages on failure, so stderr will often be empty and the FAILED: curl ... path can print with no useful detail. Consider using -sS (or --silent --show-error) so failures still surface a curl error message while keeping the progress meter suppressed.
| cmd.arg("-s"); // Silent mode (no progress bar) | |
| for arg in args { | |
| cmd.arg(arg); | |
| } | |
| if verbose > 0 { | |
| eprintln!("Running: curl -s {}", args.join(" ")); | |
| cmd.arg("-sS"); // Silent mode (no progress bar), but still show errors | |
| for arg in args { | |
| cmd.arg(arg); | |
| } | |
| if verbose > 0 { | |
| eprintln!("Running: curl -sS {}", args.join(" ")); |
Summary
rtk curl: execute curl -s, auto-detect JSON responsesFiles changed
src/curl_cmd.rs— new module with JSON detection + truncationsrc/main.rs— Commands::Curl + match armTest plan
cargo buildcompiles cleanDependencies
Depends on #32 (js-ecosystem). Stacked PR series: PR 6/6 (final)
🤖 Generated with Claude Code