opencode-mem 2.11.4 → 2.11.7

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,265 @@
1
+ const translations = {
2
+ en: {
3
+ title: "┌─ OPENCODE MEMORY EXPLORER ─┐",
4
+ "tab-project": "PROJECT MEMORIES",
5
+ "tab-profile": "USER PROFILE",
6
+ "label-tag": "Tag:",
7
+ "label-type": "Type:",
8
+ "label-tags": "Tags:",
9
+ "label-content": "Content:",
10
+ "btn-cleanup": "Cleanup",
11
+ "btn-deduplicate": "Deduplicate",
12
+ "btn-delete-selected": "Delete Selected",
13
+ "btn-deselect-all": "Deselect All",
14
+ "btn-add-memory": "Add Memory",
15
+ "section-project": "└─ PROJECT MEMORIES ({count}) ──",
16
+ "section-profile": "└─ USER PROFILE ──",
17
+ "section-add": "└─ ADD NEW MEMORY ──",
18
+ "opt-all-tags": "All Tags",
19
+ "opt-select-tag": "Select tag",
20
+ "opt-other": "other",
21
+ "opt-feature": "feature",
22
+ "opt-bug-fix": "bug-fix",
23
+ "opt-refactor": "refactor",
24
+ "opt-architecture": "architecture",
25
+ "opt-rule": "rule",
26
+ "opt-documentation": "documentation",
27
+ "opt-discussion": "discussion",
28
+ "opt-analysis": "analysis",
29
+ "opt-configuration": "configuration",
30
+ "modal-edit-title": "Edit Memory",
31
+ "modal-migration-title": "Memory Tagging Migration",
32
+ "modal-changelog-title": "Profile Version History",
33
+ "btn-cancel": "Cancel",
34
+ "btn-save": "Save Changes",
35
+ "btn-start-migration": "Start Migration",
36
+ "loading-init": "Initializing...",
37
+ "loading-profile": "Loading profile...",
38
+ "loading-changelog": "Loading changelog...",
39
+ "migration-mismatch": "Model dimension mismatch detected!",
40
+ "migration-understand":
41
+ "I understand this operation is irreversible and will affect all stored memories",
42
+ "btn-fresh-start": "Fresh Start (Delete All)",
43
+ "btn-reembed": "Re-embed (Preserve Data)",
44
+ "migration-note":
45
+ "Please don't close the browser. This will re-vectorize your memories with technical tags to improve search accuracy.",
46
+ "placeholder-search": "Search memories...",
47
+ "placeholder-tags": "react, hooks, auth (comma separated)",
48
+ "placeholder-content": "Enter memory content...",
49
+ "toast-add-success": "Memory added successfully",
50
+ "toast-add-error": "Content and tag are required",
51
+ "toast-add-failed": "Failed to add memory",
52
+ "toast-delete-success": "Memory deleted successfully",
53
+ "toast-delete-failed": "Failed to delete memory",
54
+ "toast-update-success": "Memory updated successfully",
55
+ "toast-update-failed": "Failed to update memory",
56
+ "toast-cleanup-success": "Cleanup completed successfully",
57
+ "toast-cleanup-failed": "Cleanup failed",
58
+ "toast-dedup-success": "Deduplication completed successfully",
59
+ "toast-dedup-failed": "Deduplication failed",
60
+ "toast-bulk-delete-success": "Selected memories deleted successfully",
61
+ "toast-bulk-delete-failed": "Failed to delete selected memories",
62
+ "toast-migration-success": "Migration completed successfully",
63
+ "toast-migration-failed": "Migration failed",
64
+ "toast-fresh-start-success": "Fresh start completed successfully",
65
+ "toast-fresh-start-failed": "Fresh start failed",
66
+ "confirm-delete": "Delete this memory?",
67
+ "confirm-delete-pair": "Delete this memory AND its linked prompt?",
68
+ "confirm-delete-prompt": "Delete this prompt AND its linked memory?",
69
+ "confirm-bulk-delete": "Delete {count} selected memories?",
70
+ "confirm-cleanup": "This will remove all memories that are no longer relevant. Continue?",
71
+ "confirm-dedup": "This will merge duplicate or highly similar memories. Continue?",
72
+ "text-selected": "{count} selected",
73
+ "text-page": "Page {current} of {total}",
74
+ "text-total": "Total: {count}",
75
+ "empty-memories": "No memories found",
76
+ "empty-changelog": "No changelog available",
77
+ "status-cleanup": "Running cleanup...",
78
+ "status-dedup": "Running deduplication...",
79
+ "status-migration-init": "Initializing migration...",
80
+ "status-migration-progress": "Migrating... {current}/{total}",
81
+ "profile-version": "VERSION",
82
+ "profile-prompts": "PROMPTS",
83
+ "profile-updated": "LAST UPDATED",
84
+ "profile-preferences": "PREFERENCES",
85
+ "profile-patterns": "PATTERNS",
86
+ "profile-workflows": "WORKFLOWS",
87
+ "badge-prompt": "USER PROMPT",
88
+ "badge-memory": "MEMORY",
89
+ "badge-pinned": "PINNED",
90
+ "badge-linked": "LINKED",
91
+ "date-created": "Created:",
92
+ "date-updated": "Updated:",
93
+ "empty-preferences": "No preferences learned yet",
94
+ "empty-patterns": "No patterns detected yet",
95
+ "empty-workflows": "No workflows identified yet",
96
+ "btn-delete-pair": "Delete Pair",
97
+ "btn-delete": "Delete",
98
+ "text-generated-above": "Generated memory above",
99
+ "text-from-below": "From prompt below",
100
+ "btn-refresh": "Refresh",
101
+ "migration-found-tags": "Found {count} memories needing technical tags.",
102
+ "migration-stopped": "Migration stopped: maximum attempts reached",
103
+ "migration-shards-mismatch": "{count} shard(s) have different dimensions",
104
+ "migration-dimension-mismatch": "dimension mismatch detected",
105
+ "migration-mismatch-details":
106
+ "Model mismatch: Config uses {configDimensions}D ({configModel}), but {shardInfo}.",
107
+ },
108
+ zh: {
109
+ title: "┌─ OPENCODE MEMORY EXPLORER ─┐",
110
+ "tab-project": "项目记忆",
111
+ "tab-profile": "用户画像",
112
+ "label-tag": "标签:",
113
+ "label-type": "类型:",
114
+ "label-tags": "标签:",
115
+ "label-content": "内容:",
116
+ "btn-cleanup": "清理",
117
+ "btn-deduplicate": "去重",
118
+ "btn-delete-selected": "删除选中",
119
+ "btn-deselect-all": "取消全选",
120
+ "btn-add-memory": "添加记忆",
121
+ "section-project": "└─ 项目记忆 ({count}) ──",
122
+ "section-profile": "└─ 用户画像 ──",
123
+ "section-add": "└─ 添加新记忆 ──",
124
+ "opt-all-tags": "所有标签",
125
+ "opt-select-tag": "选择标签",
126
+ "opt-other": "其他 (other)",
127
+ "opt-feature": "功能 (feature)",
128
+ "opt-bug-fix": "修复 (bug-fix)",
129
+ "opt-refactor": "重构 (refactor)",
130
+ "opt-architecture": "架构 (architecture)",
131
+ "opt-rule": "规则 (rule)",
132
+ "opt-documentation": "文档 (documentation)",
133
+ "opt-discussion": "讨论 (discussion)",
134
+ "opt-analysis": "分析 (analysis)",
135
+ "opt-configuration": "配置 (configuration)",
136
+ "modal-edit-title": "编辑记忆",
137
+ "modal-migration-title": "记忆标签迁移",
138
+ "modal-changelog-title": "画像版本历史",
139
+ "btn-cancel": "取消",
140
+ "btn-save": "保存更改",
141
+ "btn-start-migration": "开始迁移",
142
+ "loading-init": "初始化中...",
143
+ "loading-profile": "加载画像中...",
144
+ "loading-changelog": "加载更新日志中...",
145
+ "migration-mismatch": "检测到模型维度不匹配!",
146
+ "migration-understand": "我了解此操作不可逆,并将影响所有存储的记忆",
147
+ "btn-fresh-start": "重新开始 (删除所有)",
148
+ "btn-reembed": "重新向量化 (保留数据)",
149
+ "migration-note": "请不要关闭浏览器。这将使用技术标签重新向量化您的记忆,以提高搜索准确性。",
150
+ "placeholder-search": "搜索记忆...",
151
+ "placeholder-tags": "react, hooks, auth (逗号分隔)",
152
+ "placeholder-content": "输入记忆内容...",
153
+ "toast-add-success": "记忆添加成功",
154
+ "toast-add-error": "内容和标签为必填项",
155
+ "toast-add-failed": "添加记忆失败",
156
+ "toast-delete-success": "记忆删除成功",
157
+ "toast-delete-failed": "删除记忆失败",
158
+ "toast-update-success": "记忆更新成功",
159
+ "toast-update-failed": "更新记忆失败",
160
+ "toast-cleanup-success": "清理完成",
161
+ "toast-cleanup-failed": "清理失败",
162
+ "toast-dedup-success": "去重完成",
163
+ "toast-dedup-failed": "去重失败",
164
+ "toast-bulk-delete-success": "选中的记忆删除成功",
165
+ "toast-bulk-delete-failed": "删除选中的记忆失败",
166
+ "toast-migration-success": "迁移完成",
167
+ "toast-migration-failed": "迁移失败",
168
+ "toast-fresh-start-success": "重新开始完成",
169
+ "toast-fresh-start-failed": "重新开始失败",
170
+ "confirm-delete": "删除这条记忆?",
171
+ "confirm-delete-pair": "删除这条记忆及其关联的提示词?",
172
+ "confirm-delete-prompt": "删除这条提示词及其关联的记忆?",
173
+ "confirm-bulk-delete": "删除选中的 {count} 条记忆?",
174
+ "confirm-cleanup": "这将删除所有不再相关的记忆。是否继续?",
175
+ "confirm-dedup": "这将合并重复或高度相似的记忆。是否继续?",
176
+ "text-selected": "已选择 {count} 条",
177
+ "text-page": "第 {current} 页,共 {total} 页",
178
+ "text-total": "总计: {count}",
179
+ "empty-memories": "未找到记忆",
180
+ "empty-changelog": "暂无更新日志",
181
+ "status-cleanup": "正在运行清理...",
182
+ "status-dedup": "正在运行去重...",
183
+ "status-migration-init": "正在初始化迁移...",
184
+ "status-migration-progress": "迁移中... {current}/{total}",
185
+ "profile-version": "版本",
186
+ "profile-prompts": "提示词数",
187
+ "profile-updated": "最后更新",
188
+ "profile-preferences": "偏好设置",
189
+ "profile-patterns": "行为模式",
190
+ "profile-workflows": "工作流程",
191
+ "badge-prompt": "用户提示词",
192
+ "badge-memory": "记忆",
193
+ "badge-pinned": "已置顶",
194
+ "badge-linked": "已关联",
195
+ "date-created": "创建于:",
196
+ "date-updated": "更新于:",
197
+ "empty-preferences": "尚未学习到偏好设置",
198
+ "empty-patterns": "尚未检测到行为模式",
199
+ "empty-workflows": "尚未识别出工作流程",
200
+ "btn-delete-pair": "删除组合",
201
+ "btn-delete": "删除",
202
+ "text-generated-above": "由上方记忆生成",
203
+ "text-from-below": "来自下方提示词",
204
+ "btn-refresh": "刷新",
205
+ "migration-found-tags": "发现 {count} 条需要技术标签的记忆。",
206
+ "migration-stopped": "迁移已停止:达到最大尝试次数",
207
+ "migration-shards-mismatch": "{count} 个分片具有不同的维度",
208
+ "migration-dimension-mismatch": "检测到维度不匹配",
209
+ "migration-mismatch-details":
210
+ "模型不匹配:配置使用 {configDimensions}D ({configModel}),但{shardInfo}。",
211
+ },
212
+ };
213
+
214
+ function getLanguage() {
215
+ return localStorage.getItem("opencode-mem-lang") || "en";
216
+ }
217
+
218
+ function setLanguage(lang) {
219
+ localStorage.setItem("opencode-mem-lang", lang);
220
+ applyLanguage();
221
+ }
222
+
223
+ function t(key, params = {}) {
224
+ const lang = getLanguage();
225
+ let text = translations[lang][key] || translations["en"][key] || key;
226
+
227
+ for (const [k, v] of Object.entries(params)) {
228
+ text = text.replace(new RegExp(`\\{${k}\\}`, "g"), v);
229
+ }
230
+
231
+ return text;
232
+ }
233
+
234
+ function applyLanguage() {
235
+ document.querySelectorAll("[data-i18n]").forEach((el) => {
236
+ const key = el.getAttribute("data-i18n");
237
+ const translated = t(key);
238
+
239
+ // If element has child nodes (like icons), we need to replace only the text nodes
240
+ if (el.children.length > 0) {
241
+ let textNodeFound = false;
242
+ for (const node of el.childNodes) {
243
+ if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "") {
244
+ node.textContent = " " + translated + " ";
245
+ textNodeFound = true;
246
+ }
247
+ }
248
+ if (!textNodeFound) {
249
+ el.appendChild(document.createTextNode(" " + translated));
250
+ }
251
+ } else {
252
+ el.textContent = translated;
253
+ }
254
+ });
255
+
256
+ document.querySelectorAll("[data-i18n-placeholder]").forEach((el) => {
257
+ const key = el.getAttribute("data-i18n-placeholder");
258
+ el.setAttribute("placeholder", t(key));
259
+ });
260
+ }
261
+
262
+ window.t = t;
263
+ window.getLanguage = getLanguage;
264
+ window.setLanguage = setLanguage;
265
+ window.applyLanguage = applyLanguage;
@@ -10,12 +10,14 @@
10
10
  <script src="https://cdn.jsdelivr.net/npm/marked@17.0.1/lib/marked.umd.min.js"></script>
