@adhd/apigen-core-client 0.1.0 β†’ 0.1.2

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.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,18 @@
1
- # Changelog
1
+ ## 0.1.2 (2026-07-23)
2
2
 
3
- All notable changes to `@adhd/apigen-core-client` will be documented in this file.
4
3
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
+ ### πŸš€ Features
5
+
6
+ - **apigen:** canonical route/tool-name projection across transports; serve + generate() + import-specifier fixes
7
+
8
+
9
+ ### ❀️ Thank You
10
+
11
+ - pseudosky
12
+
13
+ ## 0.1.1 (2026-07-23)
14
+
15
+ This was a version bump only for apigen-core-client to align it with other projects, there were no code changes.
7
16
 
8
17
  ## [Unreleased]
9
18
 
package/README.md CHANGED
@@ -1,19 +1,49 @@
1
1
  # @adhd/apigen-core-client
2
2
 
3
- > The core apigen engine β€” TypeScript source β†’ JSON Schema extraction, composition, and the plugin contract every apigen target implements.
3
+ > The core apigen engine β€” TypeScript source β†’ JSON Schema extraction, composition, the plugin contract, and the programmatic API for running live servers without code generation.
4
4
 
5
- ## What it does
6
-
7
- `@adhd/apigen-core-client` reads TypeScript source files, derives JSON Schemas for each exported function's parameters and return type, and composes them with middleware-contributed envelope fields. It defines the **v1 `OutputPlugin`** contract for code generation and the **v2 `Plugin`** capability interface (target / layer / mount / envelope) for the full plugin lifecycle. Pure TypeScript β€” designed for Node and the browser, though ts-morph's type resolution is Node-only. Runtime dependencies: ts-morph, ts-json-schema-generator, pino, typescript, decimal.js, and @adhd/apigen-base-logical.
5
+ `@adhd/apigen-core-client` reads TypeScript source files, derives JSON Schemas for each exported function's parameters and return type, composes them with middleware-contributed envelope fields, and provides the `OutputPlugin` contract that every plugin implements. It's the library you import when you want to **use apigen programmatically** β€” start MCP servers, Fastify HTTP services, or CLI tools directly from your Node.js code, without the CLI.
8
6
 
9
7
  Part of [apigen](../README.md). See the [apigen spec](../../../docs/apigen/SPEC.md) for the full architecture.
10
8
 
9
+ ---
10
+
11
+ ## Two paths: CLI or library
12
+
13
+ apigen serves two audiences through the same engine. Which one are you?
14
+
15
+ | You want to… | Use the CLI | Use this library |
16
+ |---|---|---|
17
+ | Start a server with one command, no code | `npx @adhd/apigen-cli run --source ./api.ts --type mcp --opt transport=sse` | β€” |
18
+ | Generate a deployable project to disk | `npx @adhd/apigen-cli generate --source ./api.ts --type api-fastify --out-dir ./out` | β€” |
19
+ | Embed a live server in your own Node.js process | β€” | `mcpPlugin.run({…})` from `@adhd/apigen-plugin-mcp` |
20
+ | Build a custom deploy pipeline with lifecycles | β€” | `extract()` β†’ `composeSchemas()` β†’ `plugin.run({ signal })` |
21
+ | Create a custom output plugin | Combined CLI + library | `OutputPlugin` / `Plugin` interface |
22
+ | Serve a multi-language polyglot front | `npx @adhd/apigen-cli serve --source ./api.ts --source ./api.py --port 8080` | β€” (this is a CLI-only orchestration) |
23
+
24
+ **The CLI is a thin wrapper** β€” every `apigen run --source ./api.ts --type mcp` call internally does exactly what you'd write in five lines of library code:
25
+
26
+ | CLI command | Library equivalent |
27
+ |---|---|
28
+ | `apigen run --source ./api.ts --type mcp` | `mcpPlugin.run({ packages: [{ id, schemas, importPath: './api.ts', fns: mod }] })` |
29
+ | `apigen run --source ./api.ts --type api-fastify --use health --use logger` | `apiFastifyPlugin.run({ packages: [...], options: { usePlugins: [healthPlugin, loggerPlugin] } })` |
30
+ | `apigen run --source ./api.ts --type mcp --opt transport=sse --opt port=3100` | `mcpPlugin.run({ packages: [...], options: { transport: 'sse', port: 3100 } })` |
31
+ | `apigen generate --source ./api.ts --type jsonschema --out-dir ./schema` | `jsonschemaPlugin.generate({ packages: [...], outputDir: './schema' })` |
32
+
33
+ **The rest of this document focuses on the library path.** See the [CLI README](../../../entrypoint/apigen-cli/README.md) for CLI usage, or the [How-To: Running Servers](./docs/how-to/running-servers.md) for a step-by-step walkthrough.
34
+
35
+ ---
36
+
11
37
  ## Install
12
38
 
13
39
  ```bash
14
40
  npm install @adhd/apigen-core-client
41
+ # Plus the plugins you want to run:
42
+ npm install @adhd/apigen-plugin-mcp @adhd/apigen-plugin-api-fastify @adhd/apigen-plugin-openapi
15
43
  ```
16
44
 
45
+ All packages are published to npm with `access: public`.
46
+
17
47
  ## Quickstart
18
48
 
19
49
  Extract canonical operation descriptors from a TypeScript file, then compose them with middleware envelope fields:
@@ -84,6 +114,229 @@ sourcesForPlugin({ language: 'ts' }, ['src/api.ts', 'src/api.py', 'README.md']);
84
114
  // => ['src/api.ts']
85
115
  ```
86
116
 
117
+ ---
118
+
119
+ ## Run Servers Programmatically
120
+
121
+ The core use case for the library path: **extract operations from your TypeScript source, then start a live server β€” no code generation, no CLI.**
122
+
123
+ Every plugin with a `run()` method receives a `RunInput` with three things: the composed schemas (for routing and validation), the live function references (your actual module imports), and an `AbortSignal` for graceful shutdown. The `run()` starts the server and returns a `Promise<void>` that resolves when the signal fires.
124
+
125
+ ### Start an MCP server (SSE transport)
126
+
127
+ ```ts
128
+ import { extract, composeSchemas } from '@adhd/apigen-core-client';
129
+ import { mcpPlugin } from '@adhd/apigen-plugin-mcp';
130
+
131
+ // A function β€” no framework imports, no decorators, no annotations
132
+ // (this lives in, say, services/api.ts)
133
+ export async function greet(name: string): Promise<string> {
134
+ return `hello, ${name}!`;
135
+ }
136
+ ```
137
+
138
+ ```ts
139
+ import { extract, composeSchemas } from '@adhd/apigen-core-client';
140
+ import { mcpPlugin } from '@adhd/apigen-plugin-mcp';
141
+
142
+ async function startMcp(sourceFile: string) {
143
+ // 1. Extract operations from your TypeScript source
144
+ const ops = await extract({ sourceFile, namespace: 'demo' });
145
+
146
+ // 2. Build generated schemas (one per exported function)
147
+ const generated = {
148
+ metadata: { namespace: 'demo', phase: '' },
149
+ schemas: Object.fromEntries(
150
+ ops.filter(o => o.kind === 'action').map(op => [
151
+ op.path[op.path.length - 1].raw,
152
+ { input: op.input, output: op.output, hasCtx: op.hasCtx, 'x-apigen-safe': op.safe },
153
+ ])
154
+ ),
155
+ };
156
+
157
+ // 3. Compose with middleware envelope (empty for this example)
158
+ const schemas = composeSchemas(generated, []);
159
+
160
+ // 4. Import the source to get live function references
161
+ const mod = await import(sourceFile);
162
+
163
+ // 5. Start the MCP server β€” no codegen, live dispatch
164
+ const abort = new AbortController();
165
+ process.on('SIGINT', () => abort.abort());
166
+
167
+ await mcpPlugin.run!({
168
+ packages: [{
169
+ id: 'demo',
170
+ schemas,
171
+ importPath: sourceFile,
172
+ fns: mod, // your actual exported functions
173
+ createClient: async () => ({}),
174
+ }],
175
+ outputDir: '',
176
+ options: {
177
+ transport: 'sse', // stdio | sse | streaming-http
178
+ port: 3100,
179
+ host: '0.0.0.0',
180
+ // Override tool descriptions per function (optional):
181
+ // toolDescriptions: { greet: 'Say hello to a user' },
182
+ },
183
+ signal: abort.signal,
184
+ operations: ops, // needed for --use mount plugins
185
+ });
186
+ }
187
+ ```
188
+
189
+ The MCP server is now live at `http://localhost:3100/sse` with `POST /messages?sessionId=...`. Every exported function in your source is an MCP tool β€” callable from Claude Desktop, Cursor, or any MCP host. **Equivalent CLI command:** `apigen run --source <file> --type mcp --opt transport=sse --opt port=3100`
190
+
191
+ ### Start a Fastify HTTP server (with OpenAPI docs)
192
+
193
+ Add the OpenAPI plugin as a `--use` mount plugin β€” it contributes a `GET /_meta/openapi` endpoint that serves a live OpenAPI 3.1 document derived from your operations at request time.
194
+
195
+ ```ts
196
+ import { extract, composeSchemas } from '@adhd/apigen-core-client';
197
+ import { apiFastifyPlugin } from '@adhd/apigen-plugin-api-fastify';
198
+ import { openapiPlugin } from '@adhd/apigen-plugin-openapi';
199
+ import { healthPlugin } from '@adhd/apigen-plugin-health';
200
+ import { loggerPlugin } from '@adhd/apigen-plugin-logger';
201
+
202
+ async function startFastify(sourceFile: string) {
203
+ const ops = await extract({ sourceFile, namespace: 'api' });
204
+ const generated = {
205
+ metadata: { namespace: 'api', phase: '' },
206
+ schemas: Object.fromEntries(
207
+ ops.filter(o => o.kind === 'action').map(op => [
208
+ op.path[op.path.length - 1].raw,
209
+ { input: op.input, output: op.output, hasCtx: op.hasCtx, 'x-apigen-safe': op.safe },
210
+ ])
211
+ ),
212
+ };
213
+ const schemas = composeSchemas(generated, []);
214
+ const mod = await import(sourceFile);
215
+
216
+ const abort = new AbortController();
217
+ process.on('SIGINT', () => abort.abort());
218
+
219
+ await apiFastifyPlugin.run!({
220
+ packages: [{
221
+ id: 'api',
222
+ schemas,
223
+ importPath: sourceFile,
224
+ fns: mod,
225
+ createClient: async () => ({}),
226
+ }],
227
+ outputDir: '',
228
+ options: {
229
+ port: 3200,
230
+ host: '0.0.0.0',
231
+ routePrefix: '',
232
+ // Mount plugins contributed as HTTP routes:
233
+ usePlugins: [openapiPlugin, healthPlugin, loggerPlugin],
234
+ // Per-plugin options:
235
+ // useOptions: { openapi: { title: 'My API', version: '1.0.0' } },
236
+ },
237
+ signal: abort.signal,
238
+ operations: ops,
239
+ });
240
+ }
241
+ ```
242
+
243
+ After startup:
244
+ - `GET /api/greet?name=ada` β€” safe operations are GET (query params)
245
+ - `POST /api/greet` β€” unsafe operations use `{"data":{…}}` body
246
+ - `GET /_meta/health` β€” contributed by `healthPlugin`
247
+ - `GET /_meta/openapi` β€” contributed by `openapiPlugin`, serves a live OpenAPI 3.1 spec
248
+
249
+ **Equivalent CLI command:** `apigen run --source <file> --type api-fastify --opt port=3200 --use openapi --use health --use logger`
250
+
251
+ ### Run both servers side by side
252
+
253
+ ```ts
254
+ async function startAll(sourceFile: string) {
255
+ const ops = await extract({ sourceFile, namespace: 'svc' });
256
+ const generated = {
257
+ metadata: { namespace: 'svc', phase: '' },
258
+ schemas: Object.fromEntries(
259
+ ops.filter(o => o.kind === 'action').map(op => [
260
+ op.path[op.path.length - 1].raw,
261
+ { input: op.input, output: op.output, hasCtx: op.hasCtx, 'x-apigen-safe': op.safe },
262
+ ])
263
+ ),
264
+ };
265
+ const schemas = composeSchemas(generated, []);
266
+ const mod = await import(sourceFile);
267
+ const pkg = [{
268
+ id: 'svc',
269
+ schemas,
270
+ importPath: sourceFile,
271
+ fns: mod,
272
+ createClient: async () => ({}),
273
+ }];
274
+
275
+ const abort = new AbortController();
276
+ process.on('SIGINT', () => abort.abort());
277
+
278
+ await Promise.all([
279
+ mcpPlugin.run!({ packages: pkg, outputDir: '', options: { transport: 'sse', port: 3100 }, signal: abort.signal, operations: ops }),
280
+ apiFastifyPlugin.run!({ packages: pkg, outputDir: '', options: { port: 3200, usePlugins: [openapiPlugin, healthPlugin] }, signal: abort.signal, operations: ops }),
281
+ ]);
282
+ }
283
+ ```
284
+
285
+ One source file, two servers, both live from the same import.
286
+
287
+ ### Integrate with your deploy system
288
+
289
+ Because `run()` returns a `Promise<void>` that resolves on `signal.abort`, you can wrap it in any lifecycle model β€” containers, process managers, custom mesh registrations.
290
+
291
+ ```ts
292
+ export async function deployService(config: {
293
+ source: string;
294
+ port: number;
295
+ type: 'mcp' | 'api-fastify';
296
+ }) {
297
+ const ops = await extract({ sourceFile: config.source, namespace: 'deploy' });
298
+ /* build schemas, import module β€” same pattern as above */
299
+
300
+ const plugin = config.type === 'mcp' ? mcpPlugin : apiFastifyPlugin;
301
+ const opts = config.type === 'mcp'
302
+ ? { transport: 'sse', port: config.port }
303
+ : { port: config.port, usePlugins: [openapiPlugin, healthPlugin] };
304
+
305
+ const abort = new AbortController();
306
+ // Your deployer hook: register with service mesh, health probe, etc.
307
+ const server = plugin.run!({ packages, outputDir: '', options: opts, signal: abort.signal });
308
+ return { abort, running: server }; // call abort.abort() to stop gracefully
309
+ }
310
+ ```
311
+
312
+ ### Options reference for `run()`
313
+
314
+ The `options` object in `RunInput` accepts plugin-specific keys. Here are the common ones:
315
+
316
+ | Key | Plugin(s) | Type | Default | Description |
317
+ |-----|-----------|------|---------|-------------|
318
+ | `transport` | `mcp` | `'stdio' \| 'sse' \| 'streaming-http'` | `'stdio'` | MCP transport protocol |
319
+ | `port` | `mcp` (HTTP), `api-fastify` | `number` | `3000` | Listen port |
320
+ | `host` | All | `string` | `'127.0.0.1'` | Bind address |
321
+ | `routePrefix` | `api-fastify` | `string` | `''` | Path prefix before `/<ns>/<fn>` |
322
+ | `usePlugins` | All `run()` targets | `Plugin[]` | `[]` | Layer/mount/envelope plugins to compose |
323
+ | `toolDescriptions` | `mcp` | `Record<string, string>` | `{}` | Per-tool description overrides |
324
+
325
+ ### Plugin cheat sheet
326
+
327
+ | Plugin | Package | `run()` | `generate()` | What it builds |
328
+ |--------|---------|---------|--------------|----------------|
329
+ | `mcpPlugin` | `@adhd/apigen-plugin-mcp` | βœ“ | βœ“ | MCP server (stdio/SSE/streaming-http) |
330
+ | `apiFastifyPlugin` | `@adhd/apigen-plugin-api-fastify` | βœ“ | βœ“ | Fastify HTTP server |
331
+ | `apiExpressPlugin` | `@adhd/apigen-plugin-api-express` | βœ“ | βœ“ | Express HTTP server |
332
+ | `cliPlugin` | `@adhd/apigen-plugin-cli-output` | βœ“ | βœ“ | Commander CLI tool |
333
+ | `jsonschemaPlugin` | `@adhd/apigen-plugin-jsonschema` | β€” | βœ“ | JSON Schema files |
334
+ | `openapiPlugin` | `@adhd/apigen-plugin-openapi` | β€” | β€” | Mount: `GET /_meta/openapi` |
335
+ | `healthPlugin` | `@adhd/apigen-plugin-health` | β€” | β€” | Mount: `GET /_meta/health` |
336
+ | `loggerPlugin` | `@adhd/apigen-plugin-logger` | β€” | β€” | Layer: per-operation logging |
337
+
338
+ > See the [How-To: Running Servers](./docs/how-to/running-servers.md) for a complete walkthrough with all three transports and deployment patterns.
339
+
87
340
  ## Features
