@particle-academy/agent-integrations 0.28.2 → 0.29.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 (161) hide show
  1. package/README.md +9 -0
  2. package/dist/bridges/artboard.d.cts +3 -3
  3. package/dist/bridges/artboard.d.ts +3 -3
  4. package/dist/bridges/catalog.d.cts +3 -3
  5. package/dist/bridges/catalog.d.ts +3 -3
  6. package/dist/bridges/charts.d.cts +3 -3
  7. package/dist/bridges/charts.d.ts +3 -3
  8. package/dist/bridges/cms.d.cts +3 -3
  9. package/dist/bridges/cms.d.ts +3 -3
  10. package/dist/bridges/code.d.cts +3 -3
  11. package/dist/bridges/code.d.ts +3 -3
  12. package/dist/bridges/doc.d.cts +3 -3
  13. package/dist/bridges/doc.d.ts +3 -3
  14. package/dist/bridges/features.d.cts +3 -3
  15. package/dist/bridges/features.d.ts +3 -3
  16. package/dist/bridges/files.d.cts +3 -3
  17. package/dist/bridges/files.d.ts +3 -3
  18. package/dist/bridges/flow.d.cts +3 -3
  19. package/dist/bridges/flow.d.ts +3 -3
  20. package/dist/bridges/forms.d.cts +3 -3
  21. package/dist/bridges/forms.d.ts +3 -3
  22. package/dist/bridges/map.d.cts +3 -3
  23. package/dist/bridges/map.d.ts +3 -3
  24. package/dist/bridges/scene.d.cts +3 -3
  25. package/dist/bridges/scene.d.ts +3 -3
  26. package/dist/bridges/screens.d.cts +3 -3
  27. package/dist/bridges/screens.d.ts +3 -3
  28. package/dist/bridges/sheets.d.cts +3 -3
  29. package/dist/bridges/sheets.d.ts +3 -3
  30. package/dist/bridges/slides.d.cts +3 -3
  31. package/dist/bridges/slides.d.ts +3 -3
  32. package/dist/bridges/terminal.d.cts +3 -3
  33. package/dist/bridges/terminal.d.ts +3 -3
  34. package/dist/bridges/tui.d.cts +45 -0
  35. package/dist/bridges/tui.d.ts +45 -0
  36. package/dist/bridges/whiteboard.d.cts +3 -3
  37. package/dist/bridges/whiteboard.d.ts +3 -3
  38. package/dist/bridges-artboard.cjs.map +1 -1
  39. package/dist/bridges-artboard.js +2 -2
  40. package/dist/bridges-catalog.cjs.map +1 -1
  41. package/dist/bridges-catalog.js +3 -3
  42. package/dist/bridges-charts.cjs.map +1 -1
  43. package/dist/bridges-charts.js +3 -3
  44. package/dist/bridges-cms.cjs.map +1 -1
  45. package/dist/bridges-cms.js +4 -4
  46. package/dist/bridges-code.cjs.map +1 -1
  47. package/dist/bridges-code.js +3 -3
  48. package/dist/bridges-doc.cjs.map +1 -1
  49. package/dist/bridges-doc.js +3 -3
  50. package/dist/bridges-features.cjs.map +1 -1
  51. package/dist/bridges-features.js +3 -3
  52. package/dist/bridges-files.cjs.map +1 -1
  53. package/dist/bridges-files.js +3 -3
  54. package/dist/bridges-flow.cjs.map +1 -1
  55. package/dist/bridges-flow.js +2 -2
  56. package/dist/bridges-forms.cjs.map +1 -1
  57. package/dist/bridges-forms.js +3 -3
  58. package/dist/bridges-map.cjs.map +1 -1
  59. package/dist/bridges-map.js +3 -3
  60. package/dist/bridges-scene.cjs.map +1 -1
  61. package/dist/bridges-scene.js +3 -3
  62. package/dist/bridges-screens.cjs.map +1 -1
  63. package/dist/bridges-screens.js +3 -3
  64. package/dist/bridges-sheets.cjs.map +1 -1
  65. package/dist/bridges-sheets.js +3 -3
  66. package/dist/bridges-slides.cjs.map +1 -1
  67. package/dist/bridges-slides.js +3 -3
  68. package/dist/bridges-terminal.cjs.map +1 -1
  69. package/dist/bridges-terminal.js +3 -3
  70. package/dist/bridges-tui.cjs +114 -0
  71. package/dist/bridges-tui.cjs.map +1 -0
  72. package/dist/bridges-tui.js +7 -0
  73. package/dist/bridges-tui.js.map +1 -0
  74. package/dist/bridges-whiteboard.cjs.map +1 -1
  75. package/dist/bridges-whiteboard.js +3 -3
  76. package/dist/{chunk-AROVENCE.js → chunk-2Y7Y5PTR.js} +4 -4
  77. package/dist/{chunk-AROVENCE.js.map → chunk-2Y7Y5PTR.js.map} +1 -1
  78. package/dist/{chunk-QDD4WHIV.js → chunk-3PKHJ4IV.js} +4 -4
  79. package/dist/{chunk-QDD4WHIV.js.map → chunk-3PKHJ4IV.js.map} +1 -1
  80. package/dist/{chunk-A57CRGEK.js → chunk-7VBB2FJB.js} +3 -3
  81. package/dist/{chunk-A57CRGEK.js.map → chunk-7VBB2FJB.js.map} +1 -1
  82. package/dist/{chunk-FF5F526J.js → chunk-AF454WRD.js} +4 -4
  83. package/dist/{chunk-FF5F526J.js.map → chunk-AF454WRD.js.map} +1 -1
  84. package/dist/{chunk-66WOHZZJ.js → chunk-BE2XS577.js} +4 -4
  85. package/dist/{chunk-66WOHZZJ.js.map → chunk-BE2XS577.js.map} +1 -1
  86. package/dist/{chunk-GHY3PBPN.js → chunk-BT7HM5I6.js} +3 -3
  87. package/dist/{chunk-GHY3PBPN.js.map → chunk-BT7HM5I6.js.map} +1 -1
  88. package/dist/{chunk-KJ5AOOV7.js → chunk-CT3LRNH7.js} +3 -3
  89. package/dist/{chunk-KJ5AOOV7.js.map → chunk-CT3LRNH7.js.map} +1 -1
  90. package/dist/{chunk-4KAIV6OD.js → chunk-DF3PLL2E.js} +10 -5
  91. package/dist/chunk-DF3PLL2E.js.map +1 -0
  92. package/dist/{chunk-AAD3Z5E7.js → chunk-HFLHLS2N.js} +4 -4
  93. package/dist/{chunk-AAD3Z5E7.js.map → chunk-HFLHLS2N.js.map} +1 -1
  94. package/dist/{chunk-HWVVS6HE.js → chunk-KKGC4ERF.js} +4 -4
  95. package/dist/{chunk-HWVVS6HE.js.map → chunk-KKGC4ERF.js.map} +1 -1
  96. package/dist/{chunk-NN3ELTVO.js → chunk-KYMEDV6E.js} +4 -4
  97. package/dist/{chunk-NN3ELTVO.js.map → chunk-KYMEDV6E.js.map} +1 -1
  98. package/dist/{chunk-YGD2VTUM.js → chunk-LZJI7EKQ.js} +4 -4
  99. package/dist/{chunk-YGD2VTUM.js.map → chunk-LZJI7EKQ.js.map} +1 -1
  100. package/dist/chunk-MFMBR6LN.js +100 -0
  101. package/dist/chunk-MFMBR6LN.js.map +1 -0
  102. package/dist/{chunk-VFKO2VUR.js → chunk-NSPL5TVF.js} +4 -4
  103. package/dist/{chunk-VFKO2VUR.js.map → chunk-NSPL5TVF.js.map} +1 -1
  104. package/dist/{chunk-AAMQOXZC.js → chunk-OFCR6JY3.js} +4 -4
  105. package/dist/{chunk-AAMQOXZC.js.map → chunk-OFCR6JY3.js.map} +1 -1
  106. package/dist/{chunk-ZX6UQURN.js → chunk-OHUDEA6R.js} +4 -4
  107. package/dist/{chunk-ZX6UQURN.js.map → chunk-OHUDEA6R.js.map} +1 -1
  108. package/dist/chunk-PMI4C5S4.js +44 -0
  109. package/dist/chunk-PMI4C5S4.js.map +1 -0
  110. package/dist/{chunk-PCW2EK5G.js → chunk-TNU6AWUO.js} +4 -4
  111. package/dist/{chunk-PCW2EK5G.js.map → chunk-TNU6AWUO.js.map} +1 -1
  112. package/dist/{chunk-QRDVJW6Q.js → chunk-UTUVN6HQ.js} +4 -4
  113. package/dist/{chunk-QRDVJW6Q.js.map → chunk-UTUVN6HQ.js.map} +1 -1
  114. package/dist/{chunk-XMMCSQ4I.js → chunk-VMCG3PJD.js} +4 -4
  115. package/dist/{chunk-XMMCSQ4I.js.map → chunk-VMCG3PJD.js.map} +1 -1
  116. package/dist/components-shared-whiteboard.cjs +8 -3
  117. package/dist/components-shared-whiteboard.cjs.map +1 -1
  118. package/dist/components-shared-whiteboard.js +3 -3
  119. package/dist/human-plus/file-store.d.cts +17 -0
  120. package/dist/human-plus/file-store.d.ts +17 -0
  121. package/dist/human-plus/index.d.cts +61 -0
  122. package/dist/human-plus/index.d.ts +61 -0
  123. package/dist/human-plus-node.cjs +121 -0
  124. package/dist/human-plus-node.cjs.map +1 -0
  125. package/dist/human-plus-node.js +76 -0
  126. package/dist/human-plus-node.js.map +1 -0
  127. package/dist/human-plus.cjs +46 -0
  128. package/dist/human-plus.cjs.map +1 -0
  129. package/dist/human-plus.js +3 -0
  130. package/dist/human-plus.js.map +1 -0
  131. package/dist/index.cjs +181 -39
  132. package/dist/index.cjs.map +1 -1
  133. package/dist/index.d.cts +9 -7
  134. package/dist/index.d.ts +9 -7
  135. package/dist/index.js +27 -25
  136. package/dist/index.js.map +1 -1
  137. package/dist/mcp/index.d.cts +5 -5
  138. package/dist/mcp/index.d.ts +5 -5
  139. package/dist/mcp.cjs +8 -3
  140. package/dist/mcp.cjs.map +1 -1
  141. package/dist/mcp.js +1 -1
  142. package/dist/presence/index.d.cts +1 -1
  143. package/dist/presence/index.d.ts +1 -1
  144. package/dist/{server-FFZpYPyM.d.ts → server-CDX643Kz.d.ts} +4 -2
  145. package/dist/{server-Dr3j48CU.d.cts → server-DDD3IZ56.d.cts} +4 -2
  146. package/dist/sharing/index.d.cts +3 -3
  147. package/dist/sharing/index.d.ts +3 -3
  148. package/dist/sheets-adapter.d.cts +3 -3
  149. package/dist/sheets-adapter.d.ts +3 -3
  150. package/dist/{tool-host-C_Vh17J_.d.ts → tool-host-CWTOJEm2.d.ts} +1 -1
  151. package/dist/{tool-host-IDecPrF1.d.cts → tool-host-EuYHYSSH.d.cts} +1 -1
  152. package/dist/{types-CBoQhR8L.d.ts → types-BKD6uf86.d.ts} +1 -1
  153. package/dist/{types-BDI_g5UG.d.ts → types-C58ZXs4K.d.cts} +6 -2
  154. package/dist/{types-BDI_g5UG.d.cts → types-C58ZXs4K.d.ts} +6 -2
  155. package/dist/{types-B0rmWyoR.d.cts → types-NFGP769G.d.cts} +1 -1
  156. package/dist/undo/index.d.cts +2 -2
  157. package/dist/undo/index.d.ts +2 -2
  158. package/dist/undo.cjs.map +1 -1
  159. package/dist/undo.js +3 -3
  160. package/package.json +13 -1
  161. package/dist/chunk-4KAIV6OD.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  import { ShareControls, AgentCursor, AgentActivityHighlight, AgentPanel } from './chunk-5KLUYF4D.js';
