open-mem 0.5.2 → 0.5.4

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 (51) hide show
  1. package/dist/ai/compressor.d.ts.map +1 -1
  2. package/dist/ai/parser.d.ts +1 -0
  3. package/dist/ai/parser.d.ts.map +1 -1
  4. package/dist/ai/prompts.d.ts.map +1 -1
  5. package/dist/context/builder.d.ts.map +1 -1
  6. package/dist/context/progressive.d.ts +6 -1
  7. package/dist/context/progressive.d.ts.map +1 -1
  8. package/dist/context/relevance.d.ts +46 -0
  9. package/dist/context/relevance.d.ts.map +1 -0
  10. package/dist/daemon/manager.d.ts.map +1 -1
  11. package/dist/daemon/reaper.d.ts +14 -0
  12. package/dist/daemon/reaper.d.ts.map +1 -0
  13. package/dist/daemon.js +39 -22
  14. package/dist/db/observations.d.ts +11 -3
  15. package/dist/db/observations.d.ts.map +1 -1
  16. package/dist/db/pending.d.ts +1 -0
  17. package/dist/db/pending.d.ts.map +1 -1
  18. package/dist/db/schema.d.ts.map +1 -1
  19. package/dist/hooks/chat-capture.d.ts +1 -1
  20. package/dist/hooks/chat-capture.d.ts.map +1 -1
  21. package/dist/hooks/session-events.d.ts +2 -1
  22. package/dist/hooks/session-events.d.ts.map +1 -1
  23. package/dist/hooks/tool-capture.d.ts.map +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +97 -74
  26. package/dist/mcp.js +49 -36
  27. package/dist/queue/processor.d.ts.map +1 -1
  28. package/dist/search/orchestrator.d.ts +25 -0
  29. package/dist/search/orchestrator.d.ts.map +1 -0
  30. package/dist/servers/http-server.d.ts.map +1 -1
  31. package/dist/servers/mcp-server.d.ts +2 -0
  32. package/dist/servers/mcp-server.d.ts.map +1 -1
  33. package/dist/tools/delete.d.ts +5 -0
  34. package/dist/tools/delete.d.ts.map +1 -0
  35. package/dist/tools/import.d.ts.map +1 -1
  36. package/dist/tools/save.d.ts.map +1 -1
  37. package/dist/tools/search.d.ts +2 -3
  38. package/dist/tools/search.d.ts.map +1 -1
  39. package/dist/tools/timeline.d.ts.map +1 -1
  40. package/dist/tools/update.d.ts +5 -0
  41. package/dist/tools/update.d.ts.map +1 -0
  42. package/dist/types.d.ts +3 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/utils/agents-md.d.ts.map +1 -1
  45. package/dist/utils/bun-path.d.ts +19 -0
  46. package/dist/utils/bun-path.d.ts.map +1 -0
  47. package/dist/utils/privacy.d.ts +5 -0
  48. package/dist/utils/privacy.d.ts.map +1 -0
  49. package/dist/utils/retention.d.ts +5 -0
  50. package/dist/utils/retention.d.ts.map +1 -0
  51. package/package.json +2 -7
