@adhd/apigen-core-client 0.1.0

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 ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@adhd/apigen-core-client` will be documented in this file.
4
+
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).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Fixed
11
+
12
+ - BUG-APIGEN-CORE-004: `isSerializableType()` used a purely textual allow-list over `type.getText()`, so a serializable const typed as a generic-utility-type wrapper — e.g. `Record<K, V>` — was rendered as text matching none of the allow-list's patterns and silently skipped instead of extracted as `kind:'query'`. Replaced with structural inspection of the ts-morph `Type` object (index signatures, properties, call/construct signatures, recursing through arrays/tuples/unions/intersections), which recognizes `Record<K, V>` and other generic wrappers (`Partial<T>`, `Readonly<T>`, `Array<T>`) around serializable shapes while still correctly excluding genuinely non-serializable generics like `Map<K, V>`. See `packages/apigen/apigen-core-client/BACKLOG.md`'s `## Fixed` section for full root-cause and fix detail.
13
+
14
+ ## [0.1.0] — 2026-07-02
15
+
16
+ ### Added
17
+
18
+ - `extract()` — v2 symbol-based extractor producing canonical `Operation[]` descriptors from TypeScript source. Handles all six export shapes (named fn, const/arrow, named-object, default named, anonymous default, CJS) plus renamed exports.
19
+ - `generateSchemas()` — v1 schema extraction with three export modes (named, default, named-object). Ctx first-param excluded by name match only.
20
+ - `composeSchemas()` — middleware envelope composition with `data: {}` wrapper. `false` override suppresses a middleware per-function.
21
+ - `extractClasses()` — class export extraction per SPEC §10. Static methods always extracted; constructor + instance methods opt-in via `includeInstances`.
22
+ - `createExtractionSession()` / `clearPersistentProjectCache()` — two-tier extraction cache (per-session + persistent process-lifetime). LRU-capped generator cache via `APIGEN_PROGRAM_CACHE`.
23
+ - `tokenize()` — camelCase/PascalCase/kebab-case/snake_case tokenizer for casing-neutral `Segment` records.
24
+ - `languageOfSource()` / `pluginConsumesSource()` / `sourcesForPlugin()` / `effectiveLanguage()` — polyglot source-language routing for multi-host `serve` mode.
25
+ - `OutputPlugin` (v1) — legacy `{ id, generate(input), run?(input) }` contract for codegen plugins.
26
+ - `Plugin<Opts>` (v2) — capability-based plugin interface: `target` (project descriptor), `layer` (wrap operations), `mount` (synthetic operations), `envelope` (side-channel fields).
27
+ - Transport-neutral v2 types: `Call`, `Next`, `Result`, `Chunk`, `Transport`, `Extensions`, `Descriptor`, `Harness`, `Server`, `File`.
28
+ - Canonical descriptor types: `Operation`, `Segment`, `JSONSchema`, `TypeText`, `OperationKind`, `ApigenSchemaHints`. JSON Schema 2020-12 IR with `$defs`/`$ref`.
29
+ - `PluginLanguage` union type (`'ts' | 'py' | 'rust' | 'go' | 'java'`).
30
+ - Internal schema builders: `buildSchema` (three-stage pipeline), `buildNominalSchema` (branded types with `x-apigen-logical:'nominal'`), `buildUnionSchema` (discriminated unions with `oneOf`).
31
+ - Logger types re-exported from `pino`.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # @adhd/apigen-core-client
2
+
3
+ > The core apigen engine — TypeScript source → JSON Schema extraction, composition, and the plugin contract every apigen target implements.
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.
8
+
9
+ Part of [apigen](../README.md). See the [apigen spec](../../../docs/apigen/SPEC.md) for the full architecture.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install @adhd/apigen-core-client
15
+ ```
16
+
17
+ ## Quickstart
18
+
19
+ Extract canonical operation descriptors from a TypeScript file, then compose them with middleware envelope fields:
20
+
21
+ ```ts
22
+ import { extract, composeSchemas, generateSchemas } from '@adhd/apigen-core-client';
23
+
24
+ // v2 extraction — walk a source file and produce Operation[] descriptors
25
+ const ops = await extract({ sourceFile: './src/api.ts' });
26
+ // ops[0].id === 'api/getUser'
27
+ // ops[0].kind === 'action'
28
+ // ops[0].input === { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] }
29
+
30
+ // v1 schema extraction — JSON Schema per exported function
31
+ const gen = await generateSchemas({ sourceFile: './src/api.ts' });
32
+
33
+ // Compose with middleware envelope fields
34
+ const composed = composeSchemas(gen, [
35
+ { id: 'auth', envelope: { session: { type: 'string' } } }
36
+ ]);
37
+ // composed.getUser.input.properties.data.properties.id.type === 'string'
38
+ // composed.getUser.input.properties.session.type === 'string'
39
+ ```
40
+
41
+ Real output from `composeSchemas` with an auth middleware — the `data` wrapper is always present, even for zero-param functions:
42
+
43
+ ```ts
44
+ import { composeSchemas } from '@adhd/apigen-core-client';
45
+
46
+ const composed = composeSchemas(
47
+ {
48
+ metadata: { namespace: 'demo', phase: '' },
49
+ schemas: {
50
+ getUser: {
51
+ input: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
52
+ output: { type: 'object', properties: { name: { type: 'string' } } }
53
+ },
54
+ ping: {
55
+ input: { type: 'object', properties: {} },
56
+ output: { type: 'string' }
57
+ }
58
+ }
59
+ },
60
+ [{ id: 'auth', envelope: { session: { type: 'string' } } }]
61
+ );
62
+ ```
63
+
64
+ ```
65
+ // => composed.getUser.input.properties.data.properties.id.type === 'string'
66
+ // => composed.getUser.input.properties.session.type === 'string'
67
+ // => composed.ping.input.properties.data.properties is {} (zero-param → empty data wrapper)
68
+ // => composed.ping.input.required === ['session', 'data'] (data always required)
69
+ ```
70
+
71
+ Source-language routing identifies file languages for polyglot pipelines:
72
+
73
+ ```ts
74
+ import { tokenize, languageOfSource, sourcesForPlugin } from '@adhd/apigen-core-client';
75
+
76
+ tokenize('humanizeBytes'); // => ['humanize', 'bytes']
77
+ tokenize('SOME_CONST'); // => ['some', 'const']
78
+
79
+ languageOfSource('src/api.ts'); // => 'ts'
80
+ languageOfSource('src/api.py'); // => 'py'
81
+ languageOfSource('README.md'); // => undefined
82
+
83
+ sourcesForPlugin({ language: 'ts' }, ['src/api.ts', 'src/api.py', 'README.md']);
84
+ // => ['src/api.ts']
85
+ ```
86
+
87
+ ## Features
88
+
89
+ ### v2 Symbol-Based Extraction
90
+
91
+ `extract()` walks a TypeScript source module and produces canonical `Operation[]` descriptors — one per exported function, const, or class member. Handles the full six-shape export matrix:
92
+
93
+ - **Named function exports** — `export function foo(…)`
94
+ - **Named const/arrow exports** — `export const foo = (…) => …`
95
+ - **Named-object exports** — `export const api = { foo, bar }`
96
+ - **Default-export named functions** — `export default function foo(…)`
97
+ - **Anonymous default exports** — `export default () => …` (id synthesized from filename)
98
+ - **CJS source** — `module.exports = { foo, bar }`
99
+
100
+ Each operation carries an `id` derived deterministically from `namespace/path`, a `kind` (action / query / constructor / instance-method), JSON Schema 2020-12 `input` and `output`, and optional `typeText` for same-host sugar.
101
+
102
+ ```ts
103
+ import { extract } from '@adhd/apigen-core-client';
104
+
105
+ const ops = await extract({ sourceFile: './src/api.ts', namespace: 'myapi' });
106
+ for (const op of ops) {
107
+ console.log(`${op.id} kind=${op.kind} async=${op.async} safe=${op.safe}`);
108
+ }
109
+ ```
110
+
111
+ ### Two-Tier Extraction Caching
112
+
113
+ Building a TypeScript program (parsing lib.d.ts + type-checking) is the dominant cost. Two cache layers eliminate redundant work:
114
+
115
+ - **Per-run `ExtractionSession`** — pass one session to every `extract` / `generateSchemas` / `extractClasses` call and they share one ts-morph Project per tsconfig, one schema generator per file, and memoized `(file, typeText)` schemas. `dispose()` releases the run.
116
+
117
+ - **Persistent process-lifetime tier** — Projects and generators are reused across sessions in the same process (watch/serve rebuilds, test loops), version-checked by mtime+size. The generator cache is LRU-capped (`APIGEN_PROGRAM_CACHE`, default 8 entries; each is a full TS program, ~100–200 MB). Set to `0` to disable persistence.
118
+
119
+ ```ts
120
+ import { createExtractionSession, extract, generateSchemas } from '@adhd/apigen-core-client';
121
+
122
+ const session = createExtractionSession();
123
+ // => session.stats === { projectsBuilt: 0, generatorsBuilt: 0, schemaCacheHits: 0, schemaCacheMisses: 0 }
124
+
125
+ try {
126
+ const ops = await extract({ sourceFile: './src/api.ts', session });
127
+ // session.stats.projectsBuilt is now 1 (first Project construction)
128
+ const gen = await generateSchemas({ sourceFile: './src/api.ts', session });
129
+ // session.stats.generatorsBuilt === 1, schemaCacheHits > 0 — pure cache hits
130
+ } finally {
131
+ session.dispose();
132
+ }
133
+ ```
134
+
135
+ **Important:** Do **not** parallelize `buildSchema` loops — the work is synchronous CPU under an async signature, and morph-walk mutates the shared SourceFile, so `Promise.all` gains nothing and can race.
136
+
137
+ ### v2 Plugin Capability Interface
138
+
139
+ The `Plugin` interface (SPEC §7.1) declares four orthogonal capabilities — a plugin implements only what it needs:
140
+
141
+ | Capability | Purpose | Example |
142
+ |-----------|---------|---------|
143
+ | `target` | Project descriptor to transport/format (codegen) or host functions in-process (serve) | MCP server, Fastify HTTP server, proto client |
144
+ | `layer` | Wrap all operations in the onion (middleware) | Logger, auth, rate-limiting |
145
+ | `mount` | Add synthetic operations | `/meta/openapi`, `/meta/health` |
146
+ | `envelope` | Declare transport-agnostic side-channel fields (request/response headers, metadata) | Session tokens, request IDs |
147
+
148
+ ```ts
149
+ import type { Plugin } from '@adhd/apigen-core-client';
150
+
151
+ // A minimal logger layer plugin
152
+ export default {
153
+ id: 'logger',
154
+ capabilities: {
155
+ layer: {
156
+ layer: async (call, next) => {
157
+ const t = Date.now();
158
+ console.error(`→ ${call.operation.id}`);
159
+ try {
160
+ const r = await next();
161
+ console.error(`← ${call.operation.id} ${Date.now() - t}ms`);
162
+ return r;
163
+ } catch (e) {
164
+ console.error(`✗ ${call.operation.id}`);
165
+ throw e;
166
+ }
167
+ },
168
+ },
169
+ },
170
+ } satisfies Plugin;
171
+ ```
172
+
173
+ All transports (`http`, `grpc`, `mcp`, `cli`) share the same `Call` / `Next` / `Result` / `Chunk` contract. The v1 `OutputPlugin` interface coexists — migrate by wrapping `generate(PluginInput)` in a `TargetCapability.generate(Descriptor)`.
174
+
175
+ ### Schema Pipeline: generateSchemas + composeSchemas
176
+
177
+ `generateSchemas` supports three mutually exclusive extraction modes:
178
+
179
+ - **`named`** (default) — per-function schemas for all exported functions
180
+ - **`default`** — treat the default export as the sole function
181
+ - **`named-object`** — extract from `export const api = { … }` by object name
182
+
183
+ The first parameter named `ctx` is excluded from the schema by name-match only (`ctx-name-only` invariant) and recorded via `hasCtx` so dispatch can re-inject it.
184
+
185
+ `composeSchemas` folds middleware envelope fields into the composed `input`, always wrapping domain params in a `data: {}` wrapper. Override a middleware per-function with `false` to suppress its contribution.
186
+
187
+ ### Polyglot Source-Language Routing
188
+
189
+ When `apigen serve` watches a directory containing multiple host languages, the source-language helpers route each file to the correct plugin:
190
+
191
+ ```ts
192
+ import { languageOfSource, pluginConsumesSource, sourcesForPlugin } from '@adhd/apigen-core-client';
193
+
194
+ languageOfSource('src/api.py'); // => 'py'
195
+ pluginConsumesSource({ language: 'py' }, 'src/api.py'); // => true
196
+ pluginConsumesSource({ language: 'ts' }, 'src/api.py'); // => false
197
+
198
+ sourcesForPlugin({ language: 'ts' }, ['src/api.ts', 'src/utils.mts', 'src/api.py']);
199
+ // => ['src/api.ts', 'src/utils.mts']
200
+ ```
201
+
202
+ Recognized extensions: `.ts/.tsx/.mts/.cts` → `ts`, `.py` → `py`, `.rs` → `rust`, `.go` → `go`, `.java` → `java`. Plugins without an explicit `language` default to `'ts'`.
203
+
204
+ ### Class Extraction
205
+
206
+ `extractClasses()` extracts exported class members per SPEC §10:
207
+ - **Static methods** — always extracted as `kind: 'action'`
208
+ - **Constructor** — opt-in via `includeInstances: true`, emits `kind: 'constructor'` with `instanceId` output
209
+ - **Instance methods** — opt-in, emit `kind: 'instance-method'` with `instanceId` envelope
210
+ - Private/protected members are skipped; `_`-prefixed methods are skipped (SPEC §3 opt-out ladder)
211
+
212
+ ## Module Map
213
+
214
+ | Module | Purpose | Key Exports |
215
+ |--------|---------|-------------|
216
+ | [Extract](./docs/reference/extract.md) | v2 symbol-based extraction | `extract()`, `tokenize()`, `ExtractOptions` |
217
+ | [Schemas](./docs/reference/schemas.md) | Schema generation & composition | `generateSchemas()`, `composeSchemas()`, `GenerateSchemasOptions`, `ComposedSchemas` |
218
+ | [Plugin](./docs/reference/plugin.md) | v1 & v2 Plugin contracts | `Plugin`, `OutputPlugin`, `TargetCapability`, `LayerCapability`, `MountCapability`, `EnvelopeCapability` |
219
+ | [Extraction Session](./docs/reference/session.md) | Per-run caching | `createExtractionSession()`, `clearPersistentProjectCache()`, `ExtractionSession` |
220
+ | [Extract Classes](./docs/reference/extract-classes.md) | Class export extraction | `extractClasses()`, `ExtractClassesOptions` |
221
+ | [Source Language](./docs/reference/source-language.md) | Polyglot file routing | `languageOfSource()`, `sourcesForPlugin()`, `pluginConsumesSource()` |
222
+ | [Descriptor](./docs/reference/descriptor.md) | Canonical types | `Operation`, `Segment`, `JSONSchema`, `TypeText`, `OperationKind` |
223
+
224
+ ## How-To Guides
225
+
226
+ - [End-to-End Extraction Pipeline](./docs/how-to/extraction-pipeline.md) — From source file to composed schemas
227
+ - [Building apigen Plugins](./docs/how-to/building-plugins.md) — v1 OutputPlugin and v2 Plugin development
228
+
229
+ ## Develop
230
+
231
+ ```bash
232
+ npx nx build apigen-core-client
233
+ npx nx test apigen-core-client
234
+ ```
235
+
236
+ ## License
237
+
238
+ MIT — see [LICENSE](./LICENSE).
package/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export type { GeneratedSchemas, ComposedSchemas, ExportMode, PluginInput, PluginOutput, RunInput, OutputPlugin, PluginLanguage, } from './lib/types';
2
+ export type { Operation, OperationKind, Segment, TypeText, JSONSchema, ApigenSchemaHints, } from './lib/descriptor';
3
+ export type { Plugin, TargetCapability, LayerCapability, MountCapability, MountedOperation, EnvelopeCapability, Call, Next, Result, Chunk, Transport, Extensions, Descriptor, Harness, Server, File, } from './lib/plugin';
4
+ export type { Logger } from 'pino';
5
+ export { createExtractionSession, clearPersistentProjectCache, } from './lib/extraction-session';
6
+ export type { ExtractionSession, ISessionStats, } from './lib/extraction-session';
7
+ export { composeSchemas } from './lib/compose-schemas';
8
+ export { isPrimitiveOnlyInputSchema } from './lib/get-safety';
9
+ export { extract, tokenize } from './lib/extract';
10
+ export type { ExtractOptions } from './lib/extract';
11
+ export { extractClasses } from './lib/extract-classes';
12
+ export type { ExtractClassesOptions } from './lib/extract-classes';
13
+ export { languageOfSource, pluginConsumesSource, sourcesForPlugin, effectiveLanguage, } from './lib/source-language';
14
+ export type { LanguageAwarePlugin } from './lib/source-language';
package/index.js ADDED
@@ -0,0 +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;