@a9i5k4/dsh-auto-memory 0.1.13 → 0.1.14

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.
Files changed (2) hide show
  1. package/lib/client.js +131 -9
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -86,6 +86,8 @@ window.__ModuleLoader__.load({
86
86
  panelClosing = true; emit()
87
87
  closeTimer = setTimeout(function () {
88
88
  panelOpen = false; panelClosing = false; closeTimer = null; emit()
89
+ // 面板关闭时记录本次活动时间:离开>1小时再回来时自动弹开+欢迎语
90
+ try { localStorage.setItem('dsh-auto-memory.lastActive', String(Date.now())) } catch (e) {}
89
91
  }, 170)
90
92
  },
91
93
  subscribe: function (fn) { listeners.add(fn); return function () { listeners.delete(fn) } },
@@ -113,6 +115,15 @@ window.__ModuleLoader__.load({
113
115
  kvAvail: '可用', kvUnavail: '不可用', kvDup: '项目笔记重复标题', kvDupCount: ' 个',
114
116
  kvMem: '记忆文件', kvMemUser: '用户', kvMemNotes: '笔记', kvMemLog: '日志', kvMemMissing: '缺失',
115
117
  kvWs: '当前工作区', kvWsUnknown: '(未取到)', kvApi: 'API 连通', unknown: '(未知)',
118
+ guideTitle: '欢迎使用 dsh-auto-memory', guideSub: '这个插件能干什么:',
119
+ gFeat1: '三层记忆自动注入与检索:用户级 / 项目笔记 / 每日日志,每轮对话自动读、自动写',
120
+ gFeat2: '每轮对话结束自动沉淀:修了什么 bug、做了哪些决策,自动按主题写进今日日志',
121
+ gFeat3: 'AI 时段问候与三级抽屉:打开「记忆」面板,AI 按时段向你汇报当天进展',
122
+ gFeat4: '智能检索与日历:自然语言提问找记忆;AI 自动把 deadline 记进日历并提醒',
123
+ gFeat5: '接续其他 AI 工具的记忆:CodeBuddy / Claude Code / Codex 等的历史记忆一键接入',
124
+ gFeat6: '自动检查更新:启动时检测新版本,设置页可一键更新',
125
+ guideTip: '打开侧边栏「记忆」按钮即可使用;所有记忆都是本地明文文件,可随时查看修改。',
126
+ updateTitle: 'dsh-auto-memory 已更新', updateSub: '本次更新内容:', gotIt: '知道了',
116
127
  refresh: '刷新', refreshing: '刷新中…', close: '关闭', dragMove: '拖动移动', dragResize: '拖动调整大小', resetPos: '恢复默认位置',
117
128
  generated: '已生成', failed: '失败: ',
118
129
  generatedAt: '生成于 ',
@@ -194,6 +205,15 @@ window.__ModuleLoader__.load({
194
205
  kvAvail: 'available', kvUnavail: 'unavailable', kvDup: 'Duplicate note headings', kvDupCount: '',
195
206
  kvMem: 'Memory files', kvMemUser: 'user', kvMemNotes: 'notes', kvMemLog: 'log', kvMemMissing: 'missing',
196
207
  kvWs: 'Current workspace', kvWsUnknown: '(unknown)', kvApi: 'API probes', unknown: '(unknown)',
208
+ guideTitle: 'Welcome to dsh-auto-memory', guideSub: 'What this plugin does:',
209
+ gFeat1: 'Three-layer memory with automatic injection & retrieval: user / project notes / daily logs',
210
+ gFeat2: 'Auto-consolidation after every turn: bugs fixed and decisions made are written into today\'s log automatically',
211
+ gFeat3: 'AI period greetings with three-level drawers: open the Memory panel for a period-by-period digest',
212
+ gFeat4: 'Smart search & calendar: ask in natural language; AI files deadlines into the calendar and reminds you',
213
+ gFeat5: 'Inherit memories from other AI tools: CodeBuddy / Claude Code / Codex etc. in one click',
214
+ gFeat6: 'Auto update check at boot, one-click update in settings',
215
+ guideTip: 'Click the Memory button in the sidebar to start; all memories are plain local Markdown files you can inspect anytime.',
216
+ updateTitle: 'dsh-auto-memory Updated', updateSub: 'What\'s new in this update:', gotIt: 'Got it',
197
217
  refresh: 'Refresh', refreshing: 'Refreshing…', close: 'Close', dragMove: 'Drag to move', dragResize: 'Drag to resize', resetPos: 'Reset position',
198
218
  generated: 'Generated', failed: 'Failed: ',
199
219
  generatedAt: 'Generated ',
@@ -284,6 +304,40 @@ window.__ModuleLoader__.load({
284
304
  function t(key) { return (I18N[locale] && I18N[locale][key]) || I18N.zh[key] || key }
285
305
  function setLocale(l) { if (l !== 'zh' && l !== 'en') return; if (l === locale) return; locale = l; localeListeners.forEach(function (fn) { try { fn(l) } catch (e) {} }) }
286
306
  function onLocale(fn) { localeListeners.add(fn); return function () { localeListeners.delete(fn) } }
307
+ // 暂离检测:距离上次关闭面板超过 1 小时视为暂离回来
308
+ function isAway() {
309
+ var lastSeen = 0
310
+ try { lastSeen = Number(localStorage.getItem('dsh-auto-memory.lastActive') || 0) } catch (e) {}
311
+ return lastSeen > 0 && (Date.now() - lastSeen) > 3600000
312
+ }
313
+
314
+ // ───────────────────────── 更新弹窗 / 首次指导 ─────────────────────────
315
+ var CHANGELOG = {
316
+ '0.1.14': { zh: ['新增:更新后自动弹出更新说明窗口,首次安装有功能指导窗口', '新增:暂离超过 1 小时回来,记忆窗口自动打开并显示 AI 总结', '优化:弹窗改为左下角毛玻璃小卡片,更透明更轻量'], en: ['New: update dialog shows what changed after an upgrade; first-run guide dialog for new installs', 'New: the memory panel auto-opens with an AI summary after returning from >1h away', 'Polish: dialogs are now compact frosted-glass cards in the bottom-left corner'] },
317
+ '0.1.13': { zh: ['修复 npm 安装后客户端面板无法加载(bundle 注册名拼写)', '修复秒级时间戳击穿 DeepSeek 前缀缓存(改日期级,大幅节省 token)', '修复记忆接续导入报错'], en: ['Fix client panel not loading after npm install (bundle registration id)', 'Fix second-level timestamp breaking DeepSeek prefix cache (date-level now, big token savings)', 'Fix memory import error (inherit external memory)'] },
318
+ '0.1.12': { zh: ['声明 @deepseek-ai/cordis 为 peerDependency(插件市场收录规范)'], en: ['Declare @deepseek-ai/cordis as peerDependency (plugin market checklist)'] },
319
+ '0.1.11': { zh: ['界面语言跟随 DSH 系统语言,实时切换', 'README 重构:宣传图/真实截图/快速安装', '修复设置页加载崩溃'], en: ['UI language follows the DSH system language', 'README overhaul: banner, real screenshots, quick install', 'Fix settings page crash'] },
320
+ '0.1.10': { zh: ['自动检查更新 + 设置页一键更新', '日界:凌晨的活儿归前一天(默认 7:30)', '记忆根目录系统文件夹选择器,换位置自动迁移', '每日写入预算,超限自动压缩旧内容', '30 天 AI 蒸馏'], en: ['Auto update check + one-click update in settings', 'Day boundary: late-night work logs to yesterday (default 07:30)', 'Native OS folder picker for memory root, auto-migration', 'Daily write budget with auto-compaction', '30-day AI distillation'] },
321
+ }
322
+ var dialogListeners = new Set()
323
+ var dialogState = null // {kind:'update', versions:[...]} | {kind:'first'}
324
+ function openDialog(d) { dialogState = d; dialogListeners.forEach(function (fn) { try { fn() } catch (e) {} }) }
325
+ function closeDialog() { dialogState = null; dialogListeners.forEach(function (fn) { try { fn() } catch (e) {} }) }
326
+ function onDialog(fn) { dialogListeners.add(fn); return function () { dialogListeners.delete(fn) } }
327
+ function cmpVersion(a, b) {
328
+ var pa = String(a).split('.').map(Number), pb = String(b).split('.').map(Number)
329
+ for (var i = 0; i < 3; i++) {
330
+ var x = pa[i] || 0, y = pb[i] || 0
331
+ if (x > y) return 1
332
+ if (x < y) return -1
333
+ }
334
+ return 0
335
+ }
336
+ function changelogBetween(fromVer, toVer) {
337
+ var keys = Object.keys(CHANGELOG).filter(function (v) { return cmpVersion(v, fromVer) > 0 && cmpVersion(v, toVer) <= 0 })
338
+ keys.sort(function (a, b) { return cmpVersion(a, b) })
339
+ return keys.map(function (v) { return { version: v, items: CHANGELOG[v] } })
340
+ }
287
341
 
288
342
  // ───────────────────────── API ─────────────────────────
289
343
  var API = {
@@ -472,11 +526,7 @@ window.__ModuleLoader__.load({
472
526
  return base
473
527
  })()
474
528
  // 离开>1小时后回来
475
- function away() {
476
- var lastSeen = 0
477
- try { lastSeen = Number(localStorage.getItem('dsh-auto-memory.lastActive') || 0) } catch (e) {}
478
- return lastSeen > 0 && (Date.now() - lastSeen) > 3600000
479
- }
529
+ function away() { return isAway() }
480
530
  var rows = []
481
531
  rows.push(h('div', { 'data-dam-content': '' }, greetLine))
482
532
  // 抽屉列表(AI 生活化总结缓存)
@@ -593,10 +643,7 @@ window.__ModuleLoader__.load({
593
643
  }, 30000)
594
644
  return function () { clearInterval(timer) }
595
645
  }, [])
596
- useEffect(function () {
597
- // 记录本次活动时间;下次打开若相隔>1小时,GreetingCard 显示"欢迎回来"
598
- try { localStorage.setItem('dsh-auto-memory.lastActive', String(Date.now())) } catch (e) {}
599
- }, [])
646
+
600
647
  if (!state) return h(Loading)
601
648
  function oneClickReflect() {
602
649
  if (reflectBusy) return
@@ -1211,6 +1258,50 @@ window.__ModuleLoader__.load({
1211
1258
  kv(t('kvApi'), probes ? Object.keys(probes).map(function (k) { return k + '=' + (probes[k].status !== undefined ? probes[k].status : probes[k].error) }).join(' ') : '…', apiBad))
1212
1259
  }
1213
1260
 
1261
+ // ───────────────────────── 更新弹窗 / 首次指导(毛玻璃) ─────────────────────────
1262
+ function DialogHost() {
1263
+ var tickPair = useTick()
1264
+ useEffect(function () { return onDialog(tickPair[1]) }, [])
1265
+ if (!dialogState) return null
1266
+ // 左下角小卡片(记忆按钮上方),高透明毛玻璃,不遮全屏
1267
+ var overlay = { position: 'fixed', left: '10px', bottom: '64px', zIndex: 2147483000, width: 'min(360px, calc(100vw - 20px))', maxHeight: 'min(46vh, 430px)', display: 'flex', flexDirection: 'column' }
1268
+ var box = {
1269
+ overflow: 'auto', borderRadius: '14px', padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: '6px',
1270
+ background: 'color-mix(in srgb, var(--dsw-alias-bg-overlay, rgba(24,26,32,.9)) 58%, transparent)',
1271
+ backdropFilter: 'blur(14px) saturate(1.3)', WebkitBackdropFilter: 'blur(14px) saturate(1.3)',
1272
+ border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.35)) 45%, transparent)',
1273
+ boxShadow: '0 8px 28px rgba(0,0,0,.18)',
1274
+ }
1275
+ var head = { fontSize: 'calc(13px * var(--dam-scale))', fontWeight: 700, color: 'var(--dsw-alias-text-primary, inherit)' }
1276
+ var sub = { fontSize: 'calc(11px * var(--dam-scale))', opacity: .7 }
1277
+ var item = { fontSize: 'calc(11px * var(--dam-scale))', lineHeight: 1.55, padding: '1px 0 1px 16px', position: 'relative' }
1278
+ var close = { alignSelf: 'flex-end', padding: '4px 16px', borderRadius: '8px', border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.35)) 45%, transparent)', background: 'color-mix(in srgb, var(--dsw-alias-brand-primary, #4f7cff) 12%, transparent)', color: 'var(--dsw-alias-text-primary, inherit)', cursor: 'pointer', fontSize: 'calc(11.5px * var(--dam-scale))' }
1279
+ var dot = { position: 'absolute', left: '0', top: '10px', width: '7px', height: '7px', borderRadius: '50%', background: 'var(--dsw-alias-brand-primary, #4f7cff)' }
1280
+ if (dialogState.kind === 'first') {
1281
+ var feats = [t('gFeat1'), t('gFeat2'), t('gFeat3'), t('gFeat4'), t('gFeat5'), t('gFeat6')]
1282
+ return h('div', { style: overlay },
1283
+ h('div', { style: box },
1284
+ h('div', { style: head }, t('guideTitle')),
1285
+ h('div', { style: sub }, t('guideSub')),
1286
+ feats.map(function (f) { return h('div', { style: item }, h('span', { style: dot }), f) }),
1287
+ h('div', { style: { fontSize: 'calc(12px * var(--dam-scale))', opacity: .8, marginTop: '4px' } }, t('guideTip')),
1288
+ h('button', { 'data-dam-btn': '', style: close, onClick: closeDialog }, t('gotIt'))))
1289
+ }
1290
+ var versions = dialogState.versions || []
1291
+ var lastV = versions.length ? versions[versions.length - 1].version : ''
1292
+ return h('div', { style: overlay },
1293
+ h('div', { style: box },
1294
+ h('div', { style: head }, t('updateTitle') + ' v' + lastV),
1295
+ h('div', { style: sub }, t('updateSub')),
1296
+ versions.map(function (v) {
1297
+ var items = (v.items && (v.items[locale] || v.items.zh)) || []
1298
+ return h('div', null,
1299
+ h('div', { style: { fontSize: 'calc(13px * var(--dam-scale))', fontWeight: 700, margin: '6px 0 2px', opacity: .9 } }, 'v' + v.version),
1300
+ items.map(function (it) { return h('div', { style: item }, h('span', { style: dot }), it) }))
1301
+ }),
1302
+ h('button', { 'data-dam-btn': '', style: close, onClick: closeDialog }, t('gotIt'))))
1303
+ }
1304
+
1214
1305
  // ───────────────────────── 设置页 ─────────────────────────
1215
1306
  var STYLE_IDS = ['auto', 'life', 'professional']
1216
1307
  var LOCALE_IDS_LIST = ['system', 'zh', 'en']
@@ -1403,6 +1494,34 @@ window.__ModuleLoader__.load({
1403
1494
  })
1404
1495
  // 语言切换时通知所有订阅者重渲染
1405
1496
  onLocale(function () { emit() })
1497
+ // 暂离回来自动弹开记忆窗口:距离上次关闭面板超过 1 小时,页面加载或切回标签页时自动打开(欢迎语在 GreetingCard 展示)
1498
+ function autoOpenOnReturn() {
1499
+ try {
1500
+ if (isAway() && !controller.isOpen()) controller.open()
1501
+ } catch (e) {}
1502
+ }
1503
+ autoOpenOnReturn()
1504
+ try {
1505
+ document.addEventListener('visibilitychange', function () {
1506
+ if (!document.hidden) autoOpenOnReturn()
1507
+ })
1508
+ } catch (e) {}
1509
+ // 更新弹窗 / 首次指导:对比本地记录的已见版本,有更新或首次安装时弹窗(host 12h 缓存,不重复查网)
1510
+ apiGet(API.updateCheck).then(function (d) {
1511
+ if (d && d.current) {
1512
+ try {
1513
+ var seen = localStorage.getItem('dsh-auto-memory.seenVersion')
1514
+ if (!seen && !localStorage.getItem('dsh-auto-memory.firstRunDone')) {
1515
+ try { localStorage.setItem('dsh-auto-memory.firstRunDone', '1') } catch (e2) {}
1516
+ openDialog({ kind: 'first' })
1517
+ } else if (seen && seen !== d.current) {
1518
+ var versions = changelogBetween(seen, d.current)
1519
+ if (versions.length) openDialog({ kind: 'update', versions: versions })
1520
+ }
1521
+ try { localStorage.setItem('dsh-auto-memory.seenVersion', d.current) } catch (e3) {}
1522
+ } catch (e) {}
1523
+ }
1524
+ }).catch(function () {})
1406
1525
 
1407
1526
  var surfaceDisposers = []
1408
1527
  function registerSurfaces() {
@@ -1413,6 +1532,9 @@ window.__ModuleLoader__.load({
1413
1532
  surfaceDisposers.push(slots.inject('shell.overlay', function () {
1414
1533
  return slots.register({ name: 'shell.overlay', id: 'auto-memory', order: 5 }, function () { return h(MemoryPanel) })
1415
1534
  }))
1535
+ surfaceDisposers.push(slots.inject('shell.overlay', function () {
1536
+ return slots.register({ name: 'shell.overlay', id: 'auto-memory-dialogs', order: 6 }, function () { return h(DialogHost) })
1537
+ }))
1416
1538
  surfaceDisposers.push(slots.inject('settings.section', function () {
1417
1539
  return slots.register({ name: 'settings.section', id: 'auto-memory', order: 25, label: t('autoMemory') }, function (props) { return h(SettingsPage, { close: props && props.close }) })
1418
1540
  }))
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@a9i5k4/dsh-auto-memory",
3
3
  "description": "DSH 自动记忆插件:三层记忆(用户级/项目笔记/每日日志)自动注入与检索、每轮对话自动沉淀、每日反思、可视化面板与设置页,支持继承其他 AI 工具的记忆。",
4
- "version": "0.1.13",
4
+ "version": "0.1.14",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {