@haisto/opencode-mem 2.14.3-beta.0 → 2.14.3-beta.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.
@@ -15,6 +15,7 @@ export interface UserProfileWorkflow {
15
15
  description: string;
16
16
  steps: string[];
17
17
  frequency: number;
18
+ lastSeen: number;
18
19
  }
19
20
  export interface UserProfileData {
20
21
  preferences: UserProfilePreference[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACrC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,mBAAmB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACrC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,SAAS,EAAE,mBAAmB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"user-profile-manager.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/user-profile-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASrF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAQhC,OAAO,CAAC,YAAY;IA0CpB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAapD,aAAa,CACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,eAAe,EAAE,MAAM,GACtB,MAAM;IAoCT,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,yBAAyB,EAAE,MAAM,EACjC,aAAa,EAAE,MAAM,GACpB,IAAI;IAmCP,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,oBAAoB;IAiB5B,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,oBAAoB,EAAE;IAYnF,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAqE7C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAOrD,oBAAoB,IAAI,WAAW,EAAE;IAMrC,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,cAAc;IAYtB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe;IA6F/F,OAAO,CAAC,WAAW;CAWpB;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
1
+ {"version":3,"file":"user-profile-manager.d.ts","sourceRoot":"","sources":["../../../src/services/user-profile/user-profile-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASrF,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAQhC,OAAO,CAAC,YAAY;IA0CpB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAapD,aAAa,CACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,eAAe,EAAE,MAAM,GACtB,MAAM;IAoCT,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,eAAe,EAC5B,yBAAyB,EAAE,MAAM,EACjC,aAAa,EAAE,MAAM,GACpB,IAAI;IAmCP,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,oBAAoB;IAiB5B,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,oBAAoB,EAAE;IAYnF,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA+F7C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAOrD,oBAAoB,IAAI,WAAW,EAAE;IAMrC,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,cAAc;IAYtB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe;IAsG/F,OAAO,CAAC,WAAW;CAWpB;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
@@ -197,6 +197,30 @@ export class UserProfileManager {
197
197
  details: decayLogs,
198
198
  });
199
199
  }
200
+ // Decay patterns by lastSeen + frequency (integer counter)
201
+ profileData.patterns = profileData.patterns
202
+ .map((pattern) => {
203
+ const age = now - pattern.lastSeen;
204
+ if (age > decayThreshold) {
205
+ hasChanges = true;
206
+ const decayFactor = Math.max(0.5, 1 - (age - decayThreshold) / decayThreshold);
207
+ return { ...pattern, frequency: Math.floor(pattern.frequency * decayFactor) };
208
+ }
209
+ return pattern;
210
+ })
211
+ .filter((pattern) => pattern.frequency >= 1);
212
+ // Decay workflows by lastSeen + frequency (integer counter)
213
+ profileData.workflows = profileData.workflows
214
+ .map((workflow) => {
215
+ const age = now - workflow.lastSeen;
216
+ if (age > decayThreshold) {
217
+ hasChanges = true;
218
+ const decayFactor = Math.max(0.5, 1 - (age - decayThreshold) / decayThreshold);
219
+ return { ...workflow, frequency: Math.floor(workflow.frequency * decayFactor) };
220
+ }
221
+ return workflow;
222
+ })
223
+ .filter((workflow) => workflow.frequency >= 1);
200
224
  if (hasChanges) {
201
225
  this.updateProfile(profileId, profileData, 0, "Applied confidence decay to preferences");
202
226
  }
@@ -285,10 +309,13 @@ export class UserProfileManager {
285
309
  if (existingIndex >= 0) {
286
310
  const existingItem = merged.patterns[existingIndex];
287
311
  if (existingItem) {
312
+ const newFreq = (existingItem.frequency || 1) + 1;
288
313
  merged.patterns[existingIndex] = {
289
314
  ...newPattern,
290
- frequency: (existingItem.frequency || 1) + 1,
291
- lastSeen: Date.now(),
315
+ frequency: newFreq,
316
+ lastSeen: newFreq > (existingItem.frequency || 1) * 1.5
317
+ ? Date.now()
318
+ : existingItem.lastSeen,
292
319
  };
293
320
  }
294
321
  }
@@ -306,14 +333,18 @@ export class UserProfileManager {
306
333
  if (existingIndex >= 0) {
307
334
  const existingItem = merged.workflows[existingIndex];
308
335
  if (existingItem) {
336
+ const newFreq = (existingItem.frequency || 1) + 1;
309
337
  merged.workflows[existingIndex] = {
310
338
  ...newWorkflow,
311
- frequency: (existingItem.frequency || 1) + 1,
339
+ frequency: newFreq,
340
+ lastSeen: newFreq > (existingItem.frequency || 1) * 1.5
341
+ ? Date.now()
342
+ : existingItem.lastSeen,
312
343
  };
313
344
  }
314
345
  }
315
346
  else {
316
- merged.workflows.push({ ...newWorkflow, frequency: 1 });
347
+ merged.workflows.push({ ...newWorkflow, frequency: 1, lastSeen: Date.now() });
317
348
  }
318
349
  }
319
350
  merged.workflows.sort((a, b) => (b.frequency || 0) - (a.frequency || 0));
package/dist/web/app.js CHANGED
@@ -1003,6 +1003,12 @@ function renderUserProfile() {
1003
1003
  <div class="card-body">
1004
1004
  <p class="card-text">${escapeHtml(p.description || "")}</p>
1005
1005
  </div>
1006
+ <div class="card-footer">
1007
+ <span class="evidence-toggle">
1008
+ <i data-lucide="activity" class="icon-xs"></i> ${p.frequency || 1}
1009
+ </span>
1010
+ <span class="pattern-lastSeen">${formatDate(p.lastSeen)}</span>
1011
+ </div>
1006
1012
  </div>
1007
1013
  `
1008
1014
  )
@@ -1037,6 +1043,12 @@ function renderUserProfile() {
1037
1043
  )
1038
1044
  .join("")}
1039
1045
  </div>
1046
+ <div class="card-footer">
1047
+ <span class="evidence-toggle">
1048
+ <i data-lucide="repeat" class="icon-xs"></i> ${w.frequency || 1}
1049
+ </span>
1050
+ <span class="workflow-lastSeen">${formatDate(w.lastSeen)}</span>
1051
+ </div>
1040
1052
  </div>
1041
1053
  `
1042
1054
  )
@@ -1,5 +1,5 @@
1
1
  <!doctype html>
2
- <html lang="en" data-theme="dark">
2
+ <html data-theme="dark">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -1550,7 +1550,9 @@ textarea:focus-visible {
1550
1550
  align-items: center;
1551
1551
  }
1552
1552
 
1553
- .preference-updated {
1553
+ .preference-updated,
1554
+ .pattern-lastSeen,
1555
+ .workflow-lastSeen {
1554
1556
  font-size: 10px;
1555
1557
  color: var(--om-text-muted);
1556
1558
  }
@@ -1592,6 +1594,7 @@ textarea:focus-visible {
1592
1594
  flex-wrap: wrap;
1593
1595
  align-items: center;
1594
1596
  gap: 8px;
1597
+ margin-bottom: 6px;
1595
1598
  }
1596
1599
 
1597
1600
  .step-node {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haisto/opencode-mem",
3
- "version": "2.14.3-beta.0",
3
+ "version": "2.14.3-beta.1",
4
4
  "description": "OpenCode plugin that gives coding agents persistent memory using local vector database",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",