opencode-supermemory 0.1.5 → 0.1.8

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.
package/README.md CHANGED
@@ -145,6 +145,8 @@ You: "Remember that this project uses bun"
145
145
  Agent: [saves to project memory]
146
146
  ```
147
147
 
148
+ Add custom triggers via `keywordPatterns` config.
149
+
148
150
  ### Codebase Indexing
149
151
 
150
152
  Run `/supermemory-init` to explore and memorize your codebase structure, patterns, and conventions.
@@ -214,7 +216,13 @@ Create `~/.config/opencode/supermemory.jsonc`:
214
216
  "injectProfile": true,
215
217
 
216
218
  // Prefix for container tags
217
- "containerTagPrefix": "opencode"
219
+ "containerTagPrefix": "opencode",
220
+
221
+ // Extra keyword patterns for memory detection (regex)
222
+ "keywordPatterns": ["log\\s+this", "write\\s+down"],
223
+
224
+ // Context usage ratio that triggers compaction (0-1)
225
+ "compactionThreshold": 0.80
218
226
  }
219
227
  ```
220
228
 
package/dist/cli.js CHANGED
@@ -74,7 +74,7 @@ function stripJsoncComments(content) {
74
74
  result += char;
75
75
  i++;
76
76
  }
77
- return result;
77
+ return result.replace(/,\s*([}\]])/g, "$1");
78
78
  }
79
79
 
80
80
  // src/cli.ts
package/dist/config.d.ts CHANGED
@@ -7,6 +7,8 @@ export declare const CONFIG: {
7
7
  injectProfile: boolean;
8
8
  containerTagPrefix: string;
9
9
  filterPrompt: string;
10
+ keywordPatterns: string[];
11
+ compactionThreshold: number;
10
12
  };
11
13
  export declare function isConfigured(): boolean;
12
14
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiDA,eAAO,MAAM,mBAAmB,oBAAuD,CAAC;AAExF,eAAO,MAAM,MAAM;;;;;;;;CAQlB,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAyFA,eAAO,MAAM,mBAAmB,oBAAuD,CAAC;AAExF,eAAO,MAAM,MAAM;;;;;;;;;;CAalB,CAAC;AAEF,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAuC/D,eAAO,MAAM,iBAAiB,EAAE,MAwa/B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAsC/D,eAAO,MAAM,iBAAiB,EAAE,MAsc/B,CAAC"}
package/dist/index.js CHANGED
@@ -13674,7 +13674,7 @@ function stripJsoncComments(content) {
13674
13674
  result += char;
13675
13675
  i++;
13676
13676
  }
13677
- return result;
13677
+ return result.replace(/,\s*([}\]])/g, "$1");
13678
13678
  }
13679
13679
 
13680
13680
  // src/config.ts
@@ -13683,6 +13683,24 @@ var CONFIG_FILES = [
13683
13683
  join(CONFIG_DIR, "supermemory.jsonc"),
13684
13684
  join(CONFIG_DIR, "supermemory.json")
13685
13685
  ];
