@1yefuwang1/dsh-worktrees 0.0.0-stage → 0.2.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.
package/README.md CHANGED
@@ -1,3 +1,475 @@
1
- # Temporary Holding Version
1
+ # @1yefuwang1/dsh-worktrees
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Multi-folder projects with Local and isolated Git worktree threads for DeepSeek
4
+ Harness. This experimental Host + Web Client package is **`0.2.14`**; new releases
5
+ use staged npm publishing with maintainer review/2FA. It does not require Copilot, the
6
+ catalog plugin, or the search plugin. The scoped name avoids collision with the
7
+ unrelated npm package `dsh-worktrees`; stable tool, command and metadata names are
8
+ unchanged.
9
+
10
+ ## Projects and threads
11
+
12
+ A **project** is a durable logical group containing one or more existing folders.
13
+ A **thread** belongs to that project and executes in one selected folder: either
14
+ its Local directory or a managed linked Git checkout. Project membership is not
15
+ native Workspace membership, a working-directory change or a permission grant.
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.
20
+ - The compact **Projects** header uses Search, View options and Add project icon
21
+ controls. Search appears only when opened; Escape/Close clears it and restores
22
+ focus. Archive filters are in View options, not an always-visible dropdown.
23
+ - The **Projects** sidebar lists project headers and their Local/worktree threads
24
+ together, using the native Folder view's open/closed workspace icons, regular
25
+ 14px session titles, compact last-active times and 12px **Show X more sessions**
26
+ controls. Dates use session activity, not project edits; counts reflect only
27
+ hidden sessions. Hover/focus reveals row actions without permanently reserving
28
+ their width. Activity uses the native neutral 14px animated ring (including
29
+ reduced-motion behavior); pending/completion use solid state dots. A permanent
30
+ branch/worktree icon separately identifies managed worktree backing,
31
+ independent of whether a row is hovered. Worktree/branch names are not shown
32
+ inline; hover the thread title or worktree icon to see them, or open thread
33
+ details. The accessible label and details retain the original folder and actual
34
+ execution directory; branch names are cached
35
+ last-known values, not a background Git status poll.
36
+ - Existing Local native workspaces are imported as one-folder projects. Managed
37
+ checkout workspaces are grouped under their source project, not promoted into
38
+ separate projects. **Edit project** can combine imported folders into an
39
+ explicitly named multi-folder project without moving files, sessions or logs.
40
+ - **Create project** uses a compact project-name field and **Source folders** card.
41
+ Click **Add** to browse Host folders, check several folders (including folders
42
+ from different directories), then add the batch. Selections survive directory
43
+ navigation. Repeat Add to extend the list; each selected folder shows its name,
44
+ full path and a remove action. A project supports **1–32 folders**; duplicate
45
+ picks are ignored and over-limit batches are refused without dropping entries.
46
+ The source dropdown also offers manual absolute paths and the optional native
47
+ system chooser (one folder per pick). Use **Cancel** to discard unsaved edits;
48
+ saving/native picking blocks dismissal until it settles, and Host refusals preserve the
49
+ draft. The same folder-list design is used by **Manage project**. Removal edits
50
+ membership only, never deletes files; ownership/use restrictions remain Host-
51
+ authoritative. Canonical aliases are checked by the Host, not guessed in the UI.
52
+ - **Main folder** is required when creating a new multi-folder project in the GUI.
53
+ Choose it in Create/Manage project; a one-folder project uses its only folder.
54
+ The choice is saved by stable folder ID, so reordering folders does not change
55
+ it. Existing projects without a choice adopt their first folder on upgrade.
56
+ Changing main never moves or rebinds existing conversations or worktrees.
57
+ - The project's **+ / New Thread** uses the normal new-conversation flow in its
58
+ main folder. Use the adjacent folder arrow to start in another project folder,
59
+ or change **Conversation folder** in an empty blank composer before typing or
60
+ attaching files. An override is per conversation and never changes main. Drafts,
61
+ attachments, queued work and active setup block folder switching. The native
62
+ workspace picker/editor stay installed; there is no first-message dialog.
63
+ Choose **New worktree** before the first Send; mode selection only changes
64
+ intent and leaves the native draft/chips/files intact.
65
+ - Search, pinned order, running/pending indicators, archived-thread access and
66
+ native row actions remain available. Installed row extensions are mirrored into
67
+ plugin-owned aliases through public slot APIs; native entries and declarations
68
+ are never changed. The footer **Folder view** switch restores the original
69
+ native browser; **Projects** switches back. Plugin unload restores native UI.
70
+ - **Manage project → Remove project** asks for confirmation and removes only the
71
+ logical project and its folder/thread associations. Source folders, files,
72
+ native workspaces, conversations, managed worktrees and start receipts are kept,
73
+ even if threads are running. Conversations remain available under **Other
74
+ threads** and **Folder view**, with permanent worktree icons and path/branch
75
+ details. Cancel keeps all unsaved edits; failures preserve the editor draft.
76
+ - Removal remains effective after refresh/restart: a minimal durable removal
77
+ receipt suppresses automatic folder import and repairs interrupted metadata
78
+ cleanup. The project storage domain remains additive v1. To group the retained
79
+ folders again, explicitly create a project with a fresh UUID; existing native
80
+ folder identities and conversations are reused. Removed UUIDs are not recycled.
81
+ - A folder has one project owner. Explicit custom-project conflicts are refused;
82
+ imported ownership can be adopted. Removing individual folders from a retained
83
+ project is still refused if they have threads, worktrees or start receipts;
84
+ removing the project itself is metadata-only and has no such restriction.
85
+ Existing cwd values and history stay immutable.
86
+
87
+ For a multi-folder project, only the **selected Git folder** is isolated in a new
88
+ worktree. Other folders still refer to Local directories; the plugin does not
89
+ clone/synchronize every repository or loosen filesystem policy. The agent's
90
+ native **system reminder** states the project, main/default folder, actual selected
91
+ source folder, execution directory and truthful thread backing. Its bounded
92
+ folder list includes IDs and Local paths (first eight plus main/selected when
93
+ needed, at most ten); omitted folders/truncated values are marked, and an exact
94
+ `workspace_project` list request retrieves full metadata. Main/folder edits appear
95
+ on the next prompt assembly from cached metadata, without scanning repositories
96
+ or injecting user messages. Membership and defaults do not grant permissions.
97
+
98
+ All these changes are plugin-only. Native Workspace records retain their exact
99
+ canonical execution paths; DSH core and the application shell are not modified.
100
+
101
+ ## New Conversation: Local or New worktree
102
+
103
+ Start a new conversation through the default UI. Its **normal composer** offers
104
+ **New worktree** only after its actual selected folder passes local Git validation
105
+ and has a configured remote. Ordinary non-Git folders, unverified/unsupported
106
+ sources and failed checks show **Local** only, with no remote-branch controls.
107
+ Git repository subfolders remain eligible; no `.git`-directory heuristic is used.
108
+ The workspace picker, rich editor, attachments, native Enter/Send and rollback
109
+ stay installed; there is no separate first-message dialog.
110
+
111
+ A ready blank target performs one coalesced authenticated read-only status request
112
+ (several bounded local Git commands), not fetch/remote advertising, naming,
113
+ checkout or session creation. Observations are cached for the exact actor binding,
114
+ selected folder and connection generation. Target/view/panel changes, reconnect
115
+ and disposal abort stale reads. Main/title/token changes do not poll Git; failed
116
+ checks leave Local usable. Fresh configure/Send discovery remains authoritative
117
+ and can revoke an earlier positive. If New was already selected, revocation
118
+ preserves that intent and refuses Send safely until you explicitly choose Local.
119
+ A positive observation is not a permission grant or guarantee of remote/fetched-
120
+ tree support; normal creation checks still apply.
121
+
122
+ 1. Choose **New worktree**. This only selects the mode: no Git work, checkout,
123
+ branch, setup request or naming inference is performed on selection. Existing
124
+ draft text, reference chips and attachment objects stay in their native editor.
125
+ 2. Write your first ordinary message and press the **native Send** button (or its
126
+ native keyboard gesture). Native command adjudication and chip serialization
127
+ run first; claimed/handled commands keep their original command path and do
128
+ not provision a checkout.
129
+ 3. A full-width progress panel shows **Fetching latest remote branch → Creating
130
+ worktree → Generating and applying branch name**. The Host freshly fetches the
131
+ chosen base, creates a random directory/initial local branch, then runs the
132
+ configured fast auxiliary naming model and renames only that branch. Naming
133
+ completes before the new conversation receives the prompt.
134
+ 4. After the named checkout and exact blank session are ready, generic file drafts
135
+ are re-uploaded for that exact session (receipts cannot cross sessions). The
136
+ original, natively serialized prompt and ordered attachments are admitted once
137
+ to the **normal conversation LLM**, then that conversation opens.
138
+
139
+ The checkout directory, execution cwd, pinned base and session identity do not
140
+ move during naming. Naming uses `github-copilot/gpt-6-luna` by default, independent
141
+ of the normal conversation model. The foreground naming deadline is at most
142
+ 15 seconds (or a shorter configured deadline); unavailable or invalid output
143
+ uses a deterministic safe fallback, never another-model retry.
144
+
145
+ The optional **Base branch** control explicitly reads advertised branches so you
146
+ can choose any configured remote/base before Send. Selecting the worktree mode
147
+ itself does not query Git. `origin`/`main` are preferences, not restrictions. The
148
+ actual checkout always uses a fresh selected-branch fetch; failed fetches never
149
+ substitute cached commits. Only the selected project folder is isolated.
150
+
151
+ Progress uses bounded, event-driven wait requests over authenticated Connection
152
+ RPC, not periodic status polling. Preparation holds message admission and shows a
153
+ Cancel action; it does not freeze navigation or invoke the normal LLM early.
154
+ Failures return through native draft/chip restoration rather than a replacement
155
+ editor. A created checkout is retained if preparation or admission is cancelled.
156
+ Unknown admission is never blindly resent: inspect/open the exact created session.
157
+
158
+ ### Guarded native submission adapter
159
+
160
+ The installed runtime has no public ordinary-message target-resolution hook.
161
+ This version uses the **explicitly approved version-pinned adapter**: it leases
162
+ only the per-session native submit sink plus the trigger-controller thunk needed
163
+ to capture Send-time intent before asynchronous codecs/adjudication. The editor,
164
+ command machine, serialization, undo/rollback and normal prompt transport remain
165
+ native. No core file, global business service, native endpoint, keyboard handler
166
+ or other plugin's DOM is replaced.
167
+
168
+ Compatibility is the exact manifest/peer pin to DSH `0.2.0-rc.2` **plus structural
169
+ callback/owner checks**, not a runtime-source fingerprint or an upgrade-stability
170
+ claim. Missing/changed shapes fail closed rather than sending a worktree-selected
171
+ prompt to Local. Descriptor ownership is identity-checked on teardown; pending
172
+ attempts settle before restoration. Future runtime upgrades require reviewing this
173
+ adapter. Do not grant a version exemption to bypass that compatibility boundary.
174
+
175
+ ### Configurable automatic naming
176
+
177
+ Naming uses a small auxiliary call independent of the conversation model. Defaults:
178
+
179
+ ```yaml
180
+ namingEnabled: true
181
+ namingProvider: github-copilot
182
+ namingModel: gpt-6-luna
183
+ namingTimeoutMs: 15000
184
+ namingMaxTokens: 256
185
+ ```
186
+
187
+ These are plugin Config fields, not another New Chat form. The first ordinary
188
+ prompt is bounded before branch naming. Inference happens only after successful
189
+ fresh fetch and checkout creation, and the exact generated result is persisted
190
+ before rename; ready same-operation replay does no fetch, inference or creation.
191
+ The foreground deadline is `min(namingTimeoutMs, 15000)`. Disabled/unavailable,
192
+ timed-out or malformed naming yields a safe deterministic branch name and can
193
+ consume no more than the bounded configured auxiliary call.
194
+
195
+ The directory remains the random `worktree-<UUID>` name; the record's
196
+ `naming.directoryName` is suggestion metadata, not its actual basename. Session
197
+ titles stay with the native title feature. A branch collision or changed initial
198
+ branch is not forced; preparation fails and retains its receipts/files.
199
+
200
+ Explicit command/tool `create` with `firstPrompt` uses the same checkout-first
201
+ foreground naming order. Legacy no-`firstPrompt` tool creates may still use the
202
+ previous post-first-message naming path (with its idle/maintenance checks); the
203
+ new lazy UI supplies `firstPrompt` and never schedules that background rename.
204
+
205
+ ## Manager, reminders and guarded Local handoff
206
+
207
+ The advanced **Worktrees** sidebar panel shows recorded checkouts, fetched bases,
208
+ current/last-known branch and dirty state, conversations, protection, archive
209
+ state and errors. The started-conversation header reads cached project/backing
210
+ metadata only; there is no Worktrees button beside the project name in the chat
211
+ header. Open the manager from its sidebar entry, with no background Git query.
212
+ A ready blank conversation checks only its actual target's local Git availability;
213
+ Local mode sends no setup/fetch and remains usable if discovery fails. There is no
214
+ sidebar-wide or per-token Git polling. Project metadata refreshes on connection
215
+ generation, explicit edits and structural native Workspace changes, not per render/token or timer.
216
+ UI requests use the existing authenticated Connection RPC transport, not the
217
+ slash-command registry. The plugin owns exact POST routes
218
+ `/api/dsh-worktrees/projects`, `/api/dsh-worktrees/execute`,
219
+ `/api/dsh-worktrees/prepare` and `/api/dsh-worktrees/progress`, preserving the
220
+ public RPC envelope/correlation. It does not claim the shared `/api` interceptor,
221
+ which is exclusive and already belongs to the native API gateway. Selecting New worktree, opening or refreshing the manager,
222
+ reading checkout status and cancelling a UI request therefore create no
223
+ `command/run` or `command/done` conversation rows. Explicit user-entered
224
+ `/worktree` commands and agent `git_worktree` calls remain visible normally.
225
+ There is no periodic polling; actor identity and filesystem authorization are
226
+ unchanged, and UI errors are shown inline. Existing historical rows are not erased.
227
+ Agent runtime-context reminders are separate from these UI queries.
228
+ Open an exact conversation, create a branch in the worktree, protect/unprotect it,
229
+ or archive/restore its plugin record. **Archive is not deletion**: checkout files,
230
+ pinned base refs, sessions and logs remain. Protection prevents branch creation,
231
+ handoff and archiving until explicitly removed; it is not an OS write lock.
232
+
233
+ For handoff, open a conversation belonging to the chosen worktree first:
234
+
235
+ 1. Stop all writers in both checkouts, including external editors, processes,
236
+ terminals, jobs and other sessions.
237
+ 2. Preview the patch relative to the saved fetched base. The default target is
238
+ the original Local checkout; an optional explicit Local path must pass the
239
+ same repository and identity checks.
240
+ 3. Review changed files, binary markers, byte count, base identity and retained
241
+ patch path. Export can return bounded inline text; for a large patch, copy the
242
+ retained path. No unauthenticated download endpoint is invented.
243
+ 4. Explicitly confirm that other writers are stopped, then apply and continue in
244
+ the exact Local continuation returned by the Host.
245
+
246
+ Handoff requires Full access, idle known source/target sessions and a clean
247
+ Local checkout at the saved base. It checks repository identities, source/target
248
+ fingerprints, patch integrity and optimistic preconditions, and obtains Host
249
+ maintenance claims for known sessions. It never pulls, resets or switches the
250
+ Local branch to make a mismatch fit. **It is not globally atomic**: outside
251
+ writers must remain stopped through completion. Applying from an agent tool in
252
+ its own running source turn is unsupported and returns `BUSY`, rather than
253
+ waiting for that turn to become idle. Use the idle GUI command path instead.
254
+
255
+ Sources, original history and retained patch files are not deleted. Continuation
256
+ uses the normal fork seed through the last completed turn, not a log rewrite;
257
+ older paths in inherited history may refer to the original checkout. Normal
258
+ preset/model/permission/approval/plan and Goal semantics remain authoritative;
259
+ the plugin does not reinterpret Goal state or grant permission through a copied
260
+ history or a confirmation checkbox.
261
+
262
+ ## Permissions, supported repositories and limits
263
+
264
+ **Cross-root Git mutations are Full-access-only.** Creation, starting a session
265
+ in a recorded checkout, branch creation, preview/export (which write snapshots),
266
+ and handoff require the receiving ordinary session's existing `danger-full-access`
267
+ policy. Shared Git administration cannot be honestly confined to a single
268
+ workspace-write checkout. List/status/branch discovery use the caller's managed
269
+ filesystem/subprocess capabilities and may still be refused by its sandbox.
270
+ Protect/archive change plugin metadata rather than deleting repository data.
271
+ Agent mutation tools are refused while plan mode is active or pending enabled.
272
+
273
+ The GUI never creates a more-privileged blank actor to bypass the current
274
+ conversation's policy. Without a usable current ordinary conversation, the root
275
+ manager asks you to open one. An acknowledgement confirms user intent only;
276
+ change permissions through the existing permission control if needed. No
277
+ privilege flags or automatic escalation are supplied.
278
+
279
+ Supported: ordinary non-bare, non-shallow local Git repositories with a committed
280
+ HEAD, canonical local filesystem/subprocess execution, and HTTPS, SSH or local
281
+ file remotes. Repository files must fit the configured count/byte bounds and
282
+ supported UTF-8 paths/mappings. Git authentication uses existing noninteractive
283
+ Git transport configuration; the plugin does not add a sign-in or password prompt.
284
+
285
+ Unsupported cases fail explicitly, including:
286
+
287
+ - Git LFS and clean/smudge filters or working-tree encoding attributes;
288
+ - sparse checkouts, partial/promisor clones, shallow clones, submodules and
289
+ unsupported/custom Git worktree or ref-storage mappings;
290
+ - unborn/bare repositories, executable remote helpers, unsafe/escaping paths or
291
+ symlinks, unmerged files, and unavailable project subdirectories;
292
+ - remote filesystem execution providers without the required local capability
293
+ mapping, stale previews/cursors, changed remote identities, or over-limit output.
294
+
295
+ Hooks, external diff/fsmonitor and recursive submodule behavior are suppressed
296
+ for plugin Git operations. This is not a claim that arbitrary configured Git
297
+ transports or external writers are globally sandboxed in Full access.
298
+
299
+ ## Cancellation and recovery
300
+
301
+ Cancellation is not destructive rollback. A fetch, checkout, registered session,
302
+ or applied patch may already be committed when cancellation arrives. Inspect
303
+ **operation status** and the manager before retrying; recovery-required records
304
+ are retained with errors. A successfully committed operation replay with the
305
+ **same immutable request and operation UUID** returns its original session and
306
+ fetched commit, rather than allocating another blank session or fetching again.
307
+ Changed settings, changed request or a new fresh preparation require a new UUID.
308
+
309
+ The adapter never writes/clears the source draft; native submit machinery owns
310
+ its optimistic commit and exact chip-aware rollback. Its temporary message block
311
+ is released after preparation/admission settlement, cancellation or disposal. If creation has an
312
+ uncertain outcome, **Check operation status** uses the same UUID before another
313
+ creation is allowed; an exact created conversation can be opened without sending
314
+ a message. Progress/transport receipts are scope-local and bounded to the latest
315
+ 128 terminal operations; durable controller receipts own recovery after reload. Re-preview after Host restart: preview registrations and page cursors
316
+ are transient, even though snapshot files and durable operation/worktree records
317
+ are retained. Deferred naming receipts are durable and tied to the exact original
318
+ first message, not later messages or inherited/replaced history.
319
+
320
+ There is no physical worktree-delete operation. Disabling/removing the plugin
321
+ does not remove checkout files or rewrite original session logs. Any manual Git
322
+ cleanup is a separate user-owned task after inspecting identities and retained
323
+ records; do not infer cleanup authority from an archive flag.
324
+
325
+ ## Install from this repository
326
+
327
+ Requires DSH/DSH peers `0.2.0-rc.2`, Node.js `>=22.19.0`, a suitable local Git
328
+ executable, and the ordinary session/filesystem/subprocess/sandbox/preset/plan
329
+ capabilities. The manifest names `@deepseek-ai/dsh-agent-preset-registry` and
330
+ `@deepseek-ai/dsh-plan-mode`; the Web Client mounts beside the existing
331
+ conversation/workspace UI. Development uses pnpm `11.7.0`.
332
+
333
+ After the staged release is approved and appears on npm, install the scoped
334
+ package (the similarly named unscoped package is unrelated):
335
+
336
+ ```sh
337
+ dsh plugin --profile <profile> add @1yefuwang1/dsh-worktrees@0.2.14
338
+ ```
339
+
340
+ For local development or while release approval is pending, build explicitly from
341
+ the private monorepo root, then opt into a local leaf installation:
342
+
343
+ ```sh
344
+ pnpm install --frozen-lockfile --ignore-scripts
345
+ pnpm --filter @1yefuwang1/dsh-worktrees run build
346
+ # Alters the chosen profile only if you choose to run it:
347
+ dsh plugin --profile <profile> add -w packages/worktrees
348
+ ```
349
+
350
+ Or build a standalone tarball:
351
+
352
+ ```sh
353
+ pnpm --dir packages/worktrees pack --pack-destination ../../artifacts --config.ignore-scripts=true
354
+ ```
355
+
356
+ The root Git URL is not an installable plugin. The package contains compiled ESM,
357
+ declarations, its plain-JS Client factory, bundle patch, metadata, docs and license;
358
+ there are no required `prepare` or install-time build scripts. Follow the plugin
359
+ manager's activation/restart result and refresh the existing GUI when needed;
360
+ no automatic Client updates without the normal development watcher are promised.
361
+ Development checks never install/configure an active profile or start a server.
362
+
363
+ ## Configurable worktree root folder
364
+
365
+ Open the **Plugins** page, choose **Projects and worktrees**, then configure its
366
+ **git-worktrees** entry. The **Worktree root folder** field edits the active
367
+ profile's existing `root` setting through native Host-backed settings. Enter an
368
+ absolute Host folder path outside your source repositories and choose **Save**.
369
+ **Reset to inherited default** removes only the root override. The default is
370
+ `worktrees/` under the harness home (normally `~/.dsh/worktrees`).
371
+
372
+ After this version is activated, saved root changes apply to **new creates live**;
373
+ there is no directory migration. An operation captures its root once at admission,
374
+ so a save during fetch/naming or a repository queue does not relocate that create.
375
+ Existing threads, working directories, retained files and same-operation replays
376
+ keep their original paths and identities. Saving this setting does not create a
377
+ folder, fetch Git, or grant filesystem permission.
378
+
379
+ The form uses native revision fences; conflicting/refused writes preserve the
380
+ path draft. Non-Host-backed/remote-browser forms are unavailable rather than
381
+ pretending to persist locally. Private snapshot/export/handoff storage remains
382
+ pinned to the root resolved at this plugin load, preserving existing previews;
383
+ the next normal Host/plugin load adopts the persisted root for those snapshots.
384
+
385
+ ## Configuration and command/tool surface
386
+
387
+ The bundle inserts the `git-worktrees` Host entry. Change its supported config
388
+ through normal profile composition/settings, not the plugin's package files.
389
+
390
+ | Field | Default | Meaning |
391
+ | --- | --- | --- |
392
+ | `root` | Harness home `worktrees/` | Persisted native settings field for new worktree directories; absolute Host path, outside source repositories; snapshots retain their load-time root |
393
+ | `gitExecutable` | `git` | Executable resolved by the managed subprocess provider |
394
+ | `defaultRemote` / `defaultBranch` | `origin` / `main` | Initial preferences, never an allowlist |
395
+ | `commandTimeoutMs` | `30000` | Git command deadline |
396
+ | `fetchTimeoutMs` | `60000` | Advertisement/fetch deadline |
397
+ | `operationTimeoutMs` | `120000` | Overall operation deadline |
398
+ | `maxSnapshotBytes` | `33554432` | Snapshot byte limit (32 MiB) |
399
+ | `maxFiles` | `1000` | Repository/snapshot and advertised-branch count limit |
400
+ | `maxRefBytes` | `8388608` | Bounded Git output (8 MiB) |
401
+
402
+ The `/worktree` command and `git_worktree` agent tool share the Host controller.
403
+ Commands accept `<action> [JSON arguments]` or one JSON request object; no input
404
+ means `list`. IDs and operation/preview IDs are UUIDs. Example read operations:
405
+
406
+ ```text
407
+ /worktree status
408
+ /worktree list {"includeArchived":true,"limit":50}
409
+ /worktree branches {"remote":"upstream","query":"feature","limit":50}
410
+ ```
411
+
412
+ Actions: `list`, `status`, `branches`, `create`, `start`, `branch`, `protect`,
413
+ `archive`, `preview`, `export`, `handoff`. `repoPath` defaults to the caller's
414
+ execution directory where supported. `create` requires a new `operationId`,
415
+ remote and remote branch; the UI also captures remote identity/settings hash and
416
+ requires an unchanged blank source. `sessionMode: "new"` starts empty history;
417
+ `"continue"` inherits through a completed turn. `status` can inspect a worktree
418
+ `id` or an `operationId`, not both. `export` consumes a retained `previewId`;
419
+ `handoff` requires that preview and its own operation UUID.
420
+
421
+ The Client uses authenticated quiet Connection RPC, not commands. Git requests
422
+ resolve the actual selected ordinary session; metadata-only project reads omit an
423
+ actor and never resume a conversation. UI Local creation delegates to the native
424
+ new-session service; it is never a fallback actor for Git operations. The explicit
425
+ project `start` operation remains available to commands and tools.
426
+ Versioned results are `{v:1,ok:true,data:...}` or
427
+ `{v:1,ok:false,error:{code,message}}`; transport and decode failures are shown inline.
428
+ Explicit commands remain normally logged.
429
+
430
+ `/project` (one JSON action object) and `workspace_project` share the project
431
+ controller: `list` (optional `projectId` filter), `create`, `update`, `remove`,
432
+ `bind`, and `start`. `remove` takes only `projectId` and returns
433
+ `{removed:true,projectId,scope:"project-metadata"}`. Repeating a committed removal
434
+ is safe; it never deletes directories, sessions or Git data. UI removal uses the
435
+ actual authenticated operator without activating an unrelated conversation;
436
+ commands/tools retain their genuine caller and normal mutation policy.
437
+ `create` takes a fresh UUID `id`, title and absolute existing `folders`.
438
+ Optional `mainFolder` is an absolute path matching a resulting source folder
439
+ canonically; omitted create uses first for API compatibility. `update.folders`
440
+ replaces the complete list; `update.mainFolder` can change only the default.
441
+ Omitted update preserves main across reordering; removing it with multiple folders
442
+ remaining requires a replacement (a sole remaining folder becomes main).
443
+ Snapshots expose `mainFolderId`. `bind` validates actual ordinary cwd/backing;
444
+ it cannot move a session. `start` takes a unique `operationId`, `projectId` and
445
+ optional native `folderId`: omitted uses main, explicit selects another folder.
446
+ It returns an exact blank session and never sends a prompt. Ready replay uses
447
+ its original receipt folder/session even after main changes; ambiguous partial
448
+ starts refuse duplication. `git_worktree create` accepts paired
449
+ `projectId`/`folderId`; the selected original folder must match its creation path.
450
+ Project metadata never grants Full access; cross-root thread starts retain caller
451
+ checks and tool mutations respect active/pending plan mode.
452
+
453
+ Public ESM exports are the root plugin/config/types, `./git`, `./naming`,
454
+ `./projects`, `./types`, `./client`, `./package.json` and `./locale/en.json`.
455
+
456
+ ## Verification and release status
457
+
458
+ ```sh
459
+ pnpm --filter @1yefuwang1/dsh-worktrees run test
460
+ pnpm --filter @1yefuwang1/dsh-worktrees run test:integration
461
+ pnpm --filter @1yefuwang1/dsh-worktrees run test:types
462
+ pnpm --filter @1yefuwang1/dsh-worktrees run test:pack
463
+ ```
464
+
465
+ Unit/protocol tests and temporary local-Git fixtures are not a live GUI, remote
466
+ credential or transport-compatibility probe. Client tests are static/pure protocol
467
+ checks, not a fake DOM or screenshot renderer. Browser interaction, visible slot
468
+ registration and light/dark appearance still require verification in the installed
469
+ GUI; they were unavailable during initial Client implementation.
470
+
471
+ Release tags use `@1yefuwang1/dsh-worktrees-vX.Y.Z`, matching this leaf's full scoped
472
+ name and version. The shared release gate/staged OIDC workflow never publishes the
473
+ private root or all leaves together. The workflow stages the release; a maintainer
474
+ reviews and approves it with npm 2FA before the version becomes publicly available.
475
+ See [the package changelog](<CHANGELOG.md>) and [MIT license](<LICENSE>).