@ephemushroom/opencode-claude-mem 0.5.0 → 0.6.1

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.
@@ -0,0 +1,12 @@
1
+ export interface InjectionOptions {
2
+ readonly enabled: boolean;
3
+ readonly limit: number;
4
+ readonly maxChars: number;
5
+ readonly timeoutMs: number;
6
+ }
7
+ export interface MemoryOptions {
8
+ readonly semanticInjection: InjectionOptions;
9
+ readonly fileContext: InjectionOptions;
10
+ }
11
+ export declare function parseMemoryOptions(options: unknown, env: Readonly<Record<string, string | undefined>>, settings: unknown): MemoryOptions;
12
+ export declare function resolveMemoryOptions(options: unknown): MemoryOptions;
@@ -0,0 +1,22 @@
1
+ import type { MemoryOptions } from './memory-options';
2
+ import type { MemoryTurn } from './memory-turn';
3
+ import { MemoryWorker } from './memory-worker';
4
+ export declare class MemorySessions {
5
+ private readonly sessions;
6
+ private readonly deleted;
7
+ private readonly options;
8
+ private readonly worker;
9
+ constructor(options: MemoryOptions, worker?: typeof MemoryWorker);
10
+ private state;
11
+ select(session: string, turn: MemoryTurn): boolean;
12
+ hasTurn(session: string): boolean;
13
+ hasMessage(session: string, id: string): boolean;
14
+ isDeleted(session: string): boolean;
15
+ canCapture(session: string): boolean;
16
+ register(session: string, project: string): Promise<boolean>;
17
+ semantic(session: string, project: string): Promise<string>;
18
+ context(session: string, project: string): Promise<string | null>;
19
+ invalidate(session: string): void;
20
+ delete(session: string): void;
21
+ clear(): void;
22
+ }
@@ -0,0 +1,10 @@
1
+ export interface MemoryTurn {
2
+ readonly id: string;
3
+ readonly text: string;
4
+ readonly capture: boolean;
5
+ readonly semantic: boolean;
6
+ }
7
+ export declare function memoryTurn(id: string, text: string, media?: boolean): MemoryTurn;
8
+ /** Only consumed session context, never the admission/inbox list. */
9
+ export declare function deliveredTurn(messages: readonly unknown[]): MemoryTurn | undefined;
10
+ export declare function resumedV1Turn(messages: unknown): MemoryTurn | undefined;
@@ -0,0 +1,21 @@
1
+ import type { InjectionOptions } from './memory-options';
2
+ import { z } from 'zod';
3
+ declare const fileResponse: z.ZodObject<{
4
+ observations: z.ZodArray<z.ZodObject<{
5
+ id: z.ZodNumber;
6
+ title: z.ZodNullable<z.ZodString>;
7
+ type: z.ZodString;
8
+ created_at_epoch: z.ZodNumber;
9
+ memory_session_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
10
+ }, z.core.$strip>>;
11
+ count: z.ZodNumber;
12
+ }, z.core.$strip>;
13
+ export type FileObservation = z.infer<typeof fileResponse>['observations'][number];
14
+ export declare class MemoryWorker {
15
+ private static readonly baseUrl;
16
+ private static json;
17
+ static save(input: unknown, project: string): Promise<string>;
18
+ static semantic(prompt: string, project: string, options: InjectionOptions): Promise<string>;
19
+ static byFile(paths: readonly string[], project: string, options: InjectionOptions): Promise<readonly FileObservation[]>;
20
+ }
21
+ export {};
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  id: string;
3
3
  tui: (api: any) => Promise<void>;
4
- setup: (context: import("@opencode-ai/plugin-v2/tui/context").Context) => Promise<import("@opencode-ai/plugin-v2/tui/plugin").Cleanup | void> | import("@opencode-ai/plugin-v2/tui/plugin").Cleanup | void;
4
+ setup: (context: import("@opencode/plugin/tui/context").Context) => Promise<import("@opencode/plugin/tui/plugin").Cleanup | void> | import("@opencode/plugin/tui/plugin").Cleanup | void;
5
5
  };
