@1yefuwang1/dsh-worktrees 0.2.13 → 0.2.18

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,5 +1,117 @@
1
1
  # @1yefuwang1/dsh-worktrees changelog
2
2
 
3
+ ## 0.2.18 — Theme-aligned conversation controls and local starting branches
4
+
5
+ - Replace the native Local/New worktree dropdown and the mismatched Local-only
6
+ button with the same compact, theme-aware menu control.
7
+ - Default the starting branch to the current local branch (or the detached HEAD
8
+ commit), display its name, and replace “Base branch” with “Starting branch”.
9
+ - Offer Local and Remote branch sources. Local worktrees pin an exact committed
10
+ local branch without fetching, including repositories with no configured remote;
11
+ remote worktrees keep the fresh-fetch creation path.
12
+ - Load one bounded branch generation and search it locally. Keystrokes preserve
13
+ selection and never rediscover remote branches; source/remote switching reuses
14
+ loaded lists until explicit Refresh or target/connection invalidation.
15
+ - Select and dismiss immediately on branch click, with Escape/focus dismissal and
16
+ keyboard navigation instead of a Close button.
17
+ - Preserve source-checkout, permission, cancellation and native-draft guards;
18
+ refuse moved local selections rather than silently substituting another commit.
19
+ - Use the native desktop menu fill/elevation rather than the light overlay token;
20
+ match native hover/segment colors and keep the search icon/input on one row.
21
+ Fence the search reset against generic input/focus rules to avoid double borders.
22
+ - Keep the branch picker open during Refresh: move focus to the stable search
23
+ field before disabling Refresh, and distinguish loading-related null blur from
24
+ actual outside focus. Preserve search and selection across local/remote reloads.
25
+ - Add backend, protocol/cache and real React interaction/style-cascade coverage.
26
+
27
+ ## 0.2.17 — Folder entries follow the composed picker, with a working default
28
+
29
+ - Stop offering an add interaction the session cannot serve. The Host composes
30
+ either the system chooser (loopback desktop: `pick` only) or the in-app browser
31
+ (remote, SSH or browse-composed sessions: `listDirectory`/`createDirectory`
32
+ only), and the other verb set fails with `directory-picker/unavailable`. The
33
+ dialog now probes listing once and shows **Browse for folders** only when the
34
+ in-app browser can actually list Host folders.
35
+ - Keep **Choose a folder…** for a session with any reachable chooser (desktop
36
+ bridge or `uiWorkspace.pickDirectory`) and **Enter a folder path** everywhere, so
37
+ project creation stays possible in every composition, including desktop where
38
+ multi-folder projects are built by repeating the system dialog or pasting paths.
39
+ - Fall back deterministically when a selected entry disappears: to the system
40
+ chooser when there is one, otherwise to path entry.
41
+ - Ask one dialog source at a time for the native entry: the shell bridge first,
42
+ `uiWorkspace.pickDirectory` only when the bridge is absent or fails. A cancelled
43
+ dialog is an answer and is never handed to the second source, so cancelling opens
44
+ no follow-up dialog, while a broken bridge still falls through to a working Host
45
+ verb. A source that never settles stays with the operator to dismiss — the client
46
+ bundle is timer-free by contract, so no deadline can be imposed.
47
+ - Default to the entry that needs no typing: the system chooser where one exists,
48
+ the in-app browser where the Host lists directories, and path entry only when
49
+ neither is reachable. Path entry stays the pre-probe placeholder and is
50
+ promoted once the capability answer arrives, never overriding a user choice.
51
+ - Assert executable-bit and unreadable-file behaviour only where the platform carries
52
+ POSIX permission bits; Windows has neither, so those checks reported failures
53
+ instead of uncovered behaviour. Path expectations use the platform separator
54
+ throughout.
55
+ - Use portable fixture names (no newline in a filename, which Windows rejects), and
56
+ make the handoff fixture's line endings independent of the runner: the source
57
+ pins `core.autocrlf` before its first add, and the clone's working tree is
58
+ re-materialised under the same pin. A fresh target clone must then read clean with
59
+ the exact status command the engine's cleanliness gate runs — measured, because a
60
+ Windows runner materialised the clone with endings that differed from the blob and
61
+ every handoff preview failed as `TARGET_DIRTY` far from the cause.
62
+ - Compare worktree registrations canonically when verifying a checkout: Git reports
63
+ `worktree list` in machine format, so a raw string comparison against the
64
+ canonical root failed on Windows, where separators and short names differ. An
65
+ entry that cannot be resolved now stays unmatched instead of turning a stale
66
+ registration into a failure to enumerate.
67
+ - Use the platform separator in fixture ownership assertions and accept CRLF when
68
+ parsing the checked-out client bundle, so the suites can pass on Windows.
69
+ - Test fixtures create their owned directories under one canonical temporary root.
70
+ macOS resolves `/var` through a symlink to `/private/var` and Windows can return
71
+ short or differently-cased names, so fixtures that mixed `os.tmpdir()` with
72
+ `realpath(tmpdir())` failed their own containment assertions on both platforms
73
+ while passing on Linux. A filesystem that rejects non-UTF-8 names now reports that
74
+ decoding coverage is not exercisable instead of failing the suite.
75
+
76
+ - Deferred, not implemented: serving directory listing from this plugin's own Host
77
+ half, which would restore the in-app multi-folder browser on desktop. The design,
78
+ the measured reason DSH's composed picker cannot serve both verb sets, and the
79
+ test matrix to carry over are recorded in
80
+ [docs/host-directory-listing.md](docs/host-directory-listing.md).
81
+
82
+ ## 0.2.16 — Clearer folder-entry labels
83
+
84
+ - Rename the three Add entries so each states its interaction: **Browse for
85
+ folders** (in-app multi-select), **Choose a folder…** (one folder from the
86
+ system dialog) and **Enter a folder path**, in English and Chinese. The
87
+ resource keys are unchanged, so only the visible text moves.
88
+ - Lock the mapping with coverage that reads the rendered options and fails when a
89
+ value is missing, renamed or labelled like another entry.
90
+
91
+ ## 0.2.15 — Capability-aware folder chooser
92
+
93
+ - Resolve the native add option from the picker that really exists in the current
94
+ session instead of a fixed dropdown entry: the desktop shell's renderer bridge
95
+ first, then the Host directory-picker plugin's `uiWorkspace.pickDirectory`.
96
+ Hide the option entirely when neither is present, and fall back to browsing if
97
+ it disappears while selected.
98
+ - Keep the in-app browser and the manual absolute-path entry available in every
99
+ session, including desktop, where the native option previously failed with a
100
+ picker error.
101
+ - Add regression coverage for desktop, browser, missing and non-callable picker
102
+ sources plus the unavailable-mode fallback.
103
+
104
+ ## 0.2.14 — Native sidebar view switch
105
+
106
+ - Move the view switch from the footer into native sidebar navigation, between
107
+ Automation tasks and Worktrees, using the native row styling and icon sizing.
108
+ - Label the action by its destination: **Switch to Projects View** or
109
+ **Switch to Workspace View**, with matching Chinese translations.
110
+ - Preserve native sidebar declarations and extensions through owned slot aliases;
111
+ switching views leaves the current conversation and other panel actions intact.
112
+ - Add regression coverage for navigation order, labels, callback routing and
113
+ native sidebar restoration on plugin unload.
114
+
3
115
  ## 0.2.13 — First scoped release preparation
