@swifty.js/swifty 0.0.21 → 0.0.22

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.
Files changed (34) hide show
  1. package/dist/{agent-ZCMBUWLZ.js → agent-5T7KNC7V.js} +1 -1
  2. package/dist/{anthropic-4ZVG7AMA.js → anthropic-P2R4GW6F.js} +1 -1
  3. package/dist/{chunk-Y5WGBAGP.js → chunk-HJIGA37J.js} +1 -1
  4. package/dist/{chunk-DDBH5AEN.js → chunk-L73IHJF4.js} +53 -53
  5. package/dist/{chunk-S6ZADC7C.js → chunk-NEAR6YPZ.js} +1 -1
  6. package/dist/{chunk-MUPVOATV.js → chunk-NLNH3IRT.js} +1 -1
  7. package/dist/{chunk-6E6UA7MT.js → chunk-YQQVB6VB.js} +9 -8
  8. package/dist/lib/agent-2AGRYN3R.js +9 -0
  9. package/dist/lib/anthropic-GFWP3ORB.js +22 -0
  10. package/dist/lib/bwrap-QRGPUP4J.js +6 -0
  11. package/dist/lib/checker-IIXJXQCB.js +19 -0
  12. package/dist/lib/chunk-6GOWRPYS.js +339 -0
  13. package/dist/lib/chunk-7URDLWQN.js +426 -0
  14. package/dist/lib/chunk-C7IHCJZ3.js +849 -0
  15. package/dist/lib/chunk-EJLGB2EJ.js +377 -0
  16. package/dist/lib/chunk-GHF2PSEW.js +8 -0
  17. package/dist/lib/chunk-GNBXECZN.js +243 -0
  18. package/dist/lib/chunk-HK2Z6WP4.js +223 -0
  19. package/dist/lib/chunk-LUEP4JMF.js +549 -0
  20. package/dist/lib/chunk-ORSYNBMM.js +38 -0
  21. package/dist/lib/chunk-RR2CZ6CY.js +598 -0
  22. package/dist/lib/chunk-UHVO63Y7.js +1246 -0
  23. package/dist/lib/chunk-UMFNTXKA.js +88 -0
  24. package/dist/lib/chunk-VUD72RTY.js +39 -0
  25. package/dist/lib/glob.wasm +0 -0
  26. package/dist/lib/index.d.ts +5350 -0
  27. package/dist/lib/index.js +12002 -0
  28. package/dist/lib/openai-HXRMPNB7.js +15 -0
  29. package/dist/lib/seatbelt-FT5IY73W.js +6 -0
  30. package/dist/lib/tool-filter-VF7TZRE5.js +19 -0
  31. package/dist/main.js +225 -225
  32. package/dist/{openai-HXD52MZB.js → openai-TVUUHRG7.js} +1 -1
  33. package/dist/{server-VMHWEO2Y.js → server-ZTLHJWEQ.js} +14 -14
  34. package/package.json +14 -2
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __swiftyCreateRequire } from "node:module";
3
3
  const require = __swiftyCreateRequire(import.meta.url);
4
- import{b as L,c as D,d as O,f as U,l as W,m as j,n as Y}from"./chunk-6E6UA7MT.js";import{a as P,e as N,g as M}from"./chunk-FZPTNGTU.js";import{I as f,K as _,M as C,N as R,O as A,P as F,S as E}from"./chunk-LX2LK3TF.js";import{readFile as xe}from"fs/promises";function T(r){return r?Math.floor(r.length/3.5):0}function B(r,e){if(e<=0||!r||T(r)<=e)return r;let t=Math.floor(e*3.5);return t<=0||t>=r.length?r:r.slice(0,t)+`
4
+ import{b as L,c as D,d as O,f as U,l as W,m as j,n as Y}from"./chunk-YQQVB6VB.js";import{a as P,e as N,g as M}from"./chunk-FZPTNGTU.js";import{I as f,K as _,M as C,N as R,O as A,P as F,S as E}from"./chunk-LX2LK3TF.js";import{readFile as xe}from"fs/promises";function T(r){return r?Math.floor(r.length/3.5):0}function B(r,e){if(e<=0||!r||T(r)<=e)return r;let t=Math.floor(e*3.5);return t<=0||t>=r.length?r:r.slice(0,t)+`
5
5
  \u2026 (content truncated)`}var b=class{files=new Map;skills=new Map;recordFileRead(e,t){this.files.set(e,{path:e,content:t,timestamp:Date.now()})}recordSkillInvocation(e,t){this.skills.set(e,{name:e,body:t,timestamp:Date.now()})}snapshotFiles(e=5){return[...this.files.values()].sort((n,s)=>s.timestamp-n.timestamp).slice(0,e)}snapshotSkills(){return[...this.skills.values()].sort((e,t)=>t.timestamp-e.timestamp)}buildRecoveryAttachment(e){let t=[],n=this.snapshotFiles();if(n.length>0){t.push(`## Recently read files
6
6
  `),t.push(`These snapshots are what the file-reading tool last returned. Re-open with the tool if you need the current bytes.
7
7
  `);for(let o of n){let i=B(o.content,5e3),l=new Date(o.timestamp).toISOString().replace(/\.\d{3}Z$/,"Z");t.push(`### ${o.path} (read ${l})
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __swiftyCreateRequire } from "node:module";
3
3
  const require = __swiftyCreateRequire(import.meta.url);