11
11
  <script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.2/dist/purify.min.js"></script>
12
12
  <script src="https://cdn.jsdelivr.net/npm/jsonrepair@latest/lib/umd/jsonrepair.min.js"></script>
13
+ <script src="/i18n.js"></script>
13
14
  </head>
14
15
  <body>
15
16
  <div class="container">
16
17
  <header class="header">
17
18
  <div class="header-top">
18
- <h1 class="title">┌─ OPENCODE MEMORY EXPLORER ─┐</h1>
19
+ <h1 class="title" data-i18n="title">┌─ OPENCODE MEMORY EXPLORER ─┐</h1>
20
+ <button id="lang-toggle" class="lang-toggle" title="Switch Language">EN</button>
19
21
  <a
20
22
  href="https://github.com/tickernelz/opencode-mem"
21
23
  target="_blank"
@@ -35,11 +37,11 @@
35
37
  </header>
36
38
 
37
39
  <div class="scope-tabs">
38
- <button id="tab-project" class="tab-btn active">
40
+ <button id="tab-project" class="tab-btn active" data-i18n="tab-project">
39
41
  <i data-lucide="folder" class="icon"></i>
40
42
  PROJECT MEMORIES
41
43
  </button>
42
- <button id="tab-profile" class="tab-btn">
44
+ <button id="tab-profile" class="tab-btn" data-i18n="tab-profile">
43
45
  <i data-lucide="user" class="icon"></i>
