@vinhnt-sdk/step-executor 0.6.4 → 0.11.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.
Files changed (43) hide show
  1. package/README.md +3 -2
  2. package/dist/approval-handler.d.ts +2 -1
  3. package/dist/approval-handler.d.ts.map +1 -1
  4. package/dist/approval-handler.js +10 -4
  5. package/dist/approval-handler.js.map +1 -1
  6. package/dist/file-snapshot.d.ts +162 -0
  7. package/dist/file-snapshot.d.ts.map +1 -0
  8. package/dist/file-snapshot.js +233 -0
  9. package/dist/file-snapshot.js.map +1 -0
  10. package/dist/index.d.ts +4 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/kernel-error.d.ts +2 -9
  15. package/dist/kernel-error.d.ts.map +1 -1
  16. package/dist/kernel-error.js +1 -11
  17. package/dist/kernel-error.js.map +1 -1
  18. package/dist/permission-gate.d.ts +48 -3
  19. package/dist/permission-gate.d.ts.map +1 -1
  20. package/dist/permission-gate.js +83 -21
  21. package/dist/permission-gate.js.map +1 -1
  22. package/dist/run-state.d.ts +35 -0
  23. package/dist/run-state.d.ts.map +1 -1
  24. package/dist/run-state.js +59 -0
  25. package/dist/run-state.js.map +1 -1
  26. package/dist/self-correction.d.ts.map +1 -1
  27. package/dist/self-correction.js +4 -4
  28. package/dist/self-correction.js.map +1 -1
  29. package/dist/step-executor.d.ts +22 -0
  30. package/dist/step-executor.d.ts.map +1 -1
  31. package/dist/step-executor.js +107 -9
  32. package/dist/step-executor.js.map +1 -1
  33. package/dist/tool-context-builder.d.ts +4 -0
  34. package/dist/tool-context-builder.d.ts.map +1 -1
  35. package/dist/tool-context-builder.js +6 -1
  36. package/dist/tool-context-builder.js.map +1 -1
  37. package/dist/tool-error-router.d.ts.map +1 -1
  38. package/dist/tool-error-router.js +2 -2
  39. package/dist/tool-error-router.js.map +1 -1
  40. package/dist/tool-result-processor.d.ts.map +1 -1
  41. package/dist/tool-result-processor.js +28 -9
  42. package/dist/tool-result-processor.js.map +1 -1
  43. package/package.json +8 -8
package/README.md CHANGED
@@ -11,7 +11,7 @@ pnpm add @vinhnt-sdk/step-executor
11
11
  ## Usage
12
12
 
13
13
  ```ts
14
- import { StepExecutor, PermissionGate, runLoop, RunStateMachine } from "@vinhnt-sdk/step-executor";
14
+ import { StepExecutor, PermissionGate, RunStateMachine } from "@vinhnt-sdk/step-executor";
15
15
  ```
16
16
 
17
17
  ## Contents
@@ -22,7 +22,8 @@ import { StepExecutor, PermissionGate, runLoop, RunStateMachine } from "@vinhnt-
22
22
  - `termination` — stop-condition evaluation and judge-based loop termination
23
23
  - `kernel-utils` — doom-loop detection, arg hashing, timeouts, tool domains, defaults
24
24
  - `run-state` / `run-context` — per-run state machine and context
25
- - `circuit-breaker` / `kernel-error` — failure isolation and typed errors
25
+ - `loop-policy` / `path-policy` — loop/path safety policies
26
+ - `kernel-error` — typed step errors; failure isolation via `@vinhnt-sdk/guard` circuit breaker
26
27
 
27
28
  ## Hooks
28
29
 
@@ -13,6 +13,7 @@ export interface ApprovalHandlerDeps {
13
13
  readonly permissionGate: PermissionGate;
14
14
  readonly pluginManager: StepExecutorPluginHooks | undefined;
15
15
  currentAgent: AgentConfig | undefined;
16
+ readonly addSessionMessage: (sessionId: string | undefined, role: string, content: string, extra?: Record<string, unknown>) => Promise<void>;
16
17
  }
