@dhzh/foundry 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,12 +55,12 @@ Codex Providers use the Responses protocol and support a default model, optional
55
55
 
56
56
  ### Runtimes
57
57
 
58
- Foundry detects the `codex` and `claude` executables from `PATH`, reads their version, and manages these user-level configuration files:
58
+ Foundry detects the `codex` and `claude` executables from `PATH`, reads their version, and manages these user-level configuration files. It honors each Runtime's configuration-directory environment variable and otherwise uses the standard home-directory location:
59
59
 
60
- | Runtime | Configuration file |
61
- | --- | --- |
62
- | Codex | `~/.codex/config.toml` |
63
- | Claude Code | `~/.claude/settings.json` |
60
+ | Runtime | Environment override | Default configuration file |
61
+ | --- | --- | --- |
62
+ | Codex | `$CODEX_HOME/config.toml` | `~/.codex/config.toml` |
63
+ | Claude Code | `$CLAUDE_CONFIG_DIR/settings.json` | `~/.claude/settings.json` |
64
64
 
65
65
  Before applying a saved Provider or Official Default, Foundry compares every managed field and separates proposed changes from unchanged fields. Long configuration paths, field names, and field values remain on one line and reveal the full value on hover when truncated. Applying a preview:
66
66
 
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{t as e}from"./package-sD3q513f.mjs";import{defineCommand as t,renderUsage as n,runMain as r}from"citty";import i from"node:process";import a from"open";import{serve as o}from"@hono/node-server";import{serveStatic as s}from"@hono/node-server/serve-static";import{zValidator as c}from"@hono/zod-validator";import{constants as l,existsSync as u}from"node:fs";import d from"node:path";import{Hono as f}from"hono";import{z as p}from"zod";import{Uint8ArrayReader as m,Uint8ArrayWriter as h,ZipReader as ee,ZipWriter as te}from"@zip.js/zip.js";import{createHash as g,randomUUID as ne,randomUUIDv7 as re}from"node:crypto";import{bodyLimit as ie}from"hono/body-limit";import{TextDecoder as ae,promisify as oe}from"node:util";import{Buffer as se}from"node:buffer";import ce from"better-sqlite3";import{drizzle as le}from"drizzle-orm/better-sqlite3";import{access as ue,chmod as de,lstat as fe,mkdir as _,readFile as pe,readdir as me,realpath as he,rename as ge,rm as v,stat as _e,writeFile as ve}from"node:fs/promises";import{readMigrationFiles as ye}from"drizzle-orm/migrator";import be from"env-paths";import{homedir as xe}from"node:os";import{and as y,desc as Se,eq as b,isNull as x,sql as S}from"drizzle-orm";import{blob as Ce,check as C,index as we,integer as w,sqliteTable as T,text as E,uniqueIndex as Te}from"drizzle-orm/sqlite-core";import{parse as Ee,patch as De,stringify as Oe}from"@decimalturn/toml-patch";import{execFile as ke}from"node:child_process";var Ae=Object.defineProperty,je=(e,t)=>{let n={};for(var r in e)Ae(n,r,{get:e[r],enumerable:!0});return t||Ae(n,Symbol.toStringTag,{value:`Module`}),n};const D={providerConnectionFailed:`PROVIDER_CONNECTION_FAILED`,providerInUse:`PROVIDER_IN_USE`,providerNotFound:`PROVIDER_NOT_FOUND`,runtimeApplyFailed:`RUNTIME_APPLY_FAILED`,runtimeConfigurationChanged:`RUNTIME_CONFIGURATION_CHANGED`,runtimeConfigurationInvalid:`RUNTIME_CONFIGURATION_INVALID`,runtimeNotDetected:`RUNTIME_NOT_DETECTED`,success:`SUCCESS`},O=[`system`,`light`,`dark`],Me=`foundry-export-v1`,Ne=[`settings`,`providers`],k=[`codex`,`claude-code`],Pe=[`image/png`,`image/jpeg`,`image/webp`,`image/svg+xml`],Fe=[`authorization`,`x-api-key`],Ie=[`effort`,`xhigh_effort`,`max_effort`,`thinking`,`adaptive_thinking`,`interleaved_thinking`],Le=p.strictObject({});function Re(e,t){e.get(`/api/data/export`,c(`query`,Le),async()=>{let e=await t.createExport();return new Response(e.content,{headers:{"cache-control":`no-store`,"content-disposition":`attachment; filename="${e.filename}"`,"content-length":String(e.content.byteLength),"content-type":`application/octet-stream`,"x-content-type-options":`nosniff`}})})}const ze=new TextEncoder;function A(e){return String(e).padStart(2,`0`)}function Be(e){let t={avatar:e.avatar,name:e.name,officialWebsite:e.officialWebsite,remark:e.remark};return e.runtime,{...t,configuration:e.configuration,runtime:e.runtime}}function Ve(e,t,n,r){let i=ze.encode(JSON.stringify(r));return{content:i,manifest:{id:e,mediaType:`application/json`,overwrite:n,path:t,sha256:g(`sha256`).update(i).digest(`hex`),size:i.byteLength}}}function He(e){return`foundry-export-${[e.getFullYear(),`-`,A(e.getMonth()+1),`-`,A(e.getDate()),`T`,A(e.getHours()),A(e.getMinutes()),A(e.getSeconds())].join(``)}.foundry`}var Ue=class{providerStore;settingsStore;now;foundryVersion;constructor(t,n,r=()=>new Date,i=e){this.providerStore=t,this.settingsStore=n,this.now=r,this.foundryVersion=i}async createExport(){let e=this.now(),t=this.settingsStore.getApplicationSettings(),n=k.flatMap(e=>this.providerStore.listProviders(e).map(e=>Be(e))),r=[Ve(`settings`,`modules/settings.json`,!0,t),Ve(`providers`,`modules/providers.json`,!1,n)],i={createdAt:e.toISOString(),format:Me,foundryVersion:this.foundryVersion,modules:r.map(e=>e.manifest)},a=new te(new h),o=JSON.stringify(i),s=ze.encode(o);await a.add(`manifest.json`,new m(s));for(let e of r)await a.add(e.manifest.path,new m(e.content));return{content:await a.close(),filename:He(e),manifest:i}}};const We=/^[A-Za-z0-9+/]+={0,2}$/u;function Ge(e,t){for(let n of e){let e=n.codePointAt(0)??0,r=t&&[9,10,13].includes(e);if(e===127||!r&&e<32)return!0}return!1}function j(e){return p.string().trim().max(e).refine(e=>!Ge(e,!0),{message:`Control characters are not allowed.`})}function M(e){return j(e).nullable().transform(e=>e===``?null:e)}function Ke(e,t){try{let n=new URL(e);return[`http:`,`https:`].includes(n.protocol)&&n.username===``&&n.password===``&&(t||n.search===``&&n.hash===``)}catch{return!1}}const qe=j(2048).min(1).refine(e=>Ke(e,!1),{message:`Provide an HTTP or HTTPS URL without credentials, a query, or a fragment.`}),Je=M(2048).refine(e=>e===null||Ke(e,!0),{message:`Provide an HTTP or HTTPS URL without credentials.`}),Ye=j(100).min(1),Xe=M(100),Ze=M(2e3),N=j(200).min(1),Qe=M(200),$e=M(2e3),et=p.string().min(1).max(16384).refine(e=>!Ge(e,!1),{message:`Control characters are not allowed.`}),tt=p.union([et,p.literal(``),p.null()]).transform(e=>e===``?null:e);function nt(e,t){if(e===`image/png`)return[137,80,78,71,13,10,26,10].every((e,n)=>t[n]===e);if(e===`image/jpeg`)return t[0]===255&&t[1]===216&&t[2]===255;if(e===`image/svg+xml`)try{let e=new ae(`utf-8`,{fatal:!0}).decode(t);return/^\s*(?:(?:<\?xml[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE[\s\S]*?>)\s*)*<svg(?:\s|>)/u.test(e)}catch{return!1}return t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70&&t[8]===87&&t[9]===69&&t[10]===66&&t[11]===80}const rt=p.strictObject({data:p.string().min(1).max(2796204),mimeType:p.enum(Pe)}).superRefine((e,t)=>{if(!We.test(e.data)){t.addIssue({code:`custom`,message:`Avatar data must be valid Base64.`});return}let n=se.from(e.data,`base64`);(n.byteLength===0||n.byteLength>2097152||n.toString(`base64`)!==e.data||!nt(e.mimeType,n))&&t.addIssue({code:`custom`,message:`Avatar data must be a valid PNG, JPEG, WebP, or SVG image no larger than 2 MB.`})}),it=p.array(p.enum(Ie)).max(Ie.length).refine(e=>new Set(e).size===e.length,{message:`Model capabilities must be unique.`}),P=p.strictObject({description:Ze,displayName:Xe,model:N,supportedCapabilities:it}),at=p.union([N,P.transform(e=>e.model)]),ot=p.strictObject({apiKey:tt,baseUrl:qe,defaultModel:N,protocol:p.literal(`responses`),reviewModel:Qe}),st=p.strictObject({apiKey:et,apiKeyHeader:p.enum(Fe),baseUrl:qe,fableModel:P.nullable(),haikuModel:P.nullable(),opusModel:P.nullable(),defaultModel:at,protocol:p.literal(`messages`),sonnetModel:P.nullable(),subagentModel:Qe,subagentModelForce:p.boolean().default(!1),hideAiAttribution:p.boolean().default(!1),teammatesMode:p.boolean().default(!1),enableToolSearch:p.boolean().default(!1),maxEffortThinking:p.boolean().default(!1),disableAutoUpdater:p.boolean().default(!1)}),ct={avatar:rt.nullable(),name:Ye,officialWebsite:Je,remark:$e},F=p.discriminatedUnion(`runtime`,[p.strictObject({...ct,configuration:ot,runtime:p.literal(`codex`)}),p.strictObject({...ct,configuration:st,runtime:p.literal(`claude-code`)})]),I=p.strictObject({providerId:p.string().min(1)}),lt=p.strictObject({runtime:p.enum(k)});function L(e){return F.parse(e)}function ut(e){return ot.parse(e)}function dt(e){return st.parse(e)}function ft(e){return e===null?null:se.from(rt.parse(e).data,`base64`)}const pt=new ae(`utf-8`,{fatal:!0}),mt=p.string().regex(/^[a-f0-9]{64}$/u),ht=p.strictObject({id:p.string().min(1).max(100).regex(/^[a-z][a-z0-9-]*$/u),mediaType:p.string().min(1).max(100),overwrite:p.boolean(),path:p.string().min(1).max(512),sha256:mt,size:p.number().int().nonnegative().max(2**53-1)}),gt=p.strictObject({createdAt:p.string().min(1).max(64).refine(e=>!Number.isNaN(Date.parse(e))),format:p.literal(Me),foundryVersion:p.string().min(1).max(100),modules:p.array(ht).max(256)}).superRefine((e,t)=>{let n=new Set,r=new Set;for(let[i,a]of e.modules.entries())n.has(a.id)&&t.addIssue({code:`custom`,message:`Export Module identifiers must be unique.`,path:[`modules`,i,`id`]}),r.has(a.path)&&t.addIssue({code:`custom`,message:`Export Module paths must be unique.`,path:[`modules`,i,`path`]}),n.add(a.id),r.add(a.path)}),_t=p.strictObject({colorMode:p.enum(O)}),vt=p.array(F);var R=class extends Error{constructor(e){super(`The selected file is not a valid Foundry Export.`,{cause:e}),this.name=`FoundryImportFileError`}};function yt(e){return Ne.includes(e)}function bt(e,t){let n=e.find(e=>e.filename===t);if(!n||n.directory||n.encrypted||n.symlink)throw Error(`The Export Module entry is unavailable.`);return n}async function xt(e,t){if(e.uncompressedSize>t)throw Error(`The archive entry is too large.`);let n=await e.getData(new h);if(n.byteLength>t)throw Error(`The archive entry is too large.`);return JSON.parse(pt.decode(n))}async function St(e){try{let t=gt.parse(await xt(bt(e,`manifest.json`),1048576)),n=new Set([`manifest.json`,...t.modules.map(e=>e.path)]),r=e.some(e=>!e.directory&&!n.has(e.filename)),i=new Set(t.modules.map(e=>e.id));if(r||Ne.some(e=>!i.has(e)))throw Error(`The Foundry Export package is incomplete.`);return t}catch(e){throw new R(e)}}async function Ct(e,t){if(e.mediaType!==`application/json`||e.size>268435456)throw Error(`The Export Module metadata is invalid.`);let n=bt(t,e.path);if(n.uncompressedSize!==e.size)throw Error(`The Export Module size does not match its manifest.`);let r=await n.getData(new h),i=g(`sha256`).update(r).digest(`hex`);if(r.byteLength!==e.size||i!==e.sha256)throw Error(`The Export Module does not match its manifest.`);return JSON.parse(pt.decode(r))}function wt(e){return{id:e,importedItems:0,message:`${e===`settings`?`Application Settings`:`Providers`} could not be imported.`,status:`failed`}}var Tt=class{providerStore;settingsStore;constructor(e,t){this.providerStore=e,this.settingsStore=t}async importData(e){if(e.byteLength===0)throw new R;let t=new ee(new m(e),{checkCrc32:!0,filenameValidation:`strict`,maxAppendedDataSize:0,strictness:`strict`});try{let e;try{e=await t.getEntries()}catch(e){throw new R(e)}if(e.length>256)throw new R;let n=await St(e),r=[];for(let t of n.modules){if(!yt(t.id)){r.push({id:t.id,importedItems:0,message:`This Export Module is not supported by this Foundry version.`,status:`unsupported`});continue}try{let n=await Ct(t,e);if(t.id===`settings`){if(!t.overwrite)throw Error(`Application Settings must use overwrite import behavior.`);this.settingsStore.updateApplicationSettings(_t.parse(n)),r.push({id:t.id,importedItems:1,status:`imported`})}else{if(t.overwrite)throw Error(`Providers must use append import behavior.`);let e=vt.parse(n);this.providerStore.createProviders(e),r.push({id:t.id,importedItems:e.length,status:`imported`})}}catch{r.push(wt(t.id))}}return{modules:r}}finally{await t.close()}}};const Et=p.strictObject({});function Dt(e,t){e.post(`/api/data/import`,c(`query`,Et),ie({maxSize:268435456}),async e=>{try{let n=await t.importData(new Uint8Array(await e.req.arrayBuffer()));return e.json({status:D.success,data:n})}catch(t){if(t instanceof R)return e.json({message:t.message},400);throw t}})}function z(e){return{avatar:e.avatar,baseUrl:e.configuration.baseUrl,id:e.id,name:e.name,officialWebsite:e.officialWebsite,remark:e.remark,runtime:e.runtime}}function Ot(e,t,n){e.get(`/api/providers`,c(`query`,lt),e=>e.json({status:D.success,data:t.listProviders(e.req.valid(`query`).runtime).map(e=>z(e))})),e.delete(`/api/providers/:providerId`,c(`param`,I),e=>{let n=t.deleteProvider(e.req.valid(`param`).providerId);return n===`in-use`?e.json({status:D.providerInUse,data:!1,message:`A Provider in use cannot be deleted.`}):n===`not-found`?e.json({status:D.providerNotFound,data:!1,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:!0})}),e.post(`/api/providers/:providerId/test-connection`,c(`param`,I),async e=>{let r=t.getProvider(e.req.valid(`param`).providerId);if(r===null)return e.json({status:D.providerNotFound,data:!1,message:`The selected Provider is unavailable.`});let i=await n.testProvider(r);return i.successful?e.json({status:D.success,data:!0}):e.json({status:D.providerConnectionFailed,data:!1,message:i.message})}),e.post(`/api/providers`,c(`json`,F),e=>{let n=e.req.valid(`json`),r=z(t.createProvider(n));return e.json({status:D.success,data:r},201)}),e.get(`/api/providers/:providerId`,c(`param`,I),e=>{let n=t.getProvider(e.req.valid(`param`).providerId);return n===null?e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:n})}),e.post(`/api/providers/:providerId/copy`,c(`param`,I),c(`json`,F),e=>{let n=e.req.valid(`param`).providerId,r=t.getProvider(n);if(r===null)return e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`});let i=e.req.valid(`json`);if(i.runtime!==r.runtime)return e.json({message:`A Provider Runtime cannot be changed.`},400);let a=t.copyProvider(n,i);return a===null?e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:z(a)},201)}),e.put(`/api/providers/:providerId`,c(`param`,I),c(`json`,F),e=>{let n=e.req.valid(`param`).providerId,r=t.getProvider(n);if(r===null)return e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`});let i=e.req.valid(`json`);if(i.runtime!==r.runtime)return e.json({message:`A Provider Runtime cannot be changed.`},400);let a=t.updateProvider(n,i);return e.json({status:D.success,data:a===null?null:z(a)})})}var B=class extends Error{status;constructor(e,t){super(t),this.status=e}};const kt=p.discriminatedUnion(`kind`,[p.strictObject({kind:p.literal(`official-default`)}),p.strictObject({kind:p.literal(`provider`),providerId:p.string().min(1)})]),At=p.strictObject({runtime:p.enum(k)}),jt=p.strictObject({}),Mt=p.strictObject({providerKey:p.string().min(1).max(200).optional(),target:kt}),Nt=p.strictObject({expectedFileHash:p.string().regex(/^[0-9a-f]{64}$/),providerKey:p.string().min(1).max(200).optional(),target:kt});function Pt(e,t){e.get(`/api/runtimes`,c(`query`,jt),async e=>e.json({status:D.success,data:await t.listRuntimes()})),e.post(`/api/runtimes/:runtime/preview`,c(`param`,At),c(`json`,Mt),async e=>{try{return e.json({status:D.success,data:await t.previewConfiguration(e.req.valid(`param`).runtime,e.req.valid(`json`))})}catch(t){if(t instanceof B)return e.json({status:t.status,data:null,message:t.message});throw t}}),e.post(`/api/runtimes/:runtime/apply`,c(`param`,At),c(`json`,Nt),async e=>{try{return e.json({status:D.success,data:await t.applyConfiguration(e.req.valid(`param`).runtime,e.req.valid(`json`))})}catch(t){if(t instanceof B)return e.json({status:t.status,data:null,message:t.message});throw t}})}const Ft=p.strictObject({}),It=p.strictObject({colorMode:p.enum(O)});function Lt(e,t){e.get(`/api/settings`,c(`query`,Ft),e=>e.json({status:D.success,data:t.getApplicationSettings()})),e.patch(`/api/settings`,c(`json`,It),e=>e.json({status:D.success,data:t.updateApplicationSettings(e.req.valid(`json`))}))}const Rt=p.strictObject({});function zt(){return[d.resolve(import.meta.dirname,`app`),d.resolve(import.meta.dirname,`../../dist/app`)].find(e=>u(e))}function Bt(e){let t=new f;t.get(`/api/health`,c(`query`,Rt),e=>e.json({status:D.success,data:!0,message:`Service is healthy.`})),Re(t,new Ue(e.providerStore,e.settingsStore)),Dt(t,new Tt(e.providerStore,e.settingsStore)),Lt(t,e.settingsStore),Ot(t,e.providerStore,e.providerConnectionTester),Pt(t,e.runtimeService);let n=e.webRoot??zt();return n&&t.use(`*`,s({root:n})),t}const V=`__drizzle_migrations`;function Vt(e){return!!e.prepare(`
2
+ import{t as e}from"./package-BRv6jbgV.mjs";import{defineCommand as t,renderUsage as n,runMain as r}from"citty";import i from"node:process";import a from"open";import{serve as o}from"@hono/node-server";import{serveStatic as s}from"@hono/node-server/serve-static";import{zValidator as c}from"@hono/zod-validator";import{constants as l,existsSync as u}from"node:fs";import d from"node:path";import{Hono as f}from"hono";import{z as p}from"zod";import{Uint8ArrayReader as m,Uint8ArrayWriter as h,ZipReader as ee,ZipWriter as te}from"@zip.js/zip.js";import{createHash as g,randomUUID as ne,randomUUIDv7 as re}from"node:crypto";import{bodyLimit as ie}from"hono/body-limit";import{TextDecoder as ae,promisify as oe}from"node:util";import{Buffer as se}from"node:buffer";import ce from"better-sqlite3";import{drizzle as le}from"drizzle-orm/better-sqlite3";import{access as ue,chmod as de,lstat as fe,mkdir as _,readFile as pe,readdir as me,realpath as he,rename as ge,rm as v,stat as _e,writeFile as ve}from"node:fs/promises";import{readMigrationFiles as ye}from"drizzle-orm/migrator";import be from"env-paths";import{homedir as xe}from"node:os";import{and as y,desc as Se,eq as b,isNull as x,sql as S}from"drizzle-orm";import{blob as Ce,check as C,index as we,integer as w,sqliteTable as T,text as E,uniqueIndex as Te}from"drizzle-orm/sqlite-core";import{parse as Ee,patch as De,stringify as Oe}from"@decimalturn/toml-patch";import{execFile as ke}from"node:child_process";var Ae=Object.defineProperty,je=(e,t)=>{let n={};for(var r in e)Ae(n,r,{get:e[r],enumerable:!0});return t||Ae(n,Symbol.toStringTag,{value:`Module`}),n};const D={providerConnectionFailed:`PROVIDER_CONNECTION_FAILED`,providerInUse:`PROVIDER_IN_USE`,providerNotFound:`PROVIDER_NOT_FOUND`,runtimeApplyFailed:`RUNTIME_APPLY_FAILED`,runtimeConfigurationChanged:`RUNTIME_CONFIGURATION_CHANGED`,runtimeConfigurationInvalid:`RUNTIME_CONFIGURATION_INVALID`,runtimeNotDetected:`RUNTIME_NOT_DETECTED`,success:`SUCCESS`},O=[`system`,`light`,`dark`],Me=`foundry-export-v1`,Ne=[`settings`,`providers`],k=[`codex`,`claude-code`],Pe=[`image/png`,`image/jpeg`,`image/webp`,`image/svg+xml`],Fe=[`authorization`,`x-api-key`],Ie=[`effort`,`xhigh_effort`,`max_effort`,`thinking`,`adaptive_thinking`,`interleaved_thinking`],Le=p.strictObject({});function Re(e,t){e.get(`/api/data/export`,c(`query`,Le),async()=>{let e=await t.createExport();return new Response(e.content,{headers:{"cache-control":`no-store`,"content-disposition":`attachment; filename="${e.filename}"`,"content-length":String(e.content.byteLength),"content-type":`application/octet-stream`,"x-content-type-options":`nosniff`}})})}const ze=new TextEncoder;function A(e){return String(e).padStart(2,`0`)}function Be(e){let t={avatar:e.avatar,name:e.name,officialWebsite:e.officialWebsite,remark:e.remark};return e.runtime,{...t,configuration:e.configuration,runtime:e.runtime}}function Ve(e,t,n,r){let i=ze.encode(JSON.stringify(r));return{content:i,manifest:{id:e,mediaType:`application/json`,overwrite:n,path:t,sha256:g(`sha256`).update(i).digest(`hex`),size:i.byteLength}}}function He(e){return`foundry-export-${[e.getFullYear(),`-`,A(e.getMonth()+1),`-`,A(e.getDate()),`T`,A(e.getHours()),A(e.getMinutes()),A(e.getSeconds())].join(``)}.foundry`}var Ue=class{providerStore;settingsStore;now;foundryVersion;constructor(t,n,r=()=>new Date,i=e){this.providerStore=t,this.settingsStore=n,this.now=r,this.foundryVersion=i}async createExport(){let e=this.now(),t=this.settingsStore.getApplicationSettings(),n=k.flatMap(e=>this.providerStore.listProviders(e).map(e=>Be(e))),r=[Ve(`settings`,`modules/settings.json`,!0,t),Ve(`providers`,`modules/providers.json`,!1,n)],i={createdAt:e.toISOString(),format:Me,foundryVersion:this.foundryVersion,modules:r.map(e=>e.manifest)},a=new te(new h),o=JSON.stringify(i),s=ze.encode(o);await a.add(`manifest.json`,new m(s));for(let e of r)await a.add(e.manifest.path,new m(e.content));return{content:await a.close(),filename:He(e),manifest:i}}};const We=/^[A-Za-z0-9+/]+={0,2}$/u;function Ge(e,t){for(let n of e){let e=n.codePointAt(0)??0,r=t&&[9,10,13].includes(e);if(e===127||!r&&e<32)return!0}return!1}function j(e){return p.string().trim().max(e).refine(e=>!Ge(e,!0),{message:`Control characters are not allowed.`})}function M(e){return j(e).nullable().transform(e=>e===``?null:e)}function Ke(e,t){try{let n=new URL(e);return[`http:`,`https:`].includes(n.protocol)&&n.username===``&&n.password===``&&(t||n.search===``&&n.hash===``)}catch{return!1}}const qe=j(2048).min(1).refine(e=>Ke(e,!1),{message:`Provide an HTTP or HTTPS URL without credentials, a query, or a fragment.`}),Je=M(2048).refine(e=>e===null||Ke(e,!0),{message:`Provide an HTTP or HTTPS URL without credentials.`}),Ye=j(100).min(1),Xe=M(100),Ze=M(2e3),N=j(200).min(1),Qe=M(200),$e=M(2e3),et=p.string().min(1).max(16384).refine(e=>!Ge(e,!1),{message:`Control characters are not allowed.`}),tt=p.union([et,p.literal(``),p.null()]).transform(e=>e===``?null:e);function nt(e,t){if(e===`image/png`)return[137,80,78,71,13,10,26,10].every((e,n)=>t[n]===e);if(e===`image/jpeg`)return t[0]===255&&t[1]===216&&t[2]===255;if(e===`image/svg+xml`)try{let e=new ae(`utf-8`,{fatal:!0}).decode(t);return/^\s*(?:(?:<\?xml[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE[\s\S]*?>)\s*)*<svg(?:\s|>)/u.test(e)}catch{return!1}return t[0]===82&&t[1]===73&&t[2]===70&&t[3]===70&&t[8]===87&&t[9]===69&&t[10]===66&&t[11]===80}const rt=p.strictObject({data:p.string().min(1).max(2796204),mimeType:p.enum(Pe)}).superRefine((e,t)=>{if(!We.test(e.data)){t.addIssue({code:`custom`,message:`Avatar data must be valid Base64.`});return}let n=se.from(e.data,`base64`);(n.byteLength===0||n.byteLength>2097152||n.toString(`base64`)!==e.data||!nt(e.mimeType,n))&&t.addIssue({code:`custom`,message:`Avatar data must be a valid PNG, JPEG, WebP, or SVG image no larger than 2 MB.`})}),it=p.array(p.enum(Ie)).max(Ie.length).refine(e=>new Set(e).size===e.length,{message:`Model capabilities must be unique.`}),P=p.strictObject({description:Ze,displayName:Xe,model:N,supportedCapabilities:it}),at=p.union([N,P.transform(e=>e.model)]),ot=p.strictObject({apiKey:tt,baseUrl:qe,defaultModel:N,protocol:p.literal(`responses`),reviewModel:Qe}),st=p.strictObject({apiKey:et,apiKeyHeader:p.enum(Fe),baseUrl:qe,fableModel:P.nullable(),haikuModel:P.nullable(),opusModel:P.nullable(),defaultModel:at,protocol:p.literal(`messages`),sonnetModel:P.nullable(),subagentModel:Qe,subagentModelForce:p.boolean().default(!1),hideAiAttribution:p.boolean().default(!1),teammatesMode:p.boolean().default(!1),enableToolSearch:p.boolean().default(!1),maxEffortThinking:p.boolean().default(!1),disableAutoUpdater:p.boolean().default(!1)}),ct={avatar:rt.nullable(),name:Ye,officialWebsite:Je,remark:$e},F=p.discriminatedUnion(`runtime`,[p.strictObject({...ct,configuration:ot,runtime:p.literal(`codex`)}),p.strictObject({...ct,configuration:st,runtime:p.literal(`claude-code`)})]),I=p.strictObject({providerId:p.string().min(1)}),lt=p.strictObject({runtime:p.enum(k)});function L(e){return F.parse(e)}function ut(e){return ot.parse(e)}function dt(e){return st.parse(e)}function ft(e){return e===null?null:se.from(rt.parse(e).data,`base64`)}const pt=new ae(`utf-8`,{fatal:!0}),mt=p.string().regex(/^[a-f0-9]{64}$/u),ht=p.strictObject({id:p.string().min(1).max(100).regex(/^[a-z][a-z0-9-]*$/u),mediaType:p.string().min(1).max(100),overwrite:p.boolean(),path:p.string().min(1).max(512),sha256:mt,size:p.number().int().nonnegative().max(2**53-1)}),gt=p.strictObject({createdAt:p.string().min(1).max(64).refine(e=>!Number.isNaN(Date.parse(e))),format:p.literal(Me),foundryVersion:p.string().min(1).max(100),modules:p.array(ht).max(256)}).superRefine((e,t)=>{let n=new Set,r=new Set;for(let[i,a]of e.modules.entries())n.has(a.id)&&t.addIssue({code:`custom`,message:`Export Module identifiers must be unique.`,path:[`modules`,i,`id`]}),r.has(a.path)&&t.addIssue({code:`custom`,message:`Export Module paths must be unique.`,path:[`modules`,i,`path`]}),n.add(a.id),r.add(a.path)}),_t=p.strictObject({colorMode:p.enum(O)}),vt=p.array(F);var R=class extends Error{constructor(e){super(`The selected file is not a valid Foundry Export.`,{cause:e}),this.name=`FoundryImportFileError`}};function yt(e){return Ne.includes(e)}function bt(e,t){let n=e.find(e=>e.filename===t);if(!n||n.directory||n.encrypted||n.symlink)throw Error(`The Export Module entry is unavailable.`);return n}async function xt(e,t){if(e.uncompressedSize>t)throw Error(`The archive entry is too large.`);let n=await e.getData(new h);if(n.byteLength>t)throw Error(`The archive entry is too large.`);return JSON.parse(pt.decode(n))}async function St(e){try{let t=gt.parse(await xt(bt(e,`manifest.json`),1048576)),n=new Set([`manifest.json`,...t.modules.map(e=>e.path)]),r=e.some(e=>!e.directory&&!n.has(e.filename)),i=new Set(t.modules.map(e=>e.id));if(r||Ne.some(e=>!i.has(e)))throw Error(`The Foundry Export package is incomplete.`);return t}catch(e){throw new R(e)}}async function Ct(e,t){if(e.mediaType!==`application/json`||e.size>268435456)throw Error(`The Export Module metadata is invalid.`);let n=bt(t,e.path);if(n.uncompressedSize!==e.size)throw Error(`The Export Module size does not match its manifest.`);let r=await n.getData(new h),i=g(`sha256`).update(r).digest(`hex`);if(r.byteLength!==e.size||i!==e.sha256)throw Error(`The Export Module does not match its manifest.`);return JSON.parse(pt.decode(r))}function wt(e){return{id:e,importedItems:0,message:`${e===`settings`?`Application Settings`:`Providers`} could not be imported.`,status:`failed`}}var Tt=class{providerStore;settingsStore;constructor(e,t){this.providerStore=e,this.settingsStore=t}async importData(e){if(e.byteLength===0)throw new R;let t=new ee(new m(e),{checkCrc32:!0,filenameValidation:`strict`,maxAppendedDataSize:0,strictness:`strict`});try{let e;try{e=await t.getEntries()}catch(e){throw new R(e)}if(e.length>256)throw new R;let n=await St(e),r=[];for(let t of n.modules){if(!yt(t.id)){r.push({id:t.id,importedItems:0,message:`This Export Module is not supported by this Foundry version.`,status:`unsupported`});continue}try{let n=await Ct(t,e);if(t.id===`settings`){if(!t.overwrite)throw Error(`Application Settings must use overwrite import behavior.`);this.settingsStore.updateApplicationSettings(_t.parse(n)),r.push({id:t.id,importedItems:1,status:`imported`})}else{if(t.overwrite)throw Error(`Providers must use append import behavior.`);let e=vt.parse(n);this.providerStore.createProviders(e),r.push({id:t.id,importedItems:e.length,status:`imported`})}}catch{r.push(wt(t.id))}}return{modules:r}}finally{await t.close()}}};const Et=p.strictObject({});function Dt(e,t){e.post(`/api/data/import`,c(`query`,Et),ie({maxSize:268435456}),async e=>{try{let n=await t.importData(new Uint8Array(await e.req.arrayBuffer()));return e.json({status:D.success,data:n})}catch(t){if(t instanceof R)return e.json({message:t.message},400);throw t}})}function z(e){return{avatar:e.avatar,baseUrl:e.configuration.baseUrl,id:e.id,name:e.name,officialWebsite:e.officialWebsite,remark:e.remark,runtime:e.runtime}}function Ot(e,t,n){e.get(`/api/providers`,c(`query`,lt),e=>e.json({status:D.success,data:t.listProviders(e.req.valid(`query`).runtime).map(e=>z(e))})),e.delete(`/api/providers/:providerId`,c(`param`,I),e=>{let n=t.deleteProvider(e.req.valid(`param`).providerId);return n===`in-use`?e.json({status:D.providerInUse,data:!1,message:`A Provider in use cannot be deleted.`}):n===`not-found`?e.json({status:D.providerNotFound,data:!1,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:!0})}),e.post(`/api/providers/:providerId/test-connection`,c(`param`,I),async e=>{let r=t.getProvider(e.req.valid(`param`).providerId);if(r===null)return e.json({status:D.providerNotFound,data:!1,message:`The selected Provider is unavailable.`});let i=await n.testProvider(r);return i.successful?e.json({status:D.success,data:!0}):e.json({status:D.providerConnectionFailed,data:!1,message:i.message})}),e.post(`/api/providers`,c(`json`,F),e=>{let n=e.req.valid(`json`),r=z(t.createProvider(n));return e.json({status:D.success,data:r},201)}),e.get(`/api/providers/:providerId`,c(`param`,I),e=>{let n=t.getProvider(e.req.valid(`param`).providerId);return n===null?e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:n})}),e.post(`/api/providers/:providerId/copy`,c(`param`,I),c(`json`,F),e=>{let n=e.req.valid(`param`).providerId,r=t.getProvider(n);if(r===null)return e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`});let i=e.req.valid(`json`);if(i.runtime!==r.runtime)return e.json({message:`A Provider Runtime cannot be changed.`},400);let a=t.copyProvider(n,i);return a===null?e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`}):e.json({status:D.success,data:z(a)},201)}),e.put(`/api/providers/:providerId`,c(`param`,I),c(`json`,F),e=>{let n=e.req.valid(`param`).providerId,r=t.getProvider(n);if(r===null)return e.json({status:D.providerNotFound,data:null,message:`The selected Provider is unavailable.`});let i=e.req.valid(`json`);if(i.runtime!==r.runtime)return e.json({message:`A Provider Runtime cannot be changed.`},400);let a=t.updateProvider(n,i);return e.json({status:D.success,data:a===null?null:z(a)})})}var B=class extends Error{status;constructor(e,t){super(t),this.status=e}};const kt=p.discriminatedUnion(`kind`,[p.strictObject({kind:p.literal(`official-default`)}),p.strictObject({kind:p.literal(`provider`),providerId:p.string().min(1)})]),At=p.strictObject({runtime:p.enum(k)}),jt=p.strictObject({}),Mt=p.strictObject({providerKey:p.string().min(1).max(200).optional(),target:kt}),Nt=p.strictObject({expectedFileHash:p.string().regex(/^[0-9a-f]{64}$/),providerKey:p.string().min(1).max(200).optional(),target:kt});function Pt(e,t){e.get(`/api/runtimes`,c(`query`,jt),async e=>e.json({status:D.success,data:await t.listRuntimes()})),e.post(`/api/runtimes/:runtime/preview`,c(`param`,At),c(`json`,Mt),async e=>{try{return e.json({status:D.success,data:await t.previewConfiguration(e.req.valid(`param`).runtime,e.req.valid(`json`))})}catch(t){if(t instanceof B)return e.json({status:t.status,data:null,message:t.message});throw t}}),e.post(`/api/runtimes/:runtime/apply`,c(`param`,At),c(`json`,Nt),async e=>{try{return e.json({status:D.success,data:await t.applyConfiguration(e.req.valid(`param`).runtime,e.req.valid(`json`))})}catch(t){if(t instanceof B)return e.json({status:t.status,data:null,message:t.message});throw t}})}const Ft=p.strictObject({}),It=p.strictObject({colorMode:p.enum(O)});function Lt(e,t){e.get(`/api/settings`,c(`query`,Ft),e=>e.json({status:D.success,data:t.getApplicationSettings()})),e.patch(`/api/settings`,c(`json`,It),e=>e.json({status:D.success,data:t.updateApplicationSettings(e.req.valid(`json`))}))}const Rt=p.strictObject({});function zt(){return[d.resolve(import.meta.dirname,`app`),d.resolve(import.meta.dirname,`../../dist/app`)].find(e=>u(e))}function Bt(e){let t=new f;t.get(`/api/health`,c(`query`,Rt),e=>e.json({status:D.success,data:!0,message:`Service is healthy.`})),Re(t,new Ue(e.providerStore,e.settingsStore)),Dt(t,new Tt(e.providerStore,e.settingsStore)),Lt(t,e.settingsStore),Ot(t,e.providerStore,e.providerConnectionTester),Pt(t,e.runtimeService);let n=e.webRoot??zt();return n&&t.use(`*`,s({root:n})),t}const V=`__drizzle_migrations`;function Vt(e){return!!e.prepare(`
3
3
  SELECT 1
