



























@@ -2301,6 +2301,119 @@ describe.concurrent("scripts/crabbox-wrapper", () => {
23012301);
23022302});
230323032304+it("preserves sparse changed-gate Git bootstrap for direct env -i commands", () => {
2305+const result = runWrapper(
2306+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
2307+["run", "--provider", "aws", "--", "env", "-i", "pnpm", "check:changed"],
2308+{
2309+gitResponses: {
2310+[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
2311+[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
2312+[GIT_MERGE_BASE_MAIN_HEAD_KEY]: { stdout: "abc123\n" },
2313+},
2314+},
2315+);
2316+2317+const output = parseFakeCrabboxOutput(result);
2318+const remoteCommand = normalizeShellLineEndings(output.args.at(-1) ?? "");
2319+expect(result.status).toBe(0);
2320+expect(output.args).toContain("--shell");
2321+expect(remoteCommand).toContain("git init -q");
2322+expect(remoteCommand).toMatch(
2323+/&& env -i OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 pnpm check:changed$/u,
2324+);
2325+});
2326+2327+it("does not mark assignment-prefixed env -i changed gates outside the sanitized env", () => {
2328+const result = runWrapper(
2329+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
2330+["run", "--provider", "aws", "--", "FOO=1", "env", "-i", "pnpm", "check:changed"],
2331+{
2332+gitResponses: {
2333+[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
2334+[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
2335+[GIT_MERGE_BASE_MAIN_HEAD_KEY]: { stdout: "abc123\n" },
2336+},
2337+},
2338+);
2339+2340+const output = parseFakeCrabboxOutput(result);
2341+expect(result.status).toBe(0);
2342+expect(output.args.join("\0")).not.toContain("OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1");
2343+expect(output.args.join("\0")).not.toContain("git init -q");
2344+});
2345+2346+it("does not mark timeout-prefixed env -i changed gates outside the sanitized env", () => {
2347+const result = runWrapper(
2348+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
2349+[
2350+"run",
2351+"--provider",
2352+"aws",
2353+"--",
2354+"timeout",
2355+"1200s",
2356+"env",
2357+"-i",
2358+"CI=1",
2359+"pnpm",
2360+"check:changed",
2361+],
2362+{
2363+gitResponses: {
2364+[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
2365+[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
2366+[GIT_MERGE_BASE_MAIN_HEAD_KEY]: { stdout: "abc123\n" },
2367+},
2368+},
2369+);
2370+2371+const output = parseFakeCrabboxOutput(result);
2372+expect(result.status).toBe(0);
2373+expect(output.args.join("\0")).not.toContain("OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1");
2374+expect(output.args.join("\0")).not.toContain("git init -q");
2375+});
2376+2377+it("does not mark nested env -i changed gates outside the sanitized env", () => {
2378+const result = runWrapper(
2379+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
2380+["run", "--provider", "aws", "--", "env", "env", "-i", "pnpm", "check:changed"],
2381+{
2382+gitResponses: {
2383+[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
2384+[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
2385+[GIT_MERGE_BASE_MAIN_HEAD_KEY]: { stdout: "abc123\n" },
2386+},
2387+},
2388+);
2389+2390+const output = parseFakeCrabboxOutput(result);
2391+expect(result.status).toBe(0);
2392+expect(output.args.join("\0")).not.toContain("OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1");
2393+expect(output.args.join("\0")).not.toContain("git init -q");
2394+});
2395+2396+it("does not mark shell env -i changed gates outside the sanitized env", () => {
2397+const shellScript = "bash -lc 'env -i CI=1 pnpm check:changed'";
2398+const result = runWrapper(
2399+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
2400+["run", "--provider", "aws", "--shell", "--", shellScript],
2401+{
2402+gitResponses: {
2403+[GIT_CONFIG_SPARSE_KEY]: { stdout: "true\n" },
2404+[GIT_STATUS_PORCELAIN_KEY]: { stdout: "" },
2405+[GIT_MERGE_BASE_MAIN_HEAD_KEY]: { stdout: "abc123\n" },
2406+},
2407+},
2408+);
2409+2410+const output = parseFakeCrabboxOutput(result);
2411+const remoteCommand = normalizeShellLineEndings(output.args.at(-1) ?? "");
2412+expect(result.status).toBe(0);
2413+expect(remoteCommand).not.toContain("OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1");
2414+expect(remoteCommand).not.toContain("git init -q");
2415+});
2416+23042417it("does not treat quoted sparse shell text as a changed gate", () => {
23052418const result = runWrapper(
23062419"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。