4
- import{a as x}from"./chunk-7MHXMDYC.js";import{C as o,I as S,b as p,c as u}from"./chunk-LX2LK3TF.js";import{existsSync as E,readFileSync as $}from"fs";import{homedir as I}from"os";import{join as m}from"path";function l(e){return!!e._zod}function f(e,t){return l(e)?p(e,t):e.safeParse(t)}async function ee(e,t){return l(e)?await u(e,t):await e.safeParseAsync(t)}function oe(e){if(!e)return;let t;if(l(e)?t=e._zod?.def?.shape:t=e.shape,!!t){if(typeof t=="function")try{return t()}catch{return}return t}}function ne(e){if(l(e)){let s=e._zod?.def;if(s){if(s.value!==void 0)return s.value;if(Array.isArray(s.values)&&s.values.length>0)return s.values[0]}}let n=e._def;if(n){if(n.value!==void 0)return n.value;if(Array.isArray(n.values)&&n.values.length>0)return n.values[0]}let r=e.value;if(r!==void 0)return r}var g=S({module:"config"}),A={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY","openai-compat":"OPENAI_API_KEY"};function N(e){return _.has(e)}var _=new Set(Object.keys(A)),d=class extends Error{constructor(t){super(t),this.name="ConfigError"}},P=o.object({name:o.string(),protocol:o.enum(["anthropic","openai","openai-compat"]),base_url:o.string(),model:o.string(),api_key:o.string().optional(),thinking:o.boolean().optional(),context_window:o.coerce.number().optional(),max_output_tokens:o.coerce.number().optional()}),V=[["1m",1e6],["gpt-4.1",1e6],["gpt-4o",128e3],["gpt-4-turbo",128e3],["o1",2e5],["o3",2e5],["o4",2e5],["gpt-3.5",16385],["claude",2e5]];function j(e){let t=e.toLowerCase();for(let[n,r]of V)if(t.includes(n))return r;return t.includes("claude")?2e5:128e3}function le(e){return e.context_window&&e.context_window>0?e.context_window:j(e.model)}var w=new Map;async function pe(e,t){if(e.context_window&&e.context_window>0)return e.context_window;if(e.protocol==="anthropic"){let n=`${e.name}-${e.model}`,r=w.get(n);if(r===void 0){try{r=await(t??(await import("./anthropic-4ZVG7AMA.js")).fetchModelContextWindow)(e)}catch(i){g.error({err:i},"config operation failed"),r=0}w.set(n,r)}if(r&&r>0)return r}return j(e.model)}function ue(e){return e.max_output_tokens&&e.max_output_tokens>0?e.max_output_tokens:e.thinking?64e3:8192}function me(e){if(e.api_key)return e.api_key;let t=N(e.protocol)?A[e.protocol]:"";return t?process.env[t]??"":""}var O=o.object({name:o.string(),command:o.string().optional(),args:o.array(o.string()).optional(),url:o.string().optional(),transport:o.string().optional(),headers:o.record(o.string(),o.string()).optional(),env:o.record(o.string(),o.string()).optional()}),z=o.object({id:o.string().optional(),event:o.string(),condition:o.string().optional(),action:o.object({type:o.string(),command:o.string().optional(),url:o.string().optional(),method:o.string().optional(),prompt:o.string().optional()}),reject:o.boolean().optional(),once:o.boolean().optional(),async:o.boolean().optional(),on_error:o.string().optional()}),M=o.object({enabled:o.boolean().optional(),auto_allow:o.boolean().optional(),network_enabled:o.boolean().optional()}),T=o.looseObject({providers:o.array(P),permission_mode:o.string().optional(),mcp_servers:o.array(O).default([]),hooks:o.array(z).default([]),sandbox:M.optional(),enable_coordinator_mode:o.boolean().optional(),enable_fork:o.boolean().optional()});function ge(e){return e.enable_fork!==!1}function Y(e){return typeof e=="object"&&e!==null}function C(e){let t=$(e,"utf-8"),n=x.load(t);if(!Y(n))return g.error({path:e},"invalid yaml"),{providers:[],mcp_servers:[],hooks:[]};let r=f(T,n);if(r.success){let a=r.data;return{providers:a.providers,permission_mode:a.permission_mode,mcp_servers:a.mcp_servers,hooks:a.hooks}}g.error({error:r.error},"config error");let i=[],s,c=[],y=[],v,b=!1,h=!0;if("providers"in n){let a=f(o.array(P),n.providers);a.success&&(i=a.data)}if("permission_mode"in n&&typeof n.permission_mode=="string"&&(s=n.permission_mode),"mcp_servers"in n){let a=f(o.array(O),n.mcp_servers);a.success&&(c=a.data)}if("hooks"in n){let a=f(o.array(z),n.hooks);a.success&&(y=a.data)}if("sandbox"in n){let a=f(M,n.sandbox);a.success&&(v=a.data)}return"enable_coordinator_mode"in n&&(b=!!n.enable_coordinator_mode),"enable_fork"in n&&(h=!!n.enable_fork),{providers:i,permission_mode:s,mcp_servers:c,hooks:y,sandbox:v,enable_coordinator_mode:b,enable_fork:h}}function K(e,t){if(t.providers.length>0&&(e.providers=t.providers),t.permission_mode&&(e.permission_mode=t.permission_mode),t.mcp_servers.length>0){let n=new Map;for(let r=0;r<e.mcp_servers.length;r++){let i=e.mcp_servers[r];n.set(i.name,r)}for(let r of t.mcp_servers){let i=n.get(r.name);i!==void 0?e.mcp_servers[i]=r:(e.mcp_servers.push(r),n.set(r.name,e.mcp_servers.length-1))}}return e.hooks=[...e.hooks,...t.hooks],t.sandbox&&(e.sandbox={...e.sandbox,...t.sandbox}),t.enable_coordinator_mode&&(e.enable_coordinator_mode=!0),t.enable_fork!==void 0&&(e.enable_fork=t.enable_fork),e}function k(e){if(e.providers.length===0)throw new d("At least one provider MUST be configured.");let t=["name","protocol","base_url","model"];for(let n=0;n<e.providers.length;n++){let r=e.providers[n],i={name:r.name,protocol:r.protocol,base_url:r.base_url,model:r.model},s=t.filter(c=>!(c in i));if(s.length>0)throw new d(`Provider #${String(n+1)}: missing fields: ${s.join(", ")}`);if(!_.has(r.protocol))throw new d(`Provider #${String(n+1)}: invalid protocol '${r.protocol}', MUST be one of: ${Array.from(_).join(", ")}`)}}function _e(e){if(e){let s=C(e);return k(s),s}let t=process.cwd(),n=I(),r=[m(n,".swifty","config.yaml"),m(t,".swifty","config.yaml"),m(t,".swifty","config.local.yaml")],i=null;for(let s of r){if(!E(s))continue;let c=C(s);i?i=K(i,c):i=c}if(!i)throw new d("No config file found, expected .swifty/config.y(a)ml under project or $HOME/.swifty/config.y(a)ml.");return k(i),i}export{f as a,ee as b,oe as c,ne as d,le as e,pe as f,ue as g,me as h,ge as i,_e as j};
4
+ import{a as x}from"./chunk-7MHXMDYC.js";import{C as o,I as S,b as p,c as u}from"./chunk-LX2LK3TF.js";import{existsSync as E,readFileSync as $}from"fs";import{homedir as I}from"os";import{join as m}from"path";function l(e){return!!e._zod}function f(e,t){return l(e)?p(e,t):e.safeParse(t)}async function ee(e,t){return l(e)?await u(e,t):await e.safeParseAsync(t)}function oe(e){if(!e)return;let t;if(l(e)?t=e._zod?.def?.shape:t=e.shape,!!t){if(typeof t=="function")try{return t()}catch{return}return t}}function ne(e){if(l(e)){let s=e._zod?.def;if(s){if(s.value!==void 0)return s.value;if(Array.isArray(s.values)&&s.values.length>0)return s.values[0]}}let n=e._def;if(n){if(n.value!==void 0)return n.value;if(Array.isArray(n.values)&&n.values.length>0)return n.values[0]}let r=e.value;if(r!==void 0)return r}var g=S({module:"config"}),A={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY","openai-compat":"OPENAI_API_KEY"};function N(e){return _.has(e)}var _=new Set(Object.keys(A)),d=class extends Error{constructor(t){super(t),this.name="ConfigError"}},P=o.object({name:o.string(),protocol:o.enum(["anthropic","openai","openai-compat"]),base_url:o.string(),model:o.string(),api_key:o.string().optional(),thinking:o.boolean().optional(),context_window:o.coerce.number().optional(),max_output_tokens:o.coerce.number().optional()}),V=[["1m",1e6],["gpt-4.1",1e6],["gpt-4o",128e3],["gpt-4-turbo",128e3],["o1",2e5],["o3",2e5],["o4",2e5],["gpt-3.5",16385],["claude",2e5]];function j(e){let t=e.toLowerCase();for(let[n,r]of V)if(t.includes(n))return r;return t.includes("claude")?2e5:128e3}function le(e){return e.context_window&&e.context_window>0?e.context_window:j(e.model)}var w=new Map;async function pe(e,t){if(e.context_window&&e.context_window>0)return e.context_window;if(e.protocol==="anthropic"){let n=`${e.name}-${e.model}`,r=w.get(n);if(r===void 0){try{r=await(t??(await import("./anthropic-P2R4GW6F.js")).fetchModelContextWindow)(e)}catch(i){g.error({err:i},"config operation failed"),r=0}w.set(n,r)}if(r&&r>0)return r}return j(e.model)}function ue(e){return e.max_output_tokens&&e.max_output_tokens>0?e.max_output_tokens:e.thinking?64e3:8192}function me(e){if(e.api_key)return e.api_key;let t=N(e.protocol)?A[e.protocol]:"";return t?process.env[t]??"":""}var O=o.object({name:o.string(),command:o.string().optional(),args:o.array(o.string()).optional(),url:o.string().optional(),transport:o.string().optional(),headers:o.record(o.string(),o.string()).optional(),env:o.record(o.string(),o.string()).optional()}),z=o.object({id:o.string().optional(),event:o.string(),condition:o.string().optional(),action:o.object({type:o.string(),command:o.string().optional(),url:o.string().optional(),method:o.string().optional(),prompt:o.string().optional()}),reject:o.boolean().optional(),once:o.boolean().optional(),async:o.boolean().optional(),on_error:o.string().optional()}),M=o.object({enabled:o.boolean().optional(),auto_allow:o.boolean().optional(),network_enabled:o.boolean().optional()}),T=o.looseObject({providers:o.array(P),permission_mode:o.string().optional(),mcp_servers:o.array(O).default([]),hooks:o.array(z).default([]),sandbox:M.optional(),enable_coordinator_mode:o.boolean().optional(),enable_fork:o.boolean().optional()});function ge(e){return e.enable_fork!==!1}function Y(e){return typeof e=="object"&&e!==null}function C(e){let t=$(e,"utf-8"),n=x.load(t);if(!Y(n))return g.error({path:e},"invalid yaml"),{providers:[],mcp_servers:[],hooks:[]};let r=f(T,n);if(r.success){let a=r.data;return{providers:a.providers,permission_mode:a.permission_mode,mcp_servers:a.mcp_servers,hooks:a.hooks}}g.error({error:r.error},"config error");let i=[],s,c=[],y=[],v,b=!1,h=!0;if("providers"in n){let a=f(o.array(P),n.providers);a.success&&(i=a.data)}if("permission_mode"in n&&typeof n.permission_mode=="string"&&(s=n.permission_mode),"mcp_servers"in n){let a=f(o.array(O),n.mcp_servers);a.success&&(c=a.data)}if("hooks"in n){let a=f(o.array(z),n.hooks);a.success&&(y=a.data)}if("sandbox"in n){let a=f(M,n.sandbox);a.success&&(v=a.data)}return"enable_coordinator_mode"in n&&(b=!!n.enable_coordinator_mode),"enable_fork"in n&&(h=!!n.enable_fork),{providers:i,permission_mode:s,mcp_servers:c,hooks:y,sandbox:v,enable_coordinator_mode:b,enable_fork:h}}function K(e,t){if(t.providers.length>0&&(e.providers=t.providers),t.permission_mode&&(e.permission_mode=t.permission_mode),t.mcp_servers.length>0){let n=new Map;for(let r=0;r<e.mcp_servers.length;r++){let i=e.mcp_servers[r];n.set(i.name,r)}for(let r of t.mcp_servers){let i=n.get(r.name);i!==void 0?e.mcp_servers[i]=r:(e.mcp_servers.push(r),n.set(r.name,e.mcp_servers.length-1))}}return e.hooks=[...e.hooks,...t.hooks],t.sandbox&&(e.sandbox={...e.sandbox,...t.sandbox}),t.enable_coordinator_mode&&(e.enable_coordinator_mode=!0),t.enable_fork!==void 0&&(e.enable_fork=t.enable_fork),e}function k(e){if(e.providers.length===0)throw new d("At least one provider MUST be configured.");let t=["name","protocol","base_url","model"];for(let n=0;n<e.providers.length;n++){let r=e.providers[n],i={name:r.name,protocol:r.protocol,base_url:r.base_url,model:r.model},s=t.filter(c=>!(c in i));if(s.length>0)throw new d(`Provider #${String(n+1)}: missing fields: ${s.join(", ")}`);if(!_.has(r.protocol))throw new d(`Provider #${String(n+1)}: invalid protocol '${r.protocol}', MUST be one of: ${Array.from(_).join(", ")}`)}}function _e(e){if(e){let s=C(e);return k(s),s}let t=process.cwd(),n=I(),r=[m(n,".swifty","config.yaml"),m(t,".swifty","config.yaml"),m(t,".swifty","config.local.yaml")],i=null;for(let s of r){if(!E(s))continue;let c=C(s);i?i=K(i,c):i=c}if(!i)throw new d("No config file found, expected .swifty/config.y(a)ml under project or $HOME/.swifty/config.y(a)ml.");return k(i),i}export{f as a,ee as b,oe as c,ne as d,le as e,pe as f,ue as g,me as h,ge as i,_e as j};
@@ -6,10 +6,11 @@ ${e}
6
6
  </system-reminder>`})}hasReminderContaining(e){return this.history.some(o=>o.role==="user"&&p(o.content).includes(e))}injectLongTermMemory(e,o,s=""){if(this.longTermMemoryInjected)return;let n=[];if(e&&n.push(`# SWIFTY.md
7
7
  Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.
8
8
 
9
- `+e),o&&n.push(`# Auto Memory
10
- `+o),s&&n.push(`# availableSkills
9
+ ${e}}`),o&&n.push(`# Auto Memory
10
+ `+o),s&&n.push(`# Available Skills
11
11
  `+s),n.length===0)return;let r=new Date().toISOString().split("T")[0];n.push(`# Current Date
12
- Today's date is `+r+".");let a=`
12
+
13
+ Today's date is ${r}.`);let a=`
13
14
  <system-reminder>
14
15
  As you answer the user's questions, you can use the following context:
15
16
 
@@ -18,14 +19,14 @@ ${n.join(`
18
19
  `)}
19
20
 
20
21
  IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant to your task.
21
- </system-reminder>`;this.history.unshift({role:"user",content:a}),this.longTermMemoryInjected=!0}len(){return this.history.length}truncateTo(e){e<0&&(e=0),!(e>this.history.length)&&(this.history=this.history.slice(0,e))}getMessages(){return[...this.history]}replaceWithCompacted(e,o){this.history=[{role:"user",content:e},...o],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}recordUsageAnchor(e,o,s,n){let r=e+s+n+o;r<=0||(this.baselineTokens=r,this._anchorCount=this.history.length)}clearUsageAnchor(){this.baselineTokens=0,this._anchorCount=0}usageAnchorState(){return this.baselineTokens<=0?null:{baselineTokens:this.baselineTokens,anchorCount:this._anchorCount}}};import{randomBytes as z}from"crypto";import{readFileSync as I,writeFileSync as H,readdirSync as W,mkdirSync as J,statSync as X,existsSync as A,unlinkSync as Ce,rmSync as xe}from"fs";import{join as y}from"path";var S="compact_boundary";var E=i.object({tool_use_id:i.string(),tool_name:i.string(),arguments:i.record(i.string(),i.unknown()).optional()}),k=i.union([i.string(),i.array(i.record(i.string(),i.unknown()))]),N=i.object({tool_use_id:i.string(),content:k,is_error:i.boolean().optional()}),B=i.object({role:i.string(),content:k.default(""),timestamp:i.number(),type:i.string().optional(),tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()}),G=i.object({role:i.string(),content:k,tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()});function O(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,tool_name:e.toolName,...e.arguments&&Object.keys(e.arguments).length?{arguments:e.arguments}:{}}))}function L(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,content:e.content,...e.isError?{is_error:!0}:{}}))}var V=i.object({summary:i.string(),keep:i.array(G)}),b=v({module:"session"});function R(t){return y(t,".swifty","sessions")}function Ie(t,e){return y(R(t),e+".jsonl")}function Ae(){let t=Date.now().toString(36),e=z(4).toString("hex");return`${t}-${e}`}function Q(t,e,o){let s=R(t);J(s,{recursive:!0});let n=y(s,`${e}.jsonl`),r=JSON.stringify(o)+`
22
- `;H(n,r,{flag:"a",encoding:"utf-8"})}function Ee(t,e,o){Q(t,e,{role:"system",content:JSON.stringify(o),timestamp:Math.floor(Date.now()/1e3),type:S})}function Ne(t,e){let o=y(R(t),`${e}.jsonl`);if(!A(o))return[];let s=[];for(let n of I(o,"utf-8").split(`
22
+ </system-reminder>`;this.history.unshift({role:"user",content:a}),this.longTermMemoryInjected=!0}len(){return this.history.length}truncateTo(e){e<0&&(e=0),!(e>this.history.length)&&(this.history=this.history.slice(0,e))}reset(){this.history=[],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}getMessages(){return[...this.history]}replaceWithCompacted(e,o){this.history=[{role:"user",content:e},...o],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}recordUsageAnchor(e,o,s,n){let r=e+s+n+o;r<=0||(this.baselineTokens=r,this._anchorCount=this.history.length)}clearUsageAnchor(){this.baselineTokens=0,this._anchorCount=0}usageAnchorState(){return this.baselineTokens<=0?null:{baselineTokens:this.baselineTokens,anchorCount:this._anchorCount}}};import{randomBytes as z}from"crypto";import{readFileSync as A,writeFileSync as H,readdirSync as W,mkdirSync as J,statSync as X,existsSync as I,unlinkSync as Ce,rmSync as xe}from"fs";import{join as y}from"path";var S="compact_boundary";var E=i.object({tool_use_id:i.string(),tool_name:i.string(),arguments:i.record(i.string(),i.unknown()).optional()}),k=i.union([i.string(),i.array(i.record(i.string(),i.unknown()))]),N=i.object({tool_use_id:i.string(),content:k,is_error:i.boolean().optional()}),B=i.object({role:i.string(),content:k.default(""),timestamp:i.number(),type:i.string().optional(),tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()}),G=i.object({role:i.string(),content:k,tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()});function O(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,tool_name:e.toolName,...e.arguments&&Object.keys(e.arguments).length?{arguments:e.arguments}:{}}))}function L(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,content:e.content,...e.isError?{is_error:!0}:{}}))}var V=i.object({summary:i.string(),keep:i.array(G)}),b=v({module:"session"});function R(t){return y(t,".swifty","sessions")}function Ae(t,e){return y(R(t),e+".jsonl")}function Ie(){let t=Date.now().toString(36),e=z(4).toString("hex");return`${t}-${e}`}function Q(t,e,o){let s=R(t);J(s,{recursive:!0});let n=y(s,`${e}.jsonl`),r=JSON.stringify(o)+`
23
+ `;H(n,r,{flag:"a",encoding:"utf-8"})}function Ee(t,e,o){Q(t,e,{role:"system",content:JSON.stringify(o),timestamp:Math.floor(Date.now()/1e3),type:S})}function Ne(t,e){let o=y(R(t),`${e}.jsonl`);if(!I(o))return[];let s=[];for(let n of A(o,"utf-8").split(`
23
24
  `))if(n.trim())try{let r=JSON.parse(n),{success:l,data:a,error:c}=x(B,r);l?!a.content&&!(a.tool_uses?.length??0)&&!(a.tool_results?.length??0)||s.push(a):b.error({err:c},"session operation failed")}catch(r){b.error({err:r},"session operation failed")}return s}function j(t){return t?.map(e=>({toolUseId:e.tool_use_id,toolName:e.tool_name,arguments:e.arguments}))}function F(t){return t?.map(e=>({toolUseId:e.tool_use_id,content:e.content,isError:e.is_error}))}function Be(t){let e=-1;for(let s=t.length-1;s>=0;s--)if(t[s].type===S){e=s;break}let o=[];if(e>=0){let s=null;try{let n=t[e].content,r=typeof n=="string"?JSON.parse(n):null;s=M(V,r)}catch{s=null}if(s){let n=`This session continues from a previous conversation, which has been compressed due to context limitations. Here is a summary of the earlier messages:
24
25
 
25
26
  `+s.summary;s.keep.length>0&&(n+=`
26
27
 
27
- Recent messages have been preserved verbatim.`),o.push({role:"user",content:n});for(let r of s.keep)r.role!=="user"&&r.role!=="assistant"||!r.content&&!(r.tool_uses?.length??0)&&!(r.tool_results?.length??0)||o.push({role:r.role,content:r.content,toolUses:j(r.tool_uses),toolResults:F(r.tool_results)})}for(let n=e+1;n<t.length;n++){let r=t[n];if(r.type===S)continue;let l=P(r);l&&o.push(l)}return o}for(let s of t){let n=P(s);n&&o.push(n)}return o}function P(t){return t.role!=="user"&&t.role!=="assistant"||!t.content&&!(t.tool_uses?.length??0)&&!(t.tool_results?.length??0)?null:{role:t.role,content:t.content,toolUses:j(t.tool_uses),toolResults:F(t.tool_results)}}function Oe(t){let e=R(t);if(!A(e))return[];let o=W(e).filter(n=>n.endsWith(".jsonl")),s=[];for(let n of o){let r=y(e,n),l=X(r),a=n.replace(".jsonl",""),c="",u=0;try{for(let d of I(r,"utf-8").split(`
28
- `)){if(!d.trim())continue;let m;try{let g=JSON.parse(d);m=M(B,g)}catch(g){b.error({err:g},"session operation failed");continue}u++,!c&&m.role==="user"&&m.content&&(c=p(m.content).slice(0,100))}}catch(d){b.error({err:d},"session operation failed");continue}s.push({id:a,firstMessage:c,messageCount:u,size:l.size,modTime:l.mtime})}return s.sort((n,r)=>r.modTime.getTime()-n.modTime.getTime()),s}var D=3,Z=3,ee="[earlier conversation truncated for compaction retry]",te=3.5,oe=1e4,se=5,ne=4e4,re=2,ie=2e4,ae=13e3,le=3e3;function $(t,e,o=!1){return t-Math.min(e,ie)-(o?le:ae)}var q=class{consecutiveFailures=0},ce=7e3;function Y(t){if(typeof t=="string")return t.length;let e=0;for(let o of t)o.type==="text"?e+=U(o,"text").length:o.type==="image"&&(e+=ce);return e}function w(t){let e=0;for(let o of t){if(e+=Y(o.content),o.toolUses&&(e+=JSON.stringify(o.toolUses).length),o.toolResults)for(let s of o.toolResults)e+=Y(s.content);if(o.thinkingBlocks)for(let s of o.thinkingBlocks)e+=s.thinking.length}return Math.ceil(e/te)}function ue(t){return w(t.getMessages())}function C(t){return w([t])}function de(t){return t.role==="user"&&!!t.toolResults&&t.toolResults.length>0}function me(t){let e=0,o=0,s=t.length;for(let n=t.length-1;n>=0;n--){let r=C(t[n]);if(o>0&&e+r>ne||(s=n,e+=r,o++,e>=oe||o>=se))break}return s=he(t,s),s}function he(t,e){if(e<=0||e>=t.length||!de(t[e]))return e;let o=new Set((t[e].toolResults??[]).map(s=>s.toolUseId));for(let s=e-1;s>=0;s--){let n=t[s];if(n.role==="assistant"&&n.toolUses?.some(r=>o.has(r.toolUseId)))return s}return e}function ge(t,e){let o=e??t.usageAnchorState();if(!o)return ue(t);let s=t.getMessages(),n=Math.min(o.anchorCount,s.length);return o.baselineTokens+w(s.slice(n))}async function $e(t,e,o,s,n,r,l,a,c=""){let u=ge(t),d=$(o,s),m=$(o,s,!0);if(u<d)return{compacted:!1,message:""};if(!(u>=m)&&n.consecutiveFailures>=D)return{compacted:!1,message:`Auto-compact circuit breaker: ${String(D)} consecutive failures`};try{let f=await K(t,e,r,l,a,c);return n.consecutiveFailures=0,f}catch(f){return n.consecutiveFailures++,{compacted:!1,message:`Auto-compact failed: ${_(f)}`}}}async function qe(t,e,o,s,n,r=""){return K(t,e,o,s,n,r)}var fe=`Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
28
+ Recent messages have been preserved verbatim.`),o.push({role:"user",content:n});for(let r of s.keep)r.role!=="user"&&r.role!=="assistant"||!r.content&&!(r.tool_uses?.length??0)&&!(r.tool_results?.length??0)||o.push({role:r.role,content:r.content,toolUses:j(r.tool_uses),toolResults:F(r.tool_results)})}for(let n=e+1;n<t.length;n++){let r=t[n];if(r.type===S)continue;let l=P(r);l&&o.push(l)}return o}for(let s of t){let n=P(s);n&&o.push(n)}return o}function P(t){return t.role!=="user"&&t.role!=="assistant"||!t.content&&!(t.tool_uses?.length??0)&&!(t.tool_results?.length??0)?null:{role:t.role,content:t.content,toolUses:j(t.tool_uses),toolResults:F(t.tool_results)}}function Oe(t){let e=R(t);if(!I(e))return[];let o=W(e).filter(n=>n.endsWith(".jsonl")),s=[];for(let n of o){let r=y(e,n),l=X(r),a=n.replace(".jsonl",""),c="",u=0;try{for(let d of A(r,"utf-8").split(`
29
+ `)){if(!d.trim())continue;let m;try{let g=JSON.parse(d);m=M(B,g)}catch(g){b.error({err:g},"session operation failed");continue}u++,!c&&m.role==="user"&&m.content&&(c=p(m.content).slice(0,100))}}catch(d){b.error({err:d},"session operation failed");continue}s.push({id:a,firstMessage:c,messageCount:u,size:l.size,modTime:l.mtime})}return s.sort((n,r)=>r.modTime.getTime()-n.modTime.getTime()),s}var $=3,Z=3,ee="[earlier conversation truncated for compaction retry]",te=3.5,oe=1e4,se=5,ne=4e4,re=2,ie=2e4,ae=13e3,le=3e3;function D(t,e,o=!1){return t-Math.min(e,ie)-(o?le:ae)}var q=class{consecutiveFailures=0},ce=7e3;function Y(t){if(typeof t=="string")return t.length;let e=0;for(let o of t)o.type==="text"?e+=U(o,"text").length:o.type==="image"&&(e+=ce);return e}function w(t){let e=0;for(let o of t){if(e+=Y(o.content),o.toolUses&&(e+=JSON.stringify(o.toolUses).length),o.toolResults)for(let s of o.toolResults)e+=Y(s.content);if(o.thinkingBlocks)for(let s of o.thinkingBlocks)e+=s.thinking.length}return Math.ceil(e/te)}function ue(t){return w(t.getMessages())}function C(t){return w([t])}function de(t){return t.role==="user"&&!!t.toolResults&&t.toolResults.length>0}function me(t){let e=0,o=0,s=t.length;for(let n=t.length-1;n>=0;n--){let r=C(t[n]);if(o>0&&e+r>ne||(s=n,e+=r,o++,e>=oe||o>=se))break}return s=he(t,s),s}function he(t,e){if(e<=0||e>=t.length||!de(t[e]))return e;let o=new Set((t[e].toolResults??[]).map(s=>s.toolUseId));for(let s=e-1;s>=0;s--){let n=t[s];if(n.role==="assistant"&&n.toolUses?.some(r=>o.has(r.toolUseId)))return s}return e}function ge(t,e){let o=e??t.usageAnchorState();if(!o)return ue(t);let s=t.getMessages(),n=Math.min(o.anchorCount,s.length);return o.baselineTokens+w(s.slice(n))}async function De(t,e,o,s,n,r,l,a,c=""){let u=ge(t),d=D(o,s),m=D(o,s,!0);if(u<d)return{compacted:!1,message:""};if(!(u>=m)&&n.consecutiveFailures>=$)return{compacted:!1,message:`Auto-compact circuit breaker: ${String($)} consecutive failures`};try{let f=await K(t,e,r,l,a,c);return n.consecutiveFailures=0,f}catch(f){return n.consecutiveFailures++,{compacted:!1,message:`Auto-compact failed: ${_(f)}`}}}async function qe(t,e,o,s,n,r=""){return K(t,e,o,s,n,r)}var fe=`Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
29
30
  This summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing development work without losing context.
30
31
 
31
32
  Before providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points. In your analysis process:
@@ -123,4 +124,4 @@ If you need specific details from before compaction (code snippets, error messag
123
124
 
124
125
  ---
125
126
 
126
- ${m}`),t.replaceWithCompacted(g,u);let f=u.filter(h=>(h.role==="user"||h.role==="assistant")&&(h.content||(h.toolUses?.length??0)||(h.toolResults?.length??0))).map(h=>({role:h.role,content:h.content,...h.toolUses?.length?{tool_uses:O(h.toolUses)}:{},...h.toolResults?.length?{tool_results:L(h.toolResults)}:{}}));return{compacted:!0,message:`Compacted ${String(c.length)} messages into summary (${String(d.length)} chars), kept ${String(u.length)} recent messages verbatim`,boundary:{summary:d,keep:f}}}export{T as a,O as b,L as c,Ie as d,Ae as e,Q as f,Ee as g,Ne as h,Be as i,Oe as j,$ as k,q as l,$e as m,qe as n};
127
+ ${m}`),t.replaceWithCompacted(g,u);let f=u.filter(h=>(h.role==="user"||h.role==="assistant")&&(h.content||(h.toolUses?.length??0)||(h.toolResults?.length??0))).map(h=>({role:h.role,content:h.content,...h.toolUses?.length?{tool_uses:O(h.toolUses)}:{},...h.toolResults?.length?{tool_results:L(h.toolResults)}:{}}));return{compacted:!0,message:`Compacted ${String(c.length)} messages into summary (${String(d.length)} chars), kept ${String(u.length)} recent messages verbatim`,boundary:{summary:d,keep:f}}}export{T as a,O as b,L as c,Ae as d,Ie as e,Q as f,Ee as g,Ne as h,Be as i,Oe as j,D as k,q as l,De as m,qe as n};
@@ -0,0 +1,9 @@
1
+ import {
2
+ Agent
3
+ } from "./chunk-UHVO63Y7.js";
4
+ import "./chunk-C7IHCJZ3.js";
5
+ import "./chunk-UMFNTXKA.js";
6
+ import "./chunk-EJLGB2EJ.js";
7
+ export {
8
+ Agent
9
+ };
@@ -0,0 +1,22 @@
1
+ import {
2
+ AnthropicClient,
3
+ buildAnthropicMessages,
4
+ fetchModelContextWindow,
5
+ markLastUserTailForCache,
6
+ markToolsForCache,
7
+ needsToolSearchBeta
8
+ } from "./chunk-LUEP4JMF.js";
9
+ import "./chunk-C7IHCJZ3.js";
10
+ import "./chunk-6GOWRPYS.js";
11
+ import "./chunk-UMFNTXKA.js";
12
+ import "./chunk-GNBXECZN.js";
13
+ import "./chunk-EJLGB2EJ.js";
14
+ import "./chunk-GHF2PSEW.js";
15
+ export {
16
+ AnthropicClient,
17
+ buildAnthropicMessages,
18
+ fetchModelContextWindow,
19
+ markLastUserTailForCache,
20
+ markToolsForCache,
21
+ needsToolSearchBeta
22
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ BwrapSandbox
3
+ } from "./chunk-ORSYNBMM.js";
4
+ export {
5
+ BwrapSandbox
6
+ };
@@ -0,0 +1,19 @@
1
+ import {
2
+ PathSandbox,
3
+ PermissionChecker,
4
+ RuleEngine,
5
+ evaluateRules,
6
+ extractContent,
7
+ isSafeCommand
8
+ } from "./chunk-7URDLWQN.js";
9
+ import "./chunk-GNBXECZN.js";
10
+ import "./chunk-EJLGB2EJ.js";
11
+ import "./chunk-GHF2PSEW.js";
12
+ export {
13
+ PathSandbox,
14
+ PermissionChecker,
15
+ RuleEngine,
16
+ evaluateRules,
17
+ extractContent,
18
+ isSafeCommand
19
+ };
@@ -0,0 +1,339 @@
1
+ import {
2
+ createChildLogger
3
+ } from "./chunk-EJLGB2EJ.js";
4
+
5
+ // src/config/config.ts
6
+ import { existsSync, readFileSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ import { safeParse } from "@modelcontextprotocol/sdk/server/zod-compat.js";
10
+ import yaml from "js-yaml";
11
+ import { z } from "zod";
12
+ var log = createChildLogger({ module: "config" });
13
+ var ENV_KEY_MAP = {
14
+ anthropic: "ANTHROPIC_API_KEY",
15
+ openai: "OPENAI_API_KEY",
16
+ "openai-compat": "OPENAI_API_KEY"
17
+ };
18
+ function isKeyofTypeofEnvKeyMap(k) {
19
+ return VALID_PROTOCOLS.has(k);
20
+ }
21
+ var VALID_PROTOCOLS = new Set(Object.keys(ENV_KEY_MAP));
22
+ var ConfigError = class extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "ConfigError";
26
+ }
27
+ };
28
+ var ProviderConfigSchema = z.object({
29
+ name: z.string(),
30
+ /**
31
+ * enum: ["anthropic", "openai", "openai-compat"]
32
+ */
33
+ protocol: z.enum(["anthropic", "openai", "openai-compat"]),
34
+ base_url: z.string(),
35
+ model: z.string(),
36
+ api_key: z.string().optional(),
37
+ thinking: z.boolean().optional(),
38
+ context_window: z.coerce.number().optional(),
39
+ max_output_tokens: z.coerce.number().optional()
40
+ });
41
+ var MODEL_CONTEXT_WINDOWS = [
42
+ // 1M-token variants (e.g. "...-1m") come first so they win over the base family.
43
+ ["1m", 1e6],
44
+ ["gpt-4.1", 1e6],
45
+ ["gpt-4o", 128e3],
46
+ ["gpt-4-turbo", 128e3],
47
+ ["o1", 2e5],
48
+ ["o3", 2e5],
49
+ ["o4", 2e5],
50
+ ["gpt-3.5", 16385],
51
+ ["claude", 2e5]
52
+ ];
53
+ function lookupModelContextWindow(model) {
54
+ const model_ = model.toLowerCase();
55
+ for (const [m, window] of MODEL_CONTEXT_WINDOWS) {
56
+ if (model_.includes(m)) {
57
+ return window;
58
+ }
59
+ }
60
+ return model_.includes("claude") ? 2e5 : 128e3;
61
+ }
62
+ function getContextWindow(p) {
63
+ if (p.context_window && p.context_window > 0) {
64
+ return p.context_window;
65
+ }
66
+ return lookupModelContextWindow(p.model);
67
+ }
68
+ var fetchedWindowCache = /* @__PURE__ */ new Map();
69
+ async function getContextWindowAsync(p, fetcher) {
70
+ if (p.context_window && p.context_window > 0) {
71
+ return p.context_window;
72
+ }
73
+ if (p.protocol === "anthropic") {
74
+ const key = `${p.name}-${p.model}`;
75
+ let fetched = fetchedWindowCache.get(key);
76
+ if (fetched === void 0) {
77
+ try {
78
+ const fn = fetcher ?? (await import("./anthropic-GFWP3ORB.js")).fetchModelContextWindow;
79
+ fetched = await fn(p);
80
+ } catch (err) {
81
+ log.error({ err }, "config operation failed");
82
+ fetched = 0;
83
+ }
84
+ fetchedWindowCache.set(key, fetched);
85
+ }
86
+ if (fetched && fetched > 0) {
87
+ return fetched;
88
+ }
89
+ }
90
+ return lookupModelContextWindow(p.model);
91
+ }
92
+ function _resetContextWindowCache() {
93
+ fetchedWindowCache.clear();
94
+ }
95
+ function getMaxOutputTokens(p) {
96
+ if (p.max_output_tokens && p.max_output_tokens > 0) {
97
+ return p.max_output_tokens;
98
+ }
99
+ if (p.thinking) {
100
+ return 64e3;
101
+ }
102
+ return 8192;
103
+ }
104
+ function resolveAPIKey(p) {
105
+ if (p.api_key) {
106
+ return p.api_key;
107
+ }
108
+ const envVar = isKeyofTypeofEnvKeyMap(p.protocol) ? ENV_KEY_MAP[p.protocol] : "";
109
+ if (!envVar) {
110
+ return "";
111
+ }
112
+ return process.env[envVar] ?? "";
113
+ }
114
+ var MCPServerConfigSchema = z.object({
115
+ name: z.string(),
116
+ command: z.string().optional(),
117
+ args: z.array(z.string()).optional(),
118
+ url: z.string().optional(),
119
+ transport: z.string().optional(),
120
+ headers: z.record(z.string(), z.string()).optional(),
121
+ env: z.record(z.string(), z.string()).optional()
122
+ });
123
+ var HookConfigSchema = z.object({
124
+ id: z.string().optional(),
125
+ event: z.string(),
126
+ condition: z.string().optional(),
127
+ action: z.object({
128
+ type: z.string(),
129
+ command: z.string().optional(),
130
+ url: z.string().optional(),
131
+ method: z.string().optional(),
132
+ prompt: z.string().optional()
133
+ }),
134
+ reject: z.boolean().optional(),
135
+ once: z.boolean().optional(),
136
+ async: z.boolean().optional(),
137
+ on_error: z.string().optional()
138
+ });
139
+ var SandboxYamlConfigSchema = z.object({
140
+ enabled: z.boolean().optional(),
141
+ auto_allow: z.boolean().optional(),
142
+ network_enabled: z.boolean().optional()
143
+ });
144
+ var AppConfigSchema = z.looseObject({
145
+ providers: z.array(ProviderConfigSchema),
146
+ permission_mode: z.string().optional(),
147
+ mcp_servers: z.array(MCPServerConfigSchema).default([]),
148
+ hooks: z.array(HookConfigSchema).default([]),
149
+ sandbox: SandboxYamlConfigSchema.optional(),
150
+ enable_coordinator_mode: z.boolean().optional(),
151
+ /**
152
+ * Whether to fork when subagent_type is omitted. Enabled by default, so this
153
+ * field is left as undefined to represent "not specified in config". Using a
154
+ * concrete boolean would make it impossible to distinguish "not set" from
155
+ * "explicitly false", and the latter could never be turned back off.
156
+ */
157
+ enable_fork: z.boolean().optional()
158
+ });
159
+ function forkEnabled(cfg) {
160
+ return cfg.enable_fork !== false;
161
+ }
162
+ function isRecord(value) {
163
+ return typeof value === "object" && value !== null;
164
+ }
165
+ function loadSingleFile(path) {
166
+ const data = readFileSync(path, "utf-8");
167
+ const raw = yaml.load(data);
168
+ if (!isRecord(raw)) {
169
+ log.error({ path }, "invalid yaml");
170
+ return { providers: [], mcp_servers: [], hooks: [] };
171
+ }
172
+ const parsed = safeParse(AppConfigSchema, raw);
173
+ if (parsed.success) {
174
+ const data2 = parsed.data;
175
+ return {
176
+ providers: data2.providers,
177
+ permission_mode: data2.permission_mode,
178
+ mcp_servers: data2.mcp_servers,
179
+ hooks: data2.hooks
180
+ };
181
+ }
182
+ log.error({ error: parsed.error }, "config error");
183
+ let providers = [];
184
+ let permissionMode;
185
+ let mcpServers = [];
186
+ let hooks = [];
187
+ let sandbox = void 0;
188
+ let enableCoordinatorMode = false;
189
+ let enableFork = true;
190
+ if ("providers" in raw) {
191
+ const parsed2 = safeParse(z.array(ProviderConfigSchema), raw.providers);
192
+ if (parsed2.success) {
193
+ providers = parsed2.data;
194
+ }
195
+ }
196
+ if ("permission_mode" in raw && typeof raw.permission_mode === "string") {
197
+ permissionMode = raw.permission_mode;
198
+ }
199
+ if ("mcp_servers" in raw) {
200
+ const parsed2 = safeParse(z.array(MCPServerConfigSchema), raw.mcp_servers);
201
+ if (parsed2.success) {
202
+ mcpServers = parsed2.data;
203
+ }
204
+ }
205
+ if ("hooks" in raw) {
206
+ const parsed2 = safeParse(z.array(HookConfigSchema), raw.hooks);
207
+ if (parsed2.success) {
208
+ hooks = parsed2.data;
209
+ }
210
+ }
211
+ if ("sandbox" in raw) {
212
+ const parsed2 = safeParse(SandboxYamlConfigSchema, raw.sandbox);
213
+ if (parsed2.success) {
214
+ sandbox = parsed2.data;
215
+ }
216
+ }
217
+ if ("enable_coordinator_mode" in raw) {
218
+ enableCoordinatorMode = Boolean(raw.enable_coordinator_mode);
219
+ }
220
+ if ("enable_fork" in raw) {
221
+ enableFork = Boolean(raw.enable_fork);
222
+ }
223
+ return {
224
+ providers,
225
+ permission_mode: permissionMode,
226
+ mcp_servers: mcpServers,
227
+ hooks,
228
+ sandbox,
229
+ enable_coordinator_mode: enableCoordinatorMode,
230
+ enable_fork: enableFork
231
+ };
232
+ }
233
+ function mergeConfig(base, override) {
234
+ if (override.providers.length > 0) {
235
+ base.providers = override.providers;
236
+ }
237
+ if (override.permission_mode) {
238
+ base.permission_mode = override.permission_mode;
239
+ }
240
+ if (override.mcp_servers.length > 0) {
241
+ const mcpToIdx = /* @__PURE__ */ new Map();
242
+ for (let i = 0; i < base.mcp_servers.length; i++) {
243
+ const mcp = base.mcp_servers[i];
244
+ mcpToIdx.set(mcp.name, i);
245
+ }
246
+ for (const s of override.mcp_servers) {
247
+ const idx = mcpToIdx.get(s.name);
248
+ if (idx !== void 0) {
249
+ base.mcp_servers[idx] = s;
250
+ } else {
251
+ base.mcp_servers.push(s);
252
+ mcpToIdx.set(s.name, base.mcp_servers.length - 1);
253
+ }
254
+ }
255
+ }
256
+ base.hooks = [...base.hooks, ...override.hooks];
257
+ if (override.sandbox) {
258
+ base.sandbox = { ...base.sandbox, ...override.sandbox };
259
+ }
260
+ if (override.enable_coordinator_mode) {
261
+ base.enable_coordinator_mode = true;
262
+ }
263
+ if (override.enable_fork !== void 0) {
264
+ base.enable_fork = override.enable_fork;
265
+ }
266
+ return base;
267
+ }
268
+ function validateProviders(config) {
269
+ if (config.providers.length === 0) {
270
+ throw new ConfigError("At least one provider MUST be configured.");
271
+ }
272
+ const requiredFields = ["name", "protocol", "base_url", "model"];
273
+ for (let i = 0; i < config.providers.length; i++) {
274
+ const p = config.providers[i];
275
+ const values = {
276
+ name: p.name,
277
+ protocol: p.protocol,
278
+ base_url: p.base_url,
279
+ model: p.model
280
+ };
281
+ const missing = requiredFields.filter((field) => !(field in values));
282
+ if (missing.length > 0) {
283
+ throw new ConfigError(`Provider #${String(i + 1)}: missing fields: ${missing.join(", ")}`);
284
+ }
285
+ if (!VALID_PROTOCOLS.has(p.protocol)) {
286
+ throw new ConfigError(
287
+ `Provider #${String(i + 1)}: invalid protocol '${p.protocol}', MUST be one of: ${Array.from(VALID_PROTOCOLS).join(", ")}`
288
+ );
289
+ }
290
+ }
291
+ }
292
+ function loadConfig(path) {
293
+ if (path) {
294
+ const config = loadSingleFile(path);
295
+ validateProviders(config);
296
+ return config;
297
+ }
298
+ const wd = process.cwd();
299
+ const home = homedir();
300
+ const candidates = [
301
+ join(home, ".swifty", "config.yaml"),
302
+ join(wd, ".swifty", "config.yaml"),
303
+ join(wd, ".swifty", "config.local.yaml")
304
+ ];
305
+ let merged = null;
306
+ for (const candidate of candidates) {
307
+ if (!existsSync(candidate)) {
308
+ continue;
309
+ }
310
+ const layer = loadSingleFile(candidate);
311
+ if (!merged) {
312
+ merged = layer;
313
+ } else {
314
+ merged = mergeConfig(merged, layer);
315
+ }
316
+ }
317
+ if (!merged) {
318
+ throw new ConfigError(
319
+ "No config file found, expected .swifty/config.y(a)ml under project or $HOME/.swifty/config.y(a)ml."
320
+ );
321
+ }
322
+ validateProviders(merged);
323
+ return merged;
324
+ }
325
+
326
+ export {
327
+ ConfigError,
328
+ ProviderConfigSchema,
329
+ lookupModelContextWindow,
330
+ getContextWindow,
331
+ getContextWindowAsync,
332
+ _resetContextWindowCache,
333
+ getMaxOutputTokens,
334
+ resolveAPIKey,
335
+ HookConfigSchema,
336
+ forkEnabled,
337
+ mergeConfig,
338
+ loadConfig
339
+ };