4
4
  FROM sqlite_master
5
5
  WHERE type = 'table' AND name = ?
@@ -23,4 +23,4 @@ import{t as e}from"./package-sD3q513f.mjs";import{defineCommand as t,renderUsage
23
23
  `),i=JSON.stringify(t,null,gn(e.content));return n===`\r
24
24
  `&&(i=i.replaceAll(`
25
25
  `,`\r
26
- `)),r?`${i}${n}`:i}function vn(e,t){return d.join(d.dirname(e),`.${d.basename(e)}.foundry-${t}-${ne()}.tmp`)}async function Z(e,t,n,r){let i=vn(e,r);try{await ve(i,t,{encoding:`utf8`,flag:`wx`,mode:n}),await de(i,n),await ge(i,e)}catch(e){try{await v(i,{force:!0})}catch{}throw e}}async function yn(e,t,n,r){if(n.source.hash!==r)throw new B(`RUNTIME_CONFIGURATION_CHANGED`,`The Runtime configuration changed after Preview. Refresh and review it again.`);let{source:i}=n,a=d.dirname(t),o=`${t}.foundry-backup`;if(!(!i.exists||n.content!==i.content))return{rollback:async()=>{}};pn(e,n.content);try{await _(a,{mode:448,recursive:!0}),i.exists&&i.content!==null?await Z(o,i.content,384,`backup`):await v(o,{force:!0}),await Z(t,n.content,i.mode,`write`)}catch(e){throw e instanceof B?e:new B(`RUNTIME_APPLY_FAILED`,`The Runtime configuration could not be safely updated.`)}return{rollback:async()=>{try{i.exists&&i.content!==null?await Z(t,i.content,i.mode,`rollback`):await v(t,{force:!0})}catch{throw new B(`RUNTIME_APPLY_FAILED`,`The previous Runtime configuration could not be restored.`)}}}}const bn=[`ANTHROPIC_DEFAULT_OPUS_MODEL`,`ANTHROPIC_DEFAULT_SONNET_MODEL`,`ANTHROPIC_DEFAULT_HAIKU_MODEL`,`ANTHROPIC_DEFAULT_FABLE_MODEL`],xn=[``,`_NAME`,`_DESCRIPTION`,`_SUPPORTED_CAPABILITIES`],Sn=bn.flatMap(e=>xn.map(t=>`${e}${t}`)),Cn=[`CLAUDE_CODE_SUBAGENT_MODEL`,`CLAUDE_CODE_SUBAGENT_MODEL_FORCE`],wn=[`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`,`ENABLE_TOOL_SEARCH`,`CLAUDE_CODE_EFFORT_LEVEL`,`DISABLE_AUTOUPDATER`],Tn=[`commit`,`pr`,`sessionUrl`],En=[`ANTHROPIC_BASE_URL`,`ANTHROPIC_AUTH_TOKEN`,`ANTHROPIC_API_KEY`,`ANTHROPIC_MODEL`,...Sn,...Cn,...wn];function Dn(e){return e===null?[void 0,void 0,void 0,void 0]:[e.model,e.displayName??void 0,e.description??void 0,e.supportedCapabilities.length>0?e.supportedCapabilities.join(`,`):void 0]}function On(e){let t=Object.fromEntries(En.map(e=>[e,void 0]));if(e===null)return t;t.ANTHROPIC_BASE_URL=e.baseUrl,t.ANTHROPIC_AUTH_TOKEN=e.apiKeyHeader===`authorization`?e.apiKey:void 0,t.ANTHROPIC_API_KEY=e.apiKeyHeader===`x-api-key`?e.apiKey:void 0,t.ANTHROPIC_MODEL=e.defaultModel;let n=[e.opusModel,e.sonnetModel,e.haikuModel,e.fableModel];for(let[e,r]of bn.entries()){let i=Dn(n[e]);for(let[e,n]of xn.entries())t[`${r}${n}`]=i[e]}return t.CLAUDE_CODE_SUBAGENT_MODEL=e.subagentModel??void 0,t.CLAUDE_CODE_SUBAGENT_MODEL_FORCE=e.subagentModelForce?`1`:void 0,t.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=e.teammatesMode?`1`:void 0,t.ENABLE_TOOL_SEARCH=e.enableToolSearch?`true`:void 0,t.CLAUDE_CODE_EFFORT_LEVEL=e.maxEffortThinking?`max`:void 0,t.DISABLE_AUTOUPDATER=e.disableAutoUpdater?`1`:void 0,t}function kn(e){let t=e?.hideAiAttribution===!0;return{commit:t?``:void 0,pr:t?``:void 0,sessionUrl:!t&&void 0}}function An(e,t,n,r){let i=e.values.env;if(i!==void 0&&!K(i))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Claude Code env must be an object.`);let a=i??{},o=On(r?.configuration??null),s=e.values.attribution;if(s!==void 0&&!K(s))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Claude Code attribution must be an object.`);let c=s??{},l=kn(r?.configuration??null),u=[...En.map(e=>q(`env.${e}`,a[e],o[e],e===`ANTHROPIC_AUTH_TOKEN`||e===`ANTHROPIC_API_KEY`)),...Tn.map(e=>q(`attribution.${e}`,c[e],l[e]))],d=Y(e.values),f=K(d.env)?d.env:{};d.env=f;for(let e of En)X(f,e,o[e]);Object.keys(f).length===0&&delete d.env;let p=K(d.attribution)?d.attribution:{};d.attribution=p;for(let e of Tn){let t=l[e];t===void 0?delete p[e]:p[e]=t}Object.keys(p).length===0&&delete d.attribution;let m=J(u);return{content:_n(e,d),preview:{...m,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:null,runtime:`claude-code`,target:n},source:e}}const Q=[`model`,`review_model`,`model_provider`],jn=[`name`,`base_url`,`wire_api`,`experimental_bearer_token`];function Mn(e){let t=e.model_providers;if(t===void 0)return{};if(!K(t))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Codex model_providers must be a table.`);return t}function Nn(e){return Object.entries(Mn(e)).filter(e=>K(e[1])).map(([e])=>e)}function Pn(e,t){let n=Nn(e);if(n.length===0){if(t!==void 0&&t!==`foundry`)throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:`foundry`,keys:n}}if(n.length===1){if(t!==void 0&&t!==n[0])throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:n[0],keys:n}}if(t===void 0)return{key:null,keys:n};if(!n.includes(t))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:t,keys:n}}function Fn(e,t){let n=Mn(e)[t];if(n===void 0)return{};if(!K(n))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Codex model_providers.${t} must be a table.`);return n}function In(e){let t=K(e.model_providers)?e.model_providers:{};if(typeof e.model_provider==`string`){let n=t[e.model_provider];return{key:e.model_provider,table:K(n)?n:{}}}let n=Object.entries(t).filter(e=>K(e[1]));return n.length===1?{key:n[0][0],table:n[0][1]}:{key:`<key>`,table:{}}}function Ln(e,t,n,r,i){if(n.kind===`official-default`){let r=In(e.values),i=[...Q.map(t=>q(t,e.values[t],void 0)),...jn.map(e=>q(`[model_providers.${r.key}].${e}`,r.table[e],r.table[e],e===`experimental_bearer_token`))],a=Y(e.values);for(let e of Q)delete a[e];let o=J(i);return{content:hn(e,a),preview:{...o,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:null,runtime:`codex`,target:n},source:e}}if(r===null)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);let a=Pn(e.values,i);if(a.key===null)return{file:{exists:e.exists,hash:e.hash,path:t},kind:`provider-key-selection`,providerKeys:a.keys,runtime:`codex`,target:n};let o=a.key,s=Fn(e.values,o),c={model:r.configuration.defaultModel,model_provider:o,review_model:r.configuration.reviewModel??void 0},l={base_url:r.configuration.baseUrl,experimental_bearer_token:r.configuration.apiKey??void 0,name:r.name,wire_api:`responses`},u=[...Q.map(t=>q(t,e.values[t],c[t])),...jn.map(e=>q(`[model_providers.${o}].${e}`,s[e],l[e],e===`experimental_bearer_token`))],d=Y(e.values);for(let e of Q)X(d,e,c[e]);let f=K(d.model_providers)?d.model_providers:{};d.model_providers=f;let p=K(f[o])?f[o]:{};f[o]=p;for(let e of jn)X(p,e,l[e]);let m=J(u);return{content:hn(e,d),preview:{...m,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:o,runtime:`codex`,target:n},source:e}}function Rn(e,t,n){if(t.kind===`official-default`)return null;if(n?.id!==t.providerId||n.runtime!==e)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);return n}async function zn(e,t,n,r,i){let a=await mn(e,t),o=Rn(e,n,r);return e===`codex`?Ln(a,t,n,o,i):An(a,t,n,o)}function Bn(e){return`preview`in e}var Vn=class{async preview(e,t,n,r,i){let a=await zn(e,t,n,r,i);return Bn(a)?a.preview:a}async apply(e,t,n,r,i,a){let o=await zn(e,t,n,r,a);if(!Bn(o))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Select a Codex Provider key before applying changes.`);return yn(e,t,o,i)}};const Hn=oe(ke),Un={"claude-code":{command:`claude`,configurationPath:d.join(`.claude`,`settings.json`)},codex:{command:`codex`,configurationPath:d.join(`.codex`,`config.toml`)}};async function Wn(e){try{return await _e(e),!0}catch(e){return!!(e&&typeof e==`object`&&`code`in e&&e.code!==`ENOENT`)}}async function Gn(e,t){let n=i.platform===`win32`?(i.env.PATHEXT??`.EXE;.CMD;.BAT;.COM`).split(`;`):[``];for(let r of t.split(d.delimiter))if(r)for(let t of n){let n=d.join(r,`${e}${t}`);try{return await ue(n,i.platform===`win32`?l.F_OK:l.X_OK),await he(n)}catch{}}return null}var Kn=class{homeDirectory;environmentPath;runVersion;constructor(e=xe(),t=i.env.PATH??``,n=async e=>{let t=await Hn(e,[`--version`],{timeout:3e3,windowsHide:!0});return(t.stdout||t.stderr).trim()}){this.homeDirectory=e,this.environmentPath=t,this.runVersion=n}async detect(e){let t=Un[e],n=d.join(this.homeDirectory,t.configurationPath),r=await Wn(n),i=await Gn(t.command,this.environmentPath);if(!i)return{configurationExists:r,configurationPath:n,executablePath:null,message:`${t.command} was not found in PATH.`,status:`not-detected`,version:null};try{return{configurationExists:r,configurationPath:n,executablePath:i,message:null,status:`detected`,version:await this.runVersion(i)}}catch{return{configurationExists:r,configurationPath:n,executablePath:i,message:`${t.command} --version could not be completed.`,status:`failed`,version:null}}}},qn=class{runtimeStore;providerStore;detector;configurationManager;inFlightRuntimes=new Set;constructor(e,t,n,r){this.runtimeStore=e,this.providerStore=t,this.detector=n,this.configurationManager=r}resolveProvider(e,t){if(t.kind===`official-default`)return null;let n=this.providerStore.getProvider(t.providerId);if(n?.runtime!==e)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);return n}async requireDetection(e){let t=await this.detector.detect(e);if(t.status!==`detected`)throw new B(`RUNTIME_NOT_DETECTED`,t.message??`The Runtime could not be detected.`);return t}async listRuntimes(){let e=new Map(this.runtimeStore.listAssignments().map(e=>[e.runtime,e])),t=await Promise.all(k.map(e=>this.detector.detect(e)));return k.map((n,r)=>{let i=e.get(n);if(!i)throw Error(`Runtime assignment ${n} is missing.`);return{...i,detection:t[r]}})}async previewConfiguration(e,t){let n=await this.requireDetection(e),r=this.resolveProvider(e,t.target);return this.configurationManager.preview(e,n.configurationPath,t.target,r,t.providerKey)}async applyConfiguration(e,t){if(this.inFlightRuntimes.has(e))throw new B(`RUNTIME_APPLY_FAILED`,`A configuration update is already running for this Runtime.`);this.inFlightRuntimes.add(e);try{let n=await this.requireDetection(e),r=this.resolveProvider(e,t.target),i=await this.configurationManager.apply(e,n.configurationPath,t.target,r,t.expectedFileHash,t.providerKey);try{return{...this.runtimeStore.recordAssignment(e,t.target),detection:{...n,configurationExists:!0}}}catch(e){throw await i.rollback(),e}}finally{this.inFlightRuntimes.delete(e)}}},Jn=class{database;now;constructor(e,t=Date.now){this.database=e,this.now=t}listAssignments(){let e=new Map(this.database.select().from(W).all().map(e=>[e.runtime,{appliedAt:e.appliedAt,managed:e.managed,providerId:e.providerId,runtime:e.runtime}]));return k.map(t=>{let n=e.get(t);if(!n)throw Error(`Runtime assignment ${t} is missing.`);return n})}recordAssignment(e,t){return this.database.transaction(()=>{let n=t.kind===`provider`?t.providerId:null;if(n!==null&&!this.database.select({runtime:U.runtime}).from(U).where(y(b(U.id,n),b(U.runtime,e),x(U.deletedAt))).get())throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);let r=this.now();if(this.database.update(W).set({appliedAt:r,managed:!0,providerId:n}).where(b(W.runtime,e)).run().changes!==1)throw Error(`Runtime assignment ${e} could not be saved.`);return{appliedAt:r,managed:!0,providerId:n,runtime:e}})}};const Yn=`color_mode`,Xn=p.enum(O);var Zn=class{database;now;constructor(e,t=Date.now){this.database=e,this.now=t}getApplicationSettings(){let e=this.database.select({deletedAt:H.deletedAt,key:H.key,value:H.value}).from(H).all();if(e.length!==1)throw Error(`Stored Application Settings are invalid.`);let[t]=e;if(t.key!==Yn||t.deletedAt!==null)throw Error(`Stored Application Settings are invalid.`);return{colorMode:Xn.parse(t.value)}}updateApplicationSettings(e){if(this.database.update(H).set({updatedAt:this.now(),value:e.colorMode}).where(b(H.key,Yn)).run().changes!==1)throw Error(`Stored Application Settings are invalid.`);return this.getApplicationSettings()}};const $=`127.0.0.1`;function Qn(e){return new Promise((t,n)=>{e.close(e=>{if(e){n(e);return}t()})})}async function $n(e={}){let t=e.port??54321,n=await Qt({databasePath:e.databasePath,migrationsFolder:e.migrationsFolder}),r=new en(n.db),i=Bt({providerConnectionTester:new ln,providerStore:r,runtimeService:new qn(new Jn(n.db),r,new Kn,new Vn),settingsStore:new Zn(n.db)});return new Promise((e,r)=>{let a=e=>{n.client.close(),r(e)},s=o({fetch:i.fetch,hostname:$,port:t},t=>{s.off(`error`,a);let r,i=t.port,o=async()=>{try{await Qn(s)}finally{n.client.close()}};e({close:()=>(r??=o(),r),hostname:$,port:i,url:`http://${$}:${i}`})});s.once(`error`,a)})}function er(e,t){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`?`Port ${t} is already in use on 127.0.0.1.`:`Could not start Foundry Server: ${e instanceof Error?e.message:String(e)}`}function tr(e,t=i,n=console.error){let r=!1,a=()=>{r||(r=!0,t.off(`SIGINT`,a),t.off(`SIGTERM`,a),e.close().catch(e=>{n(`Could not stop Foundry Server: ${e instanceof Error?e.message:String(e)}`),t.exitCode=1}))};return t.once(`SIGINT`,a),t.once(`SIGTERM`,a),()=>{t.off(`SIGINT`,a),t.off(`SIGTERM`,a)}}const nr={error:console.error,log:console.info,openBrowser:a,registerShutdown:e=>{tr(e)},setExitCode:e=>{i.exitCode=e},startServer:$n};function rr(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n===`--port`){if(t+1>=e.length||e[t+1].startsWith(`--`))return`Missing value for option: --port`;t+=1;continue}if(!n.startsWith(`--port=`)&&n!==`--open`&&n!==`--no-open`)return`${n.startsWith(`-`)?`Unknown option`:`Unexpected argument`}: ${n}`}}function ir(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1||t>65535)throw RangeError(`Port must be an integer between 1 and 65535. Received "${e}".`);return t}function ar(e=nr){return t({meta:{description:`Start the Local Web UI`,name:`ui`},args:{port:{default:`54321`,description:`Port for the Local Web UI`,type:`string`,valueHint:`port`},open:{default:!0,description:`Open the Local Web UI in the default browser`,negativeDescription:`Do not open the default browser`,type:`boolean`}},async run({args:t,rawArgs:n}){let r=rr(n);if(r){e.error(`${r}\nRun \`foundry ui --help\` for usage.`),e.setExitCode(1);return}let i;try{i=ir(t.port)}catch(t){e.error(`${t instanceof Error?t.message:String(t)}\nRun \`foundry ui --help\` for usage.`),e.setExitCode(1);return}let a;try{a=await e.startServer({port:i})}catch(t){e.error(er(t,i)),e.setExitCode(1);return}if(e.registerShutdown(a),e.log(`Foundry Local Web UI: ${a.url}`),t.open)try{await e.openBrowser(a.url)}catch{e.error(`Could not open the default browser. Open ${a.url} manually.`)}}})}const or=t({meta:{description:`An AI-native local developer runtime`,name:`foundry`,version:e},subCommands:{ui:ar()}});function sr(e){if(!e.some(e=>e===`--help`||e===`-h`)&&(e.length!==1||e[0]!==`--version`&&e[0]!==`-v`)&&!(e[0]===`ui`||!e[0]?.startsWith(`-`)))return`Unknown option: ${e[0]}`}async function cr(e=i.argv.slice(2)){if(e.length===0){console.info(`${await n(or)}\n`);return}let t=sr(e);if(t){console.error(`${t}\nRun \`foundry --help\` for usage.`),i.exitCode=1;return}await r(or,{rawArgs:e})}cr();export{};
26
+ `)),r?`${i}${n}`:i}function vn(e,t){return d.join(d.dirname(e),`.${d.basename(e)}.foundry-${t}-${ne()}.tmp`)}async function Z(e,t,n,r){let i=vn(e,r);try{await ve(i,t,{encoding:`utf8`,flag:`wx`,mode:n}),await de(i,n),await ge(i,e)}catch(e){try{await v(i,{force:!0})}catch{}throw e}}async function yn(e,t,n,r){if(n.source.hash!==r)throw new B(`RUNTIME_CONFIGURATION_CHANGED`,`The Runtime configuration changed after Preview. Refresh and review it again.`);let{source:i}=n,a=d.dirname(t),o=`${t}.foundry-backup`;if(!(!i.exists||n.content!==i.content))return{rollback:async()=>{}};pn(e,n.content);try{await _(a,{mode:448,recursive:!0}),i.exists&&i.content!==null?await Z(o,i.content,384,`backup`):await v(o,{force:!0}),await Z(t,n.content,i.mode,`write`)}catch(e){throw e instanceof B?e:new B(`RUNTIME_APPLY_FAILED`,`The Runtime configuration could not be safely updated.`)}return{rollback:async()=>{try{i.exists&&i.content!==null?await Z(t,i.content,i.mode,`rollback`):await v(t,{force:!0})}catch{throw new B(`RUNTIME_APPLY_FAILED`,`The previous Runtime configuration could not be restored.`)}}}}const bn=[`ANTHROPIC_DEFAULT_OPUS_MODEL`,`ANTHROPIC_DEFAULT_SONNET_MODEL`,`ANTHROPIC_DEFAULT_HAIKU_MODEL`,`ANTHROPIC_DEFAULT_FABLE_MODEL`],xn=[``,`_NAME`,`_DESCRIPTION`,`_SUPPORTED_CAPABILITIES`],Sn=bn.flatMap(e=>xn.map(t=>`${e}${t}`)),Cn=[`CLAUDE_CODE_SUBAGENT_MODEL`,`CLAUDE_CODE_SUBAGENT_MODEL_FORCE`],wn=[`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`,`ENABLE_TOOL_SEARCH`,`CLAUDE_CODE_EFFORT_LEVEL`,`DISABLE_AUTOUPDATER`],Tn=[`commit`,`pr`,`sessionUrl`],En=[`ANTHROPIC_BASE_URL`,`ANTHROPIC_AUTH_TOKEN`,`ANTHROPIC_API_KEY`,`ANTHROPIC_MODEL`,...Sn,...Cn,...wn];function Dn(e){return e===null?[void 0,void 0,void 0,void 0]:[e.model,e.displayName??void 0,e.description??void 0,e.supportedCapabilities.length>0?e.supportedCapabilities.join(`,`):void 0]}function On(e){let t=Object.fromEntries(En.map(e=>[e,void 0]));if(e===null)return t;t.ANTHROPIC_BASE_URL=e.baseUrl,t.ANTHROPIC_AUTH_TOKEN=e.apiKeyHeader===`authorization`?e.apiKey:void 0,t.ANTHROPIC_API_KEY=e.apiKeyHeader===`x-api-key`?e.apiKey:void 0,t.ANTHROPIC_MODEL=e.defaultModel;let n=[e.opusModel,e.sonnetModel,e.haikuModel,e.fableModel];for(let[e,r]of bn.entries()){let i=Dn(n[e]);for(let[e,n]of xn.entries())t[`${r}${n}`]=i[e]}return t.CLAUDE_CODE_SUBAGENT_MODEL=e.subagentModel??void 0,t.CLAUDE_CODE_SUBAGENT_MODEL_FORCE=e.subagentModelForce?`1`:void 0,t.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=e.teammatesMode?`1`:void 0,t.ENABLE_TOOL_SEARCH=e.enableToolSearch?`true`:void 0,t.CLAUDE_CODE_EFFORT_LEVEL=e.maxEffortThinking?`max`:void 0,t.DISABLE_AUTOUPDATER=e.disableAutoUpdater?`1`:void 0,t}function kn(e){let t=e?.hideAiAttribution===!0;return{commit:t?``:void 0,pr:t?``:void 0,sessionUrl:!t&&void 0}}function An(e,t,n,r){let i=e.values.env;if(i!==void 0&&!K(i))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Claude Code env must be an object.`);let a=i??{},o=On(r?.configuration??null),s=e.values.attribution;if(s!==void 0&&!K(s))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Claude Code attribution must be an object.`);let c=s??{},l=kn(r?.configuration??null),u=[...En.map(e=>q(`env.${e}`,a[e],o[e],e===`ANTHROPIC_AUTH_TOKEN`||e===`ANTHROPIC_API_KEY`)),...Tn.map(e=>q(`attribution.${e}`,c[e],l[e]))],d=Y(e.values),f=K(d.env)?d.env:{};d.env=f;for(let e of En)X(f,e,o[e]);Object.keys(f).length===0&&delete d.env;let p=K(d.attribution)?d.attribution:{};d.attribution=p;for(let e of Tn){let t=l[e];t===void 0?delete p[e]:p[e]=t}Object.keys(p).length===0&&delete d.attribution;let m=J(u);return{content:_n(e,d),preview:{...m,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:null,runtime:`claude-code`,target:n},source:e}}const Q=[`model`,`review_model`,`model_provider`],jn=[`name`,`base_url`,`wire_api`,`experimental_bearer_token`];function Mn(e){let t=e.model_providers;if(t===void 0)return{};if(!K(t))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Codex model_providers must be a table.`);return t}function Nn(e){return Object.entries(Mn(e)).filter(e=>K(e[1])).map(([e])=>e)}function Pn(e,t){let n=Nn(e);if(n.length===0){if(t!==void 0&&t!==`foundry`)throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:`foundry`,keys:n}}if(n.length===1){if(t!==void 0&&t!==n[0])throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:n[0],keys:n}}if(t===void 0)return{key:null,keys:n};if(!n.includes(t))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`The selected Codex Provider key is unavailable.`);return{key:t,keys:n}}function Fn(e,t){let n=Mn(e)[t];if(n===void 0)return{};if(!K(n))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Codex model_providers.${t} must be a table.`);return n}function In(e){let t=K(e.model_providers)?e.model_providers:{};if(typeof e.model_provider==`string`){let n=t[e.model_provider];return{key:e.model_provider,table:K(n)?n:{}}}let n=Object.entries(t).filter(e=>K(e[1]));return n.length===1?{key:n[0][0],table:n[0][1]}:{key:`<key>`,table:{}}}function Ln(e,t,n,r,i){if(n.kind===`official-default`){let r=In(e.values),i=[...Q.map(t=>q(t,e.values[t],void 0)),...jn.map(e=>q(`[model_providers.${r.key}].${e}`,r.table[e],r.table[e],e===`experimental_bearer_token`))],a=Y(e.values);for(let e of Q)delete a[e];let o=J(i);return{content:hn(e,a),preview:{...o,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:null,runtime:`codex`,target:n},source:e}}if(r===null)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);let a=Pn(e.values,i);if(a.key===null)return{file:{exists:e.exists,hash:e.hash,path:t},kind:`provider-key-selection`,providerKeys:a.keys,runtime:`codex`,target:n};let o=a.key,s=Fn(e.values,o),c={model:r.configuration.defaultModel,model_provider:o,review_model:r.configuration.reviewModel??void 0},l={base_url:r.configuration.baseUrl,experimental_bearer_token:r.configuration.apiKey??void 0,name:r.name,wire_api:`responses`},u=[...Q.map(t=>q(t,e.values[t],c[t])),...jn.map(e=>q(`[model_providers.${o}].${e}`,s[e],l[e],e===`experimental_bearer_token`))],d=Y(e.values);for(let e of Q)X(d,e,c[e]);let f=K(d.model_providers)?d.model_providers:{};d.model_providers=f;let p=K(f[o])?f[o]:{};f[o]=p;for(let e of jn)X(p,e,l[e]);let m=J(u);return{content:hn(e,d),preview:{...m,file:{exists:e.exists,hash:e.hash,path:t},kind:`ready`,providerKey:o,runtime:`codex`,target:n},source:e}}function Rn(e,t,n){if(t.kind===`official-default`)return null;if(n?.id!==t.providerId||n.runtime!==e)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);return n}async function zn(e,t,n,r,i){let a=await mn(e,t),o=Rn(e,n,r);return e===`codex`?Ln(a,t,n,o,i):An(a,t,n,o)}function Bn(e){return`preview`in e}var Vn=class{async preview(e,t,n,r,i){let a=await zn(e,t,n,r,i);return Bn(a)?a.preview:a}async apply(e,t,n,r,i,a){let o=await zn(e,t,n,r,a);if(!Bn(o))throw new B(`RUNTIME_CONFIGURATION_INVALID`,`Select a Codex Provider key before applying changes.`);return yn(e,t,o,i)}};const Hn=oe(ke),Un={"claude-code":{command:`claude`,configurationDirectory:`.claude`,configurationDirectoryEnvironmentVariable:`CLAUDE_CONFIG_DIR`,configurationFilename:`settings.json`},codex:{command:`codex`,configurationDirectory:`.codex`,configurationDirectoryEnvironmentVariable:`CODEX_HOME`,configurationFilename:`config.toml`}};async function Wn(e){try{return await _e(e),!0}catch(e){return!!(e&&typeof e==`object`&&`code`in e&&e.code!==`ENOENT`)}}async function Gn(e,t){let n=i.platform===`win32`?(i.env.PATHEXT??`.EXE;.CMD;.BAT;.COM`).split(`;`):[``];for(let r of t.split(d.delimiter))if(r)for(let t of n){let n=d.join(r,`${e}${t}`);try{return await ue(n,i.platform===`win32`?l.F_OK:l.X_OK),await he(n)}catch{}}return null}var Kn=class{homeDirectory;environmentPath;runVersion;environment;constructor(e=xe(),t=i.env.PATH??``,n=async e=>{let t=await Hn(e,[`--version`],{timeout:3e3,windowsHide:!0});return(t.stdout||t.stderr).trim()},r=i.env){this.homeDirectory=e,this.environmentPath=t,this.runVersion=n,this.environment=r}async detect(e){let t=Un[e],n=this.environment[t.configurationDirectoryEnvironmentVariable]?.trim(),r=n?d.resolve(n):d.join(this.homeDirectory,t.configurationDirectory),i=d.join(r,t.configurationFilename),a=await Wn(i),o=await Gn(t.command,this.environmentPath);if(!o)return{configurationExists:a,configurationPath:i,executablePath:null,message:`${t.command} was not found in PATH.`,status:`not-detected`,version:null};try{return{configurationExists:a,configurationPath:i,executablePath:o,message:null,status:`detected`,version:await this.runVersion(o)}}catch{return{configurationExists:a,configurationPath:i,executablePath:o,message:`${t.command} --version could not be completed.`,status:`failed`,version:null}}}},qn=class{runtimeStore;providerStore;detector;configurationManager;inFlightRuntimes=new Set;constructor(e,t,n,r){this.runtimeStore=e,this.providerStore=t,this.detector=n,this.configurationManager=r}resolveProvider(e,t){if(t.kind===`official-default`)return null;let n=this.providerStore.getProvider(t.providerId);if(n?.runtime!==e)throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);return n}async requireDetection(e){let t=await this.detector.detect(e);if(t.status!==`detected`)throw new B(`RUNTIME_NOT_DETECTED`,t.message??`The Runtime could not be detected.`);return t}async listRuntimes(){let e=new Map(this.runtimeStore.listAssignments().map(e=>[e.runtime,e])),t=await Promise.all(k.map(e=>this.detector.detect(e)));return k.map((n,r)=>{let i=e.get(n);if(!i)throw Error(`Runtime assignment ${n} is missing.`);return{...i,detection:t[r]}})}async previewConfiguration(e,t){let n=await this.requireDetection(e),r=this.resolveProvider(e,t.target);return this.configurationManager.preview(e,n.configurationPath,t.target,r,t.providerKey)}async applyConfiguration(e,t){if(this.inFlightRuntimes.has(e))throw new B(`RUNTIME_APPLY_FAILED`,`A configuration update is already running for this Runtime.`);this.inFlightRuntimes.add(e);try{let n=await this.requireDetection(e),r=this.resolveProvider(e,t.target),i=await this.configurationManager.apply(e,n.configurationPath,t.target,r,t.expectedFileHash,t.providerKey);try{return{...this.runtimeStore.recordAssignment(e,t.target),detection:{...n,configurationExists:!0}}}catch(e){throw await i.rollback(),e}}finally{this.inFlightRuntimes.delete(e)}}},Jn=class{database;now;constructor(e,t=Date.now){this.database=e,this.now=t}listAssignments(){let e=new Map(this.database.select().from(W).all().map(e=>[e.runtime,{appliedAt:e.appliedAt,managed:e.managed,providerId:e.providerId,runtime:e.runtime}]));return k.map(t=>{let n=e.get(t);if(!n)throw Error(`Runtime assignment ${t} is missing.`);return n})}recordAssignment(e,t){return this.database.transaction(()=>{let n=t.kind===`provider`?t.providerId:null;if(n!==null&&!this.database.select({runtime:U.runtime}).from(U).where(y(b(U.id,n),b(U.runtime,e),x(U.deletedAt))).get())throw new B(`PROVIDER_NOT_FOUND`,`The selected Provider is unavailable.`);let r=this.now();if(this.database.update(W).set({appliedAt:r,managed:!0,providerId:n}).where(b(W.runtime,e)).run().changes!==1)throw Error(`Runtime assignment ${e} could not be saved.`);return{appliedAt:r,managed:!0,providerId:n,runtime:e}})}};const Yn=`color_mode`,Xn=p.enum(O);var Zn=class{database;now;constructor(e,t=Date.now){this.database=e,this.now=t}getApplicationSettings(){let e=this.database.select({deletedAt:H.deletedAt,key:H.key,value:H.value}).from(H).all();if(e.length!==1)throw Error(`Stored Application Settings are invalid.`);let[t]=e;if(t.key!==Yn||t.deletedAt!==null)throw Error(`Stored Application Settings are invalid.`);return{colorMode:Xn.parse(t.value)}}updateApplicationSettings(e){if(this.database.update(H).set({updatedAt:this.now(),value:e.colorMode}).where(b(H.key,Yn)).run().changes!==1)throw Error(`Stored Application Settings are invalid.`);return this.getApplicationSettings()}};const $=`127.0.0.1`;function Qn(e){return new Promise((t,n)=>{e.close(e=>{if(e){n(e);return}t()})})}async function $n(e={}){let t=e.port??54321,n=await Qt({databasePath:e.databasePath,migrationsFolder:e.migrationsFolder}),r=new en(n.db),i=Bt({providerConnectionTester:new ln,providerStore:r,runtimeService:new qn(new Jn(n.db),r,new Kn,new Vn),settingsStore:new Zn(n.db)});return new Promise((e,r)=>{let a=e=>{n.client.close(),r(e)},s=o({fetch:i.fetch,hostname:$,port:t},t=>{s.off(`error`,a);let r,i=t.port,o=async()=>{try{await Qn(s)}finally{n.client.close()}};e({close:()=>(r??=o(),r),hostname:$,port:i,url:`http://${$}:${i}`})});s.once(`error`,a)})}function er(e,t){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`?`Port ${t} is already in use on 127.0.0.1.`:`Could not start Foundry Server: ${e instanceof Error?e.message:String(e)}`}function tr(e,t=i,n=console.error){let r=!1,a=()=>{r||(r=!0,t.off(`SIGINT`,a),t.off(`SIGTERM`,a),e.close().catch(e=>{n(`Could not stop Foundry Server: ${e instanceof Error?e.message:String(e)}`),t.exitCode=1}))};return t.once(`SIGINT`,a),t.once(`SIGTERM`,a),()=>{t.off(`SIGINT`,a),t.off(`SIGTERM`,a)}}const nr={error:console.error,log:console.info,openBrowser:a,registerShutdown:e=>{tr(e)},setExitCode:e=>{i.exitCode=e},startServer:$n};function rr(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n===`--port`){if(t+1>=e.length||e[t+1].startsWith(`--`))return`Missing value for option: --port`;t+=1;continue}if(!n.startsWith(`--port=`)&&n!==`--open`&&n!==`--no-open`)return`${n.startsWith(`-`)?`Unknown option`:`Unexpected argument`}: ${n}`}}function ir(e){let t=Number(e);if(!Number.isSafeInteger(t)||t<1||t>65535)throw RangeError(`Port must be an integer between 1 and 65535. Received "${e}".`);return t}function ar(e=nr){return t({meta:{description:`Start the Local Web UI`,name:`ui`},args:{port:{default:`54321`,description:`Port for the Local Web UI`,type:`string`,valueHint:`port`},open:{default:!0,description:`Open the Local Web UI in the default browser`,negativeDescription:`Do not open the default browser`,type:`boolean`}},async run({args:t,rawArgs:n}){let r=rr(n);if(r){e.error(`${r}\nRun \`foundry ui --help\` for usage.`),e.setExitCode(1);return}let i;try{i=ir(t.port)}catch(t){e.error(`${t instanceof Error?t.message:String(t)}\nRun \`foundry ui --help\` for usage.`),e.setExitCode(1);return}let a;try{a=await e.startServer({port:i})}catch(t){e.error(er(t,i)),e.setExitCode(1);return}if(e.registerShutdown(a),e.log(`Foundry Local Web UI: ${a.url}`),t.open)try{await e.openBrowser(a.url)}catch{e.error(`Could not open the default browser. Open ${a.url} manually.`)}}})}const or=t({meta:{description:`An AI-native local developer runtime`,name:`foundry`,version:e},subCommands:{ui:ar()}});function sr(e){if(!e.some(e=>e===`--help`||e===`-h`)&&(e.length!==1||e[0]!==`--version`&&e[0]!==`-v`)&&!(e[0]===`ui`||!e[0]?.startsWith(`-`)))return`Unknown option: ${e[0]}`}async function cr(e=i.argv.slice(2)){if(e.length===0){console.info(`${await n(or)}\n`);return}let t=sr(e);if(t){console.error(`${t}\nRun \`foundry --help\` for usage.`),i.exitCode=1;return}await r(or,{rawArgs:e})}cr();export{};
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
1
 
2
- import{t as e}from"./package-sD3q513f.mjs";function t(){return e}export{t as getVersion};
2
+ import{t as e}from"./package-BRv6jbgV.mjs";function t(){return e}export{t as getVersion};
@@ -0,0 +1,2 @@
1
+
2
+ var e=`1.4.0`;export{e as t};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dhzh/foundry",
3
3
  "type": "module",
4
- "version": "1.3.2",
4
+ "version": "1.4.0",
5
5
  "devEngines": {
6
6
  "packageManager": {
7
7
  "name": "pnpm",
@@ -1,2 +0,0 @@
1
-
2
- var e=`1.3.2`;export{e as t};