13686
+ var DEFAULT_KEYWORD_PATTERNS = [
13687
+ "remember",
13688
+ "memorize",
13689
+ "save\\s+this",
13690
+ "note\\s+this",
13691
+ "keep\\s+in\\s+mind",
13692
+ "don'?t\\s+forget",
13693
+ "learn\\s+this",
13694
+ "store\\s+this",
13695
+ "record\\s+this",
13696
+ "make\\s+a\\s+note",
13697
+ "take\\s+note",
13698
+ "jot\\s+down",
13699
+ "commit\\s+to\\s+memory",
13700
+ "remember\\s+that",
13701
+ "never\\s+forget",
13702
+ "always\\s+remember"
13703
+ ];
13686
13704
  var DEFAULTS = {
13687
13705
  similarityThreshold: 0.6,
13688
13706
  maxMemories: 5,
@@ -13690,8 +13708,26 @@ var DEFAULTS = {
13690
13708
  maxProfileItems: 5,
13691
13709
  injectProfile: true,
13692
13710
  containerTagPrefix: "opencode",
13693
- filterPrompt: "You are a stateful coding agent. Remember all the information, including but not limited to user's coding preferences, tech stack, behaviours, workflows, and any other relevant details."
13711
+ filterPrompt: "You are a stateful coding agent. Remember all the information, including but not limited to user's coding preferences, tech stack, behaviours, workflows, and any other relevant details.",
13712
+ keywordPatterns: [],
13713
+ compactionThreshold: 0.8
13694
13714
  };
13715
+ function isValidRegex(pattern) {
13716
+ try {
13717
+ new RegExp(pattern);
13718
+ return true;
13719
+ } catch {
13720
+ return false;
13721
+ }
13722
+ }
13723
+ function validateCompactionThreshold(value) {
13724
+ if (value === undefined || typeof value !== "number" || isNaN(value)) {
13725
+ return DEFAULTS.compactionThreshold;
13726
+ }
13727
+ if (value <= 0 || value > 1)
13728
+ return DEFAULTS.compactionThreshold;
13729
+ return value;
13730
+ }
13695
13731
  function loadConfig() {
13696
13732
  for (const path2 of CONFIG_FILES) {
13697
13733
  if (existsSync(path2)) {
@@ -13713,7 +13749,12 @@ var CONFIG = {
13713
13749
  maxProfileItems: fileConfig.maxProfileItems ?? DEFAULTS.maxProfileItems,
13714
13750
  injectProfile: fileConfig.injectProfile ?? DEFAULTS.injectProfile,
13715
13751
  containerTagPrefix: fileConfig.containerTagPrefix ?? DEFAULTS.containerTagPrefix,
13716
- filterPrompt: fileConfig.filterPrompt ?? DEFAULTS.filterPrompt
13752
+ filterPrompt: fileConfig.filterPrompt ?? DEFAULTS.filterPrompt,
13753
+ keywordPatterns: [
13754
+ ...DEFAULT_KEYWORD_PATTERNS,
13755
+ ...(fileConfig.keywordPatterns ?? []).filter(isValidRegex)
13756
+ ],
13757
+ compactionThreshold: validateCompactionThreshold(fileConfig.compactionThreshold)
13717
13758
  };
13718
13759
  function isConfigured() {
13719
13760
  return !!SUPERMEMORY_API_KEY;
@@ -13968,8 +14009,7 @@ var PART_STORAGE = join3(homedir3(), ".opencode", "parts");
13968
14009
  var DEFAULT_THRESHOLD = 0.8;
13969
14010
  var MIN_TOKENS_FOR_COMPACTION = 50000;
13970
14011
  var COMPACTION_COOLDOWN_MS = 30000;
13971
- var CLAUDE_DEFAULT_CONTEXT_LIMIT = 200000;
13972
- var CLAUDE_MODEL_PATTERN = /claude-(opus|sonnet|haiku)/i;
14012
+ var DEFAULT_CONTEXT_LIMIT = 200000;
13973
14013
  function createCompactionPrompt(projectMemories) {
13974
14014
  const memoriesSection = projectMemories.length > 0 ? `
13975
14015
  ## Project Knowledge (from Supermemory)
@@ -14009,9 +14049,6 @@ ${memoriesSection}
14009
14049
  This context is critical for maintaining continuity after compaction.
14010
14050
  `;
14011
14051
  }
14012
- function isSupportedModel(modelID) {
14013
- return CLAUDE_MODEL_PATTERN.test(modelID);
14014
- }
14015
14052
  function getMessageDir(sessionID) {
14016
14053
  if (!existsSync2(MESSAGE_STORAGE))
14017
14054
  return null;
@@ -14187,12 +14224,8 @@ ${summaryContent}`, tags.project, { type: "conversation" });
14187
14224
  modelID = storedMessage.model.modelID;
14188
14225
  }
14189
14226
  agent = storedMessage?.agent;
14190
- if (!isSupportedModel(modelID)) {
14191
- log("[compaction] skipping unsupported model", { modelID });
14192
- return;
14193
- }
14194
14227
  const configLimit = getModelLimit?.(providerID, modelID);
14195
- const contextLimit = configLimit ?? CLAUDE_DEFAULT_CONTEXT_LIMIT;
14228
+ const contextLimit = configLimit ?? DEFAULT_CONTEXT_LIMIT;
14196
14229
  const totalUsed = tokens.input + tokens.cache.read + tokens.output;
14197
14230
  if (totalUsed < MIN_TOKENS_FOR_COMPACTION)
14198
14231
  return;
@@ -14359,7 +14392,7 @@ ${summaryContent}`, tags.project, { type: "conversation" });
14359
14392
  // src/index.ts
14360
14393
  var CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
14361
14394
  var INLINE_CODE_PATTERN = /`[^`]+`/g;
14362
- var MEMORY_KEYWORD_PATTERN = /\b(remember|memorize|save\s+this|note\s+this|keep\s+in\s+mind|don'?t\s+forget|learn\s+this|store\s+this|record\s+this|make\s+a\s+note|take\s+note|jot\s+down|commit\s+to\s+memory|remember\s+that|never\s+forget|always\s+remember)\b/i;
14395
+ var MEMORY_KEYWORD_PATTERN = new RegExp(`\\b(${CONFIG.keywordPatterns.join("|")})\\b`, "i");
14363
14396
  var MEMORY_NUDGE_MESSAGE = `[MEMORY TRIGGER DETECTED]
14364
14397
  The user wants you to remember something. You MUST use the \`supermemory\` tool with \`mode: "add"\` to save this information.
14365
14398
 
@@ -14384,7 +14417,33 @@ var SupermemoryPlugin = async (ctx) => {
14384
14417
  if (!isConfigured()) {
14385
14418
  log("Plugin disabled - SUPERMEMORY_API_KEY not set");
14386
14419
  }
14387
- const compactionHook = isConfigured() && ctx.client ? createCompactionHook(ctx, tags) : null;
14420
+ const modelLimits = new Map;
14421
+ (async () => {
14422
+ try {
14423
+ const response = await ctx.client.provider.list();
14424
+ if (response.data?.all) {
14425
+ for (const provider of response.data.all) {
14426
+ if (provider.models) {
14427
+ for (const [modelId, model] of Object.entries(provider.models)) {
14428
+ if (model.limit?.context) {
14429
+ modelLimits.set(`${provider.id}/${modelId}`, model.limit.context);
14430
+ }
14431
+ }
14432
+ }
14433
+ }
14434
+ }
14435
+ log("Model limits loaded", { count: modelLimits.size });
14436
+ } catch (error45) {
14437
+ log("Failed to fetch model limits", { error: String(error45) });
14438
+ }
14439
+ })();
14440
+ const getModelLimit = (providerID, modelID) => {
14441
+ return modelLimits.get(`${providerID}/${modelID}`);
14442
+ };
14443
+ const compactionHook = isConfigured() && ctx.client ? createCompactionHook(ctx, tags, {
14444
+ threshold: CONFIG.compactionThreshold,
14445
+ getModelLimit
14446
+ }) : null;
14388
14447
  return {
14389
14448
  "chat.message": async (input, output) => {
14390
14449
  if (!isConfigured())
@@ -1 +1 @@
1
- {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/services/compaction.ts"],"names":[],"mappings":"AAsBA,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAgBD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7E;AAuLD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QACN,OAAO,EAAE;YACP,SAAS,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,IAAI,EAAE;oBAAE,UAAU,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/I,QAAQ,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC;gBAAE,IAAI,CAAC,EAAE,KAAK,CAAC;oBAAE,IAAI,EAAE,WAAW,CAAA;iBAAE,CAAC,CAAA;aAAE,CAAC,CAAC;YAC/H,WAAW,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,IAAI,EAAE;oBAAE,KAAK,CAAC,EAAE,MAAM,CAAC;oBAAC,KAAK,EAAE,KAAK,CAAC;wBAAE,IAAI,EAAE,MAAM,CAAC;wBAAC,IAAI,EAAE,MAAM,CAAA;qBAAE,CAAC,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SAC3K,CAAC;QACF,GAAG,EAAE;YACH,SAAS,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,KAAK,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAC;oBAAC,QAAQ,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SAC1H,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACvC,OAAO,CAAC,EAAE,iBAAiB;qBAqOF;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;EAgE3E"}
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/services/compaction.ts"],"names":[],"mappings":"AAqBA,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAgBD,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7E;AAmLD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QACN,OAAO,EAAE;YACP,SAAS,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,IAAI,EAAE;oBAAE,UAAU,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/I,QAAQ,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC;gBAAE,IAAI,CAAC,EAAE,KAAK,CAAC;oBAAE,IAAI,EAAE,WAAW,CAAA;iBAAE,CAAC,CAAA;aAAE,CAAC,CAAC;YAC/H,WAAW,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,IAAI,EAAE;oBAAE,KAAK,CAAC,EAAE,MAAM,CAAC;oBAAC,KAAK,EAAE,KAAK,CAAC;wBAAE,IAAI,EAAE,MAAM,CAAC;wBAAC,IAAI,EAAE,MAAM,CAAA;qBAAE,CAAC,CAAA;iBAAE,CAAC;gBAAC,KAAK,EAAE;oBAAE,SAAS,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SAC3K,CAAC;QACF,GAAG,EAAE;YACH,SAAS,EAAE,CAAC,MAAM,EAAE;gBAAE,IAAI,EAAE;oBAAE,KAAK,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAC;oBAAC,OAAO,EAAE,MAAM,CAAC;oBAAC,QAAQ,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;SAC1H,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACvC,OAAO,CAAC,EAAE,iBAAiB;qBAgOF;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE;EAgE3E"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Strips comments from JSONC content while respecting string boundaries.
3
3
  * Handles // and /* comments, URLs in strings, and escaped quotes.
4
+ * Also removes trailing commas to support more relaxed JSONC format.
4
5
  */
5
6
  export declare function stripJsoncComments(content: string): string;
6
7
  //# sourceMappingURL=jsonc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../../src/services/jsonc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA8E1D"}
1
+ {"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../../src/services/jsonc.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA+E1D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-supermemory",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "OpenCode plugin that gives coding agents persistent memory using Supermemory",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",