@@ -1 +1 @@
1
- {"version":3,"file":"compressor.d.ts","sourceRoot":"","sources":["../../src/ai/compressor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,YAAY,EAAE,MAAM,IAAI,CAAC;AAEtD,OAAO,EAAE,KAAK,iBAAiB,EAA4B,MAAM,UAAU,CAAC;AAU5E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC7B;AAMD;;;;GAIG;AACH,qBAAa,qBAAqB;IACjC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAmB;IAGjC,SAAS,sBAAgB;gBAEb,MAAM,EAAE,gBAAgB;IAsBpC,+DAA+D;IAC/D,MAAM,CAAC,QAAQ,CAAC,gBAAgB,SAAU;IAE1C;;;;OAIG;IACG,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAqDpC;;;OAGG;IACG,aAAa,CAClB,KAAK,EAAE,aAAa,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC,GACA,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAqBjD;;;OAGG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB;IAsB5E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAarC"}
1
+ {"version":3,"file":"compressor.d.ts","sourceRoot":"","sources":["../../src/ai/compressor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,YAAY,EAAE,MAAM,IAAI,CAAC;AAEtD,OAAO,EAAE,KAAK,iBAAiB,EAA4B,MAAM,UAAU,CAAC;AAU5E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC7B;AAMD;;;;GAIG;AACH,qBAAa,qBAAqB;IACjC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAmB;IAGjC,SAAS,sBAAgB;gBAEb,MAAM,EAAE,gBAAgB;IAsBpC,+DAA+D;IAC/D,MAAM,CAAC,QAAQ,CAAC,gBAAgB,SAAU;IAE1C;;;;OAIG;IACG,QAAQ,CACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAqDpC;;;OAGG;IACG,aAAa,CAClB,KAAK,EAAE,aAAa,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC,GACA,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAqBjD;;;OAGG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB;IAuB5E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAarC"}
@@ -9,6 +9,7 @@ export interface ParsedObservation {
9
9
  filesRead: string[];
10
10
  filesModified: string[];
11
11
  discoveryTokens?: number;
12
+ importance?: number;
12
13
  }
13
14
  export interface ParsedSummary {
14
15
  summary: string;
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ai/parser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAyCD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CA4BnF;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA0B3E;AAMD,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ai/parser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMhD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAyCD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAmCnF;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CA0B3E;AAMD,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACrB,MAAM,CAkDR;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACvC,YAAY,EAAE,aAAa,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC,EACF,SAAS,EAAE,MAAM,GACf,MAAM,CAwCR"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACrB,MAAM,CAmDR;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACvC,YAAY,EAAE,aAAa,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC,EACF,SAAS,EAAE,MAAM,GACf,MAAM,CAwCR"}
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/context/builder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiC,eAAe,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAMxD,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAC5C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CACzB;AA0BD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,GAAE,oBAA6C,GACnD,MAAM,CAoFR;AA4DD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAoBvE"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/context/builder.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiC,eAAe,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAMxD,MAAM,WAAW,oBAAoB;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC;IAC5C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CACzB;AA0BD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,GAAE,oBAA6C,GACnD,MAAM,CA2FR;AA4DD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAoBvE"}
@@ -1,4 +1,5 @@
1
1
  import type { Observation, ObservationIndex, Session, SessionSummary } from "../types";
2
+ import { type ScoringContext } from "./relevance";
2
3
  export interface ProgressiveContext {
3
4
  recentSummaries: SessionSummary[];
4
5
  observationIndex: ObservationIndex[];
@@ -8,6 +9,10 @@ export interface ProgressiveContext {
8
9
  /**
9
10
  * Select summaries and observation-index entries that fit within the
10
11
  * token budget. Summaries are higher priority (richer context).
12
+ *
13
+ * When `scoringContext` is provided, observations are sorted by relevance
14
+ * score (descending) before applying the token budget — prioritizing
15
+ * recent, important entries. Without it, chronological order is preserved.
11
16
  */
12
- export declare function buildProgressiveContext(_recentSessions: ReadonlyArray<Session>, summaries: ReadonlyArray<SessionSummary>, observationIndex: ReadonlyArray<ObservationIndex>, maxTokens: number, fullObservations?: ReadonlyArray<Observation>): ProgressiveContext;
17
+ export declare function buildProgressiveContext(_recentSessions: ReadonlyArray<Session>, summaries: ReadonlyArray<SessionSummary>, observationIndex: ReadonlyArray<ObservationIndex>, maxTokens: number, fullObservations?: ReadonlyArray<Observation>, scoringContext?: ScoringContext): ProgressiveContext;
13
18
  //# sourceMappingURL=progressive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progressive.d.ts","sourceRoot":"","sources":["../../src/context/progressive.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAMvF,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACpB;AAMD;;;GAGG;AACH,wBAAgB,uBAAuB,CACtC,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,EACvC,SAAS,EAAE,aAAa,CAAC,cAAc,CAAC,EACxC,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACjD,SAAS,EAAE,MAAM,EACjB,gBAAgB,GAAE,aAAa,CAAC,WAAW,CAAM,GAC/C,kBAAkB,CA2BpB"}
1
+ {"version":3,"file":"progressive.d.ts","sourceRoot":"","sources":["../../src/context/progressive.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvF,OAAO,EAAE,KAAK,cAAc,EAAmB,MAAM,aAAa,CAAC;AAMnE,MAAM,WAAW,kBAAkB;IAClC,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACtC,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,EACvC,SAAS,EAAE,aAAa,CAAC,cAAc,CAAC,EACxC,gBAAgB,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACjD,SAAS,EAAE,MAAM,EACjB,gBAAgB,GAAE,aAAa,CAAC,WAAW,CAAM,EACjD,cAAc,CAAC,EAAE,cAAc,GAC7B,kBAAkB,CA+BpB"}
@@ -0,0 +1,46 @@
1
+ import type { ObservationIndex, ObservationType } from "../types";
2
+ export interface ScoringContext {
3
+ /** Boost observations from the current session */
4
+ currentSessionId?: string;
5
+ /** Reference time for recency scoring */
6
+ now: Date;
7
+ }
8
+ /**
9
+ * Compute recency score using a step function.
10
+ *
11
+ * - Today (< 24h): 1.0
12
+ * - Yesterday (24-48h): 0.8
13
+ * - Last week (2-7 days): 0.5
14
+ * - Older (> 7 days): 0.2
15
+ */
16
+ export declare function scoreRecency(createdAt: string, now: Date): number;
17
+ /**
18
+ * Score based on observation type importance.
19
+ * Decisions and bugfixes are most valuable; changes are least.
20
+ */
21
+ export declare function scoreTypeImportance(type: ObservationType): number;
22
+ /**
23
+ * Boost observations from the current session.
24
+ * Current session = 1.0, other sessions = 0.3.
25
+ */
26
+ export declare function scoreSessionAffinity(entrySessionId: string, currentSessionId: string | undefined): number;
27
+ /**
28
+ * Smaller observations score higher — they give more info per token.
29
+ * Linear interpolation between MIN_EFFICIENT_TOKENS (score=1.0)
30
+ * and MAX_EFFICIENT_TOKENS (score=0.2).
31
+ */
32
+ export declare function scoreTokenEfficiency(tokenCount: number): number;
33
+ /**
34
+ * Compute a weighted relevance score for an observation index entry.
35
+ *
36
+ * Score = recency * 0.4 + typeImportance * 0.3 + sessionAffinity * 0.2 + tokenEfficiency * 0.1
37
+ *
38
+ * Returns a value in [0, 1] where higher = more relevant.
39
+ */
40
+ export declare function scoreObservation(entry: ObservationIndex, context: ScoringContext): number;
41
+ /**
42
+ * Sort observation index entries by relevance score (descending).
43
+ * Returns a new array — does not mutate the input.
44
+ */
45
+ export declare function sortByRelevance(entries: ReadonlyArray<ObservationIndex>, context: ScoringContext): ObservationIndex[];
46
+ //# sourceMappingURL=relevance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relevance.d.ts","sourceRoot":"","sources":["../../src/context/relevance.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMlE,MAAM,WAAW,cAAc;IAC9B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,GAAG,EAAE,IAAI,CAAC;CACV;AA2CD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAUjE;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAEjE;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAClC,MAAM,CAGR;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAO/D;AAMD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAYzF;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,EACxC,OAAO,EAAE,cAAc,GACrB,gBAAgB,EAAE,CAcpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"AAMA,UAAU,mBAAmB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,UAAU,CAA6C;gBAEnD,MAAM,EAAE,mBAAmB;IAMvC,KAAK,IAAI,OAAO;IA4BhB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ7B,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,OAAO;IAQpB,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAUrD"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/daemon/manager.ts"],"names":[],"mappings":"AAOA,UAAU,mBAAmB;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,UAAU,CAA6C;gBAEnD,MAAM,EAAE,mBAAmB;IAMvC,KAAK,IAAI,OAAO;IA+BhB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ7B,IAAI,IAAI,IAAI;IAaZ,SAAS,IAAI,OAAO;IAQpB,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAUrD"}
@@ -0,0 +1,14 @@
1
+ export interface ReapResult {
2
+ reaped: number;
3
+ errors: string[];
4
+ }
5
+ /**
6
+ * Reap orphan daemon PID files for a given database path.
7
+ *
8
+ * - If no PID file exists → no-op
9
+ * - If PID file exists but process is dead → remove stale PID file
10
+ * - If PID file exists and process is alive → skip (don't kill random processes)
11
+ * - If PID file is invalid (non-numeric) → remove corrupt PID file
12
+ */
13
+ export declare function reapOrphanDaemons(dbPath: string): ReapResult;
14
+ //# sourceMappingURL=reaper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reaper.d.ts","sourceRoot":"","sources":["../../src/daemon/reaper.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAiD5D"}
package/dist/daemon.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var z=import.meta.require;import{parseArgs as T0}from"util";import{generateText as V0}from"ai";var Q0=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function W(J,X){let Z=new RegExp(`<${X}[^>]*>([\\s\\S]*?)</${X}>`,"i"),$=J.match(Z);return $?$[1].trim():""}function G(J,X){let Z=new RegExp(`<${X}[^>]*>([\\s\\S]*?)</${X}>`,"gi"),$=[];for(let Q of J.matchAll(Z)){let H=Q[1].trim();if(H)$.push(H)}return $}function I(J){let X=W(J,"observation");if(!X)return null;let Z=W(X,"type").toLowerCase(),$=Q0.has(Z)?Z:"discovery",Q=W(X,"title")||"Untitled observation",H=W(X,"subtitle"),V=W(X,"narrative"),Y=G(W(X,"facts"),"fact"),K=G(W(X,"concepts"),"concept"),U=G(W(X,"files_read"),"file"),A=G(W(X,"files_modified"),"file");return{type:$,title:Q,subtitle:H,facts:Y,narrative:V,concepts:K,filesRead:U,filesModified:A}}function h(J){let X=W(J,"session_summary");if(!X)return null;let Z=W(X,"summary")||"No summary available",$=G(W(X,"key_decisions"),"decision"),Q=G(W(X,"files_modified"),"file"),H=G(W(X,"concepts"),"concept"),V=W(X,"request")||void 0,Y=W(X,"investigated")||void 0,K=W(X,"learned")||void 0,U=W(X,"completed")||void 0,A=W(X,"next_steps")||void 0;return{summary:Z,keyDecisions:$,filesModified:Q,concepts:H,request:V,investigated:Y,learned:K,completed:U,nextSteps:A}}function F(J){return Math.ceil(J.length/4)}function f(J,X,Z){let $=Z?`<session_context>
3
+ var z=import.meta.require;import{parseArgs as P0}from"util";import{generateText as z0}from"ai";var V0=new Set(["decision","bugfix","feature","refactor","discovery","change"]);function K(J,X){let Z=new RegExp(`<${X}[^>]*>([\\s\\S]*?)</${X}>`,"i"),$=J.match(Z);return $?$[1].trim():""}function G(J,X){let Z=new RegExp(`<${X}[^>]*>([\\s\\S]*?)</${X}>`,"gi"),$=[];for(let Q of J.matchAll(Z)){let Y=Q[1].trim();if(Y)$.push(Y)}return $}function v(J){let X=K(J,"observation");if(!X)return null;let Z=K(X,"type").toLowerCase(),$=V0.has(Z)?Z:"discovery",Q=K(X,"title")||"Untitled observation",Y=K(X,"subtitle"),W=K(X,"narrative"),H=G(K(X,"facts"),"fact"),V=G(K(X,"concepts"),"concept"),U=G(K(X,"files_read"),"file"),E=G(K(X,"files_modified"),"file"),H0=K(X,"importance"),f=Number.parseInt(H0,10),W0=Number.isNaN(f)?3:Math.max(1,Math.min(5,f));return{type:$,title:Q,subtitle:Y,facts:H,narrative:W,concepts:V,filesRead:U,filesModified:E,importance:W0}}function w(J){let X=K(J,"session_summary");if(!X)return null;let Z=K(X,"summary")||"No summary available",$=G(K(X,"key_decisions"),"decision"),Q=G(K(X,"files_modified"),"file"),Y=G(K(X,"concepts"),"concept"),W=K(X,"request")||void 0,H=K(X,"investigated")||void 0,V=K(X,"learned")||void 0,U=K(X,"completed")||void 0,E=K(X,"next_steps")||void 0;return{summary:Z,keyDecisions:$,filesModified:Q,concepts:Y,request:W,investigated:H,learned:V,completed:U,nextSteps:E}}function F(J){return Math.ceil(J.length/4)}function u(J,X,Z){let $=Z?`<session_context>
4
4
  ${Z}
5
5
  </session_context>
6
6
 
@@ -32,6 +32,7 @@ Respond with EXACTLY this XML format:
32
32
  <type>decision|bugfix|feature|refactor|discovery|change</type>
33
33
  <title>Brief descriptive title (max 80 chars)</title>
34
34
  <subtitle>One-line elaboration</subtitle>
35
+ <importance>1-5 (1=trivial/routine, 2=low, 3=normal, 4=significant, 5=critical decision or discovery)</importance>
35
36
  <facts>
36
37
  <fact>Specific factual detail 1</fact>
37
38
  <fact>Specific factual detail 2</fact>
@@ -48,7 +49,7 @@ Respond with EXACTLY this XML format:
48
49
  <file>path/to/file/modified</file>
49
50
  </files_modified>
50
51
  </observation>
51
- </instructions>`}function v(J,X){let Z=J.map(($,Q)=>` <obs index="${Q+1}" type="${$.type}">
52
+ </instructions>`}function b(J,X){let Z=J.map(($,Q)=>` <obs index="${Q+1}" type="${$.type}">
52
53
  <title>${$.title}</title>
53
54
  <narrative>${$.narrative}</narrative>
54
55
  </obs>`).join(`
@@ -83,57 +84,72 @@ Respond with EXACTLY this XML format:
83
84
  <concept>key-concept</concept>
84
85
  </concepts>
85
86
  </session_summary>
86
- </instructions>`}var Y0={"claude-sonnet-4-20250514":"us.anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4-20250514":"us.anthropic.claude-opus-4-20250514-v1:0","claude-3-5-sonnet-20241022":"us.anthropic.claude-3-5-sonnet-20241022-v2:0","claude-3-5-haiku-20241022":"us.anthropic.claude-3-5-haiku-20241022-v1:0","claude-3-haiku-20240307":"anthropic.claude-3-haiku-20240307-v1:0"};function H0(J){if(J.includes("."))return J;return Y0[J]||`us.anthropic.${J}-v1:0`}function N(J){switch(J.provider){case"anthropic":{let{createAnthropic:X}=z("@ai-sdk/anthropic");return X({apiKey:J.apiKey})(J.model)}case"bedrock":{let{createAmazonBedrock:X}=z("@ai-sdk/amazon-bedrock");return X()(H0(J.model))}case"openai":{let{createOpenAI:X}=z("@ai-sdk/openai");return X({apiKey:J.apiKey})(J.model)}case"google":{let{createGoogleGenerativeAI:X}=z("@ai-sdk/google");return X({apiKey:J.apiKey})(J.model)}default:throw Error(`Unknown provider: ${J.provider}. Supported: anthropic, bedrock, openai, google`)}}function w(J){try{switch(J.provider){case"google":{let{createGoogleGenerativeAI:X}=z("@ai-sdk/google");return X({apiKey:J.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:X}=z("@ai-sdk/openai");return X({apiKey:J.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:X}=z("@ai-sdk/amazon-bedrock");return X().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}var W0={"gemini-2.5-flash-lite":10,"gemini-2.5-flash":10,"gemini-2.5-pro":5,"gemini-2.0-flash":15,"gemini-2.0-flash-lite":30,"gemini-3-flash":5},u=0;async function M(J,X){if(!X)return;let Z=W0[J]||5,$=Math.ceil(60000/Z)+100,H=Date.now()-u;if(H<$){let V=$-H;await new Promise((Y)=>setTimeout(Y,V))}u=Date.now()}class _{model;config;_generate=V0;constructor(J){this.config=J,this.model=null;let X=J.provider!=="bedrock";if(J.compressionEnabled&&(!X||J.apiKey))try{this.model=N({provider:J.provider,model:J.model,apiKey:J.apiKey})}catch{}}static MAX_INPUT_LENGTH=50000;async compress(J,X,Z){if(!this.config.compressionEnabled||!this.model)return null;if(X.length<this.config.minOutputLength)return null;let $=F(X),Q=X.length>_.MAX_INPUT_LENGTH?`${X.substring(0,_.MAX_INPUT_LENGTH)}
87
+ </instructions>`}var K0={"claude-sonnet-4-20250514":"us.anthropic.claude-sonnet-4-20250514-v1:0","claude-opus-4-20250514":"us.anthropic.claude-opus-4-20250514-v1:0","claude-3-5-sonnet-20241022":"us.anthropic.claude-3-5-sonnet-20241022-v2:0","claude-3-5-haiku-20241022":"us.anthropic.claude-3-5-haiku-20241022-v1:0","claude-3-haiku-20240307":"anthropic.claude-3-haiku-20240307-v1:0"};function B0(J){if(J.includes("."))return J;return K0[J]||`us.anthropic.${J}-v1:0`}function N(J){switch(J.provider){case"anthropic":{let{createAnthropic:X}=z("@ai-sdk/anthropic");return X({apiKey:J.apiKey})(J.model)}case"bedrock":{let{createAmazonBedrock:X}=z("@ai-sdk/amazon-bedrock");return X()(B0(J.model))}case"openai":{let{createOpenAI:X}=z("@ai-sdk/openai");return X({apiKey:J.apiKey})(J.model)}case"google":{let{createGoogleGenerativeAI:X}=z("@ai-sdk/google");return X({apiKey:J.apiKey})(J.model)}default:throw Error(`Unknown provider: ${J.provider}. Supported: anthropic, bedrock, openai, google`)}}function g(J){try{switch(J.provider){case"google":{let{createGoogleGenerativeAI:X}=z("@ai-sdk/google");return X({apiKey:J.apiKey}).embedding("text-embedding-004")}case"openai":{let{createOpenAI:X}=z("@ai-sdk/openai");return X({apiKey:J.apiKey}).embedding("text-embedding-3-small")}case"bedrock":{let{createAmazonBedrock:X}=z("@ai-sdk/amazon-bedrock");return X().embedding("amazon.titan-embed-text-v2:0")}case"anthropic":return null;default:return null}}catch{return null}}var U0={"gemini-2.5-flash-lite":10,"gemini-2.5-flash":10,"gemini-2.5-pro":5,"gemini-2.0-flash":15,"gemini-2.0-flash-lite":30,"gemini-3-flash":5},l=0;async function M(J,X){if(!X)return;let Z=U0[J]||5,$=Math.ceil(60000/Z)+100,Y=Date.now()-l;if(Y<$){let W=$-Y;await new Promise((H)=>setTimeout(H,W))}l=Date.now()}class _{model;config;_generate=z0;constructor(J){this.config=J,this.model=null;let X=J.provider!=="bedrock";if(J.compressionEnabled&&(!X||J.apiKey))try{this.model=N({provider:J.provider,model:J.model,apiKey:J.apiKey})}catch{}}static MAX_INPUT_LENGTH=50000;async compress(J,X,Z){if(!this.config.compressionEnabled||!this.model)return null;if(X.length<this.config.minOutputLength)return null;let $=F(X),Q=X.length>_.MAX_INPUT_LENGTH?`${X.substring(0,_.MAX_INPUT_LENGTH)}
87
88
 
88
- [... truncated ...]`:X,H=f(J,Q,Z),V=2;for(let Y=0;Y<=V;Y++)try{if(this.config.provider==="google")await M(this.config.model,this.config.rateLimitingEnabled);let{text:K}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:H}),U=I(K);if(U)U.discoveryTokens=$;return U}catch(K){if(z0(K)&&Y<V){let U=2**Y*1000;await b(U);continue}return null}return null}async compressBatch(J){let X=new Map;for(let Z=0;Z<J.length;Z++){let $=J[Z],Q=await this.compress($.toolName,$.toolOutput,$.sessionContext);if(X.set($.callId,Q),Z<J.length-1)await b(200)}return X}createFallbackObservation(J,X){let Z=U0(X),$=K0[J]??"discovery";return{type:$,title:`${J} execution`,subtitle:X.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${J} was executed. Output length: ${X.length} chars.`,concepts:[],filesRead:$==="discovery"?Z:[],filesModified:$==="change"?Z:[],discoveryTokens:F(X)}}async isAvailable(){if(!this.model)return!1;try{return await this._generate({model:this.model,maxOutputTokens:10,prompt:"ping"}),!0}catch{return!1}}}var K0={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},B0=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function U0(J){let X=[];for(let Z of J.matchAll(B0))X.push(Z[1]);return[...new Set(X)]}function z0(J){if(typeof J!=="object"||J===null)return!1;let X=J,Z=X.status;if(Z===429||Z===500||Z===503)return!0;let $=X.error;if(typeof $==="object"&&$!==null&&$.type==="overloaded_error")return!0;return!1}function b(J){return new Promise((X)=>setTimeout(X,J))}import{generateText as G0}from"ai";class C{model;config;_generate=G0;constructor(J){this.config=J,this.model=null;let X=J.provider!=="bedrock";if(J.compressionEnabled&&(!X||J.apiKey))try{this.model=N({provider:J.provider,model:J.model,apiKey:J.apiKey})}catch{}}async summarize(J,X){if(X.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(X);let Z=v(X.map(($)=>({type:$.type,title:$.title,narrative:$.narrative})),J);try{if(this.config.provider==="google")await M(this.config.model,this.config.rateLimitingEnabled);let{text:$}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:Z}),Q=h($);if(!Q)return this.createFallbackSummary(X);return Q}catch{return this.createFallbackSummary(X)}}createFallbackSummary(J){let X=new Set,Z=new Set,$=[];for(let Y of J){for(let K of Y.filesModified)X.add(K);for(let K of Y.concepts)Z.add(K);if(Y.type==="decision")$.push(Y.title)}let Q=new Map;for(let Y of J)Q.set(Y.type,(Q.get(Y.type)??0)+1);let H=Array.from(Q.entries()).map(([Y,K])=>`${K} ${Y}${K>1?"s":""}`).join(", "),V=Array.from(Z).slice(0,5).join(", ");return{summary:`Session with ${J.length} observations: ${H}. Files modified: ${X.size}. Key concepts: ${V}.`,keyDecisions:$.slice(0,5),filesModified:Array.from(X),concepts:Array.from(Z)}}shouldSummarize(J){return J>=2}}var F0={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,embeddingDimension:void 0};function L0(){let J={};if(process.env.OPEN_MEM_DB_PATH)J.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)J.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)J.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)J.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")J.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")J.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)J.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((X)=>X.trim());if(process.env.OPEN_MEM_BATCH_SIZE)J.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)J.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)J.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")J.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)J.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((X)=>X.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)J.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)J.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")J.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")J.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")J.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)J.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_DAEMON==="true")J.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")J.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)J.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)J.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);return J}function _0(J){switch(J){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function g(J,X){let Z=L0(),$={...F0,...Z,...X};if(!$.dbPath.startsWith("/"))$.dbPath=`${J}/${$.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!X?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)$.provider="google";else if(process.env.ANTHROPIC_API_KEY)$.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)$.provider="bedrock"}if(!$.apiKey)switch($.provider){case"google":$.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":$.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":$.apiKey=process.env.OPENAI_API_KEY;break;case"bedrock":break}if($.embeddingDimension===void 0)$.embeddingDimension=_0($.provider);return $}import{existsSync as WJ,mkdirSync as N0,readFileSync as VJ,unlinkSync as M0,writeFileSync as E0}from"fs";function p(J){let X=J.lastIndexOf("/");if(X>0){let Z=J.substring(0,X);N0(Z,{recursive:!0})}E0(J,String(process.pid),"utf-8")}function l(J){try{M0(J)}catch{}}function m(J){let X=J.lastIndexOf("/");if(X>=0)return`${J.substring(0,X)}/worker.pid`;return"worker.pid"}class j{queueProcessor;pollIntervalMs;timer=null;lastActiveAt=Date.now();processing=!1;constructor(J){this.queueProcessor=J.queueProcessor,this.pollIntervalMs=J.pollIntervalMs}start(){if(this.timer)return;this.lastActiveAt=Date.now(),this.timer=setInterval(async()=>{if(this.processing)return;this.processing=!0;try{if(await this.queueProcessor.processBatch()>0)this.lastActiveAt=Date.now()}catch{}finally{this.processing=!1}},this.pollIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get idleMs(){return Date.now()-this.lastActiveAt}get shouldAutoExit(){return this.idleMs>=60000&&!process.send}handleMessage(J){if(J==="SHUTDOWN")this.stop();else if(J==="PROCESS_NOW"){if(!this.processing)this.processing=!0,this.queueProcessor.processBatch().then((X)=>{if(X>0)this.lastActiveAt=Date.now()}).catch(()=>{}).finally(()=>{this.processing=!1})}}}import{Database as c}from"bun:sqlite";import{existsSync as S,mkdirSync as A0,unlinkSync as d}from"fs";import*as n from"sqlite-vec";class E{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let J=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let X of J)try{if(S(X))return c.setCustomSQLite(X),!0}catch{return!1}return!1}constructor(J){this.dbPath=J,this.db=this.open(J),this.configure()}open(J){let X=J.lastIndexOf("/");if(X>0){let Z=J.substring(0,X);A0(Z,{recursive:!0})}return new c(J,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(J){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",J.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(X){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",X.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(Z){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",Z.message),J}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{n.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let J of["-wal","-shm"]){let X=this.dbPath+J;try{if(S(X))d(X)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(S(this.dbPath))d(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
89
+ [... truncated ...]`:X,Y=u(J,Q,Z),W=2;for(let H=0;H<=W;H++)try{if(this.config.provider==="google")await M(this.config.model,this.config.rateLimitingEnabled);let{text:V}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:Y}),U=v(V);if(U)U.discoveryTokens=$;return U}catch(V){if(_0(V)&&H<W){let U=2**H*1000;await p(U);continue}return null}return null}async compressBatch(J){let X=new Map;for(let Z=0;Z<J.length;Z++){let $=J[Z],Q=await this.compress($.toolName,$.toolOutput,$.sessionContext);if(X.set($.callId,Q),Z<J.length-1)await p(200)}return X}createFallbackObservation(J,X){let Z=L0(X),$=G0[J]??"discovery";return{type:$,title:`${J} execution`,subtitle:X.substring(0,100).replace(/\n/g," "),facts:[],narrative:`Tool ${J} was executed. Output length: ${X.length} chars.`,concepts:[],filesRead:$==="discovery"?Z:[],filesModified:$==="change"?Z:[],discoveryTokens:F(X),importance:2}}async isAvailable(){if(!this.model)return!1;try{return await this._generate({model:this.model,maxOutputTokens:10,prompt:"ping"}),!0}catch{return!1}}}var G0={Read:"discovery",Write:"change",Edit:"change",Bash:"change",Glob:"discovery",Grep:"discovery"},F0=/(?:^|\s)((?:\.\/|\/|src\/|tests\/|lib\/)\S+\.\w+)/gm;function L0(J){let X=[];for(let Z of J.matchAll(F0))X.push(Z[1]);return[...new Set(X)]}function _0(J){if(typeof J!=="object"||J===null)return!1;let X=J,Z=X.status;if(Z===429||Z===500||Z===503)return!0;let $=X.error;if(typeof $==="object"&&$!==null&&$.type==="overloaded_error")return!0;return!1}function p(J){return new Promise((X)=>setTimeout(X,J))}import{generateText as N0}from"ai";class C{model;config;_generate=N0;constructor(J){this.config=J,this.model=null;let X=J.provider!=="bedrock";if(J.compressionEnabled&&(!X||J.apiKey))try{this.model=N({provider:J.provider,model:J.model,apiKey:J.apiKey})}catch{}}async summarize(J,X){if(X.length===0)return null;if(!this.config.compressionEnabled||!this.model)return this.createFallbackSummary(X);let Z=b(X.map(($)=>({type:$.type,title:$.title,narrative:$.narrative})),J);try{if(this.config.provider==="google")await M(this.config.model,this.config.rateLimitingEnabled);let{text:$}=await this._generate({model:this.model,maxOutputTokens:this.config.maxTokensPerCompression,prompt:Z}),Q=w($);if(!Q)return this.createFallbackSummary(X);return Q}catch{return this.createFallbackSummary(X)}}createFallbackSummary(J){let X=new Set,Z=new Set,$=[];for(let H of J){for(let V of H.filesModified)X.add(V);for(let V of H.concepts)Z.add(V);if(H.type==="decision")$.push(H.title)}let Q=new Map;for(let H of J)Q.set(H.type,(Q.get(H.type)??0)+1);let Y=Array.from(Q.entries()).map(([H,V])=>`${V} ${H}${V>1?"s":""}`).join(", "),W=Array.from(Z).slice(0,5).join(", ");return{summary:`Session with ${J.length} observations: ${Y}. Files modified: ${X.size}. Key concepts: ${W}.`,keyDecisions:$.slice(0,5),filesModified:Array.from(X),concepts:Array.from(Z)}}shouldSummarize(J){return J>=2}}var M0={dbPath:".open-mem/memory.db",provider:"google",apiKey:void 0,model:"gemini-2.5-flash-lite",maxTokensPerCompression:1024,compressionEnabled:!0,contextInjectionEnabled:!0,maxContextTokens:4000,batchSize:5,batchIntervalMs:30000,ignoredTools:[],minOutputLength:50,maxIndexEntries:20,sensitivePatterns:[],retentionDays:90,maxDatabaseSizeMb:500,logLevel:"warn",contextShowTokenCosts:!0,contextObservationTypes:"all",contextFullObservationCount:3,maxObservations:50,contextShowLastSummary:!0,rateLimitingEnabled:!0,folderContextEnabled:!0,folderContextMaxDepth:5,daemonEnabled:!1,dashboardEnabled:!1,dashboardPort:3737,embeddingDimension:void 0};function A0(){let J={};if(process.env.OPEN_MEM_DB_PATH)J.dbPath=process.env.OPEN_MEM_DB_PATH;if(process.env.OPEN_MEM_PROVIDER)J.provider=process.env.OPEN_MEM_PROVIDER;if(process.env.OPEN_MEM_MODEL)J.model=process.env.OPEN_MEM_MODEL;if(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS)J.maxContextTokens=Number.parseInt(process.env.OPEN_MEM_MAX_CONTEXT_TOKENS,10);if(process.env.OPEN_MEM_COMPRESSION==="false")J.compressionEnabled=!1;if(process.env.OPEN_MEM_CONTEXT_INJECTION==="false")J.contextInjectionEnabled=!1;if(process.env.OPEN_MEM_IGNORED_TOOLS)J.ignoredTools=process.env.OPEN_MEM_IGNORED_TOOLS.split(",").map((X)=>X.trim());if(process.env.OPEN_MEM_BATCH_SIZE)J.batchSize=Number.parseInt(process.env.OPEN_MEM_BATCH_SIZE,10);if(process.env.OPEN_MEM_RETENTION_DAYS)J.retentionDays=Number.parseInt(process.env.OPEN_MEM_RETENTION_DAYS,10);if(process.env.OPEN_MEM_LOG_LEVEL)J.logLevel=process.env.OPEN_MEM_LOG_LEVEL;if(process.env.OPEN_MEM_CONTEXT_SHOW_TOKEN_COSTS==="false")J.contextShowTokenCosts=!1;if(process.env.OPEN_MEM_CONTEXT_TYPES)J.contextObservationTypes=process.env.OPEN_MEM_CONTEXT_TYPES==="all"?"all":process.env.OPEN_MEM_CONTEXT_TYPES.split(",").map((X)=>X.trim());if(process.env.OPEN_MEM_CONTEXT_FULL_COUNT)J.contextFullObservationCount=Number.parseInt(process.env.OPEN_MEM_CONTEXT_FULL_COUNT,10);if(process.env.OPEN_MEM_MAX_OBSERVATIONS)J.maxObservations=Number.parseInt(process.env.OPEN_MEM_MAX_OBSERVATIONS,10);if(process.env.OPEN_MEM_CONTEXT_SHOW_LAST_SUMMARY==="false")J.contextShowLastSummary=!1;if(process.env.OPEN_MEM_RATE_LIMITING==="false")J.rateLimitingEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT==="false")J.folderContextEnabled=!1;if(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH)J.folderContextMaxDepth=Number.parseInt(process.env.OPEN_MEM_FOLDER_CONTEXT_MAX_DEPTH,10);if(process.env.OPEN_MEM_DAEMON==="true")J.daemonEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD==="true")J.dashboardEnabled=!0;if(process.env.OPEN_MEM_DASHBOARD_PORT)J.dashboardPort=Number.parseInt(process.env.OPEN_MEM_DASHBOARD_PORT,10);if(process.env.OPEN_MEM_EMBEDDING_DIMENSION)J.embeddingDimension=Number.parseInt(process.env.OPEN_MEM_EMBEDDING_DIMENSION,10);return J}function E0(J){switch(J){case"google":return 768;case"openai":return 1536;case"bedrock":return 1024;case"anthropic":return 0;default:return 768}}function m(J,X){let Z=A0(),$={...M0,...Z,...X};if(!$.dbPath.startsWith("/"))$.dbPath=`${J}/${$.dbPath}`;if(!process.env.OPEN_MEM_PROVIDER&&!X?.provider){if(process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY)$.provider="google";else if(process.env.ANTHROPIC_API_KEY)$.provider="anthropic";else if(process.env.AWS_BEARER_TOKEN_BEDROCK||process.env.AWS_ACCESS_KEY_ID||process.env.AWS_PROFILE)$.provider="bedrock"}if(!$.apiKey)switch($.provider){case"google":$.apiKey=process.env.GOOGLE_GENERATIVE_AI_API_KEY||process.env.GEMINI_API_KEY;break;case"anthropic":$.apiKey=process.env.ANTHROPIC_API_KEY;break;case"openai":$.apiKey=process.env.OPENAI_API_KEY;break;case"bedrock":break}if($.embeddingDimension===void 0)$.embeddingDimension=E0($.provider);return $}import{existsSync as UJ,mkdirSync as C0,readFileSync as zJ,unlinkSync as S0,writeFileSync as O0}from"fs";function c(J){let X=J.lastIndexOf("/");if(X>0){let Z=J.substring(0,X);C0(Z,{recursive:!0})}O0(J,String(process.pid),"utf-8")}function n(J){try{S0(J)}catch{}}function d(J){let X=J.lastIndexOf("/");if(X>=0)return`${J.substring(0,X)}/worker.pid`;return"worker.pid"}class S{queueProcessor;pollIntervalMs;timer=null;lastActiveAt=Date.now();processing=!1;constructor(J){this.queueProcessor=J.queueProcessor,this.pollIntervalMs=J.pollIntervalMs}start(){if(this.timer)return;this.lastActiveAt=Date.now(),this.timer=setInterval(async()=>{if(this.processing)return;this.processing=!0;try{if(await this.queueProcessor.processBatch()>0)this.lastActiveAt=Date.now()}catch{}finally{this.processing=!1}},this.pollIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get idleMs(){return Date.now()-this.lastActiveAt}get shouldAutoExit(){return this.idleMs>=60000&&!process.send}handleMessage(J){if(J==="SHUTDOWN")this.stop();else if(J==="PROCESS_NOW"){if(!this.processing)this.processing=!0,this.queueProcessor.processBatch().then((X)=>{if(X>0)this.lastActiveAt=Date.now()}).catch(()=>{}).finally(()=>{this.processing=!1})}}}import{Database as i}from"bun:sqlite";import{existsSync as O,mkdirSync as D0,unlinkSync as s}from"fs";import*as r from"sqlite-vec";class A{db;dbPath;_hasVectorExtension=!1;static enableExtensionSupport(){let J=["/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib","/usr/local/opt/sqlite/lib/libsqlite3.dylib"];for(let X of J)try{if(O(X))return i.setCustomSQLite(X),!0}catch{return!1}return!1}constructor(J){this.dbPath=J,this.db=this.open(J),this.configure()}open(J){let X=J.lastIndexOf("/");if(X>0){let Z=J.substring(0,X);D0(Z,{recursive:!0})}return new i(J,{create:!0})}configure(){try{this.applyPragmas(),this.loadExtensions()}catch(J){console.warn("[open-mem] Database configure failed, attempting recovery by removing WAL/SHM files:",J.message);try{this.db.close()}catch{}this.deleteSidecarFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after removing WAL/SHM files");return}catch(X){console.warn("[open-mem] WAL/SHM cleanup insufficient, recreating database from scratch:",X.message);try{this.db.close()}catch{}this.deleteDatabaseFiles();try{this.db=this.open(this.dbPath),this.applyPragmas(),this.loadExtensions(),console.warn("[open-mem] Recovery successful after full database recreation");return}catch(Z){throw console.warn("[open-mem] All recovery attempts failed, filesystem may be broken:",Z.message),J}}}}applyPragmas(){this.db.exec("PRAGMA journal_mode = WAL"),this.db.exec("PRAGMA synchronous = NORMAL"),this.db.exec("PRAGMA foreign_keys = ON"),this.db.exec("PRAGMA busy_timeout = 5000")}loadExtensions(){try{r.load(this.db),this._hasVectorExtension=!0}catch{this._hasVectorExtension=!1}}get hasVectorExtension(){return this._hasVectorExtension}deleteSidecarFiles(){for(let J of["-wal","-shm"]){let X=this.dbPath+J;try{if(O(X))s(X)}catch{}}}deleteDatabaseFiles(){this.deleteSidecarFiles();try{if(O(this.dbPath))s(this.dbPath)}catch{}}ensureMigrationTable(){this.db.exec(`
89
90
  CREATE TABLE IF NOT EXISTS _migrations (
90
91
  version INTEGER PRIMARY KEY,
91
92
  name TEXT NOT NULL,
92
93
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
93
94
  )
94
- `)}migrate(J){this.ensureMigrationTable();let X=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),Z=new Set(X.map((Q)=>Q.version)),$=J.filter((Q)=>!Z.has(Q.version)).sort((Q,H)=>Q.version-H.version);for(let Q of $)this.db.transaction(()=>{this.db.exec(Q.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:Q.version,$name:Q.name})})()}run(J,X){let Z=this.db.query(J);if(X)Z.run(...X);else Z.run()}get(J,X){let Z=this.db.query(J);return X?Z.get(...X):Z.get()}all(J,X){let Z=this.db.query(J);return X?Z.all(...X):Z.all()}exec(J){this.db.exec(J)}transaction(J){return this.db.transaction(J)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function i(J){return new E(J)}import{randomUUID as C0}from"crypto";class q{db;constructor(J){this.db=J}create(J){let X=C0(),Z=new Date().toISOString(),$=J.discoveryTokens??0;return this.db.run(`INSERT INTO observations
95
+ `)}migrate(J){this.ensureMigrationTable();let X=this.db.query("SELECT version FROM _migrations ORDER BY version").all(),Z=new Set(X.map((Q)=>Q.version)),$=J.filter((Q)=>!Z.has(Q.version)).sort((Q,Y)=>Q.version-Y.version);for(let Q of $)this.db.transaction(()=>{this.db.exec(Q.up),this.db.query("INSERT INTO _migrations (version, name) VALUES ($version, $name)").run({$version:Q.version,$name:Q.name})})()}run(J,X){let Z=this.db.query(J);if(X)Z.run(...X);else Z.run()}get(J,X){let Z=this.db.query(J);return X?Z.get(...X):Z.get()}all(J,X){let Z=this.db.query(J);return X?Z.all(...X):Z.all()}exec(J){this.db.exec(J)}transaction(J){return this.db.transaction(J)()}close(){this.db.close()}get isOpen(){try{return this.db.query("SELECT 1").get(),!0}catch{return!1}}get raw(){return this.db}}function t(J){return new A(J)}import{randomUUID as j0}from"crypto";import{embed as R0}from"ai";async function D(J,X){try{let{embedding:Z}=await R0({model:J,value:X});return Z}catch{return null}}function e(J,X){if(J.length!==X.length||J.length===0)return 0;let Z=0,$=0,Q=0;for(let W=0;W<J.length;W++)Z+=J[W]*X[W],$+=J[W]*J[W],Q+=X[W]*X[W];let Y=Math.sqrt($)*Math.sqrt(Q);if(Y===0)return 0;return Z/Y}function R(J){let X=[J.title,J.narrative];if(J.concepts.length>0)X.push(J.concepts.join(", "));return X.join(`
96
+ `)}class j{db;constructor(J){this.db=J}create(J){let X=j0(),Z=new Date().toISOString(),$=J.discoveryTokens??0,Q=J.importance??3;return this.db.run(`INSERT INTO observations
95
97
  (id, session_id, type, title, subtitle, facts, narrative,
96
98
  concepts, files_read, files_modified, raw_tool_output,
97
- tool_name, created_at, token_count, discovery_tokens)
98
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[X,J.sessionId,J.type,J.title,J.subtitle,JSON.stringify(J.facts),J.narrative,JSON.stringify(J.concepts),JSON.stringify(J.filesRead),JSON.stringify(J.filesModified),J.rawToolOutput,J.toolName,Z,J.tokenCount,$]),{...J,id:X,createdAt:Z,discoveryTokens:$}}importObservation(J){this.db.run(`INSERT INTO observations
99
+ tool_name, created_at, token_count, discovery_tokens, importance)
100
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[X,J.sessionId,J.type,J.title,J.subtitle,JSON.stringify(J.facts),J.narrative,JSON.stringify(J.concepts),JSON.stringify(J.filesRead),JSON.stringify(J.filesModified),J.rawToolOutput,J.toolName,Z,J.tokenCount,$,Q]),{...J,id:X,createdAt:Z,discoveryTokens:$,importance:Q}}importObservation(J){this.db.run(`INSERT INTO observations
99
101
  (id, session_id, type, title, subtitle, facts, narrative,
100
102
  concepts, files_read, files_modified, raw_tool_output,
101
- tool_name, created_at, token_count, discovery_tokens)
102
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[J.id,J.sessionId,J.type,J.title,J.subtitle,JSON.stringify(J.facts),J.narrative,JSON.stringify(J.concepts),JSON.stringify(J.filesRead),JSON.stringify(J.filesModified),J.rawToolOutput,J.toolName,J.createdAt,J.tokenCount,J.discoveryTokens??0])}getById(J){let X=this.db.get("SELECT * FROM observations WHERE id = ?",[J]);return X?this.mapRow(X):null}getBySession(J){return this.db.all("SELECT * FROM observations WHERE session_id = ? ORDER BY created_at ASC",[J]).map((X)=>this.mapRow(X))}getCount(J){if(J)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[J])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(J,X=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at
103
+ tool_name, created_at, token_count, discovery_tokens, importance)
104
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[J.id,J.sessionId,J.type,J.title,J.subtitle,JSON.stringify(J.facts),J.narrative,JSON.stringify(J.concepts),JSON.stringify(J.filesRead),JSON.stringify(J.filesModified),J.rawToolOutput,J.toolName,J.createdAt,J.tokenCount,J.discoveryTokens??0,J.importance??3])}getById(J){let X=this.db.get("SELECT * FROM observations WHERE id = ?",[J]);return X?this.mapRow(X):null}getBySession(J){return this.db.all("SELECT * FROM observations WHERE session_id = ? ORDER BY created_at ASC",[J]).map((X)=>this.mapRow(X))}getCount(J){if(J)return this.db.get("SELECT COUNT(*) as count FROM observations WHERE session_id = ?",[J])?.count??0;return this.db.get("SELECT COUNT(*) as count FROM observations")?.count??0}getIndex(J,X=20){return this.db.all(`SELECT o.id, o.session_id, o.type, o.title, o.token_count, o.discovery_tokens, o.created_at, o.importance
103
105
  FROM observations o
104
106
  JOIN sessions s ON o.session_id = s.id
105
107
  WHERE s.project_path = ?
106
108
  ORDER BY o.created_at DESC
107
- LIMIT ?`,[J,X]).map((Z)=>({id:Z.id,sessionId:Z.session_id,type:Z.type,title:Z.title,tokenCount:Z.token_count,discoveryTokens:Z.discovery_tokens??0,createdAt:Z.created_at}))}search(J){let X=`
109
+ LIMIT ?`,[J,X]).map((Z)=>({id:Z.id,sessionId:Z.session_id,type:Z.type,title:Z.title,tokenCount:Z.token_count,discoveryTokens:Z.discovery_tokens??0,createdAt:Z.created_at,importance:Z.importance??3}))}search(J){let X=!!J.projectPath,Z=`
108
110
  SELECT o.*, rank
109
111
  FROM observations o
110
112
  JOIN observations_fts fts ON o._rowid = fts.rowid
113
+ ${X?"JOIN sessions s ON o.session_id = s.id":""}
111
114
  WHERE observations_fts MATCH ?
112
- `,Z=[J.query];if(J.sessionId)X+=" AND o.session_id = ?",Z.push(J.sessionId);if(J.type)X+=" AND o.type = ?",Z.push(J.type);return X+=" ORDER BY rank LIMIT ? OFFSET ?",Z.push(J.limit??10),Z.push(J.offset??0),this.db.all(X,Z).map(($)=>({observation:this.mapRow($),rank:$.rank,snippet:$.title}))}searchByConcept(J,X=10){return this.db.all(`SELECT o.*
115
+ `,$=[J.query];if(X&&J.projectPath)Z+=" AND s.project_path = ?",$.push(J.projectPath);if(J.sessionId)Z+=" AND o.session_id = ?",$.push(J.sessionId);if(J.type)Z+=" AND o.type = ?",$.push(J.type);return Z+=" ORDER BY rank LIMIT ? OFFSET ?",$.push(J.limit??10),$.push(J.offset??0),this.db.all(Z,$).map((Q)=>({observation:this.mapRow(Q),rank:Q.rank,snippet:Q.title}))}searchByConcept(J,X=10,Z){let $=!!Z,Q=`SELECT o.*
113
116
  FROM observations o
114
117
  JOIN observations_fts fts ON o._rowid = fts.rowid
118
+ ${$?"JOIN sessions s ON o.session_id = s.id":""}
115
119
  WHERE observations_fts MATCH ?
120
+ ${$?"AND s.project_path = ?":""}
116
121
  ORDER BY rank
117
- LIMIT ?`,[`concepts:${J}`,X]).map((Z)=>this.mapRow(Z))}searchByFile(J,X=10){return this.db.all(`SELECT o.*
122
+ LIMIT ?`,Y=[`concepts:${J}`];if($&&Z)Y.push(Z);return Y.push(X),this.db.all(Q,Y).map((W)=>this.mapRow(W))}searchByFile(J,X=10,Z){let $=!!Z,Q=`SELECT o.*
118
123
  FROM observations o
119
124
  JOIN observations_fts fts ON o._rowid = fts.rowid
125
+ ${$?"JOIN sessions s ON o.session_id = s.id":""}
120
126
  WHERE observations_fts MATCH ?
127
+ ${$?"AND s.project_path = ?":""}
121
128
  ORDER BY rank
122
- LIMIT ?`,[`files_read:"${J.replace(/"/g,'""')}" OR files_modified:"${J.replace(/"/g,'""')}"`,X]).map((Z)=>this.mapRow(Z))}setEmbedding(J,X){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(X),J])}getWithEmbeddings(J,X){return this.db.all(`SELECT o.id, o.embedding, o.title
129
+ LIMIT ?`,Y=[`files_read:"${J.replace(/"/g,'""')}" OR files_modified:"${J.replace(/"/g,'""')}"`];if($&&Z)Y.push(Z);return Y.push(X),this.db.all(Q,Y).map((W)=>this.mapRow(W))}setEmbedding(J,X){this.db.run("UPDATE observations SET embedding = ? WHERE id = ?",[JSON.stringify(X),J])}getWithEmbeddings(J,X){return this.db.all(`SELECT o.id, o.embedding, o.title
123
130
  FROM observations o
124
131
  JOIN sessions s ON o.session_id = s.id
125
132
  WHERE s.project_path = ? AND o.embedding IS NOT NULL
126
133
  ORDER BY o.created_at DESC
127
- LIMIT ?`,[J,X]).map((Z)=>{try{return{id:Z.id,embedding:JSON.parse(Z.embedding),title:Z.title}}catch{return null}}).filter((Z)=>Z!==null)}insertVecEmbedding(J,X){let Z=new Float32Array(X);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[J]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[J,Z]),this.db.run("COMMIT")}catch($){throw this.db.run("ROLLBACK"),$}}migrateExistingEmbeddings(J){let X=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),Z=0,$=0;for(let Q of X)try{let H=JSON.parse(Q.embedding);if(!Array.isArray(H)||H.length!==J){$++;continue}this.insertVecEmbedding(Q.id,H),Z++}catch{$++}return{migrated:Z,skipped:$}}getVecEmbeddingMatches(J,X){try{let Z=new Float32Array(J);return this.db.all(`SELECT observation_id, distance
134
+ LIMIT ?`,[J,X]).map((Z)=>{try{return{id:Z.id,embedding:JSON.parse(Z.embedding),title:Z.title}}catch{return null}}).filter((Z)=>Z!==null)}findSimilar(J,X,Z,$){let Q=this.db.all(`SELECT id, embedding FROM observations
135
+ WHERE embedding IS NOT NULL AND type = ?
136
+ ORDER BY created_at DESC
137
+ LIMIT 200`,[X]),Y=[];for(let W of Q)try{let H=JSON.parse(W.embedding);if(!Array.isArray(H)||H.length!==J.length)continue;let V=e(J,H);if(V>=Z)Y.push({id:W.id,similarity:V})}catch{}return Y.sort((W,H)=>H.similarity-W.similarity).slice(0,$)}insertVecEmbedding(J,X){let Z=new Float32Array(X);this.db.run("BEGIN");try{this.db.run("DELETE FROM observation_embeddings WHERE observation_id = ?",[J]),this.db.run("INSERT INTO observation_embeddings (observation_id, embedding) VALUES (?, ?)",[J,Z]),this.db.run("COMMIT")}catch($){throw this.db.run("ROLLBACK"),$}}migrateExistingEmbeddings(J){let X=this.db.all("SELECT id, embedding FROM observations WHERE embedding IS NOT NULL"),Z=0,$=0;for(let Q of X)try{let Y=JSON.parse(Q.embedding);if(!Array.isArray(Y)||Y.length!==J){$++;continue}this.insertVecEmbedding(Q.id,Y),Z++}catch{$++}return{migrated:Z,skipped:$}}getVecEmbeddingMatches(J,X){try{let Z=new Float32Array(J);return this.db.all(`SELECT observation_id, distance
128
138
  FROM observation_embeddings
129
- WHERE embedding MATCH ? AND k = ?`,[Z,X]).map(($)=>({observationId:$.observation_id,distance:$.distance}))}catch{return[]}}searchVecSubset(J,X,Z){if(X.length===0)return[];try{let $=new Float32Array(J),Q=Math.max(Z*5,X.length),H=this.db.all(`SELECT observation_id, distance
139
+ WHERE embedding MATCH ? AND k = ?`,[Z,X]).map(($)=>({observationId:$.observation_id,distance:$.distance}))}catch{return[]}}searchVecSubset(J,X,Z){if(X.length===0)return[];try{let $=new Float32Array(J),Q=Math.max(Z*5,X.length),Y=this.db.all(`SELECT observation_id, distance
130
140
  FROM observation_embeddings
131
- WHERE embedding MATCH ? AND k = ?`,[$,Q]),V=new Set(X);return H.filter((Y)=>V.has(Y.observation_id)).slice(0,Z).map((Y)=>({observationId:Y.observation_id,distance:Y.distance}))}catch{return[]}}mapRow(J){return{id:J.id,sessionId:J.session_id,type:J.type,title:J.title,subtitle:J.subtitle,facts:JSON.parse(J.facts),narrative:J.narrative,concepts:JSON.parse(J.concepts),filesRead:JSON.parse(J.files_read),filesModified:JSON.parse(J.files_modified),rawToolOutput:J.raw_tool_output,toolName:J.tool_name,createdAt:J.created_at,tokenCount:J.token_count,discoveryTokens:J.discovery_tokens??0}}}import{randomUUID as j0}from"crypto";class O{db;constructor(J){this.db=J}create(J){let X=j0(),Z=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
141
+ WHERE embedding MATCH ? AND k = ?`,[$,Q]),W=new Set(X);return Y.filter((H)=>W.has(H.observation_id)).slice(0,Z).map((H)=>({observationId:H.observation_id,distance:H.distance}))}catch{return[]}}update(J,X){let Z=this.getById(J);if(!Z)return null;let $=[],Q=[];if(X.title!==void 0)$.push("title = ?"),Q.push(X.title);if(X.narrative!==void 0)$.push("narrative = ?"),Q.push(X.narrative);if(X.type!==void 0)$.push("type = ?"),Q.push(X.type);if(X.concepts!==void 0)$.push("concepts = ?"),Q.push(JSON.stringify(X.concepts));if(X.importance!==void 0)$.push("importance = ?"),Q.push(X.importance);if($.length===0)return Z;return Q.push(J),this.db.run(`UPDATE observations SET ${$.join(", ")} WHERE id = ?`,Q),this.getById(J)}delete(J){if(this.db.all("DELETE FROM observations WHERE id = ? RETURNING id",[J]).length===0)return!1;return this.deleteEmbeddingsForObservations([J]),!0}deleteOlderThan(J){return this.db.all(`DELETE FROM observations
142
+ WHERE created_at < datetime('now', '-' || ? || ' days')
143
+ AND session_id NOT IN (SELECT id FROM sessions WHERE status != 'completed')
144
+ RETURNING id`,[J]).length}deleteEmbeddingsForObservations(J){if(J.length===0)return;let X=J.map(()=>"?").join(",");try{this.db.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${X})`,J)}catch{}this.db.run(`UPDATE observations SET embedding = NULL WHERE id IN (${X})`,J)}mapRow(J){return{id:J.id,sessionId:J.session_id,type:J.type,title:J.title,subtitle:J.subtitle,facts:JSON.parse(J.facts),narrative:J.narrative,concepts:JSON.parse(J.concepts),filesRead:JSON.parse(J.files_read),filesModified:JSON.parse(J.files_modified),rawToolOutput:J.raw_tool_output,toolName:J.tool_name,createdAt:J.created_at,tokenCount:J.token_count,discoveryTokens:J.discovery_tokens??0,importance:J.importance??3}}}import{randomUUID as q0}from"crypto";class q{db;constructor(J){this.db=J}create(J){let X=q0(),Z=new Date().toISOString();return this.db.run(`INSERT INTO pending_messages
132
145
  (id, session_id, tool_name, tool_output, call_id, created_at)
133
146
  VALUES (?, ?, ?, ?, ?, ?)`,[X,J.sessionId,J.toolName,J.toolOutput,J.callId,Z]),{...J,id:X,createdAt:Z,status:"pending",retryCount:0,error:null}}getPending(J=10){return this.db.all("SELECT * FROM pending_messages WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?",[J]).map((X)=>this.mapRow(X))}getByStatus(J){return this.db.all("SELECT * FROM pending_messages WHERE status = ? ORDER BY created_at ASC",[J]).map((X)=>this.mapRow(X))}markProcessing(J){this.db.run("UPDATE pending_messages SET status = 'processing' WHERE id = ?",[J])}markCompleted(J){this.db.run("UPDATE pending_messages SET status = 'completed' WHERE id = ?",[J])}markFailed(J,X){this.db.run("UPDATE pending_messages SET status = 'failed', error = ?, retry_count = retry_count + 1 WHERE id = ?",[X,J])}resetStale(J=5){return this.db.all(`UPDATE pending_messages SET status = 'pending'
134
147
  WHERE status = 'processing'
135
148
  AND created_at < datetime('now', ? || ' minutes')
136
- RETURNING id`,[`-${J}`]).length}mapRow(J){return{id:J.id,sessionId:J.session_id,toolName:J.tool_name,toolOutput:J.tool_output,callId:J.call_id,createdAt:J.created_at,status:J.status,retryCount:J.retry_count,error:J.error??null}}}var S0=[{version:1,name:"create-core-tables",up:`
149
+ RETURNING id`,[`-${J}`]).length}deleteCompletedOlderThan(J){return this.db.all(`DELETE FROM pending_messages
150
+ WHERE status = 'completed'
151
+ AND created_at < datetime('now', '-' || ? || ' days')
152
+ RETURNING id`,[J]).length}mapRow(J){return{id:J.id,sessionId:J.session_id,toolName:J.tool_name,toolOutput:J.tool_output,callId:J.call_id,createdAt:J.created_at,status:J.status,retryCount:J.retry_count,error:J.error??null}}}var k0=[{version:1,name:"create-core-tables",up:`
137
153
  -- Sessions table
138
154
  CREATE TABLE IF NOT EXISTS sessions (
139
155
  _rowid INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -311,11 +327,13 @@ Respond with EXACTLY this XML format:
311
327
  key TEXT PRIMARY KEY,
312
328
  value TEXT NOT NULL
313
329
  );
314
- `}];function s(J,X){if(J.migrate(S0),X?.hasVectorExtension&&X?.embeddingDimension&&X.embeddingDimension>0)q0(J,X.embeddingDimension)}function q0(J,X){if(J.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let $=J.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if($&&Number($.value)!==X){console.warn(`[open-mem] vec0 table exists with dimension ${$.value}, but config specifies ${X}. Drop observation_embeddings to re-create with new dimension.`);return}}else J.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
330
+ `},{version:7,name:"add-importance-column",up:`
331
+ ALTER TABLE observations ADD COLUMN importance INTEGER NOT NULL DEFAULT 3;
332
+ `}];function a(J,X){if(J.migrate(k0),X?.hasVectorExtension&&X?.embeddingDimension&&X.embeddingDimension>0)T0(J,X.embeddingDimension)}function T0(J,X){if(J.get("SELECT name FROM sqlite_master WHERE type='table' AND name='observation_embeddings'")){let $=J.get("SELECT value FROM _embedding_meta WHERE key = 'dimension'");if($&&Number($.value)!==X){console.warn(`[open-mem] vec0 table exists with dimension ${$.value}, but config specifies ${X}. Drop observation_embeddings to re-create with new dimension.`);return}}else J.exec(`CREATE VIRTUAL TABLE observation_embeddings USING vec0(
315
333
  observation_id TEXT PRIMARY KEY,
316
334
  embedding float[${X}] distance_metric=cosine
317
- )`);J.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(X)])}class D{db;constructor(J){this.db=J}create(J,X){let Z=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
318
- VALUES (?, ?, ?, 'active')`,[J,X,Z]),this.getById(J)}getOrCreate(J,X){let Z=this.getById(J);if(Z)return Z;return this.create(J,X)}getById(J){let X=this.db.get("SELECT * FROM sessions WHERE id = ?",[J]);return X?this.mapRow(X):null}getRecent(J,X=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[J,X]).map((Z)=>this.mapRow(Z))}getAll(J){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[J]).map((X)=>this.mapRow(X))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((J)=>this.mapRow(J))}updateStatus(J,X){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[X,J])}markCompleted(J){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[J])}incrementObservationCount(J){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[J])}setSummary(J,X){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[X,J])}mapRow(J){return{id:J.id,projectPath:J.project_path,startedAt:J.started_at,endedAt:J.ended_at??null,status:J.status,observationCount:J.observation_count,summaryId:J.summary_id??null}}}import{randomUUID as O0}from"crypto";class R{db;constructor(J){this.db=J}create(J){let X=O0(),Z=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
335
+ )`);J.run("INSERT OR REPLACE INTO _embedding_meta (key, value) VALUES (?, ?)",["dimension",String(X)])}class k{db;constructor(J){this.db=J}create(J,X){let Z=new Date().toISOString();return this.db.run(`INSERT INTO sessions (id, project_path, started_at, status)
336
+ VALUES (?, ?, ?, 'active')`,[J,X,Z]),this.getById(J)}getOrCreate(J,X){let Z=this.getById(J);if(Z)return Z;return this.create(J,X)}getById(J){let X=this.db.get("SELECT * FROM sessions WHERE id = ?",[J]);return X?this.mapRow(X):null}getRecent(J,X=10){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC LIMIT ?",[J,X]).map((Z)=>this.mapRow(Z))}getAll(J){return this.db.all("SELECT * FROM sessions WHERE project_path = ? ORDER BY started_at DESC",[J]).map((X)=>this.mapRow(X))}getActive(){return this.db.all("SELECT * FROM sessions WHERE status = 'active' ORDER BY started_at DESC").map((J)=>this.mapRow(J))}updateStatus(J,X){this.db.run("UPDATE sessions SET status = ? WHERE id = ?",[X,J])}markCompleted(J){this.db.run("UPDATE sessions SET status = 'completed', ended_at = datetime('now') WHERE id = ?",[J])}incrementObservationCount(J){this.db.run("UPDATE sessions SET observation_count = observation_count + 1 WHERE id = ?",[J])}setSummary(J,X){this.db.run("UPDATE sessions SET summary_id = ? WHERE id = ?",[X,J])}mapRow(J){return{id:J.id,projectPath:J.project_path,startedAt:J.started_at,endedAt:J.ended_at??null,status:J.status,observationCount:J.observation_count,summaryId:J.summary_id??null}}}import{randomUUID as x0}from"crypto";class T{db;constructor(J){this.db=J}create(J){let X=x0(),Z=new Date().toISOString();return this.db.run(`INSERT INTO session_summaries
319
337
  (id, session_id, summary, key_decisions, files_modified,
320
338
  concepts, created_at, token_count,
321
339
  request, investigated, learned, completed, next_steps)
@@ -328,5 +346,4 @@ Respond with EXACTLY this XML format:
328
346
  JOIN summaries_fts fts ON ss._rowid = fts.rowid
329
347
  WHERE summaries_fts MATCH ?
330
348
  ORDER BY rank
331
- LIMIT ?`,[J,X]).map((Z)=>this.mapRow(Z))}mapRow(J){return{id:J.id,sessionId:J.session_id,summary:J.summary,keyDecisions:JSON.parse(J.key_decisions),filesModified:JSON.parse(J.files_modified),concepts:JSON.parse(J.concepts),createdAt:J.created_at,tokenCount:J.token_count,request:J.request||void 0,investigated:J.investigated||void 0,learned:J.learned||void 0,completed:J.completed||void 0,nextSteps:J.next_steps||void 0}}}import{embed as D0}from"ai";async function r(J,X){try{let{embedding:Z}=await D0({model:J,value:X});return Z}catch{return null}}function a(J){let X=[J.title,J.narrative];if(J.concepts.length>0)X.push(J.concepts.join(", "));return X.join(`
332
- `)}class k{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(J,X,Z,$,Q,H,V,Y=null){this.config=J;this.compressor=X;this.summarizer=Z;this.pendingRepo=$;this.observationRepo=Q;this.sessionRepo=H;this.summaryRepo=V;this.embeddingModel=Y}setMode(J){if(this.mode=J,J==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(J){this.onEnqueue=J}enqueue(J,X,Z,$){if(this.pendingRepo.create({sessionId:J,toolName:X,toolOutput:Z,callId:$}),this.mode==="enqueue-only")this.onEnqueue?.()}async processBatch(){if(this.mode==="enqueue-only")return 0;if(this.processing)return 0;this.processing=!0;let J=0;try{this.pendingRepo.resetStale(5);let X=this.pendingRepo.getPending(this.config.batchSize);if(X.length===0)return 0;for(let Z of X)try{this.pendingRepo.markProcessing(Z.id);let Q=await this.compressor.compress(Z.toolName,Z.toolOutput)??this.compressor.createFallbackObservation(Z.toolName,Z.toolOutput),H=this.observationRepo.create({sessionId:Z.sessionId,type:Q.type,title:Q.title,subtitle:Q.subtitle,facts:Q.facts,narrative:Q.narrative,concepts:Q.concepts,filesRead:Q.filesRead,filesModified:Q.filesModified,rawToolOutput:Z.toolOutput,toolName:Z.toolName,tokenCount:F(`${Q.title} ${Q.narrative} ${Q.facts.join(" ")}`),discoveryTokens:Q.discoveryTokens??F(Z.toolOutput)});if(this.embeddingModel)try{let V=a({title:H.title,narrative:H.narrative,concepts:H.concepts}),Y=await r(this.embeddingModel,V);if(Y)this.observationRepo.setEmbedding(H.id,Y)}catch{}this.sessionRepo.incrementObservationCount(Z.sessionId),this.pendingRepo.markCompleted(Z.id),J++}catch($){this.pendingRepo.markFailed(Z.id,String($))}return J}finally{this.processing=!1}}async summarizeSession(J){let X=this.observationRepo.getBySession(J);if(!this.summarizer.shouldSummarize(X.length))return;if(this.summaryRepo.getBySessionId(J))return;let $=await this.summarizer.summarize(J,X);if(!$)return;let Q=this.summaryRepo.create({sessionId:J,summary:$.summary,keyDecisions:$.keyDecisions,filesModified:$.filesModified,concepts:$.concepts,tokenCount:F($.summary)});this.sessionRepo.setSummary(J,Q.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}import{spawnSync as t}from"child_process";import{dirname as R0,resolve as e}from"path";function k0(J){try{let X=t("git",["rev-parse","--git-common-dir"],{cwd:J,encoding:"utf-8",timeout:5000});if(X.status!==0||!X.stdout)return null;let Z=X.stdout.trim();if(Z===".git")return null;let $=t("git",["rev-parse","--git-dir"],{cwd:J,encoding:"utf-8",timeout:5000});if($.status!==0||!$.stdout)return null;let Q=$.stdout.trim(),H=e(J,Z),V=e(J,Q);if(H===V)return null;let Y=R0(H);if(Y===H||Y==="/")return null;return Y}catch{return null}}function o(J){return k0(J)??J}var x0=5000,{values:T}=T0({options:{project:{type:"string",short:"p"},"poll-interval":{type:"string"}},strict:!1}),Z0=typeof T.project==="string"?T.project:null;if(!Z0)console.error("Usage: open-mem-daemon --project <path> [--poll-interval <ms>]"),process.exit(1);var J0=T["poll-interval"],x=typeof J0==="string"?Number.parseInt(J0,10):x0;if(Number.isNaN(x)||x<100)console.error("--poll-interval must be a number >= 100"),process.exit(1);var P0=o(Z0),B=g(P0);E.enableExtensionSupport();var L=i(B.dbPath);s(L,{hasVectorExtension:L.hasVectorExtension,embeddingDimension:B.embeddingDimension});var y0=new O(L),I0=new q(L),h0=new D(L),f0=new R(L),v0=new _(B),w0=new C(B),u0=B.provider!=="bedrock",b0=B.compressionEnabled&&(!u0||B.apiKey)?w({provider:B.provider,model:B.model,apiKey:B.apiKey}):null,g0=new k(B,v0,w0,y0,I0,h0,f0,b0),$0=m(B.dbPath);p($0);var P=new j({queueProcessor:g0,pollIntervalMs:x});if(process.send)process.on("message",(J)=>{P.handleMessage(J)});var X0=!1,y=()=>{if(X0)return;X0=!0,P.stop(),l($0),L.close()};process.on("SIGTERM",()=>{y(),process.exit(0)});process.on("SIGINT",()=>{y(),process.exit(0)});process.on("beforeExit",y);P.start();
349
+ LIMIT ?`,[J,X]).map((Z)=>this.mapRow(Z))}mapRow(J){return{id:J.id,sessionId:J.session_id,summary:J.summary,keyDecisions:JSON.parse(J.key_decisions),filesModified:JSON.parse(J.files_modified),concepts:JSON.parse(J.concepts),createdAt:J.created_at,tokenCount:J.token_count,request:J.request||void 0,investigated:J.investigated||void 0,learned:J.learned||void 0,completed:J.completed||void 0,nextSteps:J.next_steps||void 0}}}class x{config;compressor;summarizer;pendingRepo;observationRepo;sessionRepo;summaryRepo;embeddingModel;processing=!1;timer=null;mode="in-process";onEnqueue=null;constructor(J,X,Z,$,Q,Y,W,H=null){this.config=J;this.compressor=X;this.summarizer=Z;this.pendingRepo=$;this.observationRepo=Q;this.sessionRepo=Y;this.summaryRepo=W;this.embeddingModel=H}setMode(J){if(this.mode=J,J==="enqueue-only")this.stop()}getMode(){return this.mode}setOnEnqueue(J){this.onEnqueue=J}enqueue(J,X,Z,$){if(this.pendingRepo.create({sessionId:J,toolName:X,toolOutput:Z,callId:$}),this.mode==="enqueue-only")this.onEnqueue?.()}async processBatch(){if(this.mode==="enqueue-only")return 0;if(this.processing)return 0;this.processing=!0;let J=0;try{this.pendingRepo.resetStale(5);let X=this.pendingRepo.getPending(this.config.batchSize);if(X.length===0)return 0;for(let Z of X)try{this.pendingRepo.markProcessing(Z.id);let Q=await this.compressor.compress(Z.toolName,Z.toolOutput)??this.compressor.createFallbackObservation(Z.toolName,Z.toolOutput);if(this.embeddingModel)try{let W=R({title:Q.title,narrative:Q.narrative,concepts:Q.concepts}),H=await D(this.embeddingModel,W);if(H){let V=this.observationRepo.findSimilar(H,Q.type,0.92,1);if(V.length>0){console.log(`[open-mem] Dedup: skipping duplicate of ${V[0].id} (similarity: ${V[0].similarity.toFixed(3)})`),this.pendingRepo.markCompleted(Z.id);continue}}}catch{}let Y=this.observationRepo.create({sessionId:Z.sessionId,type:Q.type,title:Q.title,subtitle:Q.subtitle,facts:Q.facts,narrative:Q.narrative,concepts:Q.concepts,filesRead:Q.filesRead,filesModified:Q.filesModified,rawToolOutput:Z.toolOutput,toolName:Z.toolName,tokenCount:F(`${Q.title} ${Q.narrative} ${Q.facts.join(" ")}`),discoveryTokens:Q.discoveryTokens??F(Z.toolOutput),importance:Q.importance??3});if(this.embeddingModel)try{let W=R({title:Y.title,narrative:Y.narrative,concepts:Y.concepts}),H=await D(this.embeddingModel,W);if(H)this.observationRepo.setEmbedding(Y.id,H)}catch{}this.sessionRepo.incrementObservationCount(Z.sessionId),this.pendingRepo.markCompleted(Z.id),J++}catch($){this.pendingRepo.markFailed(Z.id,String($))}return J}finally{this.processing=!1}}async summarizeSession(J){let X=this.observationRepo.getBySession(J);if(!this.summarizer.shouldSummarize(X.length))return;if(this.summaryRepo.getBySessionId(J))return;let $=await this.summarizer.summarize(J,X);if(!$)return;let Q=this.summaryRepo.create({sessionId:J,summary:$.summary,keyDecisions:$.keyDecisions,filesModified:$.filesModified,concepts:$.concepts,tokenCount:F($.summary)});this.sessionRepo.setSummary(J,Q.id)}start(){if(this.mode==="enqueue-only")return;if(this.timer)return;this.timer=setInterval(async()=>{try{await this.processBatch()}catch{}},this.config.batchIntervalMs)}stop(){if(this.timer)clearInterval(this.timer),this.timer=null}get isRunning(){return this.timer!==null}get isProcessing(){return this.processing}getStats(){return{pending:this.pendingRepo.getPending(1000).length,processing:this.processing}}}import{spawnSync as o}from"child_process";import{dirname as I0,resolve as J0}from"path";function y0(J){try{let X=o("git",["rev-parse","--git-common-dir"],{cwd:J,encoding:"utf-8",timeout:5000});if(X.status!==0||!X.stdout)return null;let Z=X.stdout.trim();if(Z===".git")return null;let $=o("git",["rev-parse","--git-dir"],{cwd:J,encoding:"utf-8",timeout:5000});if($.status!==0||!$.stdout)return null;let Q=$.stdout.trim(),Y=J0(J,Z),W=J0(J,Q);if(Y===W)return null;let H=I0(Y);if(H===Y||H==="/")return null;return H}catch{return null}}function X0(J){return y0(J)??J}var h0=5000,{values:I}=P0({options:{project:{type:"string",short:"p"},"poll-interval":{type:"string"}},strict:!1}),Q0=typeof I.project==="string"?I.project:null;if(!Q0)console.error("Usage: open-mem-daemon --project <path> [--poll-interval <ms>]"),process.exit(1);var Z0=I["poll-interval"],y=typeof Z0==="string"?Number.parseInt(Z0,10):h0;if(Number.isNaN(y)||y<100)console.error("--poll-interval must be a number >= 100"),process.exit(1);var f0=X0(Q0),B=m(f0);A.enableExtensionSupport();var L=t(B.dbPath);a(L,{hasVectorExtension:L.hasVectorExtension,embeddingDimension:B.embeddingDimension});var v0=new q(L),w0=new j(L),u0=new k(L),b0=new T(L),g0=new _(B),l0=new C(B),p0=B.provider!=="bedrock",m0=B.compressionEnabled&&(!p0||B.apiKey)?g({provider:B.provider,model:B.model,apiKey:B.apiKey}):null,c0=new x(B,g0,l0,v0,w0,u0,b0,m0),Y0=d(B.dbPath);c(Y0);var P=new S({queueProcessor:c0,pollIntervalMs:y});if(process.send)process.on("message",(J)=>{P.handleMessage(J)});var $0=!1,h=()=>{if($0)return;$0=!0,P.stop(),n(Y0),L.close()};process.on("SIGTERM",()=>{h(),process.exit(0)});process.on("SIGINT",()=>{h(),process.exit(0)});process.on("beforeExit",h);P.start();
@@ -1,4 +1,4 @@
1
- import type { Observation, ObservationIndex, SearchQuery, SearchResult } from "../types";
1
+ import type { Observation, ObservationIndex, ObservationType, SearchQuery, SearchResult } from "../types";
2
2
  import type { Database } from "./database";
