























@@ -204,6 +204,85 @@ describe("scripts/crabbox-wrapper", () => {
204204]);
205205});
206206207+it("bootstraps a Node toolchain for raw AWS macOS JavaScript commands", () => {
208+const result = runWrapper(
209+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
210+["run", "--provider", "aws", "--target", "macos", "--", "pnpm", "--version"],
211+);
212+213+const output = parseFakeCrabboxOutput(result);
214+const remoteCommand = output.args.at(-1) ?? "";
215+expect(result.status).toBe(0);
216+expect(output.args).toContain("--shell");
217+expect(result.stderr).toContain(
218+"bootstrapping a pinned user-local Node toolchain before the command",
219+);
220+expect(remoteCommand).toContain("openclaw_crabbox_bootstrap_macos_js");
221+expect(remoteCommand).toContain("node-v${node_version}-darwin-${node_arch}.tar.gz");
222+expect(remoteCommand).toContain("shasum -a 256 -c -");
223+expect(remoteCommand).not.toContain("set -euo pipefail");
224+expect(remoteCommand).toContain('return "$status"');
225+expect(remoteCommand).toContain("node --version >&2");
226+expect(remoteCommand).toContain("pnpm --version >&2");
227+expect(remoteCommand).toContain("&& { pnpm --version\n}");
228+});
229+230+it("preserves shell commands when bootstrapping raw AWS macOS JavaScript commands", () => {
231+const result = runWrapper(
232+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
233+["run", "--provider", "aws", "--target", "macos", "--shell", "--", "pnpm check:changed"],
234+);
235+236+const output = parseFakeCrabboxOutput(result);
237+const remoteCommand = output.args.at(-1) ?? "";
238+expect(result.status).toBe(0);
239+expect(output.args.filter((arg) => arg === "--shell")).toHaveLength(1);
240+expect(remoteCommand).toContain("openclaw_crabbox_bootstrap_macos_js");
241+expect(remoteCommand).toContain("&& { pnpm check:changed\n}");
242+});
243+244+it("groups shell commands so fallbacks cannot mask AWS macOS bootstrap failures", () => {
245+const result = runWrapper(
246+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
247+[
248+"run",
249+"--provider",
250+"aws",
251+"--target",
252+"macos",
253+"--shell",
254+"--",
255+"pnpm check:changed || true",
256+],
257+);
258+259+const output = parseFakeCrabboxOutput(result);
260+const remoteCommand = output.args.at(-1) ?? "";
261+expect(result.status).toBe(0);
262+expect(remoteCommand).toContain("openclaw_crabbox_bootstrap_macos_js && {");
263+expect(remoteCommand).toContain("pnpm check:changed || true\n}");
264+});
265+266+it("does not bootstrap non-macOS AWS JavaScript commands", () => {
267+const result = runWrapper(
268+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
269+["run", "--provider", "aws", "--target", "linux", "--", "pnpm", "--version"],
270+);
271+272+const output = parseFakeCrabboxOutput(result);
273+expect(result.status).toBe(0);
274+expect(output.args).toEqual([
275+"run",
276+"--provider",
277+"aws",
278+"--target",
279+"linux",
280+"--",
281+"pnpm",
282+"--version",
283+]);
284+});
285+207286it("finds a Crabbox checkout next to the Git common dir in linked worktrees", () => {
208287const fakeWorkspaceParent = mkdtempSync(path.join(tmpdir(), "openclaw-linked-worktree-"));
209288tempDirs.push(fakeWorkspaceParent);
@@ -442,6 +521,32 @@ describe("scripts/crabbox-wrapper", () => {
442521expect(remoteCommand).toMatch(/&& corepack pnpm check:changed$/u);
443522});
444523524+it("preserves macOS JS bootstrapping for sparse changed gates on remote raw syncs", () => {
525+const result = runWrapper(
526+"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
527+["run", "--provider", "aws", "--target", "macos", "--", "pnpm", "check:changed"],
528+{
529+gitResponses: {
530+["config\u0000--bool\u0000core.sparseCheckout"]: { stdout: "true\n" },
531+["status\u0000--porcelain=v1"]: { stdout: "" },
532+["merge-base\u0000origin/main\u0000HEAD"]: { stdout: "abc123\n" },
533+},
534+},
535+);
536+537+const output = parseFakeCrabboxOutput(result);
538+const remoteCommand = output.args.at(-1) ?? "";
539+expect(result.status).toBe(0);
540+expect(output.args.filter((arg) => arg === "--shell")).toHaveLength(1);
541+expect(remoteCommand).toContain(
542+"git fetch -q --depth=1 origin abc123:refs/remotes/origin/main",
543+);
544+expect(remoteCommand).toContain("openclaw_crabbox_bootstrap_macos_js");
545+expect(remoteCommand).toContain(
546+"openclaw_crabbox_bootstrap_macos_js && { pnpm check:changed\n}",
547+);
548+});
549+445550it("preserves existing shell changed-gate commands after remote Git bootstrap", () => {
446551const result = runWrapper(
447552"provider: hetzner, aws, local-container, blacksmith-testbox, or cloudflare\n",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。