@nifrajs/coding-agent 3.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/EXTENSIONS.md +25 -0
- package/PERFORMANCE.md +19 -0
- package/README.md +69 -0
- package/REGISTRY.md +15 -0
- package/SECURITY.md +32 -0
- package/dist/approvals.d.ts +70 -0
- package/dist/approvals.d.ts.map +1 -0
- package/dist/approvals.js +174 -0
- package/dist/approvals.js.map +1 -0
- package/dist/capabilities.d.ts +20 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +49 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +380 -0
- package/dist/cli.js.map +1 -0
- package/dist/context.d.ts +17 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +66 -0
- package/dist/context.js.map +1 -0
- package/dist/deployment-adapters.d.ts +40 -0
- package/dist/deployment-adapters.d.ts.map +1 -0
- package/dist/deployment-adapters.js +147 -0
- package/dist/deployment-adapters.js.map +1 -0
- package/dist/diff.d.ts +17 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +61 -0
- package/dist/diff.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +35 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensions.d.ts +104 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +284 -0
- package/dist/extensions.js.map +1 -0
- package/dist/handoffs.d.ts +97 -0
- package/dist/handoffs.d.ts.map +1 -0
- package/dist/handoffs.js +199 -0
- package/dist/handoffs.js.map +1 -0
- package/dist/healing.d.ts +56 -0
- package/dist/healing.d.ts.map +1 -0
- package/dist/healing.js +54 -0
- package/dist/healing.js.map +1 -0
- package/dist/host.d.ts +61 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +369 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/isolated-worker.d.ts +2 -0
- package/dist/isolated-worker.d.ts.map +1 -0
- package/dist/isolated-worker.js +155 -0
- package/dist/isolated-worker.js.map +1 -0
- package/dist/isolated.d.ts +52 -0
- package/dist/isolated.d.ts.map +1 -0
- package/dist/isolated.js +293 -0
- package/dist/isolated.js.map +1 -0
- package/dist/native.d.ts +92 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +339 -0
- package/dist/native.js.map +1 -0
- package/dist/orchestration/artifact-port.d.ts +30 -0
- package/dist/orchestration/artifact-port.d.ts.map +1 -0
- package/dist/orchestration/artifact-port.js +59 -0
- package/dist/orchestration/artifact-port.js.map +1 -0
- package/dist/orchestration/catalog.d.ts +71 -0
- package/dist/orchestration/catalog.d.ts.map +1 -0
- package/dist/orchestration/catalog.js +46 -0
- package/dist/orchestration/catalog.js.map +1 -0
- package/dist/orchestration/compile.d.ts +59 -0
- package/dist/orchestration/compile.d.ts.map +1 -0
- package/dist/orchestration/compile.js +268 -0
- package/dist/orchestration/compile.js.map +1 -0
- package/dist/orchestration/dispatch.d.ts +115 -0
- package/dist/orchestration/dispatch.d.ts.map +1 -0
- package/dist/orchestration/dispatch.js +220 -0
- package/dist/orchestration/dispatch.js.map +1 -0
- package/dist/orchestration/durable-jobs.d.ts +35 -0
- package/dist/orchestration/durable-jobs.d.ts.map +1 -0
- package/dist/orchestration/durable-jobs.js +273 -0
- package/dist/orchestration/durable-jobs.js.map +1 -0
- package/dist/orchestration/effect-key.d.ts +23 -0
- package/dist/orchestration/effect-key.d.ts.map +1 -0
- package/dist/orchestration/effect-key.js +24 -0
- package/dist/orchestration/effect-key.js.map +1 -0
- package/dist/orchestration/evidence-store.d.ts +75 -0
- package/dist/orchestration/evidence-store.d.ts.map +1 -0
- package/dist/orchestration/evidence-store.js +183 -0
- package/dist/orchestration/evidence-store.js.map +1 -0
- package/dist/orchestration/hash.d.ts +12 -0
- package/dist/orchestration/hash.d.ts.map +1 -0
- package/dist/orchestration/hash.js +43 -0
- package/dist/orchestration/hash.js.map +1 -0
- package/dist/orchestration/host.d.ts +121 -0
- package/dist/orchestration/host.d.ts.map +1 -0
- package/dist/orchestration/host.js +334 -0
- package/dist/orchestration/host.js.map +1 -0
- package/dist/orchestration/index.d.ts +20 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +19 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/policy.d.ts +63 -0
- package/dist/orchestration/policy.d.ts.map +1 -0
- package/dist/orchestration/policy.js +80 -0
- package/dist/orchestration/policy.js.map +1 -0
- package/dist/orchestration/recovery.d.ts +87 -0
- package/dist/orchestration/recovery.d.ts.map +1 -0
- package/dist/orchestration/recovery.js +197 -0
- package/dist/orchestration/recovery.js.map +1 -0
- package/dist/orchestration/tracer.d.ts +31 -0
- package/dist/orchestration/tracer.d.ts.map +1 -0
- package/dist/orchestration/tracer.js +141 -0
- package/dist/orchestration/tracer.js.map +1 -0
- package/dist/plans.d.ts +35 -0
- package/dist/plans.d.ts.map +1 -0
- package/dist/plans.js +63 -0
- package/dist/plans.js.map +1 -0
- package/dist/presets.d.ts +10 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +70 -0
- package/dist/presets.js.map +1 -0
- package/dist/process.d.ts +6 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +42 -0
- package/dist/process.js.map +1 -0
- package/dist/registry.d.ts +37 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +51 -0
- package/dist/registry.js.map +1 -0
- package/dist/replay.d.ts +24 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +154 -0
- package/dist/replay.js.map +1 -0
- package/dist/rpc.d.ts +51 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +412 -0
- package/dist/rpc.js.map +1 -0
- package/dist/session-migration.d.ts +59 -0
- package/dist/session-migration.d.ts.map +1 -0
- package/dist/session-migration.js +315 -0
- package/dist/session-migration.js.map +1 -0
- package/dist/sessions.d.ts +74 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +222 -0
- package/dist/sessions.js.map +1 -0
- package/dist/subagents.d.ts +51 -0
- package/dist/subagents.d.ts.map +1 -0
- package/dist/subagents.js +141 -0
- package/dist/subagents.js.map +1 -0
- package/dist/tools.d.ts +13 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +37 -0
- package/dist/tools.js.map +1 -0
- package/dist/ui.d.ts +42 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +93 -0
- package/dist/ui.js.map +1 -0
- package/dist/verification.d.ts +34 -0
- package/dist/verification.d.ts.map +1 -0
- package/dist/verification.js +91 -0
- package/dist/verification.js.map +1 -0
- package/dist/workflows.d.ts +98 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +174 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +84 -0
- package/src/approvals.ts +249 -0
- package/src/capabilities.ts +74 -0
- package/src/cli.ts +405 -0
- package/src/context.ts +81 -0
- package/src/deployment-adapters.ts +181 -0
- package/src/diff.ts +80 -0
- package/src/errors.ts +46 -0
- package/src/extensions.ts +402 -0
- package/src/handoffs.ts +299 -0
- package/src/healing.ts +93 -0
- package/src/host.ts +465 -0
- package/src/index.ts +165 -0
- package/src/isolated-worker.ts +177 -0
- package/src/isolated.ts +344 -0
- package/src/native.ts +478 -0
- package/src/orchestration/artifact-port.ts +75 -0
- package/src/orchestration/catalog.ts +102 -0
- package/src/orchestration/compile.ts +373 -0
- package/src/orchestration/dispatch.ts +383 -0
- package/src/orchestration/durable-jobs.ts +374 -0
- package/src/orchestration/effect-key.ts +35 -0
- package/src/orchestration/evidence-store.ts +233 -0
- package/src/orchestration/hash.ts +43 -0
- package/src/orchestration/host.ts +445 -0
- package/src/orchestration/index.ts +131 -0
- package/src/orchestration/policy.ts +116 -0
- package/src/orchestration/recovery.ts +271 -0
- package/src/orchestration/tracer.ts +177 -0
- package/src/plans.ts +105 -0
- package/src/presets.ts +90 -0
- package/src/process.ts +47 -0
- package/src/registry.ts +80 -0
- package/src/replay.ts +190 -0
- package/src/rpc.ts +598 -0
- package/src/session-migration.ts +401 -0
- package/src/sessions.ts +303 -0
- package/src/subagents.ts +210 -0
- package/src/tools.ts +52 -0
- package/src/ui.ts +137 -0
- package/src/verification.ts +133 -0
- package/src/workflows.ts +279 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { access, mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, join, resolve } from "node:path";
|
|
3
|
+
/** Version of the evidence-only legacy session file format. */
|
|
4
|
+
export const SESSION_EVIDENCE_VERSION = 1;
|
|
5
|
+
const HEX64 = /^[0-9a-f]{64}$/;
|
|
6
|
+
const SESSION_TOKEN = /^[a-zA-Z0-9._:-]{1,128}$/;
|
|
7
|
+
const EVENT_TYPE = /^[a-z][a-z0-9._:-]{0,63}$/;
|
|
8
|
+
const MAX_SOURCE_BYTES = 64 * 1024 * 1024;
|
|
9
|
+
export class SessionMigrationError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(code, message) {
|
|
12
|
+
super(`session migration [${code}]: ${message}`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.name = "SessionMigrationError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Convert a legacy event type into a stable, content-free evidence code.
|
|
19
|
+
* Unknown event names are intentionally not copied to the target: their SHA-256 prefix gives a
|
|
20
|
+
* repeatable grouping key without disclosing an arbitrary source string.
|
|
21
|
+
*/
|
|
22
|
+
export async function stableSessionEventCode(type) {
|
|
23
|
+
if (KNOWN_EVENT_CODES.has(type))
|
|
24
|
+
return { code: type, replaced: false };
|
|
25
|
+
const digest = await sha256Hex(type);
|
|
26
|
+
return { code: `legacy.unknown.${digest.slice(0, 16)}`, replaced: true };
|
|
27
|
+
}
|
|
28
|
+
/** Parse one evidence record strictly. Payload-bearing or unknown fields are rejected. */
|
|
29
|
+
export function parseSessionEvidenceRecord(value) {
|
|
30
|
+
if (!isRecord(value))
|
|
31
|
+
throw new SessionMigrationError("invalid_record", "record must be an object");
|
|
32
|
+
const allowed = ["version", "sessionId", "seq", "at", "code", "count", "digest", "pinned"];
|
|
33
|
+
for (const key of Object.keys(value))
|
|
34
|
+
if (!allowed.includes(key))
|
|
35
|
+
throw new SessionMigrationError("invalid_record", `unknown evidence field '${key}'`);
|
|
36
|
+
if (value.version !== SESSION_EVIDENCE_VERSION)
|
|
37
|
+
throw new SessionMigrationError("invalid_record", "unsupported evidence version");
|
|
38
|
+
const sessionId = requiredToken(value.sessionId, "sessionId");
|
|
39
|
+
const seq = nonNegativeInteger(value.seq, "seq");
|
|
40
|
+
const at = nonNegativeInteger(value.at, "at");
|
|
41
|
+
const code = requiredCode(value.code);
|
|
42
|
+
if (value.count !== 1)
|
|
43
|
+
throw new SessionMigrationError("invalid_record", "count must be 1");
|
|
44
|
+
const digest = value.digest;
|
|
45
|
+
if (typeof digest !== "string" || !HEX64.test(digest))
|
|
46
|
+
throw new SessionMigrationError("invalid_record", "digest must be sha256 hex");
|
|
47
|
+
if (value.pinned !== undefined && typeof value.pinned !== "boolean")
|
|
48
|
+
throw new SessionMigrationError("invalid_record", "pinned must be boolean");
|
|
49
|
+
return {
|
|
50
|
+
version: SESSION_EVIDENCE_VERSION,
|
|
51
|
+
sessionId,
|
|
52
|
+
seq,
|
|
53
|
+
at,
|
|
54
|
+
code,
|
|
55
|
+
count: 1,
|
|
56
|
+
digest,
|
|
57
|
+
...(value.pinned === true ? { pinned: true } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Read, project, validate, and atomically commit one legacy local session. */
|
|
61
|
+
export async function migrateLegacySession(options) {
|
|
62
|
+
assertNotAborted(options.signal);
|
|
63
|
+
const sourceRoot = resolve(options.sourceRoot);
|
|
64
|
+
const targetRoot = resolve(options.targetRoot);
|
|
65
|
+
const sessionId = validateSessionId(options.sessionId);
|
|
66
|
+
const maxSourceBytes = options.maxSourceBytes ?? MAX_SOURCE_BYTES;
|
|
67
|
+
if (!Number.isSafeInteger(maxSourceBytes) || maxSourceBytes < 1)
|
|
68
|
+
throw new SessionMigrationError("invalid_options", "maxSourceBytes must be positive");
|
|
69
|
+
if (sourceRoot === targetRoot ||
|
|
70
|
+
isWithin(sourceRoot, targetRoot) ||
|
|
71
|
+
isWithin(targetRoot, sourceRoot))
|
|
72
|
+
throw new SessionMigrationError("overlapping_roots", "sourceRoot and targetRoot must be separate directories");
|
|
73
|
+
const sourceEntries = await readLegacyEntries(sourceRoot, sessionId, maxSourceBytes);
|
|
74
|
+
const records = [];
|
|
75
|
+
const counts = Object.create(null);
|
|
76
|
+
const skippedByCode = Object.create(null);
|
|
77
|
+
let previousSeq = -1;
|
|
78
|
+
for (const entry of sourceEntries) {
|
|
79
|
+
assertNotAborted(options.signal);
|
|
80
|
+
if (entry.seq <= previousSeq)
|
|
81
|
+
throw new SessionMigrationError("invalid_source", "legacy sequence must increase strictly");
|
|
82
|
+
previousSeq = entry.seq;
|
|
83
|
+
const mapped = await stableSessionEventCode(entry.type);
|
|
84
|
+
const base = {
|
|
85
|
+
version: SESSION_EVIDENCE_VERSION,
|
|
86
|
+
sessionId,
|
|
87
|
+
seq: entry.seq,
|
|
88
|
+
at: entry.at,
|
|
89
|
+
code: mapped.code,
|
|
90
|
+
count: 1,
|
|
91
|
+
...(entry.pinned === true ? { pinned: true } : {}),
|
|
92
|
+
};
|
|
93
|
+
const record = {
|
|
94
|
+
...base,
|
|
95
|
+
digest: await sha256Hex(JSON.stringify(base)),
|
|
96
|
+
};
|
|
97
|
+
parseSessionEvidenceRecord(record);
|
|
98
|
+
records.push(Object.freeze(record));
|
|
99
|
+
counts[mapped.code] = (counts[mapped.code] ?? 0) + 1;
|
|
100
|
+
if (mapped.replaced)
|
|
101
|
+
skippedByCode[mapped.code] = (skippedByCode[mapped.code] ?? 0) + 1;
|
|
102
|
+
}
|
|
103
|
+
const lines = records.map((record) => JSON.stringify(record));
|
|
104
|
+
const content = lines.length === 0 ? "" : `${lines.join("\n")}\n`;
|
|
105
|
+
const digest = await sha256Hex(content);
|
|
106
|
+
const targetFile = join(targetRoot, `${sessionId}.jsonl`);
|
|
107
|
+
await commitTarget(targetRoot, targetFile, content, options.signal);
|
|
108
|
+
// Re-read the committed target and validate every line before the caller treats this as active.
|
|
109
|
+
const committed = await readEvidenceTarget(targetFile, sessionId);
|
|
110
|
+
if (committed.records.length !== records.length || (await sha256Hex(committed.raw)) !== digest)
|
|
111
|
+
throw new SessionMigrationError("target_validation", "committed evidence target changed");
|
|
112
|
+
for (let index = 0; index < committed.records.length; index++) {
|
|
113
|
+
const actual = committed.records[index];
|
|
114
|
+
const expected = records[index];
|
|
115
|
+
if (canonicalRecord(actual) !== canonicalRecord(expected))
|
|
116
|
+
throw new SessionMigrationError("target_validation", "committed evidence record differs");
|
|
117
|
+
}
|
|
118
|
+
const report = {
|
|
119
|
+
version: SESSION_EVIDENCE_VERSION,
|
|
120
|
+
sessionId,
|
|
121
|
+
records: records.length,
|
|
122
|
+
skipped: Object.values(skippedByCode).reduce((sum, value) => sum + value, 0),
|
|
123
|
+
skippedByCode: Object.freeze({ ...skippedByCode }),
|
|
124
|
+
counts: Object.freeze({ ...counts }),
|
|
125
|
+
...(records[0] === undefined ? {} : { firstSeq: records[0].seq }),
|
|
126
|
+
...(records.at(-1) === undefined ? {} : { lastSeq: records.at(-1).seq }),
|
|
127
|
+
digest,
|
|
128
|
+
};
|
|
129
|
+
return Object.freeze(report);
|
|
130
|
+
}
|
|
131
|
+
const KNOWN_EVENT_CODES = new Set([
|
|
132
|
+
"session.started",
|
|
133
|
+
"session.updated",
|
|
134
|
+
"turn.started",
|
|
135
|
+
"assistant.delta",
|
|
136
|
+
"assistant.message",
|
|
137
|
+
"tool.started",
|
|
138
|
+
"tool.delta",
|
|
139
|
+
"tool.completed",
|
|
140
|
+
"approval.required",
|
|
141
|
+
"approval.resolved",
|
|
142
|
+
"repair.required",
|
|
143
|
+
"verification.completed",
|
|
144
|
+
"memory.compacted",
|
|
145
|
+
"extension.reloaded",
|
|
146
|
+
"session.completed",
|
|
147
|
+
"session.failed",
|
|
148
|
+
"session.stopped",
|
|
149
|
+
"session.checkpoint",
|
|
150
|
+
"session.forked",
|
|
151
|
+
]);
|
|
152
|
+
async function readLegacyEntries(sourceRoot, sessionId, maxSourceBytes) {
|
|
153
|
+
const path = join(sourceRoot, `${sessionId}.jsonl`);
|
|
154
|
+
let text;
|
|
155
|
+
try {
|
|
156
|
+
const bytes = await readFile(path);
|
|
157
|
+
if (bytes.byteLength > maxSourceBytes)
|
|
158
|
+
throw new SessionMigrationError("source_too_large", "legacy session exceeds maxSourceBytes");
|
|
159
|
+
text = bytes.toString("utf8");
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
if (isNotFound(error))
|
|
163
|
+
return Object.freeze([]);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
const entries = [];
|
|
167
|
+
const lines = text.split("\n");
|
|
168
|
+
for (let index = 0; index < lines.length; index++) {
|
|
169
|
+
const line = lines[index];
|
|
170
|
+
if (line.trim().length === 0)
|
|
171
|
+
continue;
|
|
172
|
+
let value;
|
|
173
|
+
try {
|
|
174
|
+
value = JSON.parse(line);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
throw new SessionMigrationError("invalid_source", `legacy line ${index + 1} is not JSON`);
|
|
178
|
+
}
|
|
179
|
+
if (!isRecord(value))
|
|
180
|
+
throw new SessionMigrationError("invalid_source", `legacy line ${index + 1} is not an object`);
|
|
181
|
+
if (value.version !== 1 || value.sessionId !== sessionId)
|
|
182
|
+
throw new SessionMigrationError("invalid_source", `legacy line ${index + 1} has invalid identity`);
|
|
183
|
+
const seq = nonNegativeInteger(value.seq, `legacy line ${index + 1}.seq`);
|
|
184
|
+
const at = nonNegativeInteger(value.at, `legacy line ${index + 1}.at`);
|
|
185
|
+
if (typeof value.type !== "string" || !EVENT_TYPE.test(value.type))
|
|
186
|
+
throw new SessionMigrationError("invalid_source", `legacy line ${index + 1} has invalid type`);
|
|
187
|
+
if (value.pinned !== undefined && typeof value.pinned !== "boolean")
|
|
188
|
+
throw new SessionMigrationError("invalid_source", `legacy line ${index + 1} has invalid pinned flag`);
|
|
189
|
+
entries.push({
|
|
190
|
+
sessionId,
|
|
191
|
+
seq,
|
|
192
|
+
at,
|
|
193
|
+
type: value.type,
|
|
194
|
+
...(value.pinned === true ? { pinned: true } : {}),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return Object.freeze(entries);
|
|
198
|
+
}
|
|
199
|
+
async function commitTarget(targetRoot, targetFile, content, signal) {
|
|
200
|
+
await mkdir(targetRoot, { recursive: true, mode: 0o700 });
|
|
201
|
+
try {
|
|
202
|
+
await access(targetFile);
|
|
203
|
+
throw new SessionMigrationError("target_exists", "migration target already exists");
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (!(error instanceof SessionMigrationError) && !isNotFound(error))
|
|
207
|
+
throw error;
|
|
208
|
+
if (error instanceof SessionMigrationError)
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
assertNotAborted(signal);
|
|
212
|
+
const temporary = join(targetRoot, `.${basename(targetFile)}.${process.pid}.${randomToken()}.tmp`);
|
|
213
|
+
try {
|
|
214
|
+
await writeFile(temporary, content, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
215
|
+
assertNotAborted(signal);
|
|
216
|
+
// The target is created only after the complete temporary file exists. A pre-existing target
|
|
217
|
+
// was rejected above; callers must treat a concurrent target race as a failed migration.
|
|
218
|
+
try {
|
|
219
|
+
await access(targetFile);
|
|
220
|
+
throw new SessionMigrationError("target_exists", "migration target appeared during migration");
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
if (error instanceof SessionMigrationError)
|
|
224
|
+
throw error;
|
|
225
|
+
if (!isNotFound(error))
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
await rename(temporary, targetFile);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
await unlink(temporary).catch(() => undefined);
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function readEvidenceTarget(path, sessionId) {
|
|
236
|
+
const raw = await readFile(path, "utf8");
|
|
237
|
+
const records = [];
|
|
238
|
+
let previousSeq = -1;
|
|
239
|
+
for (const line of raw.split("\n")) {
|
|
240
|
+
if (line.trim().length === 0)
|
|
241
|
+
continue;
|
|
242
|
+
const record = parseSessionEvidenceRecord(JSON.parse(line));
|
|
243
|
+
if (record.sessionId !== sessionId || record.seq <= previousSeq)
|
|
244
|
+
throw new SessionMigrationError("target_validation", "target identity or order is invalid");
|
|
245
|
+
const base = {
|
|
246
|
+
version: record.version,
|
|
247
|
+
sessionId: record.sessionId,
|
|
248
|
+
seq: record.seq,
|
|
249
|
+
at: record.at,
|
|
250
|
+
code: record.code,
|
|
251
|
+
count: record.count,
|
|
252
|
+
...(record.pinned === true ? { pinned: true } : {}),
|
|
253
|
+
};
|
|
254
|
+
if ((await sha256Hex(JSON.stringify(base))) !== record.digest)
|
|
255
|
+
throw new SessionMigrationError("target_validation", "target record digest is invalid");
|
|
256
|
+
previousSeq = record.seq;
|
|
257
|
+
records.push(record);
|
|
258
|
+
}
|
|
259
|
+
return { records: Object.freeze(records), raw };
|
|
260
|
+
}
|
|
261
|
+
function validateSessionId(value) {
|
|
262
|
+
if (!SESSION_TOKEN.test(value))
|
|
263
|
+
throw new SessionMigrationError("invalid_options", "invalid sessionId");
|
|
264
|
+
return value;
|
|
265
|
+
}
|
|
266
|
+
function requiredToken(value, name) {
|
|
267
|
+
if (typeof value !== "string" || !SESSION_TOKEN.test(value))
|
|
268
|
+
throw new SessionMigrationError("invalid_record", `${name} must be a bounded token`);
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
function requiredCode(value) {
|
|
272
|
+
if (typeof value !== "string" ||
|
|
273
|
+
(!/^legacy\.[a-z0-9.-]+$/.test(value) && !KNOWN_EVENT_CODES.has(value)))
|
|
274
|
+
throw new SessionMigrationError("invalid_record", "code is invalid");
|
|
275
|
+
return value;
|
|
276
|
+
}
|
|
277
|
+
function nonNegativeInteger(value, name) {
|
|
278
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
279
|
+
throw new SessionMigrationError("invalid_record", `${name} must be a non-negative integer`);
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
282
|
+
function isRecord(value) {
|
|
283
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
284
|
+
}
|
|
285
|
+
function isNotFound(error) {
|
|
286
|
+
return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
|
|
287
|
+
}
|
|
288
|
+
function isWithin(parent, child) {
|
|
289
|
+
const prefix = parent.endsWith("/") ? parent : `${parent}/`;
|
|
290
|
+
return child.startsWith(prefix);
|
|
291
|
+
}
|
|
292
|
+
function assertNotAborted(signal) {
|
|
293
|
+
if (signal?.aborted)
|
|
294
|
+
throw new SessionMigrationError("aborted", "migration was interrupted");
|
|
295
|
+
}
|
|
296
|
+
function randomToken() {
|
|
297
|
+
return crypto.randomUUID().replaceAll("-", "");
|
|
298
|
+
}
|
|
299
|
+
async function sha256Hex(value) {
|
|
300
|
+
const hash = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
|
|
301
|
+
return [...new Uint8Array(hash)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
302
|
+
}
|
|
303
|
+
function canonicalRecord(record) {
|
|
304
|
+
return JSON.stringify({
|
|
305
|
+
version: record.version,
|
|
306
|
+
sessionId: record.sessionId,
|
|
307
|
+
seq: record.seq,
|
|
308
|
+
at: record.at,
|
|
309
|
+
code: record.code,
|
|
310
|
+
count: record.count,
|
|
311
|
+
...(record.pinned === true ? { pinned: true } : {}),
|
|
312
|
+
digest: record.digest,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=session-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-migration.js","sourceRoot":"","sources":["../src/session-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface SessionLogEntry {
|
|
2
|
+
readonly version: 1;
|
|
3
|
+
readonly sessionId: string;
|
|
4
|
+
readonly seq: number;
|
|
5
|
+
readonly at: number;
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly payload?: unknown;
|
|
8
|
+
readonly pinned?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface SessionStore {
|
|
11
|
+
append(sessionId: string, type: string, payload?: unknown, options?: {
|
|
12
|
+
readonly pinned?: boolean;
|
|
13
|
+
}): Promise<SessionLogEntry>;
|
|
14
|
+
read(sessionId: string): Promise<readonly SessionLogEntry[]>;
|
|
15
|
+
checkpoint(sessionId: string, payload: unknown): Promise<void>;
|
|
16
|
+
fork(sessionId: string, targetSessionId?: string): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
export interface FileSessionStoreOptions {
|
|
19
|
+
readonly root: string;
|
|
20
|
+
readonly maxEntryBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Small append-only JSONL store. It stores redacted, bounded event evidence rather than raw model
|
|
24
|
+
* transcripts, so session recovery is useful without turning the agent into a memory sink.
|
|
25
|
+
*/
|
|
26
|
+
export declare class FileSessionStore implements SessionStore {
|
|
27
|
+
private readonly root;
|
|
28
|
+
private readonly maxEntryBytes;
|
|
29
|
+
private readonly sequences;
|
|
30
|
+
constructor(options: FileSessionStoreOptions);
|
|
31
|
+
append(sessionId: string, type: string, payload?: unknown, options?: {
|
|
32
|
+
readonly pinned?: boolean;
|
|
33
|
+
}): Promise<SessionLogEntry>;
|
|
34
|
+
read(sessionId: string): Promise<readonly SessionLogEntry[]>;
|
|
35
|
+
checkpoint(sessionId: string, payload: unknown): Promise<void>;
|
|
36
|
+
fork(sessionId: string, targetSessionId?: string): Promise<string>;
|
|
37
|
+
private pathFor;
|
|
38
|
+
private nextSequence;
|
|
39
|
+
}
|
|
40
|
+
export interface ContextRecord {
|
|
41
|
+
readonly kind: string;
|
|
42
|
+
readonly content: string;
|
|
43
|
+
readonly pinned?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface CompactionReport {
|
|
46
|
+
readonly before: number;
|
|
47
|
+
readonly after: number;
|
|
48
|
+
readonly removed: number;
|
|
49
|
+
readonly reason: "manual" | "threshold" | "overflow" | "workflow";
|
|
50
|
+
}
|
|
51
|
+
export interface ContextWindowOptions {
|
|
52
|
+
readonly maxTokens?: number;
|
|
53
|
+
readonly keepRecent?: number;
|
|
54
|
+
readonly maxSummaryChars?: number;
|
|
55
|
+
/** Optional extension-owned summary function. It cannot alter authoritative records. */
|
|
56
|
+
readonly summarize?: (records: readonly ContextRecord[], maxChars: number) => string;
|
|
57
|
+
}
|
|
58
|
+
/** In-memory prompt window with automatic, deterministic compaction and a hard size ceiling. */
|
|
59
|
+
export declare class ContextWindow {
|
|
60
|
+
private readonly maxTokens;
|
|
61
|
+
private readonly keepRecent;
|
|
62
|
+
private readonly maxSummaryChars;
|
|
63
|
+
private readonly summarizeRecord;
|
|
64
|
+
private records;
|
|
65
|
+
constructor(options?: ContextWindowOptions);
|
|
66
|
+
get tokens(): number;
|
|
67
|
+
get size(): number;
|
|
68
|
+
snapshot(): readonly ContextRecord[];
|
|
69
|
+
/** Restore bounded prompt context from persisted evidence without bypassing compaction rules. */
|
|
70
|
+
restore(records: readonly ContextRecord[]): void;
|
|
71
|
+
append(record: ContextRecord): CompactionReport | undefined;
|
|
72
|
+
compact(reason?: CompactionReport["reason"]): CompactionReport;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/sessions.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Small append-only JSONL store. It stores redacted, bounded event evidence rather than raw model
|
|
5
|
+
* transcripts, so session recovery is useful without turning the agent into a memory sink.
|
|
6
|
+
*/
|
|
7
|
+
export class FileSessionStore {
|
|
8
|
+
root;
|
|
9
|
+
maxEntryBytes;
|
|
10
|
+
sequences = new Map();
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.root = options.root;
|
|
13
|
+
this.maxEntryBytes = options.maxEntryBytes ?? 256 * 1024;
|
|
14
|
+
if (!Number.isSafeInteger(this.maxEntryBytes) || this.maxEntryBytes < 1024)
|
|
15
|
+
throw new RangeError("session store: maxEntryBytes must be at least 1024");
|
|
16
|
+
}
|
|
17
|
+
async append(sessionId, type, payload, options = {}) {
|
|
18
|
+
validateToken(sessionId, "sessionId");
|
|
19
|
+
if (!/^[a-z][a-z0-9._:-]{0,63}$/.test(type))
|
|
20
|
+
throw new TypeError("session store: invalid event type");
|
|
21
|
+
await mkdir(this.root, { recursive: true });
|
|
22
|
+
const nextSeq = await this.nextSequence(sessionId);
|
|
23
|
+
const entry = Object.freeze({
|
|
24
|
+
version: 1,
|
|
25
|
+
sessionId,
|
|
26
|
+
seq: nextSeq,
|
|
27
|
+
at: Date.now(),
|
|
28
|
+
type,
|
|
29
|
+
...(payload === undefined
|
|
30
|
+
? {}
|
|
31
|
+
: { payload: boundValue(redactValue(payload), this.maxEntryBytes) }),
|
|
32
|
+
...(options.pinned === true ? { pinned: true } : {}),
|
|
33
|
+
});
|
|
34
|
+
const line = JSON.stringify(entry);
|
|
35
|
+
if (Buffer.byteLength(line, "utf8") > this.maxEntryBytes)
|
|
36
|
+
throw new RangeError("session store: event exceeds maxEntryBytes");
|
|
37
|
+
await appendFile(this.pathFor(sessionId), `${line}\n`, "utf8");
|
|
38
|
+
this.sequences.set(sessionId, nextSeq);
|
|
39
|
+
return entry;
|
|
40
|
+
}
|
|
41
|
+
async read(sessionId) {
|
|
42
|
+
validateToken(sessionId, "sessionId");
|
|
43
|
+
try {
|
|
44
|
+
const text = await readFile(this.pathFor(sessionId), "utf8");
|
|
45
|
+
const entries = [];
|
|
46
|
+
for (const line of text.split("\n")) {
|
|
47
|
+
if (line.trim().length === 0)
|
|
48
|
+
continue;
|
|
49
|
+
const value = JSON.parse(line);
|
|
50
|
+
if (isSessionLogEntry(value, sessionId))
|
|
51
|
+
entries.push(Object.freeze(value));
|
|
52
|
+
}
|
|
53
|
+
const last = entries.at(-1)?.seq;
|
|
54
|
+
if (last !== undefined)
|
|
55
|
+
this.sequences.set(sessionId, last);
|
|
56
|
+
return Object.freeze(entries);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (isNotFound(error))
|
|
60
|
+
return Object.freeze([]);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async checkpoint(sessionId, payload) {
|
|
65
|
+
validateToken(sessionId, "sessionId");
|
|
66
|
+
const target = join(this.root, `${sessionId}.checkpoint.json`);
|
|
67
|
+
const temporary = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
68
|
+
await mkdir(dirname(target), { recursive: true });
|
|
69
|
+
const content = JSON.stringify({
|
|
70
|
+
version: 1,
|
|
71
|
+
sessionId,
|
|
72
|
+
at: Date.now(),
|
|
73
|
+
payload: boundValue(redactValue(payload), this.maxEntryBytes),
|
|
74
|
+
});
|
|
75
|
+
await writeFile(temporary, content, "utf8");
|
|
76
|
+
await rename(temporary, target);
|
|
77
|
+
}
|
|
78
|
+
async fork(sessionId, targetSessionId = `${sessionId}:fork:${Date.now().toString(36)}`) {
|
|
79
|
+
validateToken(sessionId, "sessionId");
|
|
80
|
+
validateToken(targetSessionId, "targetSessionId");
|
|
81
|
+
const entries = await this.read(sessionId);
|
|
82
|
+
await mkdir(this.root, { recursive: true });
|
|
83
|
+
const target = this.pathFor(targetSessionId);
|
|
84
|
+
const lines = entries.map((entry, index) => JSON.stringify({ ...entry, sessionId: targetSessionId, seq: index }));
|
|
85
|
+
await writeFile(target, lines.length === 0 ? "" : `${lines.join("\n")}\n`, "utf8");
|
|
86
|
+
this.sequences.set(targetSessionId, Math.max(0, lines.length - 1));
|
|
87
|
+
return targetSessionId;
|
|
88
|
+
}
|
|
89
|
+
pathFor(sessionId) {
|
|
90
|
+
return join(this.root, `${sessionId}.jsonl`);
|
|
91
|
+
}
|
|
92
|
+
async nextSequence(sessionId) {
|
|
93
|
+
const cached = this.sequences.get(sessionId);
|
|
94
|
+
if (cached !== undefined)
|
|
95
|
+
return cached + 1;
|
|
96
|
+
const entries = await this.read(sessionId);
|
|
97
|
+
return (entries.at(-1)?.seq ?? -1) + 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** In-memory prompt window with automatic, deterministic compaction and a hard size ceiling. */
|
|
101
|
+
export class ContextWindow {
|
|
102
|
+
maxTokens;
|
|
103
|
+
keepRecent;
|
|
104
|
+
maxSummaryChars;
|
|
105
|
+
summarizeRecord;
|
|
106
|
+
records = [];
|
|
107
|
+
constructor(options = {}) {
|
|
108
|
+
this.maxTokens = options.maxTokens ?? 32_000;
|
|
109
|
+
this.keepRecent = options.keepRecent ?? 24;
|
|
110
|
+
this.maxSummaryChars = options.maxSummaryChars ?? 4_096;
|
|
111
|
+
this.summarizeRecord = options.summarize ?? summarize;
|
|
112
|
+
if (!Number.isSafeInteger(this.maxTokens) || this.maxTokens < 256)
|
|
113
|
+
throw new RangeError("context window: maxTokens must be at least 256");
|
|
114
|
+
if (!Number.isSafeInteger(this.keepRecent) || this.keepRecent < 1)
|
|
115
|
+
throw new RangeError("context window: keepRecent must be positive");
|
|
116
|
+
}
|
|
117
|
+
get tokens() {
|
|
118
|
+
return estimateTokens(this.records);
|
|
119
|
+
}
|
|
120
|
+
get size() {
|
|
121
|
+
return this.records.length;
|
|
122
|
+
}
|
|
123
|
+
snapshot() {
|
|
124
|
+
return Object.freeze(this.records.map((record) => Object.freeze({ ...record })));
|
|
125
|
+
}
|
|
126
|
+
/** Restore bounded prompt context from persisted evidence without bypassing compaction rules. */
|
|
127
|
+
restore(records) {
|
|
128
|
+
this.records = [];
|
|
129
|
+
for (const record of records.slice(-Math.max(this.keepRecent * 8, 256)))
|
|
130
|
+
this.append(record);
|
|
131
|
+
}
|
|
132
|
+
append(record) {
|
|
133
|
+
this.records.push({
|
|
134
|
+
kind: record.kind,
|
|
135
|
+
content: record.content.slice(0, this.maxSummaryChars),
|
|
136
|
+
...(record.pinned === true ? { pinned: true } : {}),
|
|
137
|
+
});
|
|
138
|
+
if (this.tokens <= this.maxTokens)
|
|
139
|
+
return undefined;
|
|
140
|
+
return this.compact("threshold");
|
|
141
|
+
}
|
|
142
|
+
compact(reason = "manual") {
|
|
143
|
+
const before = this.tokens;
|
|
144
|
+
if (this.records.length <= this.keepRecent)
|
|
145
|
+
return { before, after: before, removed: 0, reason };
|
|
146
|
+
// A compacted summary is replaceable context, not authoritative evidence. Keeping old pinned
|
|
147
|
+
// summaries in `protectedRecords` would make every threshold compaction grow the live window.
|
|
148
|
+
const protectedRecords = this.records.filter((record) => record.kind !== "memory.summary" &&
|
|
149
|
+
(record.pinned === true || isAuthoritative(record.kind)));
|
|
150
|
+
const recent = this.records.slice(-this.keepRecent);
|
|
151
|
+
const retained = new Set([...protectedRecords, ...recent]);
|
|
152
|
+
const omitted = this.records.filter((record) => !retained.has(record));
|
|
153
|
+
if (omitted.length === 0)
|
|
154
|
+
return { before, after: before, removed: 0, reason };
|
|
155
|
+
const summary = this.summarizeRecord(omitted, this.maxSummaryChars).slice(0, this.maxSummaryChars);
|
|
156
|
+
this.records = [
|
|
157
|
+
...protectedRecords,
|
|
158
|
+
{ kind: "memory.summary", content: summary, pinned: true },
|
|
159
|
+
...recent.filter((record) => record.kind !== "memory.summary" && !protectedRecords.includes(record)),
|
|
160
|
+
];
|
|
161
|
+
const after = this.tokens;
|
|
162
|
+
return { before, after, removed: omitted.length, reason };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function validateToken(value, name) {
|
|
166
|
+
if (!/^[a-zA-Z0-9._:-]{1,128}$/.test(value))
|
|
167
|
+
throw new TypeError(`session store: ${name} must be a bounded token`);
|
|
168
|
+
}
|
|
169
|
+
function isNotFound(error) {
|
|
170
|
+
return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
|
|
171
|
+
}
|
|
172
|
+
function isSessionLogEntry(value, sessionId) {
|
|
173
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
174
|
+
return false;
|
|
175
|
+
const record = value;
|
|
176
|
+
return (record.version === 1 &&
|
|
177
|
+
record.sessionId === sessionId &&
|
|
178
|
+
typeof record.seq === "number" &&
|
|
179
|
+
Number.isSafeInteger(record.seq) &&
|
|
180
|
+
typeof record.at === "number" &&
|
|
181
|
+
typeof record.type === "string");
|
|
182
|
+
}
|
|
183
|
+
function redactValue(value, key = "", depth = 0) {
|
|
184
|
+
if (depth > 5)
|
|
185
|
+
return "[depth-limited]";
|
|
186
|
+
if (/(?:secret|token|password|passwd|authorization|api[-_]?key|private[-_]?key)/i.test(key))
|
|
187
|
+
return "[redacted]";
|
|
188
|
+
if (typeof value === "string")
|
|
189
|
+
return value.length > 16_384 ? `${value.slice(0, 16_384)}…[truncated]` : value;
|
|
190
|
+
if (Array.isArray(value))
|
|
191
|
+
return value.slice(0, 256).map((item) => redactValue(item, "", depth + 1));
|
|
192
|
+
if (value !== null && typeof value === "object") {
|
|
193
|
+
const result = {};
|
|
194
|
+
for (const [childKey, childValue] of Object.entries(value).slice(0, 256))
|
|
195
|
+
result[childKey] = redactValue(childValue, childKey, depth + 1);
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
function boundValue(value, maxBytes) {
|
|
201
|
+
const text = JSON.stringify(value);
|
|
202
|
+
if (Buffer.byteLength(text, "utf8") <= maxBytes)
|
|
203
|
+
return value;
|
|
204
|
+
return "[payload-truncated]";
|
|
205
|
+
}
|
|
206
|
+
function estimateTokens(records) {
|
|
207
|
+
return Math.ceil(records.reduce((total, record) => total + record.kind.length + record.content.length, 0) / 4);
|
|
208
|
+
}
|
|
209
|
+
function isAuthoritative(kind) {
|
|
210
|
+
return (kind.startsWith("approval") || kind.startsWith("verification") || kind === "session.checkpoint");
|
|
211
|
+
}
|
|
212
|
+
function summarize(records, maxChars) {
|
|
213
|
+
const lines = [`Compacted ${records.length} earlier context entries.`];
|
|
214
|
+
for (const record of records.slice(-32)) {
|
|
215
|
+
const line = `- ${record.kind}: ${record.content.replace(/\s+/g, " ").slice(0, 180)}`;
|
|
216
|
+
if (lines.join("\n").length + line.length + 1 > maxChars)
|
|
217
|
+
break;
|
|
218
|
+
lines.push(line);
|
|
219
|
+
}
|
|
220
|
+
return lines.join("\n");
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"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"}
|