17
- export declare function handleApproval(permResult: PermissionCheckResult, tc: ToolExecutionPlan, toolCtx: ToolContext, runId: RunId, ctx: RequestContext, _sessionId: string | undefined, messages: ChatMessage[], deps: ApprovalHandlerDeps, selfApproving?: boolean): Promise<boolean>;
18
+ export declare function handleApproval(permResult: PermissionCheckResult, tc: ToolExecutionPlan, toolCtx: ToolContext, runId: RunId, ctx: RequestContext, sessionId: string | undefined, messages: ChatMessage[], deps: ApprovalHandlerDeps, selfApproving?: boolean): Promise<boolean>;
18
19
  //# sourceMappingURL=approval-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"approval-handler.d.ts","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE;QAAE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,oBAAoB,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACrI,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5D,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;CACvC;AAED,wBAAsB,cAAc,CAClC,UAAU,EAAE,qBAAqB,EACjC,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,EAAE,WAAW,EAAE,EACvB,IAAI,EAAE,mBAAmB,EACzB,aAAa,CAAC,EAAE,OAAO,GACtB,OAAO,CAAC,OAAO,CAAC,CAmDlB"}
1
+ {"version":3,"file":"approval-handler.d.ts","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE;QAAE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,oBAAoB,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACrI,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5D,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9I;AAED,wBAAsB,cAAc,CAClC,UAAU,EAAE,qBAAqB,EACjC,EAAE,EAAE,iBAAiB,EACrB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,QAAQ,EAAE,WAAW,EAAE,EACvB,IAAI,EAAE,mBAAmB,EACzB,aAAa,CAAC,EAAE,OAAO,GACtB,OAAO,CAAC,OAAO,CAAC,CAyDlB"}
@@ -1,13 +1,15 @@
1
1
  import { formatToolFailure } from "@vinhnt-sdk/schema";
2
2
  import { toolDomain } from "./kernel-utils.js";
3
- export async function handleApproval(permResult, tc, toolCtx, runId, ctx, _sessionId, messages, deps, selfApproving) {
3
+ export async function handleApproval(permResult, tc, toolCtx, runId, ctx, sessionId, messages, deps, selfApproving) {
4
4
  // Allowed or needs-approval → proceed. A hard deny (!allowed, no approval
5
5
  // needed) must surface as a rejection — a caller who skips this check would
6
6
  // otherwise hand a denied tool straight through to execution.
7
7
  if (permResult.allowed)
8
8
  return true;
9
9
  if (!permResult.needsApproval) {
10
- messages.push({ role: "tool", toolCallId: tc.toolId, content: formatToolFailure(`Tool "${tc.toolName}" denied by permission rules`, undefined, "permission_denied") });
10
+ const content = formatToolFailure(`Tool "${tc.toolName}" denied by permission rules`, undefined, "permission_denied");
11
+ messages.push({ role: "tool", toolCallId: tc.toolId, content });
12
+ await deps.addSessionMessage(sessionId, "tool", content, { toolCallId: tc.toolId });
11
13
  return false;
12
14
  }
13
15
  // Single approval path: self-approving tools ask via their own `ctx.ask`
@@ -26,7 +28,9 @@ export async function handleApproval(permResult, tc, toolCtx, runId, ctx, _sessi
26
28
  occurredAt: new Date().toISOString(), traceId: ctx.traceId,
27
29
  data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), decision: "deny", error: `Tool "${tc.toolName}" rejected by user` },
28
30
  });
29
- messages.push({ role: "tool", toolCallId: tc.toolId, content: `Error: Tool "${tc.toolName}" rejected by user (previously rejected — will not re-prompt; choose a different approach or ask the user directly)` });
31
+ const content = `Error: Tool "${tc.toolName}" rejected by user (previously rejected — will not re-prompt; choose a different approach or ask the user directly)`;
32
+ messages.push({ role: "tool", toolCallId: tc.toolId, content });
33
+ await deps.addSessionMessage(sessionId, "tool", content, { toolCallId: tc.toolId });
30
34
  return false;
31
35
  }
32
36
  const reply = await toolCtx.ask({
@@ -41,7 +45,9 @@ export async function handleApproval(permResult, tc, toolCtx, runId, ctx, _sessi
41
45
  occurredAt: new Date().toISOString(), traceId: ctx.traceId,
42
46
  data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), decision: "deny", error: `Tool "${tc.toolName}" rejected by user` },
43
47
  });
44
- messages.push({ role: "tool", toolCallId: tc.toolId, content: `Error: Tool "${tc.toolName}" rejected by user` });
48
+ const content = `Error: Tool "${tc.toolName}" rejected by user`;
49
+ messages.push({ role: "tool", toolCallId: tc.toolId, content });
50
+ await deps.addSessionMessage(sessionId, "tool", content, { toolCallId: tc.toolId });
45
51
  return false;
46
52
  }