2
2
  import { createSessionDescriptor, attachSseRelay } from './chunk-KMSRG5KH.js';
3
3
  import { attachInProcess } from './chunk-AFUULW5E.js';
4
- import { registerWhiteboardBridge } from './chunk-AAMQOXZC.js';
4
+ import { registerWhiteboardBridge } from './chunk-OFCR6JY3.js';
5
+ import './chunk-CT3LRNH7.js';
5
6
  import './chunk-ULJL53DL.js';
6
- import './chunk-KJ5AOOV7.js';
7
7
  import './chunk-C3TYI5TJ.js';
8
- import { MicroMcpServer } from './chunk-4KAIV6OD.js';
8
+ import { MicroMcpServer } from './chunk-DF3PLL2E.js';
9
9
  import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
10
10
  import { Board, Connector, Shape, StickyNote, CursorLayer } from '@particle-academy/fancy-whiteboard';
11
11
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -0,0 +1,17 @@
1
+ import { MemoryHumanPlusEventStore, NewHumanPlusEvent, HumanPlusEvent, HumanPlusEventPage, HumanPlusDisposition } from './index.cjs';
2
+
3
+ /** Single-process append-only JSONL store for local terminal applications. */
4
+ declare class FileHumanPlusEventStore extends MemoryHumanPlusEventStore {
5
+ private readonly path;
6
+ private ready;
7
+ private writes;
8
+ constructor(path: string);
9
+ private load;
10
+ private enqueue;
11
+ append(input: NewHumanPlusEvent): Promise<HumanPlusEvent<unknown>>;
12
+ list(query: Parameters<MemoryHumanPlusEventStore["list"]>[0]): Promise<HumanPlusEventPage>;
13
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
14
+ compact(options?: Parameters<MemoryHumanPlusEventStore["compact"]>[0]): Promise<void>;
15
+ }
16
+
17
+ export { FileHumanPlusEventStore };
@@ -0,0 +1,17 @@
1
+ import { MemoryHumanPlusEventStore, NewHumanPlusEvent, HumanPlusEvent, HumanPlusEventPage, HumanPlusDisposition } from './index.js';
2
+
3
+ /** Single-process append-only JSONL store for local terminal applications. */
4
+ declare class FileHumanPlusEventStore extends MemoryHumanPlusEventStore {
5
+ private readonly path;
6
+ private ready;
7
+ private writes;
8
+ constructor(path: string);
9
+ private load;
10
+ private enqueue;
11
+ append(input: NewHumanPlusEvent): Promise<HumanPlusEvent<unknown>>;
12
+ list(query: Parameters<MemoryHumanPlusEventStore["list"]>[0]): Promise<HumanPlusEventPage>;
13
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
14
+ compact(options?: Parameters<MemoryHumanPlusEventStore["compact"]>[0]): Promise<void>;
15
+ }
16
+
17
+ export { FileHumanPlusEventStore };
@@ -0,0 +1,61 @@
1
+ type HumanPlusActor = {
2
+ kind: "human" | "agent" | "system";
3
+ id: string;
4
+ name?: string;
5
+ };
6
+ type HumanPlusPriority = "background" | "normal" | "attention" | "blocking";
7
+ type HumanPlusDisposition = "seen" | "handled" | "rejected" | "ignored";
8
+ interface HumanPlusEvent<T = unknown> {
9
+ id: string;
10
+ sequence: number;
11
+ timestamp: number;
12
+ appId: string;
13
+ surfaceId: string;
14
+ sessionId?: string;
15
+ type: string;
16
+ payload: T;
17
+ actor: HumanPlusActor;
18
+ priority: HumanPlusPriority;
19
+ correlationId?: string;
20
+ causationId?: string;
21
+ }
22
+ type NewHumanPlusEvent<T = unknown> = Omit<HumanPlusEvent<T>, "id" | "sequence" | "timestamp"> & Partial<Pick<HumanPlusEvent<T>, "id" | "timestamp">>;
23
+ interface HumanPlusEventQuery {
24
+ consumerId: string;
25
+ after?: number;
26
+ limit?: number;
27
+ unacknowledgedOnly?: boolean;
28
+ types?: string[];
29
+ surfaces?: string[];
30
+ }
31
+ interface HumanPlusEventPage {
32
+ events: HumanPlusEvent[];
33
+ nextCursor: number;
34
+ }
35
+ type HumanPlusEventListener = (event: HumanPlusEvent) => void;
36
+ interface HumanPlusEventStore {
37
+ append(event: NewHumanPlusEvent): Promise<HumanPlusEvent>;
38
+ list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;
39
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
40
+ subscribe(listener: HumanPlusEventListener): () => void;
41
+ compact?(options?: {
42
+ before?: number;
43
+ keepLast?: number;
44
+ }): Promise<void>;
45
+ }
46
+ declare class MemoryHumanPlusEventStore implements HumanPlusEventStore {
47
+ protected events: HumanPlusEvent[];
48
+ protected acknowledgements: Map<string, Map<string, HumanPlusDisposition>>;
49
+ protected listeners: Set<HumanPlusEventListener>;
50
+ protected nextSequence: number;
51
+ append(input: NewHumanPlusEvent): Promise<HumanPlusEvent>;
52
+ list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;
53
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
54
+ subscribe(listener: HumanPlusEventListener): () => void;
55
+ compact(options?: {
56
+ before?: number;
57
+ keepLast?: number;
58
+ }): Promise<void>;
59
+ }
60
+
61
+ export { type HumanPlusActor, type HumanPlusDisposition, type HumanPlusEvent, type HumanPlusEventListener, type HumanPlusEventPage, type HumanPlusEventQuery, type HumanPlusEventStore, type HumanPlusPriority, MemoryHumanPlusEventStore, type NewHumanPlusEvent };
@@ -0,0 +1,61 @@
1
+ type HumanPlusActor = {
2
+ kind: "human" | "agent" | "system";
3
+ id: string;
4
+ name?: string;
5
+ };
6
+ type HumanPlusPriority = "background" | "normal" | "attention" | "blocking";
7
+ type HumanPlusDisposition = "seen" | "handled" | "rejected" | "ignored";
8
+ interface HumanPlusEvent<T = unknown> {
9
+ id: string;
10
+ sequence: number;
11
+ timestamp: number;
12
+ appId: string;
13
+ surfaceId: string;
14
+ sessionId?: string;
15
+ type: string;
16
+ payload: T;
17
+ actor: HumanPlusActor;
18
+ priority: HumanPlusPriority;
19
+ correlationId?: string;
20
+ causationId?: string;
21
+ }
22
+ type NewHumanPlusEvent<T = unknown> = Omit<HumanPlusEvent<T>, "id" | "sequence" | "timestamp"> & Partial<Pick<HumanPlusEvent<T>, "id" | "timestamp">>;
23
+ interface HumanPlusEventQuery {
24
+ consumerId: string;
25
+ after?: number;
26
+ limit?: number;
27
+ unacknowledgedOnly?: boolean;
28
+ types?: string[];
29
+ surfaces?: string[];
30
+ }
31
+ interface HumanPlusEventPage {
32
+ events: HumanPlusEvent[];
33
+ nextCursor: number;
34
+ }
35
+ type HumanPlusEventListener = (event: HumanPlusEvent) => void;
36
+ interface HumanPlusEventStore {
37
+ append(event: NewHumanPlusEvent): Promise<HumanPlusEvent>;
38
+ list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;
39
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
40
+ subscribe(listener: HumanPlusEventListener): () => void;
41
+ compact?(options?: {
42
+ before?: number;
43
+ keepLast?: number;
44
+ }): Promise<void>;
45
+ }
46
+ declare class MemoryHumanPlusEventStore implements HumanPlusEventStore {
47
+ protected events: HumanPlusEvent[];
48
+ protected acknowledgements: Map<string, Map<string, HumanPlusDisposition>>;
49
+ protected listeners: Set<HumanPlusEventListener>;
50
+ protected nextSequence: number;
51
+ append(input: NewHumanPlusEvent): Promise<HumanPlusEvent>;
52
+ list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;
53
+ acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;
54
+ subscribe(listener: HumanPlusEventListener): () => void;
55
+ compact(options?: {
56
+ before?: number;
57
+ keepLast?: number;
58
+ }): Promise<void>;
59
+ }
60
+
61
+ export { type HumanPlusActor, type HumanPlusDisposition, type HumanPlusEvent, type HumanPlusEventListener, type HumanPlusEventPage, type HumanPlusEventQuery, type HumanPlusEventStore, type HumanPlusPriority, MemoryHumanPlusEventStore, type NewHumanPlusEvent };
@@ -0,0 +1,121 @@
1
+ 'use strict';
2
+
3
+ var promises = require('fs/promises');
4
+ var path = require('path');
5
+
6
+ // src/human-plus/file-store.ts
7
+
8
+ // src/human-plus/events.ts
9
+ var MemoryHumanPlusEventStore = class {
10
+ constructor() {
11
+ this.events = [];
12
+ this.acknowledgements = /* @__PURE__ */ new Map();
13
+ this.listeners = /* @__PURE__ */ new Set();
14
+ this.nextSequence = 1;
15
+ }
16
+ async append(input) {
17
+ const event = { ...input, id: input.id ?? globalThis.crypto.randomUUID(), timestamp: input.timestamp ?? Date.now(), sequence: this.nextSequence++ };
18
+ this.events.push(event);
19
+ this.listeners.forEach((listener) => listener(event));
20
+ return event;
21
+ }
22
+ async list(query) {
23
+ const acknowledged = this.acknowledgements.get(query.consumerId);
24
+ const events = this.events.filter((event) => event.sequence > (query.after ?? 0) && (!query.unacknowledgedOnly || !acknowledged?.has(event.id)) && (!query.types?.length || query.types.includes(event.type)) && (!query.surfaces?.length || query.surfaces.includes(event.surfaceId))).slice(0, Math.max(1, Math.min(500, query.limit ?? 50)));
25
+ return { events, nextCursor: events.at(-1)?.sequence ?? query.after ?? 0 };
26
+ }
27
+ async acknowledge(consumerId, eventIds, disposition) {
28
+ let values = this.acknowledgements.get(consumerId);
29
+ if (!values) {
30
+ values = /* @__PURE__ */ new Map();
31
+ this.acknowledgements.set(consumerId, values);
32
+ }
33
+ eventIds.forEach((id) => values.set(id, disposition));
34
+ }
35
+ subscribe(listener) {
36
+ this.listeners.add(listener);
37
+ return () => this.listeners.delete(listener);
38
+ }
39
+ async compact(options = {}) {
40
+ const cutoff = options.before ?? Number.POSITIVE_INFINITY;
41
+ const keep = options.keepLast ?? 1e3;
42
+ const removable = Math.max(0, this.events.length - keep);
43
+ this.events = this.events.filter((event, index) => index >= removable || event.timestamp >= cutoff);
44
+ const ids = new Set(this.events.map((event) => event.id));
45
+ for (const values of this.acknowledgements.values()) for (const id of values.keys()) if (!ids.has(id)) values.delete(id);
46
+ }
47
+ };
48
+
49
+ // src/human-plus/file-store.ts
50
+ var FileHumanPlusEventStore = class extends MemoryHumanPlusEventStore {
51
+ constructor(path) {
52
+ super();
53
+ this.path = path;
54
+ this.writes = Promise.resolve();
55
+ this.ready = this.load();
56
+ }
57
+ async load() {
58
+ let source = "";
59
+ try {
60
+ source = await promises.readFile(this.path, "utf8");
61
+ } catch (error) {
62
+ if (error?.code !== "ENOENT") throw error;
63
+ }
64
+ for (const line of source.split("\n")) {
65
+ if (!line.trim()) continue;
66
+ try {
67
+ const record = JSON.parse(line);
68
+ if (record.kind === "event") {
69
+ this.events.push(record.event);
70
+ this.nextSequence = Math.max(this.nextSequence, record.event.sequence + 1);
71
+ } else await super.acknowledge(record.consumerId, record.eventIds, record.disposition);
72
+ } catch {
73
+ }
74
+ }
75
+ }
76
+ enqueue(record) {
77
+ this.writes = this.writes.then(async () => {
78
+ await promises.mkdir(path.dirname(this.path), { recursive: true });
79
+ const handle = await promises.open(this.path, "a");
80
+ try {
81
+ await handle.appendFile(`${JSON.stringify(record)}
82
+ `, "utf8");
83
+ await handle.sync();
84
+ } finally {
85
+ await handle.close();
86
+ }
87
+ });
88
+ return this.writes;
89
+ }
90
+ async append(input) {
91
+ await this.ready;
92
+ const event = await super.append(input);
93
+ await this.enqueue({ kind: "event", event });
94
+ return event;
95
+ }
96
+ async list(query) {
97
+ await this.ready;
98
+ await this.writes;
99
+ return super.list(query);
100
+ }
101
+ async acknowledge(consumerId, eventIds, disposition) {
102
+ await this.ready;
103
+ await super.acknowledge(consumerId, eventIds, disposition);
104
+ await this.enqueue({ kind: "ack", consumerId, eventIds, disposition });
105
+ }
106
+ async compact(options = {}) {
107
+ await this.ready;
108
+ await this.writes;
109
+ await super.compact(options);
110
+ const records = this.events.map((event) => ({ kind: "event", event }));
111
+ for (const [consumerId, values] of this.acknowledgements) for (const [id, disposition] of values) records.push({ kind: "ack", consumerId, eventIds: [id], disposition });
112
+ const temporary = `${this.path}.${process.pid}.tmp`;
113
+ await promises.mkdir(path.dirname(this.path), { recursive: true });
114
+ await promises.writeFile(temporary, records.map((x) => JSON.stringify(x)).join("\n") + "\n", "utf8");
115
+ await promises.rename(temporary, this.path);
116
+ }
117
+ };
118
+
119
+ exports.FileHumanPlusEventStore = FileHumanPlusEventStore;
120
+ //# sourceMappingURL=human-plus-node.cjs.map
121
+ //# sourceMappingURL=human-plus-node.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/human-plus/events.ts","../src/human-plus/file-store.ts"],"names":["readFile","mkdir","dirname","open","writeFile","rename"],"mappings":";;;;;;;;AA+BO,IAAM,4BAAN,MAA+D;AAAA,EAA/D,WAAA,GAAA;AACL,IAAA,IAAA,CAAU,SAA2B,EAAC;AACtC,IAAA,IAAA,CAAU,gBAAA,uBAAuB,GAAA,EAA+C;AAChF,IAAA,IAAA,CAAU,SAAA,uBAAgB,GAAA,EAA4B;AACtD,IAAA,IAAA,CAAU,YAAA,GAAe,CAAA;AAAA,EAAA;AAAA,EAEzB,MAAM,OAAO,KAAA,EAAmD;AAC9D,IAAA,MAAM,QAAwB,EAAE,GAAG,OAAO,EAAA,EAAI,KAAA,CAAM,MAAM,UAAA,CAAW,MAAA,CAAO,YAAW,EAAG,SAAA,EAAW,MAAM,SAAA,IAAa,IAAA,CAAK,KAAI,EAAG,QAAA,EAAU,KAAK,YAAA,EAAA,EAAe;AAClK,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAAG,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,KAAK,CAAC,CAAA;AAAG,IAAA,OAAO,KAAA;AAAA,EACzF;AAAA,EACA,MAAM,KAAK,KAAA,EAAyD;AAClE,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,MAAM,UAAU,CAAA;AAC/D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,UAAU,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,KAAA,IAAS,CAAA,CAAA,KACxE,CAAC,MAAM,kBAAA,IAAsB,CAAC,YAAA,EAAc,GAAA,CAAI,KAAA,CAAM,EAAE,OACxD,CAAC,KAAA,CAAM,KAAA,EAAO,MAAA,IAAU,KAAA,CAAM,KAAA,CAAM,SAAS,KAAA,CAAM,IAAI,CAAA,CAAA,KACvD,CAAC,KAAA,CAAM,QAAA,EAAU,UAAU,KAAA,CAAM,QAAA,CAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,CAAE,EACvE,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAA,CAAM,KAAA,IAAS,EAAE,CAAC,CAAC,CAAA;AACzD,IAAA,OAAO,EAAE,MAAA,EAAQ,UAAA,EAAY,MAAA,CAAO,EAAA,CAAG,EAAE,CAAA,EAAG,QAAA,IAAY,KAAA,CAAM,KAAA,IAAS,CAAA,EAAE;AAAA,EAC3E;AAAA,EACA,MAAM,WAAA,CAAY,UAAA,EAAoB,QAAA,EAAoB,WAAA,EAAkD;AAC1G,IAAA,IAAI,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,UAAU,CAAA;AAAG,IAAA,IAAI,CAAC,MAAA,EAAQ;AAAE,MAAA,MAAA,uBAAa,GAAA,EAAI;AAAG,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,UAAA,EAAY,MAAM,CAAA;AAAA,IAAG;AACtI,IAAA,QAAA,CAAS,QAAQ,CAAC,EAAA,KAAO,OAAQ,GAAA,CAAI,EAAA,EAAI,WAAW,CAAC,CAAA;AAAA,EACvD;AAAA,EACA,UAAU,QAAA,EAA8C;AAAE,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAAG,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAAG;AAAA,EACtI,MAAM,OAAA,CAAQ,OAAA,GAAkD,EAAC,EAAkB;AACjF,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,MAAA,CAAO,iBAAA;AAAmB,IAAA,MAAM,IAAA,GAAO,QAAQ,QAAA,IAAY,GAAA;AAC5F,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,MAAA,CAAO,SAAS,IAAI,CAAA;AACvD,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,KAAA,EAAO,KAAA,KAAU,KAAA,IAAS,SAAA,IAAa,KAAA,CAAM,SAAA,IAAa,MAAM,CAAA;AAClG,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,IAAI,CAAC,KAAA,KAAU,KAAA,CAAM,EAAE,CAAC,CAAA;AACxD,IAAA,KAAA,MAAW,UAAU,IAAA,CAAK,gBAAA,CAAiB,QAAO,EAAG,KAAA,MAAW,MAAM,MAAA,CAAO,IAAA,EAAK,EAAG,IAAI,CAAC,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG,MAAA,CAAO,OAAO,EAAE,CAAA;AAAA,EACzH;AACF,CAAA;;;ACvDO,IAAM,uBAAA,GAAN,cAAsC,yBAAA,CAA0B;AAAA,EAGrE,YAA6B,IAAA,EAAc;AAAE,IAAA,KAAA,EAAM;AAAtB,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAD7B,IAAA,IAAA,CAAQ,MAAA,GAAS,QAAQ,OAAA,EAAQ;AACqB,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,IAAA,EAAK;AAAA,EAAG;AAAA,EAChF,MAAc,IAAA,GAAO;AACnB,IAAA,IAAI,MAAA,GAAS,EAAA;AAAI,IAAA,IAAI;AAAE,MAAA,MAAA,GAAS,MAAMA,iBAAA,CAAS,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,IAAG,SAAS,KAAA,EAAY;AAAE,MAAA,IAAI,KAAA,EAAO,IAAA,KAAS,QAAA,EAAU,MAAM,KAAA;AAAA,IAAO;AACrI,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,EAAG;AACrC,MAAA,IAAI,CAAC,IAAA,CAAK,IAAA,EAAK,EAAG;AAClB,MAAA,IAAI;AAAE,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAAoB,QAAA,IAAI,MAAA,CAAO,SAAS,OAAA,EAAS;AAAE,UAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA;AAAG,UAAA,IAAA,CAAK,YAAA,GAAe,KAAK,GAAA,CAAI,IAAA,CAAK,cAAc,MAAA,CAAO,KAAA,CAAM,WAAW,CAAC,CAAA;AAAA,QAAG,CAAA,YAAa,KAAA,CAAM,WAAA,CAAY,OAAO,UAAA,EAAY,MAAA,CAAO,QAAA,EAAU,MAAA,CAAO,WAAW,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAA0C;AAAA,IAC/U;AAAA,EACF;AAAA,EACQ,QAAQ,MAAA,EAAuB;AACrC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,YAAY;AAAE,MAAA,MAAMC,cAAA,CAAMC,aAAQ,IAAA,CAAK,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAAG,MAAA,MAAM,MAAA,GAAS,MAAMC,aAAA,CAAK,IAAA,CAAK,MAAM,GAAG,CAAA;AAAG,MAAA,IAAI;AAAE,QAAA,MAAM,OAAO,UAAA,CAAW,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC;AAAA,CAAA,EAAM,MAAM,CAAA;AAAG,QAAA,MAAM,OAAO,IAAA,EAAK;AAAA,MAAG,CAAA,SAAE;AAAU,QAAA,MAAM,OAAO,KAAA,EAAM;AAAA,MAAG;AAAA,IAAE,CAAC,CAAA;AAC9Q,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EACA,MAAe,OAAO,KAAA,EAA0B;AAAE,IAAA,MAAM,IAAA,CAAK,KAAA;AAAO,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,MAAA,CAAO,KAAK,CAAA;AAAG,IAAA,MAAM,KAAK,OAAA,CAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAAG,IAAA,OAAO,KAAA;AAAA,EAAO;AAAA,EACzK,MAAe,KAAK,KAAA,EAAyD;AAAE,IAAA,MAAM,IAAA,CAAK,KAAA;AAAO,IAAA,MAAM,IAAA,CAAK,MAAA;AAAQ,IAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,EAAG;AAAA,EAC9I,MAAe,WAAA,CAAY,UAAA,EAAoB,QAAA,EAAoB,WAAA,EAAmC;AAAE,IAAA,MAAM,IAAA,CAAK,KAAA;AAAO,IAAA,MAAM,KAAA,CAAM,WAAA,CAAY,UAAA,EAAY,QAAA,EAAU,WAAW,CAAA;AAAG,IAAA,MAAM,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAM,OAAO,UAAA,EAAY,QAAA,EAAU,aAAa,CAAA;AAAA,EAAG;AAAA,EAC9P,MAAe,OAAA,CAAQ,OAAA,GAA+D,EAAC,EAAG;AACxF,IAAA,MAAM,IAAA,CAAK,KAAA;AAAO,IAAA,MAAM,IAAA,CAAK,MAAA;AAAQ,IAAA,MAAM,KAAA,CAAM,QAAQ,OAAO,CAAA;AAChE,IAAA,MAAM,OAAA,GAA2B,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,CAAC,WAAW,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAM,CAAE,CAAA;AACtF,IAAA,KAAA,MAAW,CAAC,YAAY,MAAM,CAAA,IAAK,KAAK,gBAAA,EAAkB,KAAA,MAAW,CAAC,EAAA,EAAI,WAAW,CAAA,IAAK,QAAQ,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,KAAA,EAAO,UAAA,EAAY,UAAU,CAAC,EAAE,CAAA,EAAG,WAAA,EAAa,CAAA;AACvK,IAAA,MAAM,YAAY,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI,QAAQ,GAAG,CAAA,IAAA,CAAA;AAAQ,IAAA,MAAMF,cAAA,CAAMC,aAAQ,IAAA,CAAK,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAAG,IAAA,MAAME,kBAAA,CAAU,SAAA,EAAW,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAAI,MAAM,MAAM,CAAA;AAAG,IAAA,MAAMC,eAAA,CAAO,SAAA,EAAW,IAAA,CAAK,IAAI,CAAA;AAAA,EAC3O;AACF","file":"human-plus-node.cjs","sourcesContent":["export type HumanPlusActor = { kind: \"human\" | \"agent\" | \"system\"; id: string; name?: string };\nexport type HumanPlusPriority = \"background\" | \"normal\" | \"attention\" | \"blocking\";\nexport type HumanPlusDisposition = \"seen\" | \"handled\" | \"rejected\" | \"ignored\";\n\nexport interface HumanPlusEvent<T = unknown> {\n id: string;\n sequence: number;\n timestamp: number;\n appId: string;\n surfaceId: string;\n sessionId?: string;\n type: string;\n payload: T;\n actor: HumanPlusActor;\n priority: HumanPlusPriority;\n correlationId?: string;\n causationId?: string;\n}\nexport type NewHumanPlusEvent<T = unknown> = Omit<HumanPlusEvent<T>, \"id\" | \"sequence\" | \"timestamp\"> & Partial<Pick<HumanPlusEvent<T>, \"id\" | \"timestamp\">>;\nexport interface HumanPlusEventQuery { consumerId: string; after?: number; limit?: number; unacknowledgedOnly?: boolean; types?: string[]; surfaces?: string[]; }\nexport interface HumanPlusEventPage { events: HumanPlusEvent[]; nextCursor: number; }\nexport type HumanPlusEventListener = (event: HumanPlusEvent) => void;\n\nexport interface HumanPlusEventStore {\n append(event: NewHumanPlusEvent): Promise<HumanPlusEvent>;\n list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;\n acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;\n subscribe(listener: HumanPlusEventListener): () => void;\n compact?(options?: { before?: number; keepLast?: number }): Promise<void>;\n}\n\nexport class MemoryHumanPlusEventStore implements HumanPlusEventStore {\n protected events: HumanPlusEvent[] = [];\n protected acknowledgements = new Map<string, Map<string, HumanPlusDisposition>>();\n protected listeners = new Set<HumanPlusEventListener>();\n protected nextSequence = 1;\n\n async append(input: NewHumanPlusEvent): Promise<HumanPlusEvent> {\n const event: HumanPlusEvent = { ...input, id: input.id ?? globalThis.crypto.randomUUID(), timestamp: input.timestamp ?? Date.now(), sequence: this.nextSequence++ };\n this.events.push(event); this.listeners.forEach((listener) => listener(event)); return event;\n }\n async list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage> {\n const acknowledged = this.acknowledgements.get(query.consumerId);\n const events = this.events.filter((event) => event.sequence > (query.after ?? 0)\n && (!query.unacknowledgedOnly || !acknowledged?.has(event.id))\n && (!query.types?.length || query.types.includes(event.type))\n && (!query.surfaces?.length || query.surfaces.includes(event.surfaceId)))\n .slice(0, Math.max(1, Math.min(500, query.limit ?? 50)));\n return { events, nextCursor: events.at(-1)?.sequence ?? query.after ?? 0 };\n }\n async acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void> {\n let values = this.acknowledgements.get(consumerId); if (!values) { values = new Map(); this.acknowledgements.set(consumerId, values); }\n eventIds.forEach((id) => values!.set(id, disposition));\n }\n subscribe(listener: HumanPlusEventListener): () => void { this.listeners.add(listener); return () => this.listeners.delete(listener); }\n async compact(options: { before?: number; keepLast?: number } = {}): Promise<void> {\n const cutoff = options.before ?? Number.POSITIVE_INFINITY; const keep = options.keepLast ?? 1000;\n const removable = Math.max(0, this.events.length - keep);\n this.events = this.events.filter((event, index) => index >= removable || event.timestamp >= cutoff);\n const ids = new Set(this.events.map((event) => event.id));\n for (const values of this.acknowledgements.values()) for (const id of values.keys()) if (!ids.has(id)) values.delete(id);\n }\n}\n","import { mkdir, open, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { MemoryHumanPlusEventStore, type HumanPlusDisposition, type HumanPlusEvent, type NewHumanPlusEvent } from \"./events\";\n\ntype JournalRecord = { kind: \"event\"; event: HumanPlusEvent } | { kind: \"ack\"; consumerId: string; eventIds: string[]; disposition: HumanPlusDisposition };\n\n/** Single-process append-only JSONL store for local terminal applications. */\nexport class FileHumanPlusEventStore extends MemoryHumanPlusEventStore {\n private ready: Promise<void>;\n private writes = Promise.resolve();\n constructor(private readonly path: string) { super(); this.ready = this.load(); }\n private async load() {\n let source = \"\"; try { source = await readFile(this.path, \"utf8\"); } catch (error: any) { if (error?.code !== \"ENOENT\") throw error; }\n for (const line of source.split(\"\\n\")) {\n if (!line.trim()) continue;\n try { const record = JSON.parse(line) as JournalRecord; if (record.kind === \"event\") { this.events.push(record.event); this.nextSequence = Math.max(this.nextSequence, record.event.sequence + 1); } else await super.acknowledge(record.consumerId, record.eventIds, record.disposition); } catch { /* isolate truncated/corrupt records */ }\n }\n }\n private enqueue(record: JournalRecord) {\n this.writes = this.writes.then(async () => { await mkdir(dirname(this.path), { recursive: true }); const handle = await open(this.path, \"a\"); try { await handle.appendFile(`${JSON.stringify(record)}\\n`, \"utf8\"); await handle.sync(); } finally { await handle.close(); } });\n return this.writes;\n }\n override async append(input: NewHumanPlusEvent) { await this.ready; const event = await super.append(input); await this.enqueue({ kind: \"event\", event }); return event; }\n override async list(query: Parameters<MemoryHumanPlusEventStore[\"list\"]>[0]) { await this.ready; await this.writes; return super.list(query); }\n override async acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition) { await this.ready; await super.acknowledge(consumerId, eventIds, disposition); await this.enqueue({ kind: \"ack\", consumerId, eventIds, disposition }); }\n override async compact(options: Parameters<MemoryHumanPlusEventStore[\"compact\"]>[0] = {}) {\n await this.ready; await this.writes; await super.compact(options);\n const records: JournalRecord[] = this.events.map((event) => ({ kind: \"event\", event }));\n for (const [consumerId, values] of this.acknowledgements) for (const [id, disposition] of values) records.push({ kind: \"ack\", consumerId, eventIds: [id], disposition });\n const temporary = `${this.path}.${process.pid}.tmp`; await mkdir(dirname(this.path), { recursive: true }); await writeFile(temporary, records.map((x) => JSON.stringify(x)).join(\"\\n\") + \"\\n\", \"utf8\"); await rename(temporary, this.path);\n }\n}\n"]}
@@ -0,0 +1,76 @@
1
+ import { MemoryHumanPlusEventStore } from './chunk-PMI4C5S4.js';
2
+ import { readFile, mkdir, open, writeFile, rename } from 'fs/promises';
3
+ import { dirname } from 'path';
4
+
5
+ var FileHumanPlusEventStore = class extends MemoryHumanPlusEventStore {
6
+ constructor(path) {
7
+ super();
8
+ this.path = path;
9
+ this.writes = Promise.resolve();
10
+ this.ready = this.load();
11
+ }
12
+ async load() {
13
+ let source = "";
14
+ try {
15
+ source = await readFile(this.path, "utf8");
16
+ } catch (error) {
17
+ if (error?.code !== "ENOENT") throw error;
18
+ }
19
+ for (const line of source.split("\n")) {
20
+ if (!line.trim()) continue;
21
+ try {
22
+ const record = JSON.parse(line);
23
+ if (record.kind === "event") {
24
+ this.events.push(record.event);
25
+ this.nextSequence = Math.max(this.nextSequence, record.event.sequence + 1);
26
+ } else await super.acknowledge(record.consumerId, record.eventIds, record.disposition);
27
+ } catch {
28
+ }
29
+ }
30
+ }
31
+ enqueue(record) {
32
+ this.writes = this.writes.then(async () => {
33
+ await mkdir(dirname(this.path), { recursive: true });
34
+ const handle = await open(this.path, "a");
35
+ try {
36
+ await handle.appendFile(`${JSON.stringify(record)}
37
+ `, "utf8");
38
+ await handle.sync();
39
+ } finally {
40
+ await handle.close();
41
+ }
42
+ });
43
+ return this.writes;
44
+ }
45
+ async append(input) {
46
+ await this.ready;
47
+ const event = await super.append(input);
48
+ await this.enqueue({ kind: "event", event });
49
+ return event;
50
+ }
51
+ async list(query) {
52
+ await this.ready;
53
+ await this.writes;
54
+ return super.list(query);
55
+ }
56
+ async acknowledge(consumerId, eventIds, disposition) {
57
+ await this.ready;
58
+ await super.acknowledge(consumerId, eventIds, disposition);
59
+ await this.enqueue({ kind: "ack", consumerId, eventIds, disposition });
60
+ }
61
+ async compact(options = {}) {
62
+ await this.ready;
63
+ await this.writes;
64
+ await super.compact(options);
65
+ const records = this.events.map((event) => ({ kind: "event", event }));
66
+ for (const [consumerId, values] of this.acknowledgements) for (const [id, disposition] of values) records.push({ kind: "ack", consumerId, eventIds: [id], disposition });
67
+ const temporary = `${this.path}.${process.pid}.tmp`;
68
+ await mkdir(dirname(this.path), { recursive: true });
69
+ await writeFile(temporary, records.map((x) => JSON.stringify(x)).join("\n") + "\n", "utf8");
70
+ await rename(temporary, this.path);
71
+ }
72
+ };
73
+
74
+ export { FileHumanPlusEventStore };
75
+ //# sourceMappingURL=human-plus-node.js.map
76
+ //# sourceMappingURL=human-plus-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/human-plus/file-store.ts"],"names":[],"mappings":"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","file":"human-plus-node.js","sourcesContent":["import { mkdir, open, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { MemoryHumanPlusEventStore, type HumanPlusDisposition, type HumanPlusEvent, type NewHumanPlusEvent } from \"./events\";\n\ntype JournalRecord = { kind: \"event\"; event: HumanPlusEvent } | { kind: \"ack\"; consumerId: string; eventIds: string[]; disposition: HumanPlusDisposition };\n\n/** Single-process append-only JSONL store for local terminal applications. */\nexport class FileHumanPlusEventStore extends MemoryHumanPlusEventStore {\n private ready: Promise<void>;\n private writes = Promise.resolve();\n constructor(private readonly path: string) { super(); this.ready = this.load(); }\n private async load() {\n let source = \"\"; try { source = await readFile(this.path, \"utf8\"); } catch (error: any) { if (error?.code !== \"ENOENT\") throw error; }\n for (const line of source.split(\"\\n\")) {\n if (!line.trim()) continue;\n try { const record = JSON.parse(line) as JournalRecord; if (record.kind === \"event\") { this.events.push(record.event); this.nextSequence = Math.max(this.nextSequence, record.event.sequence + 1); } else await super.acknowledge(record.consumerId, record.eventIds, record.disposition); } catch { /* isolate truncated/corrupt records */ }\n }\n }\n private enqueue(record: JournalRecord) {\n this.writes = this.writes.then(async () => { await mkdir(dirname(this.path), { recursive: true }); const handle = await open(this.path, \"a\"); try { await handle.appendFile(`${JSON.stringify(record)}\\n`, \"utf8\"); await handle.sync(); } finally { await handle.close(); } });\n return this.writes;\n }\n override async append(input: NewHumanPlusEvent) { await this.ready; const event = await super.append(input); await this.enqueue({ kind: \"event\", event }); return event; }\n override async list(query: Parameters<MemoryHumanPlusEventStore[\"list\"]>[0]) { await this.ready; await this.writes; return super.list(query); }\n override async acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition) { await this.ready; await super.acknowledge(consumerId, eventIds, disposition); await this.enqueue({ kind: \"ack\", consumerId, eventIds, disposition }); }\n override async compact(options: Parameters<MemoryHumanPlusEventStore[\"compact\"]>[0] = {}) {\n await this.ready; await this.writes; await super.compact(options);\n const records: JournalRecord[] = this.events.map((event) => ({ kind: \"event\", event }));\n for (const [consumerId, values] of this.acknowledgements) for (const [id, disposition] of values) records.push({ kind: \"ack\", consumerId, eventIds: [id], disposition });\n const temporary = `${this.path}.${process.pid}.tmp`; await mkdir(dirname(this.path), { recursive: true }); await writeFile(temporary, records.map((x) => JSON.stringify(x)).join(\"\\n\") + \"\\n\", \"utf8\"); await rename(temporary, this.path);\n }\n}\n"]}
@@ -0,0 +1,46 @@
1
+ 'use strict';
2
+
3
+ // src/human-plus/events.ts
4
+ var MemoryHumanPlusEventStore = class {
5
+ constructor() {
6
+ this.events = [];
7
+ this.acknowledgements = /* @__PURE__ */ new Map();
8
+ this.listeners = /* @__PURE__ */ new Set();
9
+ this.nextSequence = 1;
10
+ }
11
+ async append(input) {
12
+ const event = { ...input, id: input.id ?? globalThis.crypto.randomUUID(), timestamp: input.timestamp ?? Date.now(), sequence: this.nextSequence++ };
13
+ this.events.push(event);
14
+ this.listeners.forEach((listener) => listener(event));
15
+ return event;
16
+ }
17
+ async list(query) {
18
+ const acknowledged = this.acknowledgements.get(query.consumerId);
19
+ const events = this.events.filter((event) => event.sequence > (query.after ?? 0) && (!query.unacknowledgedOnly || !acknowledged?.has(event.id)) && (!query.types?.length || query.types.includes(event.type)) && (!query.surfaces?.length || query.surfaces.includes(event.surfaceId))).slice(0, Math.max(1, Math.min(500, query.limit ?? 50)));
20
+ return { events, nextCursor: events.at(-1)?.sequence ?? query.after ?? 0 };
21
+ }
22
+ async acknowledge(consumerId, eventIds, disposition) {
23
+ let values = this.acknowledgements.get(consumerId);
24
+ if (!values) {
25
+ values = /* @__PURE__ */ new Map();
26
+ this.acknowledgements.set(consumerId, values);
27
+ }
28
+ eventIds.forEach((id) => values.set(id, disposition));
29
+ }
30
+ subscribe(listener) {
31
+ this.listeners.add(listener);
32
+ return () => this.listeners.delete(listener);
33
+ }
34
+ async compact(options = {}) {
35
+ const cutoff = options.before ?? Number.POSITIVE_INFINITY;
36
+ const keep = options.keepLast ?? 1e3;
37
+ const removable = Math.max(0, this.events.length - keep);
38
+ this.events = this.events.filter((event, index) => index >= removable || event.timestamp >= cutoff);
39
+ const ids = new Set(this.events.map((event) => event.id));
40
+ for (const values of this.acknowledgements.values()) for (const id of values.keys()) if (!ids.has(id)) values.delete(id);
41
+ }
42
+ };
43
+
44
+ exports.MemoryHumanPlusEventStore = MemoryHumanPlusEventStore;
45
+ //# sourceMappingURL=human-plus.cjs.map
46
+ //# sourceMappingURL=human-plus.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/human-plus/events.ts"],"names":[],"mappings":";;;AA+BO,IAAM,4BAAN,MAA+D;AAAA,EAA/D,WAAA,GAAA;AACL,IAAA,IAAA,CAAU,SAA2B,EAAC;AACtC,IAAA,IAAA,CAAU,gBAAA,uBAAuB,GAAA,EAA+C;AAChF,IAAA,IAAA,CAAU,SAAA,uBAAgB,GAAA,EAA4B;AACtD,IAAA,IAAA,CAAU,YAAA,GAAe,CAAA;AAAA,EAAA;AAAA,EAEzB,MAAM,OAAO,KAAA,EAAmD;AAC9D,IAAA,MAAM,QAAwB,EAAE,GAAG,OAAO,EAAA,EAAI,KAAA,CAAM,MAAM,UAAA,CAAW,MAAA,CAAO,YAAW,EAAG,SAAA,EAAW,MAAM,SAAA,IAAa,IAAA,CAAK,KAAI,EAAG,QAAA,EAAU,KAAK,YAAA,EAAA,EAAe;AAClK,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAAG,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,QAAA,KAAa,QAAA,CAAS,KAAK,CAAC,CAAA;AAAG,IAAA,OAAO,KAAA;AAAA,EACzF;AAAA,EACA,MAAM,KAAK,KAAA,EAAyD;AAClE,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,MAAM,UAAU,CAAA;AAC/D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,UAAU,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,KAAA,IAAS,CAAA,CAAA,KACxE,CAAC,MAAM,kBAAA,IAAsB,CAAC,YAAA,EAAc,GAAA,CAAI,KAAA,CAAM,EAAE,OACxD,CAAC,KAAA,CAAM,KAAA,EAAO,MAAA,IAAU,KAAA,CAAM,KAAA,CAAM,SAAS,KAAA,CAAM,IAAI,CAAA,CAAA,KACvD,CAAC,KAAA,CAAM,QAAA,EAAU,UAAU,KAAA,CAAM,QAAA,CAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,CAAE,EACvE,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAA,CAAM,KAAA,IAAS,EAAE,CAAC,CAAC,CAAA;AACzD,IAAA,OAAO,EAAE,MAAA,EAAQ,UAAA,EAAY,MAAA,CAAO,EAAA,CAAG,EAAE,CAAA,EAAG,QAAA,IAAY,KAAA,CAAM,KAAA,IAAS,CAAA,EAAE;AAAA,EAC3E;AAAA,EACA,MAAM,WAAA,CAAY,UAAA,EAAoB,QAAA,EAAoB,WAAA,EAAkD;AAC1G,IAAA,IAAI,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,UAAU,CAAA;AAAG,IAAA,IAAI,CAAC,MAAA,EAAQ;AAAE,MAAA,MAAA,uBAAa,GAAA,EAAI;AAAG,MAAA,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,UAAA,EAAY,MAAM,CAAA;AAAA,IAAG;AACtI,IAAA,QAAA,CAAS,QAAQ,CAAC,EAAA,KAAO,OAAQ,GAAA,CAAI,EAAA,EAAI,WAAW,CAAC,CAAA;AAAA,EACvD;AAAA,EACA,UAAU,QAAA,EAA8C;AAAE,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAAG,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAAG;AAAA,EACtI,MAAM,OAAA,CAAQ,OAAA,GAAkD,EAAC,EAAkB;AACjF,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,MAAA,CAAO,iBAAA;AAAmB,IAAA,MAAM,IAAA,GAAO,QAAQ,QAAA,IAAY,GAAA;AAC5F,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,MAAA,CAAO,SAAS,IAAI,CAAA;AACvD,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,CAAC,KAAA,EAAO,KAAA,KAAU,KAAA,IAAS,SAAA,IAAa,KAAA,CAAM,SAAA,IAAa,MAAM,CAAA;AAClG,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,IAAI,CAAC,KAAA,KAAU,KAAA,CAAM,EAAE,CAAC,CAAA;AACxD,IAAA,KAAA,MAAW,UAAU,IAAA,CAAK,gBAAA,CAAiB,QAAO,EAAG,KAAA,MAAW,MAAM,MAAA,CAAO,IAAA,EAAK,EAAG,IAAI,CAAC,GAAA,CAAI,GAAA,CAAI,EAAE,CAAA,EAAG,MAAA,CAAO,OAAO,EAAE,CAAA;AAAA,EACzH;AACF","file":"human-plus.cjs","sourcesContent":["export type HumanPlusActor = { kind: \"human\" | \"agent\" | \"system\"; id: string; name?: string };\nexport type HumanPlusPriority = \"background\" | \"normal\" | \"attention\" | \"blocking\";\nexport type HumanPlusDisposition = \"seen\" | \"handled\" | \"rejected\" | \"ignored\";\n\nexport interface HumanPlusEvent<T = unknown> {\n id: string;\n sequence: number;\n timestamp: number;\n appId: string;\n surfaceId: string;\n sessionId?: string;\n type: string;\n payload: T;\n actor: HumanPlusActor;\n priority: HumanPlusPriority;\n correlationId?: string;\n causationId?: string;\n}\nexport type NewHumanPlusEvent<T = unknown> = Omit<HumanPlusEvent<T>, \"id\" | \"sequence\" | \"timestamp\"> & Partial<Pick<HumanPlusEvent<T>, \"id\" | \"timestamp\">>;\nexport interface HumanPlusEventQuery { consumerId: string; after?: number; limit?: number; unacknowledgedOnly?: boolean; types?: string[]; surfaces?: string[]; }\nexport interface HumanPlusEventPage { events: HumanPlusEvent[]; nextCursor: number; }\nexport type HumanPlusEventListener = (event: HumanPlusEvent) => void;\n\nexport interface HumanPlusEventStore {\n append(event: NewHumanPlusEvent): Promise<HumanPlusEvent>;\n list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage>;\n acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void>;\n subscribe(listener: HumanPlusEventListener): () => void;\n compact?(options?: { before?: number; keepLast?: number }): Promise<void>;\n}\n\nexport class MemoryHumanPlusEventStore implements HumanPlusEventStore {\n protected events: HumanPlusEvent[] = [];\n protected acknowledgements = new Map<string, Map<string, HumanPlusDisposition>>();\n protected listeners = new Set<HumanPlusEventListener>();\n protected nextSequence = 1;\n\n async append(input: NewHumanPlusEvent): Promise<HumanPlusEvent> {\n const event: HumanPlusEvent = { ...input, id: input.id ?? globalThis.crypto.randomUUID(), timestamp: input.timestamp ?? Date.now(), sequence: this.nextSequence++ };\n this.events.push(event); this.listeners.forEach((listener) => listener(event)); return event;\n }\n async list(query: HumanPlusEventQuery): Promise<HumanPlusEventPage> {\n const acknowledged = this.acknowledgements.get(query.consumerId);\n const events = this.events.filter((event) => event.sequence > (query.after ?? 0)\n && (!query.unacknowledgedOnly || !acknowledged?.has(event.id))\n && (!query.types?.length || query.types.includes(event.type))\n && (!query.surfaces?.length || query.surfaces.includes(event.surfaceId)))\n .slice(0, Math.max(1, Math.min(500, query.limit ?? 50)));\n return { events, nextCursor: events.at(-1)?.sequence ?? query.after ?? 0 };\n }\n async acknowledge(consumerId: string, eventIds: string[], disposition: HumanPlusDisposition): Promise<void> {\n let values = this.acknowledgements.get(consumerId); if (!values) { values = new Map(); this.acknowledgements.set(consumerId, values); }\n eventIds.forEach((id) => values!.set(id, disposition));\n }\n subscribe(listener: HumanPlusEventListener): () => void { this.listeners.add(listener); return () => this.listeners.delete(listener); }\n async compact(options: { before?: number; keepLast?: number } = {}): Promise<void> {\n const cutoff = options.before ?? Number.POSITIVE_INFINITY; const keep = options.keepLast ?? 1000;\n const removable = Math.max(0, this.events.length - keep);\n this.events = this.events.filter((event, index) => index >= removable || event.timestamp >= cutoff);\n const ids = new Set(this.events.map((event) => event.id));\n for (const values of this.acknowledgements.values()) for (const id of values.keys()) if (!ids.has(id)) values.delete(id);\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { MemoryHumanPlusEventStore } from './chunk-PMI4C5S4.js';
2
+ //# sourceMappingURL=human-plus.js.map
3
+ //# sourceMappingURL=human-plus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"human-plus.js"}