@samjurnio_/memento 0.2.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/LICENSE +202 -0
- package/README.md +144 -0
- package/dist/adapters/antigravity.d.ts +19 -0
- package/dist/adapters/antigravity.js +463 -0
- package/dist/adapters/antigravity.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +14 -0
- package/dist/adapters/claude-code.js +213 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/codex.d.ts +12 -0
- package/dist/adapters/codex.js +247 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/gemini.d.ts +10 -0
- package/dist/adapters/gemini.js +171 -0
- package/dist/adapters/gemini.js.map +1 -0
- package/dist/adapters/opencode.d.ts +3 -0
- package/dist/adapters/opencode.js +137 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/pi.d.ts +6 -0
- package/dist/adapters/pi.js +172 -0
- package/dist/adapters/pi.js.map +1 -0
- package/dist/artifacts.d.ts +25 -0
- package/dist/artifacts.js +50 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/bench-live.d.ts +28 -0
- package/dist/bench-live.js +187 -0
- package/dist/bench-live.js.map +1 -0
- package/dist/bench.d.ts +33 -0
- package/dist/bench.js +213 -0
- package/dist/bench.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +338 -0
- package/dist/cli.js.map +1 -0
- package/dist/compile.d.ts +27 -0
- package/dist/compile.js +193 -0
- package/dist/compile.js.map +1 -0
- package/dist/git.d.ts +45 -0
- package/dist/git.js +172 -0
- package/dist/git.js.map +1 -0
- package/dist/handoff.d.ts +26 -0
- package/dist/handoff.js +80 -0
- package/dist/handoff.js.map +1 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.js +114 -0
- package/dist/hooks.js.map +1 -0
- package/dist/ids.d.ts +10 -0
- package/dist/ids.js +32 -0
- package/dist/ids.js.map +1 -0
- package/dist/inject/antigravity.d.ts +7 -0
- package/dist/inject/antigravity.js +391 -0
- package/dist/inject/antigravity.js.map +1 -0
- package/dist/inject/claude-code.d.ts +15 -0
- package/dist/inject/claude-code.js +53 -0
- package/dist/inject/claude-code.js.map +1 -0
- package/dist/inject/codex.d.ts +7 -0
- package/dist/inject/codex.js +307 -0
- package/dist/inject/codex.js.map +1 -0
- package/dist/inject/dispatch.d.ts +11 -0
- package/dist/inject/dispatch.js +42 -0
- package/dist/inject/dispatch.js.map +1 -0
- package/dist/inject.d.ts +22 -0
- package/dist/inject.js +47 -0
- package/dist/inject.js.map +1 -0
- package/dist/ledger.d.ts +45 -0
- package/dist/ledger.js +50 -0
- package/dist/ledger.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.js +197 -0
- package/dist/mcp.js.map +1 -0
- package/dist/packet.d.ts +185 -0
- package/dist/packet.js +154 -0
- package/dist/packet.js.map +1 -0
- package/dist/redact.d.ts +19 -0
- package/dist/redact.js +86 -0
- package/dist/redact.js.map +1 -0
- package/dist/render.d.ts +11 -0
- package/dist/render.js +145 -0
- package/dist/render.js.map +1 -0
- package/dist/summarize.d.ts +35 -0
- package/dist/summarize.js +166 -0
- package/dist/summarize.js.map +1 -0
- package/package.json +61 -0
- package/schemas/packet.v1.schema.json +510 -0
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { loadPacket } from "./artifacts.js";
|
|
6
|
+
import { captureGitState, restoreWorkspace, snapshotRefExists, verifyWorkspace } from "./git.js";
|
|
7
|
+
import { AGENTS, performHandoff, REASONS } from "./handoff.js";
|
|
8
|
+
import { INJECT_TARGETS, injectPacket, isInjectTarget } from "./inject/dispatch.js";
|
|
9
|
+
import { verifySeal } from "./packet.js";
|
|
10
|
+
import { renderResumePrompt, renderStatus } from "./render.js";
|
|
11
|
+
/**
|
|
12
|
+
* Memento as an MCP server (spec §6.3, stdio transport): the same tool
|
|
13
|
+
* vocabulary every agent CLI can call natively, removing the paste step from
|
|
14
|
+
* cross-agent handoff. Built on the SDK's low-level Server API with plain
|
|
15
|
+
* JSON Schema inputs — deliberately avoiding the high-level zod bridge so
|
|
16
|
+
* Memento's zod v4 never has to interoperate with the SDK's bundled zod.
|
|
17
|
+
*
|
|
18
|
+
* Register (examples):
|
|
19
|
+
* claude mcp add memento -- memento mcp
|
|
20
|
+
* codex config: [mcp_servers.memento] command = "memento" args = ["mcp"]
|
|
21
|
+
*/
|
|
22
|
+
const WORKSPACE_PROP = {
|
|
23
|
+
workspace: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "Workspace directory. Defaults to the server process cwd.",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const TOOLS = [
|
|
29
|
+
{
|
|
30
|
+
name: "memento_handoff",
|
|
31
|
+
description: "Compile a sealed Continuation Packet from the workspace's latest agent session " +
|
|
32
|
+
"(or an explicit transcript) and write .memento/handoff.json + HANDOFF.md. " +
|
|
33
|
+
"Pass `to` to also inject it as a native session for that agent in one step. " +
|
|
34
|
+
"Successive calls chain automatically (same task, parent pointer, seq+1).",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
...WORKSPACE_PROP,
|
|
39
|
+
agent: { type: "string", enum: [...AGENTS], description: "Which agent's session to capture (default claude-code)." },
|
|
40
|
+
to: { type: "string", enum: [...INJECT_TARGETS], description: "Optional: also inject the packet as a native session for this agent." },
|
|
41
|
+
transcript: { type: "string", description: "Explicit session file; defaults to newest for the workspace." },
|
|
42
|
+
reason: { type: "string", enum: [...REASONS], description: "Why the handoff is happening (default operator_switch)." },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "memento_resume",
|
|
48
|
+
description: "Return the resume prompt for the workspace's current packet: continuation " +
|
|
49
|
+
"instructions plus the full handoff. Refuses packets whose seal fails verification. " +
|
|
50
|
+
"Call this FIRST when continuing another agent's task.",
|
|
51
|
+
inputSchema: { type: "object", properties: { ...WORKSPACE_PROP } },
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "memento_verify",
|
|
55
|
+
description: "Continuity check: compare the live workspace git state against the packet. " +
|
|
56
|
+
"Returns a drift report; isError is set when drift is detected. " +
|
|
57
|
+
"Run before editing anything after a resume.",
|
|
58
|
+
inputSchema: { type: "object", properties: { ...WORKSPACE_PROP } },
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "memento_restore",
|
|
62
|
+
description: "Materialize the packet's working-tree snapshot into the workspace — the prior " +
|
|
63
|
+
"agent's actual uncommitted and untracked files, not just a summary of them. " +
|
|
64
|
+
"Refuses to overwrite diverging local edits unless force is set.",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
...WORKSPACE_PROP,
|
|
69
|
+
force: { type: "boolean", description: "Overwrite local edits that diverge from the packet." },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "memento_status",
|
|
75
|
+
description: "Summarize the workspace's current packet: ids, chain position, seal, next step.",
|
|
76
|
+
inputSchema: { type: "object", properties: { ...WORKSPACE_PROP } },
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
function requirePacket(workspace) {
|
|
80
|
+
const packet = loadPacket(workspace);
|
|
81
|
+
if (!packet) {
|
|
82
|
+
throw new Error(`No packet found in ${workspace}/.memento — run memento_handoff first.`);
|
|
83
|
+
}
|
|
84
|
+
return packet;
|
|
85
|
+
}
|
|
86
|
+
async function dispatch(name, args) {
|
|
87
|
+
const workspace = resolve(typeof args.workspace === "string" ? args.workspace : process.cwd());
|
|
88
|
+
switch (name) {
|
|
89
|
+
case "memento_handoff": {
|
|
90
|
+
const reason = typeof args.reason === "string" ? args.reason : undefined;
|
|
91
|
+
if (reason && !REASONS.includes(reason)) {
|
|
92
|
+
throw new Error(`Unknown reason "${reason}". One of: ${REASONS.join(", ")}`);
|
|
93
|
+
}
|
|
94
|
+
const to = typeof args.to === "string" ? args.to : undefined;
|
|
95
|
+
if (to && !isInjectTarget(to)) {
|
|
96
|
+
throw new Error(`Unknown target "${to}". One of: ${INJECT_TARGETS.join(", ")}`);
|
|
97
|
+
}
|
|
98
|
+
const result = await performHandoff({
|
|
99
|
+
workspaceDir: workspace,
|
|
100
|
+
...(typeof args.agent === "string" ? { agent: args.agent } : {}),
|
|
101
|
+
...(typeof args.transcript === "string" ? { transcript: args.transcript } : {}),
|
|
102
|
+
...(reason ? { reason: reason } : {}),
|
|
103
|
+
});
|
|
104
|
+
const out = [
|
|
105
|
+
`Sealed packet ${result.packet.packet.id} (task ${result.packet.packet.taskId}, seq ${result.packet.packet.seq})`,
|
|
106
|
+
`ledger: ${result.transcriptPath} (${result.eventCount} events)`,
|
|
107
|
+
`snapshot: ${result.packet.workspace.git?.snapshotRef ?? "(none)"}`,
|
|
108
|
+
`redaction: ${result.packet.redaction.count} hit(s)`,
|
|
109
|
+
`wrote: ${result.artifacts.jsonPath}`,
|
|
110
|
+
];
|
|
111
|
+
if (to && isInjectTarget(to)) {
|
|
112
|
+
out.push("", ...(await injectPacket(to, result.packet, workspace)));
|
|
113
|
+
}
|
|
114
|
+
return { text: out.join("\n") };
|
|
115
|
+
}
|
|
116
|
+
case "memento_resume": {
|
|
117
|
+
const packet = requirePacket(workspace);
|
|
118
|
+
if (!verifySeal(packet)) {
|
|
119
|
+
throw new Error("Packet seal does not verify — it was modified after sealing. Refusing.");
|
|
120
|
+
}
|
|
121
|
+
return { text: renderResumePrompt(packet) };
|
|
122
|
+
}
|
|
123
|
+
case "memento_verify": {
|
|
124
|
+
const packet = requirePacket(workspace);
|
|
125
|
+
if (!packet.workspace.git) {
|
|
126
|
+
return { text: "Packet carries no git state; nothing to verify." };
|
|
127
|
+
}
|
|
128
|
+
const report = await verifyWorkspace(workspace, packet.workspace.git);
|
|
129
|
+
if (report.clean) {
|
|
130
|
+
return { text: `Workspace matches packet ${packet.packet.id} — safe to continue.` };
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
text: [`Drift detected against packet ${packet.packet.id}:`, ...report.drift].join("\n"),
|
|
134
|
+
isError: true,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
case "memento_restore": {
|
|
138
|
+
const packet = requirePacket(workspace);
|
|
139
|
+
const snapshotRef = packet.workspace.git?.snapshotRef;
|
|
140
|
+
if (!snapshotRef) {
|
|
141
|
+
return { text: "Packet carries no working-tree snapshot — nothing to restore.", isError: true };
|
|
142
|
+
}
|
|
143
|
+
if (!(await snapshotRefExists(workspace, snapshotRef))) {
|
|
144
|
+
return {
|
|
145
|
+
text: `Snapshot ${snapshotRef} is not present in this repo (cross-machine restore needs a bundle).`,
|
|
146
|
+
isError: true,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const force = args.force === true;
|
|
150
|
+
if (!force && packet.workspace.git) {
|
|
151
|
+
const current = await captureGitState(workspace);
|
|
152
|
+
if (current && current.dirty.length > 0) {
|
|
153
|
+
const report = await verifyWorkspace(workspace, packet.workspace.git);
|
|
154
|
+
if (!report.clean) {
|
|
155
|
+
return {
|
|
156
|
+
text: ["Workspace has uncommitted changes that diverge from the packet; restore would overwrite them. Pass force:true to proceed.", ...report.drift].join("\n"),
|
|
157
|
+
isError: true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const result = await restoreWorkspace(workspace, snapshotRef);
|
|
163
|
+
return { text: `Restored ${result.files.length} file(s) from ${snapshotRef}: ${result.files.slice(0, 20).join(", ")}${result.files.length > 20 ? ", …" : ""}` };
|
|
164
|
+
}
|
|
165
|
+
case "memento_status": {
|
|
166
|
+
const packet = requirePacket(workspace);
|
|
167
|
+
return { text: renderStatus(packet, verifySeal(packet)) };
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
throw new Error(`Unknown tool "${name}".`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function buildMcpServer() {
|
|
174
|
+
const server = new Server({ name: "memento", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
175
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
176
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
177
|
+
try {
|
|
178
|
+
const reply = await dispatch(request.params.name, (request.params.arguments ?? {}));
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: "text", text: reply.text }],
|
|
181
|
+
...(reply.isError ? { isError: true } : {}),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
return {
|
|
186
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
187
|
+
isError: true,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return server;
|
|
192
|
+
}
|
|
193
|
+
export async function runMcpServer() {
|
|
194
|
+
await buildMcpServer().connect(new StdioServerTransport());
|
|
195
|
+
// stdio transport keeps the process alive until the client disconnects.
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
package/dist/packet.d.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Continuation Packet v1 (spec §5.3) — the portable execution-state snapshot.
|
|
4
|
+
* This zod schema is the single source of truth: runtime validation AND the
|
|
5
|
+
* published JSON Schema artifact (schemas/packet.v1.schema.json) derive from it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PlanStep: z.ZodObject<{
|
|
8
|
+
n: z.ZodNumber;
|
|
9
|
+
desc: z.ZodString;
|
|
10
|
+
status: z.ZodEnum<{
|
|
11
|
+
done: "done";
|
|
12
|
+
in_progress: "in_progress";
|
|
13
|
+
pending: "pending";
|
|
14
|
+
}>;
|
|
15
|
+
note: z.ZodOptional<z.ZodString>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export declare const Decision: z.ZodObject<{
|
|
18
|
+
what: z.ZodString;
|
|
19
|
+
why: z.ZodString;
|
|
20
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
export declare const DirtyFile: z.ZodObject<{
|
|
23
|
+
path: z.ZodString;
|
|
24
|
+
state: z.ZodString;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export declare const GitState: z.ZodObject<{
|
|
27
|
+
remote: z.ZodNullable<z.ZodString>;
|
|
28
|
+
branch: z.ZodNullable<z.ZodString>;
|
|
29
|
+
headSha: z.ZodNullable<z.ZodString>;
|
|
30
|
+
snapshotRef: z.ZodNullable<z.ZodString>;
|
|
31
|
+
dirtyDigest: z.ZodString;
|
|
32
|
+
dirty: z.ZodArray<z.ZodObject<{
|
|
33
|
+
path: z.ZodString;
|
|
34
|
+
state: z.ZodString;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export declare const ToolOutcome: z.ZodObject<{
|
|
38
|
+
tool: z.ZodString;
|
|
39
|
+
target: z.ZodOptional<z.ZodString>;
|
|
40
|
+
outcome: z.ZodString;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export declare const InFlightTool: z.ZodObject<{
|
|
43
|
+
tool: z.ZodString;
|
|
44
|
+
target: z.ZodOptional<z.ZodString>;
|
|
45
|
+
intent: z.ZodOptional<z.ZodString>;
|
|
46
|
+
disposition: z.ZodString;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export declare const Approvals: z.ZodObject<{
|
|
49
|
+
granted_session: z.ZodArray<z.ZodString>;
|
|
50
|
+
pending: z.ZodArray<z.ZodString>;
|
|
51
|
+
denied: z.ZodArray<z.ZodObject<{
|
|
52
|
+
tool: z.ZodString;
|
|
53
|
+
target: z.ZodOptional<z.ZodString>;
|
|
54
|
+
note: z.ZodOptional<z.ZodString>;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
export declare const LastRun: z.ZodObject<{
|
|
58
|
+
cmd: z.ZodString;
|
|
59
|
+
result: z.ZodString;
|
|
60
|
+
at: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const PacketSchema: z.ZodObject<{
|
|
63
|
+
memento: z.ZodLiteral<"1.0">;
|
|
64
|
+
packet: z.ZodObject<{
|
|
65
|
+
id: z.ZodString;
|
|
66
|
+
taskId: z.ZodString;
|
|
67
|
+
workspaceId: z.ZodString;
|
|
68
|
+
scope: z.ZodEnum<{
|
|
69
|
+
personal: "personal";
|
|
70
|
+
workspace: "workspace";
|
|
71
|
+
team: "team";
|
|
72
|
+
org: "org";
|
|
73
|
+
}>;
|
|
74
|
+
createdAt: z.ZodString;
|
|
75
|
+
reason: z.ZodEnum<{
|
|
76
|
+
context_exhaustion: "context_exhaustion";
|
|
77
|
+
operator_switch: "operator_switch";
|
|
78
|
+
session_end: "session_end";
|
|
79
|
+
scheduled: "scheduled";
|
|
80
|
+
team_handoff: "team_handoff";
|
|
81
|
+
}>;
|
|
82
|
+
from: z.ZodObject<{
|
|
83
|
+
peer: z.ZodString;
|
|
84
|
+
agent: z.ZodString;
|
|
85
|
+
model: z.ZodOptional<z.ZodString>;
|
|
86
|
+
human: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, z.core.$strip>;
|
|
88
|
+
seq: z.ZodNumber;
|
|
89
|
+
parent: z.ZodNullable<z.ZodString>;
|
|
90
|
+
}, z.core.$strip>;
|
|
91
|
+
task: z.ZodObject<{
|
|
92
|
+
title: z.ZodString;
|
|
93
|
+
objective: z.ZodString;
|
|
94
|
+
constraints: z.ZodArray<z.ZodString>;
|
|
95
|
+
acceptance: z.ZodArray<z.ZodString>;
|
|
96
|
+
}, z.core.$strip>;
|
|
97
|
+
plan: z.ZodObject<{
|
|
98
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
99
|
+
n: z.ZodNumber;
|
|
100
|
+
desc: z.ZodString;
|
|
101
|
+
status: z.ZodEnum<{
|
|
102
|
+
done: "done";
|
|
103
|
+
in_progress: "in_progress";
|
|
104
|
+
pending: "pending";
|
|
105
|
+
}>;
|
|
106
|
+
note: z.ZodOptional<z.ZodString>;
|
|
107
|
+
}, z.core.$strip>>;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
decisions: z.ZodArray<z.ZodObject<{
|
|
110
|
+
what: z.ZodString;
|
|
111
|
+
why: z.ZodString;
|
|
112
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, z.core.$strip>>;
|
|
114
|
+
workspace: z.ZodObject<{
|
|
115
|
+
git: z.ZodOptional<z.ZodObject<{
|
|
116
|
+
remote: z.ZodNullable<z.ZodString>;
|
|
117
|
+
branch: z.ZodNullable<z.ZodString>;
|
|
118
|
+
headSha: z.ZodNullable<z.ZodString>;
|
|
119
|
+
snapshotRef: z.ZodNullable<z.ZodString>;
|
|
120
|
+
dirtyDigest: z.ZodString;
|
|
121
|
+
dirty: z.ZodArray<z.ZodObject<{
|
|
122
|
+
path: z.ZodString;
|
|
123
|
+
state: z.ZodString;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
commands: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
127
|
+
lastRun: z.ZodOptional<z.ZodObject<{
|
|
128
|
+
cmd: z.ZodString;
|
|
129
|
+
result: z.ZodString;
|
|
130
|
+
at: z.ZodOptional<z.ZodString>;
|
|
131
|
+
}, z.core.$strip>>;
|
|
132
|
+
}, z.core.$strip>;
|
|
133
|
+
toolState: z.ZodObject<{
|
|
134
|
+
completed: z.ZodArray<z.ZodObject<{
|
|
135
|
+
tool: z.ZodString;
|
|
136
|
+
target: z.ZodOptional<z.ZodString>;
|
|
137
|
+
outcome: z.ZodString;
|
|
138
|
+
}, z.core.$strip>>;
|
|
139
|
+
inFlight: z.ZodArray<z.ZodObject<{
|
|
140
|
+
tool: z.ZodString;
|
|
141
|
+
target: z.ZodOptional<z.ZodString>;
|
|
142
|
+
intent: z.ZodOptional<z.ZodString>;
|
|
143
|
+
disposition: z.ZodString;
|
|
144
|
+
}, z.core.$strip>>;
|
|
145
|
+
approvals: z.ZodObject<{
|
|
146
|
+
granted_session: z.ZodArray<z.ZodString>;
|
|
147
|
+
pending: z.ZodArray<z.ZodString>;
|
|
148
|
+
denied: z.ZodArray<z.ZodObject<{
|
|
149
|
+
tool: z.ZodString;
|
|
150
|
+
target: z.ZodOptional<z.ZodString>;
|
|
151
|
+
note: z.ZodOptional<z.ZodString>;
|
|
152
|
+
}, z.core.$strip>>;
|
|
153
|
+
}, z.core.$strip>;
|
|
154
|
+
}, z.core.$strip>;
|
|
155
|
+
memory: z.ZodObject<{
|
|
156
|
+
inline: z.ZodArray<z.ZodString>;
|
|
157
|
+
query: z.ZodOptional<z.ZodString>;
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
next: z.ZodArray<z.ZodString>;
|
|
160
|
+
warnings: z.ZodArray<z.ZodString>;
|
|
161
|
+
ledgerRef: z.ZodOptional<z.ZodString>;
|
|
162
|
+
fidelity: z.ZodEnum<{
|
|
163
|
+
narrative: "narrative";
|
|
164
|
+
structural: "structural";
|
|
165
|
+
native: "native";
|
|
166
|
+
}>;
|
|
167
|
+
redaction: z.ZodObject<{
|
|
168
|
+
applied: z.ZodBoolean;
|
|
169
|
+
rules: z.ZodArray<z.ZodString>;
|
|
170
|
+
count: z.ZodNumber;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
seal: z.ZodOptional<z.ZodObject<{
|
|
173
|
+
alg: z.ZodLiteral<"sha256">;
|
|
174
|
+
digest: z.ZodString;
|
|
175
|
+
sig: z.ZodNullable<z.ZodString>;
|
|
176
|
+
}, z.core.$strip>>;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
export type Packet = z.infer<typeof PacketSchema>;
|
|
179
|
+
export type PacketGitState = z.infer<typeof GitState>;
|
|
180
|
+
/** Stable stringify: objects serialized with sorted keys, recursively. */
|
|
181
|
+
export declare function canonicalStringify(value: unknown): string;
|
|
182
|
+
/** Seal = sha256 over the canonical JSON of everything except the seal itself. */
|
|
183
|
+
export declare function sealPacket(packet: Packet): Packet;
|
|
184
|
+
export declare function verifySeal(packet: Packet): boolean;
|
|
185
|
+
export declare function packetJsonSchema(): unknown;
|
package/dist/packet.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* Continuation Packet v1 (spec §5.3) — the portable execution-state snapshot.
|
|
5
|
+
* This zod schema is the single source of truth: runtime validation AND the
|
|
6
|
+
* published JSON Schema artifact (schemas/packet.v1.schema.json) derive from it.
|
|
7
|
+
*/
|
|
8
|
+
export const PlanStep = z.object({
|
|
9
|
+
n: z.number().int().positive(),
|
|
10
|
+
desc: z.string(),
|
|
11
|
+
status: z.enum(["done", "in_progress", "pending"]),
|
|
12
|
+
note: z.string().optional(),
|
|
13
|
+
});
|
|
14
|
+
export const Decision = z.object({
|
|
15
|
+
what: z.string(),
|
|
16
|
+
why: z.string(),
|
|
17
|
+
ref: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
export const DirtyFile = z.object({
|
|
20
|
+
path: z.string(),
|
|
21
|
+
state: z.string(),
|
|
22
|
+
});
|
|
23
|
+
export const GitState = z.object({
|
|
24
|
+
remote: z.string().nullable(),
|
|
25
|
+
branch: z.string().nullable(),
|
|
26
|
+
headSha: z.string().nullable(),
|
|
27
|
+
/** Shadow ref holding a snapshot of the FULL tree incl. uncommitted work. */
|
|
28
|
+
snapshotRef: z.string().nullable(),
|
|
29
|
+
/** sha256 of porcelain status + diff at capture time; drift detector input. */
|
|
30
|
+
dirtyDigest: z.string(),
|
|
31
|
+
dirty: z.array(DirtyFile),
|
|
32
|
+
});
|
|
33
|
+
export const ToolOutcome = z.object({
|
|
34
|
+
tool: z.string(),
|
|
35
|
+
target: z.string().optional(),
|
|
36
|
+
outcome: z.string(),
|
|
37
|
+
});
|
|
38
|
+
export const InFlightTool = z.object({
|
|
39
|
+
tool: z.string(),
|
|
40
|
+
target: z.string().optional(),
|
|
41
|
+
intent: z.string().optional(),
|
|
42
|
+
/** Always present: tells the receiver an in-flight call was NOT applied. */
|
|
43
|
+
disposition: z.string(),
|
|
44
|
+
});
|
|
45
|
+
export const Approvals = z.object({
|
|
46
|
+
granted_session: z.array(z.string()),
|
|
47
|
+
pending: z.array(z.string()),
|
|
48
|
+
denied: z.array(z.object({
|
|
49
|
+
tool: z.string(),
|
|
50
|
+
target: z.string().optional(),
|
|
51
|
+
note: z.string().optional(),
|
|
52
|
+
})),
|
|
53
|
+
});
|
|
54
|
+
export const LastRun = z.object({
|
|
55
|
+
cmd: z.string(),
|
|
56
|
+
result: z.string(),
|
|
57
|
+
at: z.string().optional(),
|
|
58
|
+
});
|
|
59
|
+
export const PacketSchema = z.object({
|
|
60
|
+
memento: z.literal("1.0"),
|
|
61
|
+
packet: z.object({
|
|
62
|
+
id: z.string(),
|
|
63
|
+
taskId: z.string(),
|
|
64
|
+
workspaceId: z.string(),
|
|
65
|
+
scope: z.enum(["personal", "workspace", "team", "org"]),
|
|
66
|
+
createdAt: z.string(),
|
|
67
|
+
reason: z.enum([
|
|
68
|
+
"context_exhaustion",
|
|
69
|
+
"operator_switch",
|
|
70
|
+
"session_end",
|
|
71
|
+
"scheduled",
|
|
72
|
+
"team_handoff",
|
|
73
|
+
]),
|
|
74
|
+
from: z.object({
|
|
75
|
+
peer: z.string(),
|
|
76
|
+
agent: z.string(),
|
|
77
|
+
model: z.string().optional(),
|
|
78
|
+
human: z.string().optional(),
|
|
79
|
+
}),
|
|
80
|
+
seq: z.number().int().nonnegative(),
|
|
81
|
+
parent: z.string().nullable(),
|
|
82
|
+
}),
|
|
83
|
+
task: z.object({
|
|
84
|
+
title: z.string(),
|
|
85
|
+
objective: z.string(),
|
|
86
|
+
constraints: z.array(z.string()),
|
|
87
|
+
acceptance: z.array(z.string()),
|
|
88
|
+
}),
|
|
89
|
+
plan: z.object({ steps: z.array(PlanStep) }),
|
|
90
|
+
decisions: z.array(Decision),
|
|
91
|
+
workspace: z.object({
|
|
92
|
+
git: GitState.optional(),
|
|
93
|
+
commands: z.record(z.string(), z.string()).optional(),
|
|
94
|
+
lastRun: LastRun.optional(),
|
|
95
|
+
}),
|
|
96
|
+
toolState: z.object({
|
|
97
|
+
completed: z.array(ToolOutcome),
|
|
98
|
+
inFlight: z.array(InFlightTool),
|
|
99
|
+
approvals: Approvals,
|
|
100
|
+
}),
|
|
101
|
+
memory: z.object({
|
|
102
|
+
inline: z.array(z.string()),
|
|
103
|
+
query: z.string().optional(),
|
|
104
|
+
}),
|
|
105
|
+
next: z.array(z.string()),
|
|
106
|
+
warnings: z.array(z.string()),
|
|
107
|
+
ledgerRef: z.string().optional(),
|
|
108
|
+
fidelity: z.enum(["narrative", "structural", "native"]),
|
|
109
|
+
redaction: z.object({
|
|
110
|
+
applied: z.boolean(),
|
|
111
|
+
rules: z.array(z.string()),
|
|
112
|
+
count: z.number().int().nonnegative(),
|
|
113
|
+
}),
|
|
114
|
+
seal: z.object({
|
|
115
|
+
alg: z.literal("sha256"),
|
|
116
|
+
digest: z.string(),
|
|
117
|
+
sig: z.string().nullable(),
|
|
118
|
+
}).optional(),
|
|
119
|
+
});
|
|
120
|
+
/** Stable stringify: objects serialized with sorted keys, recursively. */
|
|
121
|
+
export function canonicalStringify(value) {
|
|
122
|
+
return JSON.stringify(sortValue(value));
|
|
123
|
+
}
|
|
124
|
+
function sortValue(value) {
|
|
125
|
+
if (Array.isArray(value)) {
|
|
126
|
+
return value.map(sortValue);
|
|
127
|
+
}
|
|
128
|
+
if (value !== null && typeof value === "object") {
|
|
129
|
+
const sorted = {};
|
|
130
|
+
for (const key of Object.keys(value).sort()) {
|
|
131
|
+
sorted[key] = sortValue(value[key]);
|
|
132
|
+
}
|
|
133
|
+
return sorted;
|
|
134
|
+
}
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
/** Seal = sha256 over the canonical JSON of everything except the seal itself. */
|
|
138
|
+
export function sealPacket(packet) {
|
|
139
|
+
const { seal: _ignored, ...rest } = packet;
|
|
140
|
+
const digest = createHash("sha256").update(canonicalStringify(rest)).digest("hex");
|
|
141
|
+
return { ...packet, seal: { alg: "sha256", digest, sig: null } };
|
|
142
|
+
}
|
|
143
|
+
export function verifySeal(packet) {
|
|
144
|
+
if (!packet.seal) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
const { seal, ...rest } = packet;
|
|
148
|
+
const digest = createHash("sha256").update(canonicalStringify(rest)).digest("hex");
|
|
149
|
+
return digest === seal.digest;
|
|
150
|
+
}
|
|
151
|
+
export function packetJsonSchema() {
|
|
152
|
+
return z.toJSONSchema(PacketSchema);
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packet.js","sourceRoot":"","sources":["../src/packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB;;;;GAIG;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IAClD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,6EAA6E;IAC7E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,+EAA+E;IAC/E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,4EAA4E;IAC5E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9B,CAAC,CAAC;CACN,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;IACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACzB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;QACd,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACvD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;YACX,oBAAoB;YACpB,iBAAiB;YACjB,aAAa;YACb,WAAW;YACX,cAAc;SACjB,CAAC;QACF,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC/B,CAAC;QACF,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAChC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KAClC,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAC,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE;QACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACrD,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;KAC9B,CAAC;IACF,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QAC/B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;QAC/B,SAAS,EAAE,SAAS;KACvB,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC/B,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;QACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;KACxC,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACX,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC7B,CAAC,CAAC,QAAQ,EAAE;CAChB,CAAC,CAAC;AAKH,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACrE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,UAAU,CAAC,MAAc;IACrC,MAAM,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC,GAAG,MAAM,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnF,OAAO,EAAC,GAAG,MAAM,EAAE,IAAI,EAAE,EAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAC,EAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACrC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,EAAC,IAAI,EAAE,GAAG,IAAI,EAAC,GAAG,MAAM,CAAC;IAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnF,OAAO,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC5B,OAAO,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/redact.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction (spec §9.2). Runs over every narrative/outcome string
|
|
3
|
+
* before a packet is sealed. Secrets never travel: transcripts routinely
|
|
4
|
+
* contain pasted tokens and tool-echoed env values.
|
|
5
|
+
*/
|
|
6
|
+
export interface RedactionResult {
|
|
7
|
+
text: string;
|
|
8
|
+
count: number;
|
|
9
|
+
rulesHit: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function redactText(text: string): RedactionResult;
|
|
12
|
+
export interface DeepRedactionResult<T> {
|
|
13
|
+
value: T;
|
|
14
|
+
count: number;
|
|
15
|
+
rulesHit: string[];
|
|
16
|
+
}
|
|
17
|
+
/** Walk any JSON-ish value and redact every string in place (copy-on-write). */
|
|
18
|
+
export declare function redactDeep<T>(value: T): DeepRedactionResult<T>;
|
|
19
|
+
export declare const REDACTION_RULE_IDS: string[];
|
package/dist/redact.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction (spec §9.2). Runs over every narrative/outcome string
|
|
3
|
+
* before a packet is sealed. Secrets never travel: transcripts routinely
|
|
4
|
+
* contain pasted tokens and tool-echoed env values.
|
|
5
|
+
*/
|
|
6
|
+
const RULES = [
|
|
7
|
+
{
|
|
8
|
+
id: "pem",
|
|
9
|
+
pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
10
|
+
replace: () => "[REDACTED:pem]",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "aws-key",
|
|
14
|
+
pattern: /\b(AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
15
|
+
replace: () => "[REDACTED:aws-key]",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "github-token",
|
|
19
|
+
pattern: /\bgh[pousr]_[A-Za-z0-9]{20,255}\b/g,
|
|
20
|
+
replace: () => "[REDACTED:github-token]",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "slack-token",
|
|
24
|
+
pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
|
|
25
|
+
replace: () => "[REDACTED:slack-token]",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "jwt",
|
|
29
|
+
pattern: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\b/g,
|
|
30
|
+
replace: () => "[REDACTED:jwt]",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "bearer",
|
|
34
|
+
pattern: /\b[Bb]earer\s+[A-Za-z0-9._~+/=-]{20,}/g,
|
|
35
|
+
replace: () => "Bearer [REDACTED:bearer]",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "assignment",
|
|
39
|
+
// KEY=value / SECRET: "value" style assignments; keeps the name,
|
|
40
|
+
// redacts the value. Requires a secret-ish name to avoid false hits.
|
|
41
|
+
pattern: /\b([A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL)[A-Za-z0-9_]*)\s*[=:]\s*['"]?([^\s'"]{8,})['"]?/g,
|
|
42
|
+
replace: (match) => `${match[1]}=[REDACTED:assignment]`,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
export function redactText(text) {
|
|
46
|
+
let out = text;
|
|
47
|
+
let count = 0;
|
|
48
|
+
const rulesHit = new Set();
|
|
49
|
+
for (const rule of RULES) {
|
|
50
|
+
out = out.replace(rule.pattern, (...args) => {
|
|
51
|
+
count += 1;
|
|
52
|
+
rulesHit.add(rule.id);
|
|
53
|
+
// Rebuild an exec-style array for the replace callback.
|
|
54
|
+
const match = args.slice(0, -2);
|
|
55
|
+
return rule.replace(match);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return { text: out, count, rulesHit: [...rulesHit] };
|
|
59
|
+
}
|
|
60
|
+
/** Walk any JSON-ish value and redact every string in place (copy-on-write). */
|
|
61
|
+
export function redactDeep(value) {
|
|
62
|
+
let count = 0;
|
|
63
|
+
const rulesHit = new Set();
|
|
64
|
+
const walk = (node) => {
|
|
65
|
+
if (typeof node === "string") {
|
|
66
|
+
const result = redactText(node);
|
|
67
|
+
count += result.count;
|
|
68
|
+
result.rulesHit.forEach((rule) => rulesHit.add(rule));
|
|
69
|
+
return result.text;
|
|
70
|
+
}
|
|
71
|
+
if (Array.isArray(node)) {
|
|
72
|
+
return node.map(walk);
|
|
73
|
+
}
|
|
74
|
+
if (node !== null && typeof node === "object") {
|
|
75
|
+
const out = {};
|
|
76
|
+
for (const [key, val] of Object.entries(node)) {
|
|
77
|
+
out[key] = walk(val);
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
return node;
|
|
82
|
+
};
|
|
83
|
+
return { value: walk(value), count, rulesHit: [...rulesHit] };
|
|
84
|
+
}
|
|
85
|
+
export const REDACTION_RULE_IDS = RULES.map((rule) => rule.id);
|
|
86
|
+
//# sourceMappingURL=redact.js.map
|