mirror of
https://github.com/JuliusBrussee/caveman.git
synced 2026-09-14 18:02:35 +08:00
82864c8f4c
Single-commit port of the Caveman 2 tree onto the original repo history (candidate caveman-2@88878a4 applied over main@3098342). No unrelated-history merge; original history untouched. Preserved v1 surfaces: - skills/caveman/SKILL.md byte-for-byte, plus plugin mirror and caveman.skill zip - legacy CI (Node 18/20/22 installer + Python 3.11 suites) alongside engine-ci - cli/install.js compatibility shim forwarding to bin/install.js - .codex/config.toml ships both hooks and codex_hooks for older Codex (#617) - README Trendshift + Skills.sh badges and local star-history asset - v1.10.0-pinned curl installs; benchmarks/tmp-starcharts ignore rules Fixed for public same-repo release: - SECURITY.md vulnerability reporting points at this repository - release-binaries.yml publishes to this repo via job-scoped GITHUB_TOKEN (cross-repo PAT removed); binary-release environment still gates signing - packages/cli/PUBLISHING.md rewritten for packages/ layout and same-repo flow - profile-contract and provider-catalog lanes skip lane-scope gates on initial import so the launch PR can gate on their real validation steps - ANNOUNCEMENT.md network claim corrected: compression is local; requests still go to the provider you configured Caveman 2 stays opt-in: bin-v1.0.0 binaries and @caveman-ai/cli publish separately after this lands and soaks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BLvb5QniwYjmcawyssQNw9
82 lines
2.7 KiB
JavaScript
82 lines
2.7 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert";
|
|
import { spawn } from "node:child_process";
|
|
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const cli = join(here, "..", "dist", "index.js");
|
|
|
|
function proxyStub(dir) {
|
|
const path = join(dir, "caveman-proxy-stub.mjs");
|
|
writeFileSync(path, `#!/usr/bin/env node
|
|
const rows = JSON.parse(process.env.STUB_PROXY_ROWS || "[]");
|
|
for (const row of rows) {
|
|
if (row.ts === "__NOW__") row.ts = new Date().toISOString();
|
|
}
|
|
if (process.argv[2] !== "stats" || !process.argv.includes("--recent")) process.exit(2);
|
|
process.stdout.write(JSON.stringify(rows));
|
|
`, { mode: 0o755 });
|
|
return path;
|
|
}
|
|
|
|
function runVerify(args, rows) {
|
|
const dir = mkdtempSync(join(tmpdir(), "cave-verify-"));
|
|
const stub = proxyStub(dir);
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn("node", [cli, "verify", ...args], {
|
|
env: {
|
|
...process.env,
|
|
NO_COLOR: "1",
|
|
CAVEMAN_PROXY_BIN: stub,
|
|
STUB_PROXY_ROWS: JSON.stringify(rows),
|
|
},
|
|
});
|
|
let stdout = "";
|
|
let stderr = "";
|
|
child.stdout.on("data", (d) => (stdout += d));
|
|
child.stderr.on("data", (d) => (stderr += d));
|
|
child.on("exit", (code) => resolve({ code, stdout, stderr }));
|
|
child.on("error", reject);
|
|
});
|
|
}
|
|
|
|
test("verify succeeds when proxy reports a fresh row for the requested app", async () => {
|
|
const out = await runVerify(["--app", "checkout", "--timeout-ms", "500"], [{
|
|
ts: "__NOW__",
|
|
agent_slug: "checkout",
|
|
provider: "openai",
|
|
model: "gpt-4.1",
|
|
endpoint: "/w/checkout/openai/v1/responses",
|
|
input_tokens: 123,
|
|
output_tokens: 45,
|
|
basis: "inferred",
|
|
}]);
|
|
assert.equal(out.code, 0, out.stderr);
|
|
assert.equal(out.stdout.trim(), "checkout openai/gpt-4.1 input:123 output:45 basis: inferred");
|
|
});
|
|
|
|
test("verify exits non-zero on empty recent rows", async () => {
|
|
const out = await runVerify(["--timeout-ms", "50"], []);
|
|
assert.notEqual(out.code, 0, "empty rows must fail");
|
|
assert.match(out.stderr, /no request seen through the proxy in 1s/);
|
|
assert.match(out.stderr, /caveman start/);
|
|
});
|
|
|
|
test("verify exits non-zero on stale recent rows", async () => {
|
|
const out = await runVerify(["--app", "checkout", "--timeout-ms", "50"], [{
|
|
ts: "2000-01-01T00:00:00.000Z",
|
|
agent_slug: "checkout",
|
|
provider: "openai",
|
|
model: "gpt-4.1",
|
|
endpoint: "/w/checkout/openai/v1/responses",
|
|
input_tokens: 123,
|
|
output_tokens: 45,
|
|
basis: "inferred",
|
|
}]);
|
|
assert.notEqual(out.code, 0, "stale rows must fail");
|
|
assert.match(out.stderr, /no request seen through the proxy in 1s/);
|
|
});
|