opencode-mem 2.3.7 → 2.5.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/README.md +15 -19
- package/dist/config.d.ts +4 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +33 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -82
- 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.d.ts.map +1 -1
- package/dist/services/auto-capture.js +34 -34
- package/dist/services/language-detector.d.ts +3 -0
- package/dist/services/language-detector.d.ts.map +1 -0
- package/dist/services/language-detector.js +16 -0
- package/dist/services/secret-resolver.d.ts +2 -0
- package/dist/services/secret-resolver.d.ts.map +1 -0
- package/dist/services/secret-resolver.js +55 -0
- package/dist/services/user-memory-learning.d.ts.map +1 -1
- package/dist/services/user-memory-learning.js +27 -33
- 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 +191 -112
- package/dist/web/styles.css +202 -122
- package/package.json +3 -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);
|
|
@@ -723,129 +801,130 @@ function renderUserProfile() {
|
|
|
723
801
|
const preferences = data.preferences || [];
|
|
724
802
|
const patterns = data.patterns || [];
|
|
725
803
|
const workflows = data.workflows || [];
|
|
726
|
-
const skillLevel = data.skillLevel || {};
|
|
727
804
|
|
|
728
805
|
container.innerHTML = `
|
|
729
806
|
<div class="profile-header">
|
|
730
807
|
<div class="profile-info">
|
|
731
808
|
<h3>${profile.displayName || profile.userId}</h3>
|
|
732
|
-
<
|
|
733
|
-
<
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
<
|
|
738
|
-
|
|
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>
|
|
739
823
|
</div>
|
|
740
|
-
<button id="view-changelog-btn" class="btn-secondary">
|
|
741
|
-
<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
|
|
742
826
|
</button>
|
|
743
827
|
</div>
|
|
744
828
|
|
|
745
|
-
<div class="
|
|
746
|
-
<
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
(
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
<
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
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
|
+
}
|
|
762
861
|
</div>
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
`
|
|
771
|
-
}
|
|
772
|
-
</div>
|
|
862
|
+
`
|
|
863
|
+
)
|
|
864
|
+
.join("")}
|
|
865
|
+
</div>
|
|
866
|
+
`
|
|
867
|
+
}
|
|
868
|
+
</div>
|
|
773
869
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
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>
|
|
788
887
|
</div>
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
</div>
|
|
888
|
+
`
|
|
889
|
+
)
|
|
890
|
+
.join("")}
|
|
891
|
+
</div>
|
|
892
|
+
`
|
|
893
|
+
}
|
|
894
|
+
</div>
|
|
797
895
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
<
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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>
|
|
822
921
|
</div>
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
.join("")}
|
|
827
|
-
</div>
|
|
828
|
-
`
|
|
829
|
-
}
|
|
830
|
-
</div>
|
|
831
|
-
|
|
832
|
-
<div class="profile-section">
|
|
833
|
-
<h4><i data-lucide="award" class="icon"></i> Skill Level</h4>
|
|
834
|
-
<div class="skill-level">
|
|
835
|
-
<div class="skill-item">
|
|
836
|
-
<span class="skill-label">Overall</span>
|
|
837
|
-
<span class="skill-value">${escapeHtml(skillLevel.overall || "unknown")}</span>
|
|
838
|
-
</div>
|
|
839
|
-
${Object.entries(skillLevel.domains || {})
|
|
840
|
-
.map(
|
|
841
|
-
([domain, level]) => `
|
|
842
|
-
<div class="skill-item">
|
|
843
|
-
<span class="skill-label">${escapeHtml(domain)}</span>
|
|
844
|
-
<span class="skill-value">${escapeHtml(level)}</span>
|
|
922
|
+
`
|
|
923
|
+
)
|
|
924
|
+
.join("")}
|
|
845
925
|
</div>
|
|
846
926
|
`
|
|
847
|
-
|
|
848
|
-
.join("")}
|
|
927
|
+
}
|
|
849
928
|
</div>
|
|
850
929
|
</div>
|
|
851
930
|
`;
|