fix(beehive): own custom harness discovery independently of Desktop

Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
Logan Johnson
2026-09-21 12:20:09 -04:00
parent caa7eca39e
commit 8a9732be9b
3 changed files with 29 additions and 8 deletions

View File

@@ -872,3 +872,18 @@ CHECKPOINT's MODEL_PROVIDER_CORRECTION entry for validation and observation limi
Public identity editing/publication is separate from private instructions: see
[PUBLIC_METADATA.md](PUBLIC_METADATA.md) for offline metadata drafts, deliberate
agent-signed kind0 publication while stopped, and pending/error recovery.
### Standalone harness inventory
Beehive ships its built-in runtime catalog in `src/harness-contract.json`.
Desktop is not required. Additional local detection definitions live in
`~/.beehive/custom_harnesses/*.json` on every platform (under `BEEHIVE_HOME`
when set). A definition has `id`, `label`, and `command` fields; `command` is
an absolute executable path or a command name resolved through local discovery.
Built-in IDs cannot be overridden. Malformed definitions are ignored.
Beehive does not read or automatically import Desktop's `custom_harnesses`.
To reuse a local definition, explicitly copy its JSON into the Beehive directory
and choose **Refresh harnesses**. Only detection fields are read: launch arguments,
environment variables, credentials, and Desktop agent state are not imported.
Refresh replaces the saved inventory; saved runtime configurations are unchanged.

View File

@@ -57,13 +57,13 @@ function customHarnesses(directory: string, reserved: Set<string>): HarnessDefin
const value = JSON.parse(readFileSync(path, 'utf8')) as Partial<HarnessDefinition>;
if (!value.id || !validCustomId(value.id) || reserved.has(value.id) || typeof value.label !== 'string' || !value.label.trim() || typeof value.command !== 'string' || !value.command.trim()) continue;
reserved.add(value.id); result.push({ id: value.id, label: value.label, command: value.command });
} catch { /* One malformed Desktop definition must not suppress the rest. */ }
} catch { /* One malformed local definition must not suppress the rest. */ }
return result;
}
/** Forced local discovery at startup or explicit refresh. Inputs permit isolated
* fixture roots and fake probe executables. Desktop custom definitions are
* included from the same app-data directory when that directory exists. */
* fixture roots and fake probe executables. Beehive owns its custom definitions;
* Desktop installation state is not a catalog input. */
export async function discoverHarnesses(signal: AbortSignal, options: { home?: string; path?: string; bundled?: string[]; common?: string[]; loginShells?: string[]; customDirectories?: string[]; probe?: typeof harnessProbe } = {}): Promise<DetectedHarness[]> {
const home = options.home ?? homedir(), path = options.path ?? process.env.PATH ?? '', probe = options.probe ?? harnessProbe;
const bundled = options.bundled ?? [fileURLToPath(new URL('../bin', import.meta.url)), '/Applications/Buzz.app/Contents/MacOS'];
@@ -107,11 +107,11 @@ export async function discoverHarnesses(signal: AbortSignal, options: { home?: s
result.push({ id: row.id, label: row.label!, executable: binary, cli, ...(detectedVersion ? { version: detectedVersion } : {}), state, providers, reason });
}
const reserved = new Set(result.map(row => row.id));
for (const directory of options.customDirectories ?? (process.platform === 'darwin' ? [join(data, 'xyz.block.buzz.app/custom_harnesses')] : [])) {
for (const directory of options.customDirectories ?? [join(home, '.beehive', 'custom_harnesses')]) {
for (const definition of customHarnesses(directory, reserved)) {
signal.throwIfAborted();
const binary = await resolve(definition.command);
result.push({ id: definition.id, label: definition.label, ...(binary ? { executable: binary } : {}), state: binary ? 'available' : 'not-installed', providers: [], reason: binary ? 'Detected from Buzz Desktop custom harnesses; native configuration is retained by that harness.' : 'Custom harness executable not installed' });
result.push({ id: definition.id, label: definition.label, ...(binary ? { executable: binary } : {}), state: binary ? 'available' : 'not-installed', providers: [], reason: binary ? 'Detected from Beehive custom harnesses; native configuration is retained by that harness.' : 'Custom harness executable not installed' });
}
}
return result;

View File

@@ -83,15 +83,21 @@ test('production adapter discovers and durably saves only an explicit isolated H
} finally { rmSync(home, { recursive: true, force: true }); }
});
test('discovers Buzz Desktop custom harness definitions with absolute commands and skips malformed entries', async () => {
test('discovers Beehive-owned definitions without Desktop and skips malformed entries', async () => {
const root = mkdtempSync(join(tmpdir(), 'beehive-custom-harnesses-'));
try {
const command = join(root, 'pic-pi-acp'); writeFileSync(command, '#!/bin/sh\necho custom\n'); chmodSync(command, 0o700);
const definitions = join(root, 'custom_harnesses'); mkdirSync(definitions);
const definitions = join(root, '.beehive', 'custom_harnesses'); mkdirSync(definitions, { recursive: true });
writeFileSync(join(definitions, 'custom.json'), JSON.stringify({ id: 'pic-pi', label: 'Pi custom', command, args: [] }));
writeFileSync(join(definitions, 'bad.json'), '{');
// Desktop-only entries must not leak into Beehive, even when installed.
const desktop = join(root, 'Library/Application Support/xyz.block.buzz.app/custom_harnesses');
mkdirSync(desktop, { recursive: true });
writeFileSync(join(desktop, 'desktop.json'), JSON.stringify({ id: 'desktop-only', label: 'Desktop only', command }));
const { discoverHarnesses } = await import('../src/harness-discovery.ts');
const rows = await discoverHarnesses(new AbortController().signal, { home: root, path: '', bundled: [], common: [], loginShells: [], customDirectories: [definitions] });
const rows = await discoverHarnesses(new AbortController().signal, { home: root, path: '', bundled: [], common: [], loginShells: [] });
assert.equal(rows.some(value => value.id === 'desktop-only'), false);
assert.equal(rows.some(value => value.id === 'buzz-agent'), true, 'built-in catalog requires no Desktop');
assert.deepEqual(rows.filter(value => value.id === 'pic-pi').map(value => ({ label: value.label, state: value.state, executable: value.executable })), [{ label: 'Pi custom', state: 'available', executable: realpathSync(command) }]);
} finally { rmSync(root, { recursive: true, force: true }); }
});