@rubytech/create-maxy-code 0.1.458 → 0.1.459
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/package.json +1 -1
- package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +188 -3
- package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts +2 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts.map +1 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js +59 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js.map +1 -0
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +12 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.js +97 -0
- package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/house-credential.js +4 -2
- package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
- package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/index.js +1 -0
- package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/object-limits.d.ts +53 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.d.ts.map +1 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.js +72 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.js.map +1 -0
- package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +211 -5
- package/payload/platform/lib/storage-broker/src/__tests__/object-limits.test.ts +76 -0
- package/payload/platform/lib/storage-broker/src/cf-exec.ts +148 -6
- package/payload/platform/lib/storage-broker/src/house-credential.ts +4 -2
- package/payload/platform/lib/storage-broker/src/index.ts +1 -0
- package/payload/platform/lib/storage-broker/src/object-limits.ts +75 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -5
- package/payload/platform/plugins/cloudflare/bin/cf-token.sh +4 -3
- package/payload/platform/plugins/cloudflare/references/api.md +1 -1
- package/payload/platform/plugins/docs/references/outlook-guide.md +4 -4
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/outlook/PLUGIN.md +2 -2
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js +138 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js +121 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js +102 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js +209 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/index.js +10 -7
- package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts +37 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js +79 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +8 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +4 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +31 -8
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +40 -13
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +9 -5
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +12 -8
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +29 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +46 -13
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +8 -2
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +13 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -20
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +27 -3
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +53 -8
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
- package/payload/platform/plugins/outlook/references/graph-surfaces.md +29 -6
- package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +22 -5
- package/payload/platform/plugins/storage-broker/PLUGIN.md +41 -2
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts +2 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js +85 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts +2 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js +77 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts +12 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js +107 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js +86 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts +11 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js +35 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js.map +1 -0
- package/payload/platform/scripts/logs-read-jsonl.test.sh +118 -0
- package/payload/platform/scripts/logs-read.sh +63 -9
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +4 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/server/{chunk-F4D35LKL.js → chunk-POBXIHOF.js} +34 -0
- package/payload/server/{chunk-64FGYKNZ.js → chunk-Q6W4U6HL.js} +104 -0
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +206 -6
- package/payload/server/{src-S7C4P6TT.js → src-3I2RYZFB.js} +9 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, realpathSync, rmSync, writeFileSync, truncateSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { R2_OBJECT_MAX_BYTES } from "../../../../../lib/storage-broker/dist/object-limits.js";
|
|
6
|
+
// Task 1695 — the property under test is an ordering: the cap must fire BEFORE
|
|
7
|
+
// the file is read. Spying on readFileSync is what makes that observable. An
|
|
8
|
+
// assertion that only checked the error message would pass just as happily on an
|
|
9
|
+
// implementation that slurps a 3 GB file into memory and then measures its
|
|
10
|
+
// length, which is the bug this exists to prevent.
|
|
11
|
+
//
|
|
12
|
+
// node:fs is mocked partially so confine-path's realpathSync/statSync stay real
|
|
13
|
+
// and the confinement predicate is still exercised for what it is.
|
|
14
|
+
const readFileSpy = vi.fn();
|
|
15
|
+
vi.mock("node:fs", async (importOriginal) => {
|
|
16
|
+
const actual = await importOriginal();
|
|
17
|
+
return {
|
|
18
|
+
...actual,
|
|
19
|
+
readFileSync: (...args) => readFileSpy(...args),
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
const { readPutSource } = await import("../put-source.js");
|
|
23
|
+
let dir;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
// realpath'd at creation: on macOS mkdtemp hands back /var/folders/… which
|
|
26
|
+
// canonicalises to /private/var/folders/…, and confineToAccountDir realpaths
|
|
27
|
+
// both sides. Without this the paths under test differ from the paths asserted
|
|
28
|
+
// for a reason that has nothing to do with the cap.
|
|
29
|
+
dir = realpathSync(mkdtempSync(join(tmpdir(), "put-source-")));
|
|
30
|
+
process.env.ACCOUNT_DIR = dir;
|
|
31
|
+
readFileSpy.mockReset();
|
|
32
|
+
readFileSpy.mockReturnValue(Buffer.from([1, 2, 3]));
|
|
33
|
+
});
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
rmSync(dir, { recursive: true, force: true });
|
|
36
|
+
delete process.env.ACCOUNT_DIR;
|
|
37
|
+
});
|
|
38
|
+
/** A sparse file of `size` bytes: statSync reports the size, no disk is used and
|
|
39
|
+
* nothing is ever written. A real 100 MiB fixture would make this suite the
|
|
40
|
+
* thing that thrashes the machine. */
|
|
41
|
+
function sparseFile(name, size) {
|
|
42
|
+
const p = join(dir, name);
|
|
43
|
+
writeFileSync(p, "");
|
|
44
|
+
truncateSync(p, size);
|
|
45
|
+
return p;
|
|
46
|
+
}
|
|
47
|
+
describe("readPutSource", () => {
|
|
48
|
+
it("rejects an over-cap file before reading it", () => {
|
|
49
|
+
const p = sparseFile("huge.bin", R2_OBJECT_MAX_BYTES + 1);
|
|
50
|
+
expect(() => readPutSource(p)).toThrow(/huge\.bin/);
|
|
51
|
+
// The assertion that matters. Without it this test would pass on an
|
|
52
|
+
// implementation that reads the whole file and then checks its length.
|
|
53
|
+
expect(readFileSpy).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
55
|
+
it("names the file and the limit when it rejects", () => {
|
|
56
|
+
const p = sparseFile("huge.bin", 150 * 1024 * 1024);
|
|
57
|
+
expect(() => readPutSource(p)).toThrow(/huge\.bin is 150\.0 MiB.*100\.0 MiB/);
|
|
58
|
+
});
|
|
59
|
+
it("reads a file at exactly the cap — the cap is a bound, not a wall", () => {
|
|
60
|
+
const p = sparseFile("atcap.bin", R2_OBJECT_MAX_BYTES);
|
|
61
|
+
const out = readPutSource(p);
|
|
62
|
+
expect(readFileSpy).toHaveBeenCalledWith(p);
|
|
63
|
+
expect(out.path).toBe(p);
|
|
64
|
+
});
|
|
65
|
+
it("reads an ordinary file", () => {
|
|
66
|
+
const p = join(dir, "small.bin");
|
|
67
|
+
writeFileSync(p, Buffer.from([1, 2, 3]));
|
|
68
|
+
const out = readPutSource(p);
|
|
69
|
+
expect(out.bytes).toEqual(Buffer.from([1, 2, 3]));
|
|
70
|
+
expect(readFileSpy).toHaveBeenCalledWith(p);
|
|
71
|
+
});
|
|
72
|
+
it("still rejects a path outside the account directory, before any size check", () => {
|
|
73
|
+
expect(() => readPutSource("/etc/hosts")).toThrow(/outside the account directory/);
|
|
74
|
+
expect(readFileSpy).not.toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=put-source.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put-source.test.js","sourceRoot":"","sources":["../../src/__tests__/put-source.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve `p` and require it inside the caller's account directory.
|
|
3
|
+
*
|
|
4
|
+
* `mustExist` true (a source to read): the path itself is realpathed and must
|
|
5
|
+
* be a regular file. False (a destination to write): the path does not exist
|
|
6
|
+
* yet and cannot be realpathed, so its *parent* is — which is exactly what a
|
|
7
|
+
* symlinked parent directory would otherwise subvert.
|
|
8
|
+
*
|
|
9
|
+
* Returns the resolved absolute path. Throws naming the offending path.
|
|
10
|
+
*/
|
|
11
|
+
export declare function confineToAccountDir(p: string, mustExist: boolean): string;
|
|
12
|
+
//# sourceMappingURL=confine-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confine-path.d.ts","sourceRoot":"","sources":["../src/confine-path.ts"],"names":[],"mappings":"AAyCA;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CA4DzE"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confine an agent-supplied file path to the caller's own account directory.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the predicate proven in the email plugin's resolveOutboundAttachments
|
|
5
|
+
* (platform/plugins/email/mcp/src/lib/attachment-resolve.ts): realpath the
|
|
6
|
+
* candidate and require the result under the realpathed account directory, so a
|
|
7
|
+
* symlink cannot escape a plain string prefix check. Copied rather than
|
|
8
|
+
* imported because platform/lib/* is the only cross-plugin-importable surface
|
|
9
|
+
* and this predicate does not live there; consolidating the duplicates is its
|
|
10
|
+
* own concern, not this tool's.
|
|
11
|
+
*
|
|
12
|
+
* This is a correctness guardrail, not a security boundary, and the difference
|
|
13
|
+
* matters. Every account shares one unix user and the agent holds Bash, so it
|
|
14
|
+
* can already read anything this process can (Task 1690). What actually
|
|
15
|
+
* contains the blast radius is that the house-level broker route touches no
|
|
16
|
+
* filesystem at all: file I/O stays here, in a process running at the agent's
|
|
17
|
+
* own privilege, so it grants nothing the agent did not already have. Moving
|
|
18
|
+
* this check server-side would not harden it — it would create the very
|
|
19
|
+
* house-privileged arbitrary read/write it appears to prevent.
|
|
20
|
+
*/
|
|
21
|
+
import { realpathSync, statSync } from "node:fs";
|
|
22
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
23
|
+
/** The caller's account directory. ACCOUNT_DIR is the canonical spawn-set var;
|
|
24
|
+
* fall back to PLATFORM_ROOT + ACCOUNT_ID exactly as the email and url-get
|
|
25
|
+
* tools do. Throws rather than returning a default: with no account context
|
|
26
|
+
* there is nothing to validate against, and failing closed is the only safe
|
|
27
|
+
* answer. */
|
|
28
|
+
function accountDir() {
|
|
29
|
+
const direct = process.env.ACCOUNT_DIR;
|
|
30
|
+
if (direct && direct.trim())
|
|
31
|
+
return direct;
|
|
32
|
+
const platformRoot = process.env.PLATFORM_ROOT;
|
|
33
|
+
const accountId = process.env.ACCOUNT_ID;
|
|
34
|
+
if (platformRoot && accountId && !accountId.includes("/") && !accountId.includes("..")) {
|
|
35
|
+
return join(platformRoot, "..", "data", "accounts", accountId);
|
|
36
|
+
}
|
|
37
|
+
throw new Error("No account context (ACCOUNT_DIR unset and PLATFORM_ROOT+ACCOUNT_ID unavailable) to validate paths against.");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve `p` and require it inside the caller's account directory.
|
|
41
|
+
*
|
|
42
|
+
* `mustExist` true (a source to read): the path itself is realpathed and must
|
|
43
|
+
* be a regular file. False (a destination to write): the path does not exist
|
|
44
|
+
* yet and cannot be realpathed, so its *parent* is — which is exactly what a
|
|
45
|
+
* symlinked parent directory would otherwise subvert.
|
|
46
|
+
*
|
|
47
|
+
* Returns the resolved absolute path. Throws naming the offending path.
|
|
48
|
+
*/
|
|
49
|
+
export function confineToAccountDir(p, mustExist) {
|
|
50
|
+
let base;
|
|
51
|
+
try {
|
|
52
|
+
base = realpathSync(accountDir());
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new Error(`Account directory is not accessible: ${err instanceof Error ? err.message : String(err)}`);
|
|
56
|
+
}
|
|
57
|
+
let resolved;
|
|
58
|
+
if (mustExist) {
|
|
59
|
+
try {
|
|
60
|
+
resolved = realpathSync(p);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err.code === "ENOENT") {
|
|
64
|
+
throw new Error(`File not found: ${p}`);
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Cannot read ${p}: ${err instanceof Error ? err.message : String(err)}`);
|
|
67
|
+
}
|
|
68
|
+
if (!statSync(resolved).isFile()) {
|
|
69
|
+
throw new Error(`${p} is not a regular file.`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const absolute = resolve(p);
|
|
74
|
+
// A destination that already exists must be realpathed like any source: if
|
|
75
|
+
// the final component is a symlink pointing out of the account directory, a
|
|
76
|
+
// write to it follows the link out, and resolving only the parent would let
|
|
77
|
+
// that through. The source branch rejects exactly this escape, so the two
|
|
78
|
+
// branches would otherwise disagree about what "confined" means.
|
|
79
|
+
try {
|
|
80
|
+
resolved = realpathSync(absolute);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
if (err.code !== "ENOENT") {
|
|
84
|
+
throw new Error(`Cannot resolve destination ${p}: ${err instanceof Error ? err.message : String(err)}`);
|
|
85
|
+
}
|
|
86
|
+
// It does not exist yet, so it cannot be realpathed. Resolve its parent —
|
|
87
|
+
// which is what a symlinked parent directory would otherwise subvert —
|
|
88
|
+
// and re-attach the final name.
|
|
89
|
+
let parent;
|
|
90
|
+
try {
|
|
91
|
+
parent = realpathSync(dirname(absolute));
|
|
92
|
+
}
|
|
93
|
+
catch (perr) {
|
|
94
|
+
if (perr.code === "ENOENT") {
|
|
95
|
+
throw new Error(`Destination directory does not exist: ${dirname(absolute)}`);
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Cannot resolve destination ${p}: ${perr instanceof Error ? perr.message : String(perr)}`);
|
|
98
|
+
}
|
|
99
|
+
resolved = join(parent, basename(absolute));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (resolved !== base && !resolved.startsWith(base + "/")) {
|
|
103
|
+
throw new Error(`${p} is outside the account directory and cannot be used.`);
|
|
104
|
+
}
|
|
105
|
+
return resolved;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=confine-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confine-path.js","sourceRoot":"","sources":["../src/confine-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { initStderrTee } from "../../../../lib/mcp-stderr-tee/dist/index.js";
|
|
8
8
|
initStderrTee("storage-broker");
|
|
9
|
+
import { writeFileSync } from "node:fs";
|
|
9
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
11
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
12
|
import { z } from "zod";
|
|
12
13
|
import { callApi as rawCallApi } from "./call-api.js";
|
|
14
|
+
import { confineToAccountDir } from "./confine-path.js";
|
|
15
|
+
import { readPutSource } from "./put-source.js";
|
|
16
|
+
import { R2_OBJECT_MAX_BYTES } from "../../../../lib/storage-broker/dist/object-limits.js";
|
|
13
17
|
import { callerScopeHeaders } from "./caller-scope-headers.js";
|
|
14
18
|
import { requirePortEnv } from "../../../../lib/require-port-env/dist/index.js";
|
|
15
19
|
import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
|
|
@@ -87,6 +91,88 @@ lifelineTool(server, "storage-r2-bucket-create", "Create a Cloudflare R2 bucket
|
|
|
87
91
|
return textResult(`R2 create failed: ${err}`, true);
|
|
88
92
|
return textResult(`Created R2 bucket ${name}.`);
|
|
89
93
|
});
|
|
94
|
+
// ─── R2 objects (Task 1691) ───────────────────────────────────────────────
|
|
95
|
+
//
|
|
96
|
+
// get/put move bytes through a file rather than the tool result: these objects
|
|
97
|
+
// are photos and scans, and base64 in a tool result would push megabytes into
|
|
98
|
+
// the agent's context window. The file I/O lives here, in this account-scoped
|
|
99
|
+
// process, and never in the house-level route that holds the credential — see
|
|
100
|
+
// confine-path.ts for why that split is the part that matters.
|
|
101
|
+
// ─── storage-r2-object-list ───────────────────────────────────────────────
|
|
102
|
+
lifelineTool(server, "storage-r2-object-list", "List the objects in an R2 bucket your account owns.", {
|
|
103
|
+
bucket: z.string().describe("Bucket name"),
|
|
104
|
+
prefix: z.string().optional().describe("Only list keys starting with this prefix"),
|
|
105
|
+
}, async ({ bucket, prefix }) => {
|
|
106
|
+
const result = await callApi("storage-r2-object-list", "/api/storage/r2/object/list", "POST", { bucket, prefix });
|
|
107
|
+
const err = errorOf(result);
|
|
108
|
+
if (err)
|
|
109
|
+
return textResult(`R2 object list failed: ${err}`, true);
|
|
110
|
+
const objects = result.objects ?? [];
|
|
111
|
+
return textResult(objects.length ? objects.map((o) => `${o.key}\t${o.size}`).join("\n") : "No objects.");
|
|
112
|
+
});
|
|
113
|
+
// ─── storage-r2-object-get ────────────────────────────────────────────────
|
|
114
|
+
lifelineTool(server, "storage-r2-object-get", `Download an object from an R2 bucket your account owns to a file in your account directory. Objects larger than ${R2_OBJECT_MAX_BYTES / 1024 / 1024} MiB are rejected.`, {
|
|
115
|
+
bucket: z.string().describe("Bucket name"),
|
|
116
|
+
key: z.string().describe("Object key"),
|
|
117
|
+
destPath: z.string().describe("Destination file path, inside your account directory"),
|
|
118
|
+
}, async ({ bucket, key, destPath }) => {
|
|
119
|
+
// Confine before the fetch: a rejected destination should cost no download.
|
|
120
|
+
let dest;
|
|
121
|
+
try {
|
|
122
|
+
dest = confineToAccountDir(destPath, false);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return textResult(`R2 object get failed: ${e instanceof Error ? e.message : String(e)}`, true);
|
|
126
|
+
}
|
|
127
|
+
const result = await callApi("storage-r2-object-get", "/api/storage/r2/object/get", "POST", { bucket, key });
|
|
128
|
+
const err = errorOf(result);
|
|
129
|
+
if (err)
|
|
130
|
+
return textResult(`R2 object get failed: ${err}`, true);
|
|
131
|
+
const b64 = result.contentBase64;
|
|
132
|
+
if (typeof b64 !== "string")
|
|
133
|
+
return textResult("R2 object get failed: no content in response", true);
|
|
134
|
+
const bytes = Buffer.from(b64, "base64");
|
|
135
|
+
try {
|
|
136
|
+
writeFileSync(dest, bytes);
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
return textResult(`R2 object get failed: ${e instanceof Error ? e.message : String(e)}`, true);
|
|
140
|
+
}
|
|
141
|
+
return textResult(`Wrote ${bytes.length} bytes to ${dest}`);
|
|
142
|
+
});
|
|
143
|
+
// ─── storage-r2-object-put ────────────────────────────────────────────────
|
|
144
|
+
lifelineTool(server, "storage-r2-object-put", `Upload a file from your account directory to an R2 bucket your account owns. Files larger than ${R2_OBJECT_MAX_BYTES / 1024 / 1024} MiB are rejected.`, {
|
|
145
|
+
bucket: z.string().describe("Bucket name"),
|
|
146
|
+
key: z.string().describe("Object key"),
|
|
147
|
+
srcPath: z.string().describe("Source file path, inside your account directory"),
|
|
148
|
+
}, async ({ bucket, key, srcPath }) => {
|
|
149
|
+
let bytes;
|
|
150
|
+
try {
|
|
151
|
+
// Confined and size-checked before the read: an over-cap file costs no
|
|
152
|
+
// buffer here and never reaches the house process.
|
|
153
|
+
({ bytes } = readPutSource(srcPath));
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
return textResult(`R2 object put failed: ${e instanceof Error ? e.message : String(e)}`, true);
|
|
157
|
+
}
|
|
158
|
+
const result = await callApi("storage-r2-object-put", "/api/storage/r2/object/put", "POST", {
|
|
159
|
+
bucket,
|
|
160
|
+
key,
|
|
161
|
+
contentBase64: bytes.toString("base64"),
|
|
162
|
+
});
|
|
163
|
+
const err = errorOf(result);
|
|
164
|
+
if (err)
|
|
165
|
+
return textResult(`R2 object put failed: ${err}`, true);
|
|
166
|
+
return textResult(`Uploaded ${bytes.length} bytes to ${bucket}/${key}.`);
|
|
167
|
+
});
|
|
168
|
+
// ─── storage-r2-object-delete ─────────────────────────────────────────────
|
|
169
|
+
lifelineTool(server, "storage-r2-object-delete", "Delete an object from an R2 bucket your account owns.", { bucket: z.string().describe("Bucket name"), key: z.string().describe("Object key") }, async ({ bucket, key }) => {
|
|
170
|
+
const result = await callApi("storage-r2-object-delete", "/api/storage/r2/object/delete", "POST", { bucket, key });
|
|
171
|
+
const err = errorOf(result);
|
|
172
|
+
if (err)
|
|
173
|
+
return textResult(`R2 object delete failed: ${err}`, true);
|
|
174
|
+
return textResult(`Deleted ${bucket}/${key}.`);
|
|
175
|
+
});
|
|
90
176
|
async function main() {
|
|
91
177
|
const transport = new StdioServerTransport();
|
|
92
178
|
await server.connect(transport);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAC7E,aAAa,CAAC,gBAAgB,CAAC,CAAC;AAEhC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAE1E,gFAAgF;AAChF,8EAA8E;AAC9E,sEAAsE;AACtE,IAAI,aAAa,GAAkB,IAAI,CAAC;AACxC,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,aAAa,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,cAAc,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACxE,aAAa,GAAG,oBAAoB,IAAI,EAAE,CAAC;QAC3C,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,QAAQ,6BAA6B,CAAC,CAAC;QACtG,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AAEhF,SAAS,OAAO,CACd,QAAgB,EAChB,IAAY,EACZ,MAAsB,EACtB,IAAc;IAEd,OAAO,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,OAAO,GAAG,KAAK;IAC/C,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,MAAe;IAC9B,MAAM,CAAC,GAAI,MAA8B,EAAE,KAAK,CAAC;IACjD,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AAED,6EAA6E;AAC7E,YAAY,CAAC,MAAM,EAAE,iBAAiB,EACpC,qDAAqD,EACrD,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,iBAAiB,EAAE,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC,mBAAmB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAI,MAAkD,CAAC,SAAS,IAAI,EAAE,CAAC;IAChF,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;AACzF,CAAC,CACF,CAAC;AAEF,6EAA6E;AAC7E,YAAY,CAAC,MAAM,EAAE,mBAAmB,EACtC,wDAAwD,EACxD,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EAC9C,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9F,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC,qBAAqB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAI,MAAwD,CAAC,QAAQ,CAAC;IAC9E,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;AACtF,CAAC,CACF,CAAC;AAEF,6EAA6E;AAC7E,YAAY,CAAC,MAAM,EAAE,kBAAkB,EACrC,8DAA8D,EAC9D,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,EACzF,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;IACtB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACjG,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC,oBAAoB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC5D,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAE,MAA+B,CAAC,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,CACF,CAAC;AAEF,6EAA6E;AAC7E,YAAY,CAAC,MAAM,EAAE,wBAAwB,EAC3C,mDAAmD,EACnD,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,wBAAwB,EAAE,sBAAsB,EAAE,KAAK,CAAC,CAAC;IACtF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC,mBAAmB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAI,MAAgD,CAAC,OAAO,IAAI,EAAE,CAAC;IAChF,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;AAC/F,CAAC,CACF,CAAC;AAEF,6EAA6E;AAC7E,YAAY,CAAC,MAAM,EAAE,0BAA0B,EAC7C,sDAAsD,EACtD,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,EAC5C,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACrG,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC,qBAAqB,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7D,OAAO,UAAU,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;AAClD,CAAC,CACF,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the confined absolute path and the file's bytes.
|
|
3
|
+
*
|
|
4
|
+
* Throws naming the offending file and the limit when the file is over the cap,
|
|
5
|
+
* and naming the path when it is outside the account directory or unreadable.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readPutSource(srcPath: string): {
|
|
8
|
+
path: string;
|
|
9
|
+
bytes: Buffer;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=put-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put-source.d.ts","sourceRoot":"","sources":["../src/put-source.ts"],"names":[],"mappings":"AAuBA;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAQ9E"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a put's source file: confine it to the caller's account directory,
|
|
3
|
+
* size it, reject it if it is over the cap, and only then read it.
|
|
4
|
+
*
|
|
5
|
+
* The order is the point (Task 1695). An over-cap file must cost no buffer, in
|
|
6
|
+
* this process or the house one, so the size is checked before the read rather
|
|
7
|
+
* than after — the same pre-read statSync rule the email plugin's
|
|
8
|
+
* resolveOutboundAttachments already proves for the same class of payload.
|
|
9
|
+
* Checking after the read would bound the upload while leaving the local OOM
|
|
10
|
+
* exactly where it was.
|
|
11
|
+
*
|
|
12
|
+
* This lives in its own module rather than inline in the put tool because the
|
|
13
|
+
* ordering is the behaviour worth testing, and index.ts constructs an MCP server
|
|
14
|
+
* on import.
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync, statSync } from "node:fs";
|
|
17
|
+
import { basename } from "node:path";
|
|
18
|
+
import { confineToAccountDir } from "./confine-path.js";
|
|
19
|
+
import { R2_OBJECT_MAX_BYTES, tooLargeMessage, } from "../../../../lib/storage-broker/dist/object-limits.js";
|
|
20
|
+
/**
|
|
21
|
+
* Returns the confined absolute path and the file's bytes.
|
|
22
|
+
*
|
|
23
|
+
* Throws naming the offending file and the limit when the file is over the cap,
|
|
24
|
+
* and naming the path when it is outside the account directory or unreadable.
|
|
25
|
+
*/
|
|
26
|
+
export function readPutSource(srcPath) {
|
|
27
|
+
const path = confineToAccountDir(srcPath, true);
|
|
28
|
+
// confineToAccountDir has already proven this is a regular file.
|
|
29
|
+
const { size } = statSync(path);
|
|
30
|
+
if (size > R2_OBJECT_MAX_BYTES) {
|
|
31
|
+
throw new Error(tooLargeMessage(basename(path), size));
|
|
32
|
+
}
|
|
33
|
+
return { path, bytes: readFileSync(path) };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=put-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"put-source.js","sourceRoot":"","sources":["../src/put-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,mBAAmB,EACnB,eAAe,GAChB,MAAM,sDAAsD,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAChD,iEAAiE;IACjE,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,GAAG,mBAAmB,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;AAC7C,CAAC"}
|
|
@@ -87,6 +87,52 @@ write_parent_with_error() {
|
|
|
87
87
|
} > "$f"
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
# Write a parent JSONL carrying BOTH harness rejections and the classes that
|
|
91
|
+
# must NOT be treated as rejections. A rejection is a call the CLI refused to
|
|
92
|
+
# dispatch, so the tool never ran; everything else here either ran and failed or
|
|
93
|
+
# is a different fault. Both InputValidationError sub-classes are covered:
|
|
94
|
+
# unparseable JSON (carries __unparsedToolInput) and schema-valid JSON that
|
|
95
|
+
# failed validation (no such marker, and the majority class in practice).
|
|
96
|
+
write_parent_with_rejections() {
|
|
97
|
+
local cfg="$1" uuid="$2"
|
|
98
|
+
local f="$cfg/projects/-fake-cwd/${uuid}.jsonl"
|
|
99
|
+
{
|
|
100
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:00.000Z","uuid":"r0","message":{"role":"user","content":"send it"}}'
|
|
101
|
+
# 2 x rejection sub-class A (unparseable JSON) on ONE tool -> census x2
|
|
102
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:01.000Z","uuid":"r1","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_R1","name":"outlook-mail-send","input":{"__unparsedToolInput":"{\"to\": bare@x.co}"}}]}}'
|
|
103
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:02.000Z","uuid":"r2","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_R1","is_error":true,"content":"<tool_use_error>InputValidationError: outlook-mail-send was called with input that could not be parsed as JSON.\nYou sent (first 200 of 670 bytes): {\"to\": bare@x.co} REJECT_A_ONE</tool_use_error>"}]}}'
|
|
104
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:03.000Z","uuid":"r3","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_R2","name":"outlook-mail-send","input":{"__unparsedToolInput":"{\"to\": bare@x.co}"}}]}}'
|
|
105
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:04.000Z","uuid":"r4","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_R2","is_error":true,"content":"<tool_use_error>InputValidationError: outlook-mail-send was called with input that could not be parsed as JSON.\nYou sent (first 200 of 670 bytes): {\"to\": bare@x.co} REJECT_A_TWO</tool_use_error>"}]}}'
|
|
106
|
+
# rejection sub-class B: JSON parsed fine, schema validation failed
|
|
107
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:05.000Z","uuid":"r5","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_R3","name":"Read","input":{"offset":"x"}}]}}'
|
|
108
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:06.000Z","uuid":"r6","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_R3","is_error":true,"content":"<tool_use_error>InputValidationError: Read failed due to the following issue: The parameter `offset` type is expected as `number` REJECT_B_ONE</tool_use_error>"}]}}'
|
|
109
|
+
# NOT a rejection: unknown tool (different fault, has its own PostToolUse hook)
|
|
110
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:07.000Z","uuid":"r7","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_N1","name":"work-create","input":{}}]}}'
|
|
111
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:08.000Z","uuid":"r8","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_N1","is_error":true,"content":"<tool_use_error>Error: No such tool available: work-create NOTREJ_NOTOOL</tool_use_error>"}]}}'
|
|
112
|
+
# NOT a rejection: MCP server-side validation (the call DID reach the server)
|
|
113
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:09.000Z","uuid":"r9","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_N2","name":"outlook-mail-fetch-body","input":{}}]}}'
|
|
114
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:10.000Z","uuid":"rA","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_N2","is_error":true,"content":"MCP error -32602: Input validation error: id: Required NOTREJ_32602"}]}}'
|
|
115
|
+
# NOT a rejection: built-in tool that RAN and failed its precondition
|
|
116
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T15:59:11.000Z","uuid":"rB","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_N3","name":"Edit","input":{}}]}}'
|
|
117
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T15:59:12.000Z","uuid":"rC","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_N3","is_error":true,"content":"<tool_use_error>File has not been read yet. Read it first before writing to it. NOTREJ_UNREAD</tool_use_error>"}]}}'
|
|
118
|
+
} > "$f"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Write a subagent transcript whose ONLY error is a harness rejection. Used to
|
|
122
|
+
# prove --scan-subagent-errors does not report a rejection-only subagent as an
|
|
123
|
+
# error-carrying one: the subagent did not fail, a call was never dispatched.
|
|
124
|
+
write_subagent_rejection_only() {
|
|
125
|
+
local cfg="$1" parent_uuid="$2" agent="$3" atype="$4"
|
|
126
|
+
local d="$cfg/projects/-fake-cwd/${parent_uuid}/subagents"
|
|
127
|
+
mkdir -p "$d"
|
|
128
|
+
{
|
|
129
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T16:00:00.000Z","uuid":"j1","message":{"role":"user","content":"read it"}}'
|
|
130
|
+
printf '%s\n' '{"type":"assistant","timestamp":"2026-07-16T16:00:01.000Z","uuid":"j2","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_SR","name":"Read","input":{"__unparsedToolInput":"{\"file_path\": /x}"}}]}}'
|
|
131
|
+
printf '%s\n' '{"type":"user","timestamp":"2026-07-16T16:00:02.000Z","uuid":"j3","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_SR","is_error":true,"content":"<tool_use_error>InputValidationError: Read was called with input that could not be parsed as JSON.\nYou sent (first 200 of 30 bytes): {\"file_path\": /x} SUBREJ_ONLY</tool_use_error>"}]}}'
|
|
132
|
+
} > "$d/${agent}.jsonl"
|
|
133
|
+
printf '{"agentType":"%s","description":"read a file"}\n' "$atype" > "$d/${agent}.meta.json"
|
|
134
|
+
}
|
|
135
|
+
|
|
90
136
|
# Write a CLEAN subagent transcript (no errors) + its meta.
|
|
91
137
|
write_subagent_clean() {
|
|
92
138
|
local cfg="$1" parent_uuid="$2" agent="$3" atype="$4"
|
|
@@ -248,6 +294,75 @@ case_parent_error_not_subagent() {
|
|
|
248
294
|
return 0
|
|
249
295
|
}
|
|
250
296
|
|
|
297
|
+
# --- Case J: harness rejection is distinguished from a tool that RAN and failed ---
|
|
298
|
+
# The 1692 defect: a call the CLI refused to dispatch rendered identically to a
|
|
299
|
+
# tool that ran and returned a failure, so a rejection loop read as "the tool is
|
|
300
|
+
# broken" while the tool was healthy. Only InputValidationError may be relabelled.
|
|
301
|
+
case_rejection_classified_and_counted() {
|
|
302
|
+
local root="/tmp/maxy-1692-J-$$"; local out
|
|
303
|
+
out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
|
|
304
|
+
write_parent_with_rejections "$cfg" "$UUID_A"
|
|
305
|
+
write_pidfile "$cfg" 4255 "$UUID_A" "$BRIDGE"
|
|
306
|
+
|
|
307
|
+
invoke "$script" "$cfg" "session_${BRIDGE}"
|
|
308
|
+
cleanup_tree "$root"
|
|
309
|
+
|
|
310
|
+
[[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
|
|
311
|
+
|
|
312
|
+
# Both InputValidationError sub-classes are rejections (neither dispatched).
|
|
313
|
+
[[ "$OUT" == *"REJECTED"*"REJECT_A_ONE"* ]] || { echo " sub-class A (unparseable) not flagged REJECTED"; return 1; }
|
|
314
|
+
[[ "$OUT" == *"REJECTED"*"REJECT_B_ONE"* ]] || { echo " sub-class B (schema-invalid) not flagged REJECTED"; return 1; }
|
|
315
|
+
|
|
316
|
+
# The exclusions MUST keep the plain tool-error rendering. Widening the
|
|
317
|
+
# predicate to the bare <tool_use_error> wrapper is the regression this pins.
|
|
318
|
+
local l
|
|
319
|
+
for l in NOTREJ_NOTOOL NOTREJ_32602 NOTREJ_UNREAD; do
|
|
320
|
+
grep -q "tool error.*$l" <<<"$OUT" || { echo " $l lost its '‼ tool error' rendering"; return 1; }
|
|
321
|
+
grep -q "REJECTED.*$l" <<<"$OUT" && { echo " $l wrongly flagged REJECTED"; return 1; }
|
|
322
|
+
done
|
|
323
|
+
|
|
324
|
+
# Repetition is the diagnostic fact: 2 identical calls on one tool, counted.
|
|
325
|
+
[[ "$OUT" == *"rejections: 3"* ]] || { echo " census missing or miscounted (want 3)"; return 1; }
|
|
326
|
+
[[ "$OUT" == *"outlook-mail-send x2"* ]] || { echo " census does not count the repeat per tool"; return 1; }
|
|
327
|
+
return 0
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
# --- Case K: a clean session emits NO census line (non-regression) ---
|
|
331
|
+
case_no_rejections_no_census() {
|
|
332
|
+
local root="/tmp/maxy-1692-K-$$"; local out
|
|
333
|
+
out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
|
|
334
|
+
write_parent_with_error "$cfg" "$UUID_A"
|
|
335
|
+
write_pidfile "$cfg" 4256 "$UUID_A" "$BRIDGE"
|
|
336
|
+
|
|
337
|
+
invoke "$script" "$cfg" "session_${BRIDGE}"
|
|
338
|
+
cleanup_tree "$root"
|
|
339
|
+
|
|
340
|
+
[[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC"; return 1; }
|
|
341
|
+
[[ "$OUT" != *"rejections:"* ]] || { echo " census line emitted for a session with no rejections"; return 1; }
|
|
342
|
+
[[ "$OUT" != *"REJECTED"* ]] || { echo " genuine tool error wrongly flagged REJECTED"; return 1; }
|
|
343
|
+
return 0
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
# --- Case L: --scan-subagent-errors does not report a rejection-only subagent ---
|
|
347
|
+
# A rejection is not a subagent failure: the subagent did not fail, a call was
|
|
348
|
+
# never dispatched. Counting it re-creates the 1692 conflation one mode over.
|
|
349
|
+
case_scan_ignores_rejection_only_subagent() {
|
|
350
|
+
local root="/tmp/maxy-1692-L-$$"; local out
|
|
351
|
+
out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
|
|
352
|
+
write_parent "$cfg" "$UUID_A"
|
|
353
|
+
write_subagent_rejection_only "$cfg" "$UUID_A" "agent-aREJ00001" "content-producer"
|
|
354
|
+
write_subagent_failed "$cfg" "$UUID_A" "agent-aFAIL0001" "pdf-renderer"
|
|
355
|
+
|
|
356
|
+
invoke "$script" "$cfg" --scan-subagent-errors
|
|
357
|
+
cleanup_tree "$root"
|
|
358
|
+
|
|
359
|
+
[[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
|
|
360
|
+
[[ "$OUT" == *"aFAIL0001"* ]] || { echo " genuinely failed subagent missing from scan"; return 1; }
|
|
361
|
+
[[ "$OUT" != *"SUBREJ_ONLY"* ]] || { echo " rejection-only subagent reported as error-carrying"; return 1; }
|
|
362
|
+
[[ "$OUT" != *"aREJ00001"* ]] || { echo " rejection-only subagent listed by scan"; return 1; }
|
|
363
|
+
return 0
|
|
364
|
+
}
|
|
365
|
+
|
|
251
366
|
# --- Case I: content-grep resolves a unique body match (last-resort tier) ---
|
|
252
367
|
case_content_grep_single() {
|
|
253
368
|
local root="/tmp/maxy-585-I-$$"; local out
|
|
@@ -299,6 +414,9 @@ run_case "parent's own tool error not mislabelled SUBAGENT ERROR" case_pare
|
|
|
299
414
|
run_case "content-grep resolves a unique body match" case_content_grep_single
|
|
300
415
|
run_case "content-grep refuses an ambiguous (multi) body match" case_content_grep_ambiguous_refuses
|
|
301
416
|
run_case "unresolvable key → exit 1" case_unresolvable_miss
|
|
417
|
+
run_case "harness rejection classified + counted, exclusions intact" case_rejection_classified_and_counted
|
|
418
|
+
run_case "no rejections → no census line" case_no_rejections_no_census
|
|
419
|
+
run_case "scan ignores a rejection-only subagent" case_scan_ignores_rejection_only_subagent
|
|
302
420
|
|
|
303
421
|
echo ""
|
|
304
422
|
echo "================================================"
|