@desplega.ai/agent-fs 0.5.2 → 0.5.4
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/dist/cli.js +1 -1
- package/package.json +7 -7
package/dist/cli.js
CHANGED
|
@@ -165,7 +165,7 @@ ${dt.toHex(r)}`}getCanonicalPath({path:t}){if(this.uriEscapePath){let e=[];for(l
|
|
|
165
165
|
FROM chunk_vectors
|
|
166
166
|
WHERE embedding MATCH ?
|
|
167
167
|
ORDER BY distance
|
|
168
|
-
LIMIT ?`).all(r,n),l=[],y=new Set;for(let s of E){let T=t.db.select().from(f.contentChunks).where(eo(f.contentChunks.id,s.chunk_id)).get();if(!T||T.driveId!==t.driveId)continue;if(y.has(T.filePath))continue;y.add(T.filePath);let R=t.db.select().from(f.files).where(ud(eo(f.files.path,T.filePath),eo(f.files.driveId,t.driveId))).get();l.push({path:T.filePath,snippet:T.content.slice(0,200),author:R?.author,modifiedAt:R?.modifiedAt})}return l}function Ed(t,e,n){let o=e.split(/\s+/).filter(Boolean).map((i)=>`"${i}"`).join(" OR ");if(!o)return[];try{return $e(t.db,{pattern:o,driveId:t.driveId}).slice(0,n).map((r)=>({path:r.path,snippet:r.snippet}))}catch{return[]}}var Df=g(()=>{a()});import{eq as Pe,and as ld,or as yd,isNull as sd}from"drizzle-orm";async function vf(t,e){let n=[Pe(f.files.driveId,t.driveId),Pe(f.files.isDeleted,!1),yd(Pe(f.files.embeddingStatus,"failed"),sd(f.files.embeddingStatus),Pe(f.files.embeddingStatus,"pending"))];if(e.path){let{like:l}=await import("drizzle-orm"),y=e.path.endsWith("/")?e.path:e.path+"/";n.push(l(f.files.path,y+"%"))}let o=t.db.select({path:f.files.path}).from(f.files).where(ld(...n)).all(),i=0,r=0,u=0,E=3;for(let l=0;l<o.length;l+=E){let y=o.slice(l,l+E),s=await Promise.allSettled(y.map(async(T)=>{let R=I(t.orgId,t.driveId,T.path),v=await t.s3.getObject(R),O=new TextDecoder().decode(v.body);if(J(t.db,{path:T.path,driveId:t.driveId,content:O}),t.embeddingProvider)return await jn(t.db,t.embeddingProvider,{path:T.path,driveId:t.driveId,content:O}),"reindexed";return"skipped"}));for(let T of s)if(T.status==="fulfilled")if(T.value==="reindexed")i++;else u++;else console.error("Reindex failed:",T.reason),r++}return{reindexed:i,failed:r,skipped:u}}var Lf=g(()=>{a();X();Vt()});import{eq as Of,and as gd,like as dd}from"drizzle-orm";async function Sf(t,e){let n=Rt(e.path??"/"),o=I(t.orgId,t.driveId,n),{objects:i}=await t.s3.listObjects(o),r=t.db.select().from(f.files).where(gd(Of(f.files.driveId,t.driveId),dd(f.files.path,n+"%"),Of(f.files.isDeleted,!1))).all(),u=new Map(r.map((l)=>[l.path,l])),E=[];for(let l of i){let y=l.key.slice(o.length);if(!y)continue;let s=y.split("/").filter(Boolean);if(s.length===0)continue;if(e.depth!==void 0&&s.length>e.depth)continue;let T=E;for(let R=0;R<s.length;R++){let v=s[R],O=R===s.length-1,C=!O||y.endsWith("/");if(C&&!O){let M=T.find((H)=>H.name===v&&H.type==="directory");if(!M)M={name:v,type:"directory",children:[]},T.push(M);if(!M.children)M.children=[];T=M.children}else if(C&&O){let M=T.find((H)=>H.name===v&&H.type==="directory");if(!M)M={name:v,type:"directory",children:[]},T.push(M)}else{let M=n+s.slice(0,R+1).join("/"),H=u.get(M),on={name:v,type:"file",size:H?.size??l.size};if(H?.author)on.author=H.author;if(H?.modifiedAt??l.lastModified)on.modifiedAt=H?.modifiedAt??l.lastModified;T.push(on)}}}return{tree:E}}var Uf=g(()=>{a();X()});import{eq as hf,and as Td,like as Rd}from"drizzle-orm";function Ad(t){let e="",n=0;while(n<t.length){let o=t[n];if(o==="*")if(t[n+1]==="*"){if(e+=".*",n+=2,t[n]==="/")n++}else e+="[^/]*",n++;else if(o==="?")e+="[^/]",n++;else if(".+^${}()|[]\\".includes(o))e+="\\"+o,n++;else e+=o,n++}return new RegExp("^"+e+"$")}async function mf(t,e){let n=e.path?Rt(e.path):"/",o=I(t.orgId,t.driveId,n),{objects:i}=await t.s3.listObjects(o),r=t.db.select().from(f.files).where(Td(hf(f.files.driveId,t.driveId),Rd(f.files.path,n+"%"),hf(f.files.isDeleted,!1))).all(),u=new Map(r.map((y)=>[y.path,y])),E=Ad(e.pattern),l=[];for(let y of i){let s=y.key.slice(o.length);if(!s||s.endsWith("/"))continue;if(E.test(s)){let T=n+s,R=u.get(T);l.push({path:T,size:R?.size??y.size,modifiedAt:R?.modifiedAt??y.lastModified})}}return{matches:l}}var af=g(()=>{a();X()});async function $f(t,e){let n=au(e.path),o=I(t.orgId,t.driveId,n),i=e.expiresIn??86400;try{await t.s3.headObject(o)}catch(E){if(E?.name==="NotFound"||E?.name==="NoSuchKey"||E?.$metadata?.httpStatusCode===404)throw new U(`File not found: ${n}`,{path:n});throw E}let r=lt(n);return{url:await t.s3.getPresignedUrl(o,i,r!=="application/octet-stream"?r:void 0),path:n,expiresIn:i,expiresAt:new Date(Date.now()+i*1000).toISOString()}}var Pf=g(()=>{X();V();Bt()});function no(t,e,n,o){let i=o.startsWith("/")?o.slice(1):o;return`${t}/file/~/${e}/${n}/${i}`}import{eq as S,and as yt,sql as oo,desc as Cf}from"drizzle-orm";function io(t,e){t.db.insert(f.events).values({id:crypto.randomUUID(),orgId:t.orgId,type:e.type,resourceType:e.resourceType,resourceId:e.resourceId,actor:t.userId,target:e.target??null,status:"created",metadata:e.metadata?JSON.stringify(e.metadata):null,createdAt:new Date}).run()}function Ce(t){return{id:t.id,parentId:t.parentId??void 0,path:t.path,lineStart:t.lineStart??void 0,lineEnd:t.lineEnd??void 0,quotedContent:t.quotedContent??void 0,body:t.body,author:t.author,resolved:t.resolved??!1,resolvedBy:t.resolvedBy??void 0,resolvedAt:t.resolvedAt??void 0,fileVersionId:t.fileVersionId??void 0,replyCount:t.replyCount??0,createdAt:t.createdAt,updatedAt:t.updatedAt}}async function Me(t,e){let n=new Date,o=crypto.randomUUID(),i=e.path;if(e.parentId){let u=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.parentId),S(f.comments.isDeleted,!1))).get();if(!u)throw new U("Parent comment not found",{suggestion:"Check that the parent comment ID is correct and not deleted"});if(u.parentId)throw new z("Cannot reply to a reply \u2014 only root comments accept replies",{suggestion:"Reply to the root comment instead"});if(!i)i=u.path}if(!i)throw new z("path is required for root comments",{field:"path"});let r=t.db.select({id:f.fileVersions.id}).from(f.fileVersions).where(yt(S(f.fileVersions.path,i),S(f.fileVersions.driveId,t.driveId))).orderBy(Cf(f.fileVersions.id)).limit(1).get();return t.db.insert(f.comments).values({id:o,parentId:e.parentId??null,orgId:t.orgId,driveId:t.driveId,path:i,lineStart:e.lineStart??null,lineEnd:e.lineEnd??null,quotedContent:e.quotedContent??null,fileVersionId:r?.id??null,body:e.body,author:t.userId,resolved:!1,createdAt:n,updatedAt:n,isDeleted:!1}).run(),io(t,{type:"comment_created",resourceType:"comment",resourceId:o,metadata:{path:i,parentId:e.parentId}}),{id:o,path:i,body:e.body,parentId:e.parentId,lineStart:e.lineStart,lineEnd:e.lineEnd,author:t.userId,createdAt:n}}async function ce(t,e){let n=[S(f.comments.driveId,t.driveId),S(f.comments.isDeleted,!1)];if(e.path)n.push(S(f.comments.path,e.path));if(e.parentId)n.push(S(f.comments.parentId,e.parentId));else if(e.parentId===void 0&&!e.resolved)n.push(oo`${f.comments.parentId} IS NULL`),n.push(S(f.comments.resolved,!1));else if(e.parentId===void 0&&e.resolved)n.push(oo`${f.comments.parentId} IS NULL`);if(e.orgId)n.push(S(f.comments.orgId,e.orgId));let o=e.limit??50,i=e.offset??0;return{comments:t.db.select().from(f.comments).where(yt(...n)).orderBy(Cf(f.comments.createdAt)).limit(o).offset(i).all().map((E)=>{let y=t.db.select().from(f.comments).where(yt(S(f.comments.parentId,E.id),S(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((s)=>Ce({...s,replyCount:0}));return{...Ce({...E,replyCount:y.length}),replies:y}})}}async function Xe(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});let o=t.db.select({count:oo`count(*)`}).from(f.comments).where(yt(S(f.comments.parentId,n.id),S(f.comments.isDeleted,!1))).get(),i=Ce({...n,replyCount:o?.count??0}),u=t.db.select().from(f.comments).where(yt(S(f.comments.parentId,e.id),S(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((E)=>Ce({...E,replyCount:0}));return{comment:i,replies:u}}async function Fe(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.author!==t.userId)throw new j("You can only edit your own comments",{suggestion:"Only the comment author can update it"});let o=new Date;return t.db.update(f.comments).set({body:e.body,updatedAt:o}).where(S(f.comments.id,e.id)).run(),{id:e.id,body:e.body,updatedAt:o}}async function He(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.author!==t.userId)throw new j("You can only delete your own comments",{suggestion:"Only the comment author can delete it"});let o=new Date;if(t.db.update(f.comments).set({isDeleted:!0,updatedAt:o}).where(S(f.comments.id,e.id)).run(),!n.parentId)t.db.update(f.comments).set({isDeleted:!0,updatedAt:o}).where(S(f.comments.parentId,e.id)).run();return io(t,{type:"comment_deleted",resourceType:"comment",resourceId:e.id}),{deleted:!0}}async function Ye(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.parentId)throw new z("Cannot resolve a reply \u2014 only root comments can be resolved",{suggestion:"Resolve the parent comment instead"});let o=new Date,i=e.resolved?o:null,r=e.resolved?t.userId:null;return t.db.update(f.comments).set({resolved:e.resolved,resolvedBy:r,resolvedAt:i,updatedAt:o}).where(S(f.comments.id,e.id)).run(),io(t,{type:e.resolved?"comment_resolved":"comment_reopened",resourceType:"comment",resourceId:e.id}),{id:e.id,resolved:e.resolved,resolvedBy:r??void 0,resolvedAt:i??void 0}}var Mf=g(()=>{a();V()});import{z as d}from"zod";async function wt(t,e,n,o){let i=ro[e];if(!i)throw Error(`Unknown operation: ${e}`);if(!o?.skipAuth){let E=ue(e);fe(t.db,{userId:t.userId,driveId:t.driveId,requiredRole:E})}let r=i.schema.parse(n),u=await i.handler(t,r);if(t.appUrl&&u&&typeof u==="object"){if("path"in u)u.appUrl=no(t.appUrl,t.orgId,t.driveId,u.path);else if("to"in u)u.appUrl=no(t.appUrl,t.orgId,t.driveId,u.to)}return u}function Kt(){return Object.keys(ro)}function Nt(t){return ro[t]}var ro;var uo=g(()=>{me();cu();Fu();Yu();Zu();Vu();Ku();ku();qu();tf();nf();uf();lf();sf();Tf();Af();Nf();If();Df();Lf();Uf();af();Pf();Mf();ro={write:{description:"Write or overwrite a file. Creates the file if it doesn't exist, or creates a new version. Use expectedVersion for optimistic concurrency. Returns { version, path, size }.",handler:Mu,schema:d.object({path:d.string(),content:d.string(),message:d.string().optional(),expectedVersion:d.number().int().optional()})},cat:{description:"Read file content with optional pagination via offset/limit. Returns { content, totalLines, truncated }.",handler:Xu,schema:d.object({path:d.string(),offset:d.number().int().min(0).optional(),limit:d.number().int().min(1).optional()})},edit:{description:"Replace a specific string in a file (surgical find-and-replace). Captures the edit intent as a diff summary in version history. Returns { version, path, changes }.",handler:Hu,schema:d.object({path:d.string(),old_string:d.string(),new_string:d.string(),message:d.string().optional()})},append:{description:"Append content to the end of an existing file. Creates a new version. Returns { version, size }.",handler:Gu,schema:d.object({path:d.string(),content:d.string(),message:d.string().optional()})},ls:{description:"List immediate children of a directory. Returns { entries } where each entry has name, type (file/directory), size, author, modifiedAt.",handler:Qu,schema:d.object({path:d.string().optional()})},stat:{description:"Get file metadata without reading content. Returns path, size, contentType, author, currentVersion, createdAt, modifiedAt, isDeleted, embeddingStatus.",handler:Wu,schema:d.object({path:d.string()})},rm:{description:"Delete a file. Removes from S3, cleans up FTS5 index and vector embeddings. Returns { path, deleted }.",handler:bu,schema:d.object({path:d.string()})},mv:{description:"Move or rename a file. Preserves version history at the new path. Returns { from, to, version }.",handler:zu,schema:d.object({from:d.string(),to:d.string(),message:d.string().optional()})},cp:{description:"Copy a file using server-side S3 copy. Creates a new version at the destination. Returns { from, to, version }.",handler:xu,schema:d.object({from:d.string(),to:d.string()})},tail:{description:"Read the last N lines of a file (default 20). Returns { content, totalLines, truncated }.",handler:ef,schema:d.object({path:d.string(),lines:d.number().int().min(1).optional()})},log:{description:"Show version history for a file. Returns { versions } with version number, author, timestamp, operation type, message, and diff summary.",handler:rf,schema:d.object({path:d.string(),limit:d.number().int().min(1).optional()})},diff:{description:"Show the diff between two versions of a file. Specify v1 and v2 version numbers. Returns { changes } as add/remove/context hunks.",handler:Ef,schema:d.object({path:d.string(),v1:d.number().int(),v2:d.number().int()})},revert:{description:"Revert a file to a previous version. Creates a new version with the old content. Returns { version, revertedTo }.",handler:yf,schema:d.object({path:d.string(),version:d.number().int()})},recent:{description:"Show recent activity across the drive. Optionally filter by path prefix and time window (since). Returns { entries } with path and version details.",handler:df,schema:d.object({path:d.string().optional(),since:d.coerce.date().optional(),limit:d.number().int().min(1).optional()})},grep:{description:"Search file content using regex pattern within a specific path. Returns matching lines with line numbers. Searches the FTS5 index, not S3 directly.",handler:Rf,schema:d.object({pattern:d.string(),path:d.string()})},fts:{description:"Full-text search across all file content using FTS5 tokens. Different from grep (regex) and search (semantic). Returns { matches } with path, snippet, and rank.",handler:wf,schema:d.object({pattern:d.string(),path:d.string().optional()})},search:{description:"Hybrid search combining semantic (vector) and keyword (FTS5) matching. Best for natural language queries. Degrades to keyword-only without an embedding provider.",handler:_f,schema:d.object({query:d.string(),limit:d.number().int().min(1).optional()})},"vec-search":{description:"Vector-only semantic search using embeddings. Returns results ranked by cosine similarity. Requires an embedding provider (OPENAI_API_KEY, GEMINI_API_KEY, or local).",handler:pf,schema:d.object({query:d.string(),limit:d.number().int().min(1).optional()})},reindex:{description:"Re-index files with failed or missing FTS5/embedding entries. Optionally scope to a path prefix. Use after bulk writes or provider changes.",handler:vf,schema:d.object({path:d.string().optional()})},tree:{description:"Recursively list all files and directories. Use depth to limit recursion. Returns a nested tree structure with name, type, size, and children.",handler:Sf,schema:d.object({path:d.string().optional(),depth:d.number().int().min(1).optional()})},glob:{description:"Find files by name pattern. Use `*.md` for root-level files only, `**/*.md` for recursive matching across all subdirectories. Supports `*` (any chars except /), `?` (single char), `**` (any path depth). Optionally scope to a path prefix. Returns { matches } with path, size, and modifiedAt.",handler:mf,schema:d.object({pattern:d.string(),path:d.string().optional()})},"signed-url":{description:"Generate a temporary presigned URL for direct file download. Default expiry is 24 hours (86400 seconds). The URL requires no authentication. Returns { url, path, expiresIn, expiresAt }.",handler:$f,schema:d.object({path:d.string(),expiresIn:d.number().int().min(60).max(604800).optional()})},"comment-add":{description:"Add a comment to a file. Supports line ranges and threading via parentId. Replies auto-resolve path from parent. Returns { id, path, body, author, createdAt }.",handler:Me,schema:d.object({path:d.string().optional(),body:d.string(),parentId:d.string().optional(),lineStart:d.number().int().optional(),lineEnd:d.number().int().optional(),quotedContent:d.string().optional()})},"comment-list":{description:"List comments on a file. Filter by path, resolved state, or parentId. Defaults to unresolved root comments. Returns { comments } with inline replies.",handler:ce,schema:d.object({path:d.string().optional(),parentId:d.string().optional(),resolved:d.boolean().optional(),orgId:d.string().optional(),limit:d.number().int().min(1).optional(),offset:d.number().int().min(0).optional()})},"comment-get":{description:"Get a single comment by ID with all its replies. Returns { comment, replies }.",handler:Xe,schema:d.object({id:d.string()})},"comment-update":{description:"Update a comment's body. Only the original author can update. Returns { id, body, updatedAt }.",handler:Fe,schema:d.object({id:d.string(),body:d.string()})},"comment-delete":{description:"Soft-delete a comment. Only the original author can delete. Deleting a root comment also soft-deletes its replies. Returns { deleted }.",handler:He,schema:d.object({id:d.string()})},"comment-resolve":{description:"Resolve or reopen a root comment. Set resolved=true to resolve, resolved=false to reopen. Only root comments can be resolved. Returns { id, resolved, resolvedBy, resolvedAt }.",handler:Ye,schema:d.object({id:d.string(),resolved:d.boolean()})}}});import{eq as K,and as Ge}from"drizzle-orm";function vt(t,e){let n=crypto.randomUUID(),o=new Date;return t.insert(f.drives).values({id:n,orgId:e.orgId,name:e.name,isDefault:e.isDefault??!1,createdAt:o}).run(),{id:n,name:e.name}}function Lt(t,e){return t.select().from(f.drives).where(K(f.drives.orgId,e)).all().map((n)=>({id:n.id,name:n.name,isDefault:n.isDefault}))}function fo(t,e){let n=t.select().from(f.drives).where(K(f.drives.id,e)).get();if(!n)return null;return{id:n.id,name:n.name,orgId:n.orgId,isDefault:n.isDefault}}function Ot(t,e){return t.select({userId:f.driveMembers.userId,email:f.users.email,role:f.driveMembers.role}).from(f.driveMembers).innerJoin(f.users,K(f.driveMembers.userId,f.users.id)).where(K(f.driveMembers.driveId,e)).all()}function St(t,e){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).get())throw Error("Member not found in drive");t.update(f.driveMembers).set({role:e.role}).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).run()}function Ut(t,e){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).get())throw Error("Member not found in drive");t.delete(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).run()}function Eo(t,e){t.insert(f.driveMembers).values({driveId:e.driveId,userId:e.userId,role:e.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:e.role}}).run()}var lo=g(()=>{a()});import{eq as $,and as ht,sql as cf}from"drizzle-orm";function mt(t,e){let n=crypto.randomUUID(),o=new Date;t.insert(f.orgs).values({id:n,name:e.name,isPersonal:e.isPersonal??!1,createdAt:o}).run(),t.insert(f.orgMembers).values({orgId:n,userId:e.userId,role:"admin"}).run();let i=vt(t,{orgId:n,name:"default",isDefault:!0});return t.insert(f.driveMembers).values({driveId:i.id,userId:e.userId,role:"admin"}).run(),{id:n,name:e.name}}function Z(t,e){return t.select({orgId:f.orgMembers.orgId,role:f.orgMembers.role,name:f.orgs.name,isPersonal:f.orgs.isPersonal}).from(f.orgMembers).innerJoin(f.orgs,$(f.orgMembers.orgId,f.orgs.id)).where($(f.orgMembers.userId,e)).all().map((o)=>({id:o.orgId,name:o.name,role:o.role,isPersonal:o.isPersonal}))}function Ee(t,e){let n=t.select().from(f.orgs).where($(f.orgs.id,e)).get();if(!n)return null;return{id:n.id,name:n.name,isPersonal:n.isPersonal}}function at(t,e){return t.select({userId:f.orgMembers.userId,email:f.users.email,role:f.orgMembers.role}).from(f.orgMembers).innerJoin(f.users,$(f.orgMembers.userId,f.users.id)).where($(f.orgMembers.orgId,e)).all()}function $t(t,e){let n=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).get();if(!n)throw Error("Member not found in org");if(n.role==="admin"&&e.role!=="admin"){if(t.select({count:cf`count(*)`}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}t.update(f.orgMembers).set({role:e.role}).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).run()}function Pt(t,e){if(t.select({isPersonal:f.orgs.isPersonal}).from(f.orgs).where($(f.orgs.id,e.orgId)).get()?.isPersonal)throw Error("Cannot remove members from a personal org");let o=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).get();if(!o)throw Error("Member not found in org");if(o.role==="admin"){if(t.select({count:cf`count(*)`}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}let i=t.select({id:f.drives.id}).from(f.drives).where($(f.drives.orgId,e.orgId)).all();for(let r of i)t.delete(f.driveMembers).where(ht($(f.driveMembers.driveId,r.id),$(f.driveMembers.userId,e.userId))).run();t.delete(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).run()}function Ct(t,e){let n=t.select().from(f.users).where($(f.users.email,e.email)).get();if(!n)throw Error(`User with email ${e.email} not found`);t.insert(f.orgMembers).values({orgId:e.orgId,userId:n.id,role:e.role}).onConflictDoUpdate({target:[f.orgMembers.orgId,f.orgMembers.userId],set:{role:e.role}}).run();let o=t.select().from(f.drives).where($(f.drives.orgId,e.orgId)).get();if(o)t.insert(f.driveMembers).values({driveId:o.id,userId:n.id,role:e.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:e.role}}).run()}var yo=g(()=>{a();lo()});import{eq as Xf}from"drizzle-orm";function Ff(t){let e=new Bun.CryptoHasher("sha256");return e.update(t),e.digest("hex")}function wd(){let t=new Uint8Array(32);return crypto.getRandomValues(t),`af_${Array.from(t,(n)=>n.toString(16).padStart(2,"0")).join("")}`}function Nd(){return crypto.randomUUID()}function q(t,e){let n=Nd(),o=wd(),i=Ff(o),r=new Date;return t.insert(f.users).values({id:n,email:e.email,apiKeyHash:i,createdAt:r}).run(),mt(t,{name:e.email.split("@")[0],userId:n,isPersonal:!0}),{user:{id:n,email:e.email},apiKey:o}}function st(t,e){let n=Ff(e),o=t.select().from(f.users).where(Xf(f.users.apiKeyHash,n)).get();if(!o)return null;return{id:o.id,email:o.email}}function bt(t,e){let n=t.select().from(f.users).where(Xf(f.users.email,e)).get();if(!n)return null;return{id:n.id,email:n.email}}var so=g(()=>{a();yo()});import{eq as pt,and as go}from"drizzle-orm";function x(t,e){if(e.driveId){let r=t.select().from(f.drives).where(pt(f.drives.id,e.driveId)).get();if(!r)throw Error(`Drive not found: ${e.driveId}`);let u=Et(t,e.userId,e.driveId);if(!u)throw Error("You do not have access to this drive");return{orgId:r.orgId,driveId:e.driveId,role:u}}if(e.orgId){let r=t.select().from(f.drives).where(go(pt(f.drives.orgId,e.orgId),pt(f.drives.isDefault,!0))).get();if(!r)throw Error(`No default drive for org: ${e.orgId}`);let u=Et(t,e.userId,r.id);if(!u)throw Error("You do not have access to this drive");return{orgId:e.orgId,driveId:r.id,role:u}}let n=t.select({orgId:f.orgMembers.orgId}).from(f.orgMembers).innerJoin(f.orgs,pt(f.orgMembers.orgId,f.orgs.id)).where(go(pt(f.orgMembers.userId,e.userId),pt(f.orgs.isPersonal,!0))).get();if(!n)throw Error("No personal org found for user");let o=t.select().from(f.drives).where(go(pt(f.drives.orgId,n.orgId),pt(f.drives.isDefault,!0))).get();if(!o)throw Error("No default drive found");let i=Et(t,e.userId,o.id);if(!i)throw Error("You do not have access to your default drive");return{orgId:n.orgId,driveId:o.id,role:i}}var Hf=g(()=>{a();me()});function le(t){let e=L();if(e.auth.apiKey){if(st(t,e.auth.apiKey))return{apiKey:e.auth.apiKey}}console.error("[agent-fs] No local user found, creating one...");let n=q(t,{email:"local@agent-fs.local"});return N("auth.apiKey",n.apiKey),console.error("[agent-fs] Local user created automatically."),{apiKey:n.apiKey}}var Yf=g(()=>{zt();so()});var Gf=g(()=>{so();yo();lo();me();Hf();Yf()});var Bf;var Zf=g(()=>{Bf={name:"agent-fs",version:"0.5.2",private:!0,workspaces:["packages/*"],scripts:{typecheck:"tsc --build",test:"bun test packages/*/src/","test:coverage":"bun test --coverage packages/*/src/",build:"cd packages/cli && bun run build:npm","install-local":"bun run build && cd packages/cli && bun link","uninstall-local":"bun remove -g @desplega.ai/agent-fs && rm -f ~/.bun/bin/agent-fs","deploy:fly":"fly deploy -a agent-fs-taras"},devDependencies:{"bun-types":"^1.2.0",typescript:"^5.7.0",yaml:"^2.8.2","zod-to-json-schema":"^3.25.1"},overrides:{chromadb:"npm:empty-npm-package@1.0.0","chromadb-default-embed":"npm:empty-npm-package@1.0.0","@xenova/transformers":"npm:empty-npm-package@1.0.0","tree-sitter-wasms":"npm:empty-npm-package@1.0.0","web-tree-sitter":"npm:empty-npm-package@1.0.0","cohere-ai":"npm:empty-npm-package@1.0.0",voyageai:"npm:empty-npm-package@1.0.0",ollama:"npm:empty-npm-package@1.0.0"}}});var B;var To=g(()=>{Zf();B=Bf.version});var Vf={};Ft(Vf,{LocalEmbeddingProvider:()=>Qf});import{join as Id}from"path";import{mkdirSync as _d,existsSync as Dd}from"fs";class Qf{name="local";dimensions=768;llama=null;model=null;embeddingContext=null;initPromise=null;async init(){if(this.embeddingContext)return;if(this.initPromise)return this.initPromise;return this.initPromise=this._doInit(),this.initPromise}async _doInit(){let{getLlama:t,resolveModelFile:e}=await import("node-llama-cpp");this.llama=await t();let n=Id(nt(),"models");if(!Dd(n))_d(n,{recursive:!0});console.error("[agent-fs] Resolving local embedding model...");let o=await e(vd,n);console.error("[agent-fs] Model ready:",o),this.model=await this.llama.loadModel({modelPath:o}),this.embeddingContext=await this.model.createEmbeddingContext()}async embed(t){await this.init();let e=await this.embeddingContext.getEmbeddingFor(t);return Array.from(e.vector)}async embedBatch(t){await this.init();let e=[];for(let n of t){let o=await this.embeddingContext.getEmbeddingFor(n);e.push(Array.from(o.vector))}return e}async dispose(){if(this.embeddingContext)await this.embeddingContext.dispose(),this.embeddingContext=null;if(this.model)await this.model.dispose(),this.model=null;this.initPromise=null}}var vd="hf:nomic-ai/nomic-embed-text-v1.5-GGUF:Q8_0";var Jf=g(()=>{zt()});var Ro={};Ft(Ro,{OpenAIEmbeddingProvider:()=>Wf});import Ld from"openai";class Wf{name="openai";dimensions=768;client;constructor(t){this.client=new Ld({apiKey:t})}async embed(t){return(await this.client.embeddings.create({model:"text-embedding-3-small",input:t,dimensions:768})).data[0].embedding}async embedBatch(t){return(await this.client.embeddings.create({model:"text-embedding-3-small",input:t,dimensions:768})).data.sort((n,o)=>n.index-o.index).map((n)=>n.embedding)}}var Ao=()=>{};var wo={};Ft(wo,{GeminiEmbeddingProvider:()=>Kf});import{GoogleGenAI as Od}from"@google/genai";class Kf{name="gemini";dimensions=768;client;constructor(t){this.client=new Od({apiKey:t})}async embed(t){return(await this.client.models.embedContent({model:"gemini-embedding-001",contents:t,config:{outputDimensionality:768}})).embeddings[0].values}async embedBatch(t){let e=[];for(let n of t){let o=await this.client.models.embedContent({model:"gemini-embedding-001",contents:n,config:{outputDimensionality:768}});e.push(o.embeddings[0].values)}return e}}var No=()=>{};async function bf(t){switch(t.provider){case"local":{let{LocalEmbeddingProvider:e}=await Promise.resolve().then(() => (Jf(),Vf));return new e}case"openai":{if(!t.apiKey)throw Error("OpenAI API key required. Set embedding.apiKey in config.");let{OpenAIEmbeddingProvider:e}=await Promise.resolve().then(() => (Ao(),Ro));return new e(t.apiKey)}case"gemini":{if(!t.apiKey)throw Error("Gemini API key required. Set embedding.apiKey in config.");let{GeminiEmbeddingProvider:e}=await Promise.resolve().then(() => (No(),wo));return new e(t.apiKey)}default:throw Error(`Unknown embedding provider: ${t.provider}`)}}async function kt(t){if(process.env.OPENAI_API_KEY)try{let{OpenAIEmbeddingProvider:e}=await Promise.resolve().then(() => (Ao(),Ro));return new e(process.env.OPENAI_API_KEY)}catch(e){console.error("[agent-fs] Failed to load OpenAI provider:",e)}if(process.env.GEMINI_API_KEY)try{let{GeminiEmbeddingProvider:e}=await Promise.resolve().then(() => (No(),wo));return new e(process.env.GEMINI_API_KEY)}catch(e){console.error("[agent-fs] Failed to load Gemini provider:",e)}if(t?.provider&&t.provider!=="local"&&t.apiKey)try{return await bf(t)}catch(e){console.error("[agent-fs] Failed to create embedding provider from config:",e)}if(t?.provider==="local")try{return await bf(t)}catch(e){console.error("[agent-fs] Failed to load local embedding provider:",e)}return null}var jf,kf,zf=(t)=>typeof t==="string"?{...kf,name:t}:{...kf,...t};var Ze=g(()=>{jf=Symbol("Let zodToJsonSchema decide on which parser to use"),kf={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",target:"jsonSchema7",strictUnions:!1,definitions:{},errorMessages:!1,markdownDescription:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref",openAiAnyTypeName:"OpenAiAnyType"}});var qf=(t)=>{let e=zf(t),n=e.name!==void 0?[...e.basePath,e.definitionPath,e.name]:e.basePath;return{...e,flags:{hasReferencedOpenAiAnyType:!1},currentPath:n,propertyPath:void 0,seen:new Map(Object.entries(e.definitions).map(([o,i])=>[i._def,{def:i._def,path:[...e.basePath,e.definitionPath,o],jsonSchema:void 0}]))}};var po=g(()=>{Ze()});function Io(t,e,n,o){if(!o?.errorMessages)return;if(n)t.errorMessage={...t.errorMessage,[e]:n}}function D(t,e,n,o,i){t[e]=n,Io(t,e,o,i)}var Be=(t,e)=>{let n=0;for(;n<t.length&&n<e.length;n++)if(t[n]!==e[n])break;return[(t.length-n).toString(),...e.slice(n)].join("/")};function m(t){if(t.target!=="openAi")return{};let e=[...t.basePath,t.definitionPath,t.openAiAnyTypeName];return t.flags.hasReferencedOpenAiAnyType=!0,{$ref:t.$refStrategy==="relative"?Be(e,t.currentPath):e.join("/")}}var b=()=>{};import{ZodFirstPartyTypeKind as Sd}from"zod/v3";function xf(t,e){let n={type:"array"};if(t.type?._def&&t.type?._def?.typeName!==Sd.ZodAny)n.items=w(t.type._def,{...e,currentPath:[...e.currentPath,"items"]});if(t.minLength)D(n,"minItems",t.minLength.value,t.minLength.message,e);if(t.maxLength)D(n,"maxItems",t.maxLength.value,t.maxLength.message,e);if(t.exactLength)D(n,"minItems",t.exactLength.value,t.exactLength.message,e),D(n,"maxItems",t.exactLength.value,t.exactLength.message,e);return n}var _o=g(()=>{c()});function tE(t,e){let n={type:"integer",format:"int64"};if(!t.checks)return n;for(let o of t.checks)switch(o.kind){case"min":if(e.target==="jsonSchema7")if(o.inclusive)D(n,"minimum",o.value,o.message,e);else D(n,"exclusiveMinimum",o.value,o.message,e);else{if(!o.inclusive)n.exclusiveMinimum=!0;D(n,"minimum",o.value,o.message,e)}break;case"max":if(e.target==="jsonSchema7")if(o.inclusive)D(n,"maximum",o.value,o.message,e);else D(n,"exclusiveMaximum",o.value,o.message,e);else{if(!o.inclusive)n.exclusiveMaximum=!0;D(n,"maximum",o.value,o.message,e)}break;case"multipleOf":D(n,"multipleOf",o.value,o.message,e);break}return n}var Do=()=>{};function eE(){return{type:"boolean"}}function Qe(t,e){return w(t.type._def,e)}var Ve=g(()=>{c()});var nE=(t,e)=>{return w(t.innerType._def,e)};var vo=g(()=>{c()});function Lo(t,e,n){let o=n??e.dateStrategy;if(Array.isArray(o))return{anyOf:o.map((i,r)=>Lo(t,e,i))};switch(o){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return Ud(t,e)}}var Ud=(t,e)=>{let n={type:"integer",format:"unix-time"};if(e.target==="openApi3")return n;for(let o of t.checks)switch(o.kind){case"min":D(n,"minimum",o.value,o.message,e);break;case"max":D(n,"maximum",o.value,o.message,e);break}return n};var Oo=()=>{};function oE(t,e){return{...w(t.innerType._def,e),default:t.defaultValue()}}var So=g(()=>{c()});function iE(t,e){return e.effectStrategy==="input"?w(t.schema._def,e):m(e)}var Uo=g(()=>{c();b()});function rE(t){return{type:"string",enum:Array.from(t.values)}}function uE(t,e){let n=[w(t.left._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),w(t.right._def,{...e,currentPath:[...e.currentPath,"allOf","1"]})].filter((r)=>!!r),o=e.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,i=[];return n.forEach((r)=>{if(hd(r)){if(i.push(...r.allOf),r.unevaluatedProperties===void 0)o=void 0}else{let u=r;if("additionalProperties"in r&&r.additionalProperties===!1){let{additionalProperties:E,...l}=r;u=l}else o=void 0;i.push(u)}}),i.length?{allOf:i,...o}:void 0}var hd=(t)=>{if("type"in t&&t.type==="string")return!1;return"allOf"in t};var ho=g(()=>{c()});function fE(t,e){let n=typeof t.value;if(n!=="bigint"&&n!=="number"&&n!=="boolean"&&n!=="string")return{type:Array.isArray(t.value)?"array":"object"};if(e.target==="openApi3")return{type:n==="bigint"?"integer":n,enum:[t.value]};return{type:n==="bigint"?"integer":n,const:t.value}}function Je(t,e){let n={type:"string"};if(t.checks)for(let o of t.checks)switch(o.kind){case"min":D(n,"minLength",typeof n.minLength==="number"?Math.max(n.minLength,o.value):o.value,o.message,e);break;case"max":D(n,"maxLength",typeof n.maxLength==="number"?Math.min(n.maxLength,o.value):o.value,o.message,e);break;case"email":switch(e.emailStrategy){case"format:email":et(n,"email",o.message,e);break;case"format:idn-email":et(n,"idn-email",o.message,e);break;case"pattern:zod":G(n,tt.email,o.message,e);break}break;case"url":et(n,"uri",o.message,e);break;case"uuid":et(n,"uuid",o.message,e);break;case"regex":G(n,o.regex,o.message,e);break;case"cuid":G(n,tt.cuid,o.message,e);break;case"cuid2":G(n,tt.cuid2,o.message,e);break;case"startsWith":G(n,RegExp(`^${ao(o.value,e)}`),o.message,e);break;case"endsWith":G(n,RegExp(`${ao(o.value,e)}$`),o.message,e);break;case"datetime":et(n,"date-time",o.message,e);break;case"date":et(n,"date",o.message,e);break;case"time":et(n,"time",o.message,e);break;case"duration":et(n,"duration",o.message,e);break;case"length":D(n,"minLength",typeof n.minLength==="number"?Math.max(n.minLength,o.value):o.value,o.message,e),D(n,"maxLength",typeof n.maxLength==="number"?Math.min(n.maxLength,o.value):o.value,o.message,e);break;case"includes":{G(n,RegExp(ao(o.value,e)),o.message,e);break}case"ip":{if(o.version!=="v6")et(n,"ipv4",o.message,e);if(o.version!=="v4")et(n,"ipv6",o.message,e);break}case"base64url":G(n,tt.base64url,o.message,e);break;case"jwt":G(n,tt.jwt,o.message,e);break;case"cidr":{if(o.version!=="v6")G(n,tt.ipv4Cidr,o.message,e);if(o.version!=="v4")G(n,tt.ipv6Cidr,o.message,e);break}case"emoji":G(n,tt.emoji(),o.message,e);break;case"ulid":{G(n,tt.ulid,o.message,e);break}case"base64":{switch(e.base64Strategy){case"format:binary":{et(n,"binary",o.message,e);break}case"contentEncoding:base64":{D(n,"contentEncoding","base64",o.message,e);break}case"pattern:zod":{G(n,tt.base64,o.message,e);break}}break}case"nanoid":G(n,tt.nanoid,o.message,e);case"toLowerCase":case"toUpperCase":case"trim":break;default:((i)=>{})(o)}return n}function ao(t,e){return e.patternStrategy==="escape"?ad(t):t}function ad(t){let e="";for(let n=0;n<t.length;n++){if(!md.has(t[n]))e+="\\";e+=t[n]}return e}function et(t,e,n,o){if(t.format||t.anyOf?.some((i)=>i.format)){if(!t.anyOf)t.anyOf=[];if(t.format){if(t.anyOf.push({format:t.format,...t.errorMessage&&o.errorMessages&&{errorMessage:{format:t.errorMessage.format}}}),delete t.format,t.errorMessage){if(delete t.errorMessage.format,Object.keys(t.errorMessage).length===0)delete t.errorMessage}}t.anyOf.push({format:e,...n&&o.errorMessages&&{errorMessage:{format:n}}})}else D(t,"format",e,n,o)}function G(t,e,n,o){if(t.pattern||t.allOf?.some((i)=>i.pattern)){if(!t.allOf)t.allOf=[];if(t.pattern){if(t.allOf.push({pattern:t.pattern,...t.errorMessage&&o.errorMessages&&{errorMessage:{pattern:t.errorMessage.pattern}}}),delete t.pattern,t.errorMessage){if(delete t.errorMessage.pattern,Object.keys(t.errorMessage).length===0)delete t.errorMessage}}t.allOf.push({pattern:EE(e,o),...n&&o.errorMessages&&{errorMessage:{pattern:n}}})}else D(t,"pattern",EE(e,o),n,o)}function EE(t,e){if(!e.applyRegexFlags||!t.flags)return t.source;let n={i:t.flags.includes("i"),m:t.flags.includes("m"),s:t.flags.includes("s")},o=n.i?t.source.toLowerCase():t.source,i="",r=!1,u=!1,E=!1;for(let l=0;l<o.length;l++){if(r){i+=o[l],r=!1;continue}if(n.i){if(u){if(o[l].match(/[a-z]/)){if(E)i+=o[l],i+=`${o[l-2]}-${o[l]}`.toUpperCase(),E=!1;else if(o[l+1]==="-"&&o[l+2]?.match(/[a-z]/))i+=o[l],E=!0;else i+=`${o[l]}${o[l].toUpperCase()}`;continue}}else if(o[l].match(/[a-z]/)){i+=`[${o[l]}${o[l].toUpperCase()}]`;continue}}if(n.m){if(o[l]==="^"){i+=`(^|(?<=[\r
|
|
168
|
+
LIMIT ?`).all(r,n),l=[],y=new Set;for(let s of E){let T=t.db.select().from(f.contentChunks).where(eo(f.contentChunks.id,s.chunk_id)).get();if(!T||T.driveId!==t.driveId)continue;if(y.has(T.filePath))continue;y.add(T.filePath);let R=t.db.select().from(f.files).where(ud(eo(f.files.path,T.filePath),eo(f.files.driveId,t.driveId))).get();l.push({path:T.filePath,snippet:T.content.slice(0,200),author:R?.author,modifiedAt:R?.modifiedAt})}return l}function Ed(t,e,n){let o=e.split(/\s+/).filter(Boolean).map((i)=>`"${i}"`).join(" OR ");if(!o)return[];try{return $e(t.db,{pattern:o,driveId:t.driveId}).slice(0,n).map((r)=>({path:r.path,snippet:r.snippet}))}catch{return[]}}var Df=g(()=>{a()});import{eq as Pe,and as ld,or as yd,isNull as sd}from"drizzle-orm";async function vf(t,e){let n=[Pe(f.files.driveId,t.driveId),Pe(f.files.isDeleted,!1),yd(Pe(f.files.embeddingStatus,"failed"),sd(f.files.embeddingStatus),Pe(f.files.embeddingStatus,"pending"))];if(e.path){let{like:l}=await import("drizzle-orm"),y=e.path.endsWith("/")?e.path:e.path+"/";n.push(l(f.files.path,y+"%"))}let o=t.db.select({path:f.files.path}).from(f.files).where(ld(...n)).all(),i=0,r=0,u=0,E=3;for(let l=0;l<o.length;l+=E){let y=o.slice(l,l+E),s=await Promise.allSettled(y.map(async(T)=>{let R=I(t.orgId,t.driveId,T.path),v=await t.s3.getObject(R),O=new TextDecoder().decode(v.body);if(J(t.db,{path:T.path,driveId:t.driveId,content:O}),t.embeddingProvider)return await jn(t.db,t.embeddingProvider,{path:T.path,driveId:t.driveId,content:O}),"reindexed";return"skipped"}));for(let T of s)if(T.status==="fulfilled")if(T.value==="reindexed")i++;else u++;else console.error("Reindex failed:",T.reason),r++}return{reindexed:i,failed:r,skipped:u}}var Lf=g(()=>{a();X();Vt()});import{eq as Of,and as gd,like as dd}from"drizzle-orm";async function Sf(t,e){let n=Rt(e.path??"/"),o=I(t.orgId,t.driveId,n),{objects:i}=await t.s3.listObjects(o),r=t.db.select().from(f.files).where(gd(Of(f.files.driveId,t.driveId),dd(f.files.path,n+"%"),Of(f.files.isDeleted,!1))).all(),u=new Map(r.map((l)=>[l.path,l])),E=[];for(let l of i){let y=l.key.slice(o.length);if(!y)continue;let s=y.split("/").filter(Boolean);if(s.length===0)continue;if(e.depth!==void 0&&s.length>e.depth)continue;let T=E;for(let R=0;R<s.length;R++){let v=s[R],O=R===s.length-1,C=!O||y.endsWith("/");if(C&&!O){let M=T.find((H)=>H.name===v&&H.type==="directory");if(!M)M={name:v,type:"directory",children:[]},T.push(M);if(!M.children)M.children=[];T=M.children}else if(C&&O){let M=T.find((H)=>H.name===v&&H.type==="directory");if(!M)M={name:v,type:"directory",children:[]},T.push(M)}else{let M=n+s.slice(0,R+1).join("/"),H=u.get(M),on={name:v,type:"file",size:H?.size??l.size};if(H?.author)on.author=H.author;if(H?.modifiedAt??l.lastModified)on.modifiedAt=H?.modifiedAt??l.lastModified;T.push(on)}}}return{tree:E}}var Uf=g(()=>{a();X()});import{eq as hf,and as Td,like as Rd}from"drizzle-orm";function Ad(t){let e="",n=0;while(n<t.length){let o=t[n];if(o==="*")if(t[n+1]==="*"){if(e+=".*",n+=2,t[n]==="/")n++}else e+="[^/]*",n++;else if(o==="?")e+="[^/]",n++;else if(".+^${}()|[]\\".includes(o))e+="\\"+o,n++;else e+=o,n++}return new RegExp("^"+e+"$")}async function mf(t,e){let n=e.path?Rt(e.path):"/",o=I(t.orgId,t.driveId,n),{objects:i}=await t.s3.listObjects(o),r=t.db.select().from(f.files).where(Td(hf(f.files.driveId,t.driveId),Rd(f.files.path,n+"%"),hf(f.files.isDeleted,!1))).all(),u=new Map(r.map((y)=>[y.path,y])),E=Ad(e.pattern),l=[];for(let y of i){let s=y.key.slice(o.length);if(!s||s.endsWith("/"))continue;if(E.test(s)){let T=n+s,R=u.get(T);l.push({path:T,size:R?.size??y.size,modifiedAt:R?.modifiedAt??y.lastModified})}}return{matches:l}}var af=g(()=>{a();X()});async function $f(t,e){let n=au(e.path),o=I(t.orgId,t.driveId,n),i=e.expiresIn??86400;try{await t.s3.headObject(o)}catch(E){if(E?.name==="NotFound"||E?.name==="NoSuchKey"||E?.$metadata?.httpStatusCode===404)throw new U(`File not found: ${n}`,{path:n});throw E}let r=lt(n);return{url:await t.s3.getPresignedUrl(o,i,r!=="application/octet-stream"?r:void 0),path:n,expiresIn:i,expiresAt:new Date(Date.now()+i*1000).toISOString()}}var Pf=g(()=>{X();V();Bt()});function no(t,e,n,o){let i=o.startsWith("/")?o.slice(1):o;return`${t}/file/~/${e}/${n}/${i}`}import{eq as S,and as yt,sql as oo,desc as Cf}from"drizzle-orm";function io(t,e){t.db.insert(f.events).values({id:crypto.randomUUID(),orgId:t.orgId,type:e.type,resourceType:e.resourceType,resourceId:e.resourceId,actor:t.userId,target:e.target??null,status:"created",metadata:e.metadata?JSON.stringify(e.metadata):null,createdAt:new Date}).run()}function Ce(t){return{id:t.id,parentId:t.parentId??void 0,path:t.path,lineStart:t.lineStart??void 0,lineEnd:t.lineEnd??void 0,quotedContent:t.quotedContent??void 0,body:t.body,author:t.author,resolved:t.resolved??!1,resolvedBy:t.resolvedBy??void 0,resolvedAt:t.resolvedAt??void 0,fileVersionId:t.fileVersionId??void 0,replyCount:t.replyCount??0,createdAt:t.createdAt,updatedAt:t.updatedAt}}async function Me(t,e){let n=new Date,o=crypto.randomUUID(),i=e.path;if(e.parentId){let u=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.parentId),S(f.comments.isDeleted,!1))).get();if(!u)throw new U("Parent comment not found",{suggestion:"Check that the parent comment ID is correct and not deleted"});if(u.parentId)throw new z("Cannot reply to a reply \u2014 only root comments accept replies",{suggestion:"Reply to the root comment instead"});if(!i)i=u.path}if(!i)throw new z("path is required for root comments",{field:"path"});let r=t.db.select({id:f.fileVersions.id}).from(f.fileVersions).where(yt(S(f.fileVersions.path,i),S(f.fileVersions.driveId,t.driveId))).orderBy(Cf(f.fileVersions.id)).limit(1).get();return t.db.insert(f.comments).values({id:o,parentId:e.parentId??null,orgId:t.orgId,driveId:t.driveId,path:i,lineStart:e.lineStart??null,lineEnd:e.lineEnd??null,quotedContent:e.quotedContent??null,fileVersionId:r?.id??null,body:e.body,author:t.userId,resolved:!1,createdAt:n,updatedAt:n,isDeleted:!1}).run(),io(t,{type:"comment_created",resourceType:"comment",resourceId:o,metadata:{path:i,parentId:e.parentId}}),{id:o,path:i,body:e.body,parentId:e.parentId,lineStart:e.lineStart,lineEnd:e.lineEnd,author:t.userId,createdAt:n}}async function ce(t,e){let n=[S(f.comments.driveId,t.driveId),S(f.comments.isDeleted,!1)];if(e.path)n.push(S(f.comments.path,e.path));if(e.parentId)n.push(S(f.comments.parentId,e.parentId));else if(e.parentId===void 0&&!e.resolved)n.push(oo`${f.comments.parentId} IS NULL`),n.push(S(f.comments.resolved,!1));else if(e.parentId===void 0&&e.resolved)n.push(oo`${f.comments.parentId} IS NULL`);if(e.orgId)n.push(S(f.comments.orgId,e.orgId));let o=e.limit??50,i=e.offset??0;return{comments:t.db.select().from(f.comments).where(yt(...n)).orderBy(Cf(f.comments.createdAt)).limit(o).offset(i).all().map((E)=>{let y=t.db.select().from(f.comments).where(yt(S(f.comments.parentId,E.id),S(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((s)=>Ce({...s,replyCount:0}));return{...Ce({...E,replyCount:y.length}),replies:y}})}}async function Xe(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});let o=t.db.select({count:oo`count(*)`}).from(f.comments).where(yt(S(f.comments.parentId,n.id),S(f.comments.isDeleted,!1))).get(),i=Ce({...n,replyCount:o?.count??0}),u=t.db.select().from(f.comments).where(yt(S(f.comments.parentId,e.id),S(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((E)=>Ce({...E,replyCount:0}));return{comment:i,replies:u}}async function Fe(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.author!==t.userId)throw new j("You can only edit your own comments",{suggestion:"Only the comment author can update it"});let o=new Date;return t.db.update(f.comments).set({body:e.body,updatedAt:o}).where(S(f.comments.id,e.id)).run(),{id:e.id,body:e.body,updatedAt:o}}async function He(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.author!==t.userId)throw new j("You can only delete your own comments",{suggestion:"Only the comment author can delete it"});let o=new Date;if(t.db.update(f.comments).set({isDeleted:!0,updatedAt:o}).where(S(f.comments.id,e.id)).run(),!n.parentId)t.db.update(f.comments).set({isDeleted:!0,updatedAt:o}).where(S(f.comments.parentId,e.id)).run();return io(t,{type:"comment_deleted",resourceType:"comment",resourceId:e.id}),{deleted:!0}}async function Ye(t,e){let n=t.db.select().from(f.comments).where(yt(S(f.comments.id,e.id),S(f.comments.isDeleted,!1))).get();if(!n)throw new U("Comment not found",{suggestion:"Check that the comment ID is correct"});if(n.parentId)throw new z("Cannot resolve a reply \u2014 only root comments can be resolved",{suggestion:"Resolve the parent comment instead"});let o=new Date,i=e.resolved?o:null,r=e.resolved?t.userId:null;return t.db.update(f.comments).set({resolved:e.resolved,resolvedBy:r,resolvedAt:i,updatedAt:o}).where(S(f.comments.id,e.id)).run(),io(t,{type:e.resolved?"comment_resolved":"comment_reopened",resourceType:"comment",resourceId:e.id}),{id:e.id,resolved:e.resolved,resolvedBy:r??void 0,resolvedAt:i??void 0}}var Mf=g(()=>{a();V()});import{z as d}from"zod";async function wt(t,e,n,o){let i=ro[e];if(!i)throw Error(`Unknown operation: ${e}`);if(!o?.skipAuth){let E=ue(e);fe(t.db,{userId:t.userId,driveId:t.driveId,requiredRole:E})}let r=i.schema.parse(n),u=await i.handler(t,r);if(t.appUrl&&u&&typeof u==="object"){if("path"in u)u.appUrl=no(t.appUrl,t.orgId,t.driveId,u.path);else if("to"in u)u.appUrl=no(t.appUrl,t.orgId,t.driveId,u.to)}return u}function Kt(){return Object.keys(ro)}function Nt(t){return ro[t]}var ro;var uo=g(()=>{me();cu();Fu();Yu();Zu();Vu();Ku();ku();qu();tf();nf();uf();lf();sf();Tf();Af();Nf();If();Df();Lf();Uf();af();Pf();Mf();ro={write:{description:"Write or overwrite a file. Creates the file if it doesn't exist, or creates a new version. Use expectedVersion for optimistic concurrency. Returns { version, path, size }.",handler:Mu,schema:d.object({path:d.string(),content:d.string(),message:d.string().optional(),expectedVersion:d.number().int().optional()})},cat:{description:"Read file content with optional pagination via offset/limit. Returns { content, totalLines, truncated }.",handler:Xu,schema:d.object({path:d.string(),offset:d.number().int().min(0).optional(),limit:d.number().int().min(1).optional()})},edit:{description:"Replace a specific string in a file (surgical find-and-replace). Captures the edit intent as a diff summary in version history. Returns { version, path, changes }.",handler:Hu,schema:d.object({path:d.string(),old_string:d.string(),new_string:d.string(),message:d.string().optional()})},append:{description:"Append content to the end of an existing file. Creates a new version. Returns { version, size }.",handler:Gu,schema:d.object({path:d.string(),content:d.string(),message:d.string().optional()})},ls:{description:"List immediate children of a directory. Returns { entries } where each entry has name, type (file/directory), size, author, modifiedAt.",handler:Qu,schema:d.object({path:d.string().optional()})},stat:{description:"Get file metadata without reading content. Returns path, size, contentType, author, currentVersion, createdAt, modifiedAt, isDeleted, embeddingStatus.",handler:Wu,schema:d.object({path:d.string()})},rm:{description:"Delete a file. Removes from S3, cleans up FTS5 index and vector embeddings. Returns { path, deleted }.",handler:bu,schema:d.object({path:d.string()})},mv:{description:"Move or rename a file. Preserves version history at the new path. Returns { from, to, version }.",handler:zu,schema:d.object({from:d.string(),to:d.string(),message:d.string().optional()})},cp:{description:"Copy a file using server-side S3 copy. Creates a new version at the destination. Returns { from, to, version }.",handler:xu,schema:d.object({from:d.string(),to:d.string()})},tail:{description:"Read the last N lines of a file (default 20). Returns { content, totalLines, truncated }.",handler:ef,schema:d.object({path:d.string(),lines:d.number().int().min(1).optional()})},log:{description:"Show version history for a file. Returns { versions } with version number, author, timestamp, operation type, message, and diff summary.",handler:rf,schema:d.object({path:d.string(),limit:d.number().int().min(1).optional()})},diff:{description:"Show the diff between two versions of a file. Specify v1 and v2 version numbers. Returns { changes } as add/remove/context hunks.",handler:Ef,schema:d.object({path:d.string(),v1:d.number().int(),v2:d.number().int()})},revert:{description:"Revert a file to a previous version. Creates a new version with the old content. Returns { version, revertedTo }.",handler:yf,schema:d.object({path:d.string(),version:d.number().int()})},recent:{description:"Show recent activity across the drive. Optionally filter by path prefix and time window (since). Returns { entries } with path and version details.",handler:df,schema:d.object({path:d.string().optional(),since:d.coerce.date().optional(),limit:d.number().int().min(1).optional()})},grep:{description:"Search file content using regex pattern within a specific path. Returns matching lines with line numbers. Searches the FTS5 index, not S3 directly.",handler:Rf,schema:d.object({pattern:d.string(),path:d.string()})},fts:{description:"Full-text search across all file content using FTS5 tokens. Different from grep (regex) and search (semantic). Returns { matches } with path, snippet, and rank.",handler:wf,schema:d.object({pattern:d.string(),path:d.string().optional()})},search:{description:"Hybrid search combining semantic (vector) and keyword (FTS5) matching. Best for natural language queries. Degrades to keyword-only without an embedding provider.",handler:_f,schema:d.object({query:d.string(),limit:d.number().int().min(1).optional()})},"vec-search":{description:"Vector-only semantic search using embeddings. Returns results ranked by cosine similarity. Requires an embedding provider (OPENAI_API_KEY, GEMINI_API_KEY, or local).",handler:pf,schema:d.object({query:d.string(),limit:d.number().int().min(1).optional()})},reindex:{description:"Re-index files with failed or missing FTS5/embedding entries. Optionally scope to a path prefix. Use after bulk writes or provider changes.",handler:vf,schema:d.object({path:d.string().optional()})},tree:{description:"Recursively list all files and directories. Use depth to limit recursion. Returns a nested tree structure with name, type, size, and children.",handler:Sf,schema:d.object({path:d.string().optional(),depth:d.number().int().min(1).optional()})},glob:{description:"Find files by name pattern. Use `*.md` for root-level files only, `**/*.md` for recursive matching across all subdirectories. Supports `*` (any chars except /), `?` (single char), `**` (any path depth). Optionally scope to a path prefix. Returns { matches } with path, size, and modifiedAt.",handler:mf,schema:d.object({pattern:d.string(),path:d.string().optional()})},"signed-url":{description:"Generate a temporary presigned URL for direct file download. Default expiry is 24 hours (86400 seconds). The URL requires no authentication. Returns { url, path, expiresIn, expiresAt }.",handler:$f,schema:d.object({path:d.string(),expiresIn:d.number().int().min(60).max(604800).optional()})},"comment-add":{description:"Add a comment to a file. Supports line ranges and threading via parentId. Replies auto-resolve path from parent. Returns { id, path, body, author, createdAt }.",handler:Me,schema:d.object({path:d.string().optional(),body:d.string(),parentId:d.string().optional(),lineStart:d.number().int().optional(),lineEnd:d.number().int().optional(),quotedContent:d.string().optional()})},"comment-list":{description:"List comments on a file. Filter by path, resolved state, or parentId. Defaults to unresolved root comments. Returns { comments } with inline replies.",handler:ce,schema:d.object({path:d.string().optional(),parentId:d.string().optional(),resolved:d.boolean().optional(),orgId:d.string().optional(),limit:d.number().int().min(1).optional(),offset:d.number().int().min(0).optional()})},"comment-get":{description:"Get a single comment by ID with all its replies. Returns { comment, replies }.",handler:Xe,schema:d.object({id:d.string()})},"comment-update":{description:"Update a comment's body. Only the original author can update. Returns { id, body, updatedAt }.",handler:Fe,schema:d.object({id:d.string(),body:d.string()})},"comment-delete":{description:"Soft-delete a comment. Only the original author can delete. Deleting a root comment also soft-deletes its replies. Returns { deleted }.",handler:He,schema:d.object({id:d.string()})},"comment-resolve":{description:"Resolve or reopen a root comment. Set resolved=true to resolve, resolved=false to reopen. Only root comments can be resolved. Returns { id, resolved, resolvedBy, resolvedAt }.",handler:Ye,schema:d.object({id:d.string(),resolved:d.boolean()})}}});import{eq as K,and as Ge}from"drizzle-orm";function vt(t,e){let n=crypto.randomUUID(),o=new Date;return t.insert(f.drives).values({id:n,orgId:e.orgId,name:e.name,isDefault:e.isDefault??!1,createdAt:o}).run(),{id:n,name:e.name}}function Lt(t,e){return t.select().from(f.drives).where(K(f.drives.orgId,e)).all().map((n)=>({id:n.id,name:n.name,isDefault:n.isDefault}))}function fo(t,e){let n=t.select().from(f.drives).where(K(f.drives.id,e)).get();if(!n)return null;return{id:n.id,name:n.name,orgId:n.orgId,isDefault:n.isDefault}}function Ot(t,e){return t.select({userId:f.driveMembers.userId,email:f.users.email,role:f.driveMembers.role}).from(f.driveMembers).innerJoin(f.users,K(f.driveMembers.userId,f.users.id)).where(K(f.driveMembers.driveId,e)).all()}function St(t,e){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).get())throw Error("Member not found in drive");t.update(f.driveMembers).set({role:e.role}).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).run()}function Ut(t,e){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).get())throw Error("Member not found in drive");t.delete(f.driveMembers).where(Ge(K(f.driveMembers.driveId,e.driveId),K(f.driveMembers.userId,e.userId))).run()}function Eo(t,e){t.insert(f.driveMembers).values({driveId:e.driveId,userId:e.userId,role:e.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:e.role}}).run()}var lo=g(()=>{a()});import{eq as $,and as ht,sql as cf}from"drizzle-orm";function mt(t,e){let n=crypto.randomUUID(),o=new Date;t.insert(f.orgs).values({id:n,name:e.name,isPersonal:e.isPersonal??!1,createdAt:o}).run(),t.insert(f.orgMembers).values({orgId:n,userId:e.userId,role:"admin"}).run();let i=vt(t,{orgId:n,name:"default",isDefault:!0});return t.insert(f.driveMembers).values({driveId:i.id,userId:e.userId,role:"admin"}).run(),{id:n,name:e.name}}function Z(t,e){return t.select({orgId:f.orgMembers.orgId,role:f.orgMembers.role,name:f.orgs.name,isPersonal:f.orgs.isPersonal}).from(f.orgMembers).innerJoin(f.orgs,$(f.orgMembers.orgId,f.orgs.id)).where($(f.orgMembers.userId,e)).all().map((o)=>({id:o.orgId,name:o.name,role:o.role,isPersonal:o.isPersonal}))}function Ee(t,e){let n=t.select().from(f.orgs).where($(f.orgs.id,e)).get();if(!n)return null;return{id:n.id,name:n.name,isPersonal:n.isPersonal}}function at(t,e){return t.select({userId:f.orgMembers.userId,email:f.users.email,role:f.orgMembers.role}).from(f.orgMembers).innerJoin(f.users,$(f.orgMembers.userId,f.users.id)).where($(f.orgMembers.orgId,e)).all()}function $t(t,e){let n=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).get();if(!n)throw Error("Member not found in org");if(n.role==="admin"&&e.role!=="admin"){if(t.select({count:cf`count(*)`}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}t.update(f.orgMembers).set({role:e.role}).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).run()}function Pt(t,e){if(t.select({isPersonal:f.orgs.isPersonal}).from(f.orgs).where($(f.orgs.id,e.orgId)).get()?.isPersonal)throw Error("Cannot remove members from a personal org");let o=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).get();if(!o)throw Error("Member not found in org");if(o.role==="admin"){if(t.select({count:cf`count(*)`}).from(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}let i=t.select({id:f.drives.id}).from(f.drives).where($(f.drives.orgId,e.orgId)).all();for(let r of i)t.delete(f.driveMembers).where(ht($(f.driveMembers.driveId,r.id),$(f.driveMembers.userId,e.userId))).run();t.delete(f.orgMembers).where(ht($(f.orgMembers.orgId,e.orgId),$(f.orgMembers.userId,e.userId))).run()}function Ct(t,e){let n=t.select().from(f.users).where($(f.users.email,e.email)).get();if(!n)throw Error(`User with email ${e.email} not found`);t.insert(f.orgMembers).values({orgId:e.orgId,userId:n.id,role:e.role}).onConflictDoUpdate({target:[f.orgMembers.orgId,f.orgMembers.userId],set:{role:e.role}}).run();let o=t.select().from(f.drives).where($(f.drives.orgId,e.orgId)).get();if(o)t.insert(f.driveMembers).values({driveId:o.id,userId:n.id,role:e.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:e.role}}).run()}var yo=g(()=>{a();lo()});import{eq as Xf}from"drizzle-orm";function Ff(t){let e=new Bun.CryptoHasher("sha256");return e.update(t),e.digest("hex")}function wd(){let t=new Uint8Array(32);return crypto.getRandomValues(t),`af_${Array.from(t,(n)=>n.toString(16).padStart(2,"0")).join("")}`}function Nd(){return crypto.randomUUID()}function q(t,e){let n=Nd(),o=wd(),i=Ff(o),r=new Date;return t.insert(f.users).values({id:n,email:e.email,apiKeyHash:i,createdAt:r}).run(),mt(t,{name:e.email.split("@")[0],userId:n,isPersonal:!0}),{user:{id:n,email:e.email},apiKey:o}}function st(t,e){let n=Ff(e),o=t.select().from(f.users).where(Xf(f.users.apiKeyHash,n)).get();if(!o)return null;return{id:o.id,email:o.email}}function bt(t,e){let n=t.select().from(f.users).where(Xf(f.users.email,e)).get();if(!n)return null;return{id:n.id,email:n.email}}var so=g(()=>{a();yo()});import{eq as pt,and as go}from"drizzle-orm";function x(t,e){if(e.driveId){let r=t.select().from(f.drives).where(pt(f.drives.id,e.driveId)).get();if(!r)throw Error(`Drive not found: ${e.driveId}`);let u=Et(t,e.userId,e.driveId);if(!u)throw Error("You do not have access to this drive");return{orgId:r.orgId,driveId:e.driveId,role:u}}if(e.orgId){let r=t.select().from(f.drives).where(go(pt(f.drives.orgId,e.orgId),pt(f.drives.isDefault,!0))).get();if(!r)throw Error(`No default drive for org: ${e.orgId}`);let u=Et(t,e.userId,r.id);if(!u)throw Error("You do not have access to this drive");return{orgId:e.orgId,driveId:r.id,role:u}}let n=t.select({orgId:f.orgMembers.orgId}).from(f.orgMembers).innerJoin(f.orgs,pt(f.orgMembers.orgId,f.orgs.id)).where(go(pt(f.orgMembers.userId,e.userId),pt(f.orgs.isPersonal,!0))).get();if(!n)throw Error("No personal org found for user");let o=t.select().from(f.drives).where(go(pt(f.drives.orgId,n.orgId),pt(f.drives.isDefault,!0))).get();if(!o)throw Error("No default drive found");let i=Et(t,e.userId,o.id);if(!i)throw Error("You do not have access to your default drive");return{orgId:n.orgId,driveId:o.id,role:i}}var Hf=g(()=>{a();me()});function le(t){let e=L();if(e.auth.apiKey){if(st(t,e.auth.apiKey))return{apiKey:e.auth.apiKey}}console.error("[agent-fs] No local user found, creating one...");let n=q(t,{email:"local@agent-fs.local"});return N("auth.apiKey",n.apiKey),console.error("[agent-fs] Local user created automatically."),{apiKey:n.apiKey}}var Yf=g(()=>{zt();so()});var Gf=g(()=>{so();yo();lo();me();Hf();Yf()});var Bf;var Zf=g(()=>{Bf={name:"agent-fs",version:"0.5.4",private:!0,workspaces:["packages/*"],scripts:{typecheck:"tsc --build",test:"bun test packages/*/src/","test:coverage":"bun test --coverage packages/*/src/",build:"cd packages/cli && bun run build:npm","install-local":"bun run build && cd packages/cli && bun link","uninstall-local":"bun remove -g @desplega.ai/agent-fs && rm -f ~/.bun/bin/agent-fs","deploy:fly":"fly deploy -a agent-fs-taras"},devDependencies:{"bun-types":"^1.2.0",typescript:"^5.7.0",yaml:"^2.8.2","zod-to-json-schema":"^3.25.1"},overrides:{chromadb:"npm:empty-npm-package@1.0.0","chromadb-default-embed":"npm:empty-npm-package@1.0.0","@xenova/transformers":"npm:empty-npm-package@1.0.0","tree-sitter-wasms":"npm:empty-npm-package@1.0.0","web-tree-sitter":"npm:empty-npm-package@1.0.0","cohere-ai":"npm:empty-npm-package@1.0.0",voyageai:"npm:empty-npm-package@1.0.0",ollama:"npm:empty-npm-package@1.0.0"}}});var B;var To=g(()=>{Zf();B=Bf.version});var Vf={};Ft(Vf,{LocalEmbeddingProvider:()=>Qf});import{join as Id}from"path";import{mkdirSync as _d,existsSync as Dd}from"fs";class Qf{name="local";dimensions=768;llama=null;model=null;embeddingContext=null;initPromise=null;async init(){if(this.embeddingContext)return;if(this.initPromise)return this.initPromise;return this.initPromise=this._doInit(),this.initPromise}async _doInit(){let{getLlama:t,resolveModelFile:e}=await import("node-llama-cpp");this.llama=await t();let n=Id(nt(),"models");if(!Dd(n))_d(n,{recursive:!0});console.error("[agent-fs] Resolving local embedding model...");let o=await e(vd,n);console.error("[agent-fs] Model ready:",o),this.model=await this.llama.loadModel({modelPath:o}),this.embeddingContext=await this.model.createEmbeddingContext()}async embed(t){await this.init();let e=await this.embeddingContext.getEmbeddingFor(t);return Array.from(e.vector)}async embedBatch(t){await this.init();let e=[];for(let n of t){let o=await this.embeddingContext.getEmbeddingFor(n);e.push(Array.from(o.vector))}return e}async dispose(){if(this.embeddingContext)await this.embeddingContext.dispose(),this.embeddingContext=null;if(this.model)await this.model.dispose(),this.model=null;this.initPromise=null}}var vd="hf:nomic-ai/nomic-embed-text-v1.5-GGUF:Q8_0";var Jf=g(()=>{zt()});var Ro={};Ft(Ro,{OpenAIEmbeddingProvider:()=>Wf});import Ld from"openai";class Wf{name="openai";dimensions=768;client;constructor(t){this.client=new Ld({apiKey:t})}async embed(t){return(await this.client.embeddings.create({model:"text-embedding-3-small",input:t,dimensions:768})).data[0].embedding}async embedBatch(t){return(await this.client.embeddings.create({model:"text-embedding-3-small",input:t,dimensions:768})).data.sort((n,o)=>n.index-o.index).map((n)=>n.embedding)}}var Ao=()=>{};var wo={};Ft(wo,{GeminiEmbeddingProvider:()=>Kf});import{GoogleGenAI as Od}from"@google/genai";class Kf{name="gemini";dimensions=768;client;constructor(t){this.client=new Od({apiKey:t})}async embed(t){return(await this.client.models.embedContent({model:"gemini-embedding-001",contents:t,config:{outputDimensionality:768}})).embeddings[0].values}async embedBatch(t){let e=[];for(let n of t){let o=await this.client.models.embedContent({model:"gemini-embedding-001",contents:n,config:{outputDimensionality:768}});e.push(o.embeddings[0].values)}return e}}var No=()=>{};async function bf(t){switch(t.provider){case"local":{let{LocalEmbeddingProvider:e}=await Promise.resolve().then(() => (Jf(),Vf));return new e}case"openai":{if(!t.apiKey)throw Error("OpenAI API key required. Set embedding.apiKey in config.");let{OpenAIEmbeddingProvider:e}=await Promise.resolve().then(() => (Ao(),Ro));return new e(t.apiKey)}case"gemini":{if(!t.apiKey)throw Error("Gemini API key required. Set embedding.apiKey in config.");let{GeminiEmbeddingProvider:e}=await Promise.resolve().then(() => (No(),wo));return new e(t.apiKey)}default:throw Error(`Unknown embedding provider: ${t.provider}`)}}async function kt(t){if(process.env.OPENAI_API_KEY)try{let{OpenAIEmbeddingProvider:e}=await Promise.resolve().then(() => (Ao(),Ro));return new e(process.env.OPENAI_API_KEY)}catch(e){console.error("[agent-fs] Failed to load OpenAI provider:",e)}if(process.env.GEMINI_API_KEY)try{let{GeminiEmbeddingProvider:e}=await Promise.resolve().then(() => (No(),wo));return new e(process.env.GEMINI_API_KEY)}catch(e){console.error("[agent-fs] Failed to load Gemini provider:",e)}if(t?.provider&&t.provider!=="local"&&t.apiKey)try{return await bf(t)}catch(e){console.error("[agent-fs] Failed to create embedding provider from config:",e)}if(t?.provider==="local")try{return await bf(t)}catch(e){console.error("[agent-fs] Failed to load local embedding provider:",e)}return null}var jf,kf,zf=(t)=>typeof t==="string"?{...kf,name:t}:{...kf,...t};var Ze=g(()=>{jf=Symbol("Let zodToJsonSchema decide on which parser to use"),kf={name:void 0,$refStrategy:"root",basePath:["#"],effectStrategy:"input",pipeStrategy:"all",dateStrategy:"format:date-time",mapStrategy:"entries",removeAdditionalStrategy:"passthrough",allowedAdditionalProperties:!0,rejectedAdditionalProperties:!1,definitionPath:"definitions",target:"jsonSchema7",strictUnions:!1,definitions:{},errorMessages:!1,markdownDescription:!1,patternStrategy:"escape",applyRegexFlags:!1,emailStrategy:"format:email",base64Strategy:"contentEncoding:base64",nameStrategy:"ref",openAiAnyTypeName:"OpenAiAnyType"}});var qf=(t)=>{let e=zf(t),n=e.name!==void 0?[...e.basePath,e.definitionPath,e.name]:e.basePath;return{...e,flags:{hasReferencedOpenAiAnyType:!1},currentPath:n,propertyPath:void 0,seen:new Map(Object.entries(e.definitions).map(([o,i])=>[i._def,{def:i._def,path:[...e.basePath,e.definitionPath,o],jsonSchema:void 0}]))}};var po=g(()=>{Ze()});function Io(t,e,n,o){if(!o?.errorMessages)return;if(n)t.errorMessage={...t.errorMessage,[e]:n}}function D(t,e,n,o,i){t[e]=n,Io(t,e,o,i)}var Be=(t,e)=>{let n=0;for(;n<t.length&&n<e.length;n++)if(t[n]!==e[n])break;return[(t.length-n).toString(),...e.slice(n)].join("/")};function m(t){if(t.target!=="openAi")return{};let e=[...t.basePath,t.definitionPath,t.openAiAnyTypeName];return t.flags.hasReferencedOpenAiAnyType=!0,{$ref:t.$refStrategy==="relative"?Be(e,t.currentPath):e.join("/")}}var b=()=>{};import{ZodFirstPartyTypeKind as Sd}from"zod/v3";function xf(t,e){let n={type:"array"};if(t.type?._def&&t.type?._def?.typeName!==Sd.ZodAny)n.items=w(t.type._def,{...e,currentPath:[...e.currentPath,"items"]});if(t.minLength)D(n,"minItems",t.minLength.value,t.minLength.message,e);if(t.maxLength)D(n,"maxItems",t.maxLength.value,t.maxLength.message,e);if(t.exactLength)D(n,"minItems",t.exactLength.value,t.exactLength.message,e),D(n,"maxItems",t.exactLength.value,t.exactLength.message,e);return n}var _o=g(()=>{c()});function tE(t,e){let n={type:"integer",format:"int64"};if(!t.checks)return n;for(let o of t.checks)switch(o.kind){case"min":if(e.target==="jsonSchema7")if(o.inclusive)D(n,"minimum",o.value,o.message,e);else D(n,"exclusiveMinimum",o.value,o.message,e);else{if(!o.inclusive)n.exclusiveMinimum=!0;D(n,"minimum",o.value,o.message,e)}break;case"max":if(e.target==="jsonSchema7")if(o.inclusive)D(n,"maximum",o.value,o.message,e);else D(n,"exclusiveMaximum",o.value,o.message,e);else{if(!o.inclusive)n.exclusiveMaximum=!0;D(n,"maximum",o.value,o.message,e)}break;case"multipleOf":D(n,"multipleOf",o.value,o.message,e);break}return n}var Do=()=>{};function eE(){return{type:"boolean"}}function Qe(t,e){return w(t.type._def,e)}var Ve=g(()=>{c()});var nE=(t,e)=>{return w(t.innerType._def,e)};var vo=g(()=>{c()});function Lo(t,e,n){let o=n??e.dateStrategy;if(Array.isArray(o))return{anyOf:o.map((i,r)=>Lo(t,e,i))};switch(o){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return Ud(t,e)}}var Ud=(t,e)=>{let n={type:"integer",format:"unix-time"};if(e.target==="openApi3")return n;for(let o of t.checks)switch(o.kind){case"min":D(n,"minimum",o.value,o.message,e);break;case"max":D(n,"maximum",o.value,o.message,e);break}return n};var Oo=()=>{};function oE(t,e){return{...w(t.innerType._def,e),default:t.defaultValue()}}var So=g(()=>{c()});function iE(t,e){return e.effectStrategy==="input"?w(t.schema._def,e):m(e)}var Uo=g(()=>{c();b()});function rE(t){return{type:"string",enum:Array.from(t.values)}}function uE(t,e){let n=[w(t.left._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),w(t.right._def,{...e,currentPath:[...e.currentPath,"allOf","1"]})].filter((r)=>!!r),o=e.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,i=[];return n.forEach((r)=>{if(hd(r)){if(i.push(...r.allOf),r.unevaluatedProperties===void 0)o=void 0}else{let u=r;if("additionalProperties"in r&&r.additionalProperties===!1){let{additionalProperties:E,...l}=r;u=l}else o=void 0;i.push(u)}}),i.length?{allOf:i,...o}:void 0}var hd=(t)=>{if("type"in t&&t.type==="string")return!1;return"allOf"in t};var ho=g(()=>{c()});function fE(t,e){let n=typeof t.value;if(n!=="bigint"&&n!=="number"&&n!=="boolean"&&n!=="string")return{type:Array.isArray(t.value)?"array":"object"};if(e.target==="openApi3")return{type:n==="bigint"?"integer":n,enum:[t.value]};return{type:n==="bigint"?"integer":n,const:t.value}}function Je(t,e){let n={type:"string"};if(t.checks)for(let o of t.checks)switch(o.kind){case"min":D(n,"minLength",typeof n.minLength==="number"?Math.max(n.minLength,o.value):o.value,o.message,e);break;case"max":D(n,"maxLength",typeof n.maxLength==="number"?Math.min(n.maxLength,o.value):o.value,o.message,e);break;case"email":switch(e.emailStrategy){case"format:email":et(n,"email",o.message,e);break;case"format:idn-email":et(n,"idn-email",o.message,e);break;case"pattern:zod":G(n,tt.email,o.message,e);break}break;case"url":et(n,"uri",o.message,e);break;case"uuid":et(n,"uuid",o.message,e);break;case"regex":G(n,o.regex,o.message,e);break;case"cuid":G(n,tt.cuid,o.message,e);break;case"cuid2":G(n,tt.cuid2,o.message,e);break;case"startsWith":G(n,RegExp(`^${ao(o.value,e)}`),o.message,e);break;case"endsWith":G(n,RegExp(`${ao(o.value,e)}$`),o.message,e);break;case"datetime":et(n,"date-time",o.message,e);break;case"date":et(n,"date",o.message,e);break;case"time":et(n,"time",o.message,e);break;case"duration":et(n,"duration",o.message,e);break;case"length":D(n,"minLength",typeof n.minLength==="number"?Math.max(n.minLength,o.value):o.value,o.message,e),D(n,"maxLength",typeof n.maxLength==="number"?Math.min(n.maxLength,o.value):o.value,o.message,e);break;case"includes":{G(n,RegExp(ao(o.value,e)),o.message,e);break}case"ip":{if(o.version!=="v6")et(n,"ipv4",o.message,e);if(o.version!=="v4")et(n,"ipv6",o.message,e);break}case"base64url":G(n,tt.base64url,o.message,e);break;case"jwt":G(n,tt.jwt,o.message,e);break;case"cidr":{if(o.version!=="v6")G(n,tt.ipv4Cidr,o.message,e);if(o.version!=="v4")G(n,tt.ipv6Cidr,o.message,e);break}case"emoji":G(n,tt.emoji(),o.message,e);break;case"ulid":{G(n,tt.ulid,o.message,e);break}case"base64":{switch(e.base64Strategy){case"format:binary":{et(n,"binary",o.message,e);break}case"contentEncoding:base64":{D(n,"contentEncoding","base64",o.message,e);break}case"pattern:zod":{G(n,tt.base64,o.message,e);break}}break}case"nanoid":G(n,tt.nanoid,o.message,e);case"toLowerCase":case"toUpperCase":case"trim":break;default:((i)=>{})(o)}return n}function ao(t,e){return e.patternStrategy==="escape"?ad(t):t}function ad(t){let e="";for(let n=0;n<t.length;n++){if(!md.has(t[n]))e+="\\";e+=t[n]}return e}function et(t,e,n,o){if(t.format||t.anyOf?.some((i)=>i.format)){if(!t.anyOf)t.anyOf=[];if(t.format){if(t.anyOf.push({format:t.format,...t.errorMessage&&o.errorMessages&&{errorMessage:{format:t.errorMessage.format}}}),delete t.format,t.errorMessage){if(delete t.errorMessage.format,Object.keys(t.errorMessage).length===0)delete t.errorMessage}}t.anyOf.push({format:e,...n&&o.errorMessages&&{errorMessage:{format:n}}})}else D(t,"format",e,n,o)}function G(t,e,n,o){if(t.pattern||t.allOf?.some((i)=>i.pattern)){if(!t.allOf)t.allOf=[];if(t.pattern){if(t.allOf.push({pattern:t.pattern,...t.errorMessage&&o.errorMessages&&{errorMessage:{pattern:t.errorMessage.pattern}}}),delete t.pattern,t.errorMessage){if(delete t.errorMessage.pattern,Object.keys(t.errorMessage).length===0)delete t.errorMessage}}t.allOf.push({pattern:EE(e,o),...n&&o.errorMessages&&{errorMessage:{pattern:n}}})}else D(t,"pattern",EE(e,o),n,o)}function EE(t,e){if(!e.applyRegexFlags||!t.flags)return t.source;let n={i:t.flags.includes("i"),m:t.flags.includes("m"),s:t.flags.includes("s")},o=n.i?t.source.toLowerCase():t.source,i="",r=!1,u=!1,E=!1;for(let l=0;l<o.length;l++){if(r){i+=o[l],r=!1;continue}if(n.i){if(u){if(o[l].match(/[a-z]/)){if(E)i+=o[l],i+=`${o[l-2]}-${o[l]}`.toUpperCase(),E=!1;else if(o[l+1]==="-"&&o[l+2]?.match(/[a-z]/))i+=o[l],E=!0;else i+=`${o[l]}${o[l].toUpperCase()}`;continue}}else if(o[l].match(/[a-z]/)){i+=`[${o[l]}${o[l].toUpperCase()}]`;continue}}if(n.m){if(o[l]==="^"){i+=`(^|(?<=[\r
|
|
169
169
|
]))`;continue}else if(o[l]==="$"){i+=`($|(?=[\r
|
|
170
170
|
]))`;continue}}if(n.s&&o[l]==="."){i+=u?`${o[l]}\r
|
|
171
171
|
`:`[${o[l]}\r
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-fs",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first filesystem backed by S3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"prepublishOnly": "bun run build:npm"
|
|
31
31
|
},
|
|
32
32
|
"optionalDependencies": {
|
|
33
|
-
"sqlite-vec-darwin-arm64": "^0.1.
|
|
34
|
-
"sqlite-vec-darwin-x64": "^0.1.
|
|
35
|
-
"sqlite-vec-linux-arm64": "^0.1.
|
|
36
|
-
"sqlite-vec-linux-x64": "^0.1.
|
|
37
|
-
"sqlite-vec-windows-x64": "^0.1.
|
|
33
|
+
"sqlite-vec-darwin-arm64": "^0.1.9",
|
|
34
|
+
"sqlite-vec-darwin-x64": "^0.1.9",
|
|
35
|
+
"sqlite-vec-linux-arm64": "^0.1.9",
|
|
36
|
+
"sqlite-vec-linux-x64": "^0.1.9",
|
|
37
|
+
"sqlite-vec-windows-x64": "^0.1.9"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"commander": "^14.0.3",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"drizzle-orm": "^0.44.0",
|
|
46
46
|
"node-llama-cpp": "^3.17.1",
|
|
47
47
|
"openai": "^6.29.0",
|
|
48
|
-
"sqlite-vec": "^0.1.
|
|
48
|
+
"sqlite-vec": "^0.1.9",
|
|
49
49
|
"zod": "^3.24.0",
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
51
51
|
"hono": "^4.12.8"
|