mirror of
https://github.com/morluto/rea
synced 2026-10-27 06:33:32 -04:00
5d6029ea62
Use the matched Contents/Library/LaunchAgents or LaunchDaemons suffix to select a plist's domain. Remove the independent scan of every ancestor. Keep regular-file, application-root, sidecar and suffix admission rules. Adapt @bnkaiteam's proposal and ZIP boundary regression from PR #3504, adding public CLI/stdio MCP controls for nested bundles, case variants, misleading ancestors and excluded paths. Validation: 53 focused checks, build, check:fast and docs:check pass. Two new controls fail before the fix. 12 completed actual built CLI cost controls preserve the ordinary reply and projection ID byte for byte. No heavy profiling, target or real deep-provider execution; npm release and whole-agent costs remain unverified. Fixes #3353
94 lines
3.4 KiB
TypeScript
94 lines
3.4 KiB
TypeScript
import { writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
|
|
import { TextReader, Uint8ArrayWriter, ZipWriter } from "@zip.js/zip.js";
|
|
import { expect } from "vitest";
|
|
|
|
import { appleApplicationProjectionResultSchema } from "../../../src/domain/apple/appleApplication.js";
|
|
import { compareUnicodeCodePoints } from "../../../src/domain/unicodeCodePointOrder.js";
|
|
import { parseEvidence } from "../../../src/domain/evidence.js";
|
|
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
cliTest(
|
|
"Apple launchd domains follow their owning directory through CLI and MCP",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory("rea-apple-launchd-cli-");
|
|
const environment = { HOME: root, USERPROFILE: root };
|
|
const expected = [
|
|
[
|
|
"LaunchDaemons/Sample.app/Contents/Library/LaunchAgents/agent.plist",
|
|
"agent",
|
|
],
|
|
[
|
|
"LaunchDaemons/Sample.app/Contents/Resources/LaunchDaemons/Nested.app/Contents/Library/LaunchAgents/nested.plist",
|
|
"agent",
|
|
],
|
|
[
|
|
"LaunchAgents/Other.app/Contents/Library/LaunchDaemons/daemon.plist",
|
|
"daemon",
|
|
],
|
|
[
|
|
"launchdaemons/Case.app/contents/library/launchagents/mixed.plist",
|
|
"agent",
|
|
],
|
|
] as const;
|
|
const writer = new ZipWriter(new Uint8ArrayWriter());
|
|
for (const [path] of expected)
|
|
await writer.add(path, new TextReader("<plist/>"));
|
|
for (const path of [
|
|
"LaunchDaemons/Sample.app/Contents/Library/LaunchAgents/nested/ignored.plist",
|
|
"LaunchDaemons/Sample.app/Contents/Library/LaunchAgents/not-a-plist",
|
|
"Contents/Library/LaunchAgents/unrooted.plist",
|
|
"__MACOSX/Sample.app/Contents/Library/LaunchAgents/sidecar.plist",
|
|
])
|
|
await writer.add(path, new TextReader("<plist/>"));
|
|
await writer.add(
|
|
"LaunchDaemons/Sample.app/Contents/Library/LaunchAgents/directory.plist/",
|
|
undefined,
|
|
{ directory: true },
|
|
);
|
|
const path = join(root, "Launchd.zip");
|
|
await writeFile(path, await writer.close());
|
|
const inspected = await cli.run({
|
|
arguments: ["inspect-artifact", path, "--json"],
|
|
environment,
|
|
});
|
|
expect(inspected.exitCode, inspected.stderr).toBe(0);
|
|
const source = parseEvidence(inspected.json);
|
|
const input = { inventory_evidence: [source] };
|
|
const projected = await cli.run({
|
|
arguments: [
|
|
"project-apple-application-graph",
|
|
JSON.stringify(input),
|
|
"--json",
|
|
],
|
|
environment,
|
|
});
|
|
expect(projected.exitCode, projected.stderr).toBe(0);
|
|
const evidence = parseEvidence(projected.json);
|
|
const result = appleApplicationProjectionResultSchema.parse(
|
|
evidence.normalized_result,
|
|
);
|
|
expect(
|
|
result.components.launchd_plists.map(({ path, domain }) => [
|
|
path,
|
|
domain,
|
|
]),
|
|
).toEqual(
|
|
[...expected].sort(([left], [right]) =>
|
|
compareUnicodeCodePoints(left, right),
|
|
),
|
|
);
|
|
expect(result.coverage).toEqual({
|
|
status: "complete-within-inventory",
|
|
inventory_complete: true,
|
|
});
|
|
const { call } = await connectLocalToolsMcp(environment);
|
|
const mcp = await call("project_apple_application_graph", input);
|
|
expect(mcp.isError).not.toBe(true);
|
|
expect(parseEvidence(mcp.structuredContent)).toEqual(evidence);
|
|
},
|
|
);
|