Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d295eeab | ||
|
|
0d31902b7f | ||
|
|
ccc009412e | ||
|
|
0d2bb5fb09 | ||
|
|
47dd84ea69 | ||
|
|
4e829cea2f | ||
|
|
bf30b081db | ||
|
|
15efa61149 | ||
|
|
70435de2c6 | ||
|
|
1b3371ad7f | ||
|
|
c7fdd7e153 | ||
|
|
3c794a5cc0 | ||
|
|
16caa5ca9b | ||
|
|
2a6bef5589 | ||
|
|
cace19caad | ||
|
|
87b7bf8db1 | ||
|
|
3b66532e26 | ||
|
|
3ad063b454 | ||
|
|
69485e27f7 |
No files matched your search
@@ -162,14 +162,21 @@ const resolveSourceHead = async (
|
||||
// The library probes readFile() without a path to detect promise APIs.
|
||||
// Reject that invocation without attributing it to a source read.
|
||||
if (path === undefined)
|
||||
throw new TypeError("Git filesystem read requires a path");
|
||||
throw new TypeError("Git metadata path is required");
|
||||
try {
|
||||
const bytes = await readMetadataBytes(path);
|
||||
const encoding =
|
||||
typeof options === "string" ? options : options?.encoding;
|
||||
return encoding === undefined || encoding === null
|
||||
? bytes
|
||||
: bytes.toString(encoding);
|
||||
typeof options === "string"
|
||||
? options
|
||||
: typeof options === "object" &&
|
||||
options !== null &&
|
||||
"encoding" in options
|
||||
? options.encoding
|
||||
: undefined;
|
||||
if (encoding === undefined || encoding === null) return bytes;
|
||||
if (typeof encoding !== "string" || !Buffer.isEncoding(encoding))
|
||||
throw new TypeError("Unsupported Git metadata text encoding");
|
||||
return bytes.toString(encoding);
|
||||
} catch (cause: unknown) {
|
||||
if (cause instanceof ArtifactReaderFailure) {
|
||||
cleanupFailures.push(cause);
|
||||
|
||||
@@ -8,14 +8,14 @@ import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
|
||||
cliTest(
|
||||
"rejects malformed oversized JSON through both CLI and Evidence readers",
|
||||
"rejects malformed oversized input through CLI and Evidence readers",
|
||||
async ({ cli, processes }) => {
|
||||
const root = await createTestTempDirectory("rea-json-string-limit-");
|
||||
const input = join(root, "oversized.json");
|
||||
const file = await open(input, "wx");
|
||||
try {
|
||||
// Sparse zero bytes are valid UTF-8 but invalid JSON. Both readers
|
||||
// stream the input and reject the syntax before assembling a value.
|
||||
// Sparse zero bytes are valid UTF-8. Both streaming readers reject
|
||||
// their invalid JSON syntax without assembling a whole-document string.
|
||||
await file.truncate(constants.MAX_STRING_LENGTH + 1);
|
||||
} finally {
|
||||
await file.close();
|
||||
@@ -175,7 +175,7 @@ cliTest(
|
||||
|
||||
cliTest(
|
||||
"returns a typed string assembly constraint under a bounded heap",
|
||||
async ({ cli }) => {
|
||||
async ({ cli, processes }) => {
|
||||
const root = await createTestTempDirectory("rea-json-string-headroom-");
|
||||
const input = join(root, "long-string.json");
|
||||
const file = await open(input, "wx");
|
||||
@@ -207,5 +207,21 @@ cliTest(
|
||||
action: expect.stringContaining("re-analyze a smaller selection"),
|
||||
},
|
||||
});
|
||||
const evidence = await processes.run(process.execPath, [
|
||||
"--max-old-space-size=768",
|
||||
"--input-type=module",
|
||||
"-e",
|
||||
`import { readJsonFile } from "./dist/application/JsonFiles.js";
|
||||
import { projectAnalysisError } from "./dist/domain/analysisErrorProjection.js";
|
||||
const result = await readJsonFile(process.argv[1]);
|
||||
console.log(JSON.stringify(result.ok ? result : projectAnalysisError(result.error)));`,
|
||||
input,
|
||||
]);
|
||||
expect(JSON.parse(evidence.stdout)).toMatchObject({
|
||||
code: "resource_constraint",
|
||||
details: { operation: "read_evidence_file", resource: "memory" },
|
||||
});
|
||||
expect(evidence.stderr).toBe("");
|
||||
expect(evidence.exitCode).toBe(0);
|
||||
},
|
||||
);
|
||||
+16
-12
@@ -72,17 +72,8 @@ describe("static Electron application analysis", () => {
|
||||
|
||||
const result = await reconstructJavaScriptArtifact({ input_path: root });
|
||||
const graph = parseJavaScriptApplicationGraph(result.graph);
|
||||
// Computed access keeps no known members; the unknown access is an
|
||||
// explicit dynamic flag rather than a "*" sentinel inside members.
|
||||
const accesses = graph.nodes.flatMap((node) =>
|
||||
node.kind === "native-export"
|
||||
? node.observations.map(({ properties }) => ({
|
||||
members: Array.isArray(properties.requested_members)
|
||||
? properties.requested_members
|
||||
: [],
|
||||
dynamicMemberAccess: properties.dynamic_member_access ?? false,
|
||||
}))
|
||||
: [],
|
||||
const nativeBindings = graph.nodes.filter(
|
||||
(node) => node.kind === "native-export",
|
||||
);
|
||||
|
||||
expect(result.electron_summary).toMatchObject({
|
||||
@@ -90,7 +81,20 @@ describe("static Electron application analysis", () => {
|
||||
native_addon_bindings: 1,
|
||||
resolved_native_addon_bindings: 1,
|
||||
});
|
||||
expect(accesses).toEqual([{ members: [], dynamicMemberAccess: true }]);
|
||||
expect(nativeBindings).toMatchObject([
|
||||
{
|
||||
observations: [
|
||||
{
|
||||
properties: {
|
||||
requested_members: [],
|
||||
namespace_access: false,
|
||||
dynamic_member_access: true,
|
||||
native_export_verification: "not-performed",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("maps Electron boundaries through bundler-renamed bindings", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { mkdir, writeFile } from "node:fs/promises";
|
||||
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect, it } from "vitest";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
@@ -108,3 +108,33 @@ it("reads a linked worktree's own branch and detached HEAD through shared Git re
|
||||
dirty: null,
|
||||
});
|
||||
});
|
||||
|
||||
it.skipIf(process.platform === "win32")(
|
||||
"keeps unreadable loose refs unknown instead of falling back to packed refs",
|
||||
async () => {
|
||||
const root = await createTestTempDirectory("rea-reference-loose-ref-");
|
||||
const gitdir = join(root, ".git");
|
||||
const looseRef = join(gitdir, "refs", "heads", "main");
|
||||
await mkdir(join(gitdir, "refs", "heads"), { recursive: true });
|
||||
const head = "1234567890abcdef1234567890abcdef12345678";
|
||||
await writeFile(join(gitdir, "HEAD"), "ref: refs/heads/main\n");
|
||||
await writeFile(join(gitdir, "packed-refs"), `${head} refs/heads/main\n`);
|
||||
expect(await readVcs(root)).toEqual({
|
||||
kind: "git",
|
||||
head,
|
||||
dirty: null,
|
||||
});
|
||||
if (process.getuid?.() === 0) return;
|
||||
await writeFile(looseRef, `${head}\n`);
|
||||
await chmod(looseRef, 0);
|
||||
try {
|
||||
expect(await readVcs(root)).toEqual({
|
||||
kind: "unknown",
|
||||
head: null,
|
||||
dirty: null,
|
||||
});
|
||||
} finally {
|
||||
await chmod(looseRef, 0o600);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -319,6 +319,8 @@ describe("updated executable maintenance planning", () => {
|
||||
it("runs real setup as a noninteractive dry run and creates no new integrations or backups", async () => {
|
||||
const configPath = await writeClient("codex", staleCodex);
|
||||
const untouched = await writeClient("claude_code", '{"mcpServers":{}}');
|
||||
const skillContent = `---\nname: ${PRODUCT_IDENTITY.skillName}\nmetadata:\n version: "1"\n---\n# REA\n`;
|
||||
const skillPath = await writeSkill(skillContent);
|
||||
vi.stubEnv("npm_command", "exec");
|
||||
const result = await planIntegrationMaintenance(
|
||||
home,
|
||||
@@ -328,18 +330,35 @@ describe("updated executable maintenance planning", () => {
|
||||
);
|
||||
expect(result).toMatchObject({
|
||||
status: "planned",
|
||||
scope: { clients: ["codex"], skill: false },
|
||||
plannedActions: [
|
||||
{ id: "configure_client:codex", kind: "configure_client" },
|
||||
],
|
||||
scope: {
|
||||
clients: ["codex"],
|
||||
skill: true,
|
||||
skillDestinations: [{ client: "shared", path: dirname(skillPath) }],
|
||||
},
|
||||
});
|
||||
if (result.status !== "planned") throw new Error(JSON.stringify(result));
|
||||
expect(result.plannedActions).toEqual([
|
||||
expect.objectContaining({
|
||||
id: "configure_client:codex",
|
||||
kind: "configure_client",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "install_skill",
|
||||
kind: "install_skill",
|
||||
target: dirname(skillPath),
|
||||
}),
|
||||
]);
|
||||
expect(await readFile(configPath, "utf8")).toBe(staleCodex);
|
||||
expect(await readFile(untouched, "utf8")).toBe('{"mcpServers":{}}');
|
||||
expect(await readFile(skillPath, "utf8")).toBe(skillContent);
|
||||
await expect(access(`${configPath}.rea.backup`)).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
});
|
||||
await expect(access(`${skillPath}.rea.backup`)).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
});
|
||||
await expect(
|
||||
access(join(home, ".agents", "skills", PRODUCT_IDENTITY.skillName)),
|
||||
access(join(home, ".claude", "skills", PRODUCT_IDENTITY.skillName)),
|
||||
).rejects.toMatchObject({ code: "ENOENT" });
|
||||
});
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user