feat(omo-claude): add sync-components vendoring script with --check drift gate
Copies 6 omo-codex components (rules, comment-checker, lsp, ultrawork, ultragoal, start-work-continuation) into the CC plugin tree and applies a declarative patch manifest: relax model/turn_id validators, CLAUDE_PLUGIN_ROOT/ DATA env fallbacks, .codex-plugin->.claude-plugin, rules matcher widened to Write|Edit|MultiEdit, start-work-continuation claude: session prefix. ultragoal copied verbatim (deep refactor is a later task). --check detects vendor drift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import assert from "node:assert/strict";
|
||||
import { dirname, join } from "node:path";
|
||||
import { test } from "node:test";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { HANDLED_COMPONENTS, PATCH_MANIFEST, syncComponents } from "./sync-components.mjs";
|
||||
|
||||
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
||||
const SCRIPT_PATH = join(SCRIPT_DIR, "sync-components.mjs");
|
||||
const PLUGIN_ROOT = dirname(SCRIPT_DIR);
|
||||
const DRIFT_FILE = join(PLUGIN_ROOT, "components", "lsp", "src", "codex-hook.ts");
|
||||
|
||||
function runCli(args) {
|
||||
return spawnSync(process.execPath, [SCRIPT_PATH, ...args], { encoding: "utf8" });
|
||||
}
|
||||
|
||||
test("sync then --check is GREEN (exit 0)", () => {
|
||||
const sync = runCli([]);
|
||||
assert.equal(sync.status, 0, `sync failed: ${sync.stderr}`);
|
||||
|
||||
const check = runCli(["--check"]);
|
||||
assert.equal(check.status, 0, `--check should be green after sync but got: ${check.stderr}`);
|
||||
assert.match(check.stdout, /in sync/);
|
||||
});
|
||||
|
||||
test("--check is RED (nonzero) after hand-drift, then re-sync restores GREEN", async () => {
|
||||
runCli([]);
|
||||
|
||||
const original = await readFile(DRIFT_FILE, "utf8");
|
||||
try {
|
||||
await writeFile(DRIFT_FILE, `${original}\n// drift\n`);
|
||||
const drifted = runCli(["--check"]);
|
||||
assert.notEqual(drifted.status, 0, "--check must fail after hand-drift");
|
||||
assert.match(drifted.stderr, /out of sync/);
|
||||
assert.match(drifted.stderr, /lsp\/src\/codex-hook\.ts/);
|
||||
} finally {
|
||||
// Re-sync to restore the vendored tree regardless of assertion outcome.
|
||||
const restore = runCli([]);
|
||||
assert.equal(restore.status, 0, `restore sync failed: ${restore.stderr}`);
|
||||
}
|
||||
|
||||
const check = runCli(["--check"]);
|
||||
assert.equal(check.status, 0, `--check should be green again after re-sync: ${check.stderr}`);
|
||||
});
|
||||
|
||||
test("sync is idempotent (running twice yields no drift)", () => {
|
||||
assert.equal(runCli([]).status, 0);
|
||||
assert.equal(runCli([]).status, 0);
|
||||
assert.equal(runCli(["--check"]).status, 0);
|
||||
});
|
||||
|
||||
test("a single component can be synced and check passes", () => {
|
||||
const sync = runCli(["rules"]);
|
||||
assert.equal(sync.status, 0, sync.stderr);
|
||||
assert.match(sync.stdout, /rules/);
|
||||
// Re-sync all so the rest of the suite/state is whole.
|
||||
assert.equal(runCli([]).status, 0);
|
||||
assert.equal(runCli(["--check"]).status, 0);
|
||||
});
|
||||
|
||||
test("unknown component is rejected", () => {
|
||||
const result = runCli(["does-not-exist"]);
|
||||
assert.notEqual(result.status, 0);
|
||||
assert.match(result.stderr, /unknown component/);
|
||||
});
|
||||
|
||||
test("every required replacement in the manifest matches the source", async () => {
|
||||
const matched = [];
|
||||
await syncComponents({ check: true, components: HANDLED_COMPONENTS });
|
||||
// syncComponents records matches via its internal collector; re-derive by
|
||||
// running a check pass and asserting no required replacement is unmatched.
|
||||
const result = await syncComponents({ check: true });
|
||||
for (const entry of result.matched) {
|
||||
if (entry.required) {
|
||||
assert.equal(
|
||||
entry.matched,
|
||||
true,
|
||||
`required replacement did not match: ${entry.component}/${entry.file} :: ${entry.find}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
assert.ok(result.matched.length >= PATCH_MANIFEST.length, "expected manifest replacements to be exercised");
|
||||
// matched local kept for clarity; not otherwise used.
|
||||
void matched;
|
||||
});
|
||||
Reference in New Issue
Block a user