103 lines
3.2 KiB
JavaScript
103 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
import assert from 'node:assert/strict';
|
|
import { execFileSync } from 'node:child_process';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const repoRoot = path.resolve(__dirname, '..');
|
|
const wrapperPath = path.join(repoRoot, 'scripts', 'long_task_governor_wrapper.mjs');
|
|
|
|
const fixtures = [
|
|
{
|
|
name: 'example',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.classification, 'long_task');
|
|
},
|
|
},
|
|
{
|
|
name: 'invalid silent',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_invalid_silent_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.silentLaunchOk, false);
|
|
},
|
|
},
|
|
{
|
|
name: 'general chat',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_general_chat_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.classification, 'general_chat');
|
|
},
|
|
},
|
|
{
|
|
name: 'non-silent long task',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_non_silent_long_task_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.classification, 'long_task');
|
|
assert.equal(output.silentCandidate, false);
|
|
},
|
|
},
|
|
{
|
|
name: 'owner decision',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_silent_owner_decision_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.handoff.mode, 'button_path');
|
|
},
|
|
},
|
|
{
|
|
name: 'subagent wait',
|
|
file: path.join(repoRoot, 'docs', '_artifacts', 'long_task_governor_wrapper_subagent_wait_example.json'),
|
|
assert(output) {
|
|
assert.equal(output.silentCandidate, true);
|
|
},
|
|
},
|
|
];
|
|
|
|
function runFixture(fixture) {
|
|
const stdout = execFileSync(process.execPath, [wrapperPath, '--compact', '--input', fixture.file], {
|
|
cwd: repoRoot,
|
|
encoding: 'utf8',
|
|
});
|
|
|
|
let output;
|
|
try {
|
|
output = JSON.parse(stdout);
|
|
} catch (error) {
|
|
throw new Error(`Fixture \"${fixture.name}\" did not produce valid JSON: ${error.message}\nOutput: ${stdout}`);
|
|
}
|
|
|
|
assert.ok(output.classification !== undefined, `${fixture.name}: missing classification`);
|
|
assert.ok(output.silentCandidate !== undefined, `${fixture.name}: missing silentCandidate`);
|
|
assert.ok(output.silentLaunchOk !== undefined, `${fixture.name}: missing silentLaunchOk`);
|
|
assert.ok(output.requiredNextAction !== undefined, `${fixture.name}: missing requiredNextAction`);
|
|
assert.ok(output.handoff && output.handoff.mode !== undefined, `${fixture.name}: missing handoff.mode`);
|
|
|
|
fixture.assert(output);
|
|
|
|
return {
|
|
name: fixture.name,
|
|
output,
|
|
};
|
|
}
|
|
|
|
function main() {
|
|
const results = fixtures.map(runFixture);
|
|
const summary = {
|
|
passed: results.length,
|
|
fixtures: results.map(({ name, output }) => ({
|
|
name,
|
|
classification: output.classification,
|
|
silentCandidate: output.silentCandidate,
|
|
silentLaunchOk: output.silentLaunchOk,
|
|
requiredNextAction: output.requiredNextAction,
|
|
handoffMode: output.handoff.mode,
|
|
})),
|
|
};
|
|
|
|
process.stdout.write(JSON.stringify(summary, null, 2) + '\n');
|
|
}
|
|
|
|
main();
|