opencode-graphiti 0.1.9 → 0.1.10

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 (88) hide show
  1. package/README.md +7 -1
  2. package/esm/_dnt.polyfills.d.ts +50 -0
  3. package/esm/_dnt.polyfills.d.ts.map +1 -0
  4. package/esm/_dnt.polyfills.js +37 -0
  5. package/esm/mod.d.ts +1 -0
  6. package/esm/mod.d.ts.map +1 -1
  7. package/esm/mod.js +1 -0
  8. package/esm/src/config.d.ts +7 -1
  9. package/esm/src/config.d.ts.map +1 -1
  10. package/esm/src/config.js +17 -5
  11. package/esm/src/handlers/chat.d.ts.map +1 -1
  12. package/esm/src/handlers/chat.js +51 -42
  13. package/esm/src/handlers/event.d.ts +1 -1
  14. package/esm/src/handlers/event.d.ts.map +1 -1
  15. package/esm/src/handlers/event.js +42 -46
  16. package/esm/src/handlers/messages.d.ts.map +1 -1
  17. package/esm/src/handlers/messages.js +2 -3
  18. package/esm/src/index.js +2 -2
  19. package/esm/src/services/client.d.ts +7 -0
  20. package/esm/src/services/client.d.ts.map +1 -1
  21. package/esm/src/services/client.js +22 -24
  22. package/esm/src/services/compaction.d.ts.map +1 -1
  23. package/esm/src/services/compaction.js +24 -33
  24. package/esm/src/services/constants.d.ts +7 -0
  25. package/esm/src/services/constants.d.ts.map +1 -0
  26. package/esm/src/services/constants.js +6 -0
  27. package/esm/src/services/context-limit.d.ts +1 -1
  28. package/esm/src/services/context-limit.d.ts.map +1 -1
  29. package/esm/src/services/context-limit.js +12 -14
  30. package/esm/src/services/context.d.ts +27 -7
  31. package/esm/src/services/context.d.ts.map +1 -1
  32. package/esm/src/services/context.js +34 -2
  33. package/esm/src/services/logger.js +2 -4
  34. package/esm/src/services/sdk-normalize.d.ts +55 -0
  35. package/esm/src/services/sdk-normalize.d.ts.map +1 -0
  36. package/esm/src/services/sdk-normalize.js +61 -0
  37. package/esm/src/session.d.ts +4 -2
  38. package/esm/src/session.d.ts.map +1 -1
  39. package/esm/src/session.js +38 -34
  40. package/esm/src/types/index.d.ts +13 -14
  41. package/esm/src/types/index.d.ts.map +1 -1
  42. package/esm/src/utils.d.ts +6 -0
  43. package/esm/src/utils.d.ts.map +1 -1
  44. package/esm/src/utils.js +16 -2
  45. package/package.json +1 -1
  46. package/script/_dnt.polyfills.d.ts +50 -0
  47. package/script/_dnt.polyfills.d.ts.map +1 -0
  48. package/script/_dnt.polyfills.js +38 -0
  49. package/script/mod.d.ts +1 -0
  50. package/script/mod.d.ts.map +1 -1
  51. package/script/mod.js +1 -0
  52. package/script/src/config.d.ts +7 -1
  53. package/script/src/config.d.ts.map +1 -1
  54. package/script/src/config.js +20 -5
  55. package/script/src/handlers/chat.d.ts.map +1 -1
  56. package/script/src/handlers/chat.js +49 -40
  57. package/script/src/handlers/event.d.ts +1 -1
  58. package/script/src/handlers/event.d.ts.map +1 -1
  59. package/script/src/handlers/event.js +41 -45
  60. package/script/src/handlers/messages.d.ts.map +1 -1
  61. package/script/src/handlers/messages.js +2 -3
  62. package/script/src/index.js +2 -2
  63. package/script/src/services/client.d.ts +7 -0
  64. package/script/src/services/client.d.ts.map +1 -1
  65. package/script/src/services/client.js +22 -24
  66. package/script/src/services/compaction.d.ts.map +1 -1
  67. package/script/src/services/compaction.js +24 -33
  68. package/script/src/services/constants.d.ts +7 -0
  69. package/script/src/services/constants.d.ts.map +1 -0
  70. package/script/src/services/constants.js +9 -0
  71. package/script/src/services/context-limit.d.ts +1 -1
  72. package/script/src/services/context-limit.d.ts.map +1 -1
  73. package/script/src/services/context-limit.js +13 -15
  74. package/script/src/services/context.d.ts +27 -7
  75. package/script/src/services/context.d.ts.map +1 -1
  76. package/script/src/services/context.js +36 -4
  77. package/script/src/services/logger.js +2 -4
  78. package/script/src/services/sdk-normalize.d.ts +55 -0
  79. package/script/src/services/sdk-normalize.d.ts.map +1 -0
  80. package/script/src/services/sdk-normalize.js +67 -0
  81. package/script/src/session.d.ts +4 -2
  82. package/script/src/session.d.ts.map +1 -1
  83. package/script/src/session.js +38 -34
  84. package/script/src/types/index.d.ts +13 -14
  85. package/script/src/types/index.d.ts.map +1 -1
  86. package/script/src/utils.d.ts +6 -0
  87. package/script/src/utils.d.ts.map +1 -1
  88. package/script/src/utils.js +18 -3
