dsh-global-todo 0.7.0 → 0.7.1

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,14 @@
1
+ ## [0.7.1] — 2026-10-20
2
+
3
+ Documentation for the one piece of layout that cannot be "cleaned up".
4
+
5
+ - **`docs/DESIGN.md` now records why the wide-screen detail card is `position: fixed`**, with the
6
+ measurements from the failed attempts (an absolute card came out 348×3051 at 1440; container
7
+ queries make the panel the containing block for fixed descendants), the real cause (the panel
8
+ scrolls with the host page, not `.gt-groups`), and the rules for changing it safely.
9
+ - `/api/global-todo/review` added to both README route tables (it shipped in 0.7.0 without its
10
+ row).
11
+
1
12
  ## [0.7.0] — 2026-10-20
2
13
 
3
14
  An agent's "done" becomes a claim a person confirms, instead of a fact.
package/README.md CHANGED
@@ -268,6 +268,7 @@ fence when that service is present, and by a strict loopback check otherwise.
268
268
  | POST | `/api/global-todo/status` | `{ id, status, by?: human\|agent }` |
269
269
  | POST | `/api/global-todo/remove` | `{ id }` |
270
270
  | POST | `/api/global-todo/restore` | `{ todo }` — put a removed record back verbatim (undo) |
271
+ | POST | `/api/global-todo/review` | `{ id, decision: confirm\|reject }` — answer an agent's completion |
271
272
  | POST | `/api/global-todo/link` | `{ id, add?: [...], remove?: [value \| index] }` |
272
273
  | POST | `/api/global-todo/dispatch` | `{ id, mode?: auto\|bound\|new\|current, sessionId?, dir? }` |
273
274
  | POST | `/api/global-todo/assign` | `{ ids, items?, target?, dir? }` — hand several todos over in one call; an id that matches nothing comes back instead of being sent elsewhere |
package/README.zh.md CHANGED
@@ -164,6 +164,7 @@ dsh plugin --profile web remove dsh-global-todo
164
164
  | POST | `/api/global-todo/status` | `{ id, status, by?: human\|agent }` |
165
165
  | POST | `/api/global-todo/remove` | `{ id }` |
166
166
  | POST | `/api/global-todo/restore` | `{ todo }` —— 原样还原被删除的记录(撤销) |
167
+ | POST | `/api/global-todo/review` | `{ id, decision: confirm\|reject }` —— 回答 Agent 的完成声明 |
167
168
  | POST | `/api/global-todo/link` | `{ id, add?: [...], remove?: [值 或 下标] }` |
168
169
  | POST | `/api/global-todo/dispatch` | `{ id, mode?: auto\|bound\|new\|current, sessionId?, dir? }` |
169
170
  | POST | `/api/global-todo/assign` | `{ ids, items?, target?, dir? }`——一次把多条交给 Agent;配不上的 id 原样报回,不擅自送到别处 |
package/docs/DESIGN.md CHANGED
@@ -60,15 +60,51 @@ $DSH_HOME/global-todo/todos.json ← { version: 1, todos: [ … ] }
60
60
  ## On a wide window, the detail stands beside the list
61
61
 
62
62
  Expanding a row inline is right on a narrow window and wrong on a wide one: the list jumps, the
63
- row you were reading slides away, and the rest of the screen sits empty. Above 1100px the open
64
- row's detail is lifted out of the flow into a card bracketed between the toolbar and the footer
65
- at the panel's right edge; only the list gives way (the toolbar keeps full width), and the list gets
66
- padding equal to that card. The card's offsets are measured from the panel's own column on mount
67
- and on resize — the slot does not always fill the window, so a viewport-derived offset put the card
68
- over the list inside the real GUI. This is a CSS-only override over unchanged markup
69
- (`.gt-root[data-wide-detail]` plus one media query) precisely so there is still exactly one
70
- detail implementation — a second render path for wide screens would drift from the inline one at
71
- the first field change.
63
+ row you were reading slides away, and the rest of the screen sits empty. When the panel itself is
64
+ at least 960px wide, the open row's detail is lifted out of the flow into a card at the panel's
65
+ right edge; only the list gives way (the header and toolbar keep full width), and the list gets
66
+ 360px of right padding equal to the card. The breakpoint follows the **panel's** measured width,
67
+ not the viewport: the slot is ~265px narrower than the window, so a viewport query opened the
68
+ two-column layout while the panel still had no room for it. This is a CSS-only override over
69
+ unchanged markup (`.gt-root[data-wide]` / `[data-wide-detail]`) precisely so there is still
70
+ exactly one detail implementation — a second render path for wide screens would drift from the
71
+ inline one at the first field change.
72
+
73
+ ### Why the card is `position: fixed` and not `sticky`
74
+
75
+ Three ways to do this were tried; only one survives the host's layout.
76
+
77
+ 1. **`position: sticky`** — the card is a child of the row, so sticky is bounded by the row's
78
+ box: it never leaves the 72–94px tall item. Moving the card out of the row would mean a second
79
+ detail render path.
80
+ 2. **`position: absolute` inside a positioned wrapper around the list** — measured on
81
+ 2026-10-20: at 1440 the card came out **348 × 3051px**, at 1280 **348 × 3203px**. The card
82
+ stretched to the full height of the list's *content* and scrolled away with the page. Reason:
83
+ **the scrolling ancestor of this panel is the host page, not `.gt-groups`** — the panel is a
84
+ column in someone else's scroller, so `.gt-groups` never scrolls and an absolutely positioned
85
+ box is bracketed by the whole content column instead of the visible area.
86
+ 3. **`container-type: inline-size` + container queries** — wanted, because the breakpoint would
87
+ then be CSS. But inline-size containment applies `contain: layout`, which makes the panel the
88
+ containing block for `position: fixed` descendants. The card (and the settings popover) would
89
+ silently switch from viewport-anchored to panel-anchored and land in the wrong place.
90
+
91
+ So: **`position: fixed` plus one measurement of the panel and list boxes**, taken when a row
92
+ opens and again on resize (and on a `ResizeObserver` of the column, because collapsing the host
93
+ sidebar changes the panel's width without a window resize). The measured values land in
94
+ `--gt-detail-top/right/bottom`; the CSS fallbacks assume the centred 1040px column, which is what
95
+ the static previews render.
96
+
97
+ ### Changing this safely
98
+
99
+ - Keep **one** detail implementation: if a change needs different markup for wide screens, it is
100
+ the wrong change.
101
+ - Keep the breakpoint on the **panel** width (960px). A viewport media query was already shipped
102
+ once and put a 360px card over a 416px list at 1100.
103
+ - Never let the card cover the list: it is `.gt-groups` padding that reserves the room, and the
104
+ two numbers (360 padding / 348 card + 12 gap) have to move together.
105
+ - Verify in the real GUI, not the preview, at **1440 / 1280 / 1100**: the card must be ≈348px wide,
106
+ the list must end before it, and the open row must stay visible next to it. The preview cannot
107
+ catch this class of bug — it is server-rendered, so no measurement effect ever runs there.
72
108
  ## A shared file changes without asking
73
109
 
74
110
  The list is deliberately portable — a notes repo, a synced folder, a NAS — so another machine
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.7.0'
39
+ export const VERSION = '0.7.1'
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.7.0",
3
+ "version": "0.7.1",
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",