@desplega.ai/agent-fs 0.6.0 → 0.6.1
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/dist/fuse-bin.manifest.json +3 -3
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -169,7 +169,7 @@ ${St.toHex(r)}`}getCanonicalPath({path:t}){if(this.uriEscapePath){let n=[];for(l
|
|
|
169
169
|
FROM chunk_vectors
|
|
170
170
|
WHERE embedding MATCH ?
|
|
171
171
|
ORDER BY distance
|
|
172
|
-
LIMIT ?`).all(r,o),T=[],N=new Set;for(let R of u){let l=t.db.select().from(f.contentChunks).where(Oi(f.contentChunks.id,R.chunk_id)).get();if(!l||l.driveId!==t.driveId)continue;if(N.has(l.filePath))continue;N.add(l.filePath);let _=t.db.select().from(f.files).where(el(Oi(f.files.path,l.filePath),Oi(f.files.driveId,t.driveId))).get();T.push({path:l.filePath,snippet:l.content.slice(0,200),author:_?.author,modifiedAt:_?.modifiedAt})}return T}function El(t,n,o){let i=n.split(/\s+/).filter(Boolean).map((e)=>`"${e}"`).join(" OR ");if(!i)return[];try{return sn(t.db,{pattern:i,driveId:t.driveId}).slice(0,o).map((r)=>({path:r.path,snippet:r.snippet}))}catch{return[]}}var zf=A(()=>{H()});import{eq as xn,and as fl,or as ul,isNull as Tl}from"drizzle-orm";async function df(t,n){let o=[xn(f.files.driveId,t.driveId),xn(f.files.isDeleted,!1),ul(xn(f.files.embeddingStatus,"failed"),Tl(f.files.embeddingStatus),xn(f.files.embeddingStatus,"pending"))];if(n.path){let{like:T}=await import("drizzle-orm"),N=n.path.endsWith("/")?n.path:n.path+"/";o.push(T(f.files.path,N+"%"))}let i=t.db.select({path:f.files.path}).from(f.files).where(fl(...o)).all(),e=0,r=0,E=0,u=3;for(let T=0;T<i.length;T+=u){let N=i.slice(T,T+u),R=await Promise.allSettled(N.map(async(l)=>{let _=U(t.orgId,t.driveId,l.path),O=await t.s3.getObject(_),L=new TextDecoder().decode(O.body);if(s(t.db,{path:l.path,driveId:t.driveId,content:L}),t.embeddingProvider)return await _i(t.db,t.embeddingProvider,{path:l.path,driveId:t.driveId,content:L}),"reindexed";return"skipped"}));for(let l of R)if(l.status==="fulfilled")if(l.value==="reindexed")e++;else E++;else console.error("Reindex failed:",l.reason),r++}return{reindexed:e,failed:r,skipped:E}}var mf=A(()=>{H();V();tn()});import{eq as bf,and as Nl,like as Rl}from"drizzle-orm";async function qf(t,n){let o=Xt(n.path??"/"),i=U(t.orgId,t.driveId,o),{objects:e}=await t.s3.listObjects(i),r=t.db.select().from(f.files).where(Nl(bf(f.files.driveId,t.driveId),Rl(f.files.path,o+"%"),bf(f.files.isDeleted,!1))).all(),E=new Map(r.map((T)=>[T.path,T])),u=[];for(let T of e){let N=T.key.slice(i.length);if(!N)continue;let R=N.split("/").filter(Boolean);if(R.length===0)continue;if(n.depth!==void 0&&R.length>n.depth)continue;let l=u;for(let _=0;_<R.length;_++){let O=R[_],L=_===R.length-1,F=!L||N.endsWith("/");if(F&&!L){let X=l.find((Z)=>Z.name===O&&Z.type==="directory");if(!X)X={name:O,type:"directory",children:[]},l.push(X);if(!X.children)X.children=[];l=X.children}else if(F&&L){let X=l.find((Z)=>Z.name===O&&Z.type==="directory");if(!X)X={name:O,type:"directory",children:[]},l.push(X)}else{let X=o+R.slice(0,_+1).join("/"),Z=E.get(X),Tn={name:O,type:"file",size:Z?.size??T.size};if(Z?.author)Tn.author=Z.author;if(Z?.modifiedAt??T.lastModified)Tn.modifiedAt=Z?.modifiedAt??T.lastModified;l.push(Tn)}}}return{tree:u}}var sf=A(()=>{H();V()});import{eq as cf,and as Al,like as yl}from"drizzle-orm";function ll(t){let n="",o=0;while(o<t.length){let i=t[o];if(i==="*")if(t[o+1]==="*"){if(n+=".*",o+=2,t[o]==="/")o++}else n+="[^/]*",o++;else if(i==="?")n+="[^/]",o++;else if(".+^${}()|[]\\".includes(i))n+="\\"+i,o++;else n+=i,o++}return new RegExp("^"+n+"$")}async function xf(t,n){let o=n.path?Xt(n.path):"/",i=U(t.orgId,t.driveId,o),{objects:e}=await t.s3.listObjects(i),r=t.db.select().from(f.files).where(Al(cf(f.files.driveId,t.driveId),yl(f.files.path,o+"%"),cf(f.files.isDeleted,!1))).all(),E=new Map(r.map((N)=>[N.path,N])),u=ll(n.pattern),T=[];for(let N of e){let R=N.key.slice(i.length);if(!R||R.endsWith("/"))continue;if(u.test(R)){let l=o+R,_=E.get(l);T.push({path:l,size:_?.size??N.size,modifiedAt:_?.modifiedAt??N.lastModified})}}return{matches:T}}var af=A(()=>{H();V()});async function tu(t,n){let o=In(n.path),i=U(t.orgId,t.driveId,o),e=n.expiresIn??86400;try{await t.s3.headObject(i)}catch(u){if(u?.name==="NotFound"||u?.name==="NoSuchKey"||u?.$metadata?.httpStatusCode===404)throw new v(`File not found: ${o}`,{path:o});throw u}let r=lt(o);return{url:await t.s3.getPresignedUrl(i,e,r!=="application/octet-stream"?r:void 0),path:o,expiresIn:e,expiresAt:new Date(Date.now()+e*1000).toISOString()}}var nu=A(()=>{V();z();xt()});function Ii(t,n,o,i){let e=i.startsWith("/")?i.slice(1):i;return`${t}/file/~/${n}/${o}/${e}`}import{eq as P,and as _t,sql as Ui,desc as ou}from"drizzle-orm";function Si(t,n){t.db.insert(f.events).values({id:crypto.randomUUID(),orgId:t.orgId,type:n.type,resourceType:n.resourceType,resourceId:n.resourceId,actor:t.userId,target:n.target??null,status:"created",metadata:n.metadata?JSON.stringify(n.metadata):null,createdAt:new Date}).run()}function an(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 to(t,n){let o=new Date,i=crypto.randomUUID(),e=n.path;if(n.parentId){let E=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.parentId),P(f.comments.isDeleted,!1))).get();if(!E)throw new v("Parent comment not found",{suggestion:"Check that the parent comment ID is correct and not deleted"});if(E.parentId)throw new it("Cannot reply to a reply \u2014 only root comments accept replies",{suggestion:"Reply to the root comment instead"});if(!e)e=E.path}if(!e)throw new it("path is required for root comments",{field:"path"});let r=t.db.select({id:f.fileVersions.id}).from(f.fileVersions).where(_t(P(f.fileVersions.path,e),P(f.fileVersions.driveId,t.driveId))).orderBy(ou(f.fileVersions.id)).limit(1).get();return t.db.insert(f.comments).values({id:i,parentId:n.parentId??null,orgId:t.orgId,driveId:t.driveId,path:e,lineStart:n.lineStart??null,lineEnd:n.lineEnd??null,quotedContent:n.quotedContent??null,fileVersionId:r?.id??null,body:n.body,author:t.userId,resolved:!1,createdAt:o,updatedAt:o,isDeleted:!1}).run(),Si(t,{type:"comment_created",resourceType:"comment",resourceId:i,metadata:{path:e,parentId:n.parentId}}),{id:i,path:e,body:n.body,parentId:n.parentId,lineStart:n.lineStart,lineEnd:n.lineEnd,author:t.userId,createdAt:o}}async function no(t,n){let o=[P(f.comments.driveId,t.driveId),P(f.comments.isDeleted,!1)];if(n.path)o.push(P(f.comments.path,n.path));if(n.parentId)o.push(P(f.comments.parentId,n.parentId));else if(n.parentId===void 0&&!n.resolved)o.push(Ui`${f.comments.parentId} IS NULL`),o.push(P(f.comments.resolved,!1));else if(n.parentId===void 0&&n.resolved)o.push(Ui`${f.comments.parentId} IS NULL`);if(n.orgId)o.push(P(f.comments.orgId,n.orgId));let i=n.limit??50,e=n.offset??0;return{comments:t.db.select().from(f.comments).where(_t(...o)).orderBy(ou(f.comments.createdAt)).limit(i).offset(e).all().map((u)=>{let N=t.db.select().from(f.comments).where(_t(P(f.comments.parentId,u.id),P(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((R)=>an({...R,replyCount:0}));return{...an({...u,replyCount:N.length}),replies:N}})}}async function oo(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});let i=t.db.select({count:Ui`count(*)`}).from(f.comments).where(_t(P(f.comments.parentId,o.id),P(f.comments.isDeleted,!1))).get(),e=an({...o,replyCount:i?.count??0}),E=t.db.select().from(f.comments).where(_t(P(f.comments.parentId,n.id),P(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((u)=>an({...u,replyCount:0}));return{comment:e,replies:E}}async function io(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.author!==t.userId)throw new nt("You can only edit your own comments",{suggestion:"Only the comment author can update it"});let i=new Date;return t.db.update(f.comments).set({body:n.body,updatedAt:i}).where(P(f.comments.id,n.id)).run(),{id:n.id,body:n.body,updatedAt:i}}async function eo(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.author!==t.userId)throw new nt("You can only delete your own comments",{suggestion:"Only the comment author can delete it"});let i=new Date;if(t.db.update(f.comments).set({isDeleted:!0,updatedAt:i}).where(P(f.comments.id,n.id)).run(),!o.parentId)t.db.update(f.comments).set({isDeleted:!0,updatedAt:i}).where(P(f.comments.parentId,n.id)).run();return Si(t,{type:"comment_deleted",resourceType:"comment",resourceId:n.id}),{deleted:!0}}async function ro(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.parentId)throw new it("Cannot resolve a reply \u2014 only root comments can be resolved",{suggestion:"Resolve the parent comment instead"});let i=new Date,e=n.resolved?i:null,r=n.resolved?t.userId:null;return t.db.update(f.comments).set({resolved:n.resolved,resolvedBy:r,resolvedAt:e,updatedAt:i}).where(P(f.comments.id,n.id)).run(),Si(t,{type:n.resolved?"comment_resolved":"comment_reopened",resourceType:"comment",resourceId:n.id}),{id:n.id,resolved:n.resolved,resolvedBy:r??void 0,resolvedAt:e??void 0}}var iu=A(()=>{H();z()});import{z as y}from"zod";async function j(t,n,o,i){let e=$i[n];if(!e)throw Error(`Unknown operation: ${n}`);if(!i?.skipAuth){let u=Dn(n);On(t.db,{userId:t.userId,driveId:t.driveId,requiredRole:u})}let r=e.schema.parse(o),E=await e.handler(t,r);if(t.appUrl&&E&&typeof E==="object"){if("path"in E)E.appUrl=Ii(t.appUrl,t.orgId,t.driveId,E.path);else if("to"in E)E.appUrl=Ii(t.appUrl,t.orgId,t.driveId,E.to)}return E}function en(){return Object.keys($i)}function Pt(t){return $i[t]}var $i;var Xi=A(()=>{dn();rf();ff();Tf();Rf();lf();gf();Df();Uf();$f();Cf();Mf();Gf();Hf();Bf();Vf();pf();hf();zf();mf();sf();af();nu();iu();$i={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:cn,schema:y.object({path:y.string(),content:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},cat:{description:"Read file content with optional pagination via offset/limit. Returns { content, totalLines, truncated }.",handler:Ef,schema:y.object({path:y.string(),offset:y.number().int().min(0).optional(),limit:y.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:uf,schema:y.object({path:y.string(),old_string:y.string(),new_string:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},append:{description:"Append content to the end of an existing file. Creates a new version. Returns { version, size }.",handler:Nf,schema:y.object({path:y.string(),content:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},ls:{description:"List immediate children of a directory. Returns { entries } where each entry has name, type (file/directory), size, author, modifiedAt.",handler:yf,schema:y.object({path:y.string().optional()})},stat:{description:"Get file metadata without reading content. Returns path, size, contentType, author, currentVersion, createdAt, modifiedAt, isDeleted, embeddingStatus.",handler:wf,schema:y.object({path:y.string()})},rm:{description:"Delete a file. Removes from S3, cleans up FTS5 index and vector embeddings. Returns { path, deleted }.",handler:Lf,schema:y.object({path:y.string(),expectedVersion:y.number().int().optional()})},mv:{description:"Move or rename a file. Preserves version history at the new path. Returns { from, to, version }.",handler:If,schema:y.object({from:y.string(),to:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},cp:{description:"Copy a file using server-side S3 copy. Creates a new version at the destination. Returns { from, to, version }.",handler:Sf,schema:y.object({from:y.string(),to:y.string(),expectedVersion:y.number().int().optional()})},tail:{description:"Read the last N lines of a file (default 20). Returns { content, totalLines, truncated }.",handler:Xf,schema:y.object({path:y.string(),lines:y.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:vf,schema:y.object({path:y.string(),limit:y.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:Yf,schema:y.object({path:y.string(),v1:y.number().int(),v2:y.number().int()})},revert:{description:"Revert a file to a previous version. Creates a new version with the old content. Returns { version, revertedTo }.",handler:Zf,schema:y.object({path:y.string(),version:y.number().int(),expectedVersion:y.number().int().optional()})},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:Jf,schema:y.object({path:y.string().optional(),since:y.coerce.date().optional(),limit:y.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:Wf,schema:y.object({pattern:y.string(),path:y.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:Kf,schema:y.object({pattern:y.string(),path:y.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:kf,schema:y.object({query:y.string(),limit:y.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:jf,schema:y.object({query:y.string(),limit:y.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:df,schema:y.object({path:y.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:qf,schema:y.object({path:y.string().optional(),depth:y.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:xf,schema:y.object({pattern:y.string(),path:y.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:tu,schema:y.object({path:y.string(),expiresIn:y.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:to,schema:y.object({path:y.string().optional(),body:y.string(),parentId:y.string().optional(),lineStart:y.number().int().optional(),lineEnd:y.number().int().optional(),quotedContent:y.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:no,schema:y.object({path:y.string().optional(),parentId:y.string().optional(),resolved:y.boolean().optional(),orgId:y.string().optional(),limit:y.number().int().min(1).optional(),offset:y.number().int().min(0).optional()})},"comment-get":{description:"Get a single comment by ID with all its replies. Returns { comment, replies }.",handler:oo,schema:y.object({id:y.string()})},"comment-update":{description:"Update a comment's body. Only the original author can update. Returns { id, body, updatedAt }.",handler:io,schema:y.object({id:y.string(),body:y.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:eo,schema:y.object({id:y.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:ro,schema:y.object({id:y.string(),resolved:y.boolean()})}}});import{eq as d,and as Eo}from"drizzle-orm";function Zt(t,n){let o=crypto.randomUUID(),i=new Date;return t.insert(f.drives).values({id:o,orgId:n.orgId,name:n.name,isDefault:n.isDefault??!1,createdAt:i}).run(),{id:o,name:n.name}}function Sn(t,n){return t.select().from(f.drives).where(d(f.drives.orgId,n)).all().map((o)=>({id:o.id,name:o.name,isDefault:o.isDefault}))}function Lt(t,n,o){return t.select().from(f.drives).where(d(f.drives.orgId,n)).all().filter((e)=>{let r=t.select({userId:f.driveMembers.userId}).from(f.driveMembers).where(d(f.driveMembers.driveId,e.id)).all();if(r.length===0)return!0;return r.some((E)=>E.userId===o)}).map((e)=>({id:e.id,name:e.name,isDefault:e.isDefault}))}function Ci(t,n){let o=t.select().from(f.drives).where(d(f.drives.id,n)).get();if(!o)return null;return{id:o.id,name:o.name,orgId:o.orgId,isDefault:o.isDefault}}function Ht(t,n){return t.select({userId:f.driveMembers.userId,email:f.users.email,role:f.driveMembers.role}).from(f.driveMembers).innerJoin(f.users,d(f.driveMembers.userId,f.users.id)).where(d(f.driveMembers.driveId,n)).all()}function Qt(t,n){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).get())throw Error("Member not found in drive");t.update(f.driveMembers).set({role:n.role}).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).run()}function Jt(t,n){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).get())throw Error("Member not found in drive");t.delete(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).run()}function Pi(t,n){t.insert(f.driveMembers).values({driveId:n.driveId,userId:n.userId,role:n.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:n.role}}).run()}var vi=A(()=>{H()});import{eq as Q,and as Bt,sql as eu}from"drizzle-orm";function Wt(t,n){let o=crypto.randomUUID(),i=new Date;t.insert(f.orgs).values({id:o,name:n.name,isPersonal:n.isPersonal??!1,createdAt:i}).run(),t.insert(f.orgMembers).values({orgId:o,userId:n.userId,role:"admin"}).run();let e=Zt(t,{orgId:o,name:"default",isDefault:!0});return t.insert(f.driveMembers).values({driveId:e.id,userId:n.userId,role:"admin"}).run(),{id:o,name:n.name}}function K(t,n){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,Q(f.orgMembers.orgId,f.orgs.id)).where(Q(f.orgMembers.userId,n)).all().map((i)=>({id:i.orgId,name:i.name,role:i.role,isPersonal:i.isPersonal}))}function $n(t,n){let o=t.select().from(f.orgs).where(Q(f.orgs.id,n)).get();if(!o)return null;return{id:o.id,name:o.name,isPersonal:o.isPersonal}}function Vt(t,n){return t.select({userId:f.orgMembers.userId,email:f.users.email,role:f.orgMembers.role}).from(f.orgMembers).innerJoin(f.users,Q(f.orgMembers.userId,f.users.id)).where(Q(f.orgMembers.orgId,n)).all()}function Kt(t,n){let o=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).get();if(!o)throw Error("Member not found in org");if(o.role==="admin"&&n.role!=="admin"){if(t.select({count:eu`count(*)`}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}t.update(f.orgMembers).set({role:n.role}).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).run()}function pt(t,n){if(t.select({isPersonal:f.orgs.isPersonal}).from(f.orgs).where(Q(f.orgs.id,n.orgId)).get()?.isPersonal)throw Error("Cannot remove members from a personal org");let i=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).get();if(!i)throw Error("Member not found in org");if(i.role==="admin"){if(t.select({count:eu`count(*)`}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}let e=t.select({id:f.drives.id}).from(f.drives).where(Q(f.drives.orgId,n.orgId)).all();for(let r of e)t.delete(f.driveMembers).where(Bt(Q(f.driveMembers.driveId,r.id),Q(f.driveMembers.userId,n.userId))).run();t.delete(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).run()}function jt(t,n){let o=t.select().from(f.users).where(Q(f.users.email,n.email)).get();if(!o)throw Error(`User with email ${n.email} not found`);t.insert(f.orgMembers).values({orgId:n.orgId,userId:o.id,role:n.role}).onConflictDoUpdate({target:[f.orgMembers.orgId,f.orgMembers.userId],set:{role:n.role}}).run();let i=t.select().from(f.drives).where(Q(f.drives.orgId,n.orgId)).get();if(i)t.insert(f.driveMembers).values({driveId:i.id,userId:o.id,role:n.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:n.role}}).run()}var Mi=A(()=>{H();vi()});import{eq as ru}from"drizzle-orm";function Eu(t){let n=new Bun.CryptoHasher("sha256");return n.update(t),n.digest("hex")}function _l(){let t=new Uint8Array(32);return crypto.getRandomValues(t),`af_${Array.from(t,(o)=>o.toString(16).padStart(2,"0")).join("")}`}function wl(){return crypto.randomUUID()}function et(t,n){let o=wl(),i=_l(),e=Eu(i),r=new Date;return t.insert(f.users).values({id:o,email:n.email,apiKeyHash:e,createdAt:r}).run(),Wt(t,{name:n.email.split("@")[0],userId:o,isPersonal:!0}),{user:{id:o,email:n.email},apiKey:i}}function rt(t,n){let o=Eu(n),i=t.select().from(f.users).where(ru(f.users.apiKeyHash,o)).get();if(!i)return null;return{id:i.id,email:i.email}}function rn(t,n){let o=t.select().from(f.users).where(ru(f.users.email,n)).get();if(!o)return null;return{id:o.id,email:o.email}}var Fi=A(()=>{H();Mi()});import{eq as vt,and as Yi}from"drizzle-orm";function m(t,n){if(n.driveId){let r=t.select().from(f.drives).where(vt(f.drives.id,n.driveId)).get();if(!r)throw Error(`Drive not found: ${n.driveId}`);let E=At(t,n.userId,n.driveId);if(!E)throw Error("You do not have access to this drive");return{orgId:r.orgId,driveId:n.driveId,role:E}}if(n.orgId){let r=t.select().from(f.drives).where(Yi(vt(f.drives.orgId,n.orgId),vt(f.drives.isDefault,!0))).get();if(!r)throw Error(`No default drive for org: ${n.orgId}`);let E=At(t,n.userId,r.id);if(!E)throw Error("You do not have access to this drive");return{orgId:n.orgId,driveId:r.id,role:E}}let o=t.select({orgId:f.orgMembers.orgId}).from(f.orgMembers).innerJoin(f.orgs,vt(f.orgMembers.orgId,f.orgs.id)).where(Yi(vt(f.orgMembers.userId,n.userId),vt(f.orgs.isPersonal,!0))).get();if(!o)throw Error("No personal org found for user");let i=t.select().from(f.drives).where(Yi(vt(f.drives.orgId,o.orgId),vt(f.drives.isDefault,!0))).get();if(!i)throw Error("No default drive found");let e=At(t,n.userId,i.id);if(!e)throw Error("You do not have access to your default drive");return{orgId:o.orgId,driveId:i.id,role:e}}var fu=A(()=>{H();dn()});function Xn(t){let n=C();if(n.auth.apiKey){if(rt(t,n.auth.apiKey))return{apiKey:n.auth.apiKey}}console.error("[agent-fs] No local user found, creating one...");let o=et(t,{email:"local@agent-fs.local"});return D("auth.apiKey",o.apiKey),console.error("[agent-fs] Local user created automatically."),{apiKey:o.apiKey}}var uu=A(()=>{Nn();Fi()});var Tu=A(()=>{Fi();Mi();vi();dn();fu();uu()});var Ru;var Nu=A(()=>{Ru={name:"agent-fs",version:"0.6.0",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 Gi=A(()=>{Nu();b=Ru.version});var yu={};mt(yu,{LocalEmbeddingProvider:()=>Au});import{join as Ll}from"path";import{mkdirSync as Dl,existsSync as Ol}from"fs";class Au{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:n}=await import("node-llama-cpp");this.llama=await t();let o=Ll(W(),"models");if(!Ol(o))Dl(o,{recursive:!0});console.error("[agent-fs] Resolving local embedding model...");let i=await n(Il,o);console.error("[agent-fs] Model ready:",i),this.model=await this.llama.loadModel({modelPath:i}),this.embeddingContext=await this.model.createEmbeddingContext()}async embed(t){await this.init();let n=await this.embeddingContext.getEmbeddingFor(t);return Array.from(n.vector)}async embedBatch(t){await this.init();let n=[];for(let o of t){let i=await this.embeddingContext.getEmbeddingFor(o);n.push(Array.from(i.vector))}return n}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 Il="hf:nomic-ai/nomic-embed-text-v1.5-GGUF:Q8_0";var lu=A(()=>{Nn()});var Zi={};mt(Zi,{OpenAIEmbeddingProvider:()=>_u});import Ul from"openai";class _u{name="openai";dimensions=768;client;constructor(t){this.client=new Ul({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((o,i)=>o.index-i.index).map((o)=>o.embedding)}}var Hi=()=>{};var Qi={};mt(Qi,{GeminiEmbeddingProvider:()=>wu});import{GoogleGenAI as Sl}from"@google/genai";class wu{name="gemini";dimensions=768;client;constructor(t){this.client=new Sl({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 n=[];for(let o of t){let i=await this.client.models.embedContent({model:"gemini-embedding-001",contents:o,config:{outputDimensionality:768}});n.push(i.embeddings[0].values)}return n}}var Ji=()=>{};async function gu(t){switch(t.provider){case"local":{let{LocalEmbeddingProvider:n}=await Promise.resolve().then(() => (lu(),yu));return new n}case"openai":{if(!t.apiKey)throw Error("OpenAI API key required. Set embedding.apiKey in config.");let{OpenAIEmbeddingProvider:n}=await Promise.resolve().then(() => (Hi(),Zi));return new n(t.apiKey)}case"gemini":{if(!t.apiKey)throw Error("Gemini API key required. Set embedding.apiKey in config.");let{GeminiEmbeddingProvider:n}=await Promise.resolve().then(() => (Ji(),Qi));return new n(t.apiKey)}default:throw Error(`Unknown embedding provider: ${t.provider}`)}}async function En(t){if(process.env.OPENAI_API_KEY)try{let{OpenAIEmbeddingProvider:n}=await Promise.resolve().then(() => (Hi(),Zi));return new n(process.env.OPENAI_API_KEY)}catch(n){console.error("[agent-fs] Failed to load OpenAI provider:",n)}if(process.env.GEMINI_API_KEY)try{let{GeminiEmbeddingProvider:n}=await Promise.resolve().then(() => (Ji(),Qi));return new n(process.env.GEMINI_API_KEY)}catch(n){console.error("[agent-fs] Failed to load Gemini provider:",n)}if(t?.provider&&t.provider!=="local"&&t.apiKey)try{return await gu(t)}catch(n){console.error("[agent-fs] Failed to create embedding provider from config:",n)}if(t?.provider==="local")try{return await gu(t)}catch(n){console.error("[agent-fs] Failed to load local embedding provider:",n)}return null}var Du,Lu,Ou=(t)=>typeof t==="string"?{...Lu,name:t}:{...Lu,...t};var fo=A(()=>{Du=Symbol("Let zodToJsonSchema decide on which parser to use"),Lu={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 Iu=(t)=>{let n=Ou(t),o=n.name!==void 0?[...n.basePath,n.definitionPath,n.name]:n.basePath;return{...n,flags:{hasReferencedOpenAiAnyType:!1},currentPath:o,propertyPath:void 0,seen:new Map(Object.entries(n.definitions).map(([i,e])=>[e._def,{def:e._def,path:[...n.basePath,n.definitionPath,i],jsonSchema:void 0}]))}};var Bi=A(()=>{fo()});function Wi(t,n,o,i){if(!i?.errorMessages)return;if(o)t.errorMessage={...t.errorMessage,[n]:o}}function $(t,n,o,i,e){t[n]=o,Wi(t,n,i,e)}var uo=(t,n)=>{let o=0;for(;o<t.length&&o<n.length;o++)if(t[o]!==n[o])break;return[(t.length-o).toString(),...n.slice(o)].join("/")};function G(t){if(t.target!=="openAi")return{};let n=[...t.basePath,t.definitionPath,t.openAiAnyTypeName];return t.flags.hasReferencedOpenAiAnyType=!0,{$ref:t.$refStrategy==="relative"?uo(n,t.currentPath):n.join("/")}}var x=()=>{};import{ZodFirstPartyTypeKind as $l}from"zod/v3";function Uu(t,n){let o={type:"array"};if(t.type?._def&&t.type?._def?.typeName!==$l.ZodAny)o.items=g(t.type._def,{...n,currentPath:[...n.currentPath,"items"]});if(t.minLength)$(o,"minItems",t.minLength.value,t.minLength.message,n);if(t.maxLength)$(o,"maxItems",t.maxLength.value,t.maxLength.message,n);if(t.exactLength)$(o,"minItems",t.exactLength.value,t.exactLength.message,n),$(o,"maxItems",t.exactLength.value,t.exactLength.message,n);return o}var Vi=A(()=>{J()});function Su(t,n){let o={type:"integer",format:"int64"};if(!t.checks)return o;for(let i of t.checks)switch(i.kind){case"min":if(n.target==="jsonSchema7")if(i.inclusive)$(o,"minimum",i.value,i.message,n);else $(o,"exclusiveMinimum",i.value,i.message,n);else{if(!i.inclusive)o.exclusiveMinimum=!0;$(o,"minimum",i.value,i.message,n)}break;case"max":if(n.target==="jsonSchema7")if(i.inclusive)$(o,"maximum",i.value,i.message,n);else $(o,"exclusiveMaximum",i.value,i.message,n);else{if(!i.inclusive)o.exclusiveMaximum=!0;$(o,"maximum",i.value,i.message,n)}break;case"multipleOf":$(o,"multipleOf",i.value,i.message,n);break}return o}var Ki=()=>{};function $u(){return{type:"boolean"}}function To(t,n){return g(t.type._def,n)}var No=A(()=>{J()});var Xu=(t,n)=>{return g(t.innerType._def,n)};var pi=A(()=>{J()});function ji(t,n,o){let i=o??n.dateStrategy;if(Array.isArray(i))return{anyOf:i.map((e,r)=>ji(t,n,e))};switch(i){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return Xl(t,n)}}var Xl=(t,n)=>{let o={type:"integer",format:"unix-time"};if(n.target==="openApi3")return o;for(let i of t.checks)switch(i.kind){case"min":$(o,"minimum",i.value,i.message,n);break;case"max":$(o,"maximum",i.value,i.message,n);break}return o};var hi=()=>{};function Cu(t,n){return{...g(t.innerType._def,n),default:t.defaultValue()}}var ki=A(()=>{J()});function Pu(t,n){return n.effectStrategy==="input"?g(t.schema._def,n):G(n)}var zi=A(()=>{J();x()});function vu(t){return{type:"string",enum:Array.from(t.values)}}function Mu(t,n){let o=[g(t.left._def,{...n,currentPath:[...n.currentPath,"allOf","0"]}),g(t.right._def,{...n,currentPath:[...n.currentPath,"allOf","1"]})].filter((r)=>!!r),i=n.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,e=[];return o.forEach((r)=>{if(Cl(r)){if(e.push(...r.allOf),r.unevaluatedProperties===void 0)i=void 0}else{let E=r;if("additionalProperties"in r&&r.additionalProperties===!1){let{additionalProperties:u,...T}=r;E=T}else i=void 0;e.push(E)}}),e.length?{allOf:e,...i}:void 0}var Cl=(t)=>{if("type"in t&&t.type==="string")return!1;return"allOf"in t};var di=A(()=>{J()});function Fu(t,n){let o=typeof t.value;if(o!=="bigint"&&o!=="number"&&o!=="boolean"&&o!=="string")return{type:Array.isArray(t.value)?"array":"object"};if(n.target==="openApi3")return{type:o==="bigint"?"integer":o,enum:[t.value]};return{type:o==="bigint"?"integer":o,const:t.value}}function Ro(t,n){let o={type:"string"};if(t.checks)for(let i of t.checks)switch(i.kind){case"min":$(o,"minLength",typeof o.minLength==="number"?Math.max(o.minLength,i.value):i.value,i.message,n);break;case"max":$(o,"maxLength",typeof o.maxLength==="number"?Math.min(o.maxLength,i.value):i.value,i.message,n);break;case"email":switch(n.emailStrategy){case"format:email":ft(o,"email",i.message,n);break;case"format:idn-email":ft(o,"idn-email",i.message,n);break;case"pattern:zod":k(o,Et.email,i.message,n);break}break;case"url":ft(o,"uri",i.message,n);break;case"uuid":ft(o,"uuid",i.message,n);break;case"regex":k(o,i.regex,i.message,n);break;case"cuid":k(o,Et.cuid,i.message,n);break;case"cuid2":k(o,Et.cuid2,i.message,n);break;case"startsWith":k(o,RegExp(`^${bi(i.value,n)}`),i.message,n);break;case"endsWith":k(o,RegExp(`${bi(i.value,n)}$`),i.message,n);break;case"datetime":ft(o,"date-time",i.message,n);break;case"date":ft(o,"date",i.message,n);break;case"time":ft(o,"time",i.message,n);break;case"duration":ft(o,"duration",i.message,n);break;case"length":$(o,"minLength",typeof o.minLength==="number"?Math.max(o.minLength,i.value):i.value,i.message,n),$(o,"maxLength",typeof o.maxLength==="number"?Math.min(o.maxLength,i.value):i.value,i.message,n);break;case"includes":{k(o,RegExp(bi(i.value,n)),i.message,n);break}case"ip":{if(i.version!=="v6")ft(o,"ipv4",i.message,n);if(i.version!=="v4")ft(o,"ipv6",i.message,n);break}case"base64url":k(o,Et.base64url,i.message,n);break;case"jwt":k(o,Et.jwt,i.message,n);break;case"cidr":{if(i.version!=="v6")k(o,Et.ipv4Cidr,i.message,n);if(i.version!=="v4")k(o,Et.ipv6Cidr,i.message,n);break}case"emoji":k(o,Et.emoji(),i.message,n);break;case"ulid":{k(o,Et.ulid,i.message,n);break}case"base64":{switch(n.base64Strategy){case"format:binary":{ft(o,"binary",i.message,n);break}case"contentEncoding:base64":{$(o,"contentEncoding","base64",i.message,n);break}case"pattern:zod":{k(o,Et.base64,i.message,n);break}}break}case"nanoid":k(o,Et.nanoid,i.message,n);case"toLowerCase":case"toUpperCase":case"trim":break;default:((e)=>{})(i)}return o}function bi(t,n){return n.patternStrategy==="escape"?vl(t):t}function vl(t){let n="";for(let o=0;o<t.length;o++){if(!Pl.has(t[o]))n+="\\";n+=t[o]}return n}function ft(t,n,o,i){if(t.format||t.anyOf?.some((e)=>e.format)){if(!t.anyOf)t.anyOf=[];if(t.format){if(t.anyOf.push({format:t.format,...t.errorMessage&&i.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:n,...o&&i.errorMessages&&{errorMessage:{format:o}}})}else $(t,"format",n,o,i)}function k(t,n,o,i){if(t.pattern||t.allOf?.some((e)=>e.pattern)){if(!t.allOf)t.allOf=[];if(t.pattern){if(t.allOf.push({pattern:t.pattern,...t.errorMessage&&i.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:Yu(n,i),...o&&i.errorMessages&&{errorMessage:{pattern:o}}})}else $(t,"pattern",Yu(n,i),o,i)}function Yu(t,n){if(!n.applyRegexFlags||!t.flags)return t.source;let o={i:t.flags.includes("i"),m:t.flags.includes("m"),s:t.flags.includes("s")},i=o.i?t.source.toLowerCase():t.source,e="",r=!1,E=!1,u=!1;for(let T=0;T<i.length;T++){if(r){e+=i[T],r=!1;continue}if(o.i){if(E){if(i[T].match(/[a-z]/)){if(u)e+=i[T],e+=`${i[T-2]}-${i[T]}`.toUpperCase(),u=!1;else if(i[T+1]==="-"&&i[T+2]?.match(/[a-z]/))e+=i[T],u=!0;else e+=`${i[T]}${i[T].toUpperCase()}`;continue}}else if(i[T].match(/[a-z]/)){e+=`[${i[T]}${i[T].toUpperCase()}]`;continue}}if(o.m){if(i[T]==="^"){e+=`(^|(?<=[\r
|
|
172
|
+
LIMIT ?`).all(r,o),T=[],N=new Set;for(let R of u){let l=t.db.select().from(f.contentChunks).where(Oi(f.contentChunks.id,R.chunk_id)).get();if(!l||l.driveId!==t.driveId)continue;if(N.has(l.filePath))continue;N.add(l.filePath);let _=t.db.select().from(f.files).where(el(Oi(f.files.path,l.filePath),Oi(f.files.driveId,t.driveId))).get();T.push({path:l.filePath,snippet:l.content.slice(0,200),author:_?.author,modifiedAt:_?.modifiedAt})}return T}function El(t,n,o){let i=n.split(/\s+/).filter(Boolean).map((e)=>`"${e}"`).join(" OR ");if(!i)return[];try{return sn(t.db,{pattern:i,driveId:t.driveId}).slice(0,o).map((r)=>({path:r.path,snippet:r.snippet}))}catch{return[]}}var zf=A(()=>{H()});import{eq as xn,and as fl,or as ul,isNull as Tl}from"drizzle-orm";async function df(t,n){let o=[xn(f.files.driveId,t.driveId),xn(f.files.isDeleted,!1),ul(xn(f.files.embeddingStatus,"failed"),Tl(f.files.embeddingStatus),xn(f.files.embeddingStatus,"pending"))];if(n.path){let{like:T}=await import("drizzle-orm"),N=n.path.endsWith("/")?n.path:n.path+"/";o.push(T(f.files.path,N+"%"))}let i=t.db.select({path:f.files.path}).from(f.files).where(fl(...o)).all(),e=0,r=0,E=0,u=3;for(let T=0;T<i.length;T+=u){let N=i.slice(T,T+u),R=await Promise.allSettled(N.map(async(l)=>{let _=U(t.orgId,t.driveId,l.path),O=await t.s3.getObject(_),L=new TextDecoder().decode(O.body);if(s(t.db,{path:l.path,driveId:t.driveId,content:L}),t.embeddingProvider)return await _i(t.db,t.embeddingProvider,{path:l.path,driveId:t.driveId,content:L}),"reindexed";return"skipped"}));for(let l of R)if(l.status==="fulfilled")if(l.value==="reindexed")e++;else E++;else console.error("Reindex failed:",l.reason),r++}return{reindexed:e,failed:r,skipped:E}}var mf=A(()=>{H();V();tn()});import{eq as bf,and as Nl,like as Rl}from"drizzle-orm";async function qf(t,n){let o=Xt(n.path??"/"),i=U(t.orgId,t.driveId,o),{objects:e}=await t.s3.listObjects(i),r=t.db.select().from(f.files).where(Nl(bf(f.files.driveId,t.driveId),Rl(f.files.path,o+"%"),bf(f.files.isDeleted,!1))).all(),E=new Map(r.map((T)=>[T.path,T])),u=[];for(let T of e){let N=T.key.slice(i.length);if(!N)continue;let R=N.split("/").filter(Boolean);if(R.length===0)continue;if(n.depth!==void 0&&R.length>n.depth)continue;let l=u;for(let _=0;_<R.length;_++){let O=R[_],L=_===R.length-1,F=!L||N.endsWith("/");if(F&&!L){let X=l.find((Z)=>Z.name===O&&Z.type==="directory");if(!X)X={name:O,type:"directory",children:[]},l.push(X);if(!X.children)X.children=[];l=X.children}else if(F&&L){let X=l.find((Z)=>Z.name===O&&Z.type==="directory");if(!X)X={name:O,type:"directory",children:[]},l.push(X)}else{let X=o+R.slice(0,_+1).join("/"),Z=E.get(X),Tn={name:O,type:"file",size:Z?.size??T.size};if(Z?.author)Tn.author=Z.author;if(Z?.modifiedAt??T.lastModified)Tn.modifiedAt=Z?.modifiedAt??T.lastModified;l.push(Tn)}}}return{tree:u}}var sf=A(()=>{H();V()});import{eq as cf,and as Al,like as yl}from"drizzle-orm";function ll(t){let n="",o=0;while(o<t.length){let i=t[o];if(i==="*")if(t[o+1]==="*"){if(n+=".*",o+=2,t[o]==="/")o++}else n+="[^/]*",o++;else if(i==="?")n+="[^/]",o++;else if(".+^${}()|[]\\".includes(i))n+="\\"+i,o++;else n+=i,o++}return new RegExp("^"+n+"$")}async function xf(t,n){let o=n.path?Xt(n.path):"/",i=U(t.orgId,t.driveId,o),{objects:e}=await t.s3.listObjects(i),r=t.db.select().from(f.files).where(Al(cf(f.files.driveId,t.driveId),yl(f.files.path,o+"%"),cf(f.files.isDeleted,!1))).all(),E=new Map(r.map((N)=>[N.path,N])),u=ll(n.pattern),T=[];for(let N of e){let R=N.key.slice(i.length);if(!R||R.endsWith("/"))continue;if(u.test(R)){let l=o+R,_=E.get(l);T.push({path:l,size:_?.size??N.size,modifiedAt:_?.modifiedAt??N.lastModified})}}return{matches:T}}var af=A(()=>{H();V()});async function tu(t,n){let o=In(n.path),i=U(t.orgId,t.driveId,o),e=n.expiresIn??86400;try{await t.s3.headObject(i)}catch(u){if(u?.name==="NotFound"||u?.name==="NoSuchKey"||u?.$metadata?.httpStatusCode===404)throw new v(`File not found: ${o}`,{path:o});throw u}let r=lt(o);return{url:await t.s3.getPresignedUrl(i,e,r!=="application/octet-stream"?r:void 0),path:o,expiresIn:e,expiresAt:new Date(Date.now()+e*1000).toISOString()}}var nu=A(()=>{V();z();xt()});function Ii(t,n,o,i){let e=i.startsWith("/")?i.slice(1):i;return`${t}/file/~/${n}/${o}/${e}`}import{eq as P,and as _t,sql as Ui,desc as ou}from"drizzle-orm";function Si(t,n){t.db.insert(f.events).values({id:crypto.randomUUID(),orgId:t.orgId,type:n.type,resourceType:n.resourceType,resourceId:n.resourceId,actor:t.userId,target:n.target??null,status:"created",metadata:n.metadata?JSON.stringify(n.metadata):null,createdAt:new Date}).run()}function an(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 to(t,n){let o=new Date,i=crypto.randomUUID(),e=n.path;if(n.parentId){let E=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.parentId),P(f.comments.isDeleted,!1))).get();if(!E)throw new v("Parent comment not found",{suggestion:"Check that the parent comment ID is correct and not deleted"});if(E.parentId)throw new it("Cannot reply to a reply \u2014 only root comments accept replies",{suggestion:"Reply to the root comment instead"});if(!e)e=E.path}if(!e)throw new it("path is required for root comments",{field:"path"});let r=t.db.select({id:f.fileVersions.id}).from(f.fileVersions).where(_t(P(f.fileVersions.path,e),P(f.fileVersions.driveId,t.driveId))).orderBy(ou(f.fileVersions.id)).limit(1).get();return t.db.insert(f.comments).values({id:i,parentId:n.parentId??null,orgId:t.orgId,driveId:t.driveId,path:e,lineStart:n.lineStart??null,lineEnd:n.lineEnd??null,quotedContent:n.quotedContent??null,fileVersionId:r?.id??null,body:n.body,author:t.userId,resolved:!1,createdAt:o,updatedAt:o,isDeleted:!1}).run(),Si(t,{type:"comment_created",resourceType:"comment",resourceId:i,metadata:{path:e,parentId:n.parentId}}),{id:i,path:e,body:n.body,parentId:n.parentId,lineStart:n.lineStart,lineEnd:n.lineEnd,author:t.userId,createdAt:o}}async function no(t,n){let o=[P(f.comments.driveId,t.driveId),P(f.comments.isDeleted,!1)];if(n.path)o.push(P(f.comments.path,n.path));if(n.parentId)o.push(P(f.comments.parentId,n.parentId));else if(n.parentId===void 0&&!n.resolved)o.push(Ui`${f.comments.parentId} IS NULL`),o.push(P(f.comments.resolved,!1));else if(n.parentId===void 0&&n.resolved)o.push(Ui`${f.comments.parentId} IS NULL`);if(n.orgId)o.push(P(f.comments.orgId,n.orgId));let i=n.limit??50,e=n.offset??0;return{comments:t.db.select().from(f.comments).where(_t(...o)).orderBy(ou(f.comments.createdAt)).limit(i).offset(e).all().map((u)=>{let N=t.db.select().from(f.comments).where(_t(P(f.comments.parentId,u.id),P(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((R)=>an({...R,replyCount:0}));return{...an({...u,replyCount:N.length}),replies:N}})}}async function oo(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});let i=t.db.select({count:Ui`count(*)`}).from(f.comments).where(_t(P(f.comments.parentId,o.id),P(f.comments.isDeleted,!1))).get(),e=an({...o,replyCount:i?.count??0}),E=t.db.select().from(f.comments).where(_t(P(f.comments.parentId,n.id),P(f.comments.isDeleted,!1))).orderBy(f.comments.createdAt).all().map((u)=>an({...u,replyCount:0}));return{comment:e,replies:E}}async function io(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.author!==t.userId)throw new nt("You can only edit your own comments",{suggestion:"Only the comment author can update it"});let i=new Date;return t.db.update(f.comments).set({body:n.body,updatedAt:i}).where(P(f.comments.id,n.id)).run(),{id:n.id,body:n.body,updatedAt:i}}async function eo(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.author!==t.userId)throw new nt("You can only delete your own comments",{suggestion:"Only the comment author can delete it"});let i=new Date;if(t.db.update(f.comments).set({isDeleted:!0,updatedAt:i}).where(P(f.comments.id,n.id)).run(),!o.parentId)t.db.update(f.comments).set({isDeleted:!0,updatedAt:i}).where(P(f.comments.parentId,n.id)).run();return Si(t,{type:"comment_deleted",resourceType:"comment",resourceId:n.id}),{deleted:!0}}async function ro(t,n){let o=t.db.select().from(f.comments).where(_t(P(f.comments.id,n.id),P(f.comments.isDeleted,!1))).get();if(!o)throw new v("Comment not found",{suggestion:"Check that the comment ID is correct"});if(o.parentId)throw new it("Cannot resolve a reply \u2014 only root comments can be resolved",{suggestion:"Resolve the parent comment instead"});let i=new Date,e=n.resolved?i:null,r=n.resolved?t.userId:null;return t.db.update(f.comments).set({resolved:n.resolved,resolvedBy:r,resolvedAt:e,updatedAt:i}).where(P(f.comments.id,n.id)).run(),Si(t,{type:n.resolved?"comment_resolved":"comment_reopened",resourceType:"comment",resourceId:n.id}),{id:n.id,resolved:n.resolved,resolvedBy:r??void 0,resolvedAt:e??void 0}}var iu=A(()=>{H();z()});import{z as y}from"zod";async function j(t,n,o,i){let e=$i[n];if(!e)throw Error(`Unknown operation: ${n}`);if(!i?.skipAuth){let u=Dn(n);On(t.db,{userId:t.userId,driveId:t.driveId,requiredRole:u})}let r=e.schema.parse(o),E=await e.handler(t,r);if(t.appUrl&&E&&typeof E==="object"){if("path"in E)E.appUrl=Ii(t.appUrl,t.orgId,t.driveId,E.path);else if("to"in E)E.appUrl=Ii(t.appUrl,t.orgId,t.driveId,E.to)}return E}function en(){return Object.keys($i)}function Pt(t){return $i[t]}var $i;var Xi=A(()=>{dn();rf();ff();Tf();Rf();lf();gf();Df();Uf();$f();Cf();Mf();Gf();Hf();Bf();Vf();pf();hf();zf();mf();sf();af();nu();iu();$i={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:cn,schema:y.object({path:y.string(),content:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},cat:{description:"Read file content with optional pagination via offset/limit. Returns { content, totalLines, truncated }.",handler:Ef,schema:y.object({path:y.string(),offset:y.number().int().min(0).optional(),limit:y.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:uf,schema:y.object({path:y.string(),old_string:y.string(),new_string:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},append:{description:"Append content to the end of an existing file. Creates a new version. Returns { version, size }.",handler:Nf,schema:y.object({path:y.string(),content:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},ls:{description:"List immediate children of a directory. Returns { entries } where each entry has name, type (file/directory), size, author, modifiedAt.",handler:yf,schema:y.object({path:y.string().optional()})},stat:{description:"Get file metadata without reading content. Returns path, size, contentType, author, currentVersion, createdAt, modifiedAt, isDeleted, embeddingStatus.",handler:wf,schema:y.object({path:y.string()})},rm:{description:"Delete a file. Removes from S3, cleans up FTS5 index and vector embeddings. Returns { path, deleted }.",handler:Lf,schema:y.object({path:y.string(),expectedVersion:y.number().int().optional()})},mv:{description:"Move or rename a file. Preserves version history at the new path. Returns { from, to, version }.",handler:If,schema:y.object({from:y.string(),to:y.string(),message:y.string().optional(),expectedVersion:y.number().int().optional()})},cp:{description:"Copy a file using server-side S3 copy. Creates a new version at the destination. Returns { from, to, version }.",handler:Sf,schema:y.object({from:y.string(),to:y.string(),expectedVersion:y.number().int().optional()})},tail:{description:"Read the last N lines of a file (default 20). Returns { content, totalLines, truncated }.",handler:Xf,schema:y.object({path:y.string(),lines:y.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:vf,schema:y.object({path:y.string(),limit:y.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:Yf,schema:y.object({path:y.string(),v1:y.number().int(),v2:y.number().int()})},revert:{description:"Revert a file to a previous version. Creates a new version with the old content. Returns { version, revertedTo }.",handler:Zf,schema:y.object({path:y.string(),version:y.number().int(),expectedVersion:y.number().int().optional()})},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:Jf,schema:y.object({path:y.string().optional(),since:y.coerce.date().optional(),limit:y.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:Wf,schema:y.object({pattern:y.string(),path:y.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:Kf,schema:y.object({pattern:y.string(),path:y.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:kf,schema:y.object({query:y.string(),limit:y.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:jf,schema:y.object({query:y.string(),limit:y.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:df,schema:y.object({path:y.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:qf,schema:y.object({path:y.string().optional(),depth:y.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:xf,schema:y.object({pattern:y.string(),path:y.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:tu,schema:y.object({path:y.string(),expiresIn:y.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:to,schema:y.object({path:y.string().optional(),body:y.string(),parentId:y.string().optional(),lineStart:y.number().int().optional(),lineEnd:y.number().int().optional(),quotedContent:y.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:no,schema:y.object({path:y.string().optional(),parentId:y.string().optional(),resolved:y.boolean().optional(),orgId:y.string().optional(),limit:y.number().int().min(1).optional(),offset:y.number().int().min(0).optional()})},"comment-get":{description:"Get a single comment by ID with all its replies. Returns { comment, replies }.",handler:oo,schema:y.object({id:y.string()})},"comment-update":{description:"Update a comment's body. Only the original author can update. Returns { id, body, updatedAt }.",handler:io,schema:y.object({id:y.string(),body:y.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:eo,schema:y.object({id:y.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:ro,schema:y.object({id:y.string(),resolved:y.boolean()})}}});import{eq as d,and as Eo}from"drizzle-orm";function Zt(t,n){let o=crypto.randomUUID(),i=new Date;return t.insert(f.drives).values({id:o,orgId:n.orgId,name:n.name,isDefault:n.isDefault??!1,createdAt:i}).run(),{id:o,name:n.name}}function Sn(t,n){return t.select().from(f.drives).where(d(f.drives.orgId,n)).all().map((o)=>({id:o.id,name:o.name,isDefault:o.isDefault}))}function Lt(t,n,o){return t.select().from(f.drives).where(d(f.drives.orgId,n)).all().filter((e)=>{let r=t.select({userId:f.driveMembers.userId}).from(f.driveMembers).where(d(f.driveMembers.driveId,e.id)).all();if(r.length===0)return!0;return r.some((E)=>E.userId===o)}).map((e)=>({id:e.id,name:e.name,isDefault:e.isDefault}))}function Ci(t,n){let o=t.select().from(f.drives).where(d(f.drives.id,n)).get();if(!o)return null;return{id:o.id,name:o.name,orgId:o.orgId,isDefault:o.isDefault}}function Ht(t,n){return t.select({userId:f.driveMembers.userId,email:f.users.email,role:f.driveMembers.role}).from(f.driveMembers).innerJoin(f.users,d(f.driveMembers.userId,f.users.id)).where(d(f.driveMembers.driveId,n)).all()}function Qt(t,n){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).get())throw Error("Member not found in drive");t.update(f.driveMembers).set({role:n.role}).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).run()}function Jt(t,n){if(!t.select({role:f.driveMembers.role}).from(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).get())throw Error("Member not found in drive");t.delete(f.driveMembers).where(Eo(d(f.driveMembers.driveId,n.driveId),d(f.driveMembers.userId,n.userId))).run()}function Pi(t,n){t.insert(f.driveMembers).values({driveId:n.driveId,userId:n.userId,role:n.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:n.role}}).run()}var vi=A(()=>{H()});import{eq as Q,and as Bt,sql as eu}from"drizzle-orm";function Wt(t,n){let o=crypto.randomUUID(),i=new Date;t.insert(f.orgs).values({id:o,name:n.name,isPersonal:n.isPersonal??!1,createdAt:i}).run(),t.insert(f.orgMembers).values({orgId:o,userId:n.userId,role:"admin"}).run();let e=Zt(t,{orgId:o,name:"default",isDefault:!0});return t.insert(f.driveMembers).values({driveId:e.id,userId:n.userId,role:"admin"}).run(),{id:o,name:n.name}}function K(t,n){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,Q(f.orgMembers.orgId,f.orgs.id)).where(Q(f.orgMembers.userId,n)).all().map((i)=>({id:i.orgId,name:i.name,role:i.role,isPersonal:i.isPersonal}))}function $n(t,n){let o=t.select().from(f.orgs).where(Q(f.orgs.id,n)).get();if(!o)return null;return{id:o.id,name:o.name,isPersonal:o.isPersonal}}function Vt(t,n){return t.select({userId:f.orgMembers.userId,email:f.users.email,role:f.orgMembers.role}).from(f.orgMembers).innerJoin(f.users,Q(f.orgMembers.userId,f.users.id)).where(Q(f.orgMembers.orgId,n)).all()}function Kt(t,n){let o=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).get();if(!o)throw Error("Member not found in org");if(o.role==="admin"&&n.role!=="admin"){if(t.select({count:eu`count(*)`}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}t.update(f.orgMembers).set({role:n.role}).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).run()}function pt(t,n){if(t.select({isPersonal:f.orgs.isPersonal}).from(f.orgs).where(Q(f.orgs.id,n.orgId)).get()?.isPersonal)throw Error("Cannot remove members from a personal org");let i=t.select({role:f.orgMembers.role}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).get();if(!i)throw Error("Member not found in org");if(i.role==="admin"){if(t.select({count:eu`count(*)`}).from(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.role,"admin"))).get().count<=1)throw Error("Cannot remove the last admin from the org")}let e=t.select({id:f.drives.id}).from(f.drives).where(Q(f.drives.orgId,n.orgId)).all();for(let r of e)t.delete(f.driveMembers).where(Bt(Q(f.driveMembers.driveId,r.id),Q(f.driveMembers.userId,n.userId))).run();t.delete(f.orgMembers).where(Bt(Q(f.orgMembers.orgId,n.orgId),Q(f.orgMembers.userId,n.userId))).run()}function jt(t,n){let o=t.select().from(f.users).where(Q(f.users.email,n.email)).get();if(!o)throw Error(`User with email ${n.email} not found`);t.insert(f.orgMembers).values({orgId:n.orgId,userId:o.id,role:n.role}).onConflictDoUpdate({target:[f.orgMembers.orgId,f.orgMembers.userId],set:{role:n.role}}).run();let i=t.select().from(f.drives).where(Q(f.drives.orgId,n.orgId)).get();if(i)t.insert(f.driveMembers).values({driveId:i.id,userId:o.id,role:n.role}).onConflictDoUpdate({target:[f.driveMembers.driveId,f.driveMembers.userId],set:{role:n.role}}).run()}var Mi=A(()=>{H();vi()});import{eq as ru}from"drizzle-orm";function Eu(t){let n=new Bun.CryptoHasher("sha256");return n.update(t),n.digest("hex")}function _l(){let t=new Uint8Array(32);return crypto.getRandomValues(t),`af_${Array.from(t,(o)=>o.toString(16).padStart(2,"0")).join("")}`}function wl(){return crypto.randomUUID()}function et(t,n){let o=wl(),i=_l(),e=Eu(i),r=new Date;return t.insert(f.users).values({id:o,email:n.email,apiKeyHash:e,createdAt:r}).run(),Wt(t,{name:n.email.split("@")[0],userId:o,isPersonal:!0}),{user:{id:o,email:n.email},apiKey:i}}function rt(t,n){let o=Eu(n),i=t.select().from(f.users).where(ru(f.users.apiKeyHash,o)).get();if(!i)return null;return{id:i.id,email:i.email}}function rn(t,n){let o=t.select().from(f.users).where(ru(f.users.email,n)).get();if(!o)return null;return{id:o.id,email:o.email}}var Fi=A(()=>{H();Mi()});import{eq as vt,and as Yi}from"drizzle-orm";function m(t,n){if(n.driveId){let r=t.select().from(f.drives).where(vt(f.drives.id,n.driveId)).get();if(!r)throw Error(`Drive not found: ${n.driveId}`);let E=At(t,n.userId,n.driveId);if(!E)throw Error("You do not have access to this drive");return{orgId:r.orgId,driveId:n.driveId,role:E}}if(n.orgId){let r=t.select().from(f.drives).where(Yi(vt(f.drives.orgId,n.orgId),vt(f.drives.isDefault,!0))).get();if(!r)throw Error(`No default drive for org: ${n.orgId}`);let E=At(t,n.userId,r.id);if(!E)throw Error("You do not have access to this drive");return{orgId:n.orgId,driveId:r.id,role:E}}let o=t.select({orgId:f.orgMembers.orgId}).from(f.orgMembers).innerJoin(f.orgs,vt(f.orgMembers.orgId,f.orgs.id)).where(Yi(vt(f.orgMembers.userId,n.userId),vt(f.orgs.isPersonal,!0))).get();if(!o)throw Error("No personal org found for user");let i=t.select().from(f.drives).where(Yi(vt(f.drives.orgId,o.orgId),vt(f.drives.isDefault,!0))).get();if(!i)throw Error("No default drive found");let e=At(t,n.userId,i.id);if(!e)throw Error("You do not have access to your default drive");return{orgId:o.orgId,driveId:i.id,role:e}}var fu=A(()=>{H();dn()});function Xn(t){let n=C();if(n.auth.apiKey){if(rt(t,n.auth.apiKey))return{apiKey:n.auth.apiKey}}console.error("[agent-fs] No local user found, creating one...");let o=et(t,{email:"local@agent-fs.local"});return D("auth.apiKey",o.apiKey),console.error("[agent-fs] Local user created automatically."),{apiKey:o.apiKey}}var uu=A(()=>{Nn();Fi()});var Tu=A(()=>{Fi();Mi();vi();dn();fu();uu()});var Ru;var Nu=A(()=>{Ru={name:"agent-fs",version:"0.6.1",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 Gi=A(()=>{Nu();b=Ru.version});var yu={};mt(yu,{LocalEmbeddingProvider:()=>Au});import{join as Ll}from"path";import{mkdirSync as Dl,existsSync as Ol}from"fs";class Au{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:n}=await import("node-llama-cpp");this.llama=await t();let o=Ll(W(),"models");if(!Ol(o))Dl(o,{recursive:!0});console.error("[agent-fs] Resolving local embedding model...");let i=await n(Il,o);console.error("[agent-fs] Model ready:",i),this.model=await this.llama.loadModel({modelPath:i}),this.embeddingContext=await this.model.createEmbeddingContext()}async embed(t){await this.init();let n=await this.embeddingContext.getEmbeddingFor(t);return Array.from(n.vector)}async embedBatch(t){await this.init();let n=[];for(let o of t){let i=await this.embeddingContext.getEmbeddingFor(o);n.push(Array.from(i.vector))}return n}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 Il="hf:nomic-ai/nomic-embed-text-v1.5-GGUF:Q8_0";var lu=A(()=>{Nn()});var Zi={};mt(Zi,{OpenAIEmbeddingProvider:()=>_u});import Ul from"openai";class _u{name="openai";dimensions=768;client;constructor(t){this.client=new Ul({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((o,i)=>o.index-i.index).map((o)=>o.embedding)}}var Hi=()=>{};var Qi={};mt(Qi,{GeminiEmbeddingProvider:()=>wu});import{GoogleGenAI as Sl}from"@google/genai";class wu{name="gemini";dimensions=768;client;constructor(t){this.client=new Sl({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 n=[];for(let o of t){let i=await this.client.models.embedContent({model:"gemini-embedding-001",contents:o,config:{outputDimensionality:768}});n.push(i.embeddings[0].values)}return n}}var Ji=()=>{};async function gu(t){switch(t.provider){case"local":{let{LocalEmbeddingProvider:n}=await Promise.resolve().then(() => (lu(),yu));return new n}case"openai":{if(!t.apiKey)throw Error("OpenAI API key required. Set embedding.apiKey in config.");let{OpenAIEmbeddingProvider:n}=await Promise.resolve().then(() => (Hi(),Zi));return new n(t.apiKey)}case"gemini":{if(!t.apiKey)throw Error("Gemini API key required. Set embedding.apiKey in config.");let{GeminiEmbeddingProvider:n}=await Promise.resolve().then(() => (Ji(),Qi));return new n(t.apiKey)}default:throw Error(`Unknown embedding provider: ${t.provider}`)}}async function En(t){if(process.env.OPENAI_API_KEY)try{let{OpenAIEmbeddingProvider:n}=await Promise.resolve().then(() => (Hi(),Zi));return new n(process.env.OPENAI_API_KEY)}catch(n){console.error("[agent-fs] Failed to load OpenAI provider:",n)}if(process.env.GEMINI_API_KEY)try{let{GeminiEmbeddingProvider:n}=await Promise.resolve().then(() => (Ji(),Qi));return new n(process.env.GEMINI_API_KEY)}catch(n){console.error("[agent-fs] Failed to load Gemini provider:",n)}if(t?.provider&&t.provider!=="local"&&t.apiKey)try{return await gu(t)}catch(n){console.error("[agent-fs] Failed to create embedding provider from config:",n)}if(t?.provider==="local")try{return await gu(t)}catch(n){console.error("[agent-fs] Failed to load local embedding provider:",n)}return null}var Du,Lu,Ou=(t)=>typeof t==="string"?{...Lu,name:t}:{...Lu,...t};var fo=A(()=>{Du=Symbol("Let zodToJsonSchema decide on which parser to use"),Lu={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 Iu=(t)=>{let n=Ou(t),o=n.name!==void 0?[...n.basePath,n.definitionPath,n.name]:n.basePath;return{...n,flags:{hasReferencedOpenAiAnyType:!1},currentPath:o,propertyPath:void 0,seen:new Map(Object.entries(n.definitions).map(([i,e])=>[e._def,{def:e._def,path:[...n.basePath,n.definitionPath,i],jsonSchema:void 0}]))}};var Bi=A(()=>{fo()});function Wi(t,n,o,i){if(!i?.errorMessages)return;if(o)t.errorMessage={...t.errorMessage,[n]:o}}function $(t,n,o,i,e){t[n]=o,Wi(t,n,i,e)}var uo=(t,n)=>{let o=0;for(;o<t.length&&o<n.length;o++)if(t[o]!==n[o])break;return[(t.length-o).toString(),...n.slice(o)].join("/")};function G(t){if(t.target!=="openAi")return{};let n=[...t.basePath,t.definitionPath,t.openAiAnyTypeName];return t.flags.hasReferencedOpenAiAnyType=!0,{$ref:t.$refStrategy==="relative"?uo(n,t.currentPath):n.join("/")}}var x=()=>{};import{ZodFirstPartyTypeKind as $l}from"zod/v3";function Uu(t,n){let o={type:"array"};if(t.type?._def&&t.type?._def?.typeName!==$l.ZodAny)o.items=g(t.type._def,{...n,currentPath:[...n.currentPath,"items"]});if(t.minLength)$(o,"minItems",t.minLength.value,t.minLength.message,n);if(t.maxLength)$(o,"maxItems",t.maxLength.value,t.maxLength.message,n);if(t.exactLength)$(o,"minItems",t.exactLength.value,t.exactLength.message,n),$(o,"maxItems",t.exactLength.value,t.exactLength.message,n);return o}var Vi=A(()=>{J()});function Su(t,n){let o={type:"integer",format:"int64"};if(!t.checks)return o;for(let i of t.checks)switch(i.kind){case"min":if(n.target==="jsonSchema7")if(i.inclusive)$(o,"minimum",i.value,i.message,n);else $(o,"exclusiveMinimum",i.value,i.message,n);else{if(!i.inclusive)o.exclusiveMinimum=!0;$(o,"minimum",i.value,i.message,n)}break;case"max":if(n.target==="jsonSchema7")if(i.inclusive)$(o,"maximum",i.value,i.message,n);else $(o,"exclusiveMaximum",i.value,i.message,n);else{if(!i.inclusive)o.exclusiveMaximum=!0;$(o,"maximum",i.value,i.message,n)}break;case"multipleOf":$(o,"multipleOf",i.value,i.message,n);break}return o}var Ki=()=>{};function $u(){return{type:"boolean"}}function To(t,n){return g(t.type._def,n)}var No=A(()=>{J()});var Xu=(t,n)=>{return g(t.innerType._def,n)};var pi=A(()=>{J()});function ji(t,n,o){let i=o??n.dateStrategy;if(Array.isArray(i))return{anyOf:i.map((e,r)=>ji(t,n,e))};switch(i){case"string":case"format:date-time":return{type:"string",format:"date-time"};case"format:date":return{type:"string",format:"date"};case"integer":return Xl(t,n)}}var Xl=(t,n)=>{let o={type:"integer",format:"unix-time"};if(n.target==="openApi3")return o;for(let i of t.checks)switch(i.kind){case"min":$(o,"minimum",i.value,i.message,n);break;case"max":$(o,"maximum",i.value,i.message,n);break}return o};var hi=()=>{};function Cu(t,n){return{...g(t.innerType._def,n),default:t.defaultValue()}}var ki=A(()=>{J()});function Pu(t,n){return n.effectStrategy==="input"?g(t.schema._def,n):G(n)}var zi=A(()=>{J();x()});function vu(t){return{type:"string",enum:Array.from(t.values)}}function Mu(t,n){let o=[g(t.left._def,{...n,currentPath:[...n.currentPath,"allOf","0"]}),g(t.right._def,{...n,currentPath:[...n.currentPath,"allOf","1"]})].filter((r)=>!!r),i=n.target==="jsonSchema2019-09"?{unevaluatedProperties:!1}:void 0,e=[];return o.forEach((r)=>{if(Cl(r)){if(e.push(...r.allOf),r.unevaluatedProperties===void 0)i=void 0}else{let E=r;if("additionalProperties"in r&&r.additionalProperties===!1){let{additionalProperties:u,...T}=r;E=T}else i=void 0;e.push(E)}}),e.length?{allOf:e,...i}:void 0}var Cl=(t)=>{if("type"in t&&t.type==="string")return!1;return"allOf"in t};var di=A(()=>{J()});function Fu(t,n){let o=typeof t.value;if(o!=="bigint"&&o!=="number"&&o!=="boolean"&&o!=="string")return{type:Array.isArray(t.value)?"array":"object"};if(n.target==="openApi3")return{type:o==="bigint"?"integer":o,enum:[t.value]};return{type:o==="bigint"?"integer":o,const:t.value}}function Ro(t,n){let o={type:"string"};if(t.checks)for(let i of t.checks)switch(i.kind){case"min":$(o,"minLength",typeof o.minLength==="number"?Math.max(o.minLength,i.value):i.value,i.message,n);break;case"max":$(o,"maxLength",typeof o.maxLength==="number"?Math.min(o.maxLength,i.value):i.value,i.message,n);break;case"email":switch(n.emailStrategy){case"format:email":ft(o,"email",i.message,n);break;case"format:idn-email":ft(o,"idn-email",i.message,n);break;case"pattern:zod":k(o,Et.email,i.message,n);break}break;case"url":ft(o,"uri",i.message,n);break;case"uuid":ft(o,"uuid",i.message,n);break;case"regex":k(o,i.regex,i.message,n);break;case"cuid":k(o,Et.cuid,i.message,n);break;case"cuid2":k(o,Et.cuid2,i.message,n);break;case"startsWith":k(o,RegExp(`^${bi(i.value,n)}`),i.message,n);break;case"endsWith":k(o,RegExp(`${bi(i.value,n)}$`),i.message,n);break;case"datetime":ft(o,"date-time",i.message,n);break;case"date":ft(o,"date",i.message,n);break;case"time":ft(o,"time",i.message,n);break;case"duration":ft(o,"duration",i.message,n);break;case"length":$(o,"minLength",typeof o.minLength==="number"?Math.max(o.minLength,i.value):i.value,i.message,n),$(o,"maxLength",typeof o.maxLength==="number"?Math.min(o.maxLength,i.value):i.value,i.message,n);break;case"includes":{k(o,RegExp(bi(i.value,n)),i.message,n);break}case"ip":{if(i.version!=="v6")ft(o,"ipv4",i.message,n);if(i.version!=="v4")ft(o,"ipv6",i.message,n);break}case"base64url":k(o,Et.base64url,i.message,n);break;case"jwt":k(o,Et.jwt,i.message,n);break;case"cidr":{if(i.version!=="v6")k(o,Et.ipv4Cidr,i.message,n);if(i.version!=="v4")k(o,Et.ipv6Cidr,i.message,n);break}case"emoji":k(o,Et.emoji(),i.message,n);break;case"ulid":{k(o,Et.ulid,i.message,n);break}case"base64":{switch(n.base64Strategy){case"format:binary":{ft(o,"binary",i.message,n);break}case"contentEncoding:base64":{$(o,"contentEncoding","base64",i.message,n);break}case"pattern:zod":{k(o,Et.base64,i.message,n);break}}break}case"nanoid":k(o,Et.nanoid,i.message,n);case"toLowerCase":case"toUpperCase":case"trim":break;default:((e)=>{})(i)}return o}function bi(t,n){return n.patternStrategy==="escape"?vl(t):t}function vl(t){let n="";for(let o=0;o<t.length;o++){if(!Pl.has(t[o]))n+="\\";n+=t[o]}return n}function ft(t,n,o,i){if(t.format||t.anyOf?.some((e)=>e.format)){if(!t.anyOf)t.anyOf=[];if(t.format){if(t.anyOf.push({format:t.format,...t.errorMessage&&i.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:n,...o&&i.errorMessages&&{errorMessage:{format:o}}})}else $(t,"format",n,o,i)}function k(t,n,o,i){if(t.pattern||t.allOf?.some((e)=>e.pattern)){if(!t.allOf)t.allOf=[];if(t.pattern){if(t.allOf.push({pattern:t.pattern,...t.errorMessage&&i.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:Yu(n,i),...o&&i.errorMessages&&{errorMessage:{pattern:o}}})}else $(t,"pattern",Yu(n,i),o,i)}function Yu(t,n){if(!n.applyRegexFlags||!t.flags)return t.source;let o={i:t.flags.includes("i"),m:t.flags.includes("m"),s:t.flags.includes("s")},i=o.i?t.source.toLowerCase():t.source,e="",r=!1,E=!1,u=!1;for(let T=0;T<i.length;T++){if(r){e+=i[T],r=!1;continue}if(o.i){if(E){if(i[T].match(/[a-z]/)){if(u)e+=i[T],e+=`${i[T-2]}-${i[T]}`.toUpperCase(),u=!1;else if(i[T+1]==="-"&&i[T+2]?.match(/[a-z]/))e+=i[T],u=!0;else e+=`${i[T]}${i[T].toUpperCase()}`;continue}}else if(i[T].match(/[a-z]/)){e+=`[${i[T]}${i[T].toUpperCase()}]`;continue}}if(o.m){if(i[T]==="^"){e+=`(^|(?<=[\r
|
|
173
173
|
]))`;continue}else if(i[T]==="$"){e+=`($|(?=[\r
|
|
174
174
|
]))`;continue}}if(o.s&&i[T]==="."){e+=E?`${i[T]}\r
|
|
175
175
|
`:`[${i[T]}\r
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.6.
|
|
2
|
+
"version": "0.6.1",
|
|
3
3
|
"binaries": {
|
|
4
|
-
"linux-x64": "sha256:
|
|
5
|
-
"linux-arm64": "sha256:
|
|
4
|
+
"linux-x64": "sha256:9ce20eb26529bb3a759c588f28697442c9e68015e6bdcc4f9d0791980cd286bd",
|
|
5
|
+
"linux-arm64": "sha256:958a838931c776a8b2dbacb94d38986945c070cb6de9089df0e51541f949aee8"
|
|
6
6
|
}
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-fs",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first filesystem backed by S3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"sqlite-vec-linux-arm64": "^0.1.9",
|
|
37
37
|
"sqlite-vec-linux-x64": "^0.1.9",
|
|
38
38
|
"sqlite-vec-windows-x64": "^0.1.9",
|
|
39
|
-
"@desplega.ai/agent-fs-fuse-linux-x64": "0.6.
|
|
40
|
-
"@desplega.ai/agent-fs-fuse-linux-arm64": "0.6.
|
|
39
|
+
"@desplega.ai/agent-fs-fuse-linux-x64": "0.6.1",
|
|
40
|
+
"@desplega.ai/agent-fs-fuse-linux-arm64": "0.6.1"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"commander": "^14.0.3",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"sqlite-vec": "^0.1.9",
|
|
52
52
|
"zod": "^3.24.0",
|
|
53
53
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
54
|
-
"hono": "^4.12.8"
|
|
54
|
+
"hono": "^4.12.8",
|
|
55
|
+
"msgpackr": "^1"
|
|
55
56
|
}
|
|
56
57
|
}
|