mirror of
https://github.com/Ryder-Sun/Meldwork.git
synced 2026-11-07 06:56:03 -10:00
Implement frozen concurrent responses, Agent-negotiated V4 discussion work, strict durable receipts and recovery, validated runtime phase UI, and the animated return-to-bottom control. Prepare the 0.1.2 prerelease metadata and documentation.\n\nChecks before commit: frontend 299/299; desktop 1270/1270; deterministic eval 6 cases/18 results; web and desktop renderer builds; desktop pack; staged and unstaged diff checks.
72 lines
1.9 KiB
JavaScript
72 lines
1.9 KiB
JavaScript
const fs = require('node:fs')
|
|
const path = require('node:path')
|
|
|
|
function executable(directory, name, source) {
|
|
const filename = path.join(directory, name)
|
|
fs.writeFileSync(filename, `#!/usr/bin/env node\n${source}`)
|
|
fs.chmodSync(filename, 0o755)
|
|
return filename
|
|
}
|
|
|
|
async function readWhenReady(filename, timeoutMs = 5000) {
|
|
const deadline = Date.now() + timeoutMs
|
|
while (Date.now() < deadline) {
|
|
try {
|
|
const value = fs.readFileSync(filename, 'utf8')
|
|
if (value) return value
|
|
} catch {
|
|
// Wait for the writer to create the file.
|
|
}
|
|
await new Promise(resolve => setTimeout(resolve, 20))
|
|
}
|
|
throw new Error(`Timed out waiting for ${filename}`)
|
|
}
|
|
|
|
async function readJsonWhenReady(filename, timeoutMs = 5000) {
|
|
const deadline = Date.now() + timeoutMs
|
|
while (Date.now() < deadline) {
|
|
try {
|
|
const value = fs.readFileSync(filename, 'utf8')
|
|
if (value) return JSON.parse(value)
|
|
} catch { /* wait for the writer to finish */ }
|
|
await new Promise(resolve => setTimeout(resolve, 20))
|
|
}
|
|
throw new Error(`Timed out waiting for complete JSON in ${filename}`)
|
|
}
|
|
|
|
async function within(promise, timeoutMs = 3000) {
|
|
let timeout
|
|
try {
|
|
return await Promise.race([
|
|
promise,
|
|
new Promise((_, reject) => {
|
|
timeout = setTimeout(() => reject(new Error('Agent cancellation did not settle.')), timeoutMs)
|
|
}),
|
|
])
|
|
} finally {
|
|
clearTimeout(timeout)
|
|
}
|
|
}
|
|
|
|
async function waitForExit(pid, timeoutMs = 1000) {
|
|
const deadline = Date.now() + timeoutMs
|
|
while (Date.now() < deadline) {
|
|
try {
|
|
process.kill(pid, 0)
|
|
} catch (error) {
|
|
if (error.code === 'ESRCH') return
|
|
throw error
|
|
}
|
|
await new Promise(resolve => setTimeout(resolve, 20))
|
|
}
|
|
throw new Error(`Process ${pid} did not exit.`)
|
|
}
|
|
|
|
module.exports = {
|
|
executable,
|
|
readJsonWhenReady,
|
|
readWhenReady,
|
|
waitForExit,
|
|
within,
|
|
}
|