@tzurp/openapi-skills 1.2.8 → 1.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +65 -15
  2. package/dist/cli.min.js +51 -0
  3. package/package.json +60 -64
  4. package/bin/openapi-skills +0 -4
  5. package/dist/cli.d.ts +0 -37
  6. package/dist/cli.js +0 -1646
  7. package/dist/cli.js.map +0 -1
  8. package/dist/client-schema-builder.d.ts +0 -35
  9. package/dist/client-schema-builder.js +0 -268
  10. package/dist/client-schema-builder.js.map +0 -1
  11. package/dist/helper/base64url-json.d.ts +0 -3
  12. package/dist/helper/base64url-json.js +0 -28
  13. package/dist/helper/base64url-json.js.map +0 -1
  14. package/dist/helper/dotNotation.d.ts +0 -3
  15. package/dist/helper/dotNotation.js +0 -34
  16. package/dist/helper/dotNotation.js.map +0 -1
  17. package/dist/helper/endpoint-filter.d.ts +0 -16
  18. package/dist/helper/endpoint-filter.js +0 -165
  19. package/dist/helper/endpoint-filter.js.map +0 -1
  20. package/dist/helper/endpoint-utils.d.ts +0 -2
  21. package/dist/helper/endpoint-utils.js +0 -10
  22. package/dist/helper/endpoint-utils.js.map +0 -1
  23. package/dist/helper/error-codes.d.ts +0 -27
  24. package/dist/helper/error-codes.js +0 -116
  25. package/dist/helper/error-codes.js.map +0 -1
  26. package/dist/helper/error-formatter.d.ts +0 -46
  27. package/dist/helper/error-formatter.js +0 -72
  28. package/dist/helper/error-formatter.js.map +0 -1
  29. package/dist/helper/get-operation-filter.d.ts +0 -17
  30. package/dist/helper/get-operation-filter.js +0 -26
  31. package/dist/helper/get-operation-filter.js.map +0 -1
  32. package/dist/helper/graphql.d.ts +0 -40
  33. package/dist/helper/graphql.js +0 -967
  34. package/dist/helper/graphql.js.map +0 -1
  35. package/dist/helper/http-client.d.ts +0 -28
  36. package/dist/helper/http-client.js +0 -90
  37. package/dist/helper/http-client.js.map +0 -1
  38. package/dist/helper/json-updater.d.ts +0 -17
  39. package/dist/helper/json-updater.js +0 -195
  40. package/dist/helper/json-updater.js.map +0 -1
  41. package/dist/helper/logger.d.ts +0 -13
  42. package/dist/helper/logger.js +0 -56
  43. package/dist/helper/logger.js.map +0 -1
  44. package/dist/helper/output-size.d.ts +0 -5
  45. package/dist/helper/output-size.js +0 -7
  46. package/dist/helper/output-size.js.map +0 -1
  47. package/dist/helper/parameter-schema.d.ts +0 -14
  48. package/dist/helper/parameter-schema.js +0 -36
  49. package/dist/helper/parameter-schema.js.map +0 -1
  50. package/dist/helper/paths.d.ts +0 -11
  51. package/dist/helper/paths.js +0 -47
  52. package/dist/helper/paths.js.map +0 -1
  53. package/dist/helper/prompt-delete.d.ts +0 -1
  54. package/dist/helper/prompt-delete.js +0 -13
  55. package/dist/helper/prompt-delete.js.map +0 -1
  56. package/dist/helper/request-artifacts.d.ts +0 -14
  57. package/dist/helper/request-artifacts.js +0 -60
  58. package/dist/helper/request-artifacts.js.map +0 -1
  59. package/dist/helper/request-preparation.d.ts +0 -23
  60. package/dist/helper/request-preparation.js +0 -85
  61. package/dist/helper/request-preparation.js.map +0 -1
  62. package/dist/helper/sanitizer.d.ts +0 -1
  63. package/dist/helper/sanitizer.js +0 -17
  64. package/dist/helper/sanitizer.js.map +0 -1
  65. package/dist/helper/update-check.d.ts +0 -1
  66. package/dist/helper/update-check.js +0 -36
  67. package/dist/helper/update-check.js.map +0 -1
  68. package/dist/index.d.ts +0 -50
  69. package/dist/index.js +0 -163
  70. package/dist/index.js.map +0 -1
  71. package/dist/install-skill.d.ts +0 -5
  72. package/dist/install-skill.js +0 -139
  73. package/dist/install-skill.js.map +0 -1
  74. package/dist/parser.d.ts +0 -12
  75. package/dist/parser.js +0 -393
  76. package/dist/parser.js.map +0 -1
  77. package/dist/validate-response.d.ts +0 -47
  78. package/dist/validate-response.js +0 -1017
  79. package/dist/validate-response.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
 
