Files
orca/src/main/opencode/opencode-overlay-manifest.ts
T
70cf91299b Clean up retired OpenCode configuration copies safely (#25222)
* fix: wait for OpenCode worker composer before first dispatch

Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors.

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>

* feat(opencode): probe execution-host CLI capabilities

* fix(opencode): select plugin default for execution host loader

* fix(opencode): limit prompt prefill capability to verified release

* feat(opencode): probe launch capabilities on the execution host

* fix(opencode): select plugin loader for the launched host binary

* fix(opencode): match WSL probe cwd and declared guest environment

* fix(opencode): preserve launch environment deletion boundaries

* wip(opencode): authorize native startup prompt intent at execution owner

* fix(opencode): atomically replace status plugin entrypoints

* fix(opencode): retain plugin permissions across restrictive umasks

* test(opencode): resolve permission fixture from primary cwd

* feat(opencode): install startup prompt plugin independently of status hooks

* fix(opencode): wait for admitted startup intent and preserve failed-launch briefs

* fix(opencode): confine overlay manifest cleanup to owned directories

Co-authored-by: Adnan Khan <adnank11427@gmail.com>

* fix: wait for OpenCode worker composer before first dispatch

Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors.

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>

* feat(opencode): probe execution-host CLI capabilities

* fix(opencode): select plugin default for execution host loader

* fix(opencode): limit prompt prefill capability to verified release

* feat(opencode): probe launch capabilities on the execution host

* fix(opencode): select plugin loader for the launched host binary

* fix(opencode): match WSL probe cwd and declared guest environment

* fix(opencode): preserve launch environment deletion boundaries

* wip(opencode): authorize native startup prompt intent at execution owner

* fix(opencode): atomically replace status plugin entrypoints

* fix(opencode): retain plugin permissions across restrictive umasks

* test(opencode): resolve permission fixture from primary cwd

* feat(opencode): install startup prompt plugin independently of status hooks

* fix(opencode): wait for admitted startup intent and preserve failed-launch briefs

* fix(opencode): unsubscribe hook settings during async host shutdown

* STRICT launch CI contract correction

* CAPS launch CI contract correction

* INTENT launch CI contract correction

* test: initialize Claude prompt state in output retention fixture

* Wait for OpenCode location hydration in intent startup

* Bind OpenCode startup readiness to the current location in intent startup

* Collect retired source-scoped OpenCode configuration overlays conservatively

Credit brennanb2025 for the original bounded, delayed overlay garbage-collection contribution in PR #7627. Preserve ambiguous legacy and shared-service state.

* Correct inaccessible-source fixture without spying on native ESM exports

* Keep delayed OpenCode cleanup within existing file limits

* Reuse the overlay manifest module for existing owned-entry operations

* Use the existing filesystem import in the ownership mock

* test(opencode): keep overlay GC link tests portable

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
Co-authored-by: Ahmed Nagy <ahmednagy25t@gmail.com>
Co-authored-by: Adnan Khan <adnank11427@gmail.com>
Co-authored-by: Orca startup hydration review <agents@stably.ai>
Co-authored-by: OpenCode Campaign <opencode-campaign@users.noreply.github.com>
2026-10-04 05:40:05 -07:00

65 lines
2.0 KiB
TypeScript

import { readFileSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
import { safeRemoveOverlay } from '../pty/overlay-mirror'
export const OPENCODE_OVERLAY_MANIFEST_FILE = '.orca-opencode-overlay-manifest.json'
export type OpenCodeOverlayManifest = {
topLevelEntries: string[]
pluginEntries: string[]
sourceConfigDir?: string
}
export function readOpenCodeOverlayManifest(overlayDir: string): OpenCodeOverlayManifest {
const empty = { topLevelEntries: [], pluginEntries: [] }
try {
const parsed: unknown = JSON.parse(
readFileSync(join(overlayDir, OPENCODE_OVERLAY_MANIFEST_FILE), 'utf8')
)
if (!parsed || typeof parsed !== 'object') {
return empty
}
return {
...('sourceConfigDir' in parsed && typeof parsed.sourceConfigDir === 'string'
? { sourceConfigDir: parsed.sourceConfigDir }
: {}),
topLevelEntries:
'topLevelEntries' in parsed && Array.isArray(parsed.topLevelEntries)
? parsed.topLevelEntries.filter((entry): entry is string => typeof entry === 'string')
: [],
pluginEntries:
'pluginEntries' in parsed && Array.isArray(parsed.pluginEntries)
? parsed.pluginEntries.filter((entry): entry is string => typeof entry === 'string')
: []
}
} catch {
return empty
}
}
export function writeOpenCodeOverlayManifest(
overlayDir: string,
manifest: OpenCodeOverlayManifest
): void {
writeFileSync(
join(overlayDir, OPENCODE_OVERLAY_MANIFEST_FILE),
`${JSON.stringify(manifest, null, 2)}\n`
)
}
export function clearOpenCodeOverlayManifestEntries(
overlayDir: string,
manifest: OpenCodeOverlayManifest,
pluginFileName: string
): void {
for (const entryName of manifest.topLevelEntries) {
safeRemoveOverlay(join(overlayDir, entryName), overlayDir)
}
const overlayPluginsDir = join(overlayDir, 'plugins')
for (const entryName of manifest.pluginEntries) {
if (entryName === pluginFileName) {
continue
}
safeRemoveOverlay(join(overlayPluginsDir, entryName), overlayPluginsDir)
}
}