44
46
  USER PROFILE
45
47
  </button>
@@ -47,52 +49,68 @@
47
49
 
48
50
  <div class="controls">
49
51
  <div class="filter-group">
50
- <label>Tag:</label>
52
+ <label data-i18n="label-tag">Tag:</label>
51
53
  <select id="tag-filter">
52
- <option value="">All Tags</option>
54
+ <option value="" data-i18n="opt-all-tags">All Tags</option>
53
55
  </select>
54
56
  </div>
55
57
 
56
58
  <div class="search-group">
57
- <input type="text" id="search-input" placeholder="Search memories..." />
59
+ <input
60
+ type="text"
61
+ id="search-input"
62
+ data-i18n-placeholder="placeholder-search"
63
+ placeholder="Search memories..."
64
+ />
58
65
  <button id="search-btn"><i data-lucide="search" class="icon"></i></button>
59
66
  <button id="clear-search-btn" class="hidden"><i data-lucide="x" class="icon"></i></button>
60
67
  </div>
61
68
 
62
69
  <div class="maintenance-actions">
63
- <button id="cleanup-btn" class="btn-maintenance">
70
+ <button id="cleanup-btn" class="btn-maintenance" data-i18n="btn-cleanup">
64
71
  <i data-lucide="trash" class="icon"></i> Cleanup
