@pandablessing/dsh-user-sync 1.0.6 → 1.0.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.
Files changed (2) hide show
  1. package/lib/client.js +48 -7
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -178,7 +178,7 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
178
178
  ? R.createElement('p', { style: styles.muted }, `本地包需手动放回:${linkDeps.map((item) => item.name).join('、')}`)
179
179
  : null, R.createElement('div', { style: styles.actions }, missing.length > 0
180
180
  ? R.createElement('button', { style: styles.primary, onClick: () => onInstallPlugins(missing) }, '先安装缺失插件')
181
- : null, R.createElement('button', { style: styles.primary, onClick: () => onApply(data.latest?.name ?? '') }, '用远端覆盖本机'), R.createElement('button', { style: styles.secondary, onClick: () => onDismiss() }, '取消')));
181
+ : null, R.createElement('button', { style: styles.secondary, onClick: () => onDismiss() }, '取消')), R.createElement('p', { style: styles.muted }, '覆盖动作会在弹窗中确认。'));
182
182
  }
183
183
  return R.createElement('div', { style: styles.card }, R.createElement('strong', null, decision.action === 'skip' ? '本机已是最新' : '本机有改动'), R.createElement('p', { style: styles.muted }, `判定:${decision.reason ?? decision.action}`));
184
184
  }
@@ -187,10 +187,8 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
187
187
  return R.createElement('div', { style: styles.card }, R.createElement('strong', { style: styles.error }, remoteNewer ? '远端有更新的包' : '操作失败'), R.createElement('p', { style: styles.muted }, data.detail ?? data.error ?? '未知错误'), data.hits
188
188
  ? R.createElement('p', { style: styles.error }, `敏感扫描命中 ${data.hits.length} 处:${data.hits.map((h) => `${h.file}:${h.line}(${h.pattern})`).join(';')}`)
189
189
  : null,
190
- // 上传前发现远端更新:默认不覆盖,用户确认后才用本机覆盖远端(G2)
191
- remoteNewer
192
- ? R.createElement('div', { style: styles.actions }, R.createElement('button', { style: styles.primary, onClick: () => onForceUpload() }, '用本机覆盖远端'), R.createElement('button', { style: styles.secondary, onClick: () => onDismiss() }, '取消'))
193
- : null);
190
+ // 覆盖确认已改为弹窗;卡片只提示
191
+ remoteNewer ? R.createElement('p', { style: styles.muted }, '覆盖动作会在弹窗中确认。') : null);
194
192
  }
195
193
  // 同步后自动安装的结果:优先展示「装了哪些插件 / 哪些失败 / 哪些需手动放回」
196
194
  const pluginSummary = (() => {
@@ -225,6 +223,8 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
225
223
  const [notice, setNotice] = R.useState(null);
226
224
  // 非用户级模块确认走弹窗(dialog),不再用底部结果卡
227
225
  const [confirmDialog, setConfirmDialog] = R.useState(null);
226
+ // 覆盖确认弹窗:上传发现远端更新 / 从远端同步发现远端更新时弹出(不再用结果卡按钮)
227
+ const [overwriteDialog, setOverwriteDialog] = R.useState(null);
228
228
  // 当前展开文件清单的模块(null 表示都收起)
229
229
  const [expandedModule, setExpandedModule] = R.useState(null);
230
230
  // 设置改动后自动保存(600ms 防抖),不再提供「保存设置」按钮
@@ -389,7 +389,19 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
389
389
  headers: { 'content-type': 'application/json' },
390
390
  body: JSON.stringify({ force }),
391
391
  });
392
- setNotice({ kind: result.ok ? 'result' : 'error', data: result });
392
+ if (result.ok) {
393
+ setNotice({ kind: 'result', data: result });
394
+ refresh();
395
+ }
396
+ else if (result.code === 'E_REMOTE_NEWER') {
397
+ setOverwriteDialog({
398
+ kind: 'upload',
399
+ detail: `远端已有更新的包 ${result.latest?.name ?? ''};继续会用本机配置覆盖它。`,
400
+ });
401
+ }
402
+ else {
403
+ setNotice({ kind: 'error', data: result });
404
+ }
393
405
  refresh();
