mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 09:27:29 +00:00
* refactor(tooling): organize test runtime and maintenance owners * test(tooling): preserve relocated runtime fixture dependency edges * refactor(tooling): preserve xterm routing owner checks * ci(tooling): include routing owner in sparse checkout * test(tooling): preserve copied workflow dependency closures * fix(tooling): normalize hashed JSON assets in release parity * fix(tooling): distinguish asset aliases from literal references * fix(tooling): frame normalized asset reference payloads * fix(tooling): normalize decoded JSON asset references * refactor(tooling): organize build, CI and release owners * fix(tooling): align moved generator and workflow path contracts * fix(tooling): update generated plugin bundle owner banners * test(tooling): create relocated mobile verifier fixture directories * test(tooling): copy headless detector dependency closure * test(tooling): align native batch policy fixtures with owner path * fix(tooling): link moved reliability command to historical evidence * fix(tooling): preserve nested sandbox owners and canonical guide source * fix(tooling): target release version owners in checkout fixture
54 lines
2.2 KiB
JavaScript
54 lines
2.2 KiB
JavaScript
import { execFileSync } from 'node:child_process'
|
||
|
||
/** Written once a bundle is fully built; its absence is what marks a build still in flight. */
|
||
export const DEV_BUNDLE_MARKER_FILENAME = 'orca-dev-electron-app.json'
|
||
|
||
export function getDevBundleProcessTable(execFile = execFileSync) {
|
||
// Use portable ps -ww, not macOS pgrep (no -a); truncated/missing commands could delete live bundles. Search raw paths; see isDevBundleInUse.
|
||
try {
|
||
return execFile('/bin/ps', ['-Awwo', 'command='], {
|
||
encoding: 'utf8',
|
||
stdio: ['ignore', 'pipe', 'ignore'],
|
||
timeout: 5000
|
||
})
|
||
} catch {
|
||
// Treating a failure as "nothing live" would risk deleting a running bundle, so skip pruning.
|
||
return null
|
||
}
|
||
}
|
||
|
||
// Reclaim renamed/old-version Electron.app siblings: dev only clears its own target, leaving ~270MB per stale bundle (143/38GB observed).
|
||
|
||
// Age starts at mkdir, not activity: app copy/signing does not refresh parent mtime.
|
||
// Concurrent builds beyond this hard cutoff can be deleted; 130–200s builds leave 5–10x margin.
|
||
export const IN_PROGRESS_WINDOW_MS = 15 * 60 * 1000
|
||
|
||
// Protect current, live and unfinished-copy bundles: no process exists to reveal an in-flight copy before its marker.
|
||
// Search known absolute paths in raw ps text; parsing twice missed live paths. Trailing slash distinguishes dir from dir2.
|
||
export function isDevBundleInUse(dir, processTable) {
|
||
// Check both macOS /tmp and /private/tmp spellings or ps can hide a live bundle; extra protection is safe.
|
||
const alternate = dir.startsWith('/private/') ? dir.slice('/private'.length) : `/private${dir}`
|
||
return processTable.includes(`${dir}/`) || processTable.includes(`${alternate}/`)
|
||
}
|
||
|
||
export function selectStaleDevBundleDirs({
|
||
bundles,
|
||
currentDir,
|
||
processTable,
|
||
nowMs,
|
||
minAgeMs = 0
|
||
}) {
|
||
return bundles
|
||
.filter(({ dir, hasMarker, mtimeMs }) => {
|
||
if (dir === currentDir || isDevBundleInUse(dir, processTable)) {
|
||
return false
|
||
}
|
||
if (minAgeMs > 0 && nowMs - mtimeMs < minAgeMs) {
|
||
return false
|
||
}
|
||
const buildInFlight = !hasMarker && nowMs - mtimeMs < IN_PROGRESS_WINDOW_MS
|
||
return !buildInFlight
|
||
})
|
||
.map(({ dir }) => dir)
|
||
}
|