65
72
  </button>
66
- <button id="deduplicate-btn" class="btn-maintenance">
73
+ <button id="deduplicate-btn" class="btn-maintenance" data-i18n="btn-deduplicate">
67
74
  <i data-lucide="refresh-cw" class="icon"></i> Deduplicate
68
75
  </button>
69
76
  </div>
70
77
 
71
78
  <div class="bulk-actions hidden" id="bulk-actions">
72
- <span id="selected-count">0 selected</span>
73
- <button id="bulk-delete-btn">
79
+ <span id="selected-count" data-i18n="text-selected">0 selected</span>
80
+ <button id="bulk-delete-btn" data-i18n="btn-delete-selected">
74
81
  <i data-lucide="trash-2" class="icon"></i> Delete Selected
75
82
  </button>
76
- <button id="deselect-all-btn"><i data-lucide="x" class="icon"></i> Deselect All</button>
83
+ <button id="deselect-all-btn" data-i18n="btn-deselect-all">
84
+ <i data-lucide="x" class="icon"></i> Deselect All
85
+ </button>
77
86
  </div>
78
87
  </div>
79
88
 
80
89
  <div class="migration-section hidden" id="migration-section">
81
90
  <div class="migration-warning">
82
91
  <i data-lucide="alert-triangle" class="icon"></i>