4
116
 
5
117
  - Package as `@1yefuwang1/dsh-worktrees` to avoid an unrelated unscoped npm name;
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @1yefuwang1/dsh-worktrees
2
2
 
3
3
  Multi-folder projects with Local and isolated Git worktree threads for DeepSeek
4
- Harness. This experimental Host + Web Client package is **`0.2.13`**, prepared for
5
- scoped npm release with maintainer review/2FA. It does not require Copilot, the
4
+ Harness. This experimental Host + Web Client package is **`0.2.18`**; new releases
5
+ use staged npm publishing with maintainer review/2FA. It does not require Copilot, the
6
6
  catalog plugin, or the search plugin. The scoped name avoids collision with the
7
7
  unrelated npm package `dsh-worktrees`; stable tool, command and metadata names are
8
8
  unchanged.
@@ -14,6 +14,9 @@ A **thread** belongs to that project and executes in one selected folder: either
14
14
  its Local directory or a managed linked Git checkout. Project membership is not
15
15
  native Workspace membership, a working-directory change or a permission grant.
16
16
 
17
+ - The native sidebar navigation places the view switch between **Automation tasks**
18
+ and **Worktrees**. Its destination label is **Switch to Projects View** or
19
+ **Switch to Workspace View**; switching leaves the current conversation intact.
17
20
  - The compact **Projects** header uses Search, View options and Add project icon
18
21
  controls. Search appears only when opened; Escape/Close clears it and restores
19
22
  focus. Archive filters are in View options, not an always-visible dropdown.
@@ -40,8 +43,19 @@ native Workspace membership, a working-directory change or a permission grant.
40
43
  navigation. Repeat Add to extend the list; each selected folder shows its name,
41
44
  full path and a remove action. A project supports **1–32 folders**; duplicate
42
45
  picks are ignored and over-limit batches are refused without dropping entries.
