dsh-global-todo 0.6.2 → 0.6.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [0.6.3] — 2026-10-20
2
+
3
+ States that were still speaking to nobody.
4
+
5
+ - **The selection bar has one primary action.** Count and 全选/清空 sit on the left, `Assign` is
6
+ the only filled button, `Complete`/`Archive`/tag stay quiet, and the ambiguous `Done` becomes an
7
+ icon-only exit (it read as a second `Complete`).
8
+ - **The inbox explains itself**, and an empty filter now offers `Clear filter` instead of dead air.
9
+ - **The reminder bar says which set it is.** Copy moves to `Dismiss all` and the bar carries a note
10
+ that these reached their reminder time, unlike Overdue.
11
+ - **Selection bar is sticky and 36px tall**, so the batch actions stay reachable while scrolling.
12
+
1
13
  ## [0.6.2] — 2026-10-20
2
14
 
3
15
  The narrow-width details the spec called for after the two-column work.
Binary file
Binary file
Binary file
package/lib/client.js CHANGED
@@ -50,7 +50,7 @@ window.__ModuleLoader__.load({
50
50
  * different mechanisms (restart vs. hot reload), so "which one am I looking
51
51
  * at" needs an answer that the bundle itself carries.
52
52
  */
53
- const UI_REV = 'ui38'
53
+ const UI_REV = 'ui39'
54
54
  /** Last language resolved for the shell; module-level so a fetch failure can be worded too. */
55
55
  let activeLang = 'zh'
56
56
 
@@ -129,6 +129,7 @@ window.__ModuleLoader__.load({
129
129
  'notice.bulkPartial': '已更新 {n} 条,跳过 {m} 条',
130
130
  'select.clear': '清除',
131
131
  'select.done': '退出选择',
132
+ 'select.clear': '清空',
132
133
  'select.hint': '先勾几条待办,再点「一键分配」:优先回到写下它的那个对话,其次同工作区的对话,都找不到才让你选。',
133
134
  'assign.working': '正在分配…',
134
135
  'assign.summary': '已分配 {n} 条(原对话 {origin} · 同工作区 {workspace} · 你选的 {chosen})',
@@ -154,6 +155,8 @@ window.__ModuleLoader__.load({
154
155
  'notice.autoCollectOff': '已关闭自动获取',
155
156
  'notice.externalChange': '清单在别处被改过,已载入最新内容',
156
157
  'reminder.title': '到点提醒({n})',
158
+ 'reminder.note': '这些是到了设定的提醒时间,和「逾期」不是同一批。',
159
+ 'reminder.dismissAll': '全部知道了',
157
160
  'reminder.dismiss': '知道了',
158
161
  'reminder.enableNotifications': '开启系统通知',
159
162
  'reminder.notifyTitle': '待办到点',
@@ -245,6 +248,8 @@ window.__ModuleLoader__.load({
245
248
  'empty.none': '还没有待办。上面写一句,回车就记下了。',
246
249
  'empty.add': '记第一条',
247
250
  'empty.filtered': '这个筛选下没有待办。',
251
+ 'empty.clearFilter': '清除筛选',
252
+ 'empty.filterHint': '换个筛选,或者清空搜索关键词。',
248
253
  'meta.added': '加入于',
249
254
  'meta.due': '截止',
250
255
  'meta.overdue': '逾期 {n} 天',
@@ -370,7 +375,7 @@ window.__ModuleLoader__.load({
370
375
  'notice.bulk': 'Updated {n}',
371
376
  'notice.bulkPartial': 'Updated {n}, skipped {m}',
372
377
  'select.clear': 'Clear',
373
- 'select.done': 'Done',
378
+ 'select.done': 'Exit selection',
374
379
  'select.hint': 'Pick a few todos, then Assign: back to the conversation that wrote each one, else a conversation in the same workspace, else you choose.',
375
380
  'assign.working': 'Assigning…',
376
381
  'assign.summary': 'Assigned {n} ({origin} to origin · {workspace} same workspace · {chosen} chosen)',
@@ -396,6 +401,8 @@ window.__ModuleLoader__.load({
396
401
  'notice.autoCollectOff': 'Auto-collect off',
397
402
  'notice.externalChange': 'The list changed somewhere else; the latest content is loaded',
398
403
  'reminder.title': 'Due now ({n})',
404
+ 'reminder.note': 'These reached their reminder time — a different set from Overdue.',
405
+ 'reminder.dismissAll': 'Dismiss all',
399
406
  'reminder.dismiss': 'Dismiss',
400
407
  'reminder.enableNotifications': 'Enable notifications',
401
408
  'reminder.notifyTitle': 'Todo due',
@@ -488,6 +495,8 @@ window.__ModuleLoader__.load({
488
495
  'empty.none': 'No todos yet. Write one above and press Enter.',
489
496
  'empty.add': 'Add your first todo',
490
497
  'empty.filtered': 'Nothing matches this filter.',
498
+ 'empty.clearFilter': 'Clear filter',
499
+ 'empty.filterHint': 'Try another filter, or clear the search box.',
491
500
  'meta.added': 'added',
492
501
  'meta.due': 'due',
493
502
  'meta.overdue': '{n} d overdue',
@@ -1071,8 +1080,11 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
1071
1080
  display: inline-flex; align-items: center; justify-content: center; padding: 0; }
1072
1081
  .gt-pick[data-on="1"] { border-color: var(--dsw-alias-brand-primary); background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-base); }
1073
1082
  .gt-item[data-selected="1"] { border-color: var(--dsw-alias-brand-primary); }
1074
- .gt-selectbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 9px 12px;
1075
- border: 1px solid var(--dsw-alias-brand-primary); border-radius: 10px; background: var(--dsw-alias-bg-layer-1); font-size: 13px; }
1083
+ .gt-selectbar { position: sticky; top: 0; z-index: 10; display: flex; align-items: center;
1084
+ gap: 8px; flex-wrap: wrap; padding: 0 12px; min-height: 36px; box-sizing: border-box;
1085
+ border: 1px solid var(--dsw-alias-border-l2); border-radius: 10px;
1086
+ background: var(--dsw-alias-bg-layer-1); font-size: 13px; }
1087
+ .gt-selectbar-count { font-weight: 600; white-space: nowrap; }
1076
1088
  .gt-item-body { flex: 1; display: flex; flex-direction: column; gap: 5px; min-width: 0; cursor: pointer; }
1077
1089
  .gt-item-body:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 2px; border-radius: 6px; }
1078
1090
  .gt-item-title { font-weight: 600; font-size: 14px; word-break: break-word; line-height: 22px;
@@ -3692,7 +3704,7 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3692
3704
  ? h(
3693
3705
  'div',
3694
3706
  { className: 'gt-selectbar' },
3695
- h('span', null, t('select.count', { n: Object.keys(selected).length })),
3707
+ h('span', { className: 'gt-selectbar-count' }, t('select.count', { n: Object.keys(selected).length })),
3696
3708
  h(
3697
3709
  'button',
3698
3710
  {
@@ -3714,11 +3726,17 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3714
3726
  ? t('select.allOn')
3715
3727
  : t('select.all'),
3716
3728
  ),
3729
+ h(
3730
+ 'button',
3731
+ { type: 'button', className: 'gt-btn gt-btn-quiet', onClick: () => setSelected({}) },
3732
+ t('select.clear'),
3733
+ ),
3734
+ h('span', { className: 'gt-spacer' }),
3717
3735
  h(
3718
3736
  'button',
3719
3737
  {
3720
3738
  type: 'button',
3721
- className: 'gt-btn gt-btn-brand',
3739
+ className: 'gt-btn gt-btn-primary',
3722
3740
  disabled: assignBusy || Object.keys(selected).length === 0,
3723
3741
  onClick: () => void runAssign(Object.keys(selected)),
3724
3742
  },
@@ -3792,22 +3810,19 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3792
3810
  },
3793
3811
  t('select.addTag'),
3794
3812
  ),
3795
- h(
3796
- 'button',
3797
- { type: 'button', className: 'gt-btn gt-btn-quiet', onClick: () => setSelected({}) },
3798
- t('select.clear'),
3799
- ),
3800
3813
  h(
3801
3814
  'button',
3802
3815
  {
3803
3816
  type: 'button',
3804
- className: 'gt-btn gt-btn-quiet',
3817
+ className: 'gt-iconbtn',
3818
+ title: t('select.done'),
3819
+ 'aria-label': t('select.done'),
3805
3820
  onClick: () => {
3806
3821
  setSelectMode(false)
3807
3822
  setSelected({})
3808
3823
  },
3809
3824
  },
3810
- t('select.done'),
3825
+ h(Icon, { name: 'close', size: 13 }),
3811
3826
  ),
3812
3827
  )
3813
3828
  : null,
@@ -3818,7 +3833,7 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3818
3833
  ? null
3819
3834
  : h(
3820
3835
  'div',
3821
- { className: 'gt-reminders', role: 'status' },
3836
+ { className: 'gt-reminders', role: 'status', title: t('reminder.note') },
3822
3837
  h('span', { className: 'gt-reminders-title' }, t('reminder.title', { n: remindersDue.length })),
3823
3838
  ...remindersDue.slice(0, 3).map((item) =>
3824
3839
  h(
@@ -3852,7 +3867,7 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3852
3867
  h(
3853
3868
  'button',
3854
3869
  { type: 'button', className: 'gt-btn gt-btn-quiet', onClick: () => void ackReminders(remindersDue.map((item) => item.id)) },
3855
- t('reminder.dismiss'),
3870
+ t('reminder.dismissAll'),
3856
3871
  ),
3857
3872
  ),
3858
3873
 
@@ -3927,8 +3942,18 @@ button.gt-chip[data-on="1"] { color: var(--dsw-alias-label-primary); border-colo
3927
3942
  },
3928
3943
  t('empty.add'),
3929
3944
  )
3930
- : null,
3931
- h('div', { className: 'gt-sub' }, t('hint.keys')),
3945
+ : h(
3946
+ 'button',
3947
+ {
3948
+ type: 'button',
3949
+ className: 'gt-btn gt-btn-quiet',
3950
+ onClick: () => {
3951
+ setQuery('')
3952
+ void reload({ filter: 'active', query: '' })
3953
+ },
3954
+ },
3955
+ t('empty.clearFilter'),
3956
+ ),
3932
3957
  )
3933
3958
  : h(
3934
3959
  'div',
package/lib/index.js CHANGED
@@ -36,7 +36,7 @@ import { createStore, resolveStorePath } from './store.js'
36
36
  import { createTools } from './tools.js'
37
37
 
38
38
  /** Must equal `package.json`'s version; `npm run check` enforces that. */
39
- export const VERSION = '0.6.2'
39
+ export const VERSION = '0.6.3'
40
40
 
41
41
  /** Plugin id. Also the Loader row id in `cordis.patch.yml`. */
42
42
  export const name = 'dsh-global-todo'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-global-todo",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "icon": "./docs/icon.svg",
5
5
  "description": "Global, cross-session todos for DeepSeek Harness: one list owned by the human and the agent together, with creation time, attached documents and links, and one-click hand-off to an agent session. 全局待办:跨会话一份清单,记录加入时间,可挂文档与地址,可一键交给 Agent 继续干。",
6
6
  "type": "module",