83
- <span id="migration-message">Model dimension mismatch detected!</span>
92
+ <span id="migration-message" data-i18n="migration-mismatch"
93
+ >Model dimension mismatch detected!</span
94
+ >
84
95
  </div>
85
96
  <div class="migration-info">
86
97
  <label>
87
98
  <input type="checkbox" id="migration-confirm-checkbox" />
88
- I understand this operation is irreversible and will affect all stored memories
99
+ <span data-i18n="migration-understand"
100
+ >I understand this operation is irreversible and will affect all stored memories</span
101
+ >
89
102
  </label>
90
103
  </div>
91
104
  <div class="migration-actions">
92
- <button id="migration-fresh-btn" class="btn-migration" disabled>
105
+ <button
106
+ id="migration-fresh-btn"
107
+ class="btn-migration"
108
+ disabled
109
+ data-i18n="btn-fresh-start"
110
+ >
93
111
  <i data-lucide="trash" class="icon"></i> Fresh Start (Delete All)
94
112
  </button>
95
- <button id="migration-reembed-btn" class="btn-migration" disabled>
113
+ <button id="migration-reembed-btn" class="btn-migration" disabled data-i18n="btn-reembed">
96
114
  <i data-lucide="refresh-cw" class="icon"></i> Re-embed (Preserve Data)
97
115
  </button>
98
116
  </div>
@@ -100,12 +118,12 @@
100
118
 
101
119
  <div class="memories-section" id="project-section">
102
120
  <div class="section-header">
103
- <h2 id="section-title">└─ PROJECT MEMORIES (0) ──</h2>
121
+ <h2 id="section-title" data-i18n="section-project">└─ PROJECT MEMORIES (0) ──</h2>
104
122
  <div class="pagination" id="pagination-top">
105
123
  <button id="prev-page-top" disabled>
106
124
  <i data-lucide="chevron-left" class="icon"></i>
107
125
  </button>
108
- <span id="page-info-top">Page 1 of 1</span>
126
+ <span id="page-info-top" data-i18n="text-page">Page 1 of 1</span>
109
127
  <button id="next-page-top" disabled>
110
128
  <i data-lucide="chevron-right" class="icon"></i>
111
129
  </button>
@@ -113,14 +131,14 @@
113
131
  </div>
114
132
 
115
133
  <div id="memories-list" class="memories-list">
116
- <div class="loading">Initializing...</div>
134
+ <div class="loading" data-i18n="loading-init">Initializing...</div>
117
135
  </div>
118
136
 
119
137
  <div class="pagination" id="pagination-bottom">
120
138
  <button id="prev-page-bottom" disabled>
121
139
  <i data-lucide="chevron-left" class="icon"></i>
122
140
  </button>
123
- <span id="page-info-bottom">Page 1 of 1</span>
141
+ <span id="page-info-bottom" data-i18n="text-page">Page 1 of 1</span>
124
142
  <button id="next-page-bottom" disabled>
