humanish 0.21.0 → 0.22.0
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/dist/comms-evidence.d.ts +27 -0
- package/dist/comms-evidence.js +31 -0
- package/dist/comms-evidence.js.map +1 -0
- package/dist/comms-sandbox-catch.d.ts +63 -0
- package/dist/comms-sandbox-catch.js +157 -0
- package/dist/comms-sandbox-catch.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/docs/contracts/schemas.md +1 -1
- package/docs/goals/current.md +1 -1
- package/docs/ramp/README.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CommsMessage } from "./comms-types.js";
|
|
2
|
+
export declare const COMMS_THREAD_SCHEMA = "humanish.comms-thread.v1";
|
|
3
|
+
export interface CommsThreadEntry {
|
|
4
|
+
id: string;
|
|
5
|
+
channel: CommsMessage["channel"];
|
|
6
|
+
/** sha256-16 of the raw sender address. */
|
|
7
|
+
fromDigest: string;
|
|
8
|
+
/** sha256-16 of each recipient inbox address. */
|
|
9
|
+
toDigests: string[];
|
|
10
|
+
/** sha256-16 of the subject (non-reversible for a PII subject; correlates identical subjects). */
|
|
11
|
+
subjectDigest?: string;
|
|
12
|
+
/** sha256-16 of each actionable link (high-entropy → non-reversible). */
|
|
13
|
+
linkDigests: string[];
|
|
14
|
+
/** COUNT ONLY — a short OTP's digest is reversible, so the code itself never lands here. */
|
|
15
|
+
codeCount: number;
|
|
16
|
+
sentAt: number;
|
|
17
|
+
deliveredAt: number;
|
|
18
|
+
}
|
|
19
|
+
export interface CommsThreadArtifact {
|
|
20
|
+
schema: typeof COMMS_THREAD_SCHEMA;
|
|
21
|
+
channel: CommsMessage["channel"];
|
|
22
|
+
count: number;
|
|
23
|
+
thread: CommsThreadEntry[];
|
|
24
|
+
}
|
|
25
|
+
/** Project polled inbox messages into the digest-only thread artifact. Pure; the caller writes it into
|
|
26
|
+
* the run dir and registers it as an adapter-artifact. */
|
|
27
|
+
export declare function buildCommsThreadArtifact(messages: CommsMessage[]): CommsThreadArtifact;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Digest-only evidence for a captured comms thread (#297). Proves "the verification mail arrived and
|
|
2
|
+
// the persona could act on it" WITHOUT persisting raw PHI. Written as an adapter-artifact
|
|
3
|
+
// (humanish.comms-thread.v1), so it inherits the bundle's existence-verify + public-safety scan.
|
|
4
|
+
//
|
|
5
|
+
// Digest discipline (deliberate, see below): addresses + links are digested (high entropy → the digest
|
|
6
|
+
// is not reversible). The subject is DIGESTED too, not stored as text — redactText only scrubs
|
|
7
|
+
// secret-SHAPED tokens/paths, not free-form PII (the #108 gap), so a subject like "results for <name>"
|
|
8
|
+
// would pass through verbatim; a sha256-16 keeps a PII subject non-reversible while still letting you
|
|
9
|
+
// correlate identical subjects. OTP CODES are a COUNT ONLY, never digested — a sha256 of a 6-digit code
|
|
10
|
+
// has ~10^6 preimages and is trivially brute-forced back to the code, so a "code digest" would leak it.
|
|
11
|
+
// Net: NO raw address/subject/link/OTP text ever lands in the artifact. Same caution as the lobby code.
|
|
12
|
+
import { digestText } from "./redaction.js";
|
|
13
|
+
export const COMMS_THREAD_SCHEMA = "humanish.comms-thread.v1";
|
|
14
|
+
/** Project polled inbox messages into the digest-only thread artifact. Pure; the caller writes it into
|
|
15
|
+
* the run dir and registers it as an adapter-artifact. */
|
|
16
|
+
export function buildCommsThreadArtifact(messages) {
|
|
17
|
+
const channel = messages[0]?.channel ?? "email";
|
|
18
|
+
const thread = messages.map((message) => ({
|
|
19
|
+
id: message.id,
|
|
20
|
+
channel: message.channel,
|
|
21
|
+
fromDigest: digestText(message.from, 16),
|
|
22
|
+
toDigests: message.to.map((address) => address.digest),
|
|
23
|
+
...(message.subject === undefined ? {} : { subjectDigest: digestText(message.subject, 16) }),
|
|
24
|
+
linkDigests: message.links.map((link) => digestText(link, 16)),
|
|
25
|
+
codeCount: message.codes.length,
|
|
26
|
+
sentAt: message.sentAt,
|
|
27
|
+
deliveredAt: message.deliveredAt
|
|
28
|
+
}));
|
|
29
|
+
return { schema: COMMS_THREAD_SCHEMA, channel, count: thread.length, thread };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=comms-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comms-evidence.js","sourceRoot":"","sources":["../src/comms-evidence.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,0FAA0F;AAC1F,iGAAiG;AACjG,EAAE;AACF,uGAAuG;AACvG,+FAA+F;AAC/F,uGAAuG;AACvG,sGAAsG;AACtG,wGAAwG;AACxG,wGAAwG;AACxG,wGAAwG;AAGxG,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AA0B9D;2DAC2D;AAC3D,MAAM,UAAU,wBAAwB,CAAC,QAAwB;IAC/D,MAAM,OAAO,GAA4B,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC;IACzE,MAAM,MAAM,GAAuB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5D,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACxC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;QACtD,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5F,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;QAC/B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { CommsChannel } from "./comms-types.js";
|
|
2
|
+
import { type EmailSendProfile } from "./comms-email-catch.js";
|
|
3
|
+
import { type DetachedTimers } from "./e2b-detached.js";
|
|
4
|
+
import type { E2BDesktopSandbox } from "./e2b-desktop-launch.js";
|
|
5
|
+
/** The default in-sandbox loopback port for the catch. Fixed (not ephemeral) so the injected base-URL
|
|
6
|
+
* env is known before `createDesktopSandbox`. 8025 is the conventional local-mail-UI port and is
|
|
7
|
+
* unlikely to collide with a subject app; override via config if it does. */
|
|
8
|
+
export declare const DEFAULT_SANDBOX_CATCH_PORT = 8025;
|
|
9
|
+
/**
|
|
10
|
+
* The self-contained in-sandbox capture server (a plain node ESM string — runs on the sandbox's own
|
|
11
|
+
* node, imports nothing from humanish). It is DELIBERATELY dumb: it records each POST verbatim as an
|
|
12
|
+
* NDJSON line `{t, path, body}` and returns a plausible provider success — all normalization/profile
|
|
13
|
+
* parsing happens host-side on the drained lines, so the typed, tested profiles stay in one place.
|
|
14
|
+
* argv: <port> <deliveriesFile>.
|
|
15
|
+
*/
|
|
16
|
+
export declare const SANDBOX_CATCH_SCRIPT: string;
|
|
17
|
+
export interface DeployCommsCatchOptions {
|
|
18
|
+
/** Fixed loopback port the catch listens on (default 8025). Must be free inside the sandbox. */
|
|
19
|
+
port?: number;
|
|
20
|
+
/** In-sandbox working dir for the script + NDJSON (default /tmp/humanish-comms). */
|
|
21
|
+
dir?: string;
|
|
22
|
+
/** Detached-process name ([a-z0-9-]); default "comms-catch". */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** Readiness-probe budget (ms) for the catch's /health (default 15000). */
|
|
25
|
+
readyTimeoutMs?: number;
|
|
26
|
+
requestTimeoutMs?: number;
|
|
27
|
+
timers?: DetachedTimers;
|
|
28
|
+
}
|
|
29
|
+
export interface DeployedCommsCatch {
|
|
30
|
+
port: number;
|
|
31
|
+
/** Inject THIS as the app's email-API base URL (e.g. RESEND_API_URL) — the sandbox's own loopback. */
|
|
32
|
+
baseUrl: string;
|
|
33
|
+
deliveriesPath: string;
|
|
34
|
+
/** Whether the catch's /health returned OUR service marker within the readiness budget. Callers MUST
|
|
35
|
+
* treat `ready === false` as fatal (do not inject baseUrl into a dead catch — the app's sends would
|
|
36
|
+
* silently fail with nothing captured). */
|
|
37
|
+
ready: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** A raw send the in-sandbox catch captured (host-side parsing happens in routeCapturedSends). */
|
|
40
|
+
export interface RawCapturedSend {
|
|
41
|
+
path: string;
|
|
42
|
+
body: string;
|
|
43
|
+
t: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Write + launch the in-sandbox catch (detached), then probe it ready. Call AFTER the subject sandbox
|
|
47
|
+
* is created and BEFORE the subject app's serve.start, so the base URL resolves at the app's boot.
|
|
48
|
+
*/
|
|
49
|
+
export declare function deployCommsCatch(desktop: E2BDesktopSandbox, options?: DeployCommsCatchOptions): Promise<DeployedCommsCatch>;
|
|
50
|
+
/**
|
|
51
|
+
* Drain new captured sends from the in-sandbox NDJSON since `cursor` (a line count). Returns the fresh
|
|
52
|
+
* sends and the new cursor. Cheap `cat` over commands.run; NDJSON is small for a run.
|
|
53
|
+
*/
|
|
54
|
+
export declare function drainCommsCatch(desktop: E2BDesktopSandbox, deployed: Pick<DeployedCommsCatch, "deliveriesPath">, cursor?: number, requestTimeoutMs?: number): Promise<{
|
|
55
|
+
sends: RawCapturedSend[];
|
|
56
|
+
cursor: number;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Parse drained raw sends with the host profiles and route them into the CommsChannel (the host-side
|
|
60
|
+
* FauxInbox). Returns the number of inbox deliveries made. Same profiles as the host catch, so the
|
|
61
|
+
* in-sandbox and in-process routes normalize identically.
|
|
62
|
+
*/
|
|
63
|
+
export declare function routeCapturedSends(sends: RawCapturedSend[], channel: CommsChannel, profiles?: EmailSendProfile[]): Promise<number>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Deploy the vendor-neutral email catch INSIDE the subject E2B sandbox and bridge captured sends back
|
|
2
|
+
// to the host bus (#297 config-block core). The host `startEmailCatchServer` binds the HOST's loopback,
|
|
3
|
+
// which a sandboxed app cannot reach — `127.0.0.1:PORT` from the app is the SANDBOX's loopback. So the
|
|
4
|
+
// listener must live in the sandbox: we write a tiny self-contained capture server (no deps, no host
|
|
5
|
+
// import) into the sandbox, launch it detached (the same substrate that serves the subject app), and
|
|
6
|
+
// each poll `cat` its append-only NDJSON of captured sends back to the host, where the real profiles
|
|
7
|
+
// parse them and route into the CommsChannel. A FIXED loopback port is chosen up front so the app's
|
|
8
|
+
// injected base-URL env (`http://127.0.0.1:<port>`) is known before the sandbox is created.
|
|
9
|
+
import { DEFAULT_EMAIL_PROFILES } from "./comms-email-catch.js";
|
|
10
|
+
import { startDetachedProcess } from "./e2b-detached.js";
|
|
11
|
+
/** The default in-sandbox loopback port for the catch. Fixed (not ephemeral) so the injected base-URL
|
|
12
|
+
* env is known before `createDesktopSandbox`. 8025 is the conventional local-mail-UI port and is
|
|
13
|
+
* unlikely to collide with a subject app; override via config if it does. */
|
|
14
|
+
export const DEFAULT_SANDBOX_CATCH_PORT = 8025;
|
|
15
|
+
const DEFAULT_CATCH_DIR = "/tmp/humanish-comms";
|
|
16
|
+
/** Single-quote for safe shell interpolation. */
|
|
17
|
+
function shq(value) {
|
|
18
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The self-contained in-sandbox capture server (a plain node ESM string — runs on the sandbox's own
|
|
22
|
+
* node, imports nothing from humanish). It is DELIBERATELY dumb: it records each POST verbatim as an
|
|
23
|
+
* NDJSON line `{t, path, body}` and returns a plausible provider success — all normalization/profile
|
|
24
|
+
* parsing happens host-side on the drained lines, so the typed, tested profiles stay in one place.
|
|
25
|
+
* argv: <port> <deliveriesFile>.
|
|
26
|
+
*/
|
|
27
|
+
export const SANDBOX_CATCH_SCRIPT = [
|
|
28
|
+
'import { createServer } from "node:http";',
|
|
29
|
+
'import { appendFileSync, mkdirSync } from "node:fs";',
|
|
30
|
+
'import { dirname } from "node:path";',
|
|
31
|
+
'const port = Number(process.argv[2] || 8025);',
|
|
32
|
+
'const outFile = process.argv[3] || "/tmp/humanish-comms/deliveries.ndjson";',
|
|
33
|
+
'try { mkdirSync(dirname(outFile), { recursive: true }); } catch {}',
|
|
34
|
+
'const MAX = 5 * 1024 * 1024;',
|
|
35
|
+
'createServer((req, res) => {',
|
|
36
|
+
' const path = (req.url || "/").split("?")[0];',
|
|
37
|
+
' if (req.method === "GET" && (path === "/" || path === "/health")) { res.writeHead(200, { "content-type": "application/json" }); res.end(JSON.stringify({ ok: true, service: "humanish-comms-catch" })); return; }',
|
|
38
|
+
' if (req.method !== "POST") { res.writeHead(404, { "content-type": "application/json" }); res.end(JSON.stringify({ error: "not found" })); return; }',
|
|
39
|
+
' let size = 0; const chunks = [];',
|
|
40
|
+
' req.on("data", (c) => { size += c.length; if (size > MAX) { req.destroy(); } else { chunks.push(c); } });',
|
|
41
|
+
' req.on("end", () => {',
|
|
42
|
+
' const body = Buffer.concat(chunks).toString("utf8");',
|
|
43
|
+
' try { appendFileSync(outFile, JSON.stringify({ t: Date.now(), path, body }) + "\\n"); } catch {}',
|
|
44
|
+
' const id = "humanish-catch-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 8);',
|
|
45
|
+
' if (path === "/v3/mail/send") { res.writeHead(202, { "x-message-id": id }); res.end(); }',
|
|
46
|
+
' else if (path.endsWith("/batch")) { res.writeHead(200, { "content-type": "application/json" }); res.end(JSON.stringify({ data: [{ id }] })); }',
|
|
47
|
+
' else { res.writeHead(200, { "content-type": "application/json" }); res.end(JSON.stringify({ id })); }',
|
|
48
|
+
' });',
|
|
49
|
+
' req.on("error", () => { try { res.writeHead(400); res.end(); } catch {} });',
|
|
50
|
+
'}).listen(port, "127.0.0.1");'
|
|
51
|
+
].join("\n");
|
|
52
|
+
/** Readiness probe that asserts OUR service marker in the /health body (not merely any 2xx) — so a
|
|
53
|
+
* process squatting on the fixed port cannot produce a false "ready" while the app's sends bypass us. */
|
|
54
|
+
async function catchHealthy(desktop, port, options) {
|
|
55
|
+
const now = options.now ?? Date.now;
|
|
56
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
57
|
+
const deadline = now() + options.timeoutMs;
|
|
58
|
+
for (;;) {
|
|
59
|
+
const result = await desktop.commands
|
|
60
|
+
.run(`curl -s --max-time 5 http://127.0.0.1:${port}/health 2>/dev/null || true`, { requestTimeoutMs: options.requestTimeoutMs })
|
|
61
|
+
.catch(() => ({ stdout: "" }));
|
|
62
|
+
if ((result.stdout ?? "").includes("humanish-comms-catch"))
|
|
63
|
+
return true;
|
|
64
|
+
if (now() >= deadline)
|
|
65
|
+
return false;
|
|
66
|
+
await sleep(1000);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Write + launch the in-sandbox catch (detached), then probe it ready. Call AFTER the subject sandbox
|
|
71
|
+
* is created and BEFORE the subject app's serve.start, so the base URL resolves at the app's boot.
|
|
72
|
+
*/
|
|
73
|
+
export async function deployCommsCatch(desktop, options = {}) {
|
|
74
|
+
// Validate the port to an integer before it reaches the shell command (defense-in-depth: a future
|
|
75
|
+
// caller might cast a config value; the value is typed `number` but this makes injection impossible).
|
|
76
|
+
const port = Math.trunc(Number(options.port ?? DEFAULT_SANDBOX_CATCH_PORT));
|
|
77
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65_535) {
|
|
78
|
+
throw new Error(`deployCommsCatch: invalid port ${JSON.stringify(options.port)}`);
|
|
79
|
+
}
|
|
80
|
+
const dir = options.dir ?? DEFAULT_CATCH_DIR;
|
|
81
|
+
const name = options.name ?? "comms-catch";
|
|
82
|
+
const requestTimeoutMs = options.requestTimeoutMs ?? 30_000;
|
|
83
|
+
const scriptPath = `${dir}/catch.mjs`;
|
|
84
|
+
const deliveriesPath = `${dir}/deliveries.ndjson`;
|
|
85
|
+
await desktop.commands.run(`mkdir -p ${shq(dir)}`, { requestTimeoutMs });
|
|
86
|
+
await desktop.files.write(scriptPath, SANDBOX_CATCH_SCRIPT);
|
|
87
|
+
await startDetachedProcess(desktop, {
|
|
88
|
+
name,
|
|
89
|
+
command: `node ${shq(scriptPath)} ${port} ${shq(deliveriesPath)}`,
|
|
90
|
+
requestTimeoutMs
|
|
91
|
+
});
|
|
92
|
+
const ready = await catchHealthy(desktop, port, {
|
|
93
|
+
timeoutMs: options.readyTimeoutMs ?? 15_000,
|
|
94
|
+
requestTimeoutMs,
|
|
95
|
+
...(options.timers ?? {})
|
|
96
|
+
});
|
|
97
|
+
return { port, baseUrl: `http://127.0.0.1:${port}`, deliveriesPath, ready };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Drain new captured sends from the in-sandbox NDJSON since `cursor` (a line count). Returns the fresh
|
|
101
|
+
* sends and the new cursor. Cheap `cat` over commands.run; NDJSON is small for a run.
|
|
102
|
+
*/
|
|
103
|
+
export async function drainCommsCatch(desktop, deployed, cursor = 0, requestTimeoutMs = 30_000) {
|
|
104
|
+
const result = await desktop.commands.run(`cat ${shq(deployed.deliveriesPath)} 2>/dev/null || true`, { requestTimeoutMs });
|
|
105
|
+
const stdout = result.stdout ?? "";
|
|
106
|
+
let lines = stdout.split("\n").filter((line) => line.trim().length > 0);
|
|
107
|
+
// If the file doesn't end in a newline, the last line may be a PARTIAL append (the host `cat` raced
|
|
108
|
+
// an in-sandbox append of a large body). Drop it and don't advance the cursor past it — it re-reads
|
|
109
|
+
// complete on the next poll, so a captured send is never lost to the race (the script only ever emits
|
|
110
|
+
// valid JSON, so an incomplete line is the only cause of a parse miss).
|
|
111
|
+
if (!stdout.endsWith("\n") && lines.length > 0)
|
|
112
|
+
lines = lines.slice(0, -1);
|
|
113
|
+
const sends = [];
|
|
114
|
+
for (const line of lines.slice(cursor)) {
|
|
115
|
+
try {
|
|
116
|
+
const parsed = JSON.parse(line);
|
|
117
|
+
if (typeof parsed.path === "string" && typeof parsed.body === "string") {
|
|
118
|
+
sends.push({ path: parsed.path, body: parsed.body, t: typeof parsed.t === "number" ? parsed.t : 0 });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// skip a malformed line
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { sends, cursor: lines.length };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Parse drained raw sends with the host profiles and route them into the CommsChannel (the host-side
|
|
129
|
+
* FauxInbox). Returns the number of inbox deliveries made. Same profiles as the host catch, so the
|
|
130
|
+
* in-sandbox and in-process routes normalize identically.
|
|
131
|
+
*/
|
|
132
|
+
export async function routeCapturedSends(sends, channel, profiles = DEFAULT_EMAIL_PROFILES) {
|
|
133
|
+
let delivered = 0;
|
|
134
|
+
for (const send of sends) {
|
|
135
|
+
let parsed;
|
|
136
|
+
try {
|
|
137
|
+
parsed = JSON.parse(send.body.length > 0 ? send.body : "{}");
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const profile = profiles.find((candidate) => candidate.sendPaths.includes(send.path)) ?? profiles[0];
|
|
143
|
+
if (profile === undefined)
|
|
144
|
+
continue;
|
|
145
|
+
for (const normalized of profile.parse(send.path, parsed)) {
|
|
146
|
+
const messages = await channel.deliverRaw({
|
|
147
|
+
from: normalized.from,
|
|
148
|
+
to: normalized.to,
|
|
149
|
+
...(normalized.subject === undefined ? {} : { subject: normalized.subject }),
|
|
150
|
+
body: normalized.body
|
|
151
|
+
});
|
|
152
|
+
delivered += messages.length;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return delivered;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=comms-sandbox-catch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comms-sandbox-catch.js","sourceRoot":"","sources":["../src/comms-sandbox-catch.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,10 @@ export { FauxInbox, extractLinks, extractOtpCodes } from "./comms-faux-inbox.js"
|
|
|
21
21
|
export type { FauxInboxOptions } from "./comms-faux-inbox.js";
|
|
22
22
|
export { DEFAULT_EMAIL_PROFILES, genericEmailProfile, sendgridEmailProfile, startEmailCatchServer } from "./comms-email-catch.js";
|
|
23
23
|
export type { EmailCatchOptions, EmailCatchServer, EmailSendProfile, NormalizedSend } from "./comms-email-catch.js";
|
|
24
|
+
export { DEFAULT_SANDBOX_CATCH_PORT, SANDBOX_CATCH_SCRIPT, deployCommsCatch, drainCommsCatch, routeCapturedSends } from "./comms-sandbox-catch.js";
|
|
25
|
+
export type { DeployCommsCatchOptions, DeployedCommsCatch, RawCapturedSend } from "./comms-sandbox-catch.js";
|
|
26
|
+
export { COMMS_THREAD_SCHEMA, buildCommsThreadArtifact } from "./comms-evidence.js";
|
|
27
|
+
export type { CommsThreadArtifact, CommsThreadEntry } from "./comms-evidence.js";
|
|
24
28
|
export type { CommsAddress, CommsChannel, CommsChannelKind, CommsMessage, InboundRaw, OutboundMessage } from "./comms-types.js";
|
|
25
29
|
export { DESKTOP_RATE, MODEL_RATES, PRICING_SCHEMA, estimateActorCost, estimateDesktopCost } from "./pricing.js";
|
|
26
30
|
export type { ActorEstimatedCost, DesktopCostEstimate, DesktopRate, ModelRate } from "./pricing.js";
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,10 @@ export { adapterScoreFailureMessage, applyAdapterScoreFailureToReview, applyBrow
|
|
|
13
13
|
// same CommsChannel port.
|
|
14
14
|
export { FauxInbox, extractLinks, extractOtpCodes } from "./comms-faux-inbox.js";
|
|
15
15
|
export { DEFAULT_EMAIL_PROFILES, genericEmailProfile, sendgridEmailProfile, startEmailCatchServer } from "./comms-email-catch.js";
|
|
16
|
+
// In-sandbox deployment of the catch + the host-side delivery bridge (the config-block core: the
|
|
17
|
+
// listener must live inside the subject sandbox, since 127.0.0.1 from the app is the sandbox loopback).
|
|
18
|
+
export { DEFAULT_SANDBOX_CATCH_PORT, SANDBOX_CATCH_SCRIPT, deployCommsCatch, drainCommsCatch, routeCapturedSends } from "./comms-sandbox-catch.js";
|
|
19
|
+
export { COMMS_THREAD_SCHEMA, buildCommsThreadArtifact } from "./comms-evidence.js";
|
|
16
20
|
export { DESKTOP_RATE, MODEL_RATES, PRICING_SCHEMA, estimateActorCost, estimateDesktopCost } from "./pricing.js";
|
|
17
21
|
export { normalizeCliArgv } from "./argv.js";
|
|
18
22
|
export { CODEX_APP_SERVER_UI_SCHEMA, startCodexAppServerUi } from "./codex-app-server-ui.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,uBAAuB,EACvB,6BAA6B,EAC9B,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,oBAAoB,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEjJ,OAAO,EACL,mCAAmC,EACnC,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EACL,uBAAuB,EACvB,gCAAgC,EAChC,6BAA6B,EAC9B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,0BAA0B,EAC1B,gCAAgC,EAChC,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAOhC,6FAA6F;AAC7F,iGAAiG;AACjG,iGAAiG;AACjG,0BAA0B;AAC1B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
5
|
Status: reference map for the major contracts shipped through source version
|
|
6
|
-
`0.
|
|
6
|
+
`0.22.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
|
|
7
7
|
schema constants, parsers, and validators in `src/` are authoritative. Rows
|
|
8
8
|
marked "reserved" name layering intent only — no code emits or validates them
|
|
9
9
|
yet. Do not emit a reserved schema.
|
package/docs/goals/current.md
CHANGED
|
@@ -16,7 +16,7 @@ Humanish should be the open-source CLI that lets a maintainer ask:
|
|
|
16
16
|
The answer should be observable, verifiable, public-safe, and easy to turn into
|
|
17
17
|
actionable feedback.
|
|
18
18
|
|
|
19
|
-
## Current Program Truth (source `0.
|
|
19
|
+
## Current Program Truth (source `0.22.0`)
|
|
20
20
|
|
|
21
21
|
The package source and repository implementation in this tree agree on these
|
|
22
22
|
points:
|
package/docs/ramp/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Status: public-safe contributor and agent ramp.
|
|
4
4
|
|
|
5
|
-
Package/source version in this tree: `0.
|
|
5
|
+
Package/source version in this tree: `0.22.0` (2026-08-04). The containment boundary introduced in
|
|
6
6
|
`0.15.1` remains in force: managed run and output paths bind to validated
|
|
7
7
|
physical filesystem identities, and stored provider IDs are evidence, not
|
|
8
8
|
cleanup authority. The bundled OSS meta-lab is dry-run only until
|
package/package.json
CHANGED