3
3
  export declare class ObservationRepository {
4
4
  private db;
@@ -11,14 +11,18 @@ export declare class ObservationRepository {
11
11
  /** Lightweight index for progressive disclosure */
12
12
  getIndex(projectPath: string, limit?: number): ObservationIndex[];
13
13
  search(query: SearchQuery): SearchResult[];
14
- searchByConcept(concept: string, limit?: number): Observation[];
15
- searchByFile(filePath: string, limit?: number): Observation[];
14
+ searchByConcept(concept: string, limit?: number, projectPath?: string): Observation[];
15
+ searchByFile(filePath: string, limit?: number, projectPath?: string): Observation[];
16
16
  setEmbedding(id: string, embedding: number[]): void;
17
17
  getWithEmbeddings(projectPath: string, limit: number): Array<{
18
18
  id: string;
19
19
  embedding: number[];
20
20
  title: string;
21
21
  }>;
22
+ findSimilar(embedding: number[], type: ObservationType, threshold: number, limit: number): Array<{
23
+ id: string;
24
+ similarity: number;
25
+ }>;
22
26
  insertVecEmbedding(observationId: string, embedding: number[]): void;
23
27
  migrateExistingEmbeddings(dimension: number): {
24
28
  migrated: number;
@@ -32,6 +36,10 @@ export declare class ObservationRepository {
32
36
  observationId: string;
33
37
  distance: number;
34
38
  }>;
39
+ update(id: string, data: Partial<Pick<Observation, "title" | "narrative" | "type" | "concepts" | "importance">>): Observation | null;
40
+ delete(id: string): boolean;
41
+ deleteOlderThan(days: number): number;
42
+ deleteEmbeddingsForObservations(ids: string[]): void;
35
43
  private mapRow;
36
44
  }
37
45
  //# sourceMappingURL=observations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/db/observations.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACX,WAAW,EACX,gBAAgB,EAEhB,WAAW,EACX,YAAY,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA6C3C,qBAAa,qBAAqB;IACrB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAMhC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,WAAW;IA+BhE,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA+B1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAKvC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAS9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAYpC,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,gBAAgB,EAAE;IA0B7D,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,EAAE;IA6B1C,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE;IAc3D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,WAAW,EAAE;IAqBzD,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAOnD,iBAAiB,CAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA6B5D,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAgBpE,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IA6BnF,sBAAsB,CACrB,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmBrD,eAAe,CACd,cAAc,EAAE,MAAM,EAAE,EACxB,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BrD,OAAO,CAAC,MAAM;CAmBd"}
1
+ {"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../../src/db/observations.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACX,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA+C3C,qBAAa,qBAAqB;IACrB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAMhC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,WAAW;IAiChE,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAgC1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAKvC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAS9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAYpC,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,gBAAgB,EAAE;IA2B7D,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,EAAE;IAmC1C,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE;IAkBjF,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE;IAwB/E,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAOnD,iBAAiB,CAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA6B5D,WAAW,CACV,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IA8B5C,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAgBpE,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IA6BnF,sBAAsB,CACrB,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmBrD,eAAe,CACd,cAAc,EAAE,MAAM,EAAE,EACxB,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BrD,MAAM,CACL,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAC,CAAC,GAC1F,WAAW,GAAG,IAAI;IAmCrB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAe3B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAWrC,+BAA+B,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI;IAmBpD,OAAO,CAAC,MAAM;CAoBd"}
@@ -15,6 +15,7 @@ export declare class PendingMessageRepository {
15
15
  * Returns the number of messages reset.
16
16
  */
17
17
  resetStale(olderThanMinutes?: number): number;
18
+ deleteCompletedOlderThan(days: number): number;
18
19
  private mapRow;
19
20
  }
20
21
  //# sourceMappingURL=pending.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pending.d.ts","sourceRoot":"","sources":["../../src/db/pending.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C,qBAAa,wBAAwB;IACxB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAMhC,MAAM,CACL,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,GAChF,cAAc;IAuBjB,UAAU,CAAC,KAAK,SAAK,GAAG,cAAc,EAAE;IASxC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,cAAc,EAAE;IAa/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI/B,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO3C;;;;OAIG;IACH,UAAU,CAAC,gBAAgB,SAAI,GAAG,MAAM;IAexC,OAAO,CAAC,MAAM;CAad"}
1
+ {"version":3,"file":"pending.d.ts","sourceRoot":"","sources":["../../src/db/pending.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C,qBAAa,wBAAwB;IACxB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAMhC,MAAM,CACL,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,GAChF,cAAc;IAuBjB,UAAU,CAAC,KAAK,SAAK,GAAG,cAAc,EAAE;IASxC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,cAAc,EAAE;IAa/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI/B,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO3C;;;;OAIG;IACH,UAAU,CAAC,gBAAgB,SAAI,GAAG,MAAM;IAWxC,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe9C,OAAO,CAAC,MAAM;CAad"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMtD,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAMX,eAAO,MAAM,UAAU,EAAE,SAAS,EA4NjC,CAAC;AAMF,iEAAiE;AACjE,wBAAgB,gBAAgB,CAC/B,EAAE,EAAE,QAAQ,EACZ,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE,IAAI,CASN;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CA0BzE"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMtD,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAMX,eAAO,MAAM,UAAU,EAAE,SAAS,EAqOjC,CAAC;AAMF,iEAAiE;AACjE,wBAAgB,gBAAgB,CAC/B,EAAE,EAAE,QAAQ,EACZ,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GACrE,IAAI,CASN;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CA0BzE"}
@@ -8,7 +8,7 @@ import type { SessionRepository } from "../db/sessions";
8
8
  *
9
9
  * The handler NEVER throws — errors are caught and logged.
10
10
  */
11
- export declare function createChatCaptureHook(observations: ObservationRepository, sessions: SessionRepository, projectPath: string): (input: {
11
+ export declare function createChatCaptureHook(observations: ObservationRepository, sessions: SessionRepository, projectPath: string, sensitivePatterns?: string[]): (input: {
12
12
  sessionID: string;
13
13
  agent?: string;
14
14
  model?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/chat-capture.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA4CxD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,YAAY,EAAE,qBAAqB,EACnC,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,IAGlB,OAAO;IACN,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,QAAQ;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,KAC5C,OAAO,CAAC,IAAI,CAAC,CAwChB"}
1
+ {"version":3,"file":"chat-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/chat-capture.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA6CxD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,YAAY,EAAE,qBAAqB,EACnC,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,EACnB,iBAAiB,GAAE,MAAM,EAAO,IAG/B,OAAO;IACN,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,QAAQ;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,KAC5C,OAAO,CAAC,IAAI,CAAC,CA8ChB"}
@@ -1,4 +1,5 @@
1
1
  import type { ObservationRepository } from "../db/observations";
2
+ import type { PendingMessageRepository } from "../db/pending";
2
3
  import type { SessionRepository } from "../db/sessions";
3
4
  import type { QueueProcessor } from "../queue/processor";
4
5
  import type { OpenCodeEvent, OpenMemConfig } from "../types";
@@ -13,7 +14,7 @@ import type { OpenCodeEvent, OpenMemConfig } from "../types";
13
14
  *
14
15
  * The handler NEVER throws.
15
16
  */
16
- export declare function createEventHandler(queue: QueueProcessor, sessions: SessionRepository, projectPath: string, config: OpenMemConfig, observations: ObservationRepository): (input: {
17
+ export declare function createEventHandler(queue: QueueProcessor, sessions: SessionRepository, projectPath: string, config: OpenMemConfig, observations: ObservationRepository, pendingMessages: PendingMessageRepository): (input: {
17
18
  event: OpenCodeEvent;
18
19
  }) => Promise<void>;
19
20
  //# sourceMappingURL=session-events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../src/hooks/session-events.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG7D;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,qBAAqB,IAErB,OAAO;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAyC7D"}
1
+ {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../src/hooks/session-events.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI7D;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,qBAAqB,EACnC,eAAe,EAAE,wBAAwB,IAE3B,OAAO;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,KAAG,OAAO,CAAC,IAAI,CAAC,CAoD7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/tool-capture.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,IAGlB,OAAO;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC1D,QAAQ;IACP,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,KACC,OAAO,CAAC,IAAI,CAAC,CAkChB"}
1
+ {"version":3,"file":"tool-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/tool-capture.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,IAGlB,OAAO;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC1D,QAAQ;IACP,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,KACC,OAAO,CAAC,IAAI,CAAC,CAyBhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA2ClD,wBAA8B,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CA4LvE;AAMD,YAAY,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,cAAc,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA2ClD,wBAA8B,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CA6MvE;AAMD,YAAY,EACX,aAAa,EACb,WAAW,EACX,OAAO,EACP,cAAc,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC"}