125
143
  <i data-lucide="chevron-right" class="icon"></i>
126
144
  </button>
@@ -129,61 +147,67 @@
129
147
 
130
148
  <div class="profile-section hidden" id="profile-section">
131
149
  <div class="section-header">
132
- <h2>└─ USER PROFILE ──</h2>
133
- <button id="refresh-profile-btn" class="btn-secondary">
150
+ <h2 data-i18n="section-profile">└─ USER PROFILE ──</h2>
151
+ <button id="refresh-profile-btn" class="btn-secondary" data-i18n="btn-refresh">
134
152
  <i data-lucide="refresh-cw" class="icon"></i> Refresh
135
153
  </button>
136
154
  </div>
137
155
 
138
156
  <div id="profile-content" class="profile-content">
139
- <div class="loading">Loading profile...</div>
157
+ <div class="loading" data-i18n="loading-profile">Loading profile...</div>
140
158
  </div>
141
159
  </div>
142
160
 
143
161
  <div class="add-section">
144
- <h2>└─ ADD NEW MEMORY ──</h2>
162
+ <h2 data-i18n="section-add">└─ ADD NEW MEMORY ──</h2>
145
163
  <form id="add-form">
146
164
  <div class="form-row">
147
165
  <div class="form-group">
148
- <label>Tag:</label>
166
+ <label data-i18n="label-tag">Tag:</label>
149
167
  <select id="add-tag" required>
150
- <option value="">Select tag</option>
168
+ <option value="" data-i18n="opt-select-tag">Select tag</option>
151
169
  </select>
152
170
  </div>
153
171
 
154
172
  <div class="form-group">
155
- <label>Type:</label>
173
+ <label data-i18n="label-type">Type:</label>
156
174
  <select id="add-type">
157
- <option value="">other</option>
158
- <option value="feature">feature</option>
159
- <option value="bug-fix">bug-fix</option>
160
- <option value="refactor">refactor</option>
161
- <option value="architecture">architecture</option>
162
- <option value="rule">rule</option>
163
- <option value="documentation">documentation</option>
164
- <option value="discussion">discussion</option>
165
- <option value="analysis">analysis</option>
166
- <option value="configuration">configuration</option>
175
+ <option value="" data-i18n="opt-other">other</option>
176
+ <option value="feature" data-i18n="opt-feature">feature</option>
177
+ <option value="bug-fix" data-i18n="opt-bug-fix">bug-fix</option>
178
+ <option value="refactor" data-i18n="opt-refactor">refactor</option>
179
+ <option value="architecture" data-i18n="opt-architecture">architecture</option>
180
+ <option value="rule" data-i18n="opt-rule">rule</option>
181
+ <option value="documentation" data-i18n="opt-documentation">documentation</option>
182
+ <option value="discussion" data-i18n="opt-discussion">discussion</option>
183
+ <option value="analysis" data-i18n="opt-analysis">analysis</option>
184
+ <option value="configuration" data-i18n="opt-configuration">configuration</option>
167
185
  </select>
168
186
  </div>
169
187
 
170
188
  <div class="form-group">
171
- <label>Tags:</label>
172
- <input type="text" id="add-tags" placeholder="react, hooks, auth (comma separated)" />
189
+ <label data-i18n="label-tags">Tags:</label>
190
+ <input
191
+ type="text"
192
+ id="add-tags"
193
+ data-i18n-placeholder="placeholder-tags"
194
+ placeholder="react, hooks, auth (comma separated)"
195
+ />
173
196
  </div>
174
197
  </div>
175
198
 
176
199
  <div class="form-group">
177
- <label>Content:</label>
200
+ <label data-i18n="label-content">Content:</label>
178
201
  <textarea
179
202
  id="add-content"
180
203
  rows="4"
204
+ data-i18n-placeholder="placeholder-content"
181
205
  placeholder="Enter memory content..."
182
206
  required
183
207
  ></textarea>
184
208
  </div>
185
209
 
186
- <button type="submit" class="btn-primary">
210
+ <button type="submit" class="btn-primary" data-i18n="btn-add-memory">
187
211
  <i data-lucide="plus" class="icon"></i> Add Memory
188
212
  </button>
189
213
  </form>
