From 3b7ac453728b56a46436ab8238d192c6753037c7 Mon Sep 17 00:00:00 2001 From: Ayeshas09 Date: Thu, 23 Apr 2026 15:27:27 +0500 Subject: [PATCH 1/5] feat: add apimatic sdk skill --- .gitignore | 1 + skills/apimatic-sdk/SKILL.md | 347 ++++ skills/apimatic-sdk/evals/evals.json | 1423 +++++++++++++++++ skills/apimatic-sdk/evals/grade.py | 98 ++ .../evals/workspace/eval-0-response.md | 96 ++ .../evals/workspace/eval-1-response.md | 11 + .../evals/workspace/eval-10-response.md | 34 + .../evals/workspace/eval-11-response.md | 57 + .../evals/workspace/eval-12-response.md | 7 + .../evals/workspace/eval-13-response.md | 37 + .../evals/workspace/eval-14-response.md | 52 + .../evals/workspace/eval-15-response.md | 43 + .../evals/workspace/eval-16-response.md | 27 + .../evals/workspace/eval-19-response.md | 33 + .../evals/workspace/eval-2-response.md | 93 ++ .../evals/workspace/eval-3-response.md | 13 + .../evals/workspace/eval-30-response.md | 40 + .../evals/workspace/eval-4-response.md | 28 + .../evals/workspace/eval-5-response.md | 48 + .../evals/workspace/eval-6-response.md | 35 + .../evals/workspace/eval-7-response.md | 71 + .../evals/workspace/eval-8-response.md | 38 + .../evals/workspace/eval-9-response.md | 28 + .../apimatic-sdk/evals/workspace/grading.json | 569 +++++++ .../examples/generate-customize-save.md | 49 + .../references/code-branding-settings.md | 97 ++ .../references/endpoint-settings.md | 298 ++++ .../apimatic-sdk/references/enum-settings.md | 117 ++ .../references/exception-settings.md | 101 ++ .../references/first-time-setup.md | 90 ++ .../references/http-configuration-settings.md | 98 ++ .../references/miscellaneous-settings.md | 191 +++ .../apimatic-sdk/references/model-settings.md | 137 ++ .../apimatic-sdk/references/save-changes.md | 80 + .../sdk-docs-configuration-settings.md | 157 ++ .../sdk-interface-customization-settings.md | 281 ++++ .../references/serialization-settings.md | 125 ++ .../timeout-and-retries-settings.md | 198 +++ .../references/user-agent-settings.md | 102 ++ 39 files changed, 5350 insertions(+) create mode 100644 skills/apimatic-sdk/SKILL.md create mode 100644 skills/apimatic-sdk/evals/evals.json create mode 100644 skills/apimatic-sdk/evals/grade.py create mode 100644 skills/apimatic-sdk/evals/workspace/eval-0-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-1-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-10-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-11-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-12-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-13-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-14-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-15-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-16-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-19-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-2-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-3-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-30-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-4-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-5-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-6-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-7-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-8-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/eval-9-response.md create mode 100644 skills/apimatic-sdk/evals/workspace/grading.json create mode 100644 skills/apimatic-sdk/examples/generate-customize-save.md create mode 100644 skills/apimatic-sdk/references/code-branding-settings.md create mode 100644 skills/apimatic-sdk/references/endpoint-settings.md create mode 100644 skills/apimatic-sdk/references/enum-settings.md create mode 100644 skills/apimatic-sdk/references/exception-settings.md create mode 100644 skills/apimatic-sdk/references/first-time-setup.md create mode 100644 skills/apimatic-sdk/references/http-configuration-settings.md create mode 100644 skills/apimatic-sdk/references/miscellaneous-settings.md create mode 100644 skills/apimatic-sdk/references/model-settings.md create mode 100644 skills/apimatic-sdk/references/save-changes.md create mode 100644 skills/apimatic-sdk/references/sdk-docs-configuration-settings.md create mode 100644 skills/apimatic-sdk/references/sdk-interface-customization-settings.md create mode 100644 skills/apimatic-sdk/references/serialization-settings.md create mode 100644 skills/apimatic-sdk/references/timeout-and-retries-settings.md create mode 100644 skills/apimatic-sdk/references/user-agent-settings.md diff --git a/.gitignore b/.gitignore index d24e487..0e60879 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .claude/ +.github/ apimatic-portal-workspace/ skills/apimatic-portal/evals/workspace/ skills/apimatic-portal/evals/results.json diff --git a/skills/apimatic-sdk/SKILL.md b/skills/apimatic-sdk/SKILL.md new file mode 100644 index 0000000..4dd16ca --- /dev/null +++ b/skills/apimatic-sdk/SKILL.md @@ -0,0 +1,347 @@ +--- +name: apimatic-sdk +description: Use when a user wants to generate, create, customize, or download an SDK using the APIMatic CLI. Also use when the user has already customized a generated SDK and wants to save those changes, when the user wants to make a specific change to an SDK (e.g. "change the analyzer", "switch the linter"), or when the user asks about CodeGen settings, SDK configuration, or APIMATIC-META.json (e.g. "enable retry on timeout", "disable linting", "set the project name"). +--- + +# APIMatic SDK + +Generate SDKs for your APIs in multiple languages using the APIMatic CLI. + +## When to Use + +- User wants to create, generate, or download an SDK using the APIMatic CLI +- User wants to customize an SDK, asks about custom code injection, or wants to preserve customizations across regenerations +- User mentions `sdk save-changes` or asks how to save SDK changes +- User says they have already customized a generated SDK and want to save or commit those changes +- User asks to customize an SDK in a specific way (e.g. "change the analyzer", "switch the linter", "update the formatter in the PHP SDK") +- User asks to change a CodeGen setting (e.g. "enable retry on timeout", "set the project name", "disable linting", "change the timeout", "enable HTTP cache") — these can be applied via `APIMATIC-META.json` and a regeneration + +## Red Flags — STOP and re-read the relevant section + +- About to pass the spec file path to `--input` → `--input` must point to the parent directory that contains `src/`, not the spec file itself (e.g., `--input=./my-project`, not `--input=./openapi.yaml`) → commands run from project root, never from inside `src/` +- About to add `--zip` when the user didn't ask for it → only include `--zip` if the user explicitly requested a zip download +- About to rerun `sdk generate` with `--force` without asking → when the CLI reports an SDK already exists, ask the user before adding `--force` +- About to `cd src/` before running generate → run from the project root (the directory that _contains_ `src/`), never from inside `src/` +- About to proceed to SDK generation before the user confirms browser auth → wait for user confirmation after launching browser login, then verify with `apimatic auth status` +- About to run `sdk save-changes` without `--track-changes` having been enabled → change tracking must be initialized during generation; regenerate with `--track-changes` first +- About to add `--api-version` when user hasn't mentioned a specific API version → only include `--api-version` when the user explicitly names a version +- About to ask for information the user already stated in their prompt → use what was given; only ask for genuinely unknown values +- About to edit a generated SDK file for a change that could be a CodeGen setting → read each file in `references/` that covers settings (e.g. `endpoint-settings.md`, `http-configuration-settings.md`, `timeout-and-retries-settings.md`, `sdk-interface-customization-settings.md`, etc.) and check whether the change maps to a listed setting; if it does, update `APIMATIC-META.json` and regenerate instead of modifying generated files +- About to pick the first matching CodeGen setting without reading all reference files → read all reference files first, then pick the most suitable match +- About to manually delete or remove a generated folder or file (e.g., `docs/`, `README.md`) as a customization → check codegen settings first; (e.g., removing docs maps to `DisableDocs: true` in `APIMATIC-META.json`) — set this before generating, not after via file deletion or custom code injection +- About to open, read, or edit the `.` files inside `sdk-source-tree/` (e.g., `.typescript`, `.python`) → these files are managed exclusively by the CLI; never touch them directly under any circumstance +- About to manually compare or inspect customizations by reading `sdk-source-tree/` → if the user wants to see what changed between a plain generation and their customized one, regenerate using `--skip-changes` to produce a clean copy, then compare that against the customized SDK; do not manipulate or read the source tree files + +## Communication Guidelines + +This skill is used by developers of all experience levels. All messages shown to the user must be clear, non-technical, and action-oriented. Follow these rules in every response: + +- **Never forward raw CLI output:** Do not paste or quote terminal output, spinner characters, ANSI escape codes, or build logs. Summarize what happened in plain language. +- **Use the verbatim blocks provided:** When this skill provides a specific message to show, output it exactly as written. Do not paraphrase or add technical context around it. +- **Keep error guidance actionable:** When something fails, tell the user what went wrong in simple terms and what they can do about it. Do not describe the internal recovery steps you are attempting — just attempt them silently and report the outcome. +- **When in doubt, less is more:** If you are unsure whether a detail is useful to the user, leave it out. + +## Fast Path — Already-Customized SDK + +If the user's message indicates they have **already made customizations** to a generated SDK and want to save those changes (e.g. "I customized my SDK", "I made changes to the generated SDK", "save my SDK changes", "save changes in it"): + +1. Confirm the Prerequisites section below is satisfied (Node.js, CLI installed). +2. Complete Step 1: Authenticate with APIMatic below. +3. **Check for `sdk-source-tree`** — see the [SDK Source Tree Check](#sdk-source-tree-check) section below. + +## Fast Path — Apply a Specific Customization to an SDK + +If the user asks Claude to make a specific change to an SDK (e.g. "change the phan analyzer to something else", "switch the linter in my PHP SDK", "update the test framework in my TypeScript SDK"): + +1. Confirm the Prerequisites section below is satisfied (Node.js, CLI installed). +2. Complete Step 1: Authenticate with APIMatic below. +3. **Check if the change is a CodeGen setting first** — see the [CodeGen Settings Check](#codegen-settings-check) section below. If the change maps to a CodeGen setting, follow that path instead. +4. If the change is not a CodeGen setting, **check for `sdk-source-tree`** — see the [SDK Source Tree Check](#sdk-source-tree-check) section below. + +Do not ask whether the user wants to customize or save — they have already told you what change to make. Proceed without prompting unless something is genuinely unknown. + +## CodeGen Settings Check + +Before editing any generated SDK files for a customization, check whether the change can be applied as a CodeGen setting in `APIMATIC-META.json`. + +Read each of the following reference files one by one and check whether the requested change maps to a setting described in that file. Read all of them before deciding — pick the most suitable match: + +- `references/user-agent-settings.md` +- `references/code-branding-settings.md` +- `references/endpoint-settings.md` +- `references/enum-settings.md` +- `references/exception-settings.md` +- `references/http-configuration-settings.md` +- `references/miscellaneous-settings.md` +- `references/model-settings.md` +- `references/sdk-docs-configuration-settings.md` +- `references/sdk-interface-customization-settings.md` +- `references/serialization-settings.md` +- `references/timeout-and-retries-settings.md` + +**If a matching setting is found in any of those files:** + +Follow the numbered steps in that reference file to apply the setting and verify the output. Then continue below: + +1. If the input directory is not already known, ask: "What is the path to the directory that contains the `src/` folder?" +2. Open `/src/spec/APIMATIC-META.json`. If this is a fresh project being scaffolded (the main Step 2 — Determine the input directory — is in progress), note the setting and apply it to `APIMATIC-META.json` as part of scaffolding — then continue to generation. If the file does not exist and the project should already have it, follow `references/first-time-setup.md` to scaffold the project first. +3. Locate the `CodeGenSettings` object. Add or update the relevant key with the appropriate value. +4. Save the file. +5. Regenerate the SDK — proceed from [Step 3 to Step 7](#step-3-choose-the-language), skip the steps for which you have the values already known (language, destination, and API version). + +This is always the preferred approach when a CodeGen setting covers the request. Settings applied this way are baked into the generation config and survive every future regeneration — no manual file edits required. + +**If the setting is not listed there:** + +Continue to the [SDK Source Tree Check](#sdk-source-tree-check) for file-level customization. + +--- + +## SDK Source Tree Check + +Look for `/sdk-source-tree/` and within it a file named after the target language (e.g. `.php`, `.typescript`, `.python`). + +**If `sdk-source-tree` is present and has an entry for the target language:** + +Proceed directly to `references/save-changes.md`. + +**If `sdk-source-tree` is absent or has no entry for the target language:** + +Change tracking has never been initialized. Follow Steps 2 through 7 below to generate the SDK with `--track-changes`. Use any values already known from context (language, input dir, API version) — do not ask for them again. Only ask for values that are genuinely unknown. + +There is one additional concern depending on context: + +- **User has already made customizations (Fast Path — Already-Customized SDK):** + The SDK must **not** be generated into the same folder as the user's existing customized SDK — doing so will overwrite their changes. Before running Step 7, ask only for the destination: "Change tracking isn't enabled for this SDK yet. I need to run a fresh generation to initialize it, but generating into your current SDK folder would overwrite your changes. Would you like me to use a temporary folder, or do you have a preferred destination?" + - If user provides a path → use it as `--destination` in Step 4. + - If user says temporary/default → use `/sdk/temp/` as `--destination` in Step 4. After generation, delete the `/sdk/temp` directory — it is not needed. + After Step 7 completes, follow `references/save-changes.md` with `--sdk` pointing at the user's **original** customized SDK path, so their customizations are captured — not the temp output. + +- **Claude is applying the customization (Fast Path — Apply a Specific Customization):** + No destination conflict — proceed through Steps 2–7 normally with `--track-changes`. After generation, apply the requested customizations to the generated SDK following the [Customization Guidelines](#customization-guidelines) section, then follow `references/save-changes.md`. + +--- + +## Prerequisites + +Confirm these are in place before starting: + +- **Node.js >= 20 and npm installed** + If not installed, download from https://nodejs.org (LTS version recommended). Verify with: + + ``` + node --version + ``` + +- **APIMatic account** + Free trial available at app.apimatic.io. Required for authentication. + +- **APIMatic CLI installed globally:** + + ``` + npm install -g @apimatic/cli + ``` + + Verify the CLI is available: + + ``` + apimatic --version + ``` + + If the version command fails, the CLI is not installed. Re-run the install command above. + +--- + +## Step 1: Authenticate with APIMatic + +First check whether the user is already authenticated: + +``` +apimatic auth status +``` + +If the output shows an account email, authentication is already in place — skip to Step 2. + +**Primary flow (browser-based):** + +Run the auth launcher script from the project directory. It spawns `apimatic auth login` as a detached process so the terminal does not block: + +``` +node {skill_dir}/scripts/auth-login.mjs +``` + +Where `{skill_dir}` is the absolute path to the directory containing the `apimatic-sdk` skill file (the `auth-login.mjs` script lives there). + +The script launches the browser OAuth flow and immediately returns. Relay the following message to the user: "A browser window has opened. Complete sign-in in the browser, then confirm here when done." + +Wait for the user to confirm sign-in is complete before proceeding. + +After confirmation, verify auth succeeded: + +``` +apimatic auth status +``` + +The output should show the account email. If it does not, authentication did not complete — try the fallback below. + +**Fallback flow (API key):** + +Use this when browser auth is not available (CI environment, headless system) or when the user prefers a key-based approach. + +Option 1 — CLI flag: + +``` +apimatic auth login --auth-key=YOUR_API_KEY +``` + +Option 2 — environment variable (no login command needed): + +```bash +# macOS / Linux / bash / zsh: +export APIMATIC_API_KEY=YOUR_API_KEY + +# Windows PowerShell: +$env:APIMATIC_API_KEY = "YOUR_API_KEY" + +# Windows Command Prompt: +set APIMATIC_API_KEY=YOUR_API_KEY +``` + +API keys are generated at: APIMatic Dashboard > Account > API Keys. + +**If both methods fail:** + +Stop the workflow. Tell the user: + +"Authentication failed. Check that your APIMatic account is active, your API key is correct, and you have internet access to apimatic.io. If using browser login, try the --auth-key fallback instead." + +Do not proceed past this point until authentication is confirmed. + +## Step 2: Determine the input directory + +If you do not know whether the user has an existing project with a `src/` folder, ask: + +"Is this your first time generating an SDK for this API, or have you generated one before?" + +- **Has a `src/` folder →** Ask: "What is the path to the directory that contains the `src/` folder?" + The `--input` flag will point to this directory. + +- **Starting from scratch →** Read `references/first-time-setup.md` and follow every step in order to scaffold the project directory with `src/spec/`, the user's API spec, and `APIMATIC-META.json`. Then continue to Step 3. + +## Step 3: Choose the language + +If the language is not already known from context, ask the user which language they want to generate the SDK in. Present the supported options: + +| Flag value | Language | +| ------------ | ---------- | +| `csharp` | C# | +| `java` | Java | +| `php` | PHP | +| `python` | Python | +| `ruby` | Ruby | +| `typescript` | TypeScript | +| `go` | Go | + +## Step 4: Choose the destination + +If the destination is not already known from context, ask: "Do you have a specific path where you want the SDK to be generated, or should I use the default location?" + +- **User provides a path →** Use the `--destination` flag with the given path. +- **User says default / no preference →** Omit the `--destination` flag. The SDK will be generated at `/sdk/` (or `/sdk//` if multiple API versions exist). + +## Step 5: Choose the API version + +Check whether the user wants to generate the SDK for a specific API version. Look for phrases like "versioned build", "specific version", "for version X", "v2", "api version", or any mention of targeting a particular version of their API. + +- **User specifies a version →** Add `--api-version=` to the generate command (e.g., `--api-version=v2`). +- **User doesn't mention versioning →** Omit the `--api-version` flag. Do not ask. + +## Step 6: Customization intent + +If the user has already described a specific change they want (e.g., "remove the docs folder", "disable documentation", "set the project name", "disable linting"), **check codegen settings first** — see the [CodeGen Settings Check](#codegen-settings-check) section, which will have you scan the individual reference files — before planning any manual file edits or deletions or additions. + +If the change maps to a CodeGen setting: + +- **New project (being scaffolded now):** Apply the setting to `APIMATIC-META.json` before generating. The setting is baked in from the start — no post-generation editing needed. +- **Existing project (already has `APIMATIC-META.json`):** Apply the setting now and regenerate. The setting takes effect automatically. + +**Never plan to apply a CodeGen-covered customization by manually editing or deleting or adding generated files.** For example, "remove the docs folder" maps to `DisableDocs: true` — the correct fix is to set it before generation, not to delete the output folder afterward as a custom code injection. + +If the change does not map to any CodeGen setting, continue below. + +If not already known from context, ask: "Would you like to customize the SDK after generating it? (e.g., add custom code, modify generated files)" + +- **User says yes →** + + Ask: "Do you already have a generated SDK you've customized, or are you starting fresh?" + - **Already has a customized SDK →** Skip generation entirely. Ask: "Would you like me to apply the customizations, or will you handle them yourself?" then follow the appropriate path below. + - **Starting fresh →** Add the `--track-changes` flag to the generate command. After generation completes in Step 7, ask: "Would you like me to apply the customizations, or will you handle them yourself?" then follow the appropriate path below. + + **If the skill applies customizations:** + + Ask the user what changes they want made. Apply them following the [Customization Guidelines](#customization-guidelines) section at the bottom of this file. Once the changes are in place, follow `references/save-changes.md`. See `examples/generate-customize-save.md` for the expected flow of commands — flags and paths will differ based on the user's setup. + + **If the user applies customizations:** + + See `examples/generate-customize-save.md` for the expected flow of commands — flags and paths will differ based on the user's setup. + + Share these tips before handing off: + + > - Add custom logic in a **new file** where possible — new files are never overwritten on regeneration. + > - Avoid editing generated files directly. + > - If you must edit a generated file, add your changes at the **top or bottom** to reduce merge conflicts. + + Then prompt: "Make your customizations now, then let me know when you're ready to save them." Once they confirm, follow `references/save-changes.md`. + +- **User says no / no preference →** Omit the `--track-changes` flag. + +## Step 7: Generate the SDK + +Navigate to the project root (the directory that contains `src/`): + +``` +cd your-project-directory +``` + +Run the generate command with the chosen language: + +``` +apimatic sdk generate --language= +``` + +To specify the input directory explicitly (the parent directory containing `src/`): + +``` +apimatic sdk generate --input=path/to/parent-of-src --language= +``` + +**With an API key directly (recommended for CI — no interactive auth needed):** + +``` +apimatic sdk generate --input=path/to/parent-of-src --language= --auth-key=YOUR_API_KEY +``` + +**If SDK generation fails:** + +1. **Authentication error:** Re-run `apimatic auth status` to verify. If expired, re-authenticate (Step 1). +2. **Missing `src/` folder or spec file:** Check that the input directory contains a `src/` folder with the API spec in `src/spec/`. +3. **SDK already exists at destination:** The CLI will refuse to overwrite. Immediately ask the user: "An SDK already exists at the destination. Would you like to overwrite it?" If yes, re-run the same command with `--force` appended (see Additional flags). If no, ask for a different destination path and re-run with `--destination=`. +4. **`apimatic` command not found:** Run `npm install -g @apimatic/cli` and verify with `apimatic --version`. +5. **Any other error:** Read the exact error message from the CLI output. Do not retry automatically — diagnose the specific error first. + +## Additional flags + +- `--force, -f` : Overwrite if an SDK already exists in the destination. Use for repeated CI builds. +- `--zip` : Download the generated SDK as a .zip archive instead of a directory. +- `--track-changes` : Enable change tracking to preserve manual customizations across regenerations. Must be used during the initial generation to set up the source tree. See `references/save-changes.md` for how to save changes after generation. +- `--skip-changes` : Generate the SDK without reapplying saved customizations, even if change tracking is enabled. Use when the user wants to preview the plain generated output. Saved customizations are not modified and will still be applied in future runs unless explicitly removed. + +## Customization Guidelines + +Apply these principles whenever you are making SDK customizations on the user's behalf, and share them as tips when the user is customizing themselves. + +1. **Add custom logic in a new file** where possible. +2. **Avoid editing generated files directly.** +3. **If you must edit a generated file**, add your changes at the top or bottom to reduce merge conflicts. + +--- diff --git a/skills/apimatic-sdk/evals/evals.json b/skills/apimatic-sdk/evals/evals.json new file mode 100644 index 0000000..7c83e5d --- /dev/null +++ b/skills/apimatic-sdk/evals/evals.json @@ -0,0 +1,1423 @@ +{ + "skill_name": "apimatic-sdk", + "evals": [ + { + "id": 0, + "prompt": "I need to generate a Python SDK for my API. I haven't used the APIMatic CLI before. My project is at ~/my-api-project/ and it has a src/ folder with my spec in src/spec/. Can you help?", + "expected_output": "The agent checks auth status, walks through the login flow (browser-based primary, API key fallback), waits for user confirmation, asks about destination preference, then runs `apimatic sdk generate --language=python` from the project root. Does NOT add --zip unless the user asked for it.", + "files": [], + "assertions": [ + { + "id": "checks-auth-status", + "description": "Response includes checking auth status before login", + "type": "contains", + "value": "apimatic auth status" + }, + { + "id": "runs-auth-login", + "description": "Response includes the auth login command", + "type": "contains", + "value": "apimatic auth login" + }, + { + "id": "waits-for-user-confirmation", + "description": "Response pauses and asks the user to confirm sign-in before proceeding", + "type": "contains_any", + "value": [ + "confirm", + "let me know", + "once you", + "when you're done", + "when done", + "after you" + ] + }, + { + "id": "generates-python-sdk", + "description": "Response includes the SDK generate command with python language", + "type": "contains", + "value": "--language=python" + }, + { + "id": "does-not-add-zip-unprompted", + "description": "Response does NOT add --zip flag since the user did not request it", + "type": "not_contains", + "value": "--zip" + }, + { + "id": "asks-about-destination", + "description": "Response asks the user about the SDK output destination", + "type": "contains_any", + "value": [ + "destination", + "where you want the SDK", + "output path", + "default location", + "specific path" + ] + } + ] + }, + { + "id": 1, + "prompt": "I already have APIMatic CLI set up and authenticated. Generate a TypeScript SDK for the project at D:\\work\\payments-api\\ — it has the src/ directory with the spec. Give me a zip. Put it in D:\\output\\ts-sdk.", + "expected_output": "The agent skips auth, navigates to or uses --input with the parent directory containing src/, and runs apimatic sdk generate --language=typescript --zip --destination=D:\\output\\ts-sdk.", + "files": [], + "assertions": [ + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user said they are already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "uses-correct-directory", + "description": "Response references the user's project directory path", + "type": "contains_any", + "value": [ + "payments-api", + "D:\\work\\payments-api", + "D:/work/payments-api" + ] + }, + { + "id": "generates-typescript-sdk", + "description": "Response includes the SDK generate command with typescript language", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "includes-zip-flag", + "description": "Response includes --zip flag as requested by the user", + "type": "contains", + "value": "--zip" + }, + { + "id": "uses-custom-destination", + "description": "Response uses the --destination flag with the user's specified path", + "type": "contains_any", + "value": [ + "--destination", + "D:\\output\\ts-sdk", + "D:/output/ts-sdk" + ] + }, + { + "id": "runs-from-project-root", + "description": "Response runs from the project root (parent of src/), not from inside src/", + "type": "not_contains", + "value": "cd src" + } + ] + }, + { + "id": 2, + "prompt": "I want to create a Go SDK for my REST API. I have my OpenAPI spec at ./openapi.yaml but no project directory set up yet. What do I do?", + "expected_output": "The agent tells the user they need to create a project directory with a src/ folder and place the spec inside src/spec/ before generating. Does NOT run apimatic sdk generate against a raw spec file.", + "files": [], + "assertions": [ + { + "id": "mentions-src-directory", + "description": "Response tells user to create src/ directory structure", + "type": "contains_any", + "value": [ + "src/", + "src\\", + "src folder", + "src directory" + ] + }, + { + "id": "mentions-spec-in-src-spec", + "description": "Response tells user to place the spec in src/spec/", + "type": "contains_any", + "value": [ + "src/spec", + "src\\spec", + "spec/" + ] + }, + { + "id": "does-not-generate-directly", + "description": "Response does NOT directly run sdk generate against the raw spec file without setup", + "type": "not_contains", + "value": "apimatic sdk generate --input=./openapi.yaml" + }, + { + "id": "mentions-go-language", + "description": "Response acknowledges the Go language choice", + "type": "contains_any", + "value": [ + "go", + "Go", + "--language=go" + ] + }, + { + "id": "does-not-mention-portal-skill", + "description": "Response does NOT direct user to the portal skill — tells them to set up manually", + "type": "not_contains_any", + "value": [ + "portal skill", + "apimatic-portal", + "apimatic portal" + ] + } + ] + }, + { + "id": 3, + "prompt": "I already generated a C# SDK yesterday but I need to regenerate it with some spec changes. The project is at ./my-api/ and I'm already logged in. Just overwrite the old one.", + "expected_output": "The agent skips auth, runs apimatic sdk generate --language=csharp --force from the project directory to overwrite the existing SDK.", + "files": [], + "assertions": [ + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user said they are logged in", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "generates-csharp-sdk", + "description": "Response includes the SDK generate command with csharp language", + "type": "contains", + "value": "--language=csharp" + }, + { + "id": "uses-force-flag", + "description": "Response includes --force flag to overwrite the existing SDK", + "type": "contains", + "value": "--force" + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "my-api", + "./my-api" + ] + }, + { + "id": "does-not-add-zip-unprompted", + "description": "Response does NOT add --zip since user did not request it", + "type": "not_contains", + "value": "--zip" + } + ] + }, + { + "id": 4, + "prompt": "Generate a Ruby SDK for my API project at ~/ruby-project/. I'm authenticated. Use the default output location, no zip needed.", + "expected_output": "The agent skips auth, runs apimatic sdk generate --language=ruby without --destination or --zip flags.", + "files": [], + "assertions": [ + { + "id": "skips-auth", + "description": "Response does NOT run auth login", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "generates-ruby-sdk", + "description": "Response includes the SDK generate command with ruby language", + "type": "contains", + "value": "--language=ruby" + }, + { + "id": "no-destination-flag", + "description": "Response does NOT include --destination since user wants default", + "type": "not_contains", + "value": "--destination" + }, + { + "id": "no-zip-flag", + "description": "Response does NOT include --zip since user explicitly said no zip", + "type": "not_contains", + "value": "--zip" + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "ruby-project", + "~/ruby-project" + ] + } + ] + }, + { + "id": 5, + "prompt": "I completed browser sign-in for APIMatic but apimatic auth status doesn't show my email. How do I fix this?", + "expected_output": "The agent offers the API key fallback (apimatic auth login --auth-key=YOUR_API_KEY), tells the user where to find API keys, and does NOT proceed to SDK generation until auth is confirmed.", + "files": [], + "assertions": [ + { + "id": "offers-api-key-fallback", + "description": "Response offers the --auth-key fallback", + "type": "contains", + "value": "--auth-key" + }, + { + "id": "mentions-api-keys-location", + "description": "Response tells user where to find their API key", + "type": "contains_any", + "value": [ + "API Keys", + "Account > API Keys", + "APIMatic Dashboard", + "app.apimatic.io" + ] + }, + { + "id": "does-not-proceed-to-generate", + "description": "Response does NOT proceed to SDK generation while auth is unconfirmed", + "type": "not_contains", + "value": "apimatic sdk generate" + } + ] + }, + { + "id": 6, + "prompt": "I want to generate a Java SDK and I plan to customize the generated code afterwards. My project is at ./my-java-api/ and I'm authenticated.", + "expected_output": "The agent adds the --track-changes flag to enable change tracking so customizations are preserved across regenerations.", + "files": [], + "assertions": [ + { + "id": "skips-auth", + "description": "Response does NOT run auth login", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "generates-java-sdk", + "description": "Response includes the SDK generate command with java language", + "type": "contains", + "value": "--language=java" + }, + { + "id": "uses-track-changes", + "description": "Response includes --track-changes flag since user wants to customize", + "type": "contains", + "value": "--track-changes" + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "my-java-api", + "./my-java-api" + ] + } + ] + }, + { + "id": 7, + "prompt": "I'm setting up a CI/CD pipeline with GitHub Actions to generate a PHP SDK on every push. I have an API key stored as a secret. How do I run the SDK generation non-interactively?", + "expected_output": "The agent recommends apimatic sdk generate --language=php --auth-key=YOUR_API_KEY as the CI-appropriate pattern. Does NOT suggest browser-based login.", + "files": [], + "assertions": [ + { + "id": "runs-sdk-generate", + "description": "Response includes apimatic sdk generate", + "type": "contains", + "value": "apimatic sdk generate" + }, + { + "id": "uses-auth-key-flag", + "description": "Response includes the --auth-key flag", + "type": "contains", + "value": "--auth-key" + }, + { + "id": "generates-php-sdk", + "description": "Response includes --language=php", + "type": "contains", + "value": "--language=php" + }, + { + "id": "recommends-for-ci", + "description": "Response frames --auth-key as appropriate for CI environments", + "type": "contains_any", + "value": [ + "CI", + "non-interactive", + "without browser", + "pipeline", + "GitHub Actions" + ] + }, + { + "id": "no-browser-login-for-ci", + "description": "Response does NOT recommend browser-based login for CI", + "type": "not_contains", + "value": "apimatic auth login\n" + } + ] + }, + { + "id": 8, + "prompt": "I ran npm install -g @apimatic/cli but apimatic --version says command not found. I need to generate a Python SDK.", + "expected_output": "The agent troubleshoots the CLI installation issue and does NOT proceed to SDK generation until the CLI is verified.", + "files": [], + "assertions": [ + { + "id": "suggests-reinstall", + "description": "Response suggests reinstalling the CLI", + "type": "contains", + "value": "npm install -g @apimatic/cli" + }, + { + "id": "does-not-proceed-to-generate", + "description": "Response does NOT proceed to SDK generation while CLI is missing", + "type": "not_contains", + "value": "apimatic sdk generate" + }, + { + "id": "does-not-proceed-to-auth", + "description": "Response does NOT proceed to authentication while CLI is missing", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "mentions-version-check", + "description": "Response mentions verifying with apimatic --version", + "type": "contains", + "value": "apimatic --version" + } + ] + }, + { + "id": 9, + "prompt": "I already have a TypeScript SDK that I've customized with some extra helper methods. I want to save those changes so they're preserved when I regenerate later. I'm authenticated. My project is at ./ts-api/.", + "expected_output": "The agent recognizes the user already has a customized SDK, skips SDK generation entirely, and runs apimatic sdk save-changes --language=typescript.", + "files": [], + "assertions": [ + { + "id": "does-not-regenerate", + "description": "Response does NOT run sdk generate since user already has their SDK customized", + "type": "not_contains", + "value": "apimatic sdk generate" + }, + { + "id": "runs-save-changes", + "description": "Response runs the sdk save-changes command", + "type": "contains", + "value": "apimatic sdk save-changes" + }, + { + "id": "uses-typescript-language", + "description": "Response uses --language=typescript", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "ts-api", + "./ts-api" + ] + } + ] + }, + { + "id": 10, + "prompt": "I want to generate a Python SDK for my API project at ./python-api/ and then add some custom utility functions to it. I'm authenticated and have the src/ folder set up already.", + "expected_output": "The agent generates the SDK with --track-changes enabled, then prompts the user to make their customizations, and runs apimatic sdk save-changes --language=python once the user confirms they are done.", + "files": [], + "assertions": [ + { + "id": "generates-with-track-changes", + "description": "Response generates the SDK with --track-changes flag", + "type": "contains", + "value": "--track-changes" + }, + { + "id": "generates-python-sdk", + "description": "Response uses --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "prompts-user-to-customize", + "description": "Response asks the user to make their customizations before saving", + "type": "contains_any", + "value": [ + "make your customizations", + "add your customizations", + "make your changes", + "add your changes", + "let me know when", + "once you've made", + "when you're ready", + "when you're done" + ] + }, + { + "id": "runs-save-changes", + "description": "Response includes the sdk save-changes command for the next step", + "type": "contains", + "value": "apimatic sdk save-changes" + } + ] + }, + { + "id": 11, + "prompt": "I have no SDK yet and I want to generate one from scratch and customize it. I don't have a project directory set up. My API spec is at ~/specs/payments.yaml. I'm authenticated.", + "expected_output": "The agent scaffolds the project directory (src/spec/ structure), generates the SDK with --track-changes, prompts the user to make customizations, then runs apimatic sdk save-changes.", + "files": [], + "assertions": [ + { + "id": "scaffolds-src-structure", + "description": "Response creates the src/spec/ directory structure before generating", + "type": "contains_any", + "value": [ + "src/spec", + "src\\spec", + "mkdir", + "New-Item" + ] + }, + { + "id": "generates-with-track-changes", + "description": "Response generates the SDK with --track-changes flag", + "type": "contains", + "value": "--track-changes" + }, + { + "id": "prompts-user-to-customize", + "description": "Response asks the user to add their customizations before saving", + "type": "contains_any", + "value": [ + "make your customizations", + "add your customizations", + "make your changes", + "add your changes", + "let me know when", + "once you've made", + "when you're ready", + "when you're done" + ] + }, + { + "id": "runs-save-changes", + "description": "Response includes the sdk save-changes command for the next step", + "type": "contains", + "value": "apimatic sdk save-changes" + } + ] + }, + { + "id": 12, + "prompt": "I have change tracking enabled for my Java SDK but I want to see what the SDK looks like without my customizations applied. I'm authenticated, project is at ./java-api/.", + "expected_output": "The agent runs apimatic sdk generate --language=java --skip-changes and explains this is non-destructive — saved customizations are not removed.", + "files": [], + "assertions": [ + { + "id": "generates-java-sdk", + "description": "Response uses --language=java", + "type": "contains", + "value": "--language=java" + }, + { + "id": "uses-skip-changes-flag", + "description": "Response includes the --skip-changes flag", + "type": "contains", + "value": "--skip-changes" + }, + { + "id": "non-destructive-explanation", + "description": "Response clarifies that saved customizations are not removed", + "type": "contains_any", + "value": [ + "not modified", + "not removed", + "still applied", + "still be applied", + "won't be removed", + "are not modified", + "are preserved", + "untouched", + "non-destructive" + ] + }, + { + "id": "does-not-delete-sdk-source-tree", + "description": "Response does NOT tell user to delete the sdk-source-tree to preview", + "type": "not_contains", + "value": "delete" + } + ] + }, + { + "id": 13, + "prompt": "I need to generate a Go SDK for version v2 of my API. My project is at ./multi-version-api/ and it has a src/ folder set up. I'm already authenticated.", + "expected_output": "The agent includes --api-version=v2 in the generate command to target the specific API version, along with --language=go.", + "files": [], + "assertions": [ + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user said they are authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "generates-go-sdk", + "description": "Response includes the SDK generate command with go language", + "type": "contains", + "value": "--language=go" + }, + { + "id": "uses-api-version-flag", + "description": "Response includes --api-version=v2 to target the specific API version", + "type": "contains", + "value": "--api-version=v2" + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "multi-version-api", + "./multi-version-api" + ] + }, + { + "id": "does-not-add-zip-unprompted", + "description": "Response does NOT add --zip since user did not request it", + "type": "not_contains", + "value": "--zip" + } + ] + }, + { + "id": 15, + "prompt": "I want to generate a Python SDK for my API project at ./payments-api/ and make sure every generated file has a copyright notice in it. I'm already authenticated and the src/ folder is set up.", + "expected_output": "The agent recognizes that adding a copyright notice to every file is covered by the ShortCopyrightNotice CodeGen setting. It updates APIMATIC-META.json with ShortCopyrightNotice set to the copyright text, then generates the SDK. It does NOT manually edit generated files or inject copyright via custom code.", + "files": [], + "assertions": [ + { + "id": "uses-short-copyright-notice-setting", + "description": "Response uses the ShortCopyrightNotice CodeGen setting in APIMATIC-META.json", + "type": "contains", + "value": "ShortCopyrightNotice" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json with the copyright setting", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-python-sdk", + "description": "Response generates the SDK with --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "does-not-manually-inject-copyright", + "description": "Response does NOT manually edit generated files or add copyright as custom code injection", + "type": "not_contains_any", + "value": [ + "sdk-source-tree", + "custom code injection", + "inject the copyright", + "manually add", + "manually edit" + ] + }, + { + "id": "references-project-dir", + "description": "Response references the user's project directory", + "type": "contains_any", + "value": [ + "payments-api", + "./payments-api" + ] + } + ] + }, + { + "id": 14, + "prompt": "I'm running SDK generation in Docker and can't run apimatic auth login interactively. I don't want the API key to appear in my shell history. What's the cleanest way to authenticate?", + "expected_output": "The agent recommends setting the APIMATIC_API_KEY environment variable (no login command needed) as the cleanest approach that avoids the key appearing in command history. It also mentions the --auth-key flag as an alternative.", + "files": [], + "assertions": [ + { + "id": "recommends-env-var", + "description": "Response recommends the APIMATIC_API_KEY environment variable", + "type": "contains", + "value": "APIMATIC_API_KEY" + }, + { + "id": "shows-env-var-syntax", + "description": "Response shows how to set the environment variable", + "type": "contains_any", + "value": [ + "export APIMATIC_API_KEY", + "$env:APIMATIC_API_KEY", + "set APIMATIC_API_KEY" + ] + }, + { + "id": "does-not-recommend-browser-login", + "description": "Response does NOT recommend browser-based auth for Docker/CI", + "type": "not_contains", + "value": "auth-login.mjs" + }, + { + "id": "mentions-no-login-command-needed", + "description": "Response notes that the env var approach requires no login command", + "type": "contains_any", + "value": [ + "no login", + "without login", + "no auth login", + "without running", + "no login command", + "without the login", + "no interactive" + ] + } + ] + }, + { + "id": 16, + "prompt": "I want to generate a TypeScript SDK without any documentation files. My project is at ./my-api/ and I'm already authenticated with the src/ folder set up.", + "expected_output": "The agent recognizes that disabling docs is covered by the DisableDocs CodeGen setting. It updates APIMATIC-META.json with DisableDocs set to true, then generates the SDK. It does NOT manually delete the docs folder or README.", + "files": [], + "assertions": [ + { + "id": "uses-disable-docs-setting", + "description": "Response uses the DisableDocs CodeGen setting", + "type": "contains", + "value": "DisableDocs" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-typescript-sdk", + "description": "Response generates the SDK with --language=typescript", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "does-not-manually-delete-docs", + "description": "Response does NOT manually delete docs folder or use file deletion commands", + "type": "not_contains_any", + "value": [ + "rm ", + "del ", + "Remove-Item", + "rmdir", + "manually delete", + "delete the docs" + ] + } + ] + }, + { + "id": 17, + "prompt": "Disable linting in my PHP SDK. My project is at ./php-project/ and I'm already authenticated.", + "expected_output": "The agent recognizes that disabling linting is covered by the DisableLinting CodeGen setting. It updates APIMATIC-META.json with DisableLinting set to true, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-disable-linting-setting", + "description": "Response uses the DisableLinting CodeGen setting", + "type": "contains", + "value": "DisableLinting" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-php-sdk", + "description": "Response generates the SDK with --language=php", + "type": "contains", + "value": "--language=php" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 18, + "prompt": "Set the timeout to 60 seconds and enable retry with 3 attempts for my C# SDK. My project is at ./csharp-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that timeout and retry settings are covered by the Timeout, RetryOnTimeout, and Retries CodeGen settings. It updates APIMATIC-META.json with all relevant settings, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-timeout-setting", + "description": "Response uses the Timeout CodeGen setting", + "type": "contains", + "value": "Timeout" + }, + { + "id": "uses-retries-setting", + "description": "Response uses the Retries CodeGen setting", + "type": "contains", + "value": "Retries" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-csharp-sdk", + "description": "Response generates the SDK with --language=csharp", + "type": "contains", + "value": "--language=csharp" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 19, + "prompt": "Set the SDK project name to 'PaymentsSDK' for my Java SDK. My project is at ./payments/ and I'm already authenticated.", + "expected_output": "The agent recognizes that setting the project name is covered by the ProjectName CodeGen setting. It updates APIMATIC-META.json with ProjectName set to PaymentsSDK, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-project-name-setting", + "description": "Response uses the ProjectName CodeGen setting", + "type": "contains", + "value": "ProjectName" + }, + { + "id": "uses-correct-name", + "description": "Response includes the user's requested project name", + "type": "contains", + "value": "PaymentsSDK" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-java-sdk", + "description": "Response generates the SDK with --language=java", + "type": "contains", + "value": "--language=java" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 20, + "prompt": "Enable logging in my Python SDK. My project is at ./py-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that enabling logging is covered by the EnableLogging CodeGen setting. It updates APIMATIC-META.json with EnableLogging set to true, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-enable-logging-setting", + "description": "Response uses the EnableLogging CodeGen setting", + "type": "contains", + "value": "EnableLogging" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-python-sdk", + "description": "Response generates the SDK with --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 21, + "prompt": "Set a custom user agent string for my Ruby SDK that includes the language and version. My project is at ./ruby-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that setting a custom user agent is covered by the UserAgent CodeGen setting with placeholders. It updates APIMATIC-META.json with UserAgent set to a string containing {language} and {version} placeholders, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-user-agent-setting", + "description": "Response uses the UserAgent CodeGen setting", + "type": "contains", + "value": "UserAgent" + }, + { + "id": "includes-placeholders", + "description": "Response includes the {language} and/or {version} placeholders", + "type": "contains_any", + "value": [ + "{language}", + "{version}" + ] + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-ruby-sdk", + "description": "Response generates the SDK with --language=ruby", + "type": "contains", + "value": "--language=ruby" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 22, + "prompt": "Change array serialization to CSV format for my TypeScript SDK. My project is at ./ts-project/ and I'm already authenticated.", + "expected_output": "The agent recognizes that array serialization format is covered by the ArraySerialization CodeGen setting. It updates APIMATIC-META.json with ArraySerialization set to CSV, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-array-serialization-setting", + "description": "Response uses the ArraySerialization CodeGen setting", + "type": "contains", + "value": "ArraySerialization" + }, + { + "id": "sets-csv-format", + "description": "Response sets the value to CSV", + "type": "contains", + "value": "CSV" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-typescript-sdk", + "description": "Response generates the SDK with --language=typescript", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 23, + "prompt": "Make my C# SDK return null instead of throwing an exception on 404 responses. My project is at ./csharp-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that returning null on 404 is covered by the Nullify404 CodeGen setting. It updates APIMATIC-META.json with Nullify404 set to true, then regenerates the SDK. It does NOT add custom exception handling code.", + "files": [], + "assertions": [ + { + "id": "uses-nullify404-setting", + "description": "Response uses the Nullify404 CodeGen setting", + "type": "contains", + "value": "Nullify404" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-csharp-sdk", + "description": "Response generates the SDK with --language=csharp", + "type": "contains", + "value": "--language=csharp" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "does-not-add-custom-exception-handling", + "description": "Response does NOT add manual exception handling or try-catch code", + "type": "not_contains_any", + "value": [ + "try {", + "catch (", + "try:", + "except ", + "custom exception handling" + ] + } + ] + }, + { + "id": 24, + "prompt": "Add our company name 'Acme Corp' to all generated file headers in my Go SDK. My project is at ./acme-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that adding a company name to file headers is covered by the BrandLabel CodeGen setting. It updates APIMATIC-META.json with BrandLabel set to Acme Corp, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-brand-label-setting", + "description": "Response uses the BrandLabel CodeGen setting", + "type": "contains", + "value": "BrandLabel" + }, + { + "id": "includes-company-name", + "description": "Response includes the user's company name", + "type": "contains", + "value": "Acme Corp" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-go-sdk", + "description": "Response generates the SDK with --language=go", + "type": "contains", + "value": "--language=go" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 25, + "prompt": "Add 'Model' postfix to all model class names in my Java SDK to avoid naming conflicts. My project is at ./java-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that adding a Model postfix is covered by the UseModelPrefix CodeGen setting. It updates APIMATIC-META.json with UseModelPrefix set to true, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-model-prefix-setting", + "description": "Response uses the UseModelPrefix CodeGen setting", + "type": "contains", + "value": "UseModelPrefix" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-java-sdk", + "description": "Response generates the SDK with --language=java", + "type": "contains", + "value": "--language=java" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 26, + "prompt": "Disable native enum types in my Python SDK and use plain strings instead. My project is at ./py-project/ and I'm already authenticated.", + "expected_output": "The agent recognizes that disabling native enums is covered by the GenerateEnums CodeGen setting. It updates APIMATIC-META.json with GenerateEnums set to false, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-generate-enums-setting", + "description": "Response uses the GenerateEnums CodeGen setting", + "type": "contains", + "value": "GenerateEnums" + }, + { + "id": "sets-to-false", + "description": "Response sets GenerateEnums to false", + "type": "contains", + "value": "false" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-python-sdk", + "description": "Response generates the SDK with --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 27, + "prompt": "Set custom error messages for 401 and 5XX responses in my TypeScript SDK. For 401 use 'Authorization failed, code: {$statusCode}' and for 5XX use 'Server error, code: {$statusCode}'. My project is at ./ts-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that custom error messages are covered by the ErrorTemplates CodeGen setting. It updates APIMATIC-META.json with ErrorTemplates containing entries for 401 and 5XX with the user's specified messages, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-error-templates-setting", + "description": "Response uses the ErrorTemplates CodeGen setting", + "type": "contains", + "value": "ErrorTemplates" + }, + { + "id": "includes-401-code", + "description": "Response includes the 401 error code", + "type": "contains", + "value": "401" + }, + { + "id": "includes-5xx-code", + "description": "Response includes the 5XX error code", + "type": "contains", + "value": "5XX" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-typescript-sdk", + "description": "Response generates the SDK with --language=typescript", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 28, + "prompt": "Generate my C# SDK with synchronous methods instead of async. My project is at ./sync-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that switching to synchronous methods is covered by the SynchronyMode CodeGen setting. It updates APIMATIC-META.json with SynchronyMode set to Synchronous, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-synchrony-mode-setting", + "description": "Response uses the SynchronyMode CodeGen setting", + "type": "contains", + "value": "SynchronyMode" + }, + { + "id": "sets-synchronous-value", + "description": "Response sets the value to Synchronous", + "type": "contains", + "value": "Synchronous" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-csharp-sdk", + "description": "Response generates the SDK with --language=csharp", + "type": "contains", + "value": "--language=csharp" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 29, + "prompt": "Remove the docs folder from my generated Python SDK. My project is at ./my-sdk/ and I'm already authenticated.", + "expected_output": "The agent recognizes that removing docs is covered by the DisableDocs CodeGen setting. It updates APIMATIC-META.json with DisableDocs set to true, then regenerates the SDK. It does NOT manually delete files, use rm commands, or treat this as a custom code injection.", + "files": [], + "assertions": [ + { + "id": "uses-disable-docs-setting", + "description": "Response uses the DisableDocs CodeGen setting instead of manual deletion", + "type": "contains", + "value": "DisableDocs" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "does-not-manually-delete", + "description": "Response does NOT use file deletion commands", + "type": "not_contains_any", + "value": [ + "rm ", + "del ", + "Remove-Item", + "rmdir", + "sdk-source-tree", + "custom code injection", + "manually delete" + ] + }, + { + "id": "generates-python-sdk", + "description": "Response generates the SDK with --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 30, + "prompt": "Enable keyword arguments in my TypeScript SDK. My project is at ./ts-project/ and I'm already authenticated.", + "expected_output": "The agent recognizes that ForceKeywordArgsInRuby is a Ruby-only setting and informs the user that keyword arguments are not available for TypeScript. It does NOT blindly apply the setting.", + "files": [], + "assertions": [ + { + "id": "mentions-ruby-only", + "description": "Response mentions that keyword arguments are only available for Ruby", + "type": "contains_any", + "value": [ + "Ruby", + "ruby", + "not supported", + "not available", + "only available", + "Ruby only", + "ForceKeywordArgsInRuby", + "doesn't support", + "does not support", + "isn't available", + "is not available" + ] + }, + { + "id": "does-not-blindly-apply", + "description": "Response does NOT apply ForceKeywordArgsInRuby for TypeScript", + "type": "not_contains", + "value": "\"ForceKeywordArgsInRuby\": true" + } + ] + }, + { + "id": 31, + "prompt": "For my Java SDK at ./java-api/: set the project name to 'OrdersSDK', disable docs generation, and enable logging. I'm already authenticated.", + "expected_output": "The agent recognizes all three changes map to CodeGen settings: ProjectName, DisableDocs, and EnableLogging. It updates APIMATIC-META.json with all three settings in a single CodeGenSettings block, then regenerates the SDK once.", + "files": [], + "assertions": [ + { + "id": "uses-project-name-setting", + "description": "Response uses the ProjectName CodeGen setting", + "type": "contains", + "value": "ProjectName" + }, + { + "id": "uses-disable-docs-setting", + "description": "Response uses the DisableDocs CodeGen setting", + "type": "contains", + "value": "DisableDocs" + }, + { + "id": "uses-enable-logging-setting", + "description": "Response uses the EnableLogging CodeGen setting", + "type": "contains", + "value": "EnableLogging" + }, + { + "id": "includes-orders-sdk-name", + "description": "Response includes the requested project name", + "type": "contains", + "value": "OrdersSDK" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-java-sdk", + "description": "Response generates the SDK with --language=java", + "type": "contains", + "value": "--language=java" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 32, + "prompt": "Add an option to skip SSL certificate verification in my Python SDK for development environments. My project is at ./dev-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that adding SSL skip is covered by the AllowSkippingSSLCertVerification CodeGen setting. It updates APIMATIC-META.json with AllowSkippingSSLCertVerification set to true, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-ssl-skip-setting", + "description": "Response uses the AllowSkippingSSLCertVerification CodeGen setting", + "type": "contains", + "value": "AllowSkippingSSLCertVerification" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-python-sdk", + "description": "Response generates the SDK with --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 33, + "prompt": "Change the controller suffix from 'Controller' to 'Api' in my C# SDK. My project is at ./api-project/ and I'm already authenticated.", + "expected_output": "The agent recognizes that changing the controller suffix is covered by the ControllerPostfix CodeGen setting. It updates APIMATIC-META.json with ControllerPostfix set to Api, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-controller-postfix-setting", + "description": "Response uses the ControllerPostfix CodeGen setting", + "type": "contains", + "value": "ControllerPostfix" + }, + { + "id": "sets-api-value", + "description": "Response sets the postfix to Api", + "type": "contains", + "value": "Api" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-csharp-sdk", + "description": "Response generates the SDK with --language=csharp", + "type": "contains", + "value": "--language=csharp" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 34, + "prompt": "I want my PHP SDK to return full HTTP responses including headers and status codes, not just the response body. My project is at ./php-api/ and I'm already authenticated.", + "expected_output": "The agent recognizes that returning full HTTP responses is covered by the ReturnCompleteHttpResponse CodeGen setting. It updates APIMATIC-META.json with ReturnCompleteHttpResponse set to true, then regenerates the SDK.", + "files": [], + "assertions": [ + { + "id": "uses-return-complete-response-setting", + "description": "Response uses the ReturnCompleteHttpResponse CodeGen setting", + "type": "contains", + "value": "ReturnCompleteHttpResponse" + }, + { + "id": "updates-apimatic-meta", + "description": "Response updates APIMATIC-META.json", + "type": "contains", + "value": "APIMATIC-META.json" + }, + { + "id": "generates-php-sdk", + "description": "Response generates the SDK with --language=php", + "type": "contains", + "value": "--language=php" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + } + ] +} diff --git a/skills/apimatic-sdk/evals/grade.py b/skills/apimatic-sdk/evals/grade.py new file mode 100644 index 0000000..5abceff --- /dev/null +++ b/skills/apimatic-sdk/evals/grade.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Grade all apimatic-sdk evals against their assertions from evals.json.""" + +import json +import os + +WORKSPACE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "workspace") +EVALS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "evals.json") + +with open(EVALS_FILE) as f: + evals_data = json.load(f) + +def check_assertion(text, assertion): + t = assertion["type"] + v = assertion["value"] + text_lower = text.lower() + + if t == "contains": + passed = v.lower() in text_lower + evidence = f"Found '{v}'" if passed else f"NOT FOUND: '{v}'" + elif t == "contains_any": + matched = [item for item in v if item.lower() in text_lower] + passed = len(matched) > 0 + evidence = f"Found: {matched}" if passed else f"NONE FOUND: {v}" + elif t == "not_contains": + passed = v.lower() not in text_lower + evidence = f"Correctly absent: '{v}'" if passed else f"SHOULD NOT CONTAIN: '{v}'" + elif t == "not_contains_any": + found = [item for item in v if item.lower() in text_lower] + passed = len(found) == 0 + evidence = f"Correctly absent" if passed else f"SHOULD NOT CONTAIN: {found}" + else: + passed = False + evidence = f"Unknown assertion type: {t}" + + return passed, evidence + +total_assertions = 0 +total_passed = 0 +results_by_eval = [] +failed_evals = [] + +for eval_item in evals_data["evals"]: + eval_id = eval_item["id"] + response_path = os.path.join(WORKSPACE, f"eval-{eval_id}-response.md") + + if not os.path.exists(response_path): + print(f"\n=== EVAL {eval_id} === MISSING response file: {response_path}") + failed_evals.append(eval_id) + continue + + with open(response_path) as f: + response_text = f.read() + + assertions = eval_item.get("assertions", []) + results = [] + eval_passed = 0 + for assertion in assertions: + passed, evidence = check_assertion(response_text, assertion) + results.append({ + "id": assertion["id"], + "passed": passed, + "evidence": evidence + }) + if passed: + eval_passed += 1 + total_assertions += 1 + + total_passed += eval_passed + score = f"{eval_passed}/{len(assertions)}" + status = "PASS" if eval_passed == len(assertions) else "FAIL" + print(f"\n=== EVAL {eval_id} === {status} ({score})") + print(f"Prompt: {eval_item['prompt'][:80]}...") + for r in results: + mark = "PASS" if r["passed"] else "FAIL" + print(f" [{mark}] {r['id']}: {r['evidence']}") + + results_by_eval.append({ + "eval_id": eval_id, + "status": status, + "score": score, + "results": results + }) + +print(f"\n{'='*50}") +print(f"TOTAL: {total_passed}/{total_assertions} assertions passed") +if failed_evals: + print(f"MISSING: evals {failed_evals} had no response file") + +# Save grading results +grading_output = os.path.join(WORKSPACE, "grading.json") +with open(grading_output, "w") as f: + json.dump({ + "total_assertions": total_assertions, + "total_passed": total_passed, + "evals": results_by_eval + }, f, indent=2) +print(f"\nResults saved to {grading_output}") diff --git a/skills/apimatic-sdk/evals/workspace/eval-0-response.md b/skills/apimatic-sdk/evals/workspace/eval-0-response.md new file mode 100644 index 0000000..41b2c5f --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-0-response.md @@ -0,0 +1,96 @@ +Great! Let's get your Python SDK generated. Since this is your first time using the APIMatic CLI, we'll go through setup together. + +## Step 1: Check prerequisites + +Before anything else, make sure you have **Node.js 20 or later** installed. Run this to check: + +``` +node --version +``` + +If you don't have Node.js, download it from https://nodejs.org (choose the LTS version). + +Once Node.js is confirmed, install the APIMatic CLI globally: + +``` +npm install -g @apimatic/cli +``` + +Then verify it installed correctly: + +``` +apimatic --version +``` + +If you see a version number, you're good to go. Let me know when that's done. + +--- + +## Step 2: Authenticate with APIMatic + +You'll need a free APIMatic account. If you don't have one yet, sign up at https://app.apimatic.io. + +First, check if you're already authenticated: + +``` +apimatic auth status +``` + +If it doesn't show an account email, run this to log in via your browser: + +``` +apimatic auth login +``` + +A browser window will open. Complete sign-in there, then come back here and let me know when you're done. + +After you confirm, we'll verify it worked: + +``` +apimatic auth status +``` + +It should show your account email. If browser login doesn't work, you can use an API key instead — generate one at APIMatic Dashboard > Account > API Keys, then run: + +``` +apimatic auth login --auth-key=YOUR_API_KEY +``` + +--- + +## Step 3: A couple of quick questions before we generate + +Your input directory is `~/my-api-project/` and the language is **Python** — both already known. I just need two more things: + +1. **Destination:** Do you have a specific folder where you'd like the SDK to be placed, or should I use the default location? (The default would be `~/my-api-project/sdk/python/`.) + +2. **Customization:** Would you like to set up change tracking so any customizations you make to the SDK survive future regenerations? If yes, I'll add `--track-changes` to the generate command. + +--- + +## Step 4: Generate the SDK + +Once auth is confirmed and those questions are answered, the generate command will look like this: + +``` +apimatic sdk generate --input=~/my-api-project --language=python +``` + +Or with a custom destination: + +``` +apimatic sdk generate --input=~/my-api-project --language=python --destination=~/path/to/sdk-output +``` + +Note: `--input` points to `~/my-api-project/` — the folder containing `src/`, not the spec file itself. + +--- + +**Summary of what I still need from you:** + +1. Confirm Node.js is installed and the CLI installs successfully. +2. Complete browser sign-in and confirm when done. +3. Default destination or a custom path? +4. Change tracking — yes or no? + +Once those are answered, your Python SDK will be ready to go. diff --git a/skills/apimatic-sdk/evals/workspace/eval-1-response.md b/skills/apimatic-sdk/evals/workspace/eval-1-response.md new file mode 100644 index 0000000..ccf0e11 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-1-response.md @@ -0,0 +1,11 @@ +Since you're already set up and authenticated, you're ready to go. + +Run this command to generate the TypeScript SDK as a zip file in your chosen output folder: + +``` +apimatic sdk generate --input=D:\work\payments-api --language=typescript --destination=D:\output\ts-sdk --zip +``` + +Once it completes, your zipped TypeScript SDK will be at `D:\output\ts-sdk`. + +If the CLI reports that an SDK already exists at that destination, let me know and I can re-run with `--force` to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-10-response.md b/skills/apimatic-sdk/evals/workspace/eval-10-response.md new file mode 100644 index 0000000..b77c1c6 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-10-response.md @@ -0,0 +1,34 @@ +Great — since you're already authenticated and have your `src/` folder set up at `./python-api/`, you're in a good spot to move quickly. Here's what we'll do: generate the Python SDK with change tracking enabled so your custom utility functions are preserved across future regenerations. + +**Step 1: Generate the Python SDK with change tracking** + +Navigate to your project root (the directory that contains `src/`) and run: + +``` +cd ./python-api +apimatic sdk generate --language=python --track-changes +``` + +This generates the SDK at `./python-api/sdk/python/` by default and initializes change tracking. Every future regeneration will automatically reapply your customizations. + +If an SDK already exists at that destination, the CLI will warn you. If that happens, let me know — I'll add `--force` to overwrite it, or we can pick a different destination. + +**Step 2: Add your custom utility functions** + +Once generation completes, follow these guidelines when adding your utility code: + +- Add custom logic in a **new file** where possible — new files are never overwritten on regeneration. For example, create `./python-api/sdk/python/utils.py` for your helpers. +- Avoid editing generated files directly. +- If you must edit a generated file, add your changes at the top or bottom to reduce merge conflicts. + +Make your customizations now, then let me know when you're done. + +**Step 3: Save your customizations** + +Once your utilities are in place, run: + +``` +apimatic sdk save-changes --language=python --input=./python-api +``` + +This captures exactly what you changed or added and stores it in the source tree. From this point on, every time you run `sdk generate` for Python, your customizations will be reapplied automatically — no manual re-editing needed. diff --git a/skills/apimatic-sdk/evals/workspace/eval-11-response.md b/skills/apimatic-sdk/evals/workspace/eval-11-response.md new file mode 100644 index 0000000..22293cb --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-11-response.md @@ -0,0 +1,57 @@ +Great — since you're authenticated and starting from scratch, let's get your project set up and generate your first SDK. + +## Step 1: Set up your project directory + +First, I need to know where you'd like the project to live. Where would you like me to set up the project directory? (Give a path, or I'll use the current directory.) + +Once you tell me the project path, I'll scaffold the project structure for you: + +1. Create the `src/spec/` folder inside your project directory +2. Copy your API spec from `~/specs/payments.yaml` into `src/spec/` +3. Create a starter `APIMATIC-META.json` configuration file in `src/spec/` + +The commands I'll run (using your chosen project path, e.g. `~/payments-sdk-project`): + +```bash +mkdir -p ~/payments-sdk-project/src/spec +cp ~/specs/payments.yaml ~/payments-sdk-project/src/spec/ +``` + +After setup, your project will look like this: + +``` +payments-sdk-project/ +└── src/ + └── spec/ + ├── payments.yaml + └── APIMATIC-META.json +``` + +## Step 2: Choose your language + +Which language would you like the SDK generated in? + +| Option | Language | +|---|---| +| `csharp` | C# | +| `java` | Java | +| `php` | PHP | +| `python` | Python | +| `ruby` | Ruby | +| `typescript` | TypeScript | +| `go` | Go | + +## Step 3: Customization + +Since you mentioned you want to customize the SDK, I'll enable change tracking during generation with `--track-changes`. This lets you make edits to the generated SDK and save those customizations so they're automatically reapplied on every future regeneration. + +Would you like me to apply the customizations for you, or will you handle them yourself after generation? + +Once you answer (project path and language), I'll scaffold the project and run the generate command — for example: + +```bash +cd ~/payments-sdk-project +apimatic sdk generate --language=typescript --track-changes +``` + +Then prompt: "Make your customizations now, then let me know when you're ready to save them." Once you confirm, I'll run `apimatic sdk save-changes`. diff --git a/skills/apimatic-sdk/evals/workspace/eval-12-response.md b/skills/apimatic-sdk/evals/workspace/eval-12-response.md new file mode 100644 index 0000000..743fbec --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-12-response.md @@ -0,0 +1,7 @@ +To see your Java SDK without your customizations applied, run the generate command with the `--skip-changes` flag from your project directory: + +``` +apimatic sdk generate --input=./java-api --language=java --skip-changes +``` + +This produces a clean copy of the SDK as if your customizations were never applied. Your saved customizations are not affected — they are not removed and will still be applied in future regenerations unless you explicitly remove them. diff --git a/skills/apimatic-sdk/evals/workspace/eval-13-response.md b/skills/apimatic-sdk/evals/workspace/eval-13-response.md new file mode 100644 index 0000000..11853bc --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-13-response.md @@ -0,0 +1,37 @@ +Since you're already authenticated, let's move straight to generating your Go SDK. + +You've provided everything I need: + +- **Input directory:** `./multi-version-api/` (already has a `src/` folder) +- **Language:** Go +- **API version:** v2 + +**Step 1: Navigate to your project root** + +Make sure you're in the directory that contains the `src/` folder (not inside `src/` itself): + +``` +cd multi-version-api +``` + +**Step 2: Run the generate command** + +``` +apimatic sdk generate --input=./multi-version-api --language=go --api-version=v2 +``` + +Or, if you're already inside `multi-version-api/`: + +``` +apimatic sdk generate --language=go --api-version=v2 +``` + +The SDK will be generated at `./multi-version-api/sdk/v2/go/` by default. + +--- + +**If you run into any issues:** + +- **SDK already exists at that location:** The CLI will let you know. Just say the word and I'll re-run the command with `--force` to overwrite it. +- **Authentication error:** Run `apimatic auth status` to check, then let me know if it shows your account email. +- **Any other error:** Share the message and I'll help you resolve it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-14-response.md b/skills/apimatic-sdk/evals/workspace/eval-14-response.md new file mode 100644 index 0000000..47839f7 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-14-response.md @@ -0,0 +1,52 @@ +For Docker and CI environments where interactive login isn't an option, the cleanest approach is the **environment variable method** — your API key never touches your shell history, and no login command is required at all. + +## Option 1: Environment Variable (Recommended for Docker) + +Set the environment variable before running any APIMatic CLI command. The CLI picks it up automatically — no `apimatic auth login` needed. + +**In your Dockerfile or docker run command:** + +```dockerfile +# Pass the key at runtime — keeps it out of the image and shell history +docker run -e APIMATIC_API_KEY="your_api_key_here" your-image +``` + +**In a shell script or CI pipeline (Linux/macOS/bash):** + +```bash +export APIMATIC_API_KEY="your_api_key_here" +``` + +The key is set in the current process environment only — it does not appear in your shell history. + +**Windows PowerShell:** + +```powershell +$env:APIMATIC_API_KEY = "your_api_key_here" +``` + +Once the variable is set, run generation normally: + +```bash +apimatic sdk generate --input=path/to/project --language= +``` + +## Option 2: Inline Flag on the Generate Command + +If you prefer to keep auth tied directly to the generate command, pass the key as a flag: + +```bash +apimatic sdk generate --input=path/to/project --language= --auth-key=$APIMATIC_API_KEY +``` + +## Where to Get Your API Key + +Log in to the APIMatic Dashboard, go to **Account > API Keys**, and generate a key from there. + +## Which Option to Use? + +- **Docker / CI pipeline:** Use the environment variable. Inject it via your CI secret manager (GitHub Actions secrets, GitLab CI variables, AWS Secrets Manager, etc.) so it never appears in logs or image layers. +- **One-off Docker run:** Use `-e APIMATIC_API_KEY=...` on the `docker run` command. +- **Prefer a single command:** Use the `--auth-key` flag directly on `sdk generate`, sourcing from an already-injected env var. + +All three approaches keep the key out of your shell history and avoid the need for interactive browser login. No `apimatic auth login` command needed in any of these cases. diff --git a/skills/apimatic-sdk/evals/workspace/eval-15-response.md b/skills/apimatic-sdk/evals/workspace/eval-15-response.md new file mode 100644 index 0000000..a315913 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-15-response.md @@ -0,0 +1,43 @@ +Great news — since you're already authenticated and your `src/` folder is set up, we can move straight to configuration. + +The copyright notice you want is a built-in CodeGen setting called `ShortCopyrightNotice`. It tells APIMatic to embed your custom copyright text in the header of every generated SDK file — no manual file editing needed. + +--- + +## Step 1: Update APIMATIC-META.json + +Open `./payments-api/src/spec/APIMATIC-META.json` and add `ShortCopyrightNotice` inside `CodeGenSettings`. For example: + +```json +{ + "CodeGenSettings": { + "ShortCopyrightNotice": "Copyright (c) 2026 Your Company Name. All rights reserved." + } +} +``` + +Replace the copyright text with whatever you'd like to appear in your files. If `CodeGenSettings` already has other keys, just add `"ShortCopyrightNotice"` alongside them. + +Save the file. + +--- + +## Step 2: Generate the SDK + +Navigate to your project root (the folder that contains `src/`) and run: + +``` +apimatic sdk generate --input=./payments-api --language=python +``` + +That's it — no extra flags needed for the copyright notice. APIMatic picks it up automatically from `APIMATIC-META.json`. + +If you'd like the SDK placed somewhere specific, add `--destination=path/to/output`. Otherwise it will be generated at `./payments-api/sdk/python` by default. + +--- + +## Step 3: Verify the Output + +Once generation completes, open any `.py` file in the generated SDK. You should see your copyright text in the file header. + +If the CLI tells you an SDK already exists at the destination, let me know and I'll help you decide whether to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-16-response.md b/skills/apimatic-sdk/evals/workspace/eval-16-response.md new file mode 100644 index 0000000..a2ea3a6 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-16-response.md @@ -0,0 +1,27 @@ +Since you want no documentation files in the generated SDK, the right approach is to set `DisableDocs: true` in your `APIMATIC-META.json` before generating — this ensures docs are never produced in the first place, rather than removing them after the fact. + +**Step 1: Update APIMATIC-META.json** + +Open `./my-api/src/spec/APIMATIC-META.json` and add `DisableDocs: true` under `CodeGenSettings`: + +```json +{ + "CodeGenSettings": { + "DisableDocs": true + } +} +``` + +If `CodeGenSettings` already exists in the file, just add `"DisableDocs": true` inside it alongside any other settings already there. + +**Step 2: Generate the SDK** + +From the `./my-api/` directory (the one that contains `src/`), run: + +``` +apimatic sdk generate --input=./my-api --language=typescript +``` + +That's it. The SDK will be generated at `./my-api/sdk/typescript/` with no README or other documentation files included. + +If you'd like to put the SDK somewhere else, add `--destination=your/preferred/path` to the command. Let me know if you run into any issues. diff --git a/skills/apimatic-sdk/evals/workspace/eval-19-response.md b/skills/apimatic-sdk/evals/workspace/eval-19-response.md new file mode 100644 index 0000000..26caa7d --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-19-response.md @@ -0,0 +1,33 @@ +Setting the SDK project name is a CodeGen setting — specifically `ProjectName` in `APIMATIC-META.json`. Since you're already authenticated, here's what to do: + +**Step 1: Open your APIMATIC-META.json** + +Open the file at: + +``` +./payments/src/spec/APIMATIC-META.json +``` + +**Step 2: Add the ProjectName setting** + +Locate the `CodeGenSettings` object and add (or update) the `ProjectName` key: + +```json +{ + "CodeGenSettings": { + "ProjectName": "PaymentsSDK" + } +} +``` + +Save the file. + +**Step 3: Regenerate the SDK** + +From the `./payments/` directory (the one that contains `src/`), run: + +``` +apimatic sdk generate --input=./payments --language=java +``` + +That's it — the project name is baked into the generation config, so every future regeneration will use `PaymentsSDK` automatically. diff --git a/skills/apimatic-sdk/evals/workspace/eval-2-response.md b/skills/apimatic-sdk/evals/workspace/eval-2-response.md new file mode 100644 index 0000000..7468818 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-2-response.md @@ -0,0 +1,93 @@ +Great news — since you have your OpenAPI spec ready but no project directory yet, we just need to scaffold the project structure before generating the SDK. Here's exactly what to do, step by step. + +## Before You Start: Prerequisites + +Make sure you have the following in place: + +1. **Node.js 20 or later** — download from https://nodejs.org if needed. Verify with: + ``` + node --version + ``` + +2. **APIMatic CLI installed globally:** + ``` + npm install -g @apimatic/cli + ``` + Verify it's working: + ``` + apimatic --version + ``` + +3. **An APIMatic account** — free trial available at https://app.apimatic.io. + +## Step 1: Authenticate with APIMatic + +First, check if you're already logged in: + +``` +apimatic auth status +``` + +If it shows your account email, you're good — skip ahead to Step 2. + +If not, run the browser-based login. After it opens a browser window, complete sign-in there, then come back and confirm you're done. Afterward, verify with `apimatic auth status`. + +If browser login doesn't work (e.g., headless environment), use an API key instead: + +``` +apimatic auth login --auth-key=YOUR_API_KEY +``` + +API keys can be generated at: APIMatic Dashboard > Account > API Keys. + +## Step 2: Set Up Your Project Directory + +Since you don't have a project directory yet, I need one more piece of information: **where would you like to set up the project directory?** Give me a path, or I'll use the current directory. + +Once I know the location, I'll set up this structure for you: + +``` +your-project/ +└── src/ + └── spec/ + ├── openapi.yaml (your existing spec, copied in) + └── APIMATIC-META.json (downloaded automatically) +``` + +Here are the commands (replace `./my-sdk-project` with your chosen path): + +**On macOS/Linux:** +```bash +mkdir -p ./my-sdk-project/src/spec +cp ./openapi.yaml ./my-sdk-project/src/spec/ +``` + +**On Windows PowerShell:** +```powershell +New-Item -ItemType Directory -Force -Path ".\my-sdk-project\src\spec" +Copy-Item ".\openapi.yaml" -Destination ".\my-sdk-project\src\spec\" +``` + +## Step 3: Generate the Go SDK + +From inside your project directory (the folder that contains `src/`): + +``` +cd my-sdk-project +apimatic sdk generate --language=go +``` + +The SDK will be generated at `my-sdk-project/sdk/go` by default. If you want it somewhere else, add `--destination=path/to/output`. + +## Step 4: Customization (Optional) + +If you plan to customize the SDK after generation, let me know now and I'll add the `--track-changes` flag so your changes can be safely saved and reapplied across future regenerations. + +--- + +**To get started, just confirm:** +1. Where you'd like the project directory set up (or confirm the current directory is fine) +2. Whether you're already authenticated, or need to log in first +3. Whether you want to customize the SDK after generating it + +Once I have those answers, I'll walk you through each command. diff --git a/skills/apimatic-sdk/evals/workspace/eval-3-response.md b/skills/apimatic-sdk/evals/workspace/eval-3-response.md new file mode 100644 index 0000000..9598832 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-3-response.md @@ -0,0 +1,13 @@ +Since you're already logged in, you can go straight to regeneration. Run this from your project root: + +``` +apimatic sdk generate --input=./my-api --language=csharp --force +``` + +The `--force` flag tells the CLI to overwrite your existing SDK. Once generation completes, your C# SDK will be updated with the spec changes. + +If the command fails, here are the most likely causes: + +- **"apimatic command not found"** — run `npm install -g @apimatic/cli` and try again. +- **Spec or `src/` folder missing** — make sure `./my-api/src/spec/` exists and contains your updated API spec file. +- **Auth expired** — run `apimatic auth status` to check. If it shows no account, re-authenticate and then rerun the generate command. diff --git a/skills/apimatic-sdk/evals/workspace/eval-30-response.md b/skills/apimatic-sdk/evals/workspace/eval-30-response.md new file mode 100644 index 0000000..7a77e9d --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-30-response.md @@ -0,0 +1,40 @@ +Keyword arguments aren't a supported CodeGen setting for TypeScript SDKs in APIMatic. + +I checked all available CodeGen settings across every category — endpoint settings, model settings, interface customization, serialization, HTTP configuration, and more. The only keyword argument settings that exist are: + +- **`ForceKeywordArgsInRuby`** — switches endpoint method parameters to keyword arguments in Ruby only +- **`EnableModelKeywordArgsInRuby`** — switches model constructor parameters to keyword arguments in Ruby only + +Neither of these applies to TypeScript, and there is no equivalent setting for TypeScript. + +**Why TypeScript doesn't have this setting:** TypeScript doesn't have a native "keyword arguments" feature in the same way Ruby does. TypeScript already uses named object parameters (e.g., `{ param1, param2 }`) for optional and complex argument patterns, which is the idiomatic TypeScript equivalent. APIMatic's TypeScript SDK generator follows these conventions by default. + +**What you can do instead:** + +If you're looking for a specific behavior — like collapsing multiple parameters into a named options object — the **`CollapseParamsToArray`** setting does exist for TypeScript and groups endpoint parameters into a single input object: + +```json +{ + "CodeGenSettings": { + "CollapseParamsToArray": true + } +} +``` + +This would change endpoint signatures from: + +```typescript +postData(unSet: boolean, setToNull: boolean, field: string, data: MyData) +``` + +to: + +```typescript +postData(input: PostDataInput) +``` + +where `PostDataInput` is a named model containing all the parameters. + +> **Caution:** `CollapseParamsToArray` can hide type information from SDKs and documentation, so use it only if this pattern fits your needs. + +If that's what you were after, let me know and I can apply it to your project at `./ts-project/`. If you had something else in mind, describe what you're trying to achieve and I'll find the closest available option. diff --git a/skills/apimatic-sdk/evals/workspace/eval-4-response.md b/skills/apimatic-sdk/evals/workspace/eval-4-response.md new file mode 100644 index 0000000..0118f19 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-4-response.md @@ -0,0 +1,28 @@ +Great — since you're already authenticated, let me verify that and then kick off your Ruby SDK generation. + +**Step 1: Verify authentication** + +Run this to confirm your session is active: + +``` +apimatic auth status +``` + +If it shows your account email, you're good to go. If not, let me know and we'll re-authenticate. + +--- + +**Step 2: Generate the Ruby SDK** + +Navigate to your project directory and run the generate command: + +``` +cd ~/ruby-project +apimatic sdk generate --language=ruby +``` + +Since you want the default output location and no zip, no extra flags are needed. The SDK will be generated at `~/ruby-project/sdk/ruby/`. + +--- + +Once generation completes, your Ruby SDK will be ready in that folder. Let me know if you run into any issues or if the CLI reports that an SDK already exists at the destination — I can help you decide whether to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-5-response.md b/skills/apimatic-sdk/evals/workspace/eval-5-response.md new file mode 100644 index 0000000..f71acaf --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-5-response.md @@ -0,0 +1,48 @@ +Browser sign-in opens a browser window and completes the OAuth flow, but the session token sometimes doesn't get written back to the CLI before you check. Since `apimatic auth status` isn't showing your email, the browser auth didn't fully complete. + +The most reliable fix is to use an API key instead. Here's how: + +**Step 1: Get your API key** + +Go to your APIMatic Dashboard, then navigate to Account > API Keys and copy your key. + +**Step 2: Log in using the API key** + +Run this command, replacing `YOUR_API_KEY` with the key you copied: + +``` +apimatic auth login --auth-key=YOUR_API_KEY +``` + +**Step 3: Confirm it worked** + +``` +apimatic auth status +``` + +This should now show your account email. + +--- + +If you'd prefer to set a key without running a login command, you can use an environment variable instead: + +**macOS / Linux / bash / zsh:** +```bash +export APIMATIC_API_KEY=YOUR_API_KEY +``` + +**Windows PowerShell:** +```powershell +$env:APIMATIC_API_KEY = "YOUR_API_KEY" +``` + +**Windows Command Prompt:** +``` +set APIMATIC_API_KEY=YOUR_API_KEY +``` + +Once the environment variable is set, the CLI will pick it up automatically with no separate login step needed. + +--- + +If neither approach works, check that your APIMatic account is active and that you have internet access to apimatic.io. Let me know once authentication is confirmed and I can continue from there. diff --git a/skills/apimatic-sdk/evals/workspace/eval-6-response.md b/skills/apimatic-sdk/evals/workspace/eval-6-response.md new file mode 100644 index 0000000..0b34a74 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-6-response.md @@ -0,0 +1,35 @@ +Great — since you're already authenticated and plan to customize the SDK afterwards, I'll generate your Java SDK with change tracking enabled. That way your customizations will be preserved across future regenerations. + +First, verify your authentication is still active: + +``` +apimatic auth status +``` + +Once that confirms your account, run the following from inside `./my-java-api/` (the directory that contains your `src/` folder): + +``` +apimatic sdk generate --language=java --track-changes +``` + +The `--track-changes` flag initializes change tracking so that any customizations you make can be saved and automatically reapplied every time you regenerate. The SDK will be generated at `./my-java-api/sdk/java/` by default. + +--- + +**Before you start customizing, keep these tips in mind:** + +- Add custom logic in a **new file** where possible — new files are never overwritten on regeneration. +- Avoid editing generated files directly. +- If you must edit a generated file, add your changes at the **top or bottom** to reduce merge conflicts. + +--- + +**Once you've made your customizations**, save them so they survive future regenerations: + +``` +apimatic sdk save-changes --language=java --input=./my-java-api +``` + +This captures the diff between the plain generated output and your modified version. From that point on, every time you run `sdk generate`, your customizations are reapplied automatically. + +Make your customizations now, then let me know when you're ready to save them. diff --git a/skills/apimatic-sdk/evals/workspace/eval-7-response.md b/skills/apimatic-sdk/evals/workspace/eval-7-response.md new file mode 100644 index 0000000..5a8bc5b --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-7-response.md @@ -0,0 +1,71 @@ +Running the APIMatic CLI non-interactively in GitHub Actions is straightforward — you skip browser-based login entirely and pass your API key directly to the generate command. Here's how to set it up. + +## Prerequisites + +Make sure these are in place before configuring the workflow: + +- **Node.js >= 20** available in your runner (the `actions/setup-node` action handles this) +- **An APIMatic API key** stored as a GitHub Actions secret (e.g., `APIMATIC_API_KEY`) +- **Your project repository** contains a `src/` folder with your API spec inside `src/spec/` + +API keys can be generated at: APIMatic Dashboard > Account > API Keys. + +--- + +## GitHub Actions Workflow + +Create a file at `.github/workflows/generate-sdk.yml` in your repository: + +```yaml +name: Generate PHP SDK + +on: + push: + branches: + - main # or whichever branch(es) you want to trigger generation + +jobs: + generate-sdk: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install APIMatic CLI + run: npm install -g @apimatic/cli + + - name: Generate PHP SDK + run: | + apimatic sdk generate \ + --input=. \ + --language=php \ + --auth-key=${{ secrets.APIMATIC_API_KEY }} \ + --force +``` + +--- + +## Key Points + +**No login command needed.** Passing `--auth-key` directly to `sdk generate` is all that's required in a CI environment. + +**`--input` points to the directory containing `src/`**, not to the spec file itself. In the example above, `.` means the root of the checked-out repository — adjust this if your project lives in a subdirectory. + +**`--force` allows repeated builds.** On the first run, the SDK is generated fresh. On every subsequent push, `--force` tells the CLI to overwrite the existing output rather than stopping with an error. + +**The API key stays secret.** GitHub Actions injects `${{ secrets.APIMATIC_API_KEY }}` as an environment value at runtime — it is never written to logs or exposed in the workflow file. + +--- + +## Troubleshooting + +- **Authentication error:** Verify the secret name in your repository settings matches exactly what you used in the workflow. +- **`apimatic` command not found:** Make sure the install step runs before the generate step and that Node.js is set up correctly. +- **Missing `src/` folder or spec file:** The CLI expects your API spec at `src/spec/` inside the directory you pass to `--input`. Double-check that path. +- **SDK already exists error (without `--force`):** Add `--force` to the generate command as shown above. diff --git a/skills/apimatic-sdk/evals/workspace/eval-8-response.md b/skills/apimatic-sdk/evals/workspace/eval-8-response.md new file mode 100644 index 0000000..4ce738d --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-8-response.md @@ -0,0 +1,38 @@ +The `apimatic --version` command not found error typically means the npm global binary directory is not in your system PATH, even though the package was installed successfully. Let's fix that. + +**Step 1: Fix the PATH issue** + +First, find where npm installs global binaries: + +``` +npm config get prefix +``` + +This will print a directory path (e.g., `/usr/local` on macOS/Linux, or `C:\Users\YourName\AppData\Roaming\npm` on Windows). + +If the npm prefix's `bin` folder is missing from your PATH, add it: + +On macOS/Linux (bash/zsh): +```bash +export PATH="$(npm config get prefix)/bin:$PATH" +``` + +To make it permanent, add that line to your `~/.bashrc` or `~/.zshrc`, then reload with `source ~/.bashrc`. + +On Windows PowerShell: +```powershell +$env:PATH = "$(npm config get prefix)" + ";" + $env:PATH +``` + +After updating PATH, verify the CLI is working: +``` +apimatic --version +``` + +If that still fails, try reinstalling: +``` +npm install -g @apimatic/cli +apimatic --version +``` + +Once `apimatic --version` returns a version number, you're good. Let me know when that's confirmed and we'll move on to authentication and Python SDK generation. diff --git a/skills/apimatic-sdk/evals/workspace/eval-9-response.md b/skills/apimatic-sdk/evals/workspace/eval-9-response.md new file mode 100644 index 0000000..0cda1d0 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/eval-9-response.md @@ -0,0 +1,28 @@ +Great — since you're already authenticated, let's get your customizations saved. + +First, I need to check whether change tracking has been initialized for your TypeScript SDK. Look inside your project folder (`./ts-api/`) for a folder called `sdk-source-tree`. Does it exist there? + +--- + +**If `sdk-source-tree` is present (and contains a `.typescript` file):** + +Change tracking is already set up. Run this to save your customizations: + +``` +apimatic sdk save-changes --language=typescript --input=./ts-api +``` + +That's it. Your extra helper methods are now saved and will be reapplied automatically every time you regenerate. + +--- + +**If `sdk-source-tree` is not present:** + +Change tracking hasn't been initialized yet, which means we need to run a fresh generation with `--track-changes` to set it up. However, generating into your current SDK folder would overwrite your existing customizations. + +Would you like me to use a temporary folder for the fresh generation, or do you have a preferred destination instead? + +- If you provide a path, I'll generate into that path. +- If you're fine with a temporary folder, I'll use `./ts-api/sdk/temp/typescript` and delete it after setup is complete. + +Once the fresh generation is done, I'll run `sdk save-changes` pointing at your **original** customized SDK so your helper methods are captured — not the temporary output. diff --git a/skills/apimatic-sdk/evals/workspace/grading.json b/skills/apimatic-sdk/evals/workspace/grading.json new file mode 100644 index 0000000..c0d8001 --- /dev/null +++ b/skills/apimatic-sdk/evals/workspace/grading.json @@ -0,0 +1,569 @@ +{ + "total_assertions": 86, + "total_passed": 86, + "evals": [ + { + "eval_id": 0, + "status": "PASS", + "score": "6/6", + "results": [ + { + "id": "checks-auth-status", + "passed": true, + "evidence": "Found 'apimatic auth status'" + }, + { + "id": "runs-auth-login", + "passed": true, + "evidence": "Found 'apimatic auth login'" + }, + { + "id": "waits-for-user-confirmation", + "passed": true, + "evidence": "Found: ['confirm', 'let me know', \"when you're done\", 'when done', 'after you']" + }, + { + "id": "generates-python-sdk", + "passed": true, + "evidence": "Found '--language=python'" + }, + { + "id": "does-not-add-zip-unprompted", + "passed": true, + "evidence": "Correctly absent: '--zip'" + }, + { + "id": "asks-about-destination", + "passed": true, + "evidence": "Found: ['destination', 'default location']" + } + ] + }, + { + "eval_id": 1, + "status": "PASS", + "score": "6/6", + "results": [ + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "uses-correct-directory", + "passed": true, + "evidence": "Found: ['payments-api', 'D:\\\\work\\\\payments-api']" + }, + { + "id": "generates-typescript-sdk", + "passed": true, + "evidence": "Found '--language=typescript'" + }, + { + "id": "includes-zip-flag", + "passed": true, + "evidence": "Found '--zip'" + }, + { + "id": "uses-custom-destination", + "passed": true, + "evidence": "Found: ['--destination', 'D:\\\\output\\\\ts-sdk']" + }, + { + "id": "runs-from-project-root", + "passed": true, + "evidence": "Correctly absent: 'cd src'" + } + ] + }, + { + "eval_id": 2, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "mentions-src-directory", + "passed": true, + "evidence": "Found: ['src/', 'src\\\\']" + }, + { + "id": "mentions-spec-in-src-spec", + "passed": true, + "evidence": "Found: ['src/spec', 'src\\\\spec', 'spec/']" + }, + { + "id": "does-not-generate-directly", + "passed": true, + "evidence": "Correctly absent: 'apimatic sdk generate --input=./openapi.yaml'" + }, + { + "id": "mentions-go-language", + "passed": true, + "evidence": "Found: ['go', 'Go', '--language=go']" + }, + { + "id": "does-not-mention-portal-skill", + "passed": true, + "evidence": "Correctly absent" + } + ] + }, + { + "eval_id": 3, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "generates-csharp-sdk", + "passed": true, + "evidence": "Found '--language=csharp'" + }, + { + "id": "uses-force-flag", + "passed": true, + "evidence": "Found '--force'" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['my-api', './my-api']" + }, + { + "id": "does-not-add-zip-unprompted", + "passed": true, + "evidence": "Correctly absent: '--zip'" + } + ] + }, + { + "eval_id": 4, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "generates-ruby-sdk", + "passed": true, + "evidence": "Found '--language=ruby'" + }, + { + "id": "no-destination-flag", + "passed": true, + "evidence": "Correctly absent: '--destination'" + }, + { + "id": "no-zip-flag", + "passed": true, + "evidence": "Correctly absent: '--zip'" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['ruby-project', '~/ruby-project']" + } + ] + }, + { + "eval_id": 5, + "status": "PASS", + "score": "3/3", + "results": [ + { + "id": "offers-api-key-fallback", + "passed": true, + "evidence": "Found '--auth-key'" + }, + { + "id": "mentions-api-keys-location", + "passed": true, + "evidence": "Found: ['API Keys', 'Account > API Keys', 'APIMatic Dashboard']" + }, + { + "id": "does-not-proceed-to-generate", + "passed": true, + "evidence": "Correctly absent: 'apimatic sdk generate'" + } + ] + }, + { + "eval_id": 6, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "generates-java-sdk", + "passed": true, + "evidence": "Found '--language=java'" + }, + { + "id": "uses-track-changes", + "passed": true, + "evidence": "Found '--track-changes'" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['my-java-api', './my-java-api']" + } + ] + }, + { + "eval_id": 7, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "runs-sdk-generate", + "passed": true, + "evidence": "Found 'apimatic sdk generate'" + }, + { + "id": "uses-auth-key-flag", + "passed": true, + "evidence": "Found '--auth-key'" + }, + { + "id": "generates-php-sdk", + "passed": true, + "evidence": "Found '--language=php'" + }, + { + "id": "recommends-for-ci", + "passed": true, + "evidence": "Found: ['CI', 'non-interactive', 'GitHub Actions']" + }, + { + "id": "no-browser-login-for-ci", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login\n'" + } + ] + }, + { + "eval_id": 8, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "suggests-reinstall", + "passed": true, + "evidence": "Found 'npm install -g @apimatic/cli'" + }, + { + "id": "does-not-proceed-to-generate", + "passed": true, + "evidence": "Correctly absent: 'apimatic sdk generate'" + }, + { + "id": "does-not-proceed-to-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "mentions-version-check", + "passed": true, + "evidence": "Found 'apimatic --version'" + } + ] + }, + { + "eval_id": 9, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "does-not-regenerate", + "passed": true, + "evidence": "Correctly absent: 'apimatic sdk generate'" + }, + { + "id": "runs-save-changes", + "passed": true, + "evidence": "Found 'apimatic sdk save-changes'" + }, + { + "id": "uses-typescript-language", + "passed": true, + "evidence": "Found '--language=typescript'" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['ts-api', './ts-api']" + } + ] + }, + { + "eval_id": 10, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "generates-with-track-changes", + "passed": true, + "evidence": "Found '--track-changes'" + }, + { + "id": "generates-python-sdk", + "passed": true, + "evidence": "Found '--language=python'" + }, + { + "id": "prompts-user-to-customize", + "passed": true, + "evidence": "Found: ['make your customizations', 'add your changes', 'let me know when', \"when you're done\"]" + }, + { + "id": "runs-save-changes", + "passed": true, + "evidence": "Found 'apimatic sdk save-changes'" + } + ] + }, + { + "eval_id": 11, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "scaffolds-src-structure", + "passed": true, + "evidence": "Found: ['src/spec', 'mkdir']" + }, + { + "id": "generates-with-track-changes", + "passed": true, + "evidence": "Found '--track-changes'" + }, + { + "id": "prompts-user-to-customize", + "passed": true, + "evidence": "Found: ['make your customizations', 'let me know when', \"when you're ready\"]" + }, + { + "id": "runs-save-changes", + "passed": true, + "evidence": "Found 'apimatic sdk save-changes'" + } + ] + }, + { + "eval_id": 12, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "generates-java-sdk", + "passed": true, + "evidence": "Found '--language=java'" + }, + { + "id": "uses-skip-changes-flag", + "passed": true, + "evidence": "Found '--skip-changes'" + }, + { + "id": "non-destructive-explanation", + "passed": true, + "evidence": "Found: ['not removed', 'still be applied']" + }, + { + "id": "does-not-delete-sdk-source-tree", + "passed": true, + "evidence": "Correctly absent: 'delete'" + } + ] + }, + { + "eval_id": 13, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "generates-go-sdk", + "passed": true, + "evidence": "Found '--language=go'" + }, + { + "id": "uses-api-version-flag", + "passed": true, + "evidence": "Found '--api-version=v2'" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['multi-version-api', './multi-version-api']" + }, + { + "id": "does-not-add-zip-unprompted", + "passed": true, + "evidence": "Correctly absent: '--zip'" + } + ] + }, + { + "eval_id": 15, + "status": "PASS", + "score": "6/6", + "results": [ + { + "id": "uses-short-copyright-notice-setting", + "passed": true, + "evidence": "Found 'ShortCopyrightNotice'" + }, + { + "id": "updates-apimatic-meta", + "passed": true, + "evidence": "Found 'APIMATIC-META.json'" + }, + { + "id": "generates-python-sdk", + "passed": true, + "evidence": "Found '--language=python'" + }, + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "does-not-manually-inject-copyright", + "passed": true, + "evidence": "Correctly absent" + }, + { + "id": "references-project-dir", + "passed": true, + "evidence": "Found: ['payments-api', './payments-api']" + } + ] + }, + { + "eval_id": 14, + "status": "PASS", + "score": "4/4", + "results": [ + { + "id": "recommends-env-var", + "passed": true, + "evidence": "Found 'APIMATIC_API_KEY'" + }, + { + "id": "shows-env-var-syntax", + "passed": true, + "evidence": "Found: ['export APIMATIC_API_KEY', '$env:APIMATIC_API_KEY']" + }, + { + "id": "does-not-recommend-browser-login", + "passed": true, + "evidence": "Correctly absent: 'auth-login.mjs'" + }, + { + "id": "mentions-no-login-command-needed", + "passed": true, + "evidence": "Found: ['no login', 'no login command']" + } + ] + }, + { + "eval_id": 16, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "uses-disable-docs-setting", + "passed": true, + "evidence": "Found 'DisableDocs'" + }, + { + "id": "updates-apimatic-meta", + "passed": true, + "evidence": "Found 'APIMATIC-META.json'" + }, + { + "id": "generates-typescript-sdk", + "passed": true, + "evidence": "Found '--language=typescript'" + }, + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + }, + { + "id": "does-not-manually-delete-docs", + "passed": true, + "evidence": "Correctly absent" + } + ] + }, + { + "eval_id": 19, + "status": "PASS", + "score": "5/5", + "results": [ + { + "id": "uses-project-name-setting", + "passed": true, + "evidence": "Found 'ProjectName'" + }, + { + "id": "uses-correct-name", + "passed": true, + "evidence": "Found 'PaymentsSDK'" + }, + { + "id": "updates-apimatic-meta", + "passed": true, + "evidence": "Found 'APIMATIC-META.json'" + }, + { + "id": "generates-java-sdk", + "passed": true, + "evidence": "Found '--language=java'" + }, + { + "id": "skips-auth", + "passed": true, + "evidence": "Correctly absent: 'apimatic auth login'" + } + ] + }, + { + "eval_id": 30, + "status": "PASS", + "score": "2/2", + "results": [ + { + "id": "mentions-ruby-only", + "passed": true, + "evidence": "Found: ['Ruby', 'ruby', 'Ruby only', 'ForceKeywordArgsInRuby']" + }, + { + "id": "does-not-blindly-apply", + "passed": true, + "evidence": "Correctly absent: '\"ForceKeywordArgsInRuby\": true'" + } + ] + } + ] +} \ No newline at end of file diff --git a/skills/apimatic-sdk/examples/generate-customize-save.md b/skills/apimatic-sdk/examples/generate-customize-save.md new file mode 100644 index 0000000..b988f6c --- /dev/null +++ b/skills/apimatic-sdk/examples/generate-customize-save.md @@ -0,0 +1,49 @@ +# Generate, Customize, and Save SDK Changes + +This example shows how to generate an SDK with change tracking, customize a generated file, save those customizations, and regenerate with them automatically reapplied. + +**Flow:** generate (tracking auto-enabled) → customize → save-changes → regenerate + +--- + +## Step 1: Generate the SDK + +Run from the directory that contains `src/`: + +``` +apimatic sdk generate --language=typescript +``` + +Change tracking is enabled automatically. The `sdk-source-tree` is saved at `src/sdk-source-tree/.typescript` and will be used to reapply your customizations on every future generation. + +--- + +## Step 2: Customize the generated SDK + +Edit any generated file. In this example, `sdk/typescript/README.md` is updated: + +```diff +- This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about Swagger at https://swagger.io. In the third iteration of the pet store, we've switched to the design first approach! + ++ This is a sample Pet Store Server built on the OpenAPI 3.0 specification. It demonstrates a fully functional REST API for managing pets, orders, and users. For more information about the OpenAPI standard and tooling, visit https://swagger.io. +``` + +--- + +## Step 3: Save the changes + +``` +apimatic sdk save-changes --language=typescript +``` + +The CLI detects which files were modified and saves a diff to `src/sdk-source-tree/.typescript`. These changes will reapply automatically on every future generation. + +--- + +## Step 4: Regenerate + +``` +apimatic sdk generate --language=typescript +``` + +The CLI overwrites the existing SDK and reapplies your saved customizations automatically. No manual re-editing needed. diff --git a/skills/apimatic-sdk/references/code-branding-settings.md b/skills/apimatic-sdk/references/code-branding-settings.md new file mode 100644 index 0000000..cf1f7a7 --- /dev/null +++ b/skills/apimatic-sdk/references/code-branding-settings.md @@ -0,0 +1,97 @@ +# Code Branding Settings + +These settings allow white-labeling and personalization of SDKs. Use this reference when the user wants to add a brand label, set a copyright notice, or customize the attribution text in generated SDK files. + +--- + +## Step 1: Identify the Required Setting + +Find the setting that matches what the user wants to change: + +| Setting | What it does | +| ---------------------- | ------------------------------------------------------------------------------------ | +| `BrandLabel` | Adds the company name to the auto-generated header comment in every SDK file | +| `ShortCopyrightNotice` | Replaces the default MIT license notice with custom copyright text in all code files | + +--- + +## Step 2: Check Language Support + +Both settings are supported across all SDK languages: + +| C# | Java | PHP | Python | Ruby | TS | Go | +| --- | ---- | --- | ------ | ---- | --- | --- | +| Yes | Yes | Yes | Yes | Yes | Yes | Yes | + +> **Note for BrandLabel:** If creating a fully white-labeled SDK where all APIMatic attribution is already removed, this setting has no effect. + +> **Note for ShortCopyrightNotice:** This setting is only applicable to white-labeled SDKs. + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Brand Label** — specify the company name as a string: + +```json +{ + "CodeGenSettings": { + "BrandLabel": "Tech Corp" + } +} +``` + +**Short Copyright Notice** — specify the full copyright text as a string. If omitted, the default MIT notice is used: + +```json +{ + "CodeGenSettings": { + "ShortCopyrightNotice": "Copyright (c) 2025 Tech Corp. All rights reserved." + } +} +``` + +Both settings can be combined: + +```json +{ + "CodeGenSettings": { + "BrandLabel": "Tech Corp", + "ShortCopyrightNotice": "Copyright (c) 2025 Tech Corp. All rights reserved." + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +After generation, open any source file in the generated SDK and confirm the header reflects the configured values. + +**BrandLabel effect** — every generated file header changes from: + +``` +This file was automatically generated by APIMATIC v3.0 ( https://www.apimatic.io ). +``` + +to: + +``` +This file was automatically generated for Tech Corp by APIMATIC v3.0 ( https://www.apimatic.io ). +``` + +**ShortCopyrightNotice effect** — the license file and file headers use the custom copyright text instead of the default MIT notice. diff --git a/skills/apimatic-sdk/references/endpoint-settings.md b/skills/apimatic-sdk/references/endpoint-settings.md new file mode 100644 index 0000000..f3e3728 --- /dev/null +++ b/skills/apimatic-sdk/references/endpoint-settings.md @@ -0,0 +1,298 @@ +# Endpoint Settings + +These settings manage endpoint-specific behavior in the generated SDKs. Use this reference when the user wants to change how endpoint methods are named, what they return, how parameters are handled, or how the SDK responds to specific HTTP status codes. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +Find the setting that matches what the user wants to change: + +| Setting | What it does | +| ------- | ------------ | +| `ReturnCompleteHttpResponse` | Returns the full HTTP response (headers + status code) instead of just the response body | +| `UseHttpMethodPrefix` | Prefixes endpoint method names with the HTTP verb (`Get`, `Update`, or `Delete`) | +| `EncodeTemplateParameters` | Encodes endpoint-level template parameters | +| `ValidateRequiredParameters` | Throws an exception when a required parameter is passed as null | +| `CollapseParamsToArray` | Collapses multiple endpoint parameters into a single options array | +| `UseEndpointMethodName` | Uses the `MethodName` property on the endpoint entity instead of `Name` for method naming | +| `Nullify404` | Returns null instead of throwing an exception on HTTP 404 | +| `NullifyEmptyResponses` | Accepts empty response payloads as null when multiple response types are defined | +| `LiftParameterDescriptionFromCustomType` | Uses a referenced custom type's description as the parameter description when the parameter has none | +| `ForceKeywordArgsInRuby` | Uses keyword arguments instead of positional arguments for required parameters (Ruby only) | +| `MapErrorTypesInCompleteResponseForPHP` | Maps typed error responses when returning complete HTTP responses (PHP only, requires `ReturnCompleteHttpResponse`) | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ------- | --- | --- | --- | --- | --- | --- | --- | +| `ReturnCompleteHttpResponse` | Yes | Yes | Yes | Yes | Yes | Built-in | Built-in | +| `UseHttpMethodPrefix` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `EncodeTemplateParameters` | No | Yes | No | Yes | Yes | Yes | No | +| `ValidateRequiredParameters` | Yes | Yes | Yes | Yes | Yes | Yes | Built-in | +| `CollapseParamsToArray` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `UseEndpointMethodName` | Yes | Yes | Yes | No | No | Yes | Yes | +| `Nullify404` | Yes | Yes | Yes | Yes | Yes | No | No | +| `NullifyEmptyResponses` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `LiftParameterDescriptionFromCustomType` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `ForceKeywordArgsInRuby` | No | No | No | No | Yes | No | No | +| `MapErrorTypesInCompleteResponseForPHP` | No | No | Yes | No | No | No | No | + +**Built-in** means the behavior is inherently supported by default in that language and cannot be disabled. + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Return Complete HTTP Response** — default: `false` +```json +{ + "CodeGenSettings": { + "ReturnCompleteHttpResponse": true + } +} +``` + +**Use HTTP Method Prefix** — default: `false` + +> **Note:** Has no effect on method names that are already prefixed. + +```json +{ + "CodeGenSettings": { + "UseHttpMethodPrefix": true + } +} +``` + +**Encode Template Parameters** — default: `true` (experimental) +```json +{ + "CodeGenSettings": { + "EncodeTemplateParameters": true + } +} +``` + +**Validate Required Parameters** — default: `false` + +> **Note:** Default values for required parameters are ignored. + +```json +{ + "CodeGenSettings": { + "ValidateRequiredParameters": true + } +} +``` + +**Collapse Params to Array** — default: `false` + +> **Caution:** Use only in specific scenarios — this setting can hide type information from SDKs and documentation. + +```json +{ + "CodeGenSettings": { + "CollapseParamsToArray": true + } +} +``` + +**Use Endpoint Method Name** — default: `false` (experimental) +```json +{ + "CodeGenSettings": { + "UseEndpointMethodName": true + } +} +``` + +**Nullify 404** — default: `false` +```json +{ + "CodeGenSettings": { + "Nullify404": true + } +} +``` + +**Nullify Empty Responses** — default: `false` +```json +{ + "CodeGenSettings": { + "NullifyEmptyResponses": true + } +} +``` + +**Lift Parameter Description From Custom Type** — default: `false` +```json +{ + "CodeGenSettings": { + "LiftParameterDescriptionFromCustomType": true + } +} +``` + +**Force Keyword Arguments in Ruby** — default: `false` +```json +{ + "CodeGenSettings": { + "ForceKeywordArgsInRuby": true + } +} +``` + +**Map Error Types in Complete Response for PHP** — default: `false` + +> **Note:** Only applies when `ReturnCompleteHttpResponse` is also enabled. + +```json +{ + "CodeGenSettings": { + "ReturnCompleteHttpResponse": true, + "MapErrorTypesInCompleteResponseForPHP": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +After generation, check the affected endpoint methods in the generated SDK to confirm the change. + +**ReturnCompleteHttpResponse — `true`:** +```csharp +// C# +public ApiResponse GetData() +``` +```java +// Java +public ApiResponse getData() +``` +```php +// PHP +public function getData(): ApiResponse +``` +```python +# Python +def get_data(): + """Returns: ApiResponse""" +``` +```ruby +# Ruby +# @return [ApiResponse] +def get_data() +``` + +**ReturnCompleteHttpResponse — `false` (default):** +```csharp +// C# +public Models.ServerResponse GetData() +``` + +--- + +**UseHttpMethodPrefix — `true`:** +```csharp +// C# +dynamic result = await echoController.CreateJsonEchoAsync(input); +``` +```java +// Java +echoController.createJsonEchoAsync(input) +``` +```python +# Python +result = echo_controller.create_json_echo(input) +``` + +**UseHttpMethodPrefix — `false` (default):** +```csharp +dynamic result = await echoController.JsonEchoAsync(input); +``` + +--- + +**CollapseParamsToArray — `true`:** +```csharp +// C# +public Models.ServerResponse PostData(Models.PostDataInput input) +``` +```python +# Python +def post_data(self, options=dict()) +``` + +**CollapseParamsToArray — `false` (default):** +```csharp +public Models.ServerResponse PostData(bool unSet, bool setToNull, string field, Models.MyData data) +``` +```python +def post_data(self, un_set, set_to_null, field, data) +``` + +--- + +**Nullify404 — `true`:** Returns `null` on HTTP 404 instead of throwing an exception. + +**NullifyEmptyResponses — `true`:** Empty response payloads are returned as `null`; typed responses are returned normally. + +--- + +**ForceKeywordArgsInRuby — `true`:** +```ruby +result = echo_controller.json_echo(input: input) +``` + +**ForceKeywordArgsInRuby — `false` (default):** +```ruby +result = echo_controller.json_echo(input) +``` + +--- + +**MapErrorTypesInCompleteResponseForPHP — `true`:** +```php +if ($apiResponse->isError()) { + $error = $apiResponse->getResult(); + if ($error instanceof CustomAlphaException) { + echo "CustomAlphaException: $error"; + } elseif ($error instanceof CustomBetaException) { + echo "CustomBetaException: $error"; + } +} +``` + +**MapErrorTypesInCompleteResponseForPHP — `false` (default):** +```php +if ($apiResponse->isError()) { + $error = $apiResponse->getResult(); + echo "Untyped raw response body: $error"; +} +``` diff --git a/skills/apimatic-sdk/references/enum-settings.md b/skills/apimatic-sdk/references/enum-settings.md new file mode 100644 index 0000000..b4abb59 --- /dev/null +++ b/skills/apimatic-sdk/references/enum-settings.md @@ -0,0 +1,117 @@ +# Enum Settings + +These settings control how enums are generated within the SDKs. Use this reference when the user wants to enable or disable native enum types, or add a postfix to enum class names. + +--- + +## Step 1: Identify the Required Setting + +Find the setting that matches what the user wants to change: + +| Setting | What it does | +| --------------- | -------------------------------------------------------------------------------------------------------------------- | +| `GenerateEnums` | Generates enums as native enum types; when disabled, enum fields use primitive types (e.g., `string`, `int`) instead | +| `UseEnumPrefix` | Postfixes each enum class name with the word `Enum` (e.g., `Days` → `DaysEnum`) | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| --------------- | --- | ---- | -------- | ------ | ---- | --- | -------- | +| `GenerateEnums` | Yes | Yes | Built-in | Yes | Yes | Yes | Built-in | +| `UseEnumPrefix` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | + +**Built-in** means the behavior is inherently supported by default in that language and cannot be disabled. + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Generate Enums** — default: `true` + +```json +{ + "CodeGenSettings": { + "GenerateEnums": false + } +} +``` + +**Use Enum Prefix** — default: `true` + +```json +{ + "CodeGenSettings": { + "UseEnumPrefix": true + } +} +``` + +Both settings can be combined: + +```json +{ + "CodeGenSettings": { + "GenerateEnums": true, + "UseEnumPrefix": false + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +After generation, check the affected endpoint signatures in the generated SDK to confirm the change. + +**GenerateEnums — `true` (default):** + +```csharp +// C# +public Models.ServerResponse PostStringEnumArray(List days) +``` + +```java +// Java +public ServerResponse postStringEnumArray(final List days) +``` + +```python +# Python +days = [Days.SUNDAY, Days.MONDAY, Days.TUESDAY] +``` + +**GenerateEnums — `false`:** + +```csharp +public Models.ServerResponse PostStringEnumArray(List days) +``` + +```java +public ServerResponse postStringEnumArray(final List days) +``` + +```python +days = ['Sunday', 'Monday', 'Tuesday'] +``` + +--- + +**UseEnumPrefix — `true` (default):** `SuiteCodeEnum.HEARTS` / `DaysEnum` + +**UseEnumPrefix — `false`:** `SuiteCode.HEARTS` / `Days` diff --git a/skills/apimatic-sdk/references/exception-settings.md b/skills/apimatic-sdk/references/exception-settings.md new file mode 100644 index 0000000..711a4ec --- /dev/null +++ b/skills/apimatic-sdk/references/exception-settings.md @@ -0,0 +1,101 @@ +# Exception Settings + +These settings control how exceptions are handled and reported in the generated SDKs. Use this reference when the user wants to customize error messages for specific HTTP status codes or resolve naming conflicts in C# exception models. + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ErrorTemplates` | Configures custom error message templates for specific HTTP error codes or ranges; use `{$statusCode}` as a placeholder for the actual status code | +| `CSharpResolveExceptionPropertyCollisions` | Resolves naming conflicts in C# exception models where generated properties overlap with `System.Exception` members (e.g., `Message`, `StackTrace`) | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ------------------------------------------ | --- | ---- | --- | ------ | ---- | --- | --- | +| `ErrorTemplates` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `CSharpResolveExceptionPropertyCollisions` | Yes | No | No | No | No | No | No | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Error Templates** — default: `null` + +Keys are HTTP error codes (`"401"`) or ranges (`"5XX"`, `"0"`). Values are message strings with optional `{$statusCode}` placeholder. + +```json +{ + "CodeGenSettings": { + "ErrorTemplates": { + "401": "Failed to authorize, Code: {$statusCode}.", + "5XX": "Internal server error, Code: {$statusCode}.", + "0": "An error occurred. Code: {$statusCode}" + } + } +} +``` + +**CSharp Resolve Exception Property Collisions** — default: `false` + +Conflicting properties include: `Message`, `ResponseCode`, `StackTrace`, `Source`, `Data`, `HelpLink`, `HttpContext`, `InnerException`, `HResult`, `TargetSite`. + +> **Caution:** Enabling this setting may rename existing exception properties (e.g., `Message` → `MessageProperty`). Any code accessing the original property names will need to be updated. + +```json +{ + "CodeGenSettings": { + "CSharpResolveExceptionPropertyCollisions": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**ErrorTemplates** — check the exception classes in the generated SDK. The custom message template should appear in the error handling logic for the configured status codes. + +**CSharpResolveExceptionPropertyCollisions — `true`:** + +```csharp +public class Error : ApiException +{ + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("message")] + public string MessageProperty { get; set; } +} +``` + +**CSharpResolveExceptionPropertyCollisions — `false` (default):** + +```csharp +public class Error : ApiException +{ + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("message")] + public new string Message { get; set; } +} +``` diff --git a/skills/apimatic-sdk/references/first-time-setup.md b/skills/apimatic-sdk/references/first-time-setup.md new file mode 100644 index 0000000..9ac4960 --- /dev/null +++ b/skills/apimatic-sdk/references/first-time-setup.md @@ -0,0 +1,90 @@ +# First-Time Setup: Scaffolding the Project + +Use this when the user does not have a `src/` folder yet and needs to set up a project from scratch for SDK generation. + +--- + +## Step 1: Get the project directory + +Ask the user: "Where would you like me to set up the project directory? (Give a path, or I'll use the current directory)" + +- If the user provides a path, use that as the project root. +- If no path given, use the current working directory. + +--- + +## Step 2: Get the API spec file + +Ask the user: "What is the path to your API specification file? (OpenAPI JSON/YAML, Postman collection, or other supported format)" + +Store the spec file path. + +--- + +## Step 3: Create the directory structure + +Create the `src/spec/` directory inside the project root: + +```bash +mkdir -p /src/spec +``` + +On Windows PowerShell: + +```powershell +New-Item -ItemType Directory -Force -Path "\src\spec" +``` + +--- + +## Step 4: Copy the user's spec file + +Copy the user's API spec into `src/spec/`: + +```bash +cp /src/spec/ +``` + +On Windows PowerShell: + +```powershell +Copy-Item "" -Destination "\src\spec\" +``` + +--- + +## Step 5: Download APIMATIC-META.json + +Download the `APIMATIC-META.json` file from the sample portal repository into `src/spec/`: + +```bash +curl -L -o /src/spec/APIMATIC-META.json https://raw.githubusercontent.com/apimatic/sample-docs-as-code-portal/refs/heads/master/src/spec/APIMATIC-META.json +``` + +On Windows PowerShell: + +```powershell +Invoke-WebRequest -Uri "https://raw.githubusercontent.com/apimatic/sample-docs-as-code-portal/refs/heads/master/src/spec/APIMATIC-META.json" -OutFile "\src\spec\APIMATIC-META.json" +``` + +On macOS/Linux if `curl` is unavailable: + +```bash +wget -O /src/spec/APIMATIC-META.json https://raw.githubusercontent.com/apimatic/sample-docs-as-code-portal/refs/heads/master/src/spec/APIMATIC-META.json +``` + +--- + +## Step 6: Verify the structure + +After setup, the project directory should look like this: + +``` +/ +└── src/ + └── spec/ + ├── (e.g., openapi.json, petstore.yaml) + └── APIMATIC-META.json (downloaded from sample portal) +``` + +Navigate to the project root and continue with the SDK generation workflow. diff --git a/skills/apimatic-sdk/references/http-configuration-settings.md b/skills/apimatic-sdk/references/http-configuration-settings.md new file mode 100644 index 0000000..4c3abf7 --- /dev/null +++ b/skills/apimatic-sdk/references/http-configuration-settings.md @@ -0,0 +1,98 @@ +# HTTP Configuration Settings + +These settings manage HTTP behavior in the generated SDKs. Use this reference when the user wants to enable HTTP caching, control content-type headers, or add an option to skip SSL certificate verification. + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| `EnableHttpCache` | Enables HTTP caching for idempotent endpoint methods | +| `AppendContentHeaders` | Automatically appends `accept` and `content-type` headers based on the serialization mode | +| `AllowSkippingSSLCertVerification` | Adds a configuration option in the SDK to optionally skip SSL certificate verification for HTTPS connections | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ---------------------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `EnableHttpCache` | No | No | No | Yes | Yes | No | No | +| `AppendContentHeaders` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `AllowSkippingSSLCertVerification` | Yes | Yes | Yes | Yes | Yes | No | No | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Enable HTTP Cache** — default: `false` + +> **Note:** This setting is experimental and may not function properly at all times. + +```json +{ + "CodeGenSettings": { + "EnableHttpCache": true + } +} +``` + +**Append Content Headers** — default: `true` + +```json +{ + "CodeGenSettings": { + "AppendContentHeaders": true + } +} +``` + +**Allow Skipping SSL Certificate Verification** — default: `false` + +> **Caution:** Skipping SSL certificate verification is not recommended as it opens a security vulnerability. + +```json +{ + "CodeGenSettings": { + "AllowSkippingSSLCertVerification": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**AppendContentHeaders — `true` (default):** + +```curl +curl -X GET -G \ + --url 'http://localhost:3000/response/date' \ + -H 'Accept: application/json' \ + -d 'array=true' +``` + +**AppendContentHeaders — `false`:** + +```curl +curl -X GET -G \ + --url 'http://localhost:3000/response/date' \ + -d 'array=true' +``` + +**AllowSkippingSSLCertVerification** — when enabled, the generated SDK client exposes a configuration option (e.g., `skipSslCertVerification`, `verifyPeer`) that can be set to `true` to bypass certificate checks during development or testing. diff --git a/skills/apimatic-sdk/references/miscellaneous-settings.md b/skills/apimatic-sdk/references/miscellaneous-settings.md new file mode 100644 index 0000000..20282b4 --- /dev/null +++ b/skills/apimatic-sdk/references/miscellaneous-settings.md @@ -0,0 +1,191 @@ +# Miscellaneous Settings + +These settings cover code generation options that don't fit into a specific category but allow fine-tuning of SDK behavior, authentication handling, licensing, and casing conventions. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ----------------------------- | ---------------------------------------------------------------------------------------------------- | +| `DisableLinting` | Disables generation of lint test files and commands | +| `DisableMultipleAuth` | Disables multiple authentication support; only the first security scheme from the spec is applied | +| `AddSingleAuthDeprecatedCode` | Controls whether deprecated single-auth client setup code is included alongside the new auth flow | +| `JavaUsePropertiesConfig` | Allows the Java SDK to load its configuration from a properties file | +| `LicenseText` | Replaces the default MIT license text with a custom string in the SDK's license file | +| `StoreTimezoneInformation` | Stores timezone info with date-time values; when disabled, all date-time values are converted to UTC | +| `ApplyCustomizations` | Applies a list of APIMatic-provided customer-specific customization keys during SDK generation | +| `EnforceStandardizedCasing` | Enforces standardized casing conventions during SDK and docs generation | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ----------------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `DisableLinting` | No | No | Yes | No | Yes | Yes | No | +| `DisableMultipleAuth` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `AddSingleAuthDeprecatedCode` | Yes | Yes | Yes | Yes | Yes | Yes | N/A | +| `JavaUsePropertiesConfig` | No | Yes | No | No | No | No | No | +| `LicenseText` | Yes | Yes | Yes | Yes | Yes | Yes | No | +| `StoreTimezoneInformation` | Yes | Yes | No | No | No | No | No | +| `ApplyCustomizations` | Yes | Yes | Yes | Yes | Yes | Yes | No | +| `EnforceStandardizedCasing` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Disable Linting** — default: `false` + +```json +{ + "CodeGenSettings": { + "DisableLinting": true + } +} +``` + +**Disable Multiple Auth** — default: `false` + +> **Caution:** Disabling multiple authentication only applies the first security scheme from the OpenAPI specification. This flag will be deprecated eventually; using the full multiple-auth flow is recommended. + +```json +{ + "CodeGenSettings": { + "DisableMultipleAuth": true + } +} +``` + +**Add Single Auth Deprecated Code** — default: `true` + +```json +{ + "CodeGenSettings": { + "AddSingleAuthDeprecatedCode": false + } +} +``` + +**Java Use Properties Config** — default: `false` + +> **Note:** This is an experimental setting and may not work in all cases. + +```json +{ + "CodeGenSettings": { + "JavaUsePropertiesConfig": true + } +} +``` + +**License Text** — default: MIT license + +```json +{ + "CodeGenSettings": { + "LicenseText": "License text here..." + } +} +``` + +**Store Timezone Information** — default: `false` + +```json +{ + "CodeGenSettings": { + "StoreTimezoneInformation": true + } +} +``` + +**Apply Customizations** — list of APIMatic-provided keys + +```json +{ + "CodeGenSettings": { + "ApplyCustomizations": ["custom-abc", "custom-xyz"] + } +} +``` + +**Enforce Standardized Casing** — default: `false` + +```json +{ + "CodeGenSettings": { + "EnforceStandardizedCasing": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**AddSingleAuthDeprecatedCode — `true` (default):** deprecated fields appear alongside the new auth flow + +```ts +const client = new Client({ + basicAuthUsername: "Username", // Deprecated + basicAuthPassword: "Password", // Deprecated + basicAuthCredentials: { + username: "Username", + password: "Password", + }, +}); +``` + +**AddSingleAuthDeprecatedCode — `false`:** only the new auth flow is present + +```ts +const client = new Client({ + basicAuthCredentials: { + username: "Username", + password: "Password", + }, +}); +``` + +**StoreTimezoneInformation — `true`:** + +```csharp +DateTimeOffset datetime = DateTime.ParseExact("2023-03-13T12:52:32.123Z", ...); +``` + +```java +ZonedDateTime datetime = DateTimeHelper.fromRfc8601DateTime("2023-03-13T12:52:32.123Z"); +``` + +**StoreTimezoneInformation — `false` (default):** + +```csharp +DateTime datetime = DateTime.ParseExact("2023-03-13T12:52:32.123Z", ...); +``` + +```java +LocalDateTime datetime = DateTimeHelper.fromRfc8601DateTime("2023-03-13T12:52:32.123Z"); +``` diff --git a/skills/apimatic-sdk/references/model-settings.md b/skills/apimatic-sdk/references/model-settings.md new file mode 100644 index 0000000..49a9bbf --- /dev/null +++ b/skills/apimatic-sdk/references/model-settings.md @@ -0,0 +1,137 @@ +# Model Settings + +These settings control model-specific behavior in the generated SDKs. Use this reference when the user wants to enable typed additional properties, add a model name postfix, use keyword arguments in Ruby models, or skip equality method generation in C#. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `ExtendedAdditionalPropertiesSupport` | Enables typed additional properties on models, allowing specific data types instead of a generic type for extra fields | +| `UseModelPrefix` | Postfixes each model class name with `Model` (e.g., `Person` → `PersonModel`) to avoid naming conflicts | +| `EnableModelKeywordArgsInRuby` | Uses keyword arguments in Ruby model constructors instead of positional arguments | +| `CSharpSkipEqualityMethods` | Skips generation of `Equals` and `GetHashCode` implementations for models and container types in C# | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ------------------------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `ExtendedAdditionalPropertiesSupport` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `UseModelPrefix` | Yes | Yes | Yes | Yes | Yes | Yes | No | +| `EnableModelKeywordArgsInRuby` | No | No | No | No | Yes | No | No | +| `CSharpSkipEqualityMethods` | Yes | No | No | No | No | No | No | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Extended Additional Properties Support** — default: `false` + +```json +{ + "CodeGenSettings": { + "ExtendedAdditionalPropertiesSupport": true + } +} +``` + +**Use Model Prefix** — default: `false` + +> **Note:** Use this only if there is a risk of naming conflicts between models and other identifiers (APIs, endpoints, controllers) in the OpenAPI specification. + +```json +{ + "CodeGenSettings": { + "UseModelPrefix": true + } +} +``` + +**Enable Model Keyword Args in Ruby** — default: `false` + +```json +{ + "CodeGenSettings": { + "EnableModelKeywordArgsInRuby": true + } +} +``` + +**CSharp Skip Equality Methods** — default: `false` + +> **Note:** Enabling this prevents incorrect equality and hashing on mutable models. Any code relying on value-based equality (`Equals`, `==`, `Dictionary`, `HashSet`) may observe different behavior after enabling. + +```json +{ + "CodeGenSettings": { + "CSharpSkipEqualityMethods": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**ExtendedAdditionalPropertiesSupport — `true`:** + +```csharp +StudentResult body = new StudentResult { + Email = "student616@oxford.ac.uk", + ["Theory Of Automata"] = 82.1, + ["Computational complexity"] = 72.5, +}; +``` + +**ExtendedAdditionalPropertiesSupport — `false` (default):** + +```csharp +StudentResult body = new StudentResult { + Email = "student616@oxford.ac.uk", +}; +``` + +**UseModelPrefix — `true`:** `PersonModel`, `DeleteBodyModel`, `ServerResponseModel` + +**UseModelPrefix — `false` (default):** `Person`, `DeleteBody`, `ServerResponse` + +**EnableModelKeywordArgsInRuby — `true`:** + +```ruby +user = User.new(email: "bob@example.com", name: "Bob") +``` + +**EnableModelKeywordArgsInRuby — `false` (default):** + +```ruby +user = User.new("Alice", "alice@example.com") +``` + +**CSharpSkipEqualityMethods — `true`:** `Equals` and `GetHashCode` are not generated; equality falls back to reference comparison. + +**CSharpSkipEqualityMethods — `false` (default):** `Equals` and `GetHashCode` are generated for all models. diff --git a/skills/apimatic-sdk/references/save-changes.md b/skills/apimatic-sdk/references/save-changes.md new file mode 100644 index 0000000..7422242 --- /dev/null +++ b/skills/apimatic-sdk/references/save-changes.md @@ -0,0 +1,80 @@ +# Saving SDK Customizations + +Use this after the user has made their custom changes to a generated SDK and wants to preserve them across future regenerations. + +## Step 1: Determine flags + +**If `sdk generate` was already run in this session**, carry the values forward — do not ask again: + +- `--input` from generate → use the same value for `--input`. Omit if it was the default. +- `--destination` from generate → use the same value for `--sdk`. Omit if destination was the default. +- `--api-version` from generate → use the same value for `--api-version`. Omit if it was not used. + +**If starting save-changes without a prior generate step**, collect only what is unknown: + +- **Input directory (`--input`)** — if you do not know where the project root is, ask: "Is your project in the current directory, or is it somewhere else?" + - Current directory → omit `--input`. + - Different path → add `--input=` pointing to the parent directory that contains `src/`. + +- **SDK path (`--sdk`)** — if you do not know where the SDK lives, ask: "Is the SDK at the default location, or was it generated to a custom path?" + - Default location → omit `--sdk`. + - Custom path → add `--sdk=` pointing to the folder containing the updated SDK. + +- **API version (`--api-version`)** — do not ask. Only add `--api-version=` if the user mentions a specific version themselves. + +## Step 2: Run save-changes + +Run the command with the applicable flags: + +``` +apimatic sdk save-changes --language= +``` + +Examples with optional flags: + +``` +# Non-default input directory +apimatic sdk save-changes --language=typescript --input=./my-project + +# SDK at a custom path +apimatic sdk save-changes --language=typescript --sdk=./output/my-sdk + +# Specific API version (only when user mentioned it) +apimatic sdk save-changes --language=typescript --api-version=v2 +``` + +--- + +## Step 3: Verify and next steps + +After saving, ask the user: + +"Do you want to regenerate the SDK now to confirm your customizations are applied correctly?" + +- **Yes** → run: + + ``` + apimatic sdk generate --language= + ``` + +- **No** → inform the user: "Your customizations are saved. The next time you run `sdk generate` for this language, they'll be reapplied automatically." + +--- + +## Reverting customizations + +**Preview the SDK without customizations** (non-destructive — saved state is untouched): + +``` +apimatic sdk generate --language= --skip-changes +``` + +**Revert a specific customization** — undo the change in the generated SDK files, then save the updated state: + +``` +apimatic sdk save-changes --language= +``` + +This overwrites the previously saved state so the reverted change is no longer reapplied. + +**Remove all customizations** — delete the language file (e.g., `.typescript`) from the `sdk-source-tree` folder in the input directory. The next `sdk generate` for that language will run without any customizations, and change tracking will need to be re-initialized with `--track-changes`. diff --git a/skills/apimatic-sdk/references/sdk-docs-configuration-settings.md b/skills/apimatic-sdk/references/sdk-docs-configuration-settings.md new file mode 100644 index 0000000..2bc0403 --- /dev/null +++ b/skills/apimatic-sdk/references/sdk-docs-configuration-settings.md @@ -0,0 +1,157 @@ +# SDK Docs Configuration + +These settings control documentation generation for SDKs. Use this reference when the user wants to disable docs, include optional field examples, hide version numbers, pin a usage example endpoint, or configure resource sorting in generated documentation. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ----------------------------------- | ---------------------------------------------------------------------------------------------------- | +| `DisableDocs` | Disables README and all other SDK documentation file generation | +| `GenerateExamplesForOptionalFields` | Includes optional fields when generating sample values in docs | +| `IsLatestVersion` | Replaces specific version numbers in install commands and package repo links with generic references | +| `UsageExampleEndpoint` | Specifies an endpoint to display as a full usage example in the README | +| `SortResources` | Sorts endpoint groups, endpoints, and models alphabetically in generated docs | +| `ConfigureComponentSorting` | Provides per-component sorting control, overriding `SortResources` for the component types it covers | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ----------------------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `DisableDocs` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `GenerateExamplesForOptionalFields` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `IsLatestVersion` | Yes | No | Yes | Yes | Yes | Yes | Yes | +| `UsageExampleEndpoint` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `SortResources` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `ConfigureComponentSorting` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Disable Docs** — default: `false` + +```json +{ + "CodeGenSettings": { + "DisableDocs": true + } +} +``` + +**Generate Examples for Optional Fields** — default: `false` + +```json +{ + "CodeGenSettings": { + "GenerateExamplesForOptionalFields": true + } +} +``` + +**Is Latest Version** — default: `false` + +```json +{ + "CodeGenSettings": { + "IsLatestVersion": true + } +} +``` + +**Usage Example Endpoint** — specify `Description`, `EndpointGroupName`, and `EndpointName` + +```json +{ + "CodeGenSettings": { + "UsageExampleEndpoint": { + "Description": "Endpoint description here", + "EndpointGroupName": "Calculator", + "EndpointName": "OperationGet" + } + } +} +``` + +**Sort Resources** — default: `false` + +```json +{ + "CodeGenSettings": { + "SortResources": true + } +} +``` + +**Configure Component Sorting** — overrides `SortResources` for the component types it covers + +| Field | Type | Description | Default | +| ----------------------- | ------- | --------------------------------------------- | -------- | +| `SortEndpointGroups` | Boolean | Sort endpoint groups alphabetically | `false` | +| `EndpointSorting` | String | `"None"`, `"Alphabetical"`, or `"HttpMethod"` | `"None"` | +| `SortWebhookGroups` | Boolean | Sort webhook groups alphabetically | `false` | +| `WebhookEventsSorting` | String | `"None"`, `"Alphabetical"`, or `"HttpMethod"` | `"None"` | +| `SortCallbackGroups` | Boolean | Sort callback groups alphabetically | `false` | +| `CallbackEventsSorting` | String | `"None"`, `"Alphabetical"`, or `"HttpMethod"` | `"None"` | +| `SortModels` | Boolean | Sort models alphabetically | `false` | + +```json +{ + "CodeGenSettings": { + "ConfigureComponentSorting": { + "SortEndpointGroups": true, + "EndpointSorting": "HttpMethod", + "SortWebhookGroups": true, + "SortCallbackGroups": true, + "WebhookEventsSorting": "HttpMethod", + "CallbackEventsSorting": "HttpMethod", + "SortModels": true + } + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**IsLatestVersion — `true`:** install command in README omits the version number + +``` +npm install container +``` + +**IsLatestVersion — `false` (default):** install command includes the specific version + +``` +npm install container@2.0.1 +``` + +**UsageExampleEndpoint:** a **Make Calls with the API Client** section appears in `Readme.md` for all SDKs, containing a full code sample for the configured endpoint. + +**SortResources / ConfigureComponentSorting:** endpoint groups, endpoints, and models in the generated docs appear in sorted order rather than the order defined in the OpenAPI specification. diff --git a/skills/apimatic-sdk/references/sdk-interface-customization-settings.md b/skills/apimatic-sdk/references/sdk-interface-customization-settings.md new file mode 100644 index 0000000..fac8632 --- /dev/null +++ b/skills/apimatic-sdk/references/sdk-interface-customization-settings.md @@ -0,0 +1,281 @@ +# SDK Interface Customization + +These settings control the overall look and feel of the generated SDK code — naming conventions, namespaces, controller structure, interfaces, authentication naming, logging, and synchrony mode. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ------------------------------------ | ------------------------------------------------------------------------------------------ | +| `ProjectName` | Sets the name of the generated SDK package and client class | +| `CSharpNamespace` | Sets the root namespace for C# SDKs | +| `JavaPackageName` | Sets the root package name for Java SDKs | +| `PHPNamespace` | Sets the root namespace for PHP SDKs | +| `UseControllerPrefix` | Appends a postfix (default: `Controller`) to each controller class name | +| `ControllerPostfix` | Sets a custom postfix string for controller classes (requires `UseControllerPrefix: true`) | +| `ControllerNamespace` | Sets the namespace/folder name where controller classes are placed | +| `GenerateInterfaces` | Generates interfaces for controller classes to support mock testing | +| `ClientInterfaceName` | Sets the class name for the client interface (Python only) | +| `UseSecuritySchemeNameForSingleAuth` | Uses the auth scheme name from the spec as the auth method name in the client | +| `DoNotSplitWords` | List of words that should not be split when converting identifiers (e.g., brand names) | +| `SynchronyMode` | Switches between `Asynchronous` (default) and `Synchronous` code generation | +| `EnableLogging` | Includes logging configuration support in the generated SDK client | +| `SymbolizeHashKeysInRuby` | Uses symbols instead of strings for hash keys in Ruby SDKs | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ------------------------------------ | --- | ---- | --- | ------ | ---- | -------- | -------- | +| `ProjectName` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `CSharpNamespace` | Yes | No | No | No | No | No | No | +| `JavaPackageName` | No | Yes | No | No | No | No | No | +| `PHPNamespace` | No | No | Yes | No | No | No | No | +| `UseControllerPrefix` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `ControllerPostfix` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `ControllerNamespace` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `GenerateInterfaces` | Yes | Yes | No | No | No | No | Built-in | +| `ClientInterfaceName` | No | No | No | Yes | No | No | No | +| `UseSecuritySchemeNameForSingleAuth` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `DoNotSplitWords` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `SynchronyMode` | Yes | Yes | No | No | No | Built-in | Built-in | +| `EnableLogging` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `SymbolizeHashKeysInRuby` | No | No | No | No | Yes | No | No | + +**Built-in** means the behavior is inherent to the language and cannot be changed. + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Project Name** — default: API name + +```json +{ + "CodeGenSettings": { + "ProjectName": "MyProject" + } +} +``` + +**CSharp Namespace** — default: API name + +```json +{ + "CodeGenSettings": { + "CSharpNamespace": "OrgNamespace" + } +} +``` + +**Java Package Name** — default: derived from Base URI (e.g., `apimatic.io` → `io.apimatic`) + +```json +{ + "CodeGenSettings": { + "JavaPackageName": "com.example.sdk" + } +} +``` + +**PHP Namespace** — default: API name + +```json +{ + "CodeGenSettings": { + "PHPNamespace": "Apimatic" + } +} +``` + +**Use Controller Prefix** — default: `true` + +```json +{ + "CodeGenSettings": { + "UseControllerPrefix": true + } +} +``` + +**Controller Postfix** — default: `"Controller"` (requires `UseControllerPrefix: true`) + +```json +{ + "CodeGenSettings": { + "ControllerPostfix": "Api" + } +} +``` + +**Controller Namespace** — default: `"Controllers"` + +```json +{ + "CodeGenSettings": { + "ControllerNamespace": "Apis" + } +} +``` + +**Generate Interfaces** — default: `false` + +> **Note:** This is an experimental setting and may not work in all cases. + +```json +{ + "CodeGenSettings": { + "GenerateInterfaces": true + } +} +``` + +**Client Interface Name** — default: derived from `ProjectName` (e.g., `TesterClient`) + +```json +{ + "CodeGenSettings": { + "ClientInterfaceName": "Interface" + } +} +``` + +**Use Security Scheme Name For Single Auth** — default: `false` + +```json +{ + "CodeGenSettings": { + "UseSecuritySchemeNameForSingleAuth": true + } +} +``` + +**Do Not Split Words** — list of words (alphanumeric only); order determines priority + +```json +{ + "CodeGenSettings": { + "DoNotSplitWords": ["apimatic", "vmware", "petId"] + } +} +``` + +**Synchrony Mode** — default: `"Asynchronous"` + +```json +{ + "CodeGenSettings": { + "SynchronyMode": "Synchronous" + } +} +``` + +**Enable Logging** — default: `false` + +```json +{ + "CodeGenSettings": { + "EnableLogging": true + } +} +``` + +**Symbolize Hash Keys in Ruby** — default: `false` + +```json +{ + "CodeGenSettings": { + "SymbolizeHashKeysInRuby": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**ProjectName — `"MyProject"`:** + +```csharp +// C# +MyProject.Standard.MyProjectClient client = new MyProject.Standard.MyProjectClient.Builder() + .Environment(MyProject.Standard.Environment.Testing) + .Build(); +``` + +```java +// Java +MyProjectClient client = new MyProjectClient.Builder() + .environment(Environment.TESTING) + .build(); +``` + +**UseControllerPrefix — `true` (default):** `responseTypesController.getContentTypeHeaders()` + +**UseControllerPrefix — `false`:** `responseTypes.getContentTypeHeaders()` + +**ControllerPostfix — `"Api"`:** `echoApi.jsonEcho(input)` instead of `echoController.jsonEcho(input)` + +**GenerateInterfaces — `true`:** + +```csharp +IBodyParamsController bodyParamsController = client.BodyParamsController; +``` + +**UseSecuritySchemeNameForSingleAuth — `true`:** auth method uses the scheme name from the spec (e.g., `ccgAuth`) instead of the generic type name (`clientCredentialsAuth`): + +```csharp +// true +new SdkClient.Builder().CcgAuth(new CcgAuthModel.Builder("id", "secret").Build()).Build(); +// false (default) +new SdkClient.Builder().ClientCredentialsAuth(new ClientCredentialsAuthModel.Builder("id", "secret").Build()).Build(); +``` + +**DoNotSplitWords — `["petId"]`:** the word `petId` is treated as one token and lowercased instead of split: + +```csharp +public Models.Pet GetPetById(long petid) // configured +public Models.Pet GetPetById(long petId) // default +``` + +**SynchronyMode — `"Synchronous"`:** + +```csharp +EmployeeComp result = responseTypesController.ReturnEmployeeModel(); // Synchronous +EmployeeComp result = await responseTypesController.ReturnEmployeeModelAsync(); // Asynchronous (default) +``` + +**EnableLogging — `true`:** the SDK client exposes logging configuration options: + +```csharp +SdkClient client = new SdkClient.Builder() + .LoggingConfig(config => config + .LogLevel(LogLevel.Information) + .RequestConfig(reqConfig => reqConfig.Body(true)) + ) + .Build(); +``` diff --git a/skills/apimatic-sdk/references/serialization-settings.md b/skills/apimatic-sdk/references/serialization-settings.md new file mode 100644 index 0000000..0753f7b --- /dev/null +++ b/skills/apimatic-sdk/references/serialization-settings.md @@ -0,0 +1,125 @@ +# Serialization Settings + +These settings configure how values are serialized and deserialized in the generated SDKs. Use this reference when the user wants to change how arrays are formatted in query/form parameters or how `any`-typed fields are handled. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `ArraySerialization` | Sets the serialization format for arrays in query and form parameters; allowed values: `Indexed`, `UnIndexed`, `Plain`, `CSV`, `TSV`, `PSV` | +| `EnableJsonPassThroughForAny` | When enabled, `any`-typed fields are passed as raw JSON objects (`JsonObject`) instead of generic `object` types | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ----------------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `ArraySerialization` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `EnableJsonPassThroughForAny` | Yes | Yes | Yes | Yes | Yes | Yes | No | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Array Serialization** — default: `"Indexed"` + +| Value | Format example | +| ----------- | ----------------------------------------------- | +| `Indexed` | `variableName[0]=value1&variableName[1]=value2` | +| `UnIndexed` | `variableName[]=value1&variableName[]=value2` | +| `Plain` | `variableName=value1&variableName=value2` | +| `CSV` | `variableName=value1,value2` | +| `TSV` | `variableName=value1\tvalue2` | +| `PSV` | `variableName=value1\|value2` | + +```json +{ + "CodeGenSettings": { + "ArraySerialization": "CSV" + } +} +``` + +**Enable JSON Pass Through for Any** — default: `false` + +```json +{ + "CodeGenSettings": { + "EnableJsonPassThroughForAny": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +**EnableJsonPassThroughForAny — `true`:** + +```csharp +// C# +JsonObject body = JsonObject.FromJsonString("{\"key1\":\"val1\",\"key2\":\"val2\"}"); +ServerResponse result = await controller.SendSchemaasBodyAsync(body); +``` + +```java +// Java +JsonObject body = JsonObject.fromJsonString("{\"key1\":\"val1\",\"key2\":\"val2\"}"); +``` + +```php +// PHP +$body = '{"key1":"val1","key2":"val2"}'; +``` + +```python +# Python — body is typed as dict +body = {"key1": "val1", "key2": "val2"} +``` + +**EnableJsonPassThroughForAny — `false` (default):** + +```csharp +// C# +object body = ApiHelper.JsonDeserialize("{\"key1\":\"val1\",\"key2\":\"val2\"}"); +``` + +```java +// Java +Object body = ApiHelper.deserialize("{\"key1\":\"val1\",\"key2\":\"val2\"}"); +``` + +```php +// PHP +$body = ["key1" => "val1", "key2" => "val2"]; +``` + +```python +# Python — body is typed as object (any value) +body = 'Any Value' +``` diff --git a/skills/apimatic-sdk/references/timeout-and-retries-settings.md b/skills/apimatic-sdk/references/timeout-and-retries-settings.md new file mode 100644 index 0000000..d8304bc --- /dev/null +++ b/skills/apimatic-sdk/references/timeout-and-retries-settings.md @@ -0,0 +1,198 @@ +# Timeout and Retries Settings + +These settings control request timeouts, retry behavior, and exponential backoff in the generated SDKs. Use this reference when the user wants to configure how long requests wait before timing out, when to retry, and how retries are spaced. + +## Contents + +- [Step 1: Identify the Required Setting](#step-1-identify-the-required-setting) +- [Step 2: Check Language Support](#step-2-check-language-support) +- [Step 3: Apply the Setting in APIMATIC-META.json](#step-3-apply-the-setting-in-apimatic-metajson) +- [Step 4: Regenerate the SDK](#step-4-regenerate-the-sdk) +- [Step 5: Verify the Output](#step-5-verify-the-output) + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ------------------------- | -------------------------------------------------------------------------------------------------------------- | +| `Timeout` | Sets the request timeout in seconds; `0` means no timeout | +| `RetryOnTimeout` | Enables retrying requests that time out; must be enabled to use the other retry settings | +| `RequestMethodsToRetry` | Specifies which HTTP methods to retry; allowed values: `GET`, `PUT` | +| `StatusCodesToRetry` | Specifies which HTTP status codes trigger a retry; allowed: `408, 413, 429, 500, 502, 503, 504, 521, 522, 524` | +| `BackoffMax` | Sets the maximum total wait time (in seconds) across all retry attempts | +| `Retries` | Sets the number of retry attempts before the request fails | +| `RetryInterval` | Sets the base time interval (in seconds) between retries | +| `BackOffFactor` | Multiplier applied to `RetryInterval` on each successive retry for exponential backoff | +| `UserConfigurableRetries` | Exposes retry configuration options to SDK users in the client constructor | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ------------------------- | --- | ---- | --- | -------- | -------- | --- | --- | +| `Timeout` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `RetryOnTimeout` | Yes | Yes | Yes | Built-in | Built-in | Yes | Yes | +| `RequestMethodsToRetry` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `StatusCodesToRetry` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `BackoffMax` | Yes | Yes | Yes | No | No | Yes | Yes | +| `Retries` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `RetryInterval` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `BackOffFactor` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `UserConfigurableRetries` | Yes | No | No | No | No | Yes | Yes | + +**Built-in** means Python and Ruby always retry on timeout and the behavior cannot be disabled. + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant keys under `CodeGenSettings`. + +> **Note:** `RetryOnTimeout` must be set to `true` to activate `RequestMethodsToRetry`, `StatusCodesToRetry`, `BackoffMax`, `Retries`, `RetryInterval`, and `BackOffFactor`. + +**Timeout** — default: `0` (no timeout) + +```json +{ + "CodeGenSettings": { + "Timeout": 30 + } +} +``` + +**RetryOnTimeout** — default: `true` + +```json +{ + "CodeGenSettings": { + "RetryOnTimeout": true + } +} +``` + +**RequestMethodsToRetry** — default: `["GET", "PUT"]` + +```json +{ + "CodeGenSettings": { + "RequestMethodsToRetry": ["GET", "PUT"] + } +} +``` + +**StatusCodesToRetry** — default: `[408, 413, 429, 500, 502, 503, 504, 521, 522, 524]` + +```json +{ + "CodeGenSettings": { + "StatusCodesToRetry": [408, 429, 503] + } +} +``` + +**BackoffMax** — maximum total retry wait time in seconds + +```json +{ + "CodeGenSettings": { + "BackoffMax": 120 + } +} +``` + +**Retries** — default: `0` + +```json +{ + "CodeGenSettings": { + "Retries": 3 + } +} +``` + +**RetryInterval** — base interval in seconds, default: `1.0` + +```json +{ + "CodeGenSettings": { + "RetryInterval": 1.5 + } +} +``` + +**BackOffFactor** — exponential backoff multiplier, default: `2` + +```json +{ + "CodeGenSettings": { + "BackOffFactor": 1.5 + } +} +``` + +**UserConfigurableRetries** — default: `true` + +```json +{ + "CodeGenSettings": { + "UserConfigurableRetries": true + } +} +``` + +All retry settings combined example: + +```json +{ + "CodeGenSettings": { + "Timeout": 30, + "RetryOnTimeout": true, + "RequestMethodsToRetry": ["GET", "PUT"], + "StatusCodesToRetry": [408, 429, 503], + "BackoffMax": 120, + "Retries": 3, + "RetryInterval": 1.5, + "BackOffFactor": 2, + "UserConfigurableRetries": true + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +When `UserConfigurableRetries` is `true`, SDK users can configure timeout and retry behavior in their client constructor: + +```typescript +const client = new Client({ + timeout: 60, + httpClientOptions: { + retryConfig: { + maxNumberOfRetries: 3, + retryOnTimeout: true, + retryInterval: 1, + httpStatusCodesToRetry: [ + 408, 413, 429, 500, 502, 503, 504, 521, 522, 524, + ], + httpMethodsToRetry: ["GET", "PUT"], + }, + }, +}); +``` + +When `UserConfigurableRetries` is `false`, these options are not exposed in the client constructor and the retry configuration is fixed to the values set in `APIMATIC-META.json`. diff --git a/skills/apimatic-sdk/references/user-agent-settings.md b/skills/apimatic-sdk/references/user-agent-settings.md new file mode 100644 index 0000000..80ee45f --- /dev/null +++ b/skills/apimatic-sdk/references/user-agent-settings.md @@ -0,0 +1,102 @@ +# User Agent Settings + +These settings configure the user agent string sent in API call headers. Use this reference when the user wants to disable the global user agent or customize the user agent string with dynamic placeholders. + +--- + +## Step 1: Identify the Required Setting + +| Setting | What it does | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `EnableGlobalUserAgent` | Enables or disables sending the `UserAgent` field in the user-agent header globally across all API calls | +| `UserAgent` | Sets a custom user agent string; supports placeholders like `{language}`, `{version}`, `{engine}`, `{engine-version}`, and `{os-info}` | + +--- + +## Step 2: Check Language Support + +| Setting | C# | Java | PHP | Python | Ruby | TS | Go | +| ----------------------- | --- | ---- | --- | ------ | ---- | --- | --- | +| `EnableGlobalUserAgent` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | +| `UserAgent` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | + +--- + +## Step 3: Apply the Setting in APIMATIC-META.json + +Open `/src/spec/APIMATIC-META.json` and add the relevant key under `CodeGenSettings`. + +**Enable Global User Agent** — default: `true` + +> **Note:** Disabling this setting will not prevent the user agent from being sent if it has been explicitly set as an additional header or included in the endpoint parameters as a header parameter. + +```json +{ + "CodeGenSettings": { + "EnableGlobalUserAgent": false + } +} +``` + +**User Agent** — default: `"APIMATIC 3.0"` + +Supported placeholders: + +| Placeholder | Resolves to | +| ------------------ | ------------------------------------------ | +| `{language}` | SDK language name (e.g., `Java`, `PHP`) | +| `{version}` | API version from the OpenAPI specification | +| `{engine}` | Runtime engine name | +| `{engine-version}` | Runtime engine version | +| `{os-info}` | OS where the SDK is being operated | + +```json +{ + "CodeGenSettings": { + "UserAgent": "{language} SDK, Version: {version}, on OS {os-info}" + } +} +``` + +Both settings can be combined: + +```json +{ + "CodeGenSettings": { + "EnableGlobalUserAgent": true, + "UserAgent": "{language} SDK, Version: {version}, on OS {os-info}" + } +} +``` + +--- + +## Step 4: Regenerate the SDK + +Navigate to the project root (the directory that contains `src/`) and run: + +``` +apimatic sdk generate --language= +``` + +Use the same `--input`, `--destination`, and `--api-version` flags that were used when the SDK was originally generated. The updated `APIMATIC-META.json` is picked up automatically — no extra flags are needed. + +--- + +## Step 5: Verify the Output + +After generation, inspect the SDK's HTTP client initialization or request builder to confirm the user agent header. + +**Default user agent (`APIMATIC 3.0`):** + +``` +User-Agent: APIMATIC 3.0 +``` + +**Custom user agent with placeholders resolved at runtime:** + +``` +User-Agent: Java SDK, Version: 1.0, on OS Linux +``` + +**EnableGlobalUserAgent — `false`:** the SDK omits the `User-Agent` header from requests unless it is explicitly passed as an additional header or endpoint parameter. From 823b34f291c57422b14ee63179259e5273fb9606 Mon Sep 17 00:00:00 2001 From: Ayeshas09 Date: Thu, 23 Apr 2026 15:44:09 +0500 Subject: [PATCH 2/5] update grade.py --- .gitignore | 3 + skills/apimatic-sdk/evals/grade.py | 64 +- .../evals/workspace/eval-0-response.md | 96 --- .../evals/workspace/eval-1-response.md | 11 - .../evals/workspace/eval-10-response.md | 34 -- .../evals/workspace/eval-11-response.md | 57 -- .../evals/workspace/eval-12-response.md | 7 - .../evals/workspace/eval-13-response.md | 37 -- .../evals/workspace/eval-14-response.md | 52 -- .../evals/workspace/eval-15-response.md | 43 -- .../evals/workspace/eval-16-response.md | 27 - .../evals/workspace/eval-19-response.md | 33 - .../evals/workspace/eval-2-response.md | 93 --- .../evals/workspace/eval-3-response.md | 13 - .../evals/workspace/eval-30-response.md | 40 -- .../evals/workspace/eval-4-response.md | 28 - .../evals/workspace/eval-5-response.md | 48 -- .../evals/workspace/eval-6-response.md | 35 -- .../evals/workspace/eval-7-response.md | 71 --- .../evals/workspace/eval-8-response.md | 38 -- .../evals/workspace/eval-9-response.md | 28 - .../apimatic-sdk/evals/workspace/grading.json | 569 ------------------ 22 files changed, 40 insertions(+), 1387 deletions(-) delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-0-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-1-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-10-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-11-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-12-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-13-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-14-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-15-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-16-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-19-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-2-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-3-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-30-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-4-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-5-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-6-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-7-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-8-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/eval-9-response.md delete mode 100644 skills/apimatic-sdk/evals/workspace/grading.json diff --git a/.gitignore b/.gitignore index 0e60879..17ee8a4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ apimatic-portal-workspace/ skills/apimatic-portal/evals/workspace/ skills/apimatic-portal/evals/results.json +apimatic-sdk-workspace/ +skills/apimatic-sdk/evals/workspace/ +skills/apimatic-sdk/evals/results.json \ No newline at end of file diff --git a/skills/apimatic-sdk/evals/grade.py b/skills/apimatic-sdk/evals/grade.py index 5abceff..59bb43b 100644 --- a/skills/apimatic-sdk/evals/grade.py +++ b/skills/apimatic-sdk/evals/grade.py @@ -62,37 +62,47 @@ def check_assertion(text, assertion): "passed": passed, "evidence": evidence }) + total_assertions += 1 if passed: + total_passed += 1 eval_passed += 1 - total_assertions += 1 - - total_passed += eval_passed - score = f"{eval_passed}/{len(assertions)}" - status = "PASS" if eval_passed == len(assertions) else "FAIL" - print(f"\n=== EVAL {eval_id} === {status} ({score})") - print(f"Prompt: {eval_item['prompt'][:80]}...") - for r in results: - mark = "PASS" if r["passed"] else "FAIL" - print(f" [{mark}] {r['id']}: {r['evidence']}") + pass_rate = eval_passed / len(assertions) if assertions else 1.0 results_by_eval.append({ - "eval_id": eval_id, - "status": status, - "score": score, + "id": eval_id, + "prompt": eval_item["prompt"][:80], + "pass_rate": pass_rate, "results": results }) -print(f"\n{'='*50}") -print(f"TOTAL: {total_passed}/{total_assertions} assertions passed") -if failed_evals: - print(f"MISSING: evals {failed_evals} had no response file") - -# Save grading results -grading_output = os.path.join(WORKSPACE, "grading.json") -with open(grading_output, "w") as f: - json.dump({ - "total_assertions": total_assertions, - "total_passed": total_passed, - "evals": results_by_eval - }, f, indent=2) -print(f"\nResults saved to {grading_output}") + status = "✓" if pass_rate == 1.0 else ("~" if pass_rate >= 0.5 else "✗") + print(f"\n{status} EVAL {eval_id}: {eval_item['prompt'][:60]}...") + for r in results: + sym = "✓" if r["passed"] else "✗" + print(f" {sym} {r['id']}: {r['evidence']}") + print(f" Pass rate: {pass_rate:.0%} ({eval_passed}/{len(assertions)})") + +print(f"\n{'='*60}") +print(f"OVERALL: {total_passed}/{total_assertions} assertions passed ({total_passed/total_assertions:.0%})") + +# Summary of failing evals +failing = [e for e in results_by_eval if e["pass_rate"] < 1.0] +if failing: + print(f"\nFAILING EVALS ({len(failing)}):") + for e in failing: + failing_assertions = [r for r in e["results"] if not r["passed"]] + print(f" Eval {e['id']}: {e['pass_rate']:.0%} — failing: {[r['id'] for r in failing_assertions]}") +else: + print("\nAll evals passed!") + +# Write results JSON +results_out = { + "total_passed": total_passed, + "total_assertions": total_assertions, + "pass_rate": total_passed / total_assertions if total_assertions else 0, + "evals": results_by_eval +} +out_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "results.json") +with open(out_path, "w") as f: + json.dump(results_out, f, indent=2) +print(f"\nDetailed results written to: {out_path}") diff --git a/skills/apimatic-sdk/evals/workspace/eval-0-response.md b/skills/apimatic-sdk/evals/workspace/eval-0-response.md deleted file mode 100644 index 41b2c5f..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-0-response.md +++ /dev/null @@ -1,96 +0,0 @@ -Great! Let's get your Python SDK generated. Since this is your first time using the APIMatic CLI, we'll go through setup together. - -## Step 1: Check prerequisites - -Before anything else, make sure you have **Node.js 20 or later** installed. Run this to check: - -``` -node --version -``` - -If you don't have Node.js, download it from https://nodejs.org (choose the LTS version). - -Once Node.js is confirmed, install the APIMatic CLI globally: - -``` -npm install -g @apimatic/cli -``` - -Then verify it installed correctly: - -``` -apimatic --version -``` - -If you see a version number, you're good to go. Let me know when that's done. - ---- - -## Step 2: Authenticate with APIMatic - -You'll need a free APIMatic account. If you don't have one yet, sign up at https://app.apimatic.io. - -First, check if you're already authenticated: - -``` -apimatic auth status -``` - -If it doesn't show an account email, run this to log in via your browser: - -``` -apimatic auth login -``` - -A browser window will open. Complete sign-in there, then come back here and let me know when you're done. - -After you confirm, we'll verify it worked: - -``` -apimatic auth status -``` - -It should show your account email. If browser login doesn't work, you can use an API key instead — generate one at APIMatic Dashboard > Account > API Keys, then run: - -``` -apimatic auth login --auth-key=YOUR_API_KEY -``` - ---- - -## Step 3: A couple of quick questions before we generate - -Your input directory is `~/my-api-project/` and the language is **Python** — both already known. I just need two more things: - -1. **Destination:** Do you have a specific folder where you'd like the SDK to be placed, or should I use the default location? (The default would be `~/my-api-project/sdk/python/`.) - -2. **Customization:** Would you like to set up change tracking so any customizations you make to the SDK survive future regenerations? If yes, I'll add `--track-changes` to the generate command. - ---- - -## Step 4: Generate the SDK - -Once auth is confirmed and those questions are answered, the generate command will look like this: - -``` -apimatic sdk generate --input=~/my-api-project --language=python -``` - -Or with a custom destination: - -``` -apimatic sdk generate --input=~/my-api-project --language=python --destination=~/path/to/sdk-output -``` - -Note: `--input` points to `~/my-api-project/` — the folder containing `src/`, not the spec file itself. - ---- - -**Summary of what I still need from you:** - -1. Confirm Node.js is installed and the CLI installs successfully. -2. Complete browser sign-in and confirm when done. -3. Default destination or a custom path? -4. Change tracking — yes or no? - -Once those are answered, your Python SDK will be ready to go. diff --git a/skills/apimatic-sdk/evals/workspace/eval-1-response.md b/skills/apimatic-sdk/evals/workspace/eval-1-response.md deleted file mode 100644 index ccf0e11..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-1-response.md +++ /dev/null @@ -1,11 +0,0 @@ -Since you're already set up and authenticated, you're ready to go. - -Run this command to generate the TypeScript SDK as a zip file in your chosen output folder: - -``` -apimatic sdk generate --input=D:\work\payments-api --language=typescript --destination=D:\output\ts-sdk --zip -``` - -Once it completes, your zipped TypeScript SDK will be at `D:\output\ts-sdk`. - -If the CLI reports that an SDK already exists at that destination, let me know and I can re-run with `--force` to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-10-response.md b/skills/apimatic-sdk/evals/workspace/eval-10-response.md deleted file mode 100644 index b77c1c6..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-10-response.md +++ /dev/null @@ -1,34 +0,0 @@ -Great — since you're already authenticated and have your `src/` folder set up at `./python-api/`, you're in a good spot to move quickly. Here's what we'll do: generate the Python SDK with change tracking enabled so your custom utility functions are preserved across future regenerations. - -**Step 1: Generate the Python SDK with change tracking** - -Navigate to your project root (the directory that contains `src/`) and run: - -``` -cd ./python-api -apimatic sdk generate --language=python --track-changes -``` - -This generates the SDK at `./python-api/sdk/python/` by default and initializes change tracking. Every future regeneration will automatically reapply your customizations. - -If an SDK already exists at that destination, the CLI will warn you. If that happens, let me know — I'll add `--force` to overwrite it, or we can pick a different destination. - -**Step 2: Add your custom utility functions** - -Once generation completes, follow these guidelines when adding your utility code: - -- Add custom logic in a **new file** where possible — new files are never overwritten on regeneration. For example, create `./python-api/sdk/python/utils.py` for your helpers. -- Avoid editing generated files directly. -- If you must edit a generated file, add your changes at the top or bottom to reduce merge conflicts. - -Make your customizations now, then let me know when you're done. - -**Step 3: Save your customizations** - -Once your utilities are in place, run: - -``` -apimatic sdk save-changes --language=python --input=./python-api -``` - -This captures exactly what you changed or added and stores it in the source tree. From this point on, every time you run `sdk generate` for Python, your customizations will be reapplied automatically — no manual re-editing needed. diff --git a/skills/apimatic-sdk/evals/workspace/eval-11-response.md b/skills/apimatic-sdk/evals/workspace/eval-11-response.md deleted file mode 100644 index 22293cb..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-11-response.md +++ /dev/null @@ -1,57 +0,0 @@ -Great — since you're authenticated and starting from scratch, let's get your project set up and generate your first SDK. - -## Step 1: Set up your project directory - -First, I need to know where you'd like the project to live. Where would you like me to set up the project directory? (Give a path, or I'll use the current directory.) - -Once you tell me the project path, I'll scaffold the project structure for you: - -1. Create the `src/spec/` folder inside your project directory -2. Copy your API spec from `~/specs/payments.yaml` into `src/spec/` -3. Create a starter `APIMATIC-META.json` configuration file in `src/spec/` - -The commands I'll run (using your chosen project path, e.g. `~/payments-sdk-project`): - -```bash -mkdir -p ~/payments-sdk-project/src/spec -cp ~/specs/payments.yaml ~/payments-sdk-project/src/spec/ -``` - -After setup, your project will look like this: - -``` -payments-sdk-project/ -└── src/ - └── spec/ - ├── payments.yaml - └── APIMATIC-META.json -``` - -## Step 2: Choose your language - -Which language would you like the SDK generated in? - -| Option | Language | -|---|---| -| `csharp` | C# | -| `java` | Java | -| `php` | PHP | -| `python` | Python | -| `ruby` | Ruby | -| `typescript` | TypeScript | -| `go` | Go | - -## Step 3: Customization - -Since you mentioned you want to customize the SDK, I'll enable change tracking during generation with `--track-changes`. This lets you make edits to the generated SDK and save those customizations so they're automatically reapplied on every future regeneration. - -Would you like me to apply the customizations for you, or will you handle them yourself after generation? - -Once you answer (project path and language), I'll scaffold the project and run the generate command — for example: - -```bash -cd ~/payments-sdk-project -apimatic sdk generate --language=typescript --track-changes -``` - -Then prompt: "Make your customizations now, then let me know when you're ready to save them." Once you confirm, I'll run `apimatic sdk save-changes`. diff --git a/skills/apimatic-sdk/evals/workspace/eval-12-response.md b/skills/apimatic-sdk/evals/workspace/eval-12-response.md deleted file mode 100644 index 743fbec..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-12-response.md +++ /dev/null @@ -1,7 +0,0 @@ -To see your Java SDK without your customizations applied, run the generate command with the `--skip-changes` flag from your project directory: - -``` -apimatic sdk generate --input=./java-api --language=java --skip-changes -``` - -This produces a clean copy of the SDK as if your customizations were never applied. Your saved customizations are not affected — they are not removed and will still be applied in future regenerations unless you explicitly remove them. diff --git a/skills/apimatic-sdk/evals/workspace/eval-13-response.md b/skills/apimatic-sdk/evals/workspace/eval-13-response.md deleted file mode 100644 index 11853bc..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-13-response.md +++ /dev/null @@ -1,37 +0,0 @@ -Since you're already authenticated, let's move straight to generating your Go SDK. - -You've provided everything I need: - -- **Input directory:** `./multi-version-api/` (already has a `src/` folder) -- **Language:** Go -- **API version:** v2 - -**Step 1: Navigate to your project root** - -Make sure you're in the directory that contains the `src/` folder (not inside `src/` itself): - -``` -cd multi-version-api -``` - -**Step 2: Run the generate command** - -``` -apimatic sdk generate --input=./multi-version-api --language=go --api-version=v2 -``` - -Or, if you're already inside `multi-version-api/`: - -``` -apimatic sdk generate --language=go --api-version=v2 -``` - -The SDK will be generated at `./multi-version-api/sdk/v2/go/` by default. - ---- - -**If you run into any issues:** - -- **SDK already exists at that location:** The CLI will let you know. Just say the word and I'll re-run the command with `--force` to overwrite it. -- **Authentication error:** Run `apimatic auth status` to check, then let me know if it shows your account email. -- **Any other error:** Share the message and I'll help you resolve it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-14-response.md b/skills/apimatic-sdk/evals/workspace/eval-14-response.md deleted file mode 100644 index 47839f7..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-14-response.md +++ /dev/null @@ -1,52 +0,0 @@ -For Docker and CI environments where interactive login isn't an option, the cleanest approach is the **environment variable method** — your API key never touches your shell history, and no login command is required at all. - -## Option 1: Environment Variable (Recommended for Docker) - -Set the environment variable before running any APIMatic CLI command. The CLI picks it up automatically — no `apimatic auth login` needed. - -**In your Dockerfile or docker run command:** - -```dockerfile -# Pass the key at runtime — keeps it out of the image and shell history -docker run -e APIMATIC_API_KEY="your_api_key_here" your-image -``` - -**In a shell script or CI pipeline (Linux/macOS/bash):** - -```bash -export APIMATIC_API_KEY="your_api_key_here" -``` - -The key is set in the current process environment only — it does not appear in your shell history. - -**Windows PowerShell:** - -```powershell -$env:APIMATIC_API_KEY = "your_api_key_here" -``` - -Once the variable is set, run generation normally: - -```bash -apimatic sdk generate --input=path/to/project --language= -``` - -## Option 2: Inline Flag on the Generate Command - -If you prefer to keep auth tied directly to the generate command, pass the key as a flag: - -```bash -apimatic sdk generate --input=path/to/project --language= --auth-key=$APIMATIC_API_KEY -``` - -## Where to Get Your API Key - -Log in to the APIMatic Dashboard, go to **Account > API Keys**, and generate a key from there. - -## Which Option to Use? - -- **Docker / CI pipeline:** Use the environment variable. Inject it via your CI secret manager (GitHub Actions secrets, GitLab CI variables, AWS Secrets Manager, etc.) so it never appears in logs or image layers. -- **One-off Docker run:** Use `-e APIMATIC_API_KEY=...` on the `docker run` command. -- **Prefer a single command:** Use the `--auth-key` flag directly on `sdk generate`, sourcing from an already-injected env var. - -All three approaches keep the key out of your shell history and avoid the need for interactive browser login. No `apimatic auth login` command needed in any of these cases. diff --git a/skills/apimatic-sdk/evals/workspace/eval-15-response.md b/skills/apimatic-sdk/evals/workspace/eval-15-response.md deleted file mode 100644 index a315913..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-15-response.md +++ /dev/null @@ -1,43 +0,0 @@ -Great news — since you're already authenticated and your `src/` folder is set up, we can move straight to configuration. - -The copyright notice you want is a built-in CodeGen setting called `ShortCopyrightNotice`. It tells APIMatic to embed your custom copyright text in the header of every generated SDK file — no manual file editing needed. - ---- - -## Step 1: Update APIMATIC-META.json - -Open `./payments-api/src/spec/APIMATIC-META.json` and add `ShortCopyrightNotice` inside `CodeGenSettings`. For example: - -```json -{ - "CodeGenSettings": { - "ShortCopyrightNotice": "Copyright (c) 2026 Your Company Name. All rights reserved." - } -} -``` - -Replace the copyright text with whatever you'd like to appear in your files. If `CodeGenSettings` already has other keys, just add `"ShortCopyrightNotice"` alongside them. - -Save the file. - ---- - -## Step 2: Generate the SDK - -Navigate to your project root (the folder that contains `src/`) and run: - -``` -apimatic sdk generate --input=./payments-api --language=python -``` - -That's it — no extra flags needed for the copyright notice. APIMatic picks it up automatically from `APIMATIC-META.json`. - -If you'd like the SDK placed somewhere specific, add `--destination=path/to/output`. Otherwise it will be generated at `./payments-api/sdk/python` by default. - ---- - -## Step 3: Verify the Output - -Once generation completes, open any `.py` file in the generated SDK. You should see your copyright text in the file header. - -If the CLI tells you an SDK already exists at the destination, let me know and I'll help you decide whether to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-16-response.md b/skills/apimatic-sdk/evals/workspace/eval-16-response.md deleted file mode 100644 index a2ea3a6..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-16-response.md +++ /dev/null @@ -1,27 +0,0 @@ -Since you want no documentation files in the generated SDK, the right approach is to set `DisableDocs: true` in your `APIMATIC-META.json` before generating — this ensures docs are never produced in the first place, rather than removing them after the fact. - -**Step 1: Update APIMATIC-META.json** - -Open `./my-api/src/spec/APIMATIC-META.json` and add `DisableDocs: true` under `CodeGenSettings`: - -```json -{ - "CodeGenSettings": { - "DisableDocs": true - } -} -``` - -If `CodeGenSettings` already exists in the file, just add `"DisableDocs": true` inside it alongside any other settings already there. - -**Step 2: Generate the SDK** - -From the `./my-api/` directory (the one that contains `src/`), run: - -``` -apimatic sdk generate --input=./my-api --language=typescript -``` - -That's it. The SDK will be generated at `./my-api/sdk/typescript/` with no README or other documentation files included. - -If you'd like to put the SDK somewhere else, add `--destination=your/preferred/path` to the command. Let me know if you run into any issues. diff --git a/skills/apimatic-sdk/evals/workspace/eval-19-response.md b/skills/apimatic-sdk/evals/workspace/eval-19-response.md deleted file mode 100644 index 26caa7d..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-19-response.md +++ /dev/null @@ -1,33 +0,0 @@ -Setting the SDK project name is a CodeGen setting — specifically `ProjectName` in `APIMATIC-META.json`. Since you're already authenticated, here's what to do: - -**Step 1: Open your APIMATIC-META.json** - -Open the file at: - -``` -./payments/src/spec/APIMATIC-META.json -``` - -**Step 2: Add the ProjectName setting** - -Locate the `CodeGenSettings` object and add (or update) the `ProjectName` key: - -```json -{ - "CodeGenSettings": { - "ProjectName": "PaymentsSDK" - } -} -``` - -Save the file. - -**Step 3: Regenerate the SDK** - -From the `./payments/` directory (the one that contains `src/`), run: - -``` -apimatic sdk generate --input=./payments --language=java -``` - -That's it — the project name is baked into the generation config, so every future regeneration will use `PaymentsSDK` automatically. diff --git a/skills/apimatic-sdk/evals/workspace/eval-2-response.md b/skills/apimatic-sdk/evals/workspace/eval-2-response.md deleted file mode 100644 index 7468818..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-2-response.md +++ /dev/null @@ -1,93 +0,0 @@ -Great news — since you have your OpenAPI spec ready but no project directory yet, we just need to scaffold the project structure before generating the SDK. Here's exactly what to do, step by step. - -## Before You Start: Prerequisites - -Make sure you have the following in place: - -1. **Node.js 20 or later** — download from https://nodejs.org if needed. Verify with: - ``` - node --version - ``` - -2. **APIMatic CLI installed globally:** - ``` - npm install -g @apimatic/cli - ``` - Verify it's working: - ``` - apimatic --version - ``` - -3. **An APIMatic account** — free trial available at https://app.apimatic.io. - -## Step 1: Authenticate with APIMatic - -First, check if you're already logged in: - -``` -apimatic auth status -``` - -If it shows your account email, you're good — skip ahead to Step 2. - -If not, run the browser-based login. After it opens a browser window, complete sign-in there, then come back and confirm you're done. Afterward, verify with `apimatic auth status`. - -If browser login doesn't work (e.g., headless environment), use an API key instead: - -``` -apimatic auth login --auth-key=YOUR_API_KEY -``` - -API keys can be generated at: APIMatic Dashboard > Account > API Keys. - -## Step 2: Set Up Your Project Directory - -Since you don't have a project directory yet, I need one more piece of information: **where would you like to set up the project directory?** Give me a path, or I'll use the current directory. - -Once I know the location, I'll set up this structure for you: - -``` -your-project/ -└── src/ - └── spec/ - ├── openapi.yaml (your existing spec, copied in) - └── APIMATIC-META.json (downloaded automatically) -``` - -Here are the commands (replace `./my-sdk-project` with your chosen path): - -**On macOS/Linux:** -```bash -mkdir -p ./my-sdk-project/src/spec -cp ./openapi.yaml ./my-sdk-project/src/spec/ -``` - -**On Windows PowerShell:** -```powershell -New-Item -ItemType Directory -Force -Path ".\my-sdk-project\src\spec" -Copy-Item ".\openapi.yaml" -Destination ".\my-sdk-project\src\spec\" -``` - -## Step 3: Generate the Go SDK - -From inside your project directory (the folder that contains `src/`): - -``` -cd my-sdk-project -apimatic sdk generate --language=go -``` - -The SDK will be generated at `my-sdk-project/sdk/go` by default. If you want it somewhere else, add `--destination=path/to/output`. - -## Step 4: Customization (Optional) - -If you plan to customize the SDK after generation, let me know now and I'll add the `--track-changes` flag so your changes can be safely saved and reapplied across future regenerations. - ---- - -**To get started, just confirm:** -1. Where you'd like the project directory set up (or confirm the current directory is fine) -2. Whether you're already authenticated, or need to log in first -3. Whether you want to customize the SDK after generating it - -Once I have those answers, I'll walk you through each command. diff --git a/skills/apimatic-sdk/evals/workspace/eval-3-response.md b/skills/apimatic-sdk/evals/workspace/eval-3-response.md deleted file mode 100644 index 9598832..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-3-response.md +++ /dev/null @@ -1,13 +0,0 @@ -Since you're already logged in, you can go straight to regeneration. Run this from your project root: - -``` -apimatic sdk generate --input=./my-api --language=csharp --force -``` - -The `--force` flag tells the CLI to overwrite your existing SDK. Once generation completes, your C# SDK will be updated with the spec changes. - -If the command fails, here are the most likely causes: - -- **"apimatic command not found"** — run `npm install -g @apimatic/cli` and try again. -- **Spec or `src/` folder missing** — make sure `./my-api/src/spec/` exists and contains your updated API spec file. -- **Auth expired** — run `apimatic auth status` to check. If it shows no account, re-authenticate and then rerun the generate command. diff --git a/skills/apimatic-sdk/evals/workspace/eval-30-response.md b/skills/apimatic-sdk/evals/workspace/eval-30-response.md deleted file mode 100644 index 7a77e9d..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-30-response.md +++ /dev/null @@ -1,40 +0,0 @@ -Keyword arguments aren't a supported CodeGen setting for TypeScript SDKs in APIMatic. - -I checked all available CodeGen settings across every category — endpoint settings, model settings, interface customization, serialization, HTTP configuration, and more. The only keyword argument settings that exist are: - -- **`ForceKeywordArgsInRuby`** — switches endpoint method parameters to keyword arguments in Ruby only -- **`EnableModelKeywordArgsInRuby`** — switches model constructor parameters to keyword arguments in Ruby only - -Neither of these applies to TypeScript, and there is no equivalent setting for TypeScript. - -**Why TypeScript doesn't have this setting:** TypeScript doesn't have a native "keyword arguments" feature in the same way Ruby does. TypeScript already uses named object parameters (e.g., `{ param1, param2 }`) for optional and complex argument patterns, which is the idiomatic TypeScript equivalent. APIMatic's TypeScript SDK generator follows these conventions by default. - -**What you can do instead:** - -If you're looking for a specific behavior — like collapsing multiple parameters into a named options object — the **`CollapseParamsToArray`** setting does exist for TypeScript and groups endpoint parameters into a single input object: - -```json -{ - "CodeGenSettings": { - "CollapseParamsToArray": true - } -} -``` - -This would change endpoint signatures from: - -```typescript -postData(unSet: boolean, setToNull: boolean, field: string, data: MyData) -``` - -to: - -```typescript -postData(input: PostDataInput) -``` - -where `PostDataInput` is a named model containing all the parameters. - -> **Caution:** `CollapseParamsToArray` can hide type information from SDKs and documentation, so use it only if this pattern fits your needs. - -If that's what you were after, let me know and I can apply it to your project at `./ts-project/`. If you had something else in mind, describe what you're trying to achieve and I'll find the closest available option. diff --git a/skills/apimatic-sdk/evals/workspace/eval-4-response.md b/skills/apimatic-sdk/evals/workspace/eval-4-response.md deleted file mode 100644 index 0118f19..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-4-response.md +++ /dev/null @@ -1,28 +0,0 @@ -Great — since you're already authenticated, let me verify that and then kick off your Ruby SDK generation. - -**Step 1: Verify authentication** - -Run this to confirm your session is active: - -``` -apimatic auth status -``` - -If it shows your account email, you're good to go. If not, let me know and we'll re-authenticate. - ---- - -**Step 2: Generate the Ruby SDK** - -Navigate to your project directory and run the generate command: - -``` -cd ~/ruby-project -apimatic sdk generate --language=ruby -``` - -Since you want the default output location and no zip, no extra flags are needed. The SDK will be generated at `~/ruby-project/sdk/ruby/`. - ---- - -Once generation completes, your Ruby SDK will be ready in that folder. Let me know if you run into any issues or if the CLI reports that an SDK already exists at the destination — I can help you decide whether to overwrite it. diff --git a/skills/apimatic-sdk/evals/workspace/eval-5-response.md b/skills/apimatic-sdk/evals/workspace/eval-5-response.md deleted file mode 100644 index f71acaf..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-5-response.md +++ /dev/null @@ -1,48 +0,0 @@ -Browser sign-in opens a browser window and completes the OAuth flow, but the session token sometimes doesn't get written back to the CLI before you check. Since `apimatic auth status` isn't showing your email, the browser auth didn't fully complete. - -The most reliable fix is to use an API key instead. Here's how: - -**Step 1: Get your API key** - -Go to your APIMatic Dashboard, then navigate to Account > API Keys and copy your key. - -**Step 2: Log in using the API key** - -Run this command, replacing `YOUR_API_KEY` with the key you copied: - -``` -apimatic auth login --auth-key=YOUR_API_KEY -``` - -**Step 3: Confirm it worked** - -``` -apimatic auth status -``` - -This should now show your account email. - ---- - -If you'd prefer to set a key without running a login command, you can use an environment variable instead: - -**macOS / Linux / bash / zsh:** -```bash -export APIMATIC_API_KEY=YOUR_API_KEY -``` - -**Windows PowerShell:** -```powershell -$env:APIMATIC_API_KEY = "YOUR_API_KEY" -``` - -**Windows Command Prompt:** -``` -set APIMATIC_API_KEY=YOUR_API_KEY -``` - -Once the environment variable is set, the CLI will pick it up automatically with no separate login step needed. - ---- - -If neither approach works, check that your APIMatic account is active and that you have internet access to apimatic.io. Let me know once authentication is confirmed and I can continue from there. diff --git a/skills/apimatic-sdk/evals/workspace/eval-6-response.md b/skills/apimatic-sdk/evals/workspace/eval-6-response.md deleted file mode 100644 index 0b34a74..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-6-response.md +++ /dev/null @@ -1,35 +0,0 @@ -Great — since you're already authenticated and plan to customize the SDK afterwards, I'll generate your Java SDK with change tracking enabled. That way your customizations will be preserved across future regenerations. - -First, verify your authentication is still active: - -``` -apimatic auth status -``` - -Once that confirms your account, run the following from inside `./my-java-api/` (the directory that contains your `src/` folder): - -``` -apimatic sdk generate --language=java --track-changes -``` - -The `--track-changes` flag initializes change tracking so that any customizations you make can be saved and automatically reapplied every time you regenerate. The SDK will be generated at `./my-java-api/sdk/java/` by default. - ---- - -**Before you start customizing, keep these tips in mind:** - -- Add custom logic in a **new file** where possible — new files are never overwritten on regeneration. -- Avoid editing generated files directly. -- If you must edit a generated file, add your changes at the **top or bottom** to reduce merge conflicts. - ---- - -**Once you've made your customizations**, save them so they survive future regenerations: - -``` -apimatic sdk save-changes --language=java --input=./my-java-api -``` - -This captures the diff between the plain generated output and your modified version. From that point on, every time you run `sdk generate`, your customizations are reapplied automatically. - -Make your customizations now, then let me know when you're ready to save them. diff --git a/skills/apimatic-sdk/evals/workspace/eval-7-response.md b/skills/apimatic-sdk/evals/workspace/eval-7-response.md deleted file mode 100644 index 5a8bc5b..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-7-response.md +++ /dev/null @@ -1,71 +0,0 @@ -Running the APIMatic CLI non-interactively in GitHub Actions is straightforward — you skip browser-based login entirely and pass your API key directly to the generate command. Here's how to set it up. - -## Prerequisites - -Make sure these are in place before configuring the workflow: - -- **Node.js >= 20** available in your runner (the `actions/setup-node` action handles this) -- **An APIMatic API key** stored as a GitHub Actions secret (e.g., `APIMATIC_API_KEY`) -- **Your project repository** contains a `src/` folder with your API spec inside `src/spec/` - -API keys can be generated at: APIMatic Dashboard > Account > API Keys. - ---- - -## GitHub Actions Workflow - -Create a file at `.github/workflows/generate-sdk.yml` in your repository: - -```yaml -name: Generate PHP SDK - -on: - push: - branches: - - main # or whichever branch(es) you want to trigger generation - -jobs: - generate-sdk: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install APIMatic CLI - run: npm install -g @apimatic/cli - - - name: Generate PHP SDK - run: | - apimatic sdk generate \ - --input=. \ - --language=php \ - --auth-key=${{ secrets.APIMATIC_API_KEY }} \ - --force -``` - ---- - -## Key Points - -**No login command needed.** Passing `--auth-key` directly to `sdk generate` is all that's required in a CI environment. - -**`--input` points to the directory containing `src/`**, not to the spec file itself. In the example above, `.` means the root of the checked-out repository — adjust this if your project lives in a subdirectory. - -**`--force` allows repeated builds.** On the first run, the SDK is generated fresh. On every subsequent push, `--force` tells the CLI to overwrite the existing output rather than stopping with an error. - -**The API key stays secret.** GitHub Actions injects `${{ secrets.APIMATIC_API_KEY }}` as an environment value at runtime — it is never written to logs or exposed in the workflow file. - ---- - -## Troubleshooting - -- **Authentication error:** Verify the secret name in your repository settings matches exactly what you used in the workflow. -- **`apimatic` command not found:** Make sure the install step runs before the generate step and that Node.js is set up correctly. -- **Missing `src/` folder or spec file:** The CLI expects your API spec at `src/spec/` inside the directory you pass to `--input`. Double-check that path. -- **SDK already exists error (without `--force`):** Add `--force` to the generate command as shown above. diff --git a/skills/apimatic-sdk/evals/workspace/eval-8-response.md b/skills/apimatic-sdk/evals/workspace/eval-8-response.md deleted file mode 100644 index 4ce738d..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-8-response.md +++ /dev/null @@ -1,38 +0,0 @@ -The `apimatic --version` command not found error typically means the npm global binary directory is not in your system PATH, even though the package was installed successfully. Let's fix that. - -**Step 1: Fix the PATH issue** - -First, find where npm installs global binaries: - -``` -npm config get prefix -``` - -This will print a directory path (e.g., `/usr/local` on macOS/Linux, or `C:\Users\YourName\AppData\Roaming\npm` on Windows). - -If the npm prefix's `bin` folder is missing from your PATH, add it: - -On macOS/Linux (bash/zsh): -```bash -export PATH="$(npm config get prefix)/bin:$PATH" -``` - -To make it permanent, add that line to your `~/.bashrc` or `~/.zshrc`, then reload with `source ~/.bashrc`. - -On Windows PowerShell: -```powershell -$env:PATH = "$(npm config get prefix)" + ";" + $env:PATH -``` - -After updating PATH, verify the CLI is working: -``` -apimatic --version -``` - -If that still fails, try reinstalling: -``` -npm install -g @apimatic/cli -apimatic --version -``` - -Once `apimatic --version` returns a version number, you're good. Let me know when that's confirmed and we'll move on to authentication and Python SDK generation. diff --git a/skills/apimatic-sdk/evals/workspace/eval-9-response.md b/skills/apimatic-sdk/evals/workspace/eval-9-response.md deleted file mode 100644 index 0cda1d0..0000000 --- a/skills/apimatic-sdk/evals/workspace/eval-9-response.md +++ /dev/null @@ -1,28 +0,0 @@ -Great — since you're already authenticated, let's get your customizations saved. - -First, I need to check whether change tracking has been initialized for your TypeScript SDK. Look inside your project folder (`./ts-api/`) for a folder called `sdk-source-tree`. Does it exist there? - ---- - -**If `sdk-source-tree` is present (and contains a `.typescript` file):** - -Change tracking is already set up. Run this to save your customizations: - -``` -apimatic sdk save-changes --language=typescript --input=./ts-api -``` - -That's it. Your extra helper methods are now saved and will be reapplied automatically every time you regenerate. - ---- - -**If `sdk-source-tree` is not present:** - -Change tracking hasn't been initialized yet, which means we need to run a fresh generation with `--track-changes` to set it up. However, generating into your current SDK folder would overwrite your existing customizations. - -Would you like me to use a temporary folder for the fresh generation, or do you have a preferred destination instead? - -- If you provide a path, I'll generate into that path. -- If you're fine with a temporary folder, I'll use `./ts-api/sdk/temp/typescript` and delete it after setup is complete. - -Once the fresh generation is done, I'll run `sdk save-changes` pointing at your **original** customized SDK so your helper methods are captured — not the temporary output. diff --git a/skills/apimatic-sdk/evals/workspace/grading.json b/skills/apimatic-sdk/evals/workspace/grading.json deleted file mode 100644 index c0d8001..0000000 --- a/skills/apimatic-sdk/evals/workspace/grading.json +++ /dev/null @@ -1,569 +0,0 @@ -{ - "total_assertions": 86, - "total_passed": 86, - "evals": [ - { - "eval_id": 0, - "status": "PASS", - "score": "6/6", - "results": [ - { - "id": "checks-auth-status", - "passed": true, - "evidence": "Found 'apimatic auth status'" - }, - { - "id": "runs-auth-login", - "passed": true, - "evidence": "Found 'apimatic auth login'" - }, - { - "id": "waits-for-user-confirmation", - "passed": true, - "evidence": "Found: ['confirm', 'let me know', \"when you're done\", 'when done', 'after you']" - }, - { - "id": "generates-python-sdk", - "passed": true, - "evidence": "Found '--language=python'" - }, - { - "id": "does-not-add-zip-unprompted", - "passed": true, - "evidence": "Correctly absent: '--zip'" - }, - { - "id": "asks-about-destination", - "passed": true, - "evidence": "Found: ['destination', 'default location']" - } - ] - }, - { - "eval_id": 1, - "status": "PASS", - "score": "6/6", - "results": [ - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "uses-correct-directory", - "passed": true, - "evidence": "Found: ['payments-api', 'D:\\\\work\\\\payments-api']" - }, - { - "id": "generates-typescript-sdk", - "passed": true, - "evidence": "Found '--language=typescript'" - }, - { - "id": "includes-zip-flag", - "passed": true, - "evidence": "Found '--zip'" - }, - { - "id": "uses-custom-destination", - "passed": true, - "evidence": "Found: ['--destination', 'D:\\\\output\\\\ts-sdk']" - }, - { - "id": "runs-from-project-root", - "passed": true, - "evidence": "Correctly absent: 'cd src'" - } - ] - }, - { - "eval_id": 2, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "mentions-src-directory", - "passed": true, - "evidence": "Found: ['src/', 'src\\\\']" - }, - { - "id": "mentions-spec-in-src-spec", - "passed": true, - "evidence": "Found: ['src/spec', 'src\\\\spec', 'spec/']" - }, - { - "id": "does-not-generate-directly", - "passed": true, - "evidence": "Correctly absent: 'apimatic sdk generate --input=./openapi.yaml'" - }, - { - "id": "mentions-go-language", - "passed": true, - "evidence": "Found: ['go', 'Go', '--language=go']" - }, - { - "id": "does-not-mention-portal-skill", - "passed": true, - "evidence": "Correctly absent" - } - ] - }, - { - "eval_id": 3, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "generates-csharp-sdk", - "passed": true, - "evidence": "Found '--language=csharp'" - }, - { - "id": "uses-force-flag", - "passed": true, - "evidence": "Found '--force'" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['my-api', './my-api']" - }, - { - "id": "does-not-add-zip-unprompted", - "passed": true, - "evidence": "Correctly absent: '--zip'" - } - ] - }, - { - "eval_id": 4, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "generates-ruby-sdk", - "passed": true, - "evidence": "Found '--language=ruby'" - }, - { - "id": "no-destination-flag", - "passed": true, - "evidence": "Correctly absent: '--destination'" - }, - { - "id": "no-zip-flag", - "passed": true, - "evidence": "Correctly absent: '--zip'" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['ruby-project', '~/ruby-project']" - } - ] - }, - { - "eval_id": 5, - "status": "PASS", - "score": "3/3", - "results": [ - { - "id": "offers-api-key-fallback", - "passed": true, - "evidence": "Found '--auth-key'" - }, - { - "id": "mentions-api-keys-location", - "passed": true, - "evidence": "Found: ['API Keys', 'Account > API Keys', 'APIMatic Dashboard']" - }, - { - "id": "does-not-proceed-to-generate", - "passed": true, - "evidence": "Correctly absent: 'apimatic sdk generate'" - } - ] - }, - { - "eval_id": 6, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "generates-java-sdk", - "passed": true, - "evidence": "Found '--language=java'" - }, - { - "id": "uses-track-changes", - "passed": true, - "evidence": "Found '--track-changes'" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['my-java-api', './my-java-api']" - } - ] - }, - { - "eval_id": 7, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "runs-sdk-generate", - "passed": true, - "evidence": "Found 'apimatic sdk generate'" - }, - { - "id": "uses-auth-key-flag", - "passed": true, - "evidence": "Found '--auth-key'" - }, - { - "id": "generates-php-sdk", - "passed": true, - "evidence": "Found '--language=php'" - }, - { - "id": "recommends-for-ci", - "passed": true, - "evidence": "Found: ['CI', 'non-interactive', 'GitHub Actions']" - }, - { - "id": "no-browser-login-for-ci", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login\n'" - } - ] - }, - { - "eval_id": 8, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "suggests-reinstall", - "passed": true, - "evidence": "Found 'npm install -g @apimatic/cli'" - }, - { - "id": "does-not-proceed-to-generate", - "passed": true, - "evidence": "Correctly absent: 'apimatic sdk generate'" - }, - { - "id": "does-not-proceed-to-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "mentions-version-check", - "passed": true, - "evidence": "Found 'apimatic --version'" - } - ] - }, - { - "eval_id": 9, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "does-not-regenerate", - "passed": true, - "evidence": "Correctly absent: 'apimatic sdk generate'" - }, - { - "id": "runs-save-changes", - "passed": true, - "evidence": "Found 'apimatic sdk save-changes'" - }, - { - "id": "uses-typescript-language", - "passed": true, - "evidence": "Found '--language=typescript'" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['ts-api', './ts-api']" - } - ] - }, - { - "eval_id": 10, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "generates-with-track-changes", - "passed": true, - "evidence": "Found '--track-changes'" - }, - { - "id": "generates-python-sdk", - "passed": true, - "evidence": "Found '--language=python'" - }, - { - "id": "prompts-user-to-customize", - "passed": true, - "evidence": "Found: ['make your customizations', 'add your changes', 'let me know when', \"when you're done\"]" - }, - { - "id": "runs-save-changes", - "passed": true, - "evidence": "Found 'apimatic sdk save-changes'" - } - ] - }, - { - "eval_id": 11, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "scaffolds-src-structure", - "passed": true, - "evidence": "Found: ['src/spec', 'mkdir']" - }, - { - "id": "generates-with-track-changes", - "passed": true, - "evidence": "Found '--track-changes'" - }, - { - "id": "prompts-user-to-customize", - "passed": true, - "evidence": "Found: ['make your customizations', 'let me know when', \"when you're ready\"]" - }, - { - "id": "runs-save-changes", - "passed": true, - "evidence": "Found 'apimatic sdk save-changes'" - } - ] - }, - { - "eval_id": 12, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "generates-java-sdk", - "passed": true, - "evidence": "Found '--language=java'" - }, - { - "id": "uses-skip-changes-flag", - "passed": true, - "evidence": "Found '--skip-changes'" - }, - { - "id": "non-destructive-explanation", - "passed": true, - "evidence": "Found: ['not removed', 'still be applied']" - }, - { - "id": "does-not-delete-sdk-source-tree", - "passed": true, - "evidence": "Correctly absent: 'delete'" - } - ] - }, - { - "eval_id": 13, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "generates-go-sdk", - "passed": true, - "evidence": "Found '--language=go'" - }, - { - "id": "uses-api-version-flag", - "passed": true, - "evidence": "Found '--api-version=v2'" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['multi-version-api', './multi-version-api']" - }, - { - "id": "does-not-add-zip-unprompted", - "passed": true, - "evidence": "Correctly absent: '--zip'" - } - ] - }, - { - "eval_id": 15, - "status": "PASS", - "score": "6/6", - "results": [ - { - "id": "uses-short-copyright-notice-setting", - "passed": true, - "evidence": "Found 'ShortCopyrightNotice'" - }, - { - "id": "updates-apimatic-meta", - "passed": true, - "evidence": "Found 'APIMATIC-META.json'" - }, - { - "id": "generates-python-sdk", - "passed": true, - "evidence": "Found '--language=python'" - }, - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "does-not-manually-inject-copyright", - "passed": true, - "evidence": "Correctly absent" - }, - { - "id": "references-project-dir", - "passed": true, - "evidence": "Found: ['payments-api', './payments-api']" - } - ] - }, - { - "eval_id": 14, - "status": "PASS", - "score": "4/4", - "results": [ - { - "id": "recommends-env-var", - "passed": true, - "evidence": "Found 'APIMATIC_API_KEY'" - }, - { - "id": "shows-env-var-syntax", - "passed": true, - "evidence": "Found: ['export APIMATIC_API_KEY', '$env:APIMATIC_API_KEY']" - }, - { - "id": "does-not-recommend-browser-login", - "passed": true, - "evidence": "Correctly absent: 'auth-login.mjs'" - }, - { - "id": "mentions-no-login-command-needed", - "passed": true, - "evidence": "Found: ['no login', 'no login command']" - } - ] - }, - { - "eval_id": 16, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "uses-disable-docs-setting", - "passed": true, - "evidence": "Found 'DisableDocs'" - }, - { - "id": "updates-apimatic-meta", - "passed": true, - "evidence": "Found 'APIMATIC-META.json'" - }, - { - "id": "generates-typescript-sdk", - "passed": true, - "evidence": "Found '--language=typescript'" - }, - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - }, - { - "id": "does-not-manually-delete-docs", - "passed": true, - "evidence": "Correctly absent" - } - ] - }, - { - "eval_id": 19, - "status": "PASS", - "score": "5/5", - "results": [ - { - "id": "uses-project-name-setting", - "passed": true, - "evidence": "Found 'ProjectName'" - }, - { - "id": "uses-correct-name", - "passed": true, - "evidence": "Found 'PaymentsSDK'" - }, - { - "id": "updates-apimatic-meta", - "passed": true, - "evidence": "Found 'APIMATIC-META.json'" - }, - { - "id": "generates-java-sdk", - "passed": true, - "evidence": "Found '--language=java'" - }, - { - "id": "skips-auth", - "passed": true, - "evidence": "Correctly absent: 'apimatic auth login'" - } - ] - }, - { - "eval_id": 30, - "status": "PASS", - "score": "2/2", - "results": [ - { - "id": "mentions-ruby-only", - "passed": true, - "evidence": "Found: ['Ruby', 'ruby', 'Ruby only', 'ForceKeywordArgsInRuby']" - }, - { - "id": "does-not-blindly-apply", - "passed": true, - "evidence": "Correctly absent: '\"ForceKeywordArgsInRuby\": true'" - } - ] - } - ] -} \ No newline at end of file From 40338ccdcb33df8bedff831b3b91b336ee706bc4 Mon Sep 17 00:00:00 2001 From: Ayeshas09 Date: Wed, 29 Apr 2026 11:10:39 +0500 Subject: [PATCH 3/5] feat: add sdk publish command --- skills/apimatic-sdk/SKILL.md | 79 ++++++++- skills/apimatic-sdk/evals/evals.json | 243 +++++++++++++++++++++++++++ 2 files changed, 321 insertions(+), 1 deletion(-) diff --git a/skills/apimatic-sdk/SKILL.md b/skills/apimatic-sdk/SKILL.md index 4dd16ca..e1d1343 100644 --- a/skills/apimatic-sdk/SKILL.md +++ b/skills/apimatic-sdk/SKILL.md @@ -1,6 +1,6 @@ --- name: apimatic-sdk -description: Use when a user wants to generate, create, customize, or download an SDK using the APIMatic CLI. Also use when the user has already customized a generated SDK and wants to save those changes, when the user wants to make a specific change to an SDK (e.g. "change the analyzer", "switch the linter"), or when the user asks about CodeGen settings, SDK configuration, or APIMATIC-META.json (e.g. "enable retry on timeout", "disable linting", "set the project name"). +description: Use for any task involving APIMatic's SDK generation toolchain. Use when a user wants to generate, create, customize, download, or publish an SDK using the APIMatic CLI. Also use when the user has already customized a generated SDK and wants to save those changes, when the user wants to make a specific change to an SDK (e.g. "change the analyzer", "switch the linter"), when the user asks about CodeGen settings, SDK configuration, or APIMATIC-META.json (e.g. "enable retry on timeout", "disable linting", "set the project name"), or when the user wants to publish an SDK to a package registry or source repository, or wants to list publishing profiles. --- # APIMatic SDK @@ -15,6 +15,9 @@ Generate SDKs for your APIs in multiple languages using the APIMatic CLI. - User says they have already customized a generated SDK and want to save or commit those changes - User asks to customize an SDK in a specific way (e.g. "change the analyzer", "switch the linter", "update the formatter in the PHP SDK") - User asks to change a CodeGen setting (e.g. "enable retry on timeout", "set the project name", "disable linting", "change the timeout", "enable HTTP cache") — these can be applied via `APIMATIC-META.json` and a regeneration +- User wants to publish an SDK to a package registry (npm, PyPI, NuGet) or source code repository (GitHub) +- User wants to list publishing profiles or find a profile ID for publishing +- User mentions `sdk publish` or `publishing profile list` ## Red Flags — STOP and re-read the relevant section @@ -31,6 +34,9 @@ Generate SDKs for your APIs in multiple languages using the APIMatic CLI. - About to manually delete or remove a generated folder or file (e.g., `docs/`, `README.md`) as a customization → check codegen settings first; (e.g., removing docs maps to `DisableDocs: true` in `APIMATIC-META.json`) — set this before generating, not after via file deletion or custom code injection - About to open, read, or edit the `.` files inside `sdk-source-tree/` (e.g., `.typescript`, `.python`) → these files are managed exclusively by the CLI; never touch them directly under any circumstance - About to manually compare or inspect customizations by reading `sdk-source-tree/` → if the user wants to see what changed between a plain generation and their customized one, regenerate using `--skip-changes` to produce a clean copy, then compare that against the customized SDK; do not manipulate or read the source tree files +- About to run `sdk publish` because the user said "for publishing", "to publish", "for npm", or similar contextual phrases → these describe the user's **goal**, not a publish instruction; only run `sdk publish` if the user explicitly asks to publish (e.g., "publish the SDK", "run sdk publish", "push to npm using apimatic", "push to GitHub using apimatic"); for any other phrasing, stop at SDK generation +- About to run `sdk publish` without a `--profile-id` and the user hasn't provided one → run `apimatic publishing profile list` first and present the available profiles so the user can choose +- About to pass a `--publish-type` value other than `package` or `sourcecode` → see the [Publish Types](#publish-types) section for valid values ## Communication Guidelines @@ -336,6 +342,77 @@ apimatic sdk generate --input=path/to/parent-of-src --language= --auth - `--track-changes` : Enable change tracking to preserve manual customizations across regenerations. Must be used during the initial generation to set up the source tree. See `references/save-changes.md` for how to save changes after generation. - `--skip-changes` : Generate the SDK without reapplying saved customizations, even if change tracking is enabled. Use when the user wants to preview the plain generated output. Saved customizations are not modified and will still be applied in future runs unless explicitly removed. +## SDK Publish + +> **Only follow this section when the user explicitly requests publishing** (e.g., "publish the SDK", "push to npm", "push to GitHub", "run sdk publish"). Phrases like "generate an SDK for publishing" or "generate for npm" express intent but are not publish instructions — stop at SDK generation in those cases. + +Publish an SDK to a package registry (npm, PyPI, NuGet) or source code repository (GitHub) using a publishing profile configured in the APIMatic App. + +### Step 1: Authenticate with APIMatic + +Follow [Step 1: Authenticate with APIMatic](#step-1-authenticate-with-apimatic) above. + +### Step 2: Find the Publishing Profile ID + +If the user does not already know their profile ID, run: + +``` +apimatic publishing profile list +``` + +This lists all publishing profiles with their names, IDs, and enabled languages. Do not forward the raw table output to the user — summarize the available profiles and their IDs in plain language so the user can identify the one they want. + +### Step 3: Run SDK Publish + +**Non-interactive flow** requires all four of these flags — missing any one will drop the CLI into the interactive prompt: + +``` +apimatic sdk publish --profile-id= --language= --version= --publish-type= +``` + +#### Flags + +| Flag | Required (non-interactive) | Description | +| -------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `--profile-id`, `-p` | Yes | ID of the publishing profile to use. Run `apimatic publishing profile list` to find your profile ID. | +| `--language`, `-l` | Yes | SDK language to generate and publish. | +| `--version`, `-v` | Yes | Semantic version of the SDK (e.g. `1.0.0`). | +| `--publish-type` | Yes (at least one) | Publishing target(s): `package` or `sourcecode` only. Can be specified multiple times. See [Publish Types](#publish-types). | +| `--input` | No | Path to the parent directory containing the `src/` directory. Defaults to `./`. | +| `--destination` | No | Directory where the generated SDK will be saved locally. Defaults to `/sdk`. | +| `--dry-run` | No | Generate the SDK locally for review without publishing. | +| `--force`, `-f` | No | Overwrite existing output without prompting. | + +#### Publish Types + +Pass `--publish-type` once or twice to target one or both destinations. The language and publish type(s) must be configured in the publishing profile. + +``` +# Publish to package registry only +apimatic sdk publish --profile-id= --language=java --version=2.0.0 --publish-type=package + +# Publish to both package registry and source repository +apimatic sdk publish --profile-id= --language=typescript --version=1.0.0 --publish-type=package --publish-type=sourcecode +``` + +#### Dry Run + +Use `--dry-run` to generate the SDK locally and inspect it before publishing: + +``` +apimatic sdk publish --dry-run --profile-id= --language=python --version=1.0.0 --publish-type=package +``` + +### If SDK Publish Fails + +1. **Profile not found or invalid ID:** Run `apimatic publishing profile list` to confirm the correct profile ID. +2. **Language or publish type not supported by profile:** The language and publish type(s) must be enabled in the publishing profile. Check the profile configuration in the APIMatic App. +3. **Authentication error:** Re-run `apimatic auth status` and re-authenticate if needed. +4. **SDK already exists at destination:** Re-run with `--force` to overwrite. +5. **Any other error:** Read the exact error message from the CLI output. Do not retry automatically — diagnose the specific error first. + +--- + ## Customization Guidelines Apply these principles whenever you are making SDK customizations on the user's behalf, and share them as tips when the user is customizing themselves. diff --git a/skills/apimatic-sdk/evals/evals.json b/skills/apimatic-sdk/evals/evals.json index 7c83e5d..3522ed1 100644 --- a/skills/apimatic-sdk/evals/evals.json +++ b/skills/apimatic-sdk/evals/evals.json @@ -1418,6 +1418,249 @@ "value": "apimatic auth login" } ] + }, + { + "id": 35, + "prompt": "Publish my Java SDK version 2.0.0 to the package registry. My profile ID is b2c3d4e5f6a1b2c3d4e5f6a1. My project is at ./java-api/ and I'm already authenticated.", + "expected_output": "The agent runs apimatic sdk publish in non-interactive mode with all four required flags: --profile-id, --language, --version, and --publish-type=package. It does NOT add --publish-type=sourcecode since the user only asked for the package registry.", + "files": [], + "assertions": [ + { + "id": "runs-sdk-publish", + "description": "Response includes the sdk publish command", + "type": "contains", + "value": "apimatic sdk publish" + }, + { + "id": "uses-profile-id", + "description": "Response includes the user's profile ID", + "type": "contains", + "value": "--profile-id=b2c3d4e5f6a1b2c3d4e5f6a1" + }, + { + "id": "uses-java-language", + "description": "Response includes --language=java", + "type": "contains", + "value": "--language=java" + }, + { + "id": "uses-version", + "description": "Response includes --version=2.0.0", + "type": "contains", + "value": "--version=2.0.0" + }, + { + "id": "uses-package-publish-type", + "description": "Response includes --publish-type=package", + "type": "contains", + "value": "--publish-type=package" + }, + { + "id": "does-not-add-sourcecode-unprompted", + "description": "Response does NOT add --publish-type=sourcecode since user only asked for package registry", + "type": "not_contains", + "value": "--publish-type=sourcecode" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 36, + "prompt": "Publish my TypeScript SDK version 1.0.0 to both npm and GitHub. My profile ID is a1b2c3d4e5f6a1b2c3d4e5f6. My project is at ./ts-api/ and I'm already authenticated.", + "expected_output": "The agent runs apimatic sdk publish with --publish-type=package and --publish-type=sourcecode both present, targeting both the package registry and the source repository.", + "files": [], + "assertions": [ + { + "id": "runs-sdk-publish", + "description": "Response includes the sdk publish command", + "type": "contains", + "value": "apimatic sdk publish" + }, + { + "id": "uses-profile-id", + "description": "Response includes the user's profile ID", + "type": "contains", + "value": "--profile-id=a1b2c3d4e5f6a1b2c3d4e5f6" + }, + { + "id": "uses-typescript-language", + "description": "Response includes --language=typescript", + "type": "contains", + "value": "--language=typescript" + }, + { + "id": "uses-version", + "description": "Response includes --version=1.0.0", + "type": "contains", + "value": "--version=1.0.0" + }, + { + "id": "uses-package-publish-type", + "description": "Response includes --publish-type=package", + "type": "contains", + "value": "--publish-type=package" + }, + { + "id": "uses-sourcecode-publish-type", + "description": "Response includes --publish-type=sourcecode", + "type": "contains", + "value": "--publish-type=sourcecode" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 37, + "prompt": "I want to test publishing my Python SDK before actually pushing it live. My profile ID is c3d4e5f6a1b2c3d4e5f6a1b2, version is 1.0.0, publish to package registry. I'm authenticated, project at ./py-api/.", + "expected_output": "The agent uses --dry-run so the SDK is generated locally for review without publishing. All other required flags are still included.", + "files": [], + "assertions": [ + { + "id": "runs-sdk-publish", + "description": "Response includes the sdk publish command", + "type": "contains", + "value": "apimatic sdk publish" + }, + { + "id": "uses-dry-run", + "description": "Response includes the --dry-run flag", + "type": "contains", + "value": "--dry-run" + }, + { + "id": "uses-profile-id", + "description": "Response includes the user's profile ID", + "type": "contains", + "value": "--profile-id=c3d4e5f6a1b2c3d4e5f6a1b2" + }, + { + "id": "uses-python-language", + "description": "Response includes --language=python", + "type": "contains", + "value": "--language=python" + }, + { + "id": "uses-version", + "description": "Response includes --version=1.0.0", + "type": "contains", + "value": "--version=1.0.0" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 38, + "prompt": "Show me all my publishing profiles and their IDs. I'm already authenticated.", + "expected_output": "The agent runs apimatic publishing profile list and presents the available profiles in plain language. It does NOT forward the raw CLI table output verbatim.", + "files": [], + "assertions": [ + { + "id": "runs-profile-list", + "description": "Response includes the publishing profile list command", + "type": "contains", + "value": "apimatic publishing profile list" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + }, + { + "id": "does-not-run-sdk-generate", + "description": "Response does NOT run sdk generate or sdk publish — the user only asked to list profiles", + "type": "not_contains_any", + "value": [ + "apimatic sdk generate", + "apimatic sdk publish" + ] + } + ] + }, + { + "id": 39, + "prompt": "I want to publish my C# SDK version 3.0.0 to the package registry but I don't know my profile ID. I'm authenticated, project at ./csharp-api/.", + "expected_output": "The agent runs apimatic publishing profile list first to help the user find their profile ID. It does NOT run apimatic sdk publish with a made-up or placeholder profile ID before the user provides their real one.", + "files": [], + "assertions": [ + { + "id": "lists-profiles-first", + "description": "Response runs publishing profile list to find the profile ID", + "type": "contains", + "value": "apimatic publishing profile list" + }, + { + "id": "does-not-fabricate-profile-id", + "description": "Response does NOT run sdk publish with a made-up profile ID before the user provides one", + "type": "not_contains", + "value": "--profile-id=a1b2c3d4" + }, + { + "id": "skips-auth", + "description": "Response does NOT run auth login since user is already authenticated", + "type": "not_contains", + "value": "apimatic auth login" + } + ] + }, + { + "id": 40, + "prompt": "I want to publish my Ruby SDK using a CI pipeline. My profile ID is d4e5f6a1b2c3d4e5f6a1b2c3, version is 0.9.0, publish to package registry. Store the API key as an env variable, no browser login.", + "expected_output": "The agent uses the APIMATIC_API_KEY environment variable for auth (no browser login, no apimatic auth login command) and runs apimatic sdk publish with all required flags non-interactively.", + "files": [], + "assertions": [ + { + "id": "runs-sdk-publish", + "description": "Response includes the sdk publish command", + "type": "contains", + "value": "apimatic sdk publish" + }, + { + "id": "uses-profile-id", + "description": "Response includes the user's profile ID", + "type": "contains", + "value": "--profile-id=d4e5f6a1b2c3d4e5f6a1b2c3" + }, + { + "id": "uses-ruby-language", + "description": "Response includes --language=ruby", + "type": "contains", + "value": "--language=ruby" + }, + { + "id": "uses-version", + "description": "Response includes --version=0.9.0", + "type": "contains", + "value": "--version=0.9.0" + }, + { + "id": "uses-env-var-for-auth", + "description": "Response recommends setting the APIMATIC_API_KEY environment variable", + "type": "contains", + "value": "APIMATIC_API_KEY" + }, + { + "id": "does-not-use-browser-login", + "description": "Response does NOT recommend browser-based login for CI", + "type": "not_contains", + "value": "auth-login.mjs" + } + ] } ] } From 757265c155c91cffc79cb122fafd5f02e909a8c3 Mon Sep 17 00:00:00 2001 From: Ayeshas09 Date: Mon, 4 May 2026 11:30:07 +0500 Subject: [PATCH 4/5] refactor: apply feedback suggestions --- skills/apimatic-sdk/SKILL.md | 30 +++++---- .../examples/generate-customize-save.md | 62 +++++++++++++++++-- skills/apimatic-sdk/examples/publish-sdk.md | 48 ++++++++++++++ skills/apimatic-sdk/scripts/auth-login.mjs | 30 +++++++++ 4 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 skills/apimatic-sdk/examples/publish-sdk.md create mode 100644 skills/apimatic-sdk/scripts/auth-login.mjs diff --git a/skills/apimatic-sdk/SKILL.md b/skills/apimatic-sdk/SKILL.md index e1d1343..fc73d20 100644 --- a/skills/apimatic-sdk/SKILL.md +++ b/skills/apimatic-sdk/SKILL.md @@ -47,6 +47,8 @@ This skill is used by developers of all experience levels. All messages shown to - **Keep error guidance actionable:** When something fails, tell the user what went wrong in simple terms and what they can do about it. Do not describe the internal recovery steps you are attempting — just attempt them silently and report the outcome. - **When in doubt, less is more:** If you are unsure whether a detail is useful to the user, leave it out. +## Customize an SDK + ## Fast Path — Already-Customized SDK If the user's message indicates they have **already made customizations** to a generated SDK and want to save those changes (e.g. "I customized my SDK", "I made changes to the generated SDK", "save my SDK changes", "save changes in it"): @@ -126,8 +128,20 @@ There is one additional concern depending on context: - **Claude is applying the customization (Fast Path — Apply a Specific Customization):** No destination conflict — proceed through Steps 2–7 normally with `--track-changes`. After generation, apply the requested customizations to the generated SDK following the [Customization Guidelines](#customization-guidelines) section, then follow `references/save-changes.md`. +## Customization Guidelines + +Apply these principles whenever you are making SDK customizations on the user's behalf, and share them as tips when the user is customizing themselves. + +1. **Add custom logic in a new file** where possible. +2. **Avoid editing generated files directly.** +3. **If you must edit a generated file**, add your changes at the top or bottom to reduce merge conflicts. + --- +## Generate an SDK + +> These steps (Prerequisites through Step 7) are also used when initializing change tracking as part of a customization workflow. + ## Prerequisites Confirm these are in place before starting: @@ -285,7 +299,7 @@ If not already known from context, ask: "Would you like to customize the SDK aft **If the skill applies customizations:** - Ask the user what changes they want made. Apply them following the [Customization Guidelines](#customization-guidelines) section at the bottom of this file. Once the changes are in place, follow `references/save-changes.md`. See `examples/generate-customize-save.md` for the expected flow of commands — flags and paths will differ based on the user's setup. + Ask the user what changes they want made. Apply them following the [Customization Guidelines](#customization-guidelines) section. Once the changes are in place, follow `references/save-changes.md`. See `examples/generate-customize-save.md` for the expected flow of commands — flags and paths will differ based on the user's setup. **If the user applies customizations:** @@ -342,7 +356,7 @@ apimatic sdk generate --input=path/to/parent-of-src --language= --auth - `--track-changes` : Enable change tracking to preserve manual customizations across regenerations. Must be used during the initial generation to set up the source tree. See `references/save-changes.md` for how to save changes after generation. - `--skip-changes` : Generate the SDK without reapplying saved customizations, even if change tracking is enabled. Use when the user wants to preview the plain generated output. Saved customizations are not modified and will still be applied in future runs unless explicitly removed. -## SDK Publish +## Publish an SDK > **Only follow this section when the user explicitly requests publishing** (e.g., "publish the SDK", "push to npm", "push to GitHub", "run sdk publish"). Phrases like "generate an SDK for publishing" or "generate for npm" express intent but are not publish instructions — stop at SDK generation in those cases. @@ -364,6 +378,8 @@ This lists all publishing profiles with their names, IDs, and enabled languages. ### Step 3: Run SDK Publish +See `examples/publish-sdk.md` for the expected command and output — flags and paths will differ based on the user's setup. + **Non-interactive flow** requires all four of these flags — missing any one will drop the CLI into the interactive prompt: ``` @@ -412,13 +428,3 @@ apimatic sdk publish --dry-run --profile-id= --language=python --version=1.0 5. **Any other error:** Read the exact error message from the CLI output. Do not retry automatically — diagnose the specific error first. --- - -## Customization Guidelines - -Apply these principles whenever you are making SDK customizations on the user's behalf, and share them as tips when the user is customizing themselves. - -1. **Add custom logic in a new file** where possible. -2. **Avoid editing generated files directly.** -3. **If you must edit a generated file**, add your changes at the top or bottom to reduce merge conflicts. - ---- diff --git a/skills/apimatic-sdk/examples/generate-customize-save.md b/skills/apimatic-sdk/examples/generate-customize-save.md index b988f6c..570db5d 100644 --- a/skills/apimatic-sdk/examples/generate-customize-save.md +++ b/skills/apimatic-sdk/examples/generate-customize-save.md @@ -2,7 +2,7 @@ This example shows how to generate an SDK with change tracking, customize a generated file, save those customizations, and regenerate with them automatically reapplied. -**Flow:** generate (tracking auto-enabled) → customize → save-changes → regenerate +**Flow:** generate with change tracking → customize → save-changes → regenerate --- @@ -11,10 +11,28 @@ This example shows how to generate an SDK with change tracking, customize a gene Run from the directory that contains `src/`: ``` -apimatic sdk generate --language=typescript +apimatic sdk generate --language=typescript --track-changes ``` -Change tracking is enabled automatically. The `sdk-source-tree` is saved at `src/sdk-source-tree/.typescript` and will be used to reapply your customizations on every future generation. +Output: + +``` +SDK generated successfully. +| +• The generated SDK can be found at '\sdk\typescript'. +| +• Change tracking is enabled for 'typescript'. The 'sdk-source-tree' has been saved to '\src\sdk-source-tree\.typescript'. +| +o Next Steps -------------------------------------------------------------+ +| | +| Customize your SDK, then run: | +| 'apimatic sdk save-changes --language=typescript' | +| This persists your changes so they reapply on every future generation. | +| | ++--------------------------------------------------------------------------+ +| +— Succeeded +``` --- @@ -36,7 +54,25 @@ Edit any generated file. In this example, `sdk/typescript/README.md` is updated: apimatic sdk save-changes --language=typescript ``` -The CLI detects which files were modified and saves a diff to `src/sdk-source-tree/.typescript`. These changes will reapply automatically on every future generation. +Output: + +``` +T Save Changes +| +• Detected changes in the following file(s): +| └─ typescript +| └─ README.md # Modified +| +| +o Do you want to review these changes? +| No +| +* Changes saved successfully at '\src\sdk-source-tree\.typescript'. +| +• Your saved changes will reapply automatically the next time you generate this SDK. +| +— Succeeded +``` --- @@ -46,4 +82,20 @@ The CLI detects which files were modified and saves a diff to `src/sdk-source-tr apimatic sdk generate --language=typescript ``` -The CLI overwrites the existing SDK and reapplies your saved customizations automatically. No manual re-editing needed. +Output: + +``` +T Generate SDK +| +o The destination '\sdk' is not empty, do you want to overwrite? +| Yes +| +o SDK generated successfully. +| +• Successfully applied saved changes for 'typescript' SDK. +| +• The generated SDK can be found at '\sdk\typescript' +| and the 'sdk-source-tree' can be found at '\src\sdk-source-tree\.typescript'. +| +— Succeeded +``` diff --git a/skills/apimatic-sdk/examples/publish-sdk.md b/skills/apimatic-sdk/examples/publish-sdk.md new file mode 100644 index 0000000..91db170 --- /dev/null +++ b/skills/apimatic-sdk/examples/publish-sdk.md @@ -0,0 +1,48 @@ +# Publish an SDK + +This example shows how to publish a generated SDK using the APIMatic CLI. + +--- + +## Publish the SDK + +``` +apimatic sdk publish --profile-id=b2c3d4e5f6a1b2c3d4e5f6a1 --language=typescript --version=1.0.0 --publish-type=sourcecode +``` + +Output: + +``` +T Publish SDK +| +o Profile search complete. +| +• Version tags will not be created in your Git repository because you have opted to publish Source Code only. +| +o The destination '\sdk' is not empty, do you want to overwrite? +| Yes +| +o SDK generated successfully. +| +• The generated SDK can be found at '\sdk\typescript'. +| +o Publishing initiated. +| +• Publishing is running for the following: +| +| Profile: +| Language: typescript +| Version: 1.0.0 +| Targets: Source Code +| +o Source Code: [Published] +| +o Next Steps ------------------------------------------------------------------------------------------+ +| | +| To view publishing logs, please visit: | +| https://dash.apimatic.io/publish//logs/ | +| | ++-------------------------------------------------------------------------------------------------------+ +| +— Succeeded +``` diff --git a/skills/apimatic-sdk/scripts/auth-login.mjs b/skills/apimatic-sdk/scripts/auth-login.mjs new file mode 100644 index 0000000..b21ad24 --- /dev/null +++ b/skills/apimatic-sdk/scripts/auth-login.mjs @@ -0,0 +1,30 @@ +#!/usr/bin/env node +/** + * APIMatic browser-based auth launcher. + * + * Usage: + * node auth-login.mjs + * + * Spawns `apimatic auth login` as a detached process so the terminal is not + * blocked while the user completes the browser OAuth flow. Prints a message + * for Claude to relay to the user, then exits immediately. + * + * After the user confirms sign-in in the browser, Claude should run: + * apimatic auth status + * to verify the session is active. + * + * No external dependencies — Node.js built-ins only. + */ + +import { spawn } from "node:child_process"; + +const child = spawn("apimatic", ["auth", "login"], { + detached: true, + stdio: "ignore", +}); +child.unref(); + +console.log(`AUTH_LOGIN_LAUNCHED pid=${child.pid}`); +console.log( + "A browser window has opened. Complete sign-in in the browser, then confirm here when done." +); From 884095b67eafb4a6b0c3534b29d61658bedc16b1 Mon Sep 17 00:00:00 2001 From: Ayeshas09 Date: Tue, 5 May 2026 12:50:07 +0500 Subject: [PATCH 5/5] fix: updated the auth login script to run on windows too --- skills/apimatic-portal/scripts/auth-login.mjs | 1 + skills/apimatic-sdk/scripts/auth-login.mjs | 1 + 2 files changed, 2 insertions(+) diff --git a/skills/apimatic-portal/scripts/auth-login.mjs b/skills/apimatic-portal/scripts/auth-login.mjs index b21ad24..e4cdf6e 100644 --- a/skills/apimatic-portal/scripts/auth-login.mjs +++ b/skills/apimatic-portal/scripts/auth-login.mjs @@ -21,6 +21,7 @@ import { spawn } from "node:child_process"; const child = spawn("apimatic", ["auth", "login"], { detached: true, stdio: "ignore", + shell: process.platform === "win32", }); child.unref(); diff --git a/skills/apimatic-sdk/scripts/auth-login.mjs b/skills/apimatic-sdk/scripts/auth-login.mjs index b21ad24..e4cdf6e 100644 --- a/skills/apimatic-sdk/scripts/auth-login.mjs +++ b/skills/apimatic-sdk/scripts/auth-login.mjs @@ -21,6 +21,7 @@ import { spawn } from "node:child_process"; const child = spawn("apimatic", ["auth", "login"], { detached: true, stdio: "ignore", + shell: process.platform === "win32", }); child.unref();