@inbrowser/agent 0.0.0-placeholder → 0.1.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 (202) hide show
  1. package/AGENTS.md +270 -0
  2. package/README.md +117 -2
  3. package/bin/agent.ts +10 -0
  4. package/dist/cli/commands/describe.d.ts +14 -0
  5. package/dist/cli/commands/describe.d.ts.map +1 -0
  6. package/dist/cli/commands/describe.js +179 -0
  7. package/dist/cli/commands/describe.js.map +1 -0
  8. package/dist/cli/commands/events.d.ts +21 -0
  9. package/dist/cli/commands/events.d.ts.map +1 -0
  10. package/dist/cli/commands/events.js +59 -0
  11. package/dist/cli/commands/events.js.map +1 -0
  12. package/dist/cli/commands/fleet.d.ts +15 -0
  13. package/dist/cli/commands/fleet.d.ts.map +1 -0
  14. package/dist/cli/commands/fleet.js +149 -0
  15. package/dist/cli/commands/fleet.js.map +1 -0
  16. package/dist/cli/commands/help.d.ts +15 -0
  17. package/dist/cli/commands/help.d.ts.map +1 -0
  18. package/dist/cli/commands/help.js +93 -0
  19. package/dist/cli/commands/help.js.map +1 -0
  20. package/dist/cli/commands/migrate.d.ts +27 -0
  21. package/dist/cli/commands/migrate.d.ts.map +1 -0
  22. package/dist/cli/commands/migrate.js +109 -0
  23. package/dist/cli/commands/migrate.js.map +1 -0
  24. package/dist/cli/commands/run.d.ts +38 -0
  25. package/dist/cli/commands/run.d.ts.map +1 -0
  26. package/dist/cli/commands/run.js +535 -0
  27. package/dist/cli/commands/run.js.map +1 -0
  28. package/dist/cli/commands/schema.d.ts +8 -0
  29. package/dist/cli/commands/schema.d.ts.map +1 -0
  30. package/dist/cli/commands/schema.js +12 -0
  31. package/dist/cli/commands/schema.js.map +1 -0
  32. package/dist/cli/commands/serve.d.ts +39 -0
  33. package/dist/cli/commands/serve.d.ts.map +1 -0
  34. package/dist/cli/commands/serve.js +65 -0
  35. package/dist/cli/commands/serve.js.map +1 -0
  36. package/dist/cli/commands/undo.d.ts +36 -0
  37. package/dist/cli/commands/undo.d.ts.map +1 -0
  38. package/dist/cli/commands/undo.js +132 -0
  39. package/dist/cli/commands/undo.js.map +1 -0
  40. package/dist/cli/fixtures.d.ts +17 -0
  41. package/dist/cli/fixtures.d.ts.map +1 -0
  42. package/dist/cli/fixtures.js +107 -0
  43. package/dist/cli/fixtures.js.map +1 -0
  44. package/dist/cli/hardening.d.ts +39 -0
  45. package/dist/cli/hardening.d.ts.map +1 -0
  46. package/dist/cli/hardening.js +68 -0
  47. package/dist/cli/hardening.js.map +1 -0
  48. package/dist/cli/index.d.ts +28 -0
  49. package/dist/cli/index.d.ts.map +1 -0
  50. package/dist/cli/index.js +19 -0
  51. package/dist/cli/index.js.map +1 -0
  52. package/dist/cli/llm/openrouter.d.ts +33 -0
  53. package/dist/cli/llm/openrouter.d.ts.map +1 -0
  54. package/dist/cli/llm/openrouter.js +285 -0
  55. package/dist/cli/llm/openrouter.js.map +1 -0
  56. package/dist/cli/main.d.ts +32 -0
  57. package/dist/cli/main.d.ts.map +1 -0
  58. package/dist/cli/main.js +106 -0
  59. package/dist/cli/main.js.map +1 -0
  60. package/dist/cli/output.d.ts +36 -0
  61. package/dist/cli/output.d.ts.map +1 -0
  62. package/dist/cli/output.js +95 -0
  63. package/dist/cli/output.js.map +1 -0
  64. package/dist/cli/parse.d.ts +26 -0
  65. package/dist/cli/parse.d.ts.map +1 -0
  66. package/dist/cli/parse.js +160 -0
  67. package/dist/cli/parse.js.map +1 -0
  68. package/dist/cli/session-log.d.ts +34 -0
  69. package/dist/cli/session-log.d.ts.map +1 -0
  70. package/dist/cli/session-log.js +52 -0
  71. package/dist/cli/session-log.js.map +1 -0
  72. package/dist/cli/spec.d.ts +62 -0
  73. package/dist/cli/spec.d.ts.map +1 -0
  74. package/dist/cli/spec.js +510 -0
  75. package/dist/cli/spec.js.map +1 -0
  76. package/dist/cli/ui/RunView.d.ts +134 -0
  77. package/dist/cli/ui/RunView.d.ts.map +1 -0
  78. package/dist/cli/ui/RunView.js +341 -0
  79. package/dist/cli/ui/RunView.js.map +1 -0
  80. package/dist/events/codec.d.ts +79 -0
  81. package/dist/events/codec.d.ts.map +1 -0
  82. package/dist/events/codec.js +142 -0
  83. package/dist/events/codec.js.map +1 -0
  84. package/dist/events/log-core.d.ts +76 -0
  85. package/dist/events/log-core.d.ts.map +1 -0
  86. package/dist/events/log-core.js +73 -0
  87. package/dist/events/log-core.js.map +1 -0
  88. package/dist/events/log.d.ts +60 -0
  89. package/dist/events/log.d.ts.map +1 -0
  90. package/dist/events/log.js +193 -0
  91. package/dist/events/log.js.map +1 -0
  92. package/dist/events/replay.d.ts +106 -0
  93. package/dist/events/replay.d.ts.map +1 -0
  94. package/dist/events/replay.js +137 -0
  95. package/dist/events/replay.js.map +1 -0
  96. package/dist/events/wrap.d.ts +100 -0
  97. package/dist/events/wrap.d.ts.map +1 -0
  98. package/dist/events/wrap.js +141 -0
  99. package/dist/events/wrap.js.map +1 -0
  100. package/dist/index.d.ts +52 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +37 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/llm-adapter.d.ts +96 -0
  105. package/dist/llm-adapter.d.ts.map +1 -0
  106. package/dist/llm-adapter.js +132 -0
  107. package/dist/llm-adapter.js.map +1 -0
  108. package/dist/mcp/serve.d.ts +70 -0
  109. package/dist/mcp/serve.d.ts.map +1 -0
  110. package/dist/mcp/serve.js +154 -0
  111. package/dist/mcp/serve.js.map +1 -0
  112. package/dist/metrics/runs.d.ts +58 -0
  113. package/dist/metrics/runs.d.ts.map +1 -0
  114. package/dist/metrics/runs.js +99 -0
  115. package/dist/metrics/runs.js.map +1 -0
  116. package/dist/metrics.d.ts +38 -0
  117. package/dist/metrics.d.ts.map +1 -0
  118. package/dist/metrics.js +123 -0
  119. package/dist/metrics.js.map +1 -0
  120. package/dist/node.d.ts +22 -0
  121. package/dist/node.d.ts.map +1 -0
  122. package/dist/node.js +22 -0
  123. package/dist/node.js.map +1 -0
  124. package/dist/session.d.ts +10 -0
  125. package/dist/session.d.ts.map +1 -0
  126. package/dist/session.js +179 -0
  127. package/dist/session.js.map +1 -0
  128. package/dist/storage.d.ts +14 -0
  129. package/dist/storage.d.ts.map +1 -0
  130. package/dist/storage.js +58 -0
  131. package/dist/storage.js.map +1 -0
  132. package/dist/strategy.d.ts +26 -0
  133. package/dist/strategy.d.ts.map +1 -0
  134. package/dist/strategy.js +200 -0
  135. package/dist/strategy.js.map +1 -0
  136. package/dist/tools.d.ts +26 -0
  137. package/dist/tools.d.ts.map +1 -0
  138. package/dist/tools.js +129 -0
  139. package/dist/tools.js.map +1 -0
  140. package/dist/types/agent.d.ts +94 -0
  141. package/dist/types/agent.d.ts.map +1 -0
  142. package/dist/types/agent.js +17 -0
  143. package/dist/types/agent.js.map +1 -0
  144. package/dist/types/capabilities.d.ts +17 -0
  145. package/dist/types/capabilities.d.ts.map +1 -0
  146. package/dist/types/capabilities.js +13 -0
  147. package/dist/types/capabilities.js.map +1 -0
  148. package/dist/types/chat.d.ts +74 -0
  149. package/dist/types/chat.d.ts.map +1 -0
  150. package/dist/types/chat.js +10 -0
  151. package/dist/types/chat.js.map +1 -0
  152. package/dist/types/events.d.ts +115 -0
  153. package/dist/types/events.d.ts.map +1 -0
  154. package/dist/types/events.js +30 -0
  155. package/dist/types/events.js.map +1 -0
  156. package/dist/types/llm.d.ts +89 -0
  157. package/dist/types/llm.d.ts.map +1 -0
  158. package/dist/types/llm.js +12 -0
  159. package/dist/types/llm.js.map +1 -0
  160. package/dist/types/metrics.d.ts +34 -0
  161. package/dist/types/metrics.d.ts.map +1 -0
  162. package/dist/types/metrics.js +10 -0
  163. package/dist/types/metrics.js.map +1 -0
  164. package/dist/types/observer.d.ts +41 -0
  165. package/dist/types/observer.d.ts.map +1 -0
  166. package/dist/types/observer.js +41 -0
  167. package/dist/types/observer.js.map +1 -0
  168. package/dist/types/project-context.d.ts +18 -0
  169. package/dist/types/project-context.d.ts.map +1 -0
  170. package/dist/types/project-context.js +11 -0
  171. package/dist/types/project-context.js.map +1 -0
  172. package/dist/types/runtime.d.ts +71 -0
  173. package/dist/types/runtime.d.ts.map +1 -0
  174. package/dist/types/runtime.js +21 -0
  175. package/dist/types/runtime.js.map +1 -0
  176. package/dist/types/session.d.ts +103 -0
  177. package/dist/types/session.d.ts.map +1 -0
  178. package/dist/types/session.js +11 -0
  179. package/dist/types/session.js.map +1 -0
  180. package/dist/types/storage.d.ts +20 -0
  181. package/dist/types/storage.d.ts.map +1 -0
  182. package/dist/types/storage.js +41 -0
  183. package/dist/types/storage.js.map +1 -0
  184. package/dist/types/strategy.d.ts +76 -0
  185. package/dist/types/strategy.d.ts.map +1 -0
  186. package/dist/types/strategy.js +10 -0
  187. package/dist/types/strategy.js.map +1 -0
  188. package/dist/types/tools.d.ts +136 -0
  189. package/dist/types/tools.d.ts.map +1 -0
  190. package/dist/types/tools.js +11 -0
  191. package/dist/types/tools.js.map +1 -0
  192. package/dist/types/trace.d.ts +125 -0
  193. package/dist/types/trace.d.ts.map +1 -0
  194. package/dist/types/trace.js +24 -0
  195. package/dist/types/trace.js.map +1 -0
  196. package/dist/types/workspace.d.ts +29 -0
  197. package/dist/types/workspace.d.ts.map +1 -0
  198. package/dist/types/workspace.js +18 -0
  199. package/dist/types/workspace.js.map +1 -0
  200. package/package.json +45 -14
  201. package/skills/agent-cli.md +218 -0
  202. package/index.js +0 -2