394
406
  }
395
407
  catch (error) {
@@ -427,7 +439,22 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
427
439
  setNotice(null);
428
440
  try {
429
441
  const result = await fetchJson(`${API}/check`);
430
- setNotice(result.error ? { kind: 'error', data: result } : { kind: 'check', data: result });
442
+ if (result.error) {
443
+ setNotice({ kind: 'error', data: result });
444
+ }
445
+ else {
446
+ // 详情仍用结果卡展示;覆盖动作改为弹窗确认
447
+ setNotice({ kind: 'check', data: result });
448
+ const action = result.decision?.action;
449
+ if ((action === 'pull' || action === 'confirm') && result.latest?.name) {
450
+ const overwritten = (result.plan?.overwritten ?? []).length;
451
+ setOverwriteDialog({
452
+ kind: 'pull',
453
+ name: result.latest.name,
454
+ detail: `远端包 ${result.latest.name}(${result.meta?.createdAt ?? '时间未知'}),将覆盖本机 ${overwritten} 个文件。`,
455
+ });
456
+ }
457
+ }
431
458
  }
432
459
  catch (error) {
433
460
  setNotice({ kind: 'error', data: { detail: String(error) } });
@@ -532,6 +559,20 @@ if (typeof window !== 'undefined' && window.__ModuleLoader__) {
532
559
  onForceUpload: () => upload(true),
533
560
  }), confirmDialog
534
561
  ? R.createElement('div', { style: styles.overlay, onClick: () => setConfirmDialog(null) }, R.createElement('div', { style: styles.dialog, onClick: (event) => event.stopPropagation?.() }, R.createElement('strong', null, '同步项目/会话内容?'), R.createElement('p', { style: styles.muted }, `${confirmDialog.warning.map((id) => MODULE_LABELS[id] ?? id).join('、')} 属于项目/会话级,可能包含具体工作内容。确认要跨机器同步吗?`), R.createElement('div', { style: styles.actions }, R.createElement('button', { style: styles.primary, onClick: () => confirmModules(confirmDialog.modules) }, '仍要同步'), R.createElement('button', { style: styles.secondary, onClick: () => setConfirmDialog(null) }, '取消'))))
562
+ : null, overwriteDialog
563
+ ? R.createElement('div', { style: styles.overlay, onClick: () => setOverwriteDialog(null) }, R.createElement('div', { style: styles.dialog, onClick: (event) => event.stopPropagation?.() }, R.createElement('strong', null, overwriteDialog.kind === 'upload' ? '用本机覆盖远端?' : '用远端覆盖本机?'), R.createElement('p', { style: styles.muted }, overwriteDialog.detail), R.createElement('p', { style: styles.muted }, overwriteDialog.kind === 'upload'
564
+ ? '远端已有的包会被本机内容替换(远端只保留 1 份)。'
565
+ : '本机会先做快照,再用远端包覆盖同步范围内的文件。'), R.createElement('div', { style: styles.actions }, R.createElement('button', {
566
+ style: styles.primary,
567
+ onClick: () => {
568
+ const target = overwriteDialog;
569
+ setOverwriteDialog(null);
570
+ if (target.kind === 'upload')
571
+ void upload(true);
572
+ else if (target.name)
573
+ void applyRemote(target.name);
574
+ },
575
+ }, overwriteDialog.kind === 'upload' ? '用本机覆盖远端' : '用远端覆盖本机'), R.createElement('button', { style: styles.secondary, onClick: () => setOverwriteDialog(null) }, '取消'))))
535
576
  : null);
536
577
  }
537
578
  function apply(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandablessing/dsh-user-sync",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "DeepSeek Harness 用户级配置同步插件",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",