43
- The source dropdown also offers manual absolute paths and the optional native
44
- system chooser (one folder per pick). Use **Cancel** to discard unsaved edits;
46
+ The source dropdown names each interaction — **Browse for folders** (the in-app
47
+ multi-select dialog), **Choose a folder…** (the system dialog, one folder per
48
+ pick) and **Enter a folder path** — and offers each only where the session's
49
+ composed directory picker can serve it. A loopback desktop composes the system
50
+ chooser only, so it gets **Choose a folder…** and path entry; the in-app browser
51
+ appears where the Host lists directories (remote, SSH or browse-composed
52
+ sessions). Since the picker choice is composed at boot, it is not a setting. The dropdown
53
+ defaults to that share — the system chooser on desktop, the in-app browser where
54
+ the Host lists directories, and path entry only when neither exists.
55
+ Because that composition is fixed at boot, the in-app browser cannot be reached on
56
+ desktop through DSH's picker seam; [host-directory-listing.md](docs/host-directory-listing.md)
57
+ records the deferred design for serving listing from this plugin's own Host half.
58
+ Use **Cancel** to discard unsaved edits;
45
59
  saving/native picking blocks dismissal until it settles, and Host refusals preserve the
46
60
  draft. The same folder-list design is used by **Manage project**. Removal edits
47
61
  membership only, never deletes files; ownership/use restrictions remain Host-
@@ -98,9 +112,10 @@ canonical execution paths; DSH core and the application shell are not modified.
98
112
  ## New Conversation: Local or New worktree
99
113
 
100
114
  Start a new conversation through the default UI. Its **normal composer** offers
101
- **New worktree** only after its actual selected folder passes local Git validation
102
- and has a configured remote. Ordinary non-Git folders, unverified/unsupported
103
- sources and failed checks show **Local** only, with no remote-branch controls.
115
+ **New worktree** only after its actual selected folder passes local Git validation.
116
+ A configured remote is not required. Ordinary non-Git folders, unverified/unsupported
117
+ sources and failed checks show **Local** only, using the same compact, theme-aware
118
+ control as Git folders and no branch picker.
104
119
  Git repository subfolders remain eligible; no `.git`-directory heuristic is used.
105
120
  The workspace picker, rich editor, attachments, native Enter/Send and rollback
106
121
  stay installed; there is no separate first-message dialog.
@@ -123,11 +138,12 @@ tree support; normal creation checks still apply.
123
138
  native keyboard gesture). Native command adjudication and chip serialization
124
139
  run first; claimed/handled commands keep their original command path and do
125
140
  not provision a checkout.
126
- 3. A full-width progress panel shows **Fetching latest remote branch → Creating
127
- worktree → Generating and applying branch name**. The Host freshly fetches the
128
- chosen base, creates a random directory/initial local branch, then runs the
129
- configured fast auxiliary naming model and renames only that branch. Naming
130
- completes before the new conversation receives the prompt.
141
+ 3. A full-width progress panel shows **Creating worktree → Generating and applying
142
+ branch name**, preceded by **Fetching latest remote branch** only for a remote
143
+ selection. The Host pins the selected local commit without fetching, or freshly
144
+ fetches the selected remote branch, creates a random directory/initial branch,
145
+ then runs the configured fast auxiliary naming model and renames only that
146
+ branch. Naming completes before the new conversation receives the prompt.
131
147
  4. After the named checkout and exact blank session are ready, generic file drafts
132
148
  are re-uploaded for that exact session (receipts cannot cross sessions). The
133
149
  original, natively serialized prompt and ordered attachments are admitted once
@@ -139,10 +155,19 @@ of the normal conversation model. The foreground naming deadline is at most
139
155
  15 seconds (or a shorter configured deadline); unavailable or invalid output
140
156
  uses a deterministic safe fallback, never another-model retry.
141
157
 
142
- The optional **Base branch** control explicitly reads advertised branches so you
143
- can choose any configured remote/base before Send. Selecting the worktree mode
144
- itself does not query Git. `origin`/`main` are preferences, not restrictions. The
145
- actual checkout always uses a fresh selected-branch fetch; failed fetches never
158
+ The **Starting branch** control displays the current local branch by default,
159
+ not an ambiguous “Base branch” placeholder. Open it to choose **Local branches**
160
+ (no remote access) or **Remote branches**. A detached checkout defaults to its
161
+ current `HEAD` commit. The search filters the complete loaded branch generation
162
+ locally: keystrokes never refetch, change selection or lose its pinned commit.
163
+ Switching back to a previously loaded source/remote reuses that list; **Refresh**
164
+ explicitly loads a new generation. Clicking a branch selects it and dismisses the
165
+ picker immediately. Escape or moving focus outside also dismisses it; there is
166
+ no Close button. Selecting worktree mode itself does not query Git.
167
+
168
+ Local selection starts from a committed local branch, not uncommitted files; a
169
+ selected commit that moved before creation is refused rather than substituted.
170
+ Remote creation always fetches the selected branch afresh; failed fetches never
146
171
  substitute cached commits. Only the selected project folder is isolated.