6
6
  export default _default;
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // src/package-tui.ts
3
- import v1 from "./tui";
4
- import v2 from "./cli";
3
+ import v1 from "./tui.js";
4
+ import v2 from "./cli.js";
5
5
  var package_tui_default = { id: v2.id, tui: v1.tui, setup: v2.setup };
6
6
  export {
7
7
  package_tui_default as default
package/dist/tui.js CHANGED
@@ -4,6 +4,46 @@ import { existsSync, readFileSync } from "fs";
4
4
  import { homedir } from "os";
5
5
  import { join } from "path";
6
6
  import { spawn } from "child_process";
7
+
8
+ // src/shared.ts
9
+ var MAX_OBSERVATION_BYTES = 24 * 1024;
10
+ var META_TOOLS = new Set([
11
+ "askuserquestion",
12
+ "getmcpresource",
13
+ "listmcpresourcestool",
14
+ "listmcptools",
15
+ "mem-get-observations",
16
+ "mem-search",
17
+ "mem-timeline",
18
+ "skill",
19
+ "slashcommand",
20
+ "todowrite"
21
+ ]);
22
+ function stripTaggedContent(text) {
23
+ let result = "";
24
+ let offset = 0;
25
+ const stack = [];
26
+ for (const match of text.matchAll(/<(\/?)(private|claude-mem-context)\b[^>]*>/gi)) {
27
+ if (stack.length === 0) {
28
+ result += text.slice(offset, match.index);
29
+ }
30
+ const name = match[2].toLowerCase();
31
+ if (match[1] === "/") {
32
+ if (stack.at(-1) === name) {
33
+ stack.pop();
34
+ }
35
+ } else {
36
+ stack.push(name);
37
+ }
38
+ offset = match.index + match[0].length;
39
+ }
40
+ if (stack.length === 0) {
41
+ result += text.slice(offset);
42
+ }
43
+ return result.trim();
44
+ }
45
+
46
+ // src/worker-client.ts
7
47
  var HEALTH_TIMEOUT_MS = 1000;
8
48
  var WRITE_TIMEOUT_MS = 1e4;
9
49
  var AUTOSTART_POLL_INTERVAL_MS = 500;
@@ -199,7 +239,16 @@ class WorkerClient {
199
239
  if (!response.ok) {
200
240
  return null;
201
241
  }
202
- return await response.json();
242
+ const value = await response.json();
243
+ if (!isRecord(value) || typeof value.sessionDbId !== "number" || typeof value.promptNumber !== "number" || !Number.isFinite(value.sessionDbId) || !Number.isFinite(value.promptNumber)) {
244
+ return null;
245
+ }
246
+ return {
247
+ sessionDbId: value.sessionDbId,
248
+ promptNumber: value.promptNumber,
249
+ skipped: value.skipped === true,
250
+ reason: typeof value.reason === "string" ? value.reason : undefined
251
+ };
203
252
  } catch {
204
253
  return null;
205
254
  }
@@ -233,8 +282,8 @@ class WorkerClient {
233
282
  headers: { "Content-Type": "application/json" },
234
283
  body: JSON.stringify({
235
284
  contentSessionId,
236
- last_user_message: lastUserMessage,
237
- last_assistant_message: lastAssistantMessage,
285
+ last_user_message: stripTaggedContent(lastUserMessage),
286
+ last_assistant_message: stripTaggedContent(lastAssistantMessage),
238
287
  platformSource: PLATFORM_SOURCE,
239
288
  observedModel: metadata.observedModel,
240
289
  observedBilling: metadata.observedBilling
@@ -247,7 +296,7 @@ class WorkerClient {
247
296
  }
248
297
  static async getContext(project) {
249
298
  try {
250
- const response = await fetch(`${this.BASE_URL}/api/context/inject?project=${encodeURIComponent(project)}`);
299
+ const response = await fetch(`${this.BASE_URL}/api/context/inject?project=${encodeURIComponent(project)}`, { signal: AbortSignal.timeout(2000) });
251
300
  if (!response.ok) {
252
301
  return null;
253
302
  }