@sema-agent/mods-kernel 0.0.0-stage → 7.54.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.
@@ -0,0 +1,200 @@
1
+ export declare const KERNEL_CONTRACT_VERSION = 2;
2
+ export declare const MOD_TIERS: readonly ["prepend", "user", "append", "builtin", "core"];
3
+ export type ModTier = (typeof MOD_TIERS)[number];
4
+ export type ModRegistrationTier = Exclude<ModTier, "builtin" | "core">;
5
+ export declare const MOD_SEATS: readonly ["deployment", "task"];
6
+ export type ModSeat = (typeof MOD_SEATS)[number];
7
+ export declare const MOD_EVENT_SIDES: readonly ["engine", "surface", "both"];
8
+ export type ModEventSide = (typeof MOD_EVENT_SIDES)[number];
9
+ export type ModBusSide = Exclude<ModEventSide, "both">;
10
+ export declare const MOD_FAILURE_ANSWERS: readonly ["refuse", "skip"];
11
+ export type ModFailureAnswer = (typeof MOD_FAILURE_ANSWERS)[number];
12
+ export declare const MOD_ABORT_POSTURES: readonly ["immediate", "grace", "caller"];
13
+ export type ModAbortPosture = (typeof MOD_ABORT_POSTURES)[number];
14
+ export declare const NEXT_TO_TABLE: Readonly<{
15
+ prepend: readonly ["append", "builtin", "core"];
16
+ user: readonly [];
17
+ append: readonly ["core"];
18
+ builtin: readonly [];
19
+ core: readonly [];
20
+ }>;
21
+ export declare function nextToRefusal(from: ModTier, to: unknown): string | undefined;
22
+ export declare const SEAT_TIER_TABLE: Readonly<{
23
+ deployment: Readonly<{
24
+ declared: "required";
25
+ tiers: readonly ["prepend", "user", "append"];
26
+ }>;
27
+ task: Readonly<{
28
+ declared: "optional";
29
+ tiers: readonly ["user"];
30
+ }>;
31
+ }>;
32
+ export interface ModStation {
33
+ readonly failure: ModFailureAnswer;
34
+ readonly abort: ModAbortPosture;
35
+ readonly pinned: readonly string[];
36
+ readonly method?: {
37
+ readonly pausesCallerBudget: boolean;
38
+ };
39
+ }
40
+ export interface ModEventRow {
41
+ readonly side: ModEventSide;
42
+ readonly station?: ModStation;
43
+ }
44
+ export declare const MOD_EVENT_TABLE: Readonly<{
45
+ "classic.PreToolUse": ModEventRow;
46
+ "classic.PostToolUse": ModEventRow;
47
+ "classic.PostToolUseFailure": ModEventRow;
48
+ "classic.PostToolBatch": ModEventRow;
49
+ "classic.Notification": ModEventRow;
50
+ "classic.UserPromptSubmit": ModEventRow;
51
+ "classic.UserPromptExpansion": ModEventRow;
52
+ "classic.SessionStart": ModEventRow;
53
+ "classic.SessionEnd": ModEventRow;
54
+ "classic.Stop": ModEventRow;
55
+ "classic.StopFailure": ModEventRow;
56
+ "classic.SubagentStart": ModEventRow;
57
+ "classic.SubagentStop": ModEventRow;
58
+ "classic.PreCompact": ModEventRow;
59
+ "classic.PostCompact": ModEventRow;
60
+ "classic.PreModelSwitch": ModEventRow;
61
+ "classic.PostModelSwitch": ModEventRow;
62
+ "classic.PermissionRequest": ModEventRow;
63
+ "classic.PermissionDenied": ModEventRow;
64
+ "classic.Setup": ModEventRow;
65
+ "classic.TeammateIdle": ModEventRow;
66
+ "classic.TaskCreated": ModEventRow;
67
+ "classic.TaskCompleted": ModEventRow;
68
+ "classic.Elicitation": ModEventRow;
69
+ "classic.ElicitationResult": ModEventRow;
70
+ "classic.ConfigChange": ModEventRow;
71
+ "classic.WorktreeCreate": ModEventRow;
72
+ "classic.WorktreeRemove": ModEventRow;
73
+ "classic.InstructionsLoaded": ModEventRow;
74
+ "classic.CwdChanged": ModEventRow;
75
+ "classic.FileChanged": ModEventRow;
76
+ "classic.DirectoryAdded": ModEventRow;
77
+ "classic.MessageDisplay": ModEventRow;
78
+ "tool.call": ModEventRow;
79
+ "tool.check": ModEventRow;
80
+ "ui.render": ModEventRow;
81
+ "ui.resolve": ModEventRow;
82
+ "ui.press": ModEventRow;
83
+ "ui.input": ModEventRow;
84
+ "ui.select": ModEventRow;
85
+ "ui.message": ModEventRow;
86
+ "ui.fault": ModEventRow;
87
+ "ui.scroll": ModEventRow;
88
+ "ui.focus": ModEventRow;
89
+ "agent.offer": ModEventRow;
90
+ "agent.spawn": ModEventRow;
91
+ "prompt.submit": ModEventRow;
92
+ "prompt.fill": ModEventRow;
93
+ "prompt.suggest": ModEventRow;
94
+ "prompt.edit": ModEventRow;
95
+ "prompt.autocomplete": ModEventRow;
96
+ "prompt.section": ModEventRow;
97
+ "prompt.context": ModEventRow;
98
+ "prompt.attachment": ModEventRow;
99
+ "prompt.mention": ModEventRow;
100
+ "prompt.compose": ModEventRow;
101
+ "tool.describe": ModEventRow;
102
+ "command.run": ModEventRow;
103
+ "command.describe": ModEventRow;
104
+ "config.set": ModEventRow;
105
+ "config.describe": ModEventRow;
106
+ "telemetry.log": ModEventRow;
107
+ "telemetry.mark": ModEventRow;
108
+ "skill.prompt": ModEventRow;
109
+ "attribution.text": ModEventRow;
110
+ "session.start": ModEventRow;
111
+ "session.receive": ModEventRow;
112
+ "session.append": ModEventRow;
113
+ "session.send": ModEventRow;
114
+ "session.compact": ModEventRow;
115
+ "session.attach": ModEventRow;
116
+ "session.detach": ModEventRow;
117
+ "session.measure": ModEventRow;
118
+ "session.end": ModEventRow;
119
+ "plugin.register": Readonly<{
120
+ side: "both";
121
+ station: ModStation;
122
+ }>;
123
+ "turn.start": ModEventRow;
124
+ "turn.step": ModEventRow;
125
+ "turn.complete": ModEventRow;
126
+ "engine.create": ModEventRow;
127
+ "model.complete": ModEventRow;
128
+ "model.classify": ModEventRow;
129
+ "model.fork": ModEventRow;
130
+ "audio.play": ModEventRow;
131
+ "audio.speak": ModEventRow;
132
+ "mcp.call": ModEventRow;
133
+ "mcp.connect": ModEventRow;
134
+ "session.cwd": ModEventRow;
135
+ "session.root": ModEventRow;
136
+ "session.model": ModEventRow;
137
+ "session.turns": ModEventRow;
138
+ "session.id": ModEventRow;
139
+ "session.messages": ModEventRow;
140
+ "session.repo": ModEventRow;
141
+ "session.surface": ModEventRow;
142
+ "session.surfaces": ModEventRow;
143
+ "session.authorize": ModEventRow;
144
+ "session.usage": ModEventRow;
145
+ "session.version": ModEventRow;
146
+ "turn.abort": ModEventRow;
147
+ "prompt.read": ModEventRow;
148
+ "flag.value": ModEventRow;
149
+ "tool.list": ModEventRow;
150
+ "tool.register": ModEventRow;
151
+ "command.list": ModEventRow;
152
+ "command.register": ModEventRow;
153
+ "config.list": ModEventRow;
154
+ "agent.list": ModEventRow;
155
+ "agent.register": ModEventRow;
156
+ "ui.toast": ModEventRow;
157
+ "ui.status": ModEventRow;
158
+ "ui.log": ModEventRow;
159
+ "ui.notice": ModEventRow;
160
+ "ui.invalidate": ModEventRow;
161
+ "ui.open": ModEventRow;
162
+ "ui.close": ModEventRow;
163
+ "ui.panes": ModEventRow;
164
+ "ui.selection": ModEventRow;
165
+ "ui.copy": ModEventRow;
166
+ "ui.notify": ModEventRow;
167
+ "ui.blit": ModEventRow;
168
+ "fs.read": ModEventRow;
169
+ "fs.write": ModEventRow;
170
+ "fs.list": ModEventRow;
171
+ "fs.exists": ModEventRow;
172
+ "fs.stat": ModEventRow;
173
+ "fs.ancestors": ModEventRow;
174
+ "store.get": ModEventRow;
175
+ "store.set": ModEventRow;
176
+ "store.delete": ModEventRow;
177
+ "store.keys": ModEventRow;
178
+ "state.get": ModEventRow;
179
+ "state.set": ModEventRow;
180
+ "clock.now": ModEventRow;
181
+ "clock.sleep": ModEventRow;
182
+ "clock.after": ModEventRow;
183
+ "clock.every": ModEventRow;
184
+ "http.fetch": ModEventRow;
185
+ "process.run": ModEventRow;
186
+ "process.spawn": ModEventRow;
187
+ "settings.read": ModEventRow;
188
+ "env.get": ModEventRow;
189
+ "env.set": ModEventRow;
190
+ }>;
191
+ export type ModEventName = keyof typeof MOD_EVENT_TABLE;
192
+ export declare function isModEventName(name: unknown): name is ModEventName;
193
+ export declare function stationOn(name: ModEventName, side: ModBusSide): ModStation | undefined;
194
+ export declare function readOnSide(name: ModEventName, side: ModBusSide): boolean;
195
+ export declare function expandModPattern(pattern: unknown): {
196
+ readonly names: readonly ModEventName[];
197
+ } | {
198
+ readonly refusal: string;
199
+ };
200
+ export declare function describe(value: unknown): string;
package/dist/events.js ADDED
@@ -0,0 +1,210 @@
1
+ export const KERNEL_CONTRACT_VERSION = 2;
2
+ export const MOD_TIERS = Object.freeze(["prepend", "user", "append", "builtin", "core"]);
3
+ export const MOD_SEATS = Object.freeze(["deployment", "task"]);
4
+ export const MOD_EVENT_SIDES = Object.freeze(["engine", "surface", "both"]);
5
+ export const MOD_FAILURE_ANSWERS = Object.freeze(["refuse", "skip"]);
6
+ export const MOD_ABORT_POSTURES = Object.freeze(["immediate", "grace", "caller"]);
7
+ export const NEXT_TO_TABLE = Object.freeze({
8
+ prepend: Object.freeze(["append", "builtin", "core"]),
9
+ user: Object.freeze([]),
10
+ append: Object.freeze(["core"]),
11
+ builtin: Object.freeze([]),
12
+ core: Object.freeze([]),
13
+ });
14
+ const CONTINUABLE = NEXT_TO_TABLE.prepend;
15
+ export function nextToRefusal(from, to) {
16
+ const allowed = NEXT_TO_TABLE[from];
17
+ const named = CONTINUABLE.find((t) => t === to);
18
+ if (named === undefined)
19
+ return `next.to names ${describe(to)}, which is not a tier a dispatch continues at (${CONTINUABLE.join(", ")})`;
20
+ if (allowed.length === 0)
21
+ return `next.to is available to prepend and append handlers only, not to a ${from} handler`;
22
+ if (!allowed.includes(named))
23
+ return `next.to("${named}") skips nothing from ${from}; a ${from} handler may continue at ${allowed.join(", ")}`;
24
+ return undefined;
25
+ }
26
+ export const SEAT_TIER_TABLE = Object.freeze({
27
+ deployment: Object.freeze({ declared: "required", tiers: Object.freeze(["prepend", "user", "append"]) }),
28
+ task: Object.freeze({ declared: "optional", tiers: Object.freeze(["user"]) }),
29
+ });
30
+ const station = (failure, abort, pinned = []) => Object.freeze({ failure, abort, pinned: Object.freeze([...pinned]) });
31
+ const method = (pausesCallerBudget) => Object.freeze({ failure: "skip", abort: "caller", pinned: Object.freeze([]), method: Object.freeze({ pausesCallerBudget }) });
32
+ const engine = (s) => Object.freeze(s === undefined ? { side: "engine" } : { side: "engine", station: s });
33
+ const surface = Object.freeze({ side: "surface" });
34
+ export const MOD_EVENT_TABLE = Object.freeze({
35
+ "classic.PreToolUse": engine(station("refuse", "immediate", ["tool", "tool_use_id", "agentId", "input"])),
36
+ "classic.PostToolUse": engine(station("skip", "grace")),
37
+ "classic.PostToolUseFailure": engine(station("skip", "grace")),
38
+ "classic.PostToolBatch": engine(station("skip", "grace")),
39
+ "classic.Notification": engine(),
40
+ "classic.UserPromptSubmit": engine(station("refuse", "immediate", ["source", "inputId", "actor", "prompt"])),
41
+ "classic.UserPromptExpansion": engine(),
42
+ "classic.SessionStart": engine(),
43
+ "classic.SessionEnd": engine(),
44
+ "classic.Stop": engine(station("skip", "immediate")),
45
+ "classic.StopFailure": engine(station("skip", "grace")),
46
+ "classic.SubagentStart": engine(),
47
+ "classic.SubagentStop": engine(station("skip", "immediate")),
48
+ "classic.PreCompact": engine(station("skip", "grace")),
49
+ "classic.PostCompact": engine(station("skip", "grace")),
50
+ "classic.PreModelSwitch": engine(),
51
+ "classic.PostModelSwitch": engine(),
52
+ "classic.PermissionRequest": engine(),
53
+ "classic.PermissionDenied": engine(station("skip", "grace")),
54
+ "classic.Setup": engine(),
55
+ "classic.TeammateIdle": engine(),
56
+ "classic.TaskCreated": engine(),
57
+ "classic.TaskCompleted": engine(),
58
+ "classic.Elicitation": engine(),
59
+ "classic.ElicitationResult": engine(),
60
+ "classic.ConfigChange": engine(),
61
+ "classic.WorktreeCreate": engine(),
62
+ "classic.WorktreeRemove": engine(),
63
+ "classic.InstructionsLoaded": engine(),
64
+ "classic.CwdChanged": engine(),
65
+ "classic.FileChanged": engine(),
66
+ "classic.DirectoryAdded": engine(),
67
+ "classic.MessageDisplay": engine(),
68
+ "tool.call": engine(),
69
+ "tool.check": engine(station("refuse", "immediate", ["tool", "input", "tool_use_id", "agentId", "ceiling"])),
70
+ "ui.render": surface,
71
+ "ui.resolve": surface,
72
+ "ui.press": surface,
73
+ "ui.input": surface,
74
+ "ui.select": surface,
75
+ "ui.message": surface,
76
+ "ui.fault": surface,
77
+ "ui.scroll": surface,
78
+ "ui.focus": surface,
79
+ "agent.offer": engine(),
80
+ "agent.spawn": engine(),
81
+ "prompt.submit": engine(),
82
+ "prompt.fill": surface,
83
+ "prompt.suggest": surface,
84
+ "prompt.edit": surface,
85
+ "prompt.autocomplete": surface,
86
+ "prompt.section": engine(station("skip", "grace", ["name", "key", "mountedTools"])),
87
+ "prompt.context": engine(),
88
+ "prompt.attachment": engine(),
89
+ "prompt.mention": surface,
90
+ "prompt.compose": engine(station("skip", "grace", ["model", "catalog", "selectors"])),
91
+ "tool.describe": engine(),
92
+ "command.run": surface,
93
+ "command.describe": surface,
94
+ "config.set": surface,
95
+ "config.describe": surface,
96
+ "telemetry.log": engine(),
97
+ "telemetry.mark": engine(),
98
+ "skill.prompt": engine(),
99
+ "attribution.text": engine(),
100
+ "session.start": engine(),
101
+ "session.receive": engine(),
102
+ "session.append": engine(),
103
+ "session.send": engine(),
104
+ "session.compact": engine(),
105
+ "session.attach": engine(),
106
+ "session.detach": engine(),
107
+ "session.measure": engine(),
108
+ "session.end": engine(),
109
+ "plugin.register": Object.freeze({ side: "both", station: station("skip", "immediate", ["name", "seat", "tier", "uses"]) }),
110
+ "turn.start": engine(),
111
+ "turn.step": engine(),
112
+ "turn.complete": engine(),
113
+ "engine.create": engine(),
114
+ "model.complete": engine(method(true)),
115
+ "model.classify": engine(),
116
+ "model.fork": engine(),
117
+ "audio.play": surface,
118
+ "audio.speak": surface,
119
+ "mcp.call": engine(),
120
+ "mcp.connect": engine(),
121
+ "session.cwd": engine(method(true)),
122
+ "session.root": engine(method(true)),
123
+ "session.model": engine(method(true)),
124
+ "session.turns": engine(),
125
+ "session.id": engine(method(true)),
126
+ "session.messages": engine(method(true)),
127
+ "session.repo": engine(),
128
+ "session.surface": engine(),
129
+ "session.surfaces": engine(),
130
+ "session.authorize": engine(),
131
+ "session.usage": engine(),
132
+ "session.version": engine(),
133
+ "turn.abort": engine(),
134
+ "prompt.read": surface,
135
+ "flag.value": engine(),
136
+ "tool.list": engine(method(true)),
137
+ "tool.register": engine(),
138
+ "command.list": surface,
139
+ "command.register": surface,
140
+ "config.list": surface,
141
+ "agent.list": engine(method(true)),
142
+ "agent.register": engine(),
143
+ "ui.toast": surface,
144
+ "ui.status": surface,
145
+ "ui.log": surface,
146
+ "ui.notice": surface,
147
+ "ui.invalidate": surface,
148
+ "ui.open": surface,
149
+ "ui.close": surface,
150
+ "ui.panes": surface,
151
+ "ui.selection": surface,
152
+ "ui.copy": surface,
153
+ "ui.notify": surface,
154
+ "ui.blit": surface,
155
+ "fs.read": engine(),
156
+ "fs.write": engine(),
157
+ "fs.list": engine(),
158
+ "fs.exists": engine(),
159
+ "fs.stat": engine(),
160
+ "fs.ancestors": engine(),
161
+ "store.get": engine(),
162
+ "store.set": engine(),
163
+ "store.delete": engine(),
164
+ "store.keys": engine(),
165
+ "state.get": engine(),
166
+ "state.set": engine(),
167
+ "clock.now": engine(method(false)),
168
+ "clock.sleep": engine(method(false)),
169
+ "clock.after": engine(),
170
+ "clock.every": engine(),
171
+ "http.fetch": engine(),
172
+ "process.run": engine(method(true)),
173
+ "process.spawn": engine(),
174
+ "settings.read": engine(),
175
+ "env.get": engine(),
176
+ "env.set": engine(),
177
+ });
178
+ const EVENT_NAMES = Object.freeze(Object.keys(MOD_EVENT_TABLE).filter(isModEventName));
179
+ export function isModEventName(name) {
180
+ return typeof name === "string" && Object.prototype.hasOwnProperty.call(MOD_EVENT_TABLE, name);
181
+ }
182
+ export function stationOn(name, side) {
183
+ const row = MOD_EVENT_TABLE[name];
184
+ return row.side === side || row.side === "both" ? row.station : undefined;
185
+ }
186
+ export function readOnSide(name, side) {
187
+ const row = MOD_EVENT_TABLE[name];
188
+ return row.side === side || row.side === "both";
189
+ }
190
+ export function expandModPattern(pattern) {
191
+ if (typeof pattern !== "string" || pattern === "")
192
+ return { refusal: `${describe(pattern)} is not an event name or a "<prefix>.*" pattern` };
193
+ if (pattern.endsWith(".*")) {
194
+ const prefix = pattern.slice(0, -2);
195
+ if (prefix === "" || prefix.includes("*"))
196
+ return { refusal: `"${pattern}" is not an event name or a "<prefix>.*" pattern` };
197
+ const names = EVENT_NAMES.filter((n) => n.startsWith(`${prefix}.`));
198
+ return names.length > 0 ? { names } : { refusal: `"${pattern}" selects no event` };
199
+ }
200
+ return isModEventName(pattern) ? { names: [pattern] } : { refusal: `"${pattern}" is not an event` };
201
+ }
202
+ export function describe(value) {
203
+ if (typeof value === "string")
204
+ return `"${value}"`;
205
+ if (typeof value === "number" || typeof value === "boolean")
206
+ return String(value);
207
+ if (value === null)
208
+ return "null";
209
+ return typeof value === "object" ? (Array.isArray(value) ? "an array" : "an object") : typeof value;
210
+ }
@@ -0,0 +1,5 @@
1
+ export { KERNEL_CONTRACT_VERSION, MOD_TIERS, MOD_SEATS, MOD_EVENT_SIDES, MOD_FAILURE_ANSWERS, MOD_ABORT_POSTURES, NEXT_TO_TABLE, SEAT_TIER_TABLE, MOD_EVENT_TABLE, nextToRefusal, expandModPattern, isModEventName, stationOn, readOnSide, type ModTier, type ModRegistrationTier, type ModSeat, type ModEventSide, type ModBusSide, type ModFailureAnswer, type ModAbortPosture, type ModStation, type ModEventRow, type ModEventName, } from "./events.js";
2
+ export { DEFAULT_MOD_BUDGET_MS, CATCH_BUDGET_MS, RUNAWAY_AFTER_MS, POST_ABORT_GRACE_MS, MAX_TIMER_MS, resolveModBudgetMs, type ModBudgetReading, } from "./budget.js";
3
+ export { MOD_FAILURE_CAUSES, type ModFailureCause, type ModEventPayload, type ModAnswerCheck, type ModAnswerer, type ModMatcher, type ModSkip } from "./site-rules.js";
4
+ export { ENGINE_ORIGIN, MODS_INVALID_CODE, MODS_REGISTRATION_REFUSED_CODE, MOD_TRACE_OUTCOMES, type ModTraceOutcome, type ModUses, type ModOrigin, type ModPluginFacts, type ModDollarBase, type ModTraceEntry, type ModCaughtError, type ModNext, type ModHandler, type ModHandlerOptions, type On, type ModRegistration, type ModAdmissionRecord, type ModSeats, } from "./registration.js";
5
+ export { admitMods, type ModFrame, type ModBottomContext, type ModMethodBottom, type ModMethodSeat, type ModMethodBottoms, type ModDispatchOutcome, type ModDispatchOptions, type ModBus, type ModMountedHandler, type ModBusInput, } from "./dispatch.js";
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { KERNEL_CONTRACT_VERSION, MOD_TIERS, MOD_SEATS, MOD_EVENT_SIDES, MOD_FAILURE_ANSWERS, MOD_ABORT_POSTURES, NEXT_TO_TABLE, SEAT_TIER_TABLE, MOD_EVENT_TABLE, nextToRefusal, expandModPattern, isModEventName, stationOn, readOnSide, } from "./events.js";
2
+ export { DEFAULT_MOD_BUDGET_MS, CATCH_BUDGET_MS, RUNAWAY_AFTER_MS, POST_ABORT_GRACE_MS, MAX_TIMER_MS, resolveModBudgetMs, } from "./budget.js";
3
+ export { MOD_FAILURE_CAUSES } from "./site-rules.js";
4
+ export { ENGINE_ORIGIN, MODS_INVALID_CODE, MODS_REGISTRATION_REFUSED_CODE, MOD_TRACE_OUTCOMES, } from "./registration.js";
5
+ export { admitMods, } from "./dispatch.js";
@@ -0,0 +1,27 @@
1
+ export interface ReceiptMode {
2
+ readonly accessors: "call-once" | "refuse";
3
+ readonly depth: number;
4
+ readonly others: "as-is" | "refuse" | "copy";
5
+ readonly past?: "refuse";
6
+ readonly contain?: true;
7
+ readonly freeze?: boolean;
8
+ readonly isProxy?: (value: object) => boolean;
9
+ }
10
+ export declare const RECEIPT_FAULTS: readonly ["proxy", "accessor", "hidden", "getter-threw", "prototype-moved", "not-data", "cycle", "too-deep", "uncopyable"];
11
+ export type ReceiptFaultKind = (typeof RECEIPT_FAULTS)[number];
12
+ export interface ReceiptFault {
13
+ readonly kind: ReceiptFaultKind;
14
+ readonly path: readonly string[];
15
+ }
16
+ export type Receipt = {
17
+ readonly ok: true;
18
+ readonly value: unknown;
19
+ readonly faults?: readonly ReceiptFault[];
20
+ } | {
21
+ readonly ok: false;
22
+ readonly fault: ReceiptFault;
23
+ };
24
+ export declare function isPlainRecord(v: unknown): v is Record<string, unknown>;
25
+ export declare function receive(value: unknown, mode: ReceiptMode, held?: ReadonlySet<object>): Receipt;
26
+ export declare const MODS_PAYLOAD_MODE: ReceiptMode;
27
+ export declare function describeFault(fault: ReceiptFault): string;
@@ -0,0 +1,193 @@
1
+ export const RECEIPT_FAULTS = Object.freeze(["proxy", "accessor", "hidden", "getter-threw", "prototype-moved", "not-data", "cycle", "too-deep", "uncopyable"]);
2
+ export function isPlainRecord(v) {
3
+ if (typeof v !== "object" || v === null || Array.isArray(v))
4
+ return false;
5
+ const proto = Object.getPrototypeOf(v);
6
+ return proto === Object.prototype || proto === null;
7
+ }
8
+ function isOrdinaryArray(v) {
9
+ return Array.isArray(v) && Object.getPrototypeOf(v) === Array.prototype;
10
+ }
11
+ export function receive(value, mode, held) {
12
+ const seen = new Map();
13
+ const path = [];
14
+ const open = new Set();
15
+ const heights = new Map();
16
+ const faults = [];
17
+ const refusedAt = new Map();
18
+ const stack = [];
19
+ const refusals = new Set();
20
+ const refuse = (kind) => {
21
+ const fault = Object.freeze({ kind, path: Object.freeze([...path]) });
22
+ refusals.add(fault);
23
+ throw fault;
24
+ };
25
+ const faultOf = (err) => typeof err === "object" && err !== null && refusals.has(err) ? err : Object.freeze({ kind: "uncopyable", path: Object.freeze([...path]) });
26
+ const other = (v, kind) => (mode.others === "as-is" ? v : refuse(kind));
27
+ const refuseContainer = (v, kind) => {
28
+ if (mode.contain === true) {
29
+ refusedAt.set(v, kind);
30
+ open.delete(v);
31
+ }
32
+ return refuse(kind);
33
+ };
34
+ const memberOf = (v, d) => {
35
+ if (Object.hasOwn(d, "value")) {
36
+ if (mode.accessors === "refuse" && d.enumerable !== true)
37
+ refuse("hidden");
38
+ return d.value;
39
+ }
40
+ if (mode.accessors === "refuse")
41
+ refuse("accessor");
42
+ const get = Object.hasOwn(d, "get") ? d.get : undefined;
43
+ try {
44
+ return get === undefined ? undefined : Reflect.apply(get, v, []);
45
+ }
46
+ catch {
47
+ return refuse("getter-threw");
48
+ }
49
+ };
50
+ const measured = mode.past === "refuse" || mode.others !== "as-is";
51
+ const heightOf = (v) => heights.get(v) ?? (open.has(v) || (held?.has(v) === true && mode.isProxy?.(v) !== true && (isOrdinaryArray(v) || isPlainRecord(v))) ? 1 : 0);
52
+ const pastDepth = (v, level) => measured && level + heightOf(v) > mode.depth;
53
+ const meet = (v, level) => {
54
+ if (v === null || v === undefined || typeof v === "string" || typeof v === "number" || typeof v === "boolean")
55
+ return v;
56
+ if (typeof v !== "object")
57
+ return other(v, "not-data");
58
+ if (held?.has(v) === true)
59
+ return pastDepth(v, level) ? refuse("too-deep") : v;
60
+ if (seen.has(v)) {
61
+ if (refusedAt.has(v))
62
+ return refuse(refusedAt.get(v));
63
+ if (open.has(v) && mode.others !== "as-is")
64
+ return refuse("cycle");
65
+ return pastDepth(v, level) ? refuse("too-deep") : seen.get(v);
66
+ }
67
+ if (level >= mode.depth && mode.past === "refuse") {
68
+ if (mode.isProxy?.(v) === true)
69
+ return refuse("proxy");
70
+ if (isOrdinaryArray(v) || isPlainRecord(v))
71
+ return refuse("too-deep");
72
+ }
73
+ if (level >= mode.depth)
74
+ return other(v, "too-deep");
75
+ if (mode.isProxy?.(v) === true)
76
+ return refuse("proxy");
77
+ const list = isOrdinaryArray(v) || (mode.others === "copy" && Array.isArray(v));
78
+ if (!list && !isPlainRecord(v) && mode.others !== "copy")
79
+ return other(v, "not-data");
80
+ const proto = Object.getPrototypeOf(v);
81
+ const captured = Object.getOwnPropertyDescriptors(v);
82
+ const out = list ? [] : {};
83
+ seen.set(v, out);
84
+ open.add(v);
85
+ if (mode.accessors === "refuse") {
86
+ const symbols = Object.getOwnPropertySymbols(captured);
87
+ if (symbols.length > 0 && mode.contain !== true)
88
+ refuseContainer(v, "hidden");
89
+ for (const s of symbols)
90
+ faults.push(Object.freeze({ kind: "hidden", path: Object.freeze([...path, String(s)]) }));
91
+ }
92
+ stack.push({ v, out, list, proto, captured, keys: Object.getOwnPropertyNames(captured), level, next: 0, height: 1, key: "", member: undefined });
93
+ return out;
94
+ };
95
+ const land = (f, key, copy, member) => {
96
+ if (measured && typeof member === "object" && member !== null)
97
+ f.height = Math.max(f.height, heightOf(member) + 1);
98
+ Object.defineProperty(f.out, key, { value: copy, enumerable: true, writable: true, configurable: true });
99
+ path.length = f.level;
100
+ };
101
+ const finish = (f) => {
102
+ heights.set(f.v, f.height);
103
+ if (mode.accessors === "call-once" && mode.others !== "copy" && Object.getPrototypeOf(f.v) !== f.proto)
104
+ refuseContainer(f.v, "prototype-moved");
105
+ if (Array.isArray(f.out)) {
106
+ const length = f.captured["length"]?.value;
107
+ if (typeof length === "number")
108
+ f.out.length = length;
109
+ }
110
+ if (mode.freeze === true)
111
+ Object.freeze(f.out);
112
+ open.delete(f.v);
113
+ return f.out;
114
+ };
115
+ const received = (copy) => (mode.contain === true ? { ok: true, value: copy, faults: Object.freeze(faults) } : { ok: true, value: copy });
116
+ try {
117
+ const copy = meet(value, 0);
118
+ if (stack.length === 0)
119
+ return received(copy);
120
+ }
121
+ catch (err) {
122
+ return { ok: false, fault: faultOf(err) };
123
+ }
124
+ for (;;) {
125
+ const f = stack[stack.length - 1];
126
+ if (f.next < f.keys.length) {
127
+ const key = f.keys[f.next++];
128
+ if (f.list && key === "length")
129
+ continue;
130
+ path.push(key);
131
+ try {
132
+ const member = memberOf(f.v, f.captured[key]);
133
+ const frames = stack.length;
134
+ const copy = meet(member, f.level + 1);
135
+ if (stack.length > frames) {
136
+ f.key = key;
137
+ f.member = member;
138
+ }
139
+ else
140
+ land(f, key, copy, member);
141
+ }
142
+ catch (err) {
143
+ if (mode.contain !== true)
144
+ return { ok: false, fault: faultOf(err) };
145
+ faults.push(faultOf(err));
146
+ path.length = f.level;
147
+ }
148
+ continue;
149
+ }
150
+ let copy;
151
+ try {
152
+ copy = finish(f);
153
+ }
154
+ catch (err) {
155
+ stack.pop();
156
+ const holder = stack[stack.length - 1];
157
+ if (mode.contain !== true || holder === undefined)
158
+ return { ok: false, fault: faultOf(err) };
159
+ faults.push(faultOf(err));
160
+ path.length = holder.level;
161
+ continue;
162
+ }
163
+ stack.pop();
164
+ const holder = stack[stack.length - 1];
165
+ if (holder === undefined)
166
+ return received(copy);
167
+ land(holder, holder.key, copy, holder.member);
168
+ }
169
+ }
170
+ export const MODS_PAYLOAD_MODE = Object.freeze({ accessors: "refuse", depth: Infinity, others: "as-is", freeze: true });
171
+ export function describeFault(fault) {
172
+ const at = fault.path.length > 0 ? ` at ${fault.path.join(".")}` : "";
173
+ switch (fault.kind) {
174
+ case "proxy":
175
+ return `a Proxy${at}`;
176
+ case "accessor":
177
+ return `an accessor${at} (a getter is never run)`;
178
+ case "hidden":
179
+ return `a member that is not an enumerable data property${at}`;
180
+ case "getter-threw":
181
+ return `a getter that threw${at}`;
182
+ case "prototype-moved":
183
+ return `a prototype that moved while it was read${at}`;
184
+ case "not-data":
185
+ return `a value that is not data${at}`;
186
+ case "cycle":
187
+ return `a cycle${at}`;
188
+ case "too-deep":
189
+ return `a value nested too deep${at}`;
190
+ case "uncopyable":
191
+ return `a value that could not be copied whole${at}`;
192
+ }
193
+ }