147
172
 
148
173
  Progress uses bounded, event-driven wait requests over authenticated Connection
@@ -183,7 +208,7 @@ namingMaxTokens: 256
183
208
 
184
209
  These are plugin Config fields, not another New Chat form. The first ordinary
185
210
  prompt is bounded before branch naming. Inference happens only after successful
186
- fresh fetch and checkout creation, and the exact generated result is persisted
211
+ local pinning or remote fetch and checkout creation, and the exact generated result is persisted
187
212
  before rename; ready same-operation replay does no fetch, inference or creation.
188
213
  The foreground deadline is `min(namingTimeoutMs, 15000)`. Disabled/unavailable,
189
214
  timed-out or malformed naming yields a safe deterministic branch name and can
@@ -201,7 +226,7 @@ new lazy UI supplies `firstPrompt` and never schedules that background rename.
201
226
 
202
227
  ## Manager, reminders and guarded Local handoff
203
228
 
204
- The advanced **Worktrees** sidebar panel shows recorded checkouts, fetched bases,
229
+ The advanced **Worktrees** sidebar panel shows recorded checkouts, pinned bases,
205
230
  current/last-known branch and dirty state, conversations, protection, archive
206
231
  state and errors. The started-conversation header reads cached project/backing
207
232
  metadata only; there is no Worktrees button beside the project name in the chat
@@ -231,7 +256,7 @@ For handoff, open a conversation belonging to the chosen worktree first:
231
256
 
232
257
  1. Stop all writers in both checkouts, including external editors, processes,
233
258
  terminals, jobs and other sessions.
234
- 2. Preview the patch relative to the saved fetched base. The default target is
259
+ 2. Preview the patch relative to the saved pinned base. The default target is
235
260
  the original Local checkout; an optional explicit Local path must pass the
236
261
  same repository and identity checks.
237
262
  3. Review changed files, binary markers, byte count, base identity and retained
@@ -300,7 +325,7 @@ or applied patch may already be committed when cancellation arrives. Inspect
300
325
  **operation status** and the manager before retrying; recovery-required records
301
326
  are retained with errors. A successfully committed operation replay with the
302
327
  **same immutable request and operation UUID** returns its original session and
303
- fetched commit, rather than allocating another blank session or fetching again.
328
+ pinned commit, rather than allocating another blank session or fetching again.
304
329
  Changed settings, changed request or a new fresh preparation require a new UUID.
305
330
 
306
331
  The adapter never writes/clears the source draft; native submit machinery owns
@@ -331,7 +356,7 @@ After the staged release is approved and appears on npm, install the scoped
331
356
  package (the similarly named unscoped package is unrelated):
332
357
 
333
358
  ```sh
334
- dsh plugin --profile <profile> add @1yefuwang1/dsh-worktrees@0.2.13
359
+ dsh plugin --profile <profile> add @1yefuwang1/dsh-worktrees@0.2.18
335
360
  ```
336
361
 
337
362
  For local development or while release approval is pending, build explicitly from
@@ -403,14 +428,19 @@ means `list`. IDs and operation/preview IDs are UUIDs. Example read operations:
403
428
  ```text
404
429
  /worktree status
405
430
  /worktree list {"includeArchived":true,"limit":50}
431
+ /worktree branches {"branchSource":"local","query":"feature","limit":50}
406
432
  /worktree branches {"remote":"upstream","query":"feature","limit":50}
407
433
  ```
408
434
 
409
435
  Actions: `list`, `status`, `branches`, `create`, `start`, `branch`, `protect`,
410
436
  `archive`, `preview`, `export`, `handoff`. `repoPath` defaults to the caller's
411
- execution directory where supported. `create` requires a new `operationId`,
412
- remote and remote branch; the UI also captures remote identity/settings hash and
413
- requires an unchanged blank source. `sessionMode: "new"` starts empty history;
437
+ execution directory where supported. `create` requires a new `operationId` and
438
+ either `branchSource: "local"` with `localBranch` (plus `localOid` to refuse a
439
+ moved selection), or a remote and `remoteBranch` (the backwards-compatible default
440
+ when `branchSource` is omitted). Detached `localBranch: "HEAD"` requires `localOid`.
441
+ Local requests cannot contain remote fields, and vice versa. The UI captures the
442
+ expected local commit or remote identity, settings hash, and requires an unchanged
443
+ blank source. `sessionMode: "new"` starts empty history;
414
444
  `"continue"` inherits through a completed turn. `status` can inspect a worktree
415
445
  `id` or an `operationId`, not both. `export` consumes a retained `previewId`;
416
446
  `handoff` requires that preview and its own operation UUID.