@@ -193,20 +217,20 @@
193
217
  <div id="edit-modal" class="modal hidden">
194
218
  <div class="modal-content">
195
219
  <div class="modal-header">
196
- <h3>Edit Memory</h3>
220
+ <h3 data-i18n="modal-edit-title">Edit Memory</h3>
197
221
  <button class="modal-close" id="modal-close"><i data-lucide="x" class="icon"></i></button>
198
222
  </div>
199
223
  <form id="edit-form">
200
224
  <input type="hidden" id="edit-id" />
201
225
  <div class="form-group">
202
- <label>Content:</label>
226
+ <label data-i18n="label-content">Content:</label>
203
227
  <textarea id="edit-content" rows="6" required></textarea>
204
228
  </div>
205
229
  <div class="modal-actions">
206
- <button type="button" class="btn-secondary" id="cancel-edit">
230
+ <button type="button" class="btn-secondary" id="cancel-edit" data-i18n="btn-cancel">
207
231
  <i data-lucide="x" class="icon"></i> Cancel
208
232
  </button>
209
- <button type="submit" class="btn-primary">
233
+ <button type="submit" class="btn-primary" data-i18n="btn-save">
210
234
  <i data-lucide="check" class="icon"></i> Save Changes
211
235
  </button>
212
236
  </div>
@@ -219,20 +243,22 @@
219
243
  <div id="tag-migration-overlay" class="modal hidden">
220
244
  <div class="modal-content">
221
245
  <div class="modal-header">
222
- <h3>Memory Tagging Migration</h3>
246
+ <h3 data-i18n="modal-migration-title">Memory Tagging Migration</h3>
223
247
  </div>
224
248
  <div class="migration-progress-body">
225
- <p id="tag-migration-status">Initializing migration...</p>
249
+ <p id="tag-migration-status" data-i18n="status-migration-init">
250
+ Initializing migration...
251
+ </p>
226
252
  <div class="progress-bar-container">
227
253
  <div id="tag-migration-progress" class="progress-bar" style="width: 0%"></div>
228
254
  </div>
229
- <p class="migration-note">
255
+ <p class="migration-note" data-i18n="migration-note">
230
256
  Please don't close the browser. This will re-vectorize your memories with technical tags
231
257
  to improve search accuracy.
232
258
  </p>
233
259
  </div>
234
260
  <div class="modal-actions" id="tag-migration-actions">
235
- <button id="start-tag-migration-btn" class="btn-primary">
261
+ <button id="start-tag-migration-btn" class="btn-primary" data-i18n="btn-start-migration">
236
262
  <i data-lucide="play" class="icon"></i> Start Migration
237
263
  </button>
238
264
  </div>
@@ -242,13 +268,13 @@
242
268
  <div id="changelog-modal" class="modal hidden">
243
269
  <div class="modal-content">
244
270
  <div class="modal-header">
245
- <h3>Profile Version History</h3>
271
+ <h3 data-i18n="modal-changelog-title">Profile Version History</h3>
246
272
  <button class="modal-close" id="changelog-close">
247
273
  <i data-lucide="x" class="icon"></i>
248
274
  </button>
249
275
  </div>
250
276
  <div id="changelog-list" class="changelog-list">
251
- <div class="loading">Loading changelog...</div>
277
+ <div class="loading" data-i18n="loading-changelog">Loading changelog...</div>
252
278
  </div>
253
279
  </div>
254
280
  </div>
@@ -1612,3 +1612,20 @@ textarea:focus-visible {
1612
1612
  font-size: 11px;
1613
1613
  font-weight: bold;
1614
1614
  }
1615
+
1616
+ .lang-toggle {
1617
+ background: #0a0a0a;
1618
+ border: 1px solid #00ff00;
1619
+ color: #00ff00;
1620
+ padding: 4px 12px;
1621
+ font-family: inherit;
1622
+ font-size: 12px;
1623
+ font-weight: bold;
1624
+ cursor: pointer;
1625
+ transition: all 0.2s;
1626
+ letter-spacing: 1px;
1627
+ }
1628
+ .lang-toggle:hover {
1629
+ background: #00ff00;
1630
+ color: #0a0a0a;
1631
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-mem",
3
- "version": "2.11.4",
3
+ "version": "2.11.7",
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",