@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 +13 -4
- package/README.md +259 -4
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/lib/descriptor.d.ts +1 -1
- package/lib/types.d.ts +13 -9
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
6
|
-
|
|
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,
|
|
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
|
-
|
|
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) {
|
package/lib/descriptor.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
9
|
+
"@adhd/apigen-base-logical": "^0.0.3"
|
|
10
10
|
},
|
|
11
11
|
"main": "./index.js",
|
|
12
12
|
"module": "./index.mjs",
|