@@ -1,3 +1,5 @@
1
+ import { extractSdkMessages } from "./services/sdk-normalize.js";
2
+ import { DEFAULT_CONTEXT_LIMIT } from "./services/constants.js";
1
3
  import { logger } from "./services/logger.js";
2
4
  import { extractTextFromParts } from "./utils.js";
3
5
  /**
@@ -55,6 +57,23 @@ export class SessionManager {
55
57
  value: new Set()
56
58
  });
57
59
  }
60
+ /** Create a default main-session state for the given group IDs. */
61
+ createDefaultState(groupId, userGroupId) {
62
+ return {
63
+ groupId,
64
+ userGroupId,
65
+ injectedMemories: false,
66
+ lastInjectionFactUuids: [],
67
+ cachedMemoryContext: undefined,
68
+ cachedFactUuids: undefined,
69
+ visibleFactUuids: [],
70
+ messageCount: 0,
71
+ pendingMessages: [],
72
+ lastSnapshotBody: undefined,
73
+ contextLimit: DEFAULT_CONTEXT_LIMIT,
74
+ isMain: true,
75
+ };
76
+ }
58
77
  /** Get the current session state, if present. */
59
78
  getState(sessionId) {
60
79
  return this.sessions.get(sessionId);
@@ -102,28 +121,11 @@ export class SessionManager {
102
121
  }
103
122
  let state = this.sessions.get(sessionId);
104
123
  if (!state) {
105
- state = {
106
- groupId: this.defaultGroupId,
107
- userGroupId: this.defaultUserGroupId,
108
- injectedMemories: false,
109
- lastInjectionFactUuids: [],
110
- cachedMemoryContext: undefined,
111
- cachedFactUuids: undefined,
112
- visibleFactUuids: [],
113
- messageCount: 0,
114
- pendingMessages: [],
115
- contextLimit: 200_000,
116
- isMain: true,
117
- };
124
+ state = this.createDefaultState(this.defaultGroupId, this.defaultUserGroupId);
118
125
  this.sessions.set(sessionId, state);
119
126
  }
120
127
  return { state, resolved: true };
121
128
  }
122
- /** Determine whether a session is a subagent session. */
123
- async isSubagentSession(sessionId) {
124
- const parentId = await this.resolveParentId(sessionId);
125
- return !!parentId;
126
- }
127
129
  /** Buffer partial assistant text for a streaming message. */
