@inbrowser/agent 0.0.0-placeholder → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +270 -0
- package/LICENSE +21 -0
- package/README.md +117 -2
- package/bin/agent.ts +10 -0
- package/dist/cli/commands/describe.d.ts +14 -0
- package/dist/cli/commands/describe.d.ts.map +1 -0
- package/dist/cli/commands/describe.js +179 -0
- package/dist/cli/commands/describe.js.map +1 -0
- package/dist/cli/commands/events.d.ts +21 -0
- package/dist/cli/commands/events.d.ts.map +1 -0
- package/dist/cli/commands/events.js +59 -0
- package/dist/cli/commands/events.js.map +1 -0
- package/dist/cli/commands/fleet.d.ts +15 -0
- package/dist/cli/commands/fleet.d.ts.map +1 -0
- package/dist/cli/commands/fleet.js +149 -0
- package/dist/cli/commands/fleet.js.map +1 -0
- package/dist/cli/commands/help.d.ts +15 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +93 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +27 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +109 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/run.d.ts +38 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +535 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/schema.d.ts +8 -0
- package/dist/cli/commands/schema.d.ts.map +1 -0
- package/dist/cli/commands/schema.js +12 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +39 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +65 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/undo.d.ts +36 -0
- package/dist/cli/commands/undo.d.ts.map +1 -0
- package/dist/cli/commands/undo.js +132 -0
- package/dist/cli/commands/undo.js.map +1 -0
- package/dist/cli/fixtures.d.ts +17 -0
- package/dist/cli/fixtures.d.ts.map +1 -0
- package/dist/cli/fixtures.js +107 -0
- package/dist/cli/fixtures.js.map +1 -0
- package/dist/cli/hardening.d.ts +39 -0
- package/dist/cli/hardening.d.ts.map +1 -0
- package/dist/cli/hardening.js +68 -0
- package/dist/cli/hardening.js.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +19 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/llm/openrouter.d.ts +33 -0
- package/dist/cli/llm/openrouter.d.ts.map +1 -0
- package/dist/cli/llm/openrouter.js +285 -0
- package/dist/cli/llm/openrouter.js.map +1 -0
- package/dist/cli/main.d.ts +32 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +106 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.d.ts +36 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +95 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse.d.ts +26 -0
- package/dist/cli/parse.d.ts.map +1 -0
- package/dist/cli/parse.js +160 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/cli/session-log.d.ts +34 -0
- package/dist/cli/session-log.d.ts.map +1 -0
- package/dist/cli/session-log.js +52 -0
- package/dist/cli/session-log.js.map +1 -0
- package/dist/cli/spec.d.ts +62 -0
- package/dist/cli/spec.d.ts.map +1 -0
- package/dist/cli/spec.js +510 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/cli/ui/RunView.d.ts +134 -0
- package/dist/cli/ui/RunView.d.ts.map +1 -0
- package/dist/cli/ui/RunView.js +341 -0
- package/dist/cli/ui/RunView.js.map +1 -0
- package/dist/diagnostics/index.d.ts +5 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +3 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/diagnostics/timing.d.ts +48 -0
- package/dist/diagnostics/timing.d.ts.map +1 -0
- package/dist/diagnostics/timing.js +85 -0
- package/dist/diagnostics/timing.js.map +1 -0
- package/dist/diagnostics/truthfulness.d.ts +36 -0
- package/dist/diagnostics/truthfulness.d.ts.map +1 -0
- package/dist/diagnostics/truthfulness.js +180 -0
- package/dist/diagnostics/truthfulness.js.map +1 -0
- package/dist/dispatch-memoization.d.ts +84 -0
- package/dist/dispatch-memoization.d.ts.map +1 -0
- package/dist/dispatch-memoization.js +197 -0
- package/dist/dispatch-memoization.js.map +1 -0
- package/dist/eval/comparison-report.d.ts +164 -0
- package/dist/eval/comparison-report.d.ts.map +1 -0
- package/dist/eval/comparison-report.js +316 -0
- package/dist/eval/comparison-report.js.map +1 -0
- package/dist/eval/fixture.d.ts +74 -0
- package/dist/eval/fixture.d.ts.map +1 -0
- package/dist/eval/fixture.js +217 -0
- package/dist/eval/fixture.js.map +1 -0
- package/dist/eval/index.d.ts +13 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +7 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/load-node.d.ts +16 -0
- package/dist/eval/load-node.d.ts.map +1 -0
- package/dist/eval/load-node.js +58 -0
- package/dist/eval/load-node.js.map +1 -0
- package/dist/eval/metric-collector.d.ts +209 -0
- package/dist/eval/metric-collector.d.ts.map +1 -0
- package/dist/eval/metric-collector.js +293 -0
- package/dist/eval/metric-collector.js.map +1 -0
- package/dist/eval/run-record.d.ts +76 -0
- package/dist/eval/run-record.d.ts.map +1 -0
- package/dist/eval/run-record.js +32 -0
- package/dist/eval/run-record.js.map +1 -0
- package/dist/eval/runner.d.ts +140 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +310 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/spec-framework.d.ts +113 -0
- package/dist/eval/spec-framework.d.ts.map +1 -0
- package/dist/eval/spec-framework.js +100 -0
- package/dist/eval/spec-framework.js.map +1 -0
- package/dist/eval/spec-helpers.d.ts +245 -0
- package/dist/eval/spec-helpers.d.ts.map +1 -0
- package/dist/eval/spec-helpers.js +605 -0
- package/dist/eval/spec-helpers.js.map +1 -0
- package/dist/events/codec.d.ts +79 -0
- package/dist/events/codec.d.ts.map +1 -0
- package/dist/events/codec.js +142 -0
- package/dist/events/codec.js.map +1 -0
- package/dist/events/log-core.d.ts +76 -0
- package/dist/events/log-core.d.ts.map +1 -0
- package/dist/events/log-core.js +73 -0
- package/dist/events/log-core.js.map +1 -0
- package/dist/events/log.d.ts +60 -0
- package/dist/events/log.d.ts.map +1 -0
- package/dist/events/log.js +193 -0
- package/dist/events/log.js.map +1 -0
- package/dist/events/replay.d.ts +106 -0
- package/dist/events/replay.d.ts.map +1 -0
- package/dist/events/replay.js +137 -0
- package/dist/events/replay.js.map +1 -0
- package/dist/events/wrap.d.ts +100 -0
- package/dist/events/wrap.d.ts.map +1 -0
- package/dist/events/wrap.js +141 -0
- package/dist/events/wrap.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-adapter.d.ts +96 -0
- package/dist/llm-adapter.d.ts.map +1 -0
- package/dist/llm-adapter.js +132 -0
- package/dist/llm-adapter.js.map +1 -0
- package/dist/mcp/serve.d.ts +70 -0
- package/dist/mcp/serve.d.ts.map +1 -0
- package/dist/mcp/serve.js +154 -0
- package/dist/mcp/serve.js.map +1 -0
- package/dist/metrics/runs.d.ts +58 -0
- package/dist/metrics/runs.d.ts.map +1 -0
- package/dist/metrics/runs.js +99 -0
- package/dist/metrics/runs.js.map +1 -0
- package/dist/metrics.d.ts +38 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +123 -0
- package/dist/metrics.js.map +1 -0
- package/dist/node.d.ts +23 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +23 -0
- package/dist/node.js.map +1 -0
- package/dist/planner-executor.d.ts +132 -0
- package/dist/planner-executor.d.ts.map +1 -0
- package/dist/planner-executor.js +274 -0
- package/dist/planner-executor.js.map +1 -0
- package/dist/session.d.ts +10 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +179 -0
- package/dist/session.js.map +1 -0
- package/dist/skill-catalog.d.ts +81 -0
- package/dist/skill-catalog.d.ts.map +1 -0
- package/dist/skill-catalog.js +388 -0
- package/dist/skill-catalog.js.map +1 -0
- package/dist/skill-router.d.ts +95 -0
- package/dist/skill-router.d.ts.map +1 -0
- package/dist/skill-router.js +130 -0
- package/dist/skill-router.js.map +1 -0
- package/dist/storage.d.ts +14 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +58 -0
- package/dist/storage.js.map +1 -0
- package/dist/strategy.d.ts +45 -0
- package/dist/strategy.d.ts.map +1 -0
- package/dist/strategy.js +520 -0
- package/dist/strategy.js.map +1 -0
- package/dist/tools.d.ts +40 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +147 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/agent.d.ts +94 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +17 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/capabilities.d.ts +17 -0
- package/dist/types/capabilities.d.ts.map +1 -0
- package/dist/types/capabilities.js +13 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/chat.d.ts +74 -0
- package/dist/types/chat.d.ts.map +1 -0
- package/dist/types/chat.js +10 -0
- package/dist/types/chat.js.map +1 -0
- package/dist/types/events.d.ts +115 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +30 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/llm.d.ts +89 -0
- package/dist/types/llm.d.ts.map +1 -0
- package/dist/types/llm.js +12 -0
- package/dist/types/llm.js.map +1 -0
- package/dist/types/metrics.d.ts +34 -0
- package/dist/types/metrics.d.ts.map +1 -0
- package/dist/types/metrics.js +10 -0
- package/dist/types/metrics.js.map +1 -0
- package/dist/types/observer.d.ts +41 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +41 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/project-context.d.ts +18 -0
- package/dist/types/project-context.d.ts.map +1 -0
- package/dist/types/project-context.js +11 -0
- package/dist/types/project-context.js.map +1 -0
- package/dist/types/runtime.d.ts +71 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/runtime.js +21 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/session.d.ts +103 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +11 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/storage.d.ts +20 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +41 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/types/strategy.d.ts +124 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +10 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/types/tools.d.ts +154 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +11 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/trace.d.ts +175 -0
- package/dist/types/trace.d.ts.map +1 -0
- package/dist/types/trace.js +26 -0
- package/dist/types/trace.js.map +1 -0
- package/dist/types/workspace.d.ts +29 -0
- package/dist/types/workspace.d.ts.map +1 -0
- package/dist/types/workspace.js +18 -0
- package/dist/types/workspace.js.map +1 -0
- package/package.json +45 -14
- package/skills/agent-cli.md +218 -0
- package/index.js +0 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event value codec — round-trip non-JSON-safe values through the log.
|
|
3
|
+
*
|
|
4
|
+
* The naive approach (`JSON.stringify` everything that lands in
|
|
5
|
+
* `args`, `before`, `after`) is lossy for the exact types real
|
|
6
|
+
* Firebase code uses:
|
|
7
|
+
*
|
|
8
|
+
* - `Date` → ISO string. Replay writes `string` where `Date` was.
|
|
9
|
+
* - `Timestamp` (Firestore) → `{ seconds, nanoseconds }` map. Replay
|
|
10
|
+
* writes a MAP, not a Timestamp. Range queries break silently.
|
|
11
|
+
* - `FieldValue.serverTimestamp()` → `{}`. Sentinel never fires.
|
|
12
|
+
* - `Uint8Array` → array of numbers. Bytes corrupted.
|
|
13
|
+
* - `bigint` → throws (JSON.stringify can't serialize bigint).
|
|
14
|
+
*
|
|
15
|
+
* This module provides a small, extensible codec layer. The default
|
|
16
|
+
* codec handles the universal cases (Date / Uint8Array / bigint) via
|
|
17
|
+
* tagged envelopes. Hosts with domain-specific types (Firestore
|
|
18
|
+
* Timestamp, FieldValue, DocumentReference) compose their own codec
|
|
19
|
+
* on top — see `composeCodecs` + the AGENTS.md recipe.
|
|
20
|
+
*
|
|
21
|
+
* Not handled: `undefined`. Firestore doesn't write `undefined` to
|
|
22
|
+
* docs (it throws), and JSON.stringify drops `undefined`-valued
|
|
23
|
+
* object properties before we ever see them. Encoding it would
|
|
24
|
+
* require a "no-transform" sentinel that the walker collides with;
|
|
25
|
+
* not worth the complexity for a value real Firebase code never
|
|
26
|
+
* produces.
|
|
27
|
+
*
|
|
28
|
+
* Tagged envelope shape: `{ "__pyric": "<tag>", ...fields }`. The
|
|
29
|
+
* `__pyric` prefix makes encoded values self-describing and the
|
|
30
|
+
* round-trip lossless. Hosts using `__pyric` for their own things
|
|
31
|
+
* SHOULD pick a different prefix.
|
|
32
|
+
*/
|
|
33
|
+
export declare const ENVELOPE_KEY: "__pyric";
|
|
34
|
+
export interface EventValueCodec {
|
|
35
|
+
/** Convert a value into a JSON-safe shape. Identity on already-safe values. */
|
|
36
|
+
encode(value: unknown): unknown;
|
|
37
|
+
/** Invert `encode`. Identity on values that have no envelope. */
|
|
38
|
+
decode(value: unknown): unknown;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walks a value tree, applying a per-node transform. Returns a new
|
|
42
|
+
* tree (the input is NOT mutated). The transform returns `undefined`
|
|
43
|
+
* for nodes it doesn't want to transform; the walker then recurses
|
|
44
|
+
* into the node's children — BUT only when the node is a plain
|
|
45
|
+
* object or an array. Class instances (anything whose prototype is
|
|
46
|
+
* not `Object.prototype`) are returned as-is so composed codecs
|
|
47
|
+
* don't accidentally Object.entries() through a typed value and
|
|
48
|
+
* rebuild it as a bag-of-fields.
|
|
49
|
+
*
|
|
50
|
+
* Exported so codec authors can build their own codecs correctly —
|
|
51
|
+
* see `codec.ts` header for the pattern.
|
|
52
|
+
*/
|
|
53
|
+
export declare function walkValue(value: unknown, transform: (v: unknown) => unknown): unknown;
|
|
54
|
+
/**
|
|
55
|
+
* Default codec — handles universal non-JSON types every consumer
|
|
56
|
+
* needs. Hosts compose Firestore-specific codecs on top via
|
|
57
|
+
* `composeCodecs`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const defaultEventValueCodec: EventValueCodec;
|
|
60
|
+
/**
|
|
61
|
+
* Identity codec — pass-through. Use when the host serializes args
|
|
62
|
+
* itself before passing to a wrapped tool (e.g. tool args are
|
|
63
|
+
* already JSON-safe by contract). Cheaper than `defaultEventValueCodec`
|
|
64
|
+
* because it skips the walk.
|
|
65
|
+
*/
|
|
66
|
+
export declare const identityCodec: EventValueCodec;
|
|
67
|
+
/**
|
|
68
|
+
* Compose two codecs. The outer codec encodes first, decodes last.
|
|
69
|
+
*
|
|
70
|
+
* composeCodecs(outer, inner)
|
|
71
|
+
* encode(v) → outer.encode(inner.encode(v))
|
|
72
|
+
* decode(v) → inner.decode(outer.decode(v))
|
|
73
|
+
*
|
|
74
|
+
* Typical usage: layer a Firestore codec over the default.
|
|
75
|
+
*
|
|
76
|
+
* const codec = composeCodecs(firestoreCodec, defaultEventValueCodec);
|
|
77
|
+
*/
|
|
78
|
+
export declare function composeCodecs(outer: EventValueCodec, inner: EventValueCodec): EventValueCodec;
|
|
79
|
+
//# sourceMappingURL=codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/events/codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,eAAO,MAAM,YAAY,EAAG,SAAkB,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAChC,iEAAiE;IACjE,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;CACjC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAiBrF;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAqCpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,eAG3B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,eAAe,CAK7F"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event value codec — round-trip non-JSON-safe values through the log.
|
|
3
|
+
*
|
|
4
|
+
* The naive approach (`JSON.stringify` everything that lands in
|
|
5
|
+
* `args`, `before`, `after`) is lossy for the exact types real
|
|
6
|
+
* Firebase code uses:
|
|
7
|
+
*
|
|
8
|
+
* - `Date` → ISO string. Replay writes `string` where `Date` was.
|
|
9
|
+
* - `Timestamp` (Firestore) → `{ seconds, nanoseconds }` map. Replay
|
|
10
|
+
* writes a MAP, not a Timestamp. Range queries break silently.
|
|
11
|
+
* - `FieldValue.serverTimestamp()` → `{}`. Sentinel never fires.
|
|
12
|
+
* - `Uint8Array` → array of numbers. Bytes corrupted.
|
|
13
|
+
* - `bigint` → throws (JSON.stringify can't serialize bigint).
|
|
14
|
+
*
|
|
15
|
+
* This module provides a small, extensible codec layer. The default
|
|
16
|
+
* codec handles the universal cases (Date / Uint8Array / bigint) via
|
|
17
|
+
* tagged envelopes. Hosts with domain-specific types (Firestore
|
|
18
|
+
* Timestamp, FieldValue, DocumentReference) compose their own codec
|
|
19
|
+
* on top — see `composeCodecs` + the AGENTS.md recipe.
|
|
20
|
+
*
|
|
21
|
+
* Not handled: `undefined`. Firestore doesn't write `undefined` to
|
|
22
|
+
* docs (it throws), and JSON.stringify drops `undefined`-valued
|
|
23
|
+
* object properties before we ever see them. Encoding it would
|
|
24
|
+
* require a "no-transform" sentinel that the walker collides with;
|
|
25
|
+
* not worth the complexity for a value real Firebase code never
|
|
26
|
+
* produces.
|
|
27
|
+
*
|
|
28
|
+
* Tagged envelope shape: `{ "__pyric": "<tag>", ...fields }`. The
|
|
29
|
+
* `__pyric` prefix makes encoded values self-describing and the
|
|
30
|
+
* round-trip lossless. Hosts using `__pyric` for their own things
|
|
31
|
+
* SHOULD pick a different prefix.
|
|
32
|
+
*/
|
|
33
|
+
export const ENVELOPE_KEY = '__pyric';
|
|
34
|
+
/**
|
|
35
|
+
* Walks a value tree, applying a per-node transform. Returns a new
|
|
36
|
+
* tree (the input is NOT mutated). The transform returns `undefined`
|
|
37
|
+
* for nodes it doesn't want to transform; the walker then recurses
|
|
38
|
+
* into the node's children — BUT only when the node is a plain
|
|
39
|
+
* object or an array. Class instances (anything whose prototype is
|
|
40
|
+
* not `Object.prototype`) are returned as-is so composed codecs
|
|
41
|
+
* don't accidentally Object.entries() through a typed value and
|
|
42
|
+
* rebuild it as a bag-of-fields.
|
|
43
|
+
*
|
|
44
|
+
* Exported so codec authors can build their own codecs correctly —
|
|
45
|
+
* see `codec.ts` header for the pattern.
|
|
46
|
+
*/
|
|
47
|
+
export function walkValue(value, transform) {
|
|
48
|
+
const replaced = transform(value);
|
|
49
|
+
if (replaced !== undefined)
|
|
50
|
+
return replaced;
|
|
51
|
+
if (value === null || typeof value !== 'object')
|
|
52
|
+
return value;
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.map((v) => walkValue(v, transform));
|
|
55
|
+
// Only descend into plain {} objects. A class instance reaches here
|
|
56
|
+
// either because the transform doesn't recognize it (likely the
|
|
57
|
+
// caller's own type — return unchanged), or because we already
|
|
58
|
+
// decoded an envelope into an instance and a *later* pass shouldn't
|
|
59
|
+
// re-walk its fields.
|
|
60
|
+
const proto = Object.getPrototypeOf(value);
|
|
61
|
+
if (proto !== Object.prototype && proto !== null)
|
|
62
|
+
return value;
|
|
63
|
+
const out = {};
|
|
64
|
+
for (const [k, v] of Object.entries(value)) {
|
|
65
|
+
out[k] = walkValue(v, transform);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Default codec — handles universal non-JSON types every consumer
|
|
71
|
+
* needs. Hosts compose Firestore-specific codecs on top via
|
|
72
|
+
* `composeCodecs`.
|
|
73
|
+
*/
|
|
74
|
+
export const defaultEventValueCodec = {
|
|
75
|
+
encode(value) {
|
|
76
|
+
return walkValue(value, (v) => {
|
|
77
|
+
if (v instanceof Date) {
|
|
78
|
+
return { [ENVELOPE_KEY]: 'Date', iso: v.toISOString() };
|
|
79
|
+
}
|
|
80
|
+
if (v instanceof Uint8Array) {
|
|
81
|
+
return {
|
|
82
|
+
[ENVELOPE_KEY]: 'Uint8Array',
|
|
83
|
+
b64: Buffer.from(v).toString('base64'),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (typeof v === 'bigint') {
|
|
87
|
+
return { [ENVELOPE_KEY]: 'bigint', value: v.toString() };
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
decode(value) {
|
|
93
|
+
return walkValue(value, (v) => {
|
|
94
|
+
if (v === null || typeof v !== 'object')
|
|
95
|
+
return undefined;
|
|
96
|
+
if (Array.isArray(v))
|
|
97
|
+
return undefined;
|
|
98
|
+
const obj = v;
|
|
99
|
+
const tag = obj[ENVELOPE_KEY];
|
|
100
|
+
if (typeof tag !== 'string')
|
|
101
|
+
return undefined;
|
|
102
|
+
if (tag === 'Date' && typeof obj['iso'] === 'string') {
|
|
103
|
+
return new Date(obj['iso']);
|
|
104
|
+
}
|
|
105
|
+
if (tag === 'Uint8Array' && typeof obj['b64'] === 'string') {
|
|
106
|
+
return new Uint8Array(Buffer.from(obj['b64'], 'base64'));
|
|
107
|
+
}
|
|
108
|
+
if (tag === 'bigint' && typeof obj['value'] === 'string') {
|
|
109
|
+
return BigInt(obj['value']);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Identity codec — pass-through. Use when the host serializes args
|
|
117
|
+
* itself before passing to a wrapped tool (e.g. tool args are
|
|
118
|
+
* already JSON-safe by contract). Cheaper than `defaultEventValueCodec`
|
|
119
|
+
* because it skips the walk.
|
|
120
|
+
*/
|
|
121
|
+
export const identityCodec = {
|
|
122
|
+
encode: (v) => v,
|
|
123
|
+
decode: (v) => v,
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Compose two codecs. The outer codec encodes first, decodes last.
|
|
127
|
+
*
|
|
128
|
+
* composeCodecs(outer, inner)
|
|
129
|
+
* encode(v) → outer.encode(inner.encode(v))
|
|
130
|
+
* decode(v) → inner.decode(outer.decode(v))
|
|
131
|
+
*
|
|
132
|
+
* Typical usage: layer a Firestore codec over the default.
|
|
133
|
+
*
|
|
134
|
+
* const codec = composeCodecs(firestoreCodec, defaultEventValueCodec);
|
|
135
|
+
*/
|
|
136
|
+
export function composeCodecs(outer, inner) {
|
|
137
|
+
return {
|
|
138
|
+
encode: (v) => outer.encode(inner.encode(v)),
|
|
139
|
+
decode: (v) => inner.decode(outer.decode(v)),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/events/codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure / browser-safe pieces of the event log surface:
|
|
3
|
+
*
|
|
4
|
+
* - `EventLog`, `AppendDraft` — types describing the writer's
|
|
5
|
+
* contract; consumers (wrap, replay) describe handlers without
|
|
6
|
+
* pulling in the writer implementation.
|
|
7
|
+
* - `HOST_AGENT_ID` — string constant; canonical declaration is
|
|
8
|
+
* `types/events.ts` (also browser-safe).
|
|
9
|
+
* - `generateEventId`, `buildRollbackEvent`, `EventTooLargeError`,
|
|
10
|
+
* `DEFAULT_MAX_EVENT_BYTES` — pure helpers used by both the
|
|
11
|
+
* Node-side writer (`log.ts`) and the browser-safe `wrapMutating`
|
|
12
|
+
* decorator.
|
|
13
|
+
*
|
|
14
|
+
* The Node-side writer (`openEventLog`, `defaultProjectLogDir`) lives
|
|
15
|
+
* in `./log.ts` and imports `node:fs` / `node:os`. Splitting along
|
|
16
|
+
* this axis lets `wrap.ts` and the universal `@inbrowser/agent` entry
|
|
17
|
+
* use the pure helpers without dragging Node imports into browser
|
|
18
|
+
* bundles.
|
|
19
|
+
*/
|
|
20
|
+
import type { MutationEvent, MutationEventFilter, ReverseOp } from '../types/events.js';
|
|
21
|
+
export { HOST_AGENT_ID } from '../types/events.js';
|
|
22
|
+
/**
|
|
23
|
+
* Default per-event byte cap. Matches the Linux PIPE_BUF default and
|
|
24
|
+
* stays well inside macOS's atomic-write window. Above this, append
|
|
25
|
+
* atomicity isn't guaranteed and concurrent writers can interleave.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_MAX_EVENT_BYTES: number;
|
|
28
|
+
/**
|
|
29
|
+
* Time-prefixed base36 id with an optional per-log sequence so two
|
|
30
|
+
* appends within the same millisecond stay strictly sortable by
|
|
31
|
+
* emission order. Without the sequence the only tiebreaker is the
|
|
32
|
+
* random suffix, which can flip ordering — a real bug for
|
|
33
|
+
* `replayEvents`'s sinceEventId cursor.
|
|
34
|
+
*/
|
|
35
|
+
export declare function generateEventId(now?: () => number, sequence?: number): string;
|
|
36
|
+
export declare class EventTooLargeError extends Error {
|
|
37
|
+
readonly bytes: number;
|
|
38
|
+
readonly cap: number;
|
|
39
|
+
readonly tool: string;
|
|
40
|
+
readonly name = "EventTooLargeError";
|
|
41
|
+
constructor(bytes: number, cap: number, tool: string);
|
|
42
|
+
}
|
|
43
|
+
export interface EventLog {
|
|
44
|
+
readonly path: string;
|
|
45
|
+
readonly projectId: string;
|
|
46
|
+
/**
|
|
47
|
+
* Append a single event. `id` + `ts` are auto-populated when absent
|
|
48
|
+
* so callers can pass a partial draft. Returns the full event for
|
|
49
|
+
* convenience (e.g. wrapMutating's plan-then-commit flow).
|
|
50
|
+
*/
|
|
51
|
+
append(draft: AppendDraft): MutationEvent;
|
|
52
|
+
/**
|
|
53
|
+
* Read all events matching the filter. Returns an array, not a
|
|
54
|
+
* stream — the log is small (tens to thousands of events).
|
|
55
|
+
*/
|
|
56
|
+
read(filter?: MutationEventFilter): MutationEvent[];
|
|
57
|
+
/**
|
|
58
|
+
* Lazily-built cache of event ids that have already been applied
|
|
59
|
+
* by `replayEvents` (i.e. an event with
|
|
60
|
+
* `metadata.type === 'migrate_applied'` referencing them exists).
|
|
61
|
+
* Invalidated on every `append`.
|
|
62
|
+
*/
|
|
63
|
+
appliedEventIds(): Set<string>;
|
|
64
|
+
/** Release resources. Idempotent. */
|
|
65
|
+
close(): void;
|
|
66
|
+
}
|
|
67
|
+
export type AppendDraft = Omit<MutationEvent, 'id' | 'ts'> & Partial<Pick<MutationEvent, 'id' | 'ts'>>;
|
|
68
|
+
export declare function buildRollbackEvent(opts: {
|
|
69
|
+
original: MutationEvent;
|
|
70
|
+
reason: 'failure' | 'undo';
|
|
71
|
+
reverseOp?: ReverseOp;
|
|
72
|
+
agent: string;
|
|
73
|
+
sessionId: string;
|
|
74
|
+
now?: () => number;
|
|
75
|
+
}): AppendDraft;
|
|
76
|
+
//# sourceMappingURL=log-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-core.d.ts","sourceRoot":"","sources":["../../src/events/log-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,mBAAmB,EAEnB,SAAS,EACV,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAY,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,MAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAKvF;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAJvB,SAAkB,IAAI,wBAAwB;gBAEnC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM;CASxB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAAC;IAC1C;;;OAGG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,aAAa,EAAE,CAAC;IACpD;;;;;OAKG;IACH,eAAe,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,qCAAqC;IACrC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,GAAG,WAAW,CAiBd"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure / browser-safe pieces of the event log surface:
|
|
3
|
+
*
|
|
4
|
+
* - `EventLog`, `AppendDraft` — types describing the writer's
|
|
5
|
+
* contract; consumers (wrap, replay) describe handlers without
|
|
6
|
+
* pulling in the writer implementation.
|
|
7
|
+
* - `HOST_AGENT_ID` — string constant; canonical declaration is
|
|
8
|
+
* `types/events.ts` (also browser-safe).
|
|
9
|
+
* - `generateEventId`, `buildRollbackEvent`, `EventTooLargeError`,
|
|
10
|
+
* `DEFAULT_MAX_EVENT_BYTES` — pure helpers used by both the
|
|
11
|
+
* Node-side writer (`log.ts`) and the browser-safe `wrapMutating`
|
|
12
|
+
* decorator.
|
|
13
|
+
*
|
|
14
|
+
* The Node-side writer (`openEventLog`, `defaultProjectLogDir`) lives
|
|
15
|
+
* in `./log.ts` and imports `node:fs` / `node:os`. Splitting along
|
|
16
|
+
* this axis lets `wrap.ts` and the universal `@inbrowser/agent` entry
|
|
17
|
+
* use the pure helpers without dragging Node imports into browser
|
|
18
|
+
* bundles.
|
|
19
|
+
*/
|
|
20
|
+
export { HOST_AGENT_ID } from '../types/events.js';
|
|
21
|
+
/**
|
|
22
|
+
* Default per-event byte cap. Matches the Linux PIPE_BUF default and
|
|
23
|
+
* stays well inside macOS's atomic-write window. Above this, append
|
|
24
|
+
* atomicity isn't guaranteed and concurrent writers can interleave.
|
|
25
|
+
*/
|
|
26
|
+
export const DEFAULT_MAX_EVENT_BYTES = 64 * 1024;
|
|
27
|
+
/**
|
|
28
|
+
* Time-prefixed base36 id with an optional per-log sequence so two
|
|
29
|
+
* appends within the same millisecond stay strictly sortable by
|
|
30
|
+
* emission order. Without the sequence the only tiebreaker is the
|
|
31
|
+
* random suffix, which can flip ordering — a real bug for
|
|
32
|
+
* `replayEvents`'s sinceEventId cursor.
|
|
33
|
+
*/
|
|
34
|
+
export function generateEventId(now = Date.now, sequence) {
|
|
35
|
+
const ts = now().toString(36).padStart(9, '0');
|
|
36
|
+
const seq = sequence !== undefined ? `-${sequence.toString(36).padStart(4, '0')}` : '';
|
|
37
|
+
const rand = Math.random().toString(36).slice(2, 6);
|
|
38
|
+
return `${ts}${seq}-${rand}`;
|
|
39
|
+
}
|
|
40
|
+
export class EventTooLargeError extends Error {
|
|
41
|
+
bytes;
|
|
42
|
+
cap;
|
|
43
|
+
tool;
|
|
44
|
+
name = 'EventTooLargeError';
|
|
45
|
+
constructor(bytes, cap, tool) {
|
|
46
|
+
super(`event for tool=${tool} is ${bytes} bytes, exceeds cap ${cap}. ` +
|
|
47
|
+
`Atomic append is not guaranteed above this size; concurrent writers can interleave. ` +
|
|
48
|
+
`Raise via openEventLog({ maxEventBytes }) only if you accept the loss of atomicity guarantees, ` +
|
|
49
|
+
`or shrink the payload (truncate before/after snapshots, omit large args).`);
|
|
50
|
+
this.bytes = bytes;
|
|
51
|
+
this.cap = cap;
|
|
52
|
+
this.tool = tool;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function buildRollbackEvent(opts) {
|
|
56
|
+
const nowFn = opts.now ?? Date.now;
|
|
57
|
+
void nowFn;
|
|
58
|
+
return {
|
|
59
|
+
agent: opts.agent,
|
|
60
|
+
sessionId: opts.sessionId,
|
|
61
|
+
tool: opts.original.tool,
|
|
62
|
+
phase: 'rollback',
|
|
63
|
+
target: opts.original.target,
|
|
64
|
+
reversible: false,
|
|
65
|
+
irreversibleReason: 'rollback events are terminal',
|
|
66
|
+
...(opts.reverseOp ? { reverseOp: opts.reverseOp } : {}),
|
|
67
|
+
metadata: {
|
|
68
|
+
reason: opts.reason,
|
|
69
|
+
originalEventId: opts.original.id,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=log-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-core.js","sourceRoot":"","sources":["../../src/events/log-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAoB,IAAI,CAAC,GAAG,EAAE,QAAiB;IAC7E,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,GAAG,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGhC;IACA;IACA;IAJO,IAAI,GAAG,oBAAoB,CAAC;IAC9C,YACW,KAAa,EACb,GAAW,EACX,IAAY;QAErB,KAAK,CACH,kBAAkB,IAAI,OAAO,KAAK,uBAAuB,GAAG,IAAI;YAC9D,sFAAsF;YACtF,iGAAiG;YACjG,2EAA2E,CAC9E,CAAC;QATO,UAAK,GAAL,KAAK,CAAQ;QACb,QAAG,GAAH,GAAG,CAAQ;QACX,SAAI,GAAJ,IAAI,CAAQ;IAQvB,CAAC;CACF;AA8BD,MAAM,UAAU,kBAAkB,CAAC,IAOlC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACnC,KAAK,KAAK,CAAC;IACX,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;QACxB,KAAK,EAAE,UAAkC;QACzC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;QAC5B,UAAU,EAAE,KAAK;QACjB,kBAAkB,EAAE,8BAA8B;QAClD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,QAAQ,EAAE;YACR,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;SAClC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project event log — NDJSON append-only writer. Node-only.
|
|
3
|
+
*
|
|
4
|
+
* Pure helpers (`generateEventId`, `buildRollbackEvent`, `HOST_AGENT_ID`,
|
|
5
|
+
* `EventTooLargeError`, `DEFAULT_MAX_EVENT_BYTES`) and the `EventLog`
|
|
6
|
+
* + `AppendDraft` types live in `./log-core.ts` — that file is
|
|
7
|
+
* browser-safe and is what `wrap.ts` / `replay.ts` import.
|
|
8
|
+
*
|
|
9
|
+
* Each Firebase project gets one log at
|
|
10
|
+
* `~/.pyric/projects/<projectId>/events.ndjson`. Every mutating tool
|
|
11
|
+
* call emits at least two lines (plan + commit); failures get a
|
|
12
|
+
* rollback line. `agent events` reads + filters; `agent undo` consults
|
|
13
|
+
* the log to find the matching commit event and invoke its reverseOp.
|
|
14
|
+
*
|
|
15
|
+
* Design notes:
|
|
16
|
+
* - **Append-only.** Never rewrite. `agent undo` doesn't delete the
|
|
17
|
+
* committed event; it appends a new `rollback`-phase event that
|
|
18
|
+
* references the original id. This keeps the file replayable.
|
|
19
|
+
* - **Atomic per-event writes.** Each `append()` is one
|
|
20
|
+
* `appendFileSync` call so multi-process writers can't interleave
|
|
21
|
+
* within an event. Events have a hard byte cap (default 64KB) to
|
|
22
|
+
* stay inside the kernel's atomic-append window on Linux + macOS.
|
|
23
|
+
* - **Synchronous IO.** The log is small. A streaming reader would
|
|
24
|
+
* be over-engineering today.
|
|
25
|
+
* - **Injectable fs.** Tests pass a fake `io` object so they don't
|
|
26
|
+
* hit the real disk.
|
|
27
|
+
* - **Codec hook.** `args`, `before`, `after` are run through an
|
|
28
|
+
* `EventValueCodec` on append + decoded on read.
|
|
29
|
+
*/
|
|
30
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
31
|
+
import { type EventValueCodec } from './codec.js';
|
|
32
|
+
import { type EventLog } from './log-core.js';
|
|
33
|
+
export { HOST_AGENT_ID, DEFAULT_MAX_EVENT_BYTES, generateEventId, EventTooLargeError, buildRollbackEvent, } from './log-core.js';
|
|
34
|
+
export type { EventLog, AppendDraft } from './log-core.js';
|
|
35
|
+
export declare function defaultProjectLogDir(): string;
|
|
36
|
+
export interface EventLogIO {
|
|
37
|
+
existsSync: typeof existsSync;
|
|
38
|
+
mkdirSync: typeof mkdirSync;
|
|
39
|
+
appendFileSync: typeof appendFileSync;
|
|
40
|
+
readFileSync: typeof readFileSync;
|
|
41
|
+
}
|
|
42
|
+
export interface OpenEventLogOptions {
|
|
43
|
+
projectId: string;
|
|
44
|
+
/** Absolute path to the directory containing per-project subdirs.
|
|
45
|
+
* Defaults to `~/.pyric/projects`. */
|
|
46
|
+
logDir?: string;
|
|
47
|
+
/** Defaults to fs primitives; injectable for tests. */
|
|
48
|
+
io?: EventLogIO;
|
|
49
|
+
/** Injectable clock; defaults to `Date.now`. */
|
|
50
|
+
now?: () => number;
|
|
51
|
+
/** Codec for `args` / `before` / `after`. Default round-trips
|
|
52
|
+
* Date / Uint8Array / bigint / undefined. Pass a composed codec
|
|
53
|
+
* for Firestore types — see `codec.ts:composeCodecs`. */
|
|
54
|
+
codec?: EventValueCodec;
|
|
55
|
+
/** Per-event byte cap. Defaults to 64KB. Exceeding throws
|
|
56
|
+
* `EventTooLargeError`. */
|
|
57
|
+
maxEventBytes?: number;
|
|
58
|
+
}
|
|
59
|
+
export declare function openEventLog(opts: OpenEventLogOptions): EventLog;
|
|
60
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/events/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG9E,OAAO,EAAE,KAAK,eAAe,EAA0B,MAAM,YAAY,CAAC;AAC1E,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,eAAe,CAAC;AAMvB,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE3D,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,YAAY,EAAE,OAAO,YAAY,CAAC;CACnC;AASD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB;2CACuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;8DAE0D;IAC1D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;gCAC4B;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,QAAQ,CA+GhE"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project event log — NDJSON append-only writer. Node-only.
|
|
3
|
+
*
|
|
4
|
+
* Pure helpers (`generateEventId`, `buildRollbackEvent`, `HOST_AGENT_ID`,
|
|
5
|
+
* `EventTooLargeError`, `DEFAULT_MAX_EVENT_BYTES`) and the `EventLog`
|
|
6
|
+
* + `AppendDraft` types live in `./log-core.ts` — that file is
|
|
7
|
+
* browser-safe and is what `wrap.ts` / `replay.ts` import.
|
|
8
|
+
*
|
|
9
|
+
* Each Firebase project gets one log at
|
|
10
|
+
* `~/.pyric/projects/<projectId>/events.ndjson`. Every mutating tool
|
|
11
|
+
* call emits at least two lines (plan + commit); failures get a
|
|
12
|
+
* rollback line. `agent events` reads + filters; `agent undo` consults
|
|
13
|
+
* the log to find the matching commit event and invoke its reverseOp.
|
|
14
|
+
*
|
|
15
|
+
* Design notes:
|
|
16
|
+
* - **Append-only.** Never rewrite. `agent undo` doesn't delete the
|
|
17
|
+
* committed event; it appends a new `rollback`-phase event that
|
|
18
|
+
* references the original id. This keeps the file replayable.
|
|
19
|
+
* - **Atomic per-event writes.** Each `append()` is one
|
|
20
|
+
* `appendFileSync` call so multi-process writers can't interleave
|
|
21
|
+
* within an event. Events have a hard byte cap (default 64KB) to
|
|
22
|
+
* stay inside the kernel's atomic-append window on Linux + macOS.
|
|
23
|
+
* - **Synchronous IO.** The log is small. A streaming reader would
|
|
24
|
+
* be over-engineering today.
|
|
25
|
+
* - **Injectable fs.** Tests pass a fake `io` object so they don't
|
|
26
|
+
* hit the real disk.
|
|
27
|
+
* - **Codec hook.** `args`, `before`, `after` are run through an
|
|
28
|
+
* `EventValueCodec` on append + decoded on read.
|
|
29
|
+
*/
|
|
30
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
31
|
+
import { homedir } from 'node:os';
|
|
32
|
+
import { defaultEventValueCodec } from './codec.js';
|
|
33
|
+
import { DEFAULT_MAX_EVENT_BYTES, EventTooLargeError, generateEventId, } from './log-core.js';
|
|
34
|
+
// Convenience re-exports — Node-side callers can grab everything
|
|
35
|
+
// log-related from one entry. Browser-safe callers (wrap.ts,
|
|
36
|
+
// replay.ts) import from `./log-core.js` directly to avoid pulling
|
|
37
|
+
// `node:fs` into the universal `@inbrowser/agent` entry.
|
|
38
|
+
export { HOST_AGENT_ID, DEFAULT_MAX_EVENT_BYTES, generateEventId, EventTooLargeError, buildRollbackEvent, } from './log-core.js';
|
|
39
|
+
export function defaultProjectLogDir() {
|
|
40
|
+
return `${homedir()}/.pyric/projects`;
|
|
41
|
+
}
|
|
42
|
+
const DEFAULT_IO = {
|
|
43
|
+
existsSync,
|
|
44
|
+
mkdirSync,
|
|
45
|
+
appendFileSync,
|
|
46
|
+
readFileSync,
|
|
47
|
+
};
|
|
48
|
+
export function openEventLog(opts) {
|
|
49
|
+
if (!/^[a-zA-Z0-9_.-]+$/.test(opts.projectId)) {
|
|
50
|
+
throw new Error(`openEventLog: projectId ${JSON.stringify(opts.projectId)} contains disallowed characters; use [a-zA-Z0-9_.-]+`);
|
|
51
|
+
}
|
|
52
|
+
const io = opts.io ?? DEFAULT_IO;
|
|
53
|
+
const now = opts.now ?? Date.now;
|
|
54
|
+
const baseDir = opts.logDir ?? defaultProjectLogDir();
|
|
55
|
+
const projectDir = `${baseDir.replace(/\/$/, '')}/${opts.projectId}`;
|
|
56
|
+
const path = `${projectDir}/events.ndjson`;
|
|
57
|
+
const codec = opts.codec ?? defaultEventValueCodec;
|
|
58
|
+
const maxBytes = opts.maxEventBytes ?? DEFAULT_MAX_EVENT_BYTES;
|
|
59
|
+
if (!io.existsSync(projectDir))
|
|
60
|
+
io.mkdirSync(projectDir, { recursive: true });
|
|
61
|
+
// Strictly-monotonic counter — combined with the millisecond
|
|
62
|
+
// timestamp, makes ids sortable in emission order even when many
|
|
63
|
+
// appends share a `Date.now()` value.
|
|
64
|
+
let sequence = 0;
|
|
65
|
+
let closed = false;
|
|
66
|
+
// Lazy-built cache of `migrate_applied` originalEventIds. Invalidated
|
|
67
|
+
// on every append so the next read rebuilds it.
|
|
68
|
+
let _appliedCache = null;
|
|
69
|
+
function ensureOpen() {
|
|
70
|
+
if (closed)
|
|
71
|
+
throw new Error(`event log ${path} is closed`);
|
|
72
|
+
}
|
|
73
|
+
function appendEvent(draft) {
|
|
74
|
+
ensureOpen();
|
|
75
|
+
const event = {
|
|
76
|
+
id: draft.id ?? generateEventId(now, sequence++),
|
|
77
|
+
ts: draft.ts ?? new Date(now()).toISOString(),
|
|
78
|
+
agent: draft.agent,
|
|
79
|
+
sessionId: draft.sessionId,
|
|
80
|
+
tool: draft.tool,
|
|
81
|
+
...(draft.args !== undefined ? { args: codec.encode(draft.args) } : {}),
|
|
82
|
+
phase: draft.phase,
|
|
83
|
+
target: draft.target,
|
|
84
|
+
...(draft.before !== undefined ? { before: codec.encode(draft.before) } : {}),
|
|
85
|
+
...(draft.after !== undefined ? { after: codec.encode(draft.after) } : {}),
|
|
86
|
+
reversible: draft.reversible,
|
|
87
|
+
...(draft.irreversibleReason ? { irreversibleReason: draft.irreversibleReason } : {}),
|
|
88
|
+
...(draft.reverseOp ? { reverseOp: encodeReverseOp(draft.reverseOp, codec) } : {}),
|
|
89
|
+
...(draft.metadata ? { metadata: draft.metadata } : {}),
|
|
90
|
+
};
|
|
91
|
+
const line = JSON.stringify(event) + '\n';
|
|
92
|
+
const bytes = Buffer.byteLength(line, 'utf8');
|
|
93
|
+
if (bytes > maxBytes) {
|
|
94
|
+
throw new EventTooLargeError(bytes, maxBytes, draft.tool);
|
|
95
|
+
}
|
|
96
|
+
io.appendFileSync(path, line);
|
|
97
|
+
_appliedCache = null;
|
|
98
|
+
return event;
|
|
99
|
+
}
|
|
100
|
+
function readAll(filter) {
|
|
101
|
+
ensureOpen();
|
|
102
|
+
if (!io.existsSync(path))
|
|
103
|
+
return [];
|
|
104
|
+
const raw = io.readFileSync(path, 'utf8');
|
|
105
|
+
if (!raw)
|
|
106
|
+
return [];
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const line of raw.split('\n')) {
|
|
109
|
+
if (!line)
|
|
110
|
+
continue;
|
|
111
|
+
let parsed;
|
|
112
|
+
try {
|
|
113
|
+
parsed = JSON.parse(line);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Skip malformed lines — append-only files can become corrupt
|
|
117
|
+
// if a writer crashes mid-write. Surfacing as a hard error
|
|
118
|
+
// would prevent `agent events` from ever working again.
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const decoded = {
|
|
122
|
+
...parsed,
|
|
123
|
+
...(parsed.args !== undefined ? { args: codec.decode(parsed.args) } : {}),
|
|
124
|
+
...(parsed.before !== undefined ? { before: codec.decode(parsed.before) } : {}),
|
|
125
|
+
...(parsed.after !== undefined ? { after: codec.decode(parsed.after) } : {}),
|
|
126
|
+
...(parsed.reverseOp ? { reverseOp: decodeReverseOp(parsed.reverseOp, codec) } : {}),
|
|
127
|
+
};
|
|
128
|
+
if (filter && !matches(decoded, filter))
|
|
129
|
+
continue;
|
|
130
|
+
out.push(decoded);
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
function appliedEventIds() {
|
|
135
|
+
if (_appliedCache !== null)
|
|
136
|
+
return _appliedCache;
|
|
137
|
+
const set = new Set();
|
|
138
|
+
for (const ev of readAll()) {
|
|
139
|
+
const md = ev.metadata;
|
|
140
|
+
if (md?.type === 'migrate_applied' && typeof md.appliedEventId === 'string') {
|
|
141
|
+
set.add(md.appliedEventId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
_appliedCache = set;
|
|
145
|
+
return set;
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
path,
|
|
149
|
+
projectId: opts.projectId,
|
|
150
|
+
append: appendEvent,
|
|
151
|
+
read: readAll,
|
|
152
|
+
appliedEventIds,
|
|
153
|
+
close() {
|
|
154
|
+
if (closed)
|
|
155
|
+
return;
|
|
156
|
+
closed = true;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function encodeReverseOp(op, codec) {
|
|
161
|
+
return {
|
|
162
|
+
tool: op.tool,
|
|
163
|
+
args: codec.encode(op.args),
|
|
164
|
+
...(op.description ? { description: op.description } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function decodeReverseOp(op, codec) {
|
|
168
|
+
return {
|
|
169
|
+
tool: op.tool,
|
|
170
|
+
args: codec.decode(op.args),
|
|
171
|
+
...(op.description ? { description: op.description } : {}),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function matches(event, filter) {
|
|
175
|
+
if (filter.id && event.id !== filter.id)
|
|
176
|
+
return false;
|
|
177
|
+
if (filter.sessionId && event.sessionId !== filter.sessionId)
|
|
178
|
+
return false;
|
|
179
|
+
if (filter.tool && event.tool !== filter.tool)
|
|
180
|
+
return false;
|
|
181
|
+
if (filter.agent && event.agent !== filter.agent)
|
|
182
|
+
return false;
|
|
183
|
+
if (filter.phase && event.phase !== filter.phase)
|
|
184
|
+
return false;
|
|
185
|
+
if (filter.targetKind && event.target.kind !== filter.targetKind)
|
|
186
|
+
return false;
|
|
187
|
+
if (filter.since && event.ts < filter.since)
|
|
188
|
+
return false;
|
|
189
|
+
if (filter.until && event.ts >= filter.until)
|
|
190
|
+
return false;
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/events/log.ts"],"names":[],"mappings":"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"}
|