@a9i5k4/dsh-auto-memory 0.1.8 → 0.1.9
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 +160 -17
- package/README.zh-CN.md +158 -15
- package/lib/client.js +361 -51
- package/lib/index.js +1228 -72
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* 3. settings.section — 自动记忆设置页(存储位置、注入、反思风格)
|
|
8
8
|
* Data flows over /api/dsh-auto-memory/* (loopback-only host routes).
|
|
9
9
|
*/
|
|
10
|
+
console.log('[dsh-auto-memory] client v0.1.9 fingerprint: drawer-summary-ok')
|
|
10
11
|
window.__ModuleLoader__.load({
|
|
11
|
-
id: '@
|
|
12
|
+
id: '@deepseek-ai/dsh-auto-memory',
|
|
12
13
|
factory: (require) => {
|
|
13
14
|
var module = { exports: {} }
|
|
14
15
|
var exports = module.exports
|
|
@@ -97,12 +98,22 @@ window.__ModuleLoader__.load({
|
|
|
97
98
|
memoryPanel: '记忆面板',
|
|
98
99
|
memory: '记忆',
|
|
99
100
|
autoMemory: '自动记忆',
|
|
100
|
-
overview: '概览', logs: '日志', notes: '笔记', reflections: '反思', connect: '接续', search: '检索',
|
|
101
|
-
|
|
101
|
+
overview: '概览', logs: '日志', notes: '笔记', reflections: '反思', connect: '接续', calendar: '日历', search: '检索', workspaces: '工作区',
|
|
102
|
+
wsGenerating: '正在生成各工作区总结(每个工作区一次 AI 调用,可能稍慢)…', wsNone: '未发现带记忆的工作区', wsNoSummary: '(无总结)', wsOverview: '工作区总结(跨工作区)',
|
|
103
|
+
debugCenter: '调试中心', dbgLoading: '加载诊断信息…', dbgRefresh: '刷新', dbgRefreshing: '刷新中…',
|
|
104
|
+
fMemoryRoot: '记忆根目录', fMemoryRootHint: '集中式存储:所有工作区记忆统一放在此目录下(每工作区一个子目录),旧版分散的记忆会自动迁移。',
|
|
105
|
+
fBrowse: '浏览…', browseTitle: '选择记忆根目录', fUp: '上级', fSelectDir: '选择此目录',
|
|
106
|
+
pickedDir: '已选择目录:', rememberSave: '(点击「保存设置」后生效)', pickerUnavailable: '系统文件夹选择器不可用,改用内嵌浏览。',
|
|
107
|
+
fDayBoundary: '日界(分钟)', fDayBoundaryHint: '从 0 点起算:凌晨在此之前的活儿归前一天。默认 450=早上 7:30 进入新一天;改 480=8:00;0=按午夜切日。',
|
|
108
|
+
refresh: '刷新', refreshing: '刷新中…', close: '关闭', dragMove: '拖动移动', dragResize: '拖动调整大小', resetPos: '恢复默认位置',
|
|
102
109
|
generated: '已生成', failed: '失败: ',
|
|
110
|
+
generatedAt: '生成于 ',
|
|
111
|
+
pointsCount: ' 项', summarizing: 'AI 总结生成中…', summaryFailed: 'AI 总结生成失败,点 ⟳ 重试',
|
|
103
112
|
pendingReflection: '待生成反思: ',
|
|
104
113
|
pendingReflectionHint: ' —— 可点下方「一键反思」立即生成。',
|
|
105
114
|
todayWork: '今日工作', logEntries: ' 条日志',
|
|
115
|
+
autoSettledToday: '今日已自动沉淀 ', autoSettledSuffix: ' 条要点',
|
|
116
|
+
autoSettledRecent: '最近: ', autoSettledNone: '本轮对话暂无自动沉淀',
|
|
106
117
|
dailyReflection: '每日反思', notYet: '(还没有)',
|
|
107
118
|
workspace: '工作区',
|
|
108
119
|
reflecting: '反思生成中…', oneClickReflect: '一键反思',
|
|
@@ -121,6 +132,7 @@ window.__ModuleLoader__.load({
|
|
|
121
132
|
reflectAutoHint: '自动用最近日志生成反思草稿(便于测试)',
|
|
122
133
|
noReflection: '还没有反思。每天第一次会话时,agent 会主动呈现前一天的工作反思。',
|
|
123
134
|
searchFailed: '检索失败: ', searchPlaceholder: '搜记忆:关键词或自包含描述…', searchBtn: '检索', resultTitle: '结果',
|
|
135
|
+
smartSearch: '智能检索', smartAnswer: '智能回答', keywordsLabel: '关键词: ',
|
|
124
136
|
projectFiles: '项目文件', aiAssistant: 'AI 助手',
|
|
125
137
|
imported: '接入完成', importing: '正在接入 ', importingSuffix: ' 个源…', allImported: '全部接入完成',
|
|
126
138
|
noExternal: '未检测到其他 AI 工具的记忆文件(CodeBuddy/Claude Code/Codex 等)。',
|
|
@@ -134,6 +146,7 @@ window.__ModuleLoader__.load({
|
|
|
134
146
|
yesterdayTimeline: '昨天(', pendingReflectionShort: '昨天的工作还没复盘(',
|
|
135
147
|
saved: '已保存',
|
|
136
148
|
settingsHeader: '记忆存储与行为设置(保存到 DSH 主目录 dsh-auto-memory.json):',
|
|
149
|
+
fFontSize: '界面字号', fFontSizeHint: '记忆面板文字大小(立即生效,仅本机)', fsSm: '小', fsMd: '标准', fsLg: '大', fsXl: '特大',
|
|
137
150
|
fUserDir: '用户记忆目录', fUserDirHint: '跨项目规则存放处,支持 ~ 开头;需有文件写权限。',
|
|
138
151
|
fProjectDir: '项目记忆目录', fProjectDirHint: '相对各工作区的目录名(默认 .dsh-memory)。',
|
|
139
152
|
fInject: '注入记忆上下文', fInjectHint: '每次组装提示词时自动注入 <memory_system> 块。',
|
|
@@ -158,12 +171,22 @@ window.__ModuleLoader__.load({
|
|
|
158
171
|
memoryPanel: 'Memory Panel',
|
|
159
172
|
memory: 'Memory',
|
|
160
173
|
autoMemory: 'Auto Memory',
|
|
161
|
-
overview: 'Overview', logs: 'Logs', notes: 'Notes', reflections: 'Reflections', connect: 'Connect', search: 'Search',
|
|
162
|
-
|
|
174
|
+
overview: 'Overview', logs: 'Logs', notes: 'Notes', reflections: 'Reflections', connect: 'Connect', calendar: 'Calendar', search: 'Search', workspaces: 'Workspaces',
|
|
175
|
+
wsGenerating: 'Generating per-workspace summaries (one AI call each, may take a while)…', wsNone: 'No workspace with memory found', wsNoSummary: '(no summary)', wsOverview: 'Workspace summaries (all workspaces)',
|
|
176
|
+
debugCenter: 'Debug Center', dbgLoading: 'Loading diagnostics…', dbgRefresh: 'Refresh', dbgRefreshing: 'Refreshing…',
|
|
177
|
+
fMemoryRoot: 'Memory root', fMemoryRootHint: 'Centralized storage: all workspace memories live here (one subdir per workspace); legacy memories are auto-migrated.',
|
|
178
|
+
fBrowse: 'Browse…', browseTitle: 'Choose memory root', fUp: 'Up', fSelectDir: 'Select this folder',
|
|
179
|
+
pickedDir: 'Selected folder:', rememberSave: '(click Save to apply)', pickerUnavailable: 'Native folder picker unavailable, falling back to in-app browser.',
|
|
180
|
+
fDayBoundary: 'Day boundary (minutes)', fDayBoundaryHint: 'Minutes from midnight: work before it counts as the previous day. Default 450 = 7:30 AM starts the new day; 480 = 8:00; 0 = midnight cut.',
|
|
181
|
+
refresh: 'Refresh', refreshing: 'Refreshing…', close: 'Close', dragMove: 'Drag to move', dragResize: 'Drag to resize', resetPos: 'Reset position',
|
|
163
182
|
generated: 'Generated', failed: 'Failed: ',
|
|
183
|
+
generatedAt: 'Generated ',
|
|
184
|
+
pointsCount: ' items', summarizing: 'AI summary generating…', summaryFailed: 'Summary failed, press refresh to retry',
|
|
164
185
|
pendingReflection: 'Pending reflection: ',
|
|
165
186
|
pendingReflectionHint: ' — click "One-click Reflect" below to generate now.',
|
|
166
187
|
todayWork: 'Today', logEntries: ' log entries',
|
|
188
|
+
autoSettledToday: 'Auto-consolidated ', autoSettledSuffix: ' points today',
|
|
189
|
+
autoSettledRecent: 'Latest: ', autoSettledNone: 'Nothing auto-consolidated this turn',
|
|
167
190
|
dailyReflection: 'Daily reflection', notYet: '(none yet)',
|
|
168
191
|
workspace: 'Workspace',
|
|
169
192
|
reflecting: 'Generating…', oneClickReflect: 'One-click Reflect',
|
|
@@ -182,6 +205,7 @@ window.__ModuleLoader__.load({
|
|
|
182
205
|
reflectAutoHint: 'Auto-generate a reflection draft from recent logs (for testing)',
|
|
183
206
|
noReflection: "No reflections yet. On the first session each day, the agent presents the previous day's reflection.",
|
|
184
207
|
searchFailed: 'Search failed: ', searchPlaceholder: 'Search memory: keyword or self-contained description…', searchBtn: 'Search', resultTitle: 'Results',
|
|
208
|
+
smartSearch: 'Smart search', smartAnswer: 'AI Answer', keywordsLabel: 'Keywords: ',
|
|
185
209
|
projectFiles: 'Project files', aiAssistant: 'AI Assistant',
|
|
186
210
|
imported: 'Imported', importing: 'Importing ', importingSuffix: ' sources…', allImported: 'All imported',
|
|
187
211
|
noExternal: 'No memory files found from other AI tools (CodeBuddy/Claude Code/Codex etc.).',
|
|
@@ -195,6 +219,7 @@ window.__ModuleLoader__.load({
|
|
|
195
219
|
yesterdayTimeline: 'Yesterday (', pendingReflectionShort: 'Yesterday\'s work not reviewed (',
|
|
196
220
|
saved: 'Saved',
|
|
197
221
|
settingsHeader: 'Memory storage & behavior (saved to ~/.dsh/dsh-auto-memory.json):',
|
|
222
|
+
fFontSize: 'Panel font size', fFontSizeHint: 'Memory panel text size (applies immediately, this device only)', fsSm: 'Small', fsMd: 'Normal', fsLg: 'Large', fsXl: 'Extra large',
|
|
198
223
|
fUserDir: 'User memory dir', fUserDirHint: 'Cross-project rules; supports ~ prefix; needs write permission.',
|
|
199
224
|
fProjectDir: 'Project memory dir', fProjectDirHint: 'Directory name relative to each workspace (default .dsh-memory).',
|
|
200
225
|
fInject: 'Inject memory context', fInjectHint: 'Auto-inject <memory_system> block into every prompt.',
|
|
@@ -216,6 +241,21 @@ window.__ModuleLoader__.load({
|
|
|
216
241
|
}
|
|
217
242
|
}
|
|
218
243
|
var locale = 'zh'
|
|
244
|
+
var sessions = null
|
|
245
|
+
// 当前会话工作区(跟随 GUI 切换工作区):从 sessions 服务拿,供 state/summarize/greet 请求使用
|
|
246
|
+
function currentWs() {
|
|
247
|
+
try {
|
|
248
|
+
var snap = sessions && sessions.list && sessions.list.getSnapshot()
|
|
249
|
+
if (!snap) return ''
|
|
250
|
+
var id = snap.current
|
|
251
|
+
if (id === undefined || id === null) return ''
|
|
252
|
+
var s = snap.byId && snap.byId[id]
|
|
253
|
+
return (s && typeof s.cwd === 'string') ? s.cwd : ''
|
|
254
|
+
} catch (e) { return '' }
|
|
255
|
+
}
|
|
256
|
+
var fontScale = 'lg'
|
|
257
|
+
var FONT_SCALES = { sm: '小', md: '标准', lg: '大', xl: '特大' }
|
|
258
|
+
var FONT_SCALE_VALUES = { sm: '0.9', md: '1', lg: '1.15', xl: '1.3' }
|
|
219
259
|
var localeListeners = new Set()
|
|
220
260
|
function t(key) { return (I18N[locale] && I18N[locale][key]) || I18N.zh[key] || key }
|
|
221
261
|
function setLocale(l) { if (l !== 'zh' && l !== 'en') return; if (l === locale) return; locale = l; localeListeners.forEach(function (fn) { try { fn(l) } catch (e) {} }) }
|
|
@@ -227,6 +267,11 @@ window.__ModuleLoader__.load({
|
|
|
227
267
|
list: '/api/dsh-auto-memory/list',
|
|
228
268
|
file: '/api/dsh-auto-memory/file',
|
|
229
269
|
recall: '/api/dsh-auto-memory/recall',
|
|
270
|
+
smartRecall: '/api/dsh-auto-memory/smart-recall',
|
|
271
|
+
workspaces: '/api/dsh-auto-memory/workspaces',
|
|
272
|
+
debug: '/api/dsh-auto-memory/debug',
|
|
273
|
+
browseDir: '/api/dsh-auto-memory/browse-dir',
|
|
274
|
+
pickDir: '/api/dsh-auto-memory/pick-dir',
|
|
230
275
|
config: '/api/dsh-auto-memory/config',
|
|
231
276
|
reflect: '/api/dsh-auto-memory/reflect',
|
|
232
277
|
reflectAuto: '/api/dsh-auto-memory/reflect-auto',
|
|
@@ -234,6 +279,7 @@ window.__ModuleLoader__.load({
|
|
|
234
279
|
external: '/api/dsh-auto-memory/external',
|
|
235
280
|
externalImport: '/api/dsh-auto-memory/external-import',
|
|
236
281
|
summarize: '/api/dsh-auto-memory/summarize',
|
|
282
|
+
greet: '/api/dsh-auto-memory/greet',
|
|
237
283
|
}
|
|
238
284
|
function query(params) {
|
|
239
285
|
var search = new URLSearchParams()
|
|
@@ -258,7 +304,7 @@ window.__ModuleLoader__.load({
|
|
|
258
304
|
// 视觉:液态玻璃(毛玻璃)—— backdrop-filter + DSH 主题令牌(--dsw-alias-*),
|
|
259
305
|
// 跟随亮/暗主题与页面背景自适应;位置/尺寸由 JS 几何状态驱动(可拖动、可缩放)。
|
|
260
306
|
var CSS = [
|
|
261
|
-
'[data-dam-panel] { position: fixed; left: 16px; width: 440px; height: 560px;',
|
|
307
|
+
'[data-dam-panel] { position: fixed; left: 16px; width: 440px; height: 560px; --dam-scale: 1;',
|
|
262
308
|
' max-width: calc(100vw - 32px); max-height: calc(100vh - 32px);',
|
|
263
309
|
' display: flex; flex-direction: column; overflow: hidden; z-index: 3000; pointer-events: auto;',
|
|
264
310
|
' border-radius: 16px; font: 13px/1.55 system-ui, "Segoe UI", sans-serif;',
|
|
@@ -271,36 +317,39 @@ window.__ModuleLoader__.load({
|
|
|
271
317
|
'@keyframes dam-in { from { opacity: 0; transform: scale(.92) translateY(10px); } to { opacity: 1; transform: none; } }',
|
|
272
318
|
'@keyframes dam-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.95) translateY(6px); } }',
|
|
273
319
|
'[data-dam-panel][data-closing="true"] { animation: dam-out .16s ease-in both; }',
|
|
320
|
+
'[data-dam-panel][data-scale="sm"] { --dam-scale: .9; }',
|
|
321
|
+
'[data-dam-panel][data-scale="lg"] { --dam-scale: 1.15; }',
|
|
322
|
+
'[data-dam-panel][data-scale="xl"] { --dam-scale: 1.3; }',
|
|
274
323
|
'[data-dam-panel]::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 64%; pointer-events: none;',
|
|
275
324
|
' background: linear-gradient(180deg, rgba(255,255,255,.13), rgba(255,255,255,0) 70%); border-radius: 16px 16px 0 0; }',
|
|
276
325
|
'[data-dam-panel][data-dragging="true"] { user-select: none; }',
|
|
277
326
|
'[data-dam-panel] header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; cursor: grab;',
|
|
278
327
|
' border-bottom: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.25)) 55%, transparent); }',
|
|
279
328
|
'[data-dam-panel][data-dragging="true"] header { cursor: grabbing; }',
|
|
280
|
-
'[data-dam-panel] header strong { font-size: 14px; }',
|
|
329
|
+
'[data-dam-panel] header strong { font-size: calc(14px * var(--dam-scale)); }',
|
|
281
330
|
'[data-dam-panel] header .dam-spacer { flex: 1; }',
|
|
282
331
|
'[data-dam-resize] { position: absolute; right: 0; bottom: 0; width: 22px; height: 22px; cursor: nwse-resize;',
|
|
283
332
|
' opacity: .55; z-index: 2; border-radius: 0 0 16px 0;',
|
|
284
333
|
' background: linear-gradient(135deg, transparent 50%, color-mix(in srgb, var(--dsw-alias-label-secondary, #666) 45%, transparent) 50%); }',
|
|
285
334
|
'[data-dam-resize]:hover { opacity: 1; }',
|
|
286
|
-
'[data-dam-btn] { border: none; background: transparent; cursor: pointer; color: inherit; opacity: .75; font-size: 13px; padding: 4px 8px; border-radius: 6px; }',
|
|
335
|
+
'[data-dam-btn] { border: none; background: transparent; cursor: pointer; color: inherit; opacity: .75; font-size: calc(13px * var(--dam-scale)); padding: 4px 8px; border-radius: 6px; }',
|
|
287
336
|
'[data-dam-btn]:hover { opacity: 1; background: color-mix(in srgb, var(--dsw-alias-label-secondary, #666) 16%, transparent); }',
|
|
288
337
|
'[data-dam-tabs] { display: flex; gap: 2px; padding: 6px 10px; border-bottom: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.2)) 55%, transparent); }',
|
|
289
|
-
'[data-dam-tab] { border: none; background: transparent; cursor: pointer; color: inherit; opacity: .6; padding: 5px 10px; border-radius: 7px; font-size: 12.5px; }',
|
|
338
|
+
'[data-dam-tab] { border: none; background: transparent; cursor: pointer; color: inherit; opacity: .6; padding: 5px 10px; border-radius: 7px; font-size: calc(12.5px * var(--dam-scale)); }',
|
|
290
339
|
'[data-dam-tab][data-active="true"] { opacity: 1; background: color-mix(in srgb, var(--dsw-alias-label-secondary, #666) 18%, transparent); font-weight: 600; }',
|
|
291
340
|
'[data-dam-body] { flex: 1; overflow: auto; padding: 12px 14px; }',
|
|
292
|
-
'[data-dam-kv] { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; font-size: 12.5px; }',
|
|
341
|
+
'[data-dam-kv] { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; font-size: calc(12.5px * var(--dam-scale)); }',
|
|
293
342
|
'[data-dam-kv] b { opacity: .55; font-weight: 500; }',
|
|
294
|
-
'[data-dam-card] { border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.22)) 60%, transparent); border-radius: 9px; padding: 8px 10px; margin-bottom: 8px; font-size: 12.5px;',
|
|
343
|
+
'[data-dam-card] { border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.22)) 60%, transparent); border-radius: 9px; padding: 8px 10px; margin-bottom: 8px; font-size: calc(12.5px * var(--dam-scale));',
|
|
295
344
|
' background: color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.06)) 40%, transparent); }',
|
|
296
345
|
'[data-dam-card] .dam-date { font-weight: 600; margin-bottom: 4px; }',
|
|
297
346
|
'[data-dam-card] .dam-content { white-space: pre-wrap; word-break: break-word; max-height: 220px; overflow: auto; }',
|
|
298
347
|
'[data-dam-banner] { border: 1px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e6a23c) 55%, transparent);',
|
|
299
|
-
' background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e6a23c) 13%, transparent); border-radius: 9px; padding: 8px 10px; margin-bottom: 10px; font-size: 12.5px; }',
|
|
348
|
+
' background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #e6a23c) 13%, transparent); border-radius: 9px; padding: 8px 10px; margin-bottom: 10px; font-size: calc(12.5px * var(--dam-scale)); }',
|
|
300
349
|
'[data-dam-input], [data-dam-select] { width: 100%; box-sizing: border-box; background: color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.08)) 45%, transparent); color: inherit; border: 1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.3)) 60%, transparent); border-radius: 7px; padding: 6px 8px; font: inherit; }',
|
|
301
350
|
'[data-dam-row] { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }',
|
|
302
|
-
'[data-dam-row] label { flex: 0 0 110px; opacity: .8; font-size: 12.5px; }',
|
|
303
|
-
'[data-dam-hint] { opacity: .5; font-size: 11.5px; margin-top: 2px; }',
|
|
351
|
+
'[data-dam-row] label { flex: 0 0 110px; opacity: .8; font-size: calc(12.5px * var(--dam-scale)); }',
|
|
352
|
+
'[data-dam-hint] { opacity: .5; font-size: calc(11.5px * var(--dam-scale)); margin-top: 2px; }',
|
|
304
353
|
'[data-dam-sidebar-btn] { display: flex; align-items: center; gap: 6px; width: 100%; border: none; background: transparent; color: inherit; cursor: pointer; padding: 6px 10px; border-radius: 8px; font: inherit; font-size: 13px; opacity: .8; }',
|
|
305
354
|
'[data-dam-sidebar-btn]:hover { background: color-mix(in srgb, var(--dsw-alias-label-secondary, #666) 14%, transparent); opacity: 1; }',
|
|
306
355
|
'[data-dam-sidebar-btn][data-active="true"] { opacity: 1; background: color-mix(in srgb, var(--dsw-alias-brand-primary, #4f7cff) 16%, transparent); color: var(--dsw-alias-brand-primary, #4f7cff); }',
|
|
@@ -314,7 +363,7 @@ window.__ModuleLoader__.load({
|
|
|
314
363
|
if (document.getElementById(STYLE_ID)) return
|
|
315
364
|
var tag = document.createElement('style')
|
|
316
365
|
tag.id = STYLE_ID
|
|
317
|
-
tag.dataset.plugin = '@
|
|
366
|
+
tag.dataset.plugin = '@deepseek-ai/dsh-auto-memory'
|
|
318
367
|
tag.textContent = CSS
|
|
319
368
|
document.head.appendChild(tag)
|
|
320
369
|
}
|
|
@@ -360,6 +409,9 @@ window.__ModuleLoader__.load({
|
|
|
360
409
|
var openPair = useState({})
|
|
361
410
|
var openMap = openPair[0]
|
|
362
411
|
var setOpenMap = openPair[1]
|
|
412
|
+
var subOpenPair = useState({})
|
|
413
|
+
var subOpenMap = subOpenPair[0]
|
|
414
|
+
var setSubOpenMap = subOpenPair[1]
|
|
363
415
|
// 智能时段判定
|
|
364
416
|
var hour = new Date().getHours()
|
|
365
417
|
var seg = hour < 9 ? 'morning' : hour < 12 ? 'forenoon' : hour < 14 ? 'noon' : hour < 18 ? 'afternoon' : 'evening'
|
|
@@ -369,7 +421,7 @@ window.__ModuleLoader__.load({
|
|
|
369
421
|
var curSegName = { morning: '早晨', forenoon: '上午', noon: '中午', afternoon: '下午', evening: '晚上' }[seg]
|
|
370
422
|
// 昨天抽屉(早晨显示)
|
|
371
423
|
if (seg === 'morning' && g.entries.length) {
|
|
372
|
-
drawers.push({ key: 'yesterday', label: t('yesterdayDrawer') + (g.yesterdayDate || ''), hint: '', items: g.entries, withTime: true, defaultOpen: true })
|
|
424
|
+
drawers.push({ key: 'yesterday', label: t('yesterdayDrawer') + (g.yesterdayDate || ''), hint: '', items: g.entries, withTime: true, defaultOpen: true, period: '昨天' })
|
|
373
425
|
}
|
|
374
426
|
// 今天各时段抽屉(已过的时段)
|
|
375
427
|
var seenSeg = { '早晨': seg !== 'morning', '上午': (seg === 'forenoon' || seg === 'noon' || seg === 'afternoon' || seg === 'evening'), '中午': (seg === 'noon' || seg === 'afternoon' || seg === 'evening'), '下午': (seg === 'afternoon' || seg === 'evening'), '晚上': seg === 'evening' }
|
|
@@ -379,7 +431,7 @@ window.__ModuleLoader__.load({
|
|
|
379
431
|
if (!seenSeg[sname]) continue
|
|
380
432
|
var items = (ps && ps.groups && ps.groups[sname]) || []
|
|
381
433
|
if (!items.length) continue
|
|
382
|
-
drawers.push({ key: 'seg-' + sname, label: t('segPrefix') + sname, hint: '', items: items.map(function (x) { return { time: '', text: x } }), withTime: false, defaultOpen: sname === curSegName })
|
|
434
|
+
drawers.push({ key: 'seg-' + sname, label: t('segPrefix') + sname, hint: '', items: items.map(function (x) { return { time: '', text: x } }), withTime: false, defaultOpen: sname === curSegName, period: sname })
|
|
383
435
|
}
|
|
384
436
|
// 外层:生活化问候
|
|
385
437
|
var totalCount = 0
|
|
@@ -404,33 +456,64 @@ window.__ModuleLoader__.load({
|
|
|
404
456
|
var sumCachePair = useState({})
|
|
405
457
|
var sumCache = sumCachePair[0]
|
|
406
458
|
var setSumCache = sumCachePair[1]
|
|
407
|
-
function requestSummary(key, period) {
|
|
408
|
-
if (sumCache[key] !== undefined) return
|
|
409
|
-
apiPost(API.summarize, { period: period }).then(function (d) {
|
|
410
|
-
if (d && d.
|
|
411
|
-
|
|
459
|
+
function requestSummary(key, period, force) {
|
|
460
|
+
if (!force && sumCache[key] !== undefined) return
|
|
461
|
+
apiPost(API.summarize, { period: period, force: !!force, ws: currentWs() }).then(function (d) {
|
|
462
|
+
if (d && (d.summary || (d.works && d.works.length))) {
|
|
463
|
+
var n = Object.assign({}, sumCache)
|
|
464
|
+
n[key] = { summary: d.summary || d.result || '', works: d.works || [], at: d.generatedAt || Date.now(), failed: false }
|
|
465
|
+
setSumCache(n)
|
|
466
|
+
}
|
|
467
|
+
}).catch(function () {
|
|
468
|
+
var n = Object.assign({}, sumCache)
|
|
469
|
+
n[key] = { summary: '', works: [], at: 0, failed: true }
|
|
470
|
+
setSumCache(n)
|
|
471
|
+
})
|
|
412
472
|
}
|
|
473
|
+
// 面板刷新键(nonce 变化):已缓存的展开抽屉 force 重新生成
|
|
474
|
+
useEffect(function () {
|
|
475
|
+
if (!props.nonce) return
|
|
476
|
+
for (var d = 0; d < drawers.length; d++) {
|
|
477
|
+
var dr = drawers[d]
|
|
478
|
+
var isOpen = openMap[dr.key] !== undefined ? openMap[dr.key] : dr.defaultOpen
|
|
479
|
+
if (isOpen && sumCache[dr.key] !== undefined) requestSummary(dr.key, dr.period, true)
|
|
480
|
+
}
|
|
481
|
+
}, [props.nonce])
|
|
413
482
|
for (var d = 0; d < drawers.length; d++) {
|
|
414
483
|
(function (dr) {
|
|
415
484
|
var isOpen = openMap[dr.key] !== undefined ? openMap[dr.key] : dr.defaultOpen
|
|
416
|
-
if (isOpen && sumCache[dr.key] === undefined)
|
|
417
|
-
|
|
418
|
-
|
|
485
|
+
if (isOpen && sumCache[dr.key] === undefined) requestSummary(dr.key, dr.period, false)
|
|
486
|
+
var cached = sumCache[dr.key]
|
|
487
|
+
// 大抽屉标题:有 AI 总结时用总结内容(用户要求),否则用时段名
|
|
488
|
+
var bigTitle = cached && cached.summary ? cached.summary : dr.label
|
|
419
489
|
rows.push(h('div', { key: dr.key, style: { marginTop: '8px' } },
|
|
420
490
|
h('button', {
|
|
421
491
|
'data-dam-btn': '',
|
|
422
492
|
onClick: function () { var n = Object.assign({}, openMap); n[dr.key] = !isOpen; setOpenMap(n) },
|
|
423
|
-
style: { width: '100%',
|
|
493
|
+
style: { width: '100%', textAlign: 'left', padding: '7px 9px', borderRadius: '8px', background: 'color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.08)) 45%, transparent)', border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.3)) 50%, transparent)' },
|
|
424
494
|
},
|
|
425
|
-
h('
|
|
426
|
-
h('
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
495
|
+
h('div', { style: { fontWeight: 600, fontSize: 'calc(12.5px * var(--dam-scale))', lineHeight: 1.5 } }, (isOpen ? '▼ ' : '▶ ') + bigTitle),
|
|
496
|
+
h('div', { 'data-dam-muted': '', style: { fontSize: 'calc(11px * var(--dam-scale))', marginTop: '2px' } },
|
|
497
|
+
dr.label + ' · ' + dr.items.length + t('logEntries') + (cached && cached.at ? ' · ' + t('generatedAt') + new Date(cached.at).toLocaleTimeString() : ''))),
|
|
498
|
+
isOpen ? h('div', { style: { padding: '4px 2px 2px 8px' } },
|
|
499
|
+
cached && cached.works && cached.works.length ? cached.works.map(function (w, wi) {
|
|
500
|
+
var sk = dr.key + ':w' + wi
|
|
501
|
+
var sOpen = subOpenMap[sk] !== undefined ? subOpenMap[sk] : false
|
|
502
|
+
return h('div', { key: sk, style: { marginTop: '5px' } },
|
|
503
|
+
h('button', {
|
|
504
|
+
'data-dam-btn': '',
|
|
505
|
+
onClick: function () { var n = Object.assign({}, subOpenMap); n[sk] = !sOpen; setSubOpenMap(n) },
|
|
506
|
+
style: { width: '100%', textAlign: 'left', padding: '4px 8px', borderRadius: '6px', background: 'color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.06)) 40%, transparent)', border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.22)) 45%, transparent)' },
|
|
507
|
+
},
|
|
508
|
+
h('span', { style: { fontWeight: 600, fontSize: 'calc(12px * var(--dam-scale))' } }, (sOpen ? '▾ ' : '▸ ') + w.title),
|
|
509
|
+
h('span', { 'data-dam-muted': '', style: { fontSize: 'calc(11px * var(--dam-scale))', marginLeft: '6px' } }, w.points.length + t('pointsCount'))),
|
|
510
|
+
sOpen ? h('div', { style: { padding: '4px 4px 2px 14px' } },
|
|
511
|
+
w.points.map(function (pt, pi) {
|
|
512
|
+
return h('div', { key: pi, style: { fontSize: 'calc(12px * var(--dam-scale))', lineHeight: 1.5, marginBottom: '2px' } }, '· ' + pt)
|
|
513
|
+
})) : null)
|
|
514
|
+
}) : cached && cached.failed ? h('div', { 'data-dam-hint': '', style: { padding: '4px 6px' } }, t('summaryFailed'))
|
|
515
|
+
: cached && cached.summary ? h('div', { 'data-dam-hint': '', style: { padding: '4px 6px' } }, cached.summary)
|
|
516
|
+
: h('div', { 'data-dam-hint': '', style: { padding: '4px 6px' } }, t('summarizing'))) : null))
|
|
434
517
|
})(drawers[d])
|
|
435
518
|
}
|
|
436
519
|
// 待反思提醒
|
|
@@ -440,7 +523,7 @@ window.__ModuleLoader__.load({
|
|
|
440
523
|
return h(Card, { title: (g.period || '') + ' · ' + segLabel }, rows)
|
|
441
524
|
}
|
|
442
525
|
|
|
443
|
-
function OverviewTab() {
|
|
526
|
+
function OverviewTab(props) {
|
|
444
527
|
var statePair = useState(null)
|
|
445
528
|
var state = statePair[0]
|
|
446
529
|
var setState = statePair[1]
|
|
@@ -453,10 +536,35 @@ window.__ModuleLoader__.load({
|
|
|
453
536
|
var actMsgPair = useState('')
|
|
454
537
|
var actMsg = actMsgPair[0]
|
|
455
538
|
var setActMsg = actMsgPair[1]
|
|
539
|
+
var wsPair = useState(null)
|
|
540
|
+
var wsData = wsPair[0]
|
|
541
|
+
var setWsData = wsPair[1]
|
|
542
|
+
// 每次进入面板 / 点刷新(nonce 变化)/ 面板打开期间每 30s 自动重拉,保证自动沉淀等数据新鲜
|
|
456
543
|
useEffect(function () {
|
|
457
544
|
var alive = true
|
|
458
|
-
|
|
545
|
+
// 跨工作区总结(概览页集成:所有工作区的小总结+细分;读缓存)
|
|
546
|
+
apiPost(API.workspaces, { force: false }).then(function (d) { if (d && alive) setWsData(d) }).catch(function () {})
|
|
547
|
+
apiGet(API.state, { ws: currentWs() }).then(function (s) {
|
|
548
|
+
if (alive) setState(s)
|
|
549
|
+
// 无 AI 问候 → 自动生成一次(host 按时段缓存,不会重复生成)
|
|
550
|
+
if (s && s.greeting && !s.greeting.greeting) {
|
|
551
|
+
apiPost(API.greet, { ws: currentWs() }).then(function (d) {
|
|
552
|
+
if (d && d.greeting && alive) {
|
|
553
|
+
setState(function (prev) {
|
|
554
|
+
var g0 = (prev && prev.greeting) || {}
|
|
555
|
+
return Object.assign({}, prev, { greeting: Object.assign({}, g0, { greeting: d.greeting, hasGreeting: true }) })
|
|
556
|
+
})
|
|
557
|
+
}
|
|
558
|
+
}).catch(function () {})
|
|
559
|
+
}
|
|
560
|
+
}).catch(function () {})
|
|
459
561
|
return function () { alive = false }
|
|
562
|
+
}, [props && props.nonce])
|
|
563
|
+
useEffect(function () {
|
|
564
|
+
var timer = setInterval(function () {
|
|
565
|
+
apiGet(API.state, { ws: currentWs() }).then(function (s) { setState(s) }).catch(function () {})
|
|
566
|
+
}, 30000)
|
|
567
|
+
return function () { clearInterval(timer) }
|
|
460
568
|
}, [])
|
|
461
569
|
useEffect(function () {
|
|
462
570
|
// 记录本次活动时间;下次打开若相隔>1小时,GreetingCard 显示"欢迎回来"
|
|
@@ -468,12 +576,25 @@ window.__ModuleLoader__.load({
|
|
|
468
576
|
setReflectBusy(true); setActMsg('')
|
|
469
577
|
apiPost(API.reflectAuto, {}).then(function (d) {
|
|
470
578
|
setActMsg(d.result || t('generated')); setReflectBusy(false)
|
|
471
|
-
apiGet(API.state).then(function (s) { if (s) setState(s) }).catch(function () {})
|
|
579
|
+
apiGet(API.state, { ws: currentWs() }).then(function (s) { if (s) setState(s) }).catch(function () {})
|
|
472
580
|
}).catch(function (e) { setActMsg(t('failed') + e.message); setReflectBusy(false) })
|
|
473
581
|
}
|
|
474
582
|
return h('div', null,
|
|
475
583
|
// 今日问候卡:问候语 + 昨天时间轴 + 提醒(纯 GUI 渲染,不干扰对话流)
|
|
476
|
-
h(GreetingCard, { greeting: state.greeting, periodSummary: state.periodSummary, t: t }),
|
|
584
|
+
h(GreetingCard, { greeting: state.greeting, periodSummary: state.periodSummary, t: t, nonce: props && props.nonce }),
|
|
585
|
+
// 跨工作区总结(所有工作区的小总结 + 区内细分)
|
|
586
|
+
h('div', { style: { marginTop: '10px' } },
|
|
587
|
+
h('div', { style: { fontWeight: 700, fontSize: 'calc(12.5px * var(--dam-scale))', opacity: 0.75, marginBottom: '6px' } }, t('wsOverview')),
|
|
588
|
+
wsData && wsData.workspaces && wsData.workspaces.length
|
|
589
|
+
? wsData.workspaces.map(function (ws) {
|
|
590
|
+
return h('div', { key: ws.path, style: { border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.22)) 60%, transparent)', borderRadius: '8px', padding: '7px 9px', marginBottom: '6px', background: 'color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.05)) 40%, transparent)' } },
|
|
591
|
+
h('div', { style: { fontWeight: 600, fontSize: 'calc(12px * var(--dam-scale))' } }, ws.name + (ws.dateRange ? ' · ' + ws.dateRange : '')),
|
|
592
|
+
ws.summary ? h('div', { style: { fontSize: 'calc(12px * var(--dam-scale))', lineHeight: 1.5, marginTop: '3px' } }, ws.summary) : h('div', { 'data-dam-hint': '' }, t('wsNoSummary')),
|
|
593
|
+
(ws.items && ws.items.length) ? ws.items.map(function (it, i) {
|
|
594
|
+
return h('div', { key: i, style: { fontSize: 'calc(11.5px * var(--dam-scale))', marginTop: '2px', opacity: 0.75 } }, '· ' + it)
|
|
595
|
+
}) : null)
|
|
596
|
+
})
|
|
597
|
+
: h('div', { 'data-dam-hint': '' }, t('wsGenerating'))),
|
|
477
598
|
state.pendingReflection
|
|
478
599
|
? h(Banner, null, t('pendingReflection') + state.pendingReflection + t('pendingReflectionHint'))
|
|
479
600
|
: null,
|
|
@@ -482,6 +603,12 @@ window.__ModuleLoader__.load({
|
|
|
482
603
|
h('b', null, t('todayWork')), h('span', null, state.todayEntries + t('logEntries')),
|
|
483
604
|
h('b', null, t('dailyReflection')), h('span', null, state.latestReflectionDate || t('notYet')),
|
|
484
605
|
h('b', null, t('workspace')), h('span', null, state.ws)),
|
|
606
|
+
// 自动沉淀即时反馈(本轮/今日沉淀了多少条、最近一次时间)
|
|
607
|
+
state.autoStats && state.autoStats.count > 0
|
|
608
|
+
? h('div', { 'data-dam-hint': '', style: { marginTop: '2px' } },
|
|
609
|
+
t('autoSettledToday') + state.autoStats.count + t('autoSettledSuffix') +
|
|
610
|
+
(state.autoStats.lastAt ? ' (' + t('autoSettledRecent') + new Date(state.autoStats.lastAt).toLocaleTimeString() + ')' : ''))
|
|
611
|
+
: h('div', { 'data-dam-hint': '', style: { marginTop: '2px' } }, t('autoSettledNone')),
|
|
485
612
|
// 快捷操作
|
|
486
613
|
h('div', { 'data-dam-row': '' },
|
|
487
614
|
h('button', { 'data-dam-btn': '', onClick: oneClickReflect, disabled: reflectBusy }, reflectBusy ? t('reflecting') : t('oneClickReflect')),
|
|
@@ -641,22 +768,69 @@ window.__ModuleLoader__.load({
|
|
|
641
768
|
var resultPair = useState(null)
|
|
642
769
|
var result = resultPair[0]
|
|
643
770
|
var setResult = resultPair[1]
|
|
771
|
+
var smartPair = useState(null)
|
|
772
|
+
var smart = smartPair[0]
|
|
773
|
+
var setSmart = smartPair[1]
|
|
644
774
|
var busyPair = useState(false)
|
|
645
775
|
var busy = busyPair[0]
|
|
646
776
|
var setBusy = busyPair[1]
|
|
647
777
|
function search() {
|
|
648
778
|
if (!q.trim() || busy) return
|
|
649
|
-
setBusy(true); setResult(null)
|
|
779
|
+
setBusy(true); setResult(null); setSmart(null)
|
|
650
780
|
apiPost(API.recall, { query: q.trim() }).then(function (d) { setResult(d.result); setBusy(false) })
|
|
651
781
|
.catch(function (e) { setResult(t('searchFailed') + e.message); setBusy(false) })
|
|
652
782
|
}
|
|
783
|
+
function smartSearch() {
|
|
784
|
+
if (!q.trim() || busy) return
|
|
785
|
+
setBusy(true); setResult(null); setSmart(null)
|
|
786
|
+
apiPost(API.smartRecall, { query: q.trim() }).then(function (d) { setSmart(d); setBusy(false) })
|
|
787
|
+
.catch(function (e) { setSmart({ answer: t('searchFailed') + e.message, keywords: [], hits: [] }); setBusy(false) })
|
|
788
|
+
}
|
|
653
789
|
return h('div', null,
|
|
654
790
|
h('div', { 'data-dam-row': '' },
|
|
655
791
|
h('input', { 'data-dam-input': '', placeholder: t('searchPlaceholder'), value: q, onChange: function (e) { setQ(e.target.value) }, onKeyDown: function (e) { if (e.key === 'Enter') search() } }),
|
|
656
|
-
h('button', { 'data-dam-btn': '', onClick: search, disabled: busy }, t('searchBtn'))
|
|
792
|
+
h('button', { 'data-dam-btn': '', onClick: search, disabled: busy }, t('searchBtn')),
|
|
793
|
+
h('button', { 'data-dam-btn': '', onClick: smartSearch, disabled: busy }, t('smartSearch'))),
|
|
794
|
+
smart ? h(Card, { title: t('smartAnswer') },
|
|
795
|
+
h('div', { 'data-dam-content': '' }, smart.answer || t('empty')),
|
|
796
|
+
smart.keywords && smart.keywords.length ? h('div', { 'data-dam-hint': '', style: { marginTop: '6px' } }, t('keywordsLabel') + smart.keywords.join(' / ')) : null,
|
|
797
|
+
smart.hits && smart.hits.length ? h('div', { 'data-dam-hint': '', style: { marginTop: '6px' } },
|
|
798
|
+
smart.hits.map(function (h, i) { return h('div', { key: i, style: { marginTop: '3px' } }, '· [' + h.where + '] ' + h.line) })) : null)
|
|
799
|
+
: null,
|
|
657
800
|
result ? h(Card, { title: t('resultTitle') }, h('div', { 'data-dam-content': '' }, result)) : null)
|
|
658
801
|
}
|
|
659
802
|
|
|
803
|
+
// ───────────────────────── 工作区总览页签(跨工作区全局总结) ─────────────────────────
|
|
804
|
+
function WorkspaceTab() {
|
|
805
|
+
var dataPair = useState(null)
|
|
806
|
+
var data = dataPair[0]
|
|
807
|
+
var setData = dataPair[1]
|
|
808
|
+
var busyPair = useState(false)
|
|
809
|
+
var busy = busyPair[0]
|
|
810
|
+
var setBusy = busyPair[1]
|
|
811
|
+
function load(force) {
|
|
812
|
+
if (busy) return
|
|
813
|
+
setBusy(true)
|
|
814
|
+
apiPost(API.workspaces, { force: !!force }).then(function (d) { if (d) setData(d); setBusy(false) })
|
|
815
|
+
.catch(function () { setBusy(false) })
|
|
816
|
+
}
|
|
817
|
+
useEffect(function () { load(false) }, [])
|
|
818
|
+
if (!data) return h('div', null, busy ? h('div', { 'data-dam-hint': '' }, t('wsGenerating')) : h(Loading))
|
|
819
|
+
return h('div', null,
|
|
820
|
+
h('div', { 'data-dam-row': '' },
|
|
821
|
+
h('button', { 'data-dam-btn': '', onClick: function () { load(true) }, disabled: busy }, busy ? t('refreshing') : t('refresh')),
|
|
822
|
+
h('span', { 'data-dam-hint': '' }, data.cached ? (t('generatedAt') + new Date(data.generatedAt).toLocaleTimeString()) : '')),
|
|
823
|
+
(data.workspaces && data.workspaces.length) ? data.workspaces.map(function (ws) {
|
|
824
|
+
return h(Card, { key: ws.path, title: ws.name + (ws.dateRange ? ' · ' + ws.dateRange : '') },
|
|
825
|
+
ws.summary ? h('div', { 'data-dam-content': '' }, ws.summary) : h('div', { 'data-dam-hint': '' }, t('wsNoSummary')),
|
|
826
|
+
(ws.items && ws.items.length) ? h('div', { style: { marginTop: '6px' } },
|
|
827
|
+
ws.items.map(function (it, i) {
|
|
828
|
+
return h('div', { key: i, style: { fontSize: 'calc(12px * var(--dam-scale))', marginTop: '3px', lineHeight: 1.5 } }, '· ' + it)
|
|
829
|
+
})) : null,
|
|
830
|
+
h('div', { 'data-dam-hint': '', style: { marginTop: '4px' } }, ws.path + ' · ' + (ws.logCount || 0) + t('logEntries')))
|
|
831
|
+
}) : h('div', { 'data-dam-hint': '' }, t('wsNone')))
|
|
832
|
+
}
|
|
833
|
+
|
|
660
834
|
// ───────────────────────── 日历页签 ─────────────────────────
|
|
661
835
|
var QUADRANT_STYLE = {
|
|
662
836
|
'重要紧急': { color: 'var(--dsw-alias-state-error-primary, #d64545)', label: t('qUrgentImportant') },
|
|
@@ -716,12 +890,12 @@ window.__ModuleLoader__.load({
|
|
|
716
890
|
// 图例
|
|
717
891
|
rows.push(h('div', { 'data-dam-row': '', style: { flexWrap: 'wrap' } },
|
|
718
892
|
Object.keys(QUADRANT_STYLE).map(function (q) {
|
|
719
|
-
return h('span', { key: q, style: { fontSize: '11px', opacity: 0.8, marginRight: '10px' } },
|
|
893
|
+
return h('span', { key: q, style: { fontSize: 'calc(11px * var(--dam-scale))', opacity: 0.8, marginRight: '10px' } },
|
|
720
894
|
h('span', { style: { display: 'inline-block', width: 8, height: 8, borderRadius: 2, background: QUADRANT_STYLE[q].color, marginRight: 4 } }), QUADRANT_STYLE[q].label)
|
|
721
895
|
})))
|
|
722
896
|
// 星期表头
|
|
723
897
|
rows.push(h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '3px', marginBottom: '4px' } },
|
|
724
|
-
dowLabels.map(function (dl) { return h('div', { key: dl, style: { textAlign: 'center', fontSize: '11px', opacity: 0.55 } }, dl) })))
|
|
898
|
+
dowLabels.map(function (dl) { return h('div', { key: dl, style: { textAlign: 'center', fontSize: 'calc(11px * var(--dam-scale))', opacity: 0.55 } }, dl) })))
|
|
725
899
|
// 日历格子
|
|
726
900
|
var gridRows = []
|
|
727
901
|
for (var ci = 0; ci < cells.length; ci += 7) {
|
|
@@ -742,7 +916,7 @@ window.__ModuleLoader__.load({
|
|
|
742
916
|
overflow: 'hidden',
|
|
743
917
|
},
|
|
744
918
|
},
|
|
745
|
-
h('div', { style: { fontSize: '11.5px', fontWeight: isToday ? 700 : 500, opacity: isToday ? 1 : 0.7, marginBottom: '3px' } }, dayNum),
|
|
919
|
+
h('div', { style: { fontSize: 'calc(11.5px * var(--dam-scale))', fontWeight: isToday ? 700 : 500, opacity: isToday ? 1 : 0.7, marginBottom: '3px' } }, dayNum),
|
|
746
920
|
es.slice(0, 3).map(function (en) {
|
|
747
921
|
var qs = QUADRANT_STYLE[en.quadrant] || QUADRANT_STYLE['未分类']
|
|
748
922
|
return h('div', {
|
|
@@ -750,14 +924,14 @@ window.__ModuleLoader__.load({
|
|
|
750
924
|
title: en.time + ' ' + en.title,
|
|
751
925
|
onClick: function (ev) { ev.stopPropagation(); toggleDone(en) },
|
|
752
926
|
style: {
|
|
753
|
-
fontSize: '10.5px', lineHeight: 1.35, padding: '1px 4px', borderRadius: 4, marginBottom: 2,
|
|
927
|
+
fontSize: 'calc(10.5px * var(--dam-scale))', lineHeight: 1.35, padding: '1px 4px', borderRadius: 4, marginBottom: 2,
|
|
754
928
|
background: 'color-mix(in srgb, ' + qs.color + ' 18%, transparent)',
|
|
755
929
|
color: qs.color, textDecoration: en.done ? 'line-through' : 'none',
|
|
756
930
|
opacity: en.done ? 0.5 : 1, cursor: 'pointer', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
|
|
757
931
|
},
|
|
758
932
|
}, (en.time && en.time !== '--:--' ? en.time + ' ' : '') + en.title)
|
|
759
933
|
}),
|
|
760
|
-
es.length > 3 ? h('div', { style: { fontSize: '10px', opacity: 0.5 } }, '+' + (es.length - 3)) : null))
|
|
934
|
+
es.length > 3 ? h('div', { style: { fontSize: 'calc(10px * var(--dam-scale))', opacity: 0.5 } }, '+' + (es.length - 3)) : null))
|
|
761
935
|
})(cells[ci + cj])
|
|
762
936
|
}
|
|
763
937
|
gridRows.push(h('div', { key: 'w' + ci, style: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: '3px' } }, week))
|
|
@@ -897,23 +1071,29 @@ window.__ModuleLoader__.load({
|
|
|
897
1071
|
var tabPair = useState('overview')
|
|
898
1072
|
var tab = tabPair[0]
|
|
899
1073
|
var setTab = tabPair[1]
|
|
1074
|
+
// 刷新 nonce:每次打开面板 / 点 ⟳ 时递增,驱动各页签重拉数据
|
|
1075
|
+
var noncePair = useState(0)
|
|
1076
|
+
var nonce = noncePair[0]
|
|
1077
|
+
var setNonce = noncePair[1]
|
|
900
1078
|
var g = controller.geom()
|
|
901
1079
|
useEffect(function () { return controller.subscribe(tick[1]) }, [])
|
|
902
1080
|
if (!panelOpen && !panelClosing) return null
|
|
903
1081
|
var body
|
|
904
|
-
if (tab === 'overview') body = h(OverviewTab)
|
|
1082
|
+
if (tab === 'overview') body = h(OverviewTab, { nonce: nonce })
|
|
905
1083
|
else if (tab === 'logs') body = h(LogsTab)
|
|
906
1084
|
else if (tab === 'notes') body = h(NotesTab)
|
|
907
1085
|
else if (tab === 'reflections') body = h(ReflectionsTab)
|
|
908
1086
|
else if (tab === 'connect') body = h(ConnectTab)
|
|
909
1087
|
else if (tab === 'calendar') body = h(CalendarTab)
|
|
1088
|
+
else if (tab === 'workspaces') body = h(WorkspaceTab)
|
|
910
1089
|
else body = h(SearchTab)
|
|
911
|
-
var tabs = [['overview', t('overview')], ['logs', t('logs')], ['notes', t('notes')], ['reflections', t('reflections')], ['connect', t('connect')], ['calendar', t('calendar')], ['search', t('search')]]
|
|
1090
|
+
var tabs = [['overview', t('overview')], ['logs', t('logs')], ['notes', t('notes')], ['reflections', t('reflections')], ['connect', t('connect')], ['calendar', t('calendar')], ['search', t('search')], ['workspaces', t('workspaces')]]
|
|
912
1091
|
var style = {
|
|
913
1092
|
left: g.left + 'px',
|
|
914
1093
|
top: g.top + 'px',
|
|
915
1094
|
width: g.width + 'px',
|
|
916
1095
|
height: g.height + 'px',
|
|
1096
|
+
'--dam-scale': FONT_SCALE_VALUES[fontScale] || '1',
|
|
917
1097
|
}
|
|
918
1098
|
var dragMove = startPointerDrag(function (dx, dy) {
|
|
919
1099
|
controller.setGeom({ left: g.left + dx, top: g.top + dy })
|
|
@@ -923,6 +1103,7 @@ window.__ModuleLoader__.load({
|
|
|
923
1103
|
})
|
|
924
1104
|
return h('div', {
|
|
925
1105
|
'data-dam-panel': '',
|
|
1106
|
+
'data-scale': fontScale in FONT_SCALES ? fontScale : 'md',
|
|
926
1107
|
style: style,
|
|
927
1108
|
'data-closing': panelClosing ? 'true' : undefined,
|
|
928
1109
|
'data-dragging': dragActive ? 'true' : undefined,
|
|
@@ -934,7 +1115,7 @@ window.__ModuleLoader__.load({
|
|
|
934
1115
|
h('strong', null, t('autoMemory')),
|
|
935
1116
|
h('span', { className: 'dam-spacer' }),
|
|
936
1117
|
h('button', { 'data-dam-btn': '', title: t('resetPos'), onClick: function () { controller.resetGeom() } }, '⤾'),
|
|
937
|
-
h('button', { 'data-dam-btn': '', title: t('refresh'), onClick: function () {
|
|
1118
|
+
h('button', { 'data-dam-btn': '', title: t('refresh'), onClick: function () { setNonce(nonce + 1) } }, '⟳'),
|
|
938
1119
|
h('button', { 'data-dam-btn': '', title: t('close'), onClick: function () { controller.close() } }, '✕')),
|
|
939
1120
|
h('div', { 'data-dam-tabs': '' }, tabs.map(function (t) {
|
|
940
1121
|
return h('button', { key: t[0], 'data-dam-tab': '', 'data-active': tab === t[0] ? 'true' : undefined, onClick: function () { setTab(t[0]) } }, t[1])
|
|
@@ -943,10 +1124,70 @@ window.__ModuleLoader__.load({
|
|
|
943
1124
|
h('div', { 'data-dam-resize': '', title: t('dragResize'), onPointerDown: resizeMove }))
|
|
944
1125
|
}
|
|
945
1126
|
|
|
1127
|
+
// ───────────────────────── 调试中心(为提 issue 提供诊断) ─────────────────────────
|
|
1128
|
+
function DebugCenter() {
|
|
1129
|
+
var dataPair = useState(null)
|
|
1130
|
+
var data = dataPair[0]
|
|
1131
|
+
var setData = dataPair[1]
|
|
1132
|
+
var probesPair = useState(null)
|
|
1133
|
+
var probes = probesPair[0]
|
|
1134
|
+
var setProbes = probesPair[1]
|
|
1135
|
+
var busyPair = useState(false)
|
|
1136
|
+
var busy = busyPair[0]
|
|
1137
|
+
var setBusy = busyPair[1]
|
|
1138
|
+
function refresh() {
|
|
1139
|
+
if (busy) return
|
|
1140
|
+
setBusy(true)
|
|
1141
|
+
var probesDone = {}
|
|
1142
|
+
var probeList = [
|
|
1143
|
+
['state', API.state, 'GET'], ['config', API.config, 'GET'], ['list', API.list, 'GET'],
|
|
1144
|
+
['file', API.file, 'GET'], ['calendar', API.calendar, 'GET'], ['debug', API.debug, 'GET'],
|
|
1145
|
+
['recall', API.recall, 'POST'], ['summarize', API.summarize, 'POST'], ['greet', API.greet, 'POST'],
|
|
1146
|
+
['workspaces', API.workspaces, 'POST'], ['reflectAuto', API.reflectAuto, 'POST'],
|
|
1147
|
+
]
|
|
1148
|
+
Promise.all(probeList.map(function (pr) {
|
|
1149
|
+
var t0 = Date.now()
|
|
1150
|
+
return fetch(pr[1], pr[2] === 'POST' ? { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' } : undefined)
|
|
1151
|
+
.then(function (r) { probesDone[pr[0]] = { status: r.status, ms: Date.now() - t0 } })
|
|
1152
|
+
.catch(function (e) { probesDone[pr[0]] = { error: e.message } })
|
|
1153
|
+
})).then(function () {
|
|
1154
|
+
setProbes(probesDone)
|
|
1155
|
+
return apiGet(API.debug)
|
|
1156
|
+
}).then(function (d) { setData(d); setBusy(false) }).catch(function () { setBusy(false) })
|
|
1157
|
+
}
|
|
1158
|
+
useEffect(function () { refresh() }, [])
|
|
1159
|
+
if (!data) return h('div', { 'data-dam-hint': '' }, t('dbgLoading'))
|
|
1160
|
+
function kv(label, value, warn) {
|
|
1161
|
+
return h('div', { 'data-dam-row': '', style: { marginBottom: '3px' } },
|
|
1162
|
+
h('span', { style: { flex: '0 0 140px', opacity: .7, fontSize: 'calc(11.5px * var(--dam-scale))' } }, label),
|
|
1163
|
+
h('span', { style: { fontSize: 'calc(11.5px * var(--dam-scale))', wordBreak: 'break-all', color: warn ? 'var(--dsw-alias-state-warn-primary, #e6a23c)' : undefined } }, String(value)))
|
|
1164
|
+
}
|
|
1165
|
+
var hb = data.heartbeat || {}
|
|
1166
|
+
var hbAge = hb.exists && hb.heartbeatAt ? Math.round((Date.now() - hb.heartbeatAt) / 1000) : -1
|
|
1167
|
+
var apiBad = probes && Object.keys(probes).some(function (k) { return probes[k].status === 404 || probes[k].error })
|
|
1168
|
+
return h('div', null,
|
|
1169
|
+
h('div', { 'data-dam-row': '' },
|
|
1170
|
+
h('button', { 'data-dam-btn': '', onClick: refresh, disabled: busy }, busy ? t('dbgRefreshing') : t('dbgRefresh')),
|
|
1171
|
+
h('span', { 'data-dam-hint': '' }, data.host.indexPath || '')),
|
|
1172
|
+
kv('插件版本', data.host.version || '(读不到)', false),
|
|
1173
|
+
kv('PID / 启动', data.host.pid + ' / ' + (data.host.startTime ? new Date(data.host.startTime).toLocaleTimeString() : ''), false),
|
|
1174
|
+
kv('Host 需重启?', data.host.needsRestart ? '是(代码比进程新)' : '否', data.host.needsRestart),
|
|
1175
|
+
kv('轮询心跳', hb.exists ? (hbAge >= 0 ? '存活(上次 ' + hbAge + ' 秒前)' : '存活') : '无心跳文件', !hb.exists || hbAge > 360),
|
|
1176
|
+
kv('沉淀重试队列', data.autoConsolidate.pendingQueue + ' 条', data.autoConsolidate.pendingQueue > 0),
|
|
1177
|
+
kv('今日沉淀', data.autoConsolidate.stats.count + ' 条 / 最近 ' + (data.autoConsolidate.stats.lastAt ? new Date(data.autoConsolidate.stats.lastAt).toLocaleTimeString() : '无'), false),
|
|
1178
|
+
kv('正在沉淀中', data.autoConsolidate.consolidating ? '是' : '否', data.autoConsolidate.consolidating),
|
|
1179
|
+
kv('subagents', data.subagents.available ? (data.subagents.providers.join(', ') || '可用') : '不可用', !data.subagents.available),
|
|
1180
|
+
kv('项目笔记重复标题', data.duplicateHeadings + ' 个', data.duplicateHeadings > 0),
|
|
1181
|
+
kv('记忆文件', '用户 ' + (data.memoryFiles.user.exists ? fmtSize(data.memoryFiles.user.size) : '缺失') + ' · 笔记 ' + (data.memoryFiles.notes.exists ? fmtSize(data.memoryFiles.notes.size) : '缺失') + ' · 日志 ' + (data.memoryFiles.log.exists ? fmtSize(data.memoryFiles.log.size) : '缺失'), !data.memoryFiles.log.exists),
|
|
1182
|
+
kv('当前工作区', currentWs() || '(未取到)', false),
|
|
1183
|
+
kv('API 连通', probes ? Object.keys(probes).map(function (k) { return k + '=' + (probes[k].status !== undefined ? probes[k].status : probes[k].error) }).join(' ') : '…', apiBad))
|
|
1184
|
+
}
|
|
1185
|
+
|
|
946
1186
|
// ───────────────────────── 设置页 ─────────────────────────
|
|
947
1187
|
var STYLE_OPTIONS = [['auto', t('styleAuto')], ['life', t('styleLife')], ['professional', t('styleProfessional')]]
|
|
948
1188
|
var LOCALE_OPTIONS = [['zh', t('zh')], ['en', t('en')]]
|
|
949
1189
|
function SettingsPage() {
|
|
1190
|
+
var tickPair = useTick()
|
|
950
1191
|
var cfgPair = useState(null)
|
|
951
1192
|
var cfg = cfgPair[0]
|
|
952
1193
|
var setCfg = cfgPair[1]
|
|
@@ -959,6 +1200,47 @@ window.__ModuleLoader__.load({
|
|
|
959
1200
|
var errPair = useState('')
|
|
960
1201
|
var err = errPair[0]
|
|
961
1202
|
var setErr = errPair[1]
|
|
1203
|
+
var dbgOpenPair = useState(false)
|
|
1204
|
+
var dbgOpen = dbgOpenPair[0]
|
|
1205
|
+
var setDbgOpen = dbgOpenPair[1]
|
|
1206
|
+
var browseOpenPair = useState(false)
|
|
1207
|
+
var browseOpen = browseOpenPair[0]
|
|
1208
|
+
var setBrowseOpen = browseOpenPair[1]
|
|
1209
|
+
var browsePathPair = useState('')
|
|
1210
|
+
var browsePath = browsePathPair[0]
|
|
1211
|
+
var setBrowsePath = browsePathPair[1]
|
|
1212
|
+
var browseParentPair = useState('')
|
|
1213
|
+
var browseParent = browseParentPair[0]
|
|
1214
|
+
var setBrowseParent = browseParentPair[1]
|
|
1215
|
+
var browseDirsPair = useState(null)
|
|
1216
|
+
var browseDirs = browseDirsPair[0]
|
|
1217
|
+
var setBrowseDirs = browseDirsPair[1]
|
|
1218
|
+
function browseTo(p) {
|
|
1219
|
+
setBrowsePath(p)
|
|
1220
|
+
apiPost(API.browseDir, { path: p }).then(function (d) {
|
|
1221
|
+
if (d) { setBrowsePath(d.path); setBrowseParent(d.parent); setBrowseDirs(d.dirs || []) }
|
|
1222
|
+
}).catch(function () { setBrowseDirs([]) })
|
|
1223
|
+
}
|
|
1224
|
+
function openBrowser() {
|
|
1225
|
+
// 优先弹系统原生文件夹选择器(native 后端);不可用(远程/无显示)回退内嵌浏览
|
|
1226
|
+
apiPost(API.pickDir, {}).then(function (d) {
|
|
1227
|
+
if (d && d.native && d.dir) {
|
|
1228
|
+
set('memoryRoot', d.dir)
|
|
1229
|
+
setMsg(t('pickedDir') + ' ' + d.dir + ' ' + t('rememberSave'))
|
|
1230
|
+
} else if (d && d.native) {
|
|
1231
|
+
// 用户在系统对话框点了取消:保持原值,不动作
|
|
1232
|
+
} else {
|
|
1233
|
+
setMsg(t('pickerUnavailable'))
|
|
1234
|
+
setBrowseOpen(true)
|
|
1235
|
+
browseTo(cfg.memoryRoot || '')
|
|
1236
|
+
}
|
|
1237
|
+
}).catch(function () {
|
|
1238
|
+
setMsg(t('pickerUnavailable'))
|
|
1239
|
+
setBrowseOpen(true)
|
|
1240
|
+
browseTo(cfg.memoryRoot || '')
|
|
1241
|
+
})
|
|
1242
|
+
}
|
|
1243
|
+
useEffect(function () { return controller.subscribe(tickPair[1]) }, [])
|
|
962
1244
|
useEffect(function () {
|
|
963
1245
|
var alive = true
|
|
964
1246
|
apiGet(API.config).then(function (d) { if (alive) setCfg(d.config) }).catch(function (e) { setErr(e.message) })
|
|
@@ -969,7 +1251,7 @@ window.__ModuleLoader__.load({
|
|
|
969
1251
|
function save() {
|
|
970
1252
|
if (busy) return
|
|
971
1253
|
setBusy(true); setMsg(''); setErr('')
|
|
972
|
-
apiPost(API.config, cfg).then(function (d) { setCfg(d.config); setMsg(t('saved')); setBusy(false) })
|
|
1254
|
+
apiPost(API.config, cfg).then(function (d) { setCfg(d.config); setMsg(t('saved') + (d.migrated ? ' ' + d.migrated : '')); setBusy(false) })
|
|
973
1255
|
.catch(function (e) { setErr(e.message); setBusy(false) })
|
|
974
1256
|
}
|
|
975
1257
|
function field(label, control, hint) {
|
|
@@ -981,17 +1263,39 @@ window.__ModuleLoader__.load({
|
|
|
981
1263
|
h('div', { 'data-dam-hint': '' }, t('settingsHeader')),
|
|
982
1264
|
field(t('fLocale'), h('select', { 'data-dam-select': '', value: cfg.locale || 'zh', onChange: function (e) { set('locale', e.target.value); setLocale(e.target.value) } },
|
|
983
1265
|
LOCALE_OPTIONS.map(function (o) { return h('option', { key: o[0], value: o[0] }, o[1]) })), t('fLocaleHint')),
|
|
1266
|
+
field(t('fFontSize'), h('select', { 'data-dam-select': '', value: fontScale, onChange: function (e) { fontScale = e.target.value; try { localStorage.setItem('dsh-auto-memory.fontScale.v2', fontScale) } catch (ee) {}; try { var pp = document.querySelector('[data-dam-panel]'); if (pp) pp.style.setProperty('--dam-scale', FONT_SCALE_VALUES[fontScale] || '1') } catch (ee2) {}; emit() } },
|
|
1267
|
+
Object.keys(FONT_SCALES).map(function (k) { return h('option', { key: k, value: k }, t('fs' + k.charAt(0).toUpperCase() + k.slice(1))) })), t('fFontSizeHint')),
|
|
984
1268
|
field(t('fUserDir'), h('input', { 'data-dam-input': '', value: cfg.userMemoryDir, onChange: function (e) { set('userMemoryDir', e.target.value) } }), t('fUserDirHint')),
|
|
985
1269
|
field(t('fProjectDir'), h('input', { 'data-dam-input': '', value: cfg.projectMemoryDir, onChange: function (e) { set('projectMemoryDir', e.target.value) } }), t('fProjectDirHint')),
|
|
1270
|
+
field(t('fMemoryRoot'), h('div', { 'data-dam-row': '', style: { flex: 1 } },
|
|
1271
|
+
h('input', { 'data-dam-input': '', style: { flex: 1 }, value: cfg.memoryRoot || '', onChange: function (e) { set('memoryRoot', e.target.value) } }),
|
|
1272
|
+
h('button', { 'data-dam-btn': '', onClick: function () { openBrowser() } }, t('fBrowse'))), t('fMemoryRootHint')),
|
|
1273
|
+
browseOpen ? h('div', { style: { border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.25)) 60%, transparent)', borderRadius: '8px', padding: '8px', marginBottom: '8px', background: 'color-mix(in srgb, var(--dsw-alias-bg-layer-1, rgba(128,128,128,.06)) 40%, transparent)' } },
|
|
1274
|
+
h('div', { 'data-dam-row': '' },
|
|
1275
|
+
h('b', { style: { fontSize: 'calc(12px * var(--dam-scale))', wordBreak: 'break-all', flex: 1 } }, browsePath || '…'),
|
|
1276
|
+
h('button', { 'data-dam-btn': '', onClick: function () { browseTo(browseParent) }, disabled: browseParent === browsePath }, t('fUp'))),
|
|
1277
|
+
h('div', { style: { maxHeight: '160px', overflow: 'auto', marginTop: '4px' } },
|
|
1278
|
+
(browseDirs || []).map(function (d) {
|
|
1279
|
+
return h('button', { key: d.path, 'data-dam-btn': '', style: { display: 'block', width: '100%', textAlign: 'left', padding: '3px 6px' }, onClick: function () { browseTo(d.path) } }, '📁 ' + d.name)
|
|
1280
|
+
}).concat(browseDirs && !browseDirs.length ? [h('div', { key: 'e', 'data-dam-hint': '' }, t('empty'))] : [])),
|
|
1281
|
+
h('div', { 'data-dam-row': '', style: { marginTop: '6px' } },
|
|
1282
|
+
h('button', { 'data-dam-btn': '', onClick: function () { set('memoryRoot', browsePath); setBrowseOpen(false) } }, t('fSelectDir')),
|
|
1283
|
+
h('button', { 'data-dam-btn': '', onClick: function () { setBrowseOpen(false) } }, t('close'))))
|
|
1284
|
+
: null,
|
|
986
1285
|
field(t('fInject'), h('input', { type: 'checkbox', checked: !!cfg.injectEnabled, onChange: function (e) { set('injectEnabled', e.target.checked) } }), t('fInjectHint')),
|
|
987
1286
|
field(t('fBudget'), h('input', { 'data-dam-input': '', type: 'number', min: 400, value: cfg.injectBudgetChars, onChange: function (e) { set('injectBudgetChars', Number(e.target.value) || 2400) } }), t('fBudgetHint')),
|
|
988
1287
|
field(t('fDays'), h('input', { 'data-dam-input': '', type: 'number', min: 1, max: 14, value: cfg.recentDaysInjected, onChange: function (e) { set('recentDaysInjected', Number(e.target.value) || 3) } }), t('fDaysHint')),
|
|
1288
|
+
field(t('fDayBoundary'), h('input', { 'data-dam-input': '', type: 'number', min: 0, max: 1439, value: (cfg.dayBoundaryMinutes === undefined ? 450 : cfg.dayBoundaryMinutes), onChange: function (e) { set('dayBoundaryMinutes', parseInt(e.target.value || '0', 10)) } }), t('fDayBoundaryHint')),
|
|
989
1289
|
field(t('fReflect'), h('input', { type: 'checkbox', checked: !!cfg.reflectEnabled, onChange: function (e) { set('reflectEnabled', e.target.checked) } }), t('fReflectHint')),
|
|
990
1290
|
field(t('fStyle'), h('select', { 'data-dam-select': '', value: cfg.reflectStyle, onChange: function (e) { set('reflectStyle', e.target.value) } },
|
|
991
1291
|
STYLE_OPTIONS.map(function (o) { return h('option', { key: o[0], value: o[0] }, o[1]) })), t('fStyleHint')),
|
|
992
1292
|
h('div', { 'data-dam-row': '' },
|
|
993
1293
|
h('button', { 'data-dam-btn': '', onClick: save, disabled: busy }, busy ? t('saving') : t('saveSettings')),
|
|
994
1294
|
msg ? h('span', null, msg) : null),
|
|
1295
|
+
// 调试中心(折叠):模块状态一览,方便排查问题/提 issue
|
|
1296
|
+
h('div', { style: { marginTop: '14px', borderTop: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.2)) 55%, transparent)', paddingTop: '10px' } },
|
|
1297
|
+
h('button', { 'data-dam-btn': '', onClick: function () { setDbgOpen(!dbgOpen) } }, (dbgOpen ? '▴ ' : '▾ ') + t('debugCenter')),
|
|
1298
|
+
dbgOpen ? h('div', { style: { marginTop: '8px' } }, h(DebugCenter)) : null),
|
|
995
1299
|
err ? h('div', { 'data-dam-error': '' }, err) : null)
|
|
996
1300
|
}
|
|
997
1301
|
|
|
@@ -1008,7 +1312,13 @@ window.__ModuleLoader__.load({
|
|
|
1008
1312
|
|
|
1009
1313
|
var slots = ctx.slots
|
|
1010
1314
|
if (!slots) { console.warn('[dsh-auto-memory] slots service unavailable'); return }
|
|
1315
|
+
sessions = ctx.sessions
|
|
1011
1316
|
|
|
1317
|
+
// 初始化界面字号(本地偏好,localStorage 持久化)
|
|
1318
|
+
try {
|
|
1319
|
+
var savedScale = localStorage.getItem('dsh-auto-memory.fontScale.v2')
|
|
1320
|
+
if (savedScale in FONT_SCALES) fontScale = savedScale
|
|
1321
|
+
} catch (e3) {}
|
|
1012
1322
|
// 初始化界面语言(从 host 配置读取,持久化到 localStorage 以便即时生效)
|
|
1013
1323
|
try {
|
|
1014
1324
|
var savedLocale = localStorage.getItem('dsh-auto-memory.locale')
|
|
@@ -1039,7 +1349,7 @@ window.__ModuleLoader__.load({
|
|
|
1039
1349
|
console.log('[dsh-auto-memory] client ready: sidebar entry + panel + settings page')
|
|
1040
1350
|
}
|
|
1041
1351
|
|
|
1042
|
-
exports.inject = ['slots']
|
|
1352
|
+
exports.inject = ['slots', 'sessions']
|
|
1043
1353
|
exports.apply = apply
|
|
1044
1354
|
return module.exports
|
|
1045
1355
|
},
|