128
130
  bufferAssistantPart(sessionId, messageId, text) {
129
131
  const key = `${sessionId}:${messageId}`;
@@ -256,15 +258,24 @@ export class SessionManager {
256
258
  deleteSession(sessionId) {
257
259
  this.sessions.delete(sessionId);
258
260
  this.parentIdCache.delete(sessionId);
261
+ // Collect matching keys first, then delete in a second pass to avoid
262
+ // mutating a Map/Set while iterating over its live iterator.
263
+ const prefix = `${sessionId}:`;
264
+ const pendingToDelete = [];
259
265
  for (const key of this.pendingAssistantMessages.keys()) {
260
- if (key.startsWith(`${sessionId}:`)) {
261
- this.pendingAssistantMessages.delete(key);
262
- }
266
+ if (key.startsWith(prefix))
267
+ pendingToDelete.push(key);
268
+ }
269
+ for (const key of pendingToDelete) {
270
+ this.pendingAssistantMessages.delete(key);
263
271
  }
272
+ const bufferedToDelete = [];
264
273
  for (const key of this.bufferedAssistantMessageIds) {
265
- if (key.startsWith(`${sessionId}:`)) {
266
- this.bufferedAssistantMessageIds.delete(key);
267
- }
274
+ if (key.startsWith(prefix))
275
+ bufferedToDelete.push(key);
276
+ }
277
+ for (const key of bufferedToDelete) {
278
+ this.bufferedAssistantMessageIds.delete(key);
268
279
  }
269
280
  }
270
281
  async fetchLatestAssistantMessage(sessionId) {
@@ -273,18 +284,11 @@ export class SessionManager {
273
284
  path: { id: sessionId },
274
285
  query: { limit: 20 },
275
286
  });
276
- const payload = response && typeof response === "object" &&
277
- "data" in response
278
- ? response.data
279
- : response;
280
- const messages = Array.isArray(payload)
281
- ? payload
282
- : [];
287
+ const messages = extractSdkMessages(response);
283
288
  if (messages.length === 0)
284
289
  return null;
285
- const lastAssistant = [...messages]
286
- .reverse()
287
- .find((message) => message.info?.role === "assistant");
290
+ const lastAssistant = messages
291
+ .findLast((message) => message.info?.role === "assistant");
288
292
  if (!lastAssistant)
289
293
  return null;
290
294
  const text = extractTextFromParts(lastAssistant.parts);
@@ -30,11 +30,6 @@ export interface GraphitiFact {
30
30
  uuid: string;
31
31
  };
32
32
  }
33
- /** Response payload containing Graphiti facts. */
34
- export interface GraphitiFactsResponse {
35
- /** List of facts from Graphiti. */
36
- facts: GraphitiFact[];
37
- }
38
33
  /** A node retrieved from the Graphiti knowledge graph. */
39
34
  export interface GraphitiNode {
40
35
  /** Unique identifier for the node. */
@@ -46,12 +41,15 @@ export interface GraphitiNode {
46
41
  /** Optional labels associated with the node. */
47
42
  labels?: string[];
48
43
  }
49
- /** Response payload containing Graphiti nodes. */
50
- export interface GraphitiNodesResponse {
51
- /** List of nodes from Graphiti. */
52
- nodes: GraphitiNode[];
53
- }
54
- /** An episode retrieved from Graphiti memory. */
44
+ /**
45
+ * An episode retrieved from Graphiti memory.
46
+ *
47
+ * `sourceDescription` is the canonical field. Raw payloads may carry either
48
+ * `sourceDescription` (camelCase) or `source_description` (snake_case); the
49
+ * boundary helper `normalizeEpisode()` in `src/services/sdk-normalize.ts`
50
+ * collapses both into `sourceDescription` so downstream consumers only need to
51
+ * check one field.
52
+ */
55
53
  export interface GraphitiEpisode {
56
54
  /** Unique identifier for the episode. */
57
55
  uuid: string;
@@ -61,10 +59,11 @@ export interface GraphitiEpisode {
61
59
  content: string;
62
60
  /** Optional episode source type. */
63
61
  source?: string;
64
- /** Optional source description for the episode. */
62
+ /**
63
+ * Canonical source description (normalized from either camelCase or
64
+ * snake_case payload). Always populated by `normalizeEpisode()`.
65
+ */
65
66
  sourceDescription?: string;
66
- /** Optional source description (snake_case payload). */
67
- source_description?: string;
68
67
  /** Optional episode creation timestamp. */
69
68
  created_at?: string;
70
69
  /** Optional labels associated with the episode. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/types/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/types/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB"}
@@ -18,4 +18,10 @@ export declare const isTextPart: (value: unknown) => value is Part & {
18
18
  * Extract and join text from OpenCode message parts.
19
19
  */
20
20
  export declare const extractTextFromParts: (parts: Part[]) => string;
21
+ /**
22
+ * Truncate `text` to at most `budget` characters without cutting mid-line.
23
+ * Prefers to break at the last newline within the budget window; falls back
24
+ * to a raw slice only when the candidate contains no newline.
25
+ */
26
+ export declare const truncateAtLineBoundary: (text: string, budget: number) => string;
21
27
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAMF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,MAKF,CAAC"}
package/esm/src/utils.js CHANGED
@@ -7,7 +7,8 @@ const getUserName = (home = os.homedir().split("/").filter(Boolean).at(-1)) => h
7
7
  */
8
8
  export const makeGroupId = (prefix, directory = process.cwd()) => {
9
9
  const projectName = getProjectName(directory);
10
- const rawGroupId = `${prefix?.concat("-")}${projectName}__main`;
10
+ const prefixPart = prefix ? `${prefix}-` : "";
11
+ const rawGroupId = `${prefixPart}${projectName}__main`;
11
12
  return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
12
13
  };
13
14
  /**
@@ -16,7 +17,8 @@ export const makeGroupId = (prefix, directory = process.cwd()) => {
16
17
  export const makeUserGroupId = (prefix, directory = process.cwd()) => {
17
18
  const projectName = getProjectName(directory);
18
19
  const userName = getUserName();
19
- const rawGroupId = `${prefix?.concat("-")}${projectName}__user-${userName}`;
20
+ const prefixPart = prefix ? `${prefix}-` : "";
21
+ const rawGroupId = `${prefixPart}${projectName}__user-${userName}`;
20
22
  return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
21
23
  };
22
24
  /**
@@ -33,3 +35,15 @@ export const isTextPart = (value) => {
33
35
  * Extract and join text from OpenCode message parts.
34
36
  */
35
37
  export const extractTextFromParts = (parts) => parts.filter(isTextPart).map((part) => part.text).join(" ").trim();
38
+ /**
39
+ * Truncate `text` to at most `budget` characters without cutting mid-line.
40
+ * Prefers to break at the last newline within the budget window; falls back
41
+ * to a raw slice only when the candidate contains no newline.
42
+ */
43
+ export const truncateAtLineBoundary = (text, budget) => {
44
+ if (text.length <= budget)
45
+ return text;
46
+ const candidate = text.slice(0, budget);
47
+ const lastNl = candidate.lastIndexOf("\n");
48
+ return lastNl > 0 ? candidate.slice(0, lastNl) : candidate;
49
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-graphiti",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "OpenCode plugin for persistent memory via Graphiti knowledge graph",
5
5
  "keywords": [
6
6
  "opencode",
@@ -0,0 +1,50 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * Returns the value of the last element in the array where predicate is true, and undefined
5
+ * otherwise.
6
+ * @param predicate find calls predicate once for each element of the array, in ascending
7
+ * order, until it finds one where predicate returns true. If such an element is found, find
8
+ * immediately returns that element value. Otherwise, find returns undefined.
9
+ * @param thisArg If provided, it will be used as the this value for each invocation of
10
+ * predicate. If it is not provided, undefined is used instead.
11
+ */
12
+ findLast<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
13
+ findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
14
+ /**
15
+ * Returns the index of the last element in the array where predicate is true, and -1
16
+ * otherwise.
17
+ * @param predicate find calls predicate once for each element of the array, in ascending
18
+ * order, until it finds one where predicate returns true. If such an element is found,
19
+ * findIndex immediately returns that element index. Otherwise, findIndex returns -1.
20
+ * @param thisArg If provided, it will be used as the this value for each invocation of
21
+ * predicate. If it is not provided, undefined is used instead.
22
+ */
23
+ findLastIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
24
+ }
25
+ interface Uint8Array {
26
+ /**
27
+ * Returns the value of the last element in the array where predicate is true, and undefined
28
+ * otherwise.
29
+ * @param predicate findLast calls predicate once for each element of the array, in descending
30
+ * order, until it finds one where predicate returns true. If such an element is found, findLast
31
+ * immediately returns that element value. Otherwise, findLast returns undefined.
32
+ * @param thisArg If provided, it will be used as the this value for each invocation of
33
+ * predicate. If it is not provided, undefined is used instead.
34
+ */
35
+ findLast<S extends number>(predicate: (value: number, index: number, array: Uint8Array) => value is S, thisArg?: any): S | undefined;
36
+ findLast(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number | undefined;
37
+ /**
38
+ * Returns the index of the last element in the array where predicate is true, and -1
39
+ * otherwise.
40
+ * @param predicate findLastIndex calls predicate once for each element of the array, in descending
41
+ * order, until it finds one where predicate returns true. If such an element is found,
42
+ * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
43
+ * @param thisArg If provided, it will be used as the this value for each invocation of
44
+ * predicate. If it is not provided, undefined is used instead.
45
+ */
46
+ findLastIndex(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number;
47
+ }
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=_dnt.polyfills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK,CAAC,CAAC;QACf;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,CAAC,EAClB,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,EACxE,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACN,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QAEjB;;;;;;;;WAQG;QACH,aAAa,CACX,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,MAAM,CAAC;KACX;IACD,UAAU,UAAU;QAClB;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvB,SAAS,EAAE,CACP,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,KAChB,KAAK,IAAI,CAAC,EACf,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACJ,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,GAAG,SAAS,CAAC;QAEtB;;;;;;;;WAQG;QACH,aAAa,CACT,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,CAAC;KACX;CACF;AA4CD,OAAO,EAAE,CAAC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function findLastIndex(self, callbackfn, that) {
4
+ const boundFunc = that === undefined ? callbackfn : callbackfn.bind(that);
5
+ let index = self.length - 1;
6
+ while (index >= 0) {
7
+ const result = boundFunc(self[index], index, self);
8
+ if (result) {
9
+ return index;
10
+ }
11
+ index--;
12
+ }
13
+ return -1;
14
+ }
15
+ function findLast(self, callbackfn, that) {
16
+ const index = self.findLastIndex(callbackfn, that);
17
+ return index === -1 ? undefined : self[index];
18
+ }
19
+ if (!Array.prototype.findLastIndex) {
20
+ Array.prototype.findLastIndex = function (callbackfn, that) {
21
+ return findLastIndex(this, callbackfn, that);
22
+ };
23
+ }
24
+ if (!Array.prototype.findLast) {
25
+ Array.prototype.findLast = function (callbackfn, that) {
26
+ return findLast(this, callbackfn, that);
27
+ };
28
+ }
29
+ if (!Uint8Array.prototype.findLastIndex) {
30
+ Uint8Array.prototype.findLastIndex = function (callbackfn, that) {
31
+ return findLastIndex(this, callbackfn, that);
32
+ };
33
+ }
34
+ if (!Uint8Array.prototype.findLast) {
35
+ Uint8Array.prototype.findLast = function (callbackfn, that) {
36
+ return findLast(this, callbackfn, that);
37
+ };
38
+ }
package/script/mod.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ import "./_dnt.polyfills.js";
1
2
  export * from "./src/index.js";
2
3
  //# sourceMappingURL=mod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
package/script/mod.js CHANGED
@@ -14,4 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ require("./_dnt.polyfills.js");
17
18
  __exportStar(require("./src/index.js"), exports);
@@ -1,6 +1,12 @@
1
1
  import type { GraphitiConfig } from "./types/index.js";
2
2
  /**
3
3
  * Load Graphiti configuration from JSONC files with defaults applied.
4
+ *
5
+ * When `directory` is provided, the search starts from that directory (no
6
+ * upward traversal past it) so that a project-local `.graphitirc` or
7
+ * `package.json#graphiti` key takes precedence over any global/home config.
8
+ * If no config is found in the project directory the search falls back to a
9
+ * global search (home directory and OS-level config locations).
4
10
  */
5
- export declare function loadConfig(): GraphitiConfig;
11
+ export declare function loadConfig(directory?: string): GraphitiConfig;
6
12
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAgBvD;;GAEG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAc3C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAgBvD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAoB7D"}
@@ -32,9 +32,13 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.loadConfig = loadConfig;
37
40
  const cosmiconfig_1 = require("cosmiconfig");
41
+ const node_os_1 = __importDefault(require("node:os"));
38
42
  const z = __importStar(require("zod/mini"));
39
43
  const DEFAULT_CONFIG = {
40
44
  endpoint: "http://localhost:8000/mcp",
@@ -50,14 +54,25 @@ const GraphitiConfigSchema = z.object({
50
54
  });
51
55
  /**
52
56
  * Load Graphiti configuration from JSONC files with defaults applied.
57
+ *
58
+ * When `directory` is provided, the search starts from that directory (no
59
+ * upward traversal past it) so that a project-local `.graphitirc` or
60
+ * `package.json#graphiti` key takes precedence over any global/home config.
61
+ * If no config is found in the project directory the search falls back to a
62
+ * global search (home directory and OS-level config locations).
53
63
  */
54
- function loadConfig() {
55
- const explorer = (0, cosmiconfig_1.cosmiconfigSync)("graphiti", { searchStrategy: "global" });
56
- const result = explorer.search();
57
- const candidate = result?.config ?? {};
64
+ function loadConfig(directory) {
65
+ const result = (0, cosmiconfig_1.cosmiconfigSync)("graphiti", {
66
+ stopDir: node_os_1.default.homedir(),
67
+ mergeSearchPlaces: true,
68
+ cache: false,
69
+ }).search(directory) ??
70
+ (0, cosmiconfig_1.cosmiconfigSync)("graphiti", {
71
+ searchPlaces: [`${node_os_1.default.homedir()}/.graphitirc`],
72
+ }).search();
58
73
  const merged = {
59
74
  ...DEFAULT_CONFIG,
60
- ...candidate,
75
+ ...result?.config,
61
76
  };
62
77
  const parsed = GraphitiConfigSchema.safeParse(merged);
63
78
  if (parsed.success) {
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAkLvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBA6EzE"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,KAAK,gBAAgB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,KAAK,iBAAiB,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAGxD,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,IAwMvC,eAAe,gBAAgB,EAAE,QAAQ,iBAAiB,mBA+EzE"}
@@ -2,19 +2,32 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createChatHandler = createChatHandler;
4
4
  const context_limit_js_1 = require("../services/context-limit.js");
5
+ const constants_js_1 = require("../services/constants.js");
5
6
  const context_js_1 = require("../services/context.js");
6
7
  const logger_js_1 = require("../services/logger.js");
7
8
  const utils_js_1 = require("../utils.js");
8
9
  /** Creates the `chat.message` hook handler. */
9
10
  function createChatHandler(deps) {
10
11
  const { sessionManager, driftThreshold, factStaleDays, client } = deps;
11
- const searchAndCacheMemoryContext = async (state, messageText, useUserScope, characterBudget, seedFactUuids) => {
12
+ /**
13
+ * Fetch project facts (and optionally user facts/nodes) then build and cache
14
+ * the formatted memory context string.
15
+ *
16
+ * Task 8: When `seedProjectFacts` is supplied (from the drift check), those
17
+ * facts are used directly for the project scope so we avoid a redundant
18
+ * second searchFacts query.
19
+ */
20
+ const searchAndCacheMemoryContext = async (state, messageText, useUserScope, characterBudget, seedProjectFacts) => {
12
21
  const userGroupId = state.userGroupId;
13
- const projectFactsPromise = client.searchFacts({
14
- query: messageText,
15
- groupIds: [state.groupId],
16
- maxFacts: 50,
17
- });
22
+ // Task 8: reuse drift-check project facts when available; only issue a new
23
+ // project searchFacts call when we don't already have them.
24
+ const projectFactsPromise = seedProjectFacts != null
25
+ ? Promise.resolve(seedProjectFacts)
26
+ : client.searchFacts({
27
+ query: messageText,
28
+ groupIds: [state.groupId],
29
+ maxFacts: constants_js_1.PROJECT_MAX_FACTS,
30
+ });
18
31
  const projectNodesPromise = client.searchNodes({
19
32
  query: messageText,
20
33
  groupIds: [state.groupId],
@@ -34,20 +47,11 @@ function createChatHandler(deps) {
34
47
  maxNodes: 10,
35
48
  })
36
49
  : Promise.resolve([]);
37
- const [projectFacts, projectNodes, userFacts, userNodes] = await Promise
38
- .all([
39
- projectFactsPromise,
40
- projectNodesPromise,
41
- userFactsPromise,
42
- userNodesPromise,
43
- ]);
44
- const projectContext = (0, context_js_1.deduplicateContext)({
45
- facts: projectFacts,
46
- nodes: projectNodes,
47
- });
48
- const userContext = (0, context_js_1.deduplicateContext)({
49
- facts: userFacts,
50
- nodes: userNodes,
50
+ const { projectContext, userContext, projectFacts, projectNodes, userFacts, userNodes, } = await (0, context_js_1.resolveProjectUserContext)({
51
+ projectFacts: projectFactsPromise,
52
+ projectNodes: projectNodesPromise,
53
+ userFacts: userFactsPromise,
54
+ userNodes: userNodesPromise,
51
55
  });
52
56
  const visibleSet = new Set(state.visibleFactUuids ?? []);
53
57
  const beforeProjectFacts = projectContext.facts.length;
@@ -84,8 +88,7 @@ function createChatHandler(deps) {
84
88
  });
85
89
  const snapshot = episodes
86
90
  .filter((episode) => {
87
- const description = episode.sourceDescription ??
88
- episode.source_description ?? "";
91
+ const description = episode.sourceDescription ?? "";
89
92
  return description === "session-snapshot";
90
93
  })
91
94
  .sort((a, b) => {
@@ -94,12 +97,14 @@ function createChatHandler(deps) {
94
97
  return bTime - aTime;
95
98
  })[0];
96
99
  if (snapshot?.content) {
100
+ // Task 2: truncate snapshot at a line boundary.
97
101
  const snapshotBudget = Math.min(characterBudget, 1200);
102
+ const snapshotBody = (0, utils_js_1.truncateAtLineBoundary)(snapshot.content, snapshotBudget);
98
103
  snapshotPrimer = [
99
104
  "## Session Snapshot",
100
105
  "> Most recent session snapshot; use to restore active strategy and open questions.",
101
106
  "",
102
- snapshot.content.slice(0, snapshotBudget),
107
+ snapshotBody,
103
108
  ].join("\n");
104
109
  }
105
110
  }
@@ -107,25 +112,27 @@ function createChatHandler(deps) {
107
112
  logger_js_1.logger.error("Failed to load session snapshot", { err });
108
113
  }
109
114
  }
115
+ // Task 2: truncate project/user context strings at line boundaries.
110
116
  const projectBudget = useUserScope
111
117
  ? Math.floor(characterBudget * 0.7)
112
118
  : characterBudget;
113
119
  const userBudget = characterBudget - projectBudget;
114
- const truncatedProject = projectContextString.slice(0, projectBudget);
120
+ const truncatedProject = (0, utils_js_1.truncateAtLineBoundary)(projectContextString, projectBudget);
115
121
  const truncatedUser = useUserScope
116
- ? userContextString.slice(0, userBudget)
122
+ ? (0, utils_js_1.truncateAtLineBoundary)(userContextString, userBudget)
117
123
  : "";
118
- const memoryContext = [snapshotPrimer, truncatedProject, truncatedUser]
124
+ // Task 2: final combined context also truncated at a line boundary.
125
+ const combined = [snapshotPrimer, truncatedProject, truncatedUser]
119
126
  .filter((section) => section.trim().length > 0)
120
- .join("\n\n")
121
- .slice(0, characterBudget);
127
+ .join("\n\n");
128
+ const memoryContext = (0, utils_js_1.truncateAtLineBoundary)(combined, characterBudget);
122
129
  if (!memoryContext)
123
130
  return;
124
131
  const allFactUuids = [
125
132
  ...projectContext.facts.map((fact) => fact.uuid),
126
133
  ...userContext.facts.map((fact) => fact.uuid),
127
134
  ];
128
- const factUuids = seedFactUuids ?? Array.from(new Set(allFactUuids));
135
+ const factUuids = Array.from(new Set(allFactUuids));
129
136
  state.cachedMemoryContext = memoryContext;
130
137
  state.cachedFactUuids = factUuids;
131
138
  logger_js_1.logger.info(`Cached ${projectFacts.length + userFacts.length} facts and ${projectNodes.length + userNodes.length} nodes for user message injection`);
@@ -145,10 +152,6 @@ function createChatHandler(deps) {
145
152
  return union === 0 ? 1 : intersection / union;
146
153
  };
147
154
  return async ({ sessionID }, output) => {
148
- if (await sessionManager.isSubagentSession(sessionID)) {
149
- logger_js_1.logger.debug("Ignoring subagent chat message:", sessionID);
150
- return;
151
- }
152
155
  const { state, resolved } = await sessionManager.resolveSessionState(sessionID);
153
156
  if (!resolved) {
154
157
  logger_js_1.logger.debug("Unable to resolve session for message:", { sessionID });
@@ -169,18 +172,20 @@ function createChatHandler(deps) {
169
172
  messageLength: messageText.length,
170
173
  });
171
174
  const shouldInjectOnFirst = !state.injectedMemories;
172
- let shouldReinject = false;
173
- let currentFactUuids = null;
175
+ // Task 8: driftFacts from the drift check are passed into
176
+ // searchAndCacheMemoryContext so the project searchFacts is not repeated.
177
+ let driftProjectFacts = null;
174
178
  if (!shouldInjectOnFirst) {
175
179
  try {
176
- const driftFacts = await client.searchFacts({
180
+ const fetched = await client.searchFacts({
177
181
  query: messageText,
178
182
  groupIds: [state.groupId],
179
- maxFacts: 20,
183
+ maxFacts: constants_js_1.PROJECT_MAX_FACTS,
180
184
  });
181
- currentFactUuids = driftFacts.map((fact) => fact.uuid);
185
+ driftProjectFacts = fetched;
186
+ const currentFactUuids = fetched.map((fact) => fact.uuid);
182
187
  const similarity = computeJaccardSimilarity(currentFactUuids, state.lastInjectionFactUuids);
183
- shouldReinject = similarity < driftThreshold;
188
+ const shouldReinject = similarity < driftThreshold;
184
189
  if (!shouldReinject) {
185
190
  logger_js_1.logger.debug("Skipping reinjection; similarity above threshold", {
186
191
  sessionID,
@@ -200,7 +205,11 @@ function createChatHandler(deps) {
200
205
  try {
201
206
  const useUserScope = shouldInjectOnFirst;
202
207
  const characterBudget = (0, context_limit_js_1.calculateInjectionBudget)(state.contextLimit);
203
- await searchAndCacheMemoryContext(state, messageText, useUserScope, characterBudget, currentFactUuids);
208
+ await searchAndCacheMemoryContext(state, messageText, useUserScope, characterBudget,
209
+ // Task 8: on reinjection, pass the drift facts so the project query is
210
+ // not duplicated. On first injection driftProjectFacts is null, which
211
+ // triggers a full maxFacts=PROJECT_MAX_FACTS project search.
212
+ driftProjectFacts ?? undefined);
204
213
  state.injectedMemories = true;
205
214
  }
206
215
  catch (err) {
@@ -9,9 +9,9 @@ export interface EventHandlerDeps {
9
9
  sessionManager: SessionManager;
10
10
  client: GraphitiClient;
11
11
  defaultGroupId: string;
12
+ defaultUserGroupId: string;
12
13
  sdkClient: OpencodeClient;
13
14
  directory: string;
14
- groupIdPrefix: string;
15
15
  }
16
16
  /** Creates the `event` hook handler. */
17
17
  export declare function createEventHandler(deps: EventHandlerDeps): ({ event }: EventInput) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAqDzC,WAAW,UAAU,mBA4LpC"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/src/handlers/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,KAAK,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7C,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3C,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,IAkDzC,WAAW,UAAU,mBAiMpC"}