/** World Git execution, inherited caller identity, and VFS-only checkout registration checks. */ import { Started } from '../messages/addresses.ts' export const resolve = (base:string,path:string) => { const parts:string[]=[] for(const part of (path.startsWith('/')?path:`${base}/${path}`).split('/')) { if(part==='..')parts.pop();else if(part&&part!=='.')parts.push(part) } return '/'+parts.join('/') } export async function chain(host:any,id:number,context:any):Promise { const ids=new Set() const visit=async(id:number)=>{ if(ids.has(id))return ids.add(id) const row=await host.harness().commit((tx:any)=>tx.conversation(id),context) const up=row?.owner?.conversationId??row?.parent?.conversationId if(up!==undefined)await visit(up) const starter=(await host.harness().snapshot(Started,id,context))?.by if(starter!==undefined)await visit(starter) } await visit(id) return [...ids].map(String) } export const git = async(host:any,cwd:string,args:string[],identity:any={})=>{ const result=await host.exec(['git',...args],{cwd,timeout:30,...identity}) if(result.code)throw new Error(`${cwd}: git ${args.join(' ')}: ${result.stderr||result.stdout||`exited ${result.code}`}`) return result.stdout.trim() } export async function mkdir(host:any,path:string) { let current='' for(const part of path.split('/').filter(Boolean)) { current+='/'+part try {await host.fs.mkdir(current)} catch(error) {if((error as any).code!=='already_exists')throw error} } } export async function gitdir(host:any,source:string) { const path=`${source}/.git` return (await host.fs.stat(path)).kind==='directory'?path:resolve(source,(await host.fs.read(path)).trim().replace(/^gitdir: /,'')) } export async function registered(host:any,workspace:{source:string;path:string}) { try { const admin=await gitdir(host,workspace.path) const source=await gitdir(host,workspace.source) const common=await host.fs.read(`${source}/commondir`).then((p:string)=>resolve(source,p.trim()),(e:any)=>{if(e.code==='not_found')return source;throw e}) return admin.startsWith(`${common}/worktrees/`) && resolve(admin,(await host.fs.read(`${admin}/gitdir`)).trim())===`${workspace.path}/.git` && (await host.fs.stat(`${admin}/HEAD`)).kind==='file' } catch(error) {if((error as any).code==='not_found')return false;throw error} } export const hash=(text:string)=>{let hash=2166136261;for(const c of text)hash=Math.imul(hash^c.charCodeAt(0),16777619);return (hash>>>0).toString(16)}