From b2a70d8938ac215168a93fff91bb80676eb0b58a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 23 Feb 2026 08:55:16 -0800 Subject: [PATCH] cli: prep 0.4.0 stable release --- crates-cli/yaak-cli/README.md | 133 +++++++----------- crates-cli/yaak-cli/src/cli.rs | 10 +- .../yaak-cli/src/commands/environment.rs | 44 +++--- crates-cli/yaak-cli/src/commands/folder.rs | 29 ++-- crates-cli/yaak-cli/src/commands/request.rs | 31 ++-- crates-cli/yaak-cli/src/utils/json.rs | 24 ++++ .../yaak-cli/tests/environment_commands.rs | 52 ++++++- crates-cli/yaak-cli/tests/folder_commands.rs | 48 +++++++ crates-cli/yaak-cli/tests/request_commands.rs | 52 ++++++- npm/README.md | 7 - npm/cli/prepublish.js | 4 +- 11 files changed, 276 insertions(+), 158 deletions(-) delete mode 100644 npm/README.md diff --git a/crates-cli/yaak-cli/README.md b/crates-cli/yaak-cli/README.md index 1820a6e3..65f36868 100644 --- a/crates-cli/yaak-cli/README.md +++ b/crates-cli/yaak-cli/README.md @@ -1,93 +1,66 @@ -# yaak-cli +# Yaak CLI -Command-line interface for Yaak. +The `yaak` CLI for publishing plugins and creating/updating/sending requests. -## Command Overview +## Installation -Current top-level commands: +```sh +npm install @yaakapp/cli +``` + +## Agentic Workflows + +The `yaak` CLI is primarily meant to be used by AI agents, and has the following features: + +- `schema` subcommands to get the JSON Schema for any model (eg. `yaak request schema http`) +- `--json '{...}'` input format to create and update data +- `--verbose` mode for extracting debug info while sending requests +- The ability to send entire workspaces and folders (Supports `--parallel` and `--fail-fast`) + +### Example Prompts + +Use the `yaak` CLI with agents like Claude or Codex to do useful things for you. + +Here are some example prompts: ```text -yaakcli send -yaakcli agent-help -yaakcli workspace list -yaakcli workspace schema [--pretty] -yaakcli workspace show -yaakcli workspace create --name -yaakcli workspace create --json '{"name":"My Workspace"}' -yaakcli workspace create '{"name":"My Workspace"}' -yaakcli workspace update --json '{"id":"wk_abc","description":"Updated"}' -yaakcli workspace delete [--yes] -yaakcli request list -yaakcli request show -yaakcli request send -yaakcli request create --name --url [--method GET] -yaakcli request create --json '{"workspaceId":"wk_abc","name":"Users","url":"https://api.example.com/users"}' -yaakcli request create '{"workspaceId":"wk_abc","name":"Users","url":"https://api.example.com/users"}' -yaakcli request update --json '{"id":"rq_abc","name":"Users v2"}' -yaakcli request delete [--yes] -yaakcli folder list -yaakcli folder show -yaakcli folder create --name -yaakcli folder create --json '{"workspaceId":"wk_abc","name":"Auth"}' -yaakcli folder create '{"workspaceId":"wk_abc","name":"Auth"}' -yaakcli folder update --json '{"id":"fl_abc","name":"Auth v2"}' -yaakcli folder delete [--yes] -yaakcli environment list -yaakcli environment schema [--pretty] -yaakcli environment show -yaakcli environment create --name -yaakcli environment create --json '{"workspaceId":"wk_abc","name":"Production"}' -yaakcli environment create '{"workspaceId":"wk_abc","name":"Production"}' -yaakcli environment update --json '{"id":"ev_abc","color":"#00ff00"}' -yaakcli environment delete [--yes] +Scan my API routes and create a workspace (using yaak cli) with +all the requests needed for me to do manual testing? ``` -Global options: - -- `--data-dir `: use a custom data directory -- `-e, --environment `: environment to use during request rendering/sending -- `-v, --verbose`: verbose send output (events and streamed response body) -- `--log [level]`: enable CLI logging; optional level is `error|warn|info|debug|trace` - -Notes: - -- `send` is currently a shortcut for sending an HTTP request ID. -- `delete` commands prompt for confirmation unless `--yes` is provided. -- In non-interactive mode, `delete` commands require `--yes`. -- `create` and `update` commands support `--json` and positional JSON shorthand. -- For `create` commands, use one input mode at a time. Example: do not combine `` with `--json`. -- Template tags use `${[ ... ]}` syntax (for example `${[API_BASE_URL]}`), not `{{ ... }}`. -- `update` uses JSON Merge Patch semantics (RFC 7386) for partial updates. - -## Examples - -```bash -yaakcli workspace list -yaakcli workspace create --name "My Workspace" -yaakcli workspace show wk_abc -yaakcli workspace update --json '{"id":"wk_abc","description":"Team workspace"}' -yaakcli request list wk_abc -yaakcli request show rq_abc -yaakcli request create wk_abc --name "Users" --url "https://api.example.com/users" -yaakcli request update --json '{"id":"rq_abc","name":"Users v2"}' -yaakcli request send rq_abc -e ev_abc -yaakcli request delete rq_abc --yes -yaakcli folder create wk_abc --name "Auth" -yaakcli folder update --json '{"id":"fl_abc","name":"Auth v2"}' -yaakcli environment create wk_abc --name "Production" -yaakcli environment update --json '{"id":"ev_abc","color":"#00ff00"}' +```text +Send all the GraphQL requests in my workspace ``` -## Roadmap +## Description -Planned command expansion (request schema and polymorphic send) is tracked in `PLAN.md`. +Here's the current print of `yaak --help` -When command behavior changes, update this README and verify with: +```text +Yaak CLI - API client from the command line -```bash -cargo run -q -p yaak-cli -- --help -cargo run -q -p yaak-cli -- request --help -cargo run -q -p yaak-cli -- workspace --help -cargo run -q -p yaak-cli -- folder --help -cargo run -q -p yaak-cli -- environment --help +Usage: yaak [OPTIONS] + +Commands: + auth Authentication commands + plugin Plugin development and publishing commands + send Send a request, folder, or workspace by ID + workspace Workspace commands + request Request commands + folder Folder commands + environment Environment commands + +Options: + --data-dir Use a custom data directory + -e, --environment Environment ID to use for variable substitution + -v, --verbose Enable verbose send output (events and streamed response body) + --log [] Enable CLI logging; optionally set level (error|warn|info|debug|trace) [possible values: error, warn, info, debug, trace] + -h, --help Print help + -V, --version Print version + +Agent Hints: + - Template variable syntax is ${[ my_var ]}, not {{ ... }} + - Template function syntax is ${[ namespace.my_func(a='aaa',b='bbb') ]} + - View JSONSchema for models before creating or updating (eg. `yaak request schema http`) + - Deletion requires confirmation (--yes for non-interactive environments) ``` diff --git a/crates-cli/yaak-cli/src/cli.rs b/crates-cli/yaak-cli/src/cli.rs index 85aa46af..8ddc6c6c 100644 --- a/crates-cli/yaak-cli/src/cli.rs +++ b/crates-cli/yaak-cli/src/cli.rs @@ -68,12 +68,8 @@ pub struct SendArgs { /// Request, folder, or workspace ID pub id: String, - /// Execute requests sequentially (default) - #[arg(long, conflicts_with = "parallel")] - pub sequential: bool, - /// Execute requests in parallel - #[arg(long, conflicts_with = "sequential")] + #[arg(long)] pub parallel: bool, /// Stop on first request failure when sending folders/workspaces @@ -342,8 +338,8 @@ pub enum EnvironmentCommands { 1) yaak environment create --name 2) yaak environment create --json '{"workspaceId":"wk_abc","name":"Production"}' 3) yaak environment create '{"workspaceId":"wk_abc","name":"Production"}' - -Do not combine with --json."#)] + 4) yaak environment create --json '{"name":"Production"}' +"#)] Create { /// Workspace ID for flag-based mode, or positional JSON payload shorthand #[arg(value_name = "WORKSPACE_ID_OR_JSON")] diff --git a/crates-cli/yaak-cli/src/commands/environment.rs b/crates-cli/yaak-cli/src/commands/environment.rs index 1b65e78b..02bb31e9 100644 --- a/crates-cli/yaak-cli/src/commands/environment.rs +++ b/crates-cli/yaak-cli/src/commands/environment.rs @@ -2,8 +2,8 @@ use crate::cli::{EnvironmentArgs, EnvironmentCommands}; use crate::context::CliContext; use crate::utils::confirm::confirm_delete; use crate::utils::json::{ - apply_merge_patch, is_json_shorthand, parse_optional_json, parse_required_json, require_id, - validate_create_id, + apply_merge_patch, is_json_shorthand, merge_workspace_id_arg, parse_optional_json, + parse_required_json, require_id, validate_create_id, }; use crate::utils::schema::append_agent_hints; use schemars::schema_for; @@ -34,18 +34,13 @@ pub fn run(ctx: &CliContext, args: EnvironmentArgs) -> i32 { } fn schema(pretty: bool) -> CommandResult { - let mut schema = - serde_json::to_value(schema_for!(Environment)).map_err(|e| format!( - "Failed to serialize environment schema: {e}" - ))?; + let mut schema = serde_json::to_value(schema_for!(Environment)) + .map_err(|e| format!("Failed to serialize environment schema: {e}"))?; append_agent_hints(&mut schema); - let output = if pretty { - serde_json::to_string_pretty(&schema) - } else { - serde_json::to_string(&schema) - } - .map_err(|e| format!("Failed to format environment schema JSON: {e}"))?; + let output = + if pretty { serde_json::to_string_pretty(&schema) } else { serde_json::to_string(&schema) } + .map_err(|e| format!("Failed to format environment schema JSON: {e}"))?; println!("{output}"); Ok(()) } @@ -83,17 +78,11 @@ fn create( name: Option, json: Option, ) -> CommandResult { - if json.is_some() && workspace_id.as_deref().is_some_and(|v| !is_json_shorthand(v)) { - return Err( - "environment create cannot combine workspace_id with --json payload".to_string() - ); - } + let json_shorthand = + workspace_id.as_deref().filter(|v| is_json_shorthand(v)).map(str::to_owned); + let workspace_id_arg = workspace_id.filter(|v| !is_json_shorthand(v)); - let payload = parse_optional_json( - json, - workspace_id.clone().filter(|v| is_json_shorthand(v)), - "environment create", - )?; + let payload = parse_optional_json(json, json_shorthand, "environment create")?; if let Some(payload) = payload { if name.is_some() { @@ -103,10 +92,11 @@ fn create( validate_create_id(&payload, "environment")?; let mut environment: Environment = serde_json::from_value(payload) .map_err(|e| format!("Failed to parse environment create JSON: {e}"))?; - - if environment.workspace_id.is_empty() { - return Err("environment create JSON requires non-empty \"workspaceId\"".to_string()); - } + merge_workspace_id_arg( + workspace_id_arg.as_deref(), + &mut environment.workspace_id, + "environment create", + )?; if environment.parent_model.is_empty() { environment.parent_model = "environment".to_string(); @@ -121,7 +111,7 @@ fn create( return Ok(()); } - let workspace_id = workspace_id.ok_or_else(|| { + let workspace_id = workspace_id_arg.ok_or_else(|| { "environment create requires workspace_id unless JSON payload is provided".to_string() })?; let name = name.ok_or_else(|| { diff --git a/crates-cli/yaak-cli/src/commands/folder.rs b/crates-cli/yaak-cli/src/commands/folder.rs index b280bdcd..a5f99092 100644 --- a/crates-cli/yaak-cli/src/commands/folder.rs +++ b/crates-cli/yaak-cli/src/commands/folder.rs @@ -2,8 +2,8 @@ use crate::cli::{FolderArgs, FolderCommands}; use crate::context::CliContext; use crate::utils::confirm::confirm_delete; use crate::utils::json::{ - apply_merge_patch, is_json_shorthand, parse_optional_json, parse_required_json, require_id, - validate_create_id, + apply_merge_patch, is_json_shorthand, merge_workspace_id_arg, parse_optional_json, + parse_required_json, require_id, validate_create_id, }; use yaak_models::models::Folder; use yaak_models::util::UpdateSource; @@ -58,15 +58,11 @@ fn create( name: Option, json: Option, ) -> CommandResult { - if json.is_some() && workspace_id.as_deref().is_some_and(|v| !is_json_shorthand(v)) { - return Err("folder create cannot combine workspace_id with --json payload".to_string()); - } + let json_shorthand = + workspace_id.as_deref().filter(|v| is_json_shorthand(v)).map(str::to_owned); + let workspace_id_arg = workspace_id.filter(|v| !is_json_shorthand(v)); - let payload = parse_optional_json( - json, - workspace_id.clone().filter(|v| is_json_shorthand(v)), - "folder create", - )?; + let payload = parse_optional_json(json, json_shorthand, "folder create")?; if let Some(payload) = payload { if name.is_some() { @@ -74,12 +70,13 @@ fn create( } validate_create_id(&payload, "folder")?; - let folder: Folder = serde_json::from_value(payload) + let mut folder: Folder = serde_json::from_value(payload) .map_err(|e| format!("Failed to parse folder create JSON: {e}"))?; - - if folder.workspace_id.is_empty() { - return Err("folder create JSON requires non-empty \"workspaceId\"".to_string()); - } + merge_workspace_id_arg( + workspace_id_arg.as_deref(), + &mut folder.workspace_id, + "folder create", + )?; let created = ctx .db() @@ -90,7 +87,7 @@ fn create( return Ok(()); } - let workspace_id = workspace_id.ok_or_else(|| { + let workspace_id = workspace_id_arg.ok_or_else(|| { "folder create requires workspace_id unless JSON payload is provided".to_string() })?; let name = name.ok_or_else(|| { diff --git a/crates-cli/yaak-cli/src/commands/request.rs b/crates-cli/yaak-cli/src/commands/request.rs index a1de4372..43d76f52 100644 --- a/crates-cli/yaak-cli/src/commands/request.rs +++ b/crates-cli/yaak-cli/src/commands/request.rs @@ -2,8 +2,8 @@ use crate::cli::{RequestArgs, RequestCommands, RequestSchemaType}; use crate::context::CliContext; use crate::utils::confirm::confirm_delete; use crate::utils::json::{ - apply_merge_patch, is_json_shorthand, parse_optional_json, parse_required_json, require_id, - validate_create_id, + apply_merge_patch, is_json_shorthand, merge_workspace_id_arg, parse_optional_json, + parse_required_json, require_id, validate_create_id, }; use crate::utils::schema::append_agent_hints; use schemars::schema_for; @@ -11,8 +11,8 @@ use serde_json::{Map, Value, json}; use std::collections::HashMap; use std::io::Write; use tokio::sync::mpsc; -use yaak_http::sender::HttpResponseEvent as SenderHttpResponseEvent; use yaak::send::{SendHttpRequestByIdWithPluginsParams, send_http_request_by_id_with_plugins}; +use yaak_http::sender::HttpResponseEvent as SenderHttpResponseEvent; use yaak_models::models::{GrpcRequest, HttpRequest, WebsocketRequest}; use yaak_models::queries::any_request::AnyRequest; use yaak_models::util::UpdateSource; @@ -336,15 +336,11 @@ fn create( url: Option, json: Option, ) -> CommandResult { - if json.is_some() && workspace_id.as_deref().is_some_and(|v| !is_json_shorthand(v)) { - return Err("request create cannot combine workspace_id with --json payload".to_string()); - } + let json_shorthand = + workspace_id.as_deref().filter(|v| is_json_shorthand(v)).map(str::to_owned); + let workspace_id_arg = workspace_id.filter(|v| !is_json_shorthand(v)); - let payload = parse_optional_json( - json, - workspace_id.clone().filter(|v| is_json_shorthand(v)), - "request create", - )?; + let payload = parse_optional_json(json, json_shorthand, "request create")?; if let Some(payload) = payload { if name.is_some() || method.is_some() || url.is_some() { @@ -352,12 +348,13 @@ fn create( } validate_create_id(&payload, "request")?; - let request: HttpRequest = serde_json::from_value(payload) + let mut request: HttpRequest = serde_json::from_value(payload) .map_err(|e| format!("Failed to parse request create JSON: {e}"))?; - - if request.workspace_id.is_empty() { - return Err("request create JSON requires non-empty \"workspaceId\"".to_string()); - } + merge_workspace_id_arg( + workspace_id_arg.as_deref(), + &mut request.workspace_id, + "request create", + )?; let created = ctx .db() @@ -368,7 +365,7 @@ fn create( return Ok(()); } - let workspace_id = workspace_id.ok_or_else(|| { + let workspace_id = workspace_id_arg.ok_or_else(|| { "request create requires workspace_id unless JSON payload is provided".to_string() })?; let name = name.unwrap_or_default(); diff --git a/crates-cli/yaak-cli/src/utils/json.rs b/crates-cli/yaak-cli/src/utils/json.rs index 1c6b2744..7f2fbde9 100644 --- a/crates-cli/yaak-cli/src/utils/json.rs +++ b/crates-cli/yaak-cli/src/utils/json.rs @@ -63,6 +63,30 @@ pub fn validate_create_id(payload: &Value, context: &str) -> JsonResult<()> { } } +pub fn merge_workspace_id_arg( + workspace_id_from_arg: Option<&str>, + payload_workspace_id: &mut String, + context: &str, +) -> JsonResult<()> { + if let Some(workspace_id_arg) = workspace_id_from_arg { + if payload_workspace_id.is_empty() { + *payload_workspace_id = workspace_id_arg.to_string(); + } else if payload_workspace_id != workspace_id_arg { + return Err(format!( + "{context} got conflicting workspace_id values between positional arg and JSON payload" + )); + } + } + + if payload_workspace_id.is_empty() { + return Err(format!( + "{context} requires non-empty \"workspaceId\" in JSON payload or positional workspace_id" + )); + } + + Ok(()) +} + pub fn apply_merge_patch(existing: &T, patch: &Value, id: &str, context: &str) -> JsonResult where T: Serialize + DeserializeOwned, diff --git a/crates-cli/yaak-cli/tests/environment_commands.rs b/crates-cli/yaak-cli/tests/environment_commands.rs index 04264a1d..30e411db 100644 --- a/crates-cli/yaak-cli/tests/environment_commands.rs +++ b/crates-cli/yaak-cli/tests/environment_commands.rs @@ -79,6 +79,54 @@ fn json_create_and_update_merge_patch_round_trip() { .stdout(contains("\"color\": \"#00ff00\"")); } +#[test] +fn create_merges_positional_workspace_id_into_json_payload() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + + let create_assert = cli_cmd(data_dir) + .args([ + "environment", + "create", + "wk_test", + "--json", + r#"{"name":"Merged Environment"}"#, + ]) + .assert() + .success(); + let environment_id = parse_created_id(&create_assert.get_output().stdout, "environment create"); + + cli_cmd(data_dir) + .args(["environment", "show", &environment_id]) + .assert() + .success() + .stdout(contains("\"workspaceId\": \"wk_test\"")) + .stdout(contains("\"name\": \"Merged Environment\"")); +} + +#[test] +fn create_rejects_conflicting_workspace_ids_between_arg_and_json() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + seed_workspace(data_dir, "wk_other"); + + cli_cmd(data_dir) + .args([ + "environment", + "create", + "wk_test", + "--json", + r#"{"workspaceId":"wk_other","name":"Mismatch"}"#, + ]) + .assert() + .failure() + .stderr(contains( + "environment create got conflicting workspace_id values between positional arg and JSON payload", + )); +} + #[test] fn environment_schema_outputs_json_schema() { let temp_dir = TempDir::new().expect("Failed to create temp dir"); @@ -91,6 +139,8 @@ fn environment_schema_outputs_json_schema() { .stdout(contains("\"type\":\"object\"")) .stdout(contains("\"x-yaak-agent-hints\"")) .stdout(contains("\"templateVariableSyntax\":\"${[ my_var ]}\"")) - .stdout(contains("\"templateFunctionSyntax\":\"${[ namespace.my_func(a='aaa',b='bbb') ]}\"")) + .stdout(contains( + "\"templateFunctionSyntax\":\"${[ namespace.my_func(a='aaa',b='bbb') ]}\"", + )) .stdout(contains("\"workspaceId\"")); } diff --git a/crates-cli/yaak-cli/tests/folder_commands.rs b/crates-cli/yaak-cli/tests/folder_commands.rs index 559beb16..8b250b22 100644 --- a/crates-cli/yaak-cli/tests/folder_commands.rs +++ b/crates-cli/yaak-cli/tests/folder_commands.rs @@ -72,3 +72,51 @@ fn json_create_and_update_merge_patch_round_trip() { .stdout(contains("\"name\": \"Json Folder\"")) .stdout(contains("\"description\": \"Folder Description\"")); } + +#[test] +fn create_merges_positional_workspace_id_into_json_payload() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + + let create_assert = cli_cmd(data_dir) + .args([ + "folder", + "create", + "wk_test", + "--json", + r#"{"name":"Merged Folder"}"#, + ]) + .assert() + .success(); + let folder_id = parse_created_id(&create_assert.get_output().stdout, "folder create"); + + cli_cmd(data_dir) + .args(["folder", "show", &folder_id]) + .assert() + .success() + .stdout(contains("\"workspaceId\": \"wk_test\"")) + .stdout(contains("\"name\": \"Merged Folder\"")); +} + +#[test] +fn create_rejects_conflicting_workspace_ids_between_arg_and_json() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + seed_workspace(data_dir, "wk_other"); + + cli_cmd(data_dir) + .args([ + "folder", + "create", + "wk_test", + "--json", + r#"{"workspaceId":"wk_other","name":"Mismatch"}"#, + ]) + .assert() + .failure() + .stderr(contains( + "folder create got conflicting workspace_id values between positional arg and JSON payload", + )); +} diff --git a/crates-cli/yaak-cli/tests/request_commands.rs b/crates-cli/yaak-cli/tests/request_commands.rs index 37baffd2..cdb78c1f 100644 --- a/crates-cli/yaak-cli/tests/request_commands.rs +++ b/crates-cli/yaak-cli/tests/request_commands.rs @@ -130,6 +130,54 @@ fn create_allows_workspace_only_with_empty_defaults() { assert_eq!(request.url, ""); } +#[test] +fn create_merges_positional_workspace_id_into_json_payload() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + + let create_assert = cli_cmd(data_dir) + .args([ + "request", + "create", + "wk_test", + "--json", + r#"{"name":"Merged Request","url":"https://example.com"}"#, + ]) + .assert() + .success(); + let request_id = parse_created_id(&create_assert.get_output().stdout, "request create"); + + cli_cmd(data_dir) + .args(["request", "show", &request_id]) + .assert() + .success() + .stdout(contains("\"workspaceId\": \"wk_test\"")) + .stdout(contains("\"name\": \"Merged Request\"")); +} + +#[test] +fn create_rejects_conflicting_workspace_ids_between_arg_and_json() { + let temp_dir = TempDir::new().expect("Failed to create temp dir"); + let data_dir = temp_dir.path(); + seed_workspace(data_dir, "wk_test"); + seed_workspace(data_dir, "wk_other"); + + cli_cmd(data_dir) + .args([ + "request", + "create", + "wk_test", + "--json", + r#"{"workspaceId":"wk_other","name":"Mismatch"}"#, + ]) + .assert() + .failure() + .stderr(contains( + "request create got conflicting workspace_id values between positional arg and JSON payload", + )); +} + #[test] fn request_send_persists_response_body_and_events() { let temp_dir = TempDir::new().expect("Failed to create temp dir"); @@ -191,7 +239,9 @@ fn request_schema_http_outputs_json_schema() { .stdout(contains("\"type\":\"object\"")) .stdout(contains("\"x-yaak-agent-hints\"")) .stdout(contains("\"templateVariableSyntax\":\"${[ my_var ]}\"")) - .stdout(contains("\"templateFunctionSyntax\":\"${[ namespace.my_func(a='aaa',b='bbb') ]}\"")) + .stdout(contains( + "\"templateFunctionSyntax\":\"${[ namespace.my_func(a='aaa',b='bbb') ]}\"", + )) .stdout(contains("\"authentication\":")) .stdout(contains("/foo/:id/comments/:commentId")) .stdout(contains("put concrete values in `urlParameters`")); diff --git a/npm/README.md b/npm/README.md deleted file mode 100644 index e605cd9f..00000000 --- a/npm/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Yaak CLI NPM Packages - -The Rust `yaak` CLI binary is published to NPM with a meta package (`@yaakapp/cli`) and -platform-specific optional dependency packages. The package exposes both `yaak` and `yaakcli` -commands for compatibility. - -This follows the same strategy previously used in the standalone `yaak-cli` repo. diff --git a/npm/cli/prepublish.js b/npm/cli/prepublish.js index cddc3052..47dd4e8c 100644 --- a/npm/cli/prepublish.js +++ b/npm/cli/prepublish.js @@ -1,5 +1,5 @@ const fs = require("node:fs"); const path = require("node:path"); -const readme = path.join(__dirname, "..", "..", "README.md"); -fs.copyFileSync(readme, path.join(__dirname, "README.md")); +const cliReadme = path.join(__dirname, "..", "..", "crates-cli", "yaak-cli", "README.md"); +fs.copyFileSync(cliReadme, path.join(__dirname, "README.md"));