2
- # openapi-skills
3
- API CLI with SKILLS
2
+ # openapi-skills: OpenAPI & GraphQL CLI
3
+
4
+ Looking for the Pro version? → https://github.com/tzurp/openapi-skills-pro
5
+ [![Pro version](https://img.shields.io/badge/openapi--skills--pro-Repository-blue)](https://github.com/tzurp/openapi-skills-pro)
6
+
7
+ `openapi-skills` is an OpenAPI CLI and GraphQL CLI for exploring APIs, generating artifacts, validating schemas, and preparing live API requests. Its optional AI agent skills enable Copilot, Claude, Cursor, and other agents to use the CLI through natural language.
8
+
9
+ ![Legacy downloads](https://img.shields.io/badge/Legacy%20downloads-5347-blue)
10
+ ![openapi-skills downloads](https://img.shields.io/badge/dynamic/json?url=https://api.npmjs.org/downloads/point/2020-01-01:2030-01-01/@tzurp/openapi-skills&query=$.downloads&label=Current%20downloads&color=blue)
4
11
  <p align="center">
5
12
  <img src="https://raw.githubusercontent.com/tzurp/images/refs/heads/main/openapi-skills.png">
6
13
  </p>
@@ -10,7 +17,16 @@ Use it manually like a fast, lightweight API explorer, or unlock its full potent
10
17
 
11
18
  With Skills enabled, openapi‑skills becomes an AI‑ready API engine: agents can explore your API, prepare and execute live requests, validate schemas, and even generate client code, tests, and workflows - all from simple, conversational instructions.
12
19
 
13
- ## Overview
20
+ ## Quick links
21
+
22
+ - [Install the CLI](#install-the-cli)
23
+ - [Install the AI skill bundle](#install-the-skill)
24
+ - [Quick start](#quick-start)
25
+ - [AI agent examples](#ai-agent-integration)
26
+ - [Video demo](#-video-demo)
27
+ - [Support and issues](#support)
28
+
29
+ ## Overview: OpenAPI & GraphQL CLI
14
30
 
15
31
  `openapi-skills` helps developers work with API schemas efficiently. It parses OpenAPI and GraphQL definitions, generates structured artifacts, provides exploration tools, validates schemas, prepares request templates, and supports test generation. When the AI skills are installed, agents can understand your API and execute CLI commands automatically.
16
32
 
@@ -24,6 +40,26 @@ Working with API schemas can be slow and error‑prone. `openapi-skills` provide
24
40
  - Built‑in validation tools
25
41
  - Optional AI integration for natural-language workflows
26
42
 
43
+ ## Free vs. Pro: Choosing the right tool for your workflow
44
+
45
+ The free CLI is perfect for solo developers, quick exploration, and everyday API work.
46
+ The Pro CLI is built for teams, automation, and production‑grade workflows, where speed, orchestration, and tooling depth matter.
47
+ Here’s a concise comparison to help you understand where each version shines:
48
+
49
+ ### Comparison Table
50
+ | **Scenario / Workflow** | **Free CLI** | **Pro CLI** |
51
+ | --- | --- | --- |
52
+ | **Explore OpenAPI & GraphQL schemas** | ✔ Explore OpenAPI 2.0 / 3.0.x & GraphQL schemas | ✔ Same, with OpenAPI 3.1 support |
53
+ | **Generate artifacts** | ✔ endpoints.json, schemas/ | ✔ Extended artifacts for docs, diffing & analysis |
54
+ | **Validate schemas** | ✔ Built‑in validation | ✔ Deep validation + version comparison |
55
+ | **Prepare & execute live API requests** | ✔ Postman‑like request builder | ✔ Same, plus mock‑server integration |
56
+ | **AI agent workflows** | ✔ Optional skill bundle for LLM agents | ✔ Enhanced Skills (OpenAPI annotation generation) |
57
+ | **Mock server** | — | ✔ Local mock server from schema artifacts |
58
+ | **HTML API documentation** | — | ✔ Generate interactive HTML docs |
59
+ | **Schema diffing / version comparison** | — | ✔ Operation‑level diffing & breaking‑change detection |
60
+ | **Code‑first OpenAPI generation** | — | ✔ Bootstrap OpenAPI from annotated source code |
61
+ | **Distribution** | ``npm install -g`` | Native installers (Windows/macOS/Linux) |
62
+
27
63
  ## Manual CLI + AI Skills
28
64
 
29
65
  openapi-skills works perfectly as a traditional CLI. You can explore endpoints, inspect schemas, prepare requests, and execute live API calls directly from the terminal.
@@ -152,7 +188,7 @@ Select your preferred path and confirm — that’s it.
152
188
  > **💡 Note:**
153
189
  >
154
190
  > Installing the skill bundle allows AI agents to understand your API structure and execute CLI commands automatically.
155
- > See the section on [AI agent capabilities](#ai-agent-capabilities-some-examples).
191
+ > See the section on [AI agent capabilities](#ai-agent-integration).
156
192
 
157
193
 
158
194
  ### 2. Parse a public API and set its base URL
@@ -180,18 +216,28 @@ openapi-skills request addPet --api petstore --force --update-request '{"body.id
180
216
  openapi-skills generate https://petstore.swagger.io/v2/swagger.json --validate
181
217
  ```
182
218
 
183
- ## Examples of what AI agents can do when the Skill is enabled
219
+ ## AI agent integration
220
+
221
+ The optional skill bundle teaches AI agents how to operate this API CLI using natural-language instructions. With the skill enabled, agents can:
222
+
223
+ - Explore OpenAPI and GraphQL schemas and API operations
224
+ - Generate client code, tests, documentation, and other artifacts
225
+ - Prepare and execute live API requests
226
+ - Validate schemas and API responses
227
+ - Build multi-step API workflows
228
+
229
+ ### AI agent examples
184
230
 
185
231
  | Natural language request | CLI/Skill executed |
186
232
  |--------------------------|--------------------|
187
- | “Make a live request to addPet with name Fluffy.” | Postman‑like API call via `request --update-request` |
188
- | “Show me the first POST operation.” | Explore endpoints via `list` |
189
- | “Describe the addPet operation.” | Operation breakdown via `describe` |
190
- | “Validate this API schema.” | Schema validation via `generate --validate` |
191
- | “Generate a Jest test for addPet.” | Agent writes full Jest test using CLI metadata |
192
- | “Create a Playwright API test for addPet.” | Agent generates Playwright test using endpoint + schema |
193
- | “Build a TypeScript API client for this API.” | Agent generates typed client functions + models |
194
- | “Create a 3-step scenario: add, fetch, delete pet.” | Multi-step workflow via `request` |
233
+ | "/openapi-skills Make a live request to addPet with name Fluffy." | Postman‑like API call via `request --update-request` |
234
+ | "/openapi-skills Show me the first POST operation." | Explore endpoints via `list` |
235
+ | "/openapi-skills Describe the addPet operation." | Operation breakdown via `describe` |
236
+ | "/openapi-skills Validate this API schema." | Schema validation via `generate --validate` |
237
+ | "/openapi-skills Generate a Jest test for addPet." | Agent writes full Jest test using CLI metadata |
238
+ | "/openapi-skills Create a Playwright API test for addPet." | Agent generates Playwright test using endpoint + schema |
239
+ | "/openapi-skills Build a TypeScript API client for this API." | Agent generates typed client functions + models |
240
+ | "/openapi-skills Create a 3-step scenario: add, fetch, delete pet." | Multi-step workflow via `request` |
195
241
 
196
242
  Agents combine CLI output with code generation to produce:
197
243
  - typed API clients
@@ -205,7 +251,7 @@ Agents combine CLI output with code generation to produce:
205
251
 
206
252
  A short video clip demonstrating the CLI in action is available here:
207
253
 
208
- [https://github.com/tzurp/openapi-skills-cli/releases#release-video](https://github.com/tzurp/openapi-skills-cli/releases#release-video)
254
+ [https://github.com/tzurp/openapi-skills-cli/releases/tag/video](https://github.com/tzurp/openapi-skills-cli/releases/tag/video)
209
255
 
210
256
  ## Support
211
257
 
@@ -227,4 +273,8 @@ If you run into issues or have questions:
227
273
 
228
274
  - npm package: [https://www.npmjs.com/package/@tzurp/openapi-skills](https://www.npmjs.com/package/@tzurp/openapi-skills)
229
275
  - GitHub repository: [https://github.com/tzurp/openapi-skills-cli](https://github.com/tzurp/openapi-skills-cli)
230
- ```
276
+ - Bedekbyte: [https://www.bedekbyte.com](https://www.bedekbyte.com)
277
+
278
+ ## npm package release (maintainers)
279
+
280
+ Run `npm run package:npm` to build and test the project, bundle the CLI into a minified `dist/cli.min.js` using esbuild, and create an npm tarball under `dist/npm/`. Publish the generated tarball with `npm publish <tarball-path>`. This npm packaging flow is separate from `publish-to-public.bat`.
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ var en=Object.defineProperty;var E=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var tn=(e,t)=>{for(var r in t)en(e,r,{get:t[r],enumerable:!0})};function re(e){return e.normalize("NFKD").replace(/[\\/]/g,"_").split("_").map(s=>s===""?"_":(s=s.replace(/\./g,"_"),s=s.replace(/[^a-zA-Z0-9_-]/g,"_"),s=s.replace(/^_+|_+$/g,""),s||"_")).join("_")}var ut=E(()=>{"use strict"});import Ee from"fs-extra";import rn from"os";import Se from"path";import{createRequire as Bt}from"module";import{pathToFileURL as nn}from"url";import{buildSchema as sn,isEnumType as Vt,isInputObjectType as an,isListType as zt,isNonNullType as Ht,isObjectType as on,isScalarType as Wt}from"graphql";function Kt(e){if(!(e instanceof Error))return[String(e)];let t=[e.message],r=e.cause;return r instanceof Error?t.push(...Kt(r)):r!=null&&t.push(String(r)),t}function un(e){return!/typescript/i.test(e)||!/(?:Cannot find (?:package|module)|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND)/i.test(e)?!1:/['"]typescript(?:\/(?:unstable\/)?(?:ast|sync))?['"]/i.test(e)||/Cannot find typescript(?:\/(?:unstable\/)?(?:ast|sync))?/i.test(e)}function Yt(e){return Kt(e).some(t=>/TypeScript is required to analyze builder GraphQL schemas/i.test(t)||un(t))}function Xt(e){let t=[Bt(import.meta.url),Bt(Se.join(process.cwd(),"package.json"))];for(let r of t)try{return nn(r.resolve(e)).href}catch{}throw new Error(`Cannot find ${e}`)}async function dn(){let e;for(let t of pn)try{let r=await ln(t);if(typeof r.isCallExpression=="function")return r;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(r){e=r;try{let n=await import(Xt(t));if(typeof n.isCallExpression=="function")return n;e=new Error(`TypeScript module '${t}' does not export the AST API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}async function ln(e){return await import(e)}async function fn(){let e;for(let t of cn)try{let r=await mn(t);if(typeof r.API=="function")return r.API;let n=Qt(r);if(n)return n;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(r){e=r;try{let n=await import(Xt(t));if(typeof n.API=="function")return n.API;let s=Qt(n);if(s)return s;e=new Error(`TypeScript module '${t}' does not export API.`)}catch(n){e=n}}throw e??new Error("TypeScript is required to analyze builder GraphQL schemas.")}function Qt(e){return typeof e.createSourceFile!="function"||!e.ScriptTarget||!e.ScriptKind?null:class{updateSnapshot(r){let n=r.openFiles[0],s=Ee.readFileSync(n,"utf8"),i=e.createSourceFile(n,s,e.ScriptTarget.Latest,!0,e.ScriptKind.TS);return{getDefaultProjectForFile:()=>({program:{getSourceFile:()=>i}}),dispose:()=>{}}}close(){}}}async function mn(e){return await import(e)}async function Zt(){if(fe&&Ue)return fe;try{fe=await dn(),Ue=await fn()}catch(e){throw new Error("TypeScript is required to analyze builder GraphQL schemas.",{cause:e})}return fe}function F(){if(!fe)throw new Error("TypeScript has not been loaded.");return fe}async function gn(e,t){await Zt();let r=Se.extname(t??"").toLowerCase(),n=`graphql-source${r===".tsx"||r===".jsx"?r:".ts"}`,s=await Ee.mkdtemp(Se.join(rn.tmpdir(),"openapi-skills-graphql-")),i=Se.join(s,n);if(await Ee.writeFile(i,e,"utf8"),!Ue)throw new Error("TypeScript API has not been loaded.");let a=new Ue,o=a.updateSnapshot({openFiles:[i]});try{let c=o.getDefaultProjectForFile(i)?.program.getSourceFile(i);if(!c)throw new Error("TypeScript could not parse the GraphQL builder source.");return c}finally{o.dispose(),a.close(),await Ee.remove(s)}}function hn(e,t){return t&&[".ts",".tsx",".mts",".cts"].includes(Se.extname(t).toLowerCase())?!0:[/\bbuilder\.queryType\s*\(/,/\bbuilder\.mutationType\s*\(/,/\bbuilder\.subscriptionType\s*\(/,/\bobjectType\s*\(/,/\bnew\s+SchemaBuilder\s*\(/].some(r=>r.test(e))}async function Qe(e){if(/^https?:\/\//i.test(e)){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to load GraphQL source from ${e}: HTTP ${t.status}`);return await t.text()}return await Ee.readFile(e,"utf8")}function Me(e){return[/\btype\s+Query\b/i,/\btype\s+Mutation\b/i,/\btype\s+Subscription\b/i,/\bschema\s*\{/i,/\bextend\s+type\s+Query\b/i,/\bbuilder\.(queryType|mutationType|subscriptionType)\s*\(/i,/\btoSchema\s*\(/i].some(t=>t.test(e))}function dt(e){let t=F();if(e&&(t.isStringLiteral(e)||t.isNoSubstitutionTemplateLiteral(e)))return e.text}function yn(e,t){let r=F();if(e)return e.properties.find(n=>r.isPropertyAssignment(n)||r.isShorthandPropertyAssignment(n)?(r.isIdentifier(n.name)||r.isStringLiteral(n.name)||r.isNumericLiteral(n.name)?n.name.text:n.name.getText())===t:!1)}function L(e,t){let r=F(),n=yn(e,t);if(!(!n||!r.isPropertyAssignment(n)))return n.initializer}function me(e){let t=F(),r=e;for(;r&&t.isParenthesizedExpression(r);)r=r.expression;return r}function G(e){let t=F(),r=me(e);if(r){if(t.isObjectLiteralExpression(r))return r;if(t.isArrowFunction(r)||t.isFunctionExpression(r)){if(t.isBlock(r.body)){for(let n of r.body.statements)if(t.isReturnStatement(n)&&n.expression){let s=G(n.expression);if(s)return s}return}return G(r.body)}}}function wn(e){let t=F(),r=e.expression;if(!t.isPropertyAccessExpression(r))return;let n=r.name.text;if(n==="queryType")return"query";if(n==="mutationType")return"mutation";if(n==="subscriptionType")return"subscription"}function Mt(e,t){let r=F(),n=me(e);if(n)return r.isStringLiteral(n)||r.isNoSubstitutionTemplateLiteral(n)?n.text:r.isIdentifier(n)?t.objectTypeNames[n.text]??n.text:n.getText()}function bn(e,t){let r=F(),n=me(e);if(n){if(r.isCallExpression(n)){let s=n.expression.getText();if(/\.exposeID$/i.test(s))return"ID";if(/\.exposeString$/i.test(s))return"String";if(/\.exposeInt$/i.test(s))return"Int";if(/\.exposeFloat$/i.test(s))return"Float";if(/\.exposeBoolean$/i.test(s))return"Boolean";if(/\.string$/i.test(s))return"String";if(/\.int$/i.test(s))return"Int";if(/\.float$/i.test(s))return"Float";if(/\.boolean$/i.test(s))return"Boolean";if(/\.id$/i.test(s))return"ID";if(/\.stringList$/i.test(s))return"[String]";if(/\.intList$/i.test(s))return"[Int]";if(/\.floatList$/i.test(s))return"[Float]";if(/\.booleanList$/i.test(s))return"[Boolean]";if(/\.idList$/i.test(s))return"[ID]";let i=n.arguments[0];if(i&&r.isObjectLiteralExpression(i)){let a=L(i,"type");if(a){let o=Mt(a,t);if(o)return o}}}return Mt(n,t)}}function Tn(e){let t=F(),r={},n={};function s(i){if(t.isVariableDeclaration(i)&&i.initializer&&t.isCallExpression(i.initializer)&&t.isPropertyAccessExpression(i.initializer.expression)&&i.initializer.expression.name.text==="objectRef"){let a=i.initializer.arguments[0],o=i.name.getText(e);a&&t.isStringLiteral(a)&&(r[o]=a.text)}if(t.isCallExpression(i)&&t.isPropertyAccessExpression(i.expression)&&i.expression.name.text==="objectType"&&i.arguments.length>1){let a=i.arguments[0],o=G(i.arguments[1]),p=L(o,"name")?dt(L(o,"name")):a&&t.isIdentifier(a)?r[a.text]??a.text:a&&t.isStringLiteral(a)?a.text:void 0;if(p&&o){let c=L(o,"fields"),u=G(c);if(u){let g={};for(let f of u.properties){if(!t.isPropertyAssignment(f))continue;let l=t.isIdentifier(f.name)||t.isStringLiteral(f.name)||t.isNumericLiteral(f.name)?f.name.text:f.name.getText(e),h=bn(f.initializer,{objectTypeNames:r,objectFields:n});h&&(g[l]=h)}n[p]=g}}}i.forEachChild(s)}return s(e),{objectTypeNames:r,objectFields:n}}function $e(e,t,r=new Set){let n=e.trim();if(!n)return{kind:"unknown",typeName:"Unknown"};if(n.endsWith("!"))return{kind:"non-null",typeName:n,required:!0,ofType:$e(n.slice(0,-1),t,r)};if(n.startsWith("[")&&n.endsWith("]"))return{kind:"list",typeName:n,ofType:$e(n.slice(1,-1).trim(),t,r)};if(mt.has(n))return{kind:"scalar",typeName:n};let s=t.objectTypeNames[n]??n;if(r.has(s))return{kind:"object",typeName:s,circular:s,fields:{}};let i=t.objectFields[s];if(!i)return{kind:"object",typeName:s};let a=new Set(r);a.add(s);let o={};for(let[p,c]of Object.entries(i))o[p]=$e(c,t,a);return{kind:"object",typeName:s,fields:o}}function Ve(e){let t=e.trim();for(;t.endsWith("!");)t=t.slice(0,-1).trim();return t.startsWith("[")&&t.endsWith("]")&&(t=t.slice(1,-1).trim()),t}function An(e,t){let r=Ve(e);return mt.has(r)?"scalar":t&&/input|filter|where|args?/i.test(r)||t?"input-object":"object"}function Ge(e,t){let r=e.trim();if(!r)return{kind:"unknown",typeName:"Unknown"};if(r.endsWith("!"))return{kind:"non-null",typeName:r,required:!0,ofType:Ge(r.slice(0,-1),t)};if(r.startsWith("[")&&r.endsWith("]")){let s=r.slice(1,-1).trim();return{kind:"list",typeName:r,ofType:Ge(s,t)}}return{kind:An(r,t),typeName:r}}function Be(e){let t=F(),r=me(e);if(r){if(t.isStringLiteral(r)||t.isNoSubstitutionTemplateLiteral(r))return r.text;if(t.isNumericLiteral(r))return Number(r.text);if(r.kind===t.SyntaxKind.TrueKeyword)return!0;if(r.kind===t.SyntaxKind.FalseKeyword)return!1;if(r.kind===t.SyntaxKind.NullKeyword)return null;if(t.isArrayLiteralExpression(r))return r.elements.map(n=>Be(n));if(t.isObjectLiteralExpression(r)){let n={};for(let s of r.properties)if(t.isPropertyAssignment(s)){let i=t.isIdentifier(s.name)||t.isStringLiteral(s.name)||t.isNumericLiteral(s.name)?s.name.text:s.name.getText();n[i]=Be(s.initializer)}return n}t.isIdentifier(r)&&r.text}}function kn(e){let t=F(),r=me(e);if(!r)return{kind:"unknown",typeName:"Unknown"};if(t.isCallExpression(r)){let n=r.expression.getText(),s=r.arguments[0];if(s&&t.isObjectLiteralExpression(s)){let i=L(s,"type"),a=L(s,"required"),o=L(s,"defaultValue"),p;if(i?p=Ge(i.getText(),!0):/\.string$/i.test(n)?p={kind:"scalar",typeName:"String"}:/\.int$/i.test(n)?p={kind:"scalar",typeName:"Int"}:/\.float$/i.test(n)?p={kind:"scalar",typeName:"Float"}:/\.boolean$/i.test(n)?p={kind:"scalar",typeName:"Boolean"}:/\.id$/i.test(n)&&(p={kind:"scalar",typeName:"ID"}),p)return p.defaultValue=Be(o),a&&Be(a)===!0?{kind:"non-null",typeName:`${p.typeName}!`,required:!0,ofType:p}:p}if(/\.string$/i.test(n))return{kind:"scalar",typeName:"String"};if(/\.int$/i.test(n))return{kind:"scalar",typeName:"Int"};if(/\.float$/i.test(n))return{kind:"scalar",typeName:"Float"};if(/\.boolean$/i.test(n))return{kind:"scalar",typeName:"Boolean"};if(/\.id$/i.test(n))return{kind:"scalar",typeName:"ID"}}return Ge(r.getText(),!0)}function xn(e){let t=Ve(e);return t==="Boolean"?!1:t==="Int"||t==="Float"?0:t==="ID"||t==="String"?"":null}function lt(e){if(e.kind==="non-null"&&e.ofType)return lt(e.ofType);if(e.kind==="list")return[];if(e.kind==="scalar")return xn(e.typeName);if(e.kind==="enum")return e.enumValues?.[0]??null;if(e.kind==="input-object"){let t={};for(let[r,n]of Object.entries(e.fields??{}))t[r]=lt(n);return t}return null}function ft(e){return e.kind==="non-null"&&e.ofType?`${ft(e.ofType)}!`:e.kind==="list"&&e.ofType?`[${ft(e.ofType)}]`:e.typeName}function En(e){let t=Ve(e.typeName);return e.kind==="scalar"||e.kind==="enum"||mt.has(t)}function De(e,t=new Set){if(e.kind==="non-null"&&e.ofType||e.kind==="list"&&e.ofType)return De(e.ofType,t);if(En(e))return"";let r=Ve(e.typeName);if(t.has(r))return"__typename";if(e.kind==="object"||e.kind==="input-object"){let n=new Set(t);n.add(r);let s=Object.entries(e.fields??{});return s.length===0?"{ __typename }":`{ ${s.map(([a,o])=>{let p=De(o,n);if(!p)return a;if(o.kind==="object"||o.kind==="input-object"||o.kind==="list"||o.kind==="non-null"){let c=p.startsWith("{")?p:`{ ${p} }`;return`${a} ${c}`}return`${a} ${p}`}).join(" ")} }`}return"__typename"}function Sn(e){let t=Object.keys(e.args),r=t.map(u=>{let g=e.args[u];return`$${u}: ${g?ft(g):"String"}`}),n={};for(let[u,g]of Object.entries(e.args))n[u]=lt(g);let s=t.map(u=>`${u}: $${u}`).join(", "),i=De(e.returns),a=i?` ${i}`:"",o=re(e.operationId)||e.operationId,p=r.length>0?`(${r.join(", ")})`:"",c=s.length>0?`(${s})`:"";return{query:`${e.rootType} ${o}${p} { ${e.name}${c}${a} }`,variables:n}}function Rn(e){let t=sn(e),r=[["query",t.getQueryType()],["mutation",t.getMutationType()],["subscription",t.getSubscriptionType()]],n=[];for(let[s,i]of r)if(i)for(let a of Object.values(i.getFields())){let o={};for(let u of a.args){let g=Fe(u.type);u.defaultValue!==void 0&&(g.defaultValue=u.defaultValue),o[u.name]=g}let p={name:a.name,operationId:a.name,sanitizedOperationId:re(a.name),rootType:s,args:o,returns:Je(a.type)},c=a.description?.split(`
3
+ `).map(u=>u.trim()).filter(Boolean)[0];c&&(p.summary=c),a.description&&(p.description=a.description),n.push(p)}return n}function Fe(e,t=new Set){if(Ht(e))return{kind:"non-null",typeName:e.toString(),required:!0,ofType:Fe(e.ofType,t)};if(zt(e))return{kind:"list",typeName:e.toString(),ofType:Fe(e.ofType,t)};if(Wt(e))return{kind:"scalar",typeName:e.name};if(Vt(e))return{kind:"enum",typeName:e.name,enumValues:e.getValues().map(r=>r.name)};if(an(e)){if(t.has(e.name))return{kind:"input-object",typeName:e.name,circular:e.name,fields:{}};let r=new Set(t);r.add(e.name);let n={};for(let[s,i]of Object.entries(e.getFields())){let a=Fe(i.type,r);i.defaultValue!==void 0&&(a.defaultValue=i.defaultValue),n[s]=a}return{kind:"input-object",typeName:e.name,fields:n}}return{kind:"unknown",typeName:String(e)}}function Je(e,t=new Set){if(Ht(e))return{kind:"non-null",typeName:e.toString(),required:!0,ofType:Je(e.ofType,t)};if(zt(e))return{kind:"list",typeName:e.toString(),ofType:Je(e.ofType,t)};if(Wt(e))return{kind:"scalar",typeName:e.name};if(Vt(e))return{kind:"enum",typeName:e.name,enumValues:e.getValues().map(r=>r.name)};if(on(e)){if(t.has(e.name))return{kind:"object",typeName:e.name,circular:e.name,fields:{}};let r=new Set(t);r.add(e.name);let n={};for(let[s,i]of Object.entries(e.getFields()))n[s]=Je(i.type,r);return{kind:"object",typeName:e.name,fields:n}}return{kind:"unknown",typeName:e.toString()}}async function Pn(e,t){let r=await Zt(),n=await gn(e,t),s=Tn(n),i=[];function a(o){if(r.isCallExpression(o)&&r.isPropertyAccessExpression(o.expression)){let p=wn(o);if(p&&o.arguments.length>0){let c=G(o.arguments[0]),u=L(c,"fields"),g=G(u);if(g)for(let f of g.properties){if(!r.isPropertyAssignment(f))continue;let l=r.isIdentifier(f.name)||r.isStringLiteral(f.name)||r.isNumericLiteral(f.name)?f.name.text:f.name.getText(n),h=G(f.initializer)??G(f.initializer),w=me(f.initializer),T=w&&r.isCallExpression(w)?w:void 0,m=T?G(T.arguments[0]):h,y=L(m,"type"),O=dt(L(m,"summary")),x=dt(L(m,"description")),P=L(m,"args"),k=G(P),U={};if(k)for(let C of k.properties){if(!r.isPropertyAssignment(C))continue;let le=r.isIdentifier(C.name)||r.isStringLiteral(C.name)||r.isNumericLiteral(C.name)?C.name.text:C.name.getText(n);U[le]=kn(C.initializer)}let _={name:l,operationId:l,sanitizedOperationId:re(l),rootType:p,args:U,returns:y?$e(y.getText(n),s):{kind:"unknown",typeName:"Unknown"}};O&&(_.summary=O),x&&(_.description=x),i.push(_)}}}o.forEachChild(a)}return a(n),i}async function ze(e,t){return hn(e,t)?await Pn(e,t):Rn(e)}async function ge(e,t,r,n){let i=(await ze(e,n)).find(a=>a.rootType===t&&a.name===r);if(!i)throw new Error(`GraphQL field '${r}' not found on root type '${t}'.`);return i}function Re(e){return Sn(e)}var mt,gt,pn,cn,fe,Ue,Pe=E(()=>{"use strict";ut();mt=new Set(["String","Int","Float","Boolean","ID"]),gt="npm install typescript",pn=["typescript/ast","typescript","typescript/unstable/ast"],cn=["typescript/sync","typescript","typescript/unstable/sync"],fe=null,Ue=null});function he(e,t){process.stderr.write(t?`${e}
4
+ `:e)}function H(e){return e instanceof Error?e.message:String(e)}var z,d,ye=E(()=>{"use strict";z=process.stderr.isTTY&&process.stdout.isTTY;d={info(e){he(e,!0)},warn(e){let t="\u26A0\uFE0F ";if(z){let r=`\x1B[33m${t}${e}\x1B[0m`;he(r,!0)}else he(t+e,!0)},banner(e){he(z?`\x1B[35m${e}\x1B[0m`:e,!0)},error(e){process.stderr.write(`\u274C ${e}
5
+ `)},progress(e){z&&he(e,!1)},progressLine(e){z&&he(e,!0)},result(e){process.stdout.write(`${JSON.stringify(e)}
6
+ `)}}});import{promises as He}from"fs";import er from"path";import We from"fs-extra";async function tr(e){try{return await We.readJSON(e,"utf8")}catch(t){if(t.code==="ENOENT")return{};throw t}}function In(e,t,r){let n=t.split("."),s=e;for(let i=0;i<n.length;i++){let a=n[i]??"",o=i===n.length-1,p=typeof a=="string"&&/^[0-9]+$/.test(a),c=p?Number(a):void 0;if(o)p&&Array.isArray(s)&&c!==void 0?s[c]=r:s[a]=r;else if(p&&c!==void 0){if(!Array.isArray(s)&&i>0){let u=n[i-1]??"";s[u]=[],s=s[u]}s[c]||(s[c]={}),s=s[c]}else(!(a in s)||typeof s[a]!="object"||s[a]===null)&&(s[a]={}),s=s[a]}}function On(e,t){let r=t.split(".");if(r.length===0)return!1;let n=e;for(let a=0;a<r.length-1;a++){let o=r[a]??"",c=/^[0-9]+$/.test(o)&&Array.isArray(n)?n[Number(o)]:n&&typeof n=="object"?n[o]:void 0;if(c==null)return!1;n=c}let s=r[r.length-1]??"",i=/^[0-9]+$/.test(s);if(Array.isArray(n)&&i){let a=Number(s);return a<0||a>=n.length?!1:(n.splice(a,1),!0)}return n&&typeof n=="object"&&Object.prototype.hasOwnProperty.call(n,s)?(delete n[s],!0):!1}function qn(e,t){return e===t||e.startsWith(`${t}.`)}function vn(e,t){let r=e.split("."),n=t.split(".");if(r.length!==n.length)return n.length-r.length;let s=r[r.length-1]??"",i=n[n.length-1]??"",a=r.slice(0,-1).join("."),o=n.slice(0,-1).join(".");return a===o&&/^[0-9]+$/.test(s)&&/^[0-9]+$/.test(i)?Number(i)-Number(s):t.localeCompare(e)}async function Ie(e,t,r=2,n={}){let s={};try{let m=await He.readFile(e,"utf8");s=JSON.parse(m)}catch(m){if(m.code!=="ENOENT")throw m}let i=JSON.parse(JSON.stringify(s)),a=n.deleteSentinel,o=a===void 0?[]:Object.entries(t).filter(([,m])=>m===a).map(([m])=>m).sort(vn);for(let m of o)On(i,m);for(let[m,y]of Object.entries(t))a!==void 0&&y===a||o.some(O=>qn(m,O))||In(i,m,y);if(!(JSON.stringify(s)!==JSON.stringify(i)))return{changed:!1,before:s,after:i};let c=er.resolve(e),u=er.dirname(c),g=Math.random().toString(36).slice(2,10),f=`${c}.tmp.${process.pid}.${g}`,l,h=new Set(["EPERM","EACCES","EBUSY"]);async function w(m){await new Promise(y=>setTimeout(y,m))}async function T(m,y){for(let x=1;x<=5;x++)try{await He.rename(m,y);return}catch(P){if(!h.has(P?.code)||x===5)throw P;await w(25*x)}}try{await He.mkdir(u,{recursive:!0}),l=await He.open(f,"w"),await l.writeFile(JSON.stringify(i,null,r),"utf8"),await l.sync(),await l.close(),await T(f,c);try{let m=We.openSync(u,"r");We.fsyncSync(m),We.closeSync(m)}catch{}return{changed:!0,before:s,after:i}}catch(m){if(l)try{await l.close()}catch{}throw(m.code==="EPERM"||m.code==="EACCES"||m.code==="EBUSY")&&d.error(`Failed to atomically update JSON file due to a file lock or permission error.
7
+ Please close any programs that may have the file open and try again.
8
+ The temporary file with your changes is: ${f}`),m}}var Ke,ht=E(()=>{"use strict";ye();Ke="__delete__"});import B from"path";import Nn from"find-root";function se(e,t){let r=q(e);return B.join(r,`${t}.json`)}function ie(e){return B.resolve(ne,".openapi-skills",e,"bundled.json")}function yt(e){return B.resolve(ne,".openapi-skills",e,"components.json")}function ae(e,t){let r=q(e);return B.resolve(r,t)}function q(e){return B.resolve(ne,".openapi-skills",e,"schemas")}function Oe(e){return B.resolve(ne,".openapi-skills",e)}function rr(){return B.resolve(ne,".openapi-skills","config.json")}function j(e){return B.resolve(ne,".openapi-skills",e,"endpoints.json")}function Ye(e,t,r){let n=ae(e,t),s=r==="response-schema"?"response-schema.json":`${r}.json`;return B.join(n,s)}function Xe(){return B.resolve(ne,".openapi-skills")}function Ze(){let e=process.cwd();try{return Nn(e)}catch{return e}}var ne,W=E(()=>{"use strict";ne=Ze()});import{readFile as jn}from"fs/promises";import _n from"path";import oe from"fs-extra";async function J(){return await oe.readJSON(we)}async function wt(){if(await oe.ensureDir(Cn),!await oe.pathExists(we)){let e={apis:{}};await oe.writeJson(we,e,{spaces:2})}}function nr(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}async function be(e,t={}){if(typeof e!="string"||e.trim().length===0)throw new Error("API name is required.");let{baseUrl:r,auth:n,vars:s,version:i,openapiSource:a,schemaType:o,removeApi:p}=t,c={};if(p){if(!await oe.pathExists(we))throw new Error("Config file not found.");let u=await J();if(!nr(u)||!nr(u.apis))throw new Error("Invalid config file.");if(!(e in u.apis))throw new Error(`API '${e}' not found`);delete u.apis[e],await oe.writeJson(we,u,{spaces:2});return}if(await wt(),n!==void 0&&(c[`apis.${e}.auth.headers`]=n),s!==void 0)for(let[u,g]of Object.entries(s))c[`apis.${e}.vars.${u}`]=g;if(i!==void 0&&(c[`apis.${e}.version`]=i),a!==void 0){let u=a;try{new URL(a)}catch{u=_n.normalize(a)}c[`apis.${e}.openapiSource`]=u}r!==void 0&&(c[`apis.${e}.baseUrl`]=r),o!==void 0&&(c[`apis.${e}.schemaType`]=o),Object.keys(c).length!==0&&await Ie(we,c,2)}function Ln(e){let t=e instanceof Error?e.message:String(e);return/config/i.test(t)?{type:"ConfigError",message:t}:/permission|EACCES|EPERM/i.test(t)?{type:"DirectoryDeletionError",message:t}:{type:"DeleteApiError",message:t}}async function sr(e){if(typeof e!="string"||e.trim().length===0)return{ok:!1,error:{type:"InvalidApiName",message:"API name is required."}};try{if(!(await pe()).includes(e))return{ok:!1,error:{type:"ApiNotFound",message:`API '${e}' is not installed.`}};await be(e,{removeApi:!0});let r=Oe(e);return await oe.remove(r),{ok:!0,message:`API ${e} removed successfully`,data:{removedApi:e}}}catch(t){return{ok:!1,error:Ln(t)}}}async function et(e,t){let n=(await J()).apis[e];if(!n)throw new Error(`API '${e}' not found`);switch(t){case"version":return n.version??"unknown";case"baseUrl":return n.baseUrl;case"authHeaders":return n.auth?.headers??{};case"vars":return Object.entries(n.vars??{})}}async function ir(e){try{let t=await jn(j(e),"utf-8");return JSON.parse(t)}catch(t){throw t instanceof SyntaxError?new Error(`Failed to parse endpoints.json: Invalid JSON format. ${t.message}`):new Error(`Failed to read endpoints.json: ${t instanceof Error?t.message:String(t)}`)}}async function pe(){let e=await J();return Object.keys(e.apis)||[]}var Cn,we,ce=E(()=>{"use strict";ht();W();Cn=Xe(),we=rr()});import bt from"@apidevtools/swagger-parser";import $n from"@apidevtools/json-schema-ref-parser";import S from"fs-extra";import K from"path";function ar(e){let t;try{let r=new URL(e);t=K.basename(r.pathname,K.extname(r.pathname))}catch{t=K.basename(e,K.extname(e))}return re(t||"api")}function Dn(e){if(e instanceof Error)return/circular/i.test(e.message)||/circular/i.test(e.name);if(typeof e=="object"&&e!==null){let t=String(e.message??""),r=String(e.name??"");return/circular/i.test(t)||/circular/i.test(r)}return!1}function Tt(e,t=new WeakSet){if(e&&typeof e=="object"){if(t.has(e))return;if(t.add(e),Array.isArray(e)){let n=e.map(s=>Tt(s,t));return t.delete(e),n}let r={};for(let[n,s]of Object.entries(e)){let i=Tt(s,t);i!==void 0&&(r[n]=i)}return t.delete(e),r}return e}async function Fn(e){let t=ie(e),r=await S.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function Jn(e,t,r,n=!1){let s=se(e,r);if(!n&&await S.pathExists(s))return S.readJson(s);let i=await S.readJson(j(e)),a=Array.isArray(i)?i.find(u=>u.operationId===t||u.name===t||u.sanitizedOperationId===r):void 0;if(!a)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let o=typeof a.rootType=="string"?a.rootType:typeof a.method=="string"?a.method:void 0;if(!o||o!=="query"&&o!=="mutation"&&o!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let p=await Fn(e),c=await ge(p,o,t);return await S.ensureDir(K.dirname(s)),await S.writeJson(s,c,{spaces:2}),c}function Un(e,t){for(let[r,n]of Object.entries(e))for(let[s,i]of Object.entries(n))if(i&&typeof i=="object"&&"operationId"in i){let a=i;if(a.operationId===t)return{pathKey:r,method:s,operation:a}}}async function Gn(e,t){let r=typeof e.operationId=="string"?e.operationId:"unknown-operation",n=typeof e.method=="string"?e.method.toUpperCase():"GET",s=typeof e.path=="string"?e.path:"unknown-path",i=z;i&&d.progressLine(`Dereferencing endpoint ${r} (${n} ${s})...`);let a={openapi:"3.0.0",paths:{"/temp":{get:e}},definitions:t,components:t},o=await $n.dereference(a,{mutateInputSchema:!1,dereference:{circular:"ignore"}}),p=Tt(o),c=p.paths,u=c&&typeof c=="object"?c["/temp"]:void 0,g=u&&typeof u=="object"?u.get:void 0;return g&&typeof g=="object"?(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),g):(i&&d.progressLine(`Endpoint ${r} (${n} ${s}) dereference complete.`),p)}async function Q(e,t,r,n=!1){let s=se(e,r);if(!n&&await S.pathExists(s))return S.readJson(s);let i=ie(e),a=yt(e),o=await S.readJson(i);if(o&&typeof o=="object"&&o.schemaType==="graphql")return await Jn(e,t,r,n);if(!o||typeof o!="object"||!("paths"in o))throw new Error(`Bundled OpenAPI document not found for API '${e}'. Run generate first.`);let p={},c=o.components,u=o.definitions;c&&typeof c=="object"&&!Array.isArray(c)?p=c:u&&typeof u=="object"&&!Array.isArray(u)?p=u:await S.pathExists(a)&&(p=await S.readJson(a));let g=Un(o.paths,t);if(!g)throw new Error(`Endpoint '${t}' not found in bundled OpenAPI document.`);let f={operationId:t,method:g.method,path:g.pathKey,...g.operation},l=await Gn(f,p);return await S.ensureDir(K.dirname(s)),await S.writeJson(s,l,{spaces:2}),l}async function Bn(e,t){if(!t)return bt.bundle(e);try{return await bt.dereference(e,{dereference:{circular:!1}})}catch(r){throw Dn(r)?new Error("The --dereference flag cannot be used because this OpenAPI spec contains circular references. Try running without --dereference."):r}}function Qn(e){return typeof e.swagger=="string"&&e.swagger.startsWith("2.")?"2":typeof e.openapi=="string"&&e.openapi.startsWith("3.")?"3":"2"}async function Mn(e,t,r={}){let n="",s="unknown",i,a=r.progress!==!1&&z;try{a&&d.progressLine(`Loading OpenAPI document from ${e}...`),i=await Bn(e,r.dereference===!0),a&&d.progressLine("OpenAPI document load complete.")}catch(o){throw d.error(`Error during parsing OpenAPI schema: ${o instanceof Error?o.message:String(o)}`),o}if(typeof i!="object"||!i.paths)throw new Error("Invalid OpenAPI schema: Missing 'paths'");try{s=Qn(i),n=r.rename||ar(e);let o=Oe(n);await S.remove(o);let p=q(n);await S.ensureDir(p);let c=ie(n);if(await S.writeJson(c,i,{spaces:2}),!r.dereference){let h=yt(n);await S.writeJson(h,i?.components??{},{spaces:2})}let u=[],g=0,f=0,l=r.progress!==!1&&z;for(let[h,w]of Object.entries(i.paths))for(let[T,m]of Object.entries(w))m&&typeof m=="object"&&"operationId"in m&&m.operationId&&(g+=1);for(let[h,w]of Object.entries(i.paths))for(let[T,m]of Object.entries(w))if(m&&typeof m=="object"&&"operationId"in m){let y=m;if(y.operationId){let O={operationId:y.operationId,sanitizedOperationId:re(y.operationId),method:T,path:h};if(Array.isArray(y.tags)){let x=y.tags.map(P=>typeof P=="string"?P.trim():"").filter(P=>P.length>0);x.length>0&&(O.tags=x)}y.summary!==void 0&&(O.summary=y.summary),y.description!==void 0&&(O.description=y.description),u.push(O),f+=1,l&&d.progress(`\rProcessed ${f}/${g}`)}}l&&g>0&&d.progressLine("");try{let h=K.join(o,"endpoints.json");await S.writeJson(h,u,{spaces:2})}catch(h){throw d.error(`Error writing endpoints.json: ${h instanceof Error?h.message:String(h)}`),h}try{await be(n,{baseUrl:t,openapiSource:e,schemaType:"openapi",version:s});let h=t?"with baseUrl":"without baseUrl";d.info(`Schema '${n}' added to config.json ${h} and openapiSource recorded.`)}catch(h){throw d.error(`Error updating config.json: ${h instanceof Error?h.message:String(h)}`),h}}catch(o){throw d.error(`Error during OpenAPI schema processing: ${o instanceof Error?o.message:String(o)}`),o}return n}async function Vn(e,t,r={},n){let s="",i=r.progress!==!1&&z,a=n??await Qe(e);if(!Me(a))throw new Error("Invalid GraphQL schema: missing GraphQL schema markers or builder pattern.");i&&d.progressLine(`Loading GraphQL schema from ${e}...`),s=r.rename||ar(e);let o=Oe(s);await S.remove(o);let p=q(s);await S.ensureDir(p);let c=await ze(a,e);if(c.length===0)throw new Error("Invalid GraphQL schema: no query, mutation, or subscription fields were found.");let u=ie(s);await S.writeJson(u,{schemaType:"graphql",source:a},{spaces:2});let g=c.map(f=>({name:f.name,sanitizedOperationId:f.sanitizedOperationId,rootType:f.rootType,summary:f.summary,description:f.description}));for(let f of c){let l=se(s,f.sanitizedOperationId);await S.ensureDir(K.dirname(l)),await S.writeJson(l,f,{spaces:2})}await S.writeJson(K.join(o,"endpoints.json"),g,{spaces:2});try{await be(s,{baseUrl:t,openapiSource:e,schemaType:"graphql",version:"graphql"});let f=t?"with baseUrl":"without baseUrl";d.info(`Schema '${s}' added to config.json ${f} and GraphQL source recorded.`)}catch(f){throw d.error(`Error updating config.json: ${f instanceof Error?f.message:String(f)}`),f}return i&&d.progressLine("GraphQL schema load complete."),s}async function or(e,t,r={}){let n=await Qe(e).catch(()=>{});return n&&Me(n)?await Vn(e,t,r,n):await Mn(e,t,r)}async function pr(e){try{let t=await Qe(e).catch(()=>{});if(t&&Me(t)){await ze(t,e);return}await bt.validate(e);return}catch(t){throw new Error(t instanceof Error?t.message:String(t))}}var Te=E(()=>{"use strict";Pe();ce();W();ye();ut()});function zn(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function At(e){if(!(!e||typeof e!="object"))return zn(e.schema)?e.schema:e}function cr(e){let t=At(e);switch(typeof t?.type=="string"?t.type:typeof e?.type=="string"?e.type:void 0){case"string":return"";case"number":case"integer":return 0;case"boolean":return!1;case"array":return[];case"object":return{};default:return null}}var kt=E(()=>{"use strict"});import Ae from"fs-extra";function tt(e){return e.replace(/[^a-zA-Z0-9]+(.)/g,(t,r)=>r.toUpperCase()).replace(/^[a-z]/,t=>t.toUpperCase())}function X(e,t,r){if(!(!e||typeof e!="object")){if(Array.isArray(e.enum)){let n=tt(r);t[n]=e.enum}if(e.properties&&typeof e.properties=="object")for(let[n,s]of Object.entries(e.properties))X(s,t,`${r}_${n}`);e.items&&X(e.items,t,`${r}_item`),e.oneOf&&e.oneOf.forEach((n,s)=>X(n,t,`${r}_oneOf_${s}`)),e.anyOf&&e.anyOf.forEach((n,s)=>X(n,t,`${r}_anyOf_${s}`)),e.allOf&&e.allOf.forEach((n,s)=>X(n,t,`${r}_allOf_${s}`))}}function Z(e){if(!(!e||typeof e!="object")){if(delete e.xml,e.properties&&typeof e.properties=="object")for(let t of Object.values(e.properties))Z(t);e.items&&Z(e.items),e.oneOf&&e.oneOf.forEach(Z),e.anyOf&&e.anyOf.forEach(Z),e.allOf&&e.allOf.forEach(Z)}}function ur(e){if(!e||typeof e!="object")return null;let r=Object.keys(e).filter(n=>/^\d{3}$/.test(n)).find(n=>n.startsWith("2"));return r?e[r]:null}function xt(e){if(!e||typeof e!="object")return null;let t=Object.entries(e).find(([r])=>r.toLowerCase().includes("json"));return t?t[1]:null}function Hn(e){let t=ur(e);if(!t)return null;if(t.content){let r=xt(t.content);return!r||!r.schema?null:r.schema}return t.schema??null}function Wn(e){let t=ur(e);return t?t.schema??null:null}function Kn(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(i=>i.in==="body");if(r?.schema)return r.schema;let n=t.filter(i=>i.in==="formData");if(n.length===0)return null;let s={type:"object",properties:{}};for(let i of n){let a={};i.schema&&typeof i.schema=="object"?Object.assign(a,i.schema):(typeof i.type=="string"&&(a.type=i.type),i.items&&(a.items=i.items),typeof i.format=="string"&&(a.format=i.format),Array.isArray(i.enum)&&(a.enum=i.enum),i.type==="file"&&(a.type="string",a.format="binary")),s.properties[i.name]=a}return s}function Xn(e){let t={};if(!e||typeof e!="object")return t;for(let[r,n]of Object.entries(e)){if(!/^\d{3}$/.test(r)||r.startsWith("2"))continue;let s=n.content,i=s?xt(s):null,a=i&&i.schema?i.schema:n.schema??Yn;t[r]=a}return t}function Zn(e,t){let r={};for(let n of["path","query","header"])for(let[s,i]of Object.entries(e[n]||{}))r[s]={...i.schema,required:i.required??!1,description:i.description,in:n};return{typeName:`${tt(t)}Params`,schema:r}}async function qe(e,t,r,n=!1){let s=await J(),i=await Ae.readJson(j(e)),a=Array.isArray(i)&&i.some(y=>typeof y?.rootType=="string");if(s.apis?.[e]?.schemaType==="graphql"||s.apis?.[e]?.schemaType!=="openapi"&&a){let y=i.find(k=>k.operationId===t||k.name===t);if(!y)throw new Error(`Endpoint with operationId '${t}' not found.`);let O=typeof y.rootType=="string"?y.rootType:typeof y.method=="string"?y.method:void 0;if(!O||O!=="query"&&O!=="mutation"&&O!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let x=q(e)+`/${r}.json`,P;if(!n&&await Ae.pathExists(x))P=await Ae.readJson(x);else{let k=await Ae.readJson(ie(e)),U=typeof k?.source=="string"?k.source:typeof k?.sourceText=="string"?k.sourceText:void 0;if(!U)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);P=await ge(U,O,t),await Ae.ensureDir(q(e)),await Ae.writeJson(x,P,{spaces:2})}return{schemaType:"graphql",fieldName:y.name??t,rootType:O,args:Object.fromEntries(Object.entries(P.args??{}).map(([k,U])=>{let _=U;return[k,{type:_.typeName??"unknown",required:_.required===!0}]})),returnType:P.returns?.typeName??"unknown",query:Re(P).query}}let p=i.find(y=>y.operationId===t);if(!p)throw new Error(`Endpoint with operationId '${t}' not found.`);let c=await Q(e,t,r,n),u={path:{},query:{},header:{}};for(let y of c.parameters||[])(y.in==="path"||y.in==="query"||y.in==="header")&&(u[y.in][y.name]={description:y.description,required:y.required,schema:At(y)});let g=Hn(c.responses)??Wn(c.responses),f={};g&&(Z(g),X(g,f,`${t}_response`));let l=Zn(u,t),h=Xn(c.responses),w=null,T=c.requestBody;if(T&&T.content){let y=xt(T.content);y&&y.schema&&(w=y.schema,Z(w),X(w,f,`${t}_request`))}else w=Kn(c),w&&(Z(w),X(w,f,`${t}_request`));let m=tt(t.replace(/^(get|post|put|delete|patch|head|options)/i,"")||t);return{schemaType:"rest",operationId:t,method:p.method,path:p.path,deprecated:p.deprecated??c.deprecated??!1,params:l,response:g?{typeName:m,schema:g}:null,requestBody:w?{typeName:`${tt(t)}Request`,schema:w}:null,errors:h,enums:f}}var Yn,Et=E(()=>{"use strict";W();Te();kt();Pe();ce();Yn={type:"object",properties:{message:{type:"string"},status:{type:"number"}}}});var ve,dr=E(()=>{"use strict";ve=class{constructor(t){this.baseUrl=t}baseUrl;async request(t,r,n={}){if(!/^https?:\/\//i.test(this.baseUrl))throw new Error(`Invalid baseUrl: "${this.baseUrl}". Must include http:// or https://`);let s=this.baseUrl.endsWith("/")?this.baseUrl:this.baseUrl+"/",i=new URL(r.replace(/^\//,""),s).toString(),a="body"in n&&n.body!==void 0&&t!=="GET"&&t!=="HEAD",o=new Headers(n.headers??{}),p=null;if(a){let f=n.body,l=typeof FormData<"u"&&f instanceof FormData,h=typeof Blob<"u"&&f instanceof Blob,w=f instanceof ArrayBuffer||ArrayBuffer.isView(f),T=typeof Buffer<"u"&&Buffer.isBuffer(f);l?(o.delete("Content-Type"),p=f):h||w||T||typeof f=="string"?p=f:(o.has("Content-Type")||o.set("Content-Type","application/json"),p=JSON.stringify(f))}let c=await fetch(i,{method:t,headers:o,body:p}),u=await c.text(),g={};if(u.trim().length>0)try{g=JSON.parse(u)}catch{g=u}return g!==null&&typeof g=="object"&&!Array.isArray(g)?{...g,status:c.status,statusText:c.statusText}:{body:g,status:c.status,statusText:c.statusText}}get(t,r){return this.request("GET",t,r)}head(t,r){return this.request("HEAD",t,r)}options(t,r){return this.request("OPTIONS",t,r)}post(t,r){return this.request("POST",t,r)}put(t,r){return this.request("PUT",t,r)}patch(t,r){return this.request("PATCH",t,r)}delete(t,r){return this.request("DELETE",t,r)}}});import es from"fs-extra";function lr(e){return{orGroups:e.trim().toLowerCase().split("|").map(r=>r.trim()).filter(Boolean).map(r=>r.split(/\s+/).filter(Boolean))}}function ts(e,t){return t.orGroups.length===0?!0:t.orGroups.some(r=>r.every(n=>e.includes(n)))}function rs(e){return e.split("/").map(t=>t.trim().toLowerCase()).filter(Boolean).flatMap(t=>{if(t.startsWith("{")&&t.endsWith("}")){let r=t.slice(1,-1).trim();return r?[t,r]:[t]}return[t]})}function ns(e,t){return t?t===":param"?/\{[^/{}]+\}/.test(e):t.startsWith("/")?e.startsWith(t):rs(e).includes(t):!0}function ss(e,t){return lr(t).orGroups.some(n=>n.every(s=>ns(e,s)))}function is(e){return e?(Array.isArray(e)?e:[e]).map(t=>t.trim()).filter(Boolean):[]}function as(e,t){if(typeof t!="string"||t.trim().length===0||t.trim()===":")return e;let r=t.trim(),n=r.match(/^-?\d+$/),s=r.match(/^(-?\d*)?:(-?\d*)?$/),i,a;if(n)i=Number(r),a=i;else if(s){let f=s[1],l=s[2];i=f===void 0||f===""?0:Number(f),a=l===void 0||l===""?e.length-1:Number(l)}else throw new Error(`Invalid --index value: ${t}`);if(Number.isNaN(i)||Number.isNaN(a))throw new Error(`Invalid --index value: ${t}`);let o=f=>f<0?e.length+f:f,p=o(i),c=o(a);if(e.length===0)return[];let u=Math.max(0,p),g=Math.min(e.length-1,c);return u>g?[]:e.slice(u,g+1)}function fr(e,t){return as(e,t)}function rt(e,t){let r=e;if(t.operationId){let s=t.operationId.toLowerCase();r=r.filter(i=>(i.operationId||"").toLowerCase()===s)}if(t.method){let s=t.method.toLowerCase();r=r.filter(i=>(i.method||"").toLowerCase()===s)}if(t.rootType){let s=t.rootType.toLowerCase();r=r.filter(i=>(i.rootType||"").toLowerCase()===s)}if(t.tag){let s=t.tag.toLowerCase();r=r.filter(i=>(Array.isArray(i.tags)?i.tags:[]).some(o=>typeof o=="string"&&o.toLowerCase()===s))}let n=is(t.path);if(n.length>0&&(r=r.filter(s=>{let i=(s.path||"").toString().toLowerCase();return n.every(a=>ss(i,a))})),t.filter){let s=lr(t.filter);r=r.filter(i=>{let a=[i.operationId,i.name,i.method,i.rootType,i.path,i.summary,i.description].map(o=>(o||"").toString().toLowerCase()).join(" ");return ts(a,s)})}return r}async function os(e){let t=q(e);try{let r=await es.readdir(t,{withFileTypes:!0});return new Set(r.filter(n=>n.isFile()&&n.name.toLowerCase().endsWith(".json")).map(n=>n.name.slice(0,-5)))}catch(r){if(r?.code==="ENOENT")return new Set;throw r}}async function mr(e,t){let r=await os(e);return r.size===0?[]:t.filter(n=>{let s=typeof n.sanitizedOperationId=="string"?n.sanitizedOperationId:"";return r.has(s)})}var St=E(()=>{"use strict";W()});async function Y(e,t){let r={operationId:t},n=await ir(e),s=rt(n,r)[0]??n.find(i=>i.name===t);return s?.sanitizedOperationId??s?.operationId??s?.name??""}var ue,nt=E(()=>{"use strict";ce();St();ue=Y});function ps(e){return e.replace(/\[(\d+)\]/g,".$1").split(".").filter(r=>r.length>0).map(r=>/^\d+$/.test(r)?Number(r):r)}function Ne(e,t){let r=e;for(let n of ps(t)){if(r==null)return;if(typeof n=="number"){if(!Array.isArray(r)&&typeof r!="object")return;r=r[n];continue}if(typeof r!="object")return;r=r[n]}return r}function gr(e,t,r){return Array.isArray(e)?e.filter(n=>String(Ne(n,t))===String(r)):e}var Rt=E(()=>{"use strict"});import A from"fs-extra";import R from"path";import cs from"ajv";import{fileURLToPath as us}from"url";function je(e,t="",r={}){if(!e||typeof e!="object"||Array.isArray(e))return r;for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)?je(s,i,r):r[i]=s}return r}function Tr(e,t=""){if(!e||typeof e!="object"||Array.isArray(e))return[];let r=[];for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)&&(r.push(i),r.push(...Tr(s,i)))}return Array.from(new Set(r))}function ds(e){let t=Tr(e);if(t.length===0)return;let r=je(e);return["Use only flattened object dot-notation keys with --force.",`Example: --force --update-request '${JSON.stringify(r)}'.`,`Detected nested keys: ${t.join(", ")}.`].join(" ")}function hr(e){return e===null?"null":Ar(e)?"file":Array.isArray(e)?"array":typeof e}function Ar(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.kind==="file"}function vt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.path=="string"&&(e.kind===void 0||e.kind==="file")}function ls(e,t){return Ar(e)?typeof t=="string"||vt(t):e===null?t===null:Array.isArray(e)?Array.isArray(t):typeof e=="object"?!!t&&typeof t=="object"&&!Array.isArray(t):typeof t==typeof e}function kr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.query=="string"&&typeof e.variables=="object"&&!Array.isArray(e.variables)}function xr(e){if(e)return e.split(",")[0]?.trim()||void 0}function fs(e){switch(R.extname(e).toLowerCase()){case".pdf":return"application/pdf";case".jpg":case".jpeg":return"image/jpeg";case".png":return"image/png";case".webp":return"image/webp";case".gif":return"image/gif";case".txt":return"text/plain";case".csv":return"text/csv";case".json":return"application/json";case".xml":return"application/xml";case".xlsx":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case".xls":return"application/vnd.ms-excel";case".docx":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case".zip":return"application/zip";default:return"application/octet-stream"}}function yr(e){let t=e.trim();return t.startsWith("@")?R.resolve(t.slice(1)):t.startsWith("file://")?R.resolve(us(new URL(t))):R.resolve(t)}async function Pt(e,t){let r,n,s;if(typeof e=="string"){if(e.trim().length===0)throw new Error("File upload path cannot be empty.");r=yr(e)}else if(vt(e)){if(e.path.trim().length===0)throw new Error("File upload path cannot be empty.");r=yr(e.path),n=e.fileName?.trim()||void 0,s=e.mimeType?.trim()||void 0}if(!r)throw new Error("File upload values must be a file path string or { kind: 'file', path, fileName?, mimeType? } object.");if(!await A.pathExists(r))throw new Error(`Upload file not found: ${r}`);let i=await A.readFile(r),a=n||R.basename(r),o=s||xr(t)||fs(r);return{buffer:i,path:r,fileName:a,mimeType:o}}function wr(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}function ms(e){let t=Object.entries(e),r=t.find(([a])=>a.toLowerCase().includes("multipart/form-data"));if(r)return{contentType:r[0],contentObject:r[1]};let n=t.find(([a,o])=>{let p=o?.schema;return a.toLowerCase().includes("octet-stream")||p?.type==="string"&&p?.format==="binary"});if(n)return{contentType:n[0],contentObject:n[1]};let s=t.find(([a])=>a.toLowerCase().includes("json"));if(s)return{contentType:s[0],contentObject:s[1]};let i=t[0];return i?{contentType:i[0],contentObject:i[1]}:void 0}function gs(e){let t=e?.requestBody,n=(Array.isArray(e?.parameters)?e.parameters:[]).filter(o=>o&&o.in==="formData"),i=(Array.isArray(e?.consumes)?e.consumes:[]).some(o=>typeof o=="string"&&o.toLowerCase().includes("multipart/form-data"));if(n.length>0&&i)return{kind:"multipart",schema:Ot(e)??{type:"object",properties:{}},encoding:{}};if(!t||typeof t!="object")return n.length>0?{kind:"multipart",schema:Ot(e)??{type:"object",properties:{}},encoding:{}}:{kind:"json"};let a=t.content;if(a&&typeof a=="object"&&!Array.isArray(a)){let o=ms(a);if(!o)return{kind:"json"};let p=o.contentObject,c=p?.schema;if(o.contentType.toLowerCase().includes("multipart/form-data"))return{kind:"multipart",schema:c&&typeof c=="object"?c:{type:"object",properties:{}},encoding:p?.encoding??{}};if(o.contentType.toLowerCase().includes("octet-stream")||c?.type==="string"&&c?.format==="binary")return{kind:"binary",contentType:o.contentType}}return{kind:"json"}}async function It(e,t){let r=gs(e);if(r.kind==="multipart"){let a=t,o=!!a&&typeof a=="object"&&!Array.isArray(a)&&("requestBody"in a||"parameters"in a),p=o?a.requestBody:t,c=o&&Array.isArray(a?.parameters)?Object.fromEntries(a.parameters.filter(l=>!!l&&l.in==="formData"&&typeof l.name=="string").map(l=>[l.name,l.value])):{},u=p&&typeof p=="object"&&!Array.isArray(p)?p:c;if(!u||typeof u!="object"||Array.isArray(u))throw new Error("multipart/form-data request bodies must be JSON objects.");let g=new FormData,f=r.schema?.properties&&typeof r.schema.properties=="object"?r.schema.properties:{};for(let[l,h]of Object.entries(u)){let w=f[l],T=r.encoding[l],m=xr(T?.contentType);if(w?.type==="string"&&w?.format==="binary"){let y=await Pt(h,m);g.append(l,new Blob([wr(y.buffer)],{type:y.mimeType}),y.fileName);continue}if(vt(h)){let y=await Pt(h,m);g.append(l,new Blob([wr(y.buffer)],{type:y.mimeType}),y.fileName);continue}h==null?g.append(l,""):typeof h=="object"?g.append(l,JSON.stringify(h)):g.append(l,String(h))}return{kind:"multipart",body:g,headers:{}}}if(r.kind==="binary"){let a=t,p=!!a&&typeof a=="object"&&!Array.isArray(a)&&"requestBody"in a?a.requestBody:t,c=await Pt(p,r.contentType);return{kind:"binary",body:c.buffer,headers:{"Content-Type":c.mimeType}}}let n=t;return{kind:"json",body:!!n&&typeof n=="object"&&!Array.isArray(n)&&"requestBody"in n?n.requestBody:t,headers:{}}}function hs(e){let t={};for(let[r,n]of Object.entries(e)){let s=n.type.trim(),i=s.endsWith("!")?s.slice(0,-1).trim():s;i.startsWith("[")&&i.endsWith("]")?t[r]=[]:i==="Boolean"?t[r]=!1:i==="Int"||i==="Float"?t[r]=0:t[r]=""}return t}async function Nt(e){let r=(await J()).apis?.[e]?.schemaType;if(r==="graphql")return"graphql";if(r==="openapi")return"openapi";try{let n=await A.readJson(j(e));if(Array.isArray(n)&&n.some(s=>typeof s?.rootType=="string"))return"graphql"}catch{}return"openapi"}async function ys(e){let t=R.join(R.dirname(q(e)),"bundled.json"),r=await A.readJson(t),n=typeof r?.source=="string"?r.source:typeof r?.sourceText=="string"?r.sourceText:void 0;if(!n)throw new Error(`GraphQL source not found for API '${e}'. Run generate first.`);return n}async function jt(e,t,r=!1){let n=await ue(e,t),s=se(e,n);if(!r&&await A.pathExists(s))return await A.readJson(s);let a=(await A.readJson(j(e))).find(u=>u.operationId===t||u.name===t);if(!a)throw new Error(`Endpoint '${t}' not found in GraphQL endpoint list.`);let o=await ys(e),p=typeof a.rootType=="string"?a.rootType:typeof a.method=="string"?a.method:void 0;if(!p||p!=="query"&&p!=="mutation"&&p!=="subscription")throw new Error(`Invalid GraphQL endpoint metadata for '${t}'.`);let c=await ge(o,p,t);return await A.ensureDir(R.dirname(s)),await A.writeJson(s,c,{spaces:2}),c}async function _t(e){return await Nt(e)}function Ct(e,t){let r=je(t),n=[];for(let[s,i]of Object.entries(r)){if(i===Ke)continue;let a=Ne(e,s);a!==void 0&&(ls(a,i)||n.push(`--update-request type mismatch at ${s}: expected ${hr(a)}, received ${hr(i)}.`))}return n}async function Lt(e,t){if(await _t(e)==="graphql"){let p=await ue(e,t),c=R.join(ae(e,p),"response-schema.json");if(await A.pathExists(c))return await A.readJson(c);let u=await jt(e,t,!1);return await A.ensureDir(R.dirname(c)),await A.writeJson(c,u,{spaces:2}),u}let r=await ue(e,t),n=q(e),s=await tr(R.resolve(n,`${r}.json`)),i=ae(e,r),a=R.join(i,"response-schema.json");if(await A.pathExists(a))return await A.readJson(a);let o=Is(s);return o!==void 0&&(await A.ensureDir(i),await A.writeJson(a,o,{spaces:2})),o}async function $t(e,t,r=!1,n,s,i){let a=await qe(e,t,await ue(e,t),r),o=await J(),p=o.apis?.[e]?.baseUrl;if(!p)throw new Error("Base URL not found in config");if(a.schemaType==="graphql"){let k=await ue(e,t),U=await jt(e,t,r),{requestJson:_,responseJsonPath:C}=await ws(e,k,r,U),le=R.join(q(e),k,"request.json"),ot=_,Ut=[];if(i&&i.length>0&&Ut.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0){let ct={...je(s)};for(let[Gt,Zr]of Object.entries(s))Gt in ct||(ct[Gt]=Zr);await Ie(le,ct,2,{deleteSentinel:Ke}),ot=await A.readJson(le)}let Kr={...hs(a.args),...kr(ot)?ot.variables:{}},pt={query:a.query,variables:Kr},D={headers:{"Content-Type":"application/json"},url:"",warnings:Ut,responseJsonPath:C},Yr=new ve(p),N;try{if(N=await Yr.post(p,{headers:D.headers,body:pt}),N&&typeof N=="object"&&"status"in N){let V=N.status;typeof V=="number"&&(V<200||V>=300)&&D.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}: HTTP ${V}${"statusText"in N&&typeof N.statusText=="string"&&N.statusText?` ${N.statusText}`:""}`)}N&&typeof N=="object"&&Array.isArray(N.errors)&&N.errors?.length&&D.warnings.push("\u26A0\uFE0F GraphQL response contains errors."),await A.writeJson(D.responseJsonPath,N,{spaces:2})}catch(V){if(D.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}: ${V instanceof Error?V.message:String(V)}`),!await A.pathExists(D.responseJsonPath))return D.warnings.push(`response.json not found at ${D.responseJsonPath}`),{request:pt,response:void 0,warnings:D.warnings}}let Xr=await A.readJson(D.responseJsonPath);return{request:pt,response:Xr?.data?.[a.fieldName],warnings:D.warnings}}let c=await ue(e,t),u=await qe(e,t,c);if(u.schemaType!=="rest")throw new Error(`Invalid REST endpoint metadata for '${t}'.`);let g=await Q(e,t,c,r),{requestJson:f,responseJsonPath:l}=await Sr(e,c,r),h=R.join(q(e),c,"request.json"),w=f,T=[];if(i&&i.length>0&&T.push(...i),s&&typeof s=="object"&&Object.keys(s).length>0){let k=ds(s);k&&T.push(k);let _={...je(s)};for(let[C,le]of Object.entries(s))C in _||(_[C]=le);await Ie(h,_,2,{deleteSentinel:Ke}),w=await A.readJson(h)}let m=Ts(e,u,w,o,l,n,T),y=new ve(p);if(!u.method||!u.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t}'.`);let O=u.method.toLowerCase(),x;try{switch(O){case"get":x=await y.get(m.url,{headers:m.headers});break;case"post":{let k=await It(g,w);x=await y.post(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"put":{let k=await It(g,w);x=await y.put(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"delete":x=await y.delete(m.url,{headers:m.headers});break;case"patch":{let k=await It(g,w);x=await y.patch(m.url,{headers:{...m.headers,...k.headers},body:k.body})}break;case"head":x=await y.head(m.url,{headers:m.headers});break;case"options":x=await y.options(m.url,{headers:m.headers});break;default:throw new Error(`Unsupported HTTP method: ${u.method}`)}if(x&&typeof x=="object"&&"status"in x){let k=x.status;typeof k=="number"&&(k<200||k>=300)&&m.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}${m.url}: HTTP ${k}${"statusText"in x&&typeof x.statusText=="string"&&x.statusText?` ${x.statusText}`:""}`)}await A.writeJson(m.responseJsonPath,x,{spaces:2})}catch(k){if(m.warnings.push(`\u26A0\uFE0F The live HTTP request failed for ${p}${m.url}: ${k instanceof Error?k.message:String(k)}`),!await A.pathExists(m.responseJsonPath))return m.warnings.push(`response.json not found at ${m.responseJsonPath}`),{request:w,response:void 0,warnings:m.warnings}}let P=await A.readJson(m.responseJsonPath);return{request:w,response:P,warnings:m.warnings}}async function Er(e,t,r=!1,n,s,i){let{request:a,response:o,warnings:p}=await $t(e,t,r,n,s,i),c=p??[];if(await _t(e)==="graphql"){if(!o||typeof o!="object")return{valid:!1,warnings:c,errors:["response.body missing or invalid"]};let h=o;return Array.isArray(h.errors)&&h.errors.length>0?{valid:!1,warnings:c,errors:["GraphQL response contains errors"]}:{valid:!0,warnings:c}}let u=await Lt(e,t);if(u===void 0||Object.keys(u).length===0)return p.push("No response schema found for this operation. Skipping validation."),{valid:!0,warnings:c};if(!o)return{valid:!1,warnings:c};let f=new cs({allErrors:!0,strict:!1,strictSchema:!1,allowUnknownKeywords:!0,removeAdditional:!1}).compile(u);return f(o)?{valid:!0,warnings:c}:{valid:!1,errors:(f.errors||[]).map(w=>`${w.instancePath?w.instancePath.replace(/^\//,"response.body.").replace(/\//g,"."):"response.body"} ${w.message}`),warnings:c}}async function _e(e,t,r=!1){if(await _t(e)==="graphql"){let a=await jt(e,t,r),o=R.join(q(e),t,"request.json"),p=R.join(ae(e,t),"response.json"),c=Re(a);return await A.ensureDir(R.dirname(o)),await A.writeJson(o,c,{spaces:2}),{requestJsonPath:o,responseJsonPath:p,requestJson:c}}let{requestJson:n,responseJsonPath:s}=await Sr(e,t,r);return{requestJsonPath:R.join(q(e),t,"request.json"),responseJsonPath:s,requestJson:n}}async function Sr(e,t,r){let n=se(e,t),s=await A.readJson(n),i=R.join(q(e),t);await A.ensureDir(i);let a=R.join(i,"request.json"),o=R.join(i,"response.json");if(await(async()=>{if(r||!await A.pathExists(a))return!0;let c=await A.readJson(a);return!bs(c)})()){let c=ks(s);return await A.writeJson(a,c,{spaces:2}),{requestJson:c,responseJsonPath:o}}return{requestJson:await A.readJson(a),responseJsonPath:o}}async function ws(e,t,r,n){let s=R.join(q(e),t);await A.ensureDir(s);let i=R.join(s,"request.json"),a=R.join(s,"response.json");if(await(async()=>{if(r||!await A.pathExists(i))return!0;let p=await A.readJson(i);return!kr(p)})()){let p=Re(n);return await A.writeJson(i,p,{spaces:2}),{requestJson:p,responseJsonPath:a}}return{requestJson:await A.readJson(i),responseJsonPath:a}}function bs(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return Object.prototype.hasOwnProperty.call(t,"parameters")&&Array.isArray(t.parameters)}function Ts(e,t,r,n,s,i,a=[]){let o={},p=n.apis?.[e]?.auth?.headers;p&&typeof p=="object"&&Object.assign(o,p),i&&typeof i=="object"&&Object.assign(o,i);let c={},u={};for(let l of r.parameters||[])l.in==="path"?c[l.name]=l.value:l.in==="query"?u[l.name]=l.value:l.in==="header"&&(o[l.name]=String(l.value));if(!t.path)throw new Error(`Invalid OpenAPI endpoint metadata for '${t.operationId}'.`);let g=xs(t.path,c),f=As(u);return{headers:o,url:g+f,warnings:a,responseJsonPath:s}}function As(e){return Object.keys(e).length?"?"+Object.entries(e).map(([t,r])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(r))}`).join("&"):""}function ks(e){let t=[];if(Array.isArray(e.parameters))for(let s of e.parameters){let i=cr(s);t.push({name:s.name,in:s.in,value:i})}let r=null;(e?.requestBody||e?.parameters)&&(r=Es(e));let n={parameters:t};return r!==null&&(n.requestBody=r),n}function xs(e,t){return e.replace(/\{([^}]+)\}/g,(r,n)=>{if(!(n in t))throw new Error(`Missing path parameter: ${n}`);return encodeURIComponent(t[n])})}function Es(e){let t=Ss(e);if(t)return ke(t);let r=Ot(e);return r?ke(r):null}function Ss(e){let t=e?.requestBody?.content;if(!t||typeof t!="object")return null;for(let r of Object.values(t)){let n=r;if(n?.schema)return n.schema}return null}function Ot(e){let t=Array.isArray(e?.parameters)?e.parameters:[],r=t.find(a=>a.in==="body");if(r?.schema){let a=r.schema;return!a.type&&a.properties&&(a.type="object"),a}let n=e?.consumes||[],s=n.includes("application/x-www-form-urlencoded")||n.includes("multipart/form-data"),i=t.filter(a=>a.in==="formData");if(s&&i.length){let a={type:"object",properties:{},required:[]};for(let o of i){let p={};o.schema?Object.assign(p,o.schema):(o.type&&(p.type=o.type),o.items&&(p.items=o.items),o.format&&(p.format=o.format),o.enum&&(p.enum=o.enum),o.type==="file"&&(p.type="string",p.format="binary")),a.properties[o.name]=p,o.required&&a.required.push(o.name)}return a.required.length===0&&delete a.required,a}return null}function ke(e){if(!e)return null;if(e.const!==void 0)return e.const;if(e.default!==void 0)return e.default;if(Array.isArray(e.allOf)&&e.allOf.length>0){let t=e.allOf.map(r=>ke(r)).filter(r=>r!=null).reduce((r,n)=>Rr(r,n),{});if(t!=null)return t}if(Array.isArray(e.oneOf)&&e.oneOf.length>0)return br(e.oneOf.map(t=>ke(t)));if(Array.isArray(e.anyOf)&&e.anyOf.length>0)return br(e.anyOf.map(t=>ke(t)));if(!e.type&&e.properties&&(e.type="object"),e.$ref)throw new Error("Schema contains $ref. Resolve references before building template.");switch(e.type){case"string":return e.format==="binary"?{kind:"file",path:"",fileName:"",mimeType:""}:e.example??"";case"integer":case"number":return e.example??0;case"boolean":return e.example??!1;case"array":return[];case"object":let t={};if(e.properties)for(let[r,n]of Object.entries(e.properties))t[r]=ke(n);return t;default:return null}}function qt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Rr(e,t){if(e==null)return t;if(t==null)return e;if(qt(e)&&qt(t)){let r={...e};for(let[n,s]of Object.entries(t))r[n]=n in r?Rr(r[n],s):s;return r}return t}function br(e){let t=e.filter(n=>n!=null);if(t.length===0)return null;let r=t.filter(qt);return r.length>0?r.reduce((n,s)=>{let i=Object.keys(n).length;return Object.keys(s).length>i?s:n}):t[0]}function Rs(e){let t=e?.responses;if(!t)return null;let r=t[200]||t[201]||t.default||Object.values(t)[0];if(!r?.content)return null;let n=r.content["application/json"];if(n?.schema)return n.schema;for(let s of Object.values(r.content)){let i=s;if(i.schema)return i.schema}return null}function Ps(e){let t=e?.responses;return t?(t[200]||t[201]||t.default||Object.values(t)[0])?.schema||{}:{}}function Is(e){let t=Rs(e);if(t)return t;let r=Ps(e);if(r)return r}var Dt=E(()=>{"use strict";dr();W();Et();ht();ce();nt();kt();Rt();Pe();W();Te()});import*as ee from"node:fs/promises";import $ from"path";import Os from"readline";import{fileURLToPath as qs}from"url";function xe(e){return e?"Yes":"No"}function Ns(e){return Array.isArray(e)?e.join(`
9
+ `):e}function js(e){let t=e.arguments.length>0?e.arguments.map(s=>{let i=[s.type,s.required?"required":"optional"];s.positional&&i.push("positional"),s.flag&&i.push("flag");let a=s.description?`: ${s.description}`:"",o=s.flag?"--":"";return`- \`${s.positional?s.name:`${o}${s.name}`}\` (${i.join(", ")})${a}`}).join(`
10
+ `):"- None",r=e.examples.length>0?e.examples.map(s=>`- \`\`\`bash
11
+ ${s}
12
+ \`\`\``).join(`
13
+ `):"- None",n=e.filesWritten.length>0?e.filesWritten.map(s=>`\`${s}\``).join(", "):"None";return[`### ${e.name}`,"",`**Category:** ${e.category}`,"","**Usage:**","```bash",e.usage,"```","",`**Description:** ${Ns(e.description)}`,"","**Arguments:**",t,"","**Examples:**",r,"",`**Returns:** ${e.returns.type} - ${e.returns.description}`,"",`**Side Effects:** Writes Files: ${xe(e.sideEffects.writesFiles)}, Reads Files: ${xe(e.sideEffects.readsFiles)}, Network: ${xe(e.sideEffects.network)}`,"",`**Constraints:** Destructive: ${xe(e.constraints.destructive)}, Idempotent: ${xe(e.constraints.idempotent)}, Requires Parsed API: ${xe(e.constraints.requiresParsedApi)}`,"",`**Files Written:** ${n}`].join(`
14
+ `)}async function _s(){let{program:e}=await Nr().then(()=>vr);return e.commands.filter(n=>!!n.agentMeta).filter(n=>n.agentMeta.name!=="help"&&n.agentMeta.name!=="install").map(n=>js(n.agentMeta)).join(`
15
+
16
+ `)}async function Ir(e,t){let r=[{label:"~/.claude/skills/openapi-skills",value:$.join(e,".claude","skills","openapi-skills")},{label:"~/.cursor/skills/openapi-skills",value:$.join(e,".cursor","skills","openapi-skills")},{label:"~/.agents/skills/openapi-skills",value:$.join(e,".agents","skills","openapi-skills")},{label:"~/.github/skills/openapi-skills",value:$.join(e,".github","skills","openapi-skills")},{label:"Other (enter a custom path)",value:"__custom__"}];function n(i){let a=Os.createInterface({input:process.stdin,output:process.stderr});return new Promise(o=>a.question(i,p=>{a.close(),o(p)}))}d.info("Select install location:"),r.forEach((i,a)=>{d.info(` ${a+1}) ${i.label}`)});let s;for(;;){s=await n(`Enter number (1-${r.length}): `);let i=parseInt(s,10)-1;if(!isNaN(i)&&i>=0&&i<r.length&&r[i])return r[i].value==="__custom__"?(await n(`Enter custom install path [${t}]: `)).trim()||t:r[i].value;d.warn(`Invalid selection. Please enter a number between 1 and ${r.length}.`)}}async function Pr(e,t,r){let n=$.join(vs,"../skill-templates",e);try{let s=await ee.readFile(n,"utf8"),i=r?await r(s):s;await ee.mkdir($.dirname(t),{recursive:!0}),await ee.writeFile(t,i,"utf8")}catch(s){let i=s instanceof Error?s.message:String(s);throw new Error(`Failed to copy skill template "${e}" from "${n}" to "${t}": ${i}`,{cause:s instanceof Error?s:void 0})}}async function Or(e,t){await ee.mkdir(t,{recursive:!0});let r=$.join(t,"references");await ee.mkdir(r,{recursive:!0});let n=[{templateName:"SKILL.md",outputPath:$.join(t,"SKILL.md")},{templateName:"write-client-code.md",outputPath:$.join(r,"write-client-code.md")},{templateName:"create-endpoint-test.md",outputPath:$.join(r,"create-endpoint-test.md")},{templateName:"http-client.md",outputPath:$.join(r,"http-client.md")}];for(let s of n){if(s.templateName==="SKILL.md"){await Pr(s.templateName,s.outputPath,async i=>{let a=await _s();if(!i.includes("<command-list-here>"))throw new Error("SKILL.md template is missing <command-list-here>.");return i.replace("<command-list-here>",a)});continue}await Pr(s.templateName,s.outputPath)}return{destDir:t,files:n.map(s=>s.outputPath)}}var vs,qr=E(()=>{"use strict";ye();vs=$.dirname(qs(import.meta.url))});import jr from"fs-extra";import Cs from"https";import Ls from"os";import $s from"path";async function _r(e){try{let t=new Date().toISOString().slice(0,10),r=$s.join(Ls.tmpdir(),`openapi-skills-session-${t}`);if(jr.existsSync(r))return;jr.writeFileSync(r,String(Date.now()));let n=await new Promise((s,i)=>{Cs.get("https://registry.npmjs.org/@tzurp/openapi-skills/latest",a=>{let o="";a.on("data",p=>o+=p),a.on("end",()=>{try{let p=JSON.parse(o);s(p.version)}catch(p){i(p)}})}).on("error",i)});n&&n!==e&&(d.warn(`UPDATE_AVAILABLE: A newer version of openapi-skills is available \u2192 ${n} (current: ${e})`),d.warn("Update with: npm install -g @tzurp/openapi-skills")),d.banner(`\u{1F48E} openapi-skills v2 is available \u2014 including mock APIs, HTML docs, schema diffing, code\u2011first tools, full OpenAPI 3.1 support, premium support, and additional Pro tools.
17
+ https://openapi-skills.lemonsqueezy.com/`)}catch{}}var Cr=E(()=>{"use strict";ye()});function Ce(e){let t=JSON.stringify(e)??"",r=Buffer.byteLength(t,"utf8");return{text:t,sizeBytes:r}}var Lr=E(()=>{"use strict"});import Ds from"readline";async function $r(e){let t=`Are you sure you want to delete ${e}? Y/n `;return await new Promise(r=>{let n=Ds.createInterface({input:process.stdin,output:process.stderr});n.question(t,s=>{n.close();let i=s.trim().toLowerCase();r(i==="y"||i==="yes")})})}var Dr=E(()=>{"use strict"});function Le(e,t="",r=new Set){if(t&&r.add(t),!e||typeof e!="object")return r;if(Array.isArray(e)){for(let n=0;n<e.length;n++){let s=t?`${t}.${n}`:`${n}`;Le(e[n],s,r)}return r}for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;Le(s,i,r)}return r}function st(e,t="",r=new Set){if(!e||typeof e!="object")return r;if(Array.isArray(e))return t&&r.add(t),r;for(let[n,s]of Object.entries(e)){let i=t?`${t}.${n}`:n;s&&typeof s=="object"&&!Array.isArray(s)?st(s,i,r):r.add(i)}return r}function Fr(e){let t=[];return e.request&&t.push("request"),e.response&&t.push("response"),e.responseSchema&&t.push("response-schema"),t.length!==1?{artifactName:void 0,error:t.length===0?"Exactly one of --request, --response, or --response-schema is required.":"Only one of --request, --response, or --response-schema can be used at a time."}:{artifactName:t[0],error:void 0}}var Jr=E(()=>{"use strict"});import Ur from"fs-extra";function it(e,t){let r=ae(e,t);return{fileCount:Ur.existsSync(r)?Ur.readdirSync(r).length:0}}async function Fs(e,t){let r=new Set,n=new Set;for(let a of t)r.has(a)&&n.add(a),r.add(a);if(n.size>0)throw new Error(`Duplicate operationId(s) are not allowed in prepare-only mode: ${Array.from(n).join(", ")}`);let s=await pe();if(!Array.isArray(s)||!s.includes(e))throw new Error(`API '${e}' is not installed. Run generate first.`);let i=[];for(let a of t){let o=await Y(e,a);if(!o)throw new Error(`OperationId '${a}' was not found for API '${e}'.`);i.push({operationId:a,sanitizedOperationId:o})}return i}async function Gr(e,t,r=!1){let n=await Fs(e,t),s=[];for(let{operationId:o,sanitizedOperationId:p}of n){await Q(e,o,p),await _e(e,p,r);let c=it(e,p);s.push({kind:"request-result",apiName:e,operationId:o,sanitizedOperationId:p,preparedOnly:!0,request:null,response:null,warnings:[],...c})}let i=[`Prepared request templates for ${s.length} operations:`,"",...s.map(o=>` \u2713 ${o.operationId}`),"","No live requests were executed.","Use `openapi-skills request <operationId> --force --update-request ...` with only flattened object dot-notation keys to run each step."],a={kind:"request-result",apiName:e,preparedOnly:!0,operationIds:t,summary:i,message:"No live requests were executed.",hint:"Use `openapi-skills request <operationId> --force --update-request ...` with only flattened object dot-notation keys to run each step.",operations:s};return{operations:s,summaryText:i.join(`
18
+ `),payload:a}}var Br=E(()=>{"use strict";Te();ce();nt();W();Dt()});function Qr(e){let t=e.trim();if(t==="count")return{kind:"count"};if(/^-?\d+$/.test(t))return{kind:"index",index:Number(t)};let r=t.match(/^(-?\d*):(-?\d*)$/);if(r)return{kind:"range",start:r[1]===""?0:Number(r[1]),end:r[2]===""?Number.POSITIVE_INFINITY:Number(r[2])};let n=t.indexOf("=");if(n>0){let s=t.slice(0,n).trim();if(s)return{kind:"path",path:s,value:t.slice(n+1)}}return{kind:"invalid"}}var Mr=E(()=>{"use strict"});function Js(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function at(e,t){if(typeof e!="string"||e.trim().length===0)throw new Error(`${t} must be a non-empty base64url string.`);let r;try{r=Buffer.from(e,"base64url").toString("utf8")}catch{throw new Error(`${t} must be valid base64url-encoded JSON.`)}let n;try{n=JSON.parse(r)}catch(s){let i=s instanceof Error?s.message:String(s);throw new Error(`${t} decoded value must be valid JSON: ${i}`)}if(!Js(n))throw new Error(`${t} decoded value must be a JSON object.`);return n}var Vr=E(()=>{"use strict"});var zr,Hr,Ft=E(()=>{"use strict";zr={UNKNOWN_API:{reason:"The API name is not registered in .openapi-skills/config.json.",nextCommandHint:"Run 'openapi-skills get-api-names' to list available APIs, then use the correct name."},MISSING_PARSED_API:{reason:"No APIs have been parsed yet. The workspace is empty.",nextCommandHint:"Run 'openapi-skills generate' with an OpenAPI or GraphQL source."},NO_ENDPOINTS_FOUND:{reason:"The API endpoint file does not exist. Run generate first.",nextCommandHint:"Run 'openapi-skills generate' to create endpoints.json."},NO_RESPONSE_SCHEMA:{reason:"The response schema artifact has not been created yet.",nextCommandHint:"Run 'openapi-skills request <operationId> --api <apiName>' to create the response-schema artifact."},REQUEST_TEMPLATE_STALE:{reason:"The request template does not exist for this operation.",nextCommandHint:"Run the command again with --force to regenerate the request template."},SCHEMA_VALIDATION_FAILED:{reason:"The provided OpenAPI or GraphQL schema is malformed.",nextCommandHint:"Fix the schema at its source and retry."},INVALID_FILTER_SYNTAX:{reason:"--filter requires the target to be an array.",nextCommandHint:"Use --response-schema first to inspect the response shape, then use --get to narrow the value before filtering."},MISSING_FILTER_ARGUMENT:{reason:"The list command requires at least one filter to avoid returning large, unbounded result sets.",nextCommandHint:"Add --path, --filter, --method, --root-type, or --index to narrow results."},SCHEMA_TYPE_MISMATCH:{reason:"The flag used is incompatible with this schema type.",nextCommandHint:"Use --path and --method for OpenAPI; use --root-type for GraphQL."},INVALID_JSON_ARGUMENT:{reason:"The provided JSON argument is malformed.",nextCommandHint:"Fix the JSON syntax and retry."},INVALID_VARIABLE_SYNTAX:{reason:"Variable syntax is invalid. Expected key=value format.",nextCommandHint:"Use --var key=value format."},INVALID_UPDATE_REQUEST_JSON:{reason:"The --update-request JSON could not be parsed.",nextCommandHint:"Fix the JSON syntax and retry."},INVALID_REQUEST_UPDATE:{reason:"The request keys specified do not exist in request.json.",nextCommandHint:"Use valid request.json keys. Inspect with 'openapi-skills get-operation <operationId> --api <apiName> --request' first."},OVERSIZED_OUTPUT:{reason:"The output is too large to display.",nextCommandHint:"Use --get or --filter to reduce output size."},API_PARSE_ERROR:{reason:"An error occurred while parsing the API schema.",nextCommandHint:"Review the error details and fix the schema at its source."},REQUEST_FAILED:{reason:"The HTTP request failed.",nextCommandHint:"Check the base URL, authentication headers, and network connectivity."},VALIDATION_FAILED:{reason:"The response does not match the expected schema.",nextCommandHint:"Verify that the API response matches the declared schema."},CONFIG_ERROR:{reason:"Failed to read or write configuration file.",nextCommandHint:"Check file permissions on .openapi-skills/config.json."}},Hr={UNKNOWN_API:"usage",MISSING_FILTER_ARGUMENT:"usage",INVALID_FILTER_SYNTAX:"usage",SCHEMA_TYPE_MISMATCH:"usage",INVALID_VARIABLE_SYNTAX:"usage",INVALID_JSON_ARGUMENT:"usage",SCHEMA_VALIDATION_FAILED:"validation",INVALID_REQUEST_UPDATE:"validation",INVALID_UPDATE_REQUEST_JSON:"validation",MISSING_PARSED_API:"state",NO_ENDPOINTS_FOUND:"state",NO_RESPONSE_SCHEMA:"state",REQUEST_TEMPLATE_STALE:"state",OVERSIZED_OUTPUT:"state",API_PARSE_ERROR:"runtime",REQUEST_FAILED:"runtime",VALIDATION_FAILED:"runtime",CONFIG_ERROR:"runtime"}});function b(e,t){let r=Hr[e],n=zr[e],s=t.nextCommand??"None",i=t.reason??n?.reason??"Unable to remediate automatically.",a=t.severity??"error";return{ok:!1,error:{code:e,category:r,severity:a,summary:t.summary,message:t.message,remediation:{required:!0,next_command:s,reason:i},context:t.context??{}}}}function I(e,t){let r={ok:!0,data:e};return t?.kind!==void 0&&(r.kind=t.kind),r}var Wr=E(()=>{"use strict";Ft()});var vr={};tn(vr,{program:()=>v});import{Command as Us}from"commander";import M from"fs-extra";import Gs from"path";import Bs from"os";import{createRequire as Qs}from"module";async function de(e){return(await pe().catch(()=>[])).includes(e)?!0:(d.result(b("UNKNOWN_API",{summary:`API '${e}' is not installed.`,message:`No API named '${e}' was found. Run 'openapi-skills get-api-names' to list installed APIs, or run 'openapi-skills generate <openapi-source>' first.`,context:{api_name:e},nextCommand:"openapi-skills get-api-names"})),process.exitCode=1,!1)}var Ms,Jt,Vs,Eo,v,zs,Hs,Ws,Ks,Ys,Xs,Zs,ei,ti,ri,ni,si,ii,ai,oi,Nr=E(async()=>{Te();W();ce();Et();Dt();qr();Te();ye();St();nt();Cr();Lr();Dr();Jr();Br();Rt();Mr();Vr();Wr();Ft();Pe();Ms=Qs(import.meta.url),Jt=Ms("../package.json"),Vs=Jt.repository.url;await _r(Jt.version);Eo=Xe(),v=new Us,zs=process.argv.includes("--silent");v.name("openapi-skills").description("A command\u2011line tool for working with OpenAPI/Swagger and GraphQL specs. Use it to parse specs into artifacts, explore API endpoints and root fields, validate requests, generate typed client metadata, and teach AI agents how to operate the CLI and write API tests and client code.").version(Jt.version);Hs=`
19
+ \x1B[32m
20
+ \u2584\u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584\u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584 \u2584\u2584\u2584\u2584
21
+ \u2588\u2588\u2580\u2588\u2588 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588\u2584\u2584 \u2588\u2588\u2588\u2584\u2588\u2588 \u2588\u2588\u2580\u2588\u2588 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588 \u2584\u2584\u2584 \u2588\u2588\u2588\u2584\u2584 \u2588\u2588\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2584\u2584
22
+ \u2580\u2588\u2588\u2588\u2580 \u2588\u2588 \u2588\u2588\u2584\u2584\u2584 \u2588\u2588 \u2580\u2588\u2588 \u2588\u2588\u2580\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2584\u2584\u2588\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2584\u2584\u2584 \u2588\u2588\u2584\u2584\u2584 \u2584\u2584\u2588\u2588\u2580
23
+ \x1B[0m
24
+ `;v.option("--silent","Suppress the banner in help output for agent-friendly usage.");zs||v.addHelpText("before",Hs);v.addHelpText("before",`
25
+ ===================
26
+ openapi-skills CLI
27
+ ===================
28
+ `);Ws=2026,Ks=new Date().getFullYear(),Ys=`${Ws}-${Ks}`;v.addHelpText("after",`
29
+ -------------------------------------------------------------------------------
30
+ Copyright \xA9 ${Ys} Tzur Paldi \u2014 Powered by Bedekbyte\xAE All rights reserved
31
+ Support: tzur.paldi@outlook.com
32
+ Project: ${Vs}
33
+ -------------------------------------------------------------------------------
34
+ `);v.command("install").description("Install SKILL.md and scenario markdowns for agent frameworks like Claude and GitHub Copilot. Supports: --skills [--global].").option("--skills","Install SKILL.md files for agent frameworks.").option("--global","Install the skill bundle under the user's home directory instead of the current project.").action(async e=>{if(e.global&&!e.skills){d.result(b("CONFIG_ERROR",{summary:"--global requires --skills.",message:"Use `openapi-skills install --skills --global` to install the skill bundle under your home directory.",context:{},nextCommand:"openapi-skills install --skills --global"})),process.exitCode=1;return}if(!e.skills){await wt(),d.info(".openapi-skills directory and configuration installed. Use --skills to install SKILL.md files for agent frameworks.");return}let t=e.global?Bs.homedir():Ze(),r=Ze(),n=Gs.join(t,"installed-skills");d.info(`Source directory (copied): ${r}`);let s=await Ir(t,n);d.info(`Target install directory: ${s}`);try{let i=await Or(r,s);d.info("openapi-skills skill bundle installed")}catch(i){d.result(b("CONFIG_ERROR",{summary:"Failed to install skill bundle.",message:i instanceof Error?i.message:String(i),context:{install_path:s},nextCommand:"openapi-skills install --skills"})),process.exitCode=1}});Xs=v.command("generate [openapi-source]").description("Parse an OpenAPI or GraphQL source (file path or URL) and generate endpoints.json, schemas/, and config.json. Run this command first for a new spec. Supports: --validate, --base-url, --dereference, --no-progress.").option("--validate <schema>","Validate an OpenAPI or GraphQL schema (file path or URL) and exit").option("--base-url <url>","Base URL for the API").option("--dereference","Fully dereference the entire OpenAPI document before processing endpoints").option("--no-progress","Disable the progress indicator").option("--rename <newName>","Optional new name for the generated schema.").action(async(e,t)=>{try{if(typeof t.validate=="string"&&t.validate.length>0){try{await pr(t.validate),d.result(I({valid:!0,schemaSource:t.validate,message:"Schema is valid"},{kind:"schema-validation"})),process.exitCode=0}catch(a){d.result(b("SCHEMA_VALIDATION_FAILED",{summary:"OpenAPI or GraphQL schema is invalid.",message:`Schema validation failed: ${H(a)}`,context:{schema_source:t.validate},nextCommand:`openapi-skills generate ${t.validate}`})),process.exitCode=1}return}if(!e)throw new Error("An OpenAPI source is required unless --validate is used.");let r=typeof t.baseUrl=="string"?t.baseUrl.trim():"",n=r.length>0,i=await or(e,n?r:"",{dereference:t.dereference===!0,progress:t.progress!==!1,rename:t.rename});if(!n){let a=[`You haven't included --base-url for API "${i}".`,`If you need to make requests and validations, add baseUrl directly to .openapi-skills/config.json under apis.${i}.baseUrl.`,"Example:",`{
35
+ "apis": {
36
+ "${i}": {
37
+ "baseUrl": "https://petstore3.swagger.io/api/v3",
38
+ "openapi-sorce": "https://petstore3.swagger.io/api/v3/openapi.json"
39
+ }
40
+ }
41
+ }`].join(`
42
+ `);d.warn(a),d.result(I({apiName:i,openapiSource:e,warning:a},{kind:"generate-warning"}))}d.result(I({apiName:i,openapiSource:e,fileCount:3},{kind:"generate-result"})),process.exitCode=0}catch(r){if(Yt(r)){d.result(b("API_PARSE_ERROR",{summary:"TypeScript is required to analyze builder GraphQL schemas.",message:`TypeScript is not available in this environment. Install it with \`${gt}\` and rerun the command.`,context:{openapi_source:e},nextCommand:gt,reason:"GraphQL builder parsing requires TypeScript to be installed in the current workspace."})),process.exitCode=1;return}d.result(b(t.validate?"SCHEMA_VALIDATION_FAILED":"API_PARSE_ERROR",{summary:t.validate?"OpenAPI or GraphQL schema is invalid.":"Failed to parse the provided schema.",message:H(r),context:{openapi_source:e},nextCommand:t.validate?`openapi-skills generate ${t.validate}`:`openapi-skills generate ${e??"<openapi-source>"}`})),process.exitCode=1}});Xs.agentMeta={name:"generate",category:"Generation",usage:"openapi-skills generate [openapi-source] [--validate <schema>] [--base-url <url>] [--dereference] [--no-progress] [--rename <newName>]",description:"Parse a source file or URL and generate the API artifacts used by the rest of the CLI. Use --validate to check a schema and exit, --base-url to set the API base URL, --dereference when full dereferencing is appropriate, --rename to override the generated API name, and --no-progress to suppress progress output.",arguments:[{name:"openapi-source",type:"path|url",required:!1,positional:!0,description:"OpenAPI source file path or URL."},{name:"validate",type:"path|url",required:!1,flag:!0,description:"Validate an OpenAPI schema and exit."},{name:"base-url",type:"string",required:!1,flag:!0,description:"Base URL for the generated API."},{name:"dereference",type:"boolean",required:!1,flag:!0,description:"Fully dereference the OpenAPI document before processing endpoints."},{name:"no-progress",type:"boolean",required:!1,flag:!0,description:"Disable the progress indicator."},{name:"rename",type:"string",required:!1,flag:!0,description:"Optional new name for the generated schema."}],examples:["openapi-skills generate ./petstore.yaml --base-url https://api.example.com","openapi-skills generate https://example.com/openapi.yaml","openapi-skills generate ./petstore.yaml --validate ./petstore.yaml","openapi-skills generate ./petstore.yaml --dereference","openapi-skills generate ./petstore.yaml --rename petstore-v2","openapi-skills generate ./petstore.yaml --no-progress"],returns:{type:"json",description:"Prints output directory and config.json path."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!0},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!1},filesWritten:["endpoints.json","schemas/","config.json"]};Zs=v.command("list").description("List summarized operation objects for the specified API as JSON. Supports --filter, --tag, --resolved/--dereferenced, --index slicing, and --count for operation totals. Also supports OpenAPI\u2011only options (--path, --method) and the GraphQL\u2011only option (--root-type). At least one filter is required unless --index : is used intentionally. GraphQL APIs reject --method, --path, and --tag, and OpenAPI APIs reject --root-type.").requiredOption("--api <apiName>","API name to use").option("--count","Return the number of operations after applying any list filters and index slicing. With no filters, returns the total operation count.").option("--resolved, --dereferenced","Show only operations that already have generated schema details saved.").option("--path <path>",["Filter operations by path structure. Repeatable; multiple values are ANDed.","Supports:"," - Path prefix: /users (matches operations whose path begins with /users)"," - Parameter detection: :param (matches operations with any {param} in the path)"," - Segment matching: 'store order' (matches operations whose path contains BOTH 'store' AND 'order' as segments, in any order)"," - OR within a clause: 'store|shop' (matches operations whose path contains EITHER 'store' OR 'shop')"," - Combined AND+OR: 'store order|shop item' (matches endpoints with both 'store' and 'order', OR both 'shop' and 'item')"," - Multiple --path flags are ANDed: --path /store --path order (matches endpoints starting with /store AND containing 'order')","","Examples:"," --path /users"," --path :param"," --path 'store order'"," --path 'store|shop'"," --path /store --path order"].join(`
43
+ `),(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).option("--filter <filterPattern>","Filter operations by any of their searchable properties. Supports AND/OR (use spaces for AND, | for OR), e.g. --filter 'create account|register user'.").option("--tag <tag>","Filter OpenAPI operations by an exact tag, case-insensitive.").option("--method <method>","Filter operations by HTTP method (GET, POST, etc). Use this for OpenAPI operations.").option("--root-type <rootType>","Filter GraphQL root fields by root type (query, mutation, or subscription).").option("--index <range>","Slice the filtered results with inclusive Python-like range syntax, e.g. 0:10, 5:, :10, -1, or :").action(async e=>{let t=e.api;if(await de(t))try{let r=j(t),n=await Nt(t),s=e.resolved===!0||e.dereferenced===!0,i=!!(e.path||e.filter||e.tag||e.method||e.rootType||e.index||s),a={};if((typeof e.path=="string"||Array.isArray(e.path))&&(a.path=e.path),typeof e.filter=="string"&&(a.filter=e.filter),typeof e.tag=="string"&&(a.tag=e.tag),typeof e.method=="string"&&(a.method=e.method),typeof e.rootType=="string"&&(a.rootType=e.rootType),n==="graphql"&&(typeof e.method=="string"||typeof e.path=="string"||typeof e.tag=="string")){d.result(b("SCHEMA_TYPE_MISMATCH",{summary:"--method, --path, and --tag are only valid for OpenAPI APIs.",message:"This API is GraphQL. Use --root-type with --filter instead.",context:{api_name:t,schema_type:n},nextCommand:`openapi-skills list --api ${t} --root-type query`})),process.exitCode=2;return}if(n==="openapi"&&typeof e.rootType=="string"){d.result(b("SCHEMA_TYPE_MISMATCH",{summary:"--root-type is only valid for GraphQL APIs.",message:"This API is OpenAPI. Use --method and --path or --filter instead.",context:{api_name:t,schema_type:n},nextCommand:`openapi-skills list --api ${t} --method GET`})),process.exitCode=2;return}if(!e.count&&!i){d.result(b("MISSING_FILTER_ARGUMENT",{summary:"No filter provided. Use --path, --filter, --tag, --method, --root-type, or --index.",message:"The list command requires at least one filter to avoid returning large, unbounded result sets.",context:{api_name:t},nextCommand:`openapi-skills list --api ${t} --index :`,severity:"warning"})),process.exitCode=0;return}if(M.existsSync(r)===!1){if(e.count){d.result(I({count:0,message:`No endpoints.json found for API "${t}".`},{kind:"endpoint-count"}));return}d.result(b("NO_ENDPOINTS_FOUND",{summary:`No endpoints.json found for API "${t}".`,message:"The API has not been parsed yet. Run 'openapi-skills generate' to create it.",context:{api_name:t},nextCommand:`openapi-skills generate <openapi-source> --rename ${t}`,reason:"The API artifacts have not been generated."})),d.warn(`No endpoints found for "${t}". This API name may be misspelled or not generated yet. (openapi-skills generate <openapi-source> [options])`);return}let o=await M.readJson(r),p=rt(o,a);s&&(p=await mr(t,p)),p=fr(p,e.index);let c=p.map(({tags:u,...g})=>g);if(e.count){d.result(I({count:p.length,apiName:t},{kind:"endpoint-count"}));return}if(p.length===0){if(d.result(I({apiName:t,items:[]},{kind:"endpoint-list"})),e.path||e.filter||e.tag||e.method||e.rootType||e.index||s){let u=Array.isArray(e.path)?e.path.join(", "):e.path,g=u?`path "${u}"`:"",f=e.filter?`filter "${e.filter}"`:"",l=e.tag?`tag "${e.tag}"`:"",h=e.method?`method "${e.method}"`:"",w=e.rootType?`rootType "${e.rootType}"`:"",T=s?"resolve":"",m=e.index?`index "${e.index}"`:"",y=[g,f,l,h,w,T,m].filter(Boolean).join(", ");d.warn(`No endpoints matched the ${y}.`)}return}d.result(I({apiName:t,items:c},{kind:"endpoint-list"}))}catch(r){d.result(b("API_PARSE_ERROR",{summary:"Error listing endpoints.",message:H(r),context:{api_name:t}})),process.exitCode=1}});Zs.agentMeta={name:"list",category:"Navigation",usage:"openapi-skills list --api <apiName> [--count] [--resolved|--dereferenced] [--path <path>]... [--filter <pattern>] [--tag <tag>] [--method <method>] [--root-type <rootType>] [--index <range>]",description:["List operation summaries for a parsed API as JSON.","At least one filter is required. --index is treated as a filter input, so the command can run when only a slice is requested.","Use --count to return the number of operations after filtering and slicing, or --resolved to show only operations that already have generated schema details saved.","Filter usage differs by schema type: use --method, --path, and --tag for OpenAPI operations, use --root-type for GraphQL root fields, and use --filter and --index with either schema. Filtering is case-insensitive and supports:","- Path prefix: --path '/users' (matches operations whose path begins with the prefix)","- Parameter detection: --path :param (matches operations that contain at least one '{...}' path placeholder)","- Segment matching: --path 'store order' (matches endpoints whose path contains both segments)","- OR within a single path clause: --path 'store|shop' (matches either segment)","- Multiple path flags are ANDed: --path /store --path order","- Exact tag matching: --tag pet (matches OpenAPI operations whose tag is exactly 'pet', ignoring case)","- Simple substring filtering: --filter 'user account' (matches operations containing both 'user' and 'account' in any field, including GraphQL name/rootType fields)","- OR filtering: --filter 'create|register|signup' (matches any operation containing any of the words)","- Combined AND+OR: --filter 'create account|register user' (matches operations containing both 'create' and 'account', OR both 'register' and 'user')","- Path substring search: --filter '/users' (matches operations whose path contains the substring)","- OperationId: --filter 'getUser' (matches operationId field)","- Summary/description: --filter 'delete permanently'","- Method filtering: --method GET (OpenAPI only; can be combined with --path and/or --filter)","- GraphQL root type filtering: --root-type query (query, mutation, or subscription)","- Index slicing: --index 0:10, --index 5:, --index :10, --index -1, --index :"," Slices the filtered results using inclusive Python-like range syntax:"," N = only the Nth item (0-based, negative counts from end)"," start:end = all items from start to end, inclusive"," start: = from start to last"," :end = from first to end"," : = all items"," Negative indices count from the end (e.g., -1 is the last item, -2 is second-to-last)."," Examples:"," --index 0:2 (first three items)"," --index 5: (from 6th to last)"," --index :3 (first four items)"," --index -1 (last item)"," --index : (all items)"," --count (return the filtered/sliced endpoint count, or the total count when no filters are used)",`
44
+ `,"Use --path for path-aware matching. Use --filter for substring matching across path, operationId/name, rootType, summary, or description.","If no operations match, outputs [] and prints a message to stderr."].join(`
45
+ `),arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"API name to use."},{name:"count",type:"flag",required:!1,flag:!0,description:"Return the number of operations after filtering and slicing."},{name:"resolved",type:"flag",required:!1,flag:!0,description:"Show only operations that already have generated schema details saved. Alias: --dereferenced."},{name:"path",type:"string[]",required:!1,flag:!0,description:"Filter operations by path structure."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter operations by keywords, operationId/name, rootType, path, summary, or description."},{name:"tag",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by an exact tag, case-insensitive."},{name:"method",type:"string",required:!1,flag:!0,description:"Filter OpenAPI operations by HTTP method."},{name:"rootType",type:"string",required:!1,flag:!0,description:"Filter GraphQL operations by root type (query, mutation, or subscription)."},{name:"index",type:"string",required:!1,flag:!0,description:"Slice the filtered results with inclusive Python-like range syntax."}],examples:["openapi-skills list --api petstore","openapi-skills list --api petstore --count","openapi-skills list --api petstore --resolved","openapi-skills list --api petstore --tag pet","openapi-skills list --api petstore --path /users","openapi-skills list --api petstore --path /store --path order","openapi-skills list --api petstore --path 'store order'","openapi-skills list --api petstore --path :param","openapi-skills list --api petstore --filter addpet","openapi-skills list --api petstore --filter 'create|register' --method POST","openapi-skills list --api countries --root-type query","openapi-skills list --api petstore --resolved --count","openapi-skills list --api petstore --filter '/users'","openapi-skills list --api petstore --index 0:10"],returns:{type:"json",description:"Returns filtered operation summaries as JSON, or a count object when --count is used. When no filters are provided, returns a structured warning object."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ei=v.command("generate-client-schema <operationId>").requiredOption("--api <apiName>","API name to use").option("--force","Overwrite the cached <operationId> artifact file before generating metadata.").description("Return structured metadata for client code generation for a specific operation. Use --force to overwrite the cached <operationId> artifact file before reading it.").action(async(e,t)=>{let r=t.api;if(await de(r))try{let n=await Y(r,e),s=await qe(r,e,n,t.force===!0);d.result(I(s,{kind:"client-schema"}))}catch(n){let s=n instanceof Error?n.message:String(n);d.result(b("API_PARSE_ERROR",{summary:"Error generating client code metadata.",message:s,context:{api_name:r,operation_id:e}})),process.exitCode=1}});ei.agentMeta={name:"generate-client-schema",category:"Code Generation",usage:"openapi-skills generate-client-schema <operationId> --api <apiName> [--force]",description:"Print structured metadata optimized for client code generation as pretty-printed JSON. Returns `response: null` for operations with no JSON response body, in which case the generated client should return `Promise<void>`. The cached artifact is reused unless --force is provided.",arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId of the operation to inspect."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"force",type:"flag",required:!1,flag:!0,description:"Overwrite the cached artifact file before generating metadata."}],examples:["openapi-skills generate-client-schema addPet --api petstore","openapi-skills generate-client-schema addPet --api petstore --force"],returns:{type:"json",description:"Returns metadata as pretty-printed JSON."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ti=v.command("describe <operationId>").requiredOption("--api <apiName>","API name to use").option("--force","Overwrite the cached <operationId> artifact file before printing the raw schema.").description("describe \u2192 fallback for generate-client-schema. Use generate-client-schema first. Prints the complete raw schema for a specific operation as JSON, including all parameters, request body, and all response codes. The cached <operationId> artifact file is reused unless --force is provided, which overwrites the cached schema from the bundled API document before output.").action(async(e,t)=>{let r=t.api;if(await de(r))try{let n=await Y(r,e),s=await Q(r,e,n,t.force===!0);d.result(I({operationId:e,warnings:["describe \u2192 fallback for generate-client-schema. Use openapi-skills generate-client-schema first for client code generation."],schema:s},{kind:"describe-result"}));return}catch(n){let s=n instanceof Error?n.message:String(n);d.result(b("API_PARSE_ERROR",{summary:"Error describing operation.",message:s,context:{api_name:r,operation_id:e}})),process.exitCode=1;return}});ti.agentMeta={name:"describe",category:"Navigation",usage:"openapi-skills describe <operationId> --api <apiName> [--force]",description:["Fallback for generate-client-schema. Prints the complete raw schema for a specific operation as JSON, including all parameters, request body, and response codes. The cached artifact is reused unless --force is provided.","","**Agents MUST use `generate-client-schema` for client code generation. Use `describe` only when you need full raw schema detail beyond what `generate-client-schema` provides.**"].join(`
46
+ `),arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId of the endpoint to describe."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"force",type:"flag",required:!1,flag:!0,description:"Overwrite the cached schema file before printing the raw schema."}],examples:["openapi-skills describe getPetById --api petstore","openapi-skills describe deletePet --api petstore","openapi-skills describe getPetById --api petstore --force"],returns:{type:"json",description:"Structured JSON with a fallback warning and the raw OpenAPI schema nested under `schema`."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ri=v.command("get-operation <operationId>").alias("get-operation-artifact").requiredOption("--api <apiName>","API name to use").option("--request","Return request artifact for the operation.").option("--response","Return response artifact for the operation.").option("--response-schema","Return response-schema artifact for the operation. Inspect this first when the response shape is unknown.").option("--get <path>","Select a nested value by dot-notation path first. Inspect --response-schema first so the path matches the actual response shape.").option("--filter <expr>","Filter the selected value using count, index, range, or <path>=<value> syntax (e.g. count, 0, 0:10, status=sold). Select path first with --get, then filter or slice the selected value.").description("Return one stored operation artifact as JSON. Run `request` first for the same operationId so the artifact exists. Exactly one of --request, --response, or --response-schema is required. Select path first with --get, then apply --filter to the selected value. Use --response-schema first when the response shape is unknown.").action(async(e,t)=>{let r=t.api;if(!await de(r))return;let n=Fr(t),s=await Y(r,e);if(n.error||!n.artifactName){d.result(b("INVALID_REQUEST_UPDATE",{summary:"Invalid operation artifact selection.",message:n.error??"Invalid operation artifact selection.",context:{api_name:r,operation_id:e},nextCommand:`openapi-skills get-operation ${e} --api ${r} --request`})),process.exitCode=1;return}let i=Ye(r,s,n.artifactName);if(!await M.pathExists(i)){if(n.artifactName==="response-schema"){d.result(b("NO_RESPONSE_SCHEMA",{summary:"No response schema artifact exists for this operation.",message:"The response schema has not been created yet.",context:{api_name:r,operation_id:e,artifact_type:"response-schema"},nextCommand:`openapi-skills request ${e} --api ${r}`,reason:"Make a request first to generate the response-schema artifact."})),process.exitCode=1;return}d.result(b("REQUEST_TEMPLATE_STALE",{summary:`Artifact '${n.artifactName}' is missing for this operation.`,message:`The '${n.artifactName}' artifact does not exist yet.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName},nextCommand:`openapi-skills request ${e} --api ${r} --force`})),process.exitCode=1;return}try{let a=await M.readJson(i),o=typeof t.get=="string"?t.get:void 0,p=typeof t.filter=="string"?t.filter:void 0,c=typeof o=="string"&&o.length>0,u=typeof p=="string"&&p.length>0,g=c?Ne(a,o):a;if(c&&!u){let{sizeBytes:l}=Ce(g);l>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${l} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:l},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get ${o} --filter count`})):d.result(I({apiName:r,value:g},{kind:"artifact-value"}));return}if(u){let l=g,h=[];!Array.isArray(l)&&l!==null&&typeof l=="object"&&(h=Object.values(l).filter(y=>Array.isArray(y)),h.length===1&&(l=h[0]));let w=Qr(p),T;if(w.kind==="count"||w.kind==="index"||w.kind==="range"){if(!Array.isArray(l))if(h.length===1)l=h[0];else{d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array and contains no single array field to unwrap.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?o:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the target to be an array.",message:"The selected value is not an array.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:c?o:void 0},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName}`})),process.exitCode=1;return}if(w.kind==="count")T=l.length;else if(w.kind==="index"){let y=w.index<0?l.length+w.index:w.index;T=l[y]}else T=l.slice(w.start,w.end)}else if(w.kind==="path"){let y=w.path,x=w.value;if(c&&!Array.isArray(l)){d.result(b("INVALID_FILTER_SYNTAX",{summary:"--filter requires the --get result to be an array.",message:`The value at path '${o}' is not an array.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p,selected_path:o},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --response-schema`})),process.exitCode=1;return}if(!Array.isArray(l)){let{sizeBytes:P}=Ce(l);P>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The selected value is ${P} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:P},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(I({apiName:r,value:l},{kind:"artifact-value"}));return}T=gr(l,y,x)}else{d.result(b("INVALID_FILTER_SYNTAX",{summary:"Invalid --filter syntax.",message:"--filter must use count, index, range, or <path>=<value> syntax.",context:{api_name:r,operation_id:e,artifact_type:n.artifactName,filter:p},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter 0`})),process.exitCode=1;return}let{sizeBytes:m}=Ce(T);m>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The filtered result is ${m} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:m},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --filter count`})):d.result(I({apiName:r,value:T},{kind:"artifact-value"}));return}let{sizeBytes:f}=Ce(a);f>=51200?d.result(b("OVERSIZED_OUTPUT",{summary:"Output is too large to display.",message:`The artifact is ${f} bytes, exceeding the limit of ${51200} bytes.`,context:{api_name:r,operation_id:e,artifact_type:n.artifactName,size_bytes:f},nextCommand:`openapi-skills get-operation ${e} --api ${r} --${n.artifactName} --get <path> --filter count`})):d.result(I({apiName:r,operationId:e,artifact:a},{kind:"artifact"}))}catch(a){d.result(b("API_PARSE_ERROR",{summary:`Failed to read artifact '${n.artifactName}'.`,message:H(a),context:{api_name:r,operation_id:e,artifact_type:n.artifactName}})),process.exitCode=1}});ri.agentMeta={name:"get-operation",category:"Navigation",usage:"openapi-skills get-operation|get-operation-artifact <operationId> --api <apiName> [--request] [--response] [--response-schema] [--get <path>] [--filter count|<index>|<range>|<path>=<value>]",description:"Return a stored operation artifact created by `openapi-skills request` as raw JSON. Run `request` first so the artifact exists. Use --get to select a nested value, then --filter to count, slice, or match values. Use --response-schema first when the response shape is unknown. Exactly one of --request, --response, or --response-schema is required. Alias: `get-operation-artifact`.",arguments:[{name:"operationId",type:"string",required:!0,positional:!0,description:"The operationId whose stored artifact should be returned."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"request",type:"flag",required:!1,flag:!0,description:"Return request artifact for the operation."},{name:"response",type:"flag",required:!1,flag:!0,description:"Return response artifact for the operation."},{name:"response-schema",type:"flag",required:!1,flag:!0,description:"Return response-schema artifact for the operation. Inspect this first when the response shape is unknown."},{name:"get",type:"string",required:!1,flag:!0,description:"Select a nested value by dot-notation path first. Inspect get-operation --response-schema first so the path matches the actual response shape."},{name:"filter",type:"string",required:!1,flag:!0,description:"Filter the selected value using count, index, range, or <path>=<value> syntax. Examples: --filter count, --filter 0, --filter 0:10, --filter status=sold. Select path first with --get, then filter or slice the selected value."}],examples:["openapi-skills request getPetById --api petstore --force","openapi-skills get-operation getPetById --api petstore --request","openapi-skills get-operation-artifact getPetById --api petstore --request","openapi-skills get-operation getPetById --api petstore --response-schema","openapi-skills get-operation-artifact getPetById --api petstore --response-schema","openapi-skills get-operation getPetById --api petstore --response","openapi-skills get-operation-artifact getPetById --api petstore --response","openapi-skills get-operation getPetById --api petstore --response --get name","openapi-skills get-operation getPetById --api petstore --response --get body --filter id=555","openapi-skills get-operation getPetById --api petstore --response --filter id=5555","openapi-skills get-operation getPetById --api petstore --response --filter count","openapi-skills get-operation getPetById --api petstore --response --filter 0","openapi-skills get-operation getPetById --api petstore --response --filter 0:10"],returns:{type:"json",description:"Returns the selected artifact as raw JSON, or a nested value / filtered array when --get or --filter is supplied. When both are used, --get runs first and --filter applies to the narrowed result. Inspect --response-schema first when the response shape is unknown so --get and --filter can be applied in the right order. --filter can also return an array count, single item, or slice when the selected target is an array."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!0},filesWritten:[]};ni=v.command("request <operationId...>").description("Make a live HTTP request for a specific operation, or prepare a multi-step request scenario without executing requests. Supports: --validate (validate only the response against the schema after the request is sent; it does not validate request bodies or guarantee a response exists), --force (regenerate request artifact; use it when you want the original schema-shaped template), --update-request (patch request artifact using flattened dot-notation keys; binary fields can be file paths or {kind:'file', path,...} descriptors), --update-request-encoded (patch request artifact using base64url-encoded JSON), --header (add headers), --header-encoded (add headers using base64url-encoded JSON).").requiredOption("--api <apiName>","API name to use").option("--validate","Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists.").option("--force","Force overwrite request artifact with default values. Use this when you want the original schema-shaped template; omit it if you want to keep previous request values.").option("--update-request <json>",["Update request artifact before making the request using a single-quoted JSON string that represents a flattened object with dot-notation keys.","Nested JSON objects are supported (they will be flattened and issue a warning), but the top-level value must be a JSON object. Invalid JSON will cause the command to fail.",'To delete a field, set its value to "__delete__".','Binary request fields may be patched with a file path string or an object like {"kind":"file","path":"c:/path/file.pdf","fileName":"file.pdf","mimeType":"application/pdf"}.',`Format (POSIX shells): --update-request '{"field.path":value,...}'`,'Format (PowerShell): --update-request "{"field.path":value,...}" (escape inner quotes as needed)'," - Only flattened object dot-notation keys are recommended (e.g. 'items.0.name').","Examples:",` --update-request '{"person.id":"2"}'`,` --update-request '{"items.0.name":"Alice","items.1.value":42}'`,` --update-request '{"parameters.0":"__delete__"}'`,` --update-request '{"address.street":"Main St","address.zip":12345}'`,"Note: The CLI runs JSON.parse on the provided value; if parsing fails the command exits with an error."].join(`
47
+ `)).option("--update-request-encoded <base64url>",["Patch request artifact before making the request using base64url-encoded JSON.","Use this when a shell or agent may strip quotes from literal JSON.","Example:"," --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9"].join(`
48
+ `)).option("--header <json>",["Additional headers as a JSON string (merged with config and defaults).",`Format: --header '{"Header-Name":"value"}'`,"Example:",` --header '{"X-Api-Key":"abc"}'`].join(`
49
+ `)).option("--header-encoded <base64url>",["Additional headers as base64url-encoded JSON (merged with config and defaults).","Use this when a shell or agent may strip quotes from literal JSON.","Example:"," --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9"].join(`
50
+ `)).action(async(e,t)=>{let r=t.api;if(!await de(r))return;if(e.length>1){try{let{summaryText:o,payload:p}=await Gr(r,e,t.force===!0);d.result(I({summary:o,operationIds:e,apiName:r},{kind:"request-prepare"})),process.exitCode=0}catch(o){let p=H(o);d.result(b("API_PARSE_ERROR",{summary:"Failed to prepare multi-operation request scenario.",message:p,context:{api_name:r,operation_ids:e}})),process.exitCode=1}return}let n=e[0];if(!n){d.result(b("INVALID_REQUEST_UPDATE",{summary:"An operationId is required.",message:"Provide at least one operationId to invoke.",context:{api_name:r},nextCommand:`openapi-skills request <operationId> --api ${r}`})),process.exitCode=1;return}let s,i;if(t.updateRequest&&t.updateRequestEncoded){d.result(b("INVALID_REQUEST_UPDATE",{summary:"Specify only one of --update-request or --update-request-encoded.",message:"Choose the raw JSON form or the base64url-encoded form, not both.",context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(t.updateRequest){let o;try{o=JSON.parse(t.updateRequest)}catch(h){let w=`Invalid JSON for --update-request: ${h instanceof Error?h.message:String(h)}`;d.result(b("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request JSON is malformed.",message:w,context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}if(typeof o!="object"||Array.isArray(o)||!o||Object.keys(o).length===0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request must be a non-empty JSON object.",message:"Use flattened dot-notation keys and provide at least one update.",context:{api_name:r,operation_id:n,update_request:t.updateRequest},nextCommand:`openapi-skills request ${n} --api ${r} --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let p=await Y(r,n),c=Ye(r,p,"request");if(t.force===!0){let w=(await J()).apis?.[r]?.schemaType,T=w==="graphql";if(!T&&w!=="openapi")try{let m=await M.readJson(j(r));T=Array.isArray(m)&&m.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await _e(r,p,!0)}else if(!await M.pathExists(c)){d.result(b("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request requires an existing request.json artifact. Use --force to regenerate the request template.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force --update-request '{"field.path":"value"}'`})),process.exitCode=2;return}let u=await M.readJson(c),g=Le(u),f=st(o),l=Array.from(f).filter(h=>!g.has(h));if(l.length>0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request:t.updateRequest,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} --force`})),process.exitCode=2;return}if(t.force===!0){let h=Ct(u,o);h.length>0&&(i=h)}s=o}if(t.updateRequestEncoded){let o;try{o=at(t.updateRequestEncoded,"--update-request-encoded")}catch(h){let w=`Invalid base64url for --update-request-encoded: ${h instanceof Error?h.message:String(h)}`;d.result(b("INVALID_UPDATE_REQUEST_JSON",{summary:"--update-request-encoded value is malformed.",message:w,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}if(typeof o!="object"||Array.isArray(o)||!o||Object.keys(o).length===0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded must decode to a non-empty JSON object.",message:"The decoded payload must contain at least one flattened dot-notation key.",context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let p=await Y(r,n),c=Ye(r,p,"request");if(t.force===!0){let w=(await J()).apis?.[r]?.schemaType,T=w==="graphql";if(!T&&w!=="openapi")try{let m=await M.readJson(j(r));T=Array.isArray(m)&&m.some(y=>typeof y?.rootType=="string")}catch{T=!1}T||await Q(r,n,p),await _e(r,p,!0)}else if(!await M.pathExists(c)){d.result(b("REQUEST_TEMPLATE_STALE",{summary:"request.json does not exist for this operation.",message:"--update-request-encoded requires an existing request.json artifact. Use --force to regenerate the request template.",context:{api_name:r,operation_id:n,artifact_type:"request"},nextCommand:`openapi-skills request ${n} --api ${r} --force --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9`})),process.exitCode=2;return}let u=await M.readJson(c),g=Le(u),f=st(o),l=Array.from(f).filter(h=>!g.has(h));if(l.length>0){d.result(b("INVALID_REQUEST_UPDATE",{summary:"--update-request-encoded contains keys not present in request.json.",message:`The following keys are missing from request.json: ${l.join(", ")}.`,context:{api_name:r,operation_id:n,update_request_encoded:t.updateRequestEncoded,missing_keys:l},nextCommand:`openapi-skills request ${n} --api ${r} --force`})),process.exitCode=2;return}if(t.force===!0){let h=Ct(u,o);h.length>0&&(i=h)}s=o}if(t.header&&t.headerEncoded){d.result(b("INVALID_JSON_ARGUMENT",{summary:"Provide only one of --header or --header-encoded.",message:"--header and --header-encoded are mutually exclusive.",context:{api_name:r,operation_id:n,header:t.header,header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}let a;if(t.header)try{if(a=JSON.parse(t.header),typeof a!="object"||Array.isArray(a)||!a)throw new Error("--header must be a JSON object")}catch{d.result(b("INVALID_JSON_ARGUMENT",{summary:"--header JSON is malformed.",message:`Invalid --header JSON. Example: --header '{"X-Api-Key":"abc"}'`,context:{header:t.header},nextCommand:`openapi-skills request ${n} --api ${r} --header '{"Header-Name":"value"}'`})),process.exitCode=2;return}if(t.headerEncoded)try{a=at(t.headerEncoded,"--header-encoded")}catch(o){let p=`Invalid base64url for --header-encoded: ${o instanceof Error?o.message:String(o)}`;d.result(b("INVALID_JSON_ARGUMENT",{summary:"--header-encoded value is malformed.",message:p,context:{header_encoded:t.headerEncoded},nextCommand:`openapi-skills request ${n} --api ${r} --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=2;return}if(t.validate)try{let o=await Er(r,n,t.force,a,s,i),p=it(r,n);if(!o.valid){d.result(b("VALIDATION_FAILED",{summary:"Response validation failed.",message:(o.errors??[]).join("; ")||"The response did not match the expected schema.",context:{api_name:r,operation_id:n,validation_warnings:o.warnings??[],validation_errors:o.errors??[],operation_artifact_count:p.fileCount},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=1;return}d.result(I({apiName:r,operationId:n,valid:o.valid,warnings:o.warnings??[],errors:o.errors??[],operationArtifactCount:p.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"validation-result"})),process.exitCode=0}catch(o){d.result(b("VALIDATION_FAILED",{summary:"Validation failed.",message:H(o),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r} --validate`})),process.exitCode=2;return}else try{let{request:o,response:p,warnings:c}=await $t(r,n,t.force,a,s,i);await Lt(r,n);let u=it(r,n);d.result(I({apiName:r,operationId:n,warnings:c??[],fileCount:u.fileCount,retrieveArtifacts:"Use `get-operation-artifact [--request|--response|--response-schema] <operationId>` to view this operation's artifacts."},{kind:"request-result"})),process.exitCode=0}catch(o){d.result(b("REQUEST_FAILED",{summary:"Request failed.",message:H(o),context:{api_name:r,operation_id:n},nextCommand:`openapi-skills request ${n} --api ${r}`})),process.exitCode=2;return}});ni.agentMeta={name:"request",category:"Validation",usage:"openapi-skills request <operationId...> --api <apiName> [--validate] [--force] [--update-request <json>] [--update-request-encoded <base64url>] [--header <json>] [--header-encoded <base64url>]",description:["Make a live HTTP request for an operation, or prepare a multi-step request scenario without executing requests.","When multiple operationIds are supplied, the command enters prepare-only mode and refreshes request artifact templates for the scenario.","With --validate, validate only the response against the schema after the request is sent.","With --force, regenerate the request artifact from schema defaults.",'With --update-request, patch the request artifact using flattened dot-notation keys. Nested JSON objects are accepted, but the provided value must be valid JSON. With --update-request-encoded, pass base64url-encoded JSON instead. With --header, merge JSON headers into the request. With --header-encoded, pass base64url-encoded JSON headers instead. Binary fields can be set to a file path string or a file descriptor object. Set a field to "__delete__" to remove it.'].join(" "),arguments:[{name:"operationId",type:"string[]",required:!0,positional:!0,description:"One or more operationIds to invoke. Multiple values switch the command into prepare-only mode for a multi-step scenario."},{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"validate",type:"flag",required:!1,flag:!0,description:"Validate only the response against the schema after the request is sent. Does not validate the request body or guarantee a response exists."},{name:"force",type:"flag",required:!1,flag:!0,description:"Force overwrite request artifact with default values. Use this when you want the original schema-shaped template; omit it if you want to keep previous request values."},{name:"update-request",type:"json",required:!1,flag:!0,description:'Patch request artifact before making the request. Only flattened object dot-notation keys are allowed. Binary fields can be set to a file path string or file descriptor object. Set a field to "__delete__" to remove it. Use with --force to rebuild defaults first.'},{name:"update-request-encoded",type:"string",required:!1,flag:!0,description:"Patch request artifact before making the request using base64url-encoded JSON. Use this when quoting is unreliable."},{name:"header",type:"json",required:!1,flag:!0,description:"Additional headers as a JSON string."},{name:"header-encoded",type:"string",required:!1,flag:!0,description:"Additional headers as base64url-encoded JSON. Use this when quoting is unreliable."}],examples:["openapi-skills request getPetById --api petstore","openapi-skills request getPetById --api petstore --validate",`openapi-skills request getPetById --api petstore --force --update-request '{"user.profile.name":"Ada"}'`,"openapi-skills request getPetById --api petstore --force --update-request-encoded eyJyZXF1ZXN0Qm9keS5pZCI6MTJ9",`openapi-skills request getPetById --api petstore --update-request '{"user.profile.name":"Ada"}'`,`openapi-skills request getPetById --api petstore --update-request '{"parameters.0.id":1}'`,"openapi-skills request getPetById --api petstore --header-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",`openapi-skills request getPetById --api petstore --update-request '{"parameters.0":"__delete__"}'`,"openapi-skills request operationId1 operationId2 --api petstore"],returns:{type:"json",description:"Returns raw request and response for single-operation requests, or a structured batch preparation summary when multiple operationIds are supplied."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!0},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!0},filesWritten:["request artifact","response artifact","response-schema artifact (when response has JSON body)"]};si=v.command("set-env").requiredOption("--api <apiName>","API name to use").option("--base-url <url>","Base URL for the API environment.").option("--auth <json>","Authentication headers as a JSON string.").option("--auth-encoded <base64url>","Authentication headers as base64url-encoded JSON. Use this when a shell or agent may strip quotes from literal JSON.").option("--var <key=value>","Set a runtime variable for the API environment. Repeatable.",(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).description("Set or update the runtime environment for a parsed API.").addHelpText("after",["Use this command to set baseUrl, auth headers, and runtime vars for a parsed API.","Pass auth headers with --auth as JSON or --auth-encoded as base64url-encoded JSON when quoting is unreliable.","","Examples:",` set-env --api petstore --base-url https://dev.example.com --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",` set-env --api petstore --auth '{"Authorization":"Bearer abc"}'`," set-env --api petstore --var userId=123"].join(`
51
+ `)).action(async e=>{let t=e.api;if(!await de(t))return;let r=typeof e.baseUrl=="string"?e.baseUrl.trim():"",n=r.length>0?r:void 0,s;if(typeof e.auth=="string"&&typeof e.authEncoded=="string"){d.result(b("INVALID_JSON_ARGUMENT",{summary:"Provide only one of --auth or --auth-encoded.",message:"--auth and --auth-encoded are mutually exclusive.",context:{api_name:t,auth:e.auth,auth_encoded:e.authEncoded},nextCommand:`openapi-skills set-env --api ${t} --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=1;return}if(typeof e.auth=="string")try{let o=JSON.parse(e.auth);if(typeof o!="object"||Array.isArray(o)||!o)throw new Error("Auth must be a JSON object");s=o}catch{d.result(b("INVALID_JSON_ARGUMENT",{summary:"--auth JSON is malformed.",message:`Invalid --auth JSON. Example: '{"Authorization":"Bearer abc"}'`,context:{api_name:t,auth:e.auth??null},nextCommand:`openapi-skills set-env --api ${t} --auth '{"Authorization":"Bearer abc"}'`})),process.exitCode=1;return}if(typeof e.authEncoded=="string")try{let o=at(e.authEncoded,"--auth-encoded"),p={};for(let[c,u]of Object.entries(o)){if(typeof u!="string")throw new Error(`Auth header "${c}" must be a string`);p[c]=u}s=p}catch(o){d.result(b("INVALID_JSON_ARGUMENT",{summary:"--auth-encoded value is malformed.",message:`Invalid base64url for --auth-encoded: ${o instanceof Error?o.message:String(o)}`,context:{api_name:t,auth_encoded:e.authEncoded},nextCommand:`openapi-skills set-env --api ${t} --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9`})),process.exitCode=1;return}let i=e.var?Array.isArray(e.var)?e.var:[e.var]:[],a={};for(let o of i){let p=o.indexOf("=");if(p<=0){d.result(b("INVALID_VARIABLE_SYNTAX",{summary:"Invalid --var syntax.",message:`Invalid --var value "${o}". Use key=value.`,context:{api_name:t,variable:o},nextCommand:`openapi-skills set-env --api ${t} --var userId=123`})),process.exitCode=1;return}let c=o.slice(0,p).trim(),u=o.slice(p+1);if(!c){d.result(b("INVALID_VARIABLE_SYNTAX",{summary:"Invalid --var syntax.",message:`Invalid --var value "${o}". Use key=value.`,context:{api_name:t,variable:o},nextCommand:`openapi-skills set-env --api ${t} --var userId=123`})),process.exitCode=1;return}a[c]=u}try{let o={};n!==void 0&&(o.baseUrl=n),s!==void 0&&(o.auth=s),Object.keys(a).length>0&&(o.vars=a),await be(t,o),d.result(I({apiName:t,baseUrl:n,hasAuth:s!==void 0,varCount:Object.keys(a).length},{kind:"set-env-result"}))}catch(o){d.result(b("CONFIG_ERROR",{summary:"Failed to update API environment.",message:H(o),context:{api_name:t,base_url:n??null,var_count:Object.keys(a).length},nextCommand:`openapi-skills set-env --api ${t}`})),process.exitCode=1}});si.agentMeta={name:"set-env",category:"Configuration",usage:"openapi-skills set-env --api <apiName> [--base-url <url>] [--auth <json>] [--auth-encoded <base64url>] [--var key=value]",description:"Set or update the runtime environment for a parsed API. Persists baseUrl, auth headers, and named vars in config.json.",arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."},{name:"base-url",type:"string",required:!1,flag:!0,description:"Base URL for the API environment."},{name:"auth",type:"json",required:!1,flag:!0,description:"Authentication headers as a JSON object."},{name:"auth-encoded",type:"string",required:!1,flag:!0,description:"Authentication headers as base64url-encoded JSON."},{name:"var",type:"string",required:!1,flag:!0,description:"Runtime variable in key=value form. Repeatable."}],examples:[`openapi-skills set-env --api petstore --base-url https://dev.example.com --auth '{"Authorization":"Bearer abc"}'`,"openapi-skills set-env --api petstore --auth-encoded eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIGFiYyJ9",`openapi-skills set-env --api petstore --auth '{"Authorization":"Bearer abc"}'`,"openapi-skills set-env --api petstore --var userId=123 --var env=staging"],returns:{type:"json",description:"Returns success or error message."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!1,requiresParsedApi:!1},filesWritten:["config.json"]};ii=v.command("get-env").requiredOption("--api <apiName>","API name to use").option("--base-url","Include baseUrl in output").option("--auth","Include auth headers in output").option("--var <key=value>","Request one or more runtime vars. Repeatable; only the key part is used to filter output.",(e,t)=>[...Array.isArray(t)?t:t?[t]:[],e]).description("Read API environment configuration from `.openapi-skills/config.json`. Returns all values unless a specific field is requested via flags.").action(async e=>{let t=e.api;if(await de(t))try{let r=e.baseUrl===!0,n=e.auth===!0,s=e.var?Array.isArray(e.var)?e.var:[e.var]:[],i=r||n||s.length>0,a=await et(t,"baseUrl"),o=await et(t,"authHeaders"),p=await et(t,"vars"),c=Array.isArray(p)?p:[],u=Object.fromEntries(c),g={apiName:t};if((!i||r)&&(g.baseUrl=a),(!i||n)&&(g.authHeaders=o),!i)g.vars=c;else if(s.length>0){let f=s.map(l=>{let h=l.indexOf("=");return h>=0?l.slice(0,h).trim():l.trim()}).filter(Boolean);g.vars=f.map(l=>[l,u[l]]).filter(([l,h])=>h!==void 0)}d.result(I(g,{kind:"get-env-result"})),process.exitCode=0}catch(r){d.result(b("CONFIG_ERROR",{summary:"Failed to read API environment.",message:r instanceof Error?r.message:String(r),context:{api_name:t},nextCommand:`openapi-skills get-env --api ${t}`})),process.exitCode=1}});ii.agentMeta={name:"get-env",category:"Configuration",usage:"openapi-skills get-env --api <apiName>",description:"Read environment configuration for an API. Returns all values by default, or only a specific field when a flag is provided.",arguments:[{name:"api",type:"string",required:!0,flag:!0,description:"The API name as defined in .openapi-skills/config.json."}],examples:["openapi-skills get-env --api petstore","openapi-skills get-env --api petstore --base-url","openapi-skills get-env --api petstore --var userId"],returns:{type:"json",description:"Prints { apiName, baseUrl, authHeaders, vars } where vars is an entries array."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!1},filesWritten:[]};ai=v.command("get-api-names").description("List all available API names (parsed OpenAPI bundles) in the project.").action(async()=>{try{let e=await pe();d.result(I({apiNames:e},{kind:"api-list"})),(!e||e.length===0)&&d.warn("No APIs were generated yet. Run first: openapi-skills generate <openapi-source> [options]")}catch{d.result(b("CONFIG_ERROR",{summary:"Failed to list APIs.",message:"Run `openapi-skills generate [options] [openapi-source]` to parse APIs first.",context:{},nextCommand:"openapi-skills generate <openapi-source>"})),process.exitCode=1}});ai.agentMeta={name:"get-api-names",category:"Navigation",usage:"openapi-skills get-api-names",description:"List all available parsed API names in the project. Output is always JSON: { kind: 'api-list', apiNames: [<apiName>, ...] }.",arguments:[],examples:["openapi-skills get-api-names"],returns:{type:"json",description:"Returns { kind: 'api-list', apiNames: [<apiName>, ...] } as JSON."},sideEffects:{writesFiles:!1,readsFiles:!0,network:!1},constraints:{destructive:!1,idempotent:!0,requiresParsedApi:!1},filesWritten:[]};oi=v.command("remove-api <apiName>").description("Remove an API from config.json and delete its .openapi-skills directory after confirmation.").option("-y, --yes","Confirm removal automatically without prompting.").action(async(e,t)=>{let r=e;try{if(!(await pe()).includes(r)){d.result(b("UNKNOWN_API",{summary:`API '${r}' is not installed.`,message:`API '${r}' is not installed.`,context:{api_name:r},nextCommand:"openapi-skills get-api-names"})),process.exitCode=1;return}if(!(t?.yes===!0?!0:await $r(r))){d.result(I({cancelled:!0,apiName:r},{kind:"remove-api-result"})),process.exitCode=0;return}let i=await sr(r);if(i.ok){d.result(I({removedApi:i.data.removedApi,message:i.message},{kind:"remove-api-result"})),process.exitCode=0;return}let a=/config/i.test(i.error.message)?"CONFIG_ERROR":i.error.type==="ApiNotFound"?"UNKNOWN_API":"REQUEST_FAILED";d.result(b(a,{summary:`Remove API error for ${r}.`,message:i.error.message,context:{api_name:r},nextCommand:a==="UNKNOWN_API"?"openapi-skills get-api-names":"None"})),process.exitCode=1;return}catch(n){let s=n instanceof Error?n.message:String(n);d.result(b(/config/i.test(s)?"CONFIG_ERROR":"REQUEST_FAILED",{summary:`Remove API error for ${r}.`,message:s,context:{api_name:r},nextCommand:/config/i.test(s)?"None":`openapi-skills remove-api ${r} --yes`})),process.exitCode=1}});oi.agentMeta={name:"remove-api",category:"Configuration",usage:"openapi-skills remove-api <apiName> [--yes|-y]",description:"Remove a parsed API after confirmation. The command deletes the API entry from config.json and removes the API directory under .openapi-skills.",arguments:[{name:"apiName",type:"string",required:!0,positional:!0,description:"The API name to remove."},{name:"yes",type:"flag",required:!1,flag:!0,description:"Confirm removal automatically without prompting."}],examples:["openapi-skills remove-api petstore --yes"],returns:{type:"json",description:"Returns a structured success or error result for the deletion operation."},sideEffects:{writesFiles:!0,readsFiles:!0,network:!1},constraints:{destructive:!0,idempotent:!1,requiresParsedApi:!0},filesWritten:["config.json"]};v.parse(process.argv)});await Nr();export{v as program};