@@ -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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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * `replayEvents()` — forward replay of a project's event log against a
3
+ * caller-supplied `ToolDispatch`.
4
+ *
5
+ * Pair to `wrapMutating()` + `agent undo`:
6
+ * - `wrapMutating` writes structured events as a side effect of
7
+ * running tools.
8
+ * - `undoCommand` walks the log backwards (commit → rollback) to
9
+ * reverse a single mutation.
10
+ * - `replayEvents()` walks the log forwards (`commit` events in id
11
+ * order) and re-dispatches each tool with its recorded args, so
12
+ * the same mutations can be re-applied to a *different* dispatch
13
+ * (typical case: dev simulator → production registry).
14
+ *
15
+ * Idempotency:
16
+ * - Each successfully-applied event gets a `migrate_applied` marker
17
+ * event written back to the same log (or a separate target log
18
+ * when `targetLog` is provided). Re-running `replayEvents()` skips
19
+ * events whose marker is already present, so partial-failure +
20
+ * retry is safe.
21
+ * - The caller can additionally provide `shouldApply` to gate
22
+ * events. The callback fires for every event (it is NOT a
23
+ * conflict-only hook); the caller is responsible for whatever
24
+ * state-read or business logic decides apply / skip / abort.
25
+ *
26
+ * Boundaries:
27
+ * - This function calls `dispatch.execute()`. It is therefore
28
+ * *not* CLI-safe — it expects a real dispatch wired to real
29
+ * services. The `agent migrate` subcommand only PLANS replay; the
30
+ * host runs `replayEvents()` against its prod dispatch.
31
+ * - **The dispatch handlers MUST be unwrapped.** If you re-apply
32
+ * `wrapMutating()` at replay time, each replayed event spawns a
33
+ * fresh plan/commit pair on the target log — and a subsequent
34
+ * replay run would try to re-replay those. Wrap on the system
35
+ * that PRODUCES the log; do not wrap on the system that CONSUMES
36
+ * it via replay.
37
+ */
38
+ import type { MutationEvent } from '../types/events.js';
39
+ import type { ToolContext, ToolDispatch, ToolResult } from '../types/tools.js';
40
+ import type { EventLog } from './log-core.js';
41
+ export interface ReplayOptions {
42
+ /** Source log to read commits from. */
43
+ log: EventLog;
44
+ /** Dispatch to invoke each replayed tool against.
45
+ * **MUST register unwrapped handlers** — see file header. */
46
+ dispatch: ToolDispatch;
47
+ /** Factory producing a fresh `ToolContext` per dispatch call. */
48
+ toolContext(): ToolContext;
49
+ /** Replay only events with id >= this id (inclusive). Lexically
50
+ * compared — works because event ids are time-prefixed base36. */
51
+ sinceEventId?: string;
52
+ /** Restrict to these tool names. Unset → replay every commit. */
53
+ toolAllowlist?: readonly string[];
54
+ /** Skip events whose `target.path` matches any of these. */
55
+ pathDenyList?: readonly string[];
56
+ /**
57
+ * Per-event resolver. Fires for every event *after* it passes the
58
+ * tool / path / already-applied filters. Use it to read target
59
+ * state and decide apply / skip / abort — replayEvents itself does
60
+ * not read target state. Default: 'apply' for all events.
61
+ *
62
+ * Renamed from the previous `onConflict` to better reflect what it
63
+ * actually does (it is not a conflict-only hook).
64
+ */
65
+ shouldApply?: (event: MutationEvent) => 'apply' | 'skip' | 'abort';
66
+ /** When true: emit `plan` progress events but do NOT call dispatch.
67
+ * No `migrate_applied` markers are written. */
68
+ dryRun?: boolean;
69
+ /** Optional separate log to write the `migrate_applied` markers
70
+ * into. Defaults to the source log. Useful when the prod
71
+ * environment maintains its own event log. */
72
+ targetLog?: EventLog;
73
+ /** Agent identifier stamped on the `migrate_applied` markers.
74
+ * Defaults to 'replay'. */
75
+ agent?: string;
76
+ /** Session id stamped on markers. Defaults to a synthesized id. */
77
+ sessionId?: string;
78
+ }
79
+ export type ReplayProgress = {
80
+ type: 'plan';
81
+ event: MutationEvent;
82
+ } | {
83
+ type: 'applied';
84
+ event: MutationEvent;
85
+ markerId: string;
86
+ result: ToolResult;
87
+ } | {
88
+ type: 'skipped';
89
+ event: MutationEvent;
90
+ reason: 'already_applied' | 'tool_denied' | 'path_denied' | 'shouldapply_skip';
91
+ } | {
92
+ type: 'error';
93
+ event: MutationEvent;
94
+ message: string;
95
+ } | {
96
+ type: 'done';
97
+ total: number;
98
+ applied: number;
99
+ skipped: number;
100
+ errors: number;
101
+ };
102
+ export declare class ReplayInvariantError extends Error {
103
+ readonly name = "ReplayInvariantError";
104
+ }
105
+ export declare function replayEvents(opts: ReplayOptions): AsyncIterable<ReplayProgress>;
106
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/events/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,GAAG,EAAE,QAAQ,CAAC;IACd;kEAC8D;IAC9D,QAAQ,EAAE,YAAY,CAAC;IACvB,iEAAiE;IACjE,WAAW,IAAI,WAAW,CAAC;IAC3B;uEACmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,4DAA4D;IAC5D,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACnE;oDACgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;mDAE+C;IAC/C,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB;gCAC4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC/E;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,kBAAkB,CAAC;CAChF,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAItF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAkB,IAAI,0BAA0B;CACjD;AAED,wBAAuB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAAC,cAAc,CAAC,CAyGtF"}