mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 00:02:56 +00:00
* fix(vault): read OpenCode SQLite on WSL and SSH execution hosts * fix(vault): bound host setup and preserve cancellation across readers * fix(vault): keep WSL discovery visible and isolate probe tests * fix: retry local Vault runtime downloads without reserving remote stages Preserve verified remote cache reuse and latch only unresolved host work. Update WSL source-guard and remote dedup test integration. * fix(queue): discard aborted requests before respawn * fix(vault): preserve host paths and recover setup after reconnect * fix(ssh): fence every runtime platform probe across reconnects * fix(vault): reject setup results from superseded SSH connections --------- Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
152 lines
6.5 KiB
TypeScript
152 lines
6.5 KiB
TypeScript
import { shellEscape } from './ssh-connection-utils'
|
|
import { posix, win32 } from 'node:path'
|
|
import { powerShellCommand, powerShellLiteral, powerShellNativeArg } from './ssh-remote-powershell'
|
|
import { isWindowsRemoteHost, type RemoteHostPlatform } from './ssh-remote-platform'
|
|
|
|
export const OPENCODE_RUNTIME_RESULT = 'ORCA_VAULT_SQLITE:'
|
|
|
|
function nodeCommand(
|
|
host: RemoteHostPlatform,
|
|
nodePath: string,
|
|
script: string,
|
|
args: string[]
|
|
): string {
|
|
if (isWindowsRemoteHost(host)) {
|
|
return powerShellCommand(
|
|
`& ${powerShellLiteral(nodePath)} -e ${powerShellNativeArg(script)} -- ${args.map(powerShellNativeArg).join(' ')}; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }`
|
|
)
|
|
}
|
|
return `${shellEscape(nodePath)} -e ${shellEscape(script)} -- ${args.map(shellEscape).join(' ')}`
|
|
}
|
|
|
|
const SEND = `const send=(value)=>console.log(${JSON.stringify(OPENCODE_RUNTIME_RESULT)}+JSON.stringify(value));`
|
|
const HASH = `const fs=require('node:fs');const fsp=fs.promises;const path=require('node:path');
|
|
async function hash(file){try{const digest=require('node:crypto').createHash('sha256');for await(const chunk of fs.createReadStream(file))digest.update(chunk);return digest.digest('hex')}catch(error){if(error.code==='ENOENT')return null;throw error}}
|
|
`
|
|
|
|
export function probeOpenCodeNodeSqliteCommand(
|
|
host: RemoteHostPlatform,
|
|
nodePath: string,
|
|
homeDirectory: string
|
|
): string {
|
|
return nodeCommand(
|
|
host,
|
|
nodePath,
|
|
`${SEND}
|
|
const fs=require('node:fs/promises');const path=require('node:path');
|
|
(async()=>{const data=path.join(process.env.XDG_DATA_HOME?.trim()||path.join(process.argv[1],'.local','share'),'opencode');
|
|
const override=process.env.OPENCODE_DB?.trim();let present=false;
|
|
try{if(override&&override!==':memory:'){present=(await fs.stat(path.isAbsolute(override)?override:path.join(data,override))).isFile()}
|
|
else if(!override){const directory=await fs.opendir(data);for await(const entry of directory){if(entry.isFile()&&/^opencode(?:-[A-Za-z0-9_.-]+)?\\.db$/.test(entry.name)){present=true;break}}}}
|
|
catch(error){if(error.code!=='ENOENT'&&error.code!=='ENOTDIR')throw error}
|
|
if(!present){send({status:'not-needed'});return}
|
|
let db;try{db=new(require('node:sqlite').DatabaseSync)(':memory:');
|
|
if(db.prepare('SELECT 1 AS ready').get().ready!==1)throw Error('SQLite read failed');
|
|
send({status:'ready',executable:process.execPath})}catch{send({status:'unsupported'})}finally{if(db)db.close()}
|
|
})().catch(error=>{console.error(error.message);process.exitCode=1})`,
|
|
[homeDirectory]
|
|
)
|
|
}
|
|
|
|
export function probeOpenCodeRuntimeCacheCommand(args: {
|
|
host: RemoteHostPlatform
|
|
nodePath: string
|
|
executable: string
|
|
expectedHash: string
|
|
reference: string
|
|
}): string {
|
|
return nodeCommand(
|
|
args.host,
|
|
args.nodePath,
|
|
`${HASH}${SEND}
|
|
(async()=>{const [executable,expected,reference]=process.argv.slice(1);
|
|
let candidate=executable;let digest=candidate?await hash(candidate):null;
|
|
if(candidate&&digest!==expected){try{const ref=JSON.parse(await fsp.readFile(reference,'utf8'));
|
|
const relative=path.relative(path.dirname(executable),ref.executable);
|
|
if(ref.protocol===1&&relative&&!relative.startsWith('..'+path.sep)&&relative!=='..'&&!path.isAbsolute(relative)){candidate=ref.executable;digest=await hash(candidate)}}catch{}}
|
|
if(candidate&&digest===expected){if(process.platform!=='win32')await fsp.chmod(candidate,448);send({status:'ready',executable:candidate});return}
|
|
send({status:'missing'})})().catch(error=>{console.error(error.message);process.exitCode=1})`,
|
|
[args.executable, args.expectedHash, args.reference]
|
|
)
|
|
}
|
|
|
|
export function promoteOpenCodeRuntimeCommand(args: {
|
|
host: RemoteHostPlatform
|
|
nodePath: string
|
|
stagedBinary: string
|
|
executable: string
|
|
expectedHash: string
|
|
repairToken: string
|
|
}): string {
|
|
return nodeCommand(
|
|
args.host,
|
|
args.nodePath,
|
|
`${HASH}${SEND}
|
|
(async()=>{const [source,destination,expected,token]=process.argv.slice(1);
|
|
if(await hash(source)!==expected)throw Error('Uploaded SQLite runtime checksum mismatch');
|
|
let executable=destination;const existing=await hash(destination);
|
|
if(existing!==expected){
|
|
if(existing!==null)executable=path.join(path.dirname(destination),'repair-'+token,path.basename(destination));
|
|
await fsp.mkdir(path.dirname(executable),{recursive:true,mode:448});
|
|
if(process.platform!=='win32')await fsp.chmod(source,448);
|
|
try{await fsp.link(source,executable)}catch(error){if(await hash(executable)!==expected){
|
|
if(!['EPERM','EOPNOTSUPP','ENOTSUP','ENOSYS','EXDEV'].includes(error.code))throw error;
|
|
executable=path.join(path.dirname(destination),'repair-'+token,path.basename(destination));
|
|
await fsp.mkdir(path.dirname(executable),{recursive:true,mode:448});await fsp.rename(source,executable)
|
|
}}
|
|
}
|
|
send({status:'ready',executable})})().catch(error=>{console.error(error.message);process.exitCode=1})`,
|
|
[args.stagedBinary, args.executable, args.expectedHash, args.repairToken]
|
|
)
|
|
}
|
|
|
|
export function publishOpenCodeRuntimeReferenceCommand(args: {
|
|
host: RemoteHostPlatform
|
|
nodePath: string
|
|
stagedReference: string
|
|
reference: string
|
|
token: string
|
|
}): string {
|
|
return nodeCommand(
|
|
args.host,
|
|
args.nodePath,
|
|
`${SEND}
|
|
const fs=require('node:fs/promises');const path=require('node:path');
|
|
(async()=>{const [source,destination,token]=process.argv.slice(1);const temporary=destination+'.upload-'+token;
|
|
try{await fs.copyFile(source,temporary,require('node:fs').constants.COPYFILE_EXCL);
|
|
await fs.rename(temporary,destination);send({status:'published'})}
|
|
finally{await fs.rm(temporary,{force:true})}})().catch(error=>{console.error(error.message);process.exitCode=1})`,
|
|
[args.stagedReference, args.reference, args.token]
|
|
)
|
|
}
|
|
|
|
export function parseOpenCodeRuntimeResult(output: string): {
|
|
status: string
|
|
executable?: string
|
|
} {
|
|
const line = output.split(/\r?\n/).findLast((entry) => entry.startsWith(OPENCODE_RUNTIME_RESULT))
|
|
if (!line) {
|
|
throw new Error('The host did not confirm SQLite runtime setup.')
|
|
}
|
|
const result: unknown = JSON.parse(line.slice(OPENCODE_RUNTIME_RESULT.length))
|
|
if (
|
|
typeof result !== 'object' ||
|
|
result === null ||
|
|
!('status' in result) ||
|
|
typeof result.status !== 'string'
|
|
) {
|
|
throw new Error('Invalid SQLite runtime setup result.')
|
|
}
|
|
if ('executable' in result) {
|
|
if (
|
|
typeof result.executable !== 'string' ||
|
|
!(posix.isAbsolute(result.executable) || win32.isAbsolute(result.executable)) ||
|
|
/[\0\r\n]/.test(result.executable)
|
|
) {
|
|
throw new Error('SQLite runtime setup returned an invalid executable path.')
|
|
}
|
|
return { status: result.status, executable: result.executable }
|
|
}
|
|
return { status: result.status }
|
|
}
|