@adhd/apigen-engine-runtime 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 ADDED
@@ -0,0 +1,85 @@
1
+ ## 0.1.2 (2026-07-23)
2
+
3
+
4
+ ### ๐Ÿš€ Features
5
+
6
+ - session batch โ€” dispatch tool-exec + provider routing, publish hygiene, agent/env/apigen fixes
7
+
8
+ - **release:** nx release independent versioning + verify-dist-load publish gate (Agent 2)
9
+
10
+
11
+ ### ๐Ÿฉน Fixes
12
+
13
+ - resolve build errors from workspace-cleanup merge โ€” unterminated strings, path mappings, lint
14
+
15
+ - **apigen:** update remaining stale @adhd/apigen-errors, core, logical refs
16
+
17
+ - **apigen:** repair unterminated string literals from sed, fix apigen-core-client deps
18
+
19
+ - **apigen-core-client:** follow re-exports in extract()/extractClasses()
20
+
21
+ - **apigen-engine-runtime:** stop pre-commit --fix from deleting ajv/ajv-formats
22
+
23
+ - **apigen:** dangling $ref crash (BUG-APIGEN-026) and undefined-optional-param crash (BUG-APIGEN-027)
24
+
25
+ - **apigen:** BUG-APIGEN-036 โ€” named-type-param.spec.ts still called deleted v1 generateSchemas()
26
+
27
+ - **apigen-engine-runtime:** BUG-APIGEN-030 โ€” register x-apigen-* / discriminator as known Ajv keywords
28
+
29
+ - **apigen:** BUG-APIGEN-017/018/019/020 โ€” MCP tool-schema hardening bundle
30
+
31
+ - **apigen:** FEAT-APIGEN-022 + BUG-APIGEN-025 โ€” auto-hoist GET by param shape, wire x-apigen-safe
32
+
33
+ - **apigen:** BUG-APIGEN-033 โ€” anonymous default-export functions crash at dispatch instead of dispatching
34
+
35
+ - **apigen-core-client:** BUG-APIGEN-029 โ€” hoist nested definitions so complex/self-referential type $refs resolve at dispatch time
36
+
37
+ - **apigen:** externalize real npm deps in vite builds โ€” 10 packages shipped broken dist bundles (__filename/timeOrigin crash)
38
+
39
+
40
+ ### โค๏ธ Thank You
41
+
42
+ - pseudosky
43
+
44
+ ## 0.1.1 (2026-07-23)
45
+
46
+
47
+ ### ๐Ÿš€ Features
48
+
49
+ - session batch โ€” dispatch tool-exec + provider routing, publish hygiene, agent/env/apigen fixes
50
+
51
+ - **release:** nx release independent versioning + verify-dist-load publish gate (Agent 2)
52
+
53
+
54
+ ### ๐Ÿฉน Fixes
55
+
56
+ - resolve build errors from workspace-cleanup merge โ€” unterminated strings, path mappings, lint
57
+
58
+ - **apigen:** update remaining stale @adhd/apigen-errors, core, logical refs
59
+
60
+ - **apigen:** repair unterminated string literals from sed, fix apigen-core-client deps
61
+
62
+ - **apigen-core-client:** follow re-exports in extract()/extractClasses()
63
+
64
+ - **apigen-engine-runtime:** stop pre-commit --fix from deleting ajv/ajv-formats
65
+
66
+ - **apigen:** dangling $ref crash (BUG-APIGEN-026) and undefined-optional-param crash (BUG-APIGEN-027)
67
+
68
+ - **apigen:** BUG-APIGEN-036 โ€” named-type-param.spec.ts still called deleted v1 generateSchemas()
69
+
70
+ - **apigen-engine-runtime:** BUG-APIGEN-030 โ€” register x-apigen-* / discriminator as known Ajv keywords
71
+
72
+ - **apigen:** BUG-APIGEN-017/018/019/020 โ€” MCP tool-schema hardening bundle
73
+
74
+ - **apigen:** FEAT-APIGEN-022 + BUG-APIGEN-025 โ€” auto-hoist GET by param shape, wire x-apigen-safe
75
+
76
+ - **apigen:** BUG-APIGEN-033 โ€” anonymous default-export functions crash at dispatch instead of dispatching
77
+
78
+ - **apigen-core-client:** BUG-APIGEN-029 โ€” hoist nested definitions so complex/self-referential type $refs resolve at dispatch time
79
+
80
+ - **apigen:** externalize real npm deps in vite builds โ€” 10 packages shipped broken dist bundles (__filename/timeOrigin crash)
81
+
82
+
83
+ ### โค๏ธ Thank You
84
+
85
+ - pseudosky
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("ts-morph");require("node:fs");require("node:path");require("ts-json-schema-generator");const N=require("pino"),ge=require("ajv"),we=require("ajv-formats"),I="$apigen";class K extends Error{constructor(t){super(t),this.code="E_DUP_CODEC",this.name="CodecRegistryError"}}function be(e){const t=new Map;return{register(r,n){if(t.has(r.id)&&!(n!=null&&n.override))throw new K(`E_DUP_CODEC: a codec is already registered for id "${r.id}"`);t.set(r.id,r)},resolve(r){for(const n of t.values())if(n.matches(r))return n},get(r){return t.get(r)},ids(){return[...t.keys()]},freeze(){const r=new Map(t),n={register(){throw new K("E_DUP_CODEC: registry is frozen and cannot accept new codecs")},resolve(o){for(const i of r.values())if(i.matches(o))return i},get(o){return r.get(o)},ids(){return[...r.keys()]},freeze(){return n}};return n}}}const L="x-apigen-logical",U="x-apigen-codec",k="x-apigen-ctor",x="x-apigen-tojson",ve="0.1.0";function V(e,t){return{registry:e,resolve:r=>{throw new Error(`[apigen-logical] $ref "${r}" cannot be resolved in run-mode without a descriptor root. Supply a resolve() in the ctx override to handle $ref.`)},seen:new WeakSet,path:"",mode:"strict",...t}}function b(e,t,r){const n=r.registry.resolve(t);if(n)return n.encode(e,t,r);const o=t.$ref;if(typeof o=="string"){const s=r.resolve(o);return b(e,s,r)}const i=t.oneOf;if(Array.isArray(i)){const s=te(e,i,t);return b(e,s,r)}const a=t.type;if(a==="array"){if(!Array.isArray(e))return j(e,t,r);const s=t.items;if(!s)return e.map(c=>g(c));const f=r.path;return Array.isArray(s)?e.map((c,u)=>{const d=s[u];return d===void 0?g(c):b(c,d,{...r,path:`${f}/${u}`})}):e.map((c,u)=>b(c,s,{...r,path:`${f}/${u}`}))}if(a==="object"){if(e===null||typeof e!="object"||Array.isArray(e))return j(e,t,r);const s=t.properties;if(!s)return g(e);const f=r.path,c={};for(const[u,d]of Object.entries(s)){const p=e[u];p!==void 0&&(c[u]=b(p,d,{...r,path:`${f}/${u}`}))}return c}return a==null?j(e,t,r):g(e)}function v(e,t,r){const n=r.registry.resolve(t);if(n)return n.decode(e,t,r);const o=t.$ref;if(typeof o=="string"){const s=r.resolve(o);return v(e,s,r)}const i=t.oneOf;if(Array.isArray(i)){const s=te(e,i,t);return v(e,s,r)}const a=t.type;if(a==="array"){if(!Array.isArray(e))return e;const s=t.items;if(!s)return e;const f=r.path;return Array.isArray(s)?e.map((c,u)=>{const d=s[u];return d===void 0?c:v(c,d,{...r,path:`${f}/${u}`})}):e.map((c,u)=>v(c,s,{...r,path:`${f}/${u}`}))}if(a==="object"){if(e===null||typeof e!="object"||Array.isArray(e))return e;const s=t.properties;if(!s)return e;const f=r.path,c={};for(const[u,d]of Object.entries(s)){const p=e[u];p!==void 0&&(c[u]=v(p,d,{...r,path:`${f}/${u}`}))}return c}return a==null?$e(e,r):e}function te(e,t,r,n){const o=r.discriminator;if(o!=null&&o.propertyName){const i=e!==null&&typeof e=="object"?e[o.propertyName]:void 0;if(typeof i=="string"&&o.mapping){const a=o.mapping[i];if(a){const s=t.find(f=>f.$ref===a);if(s)return s}}}return t[0]??{}}function j(e,t,r){for(const n of r.registry.ids()){const o=r.registry.get(n);if(o)try{const i=o.encode(e,o.schema,r);return{[I]:n,v:i}}catch{}}return g(e)}function $e(e,t){if(e!==null&&typeof e=="object"&&!Array.isArray(e)&&I in e){const r=e,n=r[I],o=t.registry.get(n);if(o)return o.decode(r.v,o.schema,t)}return e}function g(e){if(e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(g);if(typeof e=="object"){const t={};for(const[r,n]of Object.entries(e))n!==void 0&&(t[r]=g(n));return t}return null}function Ne(e){return{encode(t,r,n){const o=V(e,n);return b(t,r,o)},decode(t,r,n){const o=V(e,n);return v(t,r,o)}}}const P={id:"date-time",kind:"scalar",schema:{type:"string",format:"date-time"},matches(e){return e.type==="string"&&e.format==="date-time"},encode(e,t,r){return e.toISOString()},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[date-time] expected a string on the wire at "${r.path}", got ${typeof e}`);return new Date(String(e))}if(r.mode==="strict"&&Number.isNaN(new Date(e).getTime()))throw new TypeError(`[date-time] invalid date-time string at "${r.path}": ${JSON.stringify(e)}`);return new Date(e)}},R={id:"int64",kind:"scalar",schema:{type:"string",format:"int64"},matches(e){return e.type==="string"&&e.format==="int64"},encode(e,t,r){return String(e)},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[int64] expected a string on the wire at "${r.path}", got ${typeof e}`);try{return BigInt(Math.trunc(Number(e)))}catch{return BigInt(0)}}if(r.mode==="strict")return BigInt(e);if(/^-?\d+$/.test(e))try{return BigInt(e)}catch{return BigInt(0)}return BigInt(0)}},q={id:"decimal",kind:"scalar",schema:{type:"string",format:"decimal"},matches(e){return e.type==="string"&&e.format==="decimal"},encode(e,t,r){return e},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[decimal] expected a string on the wire at "${r.path}", got ${typeof e}`);return String(e)}if(r.mode==="strict"&&!/^-?\d+(\.\d+)?$/.test(e))throw new TypeError(`[decimal] wire value "${e}" at "${r.path}" is not a valid decimal string`);return e}},B={id:"byte",kind:"scalar",schema:{type:"string",format:"byte"},matches(e){return e.type==="string"&&e.format==="byte"},encode(e,t,r){return Buffer.from(e).toString("base64")},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[byte] expected a base64 string on the wire at "${r.path}", got ${typeof e}`);return new Uint8Array(0)}if(r.mode==="strict"&&!/^[A-Za-z0-9+/]*={0,2}$/.test(e))throw new TypeError(`[byte] wire value at "${r.path}" is not standard base64 (format:byte): "${e}"`);return new Uint8Array(Buffer.from(e,"base64"))}},Oe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,W={id:"uuid",kind:"scalar",schema:{type:"string",format:"uuid"},matches(e){return e.type==="string"&&e.format==="uuid"},encode(e,t,r){return e.toLowerCase()},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[uuid] expected a string on the wire at "${r.path}", got ${typeof e}`);return String(e).toLowerCase()}if(r.mode==="strict"&&!Oe.test(e))throw new TypeError(`[uuid] wire value "${e}" at "${r.path}" is not a lowercase-hyphenated RFC 4122 UUID`);return e}},C="NaN",T="Infinity",M="-Infinity",Ae=new Set([C,T,M]),F={id:"number-special",kind:"scalar",schema:{type:"number"},matches(e){return e.type==="number"&&e.format===void 0},encode(e,t,r){return Number.isNaN(e)?C:e===1/0?T:e===-1/0?M:e},decode(e,t,r){if(typeof e=="number")return e;if(typeof e=="string"){if(e===C)return NaN;if(e===T)return 1/0;if(e===M)return-1/0;const n=Number(e);if(!Number.isNaN(n))return n}if(r.mode==="strict")throw new TypeError(`[number-special] unrecognized wire value at "${r.path}": ${JSON.stringify(e)}. Expected a number or one of ${[...Ae].join(", ")}.`);return NaN}},je=[P,R,q,B,W,F];function _e(e,t={}){for(const r of je)e.register(r,{override:t.override??!1})}P.id,R.id,q.id,B.id,W.id,F.id;const re=be();_e(re);const ne=Ne(re.freeze());function oe(e,t){var n;const r=((n=e.input)==null?void 0:n.properties)??{};return t in r}function ie(e){var r,n;const t=(n=(r=e.input)==null?void 0:r.properties)==null?void 0:n.data;return Object.keys((t==null?void 0:t.properties)??{})}function Se(e,t){var o,i,a;const r=(a=(i=(o=e.input)==null?void 0:o.properties)==null?void 0:i.data)==null?void 0:a.properties,n=r==null?void 0:r[t];return n!==void 0?n:void 0}function Ee(e,t){return t===void 0||e===void 0?e:ne.decode(e,t)}function _(e,t){const r=t.output;return!r||Object.keys(r).length===0?e:ne.encode(e,r)}async function se(e,t,r,n,o,i){const s=ie(r).map(c=>Ee(i[c],Se(r,c)));if(oe(r,"session")&&t){const c=await t({session:o.session}),u=await e[n](c,...s);return _(u,r)}if(r.hasCtx){const c=t?await t(o):void 0,u=await e[n](c,...s);return _(u,r)}const f=await e[n](...s);return _(f,r)}class Ie{constructor(){this._map=new Map}set(t,r){this._map.set(t,r)}get(t){return this._map.get(t)}has(t){return this._map.has(t)}}function ke(e=[]){return async function(r,n,o){const i=o.schemas[r];if(!i)throw new Error(`apigen/invoke: no schema found for operation "${r}"`);const a=()=>se(o.fns,o.createClient,i,r,n.envelope,n.domainArgs);return e.reduceRight((f,c)=>()=>c(n,f),a)()}}function xe(e){return e}class ae{constructor(){this.handlers=new Map}on(t,r){const n=this.handlers.get(t)??[];return this.handlers.set(t,[...n,r]),()=>this.off(t,r)}off(t,r){const n=this.handlers.get(t);if(!n)return;const o=n.filter(i=>i!==r);o.length===0?this.handlers.delete(t):this.handlers.set(t,o)}clear(){this.handlers.clear()}async emit(t){for(const[r,n]of this.handlers)if(Ce(r,t))for(const o of n)await o(t)}}function Ce(e,t){const[r,n,o]=e.split(":");return!(r!=="*"&&r!==t.module||n&&n!=="*"&&n!==t.method||o&&o!=="*"&&o!==t.lifecycle)}function ce(e,t){for(const r of e)if(r.eventMapping)for(const[n,o]of Object.entries(r.eventMapping))t.on(n,o)}async function ue(e,t,r){let n={...t};for(const o of e)if(o.createContext){await r.emit({module:o.id,method:"createContext",lifecycle:"start",ctx:n});try{const i=await o.createContext(n);n={...n,...i},await r.emit({module:o.id,method:"createContext",lifecycle:"complete",ctx:n})}catch(i){throw await r.emit({module:o.id,method:"createContext",lifecycle:"error",ctx:n,error:i}),i}}return n}function J(e,t){const r=new Set,n=[e];for(;n.length>0;){const o=n.pop();if(!o||r.has(o))continue;r.add(o);const i=o.$ref;if(typeof i=="string"){if(t){const d=t[i];if(!d){const p=Object.keys(t).join(", ")||"(none)";throw new Error(`[apigen-logical] $ref "${i}" cannot be resolved. Available $defs: ${p}`)}n.push(d)}continue}const a=o.oneOf;if(Array.isArray(a))for(const d of a)typeof d=="object"&&d!==null&&n.push(d);const s=o.properties;if(s)for(const d of Object.values(s))n.push(d);const f=o.items;if(Array.isArray(f))for(const d of f)typeof d=="object"&&d!==null&&n.push(d);else typeof f=="object"&&f!==null&&n.push(f);const c=o.additionalProperties;typeof c=="object"&&c!==null&&n.push(c);const u=o.propertyNames;typeof u=="object"&&u!==null&&n.push(u)}}const H=new Set(["string","number","boolean","integer"]);function Te(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"?H.has(r):Array.isArray(r)?r.every(n=>H.has(n)||n==="null"):Array.isArray(t.enum)&&t.enum.length>0?t.enum.every(n=>["string","number","boolean"].includes(typeof n)):!1}function Me(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(Te)}function De(e){const t={},r=n=>{for(const o of["definitions","$defs"]){const i=n[o];if(i)for(const[a,s]of Object.entries(i)){const f=a.startsWith("#/")?a:`#/${o}/${a}`;t[f]=s}}};for(const n of Object.values(e.schemas))r(n.input),r(n.output);if(Object.keys(t).length!==0)for(const[n,o]of Object.entries(e.schemas))try{J(o.input,t),J(o.output,t)}catch(i){throw new Error(`[apigen-core-client] Schema validation failed for function "${n}": ${i.message}`)}}function Le(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(n=>`"${n}"`).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 Ue(e,t,r){De(e);const n={};for(const[o,i]of Object.entries(e.schemas)){const a=(r==null?void 0:r[o])??{},s=i.input.properties??{},f=i.input.required??[],c={},u=[];for(const y of t)if(y.envelope&&a[y.id]!==!1)for(const[m,A]of Object.entries(y.envelope))c[m]=A,u.includes(m)||u.push(m);const d={type:"object",properties:s,additionalProperties:!1,...f.length>0?{required:f}:{}},p=i.safe===!0||Me(i.input),w=i.input.definitions,l=i.input.$defs;n[o]={input:{type:"object",properties:{...c,data:d},required:[...u,...f.length>0?["data"]:[]],additionalProperties:!1,description:Le(Object.keys(c),Object.keys(s).length>0),...w?{definitions:w}:{},...l?{$defs:l}:{}},output:i.output,...i.hasCtx?{hasCtx:!0}:{},"x-apigen-safe":p}}return n}const Pe={"decimal.js":"Decimal"};function Re(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}Object.entries(Pe).map(([e,t])=>({pattern:new RegExp(`import\\(["'][^"']*${Re(e)}[^"']*["']\\)\\.\\w+`,"g"),key:t}));class D extends Error{constructor(t){super(t),this.name="ConfigurationError"}}function fe(e){for(const t of e)for(const r of Object.keys(t.eventMapping??{})){const[n]=r.split(":");if(n!=="*"&&n===t.id)throw new D(`Middleware "${t.id}" subscribes to its own events via "${r}". This would cause infinite recursion.`)}}function qe(e){const{domainSchemas:t,middlewares:r,overrides:n={},strict:o=!1}=e;fe(r);for(const c of Object.keys(n))if(!(c in t.schemas)){const u=`Override key "${c}" not found in domain schemas.`;if(o)throw new D(u);console.warn("[apigen-runtime]",u)}const i=new Set(r.map(c=>c.id));for(const[c,u]of Object.entries(n))for(const d of Object.keys(u??{}))if(!i.has(d)){const p=`Override key "${c}.${d}" does not match any declared middleware id.`;if(o)throw new D(p);console.warn("[apigen-runtime]",p)}const a=Ue(t,r,n),s=new ae;return ce(r,s),{schemas:a,createClient:async c=>ue(r,c,s),dispose:()=>s.clear()}}function Be(e={}){const t=e.level??"info",r=typeof e.destination=="string"&&e.destination.length>0,n=!r&&!!process.stderr.isTTY,o=e.format??(n?"pretty":"json"),i={level:t};if(o==="pretty")return i.transport={target:"pino-pretty",options:{colorize:!r,translateTime:"SYS:HH:MM:ss.l",ignore:"pid,hostname",...r?{destination:e.destination,mkdir:!0}:{destination:2}}},N(i);const a=r?N.destination({dest:e.destination,mkdir:!0,sync:!0}):N.destination(2);return N(i,a)}function de(e){return e?e.type==="array"?`${de(e.items)}[]`:e.enum?"enum":e.$ref?String(e.$ref).split("/").pop()||"object":e.anyOf||e.oneOf?"union":e.type??"object":"unknown"}function We(e){var s;const r=(s=((e==null?void 0:e.input)??{}).properties)==null?void 0:s.data,n=(r==null?void 0:r.properties)??{},o=new Set((r==null?void 0:r.required)??[]),i=Object.entries(n).map(([f,c])=>({name:f,type:de(c),required:o.has(f)})),a=i.map(f=>`${f.name}${f.required?"":"?"}: ${f.type}`).join(", ");return{params:i,text:a}}function Fe(e){let t;return Array.isArray(e)?t=e:e?t=[e]:t=[],t.find(r=>r==="number"||r==="integer"||r==="boolean")}function ze(e,t){var i,a;const n=((a=(i=((t==null?void 0:t.input)??{}).properties)==null?void 0:i.data)==null?void 0:a.properties)??{},o={...e};for(const[s,f]of Object.entries(n)){const c=o[s];if(typeof c!="string")continue;const u=Fe(f==null?void 0:f.type);if(u==="number"||u==="integer"){const d=Number(c);!Number.isNaN(d)&&c.trim()!==""&&(o[s]=d)}else u==="boolean"&&(c==="true"?o[s]=!0:c==="false"&&(o[s]=!1))}return o}const G=new Set(["default","module.exports","__esModule"]);function Ke(e){const t={},r=(n,o)=>{for(const[i,a]of Object.entries(n))if(typeof a=="function"){!G.has(i)&&!(i in t)&&(t[i]=a);const s=a.name;s&&!(s in t)&&(t[s]=a)}else a&&typeof a=="object"&&o<2&&G.has(i)&&r(a,o+1)};return r(e,0),t}const Ve=["invalid_argument","unauthenticated","permission_denied","not_found","internal"];class z extends Error{constructor(t,r,n){super(r),this.name="ApiError",this.code=t,this.details=n,Object.setPrototypeOf(this,new.target.prototype)}toJSON(){const t={code:this.code,message:this.message};return this.details!==void 0&&(t.details=this.details),t}}function Je(e){return typeof e=="object"&&e!==null&&e.name==="ApiError"&&Ve.includes(e.code)&&typeof e.toJSON=="function"}function Y(e,t,r=0){return e==="before-first-chunk"?{phase:e,error:t}:{phase:e,error:t,chunksDelivered:r}}const $=new ge({allErrors:!0});we($);for(const e of[L,U,k,x,"discriminator"])$.addKeyword({keyword:e,valid:!0});$.addFormat("decimal",/^[+-]?(?:\d+(?:\.\d+)?|\.\d+)$/);function pe(e){return e.map(t=>`${t.instancePath||"(root)"} ${t.message??"failed schema check"}`).join("; ")}const He=async(e,t)=>{const r=e.ctx.get(le);if(r===void 0)return t();const n=e.operation.id,o=r[n];if(o===void 0)return t();const i={data:e.domainArgs,...e.envelope},a=$.compile(o.input);if(!a(i)){const f=a.errors??[];throw new z("invalid_argument",`Validation failed: ${pe(f)}`,f)}return t()},le=Symbol("ValidateSchemasToken");function Ge(e){return async function(r,n){const o=r.operation.id,i=e[o];if(i===void 0)return n();const a={data:r.domainArgs,...r.envelope},s=$.compile(i.input);if(!s(a)){const c=s.errors??[];throw new z("invalid_argument",`Validation failed: ${pe(c)}`,c)}return n()}}function Ye(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}class Qe{constructor(t={}){var n,o;this._store=new Map,this._sweeper=null,this._defaultTtlMs=t.defaultTtlMs;let r=null;t.sweepIntervalMs===0?r=null:t.sweepIntervalMs!==void 0?r=t.sweepIntervalMs:this._defaultTtlMs!==void 0?r=Math.max(1e3,Math.floor(this._defaultTtlMs/4)):r=null,r!==null&&r>0&&(this._sweeper=setInterval(()=>this._sweep(),r),(o=(n=this._sweeper).unref)==null||o.call(n))}create(t,r=[],n){const o=new t(...r),i=Ye(),a=n??this._defaultTtlMs,s=a!==void 0?Date.now()+a:null;return this._store.set(i,{instance:o,expiresAt:s}),{instanceId:i}}get(t){const r=this._store.get(t);if(!r)throw new Error(`[instance-registry] Unknown instanceId: "${t}"`);if(r.expiresAt!==null&&Date.now()>r.expiresAt)throw this._evict(t,r),new Error(`[instance-registry] Instance "${t}" has expired`);return r.instance}async dispatch(t,r,n=[]){const o=this.get(t),i=o[r];if(typeof i!="function")throw new Error(`[instance-registry] Method "${r}" not found on instance "${t}"`);return i.call(o,...n)}async dispose(t){const r=this._store.get(t);r&&(this._store.delete(t),await S(r.instance))}async disposeAll(){this._sweeper!==null&&(clearInterval(this._sweeper),this._sweeper=null);const t=[...this._store.entries()];this._store.clear(),await Promise.all(t.map(([,r])=>S(r.instance)))}get size(){return this._store.size}_sweep(){const t=Date.now();for(const[r,n]of this._store)n.expiresAt!==null&&t>n.expiresAt&&this._evict(r,n)}_evict(t,r){this._store.delete(t),S(r.instance)}}async function S(e){if(e!==null&&typeof e=="object"&&"dispose"in e){const t=e.dispose;typeof t=="function"&&await t.call(e)}}function Xe(e){const{produce:t,signal:r}=e,n=r??new AbortController().signal;return{[Symbol.asyncIterator](){const o=t(n);return{async next(){return n.aborted?(await o.return(void 0),{done:!0,value:void 0}):o.next()},async return(i){return await o.return(i),{done:!0,value:void 0}},async throw(i){return await o.throw(i),{done:!0,value:void 0}}}}}}async function Ze(e){const t=[];for await(const r of e)t.push(r);return t}async function et(e){const t=[];try{for await(const r of e)t.push(r);return{ok:!0,chunks:t}}catch(r){const n=Je(r)?r:new z("internal",r instanceof Error?r.message:String(r));return t.length===0?{ok:!1,carrier:Y("before-first-chunk",n)}:{ok:!1,carrier:Y("after-first-chunk",n,t.length)}}}function tt(e){return e!==null&&typeof e=="object"&&Symbol.asyncIterator in e}class h extends Error{constructor(t,r){super(r),this.name="UnionCodecError",this.code=t}}function E(e){const t=e.discriminator;if(t===null||typeof t!="object"||Array.isArray(t))return;const r=t;if(typeof r.propertyName!="string")return;const n=r.mapping;if(!(n===null||typeof n!="object"||Array.isArray(n)))return{propertyName:r.propertyName,mapping:n}}function ye(e,t){const r=e[U];if(typeof r=="string"){const n=t.registry.get(r);if(n)return n}return t.registry.resolve(e)}function rt(e,t,r){const n=ye(t,r);return n?n.encode(e,t,r):e}function nt(e,t,r){const n=ye(t,r);return n?n.decode(e,t,r):e}function he(e){const{id:t,schema:r}=e;return{id:t,kind:"union",schema:r,matches(n){if(n[L]==="union")return!0;const o=n.oneOf;return!Array.isArray(o)||o.length===0?!1:E(n)!==void 0},encode(n,o,i){const a=E(o);if(!a)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] schema node at "${i.path}" has no discriminator.propertyName; cannot dispatch union branch.`);const{propertyName:s,mapping:f}=a,c=n[s];if(c==null)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] value at "${i.path}" is missing the discriminator property "${s}".`);const u=String(c),d=f[u];if(!d)throw new h("E_UNION_UNKNOWN_TAG",`[${t}] discriminator tag "${u}" at "${i.path}" is not in the mapping (known: ${Object.keys(f).join(", ")}).`);const p=i.resolve(d);return rt(n,p,{...i,path:`${i.path}[${u}]`})},decode(n,o,i){if(n===null||typeof n!="object"||Array.isArray(n)){let l;throw n===null?l="null":Array.isArray(n)?l="array":l=typeof n,new h("E_UNION_INVALID_WIRE",`[${t}] expected a JSON object on the wire at "${i.path}", got ${l}.`)}const a=n,s=E(o);if(!s)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] schema node at "${i.path}" has no discriminator.propertyName; cannot dispatch union branch.`);const{propertyName:f,mapping:c}=s,u=a[f];if(u==null)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] wire object at "${i.path}" is missing the discriminator property "${f}".`);const d=String(u),p=c[d];if(!p)throw new h("E_UNION_UNKNOWN_TAG",`[${t}] discriminator tag "${d}" on the wire at "${i.path}" is not in the mapping (known: ${Object.keys(c).join(", ")}).`);const w=i.resolve(p);return nt(n,w,{...i,path:`${i.path}[${d}]`})}}}const ot="x-apigen-instances";class O extends Error{constructor(t,r){super(r),this.name="NominalCodecError",this.code=t}}function Q(e){const t=e.properties;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function it(e){const t=e.required;return Array.isArray(t)?t.filter(r=>typeof r=="string"):[]}function X(e,t,r){if(t){const n=r.registry.resolve(t);if(n)return n.encode(e,t,r)}return e}function st(e,t,r){if(t){const n=r.registry.resolve(t);if(n)return n.decode(e,t,r)}return e}function at(e){const{id:t,schema:r,ctor:n}=e;return{id:t,kind:"nominal",schema:r,matches(o){return o[L]==="nominal"?!0:o[U]===t},encode(o,i,a){if(o===null||typeof o!="object")return o;if(a.seen.has(o)){if(a.mode==="strict")throw new O("E_NOMINAL_CYCLE",`[${t}] cycle detected at "${a.path}": a nominal instance references itself. Strict mode rejects cycles (DESIGN ยง8.3); break the cycle or use 'lossy' mode.`);return null}a.seen.add(o);try{const s=Q(i),f=typeof i[x]=="string"?i[x]:"toJSON",c=o[f];if(typeof c=="function"){const l=c.call(o);if(l!==null&&typeof l=="object"&&!Array.isArray(l)){const y={};for(const[m,A]of Object.entries(l))y[m]=X(A,s[m],{...a,path:`${a.path}/${m}`});return y}return l}const u={},d=Object.keys(s),p=o,w=d.length>0?d:Object.keys(p);for(const l of w){const y=p[l];y!==void 0&&(u[l]=X(y,s[l],{...a,path:`${a.path}/${l}`}))}return u}finally{a.seen.delete(o)}},decode(o,i,a){if(o===null||typeof o!="object"||Array.isArray(o)){let u;throw o===null?u="null":Array.isArray(o)?u="array":u=typeof o,new O("E_NOMINAL_INVALID_WIRE",`[${t}] expected a JSON object on the wire at "${a.path}", got ${u}.`)}const s=o;for(const u of it(i))if(!(u in s))throw new O("E_NOMINAL_INVALID_WIRE",`[${t}] required field "${u}" missing on the wire at "${a.path}".`);if(i[ot]===!1)throw new O("E_NOMINAL_NONRECONSTRUCTABLE",`[${t}] is encode-only: the extractor marked it non-reconstructable (x-apigen-instances:false). It cannot be decoded back to a live instance.`);const f=Q(i),c={};for(const[u,d]of Object.entries(s))c[u]=st(d,f[u],{...a,path:`${a.path}/${u}`});if(n){const u=typeof i[k]=="string"?i[k]:"fromJSON",d=n[u];if(typeof d=="function")return d.call(n,c);const p=n;return new p(c)}return c}}}const me=[P,R,q,B,W,F],ct={type:"object","x-apigen-logical":"nominal","x-apigen-codec":"ts.NominalSentinel"},Z=at({id:"ts.NominalSentinel",schema:ct}),ut={oneOf:[],discriminator:{propertyName:"kind",mapping:{}},"x-apigen-logical":"union","x-apigen-codec":"ts.UnionSentinel"},ee=he({id:"ts.UnionSentinel",schema:ut});function ft(){const e=[...me.map(t=>[t.id,t]),[Z.id,Z],[ee.id,ee]];return Object.freeze(new Map(e))}const dt=Object.freeze({host:"ts",logicalTypeVersion:ve,codecs:ft()});function pt(e,t,r){var i;const n=typeof((i=t==null?void 0:t.input)==null?void 0:i.description)=="string"?t.input.description:void 0,o=[r,n].filter(a=>typeof a=="string"&&a.length>0);return o.length>0?o.join(" โ€” "):e}function lt(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0)return{outputSchema:void 0,wrapped:!1};const t=e;return t.type==="object"?{outputSchema:t,wrapped:!1}:{outputSchema:{type:"object",properties:{result:t},required:["result"]},wrapped:!0}}function yt(e,t){return e?{result:t}:t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}exports.EventBus=ae;exports.InstanceRegistry=Qe;exports.LayerContext=Ie;exports.UnionCodecError=h;exports.ValidateSchemasToken=le;exports.WELL_KNOWN_TS_CODECS=me;exports.assertNoSelfSubscription=fe;exports.buildContext=ue;exports.buildFnTable=Ke;exports.buildMcpOutputSchema=lt;exports.buildToolDescription=pt;exports.coerceQueryParams=ze;exports.collectWithPhase=et;exports.createApiPackage=qe;exports.createInvoker=ke;exports.createLogger=Be;exports.createStream=Xe;exports.createUnionCodec=he;exports.dataParamNames=ie;exports.defineMiddleware=xe;exports.describeParams=We;exports.dispatch=se;exports.drainStream=Ze;exports.isApiStream=tt;exports.makeValidateLayer=Ge;exports.needsEnvelopeField=oe;exports.tsHostBinding=dt;exports.validateLayer=He;exports.wireObservers=ce;exports.wrapMcpStructuredContent=yt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("ts-morph");require("node:fs");require("node:path");require("ts-json-schema-generator");const N=require("pino"),ge=require("ajv"),we=require("ajv-formats"),I="$apigen";class K extends Error{constructor(t){super(t),this.code="E_DUP_CODEC",this.name="CodecRegistryError"}}function be(e){const t=new Map;return{register(r,n){if(t.has(r.id)&&!(n!=null&&n.override))throw new K(`E_DUP_CODEC: a codec is already registered for id "${r.id}"`);t.set(r.id,r)},resolve(r){for(const n of t.values())if(n.matches(r))return n},get(r){return t.get(r)},ids(){return[...t.keys()]},freeze(){const r=new Map(t),n={register(){throw new K("E_DUP_CODEC: registry is frozen and cannot accept new codecs")},resolve(o){for(const i of r.values())if(i.matches(o))return i},get(o){return r.get(o)},ids(){return[...r.keys()]},freeze(){return n}};return n}}}const L="x-apigen-logical",U="x-apigen-codec",k="x-apigen-ctor",x="x-apigen-tojson",ve="0.1.0";function V(e,t){return{registry:e,resolve:r=>{throw new Error(`[apigen-logical] $ref "${r}" cannot be resolved in run-mode without a descriptor root. Supply a resolve() in the ctx override to handle $ref.`)},seen:new WeakSet,path:"",mode:"strict",...t}}function b(e,t,r){const n=r.registry.resolve(t);if(n)return n.encode(e,t,r);const o=t.$ref;if(typeof o=="string"){const s=r.resolve(o);return b(e,s,r)}const i=t.oneOf;if(Array.isArray(i)){const s=te(e,i,t);return b(e,s,r)}const a=t.type;if(a==="array"){if(!Array.isArray(e))return j(e,t,r);const s=t.items;if(!s)return e.map(c=>g(c));const f=r.path;return Array.isArray(s)?e.map((c,u)=>{const d=s[u];return d===void 0?g(c):b(c,d,{...r,path:`${f}/${u}`})}):e.map((c,u)=>b(c,s,{...r,path:`${f}/${u}`}))}if(a==="object"){if(e===null||typeof e!="object"||Array.isArray(e))return j(e,t,r);const s=t.properties;if(!s)return g(e);const f=r.path,c={};for(const[u,d]of Object.entries(s)){const p=e[u];p!==void 0&&(c[u]=b(p,d,{...r,path:`${f}/${u}`}))}return c}return a==null?j(e,t,r):g(e)}function v(e,t,r){const n=r.registry.resolve(t);if(n)return n.decode(e,t,r);const o=t.$ref;if(typeof o=="string"){const s=r.resolve(o);return v(e,s,r)}const i=t.oneOf;if(Array.isArray(i)){const s=te(e,i,t);return v(e,s,r)}const a=t.type;if(a==="array"){if(!Array.isArray(e))return e;const s=t.items;if(!s)return e;const f=r.path;return Array.isArray(s)?e.map((c,u)=>{const d=s[u];return d===void 0?c:v(c,d,{...r,path:`${f}/${u}`})}):e.map((c,u)=>v(c,s,{...r,path:`${f}/${u}`}))}if(a==="object"){if(e===null||typeof e!="object"||Array.isArray(e))return e;const s=t.properties;if(!s)return e;const f=r.path,c={};for(const[u,d]of Object.entries(s)){const p=e[u];p!==void 0&&(c[u]=v(p,d,{...r,path:`${f}/${u}`}))}return c}return a==null?$e(e,r):e}function te(e,t,r,n){const o=r.discriminator;if(o!=null&&o.propertyName){const i=e!==null&&typeof e=="object"?e[o.propertyName]:void 0;if(typeof i=="string"&&o.mapping){const a=o.mapping[i];if(a){const s=t.find(f=>f.$ref===a);if(s)return s}}}return t[0]??{}}function j(e,t,r){for(const n of r.registry.ids()){const o=r.registry.get(n);if(o)try{const i=o.encode(e,o.schema,r);return{[I]:n,v:i}}catch{}}return g(e)}function $e(e,t){if(e!==null&&typeof e=="object"&&!Array.isArray(e)&&I in e){const r=e,n=r[I],o=t.registry.get(n);if(o)return o.decode(r.v,o.schema,t)}return e}function g(e){if(e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(Array.isArray(e))return e.map(g);if(typeof e=="object"){const t={};for(const[r,n]of Object.entries(e))n!==void 0&&(t[r]=g(n));return t}return null}function Ne(e){return{encode(t,r,n){const o=V(e,n);return b(t,r,o)},decode(t,r,n){const o=V(e,n);return v(t,r,o)}}}const P={id:"date-time",kind:"scalar",schema:{type:"string",format:"date-time"},matches(e){return e.type==="string"&&e.format==="date-time"},encode(e,t,r){return e.toISOString()},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[date-time] expected a string on the wire at "${r.path}", got ${typeof e}`);return new Date(String(e))}if(r.mode==="strict"&&Number.isNaN(new Date(e).getTime()))throw new TypeError(`[date-time] invalid date-time string at "${r.path}": ${JSON.stringify(e)}`);return new Date(e)}},R={id:"int64",kind:"scalar",schema:{type:"string",format:"int64"},matches(e){return e.type==="string"&&e.format==="int64"},encode(e,t,r){return String(e)},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[int64] expected a string on the wire at "${r.path}", got ${typeof e}`);try{return BigInt(Math.trunc(Number(e)))}catch{return BigInt(0)}}if(r.mode==="strict")return BigInt(e);if(/^-?\d+$/.test(e))try{return BigInt(e)}catch{return BigInt(0)}return BigInt(0)}},q={id:"decimal",kind:"scalar",schema:{type:"string",format:"decimal"},matches(e){return e.type==="string"&&e.format==="decimal"},encode(e,t,r){return e},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[decimal] expected a string on the wire at "${r.path}", got ${typeof e}`);return String(e)}if(r.mode==="strict"&&!/^-?\d+(\.\d+)?$/.test(e))throw new TypeError(`[decimal] wire value "${e}" at "${r.path}" is not a valid decimal string`);return e}},B={id:"byte",kind:"scalar",schema:{type:"string",format:"byte"},matches(e){return e.type==="string"&&e.format==="byte"},encode(e,t,r){return Buffer.from(e).toString("base64")},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[byte] expected a base64 string on the wire at "${r.path}", got ${typeof e}`);return new Uint8Array(0)}if(r.mode==="strict"&&!/^[A-Za-z0-9+/]*={0,2}$/.test(e))throw new TypeError(`[byte] wire value at "${r.path}" is not standard base64 (format:byte): "${e}"`);return new Uint8Array(Buffer.from(e,"base64"))}},Oe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,W={id:"uuid",kind:"scalar",schema:{type:"string",format:"uuid"},matches(e){return e.type==="string"&&e.format==="uuid"},encode(e,t,r){return e.toLowerCase()},decode(e,t,r){if(typeof e!="string"){if(r.mode==="strict")throw new TypeError(`[uuid] expected a string on the wire at "${r.path}", got ${typeof e}`);return String(e).toLowerCase()}if(r.mode==="strict"&&!Oe.test(e))throw new TypeError(`[uuid] wire value "${e}" at "${r.path}" is not a lowercase-hyphenated RFC 4122 UUID`);return e}},C="NaN",T="Infinity",M="-Infinity",Ae=new Set([C,T,M]),F={id:"number-special",kind:"scalar",schema:{type:"number"},matches(e){return e.type==="number"&&e.format===void 0},encode(e,t,r){return Number.isNaN(e)?C:e===1/0?T:e===-1/0?M:e},decode(e,t,r){if(typeof e=="number")return e;if(typeof e=="string"){if(e===C)return NaN;if(e===T)return 1/0;if(e===M)return-1/0;const n=Number(e);if(!Number.isNaN(n))return n}if(r.mode==="strict")throw new TypeError(`[number-special] unrecognized wire value at "${r.path}": ${JSON.stringify(e)}. Expected a number or one of ${[...Ae].join(", ")}.`);return NaN}},je=[P,R,q,B,W,F];function _e(e,t={}){for(const r of je)e.register(r,{override:t.override??!1})}P.id,R.id,q.id,B.id,W.id,F.id;const re=be();_e(re);const ne=Ne(re.freeze());function oe(e,t){var n;const r=((n=e.input)==null?void 0:n.properties)??{};return t in r}function ie(e){var r,n;const t=(n=(r=e.input)==null?void 0:r.properties)==null?void 0:n.data;return Object.keys((t==null?void 0:t.properties)??{})}function Se(e,t){var o,i,a;const r=(a=(i=(o=e.input)==null?void 0:o.properties)==null?void 0:i.data)==null?void 0:a.properties,n=r==null?void 0:r[t];return n!==void 0?n:void 0}function Ee(e,t){return t===void 0||e===void 0?e:ne.decode(e,t)}function _(e,t){const r=t.output;return!r||Object.keys(r).length===0?e:ne.encode(e,r)}async function se(e,t,r,n,o,i){const s=ie(r).map(c=>Ee(i[c],Se(r,c)));if(oe(r,"session")&&t){const c=await t({session:o.session}),u=await e[n](c,...s);return _(u,r)}if(r.hasCtx){const c=t?await t(o):void 0,u=await e[n](c,...s);return _(u,r)}const f=await e[n](...s);return _(f,r)}class Ie{constructor(){this._map=new Map}set(t,r){this._map.set(t,r)}get(t){return this._map.get(t)}has(t){return this._map.has(t)}}function ke(e=[]){return async function(r,n,o){const i=o.schemas[r];if(!i)throw new Error(`apigen/invoke: no schema found for operation "${r}"`);const a=()=>se(o.fns,o.createClient,i,r,n.envelope,n.domainArgs);return e.reduceRight((f,c)=>()=>c(n,f),a)()}}function xe(e){return e}class ae{constructor(){this.handlers=new Map}on(t,r){const n=this.handlers.get(t)??[];return this.handlers.set(t,[...n,r]),()=>this.off(t,r)}off(t,r){const n=this.handlers.get(t);if(!n)return;const o=n.filter(i=>i!==r);o.length===0?this.handlers.delete(t):this.handlers.set(t,o)}clear(){this.handlers.clear()}async emit(t){for(const[r,n]of this.handlers)if(Ce(r,t))for(const o of n)await o(t)}}function Ce(e,t){const[r,n,o]=e.split(":");return!(r!=="*"&&r!==t.module||n&&n!=="*"&&n!==t.method||o&&o!=="*"&&o!==t.lifecycle)}function ce(e,t){for(const r of e)if(r.eventMapping)for(const[n,o]of Object.entries(r.eventMapping))t.on(n,o)}async function ue(e,t,r){let n={...t};for(const o of e)if(o.createContext){await r.emit({module:o.id,method:"createContext",lifecycle:"start",ctx:n});try{const i=await o.createContext(n);n={...n,...i},await r.emit({module:o.id,method:"createContext",lifecycle:"complete",ctx:n})}catch(i){throw await r.emit({module:o.id,method:"createContext",lifecycle:"error",ctx:n,error:i}),i}}return n}function J(e,t){const r=new Set,n=[e];for(;n.length>0;){const o=n.pop();if(!o||r.has(o))continue;r.add(o);const i=o.$ref;if(typeof i=="string"){if(t){const d=t[i];if(!d){const p=Object.keys(t).join(", ")||"(none)";throw new Error(`[apigen-logical] $ref "${i}" cannot be resolved. Available $defs: ${p}`)}n.push(d)}continue}const a=o.oneOf;if(Array.isArray(a))for(const d of a)typeof d=="object"&&d!==null&&n.push(d);const s=o.properties;if(s)for(const d of Object.values(s))n.push(d);const f=o.items;if(Array.isArray(f))for(const d of f)typeof d=="object"&&d!==null&&n.push(d);else typeof f=="object"&&f!==null&&n.push(f);const c=o.additionalProperties;typeof c=="object"&&c!==null&&n.push(c);const u=o.propertyNames;typeof u=="object"&&u!==null&&n.push(u)}}const H=new Set(["string","number","boolean","integer"]);function Te(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"?H.has(r):Array.isArray(r)?r.every(n=>H.has(n)||n==="null"):Array.isArray(t.enum)&&t.enum.length>0?t.enum.every(n=>["string","number","boolean"].includes(typeof n)):!1}function Me(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(Te)}function De(e){const t={},r=n=>{for(const o of["definitions","$defs"]){const i=n[o];if(i)for(const[a,s]of Object.entries(i)){const f=a.startsWith("#/")?a:`#/${o}/${a}`;t[f]=s}}};for(const n of Object.values(e.schemas))r(n.input),r(n.output);if(Object.keys(t).length!==0)for(const[n,o]of Object.entries(e.schemas))try{J(o.input,t),J(o.output,t)}catch(i){throw new Error(`[apigen-core-client] Schema validation failed for function "${n}": ${i.message}`)}}function Le(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(n=>`"${n}"`).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 Ue(e,t,r){De(e);const n={};for(const[o,i]of Object.entries(e.schemas)){const a=(r==null?void 0:r[o])??{},s=i.input.properties??{},f=i.input.required??[],c={},u=[];for(const y of t)if(y.envelope&&a[y.id]!==!1)for(const[m,A]of Object.entries(y.envelope))c[m]=A,u.includes(m)||u.push(m);const d={type:"object",properties:s,additionalProperties:!1,...f.length>0?{required:f}:{}},p=i.safe===!0||Me(i.input),w=i.input.definitions,l=i.input.$defs;n[o]={input:{type:"object",properties:{...c,data:d},required:[...u,...f.length>0?["data"]:[]],additionalProperties:!1,description:Le(Object.keys(c),Object.keys(s).length>0),...w?{definitions:w}:{},...l?{$defs:l}:{}},output:i.output,...i.hasCtx?{hasCtx:!0}:{},"x-apigen-safe":p}}return n}const Pe={"decimal.js":"Decimal"};function Re(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}Object.entries(Pe).map(([e,t])=>({pattern:new RegExp(`import\\(["'][^"']*${Re(e)}[^"']*["']\\)\\.\\w+`,"g"),key:t}));class D extends Error{constructor(t){super(t),this.name="ConfigurationError"}}function fe(e){for(const t of e)for(const r of Object.keys(t.eventMapping??{})){const[n]=r.split(":");if(n!=="*"&&n===t.id)throw new D(`Middleware "${t.id}" subscribes to its own events via "${r}". This would cause infinite recursion.`)}}function qe(e){const{domainSchemas:t,middlewares:r,overrides:n={},strict:o=!1}=e;fe(r);for(const c of Object.keys(n))if(!(c in t.schemas)){const u=`Override key "${c}" not found in domain schemas.`;if(o)throw new D(u);console.warn("[apigen-runtime]",u)}const i=new Set(r.map(c=>c.id));for(const[c,u]of Object.entries(n))for(const d of Object.keys(u??{}))if(!i.has(d)){const p=`Override key "${c}.${d}" does not match any declared middleware id.`;if(o)throw new D(p);console.warn("[apigen-runtime]",p)}const a=Ue(t,r,n),s=new ae;return ce(r,s),{schemas:a,createClient:async c=>ue(r,c,s),dispose:()=>s.clear()}}function Be(e={}){const t=e.level??"info",r=typeof e.destination=="string"&&e.destination.length>0,n=!r&&!!process.stderr.isTTY,o=e.format??(n?"pretty":"json"),i={level:t};if(o==="pretty")return i.transport={target:"pino-pretty",options:{colorize:!r,translateTime:"SYS:HH:MM:ss.l",ignore:"pid,hostname",...r?{destination:e.destination,mkdir:!0}:{destination:2}}},N(i);const a=r?N.destination({dest:e.destination,mkdir:!0,sync:!0}):N.destination(2);return N(i,a)}function de(e){return e?e.type==="array"?`${de(e.items)}[]`:e.enum?"enum":e.$ref?String(e.$ref).split("/").pop()||"object":e.anyOf||e.oneOf?"union":e.type??"object":"unknown"}function We(e){var s;const r=(s=((e==null?void 0:e.input)??{}).properties)==null?void 0:s.data,n=(r==null?void 0:r.properties)??{},o=new Set((r==null?void 0:r.required)??[]),i=Object.entries(n).map(([f,c])=>({name:f,type:de(c),required:o.has(f)})),a=i.map(f=>`${f.name}${f.required?"":"?"}: ${f.type}`).join(", ");return{params:i,text:a}}function Fe(e){let t;return Array.isArray(e)?t=e:e?t=[e]:t=[],t.find(r=>r==="number"||r==="integer"||r==="boolean")}function ze(e,t){var i,a;const n=((a=(i=((t==null?void 0:t.input)??{}).properties)==null?void 0:i.data)==null?void 0:a.properties)??{},o={...e};for(const[s,f]of Object.entries(n)){const c=o[s];if(typeof c!="string")continue;const u=Fe(f==null?void 0:f.type);if(u==="number"||u==="integer"){const d=Number(c);!Number.isNaN(d)&&c.trim()!==""&&(o[s]=d)}else u==="boolean"&&(c==="true"?o[s]=!0:c==="false"&&(o[s]=!1))}return o}const G=new Set(["default","module.exports","__esModule"]);function Ke(e){const t={},r=(n,o)=>{for(const[i,a]of Object.entries(n))if(typeof a=="function"){!G.has(i)&&!(i in t)&&(t[i]=a);const s=a.name;s&&!(s in t)&&(t[s]=a)}else a&&typeof a=="object"&&o<2&&G.has(i)&&r(a,o+1)};return r(e,0),t}const Ve=["invalid_argument","unauthenticated","permission_denied","not_found","internal"];class z extends Error{constructor(t,r,n){super(r),this.name="ApiError",this.code=t,this.details=n,Object.setPrototypeOf(this,new.target.prototype)}toJSON(){const t={code:this.code,message:this.message};return this.details!==void 0&&(t.details=this.details),t}}function Je(e){return typeof e=="object"&&e!==null&&e.name==="ApiError"&&Ve.includes(e.code)&&typeof e.toJSON=="function"}function Y(e,t,r=0){return e==="before-first-chunk"?{phase:e,error:t}:{phase:e,error:t,chunksDelivered:r}}const $=new ge({allErrors:!0});we($);for(const e of[L,U,k,x,"discriminator"])$.addKeyword({keyword:e,valid:!0});$.addFormat("decimal",/^[+-]?(?:\d+(?:\.\d+)?|\.\d+)$/);function pe(e){return e.map(t=>`${t.instancePath||"(root)"} ${t.message??"failed schema check"}`).join("; ")}const He=async(e,t)=>{const r=e.ctx.get(le);if(r===void 0)return t();const n=e.operation.id,o=r[n];if(o===void 0)return t();const i={data:e.domainArgs,...e.envelope},a=$.compile(o.input);if(!a(i)){const f=a.errors??[];throw new z("invalid_argument",`Validation failed: ${pe(f)}`,f)}return t()},le=Symbol("ValidateSchemasToken");function Ge(e){return async function(r,n){const o=r.operation.id,i=e[o];if(i===void 0)return n();const a={data:r.domainArgs,...r.envelope},s=$.compile(i.input);if(!s(a)){const c=s.errors??[];throw new z("invalid_argument",`Validation failed: ${pe(c)}`,c)}return n()}}function Ye(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}class Qe{constructor(t={}){var n,o;this._store=new Map,this._sweeper=null,this._defaultTtlMs=t.defaultTtlMs;let r=null;t.sweepIntervalMs===0?r=null:t.sweepIntervalMs!==void 0?r=t.sweepIntervalMs:this._defaultTtlMs!==void 0?r=Math.max(1e3,Math.floor(this._defaultTtlMs/4)):r=null,r!==null&&r>0&&(this._sweeper=setInterval(()=>this._sweep(),r),(o=(n=this._sweeper).unref)==null||o.call(n))}create(t,r=[],n){const o=new t(...r),i=Ye(),a=n??this._defaultTtlMs,s=a!==void 0?Date.now()+a:null;return this._store.set(i,{instance:o,expiresAt:s}),{instanceId:i}}get(t){const r=this._store.get(t);if(!r)throw new Error(`[instance-registry] Unknown instanceId: "${t}"`);if(r.expiresAt!==null&&Date.now()>r.expiresAt)throw this._evict(t,r),new Error(`[instance-registry] Instance "${t}" has expired`);return r.instance}async dispatch(t,r,n=[]){const o=this.get(t),i=o[r];if(typeof i!="function")throw new Error(`[instance-registry] Method "${r}" not found on instance "${t}"`);return i.call(o,...n)}async dispose(t){const r=this._store.get(t);r&&(this._store.delete(t),await S(r.instance))}async disposeAll(){this._sweeper!==null&&(clearInterval(this._sweeper),this._sweeper=null);const t=[...this._store.entries()];this._store.clear(),await Promise.all(t.map(([,r])=>S(r.instance)))}get size(){return this._store.size}_sweep(){const t=Date.now();for(const[r,n]of this._store)n.expiresAt!==null&&t>n.expiresAt&&this._evict(r,n)}_evict(t,r){this._store.delete(t),S(r.instance)}}async function S(e){if(e!==null&&typeof e=="object"&&"dispose"in e){const t=e.dispose;typeof t=="function"&&await t.call(e)}}function Xe(e){const{produce:t,signal:r}=e,n=r??new AbortController().signal;return{[Symbol.asyncIterator](){const o=t(n);return{async next(){return n.aborted?(await o.return(void 0),{done:!0,value:void 0}):o.next()},async return(i){return await o.return(i),{done:!0,value:void 0}},async throw(i){return await o.throw(i),{done:!0,value:void 0}}}}}}async function Ze(e){const t=[];for await(const r of e)t.push(r);return t}async function et(e){const t=[];try{for await(const r of e)t.push(r);return{ok:!0,chunks:t}}catch(r){const n=Je(r)?r:new z("internal",r instanceof Error?r.message:String(r));return t.length===0?{ok:!1,carrier:Y("before-first-chunk",n)}:{ok:!1,carrier:Y("after-first-chunk",n,t.length)}}}function tt(e){return e!==null&&typeof e=="object"&&Symbol.asyncIterator in e}class h extends Error{constructor(t,r){super(r),this.name="UnionCodecError",this.code=t}}function E(e){const t=e.discriminator;if(t===null||typeof t!="object"||Array.isArray(t))return;const r=t;if(typeof r.propertyName!="string")return;const n=r.mapping;if(!(n===null||typeof n!="object"||Array.isArray(n)))return{propertyName:r.propertyName,mapping:n}}function ye(e,t){const r=e[U];if(typeof r=="string"){const n=t.registry.get(r);if(n)return n}return t.registry.resolve(e)}function rt(e,t,r){const n=ye(t,r);return n?n.encode(e,t,r):e}function nt(e,t,r){const n=ye(t,r);return n?n.decode(e,t,r):e}function he(e){const{id:t,schema:r}=e;return{id:t,kind:"union",schema:r,matches(n){if(n[L]==="union")return!0;const o=n.oneOf;return!Array.isArray(o)||o.length===0?!1:E(n)!==void 0},encode(n,o,i){const a=E(o);if(!a)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] schema node at "${i.path}" has no discriminator.propertyName; cannot dispatch union branch.`);const{propertyName:s,mapping:f}=a,c=n[s];if(c==null)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] value at "${i.path}" is missing the discriminator property "${s}".`);const u=String(c),d=f[u];if(!d)throw new h("E_UNION_UNKNOWN_TAG",`[${t}] discriminator tag "${u}" at "${i.path}" is not in the mapping (known: ${Object.keys(f).join(", ")}).`);const p=i.resolve(d);return rt(n,p,{...i,path:`${i.path}[${u}]`})},decode(n,o,i){if(n===null||typeof n!="object"||Array.isArray(n)){let l;throw n===null?l="null":Array.isArray(n)?l="array":l=typeof n,new h("E_UNION_INVALID_WIRE",`[${t}] expected a JSON object on the wire at "${i.path}", got ${l}.`)}const a=n,s=E(o);if(!s)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] schema node at "${i.path}" has no discriminator.propertyName; cannot dispatch union branch.`);const{propertyName:f,mapping:c}=s,u=a[f];if(u==null)throw new h("E_UNION_NO_DISCRIMINATOR",`[${t}] wire object at "${i.path}" is missing the discriminator property "${f}".`);const d=String(u),p=c[d];if(!p)throw new h("E_UNION_UNKNOWN_TAG",`[${t}] discriminator tag "${d}" on the wire at "${i.path}" is not in the mapping (known: ${Object.keys(c).join(", ")}).`);const w=i.resolve(p);return nt(n,w,{...i,path:`${i.path}[${d}]`})}}}const ot="x-apigen-instances";class O extends Error{constructor(t,r){super(r),this.name="NominalCodecError",this.code=t}}function Q(e){const t=e.properties;return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function it(e){const t=e.required;return Array.isArray(t)?t.filter(r=>typeof r=="string"):[]}function X(e,t,r){if(t){const n=r.registry.resolve(t);if(n)return n.encode(e,t,r)}return e}function st(e,t,r){if(t){const n=r.registry.resolve(t);if(n)return n.decode(e,t,r)}return e}function at(e){const{id:t,schema:r,ctor:n}=e;return{id:t,kind:"nominal",schema:r,matches(o){return o[L]==="nominal"?!0:o[U]===t},encode(o,i,a){if(o===null||typeof o!="object")return o;if(a.seen.has(o)){if(a.mode==="strict")throw new O("E_NOMINAL_CYCLE",`[${t}] cycle detected at "${a.path}": a nominal instance references itself. Strict mode rejects cycles (DESIGN ยง8.3); break the cycle or use 'lossy' mode.`);return null}a.seen.add(o);try{const s=Q(i),f=typeof i[x]=="string"?i[x]:"toJSON",c=o[f];if(typeof c=="function"){const l=c.call(o);if(l!==null&&typeof l=="object"&&!Array.isArray(l)){const y={};for(const[m,A]of Object.entries(l))y[m]=X(A,s[m],{...a,path:`${a.path}/${m}`});return y}return l}const u={},d=Object.keys(s),p=o,w=d.length>0?d:Object.keys(p);for(const l of w){const y=p[l];y!==void 0&&(u[l]=X(y,s[l],{...a,path:`${a.path}/${l}`}))}return u}finally{a.seen.delete(o)}},decode(o,i,a){if(o===null||typeof o!="object"||Array.isArray(o)){let u;throw o===null?u="null":Array.isArray(o)?u="array":u=typeof o,new O("E_NOMINAL_INVALID_WIRE",`[${t}] expected a JSON object on the wire at "${a.path}", got ${u}.`)}const s=o;for(const u of it(i))if(!(u in s))throw new O("E_NOMINAL_INVALID_WIRE",`[${t}] required field "${u}" missing on the wire at "${a.path}".`);if(i[ot]===!1)throw new O("E_NOMINAL_NONRECONSTRUCTABLE",`[${t}] is encode-only: the extractor marked it non-reconstructable (x-apigen-instances:false). It cannot be decoded back to a live instance.`);const f=Q(i),c={};for(const[u,d]of Object.entries(s))c[u]=st(d,f[u],{...a,path:`${a.path}/${u}`});if(n){const u=typeof i[k]=="string"?i[k]:"fromJSON",d=n[u];if(typeof d=="function")return d.call(n,c);const p=n;return new p(c)}return c}}}const me=[P,R,q,B,W,F],ct={type:"object","x-apigen-logical":"nominal","x-apigen-codec":"ts.NominalSentinel"},Z=at({id:"ts.NominalSentinel",schema:ct}),ut={oneOf:[],discriminator:{propertyName:"kind",mapping:{}},"x-apigen-logical":"union","x-apigen-codec":"ts.UnionSentinel"},ee=he({id:"ts.UnionSentinel",schema:ut});function ft(){const e=[...me.map(t=>[t.id,t]),[Z.id,Z],[ee.id,ee]];return Object.freeze(new Map(e))}const dt=Object.freeze({host:"ts",logicalTypeVersion:ve,codecs:ft()});function pt(e,t,r){var i;const n=typeof((i=t==null?void 0:t.input)==null?void 0:i.description)=="string"?t.input.description:void 0,o=[r,n].filter(a=>typeof a=="string"&&a.length>0);return o.length>0?o.join(" โ€” "):e}function lt(e){if(!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0)return{outputSchema:void 0,wrapped:!1};const t=e;return t.type==="object"?{outputSchema:t,wrapped:!1}:{outputSchema:{type:"object",properties:{result:t},required:["result"]},wrapped:!0}}function yt(e,t){return e?{result:t}:t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}exports.EventBus=ae;exports.InstanceRegistry=Qe;exports.LayerContext=Ie;exports.UnionCodecError=h;exports.ValidateSchemasToken=le;exports.WELL_KNOWN_TS_CODECS=me;exports.assertNoSelfSubscription=fe;exports.buildContext=ue;exports.buildFnTable=Ke;exports.buildMcpOutputSchema=lt;exports.buildToolDescription=pt;exports.coerceQueryParams=ze;exports.collectWithPhase=et;exports.createApiPackage=qe;exports.createInvoker=ke;exports.createLogger=Be;exports.createStream=Xe;exports.createUnionCodec=he;exports.dataParamNames=ie;exports.defineMiddleware=xe;exports.describeParams=We;exports.dispatch=se;exports.drainStream=Ze;exports.isApiStream=tt;exports.makeValidateLayer=Ge;exports.needsEnvelopeField=oe;exports.tsHostBinding=dt;exports.validateLayer=He;exports.wireObservers=ce;exports.wrapMcpStructuredContent=yt;
package/index.mjs CHANGED
@@ -645,7 +645,7 @@ function Ie(e, t) {
645
645
  'apigen calling convention: all domain parameters go inside a "data" envelope โ€” e.g. { "data": { ... } }' + (t ? "." : " (an empty object for this zero-parameter tool).")
646
646
  ];
647
647
  return e.length > 0 && r.push(
648
- `Field(s) ${e.map((n) => `"${n}"`).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.`
648
+ `Field(s) ${e.map((n) => `"${n}"`).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.`
649
649
  ), r.join(" ");
650
650
  }
651
651
  function ke(e, t, r) {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@adhd/apigen-engine-runtime",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "dependencies": {
5
5
  "ajv": "^8.20.0",
6
6
  "ajv-formats": "2.1.1",
7
7
  "pino": "10.3.1",
8
- "@adhd/apigen-core-client": "^0.1.0",
9
- "@adhd/apigen-base-logical": "^0.0.1",
10
- "@adhd/apigen-base-errors": "^0.1.1",
8
+ "@adhd/apigen-core-client": "^0.1.2",
9
+ "@adhd/apigen-base-logical": "^0.0.3",
10
+ "@adhd/apigen-base-errors": "^0.1.3",
11
11
  "better-sqlite3": "12.10.0"
12
12
  },
13
13
  "main": "./index.js",