47
53
  if (reply === "always") {
@@ -1 +1 @@
1
- {"version":3,"file":"approval-handler.js","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval-handler.js","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Per-step file snapshots → undo (P2-3 / G7.2).
3
+ *
4
+ * Before a mutating file tool (`write_file`/`edit_file`/`apply_patch` by
5
+ * default) executes, the recorder captures each target file's PRE-IMAGE:
6
+ * `{existed, content}` (content skipped above `maxContentBytes`). Snapshots
7
+ * are grouped by `runId`/`step`/`toolCallId`, kept in an in-memory bounded
8
+ * store (swap `fs`/store knobs via DI — no global state), and reference
9
+ * metadata (never file content) rides on the `tool.completed` event as
10
+ * `metadata.fileSnapshots`.
11
+ *
12
+ * `undo(filter)` restores newest-first: existing files get their pre-image
13
+ * back, files the tool created are removed, entries without a captured
14
+ * pre-image are reported as skipped. Opt-in via `AgentKernelConfig.fileSnapshot`
15
+ * (default: off — zero behavior change until enabled).
16
+ */
17
+ /** Pre-image of one file captured before a mutating tool ran. */
18
+ export interface FileSnapshot {
19
+ /** Target path (absolute when `workspaceRoot` is known, else as given). */
20
+ readonly path: string;
21
+ /** Whether the file existed before the tool ran. */
22
+ readonly existed: boolean;
23
+ /**
24
+ * Pre-image content. `undefined` when the file did not exist, was
25
+ * unreadable, or exceeded `maxContentBytes` (undo then reports "no
26
+ * pre-image" instead of corrupting the file).
27
+ */
28
+ readonly content?: string;
29
+ /** Pre-image size in bytes (0 when the file did not exist). */
30
+ readonly size: number;
31
+ readonly toolCallId: string;
32
+ readonly toolName: string;
33
+ readonly step: number;
34
+ readonly runId: string;
35
+ /** ISO timestamp of the capture. */
36
+ readonly at: string;
37
+ /** Set once `undo()` restored/removed this entry (never undone twice). */
38
+ undone: boolean;
39
+ }
40
+ /** Lightweight snapshot reference attached to `tool.completed` event metadata. */
41
+ export interface FileSnapshotRef {
42
+ readonly path: string;
43
+ readonly existed: boolean;
44
+ /** Whether a restorable pre-image was captured (false = over-cap/unreadable). */
45
+ readonly hadPreImage: boolean;
46
+ }
47
+ /** Injectable filesystem seam (defaults to `node:fs/promises`). */
48
+ export interface FileSnapshotFs {
49
+ /**
50
+ * Read a utf8 file. Return `content: undefined` when it exceeds `maxBytes`
51
+ * (still report `size`). Throw an error with `code: "ENOENT"` when missing.
52
+ */
53
+ read(path: string, maxBytes: number): Promise<{
54
+ content?: string;
55
+ size: number;
56
+ }>;
57
+ write(path: string, content: string): Promise<void>;
58
+ remove(path: string): Promise<void>;
59
+ }
60
+ /** Recorder configuration (all injectable — see defaults below). */
61
+ export interface FileSnapshotConfig {
62
+ /** Tool names eligible for capture. Default: {@link DEFAULT_SNAPSHOT_TOOL_IDS}. */
63
+ readonly toolIds?: readonly string[];
64
+ /** Arg keys holding the target path (first present wins). Default: {@link DEFAULT_SNAPSHOT_PATH_ARGS}. */
65
+ readonly pathArgs?: readonly string[];
66
+ /** Skip capturing content above this many bytes (existence is still recorded). Default: 1 MiB. */
67
+ readonly maxContentBytes?: number;
68
+ /** Max retained snapshots (drop-oldest). Default: 200. */
69
+ readonly maxSnapshots?: number;
70
+ /** Resolve relative target paths against this root. */
71
+ readonly workspaceRoot?: string;
72
+ /** Filesystem seam. Default: {@link createNodeFileSnapshotFs}. */
73
+ readonly fs?: FileSnapshotFs;
74
+ }
75
+ /** Selects snapshots for `list()`/`undo()`. At least one field should match. */
76
+ export interface FileSnapshotFilter {
77
+ readonly runId?: string;
78
+ readonly step?: number;
79
+ readonly path?: string;
80
+ readonly toolCallId?: string;
81
+ }
82
+ /** One successful undo action. */
83
+ export interface FileSnapshotUndoEntry {
84
+ readonly path: string;
85
+ readonly action: "restored" | "removed";
86
+ }
87
+ /** One entry that could not be undone. */
88
+ export interface FileSnapshotUndoSkipped {
89
+ readonly path: string;
90
+ readonly reason: string;
91
+ }
92
+ /** Result of {@link FileSnapshotRecorder.undo}. */
93
+ export interface FileSnapshotUndoResult {
94
+ readonly restored: readonly FileSnapshotUndoEntry[];
95
+ readonly skipped: readonly FileSnapshotUndoSkipped[];
96
+ }
97
+ /** Input to {@link FileSnapshotRecorder.capture}. */
98
+ export interface FileSnapshotCaptureParams {
99
+ readonly toolName: string;
100
+ readonly input: unknown;
101
+ readonly toolCallId: string;
102
+ readonly step: number;
103
+ readonly runId: string;
104
+ /** Override the ISO timestamp source (tests). */
105
+ readonly now?: () => string;
106
+ }
107
+ /** Default mutating tool names eligible for capture. */
108
+ export declare const DEFAULT_SNAPSHOT_TOOL_IDS: readonly ["write_file", "edit_file", "apply_patch"];
109
+ /** Default arg keys carrying the target file path. */
110
+ export declare const DEFAULT_SNAPSHOT_PATH_ARGS: readonly ["filePath", "path"];
111
+ /** Default content cap: 1 MiB (larger files record existence only). */
112
+ export declare const DEFAULT_SNAPSHOT_MAX_CONTENT_BYTES = 1048576;
113
+ /** Default bounded store size (drop-oldest). */
114
+ export declare const DEFAULT_SNAPSHOT_MAX_COUNT = 200;
115
+ /** Filesystem backed by `node:fs/promises`. */
116
+ export declare function createNodeFileSnapshotFs(): FileSnapshotFs;
117
+ /**
118
+ * Extract the target file paths a mutating tool call will touch:
119
+ * structured `apply_patch` patches (via the G2.1 grammar — every
120
+ * `*** Update/Add/Delete File:` path plus `*** Move to:` targets), otherwise
121
+ * the first present path arg (`filePath`/`path` by default).
122
+ * Returns `[]` when nothing extractable (caller skips capture).
123
+ */
124
+ export declare function extractSnapshotPaths(toolName: string, input: unknown, config?: Pick<FileSnapshotConfig, "pathArgs">): readonly string[];
125
+ /**
126
+ * Bounded in-memory store of file pre-images with capture/undo.
127
+ * Not thread-safe across concurrent captures of the same path (per-tool
128
+ * captures are serialized by the step executor's approval flow).
129
+ */
130
+ export declare class FileSnapshotRecorder {
131
+ private readonly toolIds;
132
+ private readonly pathArgs;
133
+ private readonly maxContentBytes;
134
+ private readonly maxSnapshots;
135
+ private readonly workspaceRoot;
136
+ private readonly fs;
137
+ private readonly snapshots;
138
+ constructor(config?: FileSnapshotConfig);
139
+ /** Total retained snapshots (bounded by `maxSnapshots`, drop-oldest). */
140
+ get size(): number;
141
+ /** Whether the given tool name is eligible for capture. */
142
+ accepts(toolName: string): boolean;
143
+ /**
144
+ * Capture pre-images for a mutating tool call (best-effort — never throws).
145
+ * Returns the lightweight refs to attach to `tool.completed` metadata.
146
+ */
147
+ capture(params: FileSnapshotCaptureParams): Promise<readonly FileSnapshotRef[]>;
148
+ /** List matching snapshots (copy — oldest first). */
149
+ list(filter?: FileSnapshotFilter): readonly FileSnapshot[];
150
+ /**
151
+ * Undo matching, NOT-yet-undone snapshots, NEWEST FIRST.
152
+ * Existing files → pre-image restored; tool-created files → removed;
153
+ * entries without a captured pre-image → skipped with a reason.
154
+ */
155
+ undo(filter?: FileSnapshotFilter): Promise<FileSnapshotUndoResult>;
156
+ /** Drop snapshots (all, or only a run's) — e.g. after session cleanup. */
157
+ clear(runId?: string): void;
158
+ private resolvePath;
159
+ }
160
+ /** Factory mirroring the SDK's create* conventions. */
161
+ export declare function createFileSnapshotRecorder(config?: FileSnapshotConfig): FileSnapshotRecorder;
162
+ //# sourceMappingURL=file-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-snapshot.d.ts","sourceRoot":"","sources":["../src/file-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Per-step file snapshots → undo (P2-3 / G7.2).
3
+ *
4
+ * Before a mutating file tool (`write_file`/`edit_file`/`apply_patch` by
5
+ * default) executes, the recorder captures each target file's PRE-IMAGE:
6
+ * `{existed, content}` (content skipped above `maxContentBytes`). Snapshots
7
+ * are grouped by `runId`/`step`/`toolCallId`, kept in an in-memory bounded
8
+ * store (swap `fs`/store knobs via DI — no global state), and reference
9
+ * metadata (never file content) rides on the `tool.completed` event as
10
+ * `metadata.fileSnapshots`.
11
+ *
12
+ * `undo(filter)` restores newest-first: existing files get their pre-image
13
+ * back, files the tool created are removed, entries without a captured
14
+ * pre-image are reported as skipped. Opt-in via `AgentKernelConfig.fileSnapshot`
15
+ * (default: off — zero behavior change until enabled).
16
+ */
17
+ import { readFile, writeFile, rm, stat } from "node:fs/promises";
18
+ import { isAbsolute, resolve as resolvePath } from "node:path";
19
+ import { detectApplyPatchFormat, parseApplyPatch } from "@vinhnt-sdk/tools";
20
+ /** Default mutating tool names eligible for capture. */
21
+ export const DEFAULT_SNAPSHOT_TOOL_IDS = ["write_file", "edit_file", "apply_patch"];
22
+ /** Default arg keys carrying the target file path. */
23
+ export const DEFAULT_SNAPSHOT_PATH_ARGS = ["filePath", "path"];
24
+ /** Default content cap: 1 MiB (larger files record existence only). */
25
+ export const DEFAULT_SNAPSHOT_MAX_CONTENT_BYTES = 1_048_576;
26
+ /** Default bounded store size (drop-oldest). */
27
+ export const DEFAULT_SNAPSHOT_MAX_COUNT = 200;
28
+ /** Filesystem backed by `node:fs/promises`. */
29
+ export function createNodeFileSnapshotFs() {
30
+ return {
31
+ async read(path, maxBytes) {
32
+ const info = await stat(path);
33
+ if (info.size > maxBytes)
34
+ return { size: info.size };
35
+ const content = await readFile(path, "utf8");
36
+ return { content, size: Buffer.byteLength(content, "utf8") };
37
+ },
38
+ async write(path, content) {
39
+ await writeFile(path, content, "utf8");
40
+ },
41
+ async remove(path) {
42
+ await rm(path, { force: true });
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Extract the target file paths a mutating tool call will touch:
48
+ * structured `apply_patch` patches (via the G2.1 grammar — every
49
+ * `*** Update/Add/Delete File:` path plus `*** Move to:` targets), otherwise
50
+ * the first present path arg (`filePath`/`path` by default).
51
+ * Returns `[]` when nothing extractable (caller skips capture).
52
+ */
53
+ export function extractSnapshotPaths(toolName, input, config) {
54
+ const record = (typeof input === "object" && input !== null ? input : {});
55
+ if (toolName === "apply_patch" && typeof record.patch === "string") {
56
+ const patch = record.patch;
57
+ if (detectApplyPatchFormat(patch) === "structured") {
58
+ try {
59
+ const program = parseApplyPatch(patch, "lenient");
60
+ const paths = [];
61
+ for (const op of program.ops) {
62
+ paths.push(op.path);
63
+ if (op.kind === "update" && op.moveTo !== undefined)
64
+ paths.push(op.moveTo);
65
+ }
66
+ return [...new Set(paths)];
67
+ }
68
+ catch {
69
+ // Best-effort: fall through to path-arg extraction.
70
+ }
71
+ }
72
+ }
73
+ for (const key of config?.pathArgs ?? DEFAULT_SNAPSHOT_PATH_ARGS) {
74
+ const value = record[key];
75
+ if (typeof value === "string" && value.length > 0)
76
+ return [value];
77
+ }
78
+ return [];
79
+ }
80
+ /**
81
+ * Bounded in-memory store of file pre-images with capture/undo.
82
+ * Not thread-safe across concurrent captures of the same path (per-tool
83
+ * captures are serialized by the step executor's approval flow).
84
+ */
85
+ export class FileSnapshotRecorder {
86
+ toolIds;
87
+ pathArgs;
88
+ maxContentBytes;
89
+ maxSnapshots;
90
+ workspaceRoot;
91
+ fs;
92
+ snapshots = [];
93
+ constructor(config = {}) {
94
+ this.toolIds = new Set(config.toolIds ?? DEFAULT_SNAPSHOT_TOOL_IDS);
95
+ this.pathArgs = config.pathArgs ?? DEFAULT_SNAPSHOT_PATH_ARGS;
96
+ this.maxContentBytes = config.maxContentBytes ?? DEFAULT_SNAPSHOT_MAX_CONTENT_BYTES;
97
+ this.maxSnapshots = Math.max(1, config.maxSnapshots ?? DEFAULT_SNAPSHOT_MAX_COUNT);
98
+ this.workspaceRoot = config.workspaceRoot;
99
+ this.fs = config.fs ?? createNodeFileSnapshotFs();
100
+ }
101
+ /** Total retained snapshots (bounded by `maxSnapshots`, drop-oldest). */
102
+ get size() {
103
+ return this.snapshots.length;
104
+ }
105
+ /** Whether the given tool name is eligible for capture. */
106
+ accepts(toolName) {
107
+ return this.toolIds.has(toolName);
108
+ }
109
+ /**
110
+ * Capture pre-images for a mutating tool call (best-effort — never throws).
111
+ * Returns the lightweight refs to attach to `tool.completed` metadata.
112
+ */
113
+ async capture(params) {
114
+ if (!this.accepts(params.toolName))
115
+ return [];
116
+ const paths = extractSnapshotPaths(params.toolName, params.input, { pathArgs: this.pathArgs });
117
+ if (paths.length === 0)
118
+ return [];
119
+ const at = (params.now ?? (() => new Date().toISOString()))();
120
+ const refs = [];
121
+ for (const rawPath of paths) {
122
+ try {
123
+ const path = this.resolvePath(rawPath);
124
+ let existed = true;
125
+ let content;
126
+ let size = 0;
127
+ try {
128
+ const result = await this.fs.read(path, this.maxContentBytes);
129
+ content = result.content;
130
+ size = result.size;
131
+ }
132
+ catch (error) {
133
+ if (error.code === "ENOENT") {
134
+ existed = false;
135
+ }
136
+ else {
137
+ continue; // unreadable (permissions, directory…) — skip this path
138
+ }
139
+ }
140
+ this.snapshots.push({
141
+ path,
142
+ existed,
143
+ ...(content !== undefined ? { content } : {}),
144
+ size,
145
+ toolCallId: params.toolCallId,
146
+ toolName: params.toolName,
147
+ step: params.step,
148
+ runId: params.runId,
149
+ at,
150
+ undone: false,
151
+ });
152
+ while (this.snapshots.length > this.maxSnapshots)
153
+ this.snapshots.shift();
154
+ refs.push({ path, existed, hadPreImage: existed && content !== undefined });
155
+ }
156
+ catch {
157
+ // Path resolution failure — never break the tool call.
158
+ }
159
+ }
160
+ return refs;
161
+ }
162
+ /** List matching snapshots (copy — oldest first). */
163
+ list(filter) {
164
+ return this.snapshots.filter((s) => matches(s, filter));
165
+ }
166
+ /**
167
+ * Undo matching, NOT-yet-undone snapshots, NEWEST FIRST.
168
+ * Existing files → pre-image restored; tool-created files → removed;
169
+ * entries without a captured pre-image → skipped with a reason.
170
+ */
171
+ async undo(filter = {}) {
172
+ const target = this.snapshots
173
+ .filter((s) => !s.undone && matches(s, filter))
174
+ .sort((a, b) => b.at.localeCompare(a.at) || this.snapshots.indexOf(b) - this.snapshots.indexOf(a));
175
+ const restored = [];
176
+ const skipped = [];
177
+ for (const snapshot of target) {
178
+ try {
179
+ if (!snapshot.existed) {
180
+ await this.fs.remove(snapshot.path);
181
+ snapshot.undone = true;
182
+ restored.push({ path: snapshot.path, action: "removed" });
183
+ }
184
+ else if (snapshot.content !== undefined) {
185
+ await this.fs.write(snapshot.path, snapshot.content);
186
+ snapshot.undone = true;
187
+ restored.push({ path: snapshot.path, action: "restored" });
188
+ }
189
+ else {
190
+ skipped.push({ path: snapshot.path, reason: "no pre-image captured (missing or over size cap)" });
191
+ }
192
+ }
193
+ catch (error) {
194
+ skipped.push({ path: snapshot.path, reason: error instanceof Error ? error.message : String(error) });
195
+ }
196
+ }
197
+ return { restored, skipped };
198
+ }
199
+ /** Drop snapshots (all, or only a run's) — e.g. after session cleanup. */
200
+ clear(runId) {
201
+ if (runId === undefined) {
202
+ this.snapshots.length = 0;
203
+ return;
204
+ }
205
+ for (let i = this.snapshots.length - 1; i >= 0; i--) {
206
+ if (this.snapshots[i]?.runId === runId)
207
+ this.snapshots.splice(i, 1);
208
+ }
209
+ }
210
+ resolvePath(path) {
211
+ if (this.workspaceRoot === undefined || isAbsolute(path))
212
+ return path;
213
+ return resolvePath(this.workspaceRoot, path);
214
+ }
215
+ }
216
+ /** Factory mirroring the SDK's create* conventions. */
217
+ export function createFileSnapshotRecorder(config) {
218
+ return new FileSnapshotRecorder(config);
219
+ }
220
+ function matches(snapshot, filter) {
221
+ if (filter === undefined)
222
+ return true;
223
+ if (filter.runId !== undefined && snapshot.runId !== filter.runId)
224
+ return false;
225
+ if (filter.step !== undefined && snapshot.step !== filter.step)
226
+ return false;
227
+ if (filter.path !== undefined && snapshot.path !== filter.path)
228
+ return false;
229
+ if (filter.toolCallId !== undefined && snapshot.toolCallId !== filter.toolCallId)
230
+ return false;
231
+ return true;
232
+ }
233
+ //# sourceMappingURL=file-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-snapshot.js","sourceRoot":"","sources":["../src/file-snapshot.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,8 @@
6
6
  export type { StepExecutorPluginHooks } from "./hooks.js";
7
7
  export { StepExecutor } from "./step-executor.js";
8
8
  export type { StepExecutorDeps, ToolExecutionPlan, HandoffSignal } from "./step-executor.js";
9
+ export { FileSnapshotRecorder, createFileSnapshotRecorder, createNodeFileSnapshotFs, extractSnapshotPaths, DEFAULT_SNAPSHOT_TOOL_IDS, DEFAULT_SNAPSHOT_PATH_ARGS, DEFAULT_SNAPSHOT_MAX_CONTENT_BYTES, DEFAULT_SNAPSHOT_MAX_COUNT, } from "./file-snapshot.js";
10
+ export type { FileSnapshot, FileSnapshotRef, FileSnapshotFs, FileSnapshotConfig, FileSnapshotFilter, FileSnapshotCaptureParams, FileSnapshotUndoEntry, FileSnapshotUndoSkipped, FileSnapshotUndoResult, } from "./file-snapshot.js";
9
11
  export { DEFAULT_MAX_STEPS, DEFAULT_MAX_TOOL_CALLS_PER_STEP, DOOM_LOOP_THRESHOLD, toolDomain, } from "./kernel-utils.js";
10
12
  export { resolveLoopPolicy } from "./loop-policy.js";
11
13
  export type { LoopDetectionConfig, LoopDetectionAction, ResolvedLoopPolicy } from "./loop-policy.js";
@@ -19,6 +21,6 @@ export { KernelError } from "./kernel-error.js";
19
21
  export type { KernelErrorCode } from "./kernel-error.js";
20
22
  export { CircuitBreaker, CircuitBreakerOpenError } from "@vinhnt-sdk/guard";
21
23
  export type { CircuitState, CircuitBreakerOptions } from "@vinhnt-sdk/guard";
22
- export { RunStateMachine } from "./run-state.js";
23
- export type { RunState } from "./run-state.js";
24
+ export { RunStateMachine, MAX_RETAINED_RUN_STATES } from "./run-state.js";
25
+ export type { RunState, RunStateMachineOptions } from "./run-state.js";
24
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAI7F,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,mBAAmB,EACnB,UAAU,GACX,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIrG,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACpH,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAInH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIpH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAI7E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAI7F,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,mBAAmB,EACnB,UAAU,GACX,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIrG,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACpH,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAInH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIpH,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAI7E,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,8 @@
5
5
  */
6
6
  // === Step Executor ===
7
7
  export { StepExecutor } from "./step-executor.js";
8
+ // === File snapshots → undo (G7.2 / P2-3) ===
9
+ export { FileSnapshotRecorder, createFileSnapshotRecorder, createNodeFileSnapshotFs, extractSnapshotPaths, DEFAULT_SNAPSHOT_TOOL_IDS, DEFAULT_SNAPSHOT_PATH_ARGS, DEFAULT_SNAPSHOT_MAX_CONTENT_BYTES, DEFAULT_SNAPSHOT_MAX_COUNT, } from "./file-snapshot.js";
8
10
  // === Kernel Utils (public subset) ===
9
11
  export { DEFAULT_MAX_STEPS, DEFAULT_MAX_TOOL_CALLS_PER_STEP, DOOM_LOOP_THRESHOLD, toolDomain, } from "./kernel-utils.js";
10
12
  // === Loop Detection Policy (P1-3) ===
@@ -20,5 +22,5 @@ export { KernelError } from "./kernel-error.js";
20
22
  // === Circuit Breaker (re-exported from @vinhnt-sdk/guard) ===
21
23
  export { CircuitBreaker, CircuitBreakerOpenError } from "@vinhnt-sdk/guard";
22
24
  // === Run State ===
23
- export { RunStateMachine } from "./run-state.js";
25
+ export { RunStateMachine, MAX_RETAINED_RUN_STATES } from "./run-state.js";
24
26
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,wBAAwB;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,uCAAuC;AAEvC,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,mBAAmB,EACnB,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B,uCAAuC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,sBAAsB;AAEtB,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGpH,0BAA0B;AAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,sBAAsB;AAEtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,uBAAuB;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,+DAA+D;AAE/D,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5E,oBAAoB;AAEpB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,wBAAwB;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,8CAA8C;AAE9C,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAa5B,uCAAuC;AAEvC,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,mBAAmB,EACnB,UAAU,GACX,MAAM,mBAAmB,CAAC;AAE3B,uCAAuC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,sBAAsB;AAEtB,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGpH,0BAA0B;AAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,sBAAsB;AAEtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,uBAAuB;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,+DAA+D;AAE/D,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAG5E,oBAAoB;AAEpB,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,10 +1,3 @@
1
- import { VntError } from "@vinhnt-sdk/schema";
2
- /** Kernel-level failure codes for {@link KernelError}. */
3
- export type KernelErrorCode = "session_busy" | "cancelled" | "max_steps_exceeded" | "max_tokens_exceeded" | "tool_failed" | "model_failed" | "session_store_failed" | "internal_error" | "timeout" | "model_unavailable" | "guardrail_denied" | "validation_error" | "missed_tool_calls";
4
- /** Kernel-level failure with a typed {@link KernelErrorCode}. */
5
- export declare class KernelError extends VntError {
6
- readonly code: string;
7
- readonly retryable = false;
8
- constructor(kernelCode: KernelErrorCode, message: string, cause?: unknown);
9
- }
1
+ export { KernelError } from "@vinhnt-sdk/schema";
2
+ export type { KernelErrorCode } from "@vinhnt-sdk/schema";
10
3
  //# sourceMappingURL=kernel-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-error.d.ts","sourceRoot":"","sources":["../src/kernel-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,0DAA0D;AAC1D,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,WAAW,GACX,oBAAoB,GACpB,qBAAqB,GACrB,aAAa,GACb,cAAc,GACd,sBAAsB,GACtB,gBAAgB,GAChB,SAAS,GACT,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,CAAC;AAExB,iEAAiE;AACjE,qBAAa,WAAY,SAAQ,QAAQ;IACvC,SAAyB,IAAI,EAAE,MAAM,CAAC;IACtC,SAAyB,SAAS,SAAS;gBAE/B,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAK1E"}
1
+ {"version":3,"file":"kernel-error.d.ts","sourceRoot":"","sources":["../src/kernel-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,12 +1,2 @@
1
- import { VntError } from "@vinhnt-sdk/schema";
2
- /** Kernel-level failure with a typed {@link KernelErrorCode}. */
3
- export class KernelError extends VntError {
4
- code;
5
- retryable = false;
6
- constructor(kernelCode, message, cause) {
7
- super(message, { cause });
8
- this.code = kernelCode;
9
- this.name = `KernelError.${kernelCode}`;
10
- }
11
- }
1
+ export { KernelError } from "@vinhnt-sdk/schema";
12
2
  //# sourceMappingURL=kernel-error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-error.js","sourceRoot":"","sources":["../src/kernel-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAkB9C,iEAAiE;AACjE,MAAM,OAAO,WAAY,SAAQ,QAAQ;IACd,IAAI,CAAS;IACb,SAAS,GAAG,KAAK,CAAC;IAE3C,YAAY,UAA2B,EAAE,OAAe,EAAE,KAAe;QACvE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,eAAe,UAAU,EAAE,CAAC;IAC1C,CAAC;CACF"}
1
+ {"version":3,"file":"kernel-error.js","sourceRoot":"","sources":["../src/kernel-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}