@dizzlkheinz/ynab-mcpb 0.26.2 → 0.26.3
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 +6 -0
- package/CLAUDE.md +1 -1
- package/dist/bundle/index.cjs +1 -1
- package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +60 -0
- package/dist/tools/schemas/outputs/reconciliationOutputs.js +25 -0
- package/package.json +1 -1
- package/src/tools/schemas/outputs/reconciliationOutputs.ts +30 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.26.3] - 2026-04-01
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Reconciliation execution action schema** - Added 5 missing `type` values to `ExecutionActionRecordSchema`'s discriminated union (`batch_update_failed`, `batch_reconcile_failed`, `reconciliation_complete`, `diagnostic_step3_entry`, `diagnostic_unmatched_ynab`); these were emitted by the executor but not declared in the schema, causing `include_structured_data: true` output validation to fail whenever execution ran
|
|
15
|
+
|
|
10
16
|
## [0.26.2] - 2026-04-01
|
|
11
17
|
|
|
12
18
|
### Fixed
|
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
6
6
|
|
|
7
7
|
This is a Model Context Protocol (MCP) server for YNAB (You Need A Budget) integration, enabling AI assistants to interact with YNAB budgets, accounts, transactions, and categories. The codebase uses TypeScript with a modular, service-oriented architecture.
|
|
8
8
|
|
|
9
|
-
**Current Version:** 0.26.
|
|
9
|
+
**Current Version:** 0.26.3
|
|
10
10
|
|
|
11
11
|
## Essential Commands
|
|
12
12
|
|
package/dist/bundle/index.cjs
CHANGED
|
@@ -89,7 +89,7 @@ Valid formats:
|
|
|
89
89
|
|
|
90
90
|
You can use the ynab_list_budgets tool to see available budget IDs.`;return(n??B8).createValidationError("Invalid budget ID format",a,["Use a valid UUID format (UUID v1-v5, e.g., 123e4567-e89b-12d3-a456-426614174000; standard UUID v4 format works as well)","Run the ynab_list_budgets tool to view available budget IDs",'Use the special keyword "default" for convenience'])}static resolveBudgetIdOrThrow(t,n){let a=e.resolveBudgetId(t,n);if(typeof a=="string")return a;let r=a.content?.[0]?.type==="text"?a.content[0].text:"Budget resolution failed";throw new Error(r)}static validateBudgetIdOrThrow(t){let n=e.validateBudgetId(t);if(typeof n=="string")return n;let a=n.content?.[0]?.type==="text"?n.content[0].text:"Budget validation failed";throw new Error(a)}};$u.UUID_REGEX=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;$u.ALLOWED_KEYWORDS=["default"];var _m=class extends Error{constructor(t){super("Default argument resolution failed"),this.result=t,this.name="DefaultArgumentResolutionError"}},ym=class e{constructor(t){this.deps=t,this.tools=new Map,this.outputValidators=new Map}register(t){if(this.assertValidDefinition(t),this.tools.has(t.name))throw new Error(`Tool '${t.name}' is already registered`);let a={...t,security:{namespace:t.security?.namespace??"ynab",operation:t.security?.operation??t.name}};this.tools.set(t.name,a),t.outputSchema&&this.outputValidators.set(t.name,t.outputSchema)}listTools(){return Array.from(this.tools.values()).map(t=>{let n=this.ensureRootObjectJsonSchema(t.metadata?.inputJsonSchema??this.generateJsonSchema(t.inputSchema),"input",t.name),a={name:t.name,description:t.description,inputSchema:n};if(t.outputSchema){let r=this.ensureRootObjectJsonSchema(this.generateJsonSchema(t.outputSchema,"output"),"output",t.name);a.outputSchema=r}return t.metadata?.annotations&&(a.annotations=t.metadata.annotations),a})}hasTool(t){return this.tools.has(t)}getToolDefinitions(){return Array.from(this.tools.values()).map(t=>{let n={name:t.name,description:t.description,inputSchema:t.inputSchema,handler:t.handler,security:t.security};return t.outputSchema&&(n.outputSchema=t.outputSchema),t.metadata&&(n.metadata=t.metadata),t.defaultArgumentResolver&&(n.defaultArgumentResolver=t.defaultArgumentResolver),n})}async executeTool(t){let n=this.tools.get(t.name);if(!n)return this.deps.errorHandler.createValidationError(`Unknown tool: ${t.name}`,"The requested tool is not registered with the server");if(this.deps.validateAccessToken)try{await this.deps.validateAccessToken(t.accessToken)}catch(i){return this.isCallToolResult(i)?i:this.deps.errorHandler.handleError(i,`authenticating ${n.name}`)}let a;if(n.defaultArgumentResolver)try{a=await n.defaultArgumentResolver({name:n.name,accessToken:t.accessToken,rawArguments:t.arguments??{}})}catch(i){return i instanceof _m?i.result:this.isCallToolResult(i)?i:this.deps.errorHandler.createValidationError("Invalid parameters",i instanceof Error?i.message:"Unknown error during default argument resolution")}let r={...a??{},...t.arguments??{}};try{return await this.deps.withSecurityWrapper(n.security.namespace,n.security.operation,n.inputSchema)(t.accessToken)(r)(async o=>{try{let s={accessToken:t.accessToken,name:n.name,operation:n.security.operation,rawArguments:r};this.deps.cacheHelpers&&(s.cache=this.deps.cacheHelpers),t.sendProgress&&(s.sendProgress=t.sendProgress);let d=await n.handler({input:o,context:s});return d.isError?d:this.validateOutput(n.name,d)}catch(s){return this.deps.errorHandler.handleError(s,`executing ${n.name} - ${n.security.operation}`)}})}catch(i){return this.normalizeSecurityError(i,n)}}isCallToolResult(t){return typeof t=="object"&&t!==null&&"content"in t&&Array.isArray(t.content)}normalizeSecurityError(t,n){if(t instanceof c.ZodError){let a=Vi(t);return this.deps.errorHandler.createValidationError(`Invalid parameters for ${n.name}`,a.message)}return t instanceof Error&&t.message.includes("Validation failed")?this.deps.errorHandler.createValidationError(`Invalid parameters for ${n.name}`,t.message):this.deps.errorHandler.handleError(t,`executing ${n.name}`)}assertValidDefinition(t){if(!t||typeof t!="object")throw new Error("Tool definition must be an object");if(!t.name||typeof t.name!="string")throw new Error("Tool definition requires a non-empty name");if(!e.MCP_TOOL_NAME_REGEX.test(t.name))throw new Error(`Tool name '${t.name}' violates MCP guidelines: must be 1-128 chars using only [a-zA-Z0-9_.-]`);if(!t.description||typeof t.description!="string")throw new Error(`Tool '${t.name}' requires a description`);if(!t.inputSchema||typeof t.inputSchema.parse!="function")throw new Error(`Tool '${t.name}' requires a valid Zod schema`);if(t.outputSchema&&typeof t.outputSchema.parse!="function")throw new Error(`Tool '${t.name}' outputSchema must be a valid Zod schema when provided`);if(typeof t.handler!="function")throw new Error(`Tool '${t.name}' requires a handler function`);if(t.defaultArgumentResolver&&typeof t.defaultArgumentResolver!="function")throw new Error(`Tool '${t.name}' defaultArgumentResolver must be a function when provided`)}generateJsonSchema(t,n="input"){try{return Oi(t,{target:"draft-2020-12",io:n})}catch(a){return console.warn(`Failed to generate JSON schema for tool: ${a}`),{type:"object",additionalProperties:!0}}}ensureRootObjectJsonSchema(t,n,a){let r=t;return r.type==="object"?r:Array.isArray(r.anyOf)||Array.isArray(r.oneOf)||Array.isArray(r.allOf)?{...r,type:"object"}:(console.warn(`Generated ${n} schema for tool '${a}' is not an object root; using permissive object fallback.`),{type:"object",additionalProperties:!0})}validateOutput(t,n){let a=this.outputValidators.get(t);if(!a)return n;if(!n.content||n.content.length===0)return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler returned empty content",["Ensure the handler returns valid content in the response"]);let r=[];for(let d=0;d<n.content.length;d++){let u=n.content[d];u?u.type!=="text"?r.push({index:d,reason:`type is "${u.type}" instead of "text"`}):typeof u.text!="string"&&r.push({index:d,reason:`text property is ${typeof u.text} instead of string`}):r.push({index:d,reason:"item is null or undefined"})}if(r.length>0){let d=r.map(u=>` - Item ${u.index}: ${u.reason}`).join(`
|
|
91
91
|
`);return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,`Handler returned invalid content items (${r.length} of ${n.content.length} failed):
|
|
92
|
-
${d}`,['Ensure all content items have type="text" and a valid text property'])}let i=n.content[0];if(!i)return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler returned empty content",["Ensure the handler returns valid content in the response"]);if(i.type!=="text")throw new Error("Unexpected: firstContent is not text after validation");if(n.structuredContent!==void 0){let d=a.safeParse(n.structuredContent);if(!d.success){let u=Vi(d.error);return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,`Handler output does not match declared output schema: ${u.message}`,["Check that the handler returns data matching the output schema","Review the tool definition output schema"])}return typeof d.data!="object"||d.data===null||Array.isArray(d.data)?this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler output schema must resolve to a JSON object for structuredContent",["Ensure outputSchema root type is object","Return a JSON object from the tool handler"]):{...n,structuredContent:d.data}}let o;try{o=JSON.parse(i.text)}catch{return n}let s=a.safeParse(o);if(!s.success){let u=Vi(s.error).message;return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,`Handler output does not match declared output schema: ${u}`,["Check that the handler returns data matching the output schema","Review the tool definition output schema"])}return typeof s.data!="object"||s.data===null||Array.isArray(s.data)?this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler output schema must resolve to a JSON object for structuredContent",["Ensure outputSchema root type is object","Return a JSON object from the tool handler"]):{...n,structuredContent:s.data}}};ym.MCP_TOOL_NAME_REGEX=/^[a-zA-Z0-9_.-]{1,128}$/;function Kt(e){let{ynabAPI:t,deltaFetcher:n,deltaCache:a,serverKnowledgeStore:r}=e,{errorHandler:i}=e;return{adapt:o=>async({input:s})=>o(t,s,i),adaptNoInput:o=>async s=>o(t,i),adaptWithDelta:o=>async({input:s})=>o(t,n,s,i),adaptWithDeltaAndProgress:o=>async({input:s,context:d})=>o(t,n,s,d.sendProgress,i),adaptWrite:o=>async({input:s})=>o(t,a,r,s,i)}}function Bn(e){return()=>({rawArguments:t})=>{let n=typeof t.budget_id=="string"&&t.budget_id.length>0?t.budget_id:void 0,a=$u.resolveBudgetId(n,e.getDefaultBudgetId(),e.errorHandler);if(typeof a=="string")return{budget_id:a};throw new _m(a)}}var OC=100,Qre={info(e,t){Kg.logSuccess("delta-cache",e,t?{...t}:{})},warn(e,t){let n={...t?{...t}:{},severity:"warn"};Kg.logSuccess("delta-cache",e,n)},error(e,t){let n=t?{...t}:{},a=n.error,r=typeof a=="string"?a:e;Kg.logError("delta-cache",e,n,r)}},Ha=class{constructor(t,n,a=Qre){this.cacheManager=t,this.knowledgeStore=n,this.logger=a,this.deltaHits=0,this.deltaMisses=0,this.mergeOperations=0,this.knowledgeGapEvents=0}async fetchWithDelta(t,n,a,r,i){let o=this.assertFiniteTtl("fetchWithDelta",t,i.ttl);if(!this.isDeltaEnabled())return this.fetchWithoutDelta(t,n,a,i);let s=this.cacheManager.get(t);if(i.forceFullRefresh&&s&&!(Date.now()-s.timestamp>s.ttl))return{data:s.snapshot,wasCached:!0,usedDelta:!1,serverKnowledge:s.serverKnowledge};let d=i.forceFullRefresh?void 0:this.knowledgeStore.get(t),u=!!(!i.forceFullRefresh&&s&&d!==void 0),l=u?d:void 0,p=await a(l),m=l!==void 0?p.serverKnowledge-l:0,h=!1;m>OC&&(this.logger.warn("delta-cache.knowledge-gap",{budgetId:n,cacheKey:t,lastKnowledge:l,serverKnowledge:p.serverKnowledge,gap:m,threshold:OC,action:"full-refresh",recommendation:"Consider forcing a full refresh to resync cache."}),h=!0,this.knowledgeGapEvents++,p=await a(void 0));let _=!h&&l!==void 0&&p.serverKnowledge>l,f,g=!1;_&&s?(this.mergeOperations++,f=r(s.snapshot,p.data,i.mergeOptions),g=!0):s&&l!==void 0&&!h?f=s.snapshot:f=this.filterDeleted(p.data);let y={snapshot:f,serverKnowledge:p.serverKnowledge,timestamp:Date.now(),ttl:o};i.staleWhileRevalidate!==void 0&&(y.staleWhileRevalidate=i.staleWhileRevalidate);let v={ttl:o};return i.staleWhileRevalidate!==void 0&&(v.staleWhileRevalidate=i.staleWhileRevalidate),this.cacheManager.set(t,y,v),this.knowledgeStore.update(t,p.serverKnowledge),u?this.deltaHits++:this.deltaMisses++,{data:f,wasCached:!!s,usedDelta:g,serverKnowledge:p.serverKnowledge}}getStats(){return{deltaHits:this.deltaHits,deltaMisses:this.deltaMisses,mergeOperations:this.mergeOperations,knowledgeGapEvents:this.knowledgeGapEvents}}invalidate(t,n){if(t)if(n){let a=`${n}:list:${t}`;this.cacheManager.deleteByPrefix(a)}else this.cacheManager.deleteByBudgetId(t)}forceFullRefresh(t,n){t?this.invalidate(t,n):this.cacheManager.clear(),n&&t?this.knowledgeStore.reset(`${n}:list:${t}`):t?this.knowledgeStore.resetByBudgetId(t):this.knowledgeStore.reset()}async fetchWithoutDelta(t,n,a,r){let i=this.assertFiniteTtl("fetchWithoutDelta",t,r.ttl),o=this.cacheManager.get(t);if(o&&(!(Date.now()-o.timestamp>o.ttl)||!r.forceFullRefresh))return{data:o.snapshot,wasCached:!0,usedDelta:!1,serverKnowledge:o.serverKnowledge};let s=await a(void 0),d=this.filterDeleted(s.data),u={snapshot:d,serverKnowledge:s.serverKnowledge,timestamp:Date.now(),ttl:i};r.staleWhileRevalidate!==void 0&&(u.staleWhileRevalidate=r.staleWhileRevalidate);let l={ttl:i};return r.staleWhileRevalidate!==void 0&&(l.staleWhileRevalidate=r.staleWhileRevalidate),this.cacheManager.set(t,u,l),this.knowledgeStore.update(t,s.serverKnowledge),{data:d,wasCached:!1,usedDelta:!1,serverKnowledge:s.serverKnowledge}}filterDeleted(t){return t.filter(n=>!n.deleted)}assertFiniteTtl(t,n,a){if(!Number.isFinite(a))throw new Error(`DeltaCache.${t} requires a finite ttl for cache key "${n}". Received: ${String(a)}.`);return a}isDeltaEnabled(){return process.env.YNAB_MCP_ENABLE_DELTA==="true"}};var Ka=class{constructor(){this.knowledge=new Map}get(t){return this.knowledge.get(t)}update(t,n){if(n<0)throw new Error(`server_knowledge must be non-negative, got: ${n}`);this.knowledge.set(t,n)}reset(t){if(t===void 0||t===""){this.knowledge.clear();return}let n=[];for(let a of this.knowledge.keys())a.includes(t)&&n.push(a);for(let a of n)this.knowledge.delete(a)}resetByBudgetId(t){this.reset(`:${t}`)}getStats(){let t={};for(let[n,a]of this.knowledge.entries())t[n]=a;return{entryCount:this.knowledge.size,entries:t}}};function vm(e,t,n){let a=new Map(e.map(r=>[r.id,{...r}]));for(let r of t){if(r.deleted&&!n?.preserveDeleted){a.delete(r.id);continue}let i=a.get(r.id)??{};a.set(r.id,{...i,...r})}return Array.from(a.values())}var kC=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.month,{...i}]));for(let i of t){if(i.deleted&&!a){r.delete(i.month);continue}let o=r.get(i.month)??{};r.set(i.month,{...o,...i})}return Array.from(r.values())},IC=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.id,NC(i)]));for(let i of t){if(i.deleted&&!a){r.delete(i.id);continue}let o=r.get(i.id);if(!o){r.set(i.id,NC(i));continue}let s={...o,...i,categories:o.categories?o.categories.map(d=>({...d})):o.categories};if(i.categories){let d=new Map((o.categories??[]).map(u=>[u.id,{...u}]));for(let u of i.categories)if(u.deleted&&!a)d.delete(u.id);else{let l=d.get(u.id)??{};d.set(u.id,{...l,...u})}s.categories=Array.from(d.values())}r.set(i.id,s)}return Array.from(r.values())},V8=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.id,DC(i)]));for(let i of t){if(i.deleted&&!a){r.delete(i.id);continue}let o=r.get(i.id);if(!o){r.set(i.id,DC(i));continue}let s={...o,...i,subtransactions:o.subtransactions?o.subtransactions.map(d=>({...d})):o.subtransactions};if(i.subtransactions){let d=new Map((o.subtransactions??[]).map(u=>[u.id,{...u}]));for(let u of i.subtransactions)if(u.deleted&&!a)d.delete(u.id);else{let l=d.get(u.id)??{};d.set(u.id,{...l,...u})}s.subtransactions=Array.from(d.values())}r.set(i.id,s)}return Array.from(r.values())},NC=e=>({...e,categories:e.categories?e.categories.map(t=>({...t})):e.categories}),DC=e=>({...e,subtransactions:e.subtransactions?e.subtransactions.map(t=>({...t})):e.subtransactions});var Ed=class{constructor(t,n){this.ynabAPI=t,this.deltaCache=n}async fetchAccounts(t,n){let a=Te.generateKey("accounts","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.accounts.getAccounts(t,r):await this.ynabAPI.accounts.getAccounts(t);return{data:i.data.accounts,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.ACCOUNTS,n))}async fetchCategories(t,n){let a=Te.generateKey("categories","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.categories.getCategories(t,r):await this.ynabAPI.categories.getCategories(t);return{data:i.data.category_groups,serverKnowledge:i.data.server_knowledge??0}},IC,this.buildDeltaOptions(ot.CATEGORIES,n))}async fetchTransactions(t,n,a,r){let i=n??"all",o=a??"all",s=Te.generateKey("transactions","list",t,i,o);return await this.deltaCache.fetchWithDelta(s,t,async d=>{let u=await this.ynabAPI.transactions.getTransactions(t,n,a,d);return{data:u.data.transactions,serverKnowledge:u.data.server_knowledge??0}},V8,this.buildDeltaOptions(ot.TRANSACTIONS,r))}async fetchTransactionsByAccount(t,n,a,r){let i=a??"all",o=Te.generateKey("transactions","account",t,n,i);return await this.deltaCache.fetchWithDelta(o,t,async s=>{let d=await this.ynabAPI.transactions.getTransactionsByAccount(t,n,a,void 0,s);return{data:d.data.transactions,serverKnowledge:d.data.server_knowledge??0}},V8,this.buildDeltaOptions(ot.TRANSACTIONS,r))}async fetchAccountsFull(t){let n=await this.ynabAPI.accounts.getAccounts(t);return{data:n.data.accounts.filter(r=>!r.deleted),wasCached:!1,usedDelta:!1,serverKnowledge:n.data.server_knowledge??0}}async fetchTransactionsByAccountFull(t,n,a){let r=await this.ynabAPI.transactions.getTransactionsByAccount(t,n,a);return{data:r.data.transactions.filter(o=>!o.deleted),wasCached:!1,usedDelta:!1,serverKnowledge:r.data.server_knowledge??0}}async fetchScheduledTransactions(t,n){let a=Te.generateKey("scheduled_transactions","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.scheduledTransactions.getScheduledTransactions(t,r):await this.ynabAPI.scheduledTransactions.getScheduledTransactions(t);return{data:i.data.scheduled_transactions,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.SCHEDULED_TRANSACTIONS,n))}async fetchPayees(t,n){let a=Te.generateKey("payees","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.payees.getPayees(t,r):await this.ynabAPI.payees.getPayees(t);return{data:i.data.payees,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.PAYEES,n))}async fetchMonths(t,n){let a=Te.generateKey("months","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.months.getPlanMonths(t,r):await this.ynabAPI.months.getPlanMonths(t);return{data:i.data.months,serverKnowledge:i.data.server_knowledge??0}},kC,this.buildDeltaOptions(ot.MONTHS,n))}async fetchBudgets(t){let n=Te.generateKey("budgets","list"),a=await this.deltaCache.fetchWithDelta(n,"global",async()=>{let r=await this.ynabAPI.plans.getPlans(),i=r.data.server_knowledge??0;return{data:r.data.plans,serverKnowledge:i}},vm,{ttl:t?.ttl??ot.BUDGETS,forceFullRefresh:!0});return{...a,data:a.data}}buildDeltaOptions(t,n){return{ttl:n?.ttl??t,...n?.forceFullRefresh!==void 0&&{forceFullRefresh:n.forceFullRefresh}}}};var Xt;function eae(e){if(Xt&&!Xt.manuallyConfigured&&Xt.ynabAPI&&Xt.ynabAPI!==e&&(Xt=void 0),Xt?.deltaFetcher)return Xt.deltaFetcher;let t=Xt?{...Xt}:{};t.manuallyConfigured===void 0&&(t.manuallyConfigured=!1),t.deltaCache||(t.knowledgeStore||(t.knowledgeStore=new Ka),t.deltaCache=new Ha(Ie,t.knowledgeStore));let n=new Ed(e,t.deltaCache);return t.deltaFetcher=n,t.ynabAPI||(t.ynabAPI=e),Xt=t,n}function RC(e){return e!==null&&typeof e=="object"&&e instanceof Ed&&typeof e.fetchAccounts=="function"&&typeof e.fetchCategories=="function"}function EC(e){return e!==null&&typeof e=="object"&&e instanceof Ha&&typeof e.fetchWithDelta=="function"}function PC(e){return e!==null&&typeof e=="object"&&e instanceof Ka&&typeof e.get=="function"&&typeof e.update=="function"}function bm(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&(e.constructor===Object||e.constructor===void 0)}function Zi(e){if(e===null)return"null";if(e===void 0)return"undefined";let t=typeof e;if(t!=="object")return t;let n=e.constructor?.name;return n?`${t} (${n})`:t}function Vn(e,t,n){if(n!==void 0){if(!RC(t))throw new Error(`resolveDeltaFetcherArgs: When providing 3 arguments, the second argument must be a DeltaFetcher instance. Got: ${Zi(t)}`);if(!bm(n))throw new Error(`resolveDeltaFetcherArgs: When providing 3 arguments, the third argument must be a params object. Got: ${Zi(n)}`);return{deltaFetcher:t,params:n}}if(RC(t))throw new Error("resolveDeltaFetcherArgs: When providing 2 arguments, the second argument must be a params object, not a DeltaFetcher. To use a custom DeltaFetcher, provide all 3 arguments: (ynabAPI, deltaFetcher, params)");if(!bm(t))throw new Error(`resolveDeltaFetcherArgs: When providing 2 arguments, the second argument must be a params object. Got: ${Zi(t)}`);return{deltaFetcher:eae(e),params:t}}function Lr(e,t,n){if(n!==void 0){if(!EC(e))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the first argument must be a DeltaCache instance. Got: ${Zi(e)}`);if(!PC(t))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the second argument must be a ServerKnowledgeStore instance. Got: ${Zi(t)}`);if(!bm(n))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the third argument must be a params object. Got: ${Zi(n)}`);return{deltaCache:e,knowledgeStore:t,params:n}}if(t!==void 0){let i=PC(t),o=bm(t);if(!i&&!o)throw new Error(`resolveDeltaWriteArgs: When providing 2 arguments, the second argument must be either a ServerKnowledgeStore or a params object. Got: ${Zi(t)}`);if(o)throw new Error("resolveDeltaWriteArgs: Invalid argument combination. When providing 2 arguments where the second is a params object, this is ambiguous. Either provide 1 argument (params only) or 3 arguments (deltaCache, knowledgeStore, params).");if(i)throw new Error("resolveDeltaWriteArgs: When providing DeltaCache and ServerKnowledgeStore, you must also provide params as the third argument. Got 2 arguments, expected 3: (deltaCache, knowledgeStore, params)")}if(EC(e))throw new Error("resolveDeltaWriteArgs: When providing only 1 argument, it must be a params object, not a DeltaCache. To use a custom DeltaCache, provide all 3 arguments: (deltaCache, knowledgeStore, params)");if(!bm(e))throw new Error(`resolveDeltaWriteArgs: When providing only 1 argument, it must be a params object. Got: ${Zi(e)}`);if(Xt)return Xt.knowledgeStore||(Xt.knowledgeStore=new Ka),Xt.deltaCache||(Xt.deltaCache=new Ha(Ie,Xt.knowledgeStore)),{deltaCache:Xt.deltaCache,knowledgeStore:Xt.knowledgeStore,params:e};let a=new Ka;return{deltaCache:new Ha(Ie,a),knowledgeStore:a,params:e}}var fn=c.object({cached:c.boolean().optional().describe("Indicates if data was served from cache"),cache_info:c.string().optional().describe('Human-readable cache status message (e.g., "Cache hit", "Cache miss")'),usedDelta:c.boolean().optional().describe("Indicates if delta merge optimization was applied for budgets")}),Xg=c.object({success:c.boolean().describe("Indicates operation success"),message:c.string().describe("Human-readable success message")}),P5e=Xg.extend({details:c.record(c.string(),c.unknown()).optional().describe("Additional confirmation details as key-value pairs")}),ba=c.object({total_count:c.number().int().describe("Total number of items available"),returned_count:c.number().int().describe("Number of items returned"),offset:c.number().int().describe("Offset used for this response"),has_more:c.boolean().describe("Whether more items exist beyond this page"),next_offset:c.number().int().optional().describe("Offset for next page, if has_more is true")}),C5e=c.object({error:c.string().describe("Error message"),code:c.string().optional().describe("Error code for categorization"),details:c.string().optional().describe("Additional error context or details")});var CC=c.object({id:c.string()}),Z8=c.object({user:CC}),W8=c.object({default_budget_id:c.string().nullable(),has_default:c.boolean(),message:c.string()}),Y8=Xg.extend({default_budget_id:c.string(),cache_warm_started:c.boolean()}),G8=Xg.pick({success:!0}),AC=c.object({name:c.string(),version:c.string(),node_version:c.string(),platform:c.string(),arch:c.string(),pid:c.number(),uptime_ms:c.number(),uptime_readable:c.string(),env:c.record(c.string(),c.unknown())}),MC=c.object({rss_mb:c.number(),heap_used_mb:c.number(),heap_total_mb:c.number(),external_mb:c.number(),array_buffers_mb:c.number(),description:c.record(c.string(),c.string())}),zC=c.object({token_present:c.boolean(),token_length:c.number(),token_preview:c.string().nullable(),ynab_env_keys_present:c.array(c.string()),working_directory:c.string()}),FC=c.object({entries:c.number(),estimated_size_kb:c.number(),keys:c.array(c.string()),hits:c.number().optional(),misses:c.number().optional(),evictions:c.number().optional(),lastCleanup:c.string().nullable().optional(),maxEntries:c.number().optional(),hitRate:c.string().optional(),performance_summary:c.string().optional()}),UC=c.object({enabled:c.boolean(),knowledge_entries:c.number(),knowledge_stats:c.record(c.string(),c.unknown()),feature_flag:c.string(),delta_hits:c.number(),delta_misses:c.number(),delta_hit_rate:c.number(),merge_operations:c.number(),knowledge_gap_events:c.number()}),H8=c.object({timestamp:c.string(),server:AC.optional(),memory:MC.optional(),environment:zC.optional(),cache:FC.optional(),delta:UC.optional()}),Qg=c.object({format:c.string()}),e2=c.object({iso_code:c.string(),example_format:c.string(),decimal_digits:c.number(),decimal_separator:c.string().optional(),symbol_first:c.boolean().optional(),group_separator:c.string().optional(),currency_symbol:c.string().optional(),display_symbol:c.boolean().optional()}),JC=c.object({id:c.string(),name:c.string(),last_modified_on:c.string().optional(),first_month:c.string().optional(),last_month:c.string().optional(),date_format:Qg.optional(),currency_format:e2.optional(),accounts_count:c.number(),categories_count:c.number(),payees_count:c.number(),months_count:c.number(),message:c.string()}),K8=c.object({budget:JC});var jC=c.object({id:c.string().describe("Budget ID"),name:c.string().describe("Budget name"),last_modified_on:c.string().optional().describe("Last modification timestamp"),first_month:c.string().optional().describe("First month in budget"),last_month:c.string().optional().describe("Last month in budget"),date_format:Qg.optional().describe("Date format settings"),currency_format:e2.optional().describe("Currency format settings")}),X8=fn.extend({budgets:c.array(jC).describe("List of budgets")});var wm=c.object({id:c.string().describe("Account ID"),name:c.string().describe("Account name"),type:c.string().describe("Account type"),on_budget:c.boolean().describe("On-budget flag"),closed:c.boolean().describe("Closed flag"),note:c.string().optional().describe("Account note"),balance:c.number().describe("Account balance in dollars"),cleared_balance:c.number().describe("Cleared balance in dollars"),uncleared_balance:c.number().describe("Uncleared balance in dollars"),transfer_payee_id:c.string().describe("Transfer payee ID"),direct_import_linked:c.boolean().optional().describe("Direct import linked flag"),direct_import_in_error:c.boolean().optional().describe("Direct import error flag")}),Q8=fn.merge(ba).extend({accounts:c.array(wm).describe("List of accounts")}),ev=fn.extend({account:wm.describe("Account details")});var Pd=c.object({id:c.string().describe("Transaction ID"),date:c.string().describe("Transaction date"),amount:c.number().describe("Transaction amount in dollars"),memo:c.string().optional().describe("Transaction memo"),cleared:c.string().describe("Cleared status"),approved:c.boolean().describe("Approved flag"),flag_color:c.string().optional().describe("Flag color"),account_id:c.string().describe("Account ID"),payee_id:c.string().nullish().describe("Payee ID"),category_id:c.string().nullish().describe("Category ID"),transfer_account_id:c.string().nullish().describe("Transfer account ID"),transfer_transaction_id:c.string().nullish().describe("Transfer transaction ID"),matched_transaction_id:c.string().nullish().describe("Matched transaction ID"),import_id:c.string().optional().describe("Import ID"),deleted:c.boolean().describe("Deleted flag"),account_name:c.string().optional().describe("Account name"),payee_name:c.string().optional().describe("Payee name"),category_name:c.string().optional().describe("Category name")}),qC=c.object({id:c.string().describe("Transaction ID"),date:c.string().describe("Transaction date"),amount:c.number().describe("Transaction amount in dollars"),memo:c.string().optional().describe("Transaction memo"),account_id:c.string().describe("Account ID"),payee_name:c.string().optional().describe("Payee name"),category_name:c.string().optional().describe("Category name")}),tae=fn.merge(ba).extend({transactions:c.array(Pd).describe("List of transactions")}),nae=c.object({message:c.string().describe("Large result set message"),suggestion:c.string().describe("Suggestion to narrow results"),showing:c.string().describe("Human-readable summary of transactions shown"),total_count:c.number().int().describe("Total transaction count"),estimated_size_kb:c.number().describe("Estimated response size in KB"),preview_transactions:c.array(qC).describe("Preview transactions")}),tv=c.union([tae,nae]),nv=fn.extend({transaction:Pd.describe("Transaction details")});var Sm=c.object({id:c.string().describe("Category ID"),category_group_id:c.string().describe("Category group ID"),category_group_name:c.string().optional().describe("Category group name"),name:c.string().describe("Category name"),hidden:c.boolean().describe("Hidden flag"),original_category_group_id:c.string().optional().describe("Original category group ID"),note:c.string().optional().describe("Category note"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),balance:c.number().describe("Balance in dollars"),goal_type:c.string().optional().describe("Goal type"),goal_creation_month:c.string().optional().describe("Goal creation month"),goal_target:c.number().optional().describe("Goal target amount in dollars"),goal_target_month:c.string().optional().describe("Goal target month"),goal_percentage_complete:c.number().optional().describe("Goal percentage complete"),goal_months_to_budget:c.number().optional().describe("Goal months to budget"),goal_under_funded:c.number().optional().describe("Goal underfunded amount in dollars"),goal_overall_funded:c.number().optional().describe("Goal overall funded amount in dollars"),goal_overall_left:c.number().optional().describe("Goal overall left amount in dollars"),deleted:c.boolean().optional().describe("Deleted flag")}),LC=c.object({id:c.string().describe("Category group ID"),name:c.string().describe("Category group name"),hidden:c.boolean().describe("Hidden flag"),deleted:c.boolean().describe("Deleted flag")}),rv=fn.merge(ba).extend({categories:c.array(Sm).describe("List of categories"),category_groups:c.array(LC).describe("List of category groups")}),av=fn.extend({category:Sm.describe("Category details")});var iv=c.object({id:c.string().describe("Payee ID"),name:c.string().describe("Payee name"),transfer_account_id:c.string().optional().describe("Transfer account ID"),deleted:c.boolean().describe("Deleted flag")}),ov=fn.merge(ba).extend({payees:c.array(iv).describe("List of payees")}),sv=fn.extend({payee:iv.describe("Payee details")});var BC=c.object({id:c.string().describe("Category ID"),category_group_id:c.string().describe("Category group ID"),category_group_name:c.string().optional().describe("Category group name"),name:c.string().describe("Category name"),hidden:c.boolean().describe("Hidden flag"),original_category_group_id:c.string().optional().describe("Original category group ID"),note:c.string().optional().describe("Category note"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),balance:c.number().describe("Balance in dollars"),goal_type:c.string().optional().describe("Goal type"),goal_creation_month:c.string().optional().describe("Goal creation month"),goal_target:c.number().optional().describe("Goal target in milliunits"),goal_target_month:c.string().optional().describe("Goal target month"),goal_percentage_complete:c.number().optional().describe("Goal percentage complete"),goal_months_to_budget:c.number().optional().describe("Goal months to budget"),goal_under_funded:c.number().optional().describe("Goal under funded amount"),goal_overall_funded:c.number().optional().describe("Goal overall funded amount"),goal_overall_left:c.number().optional().describe("Goal overall left amount"),deleted:c.boolean().describe("Deleted flag")}),VC=c.object({month:c.string().describe("Month identifier"),note:c.string().optional().describe("Month note"),income:c.number().describe("Income in dollars"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),to_be_budgeted:c.number().describe("To be budgeted in dollars"),age_of_money:c.number().nullish().describe("Age of money in days"),deleted:c.boolean().describe("Deleted flag"),categories:c.array(BC).optional().describe("Categories for this month")}),ZC=c.object({month:c.string().describe("Month identifier"),note:c.string().optional().describe("Month note"),income:c.number().describe("Income in dollars"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),to_be_budgeted:c.number().describe("To be budgeted in dollars"),age_of_money:c.number().nullish().describe("Age of money in days"),deleted:c.boolean().describe("Deleted flag")}),dv=fn.extend({month:VC.describe("Month details")}),cv=fn.merge(ba).extend({months:c.array(ZC).describe("List of months")});var lv=c.object({id:c.string(),transaction_id:c.string(),amount:c.number(),memo:c.string().optional(),payee_id:c.string().optional(),payee_name:c.string().optional(),category_id:c.string().optional(),category_name:c.string().optional(),transfer_account_id:c.string().optional(),transfer_transaction_id:c.string().optional(),deleted:c.boolean()}),t2=Pd.extend({account_balance:c.number().optional(),account_cleared_balance:c.number().optional(),subtransactions:c.array(lv).optional()}),YC=c.object({name:c.string(),quantity:c.number().optional(),amount:c.number(),memo:c.string().optional()}),GC=c.object({category_id:c.string(),category_name:c.string().optional(),items:c.array(YC),subtotal:c.number(),tax:c.number(),total:c.number()}),uv=c.object({subtotal:c.number(),tax:c.number(),total:c.number(),categories:c.array(GC)}),pv=c.object({total_requested:c.number(),created:c.number().optional(),updated:c.number().optional(),duplicates:c.number().optional(),failed:c.number()}),mv=c.object({request_index:c.number(),status:c.enum(["created","duplicate","updated","failed"]),transaction_id:c.string().optional(),correlation_key:c.string(),error_code:c.string().optional(),error:c.string().optional()}).passthrough(),WC=c.object({amount:c.number().optional(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),memo:c.string().optional(),payee_id:c.string().nullable().optional(),payee_name:c.string().nullable().optional(),category_id:c.string().nullable().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),flag_color:c.enum(["red","orange","yellow","green","blue","purple"]).nullable().optional()}),HC=c.object({transaction_id:c.string(),before:c.union([c.literal("unavailable"),WC]),after:WC}),KC=c.object({code:c.string(),count:c.number(),message:c.string(),sample_ids:c.array(c.string()).optional()}),fv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_transaction"),request:c.record(c.string(),c.unknown())}),c.object({transaction:t2})]),rae=c.object({request_index:c.number(),account_id:c.string(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),amount:c.number(),memo:c.string().optional(),payee_id:c.string().optional(),payee_name:c.string().optional(),category_id:c.string().optional(),import_id:c.string().optional()}),hv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_transactions"),validation:c.literal("passed"),summary:c.object({total_transactions:c.number(),total_amount:c.number(),accounts_affected:c.array(c.string()),date_range:c.object({earliest:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),latest:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)}).optional(),categories_affected:c.array(c.string())}),transactions_preview:c.array(rae),note:c.string()}).strict(),c.object({success:c.boolean(),server_knowledge:c.number().optional(),summary:pv,results:c.array(mv),transactions:c.array(Pd).optional(),duplicate_import_ids:c.array(c.string()).optional(),message:c.string().optional(),mode:c.enum(["full","summary","ids_only"]).optional()}).passthrough()]),gv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_transaction"),request:c.record(c.string(),c.unknown())}),c.object({transaction:t2,updated_balance:c.number(),updated_cleared_balance:c.number()})]),_v=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_transactions"),validation:c.literal("passed"),summary:c.object({total_transactions:c.number(),accounts_affected:c.number(),fields_to_update:c.array(c.string())}),transactions_preview:c.array(HC),warnings:c.array(KC).optional(),note:c.string()}).strict(),c.object({success:c.boolean(),server_knowledge:c.number().optional(),summary:pv,results:c.array(mv),transactions:c.array(Pd).optional(),message:c.string().optional(),mode:c.enum(["full","summary","ids_only"]).optional()}).passthrough()]),yv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_delete_transaction"),request:c.record(c.string(),c.unknown())}),c.object({message:c.string(),transaction:c.object({id:c.string(),deleted:c.boolean()}),updated_balance:c.number(),updated_cleared_balance:c.number()})]),XC=c.object({account_id:c.string(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),amount:c.number(),memo:c.string().optional().nullable(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),flag_color:c.enum(["red","orange","yellow","green","blue","purple"]).optional().nullable(),payee_id:c.string().optional().nullable(),payee_name:c.string().optional().nullable(),category_id:c.string().optional().nullable(),import_id:c.string().optional().nullable()}),QC=lv.omit({id:!0,transaction_id:!0,deleted:!0}),vv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_receipt_split_transaction"),transaction_preview:XC,receipt_summary:uv,subtransactions:c.array(QC)}),c.object({transaction:t2,receipt_summary:uv})]),aae=c.object({budget_id:c.string(),name:c.string(),type:c.string(),balance:c.number()}),bv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_account"),request:aae}),c.object({account:wm})]),iae=c.object({budget_id:c.string(),category_id:c.string(),budgeted:c.number(),month:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)}),wv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_category"),request:iae}),c.object({category:Sm,updated_month:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)})]);var Qt=c.object({value_milliunits:c.number().int(),value:c.number().finite(),value_display:c.string(),currency:c.string(),direction:c.enum(["credit","debit","balanced"])}),Sv=c.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Date must be in ISO format (YYYY-MM-DD)").refine(e=>{let t=Date.parse(e);if(Number.isNaN(t))return!1;let n=new Date(t),a=n.getUTCFullYear(),r=String(n.getUTCMonth()+1).padStart(2,"0"),i=String(n.getUTCDate()).padStart(2,"0");return`${a}-${r}-${i}`===e},{message:"Invalid calendar date (e.g., month must be 01-12, day must be valid for the month)"}),Tm=c.object({id:c.string().uuid(),date:Sv,amount:c.number(),payee:c.string(),memo:c.string().optional(),sourceRow:c.number().int(),raw:c.object({date:c.string(),amount:c.string(),description:c.string()}).strict(),warnings:c.array(c.string()).optional(),amount_money:Qt}),Ou=c.object({id:c.string(),date:Sv,amount:c.number(),payee:c.string().nullable(),categoryName:c.string().nullable(),cleared:c.enum(["cleared","uncleared","reconciled"]),approved:c.boolean(),memo:c.string().nullable().optional(),amount_money:Qt}),nA=c.object({ynab_transaction:Ou,confidence:c.number().min(0).max(100),match_reason:c.string(),explanation:c.string()}),n2=c.object({bank_transaction:Tm,ynab_transaction:Ou.optional(),candidates:c.array(nA).optional(),confidence:c.enum(["high","medium","low","none"]),confidence_score:c.number().min(0).max(100),match_reason:c.string(),top_confidence:c.number().optional(),action_hint:c.string().optional(),recommendation:c.string().optional()}),rA=c.object({current_cleared:Qt,current_uncleared:Qt,current_total:Qt,target_statement:Qt,discrepancy:Qt,on_track:c.boolean()}),aA=c.object({statement_date_range:c.string(),bank_transactions_count:c.number(),ynab_transactions_count:c.number(),ynab_in_range_count:c.number().optional(),ynab_outside_range_count:c.number().optional(),auto_matched:c.number(),suggested_matches:c.number(),unmatched_bank:c.number(),unmatched_ynab:c.number(),current_cleared_balance:Qt,target_statement_balance:Qt,discrepancy:Qt,discrepancy_explanation:c.string()}),iA=c.object({id:c.string(),type:c.enum(["repeat_amount","near_match","anomaly"]),severity:c.enum(["info","warning","critical"]),title:c.string(),description:c.string(),evidence:c.record(c.string(),c.unknown()).optional()}),oA=c.discriminatedUnion("action_type",[c.object({id:c.string(),action_type:c.literal("create_transaction"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({account_id:c.string(),date:Sv,amount:c.number(),payee_name:c.string(),memo:c.string().optional(),cleared:c.enum(["cleared","uncleared"]),approved:c.boolean(),category_id:c.string().optional()})}),c.object({id:c.string(),action_type:c.literal("update_cleared"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({transaction_id:c.string(),cleared:c.enum(["cleared","uncleared","reconciled"])})}),c.object({id:c.string(),action_type:c.literal("review_duplicate"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({candidate_ids:c.array(c.string()),bank_transaction:Tm,suggested_match_id:c.string().optional()})}),c.object({id:c.string(),action_type:c.literal("manual_review"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({issue_type:c.string(),related_transactions:c.array(c.object({source:c.enum(["bank","ynab"]),id:c.string(),description:c.string()})).optional()})})]),eA=c.object({balance:Qt,cleared_balance:Qt,uncleared_balance:Qt}),tA=c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullable().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),payee_name:c.string().nullable().optional(),category_name:c.string().nullable().optional(),import_id:c.string().nullable().optional()}).passthrough(),oae=c.object({account_id:c.string(),date:c.string(),amount:c.number(),payee_name:c.string().optional(),memo:c.string().optional(),cleared:c.enum(["cleared","uncleared"]).optional(),approved:c.boolean().optional(),import_id:c.string().optional()}),sae=c.object({transaction_id:c.string(),new_date:c.string().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional()}),dae=c.object({transaction_id:c.string().nullable(),import_id:c.string().optional()}),cae=c.discriminatedUnion("type",[c.object({type:c.literal("create_transaction"),transaction:tA.nullable(),reason:c.string(),bulk_chunk_index:c.number().optional(),correlation_key:c.string().optional()}),c.object({type:c.literal("create_transaction_failed"),transaction:oae,reason:c.string(),bulk_chunk_index:c.number().optional(),correlation_key:c.string().optional()}),c.object({type:c.literal("create_transaction_duplicate"),transaction:dae,reason:c.string(),bulk_chunk_index:c.number(),correlation_key:c.string().optional(),duplicate:c.literal(!0)}),c.object({type:c.literal("update_transaction"),transaction:c.union([tA.nullable(),sae]),reason:c.string()}),c.object({type:c.literal("balance_checkpoint"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("bulk_create_fallback"),transaction:c.null(),reason:c.string(),bulk_chunk_index:c.number()})]),uae=c.object({bank_transactions_count:c.number(),ynab_transactions_count:c.number(),matches_found:c.number(),missing_in_ynab:c.number(),missing_in_bank:c.number(),transactions_created:c.number(),transactions_updated:c.number(),dates_adjusted:c.number(),dry_run:c.boolean()}),lae=c.object({chunks_processed:c.number(),bulk_successes:c.number(),sequential_fallbacks:c.number(),duplicates_detected:c.number(),failed_transactions:c.number(),bulk_chunk_failures:c.number(),transaction_failures:c.number(),sequential_attempts:c.number().optional()}).refine(e=>e.failed_transactions===e.transaction_failures,{message:"failed_transactions must equal transaction_failures"}),sA=c.object({summary:uae,account_balance:c.object({before:eA,after:eA}),actions_taken:c.array(cae),recommendations:c.array(c.string()),balance_reconciliation:c.unknown().optional(),bulk_operation_details:lae.optional()}),dA=c.object({data_freshness:c.string(),data_source:c.string(),server_knowledge:c.number().optional(),fetched_at:c.string(),accounts_count:c.number().optional(),transactions_count:c.number().optional(),cache_status:c.object({accounts_cached:c.boolean(),transactions_cached:c.boolean(),delta_merge_applied:c.boolean()})}).catchall(c.unknown()),pae=c.object({delimiter:c.string(),decimal_separator:c.string(),thousands_separator:c.string().nullable(),date_format:c.string(),header_row:c.boolean(),date_column:c.string().nullable(),amount_column:c.string().nullable(),payee_column:c.string().nullable()}),mae=c.object({version:c.string(),schema_url:c.string(),generated_at:c.string(),account:c.object({id:c.string().optional(),name:c.string().optional()}),summary:aA,balance:rA.extend({discrepancy_direction:c.enum(["balanced","ynab_higher","bank_higher"])}),insights:c.array(iA),next_steps:c.array(c.string()),matches:c.object({auto:c.array(n2),suggested:c.array(n2)}),unmatched:c.object({bank:c.array(Tm),ynab:c.array(Ou),ynab_outside_date_range:c.array(Ou).optional()}),recommendations:c.array(oA).optional(),csv_format:pae.optional(),execution:sA.optional(),audit:dA.optional()}),fae=c.object({unmatched_bank:c.array(Tm),unmatched_ynab:c.array(Ou),suggestions:c.array(n2)}).strict(),Tv=c.union([c.object({human:c.string(),structured:c.union([mae,fae])}).strict(),c.object({human:c.string()}).strict()]).refine(e=>{if("structured"in e&&e.structured&&"balance"in e.structured&&typeof e.structured.balance=="object"&&e.structured.balance!==null){let t=e.structured.balance.discrepancy.value,n=e.structured.balance.discrepancy_direction;if(Math.abs(t)<.01)return n==="balanced";if(t>0)return n==="ynab_higher";if(t<0)return n==="bank_higher"}return!0},{message:"Discrepancy direction mismatch: direction must match the numeric discrepancy amount",path:["balance","discrepancy_direction"]});function hae(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let t=Date.parse(e);if(Number.isNaN(t))return!1;let n=new Date(t),a=n.getUTCFullYear(),r=String(n.getUTCMonth()+1).padStart(2,"0"),i=String(n.getUTCDate()).padStart(2,"0");return`${a}-${r}-${i}`===e}var Wi=c.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Date must be in YYYY-MM-DD format").refine(hae,{message:"Invalid calendar date (e.g., month must be 01-12, day must be valid for the month)"}),gae=c.object({date:Wi,amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),description:c.string(),row_number:c.number(),suggested_payee_id:c.string().optional(),suggested_payee_name:c.string().optional(),suggestion_reason:c.string().optional()}),_ae=c.object({id:c.string(),date:Wi,amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),payee_name:c.string().nullable(),memo:c.string().nullish(),cleared:c.string()}),yae=c.object({bank_date:Wi,bank_amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),bank_description:c.string(),ynab_date:Wi,ynab_amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),ynab_payee:c.string().nullable(),ynab_transaction:c.object({id:c.string(),cleared:c.string()}),match_score:c.number(),match_reasons:c.array(c.string())}),cA=c.object({date:Wi,amount:c.number(),description:c.string(),raw_amount:c.string(),raw_date:c.string(),row_number:c.number()}),uA=c.object({id:c.string(),date:Wi,amount:c.number(),payee_name:c.string().nullable(),memo:c.string().nullish(),cleared:c.string(),account_name:c.string().optional(),category_name:c.string().optional()}),vae=c.object({bank_transaction:cA,ynab_transaction:uA,match_score:c.number().min(0).max(100),match_reasons:c.array(c.string())}),lA=c.object({amount_tolerance:c.number().optional(),date_tolerance_days:c.number().optional()}),pA=c.object({start:Wi,end:Wi}).refine(e=>{let t=Date.parse(e.start),n=Date.parse(e.end);return t<=n},{message:"Start date must be before or equal to end date"}),mA=c.object({exported_at:c.string(),total_transactions:c.number(),minimal:c.boolean(),filters:c.object({budget_id:c.string().optional(),account_id:c.string().nullable(),category_id:c.string().nullable(),since_date:c.string().nullable(),type:c.string().nullable()})}),bae=c.object({id:c.string(),date:c.string(),amount:c.number(),payee_name:c.string().nullable(),cleared:c.string()}),wae=c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullish(),cleared:c.string(),approved:c.boolean(),flag_color:c.string().nullable(),account_id:c.string(),payee_id:c.string().nullable(),category_id:c.string().nullable(),transfer_account_id:c.string().nullable(),transfer_transaction_id:c.string().nullable(),matched_transaction_id:c.string().nullable(),import_id:c.string().nullable(),deleted:c.boolean(),account_name:c.string().optional(),payee_name:c.string().nullable(),category_name:c.string().nullable()}),fA=c.union([bae,wae]),p8e=c.object({export_info:mA,transactions:c.array(fA)}),xv=c.object({summary:c.object({bank_transactions_count:c.number(),ynab_transactions_count:c.number(),matches_found:c.number(),missing_in_ynab:c.number(),missing_in_bank:c.number(),date_range:pA,parameters:lA}),matches:c.array(yae),missing_in_ynab:c.array(gae),missing_in_bank:c.array(_ae)}),$v=c.object({message:c.string(),filename:c.string(),full_path:c.string(),export_directory:c.string(),export_mode:c.enum(["minimal","full"]),minimal_fields:c.string().nullable(),filename_explanation:c.string(),preview_count:c.number(),total_count:c.number(),preview_transactions:c.array(c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullable().optional(),payee_name:c.string().nullable().optional(),category_name:c.string().nullable().optional()}))});var Ze={READ_ONLY_EXTERNAL:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0},WRITE_EXTERNAL_CREATE:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0},WRITE_EXTERNAL_UPDATE:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0},WRITE_EXTERNAL_DELETE:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!0,openWorldHint:!0},UTILITY_LOCAL_READ_ONLY:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},UTILITY_LOCAL_MUTATION:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},UTILITY_LOCAL:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}};var Sae=c.object({budget_id:c.string().min(1,"Budget ID is required"),limit:c.number().int().positive().optional(),offset:c.number().int().min(0).optional(),response_format:c.enum(["json","markdown"]).default("markdown").optional()}).strict(),Tae=c.object({budget_id:c.string().min(1,"Budget ID is required"),account_id:c.string().min(1,"Account ID is required"),response_format:c.enum(["json","markdown"]).default("markdown").optional()}).strict(),xae=c.object({budget_id:c.string().min(1,"Budget ID is required"),name:c.string().min(1,"Account name is required"),type:c.enum(["checking","savings","creditCard","cash","lineOfCredit","otherAsset","otherLiability"]),balance:c.number().optional(),dry_run:c.boolean().optional()}).strict();async function $ae(e,t,n,a){let{deltaFetcher:r,params:i}=Vn(e,t,n);return await pt(async()=>{let o=await r.fetchAccounts(i.budget_id),s=o.data,d=o.wasCached,u=i.limit??50,l=i.offset??0,p=s.slice(l,l+u),m=l+u<s.length,h=i.response_format??"markdown",_={accounts:p.map(f=>({id:f.id,name:f.name,type:f.type,on_budget:f.on_budget,closed:f.closed,note:f.note,balance:he(f.balance),cleared_balance:he(f.cleared_balance),uncleared_balance:he(f.uncleared_balance),transfer_payee_id:f.transfer_payee_id,direct_import_linked:f.direct_import_linked,direct_import_in_error:f.direct_import_in_error})),total_count:s.length,returned_count:p.length,offset:l,has_more:m,next_offset:m?l+u:void 0,cached:d,cache_info:d?`Data retrieved from cache for improved performance${o.usedDelta?" (delta merge applied)":""}`:"Fresh data retrieved from YNAB API"};return{content:[{type:"text",text:h==="markdown"?uC(_):we.format(_)}],structuredContent:_}},"ynab:list_accounts","listing accounts",a)}async function Oae(e,t,n){return await pt(async()=>{let a=Te.generateKey($n.ACCOUNTS,"get",t.budget_id,t.account_id),r=Ie.has(a),i=await Ie.wrap(a,{ttl:ot.ACCOUNTS,loader:async()=>(await e.accounts.getAccountById(t.budget_id,t.account_id)).data.account}),o=t.response_format??"markdown",s={account:{id:i.id,name:i.name,type:i.type,on_budget:i.on_budget,closed:i.closed,note:i.note,balance:he(i.balance),cleared_balance:he(i.cleared_balance),uncleared_balance:he(i.uncleared_balance),transfer_payee_id:i.transfer_payee_id,direct_import_linked:i.direct_import_linked,direct_import_in_error:i.direct_import_in_error},cached:r,cache_info:r?"Data retrieved from cache for improved performance":"Fresh data retrieved from YNAB API"};return{content:[{type:"text",text:o==="markdown"?lC(s):we.format(s)}],structuredContent:s}},"ynab:get_account","getting account details",n)}async function Nae(e,t,n,a,r){let{deltaCache:i,params:o}=Lr(t,n,a);return await pt(async()=>{if(o.dry_run){let m={dry_run:!0,action:"ynab_create_account",request:{budget_id:o.budget_id,name:o.name,type:o.type,balance:o.balance??0}};return{content:[{type:"text",text:we.format(m)}],structuredContent:m}}let s={name:o.name,type:o.type,balance:o.balance?o.balance*1e3:0},u=(await e.accounts.createAccount(o.budget_id,{account:s})).data.account,l=Te.generateKey($n.ACCOUNTS,"list",o.budget_id);Ie.delete(l),i.invalidate(o.budget_id,$n.ACCOUNTS);let p={account:{id:u.id,name:u.name,type:u.type,on_budget:u.on_budget,closed:u.closed,note:u.note,balance:he(u.balance),cleared_balance:he(u.cleared_balance),uncleared_balance:he(u.uncleared_balance),transfer_payee_id:u.transfer_payee_id,direct_import_linked:u.direct_import_linked,direct_import_in_error:u.direct_import_in_error}};return{content:[{type:"text",text:we.format(p)}],structuredContent:p}},"ynab:create_account","creating account",r)}var hA=(e,t)=>{let{adapt:n,adaptWithDelta:a,adaptWrite:r}=Kt(t),i=Bn(t);e.register({name:"ynab_list_accounts",description:`List all accounts for a budget.
|
|
92
|
+
${d}`,['Ensure all content items have type="text" and a valid text property'])}let i=n.content[0];if(!i)return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler returned empty content",["Ensure the handler returns valid content in the response"]);if(i.type!=="text")throw new Error("Unexpected: firstContent is not text after validation");if(n.structuredContent!==void 0){let d=a.safeParse(n.structuredContent);if(!d.success){let u=Vi(d.error);return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,`Handler output does not match declared output schema: ${u.message}`,["Check that the handler returns data matching the output schema","Review the tool definition output schema"])}return typeof d.data!="object"||d.data===null||Array.isArray(d.data)?this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler output schema must resolve to a JSON object for structuredContent",["Ensure outputSchema root type is object","Return a JSON object from the tool handler"]):{...n,structuredContent:d.data}}let o;try{o=JSON.parse(i.text)}catch{return n}let s=a.safeParse(o);if(!s.success){let u=Vi(s.error).message;return this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,`Handler output does not match declared output schema: ${u}`,["Check that the handler returns data matching the output schema","Review the tool definition output schema"])}return typeof s.data!="object"||s.data===null||Array.isArray(s.data)?this.deps.errorHandler.createValidationError(`Output validation failed for ${t}`,"Handler output schema must resolve to a JSON object for structuredContent",["Ensure outputSchema root type is object","Return a JSON object from the tool handler"]):{...n,structuredContent:s.data}}};ym.MCP_TOOL_NAME_REGEX=/^[a-zA-Z0-9_.-]{1,128}$/;function Kt(e){let{ynabAPI:t,deltaFetcher:n,deltaCache:a,serverKnowledgeStore:r}=e,{errorHandler:i}=e;return{adapt:o=>async({input:s})=>o(t,s,i),adaptNoInput:o=>async s=>o(t,i),adaptWithDelta:o=>async({input:s})=>o(t,n,s,i),adaptWithDeltaAndProgress:o=>async({input:s,context:d})=>o(t,n,s,d.sendProgress,i),adaptWrite:o=>async({input:s})=>o(t,a,r,s,i)}}function Bn(e){return()=>({rawArguments:t})=>{let n=typeof t.budget_id=="string"&&t.budget_id.length>0?t.budget_id:void 0,a=$u.resolveBudgetId(n,e.getDefaultBudgetId(),e.errorHandler);if(typeof a=="string")return{budget_id:a};throw new _m(a)}}var OC=100,Qre={info(e,t){Kg.logSuccess("delta-cache",e,t?{...t}:{})},warn(e,t){let n={...t?{...t}:{},severity:"warn"};Kg.logSuccess("delta-cache",e,n)},error(e,t){let n=t?{...t}:{},a=n.error,r=typeof a=="string"?a:e;Kg.logError("delta-cache",e,n,r)}},Ha=class{constructor(t,n,a=Qre){this.cacheManager=t,this.knowledgeStore=n,this.logger=a,this.deltaHits=0,this.deltaMisses=0,this.mergeOperations=0,this.knowledgeGapEvents=0}async fetchWithDelta(t,n,a,r,i){let o=this.assertFiniteTtl("fetchWithDelta",t,i.ttl);if(!this.isDeltaEnabled())return this.fetchWithoutDelta(t,n,a,i);let s=this.cacheManager.get(t);if(i.forceFullRefresh&&s&&!(Date.now()-s.timestamp>s.ttl))return{data:s.snapshot,wasCached:!0,usedDelta:!1,serverKnowledge:s.serverKnowledge};let d=i.forceFullRefresh?void 0:this.knowledgeStore.get(t),u=!!(!i.forceFullRefresh&&s&&d!==void 0),l=u?d:void 0,p=await a(l),m=l!==void 0?p.serverKnowledge-l:0,h=!1;m>OC&&(this.logger.warn("delta-cache.knowledge-gap",{budgetId:n,cacheKey:t,lastKnowledge:l,serverKnowledge:p.serverKnowledge,gap:m,threshold:OC,action:"full-refresh",recommendation:"Consider forcing a full refresh to resync cache."}),h=!0,this.knowledgeGapEvents++,p=await a(void 0));let _=!h&&l!==void 0&&p.serverKnowledge>l,f,g=!1;_&&s?(this.mergeOperations++,f=r(s.snapshot,p.data,i.mergeOptions),g=!0):s&&l!==void 0&&!h?f=s.snapshot:f=this.filterDeleted(p.data);let y={snapshot:f,serverKnowledge:p.serverKnowledge,timestamp:Date.now(),ttl:o};i.staleWhileRevalidate!==void 0&&(y.staleWhileRevalidate=i.staleWhileRevalidate);let v={ttl:o};return i.staleWhileRevalidate!==void 0&&(v.staleWhileRevalidate=i.staleWhileRevalidate),this.cacheManager.set(t,y,v),this.knowledgeStore.update(t,p.serverKnowledge),u?this.deltaHits++:this.deltaMisses++,{data:f,wasCached:!!s,usedDelta:g,serverKnowledge:p.serverKnowledge}}getStats(){return{deltaHits:this.deltaHits,deltaMisses:this.deltaMisses,mergeOperations:this.mergeOperations,knowledgeGapEvents:this.knowledgeGapEvents}}invalidate(t,n){if(t)if(n){let a=`${n}:list:${t}`;this.cacheManager.deleteByPrefix(a)}else this.cacheManager.deleteByBudgetId(t)}forceFullRefresh(t,n){t?this.invalidate(t,n):this.cacheManager.clear(),n&&t?this.knowledgeStore.reset(`${n}:list:${t}`):t?this.knowledgeStore.resetByBudgetId(t):this.knowledgeStore.reset()}async fetchWithoutDelta(t,n,a,r){let i=this.assertFiniteTtl("fetchWithoutDelta",t,r.ttl),o=this.cacheManager.get(t);if(o&&(!(Date.now()-o.timestamp>o.ttl)||!r.forceFullRefresh))return{data:o.snapshot,wasCached:!0,usedDelta:!1,serverKnowledge:o.serverKnowledge};let s=await a(void 0),d=this.filterDeleted(s.data),u={snapshot:d,serverKnowledge:s.serverKnowledge,timestamp:Date.now(),ttl:i};r.staleWhileRevalidate!==void 0&&(u.staleWhileRevalidate=r.staleWhileRevalidate);let l={ttl:i};return r.staleWhileRevalidate!==void 0&&(l.staleWhileRevalidate=r.staleWhileRevalidate),this.cacheManager.set(t,u,l),this.knowledgeStore.update(t,s.serverKnowledge),{data:d,wasCached:!1,usedDelta:!1,serverKnowledge:s.serverKnowledge}}filterDeleted(t){return t.filter(n=>!n.deleted)}assertFiniteTtl(t,n,a){if(!Number.isFinite(a))throw new Error(`DeltaCache.${t} requires a finite ttl for cache key "${n}". Received: ${String(a)}.`);return a}isDeltaEnabled(){return process.env.YNAB_MCP_ENABLE_DELTA==="true"}};var Ka=class{constructor(){this.knowledge=new Map}get(t){return this.knowledge.get(t)}update(t,n){if(n<0)throw new Error(`server_knowledge must be non-negative, got: ${n}`);this.knowledge.set(t,n)}reset(t){if(t===void 0||t===""){this.knowledge.clear();return}let n=[];for(let a of this.knowledge.keys())a.includes(t)&&n.push(a);for(let a of n)this.knowledge.delete(a)}resetByBudgetId(t){this.reset(`:${t}`)}getStats(){let t={};for(let[n,a]of this.knowledge.entries())t[n]=a;return{entryCount:this.knowledge.size,entries:t}}};function vm(e,t,n){let a=new Map(e.map(r=>[r.id,{...r}]));for(let r of t){if(r.deleted&&!n?.preserveDeleted){a.delete(r.id);continue}let i=a.get(r.id)??{};a.set(r.id,{...i,...r})}return Array.from(a.values())}var kC=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.month,{...i}]));for(let i of t){if(i.deleted&&!a){r.delete(i.month);continue}let o=r.get(i.month)??{};r.set(i.month,{...o,...i})}return Array.from(r.values())},IC=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.id,NC(i)]));for(let i of t){if(i.deleted&&!a){r.delete(i.id);continue}let o=r.get(i.id);if(!o){r.set(i.id,NC(i));continue}let s={...o,...i,categories:o.categories?o.categories.map(d=>({...d})):o.categories};if(i.categories){let d=new Map((o.categories??[]).map(u=>[u.id,{...u}]));for(let u of i.categories)if(u.deleted&&!a)d.delete(u.id);else{let l=d.get(u.id)??{};d.set(u.id,{...l,...u})}s.categories=Array.from(d.values())}r.set(i.id,s)}return Array.from(r.values())},V8=(e,t,n)=>{let a=!!n?.preserveDeleted,r=new Map(e.map(i=>[i.id,DC(i)]));for(let i of t){if(i.deleted&&!a){r.delete(i.id);continue}let o=r.get(i.id);if(!o){r.set(i.id,DC(i));continue}let s={...o,...i,subtransactions:o.subtransactions?o.subtransactions.map(d=>({...d})):o.subtransactions};if(i.subtransactions){let d=new Map((o.subtransactions??[]).map(u=>[u.id,{...u}]));for(let u of i.subtransactions)if(u.deleted&&!a)d.delete(u.id);else{let l=d.get(u.id)??{};d.set(u.id,{...l,...u})}s.subtransactions=Array.from(d.values())}r.set(i.id,s)}return Array.from(r.values())},NC=e=>({...e,categories:e.categories?e.categories.map(t=>({...t})):e.categories}),DC=e=>({...e,subtransactions:e.subtransactions?e.subtransactions.map(t=>({...t})):e.subtransactions});var Ed=class{constructor(t,n){this.ynabAPI=t,this.deltaCache=n}async fetchAccounts(t,n){let a=Te.generateKey("accounts","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.accounts.getAccounts(t,r):await this.ynabAPI.accounts.getAccounts(t);return{data:i.data.accounts,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.ACCOUNTS,n))}async fetchCategories(t,n){let a=Te.generateKey("categories","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.categories.getCategories(t,r):await this.ynabAPI.categories.getCategories(t);return{data:i.data.category_groups,serverKnowledge:i.data.server_knowledge??0}},IC,this.buildDeltaOptions(ot.CATEGORIES,n))}async fetchTransactions(t,n,a,r){let i=n??"all",o=a??"all",s=Te.generateKey("transactions","list",t,i,o);return await this.deltaCache.fetchWithDelta(s,t,async d=>{let u=await this.ynabAPI.transactions.getTransactions(t,n,a,d);return{data:u.data.transactions,serverKnowledge:u.data.server_knowledge??0}},V8,this.buildDeltaOptions(ot.TRANSACTIONS,r))}async fetchTransactionsByAccount(t,n,a,r){let i=a??"all",o=Te.generateKey("transactions","account",t,n,i);return await this.deltaCache.fetchWithDelta(o,t,async s=>{let d=await this.ynabAPI.transactions.getTransactionsByAccount(t,n,a,void 0,s);return{data:d.data.transactions,serverKnowledge:d.data.server_knowledge??0}},V8,this.buildDeltaOptions(ot.TRANSACTIONS,r))}async fetchAccountsFull(t){let n=await this.ynabAPI.accounts.getAccounts(t);return{data:n.data.accounts.filter(r=>!r.deleted),wasCached:!1,usedDelta:!1,serverKnowledge:n.data.server_knowledge??0}}async fetchTransactionsByAccountFull(t,n,a){let r=await this.ynabAPI.transactions.getTransactionsByAccount(t,n,a);return{data:r.data.transactions.filter(o=>!o.deleted),wasCached:!1,usedDelta:!1,serverKnowledge:r.data.server_knowledge??0}}async fetchScheduledTransactions(t,n){let a=Te.generateKey("scheduled_transactions","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.scheduledTransactions.getScheduledTransactions(t,r):await this.ynabAPI.scheduledTransactions.getScheduledTransactions(t);return{data:i.data.scheduled_transactions,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.SCHEDULED_TRANSACTIONS,n))}async fetchPayees(t,n){let a=Te.generateKey("payees","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.payees.getPayees(t,r):await this.ynabAPI.payees.getPayees(t);return{data:i.data.payees,serverKnowledge:i.data.server_knowledge??0}},vm,this.buildDeltaOptions(ot.PAYEES,n))}async fetchMonths(t,n){let a=Te.generateKey("months","list",t);return await this.deltaCache.fetchWithDelta(a,t,async r=>{let i=r!==void 0?await this.ynabAPI.months.getPlanMonths(t,r):await this.ynabAPI.months.getPlanMonths(t);return{data:i.data.months,serverKnowledge:i.data.server_knowledge??0}},kC,this.buildDeltaOptions(ot.MONTHS,n))}async fetchBudgets(t){let n=Te.generateKey("budgets","list"),a=await this.deltaCache.fetchWithDelta(n,"global",async()=>{let r=await this.ynabAPI.plans.getPlans(),i=r.data.server_knowledge??0;return{data:r.data.plans,serverKnowledge:i}},vm,{ttl:t?.ttl??ot.BUDGETS,forceFullRefresh:!0});return{...a,data:a.data}}buildDeltaOptions(t,n){return{ttl:n?.ttl??t,...n?.forceFullRefresh!==void 0&&{forceFullRefresh:n.forceFullRefresh}}}};var Xt;function eae(e){if(Xt&&!Xt.manuallyConfigured&&Xt.ynabAPI&&Xt.ynabAPI!==e&&(Xt=void 0),Xt?.deltaFetcher)return Xt.deltaFetcher;let t=Xt?{...Xt}:{};t.manuallyConfigured===void 0&&(t.manuallyConfigured=!1),t.deltaCache||(t.knowledgeStore||(t.knowledgeStore=new Ka),t.deltaCache=new Ha(Ie,t.knowledgeStore));let n=new Ed(e,t.deltaCache);return t.deltaFetcher=n,t.ynabAPI||(t.ynabAPI=e),Xt=t,n}function RC(e){return e!==null&&typeof e=="object"&&e instanceof Ed&&typeof e.fetchAccounts=="function"&&typeof e.fetchCategories=="function"}function EC(e){return e!==null&&typeof e=="object"&&e instanceof Ha&&typeof e.fetchWithDelta=="function"}function PC(e){return e!==null&&typeof e=="object"&&e instanceof Ka&&typeof e.get=="function"&&typeof e.update=="function"}function bm(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&(e.constructor===Object||e.constructor===void 0)}function Zi(e){if(e===null)return"null";if(e===void 0)return"undefined";let t=typeof e;if(t!=="object")return t;let n=e.constructor?.name;return n?`${t} (${n})`:t}function Vn(e,t,n){if(n!==void 0){if(!RC(t))throw new Error(`resolveDeltaFetcherArgs: When providing 3 arguments, the second argument must be a DeltaFetcher instance. Got: ${Zi(t)}`);if(!bm(n))throw new Error(`resolveDeltaFetcherArgs: When providing 3 arguments, the third argument must be a params object. Got: ${Zi(n)}`);return{deltaFetcher:t,params:n}}if(RC(t))throw new Error("resolveDeltaFetcherArgs: When providing 2 arguments, the second argument must be a params object, not a DeltaFetcher. To use a custom DeltaFetcher, provide all 3 arguments: (ynabAPI, deltaFetcher, params)");if(!bm(t))throw new Error(`resolveDeltaFetcherArgs: When providing 2 arguments, the second argument must be a params object. Got: ${Zi(t)}`);return{deltaFetcher:eae(e),params:t}}function Lr(e,t,n){if(n!==void 0){if(!EC(e))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the first argument must be a DeltaCache instance. Got: ${Zi(e)}`);if(!PC(t))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the second argument must be a ServerKnowledgeStore instance. Got: ${Zi(t)}`);if(!bm(n))throw new Error(`resolveDeltaWriteArgs: When providing 3 arguments, the third argument must be a params object. Got: ${Zi(n)}`);return{deltaCache:e,knowledgeStore:t,params:n}}if(t!==void 0){let i=PC(t),o=bm(t);if(!i&&!o)throw new Error(`resolveDeltaWriteArgs: When providing 2 arguments, the second argument must be either a ServerKnowledgeStore or a params object. Got: ${Zi(t)}`);if(o)throw new Error("resolveDeltaWriteArgs: Invalid argument combination. When providing 2 arguments where the second is a params object, this is ambiguous. Either provide 1 argument (params only) or 3 arguments (deltaCache, knowledgeStore, params).");if(i)throw new Error("resolveDeltaWriteArgs: When providing DeltaCache and ServerKnowledgeStore, you must also provide params as the third argument. Got 2 arguments, expected 3: (deltaCache, knowledgeStore, params)")}if(EC(e))throw new Error("resolveDeltaWriteArgs: When providing only 1 argument, it must be a params object, not a DeltaCache. To use a custom DeltaCache, provide all 3 arguments: (deltaCache, knowledgeStore, params)");if(!bm(e))throw new Error(`resolveDeltaWriteArgs: When providing only 1 argument, it must be a params object. Got: ${Zi(e)}`);if(Xt)return Xt.knowledgeStore||(Xt.knowledgeStore=new Ka),Xt.deltaCache||(Xt.deltaCache=new Ha(Ie,Xt.knowledgeStore)),{deltaCache:Xt.deltaCache,knowledgeStore:Xt.knowledgeStore,params:e};let a=new Ka;return{deltaCache:new Ha(Ie,a),knowledgeStore:a,params:e}}var fn=c.object({cached:c.boolean().optional().describe("Indicates if data was served from cache"),cache_info:c.string().optional().describe('Human-readable cache status message (e.g., "Cache hit", "Cache miss")'),usedDelta:c.boolean().optional().describe("Indicates if delta merge optimization was applied for budgets")}),Xg=c.object({success:c.boolean().describe("Indicates operation success"),message:c.string().describe("Human-readable success message")}),P5e=Xg.extend({details:c.record(c.string(),c.unknown()).optional().describe("Additional confirmation details as key-value pairs")}),ba=c.object({total_count:c.number().int().describe("Total number of items available"),returned_count:c.number().int().describe("Number of items returned"),offset:c.number().int().describe("Offset used for this response"),has_more:c.boolean().describe("Whether more items exist beyond this page"),next_offset:c.number().int().optional().describe("Offset for next page, if has_more is true")}),C5e=c.object({error:c.string().describe("Error message"),code:c.string().optional().describe("Error code for categorization"),details:c.string().optional().describe("Additional error context or details")});var CC=c.object({id:c.string()}),Z8=c.object({user:CC}),W8=c.object({default_budget_id:c.string().nullable(),has_default:c.boolean(),message:c.string()}),Y8=Xg.extend({default_budget_id:c.string(),cache_warm_started:c.boolean()}),G8=Xg.pick({success:!0}),AC=c.object({name:c.string(),version:c.string(),node_version:c.string(),platform:c.string(),arch:c.string(),pid:c.number(),uptime_ms:c.number(),uptime_readable:c.string(),env:c.record(c.string(),c.unknown())}),MC=c.object({rss_mb:c.number(),heap_used_mb:c.number(),heap_total_mb:c.number(),external_mb:c.number(),array_buffers_mb:c.number(),description:c.record(c.string(),c.string())}),zC=c.object({token_present:c.boolean(),token_length:c.number(),token_preview:c.string().nullable(),ynab_env_keys_present:c.array(c.string()),working_directory:c.string()}),FC=c.object({entries:c.number(),estimated_size_kb:c.number(),keys:c.array(c.string()),hits:c.number().optional(),misses:c.number().optional(),evictions:c.number().optional(),lastCleanup:c.string().nullable().optional(),maxEntries:c.number().optional(),hitRate:c.string().optional(),performance_summary:c.string().optional()}),UC=c.object({enabled:c.boolean(),knowledge_entries:c.number(),knowledge_stats:c.record(c.string(),c.unknown()),feature_flag:c.string(),delta_hits:c.number(),delta_misses:c.number(),delta_hit_rate:c.number(),merge_operations:c.number(),knowledge_gap_events:c.number()}),H8=c.object({timestamp:c.string(),server:AC.optional(),memory:MC.optional(),environment:zC.optional(),cache:FC.optional(),delta:UC.optional()}),Qg=c.object({format:c.string()}),e2=c.object({iso_code:c.string(),example_format:c.string(),decimal_digits:c.number(),decimal_separator:c.string().optional(),symbol_first:c.boolean().optional(),group_separator:c.string().optional(),currency_symbol:c.string().optional(),display_symbol:c.boolean().optional()}),JC=c.object({id:c.string(),name:c.string(),last_modified_on:c.string().optional(),first_month:c.string().optional(),last_month:c.string().optional(),date_format:Qg.optional(),currency_format:e2.optional(),accounts_count:c.number(),categories_count:c.number(),payees_count:c.number(),months_count:c.number(),message:c.string()}),K8=c.object({budget:JC});var jC=c.object({id:c.string().describe("Budget ID"),name:c.string().describe("Budget name"),last_modified_on:c.string().optional().describe("Last modification timestamp"),first_month:c.string().optional().describe("First month in budget"),last_month:c.string().optional().describe("Last month in budget"),date_format:Qg.optional().describe("Date format settings"),currency_format:e2.optional().describe("Currency format settings")}),X8=fn.extend({budgets:c.array(jC).describe("List of budgets")});var wm=c.object({id:c.string().describe("Account ID"),name:c.string().describe("Account name"),type:c.string().describe("Account type"),on_budget:c.boolean().describe("On-budget flag"),closed:c.boolean().describe("Closed flag"),note:c.string().optional().describe("Account note"),balance:c.number().describe("Account balance in dollars"),cleared_balance:c.number().describe("Cleared balance in dollars"),uncleared_balance:c.number().describe("Uncleared balance in dollars"),transfer_payee_id:c.string().describe("Transfer payee ID"),direct_import_linked:c.boolean().optional().describe("Direct import linked flag"),direct_import_in_error:c.boolean().optional().describe("Direct import error flag")}),Q8=fn.merge(ba).extend({accounts:c.array(wm).describe("List of accounts")}),ev=fn.extend({account:wm.describe("Account details")});var Pd=c.object({id:c.string().describe("Transaction ID"),date:c.string().describe("Transaction date"),amount:c.number().describe("Transaction amount in dollars"),memo:c.string().optional().describe("Transaction memo"),cleared:c.string().describe("Cleared status"),approved:c.boolean().describe("Approved flag"),flag_color:c.string().optional().describe("Flag color"),account_id:c.string().describe("Account ID"),payee_id:c.string().nullish().describe("Payee ID"),category_id:c.string().nullish().describe("Category ID"),transfer_account_id:c.string().nullish().describe("Transfer account ID"),transfer_transaction_id:c.string().nullish().describe("Transfer transaction ID"),matched_transaction_id:c.string().nullish().describe("Matched transaction ID"),import_id:c.string().optional().describe("Import ID"),deleted:c.boolean().describe("Deleted flag"),account_name:c.string().optional().describe("Account name"),payee_name:c.string().optional().describe("Payee name"),category_name:c.string().optional().describe("Category name")}),qC=c.object({id:c.string().describe("Transaction ID"),date:c.string().describe("Transaction date"),amount:c.number().describe("Transaction amount in dollars"),memo:c.string().optional().describe("Transaction memo"),account_id:c.string().describe("Account ID"),payee_name:c.string().optional().describe("Payee name"),category_name:c.string().optional().describe("Category name")}),tae=fn.merge(ba).extend({transactions:c.array(Pd).describe("List of transactions")}),nae=c.object({message:c.string().describe("Large result set message"),suggestion:c.string().describe("Suggestion to narrow results"),showing:c.string().describe("Human-readable summary of transactions shown"),total_count:c.number().int().describe("Total transaction count"),estimated_size_kb:c.number().describe("Estimated response size in KB"),preview_transactions:c.array(qC).describe("Preview transactions")}),tv=c.union([tae,nae]),nv=fn.extend({transaction:Pd.describe("Transaction details")});var Sm=c.object({id:c.string().describe("Category ID"),category_group_id:c.string().describe("Category group ID"),category_group_name:c.string().optional().describe("Category group name"),name:c.string().describe("Category name"),hidden:c.boolean().describe("Hidden flag"),original_category_group_id:c.string().optional().describe("Original category group ID"),note:c.string().optional().describe("Category note"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),balance:c.number().describe("Balance in dollars"),goal_type:c.string().optional().describe("Goal type"),goal_creation_month:c.string().optional().describe("Goal creation month"),goal_target:c.number().optional().describe("Goal target amount in dollars"),goal_target_month:c.string().optional().describe("Goal target month"),goal_percentage_complete:c.number().optional().describe("Goal percentage complete"),goal_months_to_budget:c.number().optional().describe("Goal months to budget"),goal_under_funded:c.number().optional().describe("Goal underfunded amount in dollars"),goal_overall_funded:c.number().optional().describe("Goal overall funded amount in dollars"),goal_overall_left:c.number().optional().describe("Goal overall left amount in dollars"),deleted:c.boolean().optional().describe("Deleted flag")}),LC=c.object({id:c.string().describe("Category group ID"),name:c.string().describe("Category group name"),hidden:c.boolean().describe("Hidden flag"),deleted:c.boolean().describe("Deleted flag")}),rv=fn.merge(ba).extend({categories:c.array(Sm).describe("List of categories"),category_groups:c.array(LC).describe("List of category groups")}),av=fn.extend({category:Sm.describe("Category details")});var iv=c.object({id:c.string().describe("Payee ID"),name:c.string().describe("Payee name"),transfer_account_id:c.string().optional().describe("Transfer account ID"),deleted:c.boolean().describe("Deleted flag")}),ov=fn.merge(ba).extend({payees:c.array(iv).describe("List of payees")}),sv=fn.extend({payee:iv.describe("Payee details")});var BC=c.object({id:c.string().describe("Category ID"),category_group_id:c.string().describe("Category group ID"),category_group_name:c.string().optional().describe("Category group name"),name:c.string().describe("Category name"),hidden:c.boolean().describe("Hidden flag"),original_category_group_id:c.string().optional().describe("Original category group ID"),note:c.string().optional().describe("Category note"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),balance:c.number().describe("Balance in dollars"),goal_type:c.string().optional().describe("Goal type"),goal_creation_month:c.string().optional().describe("Goal creation month"),goal_target:c.number().optional().describe("Goal target in milliunits"),goal_target_month:c.string().optional().describe("Goal target month"),goal_percentage_complete:c.number().optional().describe("Goal percentage complete"),goal_months_to_budget:c.number().optional().describe("Goal months to budget"),goal_under_funded:c.number().optional().describe("Goal under funded amount"),goal_overall_funded:c.number().optional().describe("Goal overall funded amount"),goal_overall_left:c.number().optional().describe("Goal overall left amount"),deleted:c.boolean().describe("Deleted flag")}),VC=c.object({month:c.string().describe("Month identifier"),note:c.string().optional().describe("Month note"),income:c.number().describe("Income in dollars"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),to_be_budgeted:c.number().describe("To be budgeted in dollars"),age_of_money:c.number().nullish().describe("Age of money in days"),deleted:c.boolean().describe("Deleted flag"),categories:c.array(BC).optional().describe("Categories for this month")}),ZC=c.object({month:c.string().describe("Month identifier"),note:c.string().optional().describe("Month note"),income:c.number().describe("Income in dollars"),budgeted:c.number().describe("Budgeted amount in dollars"),activity:c.number().describe("Activity in dollars"),to_be_budgeted:c.number().describe("To be budgeted in dollars"),age_of_money:c.number().nullish().describe("Age of money in days"),deleted:c.boolean().describe("Deleted flag")}),dv=fn.extend({month:VC.describe("Month details")}),cv=fn.merge(ba).extend({months:c.array(ZC).describe("List of months")});var lv=c.object({id:c.string(),transaction_id:c.string(),amount:c.number(),memo:c.string().optional(),payee_id:c.string().optional(),payee_name:c.string().optional(),category_id:c.string().optional(),category_name:c.string().optional(),transfer_account_id:c.string().optional(),transfer_transaction_id:c.string().optional(),deleted:c.boolean()}),t2=Pd.extend({account_balance:c.number().optional(),account_cleared_balance:c.number().optional(),subtransactions:c.array(lv).optional()}),YC=c.object({name:c.string(),quantity:c.number().optional(),amount:c.number(),memo:c.string().optional()}),GC=c.object({category_id:c.string(),category_name:c.string().optional(),items:c.array(YC),subtotal:c.number(),tax:c.number(),total:c.number()}),uv=c.object({subtotal:c.number(),tax:c.number(),total:c.number(),categories:c.array(GC)}),pv=c.object({total_requested:c.number(),created:c.number().optional(),updated:c.number().optional(),duplicates:c.number().optional(),failed:c.number()}),mv=c.object({request_index:c.number(),status:c.enum(["created","duplicate","updated","failed"]),transaction_id:c.string().optional(),correlation_key:c.string(),error_code:c.string().optional(),error:c.string().optional()}).passthrough(),WC=c.object({amount:c.number().optional(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),memo:c.string().optional(),payee_id:c.string().nullable().optional(),payee_name:c.string().nullable().optional(),category_id:c.string().nullable().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),flag_color:c.enum(["red","orange","yellow","green","blue","purple"]).nullable().optional()}),HC=c.object({transaction_id:c.string(),before:c.union([c.literal("unavailable"),WC]),after:WC}),KC=c.object({code:c.string(),count:c.number(),message:c.string(),sample_ids:c.array(c.string()).optional()}),fv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_transaction"),request:c.record(c.string(),c.unknown())}),c.object({transaction:t2})]),rae=c.object({request_index:c.number(),account_id:c.string(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),amount:c.number(),memo:c.string().optional(),payee_id:c.string().optional(),payee_name:c.string().optional(),category_id:c.string().optional(),import_id:c.string().optional()}),hv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_transactions"),validation:c.literal("passed"),summary:c.object({total_transactions:c.number(),total_amount:c.number(),accounts_affected:c.array(c.string()),date_range:c.object({earliest:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),latest:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)}).optional(),categories_affected:c.array(c.string())}),transactions_preview:c.array(rae),note:c.string()}).strict(),c.object({success:c.boolean(),server_knowledge:c.number().optional(),summary:pv,results:c.array(mv),transactions:c.array(Pd).optional(),duplicate_import_ids:c.array(c.string()).optional(),message:c.string().optional(),mode:c.enum(["full","summary","ids_only"]).optional()}).passthrough()]),gv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_transaction"),request:c.record(c.string(),c.unknown())}),c.object({transaction:t2,updated_balance:c.number(),updated_cleared_balance:c.number()})]),_v=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_transactions"),validation:c.literal("passed"),summary:c.object({total_transactions:c.number(),accounts_affected:c.number(),fields_to_update:c.array(c.string())}),transactions_preview:c.array(HC),warnings:c.array(KC).optional(),note:c.string()}).strict(),c.object({success:c.boolean(),server_knowledge:c.number().optional(),summary:pv,results:c.array(mv),transactions:c.array(Pd).optional(),message:c.string().optional(),mode:c.enum(["full","summary","ids_only"]).optional()}).passthrough()]),yv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_delete_transaction"),request:c.record(c.string(),c.unknown())}),c.object({message:c.string(),transaction:c.object({id:c.string(),deleted:c.boolean()}),updated_balance:c.number(),updated_cleared_balance:c.number()})]),XC=c.object({account_id:c.string(),date:c.string().regex(/^\d{4}-\d{2}-\d{2}$/),amount:c.number(),memo:c.string().optional().nullable(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),flag_color:c.enum(["red","orange","yellow","green","blue","purple"]).optional().nullable(),payee_id:c.string().optional().nullable(),payee_name:c.string().optional().nullable(),category_id:c.string().optional().nullable(),import_id:c.string().optional().nullable()}),QC=lv.omit({id:!0,transaction_id:!0,deleted:!0}),vv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_receipt_split_transaction"),transaction_preview:XC,receipt_summary:uv,subtransactions:c.array(QC)}),c.object({transaction:t2,receipt_summary:uv})]),aae=c.object({budget_id:c.string(),name:c.string(),type:c.string(),balance:c.number()}),bv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_create_account"),request:aae}),c.object({account:wm})]),iae=c.object({budget_id:c.string(),category_id:c.string(),budgeted:c.number(),month:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)}),wv=c.union([c.object({dry_run:c.literal(!0),action:c.literal("ynab_update_category"),request:iae}),c.object({category:Sm,updated_month:c.string().regex(/^\d{4}-\d{2}-\d{2}$/)})]);var Qt=c.object({value_milliunits:c.number().int(),value:c.number().finite(),value_display:c.string(),currency:c.string(),direction:c.enum(["credit","debit","balanced"])}),Sv=c.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Date must be in ISO format (YYYY-MM-DD)").refine(e=>{let t=Date.parse(e);if(Number.isNaN(t))return!1;let n=new Date(t),a=n.getUTCFullYear(),r=String(n.getUTCMonth()+1).padStart(2,"0"),i=String(n.getUTCDate()).padStart(2,"0");return`${a}-${r}-${i}`===e},{message:"Invalid calendar date (e.g., month must be 01-12, day must be valid for the month)"}),Tm=c.object({id:c.string().uuid(),date:Sv,amount:c.number(),payee:c.string(),memo:c.string().optional(),sourceRow:c.number().int(),raw:c.object({date:c.string(),amount:c.string(),description:c.string()}).strict(),warnings:c.array(c.string()).optional(),amount_money:Qt}),Ou=c.object({id:c.string(),date:Sv,amount:c.number(),payee:c.string().nullable(),categoryName:c.string().nullable(),cleared:c.enum(["cleared","uncleared","reconciled"]),approved:c.boolean(),memo:c.string().nullable().optional(),amount_money:Qt}),nA=c.object({ynab_transaction:Ou,confidence:c.number().min(0).max(100),match_reason:c.string(),explanation:c.string()}),n2=c.object({bank_transaction:Tm,ynab_transaction:Ou.optional(),candidates:c.array(nA).optional(),confidence:c.enum(["high","medium","low","none"]),confidence_score:c.number().min(0).max(100),match_reason:c.string(),top_confidence:c.number().optional(),action_hint:c.string().optional(),recommendation:c.string().optional()}),rA=c.object({current_cleared:Qt,current_uncleared:Qt,current_total:Qt,target_statement:Qt,discrepancy:Qt,on_track:c.boolean()}),aA=c.object({statement_date_range:c.string(),bank_transactions_count:c.number(),ynab_transactions_count:c.number(),ynab_in_range_count:c.number().optional(),ynab_outside_range_count:c.number().optional(),auto_matched:c.number(),suggested_matches:c.number(),unmatched_bank:c.number(),unmatched_ynab:c.number(),current_cleared_balance:Qt,target_statement_balance:Qt,discrepancy:Qt,discrepancy_explanation:c.string()}),iA=c.object({id:c.string(),type:c.enum(["repeat_amount","near_match","anomaly"]),severity:c.enum(["info","warning","critical"]),title:c.string(),description:c.string(),evidence:c.record(c.string(),c.unknown()).optional()}),oA=c.discriminatedUnion("action_type",[c.object({id:c.string(),action_type:c.literal("create_transaction"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({account_id:c.string(),date:Sv,amount:c.number(),payee_name:c.string(),memo:c.string().optional(),cleared:c.enum(["cleared","uncleared"]),approved:c.boolean(),category_id:c.string().optional()})}),c.object({id:c.string(),action_type:c.literal("update_cleared"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({transaction_id:c.string(),cleared:c.enum(["cleared","uncleared","reconciled"])})}),c.object({id:c.string(),action_type:c.literal("review_duplicate"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({candidate_ids:c.array(c.string()),bank_transaction:Tm,suggested_match_id:c.string().optional()})}),c.object({id:c.string(),action_type:c.literal("manual_review"),priority:c.enum(["high","medium","low"]),confidence:c.number().min(0).max(1),message:c.string(),reason:c.string(),estimated_impact:Qt,account_id:c.string(),source_insight_id:c.string().optional(),metadata:c.record(c.string(),c.unknown()).optional(),parameters:c.object({issue_type:c.string(),related_transactions:c.array(c.object({source:c.enum(["bank","ynab"]),id:c.string(),description:c.string()})).optional()})})]),eA=c.object({balance:Qt,cleared_balance:Qt,uncleared_balance:Qt}),tA=c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullable().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional(),approved:c.boolean().optional(),payee_name:c.string().nullable().optional(),category_name:c.string().nullable().optional(),import_id:c.string().nullable().optional()}).passthrough(),oae=c.object({account_id:c.string(),date:c.string(),amount:c.number(),payee_name:c.string().optional(),memo:c.string().optional(),cleared:c.enum(["cleared","uncleared"]).optional(),approved:c.boolean().optional(),import_id:c.string().optional()}),sae=c.object({transaction_id:c.string(),new_date:c.string().optional(),cleared:c.enum(["cleared","uncleared","reconciled"]).optional()}),dae=c.object({transaction_id:c.string().nullable(),import_id:c.string().optional()}),cae=c.discriminatedUnion("type",[c.object({type:c.literal("create_transaction"),transaction:tA.nullable(),reason:c.string(),bulk_chunk_index:c.number().optional(),correlation_key:c.string().optional()}),c.object({type:c.literal("create_transaction_failed"),transaction:oae,reason:c.string(),bulk_chunk_index:c.number().optional(),correlation_key:c.string().optional()}),c.object({type:c.literal("create_transaction_duplicate"),transaction:dae,reason:c.string(),bulk_chunk_index:c.number(),correlation_key:c.string().optional(),duplicate:c.literal(!0)}),c.object({type:c.literal("update_transaction"),transaction:c.union([tA.nullable(),sae]),reason:c.string()}),c.object({type:c.literal("balance_checkpoint"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("bulk_create_fallback"),transaction:c.null(),reason:c.string(),bulk_chunk_index:c.number()}),c.object({type:c.literal("batch_update_failed"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("batch_reconcile_failed"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("reconciliation_complete"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("diagnostic_step3_entry"),transaction:c.null(),reason:c.string()}),c.object({type:c.literal("diagnostic_unmatched_ynab"),transaction:c.record(c.string(),c.unknown()),reason:c.string()})]),uae=c.object({bank_transactions_count:c.number(),ynab_transactions_count:c.number(),matches_found:c.number(),missing_in_ynab:c.number(),missing_in_bank:c.number(),transactions_created:c.number(),transactions_updated:c.number(),dates_adjusted:c.number(),dry_run:c.boolean()}),lae=c.object({chunks_processed:c.number(),bulk_successes:c.number(),sequential_fallbacks:c.number(),duplicates_detected:c.number(),failed_transactions:c.number(),bulk_chunk_failures:c.number(),transaction_failures:c.number(),sequential_attempts:c.number().optional()}).refine(e=>e.failed_transactions===e.transaction_failures,{message:"failed_transactions must equal transaction_failures"}),sA=c.object({summary:uae,account_balance:c.object({before:eA,after:eA}),actions_taken:c.array(cae),recommendations:c.array(c.string()),balance_reconciliation:c.unknown().optional(),bulk_operation_details:lae.optional()}),dA=c.object({data_freshness:c.string(),data_source:c.string(),server_knowledge:c.number().optional(),fetched_at:c.string(),accounts_count:c.number().optional(),transactions_count:c.number().optional(),cache_status:c.object({accounts_cached:c.boolean(),transactions_cached:c.boolean(),delta_merge_applied:c.boolean()})}).catchall(c.unknown()),pae=c.object({delimiter:c.string(),decimal_separator:c.string(),thousands_separator:c.string().nullable(),date_format:c.string(),header_row:c.boolean(),date_column:c.string().nullable(),amount_column:c.string().nullable(),payee_column:c.string().nullable()}),mae=c.object({version:c.string(),schema_url:c.string(),generated_at:c.string(),account:c.object({id:c.string().optional(),name:c.string().optional()}),summary:aA,balance:rA.extend({discrepancy_direction:c.enum(["balanced","ynab_higher","bank_higher"])}),insights:c.array(iA),next_steps:c.array(c.string()),matches:c.object({auto:c.array(n2),suggested:c.array(n2)}),unmatched:c.object({bank:c.array(Tm),ynab:c.array(Ou),ynab_outside_date_range:c.array(Ou).optional()}),recommendations:c.array(oA).optional(),csv_format:pae.optional(),execution:sA.optional(),audit:dA.optional()}),fae=c.object({unmatched_bank:c.array(Tm),unmatched_ynab:c.array(Ou),suggestions:c.array(n2)}).strict(),Tv=c.union([c.object({human:c.string(),structured:c.union([mae,fae])}).strict(),c.object({human:c.string()}).strict()]).refine(e=>{if("structured"in e&&e.structured&&"balance"in e.structured&&typeof e.structured.balance=="object"&&e.structured.balance!==null){let t=e.structured.balance.discrepancy.value,n=e.structured.balance.discrepancy_direction;if(Math.abs(t)<.01)return n==="balanced";if(t>0)return n==="ynab_higher";if(t<0)return n==="bank_higher"}return!0},{message:"Discrepancy direction mismatch: direction must match the numeric discrepancy amount",path:["balance","discrepancy_direction"]});function hae(e){if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let t=Date.parse(e);if(Number.isNaN(t))return!1;let n=new Date(t),a=n.getUTCFullYear(),r=String(n.getUTCMonth()+1).padStart(2,"0"),i=String(n.getUTCDate()).padStart(2,"0");return`${a}-${r}-${i}`===e}var Wi=c.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Date must be in YYYY-MM-DD format").refine(hae,{message:"Invalid calendar date (e.g., month must be 01-12, day must be valid for the month)"}),gae=c.object({date:Wi,amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),description:c.string(),row_number:c.number(),suggested_payee_id:c.string().optional(),suggested_payee_name:c.string().optional(),suggestion_reason:c.string().optional()}),_ae=c.object({id:c.string(),date:Wi,amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),payee_name:c.string().nullable(),memo:c.string().nullish(),cleared:c.string()}),yae=c.object({bank_date:Wi,bank_amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),bank_description:c.string(),ynab_date:Wi,ynab_amount:c.string().regex(/^-?\d+\.\d{2}$/,"Amount must be a decimal string with exactly 2 decimal places"),ynab_payee:c.string().nullable(),ynab_transaction:c.object({id:c.string(),cleared:c.string()}),match_score:c.number(),match_reasons:c.array(c.string())}),cA=c.object({date:Wi,amount:c.number(),description:c.string(),raw_amount:c.string(),raw_date:c.string(),row_number:c.number()}),uA=c.object({id:c.string(),date:Wi,amount:c.number(),payee_name:c.string().nullable(),memo:c.string().nullish(),cleared:c.string(),account_name:c.string().optional(),category_name:c.string().optional()}),vae=c.object({bank_transaction:cA,ynab_transaction:uA,match_score:c.number().min(0).max(100),match_reasons:c.array(c.string())}),lA=c.object({amount_tolerance:c.number().optional(),date_tolerance_days:c.number().optional()}),pA=c.object({start:Wi,end:Wi}).refine(e=>{let t=Date.parse(e.start),n=Date.parse(e.end);return t<=n},{message:"Start date must be before or equal to end date"}),mA=c.object({exported_at:c.string(),total_transactions:c.number(),minimal:c.boolean(),filters:c.object({budget_id:c.string().optional(),account_id:c.string().nullable(),category_id:c.string().nullable(),since_date:c.string().nullable(),type:c.string().nullable()})}),bae=c.object({id:c.string(),date:c.string(),amount:c.number(),payee_name:c.string().nullable(),cleared:c.string()}),wae=c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullish(),cleared:c.string(),approved:c.boolean(),flag_color:c.string().nullable(),account_id:c.string(),payee_id:c.string().nullable(),category_id:c.string().nullable(),transfer_account_id:c.string().nullable(),transfer_transaction_id:c.string().nullable(),matched_transaction_id:c.string().nullable(),import_id:c.string().nullable(),deleted:c.boolean(),account_name:c.string().optional(),payee_name:c.string().nullable(),category_name:c.string().nullable()}),fA=c.union([bae,wae]),p8e=c.object({export_info:mA,transactions:c.array(fA)}),xv=c.object({summary:c.object({bank_transactions_count:c.number(),ynab_transactions_count:c.number(),matches_found:c.number(),missing_in_ynab:c.number(),missing_in_bank:c.number(),date_range:pA,parameters:lA}),matches:c.array(yae),missing_in_ynab:c.array(gae),missing_in_bank:c.array(_ae)}),$v=c.object({message:c.string(),filename:c.string(),full_path:c.string(),export_directory:c.string(),export_mode:c.enum(["minimal","full"]),minimal_fields:c.string().nullable(),filename_explanation:c.string(),preview_count:c.number(),total_count:c.number(),preview_transactions:c.array(c.object({id:c.string(),date:c.string(),amount:c.number(),memo:c.string().nullable().optional(),payee_name:c.string().nullable().optional(),category_name:c.string().nullable().optional()}))});var Ze={READ_ONLY_EXTERNAL:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0},WRITE_EXTERNAL_CREATE:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!0},WRITE_EXTERNAL_UPDATE:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0},WRITE_EXTERNAL_DELETE:{readOnlyHint:!1,destructiveHint:!0,idempotentHint:!0,openWorldHint:!0},UTILITY_LOCAL_READ_ONLY:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},UTILITY_LOCAL_MUTATION:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},UTILITY_LOCAL:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}};var Sae=c.object({budget_id:c.string().min(1,"Budget ID is required"),limit:c.number().int().positive().optional(),offset:c.number().int().min(0).optional(),response_format:c.enum(["json","markdown"]).default("markdown").optional()}).strict(),Tae=c.object({budget_id:c.string().min(1,"Budget ID is required"),account_id:c.string().min(1,"Account ID is required"),response_format:c.enum(["json","markdown"]).default("markdown").optional()}).strict(),xae=c.object({budget_id:c.string().min(1,"Budget ID is required"),name:c.string().min(1,"Account name is required"),type:c.enum(["checking","savings","creditCard","cash","lineOfCredit","otherAsset","otherLiability"]),balance:c.number().optional(),dry_run:c.boolean().optional()}).strict();async function $ae(e,t,n,a){let{deltaFetcher:r,params:i}=Vn(e,t,n);return await pt(async()=>{let o=await r.fetchAccounts(i.budget_id),s=o.data,d=o.wasCached,u=i.limit??50,l=i.offset??0,p=s.slice(l,l+u),m=l+u<s.length,h=i.response_format??"markdown",_={accounts:p.map(f=>({id:f.id,name:f.name,type:f.type,on_budget:f.on_budget,closed:f.closed,note:f.note,balance:he(f.balance),cleared_balance:he(f.cleared_balance),uncleared_balance:he(f.uncleared_balance),transfer_payee_id:f.transfer_payee_id,direct_import_linked:f.direct_import_linked,direct_import_in_error:f.direct_import_in_error})),total_count:s.length,returned_count:p.length,offset:l,has_more:m,next_offset:m?l+u:void 0,cached:d,cache_info:d?`Data retrieved from cache for improved performance${o.usedDelta?" (delta merge applied)":""}`:"Fresh data retrieved from YNAB API"};return{content:[{type:"text",text:h==="markdown"?uC(_):we.format(_)}],structuredContent:_}},"ynab:list_accounts","listing accounts",a)}async function Oae(e,t,n){return await pt(async()=>{let a=Te.generateKey($n.ACCOUNTS,"get",t.budget_id,t.account_id),r=Ie.has(a),i=await Ie.wrap(a,{ttl:ot.ACCOUNTS,loader:async()=>(await e.accounts.getAccountById(t.budget_id,t.account_id)).data.account}),o=t.response_format??"markdown",s={account:{id:i.id,name:i.name,type:i.type,on_budget:i.on_budget,closed:i.closed,note:i.note,balance:he(i.balance),cleared_balance:he(i.cleared_balance),uncleared_balance:he(i.uncleared_balance),transfer_payee_id:i.transfer_payee_id,direct_import_linked:i.direct_import_linked,direct_import_in_error:i.direct_import_in_error},cached:r,cache_info:r?"Data retrieved from cache for improved performance":"Fresh data retrieved from YNAB API"};return{content:[{type:"text",text:o==="markdown"?lC(s):we.format(s)}],structuredContent:s}},"ynab:get_account","getting account details",n)}async function Nae(e,t,n,a,r){let{deltaCache:i,params:o}=Lr(t,n,a);return await pt(async()=>{if(o.dry_run){let m={dry_run:!0,action:"ynab_create_account",request:{budget_id:o.budget_id,name:o.name,type:o.type,balance:o.balance??0}};return{content:[{type:"text",text:we.format(m)}],structuredContent:m}}let s={name:o.name,type:o.type,balance:o.balance?o.balance*1e3:0},u=(await e.accounts.createAccount(o.budget_id,{account:s})).data.account,l=Te.generateKey($n.ACCOUNTS,"list",o.budget_id);Ie.delete(l),i.invalidate(o.budget_id,$n.ACCOUNTS);let p={account:{id:u.id,name:u.name,type:u.type,on_budget:u.on_budget,closed:u.closed,note:u.note,balance:he(u.balance),cleared_balance:he(u.cleared_balance),uncleared_balance:he(u.uncleared_balance),transfer_payee_id:u.transfer_payee_id,direct_import_linked:u.direct_import_linked,direct_import_in_error:u.direct_import_in_error}};return{content:[{type:"text",text:we.format(p)}],structuredContent:p}},"ynab:create_account","creating account",r)}var hA=(e,t)=>{let{adapt:n,adaptWithDelta:a,adaptWrite:r}=Kt(t),i=Bn(t);e.register({name:"ynab_list_accounts",description:`List all accounts for a budget.
|
|
93
93
|
|
|
94
94
|
Args:
|
|
95
95
|
- budget_id (string, optional): Budget UUID. Omit to use the default budget.
|
|
@@ -634,6 +634,26 @@ export declare const ExecutionActionRecordSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
634
634
|
transaction: z.ZodNull;
|
|
635
635
|
reason: z.ZodString;
|
|
636
636
|
bulk_chunk_index: z.ZodNumber;
|
|
637
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
638
|
+
type: z.ZodLiteral<"batch_update_failed">;
|
|
639
|
+
transaction: z.ZodNull;
|
|
640
|
+
reason: z.ZodString;
|
|
641
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
642
|
+
type: z.ZodLiteral<"batch_reconcile_failed">;
|
|
643
|
+
transaction: z.ZodNull;
|
|
644
|
+
reason: z.ZodString;
|
|
645
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
646
|
+
type: z.ZodLiteral<"reconciliation_complete">;
|
|
647
|
+
transaction: z.ZodNull;
|
|
648
|
+
reason: z.ZodString;
|
|
649
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
650
|
+
type: z.ZodLiteral<"diagnostic_step3_entry">;
|
|
651
|
+
transaction: z.ZodNull;
|
|
652
|
+
reason: z.ZodString;
|
|
653
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
654
|
+
type: z.ZodLiteral<"diagnostic_unmatched_ynab">;
|
|
655
|
+
transaction: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
656
|
+
reason: z.ZodString;
|
|
637
657
|
}, z.core.$strip>], "type">;
|
|
638
658
|
export type ExecutionActionRecord = z.infer<typeof ExecutionActionRecordSchema>;
|
|
639
659
|
export declare const ExecutionSummarySchema: z.ZodObject<{
|
|
@@ -826,6 +846,26 @@ export declare const ExecutionResultSchema: z.ZodObject<{
|
|
|
826
846
|
transaction: z.ZodNull;
|
|
827
847
|
reason: z.ZodString;
|
|
828
848
|
bulk_chunk_index: z.ZodNumber;
|
|
849
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
850
|
+
type: z.ZodLiteral<"batch_update_failed">;
|
|
851
|
+
transaction: z.ZodNull;
|
|
852
|
+
reason: z.ZodString;
|
|
853
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
854
|
+
type: z.ZodLiteral<"batch_reconcile_failed">;
|
|
855
|
+
transaction: z.ZodNull;
|
|
856
|
+
reason: z.ZodString;
|
|
857
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
858
|
+
type: z.ZodLiteral<"reconciliation_complete">;
|
|
859
|
+
transaction: z.ZodNull;
|
|
860
|
+
reason: z.ZodString;
|
|
861
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
862
|
+
type: z.ZodLiteral<"diagnostic_step3_entry">;
|
|
863
|
+
transaction: z.ZodNull;
|
|
864
|
+
reason: z.ZodString;
|
|
865
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
866
|
+
type: z.ZodLiteral<"diagnostic_unmatched_ynab">;
|
|
867
|
+
transaction: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
868
|
+
reason: z.ZodString;
|
|
829
869
|
}, z.core.$strip>], "type">>;
|
|
830
870
|
recommendations: z.ZodArray<z.ZodString>;
|
|
831
871
|
balance_reconciliation: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -1751,6 +1791,26 @@ export declare const ReconcileAccountOutputSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
1751
1791
|
transaction: z.ZodNull;
|
|
1752
1792
|
reason: z.ZodString;
|
|
1753
1793
|
bulk_chunk_index: z.ZodNumber;
|
|
1794
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1795
|
+
type: z.ZodLiteral<"batch_update_failed">;
|
|
1796
|
+
transaction: z.ZodNull;
|
|
1797
|
+
reason: z.ZodString;
|
|
1798
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1799
|
+
type: z.ZodLiteral<"batch_reconcile_failed">;
|
|
1800
|
+
transaction: z.ZodNull;
|
|
1801
|
+
reason: z.ZodString;
|
|
1802
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1803
|
+
type: z.ZodLiteral<"reconciliation_complete">;
|
|
1804
|
+
transaction: z.ZodNull;
|
|
1805
|
+
reason: z.ZodString;
|
|
1806
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1807
|
+
type: z.ZodLiteral<"diagnostic_step3_entry">;
|
|
1808
|
+
transaction: z.ZodNull;
|
|
1809
|
+
reason: z.ZodString;
|
|
1810
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1811
|
+
type: z.ZodLiteral<"diagnostic_unmatched_ynab">;
|
|
1812
|
+
transaction: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
1813
|
+
reason: z.ZodString;
|
|
1754
1814
|
}, z.core.$strip>], "type">>;
|
|
1755
1815
|
recommendations: z.ZodArray<z.ZodString>;
|
|
1756
1816
|
balance_reconciliation: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -257,6 +257,31 @@ export const ExecutionActionRecordSchema = z.discriminatedUnion("type", [
|
|
|
257
257
|
reason: z.string(),
|
|
258
258
|
bulk_chunk_index: z.number(),
|
|
259
259
|
}),
|
|
260
|
+
z.object({
|
|
261
|
+
type: z.literal("batch_update_failed"),
|
|
262
|
+
transaction: z.null(),
|
|
263
|
+
reason: z.string(),
|
|
264
|
+
}),
|
|
265
|
+
z.object({
|
|
266
|
+
type: z.literal("batch_reconcile_failed"),
|
|
267
|
+
transaction: z.null(),
|
|
268
|
+
reason: z.string(),
|
|
269
|
+
}),
|
|
270
|
+
z.object({
|
|
271
|
+
type: z.literal("reconciliation_complete"),
|
|
272
|
+
transaction: z.null(),
|
|
273
|
+
reason: z.string(),
|
|
274
|
+
}),
|
|
275
|
+
z.object({
|
|
276
|
+
type: z.literal("diagnostic_step3_entry"),
|
|
277
|
+
transaction: z.null(),
|
|
278
|
+
reason: z.string(),
|
|
279
|
+
}),
|
|
280
|
+
z.object({
|
|
281
|
+
type: z.literal("diagnostic_unmatched_ynab"),
|
|
282
|
+
transaction: z.record(z.string(), z.unknown()),
|
|
283
|
+
reason: z.string(),
|
|
284
|
+
}),
|
|
260
285
|
]);
|
|
261
286
|
export const ExecutionSummarySchema = z.object({
|
|
262
287
|
bank_transactions_count: z.number(),
|
package/package.json
CHANGED
|
@@ -495,6 +495,36 @@ export const ExecutionActionRecordSchema = z.discriminatedUnion("type", [
|
|
|
495
495
|
reason: z.string(),
|
|
496
496
|
bulk_chunk_index: z.number(),
|
|
497
497
|
}),
|
|
498
|
+
// Bulk update chunk failure
|
|
499
|
+
z.object({
|
|
500
|
+
type: z.literal("batch_update_failed"),
|
|
501
|
+
transaction: z.null(),
|
|
502
|
+
reason: z.string(),
|
|
503
|
+
}),
|
|
504
|
+
// Bulk reconcile chunk failure
|
|
505
|
+
z.object({
|
|
506
|
+
type: z.literal("batch_reconcile_failed"),
|
|
507
|
+
transaction: z.null(),
|
|
508
|
+
reason: z.string(),
|
|
509
|
+
}),
|
|
510
|
+
// All matched transactions marked reconciled
|
|
511
|
+
z.object({
|
|
512
|
+
type: z.literal("reconciliation_complete"),
|
|
513
|
+
transaction: z.null(),
|
|
514
|
+
reason: z.string(),
|
|
515
|
+
}),
|
|
516
|
+
// Diagnostic: STEP 3 entry metadata
|
|
517
|
+
z.object({
|
|
518
|
+
type: z.literal("diagnostic_step3_entry"),
|
|
519
|
+
transaction: z.null(),
|
|
520
|
+
reason: z.string(),
|
|
521
|
+
}),
|
|
522
|
+
// Diagnostic: unmatched YNAB transaction details
|
|
523
|
+
z.object({
|
|
524
|
+
type: z.literal("diagnostic_unmatched_ynab"),
|
|
525
|
+
transaction: z.record(z.string(), z.unknown()),
|
|
526
|
+
reason: z.string(),
|
|
527
|
+
}),
|
|
498
528
|
]);
|
|
499
529
|
|
|
500
530
|
export type ExecutionActionRecord = z.infer<typeof ExecutionActionRecordSchema>;
|