@aexhq/cli 0.25.2 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.d.ts +2 -7
- package/dist/index.js +233 -7
- package/package.json +26 -29
- package/LICENSE +0 -201
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -51
- package/dist/cli.js.map +0 -1
- package/dist/cli.mjs +0 -4685
- package/dist/cli.mjs.sha256 +0 -1
- package/dist/host/cancel.d.ts +0 -3
- package/dist/host/cancel.js +0 -30
- package/dist/host/cancel.js.map +0 -1
- package/dist/host/common.d.ts +0 -135
- package/dist/host/common.js +0 -281
- package/dist/host/common.js.map +0 -1
- package/dist/host/delete-asset.d.ts +0 -3
- package/dist/host/delete-asset.js +0 -34
- package/dist/host/delete-asset.js.map +0 -1
- package/dist/host/delete.d.ts +0 -3
- package/dist/host/delete.js +0 -30
- package/dist/host/delete.js.map +0 -1
- package/dist/host/download.d.ts +0 -3
- package/dist/host/download.js +0 -80
- package/dist/host/download.js.map +0 -1
- package/dist/host/events.d.ts +0 -3
- package/dist/host/events.js +0 -97
- package/dist/host/events.js.map +0 -1
- package/dist/host/index.d.ts +0 -17
- package/dist/host/index.js +0 -18
- package/dist/host/index.js.map +0 -1
- package/dist/host/outputs.d.ts +0 -3
- package/dist/host/outputs.js +0 -36
- package/dist/host/outputs.js.map +0 -1
- package/dist/host/run-cmd.d.ts +0 -3
- package/dist/host/run-cmd.js +0 -565
- package/dist/host/run-cmd.js.map +0 -1
- package/dist/host/skills-cmd.d.ts +0 -3
- package/dist/host/skills-cmd.js +0 -304
- package/dist/host/skills-cmd.js.map +0 -1
- package/dist/host/status.d.ts +0 -3
- package/dist/host/status.js +0 -31
- package/dist/host/status.js.map +0 -1
- package/dist/host/wait.d.ts +0 -3
- package/dist/host/wait.js +0 -88
- package/dist/host/wait.js.map +0 -1
- package/dist/host/whoami.d.ts +0 -3
- package/dist/host/whoami.js +0 -33
- package/dist/host/whoami.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal.d.ts +0 -53
- package/dist/internal.js +0 -10
- package/dist/internal.js.map +0 -1
- package/dist/outputs-sync.d.ts +0 -24
- package/dist/outputs-sync.js +0 -70
- package/dist/outputs-sync.js.map +0 -1
- package/dist/proxy.d.ts +0 -16
- package/dist/proxy.js +0 -316
- package/dist/proxy.js.map +0 -1
- package/dist/run.d.ts +0 -10
- package/dist/run.js +0 -167
- package/dist/run.js.map +0 -1
- package/dist/runtime.d.ts +0 -5
- package/dist/runtime.js +0 -4
- package/dist/runtime.js.map +0 -1
- package/scripts/finalize-bundle.mjs +0 -72
- package/src/cli.ts +0 -51
- package/src/host/cancel.ts +0 -39
- package/src/host/common.ts +0 -329
- package/src/host/delete-asset.ts +0 -43
- package/src/host/delete.ts +0 -39
- package/src/host/download.ts +0 -97
- package/src/host/events.ts +0 -113
- package/src/host/index.ts +0 -25
- package/src/host/outputs.ts +0 -45
- package/src/host/run-cmd.ts +0 -594
- package/src/host/skills-cmd.ts +0 -317
- package/src/host/status.ts +0 -40
- package/src/host/wait.ts +0 -110
- package/src/host/whoami.ts +0 -42
- package/src/index.ts +0 -7
- package/src/internal.ts +0 -63
- package/src/outputs-sync.ts +0 -76
- package/src/proxy.ts +0 -359
- package/src/run.ts +0 -188
- package/src/runtime.ts +0 -15
- package/test/cli.test.ts +0 -519
- package/test/host.test.ts +0 -1154
- package/test/no-env-vars.test.ts +0 -59
- package/test/outputs-sync.test.ts +0 -107
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -4
- package/vitest.config.ts +0 -14
package/test/no-env-vars.test.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { dirname, resolve } from "node:path";
|
|
5
|
-
|
|
6
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const cliRoot = resolve(here, "..");
|
|
8
|
-
const bundlePath = resolve(cliRoot, "dist", "cli.mjs");
|
|
9
|
-
const digestPath = resolve(cliRoot, "dist", "cli.mjs.sha256");
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Mechanical lockdown of the shipped CLI bundle.
|
|
13
|
-
*
|
|
14
|
-
* The CLI MUST NOT read any `process.env.AEX_*` value at runtime.
|
|
15
|
-
* Earlier drafts proposed test-only overrides like
|
|
16
|
-
* `AEX_RUN_TOKEN_FILE` and `AEX_PROXY_BASE_FILE` — those are a
|
|
17
|
-
* prompt-injection attack surface (a compromised agent could set them
|
|
18
|
-
* to redirect the bearer mint). Tests use module-DI through
|
|
19
|
-
* `internal.ts`; the shipped bundle has no env-driven code paths.
|
|
20
|
-
*/
|
|
21
|
-
describe("CLI bundle: no env-var-driven code paths", () => {
|
|
22
|
-
it("ships a self-contained ESM bundle at dist/cli.mjs", () => {
|
|
23
|
-
expect(existsSync(bundlePath)).toBe(true);
|
|
24
|
-
expect(existsSync(digestPath)).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("contains zero process.env.AEX_* references", () => {
|
|
28
|
-
const text = readFileSync(bundlePath, "utf8");
|
|
29
|
-
const matches = text.match(/process\.env\.AEX_[A-Z0-9_]+/g) ?? [];
|
|
30
|
-
expect(matches).toEqual([]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("never reads the historic test-only override env vars", () => {
|
|
34
|
-
// These are explicitly named in the plan as forbidden surfaces.
|
|
35
|
-
const forbidden = [
|
|
36
|
-
"AEX_RUN_TOKEN_FILE",
|
|
37
|
-
"AEX_PROXY_BASE_FILE",
|
|
38
|
-
"AEX_PROXY_INDEX_FILE",
|
|
39
|
-
"AEX_CLI_BUNDLE_PATH"
|
|
40
|
-
];
|
|
41
|
-
const text = readFileSync(bundlePath, "utf8");
|
|
42
|
-
for (const name of forbidden) {
|
|
43
|
-
expect(text.includes(name)).toBe(false);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("references the fixed in-container paths exactly", () => {
|
|
48
|
-
// The CLI's discoverability surface is the manifest + run-token
|
|
49
|
-
// mounted under Anthropic's `/mnt/session/uploads/<mount_path>`
|
|
50
|
-
// rebase. Asserting their presence in the bundle catches any
|
|
51
|
-
// refactor that accidentally relativizes them or reverts to the
|
|
52
|
-
// pre-mount-fix `/aex/...` paths (which the Anthropic
|
|
53
|
-
// managed runner environment forwarding ignores these — see proxy-bootstrap.ts
|
|
54
|
-
// for the gory details).
|
|
55
|
-
const text = readFileSync(bundlePath, "utf8");
|
|
56
|
-
expect(text.includes("/mnt/session/uploads/aex/index.json")).toBe(true);
|
|
57
|
-
expect(text.includes("/mnt/session/uploads/aex/run-token")).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { runOutputsSyncCmd } from "../src/outputs-sync.js";
|
|
3
|
-
import type { CliIO, OutputsSyncFileEntry } from "../src/internal.js";
|
|
4
|
-
|
|
5
|
-
/** Build a minimal `CliIO` for `outputs sync` test cases. */
|
|
6
|
-
function makeIo(opts: {
|
|
7
|
-
walk?: (root: string) => Promise<readonly OutputsSyncFileEntry[] | null>;
|
|
8
|
-
inContainer?: boolean;
|
|
9
|
-
}): {
|
|
10
|
-
io: CliIO;
|
|
11
|
-
stdout: string;
|
|
12
|
-
stderr: string;
|
|
13
|
-
} {
|
|
14
|
-
const state = { stdout: "", stderr: "" };
|
|
15
|
-
const io: CliIO = {
|
|
16
|
-
argv: ["node", "/aex/aex", "outputs", "sync"],
|
|
17
|
-
readFile: async (path) => {
|
|
18
|
-
if (path === "/mnt/session/uploads/aex/index.json" && opts.inContainer) return "{}";
|
|
19
|
-
const err = Object.assign(new Error(`ENOENT: ${path}`), { code: "ENOENT" });
|
|
20
|
-
throw err;
|
|
21
|
-
},
|
|
22
|
-
writeFile: async () => {
|
|
23
|
-
throw new Error("not used");
|
|
24
|
-
},
|
|
25
|
-
fetchImpl: (async () => new Response("{}")) as typeof fetch,
|
|
26
|
-
cwd: () => "/tmp",
|
|
27
|
-
stdout: (chunk) => {
|
|
28
|
-
state.stdout += chunk;
|
|
29
|
-
},
|
|
30
|
-
stderr: (chunk) => {
|
|
31
|
-
state.stderr += chunk;
|
|
32
|
-
},
|
|
33
|
-
exit: () => {},
|
|
34
|
-
...(opts.walk ? { walkDirectory: opts.walk } : {})
|
|
35
|
-
};
|
|
36
|
-
return {
|
|
37
|
-
io,
|
|
38
|
-
get stdout() {
|
|
39
|
-
return state.stdout;
|
|
40
|
-
},
|
|
41
|
-
get stderr() {
|
|
42
|
-
return state.stderr;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
describe("aex outputs sync (internal)", () => {
|
|
48
|
-
it("refuses to run on the host (no /aex/index.json)", async () => {
|
|
49
|
-
const cap = makeIo({ inContainer: false, walk: async () => [] });
|
|
50
|
-
const exit = await runOutputsSyncCmd(cap.io, ["/workspace/outputs"]);
|
|
51
|
-
expect(exit.code).not.toBe(0);
|
|
52
|
-
expect(cap.stderr).toMatch(/in-container/i);
|
|
53
|
-
expect(cap.stdout).toBe("");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("rejects empty dir list", async () => {
|
|
57
|
-
const cap = makeIo({ inContainer: true });
|
|
58
|
-
const exit = await runOutputsSyncCmd(cap.io, []);
|
|
59
|
-
expect(exit.code).not.toBe(0);
|
|
60
|
-
expect(cap.stderr).toMatch(/usage/i);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("emits one JSON line per discovered file plus a summary line", async () => {
|
|
64
|
-
const cap = makeIo({
|
|
65
|
-
inContainer: true,
|
|
66
|
-
walk: async (root) => {
|
|
67
|
-
if (root === "/workspace/outputs") {
|
|
68
|
-
return [
|
|
69
|
-
{ path: "/workspace/outputs/a.txt", sizeBytes: 12 },
|
|
70
|
-
{ path: "/workspace/outputs/b.bin", sizeBytes: 99 }
|
|
71
|
-
];
|
|
72
|
-
}
|
|
73
|
-
return [];
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
const exit = await runOutputsSyncCmd(cap.io, ["/workspace/outputs", "/workspace/state"]);
|
|
77
|
-
expect(exit.code).toBe(0);
|
|
78
|
-
const lines = cap.stdout.trim().split("\n");
|
|
79
|
-
expect(lines).toHaveLength(3);
|
|
80
|
-
const parsed = lines.map((line) => JSON.parse(line) as Record<string, unknown>);
|
|
81
|
-
expect(parsed[0]).toMatchObject({ dir: "/workspace/outputs", path: "/workspace/outputs/a.txt", sizeBytes: 12 });
|
|
82
|
-
expect(parsed[1]).toMatchObject({ dir: "/workspace/outputs", path: "/workspace/outputs/b.bin", sizeBytes: 99 });
|
|
83
|
-
expect(parsed[2]).toMatchObject({ summary: { dirs: 2, files: 2, missing: 0 } });
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("reports missing dirs via stderr and continues", async () => {
|
|
87
|
-
const cap = makeIo({
|
|
88
|
-
inContainer: true,
|
|
89
|
-
walk: async (root) => (root === "/workspace/state" ? null : [])
|
|
90
|
-
});
|
|
91
|
-
const exit = await runOutputsSyncCmd(cap.io, ["/workspace/outputs", "/workspace/state"]);
|
|
92
|
-
expect(exit.code).toBe(0);
|
|
93
|
-
expect(cap.stderr).toContain(`"missing_or_unreadable"`);
|
|
94
|
-
expect(cap.stderr).toContain(`"/workspace/state"`);
|
|
95
|
-
const summary = cap.stdout.trim().split("\n").pop()!;
|
|
96
|
-
expect(JSON.parse(summary)).toMatchObject({ summary: { dirs: 2, files: 0, missing: 1 } });
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("rejects non-absolute output dirs as a defence against worker mis-instruction", async () => {
|
|
100
|
-
const cap = makeIo({ inContainer: true, walk: async () => [] });
|
|
101
|
-
const exit = await runOutputsSyncCmd(cap.io, ["workspace/outputs"]);
|
|
102
|
-
expect(exit.code).toBe(0);
|
|
103
|
-
expect(cap.stderr).toContain(`"non_absolute_path"`);
|
|
104
|
-
const summary = cap.stdout.trim().split("\n").pop()!;
|
|
105
|
-
expect(JSON.parse(summary)).toMatchObject({ summary: { dirs: 1, files: 0, missing: 1 } });
|
|
106
|
-
});
|
|
107
|
-
});
|
package/tsconfig.build.json
DELETED
package/tsconfig.json
DELETED
package/vitest.config.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vitest/config";
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
environment: "node",
|
|
6
|
-
globals: true,
|
|
7
|
-
restoreMocks: true,
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: "v8",
|
|
10
|
-
reporter: ["text", "json-summary"],
|
|
11
|
-
exclude: ["dist/**", "coverage/**", "scripts/**", "**/*.config.*"]
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
});
|