opencode-mem 2.3.6 → 2.4.0
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/dist/config.d.ts +0 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -80
- package/dist/services/ai/providers/anthropic-messages.d.ts.map +1 -1
- package/dist/services/ai/providers/anthropic-messages.js +11 -7
- package/dist/services/ai/providers/base-provider.d.ts +3 -3
- package/dist/services/ai/providers/base-provider.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-chat-completion.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-chat-completion.js +11 -6
- package/dist/services/ai/providers/openai-responses.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-responses.js +4 -2
- package/dist/services/ai/validators/user-profile-validator.d.ts +0 -1
- package/dist/services/ai/validators/user-profile-validator.d.ts.map +1 -1
- package/dist/services/ai/validators/user-profile-validator.js +0 -17
- package/dist/services/api-handlers.d.ts +32 -3
- package/dist/services/api-handlers.d.ts.map +1 -1
- package/dist/services/api-handlers.js +89 -13
- package/dist/services/auto-capture.js +11 -4
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +3 -1
- package/dist/services/sqlite/connection-manager.d.ts.map +1 -1
- package/dist/services/user-memory-learning.js +9 -14
- package/dist/services/user-profile/types.d.ts +0 -5
- package/dist/services/user-profile/types.d.ts.map +1 -1
- package/dist/services/user-profile/user-profile-manager.d.ts.map +1 -1
- package/dist/services/user-profile/user-profile-manager.js +0 -7
- package/dist/services/user-prompt/user-prompt-manager.d.ts +2 -0
- package/dist/services/user-prompt/user-prompt-manager.d.ts.map +1 -1
- package/dist/services/user-prompt/user-prompt-manager.js +21 -0
- package/dist/web/app.js +196 -114
- package/dist/web/styles.css +202 -122
- package/package.json +1 -1
package/dist/web/app.js
CHANGED
|
@@ -115,12 +115,14 @@ function renderMemories() {
|
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
container.innerHTML = state.memories
|
|
119
|
-
.map((
|
|
120
|
-
if (
|
|
121
|
-
return
|
|
118
|
+
container.innerHTML = groupMemories(state.memories)
|
|
119
|
+
.map((group) => {
|
|
120
|
+
if (group.isPair) {
|
|
121
|
+
return renderCombinedCard(group);
|
|
122
|
+
} else if (group.type === "prompt") {
|
|
123
|
+
return renderPromptCard(group.item);
|
|
122
124
|
} else {
|
|
123
|
-
return renderMemoryCard(item);
|
|
125
|
+
return renderMemoryCard(group.item);
|
|
124
126
|
}
|
|
125
127
|
})
|
|
126
128
|
.join("");
|
|
@@ -132,6 +134,82 @@ function renderMemories() {
|
|
|
132
134
|
lucide.createIcons();
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
function groupMemories(items) {
|
|
138
|
+
const map = new Map();
|
|
139
|
+
const pairs = [];
|
|
140
|
+
const processed = new Set();
|
|
141
|
+
|
|
142
|
+
items.forEach((item) => map.set(item.id, item));
|
|
143
|
+
|
|
144
|
+
items.forEach((item) => {
|
|
145
|
+
if (processed.has(item.id)) return;
|
|
146
|
+
|
|
147
|
+
if (item.type === "memory" && item.linkedPromptId && map.has(item.linkedPromptId)) {
|
|
148
|
+
const prompt = map.get(item.linkedPromptId);
|
|
149
|
+
pairs.push({ isPair: true, memory: item, prompt: prompt });
|
|
150
|
+
processed.add(item.id);
|
|
151
|
+
processed.add(prompt.id);
|
|
152
|
+
} else if (item.type === "prompt" && item.linkedMemoryId && map.has(item.linkedMemoryId)) {
|
|
153
|
+
const memory = map.get(item.linkedMemoryId);
|
|
154
|
+
pairs.push({ isPair: true, memory: memory, prompt: item });
|
|
155
|
+
processed.add(item.id);
|
|
156
|
+
processed.add(memory.id);
|
|
157
|
+
} else {
|
|
158
|
+
pairs.push({ isPair: false, type: item.type, item: item });
|
|
159
|
+
processed.add(item.id);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
return pairs.sort((a, b) => {
|
|
164
|
+
const timeA = a.isPair ? a.memory.createdAt : a.item.createdAt;
|
|
165
|
+
const timeB = b.isPair ? b.memory.createdAt : b.item.createdAt;
|
|
166
|
+
return new Date(timeB) - new Date(timeA);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function renderCombinedCard(pair) {
|
|
171
|
+
const { memory, prompt } = pair;
|
|
172
|
+
const isSelected = state.selectedMemories.has(memory.id);
|
|
173
|
+
const similarityHtml =
|
|
174
|
+
memory.similarity !== undefined
|
|
175
|
+
? `<span class="similarity-score">${Math.round(memory.similarity * 100)}%</span>`
|
|
176
|
+
: "";
|
|
177
|
+
|
|
178
|
+
return `
|
|
179
|
+
<div class="combined-card ${isSelected ? "selected" : ""}" data-id="${memory.id}">
|
|
180
|
+
<div class="combined-prompt-section">
|
|
181
|
+
<div class="combined-header">
|
|
182
|
+
<span class="badge badge-prompt">USER PROMPT</span>
|
|
183
|
+
<span class="prompt-date">${formatDate(prompt.createdAt)}</span>
|
|
184
|
+
</div>
|
|
185
|
+
<div class="prompt-content">${escapeHtml(prompt.content)}</div>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<div class="combined-divider">
|
|
189
|
+
<i data-lucide="arrow-down" class="divider-icon"></i>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div class="combined-memory-section">
|
|
193
|
+
<div class="memory-header">
|
|
194
|
+
<div class="meta">
|
|
195
|
+
<input type="checkbox" class="memory-checkbox" data-id="${memory.id}" ${isSelected ? "checked" : ""} />
|
|
196
|
+
<span class="badge badge-memory">MEMORY</span>
|
|
197
|
+
${memory.memoryType ? `<span class="badge badge-type">${memory.memoryType}</span>` : ""}
|
|
198
|
+
${similarityHtml}
|
|
199
|
+
<span class="memory-display-name">${escapeHtml(memory.displayName || memory.id)}</span>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="memory-actions">
|
|
202
|
+
<button class="btn-delete" onclick="deleteMemoryWithLink('${memory.id}', true)">
|
|
203
|
+
<i data-lucide="trash-2" class="icon"></i> Delete Pair
|
|
204
|
+
</button>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
<div class="memory-content markdown-content">${renderMarkdown(memory.content)}</div>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
|
|
135
213
|
function renderPromptCard(prompt) {
|
|
136
214
|
const isLinked = !!prompt.linkedMemoryId;
|
|
137
215
|
const isSelected = state.selectedMemories.has(prompt.id);
|
|
@@ -166,14 +244,17 @@ function renderMemoryCard(memory) {
|
|
|
166
244
|
const isSelected = state.selectedMemories.has(memory.id);
|
|
167
245
|
const isPinned = memory.isPinned || false;
|
|
168
246
|
const isLinked = !!memory.linkedPromptId;
|
|
169
|
-
const similarityHtml =
|
|
247
|
+
const similarityHtml =
|
|
170
248
|
memory.similarity !== undefined
|
|
171
249
|
? `<span class="similarity-score">${memory.similarity}%</span>`
|
|
172
250
|
: "";
|
|
173
251
|
|
|
174
252
|
let displayInfo = memory.displayName || memory.id;
|
|
175
253
|
if (memory.projectPath) {
|
|
176
|
-
const pathParts = memory.projectPath
|
|
254
|
+
const pathParts = memory.projectPath
|
|
255
|
+
.replace(/\\/g, "/")
|
|
256
|
+
.split("/")
|
|
257
|
+
.filter((p) => p);
|
|
177
258
|
displayInfo = pathParts[pathParts.length - 1] || memory.projectPath;
|
|
178
259
|
}
|
|
179
260
|
|
|
@@ -720,129 +801,130 @@ function renderUserProfile() {
|
|
|
720
801
|
const preferences = data.preferences || [];
|
|
721
802
|
const patterns = data.patterns || [];
|
|
722
803
|
const workflows = data.workflows || [];
|
|
723
|
-
const skillLevel = data.skillLevel || {};
|
|
724
804
|
|
|
725
805
|
container.innerHTML = `
|
|
726
806
|
<div class="profile-header">
|
|
727
807
|
<div class="profile-info">
|
|
728
808
|
<h3>${profile.displayName || profile.userId}</h3>
|
|
729
|
-
<
|
|
730
|
-
<
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
<
|
|
735
|
-
|
|
809
|
+
<div class="profile-stats">
|
|
810
|
+
<div class="stat-pill">
|
|
811
|
+
<span class="label">VERSION</span>
|
|
812
|
+
<span class="value">${profile.version}</span>
|
|
813
|
+
</div>
|
|
814
|
+
<div class="stat-pill">
|
|
815
|
+
<span class="label">PROMPTS</span>
|
|
816
|
+
<span class="value">${profile.totalPromptsAnalyzed}</span>
|
|
817
|
+
</div>
|
|
818
|
+
<div class="stat-pill">
|
|
819
|
+
<span class="label">LAST UPDATED</span>
|
|
820
|
+
<span class="value">${formatDate(profile.lastAnalyzedAt)}</span>
|
|
821
|
+
</div>
|
|
822
|
+
</div>
|
|
736
823
|
</div>
|
|
737
|
-
<button id="view-changelog-btn" class="btn-secondary">
|
|
738
|
-
<i data-lucide="history" class="icon"></i>
|
|
824
|
+
<button id="view-changelog-btn" class="btn-secondary compact">
|
|
825
|
+
<i data-lucide="history" class="icon"></i> History
|
|
739
826
|
</button>
|
|
740
827
|
</div>
|
|
741
828
|
|
|
742
|
-
<div class="
|
|
743
|
-
<
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
(
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
<
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
829
|
+
<div class="dashboard-grid">
|
|
830
|
+
<div class="dashboard-section preferences-section">
|
|
831
|
+
<h4><i data-lucide="heart" class="icon"></i> PREFERENCES <span class="count">${preferences.length}</span></h4>
|
|
832
|
+
${
|
|
833
|
+
preferences.length === 0
|
|
834
|
+
? '<p class="empty-text">No preferences learned yet</p>'
|
|
835
|
+
: `
|
|
836
|
+
<div class="cards-grid">
|
|
837
|
+
${preferences
|
|
838
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
839
|
+
.map(
|
|
840
|
+
(p) => `
|
|
841
|
+
<div class="compact-card preference-card">
|
|
842
|
+
<div class="card-top">
|
|
843
|
+
<span class="category-tag">${escapeHtml(p.category)}</span>
|
|
844
|
+
<div class="confidence-ring" style="--p:${Math.round(p.confidence * 100)}">
|
|
845
|
+
<span>${Math.round(p.confidence * 100)}%</span>
|
|
846
|
+
</div>
|
|
847
|
+
</div>
|
|
848
|
+
<div class="card-body">
|
|
849
|
+
<p class="card-text">${escapeHtml(p.description)}</p>
|
|
850
|
+
</div>
|
|
851
|
+
${
|
|
852
|
+
p.evidence && p.evidence.length > 0
|
|
853
|
+
? `
|
|
854
|
+
<div class="card-footer">
|
|
855
|
+
<span class="evidence-toggle" title="${escapeHtml(Array.isArray(p.evidence) ? p.evidence.join("\n") : p.evidence)}">
|
|
856
|
+
<i data-lucide="info" class="icon-xs"></i> ${Array.isArray(p.evidence) ? p.evidence.length : 1} evidence
|
|
857
|
+
</span>
|
|
858
|
+
</div>`
|
|
859
|
+
: ""
|
|
860
|
+
}
|
|
759
861
|
</div>
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
`
|
|
768
|
-
}
|
|
769
|
-
</div>
|
|
862
|
+
`
|
|
863
|
+
)
|
|
864
|
+
.join("")}
|
|
865
|
+
</div>
|
|
866
|
+
`
|
|
867
|
+
}
|
|
868
|
+
</div>
|
|
770
869
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
870
|
+
<div class="dashboard-section patterns-section">
|
|
871
|
+
<h4><i data-lucide="activity" class="icon"></i> PATTERNS <span class="count">${patterns.length}</span></h4>
|
|
872
|
+
${
|
|
873
|
+
patterns.length === 0
|
|
874
|
+
? '<p class="empty-text">No patterns detected yet</p>'
|
|
875
|
+
: `
|
|
876
|
+
<div class="cards-grid">
|
|
877
|
+
${patterns
|
|
878
|
+
.map(
|
|
879
|
+
(p) => `
|
|
880
|
+
<div class="compact-card pattern-card">
|
|
881
|
+
<div class="card-top">
|
|
882
|
+
<span class="category-tag">${escapeHtml(p.category)}</span>
|
|
883
|
+
</div>
|
|
884
|
+
<div class="card-body">
|
|
885
|
+
<p class="card-text">${escapeHtml(p.description)}</p>
|
|
886
|
+
</div>
|
|
785
887
|
</div>
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
</div>
|
|
888
|
+
`
|
|
889
|
+
)
|
|
890
|
+
.join("")}
|
|
891
|
+
</div>
|
|
892
|
+
`
|
|
893
|
+
}
|
|
894
|
+
</div>
|
|
794
895
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
<
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
896
|
+
<div class="dashboard-section workflows-section full-width">
|
|
897
|
+
<h4><i data-lucide="workflow" class="icon"></i> WORKFLOWS <span class="count">${workflows.length}</span></h4>
|
|
898
|
+
${
|
|
899
|
+
workflows.length === 0
|
|
900
|
+
? '<p class="empty-text">No workflows identified yet</p>'
|
|
901
|
+
: `
|
|
902
|
+
<div class="workflows-grid">
|
|
903
|
+
${workflows
|
|
904
|
+
.map(
|
|
905
|
+
(w) => `
|
|
906
|
+
<div class="workflow-row">
|
|
907
|
+
<div class="workflow-title">${escapeHtml(w.description)}</div>
|
|
908
|
+
<div class="workflow-steps-horizontal">
|
|
909
|
+
${w.steps
|
|
910
|
+
.map(
|
|
911
|
+
(step, i) => `
|
|
912
|
+
<div class="step-node">
|
|
913
|
+
<span class="step-idx">${i + 1}</span>
|
|
914
|
+
<span class="step-content">${escapeHtml(step)}</span>
|
|
915
|
+
</div>
|
|
916
|
+
${i < w.steps.length - 1 ? '<i data-lucide="arrow-right" class="step-arrow"></i>' : ""}
|
|
917
|
+
`
|
|
918
|
+
)
|
|
919
|
+
.join("")}
|
|
920
|
+
</div>
|
|
819
921
|
</div>
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
.join("")}
|
|
824
|
-
</div>
|
|
825
|
-
`
|
|
826
|
-
}
|
|
827
|
-
</div>
|
|
828
|
-
|
|
829
|
-
<div class="profile-section">
|
|
830
|
-
<h4><i data-lucide="award" class="icon"></i> Skill Level</h4>
|
|
831
|
-
<div class="skill-level">
|
|
832
|
-
<div class="skill-item">
|
|
833
|
-
<span class="skill-label">Overall</span>
|
|
834
|
-
<span class="skill-value">${escapeHtml(skillLevel.overall || "unknown")}</span>
|
|
835
|
-
</div>
|
|
836
|
-
${Object.entries(skillLevel.domains || {})
|
|
837
|
-
.map(
|
|
838
|
-
([domain, level]) => `
|
|
839
|
-
<div class="skill-item">
|
|
840
|
-
<span class="skill-label">${escapeHtml(domain)}</span>
|
|
841
|
-
<span class="skill-value">${escapeHtml(level)}</span>
|
|
922
|
+
`
|
|
923
|
+
)
|
|
924
|
+
.join("")}
|
|
842
925
|
</div>
|
|
843
926
|
`
|
|
844
|
-
|
|
845
|
-
.join("")}
|
|
927
|
+
}
|
|
846
928
|
</div>
|
|
847
929
|
</div>
|
|
848
930
|
`;
|