88
341
 
89
342
  ### v2 Symbol-Based Extraction
@@ -223,6 +476,8 @@ Recognized extensions: `.ts/.tsx/.mts/.cts` β†’ `ts`, `.py` β†’ `py`, `.rs` β†’
223
476
 
224
477
  ## How-To Guides
225
478
 
479
+ - [Writing Source Files for apigen](./docs/how-to/writing-source-files.md) β€” How to structure your TypeScript source: naming, exports, types, and what makes a good API surface
480
+ - [Running Servers Programmatically](./docs/how-to/running-servers.md) β€” Start MCP, Fastify, or Express servers from your own Node.js process
226
481
  - [End-to-End Extraction Pipeline](./docs/how-to/extraction-pipeline.md) β€” From source file to composed schemas
227
482
  - [Building apigen Plugins](./docs/how-to/building-plugins.md) β€” v1 OutputPlugin and v2 Plugin development
228
483
 
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Ne=Object.create;var oe=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Ce=Object.prototype.hasOwnProperty;var Ie=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ke(t))!Ce.call(e,n)&&n!==r&&oe(e,n,{get:()=>t[n],enumerable:!(o=Oe(t,n))||o.enumerable});return e};var Fe=(e,t,r)=>(r=e!=null?Ne(Ee(e)):{},Ie(t||!e||!e.__esModule?oe(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("ts-morph"),Le=require("node:fs"),D=require("node:path"),E=require("ts-json-schema-generator");function Re(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const _e=Re(D),pe=Symbol.for("adhd.apigen.extraction-session");function ge(e,t){const r=[...e.getImportDeclarations().map(o=>o.getModuleSpecifierSourceFile()),...e.getExportDeclarations().map(o=>o.getModuleSpecifierSourceFile())];for(const o of r){if(!o)continue;const n=o.getFilePath();if(!n.includes("/node_modules/")&&!t.has(n)){t.add(n);try{o.refreshFromFileSystemSync()}catch{}ge(o,t)}}}function me(e){try{const t=Le.statSync(e);return`${t.mtimeMs}:${t.size}`}catch{return"nostat"}}const L=new Map,G=new Map;function Me(e,t,r){const o=t??"",n=L.get(o);let i=r;if(n&&n.fileVersions.size>0){const c=[r],u=[...n.fileVersions.entries()].sort(([f],[l])=>f.localeCompare(l));for(const[f,l]of u)f!==e&&c.push(`${f}:${l}`);i=c.join("|")}const s=`${e}\0${t??""}`;let a=G.get(s);return(!a||a.version!==i)&&(a={version:i,schemas:new Map},G.set(s,a)),a.schemas}function Ve(){L.clear(),G.clear()}function X(){const e={projectsBuilt:0,generatorsBuilt:0,schemaCacheHits:0,schemaCacheMisses:0},t=new Map;let r=!1;return{[pe]:!0,stats:e,schemaCache:new Map,aliasCache:new WeakMap,zodImportCache:new WeakMap,generatorCache:new Map,projectFor(n){if(r)throw new Error("apigen-core: ExtractionSession used after dispose()");const i=n??"",s=n?this.statVersion(n):"";let a=L.get(i);return a&&a.tsconfigVersion!==s&&(a=void 0),a||(a={project:n?new C.Project({tsConfigFilePath:n,skipAddingFilesFromTsConfig:!0}):new C.Project({skipAddingFilesFromTsConfig:!0}),tsconfigVersion:s,fileVersions:new Map},L.set(i,a),e.projectsBuilt++),a.project},sourceFileFor(n,i){const s=this.projectFor(i),a=L.get(i??""),c=this.statVersion(n);let u=s.getSourceFile(n);if(u===void 0?u=s.addSourceFileAtPath(n):a&&a.fileVersions.get(n)!==c&&u.refreshFromFileSystemSync(),a==null||a.fileVersions.set(n,c),a){const f=new Set([n]);ge(u,f);for(const l of f)l!==n&&a.fileVersions.set(l,this.statVersion(l))}return u},statVersion(n){let i=t.get(n);return i===void 0&&(i=me(n),t.set(n,i)),i},dispose(){r=!0,this.schemaCache.clear(),this.generatorCache.clear(),t.clear()}}}function de(e){const t=e;if(t[pe]!==!0)throw new Error("apigen-core: unknown ExtractionSession implementation β€” create sessions with createExtractionSession()");return t}const q="x-apigen-logical";function ie(e,t){const r=new Set,o=[e];for(;o.length>0;){const n=o.pop();if(!n||r.has(n))continue;r.add(n);const i=n.$ref;if(typeof i=="string"){if(t){const l=t[i];if(!l){const m=Object.keys(t).join(", ")||"(none)";throw new Error(`[apigen-logical] $ref "${i}" cannot be resolved. Available $defs: ${m}`)}o.push(l)}continue}const s=n.oneOf;if(Array.isArray(s))for(const l of s)typeof l=="object"&&l!==null&&o.push(l);const a=n.properties;if(a)for(const l of Object.values(a))o.push(l);const c=n.items;if(Array.isArray(c))for(const l of c)typeof l=="object"&&l!==null&&o.push(l);else typeof c=="object"&&c!==null&&o.push(c);const u=n.additionalProperties;typeof u=="object"&&u!==null&&o.push(u);const f=n.propertyNames;typeof f=="object"&&f!==null&&o.push(f)}}const se=new Set(["string","number","boolean","integer"]);function ze(e){if(typeof e!="object"||e===null)return!1;const t=e;if(t.$ref!==void 0||t.oneOf||t.anyOf||t.allOf)return!1;const{type:r}=t;return typeof r=="string"?se.has(r):Array.isArray(r)?r.every(o=>se.has(o)||o==="null"):Array.isArray(t.enum)&&t.enum.length>0?t.enum.every(o=>["string","number","boolean"].includes(typeof o)):!1}function ye(e){if(!e||typeof e!="object")return!1;const t=e.properties;return t===void 0||typeof t!="object"||t===null?!1:Object.values(t).every(ze)}function qe(e){const t={},r=o=>{for(const n of["definitions","$defs"]){const i=o[n];if(i)for(const[s,a]of Object.entries(i)){const c=s.startsWith("#/")?s:`#/${n}/${s}`;t[c]=a}}};for(const o of Object.values(e.schemas))r(o.input),r(o.output);if(Object.keys(t).length!==0)for(const[o,n]of Object.entries(e.schemas))try{ie(n.input,t),ie(n.output,t)}catch(i){throw new Error(`[apigen-core-client] Schema validation failed for function "${o}": ${i.message}`)}}function De(e,t){const r=['apigen calling convention: all domain parameters go inside a "data" envelope β€” e.g. { "data": { ... } }'+(t?".":" (an empty object for this zero-parameter tool).")];return e.length>0&&r.push(`Field(s) ${e.map(o=>`"${o}"`).join(", ")} are transport-level envelope metadata, NOT domain data β€” do not nest them under "data". Over MCP they are read from arguments._meta["x-<pluginId>-<field>"] (default pluginId "adhd"); see @adhd/apigen-naming's envelopeMetaKey/envelopeCliFlag/envelopeEnvVar for the HTTP-header / CLI-flag / env-var equivalents.`),r.join(" ")}function Ke(e,t,r){qe(e);const o={};for(const[n,i]of Object.entries(e.schemas)){const s=(r==null?void 0:r[n])??{},a=i.input.properties??{},c=i.input.required??[],u={},f=[];for(const y of t)if(y.envelope&&s[y.id]!==!1)for(const[h,T]of Object.entries(y.envelope))u[h]=T,f.includes(h)||f.push(h);const l={type:"object",properties:a,additionalProperties:!1,...c.length>0?{required:c}:{}},m=i.safe===!0||ye(i.input),g=i.input.definitions,p=i.input.$defs;o[n]={input:{type:"object",properties:{...u,data:l},required:[...f,...c.length>0?["data"]:[]],additionalProperties:!1,description:De(Object.keys(u),Object.keys(a).length>0),...g?{definitions:g}:{},...p?{$defs:p}:{}},output:i.output,...i.hasCtx?{hasCtx:!0}:{},"x-apigen-safe":m}}return o}const We=8;function Be(e,t){try{return t?e.getText(t):e.getText()}catch{try{return e.getText()}catch{return}}}let Ue=0;async function Ge(e,t,r,o){const n=`__ApigenProbe_${process.pid}_${Ue++}`;let i;try{i=t.addTypeAlias({name:n,type:r});const s=i.getType();return await o(s)}catch{return}finally{try{i==null||i.remove()}catch{}}}async function he(e,t,r){if(r>We)return{};if(e.isString()||e.isStringLiteral())return e.isStringLiteral()?{type:"string",enum:[e.getLiteralValue()]}:{type:"string"};if(e.isNumber()||e.isNumberLiteral())return e.isNumberLiteral()?{type:"number",enum:[e.getLiteralValue()]}:{type:"number"};if(e.isBoolean())return{type:"boolean"};if(e.isBooleanLiteral())return{type:"boolean"};if(e.isNull()||e.isUndefined()||e.isVoid())return{type:"null"};if(e.isUnion()){const o=e.getUnionTypes();if(o.every(c=>c.isStringLiteral())&&o.length>0)return{type:"string",enum:o.map(c=>c.getLiteralValue())};if(o.every(c=>c.isNumberLiteral())&&o.length>0)return{type:"number",enum:o.map(c=>c.getLiteralValue())};const s=await Promise.all(o.map(c=>he(c,t,r+1))),a=Y(s);return{oneOf:s,...a?{discriminator:a}:{},[q]:"union"}}if(e.isArray()){const o=e.getArrayElementType();return{type:"array",items:o?await t(o.getText()):{}}}if(e.isTuple()){const o=e.getTupleElements(),n=await Promise.all(o.map(i=>t(i.getText())));return{type:"array",items:n,minItems:n.length,maxItems:n.length}}if(e.isObject()){const o=e.getStringIndexType(),n=e.getNumberIndexType(),i=o??n,s=e.getProperties();if(i&&s.length===0)return{type:"object",additionalProperties:await t(i.getText())};const a={};for(const c of s){const u=c.getName(),l=c.getDeclarations()[0];let m;if(l)try{m=c.getTypeAtLocation(l)}catch{m=void 0}if(m!==void 0&&m.getCallSignatures().length>0)continue;const g=m!==void 0?Be(m,l):void 0;a[u]=g!==void 0?await t(g):{}}return Object.keys(a).length>0?{type:"object",properties:a}:{}}return{}}function Y(e){if(e.length<2)return;const t=[];for(const o of e){if(o.type!=="object")return;const n=o.properties;if(!n||typeof n!="object")return;t.push(n)}const r=Object.keys(t[0]).filter(o=>t.every(n=>Object.prototype.hasOwnProperty.call(n,o)));for(const o of r){const n=[];let i=!0;for(const a of t){const c=a[o],u=c&&(c.type==="string"||c.type==="number"),f=c==null?void 0:c.enum;if(!u||!Array.isArray(f)||f.length!==1){i=!1;break}n.push(String(f[0]))}if(!i||new Set(n).size!==n.length)continue;const s={};return n.forEach((a,c)=>{s[a]=`#/oneOf/${c}`}),{propertyName:o,mapping:s}}}function V(e,t,r){if(t>6)return{};const o=e.trim();if(o==="string")return{type:"string"};if(o==="number")return{type:"number"};if(o==="boolean")return{type:"boolean"};if(o==="null")return{type:"null"};if(o==="undefined")return{type:"null"};const n=H[o];if(n!==void 0)return n;if(r!=null&&r.size){const i=r.get(o);if(i!==void 0){const s=H[i];if(s!==void 0)return s}}if(o.endsWith("[]"))return{type:"array",items:V(o.slice(0,-2),t+1,r)};if(o.includes("|")){const i=o.split("|").map(c=>c.trim());if(i.every(c=>c.startsWith("'")))return{type:"string",enum:i.map(c=>c.replace(/'/g,""))};const s=i.map(c=>V(c,t+1,r)),a=Y(s);return{oneOf:s,...a?{discriminator:a}:{},[q]:"union"}}if(o.startsWith("{")&&o.endsWith("}")){const i=o.slice(1,-1).trim(),s={};for(const a of i.split(";").filter(Boolean)){const[c,u]=a.split(":").map(f=>f.trim());c&&u&&(s[c.replace("?","")]=V(u,t+1,r))}return{type:"object",properties:s}}return{}}function Te(e){const t=[];let r=0,o=0;for(let i=0;i<e.length;i++){const s=e[i];s==="<"||s==="["||s==="{"||s==="("?r++:s===">"||s==="]"||s==="}"||s===")"?r--:s===","&&r===0&&(t.push(e.slice(o,i).trim()),o=i+1)}const n=e.slice(o).trim();return n.length>0&&t.push(n),t}function He(e){const t=/^(?:Readonly)?Map<(.+)>$/.exec(e);return t?t[1]:void 0}function Ze(e){const t=/^(?:Readonly)?Set<(.+)>$/.exec(e);return t?t[1]:void 0}function Je(e){let t=e.trim();if(t.startsWith("readonly ")&&(t=t.slice(9).trim()),!t.startsWith("[")||!t.endsWith("]"))return;const r=t.slice(1,-1).trim();if(r.length!==0)return Te(r)}async function Qe(e,t){const r=e.trim(),o=He(r);if(o!==void 0){const s=Te(o);if(s.length===2){const[a,c]=await Promise.all([t(s[0]),t(s[1])]);return{type:"array",items:{type:"array",items:[a,c],minItems:2,maxItems:2}}}}const n=Ze(r);if(n!==void 0)return{type:"array",items:await t(n),uniqueItems:!0};const i=Je(r);if(i!==void 0){const s=await Promise.all(i.map(a=>t(a)));return{type:"array",items:s,minItems:s.length,maxItems:s.length}}}const Se={"decimal.js":"Decimal"},H={Date:{type:"string",format:"date-time"},bigint:{type:"string",format:"int64"},Uint8Array:{type:"string",format:"byte"},Buffer:{type:"string",format:"byte"},URL:{type:"string",format:"uri"},RegExp:{type:"string",format:"regex"},Decimal:{type:"string",format:"decimal"}},ae={Uint8Array:"byte",Buffer:"byte",Decimal:"decimal"};function ce(e){var r;const t=new Map;for(const o of e.getImportDeclarations()){const n=o.getModuleSpecifierValue(),i=Se[n];if(!i)continue;const s=o.getDefaultImport();if(s){const a=s.getText();a!==i&&t.set(a,i)}for(const a of o.getNamedImports()){const c=((r=a.getAliasNode())==null?void 0:r.getText())??a.getName();c!==i&&t.set(c,i)}}return t}function Xe(e,t){return r=>{r.addNodeParser({supportsNode(o){var i,s,a;if(o.kind!==t)return!1;const n=((i=o.typeName)==null?void 0:i.escapedText)??((a=(s=o.typeName)==null?void 0:s.right)==null?void 0:a.escapedText);return n!==void 0&&Object.prototype.hasOwnProperty.call(ae,n)},createType(o){var i,s,a;const n=((i=o.typeName)==null?void 0:i.escapedText)??((a=(s=o.typeName)==null?void 0:s.right)==null?void 0:a.escapedText);return new E.AnnotatedType(new E.StringType,{format:ae[n]},!1)}}),r.addNodeParser({supportsNode(o){return o.kind===e},createType(){return new E.AnnotatedType(new E.StringType,{format:"int64"},!1)}})}}let I;function Ye(){if(I)return I;try{const e=D.dirname(require.resolve("ts-json-schema-generator/package.json"));I=require(require.resolve("typescript",{paths:[e]}))}catch{I=require("typescript")}return I}const O=new Map;function et(){const e=process.env.APIGEN_PROGRAM_CACHE,t=e===void 0?NaN:Number(e);return Number.isFinite(t)&&t>=0?t:8}function tt(e){const t=O.get(e);return t&&(O.delete(e),O.set(e,t)),t}function nt(e,t){const r=et();if(r!==0)for(O.delete(e),O.set(e,t);O.size>r;){const o=O.keys().next().value;O.delete(o)}}function rt(e,t){return`${e}\0${t??""}`}const ot=new Set(["zod",/^zod\/./]);function it(e){for(const t of e.getImportDeclarations()){const r=t.getModuleSpecifierValue();for(const o of ot)if(typeof o=="string"){if(r===o)return!0}else if(o.test(r))return!0}return!1}function st(e){for(const t of["$defs","definitions"]){const r=e[t];if(!r||typeof r!="object")continue;const o=Object.keys(r);if(o.length===0)continue;const n=new Set(o.filter(i=>/zod/i.test(i)));for(const[i,s]of Object.entries(r)){if(n.has(i)||typeof s!="object"||s===null)continue;const a=s,c=typeof a.$ref=="string"?a.$ref:"";if(c){for(const u of n)if(c.includes(u)){n.add(i);break}}}for(const i of n)delete r[i]}Z(e)}function Z(e,t){if(!e||typeof e!="object")return;const r=t??new WeakSet;if(!r.has(e)){r.add(e);for(const o of Object.keys(e))if(o==="$ref"&&typeof e[o]=="string"){const n=e[o];/zod/i.test(n)&&delete e[o]}for(const[,o]of Object.entries(e))if(typeof o=="object"&&o!==null)if(Array.isArray(o))for(const n of o)typeof n=="object"&&n!==null&&Z(n,r);else Z(o,r)}}function at(e){const t=new Set;for(const o of["$defs","definitions"]){const n=e[o];if(n&&typeof n=="object")for(const i of Object.keys(n))t.add(i)}const r=J(e,t);if(r.length>0)throw new Error(`[apigen-core-client] Generated schema contains ${r.length} unresolvable $ref(s): ${r.join(", ")}. This usually means zod-internal definitions were stripped but $ref references to them remain. Check the source file's imports or the ts-json-schema-generator output.`)}function J(e,t){if(!e||typeof e!="object")return[];const r=[];for(const[o,n]of Object.entries(e))if(o==="$ref"&&typeof n=="string"){const i=n.match(/#\/(?:\$defs|definitions)\/(.+)$/);i&&!t.has(i[1])&&r.push(n)}else if(typeof n=="object"&&n!==null)if(Array.isArray(n))for(const i of n)typeof i=="object"&&i!==null&&r.push(...J(i,t));else r.push(...J(n,t));return r}function ct(e){const t=e.anyOf;if(!Array.isArray(t)||t.length<2)return e;const r=t,o=Y(r),n={...e};return delete n.anyOf,{...n,oneOf:r,...o?{discriminator:o}:{},[q]:n[q]??"union"}}function ut(e,t,r){const{DEFAULT_CONFIG:o}=require("ts-json-schema-generator/dist/src/Config.js"),n={...o,...e},i=n.path,s=rt(i,n.tsconfig);let a;a=r?r.statVersion(i):me(i);let c;if(s!==void 0){const f=(r==null?void 0:r.generatorCache.get(s))??tt(s);f&&f.version===a&&(c=f.gen)}if(!c){const{createProgram:f}=require("ts-json-schema-generator/dist/factory/program.js"),l=Ye(),m=Xe(l.SyntaxKind.BigIntKeyword,l.SyntaxKind.TypeReference),g=f(n),p=E.createParser(g,n,m),y=E.createFormatter(n);if(c=new E.SchemaGenerator(g,p,y,n),r&&r.stats.generatorsBuilt++,s!==void 0&&a!==void 0){const h={version:a,gen:c};nt(s,h),r==null||r.generatorCache.set(s,h)}}const u=c.createSchema(n.type);return st(u),at(u),u}function ft(e,t){let r=e.trim();if(r=xe(r),t!=null&&t.size){const n=t.get(r);if(n!==void 0)return n}const o=r.match(/^ReadonlyArray<(.+)>$/);for(o&&(r=`${o[1].trim()}[]`);r.startsWith("readonly ");)r=r.slice(9).trim();return r}function be(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}const lt=Object.entries(Se).map(([e,t])=>({pattern:new RegExp(`import\\(["'][^"']*${be(e)}[^"']*["']\\)\\.\\w+`,"g"),key:t}));function xe(e){let t=e;for(const{pattern:r,key:o}of lt)t=t.replace(r,o);return t}function pt(e,t){let r=xe(e);for(const[o,n]of t)r=r.replace(new RegExp(`\\b${be(o)}\\b`,"g"),n);return r}async function A(e,t,r,o,n,i){const s=t.getFilePath(),a=`${s}\0${o??""}\0${r}`,c=i??new Set;if(c.has(a))return{};if(!n){const p=new Set(c);return p.add(a),ue(e,t,r,o,void 0,p)}const u=n.schemaCache.get(a);if(u!==void 0)return n.stats.schemaCacheHits++,u;const f=Me(s,o,n.statVersion(s)),l=f.get(r);if(l!==void 0)return n.stats.schemaCacheHits++,n.schemaCache.set(a,Promise.resolve(l)),l;n.stats.schemaCacheMisses++;const m=new Set(c);m.add(a);const g=ue(e,t,r,o,n,m).then(p=>(f.set(r,p),p)).catch(p=>{throw n.schemaCache.delete(a),p});return n.schemaCache.set(a,g),g}async function ue(e,t,r,o,n,i){if(["void","undefined","null","Promise<void>"].includes(r))return{type:"null"};let s;if(n){const m=n.aliasCache.get(t);s=m??ce(t),m||n.aliasCache.set(t,s)}else s=ce(t);const a=ft(r,s),c=H[a];if(c!==void 0)return c;const u=await Qe(a,m=>A(e,t,m,o,n,i));if(u!==void 0)return u;const f=(n==null?void 0:n.zodImportCache.get(t))??it(t);if(n&&n.zodImportCache.set(t,f),!f)try{const m={path:t.getFilePath(),type:a,skipTypeCheck:!0,tsconfig:o,topRef:!1},g=ut(m,!0,n);return ct(g)}catch{}try{const m=await Ge(e,t,a,g=>he(g,p=>A(e,t,p,o,n,i),0));if(m!==void 0)return m}catch{}const l=pt(a,s);return V(l,0,s)}function ee(e,t,r){if(e!=null&&e.hasInitializer()){const o=e.getInitializer();if(o)return o.getText()}return gt(r,t)}function gt(e,t){var s;const r=e,o=((s=r==null?void 0:r.getJsDocs)==null?void 0:s.call(r))??[],n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`\\[\\s*${n}\\s*=\\s*([^\\]]+)\\]`);for(const a of o)for(const c of a.getTags()){if(c.getTagName()!=="param")continue;const u=c.getText().match(i);if(u)return u[1].trim()}}function mt(e){const t=e.trim(),r=t.match(/^(['"`])([\s\S]*)\1$/);if(r)return r[2];if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(t!=="undefined"){if(/^-?\d+(\.\d+)?$/.test(t))return Number(t);try{return JSON.parse(t)}catch{return t}}}function dt(e,t){const r=mt(t);if(r===void 0)return;e.default=r;const o=typeof r=="string"?r:JSON.stringify(r),n=typeof e.description=="string"?e.description:void 0;e.description=n?`${n} (default: ${o})`:`(default: ${o})`}async function yt(e){const t=e.session===void 0,r=de(e.session??X());try{return await ht(e,r)}finally{t&&r.dispose()}}async function ht(e,t){const{sourceFile:r,namespace:o="",tsconfig:n}=e,i=t.projectFor(n),s=t.sourceFileFor(r,n),a=D.basename(r),c=P(bt(a)),u=P(o),f=[];for(const[g,p]of s.getExportedDeclarations()){if(g==="default"||M(g))continue;const y=vt(p);if(y){const d=y.getSignature(),S=fe(d,y),b=d.getReturnType().getText();f.push(await _(i,s,u,c,g,S,b,y.isAsync(),n,t));continue}const h=p.find(d=>d.getKindName()==="VariableDeclaration");if(!h)continue;const T=h.getInitializer(),x=T==null?void 0:T.getKindName();if(T&&["ArrowFunction","FunctionExpression"].includes(x??"")){const S=h.getType().getCallSignatures();if(S.length===0)continue;const b=S[0],$=le(b,h,h.getVariableStatement()),j=b.getReturnType().getText(),v=T.isAsync();f.push(await _(i,s,u,c,g,$,j,v,n,t))}else if(x==="ObjectLiteralExpression"){const d=h.getType();for(const S of d.getProperties()){const b=S.getName();if(M(b))continue;const j=S.getTypeAtLocation(h).getCallSignatures();if(j.length===0)continue;const v=j[0],w=le(v,h,h.getVariableStatement()),R=v.getReturnType().getText(),K=[c,P(g),P(b)];f.push(await z(i,s,u,K,b,w,R,!1,n,t))}}else{const d=h.getType(),S=d.getText();if(k(d,h)){const b=await A(i,s,S,n,t);f.push(St(u,c,g,b))}else console.warn(`[apigen-core] Skipping non-callable, non-serializable export: ${g}`)}}const l=s.getDefaultExportSymbol();if(l){const g=s.getExportAssignment(p=>!p.isExportEquals());if(g){const p=g.getExpression(),y=p.getKindName();if(["ArrowFunction","FunctionExpression"].includes(y)){const T=p.getType().getCallSignatures();if(T.length>0){const x=T[0],d=W(x,g),S=x.getReturnType().getText(),b=p.isAsync();f.push(await _(i,s,u,c,"default",d,S,b,n,t))}}else{const h=p.getType();for(const T of h.getProperties()){const x=T.getName();if(M(x))continue;const S=T.getTypeAtLocation(g).getCallSignatures();if(S.length===0)continue;const b=S[0],$=W(b,g),j=b.getReturnType().getText(),v=[c,P("default"),P(x)];f.push(await z(i,s,u,v,x,$,j,!1,n,t))}}}else{const p=l.getDeclarations();for(const y of p){if(y.getKindName()!=="FunctionDeclaration")continue;const h=y,T=h.getName(),x=T&&T.length>0?T:"default",d=h.getSignature(),S=fe(d,h),b=d.getReturnType().getText();f.push(await _(i,s,u,c,x,S,b,h.isAsync(),n,t))}}}const m=xt(s);if(m.length>0)for(const{name:g,sig:p}of m){if(M(g))continue;const y=W(p),h=p.getReturnType().getText(),T=[c,P(g)];f.push(await z(i,s,u,T,g,y,h,!1,n,t))}return f}function Tt(e,t,r,o){const n=new Set,i=s=>{if(Array.isArray(s))return s.map(i);if(!s||typeof s!="object"||n.has(s))return s;n.add(s);try{const a=s,c={};for(const[u,f]of Object.entries(a)){if(u==="definitions"||u==="$defs"){const l=u,m=t[l];for(const[g,p]of Object.entries(f)){const y=i(p),h=m[g];if(h!==void 0&&JSON.stringify(h)!==JSON.stringify(y))throw new Error(`[apigen-core-client] Function "${r}": param "${o}" contributes a "${l}.${g}" definition that conflicts with an identically-named definition already hoisted from another param/output in the same function. Two structurally different types share the same generated definition key, so apigen cannot safely merge them into one function-level schema.`);m[g]=y}continue}c[u]=i(f)}return c}finally{n.delete(s)}};return i(e)}async function _(e,t,r,o,n,i,s,a,c,u){const f=P(n);return z(e,t,r,[o,f],n,i,s,a,c,u)}async function z(e,t,r,o,n,i,s,a,c,u){const f=i.length>0&&i[0].name==="ctx",l=i.filter(d=>d.name!=="ctx"),m=l.filter(d=>!d.optional).map(d=>d.name),g={},p={definitions:{},$defs:{}};for(const d of l){const S=await A(e,t,d.type,c,u),b=Tt(S,p,n,d.name);d.defaultValue!==void 0&&dt(b,d.defaultValue),g[d.name]=b}const y=s.replace(/^Promise<(.+)>$/,"$1").trim(),h=await A(e,t,y,c,u),T={type:"object",properties:g,required:m,...Object.keys(p.definitions).length>0?{definitions:p.definitions}:{},...Object.keys(p.$defs).length>0?{$defs:p.$defs}:{}};return{id:ve(r,o),host:"ts",namespace:r,path:o,kind:"action",async:a,streaming:!1,safe:!1,input:T,output:h,envelope:{},typeText:{lang:"ts",input:wt(i),output:y},...f?{hasCtx:!0}:{}}}function St(e,t,r,o){const n=P(r),i=[t,n];return{id:ve(e,i),host:"ts",namespace:e,path:i,kind:"query",async:!1,streaming:!1,safe:!0,input:{type:"object",properties:{},required:[]},output:o,envelope:{},typeText:null}}function ve(e,t){return(e.raw?[e,...t]:t).map(o=>o.words.join("-")).join("/")}function te(e){return e.split(/[-_.]+/).flatMap(t=>t.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").split("_").filter(Boolean)).map(t=>t.toLowerCase()).filter(Boolean)}function P(e){return{raw:e,words:te(e)}}function bt(e){return e.replace(/\.[^.]+$/,"").replace(/[._]+/g,"-")}function xt(e){const t=[];for(const r of e.getStatements()){if(r.getKindName()!=="ExpressionStatement")continue;const o=r.getExpression();if(o.getKindName()!=="BinaryExpression")continue;const n=o;if(n.getLeft().getText().trim()!=="module.exports"||n.getOperatorToken().getKindName()!=="EqualsToken")continue;const s=n.getRight(),a=s.getType();for(const c of a.getProperties()){const f=c.getTypeAtLocation(s).getCallSignatures();f.length!==0&&t.push({name:c.getName(),sig:f[0]})}}return t}function vt(e){let t;for(const r of e){if(r.getKindName()!=="FunctionDeclaration")continue;const o=r;if(t||(t=o),o.getBody())return o}return t}function fe(e,t){return e.getParameters().map(r=>{var s;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:r.getTypeAtLocation(e.getDeclaration()).getText(),optional:i,defaultValue:ee(n,r.getName(),t)}})}function le(e,t,r){return e.getParameters().map(o=>{var a;const n=o.getDeclarations(),i=n.length>0&&n[0].getKindName()==="Parameter"?n[0]:null,s=o.isOptional()||((i==null?void 0:i.hasInitializer())??!1)||(((a=i==null?void 0:i.hasQuestionToken)==null?void 0:a.call(i))??!1);return{name:o.getName(),type:o.getTypeAtLocation(t).getText(),optional:s,defaultValue:ee(i,o.getName(),r??t)}})}function W(e,t){return e.getParameters().map(r=>{var s,a,c;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:n?n.getType().getText():((c=(a=r.getValueDeclaration())==null?void 0:a.getType())==null?void 0:c.getText())??"unknown",optional:i,defaultValue:ee(n,r.getName(),t)}})}function wt(e){const t=e.filter(r=>r.name!=="ctx");return t.length===0?"()":"("+t.map(r=>`${r.name}${r.optional?"?":""}: ${r.type}`).join(", ")+")"}function M(e){return!!(e==="__samples__"||e.startsWith("__"))}function k(e,t,r=new Set){if(e.getCallSignatures().length>0||e.getConstructSignatures().length>0)return!1;if(e.isString()||e.isNumber()||e.isBoolean()||e.isNull()||e.isUndefined()||e.isStringLiteral()||e.isNumberLiteral()||e.isBooleanLiteral()||e.isEnumLiteral())return!0;if(e.isArray()||e.isReadonlyArray()){const o=e.getArrayElementType();return o?k(o,t,r):!1}if(e.isTuple())return e.getTupleElements().every(o=>k(o,t,r));if(e.isUnion())return e.getUnionTypes().every(o=>k(o,t,r));if(e.isIntersection())return e.getIntersectionTypes().every(o=>k(o,t,r));if(e.isObject()){const o=e.getText(t);if(r.has(o))return!0;r.add(o);const n=e.getStringIndexType(),i=e.getNumberIndexType();if(n||i)return[n,i].every(a=>!a||k(a,t,r));const s=e.getProperties();return s.length===0?!0:s.every(a=>{const c=a.getTypeAtLocation(t);return k(c,t,r)})}return!1}async function jt(e){const t=e.session===void 0,r=de(e.session??X());try{return await $t(e,r)}finally{t&&r.dispose()}}async function $t(e,t){const{sourceFile:r,namespace:o="",tsconfig:n,includeInstances:i=!1}=e,s=t.projectFor(n),a=t.sourceFileFor(r,n),c=D.basename(r),u=F(Pt(c)),f=F(o),l=[];for(const[m,g]of a.getExportedDeclarations()){const p=g.find(T=>T.getKindName()==="ClassDeclaration");if(!p)continue;const y=m==="default"?p.getName():m;if(!y||U(y))continue;const h=F(y);for(const T of p.getStaticMethods()){const x=T.getName();if(U(x))continue;const d=T.getScope();if(d===C.Scope.Private||d===C.Scope.Protected)continue;const S=T.getSignature(),b=B(S,T),$=S.getReturnType().getText(),j=T.isAsync(),v=[u,h,F(x)];l.push(await At(s,a,f,v,b,$,j,n,t))}if(i){{const x=p.getConstructors()[0]??null;let d=[];if(x){const w=x.getSignature();d=B(w,x)}const S=[u,h],b=Q(f,S),$=d.filter(w=>w.name!=="ctx"),j=$.filter(w=>!w.optional).map(w=>w.name),v={};for(const w of $)v[w.name]=await A(s,a,w.type,n,t);l.push({id:b,host:"ts",namespace:f,path:S,kind:"constructor",async:!1,streaming:!1,safe:!1,input:{type:"object",properties:v,required:j},output:{type:"object",properties:{instanceId:{type:"string"}},required:["instanceId"]},envelope:{},typeText:{lang:"ts",input:Nt(d),output:"{ instanceId: string }"}})}for(const T of p.getInstanceMethods()){const x=T.getName();if(U(x))continue;const d=T.getScope();if(d===C.Scope.Private||d===C.Scope.Protected)continue;const S=T.getSignature(),b=B(S,T),$=S.getReturnType().getText(),j=T.isAsync(),v=[u,h,F(x)],w=Q(f,v),R=b.filter(N=>N.name!=="ctx"),K=R.filter(N=>!N.optional).map(N=>N.name),ne={};for(const N of R)ne[N.name]=await A(s,a,N.type,n,t);const re=$.replace(/^Promise<(.+)>$/,"$1").trim(),Pe=await A(s,a,re,n,t);l.push({id:w,host:"ts",namespace:f,path:v,kind:"instance-method",async:j,streaming:!1,safe:!1,input:{type:"object",properties:ne,required:K},output:Pe,envelope:{type:"object",properties:{instanceId:{type:"string"}},required:["instanceId"]},typeText:{lang:"ts",input:we(b),output:re}})}}}return l}async function At(e,t,r,o,n,i,s,a,c){const u=n.filter(y=>y.name!=="ctx"),f=u.filter(y=>!y.optional).map(y=>y.name),l={};for(const y of u)l[y.name]=await A(e,t,y.type,a,c);const m=i.replace(/^Promise<(.+)>$/,"$1").trim(),g=await A(e,t,m,a,c);return{id:Q(r,o),host:"ts",namespace:r,path:o,kind:"action",async:s,streaming:!1,safe:!1,input:{type:"object",properties:l,required:f},output:g,envelope:{},typeText:{lang:"ts",input:we(n),output:m}}}function Q(e,t){return(e.raw?[e,...t]:t).map(o=>o.words.join("-")).join("/")}function F(e){return{raw:e,words:te(e)}}function Pt(e){return e.replace(/\.[^.]+$/,"").replace(/[._]+/g,"-")}function B(e,t){return e.getParameters().map(r=>{var s;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:r.getTypeAtLocation(t).getText(),optional:i}})}function we(e){const t=e.filter(r=>r.name!=="ctx");return t.length===0?"()":"("+t.map(r=>`${r.name}${r.optional?"?":""}: ${r.type}`).join(", ")+")"}function Nt(e){return e.length===0?"()":"("+e.map(t=>`${t.name}${t.optional?"?":""}: ${t.type}`).join(", ")+")"}function U(e){return!!(e==="__samples__"||e.startsWith("__")||e.startsWith("_"))}const Ot=new Map([[".ts","ts"],[".tsx","ts"],[".mts","ts"],[".cts","ts"],[".py","py"],[".rs","rust"],[".go","go"],[".java","java"]]);function je(e){const t=_e.extname(e).toLowerCase();return Ot.get(t)}function $e(e){return e.language??"ts"}function Ae(e,t){const r=je(t);return r===void 0?!1:r===$e(e)}function kt(e,t){return t.filter(r=>Ae(e,r))}exports.clearPersistentProjectCache=Ve;exports.composeSchemas=Ke;exports.createExtractionSession=X;exports.effectiveLanguage=$e;exports.extract=yt;exports.extractClasses=jt;exports.isPrimitiveOnlyInputSchema=ye;exports.languageOfSource=je;exports.pluginConsumesSource=Ae;exports.sourcesForPlugin=kt;exports.tokenize=te;
1
+ "use strict";var Ne=Object.create;var oe=Object.defineProperty;var Oe=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Ce=Object.prototype.hasOwnProperty;var Ie=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ke(t))!Ce.call(e,n)&&n!==r&&oe(e,n,{get:()=>t[n],enumerable:!(o=Oe(t,n))||o.enumerable});return e};var Fe=(e,t,r)=>(r=e!=null?Ne(Ee(e)):{},Ie(t||!e||!e.__esModule?oe(r,"default",{value:e,enumerable:!0}):r,e));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("ts-morph"),Le=require("node:fs"),D=require("node:path"),E=require("ts-json-schema-generator");function Re(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const _e=Re(D),pe=Symbol.for("adhd.apigen.extraction-session");function ge(e,t){const r=[...e.getImportDeclarations().map(o=>o.getModuleSpecifierSourceFile()),...e.getExportDeclarations().map(o=>o.getModuleSpecifierSourceFile())];for(const o of r){if(!o)continue;const n=o.getFilePath();if(!n.includes("/node_modules/")&&!t.has(n)){t.add(n);try{o.refreshFromFileSystemSync()}catch{}ge(o,t)}}}function me(e){try{const t=Le.statSync(e);return`${t.mtimeMs}:${t.size}`}catch{return"nostat"}}const L=new Map,G=new Map;function Me(e,t,r){const o=t??"",n=L.get(o);let i=r;if(n&&n.fileVersions.size>0){const c=[r],u=[...n.fileVersions.entries()].sort(([f],[l])=>f.localeCompare(l));for(const[f,l]of u)f!==e&&c.push(`${f}:${l}`);i=c.join("|")}const s=`${e}\0${t??""}`;let a=G.get(s);return(!a||a.version!==i)&&(a={version:i,schemas:new Map},G.set(s,a)),a.schemas}function Ve(){L.clear(),G.clear()}function X(){const e={projectsBuilt:0,generatorsBuilt:0,schemaCacheHits:0,schemaCacheMisses:0},t=new Map;let r=!1;return{[pe]:!0,stats:e,schemaCache:new Map,aliasCache:new WeakMap,zodImportCache:new WeakMap,generatorCache:new Map,projectFor(n){if(r)throw new Error("apigen-core: ExtractionSession used after dispose()");const i=n??"",s=n?this.statVersion(n):"";let a=L.get(i);return a&&a.tsconfigVersion!==s&&(a=void 0),a||(a={project:n?new C.Project({tsConfigFilePath:n,skipAddingFilesFromTsConfig:!0}):new C.Project({skipAddingFilesFromTsConfig:!0}),tsconfigVersion:s,fileVersions:new Map},L.set(i,a),e.projectsBuilt++),a.project},sourceFileFor(n,i){const s=this.projectFor(i),a=L.get(i??""),c=this.statVersion(n);let u=s.getSourceFile(n);if(u===void 0?u=s.addSourceFileAtPath(n):a&&a.fileVersions.get(n)!==c&&u.refreshFromFileSystemSync(),a==null||a.fileVersions.set(n,c),a){const f=new Set([n]);ge(u,f);for(const l of f)l!==n&&a.fileVersions.set(l,this.statVersion(l))}return u},statVersion(n){let i=t.get(n);return i===void 0&&(i=me(n),t.set(n,i)),i},dispose(){r=!0,this.schemaCache.clear(),this.generatorCache.clear(),t.clear()}}}function de(e){const t=e;if(t[pe]!==!0)throw new Error("apigen-core: unknown ExtractionSession implementation β€” create sessions with createExtractionSession()");return t}const q="x-apigen-logical";function ie(e,t){const r=new Set,o=[e];for(;o.length>0;){const n=o.pop();if(!n||r.has(n))continue;r.add(n);const i=n.$ref;if(typeof i=="string"){if(t){const l=t[i];if(!l){const m=Object.keys(t).join(", ")||"(none)";throw new Error(`[apigen-logical] $ref "${i}" cannot be resolved. Available $defs: ${m}`)}o.push(l)}continue}const s=n.oneOf;if(Array.isArray(s))for(const l of s)typeof l=="object"&&l!==null&&o.push(l);const a=n.properties;if(a)for(const l of Object.values(a))o.push(l);const c=n.items;if(Array.isArray(c))for(const l of c)typeof l=="object"&&l!==null&&o.push(l);else typeof c=="object"&&c!==null&&o.push(c);const u=n.additionalProperties;typeof u=="object"&&u!==null&&o.push(u);const f=n.propertyNames;typeof f=="object"&&f!==null&&o.push(f)}}const se=new Set(["string","number","boolean","integer"]);function ze(e){if(typeof e!="object"||e===null)return!1;const t=e;if(t.$ref!==void 0||t.oneOf||t.anyOf||t.allOf)return!1;const{type:r}=t;return typeof r=="string"?se.has(r):Array.isArray(r)?r.every(o=>se.has(o)||o==="null"):Array.isArray(t.enum)&&t.enum.length>0?t.enum.every(o=>["string","number","boolean"].includes(typeof o)):!1}function ye(e){if(!e||typeof e!="object")return!1;const t=e.properties;return t===void 0||typeof t!="object"||t===null?!1:Object.values(t).every(ze)}function qe(e){const t={},r=o=>{for(const n of["definitions","$defs"]){const i=o[n];if(i)for(const[s,a]of Object.entries(i)){const c=s.startsWith("#/")?s:`#/${n}/${s}`;t[c]=a}}};for(const o of Object.values(e.schemas))r(o.input),r(o.output);if(Object.keys(t).length!==0)for(const[o,n]of Object.entries(e.schemas))try{ie(n.input,t),ie(n.output,t)}catch(i){throw new Error(`[apigen-core-client] Schema validation failed for function "${o}": ${i.message}`)}}function De(e,t){const r=['apigen calling convention: all domain parameters go inside a "data" envelope β€” e.g. { "data": { ... } }'+(t?".":" (an empty object for this zero-parameter tool).")];return e.length>0&&r.push(`Field(s) ${e.map(o=>`"${o}"`).join(", ")} are transport-level envelope metadata, NOT domain data β€” do not nest them under "data". Over MCP they are read from arguments._meta["x-<pluginId>-<field>"] (default pluginId "adhd"); see @adhd/apigen-engine-naming's envelopeMetaKey/envelopeCliFlag/envelopeEnvVar for the HTTP-header / CLI-flag / env-var equivalents.`),r.join(" ")}function Ke(e,t,r){qe(e);const o={};for(const[n,i]of Object.entries(e.schemas)){const s=(r==null?void 0:r[n])??{},a=i.input.properties??{},c=i.input.required??[],u={},f=[];for(const y of t)if(y.envelope&&s[y.id]!==!1)for(const[h,T]of Object.entries(y.envelope))u[h]=T,f.includes(h)||f.push(h);const l={type:"object",properties:a,additionalProperties:!1,...c.length>0?{required:c}:{}},m=i.safe===!0||ye(i.input),g=i.input.definitions,p=i.input.$defs;o[n]={input:{type:"object",properties:{...u,data:l},required:[...f,...c.length>0?["data"]:[]],additionalProperties:!1,description:De(Object.keys(u),Object.keys(a).length>0),...g?{definitions:g}:{},...p?{$defs:p}:{}},output:i.output,...i.hasCtx?{hasCtx:!0}:{},"x-apigen-safe":m}}return o}const We=8;function Be(e,t){try{return t?e.getText(t):e.getText()}catch{try{return e.getText()}catch{return}}}let Ue=0;async function Ge(e,t,r,o){const n=`__ApigenProbe_${process.pid}_${Ue++}`;let i;try{i=t.addTypeAlias({name:n,type:r});const s=i.getType();return await o(s)}catch{return}finally{try{i==null||i.remove()}catch{}}}async function he(e,t,r){if(r>We)return{};if(e.isString()||e.isStringLiteral())return e.isStringLiteral()?{type:"string",enum:[e.getLiteralValue()]}:{type:"string"};if(e.isNumber()||e.isNumberLiteral())return e.isNumberLiteral()?{type:"number",enum:[e.getLiteralValue()]}:{type:"number"};if(e.isBoolean())return{type:"boolean"};if(e.isBooleanLiteral())return{type:"boolean"};if(e.isNull()||e.isUndefined()||e.isVoid())return{type:"null"};if(e.isUnion()){const o=e.getUnionTypes();if(o.every(c=>c.isStringLiteral())&&o.length>0)return{type:"string",enum:o.map(c=>c.getLiteralValue())};if(o.every(c=>c.isNumberLiteral())&&o.length>0)return{type:"number",enum:o.map(c=>c.getLiteralValue())};const s=await Promise.all(o.map(c=>he(c,t,r+1))),a=Y(s);return{oneOf:s,...a?{discriminator:a}:{},[q]:"union"}}if(e.isArray()){const o=e.getArrayElementType();return{type:"array",items:o?await t(o.getText()):{}}}if(e.isTuple()){const o=e.getTupleElements(),n=await Promise.all(o.map(i=>t(i.getText())));return{type:"array",items:n,minItems:n.length,maxItems:n.length}}if(e.isObject()){const o=e.getStringIndexType(),n=e.getNumberIndexType(),i=o??n,s=e.getProperties();if(i&&s.length===0)return{type:"object",additionalProperties:await t(i.getText())};const a={};for(const c of s){const u=c.getName(),l=c.getDeclarations()[0];let m;if(l)try{m=c.getTypeAtLocation(l)}catch{m=void 0}if(m!==void 0&&m.getCallSignatures().length>0)continue;const g=m!==void 0?Be(m,l):void 0;a[u]=g!==void 0?await t(g):{}}return Object.keys(a).length>0?{type:"object",properties:a}:{}}return{}}function Y(e){if(e.length<2)return;const t=[];for(const o of e){if(o.type!=="object")return;const n=o.properties;if(!n||typeof n!="object")return;t.push(n)}const r=Object.keys(t[0]).filter(o=>t.every(n=>Object.prototype.hasOwnProperty.call(n,o)));for(const o of r){const n=[];let i=!0;for(const a of t){const c=a[o],u=c&&(c.type==="string"||c.type==="number"),f=c==null?void 0:c.enum;if(!u||!Array.isArray(f)||f.length!==1){i=!1;break}n.push(String(f[0]))}if(!i||new Set(n).size!==n.length)continue;const s={};return n.forEach((a,c)=>{s[a]=`#/oneOf/${c}`}),{propertyName:o,mapping:s}}}function V(e,t,r){if(t>6)return{};const o=e.trim();if(o==="string")return{type:"string"};if(o==="number")return{type:"number"};if(o==="boolean")return{type:"boolean"};if(o==="null")return{type:"null"};if(o==="undefined")return{type:"null"};const n=H[o];if(n!==void 0)return n;if(r!=null&&r.size){const i=r.get(o);if(i!==void 0){const s=H[i];if(s!==void 0)return s}}if(o.endsWith("[]"))return{type:"array",items:V(o.slice(0,-2),t+1,r)};if(o.includes("|")){const i=o.split("|").map(c=>c.trim());if(i.every(c=>c.startsWith("'")))return{type:"string",enum:i.map(c=>c.replace(/'/g,""))};const s=i.map(c=>V(c,t+1,r)),a=Y(s);return{oneOf:s,...a?{discriminator:a}:{},[q]:"union"}}if(o.startsWith("{")&&o.endsWith("}")){const i=o.slice(1,-1).trim(),s={};for(const a of i.split(";").filter(Boolean)){const[c,u]=a.split(":").map(f=>f.trim());c&&u&&(s[c.replace("?","")]=V(u,t+1,r))}return{type:"object",properties:s}}return{}}function Te(e){const t=[];let r=0,o=0;for(let i=0;i<e.length;i++){const s=e[i];s==="<"||s==="["||s==="{"||s==="("?r++:s===">"||s==="]"||s==="}"||s===")"?r--:s===","&&r===0&&(t.push(e.slice(o,i).trim()),o=i+1)}const n=e.slice(o).trim();return n.length>0&&t.push(n),t}function He(e){const t=/^(?:Readonly)?Map<(.+)>$/.exec(e);return t?t[1]:void 0}function Ze(e){const t=/^(?:Readonly)?Set<(.+)>$/.exec(e);return t?t[1]:void 0}function Je(e){let t=e.trim();if(t.startsWith("readonly ")&&(t=t.slice(9).trim()),!t.startsWith("[")||!t.endsWith("]"))return;const r=t.slice(1,-1).trim();if(r.length!==0)return Te(r)}async function Qe(e,t){const r=e.trim(),o=He(r);if(o!==void 0){const s=Te(o);if(s.length===2){const[a,c]=await Promise.all([t(s[0]),t(s[1])]);return{type:"array",items:{type:"array",items:[a,c],minItems:2,maxItems:2}}}}const n=Ze(r);if(n!==void 0)return{type:"array",items:await t(n),uniqueItems:!0};const i=Je(r);if(i!==void 0){const s=await Promise.all(i.map(a=>t(a)));return{type:"array",items:s,minItems:s.length,maxItems:s.length}}}const Se={"decimal.js":"Decimal"},H={Date:{type:"string",format:"date-time"},bigint:{type:"string",format:"int64"},Uint8Array:{type:"string",format:"byte"},Buffer:{type:"string",format:"byte"},URL:{type:"string",format:"uri"},RegExp:{type:"string",format:"regex"},Decimal:{type:"string",format:"decimal"}},ae={Uint8Array:"byte",Buffer:"byte",Decimal:"decimal"};function ce(e){var r;const t=new Map;for(const o of e.getImportDeclarations()){const n=o.getModuleSpecifierValue(),i=Se[n];if(!i)continue;const s=o.getDefaultImport();if(s){const a=s.getText();a!==i&&t.set(a,i)}for(const a of o.getNamedImports()){const c=((r=a.getAliasNode())==null?void 0:r.getText())??a.getName();c!==i&&t.set(c,i)}}return t}function Xe(e,t){return r=>{r.addNodeParser({supportsNode(o){var i,s,a;if(o.kind!==t)return!1;const n=((i=o.typeName)==null?void 0:i.escapedText)??((a=(s=o.typeName)==null?void 0:s.right)==null?void 0:a.escapedText);return n!==void 0&&Object.prototype.hasOwnProperty.call(ae,n)},createType(o){var i,s,a;const n=((i=o.typeName)==null?void 0:i.escapedText)??((a=(s=o.typeName)==null?void 0:s.right)==null?void 0:a.escapedText);return new E.AnnotatedType(new E.StringType,{format:ae[n]},!1)}}),r.addNodeParser({supportsNode(o){return o.kind===e},createType(){return new E.AnnotatedType(new E.StringType,{format:"int64"},!1)}})}}let I;function Ye(){if(I)return I;try{const e=D.dirname(require.resolve("ts-json-schema-generator/package.json"));I=require(require.resolve("typescript",{paths:[e]}))}catch{I=require("typescript")}return I}const O=new Map;function et(){const e=process.env.APIGEN_PROGRAM_CACHE,t=e===void 0?NaN:Number(e);return Number.isFinite(t)&&t>=0?t:8}function tt(e){const t=O.get(e);return t&&(O.delete(e),O.set(e,t)),t}function nt(e,t){const r=et();if(r!==0)for(O.delete(e),O.set(e,t);O.size>r;){const o=O.keys().next().value;O.delete(o)}}function rt(e,t){return`${e}\0${t??""}`}const ot=new Set(["zod",/^zod\/./]);function it(e){for(const t of e.getImportDeclarations()){const r=t.getModuleSpecifierValue();for(const o of ot)if(typeof o=="string"){if(r===o)return!0}else if(o.test(r))return!0}return!1}function st(e){for(const t of["$defs","definitions"]){const r=e[t];if(!r||typeof r!="object")continue;const o=Object.keys(r);if(o.length===0)continue;const n=new Set(o.filter(i=>/zod/i.test(i)));for(const[i,s]of Object.entries(r)){if(n.has(i)||typeof s!="object"||s===null)continue;const a=s,c=typeof a.$ref=="string"?a.$ref:"";if(c){for(const u of n)if(c.includes(u)){n.add(i);break}}}for(const i of n)delete r[i]}Z(e)}function Z(e,t){if(!e||typeof e!="object")return;const r=t??new WeakSet;if(!r.has(e)){r.add(e);for(const o of Object.keys(e))if(o==="$ref"&&typeof e[o]=="string"){const n=e[o];/zod/i.test(n)&&delete e[o]}for(const[,o]of Object.entries(e))if(typeof o=="object"&&o!==null)if(Array.isArray(o))for(const n of o)typeof n=="object"&&n!==null&&Z(n,r);else Z(o,r)}}function at(e){const t=new Set;for(const o of["$defs","definitions"]){const n=e[o];if(n&&typeof n=="object")for(const i of Object.keys(n))t.add(i)}const r=J(e,t);if(r.length>0)throw new Error(`[apigen-core-client] Generated schema contains ${r.length} unresolvable $ref(s): ${r.join(", ")}. This usually means zod-internal definitions were stripped but $ref references to them remain. Check the source file's imports or the ts-json-schema-generator output.`)}function J(e,t){if(!e||typeof e!="object")return[];const r=[];for(const[o,n]of Object.entries(e))if(o==="$ref"&&typeof n=="string"){const i=n.match(/#\/(?:\$defs|definitions)\/(.+)$/);i&&!t.has(i[1])&&r.push(n)}else if(typeof n=="object"&&n!==null)if(Array.isArray(n))for(const i of n)typeof i=="object"&&i!==null&&r.push(...J(i,t));else r.push(...J(n,t));return r}function ct(e){const t=e.anyOf;if(!Array.isArray(t)||t.length<2)return e;const r=t,o=Y(r),n={...e};return delete n.anyOf,{...n,oneOf:r,...o?{discriminator:o}:{},[q]:n[q]??"union"}}function ut(e,t,r){const{DEFAULT_CONFIG:o}=require("ts-json-schema-generator/dist/src/Config.js"),n={...o,...e},i=n.path,s=rt(i,n.tsconfig);let a;a=r?r.statVersion(i):me(i);let c;if(s!==void 0){const f=(r==null?void 0:r.generatorCache.get(s))??tt(s);f&&f.version===a&&(c=f.gen)}if(!c){const{createProgram:f}=require("ts-json-schema-generator/dist/factory/program.js"),l=Ye(),m=Xe(l.SyntaxKind.BigIntKeyword,l.SyntaxKind.TypeReference),g=f(n),p=E.createParser(g,n,m),y=E.createFormatter(n);if(c=new E.SchemaGenerator(g,p,y,n),r&&r.stats.generatorsBuilt++,s!==void 0&&a!==void 0){const h={version:a,gen:c};nt(s,h),r==null||r.generatorCache.set(s,h)}}const u=c.createSchema(n.type);return st(u),at(u),u}function ft(e,t){let r=e.trim();if(r=xe(r),t!=null&&t.size){const n=t.get(r);if(n!==void 0)return n}const o=r.match(/^ReadonlyArray<(.+)>$/);for(o&&(r=`${o[1].trim()}[]`);r.startsWith("readonly ");)r=r.slice(9).trim();return r}function be(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}const lt=Object.entries(Se).map(([e,t])=>({pattern:new RegExp(`import\\(["'][^"']*${be(e)}[^"']*["']\\)\\.\\w+`,"g"),key:t}));function xe(e){let t=e;for(const{pattern:r,key:o}of lt)t=t.replace(r,o);return t}function pt(e,t){let r=xe(e);for(const[o,n]of t)r=r.replace(new RegExp(`\\b${be(o)}\\b`,"g"),n);return r}async function A(e,t,r,o,n,i){const s=t.getFilePath(),a=`${s}\0${o??""}\0${r}`,c=i??new Set;if(c.has(a))return{};if(!n){const p=new Set(c);return p.add(a),ue(e,t,r,o,void 0,p)}const u=n.schemaCache.get(a);if(u!==void 0)return n.stats.schemaCacheHits++,u;const f=Me(s,o,n.statVersion(s)),l=f.get(r);if(l!==void 0)return n.stats.schemaCacheHits++,n.schemaCache.set(a,Promise.resolve(l)),l;n.stats.schemaCacheMisses++;const m=new Set(c);m.add(a);const g=ue(e,t,r,o,n,m).then(p=>(f.set(r,p),p)).catch(p=>{throw n.schemaCache.delete(a),p});return n.schemaCache.set(a,g),g}async function ue(e,t,r,o,n,i){if(["void","undefined","null","Promise<void>"].includes(r))return{type:"null"};let s;if(n){const m=n.aliasCache.get(t);s=m??ce(t),m||n.aliasCache.set(t,s)}else s=ce(t);const a=ft(r,s),c=H[a];if(c!==void 0)return c;const u=await Qe(a,m=>A(e,t,m,o,n,i));if(u!==void 0)return u;const f=(n==null?void 0:n.zodImportCache.get(t))??it(t);if(n&&n.zodImportCache.set(t,f),!f)try{const m={path:t.getFilePath(),type:a,skipTypeCheck:!0,tsconfig:o,topRef:!1},g=ut(m,!0,n);return ct(g)}catch{}try{const m=await Ge(e,t,a,g=>he(g,p=>A(e,t,p,o,n,i),0));if(m!==void 0)return m}catch{}const l=pt(a,s);return V(l,0,s)}function ee(e,t,r){if(e!=null&&e.hasInitializer()){const o=e.getInitializer();if(o)return o.getText()}return gt(r,t)}function gt(e,t){var s;const r=e,o=((s=r==null?void 0:r.getJsDocs)==null?void 0:s.call(r))??[],n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp(`\\[\\s*${n}\\s*=\\s*([^\\]]+)\\]`);for(const a of o)for(const c of a.getTags()){if(c.getTagName()!=="param")continue;const u=c.getText().match(i);if(u)return u[1].trim()}}function mt(e){const t=e.trim(),r=t.match(/^(['"`])([\s\S]*)\1$/);if(r)return r[2];if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(t!=="undefined"){if(/^-?\d+(\.\d+)?$/.test(t))return Number(t);try{return JSON.parse(t)}catch{return t}}}function dt(e,t){const r=mt(t);if(r===void 0)return;e.default=r;const o=typeof r=="string"?r:JSON.stringify(r),n=typeof e.description=="string"?e.description:void 0;e.description=n?`${n} (default: ${o})`:`(default: ${o})`}async function yt(e){const t=e.session===void 0,r=de(e.session??X());try{return await ht(e,r)}finally{t&&r.dispose()}}async function ht(e,t){const{sourceFile:r,namespace:o="",tsconfig:n}=e,i=t.projectFor(n),s=t.sourceFileFor(r,n),a=D.basename(r),c=P(bt(a)),u=P(o),f=[];for(const[g,p]of s.getExportedDeclarations()){if(g==="default"||M(g))continue;const y=vt(p);if(y){const d=y.getSignature(),S=fe(d,y),b=d.getReturnType().getText();f.push(await _(i,s,u,c,g,S,b,y.isAsync(),n,t));continue}const h=p.find(d=>d.getKindName()==="VariableDeclaration");if(!h)continue;const T=h.getInitializer(),x=T==null?void 0:T.getKindName();if(T&&["ArrowFunction","FunctionExpression"].includes(x??"")){const S=h.getType().getCallSignatures();if(S.length===0)continue;const b=S[0],$=le(b,h,h.getVariableStatement()),j=b.getReturnType().getText(),v=T.isAsync();f.push(await _(i,s,u,c,g,$,j,v,n,t))}else if(x==="ObjectLiteralExpression"){const d=h.getType();for(const S of d.getProperties()){const b=S.getName();if(M(b))continue;const j=S.getTypeAtLocation(h).getCallSignatures();if(j.length===0)continue;const v=j[0],w=le(v,h,h.getVariableStatement()),R=v.getReturnType().getText(),K=[c,P(g),P(b)];f.push(await z(i,s,u,K,b,w,R,!1,n,t))}}else{const d=h.getType(),S=d.getText();if(k(d,h)){const b=await A(i,s,S,n,t);f.push(St(u,c,g,b))}else console.warn(`[apigen-core] Skipping non-callable, non-serializable export: ${g}`)}}const l=s.getDefaultExportSymbol();if(l){const g=s.getExportAssignment(p=>!p.isExportEquals());if(g){const p=g.getExpression(),y=p.getKindName();if(["ArrowFunction","FunctionExpression"].includes(y)){const T=p.getType().getCallSignatures();if(T.length>0){const x=T[0],d=W(x,g),S=x.getReturnType().getText(),b=p.isAsync();f.push(await _(i,s,u,c,"default",d,S,b,n,t))}}else{const h=p.getType();for(const T of h.getProperties()){const x=T.getName();if(M(x))continue;const S=T.getTypeAtLocation(g).getCallSignatures();if(S.length===0)continue;const b=S[0],$=W(b,g),j=b.getReturnType().getText(),v=[c,P("default"),P(x)];f.push(await z(i,s,u,v,x,$,j,!1,n,t))}}}else{const p=l.getDeclarations();for(const y of p){if(y.getKindName()!=="FunctionDeclaration")continue;const h=y,T=h.getName(),x=T&&T.length>0?T:"default",d=h.getSignature(),S=fe(d,h),b=d.getReturnType().getText();f.push(await _(i,s,u,c,x,S,b,h.isAsync(),n,t))}}}const m=xt(s);if(m.length>0)for(const{name:g,sig:p}of m){if(M(g))continue;const y=W(p),h=p.getReturnType().getText(),T=[c,P(g)];f.push(await z(i,s,u,T,g,y,h,!1,n,t))}return f}function Tt(e,t,r,o){const n=new Set,i=s=>{if(Array.isArray(s))return s.map(i);if(!s||typeof s!="object"||n.has(s))return s;n.add(s);try{const a=s,c={};for(const[u,f]of Object.entries(a)){if(u==="definitions"||u==="$defs"){const l=u,m=t[l];for(const[g,p]of Object.entries(f)){const y=i(p),h=m[g];if(h!==void 0&&JSON.stringify(h)!==JSON.stringify(y))throw new Error(`[apigen-core-client] Function "${r}": param "${o}" contributes a "${l}.${g}" definition that conflicts with an identically-named definition already hoisted from another param/output in the same function. Two structurally different types share the same generated definition key, so apigen cannot safely merge them into one function-level schema.`);m[g]=y}continue}c[u]=i(f)}return c}finally{n.delete(s)}};return i(e)}async function _(e,t,r,o,n,i,s,a,c,u){const f=P(n);return z(e,t,r,[o,f],n,i,s,a,c,u)}async function z(e,t,r,o,n,i,s,a,c,u){const f=i.length>0&&i[0].name==="ctx",l=i.filter(d=>d.name!=="ctx"),m=l.filter(d=>!d.optional).map(d=>d.name),g={},p={definitions:{},$defs:{}};for(const d of l){const S=await A(e,t,d.type,c,u),b=Tt(S,p,n,d.name);d.defaultValue!==void 0&&dt(b,d.defaultValue),g[d.name]=b}const y=s.replace(/^Promise<(.+)>$/,"$1").trim(),h=await A(e,t,y,c,u),T={type:"object",properties:g,required:m,...Object.keys(p.definitions).length>0?{definitions:p.definitions}:{},...Object.keys(p.$defs).length>0?{$defs:p.$defs}:{}};return{id:ve(r,o),host:"ts",namespace:r,path:o,kind:"action",async:a,streaming:!1,safe:!1,input:T,output:h,envelope:{},typeText:{lang:"ts",input:wt(i),output:y},...f?{hasCtx:!0}:{}}}function St(e,t,r,o){const n=P(r),i=[t,n];return{id:ve(e,i),host:"ts",namespace:e,path:i,kind:"query",async:!1,streaming:!1,safe:!0,input:{type:"object",properties:{},required:[]},output:o,envelope:{},typeText:null}}function ve(e,t){return(e.raw?[e,...t]:t).map(o=>o.words.join("-")).join("/")}function te(e){return e.split(/[-_.]+/).flatMap(t=>t.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").split("_").filter(Boolean)).map(t=>t.toLowerCase()).filter(Boolean)}function P(e){return{raw:e,words:te(e)}}function bt(e){return e.replace(/\.[^.]+$/,"").replace(/[._]+/g,"-")}function xt(e){const t=[];for(const r of e.getStatements()){if(r.getKindName()!=="ExpressionStatement")continue;const o=r.getExpression();if(o.getKindName()!=="BinaryExpression")continue;const n=o;if(n.getLeft().getText().trim()!=="module.exports"||n.getOperatorToken().getKindName()!=="EqualsToken")continue;const s=n.getRight(),a=s.getType();for(const c of a.getProperties()){const f=c.getTypeAtLocation(s).getCallSignatures();f.length!==0&&t.push({name:c.getName(),sig:f[0]})}}return t}function vt(e){let t;for(const r of e){if(r.getKindName()!=="FunctionDeclaration")continue;const o=r;if(t||(t=o),o.getBody())return o}return t}function fe(e,t){return e.getParameters().map(r=>{var s;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:r.getTypeAtLocation(e.getDeclaration()).getText(),optional:i,defaultValue:ee(n,r.getName(),t)}})}function le(e,t,r){return e.getParameters().map(o=>{var a;const n=o.getDeclarations(),i=n.length>0&&n[0].getKindName()==="Parameter"?n[0]:null,s=o.isOptional()||((i==null?void 0:i.hasInitializer())??!1)||(((a=i==null?void 0:i.hasQuestionToken)==null?void 0:a.call(i))??!1);return{name:o.getName(),type:o.getTypeAtLocation(t).getText(),optional:s,defaultValue:ee(i,o.getName(),r??t)}})}function W(e,t){return e.getParameters().map(r=>{var s,a,c;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:n?n.getType().getText():((c=(a=r.getValueDeclaration())==null?void 0:a.getType())==null?void 0:c.getText())??"unknown",optional:i,defaultValue:ee(n,r.getName(),t)}})}function wt(e){const t=e.filter(r=>r.name!=="ctx");return t.length===0?"()":"("+t.map(r=>`${r.name}${r.optional?"?":""}: ${r.type}`).join(", ")+")"}function M(e){return!!(e==="__samples__"||e.startsWith("__"))}function k(e,t,r=new Set){if(e.getCallSignatures().length>0||e.getConstructSignatures().length>0)return!1;if(e.isString()||e.isNumber()||e.isBoolean()||e.isNull()||e.isUndefined()||e.isStringLiteral()||e.isNumberLiteral()||e.isBooleanLiteral()||e.isEnumLiteral())return!0;if(e.isArray()||e.isReadonlyArray()){const o=e.getArrayElementType();return o?k(o,t,r):!1}if(e.isTuple())return e.getTupleElements().every(o=>k(o,t,r));if(e.isUnion())return e.getUnionTypes().every(o=>k(o,t,r));if(e.isIntersection())return e.getIntersectionTypes().every(o=>k(o,t,r));if(e.isObject()){const o=e.getText(t);if(r.has(o))return!0;r.add(o);const n=e.getStringIndexType(),i=e.getNumberIndexType();if(n||i)return[n,i].every(a=>!a||k(a,t,r));const s=e.getProperties();return s.length===0?!0:s.every(a=>{const c=a.getTypeAtLocation(t);return k(c,t,r)})}return!1}async function jt(e){const t=e.session===void 0,r=de(e.session??X());try{return await $t(e,r)}finally{t&&r.dispose()}}async function $t(e,t){const{sourceFile:r,namespace:o="",tsconfig:n,includeInstances:i=!1}=e,s=t.projectFor(n),a=t.sourceFileFor(r,n),c=D.basename(r),u=F(Pt(c)),f=F(o),l=[];for(const[m,g]of a.getExportedDeclarations()){const p=g.find(T=>T.getKindName()==="ClassDeclaration");if(!p)continue;const y=m==="default"?p.getName():m;if(!y||U(y))continue;const h=F(y);for(const T of p.getStaticMethods()){const x=T.getName();if(U(x))continue;const d=T.getScope();if(d===C.Scope.Private||d===C.Scope.Protected)continue;const S=T.getSignature(),b=B(S,T),$=S.getReturnType().getText(),j=T.isAsync(),v=[u,h,F(x)];l.push(await At(s,a,f,v,b,$,j,n,t))}if(i){{const x=p.getConstructors()[0]??null;let d=[];if(x){const w=x.getSignature();d=B(w,x)}const S=[u,h],b=Q(f,S),$=d.filter(w=>w.name!=="ctx"),j=$.filter(w=>!w.optional).map(w=>w.name),v={};for(const w of $)v[w.name]=await A(s,a,w.type,n,t);l.push({id:b,host:"ts",namespace:f,path:S,kind:"constructor",async:!1,streaming:!1,safe:!1,input:{type:"object",properties:v,required:j},output:{type:"object",properties:{instanceId:{type:"string"}},required:["instanceId"]},envelope:{},typeText:{lang:"ts",input:Nt(d),output:"{ instanceId: string }"}})}for(const T of p.getInstanceMethods()){const x=T.getName();if(U(x))continue;const d=T.getScope();if(d===C.Scope.Private||d===C.Scope.Protected)continue;const S=T.getSignature(),b=B(S,T),$=S.getReturnType().getText(),j=T.isAsync(),v=[u,h,F(x)],w=Q(f,v),R=b.filter(N=>N.name!=="ctx"),K=R.filter(N=>!N.optional).map(N=>N.name),ne={};for(const N of R)ne[N.name]=await A(s,a,N.type,n,t);const re=$.replace(/^Promise<(.+)>$/,"$1").trim(),Pe=await A(s,a,re,n,t);l.push({id:w,host:"ts",namespace:f,path:v,kind:"instance-method",async:j,streaming:!1,safe:!1,input:{type:"object",properties:ne,required:K},output:Pe,envelope:{type:"object",properties:{instanceId:{type:"string"}},required:["instanceId"]},typeText:{lang:"ts",input:we(b),output:re}})}}}return l}async function At(e,t,r,o,n,i,s,a,c){const u=n.filter(y=>y.name!=="ctx"),f=u.filter(y=>!y.optional).map(y=>y.name),l={};for(const y of u)l[y.name]=await A(e,t,y.type,a,c);const m=i.replace(/^Promise<(.+)>$/,"$1").trim(),g=await A(e,t,m,a,c);return{id:Q(r,o),host:"ts",namespace:r,path:o,kind:"action",async:s,streaming:!1,safe:!1,input:{type:"object",properties:l,required:f},output:g,envelope:{},typeText:{lang:"ts",input:we(n),output:m}}}function Q(e,t){return(e.raw?[e,...t]:t).map(o=>o.words.join("-")).join("/")}function F(e){return{raw:e,words:te(e)}}function Pt(e){return e.replace(/\.[^.]+$/,"").replace(/[._]+/g,"-")}function B(e,t){return e.getParameters().map(r=>{var s;const o=r.getDeclarations(),n=o.length>0&&o[0].getKindName()==="Parameter"?o[0]:null,i=r.isOptional()||((n==null?void 0:n.hasInitializer())??!1)||(((s=n==null?void 0:n.hasQuestionToken)==null?void 0:s.call(n))??!1);return{name:r.getName(),type:r.getTypeAtLocation(t).getText(),optional:i}})}function we(e){const t=e.filter(r=>r.name!=="ctx");return t.length===0?"()":"("+t.map(r=>`${r.name}${r.optional?"?":""}: ${r.type}`).join(", ")+")"}function Nt(e){return e.length===0?"()":"("+e.map(t=>`${t.name}${t.optional?"?":""}: ${t.type}`).join(", ")+")"}function U(e){return!!(e==="__samples__"||e.startsWith("__")||e.startsWith("_"))}const Ot=new Map([[".ts","ts"],[".tsx","ts"],[".mts","ts"],[".cts","ts"],[".py","py"],[".rs","rust"],[".go","go"],[".java","java"]]);function je(e){const t=_e.extname(e).toLowerCase();return Ot.get(t)}function $e(e){return e.language??"ts"}function Ae(e,t){const r=je(t);return r===void 0?!1:r===$e(e)}function kt(e,t){return t.filter(r=>Ae(e,r))}exports.clearPersistentProjectCache=Ve;exports.composeSchemas=Ke;exports.createExtractionSession=X;exports.effectiveLanguage=$e;exports.extract=yt;exports.extractClasses=jt;exports.isPrimitiveOnlyInputSchema=ye;exports.languageOfSource=je;exports.pluginConsumesSource=Ae;exports.sourcesForPlugin=kt;exports.tokenize=te;
package/index.mjs CHANGED
@@ -191,7 +191,7 @@ function Fe(e, t) {
191
191
  'apigen calling convention: all domain parameters go inside a "data" envelope β€” e.g. { "data": { ... } }' + (t ? "." : " (an empty object for this zero-parameter tool).")
192
192
  ];
193
193
  return e.length > 0 && r.push(
194
- `Field(s) ${e.map((o) => `"${o}"`).join(", ")} are transport-level envelope metadata, NOT domain data β€” do not nest them under "data". Over MCP they are read from arguments._meta["x-<pluginId>-<field>"] (default pluginId "adhd"); see @adhd/apigen-naming's envelopeMetaKey/envelopeCliFlag/envelopeEnvVar for the HTTP-header / CLI-flag / env-var equivalents.`
194
+ `Field(s) ${e.map((o) => `"${o}"`).join(", ")} are transport-level envelope metadata, NOT domain data β€” do not nest them under "data". Over MCP they are read from arguments._meta["x-<pluginId>-<field>"] (default pluginId "adhd"); see @adhd/apigen-engine-naming's envelopeMetaKey/envelopeCliFlag/envelopeEnvVar for the HTTP-header / CLI-flag / env-var equivalents.`
195
195
  ), r.join(" ");
196
196
  }
197
197
  function Pt(e, t, r) {
@@ -71,7 +71,7 @@ export interface ApigenSchemaHints {
71
71
  *
72
72
  * Identity is carried by the tokenized `words`; the original `raw` spelling is
73
73
  * preserved so a same-host plugin can reproduce it, but every transport derives
74
- * its own casing from `words` via `@adhd/apigen-naming` (kebab for HTTP/CLI,
74
+ * its own casing from `words` via `@adhd/apigen-engine-naming` (kebab for HTTP/CLI,
75
75
  * `_`-joined for MCP, Pascal for gRPC). Casing is therefore per-plugin, never
76
76
  * baked into the descriptor.
77
77
  */
package/lib/types.d.ts CHANGED
@@ -44,6 +44,19 @@ export interface PluginInput {
44
44
  * a default stderr logger when this is absent.
45
45
  */
46
46
  logger?: Logger;
47
+ /**
48
+ * DEBT-APIGEN-PLUGIN-MCP-GENERATE-OPERATIONS-001: the full merged
49
+ * `Operation[]` descriptor (the same set `buildDescriptor()` produces),
50
+ * threaded through so `generate()` can call the real `project(op)` for
51
+ * every operation instead of falling back to a best-effort synthesized
52
+ * `Operation` (exact only for the single-source-file case; wrong for
53
+ * multi-file namespaces / npm-specifier importPath / default-object
54
+ * exports). Lifted from `RunInput` (BUG-APIGEN-024) onto the base
55
+ * `PluginInput` so both `generate()` and `run()` get real ops from the
56
+ * same field. Optional: absent for non-TS-extraction paths (e.g.
57
+ * py-flask) where nothing was extracted to describe.
58
+ */
59
+ operations?: Operation[];
47
60
  }
48
61
  export interface PluginOutput {
49
62
  files: Array<{
@@ -54,15 +67,6 @@ export interface PluginOutput {
54
67
  }
55
68
  export interface RunInput extends PluginInput {
56
69
  signal?: AbortSignal;
57
- /**
58
- * BUG-APIGEN-024: the full merged `Operation[]` descriptor (the same set
59
- * `buildDescriptor()` produces), threaded through so a `--use` mount plugin
60
- * (e.g. `apigen-plugin-openapi`) can build its real `Descriptor` instead of
61
- * the empty-`operations` stub `collectMountRoutes()` used to synthesize.
62
- * Absent for non-TS-extraction run paths (e.g. py-flask), where mount
63
- * plugins have nothing extracted to describe.
64
- */
65
- operations?: Operation[];
66
70
  }
67
71
  /** Source-language tags understood by apigen's routing layer. */
68
72
  export type PluginLanguage = 'ts' | 'py' | 'rust' | 'go' | 'java';
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@adhd/apigen-core-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "dependencies": {
5
5
  "ts-morph": "^23.0.0",
6
6
  "ts-json-schema-generator": "^2.3.0",
7
7
  "pino": "10.3.1",
8
8
  "typescript": "^6.0.3",
9
- "@adhd/apigen-base-logical": "^0.0.1"
9
+ "@adhd/apigen-base-logical": "^0.0.3"
10
10
  },
11
11
  "main": "./index.js",
12
12
  "module": "./index.mjs",