dsh-over-ssh 0.1.0 → 0.2.0

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 (250) hide show
  1. package/README.md +19 -17
  2. package/agents/agent-manifest.json +6 -6
  3. package/agents/linux-amd64/dsh-over-ssh-agent +0 -0
  4. package/agents/linux-arm64/dsh-over-ssh-agent +0 -0
  5. package/lib/client.js +422 -337
  6. package/lib/file-references.js +92 -35
  7. package/lib/fs.js +295 -113
  8. package/lib/index.js +6912 -4330
  9. package/lib/terminal-wrapper.js +9 -4
  10. package/lib/types/src/config.d.ts +156 -9
  11. package/lib/types/src/file-references.d.ts +0 -1
  12. package/lib/types/src/host/app/backend.d.ts +44 -3
  13. package/lib/types/src/host/app/recycle-bin/recycle-bin-contract.d.ts +0 -1
  14. package/lib/types/src/host/app/recycle-bin/recycle-bin-service.d.ts +0 -1
  15. package/lib/types/src/host/app/session-admin/session-admin-contract.d.ts +12 -1
  16. package/lib/types/src/host/app/session-admin/session-admin-service.d.ts +0 -1
  17. package/lib/types/src/host/app/transport/transport-selector.d.ts +0 -1
  18. package/lib/types/src/host/app/transport/transport-service.d.ts +0 -1
  19. package/lib/types/src/host/domain/capability.d.ts +0 -1
  20. package/lib/types/src/host/domain/errors.d.ts +0 -1
  21. package/lib/types/src/host/domain/roots/connection.d.ts +0 -1
  22. package/lib/types/src/host/domain/roots/root.d.ts +24 -9
  23. package/lib/types/src/host/domain/roots/session-roots.d.ts +23 -1
  24. package/lib/types/src/host/domain/roots/ssh-config.d.ts +0 -1
  25. package/lib/types/src/host/domain/session/session-admin.d.ts +0 -1
  26. package/lib/types/src/host/domain/transfer/recycle-bin.d.ts +0 -1
  27. package/lib/types/src/host/domain/transfer/transfer.d.ts +0 -1
  28. package/lib/types/src/host/infra/transport/agent/agent-installer.d.ts +0 -1
  29. package/lib/types/src/host/infra/transport/forward.d.ts +75 -0
  30. package/lib/types/src/host/infra/transport/ssh/ssh2-transport.d.ts +5 -1
  31. package/lib/types/src/host/infra/transport/transport-base.d.ts +0 -1
  32. package/lib/types/src/host/infra/transport/transport.d.ts +42 -2
  33. package/lib/types/src/host/integration/agent/agent-preflight.d.ts +0 -1
  34. package/lib/types/src/host/integration/fs/file-reference-provider.d.ts +0 -1
  35. package/lib/types/src/host/integration/fs/fs-provider.d.ts +18 -3
  36. package/lib/types/src/host/integration/transfer/transfer-service.d.ts +0 -1
  37. package/lib/types/src/index.d.ts +23 -1
  38. package/lib/types/src/local-bridge-refs.d.ts +0 -1
  39. package/lib/types/src/local-bridge.d.ts +0 -1
  40. package/lib/types/src/shared/root-keys.d.ts +120 -0
  41. package/lib/types/src/wiring/helpers.d.ts +0 -1
  42. package/package.json +5 -3
  43. package/lib/types/src/client/controls.d.ts +0 -131
  44. package/lib/types/src/client/core/card-focus-trap.d.ts +0 -45
  45. package/lib/types/src/client/core/controls.d.ts +0 -164
  46. package/lib/types/src/client/core/latest.d.ts +0 -48
  47. package/lib/types/src/client/core/locale.d.ts +0 -38
  48. package/lib/types/src/client/core/message.d.ts +0 -37
  49. package/lib/types/src/client/core/panel-model.d.ts +0 -134
  50. package/lib/types/src/client/core/portal.d.ts +0 -266
  51. package/lib/types/src/client/core/remote.d.ts +0 -84
  52. package/lib/types/src/client/core/styles.d.ts +0 -458
  53. package/lib/types/src/client/file-tree-io.d.ts +0 -19
  54. package/lib/types/src/client/file-tree.d.ts +0 -271
  55. package/lib/types/src/client/flows/directory-browser.d.ts +0 -587
  56. package/lib/types/src/client/flows/session-directory.d.ts +0 -415
  57. package/lib/types/src/client/flows/workspace-directory-flow.d.ts +0 -480
  58. package/lib/types/src/client/locale.d.ts +0 -31
  59. package/lib/types/src/client/panel-model.d.ts +0 -37
  60. package/lib/types/src/client/panel.d.ts +0 -77
  61. package/lib/types/src/client/roots/connection-test.d.ts +0 -69
  62. package/lib/types/src/client/roots/roots-panel-state.d.ts +0 -307
  63. package/lib/types/src/client/roots/roots-panel-view.d.ts +0 -280
  64. package/lib/types/src/client/roots/roots-panel.d.ts +0 -364
  65. package/lib/types/src/client/roots/transfer-panel-view.d.ts +0 -35
  66. package/lib/types/src/client/roots/transfer-panel.d.ts +0 -241
  67. package/lib/types/src/client/roots/transfer-progress.d.ts +0 -67
  68. package/lib/types/src/client/roots-panel-view.d.ts +0 -236
  69. package/lib/types/src/client/roots-panel.d.ts +0 -347
  70. package/lib/types/src/client/session/session-panel-view.d.ts +0 -336
  71. package/lib/types/src/client/session/session-panel.d.ts +0 -322
  72. package/lib/types/src/client/session/session-remote-mark.d.ts +0 -110
  73. package/lib/types/src/client/session/session-row-actions.d.ts +0 -398
  74. package/lib/types/src/client/session-panel.d.ts +0 -152
  75. package/lib/types/src/client/styles.d.ts +0 -252
  76. package/lib/types/src/client/workspace-directory-flow.d.ts +0 -342
  77. package/lib/types/src/fs.d.ts +0 -46
  78. package/lib/types/src/host/app/recycle-bin/recycle-bin-move.d.ts +0 -18
  79. package/lib/types/src/host/app/recycle-bin/recycle-bin-world.d.ts +0 -38
  80. package/lib/types/src/host/app/recycle-bin-contract.d.ts +0 -215
  81. package/lib/types/src/host/app/recycle-bin-move.d.ts +0 -18
  82. package/lib/types/src/host/app/recycle-bin-service.d.ts +0 -45
  83. package/lib/types/src/host/app/recycle-bin-world.d.ts +0 -35
  84. package/lib/types/src/host/app/roots/roots-api-connections.d.ts +0 -49
  85. package/lib/types/src/host/app/roots/roots-api-contract.d.ts +0 -369
  86. package/lib/types/src/host/app/roots/roots-api-directories.d.ts +0 -13
  87. package/lib/types/src/host/app/roots/roots-api-http.d.ts +0 -77
  88. package/lib/types/src/host/app/roots/roots-api-long-poll.d.ts +0 -130
  89. package/lib/types/src/host/app/roots/roots-api-projections.d.ts +0 -102
  90. package/lib/types/src/host/app/roots/roots-api-roots.d.ts +0 -13
  91. package/lib/types/src/host/app/roots/roots-api-state.d.ts +0 -22
  92. package/lib/types/src/host/app/roots/roots-api-transfers.d.ts +0 -26
  93. package/lib/types/src/host/app/roots/roots-api.d.ts +0 -55
  94. package/lib/types/src/host/app/roots/user-roots.d.ts +0 -552
  95. package/lib/types/src/host/app/roots-api-connections.d.ts +0 -49
  96. package/lib/types/src/host/app/roots-api-contract.d.ts +0 -339
  97. package/lib/types/src/host/app/roots-api-directories.d.ts +0 -13
  98. package/lib/types/src/host/app/roots-api-http.d.ts +0 -77
  99. package/lib/types/src/host/app/roots-api-projections.d.ts +0 -102
  100. package/lib/types/src/host/app/roots-api-roots.d.ts +0 -13
  101. package/lib/types/src/host/app/roots-api-state.d.ts +0 -22
  102. package/lib/types/src/host/app/roots-api-support.d.ts +0 -182
  103. package/lib/types/src/host/app/roots-api-transfers.d.ts +0 -13
  104. package/lib/types/src/host/app/roots-api.d.ts +0 -55
  105. package/lib/types/src/host/app/routed-fs.d.ts +0 -239
  106. package/lib/types/src/host/app/serialize.d.ts +0 -37
  107. package/lib/types/src/host/app/session-admin/session-admin-context.d.ts +0 -36
  108. package/lib/types/src/host/app/session-admin/session-admin-delete.d.ts +0 -34
  109. package/lib/types/src/host/app/session-admin-context.d.ts +0 -36
  110. package/lib/types/src/host/app/session-admin-contract.d.ts +0 -214
  111. package/lib/types/src/host/app/session-admin-delete.d.ts +0 -34
  112. package/lib/types/src/host/app/session-admin-service.d.ts +0 -38
  113. package/lib/types/src/host/app/takeover/takeover-plan.d.ts +0 -227
  114. package/lib/types/src/host/app/takeover/takeover-rows.d.ts +0 -55
  115. package/lib/types/src/host/app/transport-selector.d.ts +0 -98
  116. package/lib/types/src/host/app/transport-service.d.ts +0 -75
  117. package/lib/types/src/host/app/user-roots.d.ts +0 -461
  118. package/lib/types/src/host/domain/bin-location.d.ts +0 -79
  119. package/lib/types/src/host/domain/connection.d.ts +0 -95
  120. package/lib/types/src/host/domain/glob-pattern.d.ts +0 -62
  121. package/lib/types/src/host/domain/literal-text.d.ts +0 -63
  122. package/lib/types/src/host/domain/path-grammar.d.ts +0 -84
  123. package/lib/types/src/host/domain/recycle-bin.d.ts +0 -337
  124. package/lib/types/src/host/domain/root.d.ts +0 -74
  125. package/lib/types/src/host/domain/roots/bin-location.d.ts +0 -91
  126. package/lib/types/src/host/domain/roots/route-table.d.ts +0 -102
  127. package/lib/types/src/host/domain/route-table.d.ts +0 -80
  128. package/lib/types/src/host/domain/session/terminal-target.d.ts +0 -136
  129. package/lib/types/src/host/domain/session-admin.d.ts +0 -330
  130. package/lib/types/src/host/domain/shell.d.ts +0 -47
  131. package/lib/types/src/host/domain/ssh-config.d.ts +0 -73
  132. package/lib/types/src/host/domain/terminal-target.d.ts +0 -132
  133. package/lib/types/src/host/domain/tool-requests.d.ts +0 -369
  134. package/lib/types/src/host/domain/transfer.d.ts +0 -260
  135. package/lib/types/src/host/infra/backend/local-backend.d.ts +0 -84
  136. package/lib/types/src/host/infra/backend/local-version.d.ts +0 -43
  137. package/lib/types/src/host/infra/backend/platform-local-backend.d.ts +0 -89
  138. package/lib/types/src/host/infra/backend/remote-backend.d.ts +0 -239
  139. package/lib/types/src/host/infra/cache/lru.d.ts +0 -52
  140. package/lib/types/src/host/infra/cache/versioned.d.ts +0 -77
  141. package/lib/types/src/host/infra/temp-name.d.ts +0 -19
  142. package/lib/types/src/host/infra/transport/agent/agent-protocol-client.d.ts +0 -132
  143. package/lib/types/src/host/infra/transport/agent/agent-protocol-codec.d.ts +0 -140
  144. package/lib/types/src/host/infra/transport/agent/agent-protocol-errors.d.ts +0 -41
  145. package/lib/types/src/host/infra/transport/agent/agent-protocol-frames.d.ts +0 -197
  146. package/lib/types/src/host/infra/transport/agent/agent-protocol-types.d.ts +0 -564
  147. package/lib/types/src/host/infra/transport/agent/agent-transport.d.ts +0 -418
  148. package/lib/types/src/host/infra/transport/agent-installer.d.ts +0 -121
  149. package/lib/types/src/host/infra/transport/agent-protocol-client.d.ts +0 -123
  150. package/lib/types/src/host/infra/transport/agent-protocol-codec.d.ts +0 -131
  151. package/lib/types/src/host/infra/transport/agent-protocol-errors.d.ts +0 -41
  152. package/lib/types/src/host/infra/transport/agent-protocol-frames.d.ts +0 -197
  153. package/lib/types/src/host/infra/transport/agent-protocol-types.d.ts +0 -509
  154. package/lib/types/src/host/infra/transport/agent-transport.d.ts +0 -353
  155. package/lib/types/src/host/infra/transport/alias-transport.d.ts +0 -206
  156. package/lib/types/src/host/infra/transport/askpass-fs.d.ts +0 -20
  157. package/lib/types/src/host/infra/transport/askpass.d.ts +0 -133
  158. package/lib/types/src/host/infra/transport/command-pool.d.ts +0 -61
  159. package/lib/types/src/host/infra/transport/fs-commands.d.ts +0 -140
  160. package/lib/types/src/host/infra/transport/git-status-route.d.ts +0 -63
  161. package/lib/types/src/host/infra/transport/git-status.d.ts +0 -101
  162. package/lib/types/src/host/infra/transport/node-spawn.d.ts +0 -26
  163. package/lib/types/src/host/infra/transport/session-window.d.ts +0 -51
  164. package/lib/types/src/host/infra/transport/shell-quote.d.ts +0 -59
  165. package/lib/types/src/host/infra/transport/ssh/alias-transport.d.ts +0 -206
  166. package/lib/types/src/host/infra/transport/ssh/askpass-fs.d.ts +0 -20
  167. package/lib/types/src/host/infra/transport/ssh/askpass.d.ts +0 -133
  168. package/lib/types/src/host/infra/transport/ssh/shell-quote.d.ts +0 -62
  169. package/lib/types/src/host/infra/transport/ssh/ssh-argv.d.ts +0 -43
  170. package/lib/types/src/host/infra/transport/ssh-argv.d.ts +0 -43
  171. package/lib/types/src/host/infra/transport/ssh2-transport.d.ts +0 -302
  172. package/lib/types/src/host/integration/agent/agent-install-io.d.ts +0 -33
  173. package/lib/types/src/host/integration/agent/askpass-registry.d.ts +0 -66
  174. package/lib/types/src/host/integration/agent-install-io.d.ts +0 -33
  175. package/lib/types/src/host/integration/agent-preflight.d.ts +0 -56
  176. package/lib/types/src/host/integration/anchor-directory.d.ts +0 -56
  177. package/lib/types/src/host/integration/askpass-registry.d.ts +0 -59
  178. package/lib/types/src/host/integration/bin-root-resolver.d.ts +0 -81
  179. package/lib/types/src/host/integration/connection-test.d.ts +0 -73
  180. package/lib/types/src/host/integration/file-reference-provider.d.ts +0 -115
  181. package/lib/types/src/host/integration/fs/git-status-wiring.d.ts +0 -21
  182. package/lib/types/src/host/integration/fs/platform-errors.d.ts +0 -94
  183. package/lib/types/src/host/integration/fs/remote-file-tools.d.ts +0 -369
  184. package/lib/types/src/host/integration/fs/remote-index.d.ts +0 -177
  185. package/lib/types/src/host/integration/fs-provider.d.ts +0 -226
  186. package/lib/types/src/host/integration/lsp/lsp-framing.d.ts +0 -38
  187. package/lib/types/src/host/integration/lsp/lsp-registry.d.ts +0 -67
  188. package/lib/types/src/host/integration/lsp/lsp-session.d.ts +0 -130
  189. package/lib/types/src/host/integration/management-tools.d.ts +0 -64
  190. package/lib/types/src/host/integration/recycle-bin-service.d.ts +0 -247
  191. package/lib/types/src/host/integration/remote/connection-test.d.ts +0 -73
  192. package/lib/types/src/host/integration/remote/remote-face.d.ts +0 -127
  193. package/lib/types/src/host/integration/remote/remote-tool-backend.d.ts +0 -108
  194. package/lib/types/src/host/integration/remote-face.d.ts +0 -127
  195. package/lib/types/src/host/integration/remote-file-tools.d.ts +0 -241
  196. package/lib/types/src/host/integration/remote-home.d.ts +0 -69
  197. package/lib/types/src/host/integration/remote-index.d.ts +0 -165
  198. package/lib/types/src/host/integration/remote-job-tools.d.ts +0 -295
  199. package/lib/types/src/host/integration/remote-tool-backend.d.ts +0 -97
  200. package/lib/types/src/host/integration/remote-tools.d.ts +0 -206
  201. package/lib/types/src/host/integration/root-registry.d.ts +0 -115
  202. package/lib/types/src/host/integration/roots/anchor-directory.d.ts +0 -56
  203. package/lib/types/src/host/integration/roots/bin-root-resolver.d.ts +0 -81
  204. package/lib/types/src/host/integration/roots/remote-home.d.ts +0 -69
  205. package/lib/types/src/host/integration/roots/root-registry.d.ts +0 -144
  206. package/lib/types/src/host/integration/roots/roots-wiring.d.ts +0 -219
  207. package/lib/types/src/host/integration/roots/session-root-index.d.ts +0 -52
  208. package/lib/types/src/host/integration/roots-api.d.ts +0 -407
  209. package/lib/types/src/host/integration/roots-wiring.d.ts +0 -211
  210. package/lib/types/src/host/integration/session/session-api.d.ts +0 -88
  211. package/lib/types/src/host/integration/session/session-bin-lock.d.ts +0 -80
  212. package/lib/types/src/host/integration/session/session-header.d.ts +0 -151
  213. package/lib/types/src/host/integration/session/session-labels.d.ts +0 -56
  214. package/lib/types/src/host/integration/session/session-route-wiring.d.ts +0 -50
  215. package/lib/types/src/host/integration/session-admin-service.d.ts +0 -236
  216. package/lib/types/src/host/integration/session-api.d.ts +0 -81
  217. package/lib/types/src/host/integration/session-bin-lock.d.ts +0 -80
  218. package/lib/types/src/host/integration/session-header.d.ts +0 -118
  219. package/lib/types/src/host/integration/session-labels.d.ts +0 -56
  220. package/lib/types/src/host/integration/session-route-wiring.d.ts +0 -50
  221. package/lib/types/src/host/integration/session-scope.d.ts +0 -113
  222. package/lib/types/src/host/integration/session-tools.d.ts +0 -44
  223. package/lib/types/src/host/integration/strict-arguments.d.ts +0 -79
  224. package/lib/types/src/host/integration/takeover/takeover-api.d.ts +0 -62
  225. package/lib/types/src/host/integration/takeover/takeover-route-wiring.d.ts +0 -60
  226. package/lib/types/src/host/integration/takeover/takeover-service.d.ts +0 -167
  227. package/lib/types/src/host/integration/terminal-manifest.d.ts +0 -94
  228. package/lib/types/src/host/integration/tools/management-tools.d.ts +0 -245
  229. package/lib/types/src/host/integration/tools/remote-job-tools.d.ts +0 -316
  230. package/lib/types/src/host/integration/tools/remote-lsp-tools.d.ts +0 -43
  231. package/lib/types/src/host/integration/tools/remote-tools.d.ts +0 -236
  232. package/lib/types/src/host/integration/tools/session-target.d.ts +0 -52
  233. package/lib/types/src/host/integration/tools/session-tools.d.ts +0 -46
  234. package/lib/types/src/host/integration/tools/strict-arguments.d.ts +0 -79
  235. package/lib/types/src/host/integration/tools/terminal-manifest.d.ts +0 -94
  236. package/lib/types/src/host/integration/transfer/remote-copy.d.ts +0 -66
  237. package/lib/types/src/host/integration/transfer/transfer-adapters.d.ts +0 -48
  238. package/lib/types/src/host/integration/transfer/transfer-tracker.d.ts +0 -106
  239. package/lib/types/src/host/integration/transfer-adapters.d.ts +0 -44
  240. package/lib/types/src/host/integration/transfer-service.d.ts +0 -164
  241. package/lib/types/src/host/integration/transfer-tracker.d.ts +0 -106
  242. package/lib/types/src/host/integration/user-roots.d.ts +0 -461
  243. package/lib/types/src/wiring/connections.d.ts +0 -189
  244. package/lib/types/src/wiring/fs.d.ts +0 -13
  245. package/lib/types/src/wiring/install-memo.d.ts +0 -32
  246. package/lib/types/src/wiring/legacy-dirs.d.ts +0 -62
  247. package/lib/types/src/wiring/package-paths.d.ts +0 -35
  248. package/lib/types/src/wiring/roots.d.ts +0 -21
  249. package/lib/types/src/wiring/state-dir.d.ts +0 -29
  250. package/lib/types/src/wiring/tools.d.ts +0 -35
@@ -1,214 +0,0 @@
1
- /**
2
- * 会话管理的**契约**:依赖注入形状、会话头、删除/恢复/清理结果与服务接口。
3
- *
4
- * 从 `session-admin-service.ts` 抽出(审计 0076):上下文模块需要这些类型,留在 service 里会形成环。
5
- *
6
- * @module dsh-remote-workspace/app/session-admin-contract
7
- */
8
- import { type DeleteDecision, type SessionRecord, type SessionTrashEntry, type SessionTrashEntryId } from '../domain/session-admin.ts';
9
- export interface SessionDirEntry {
10
- readonly name: string;
11
- readonly isDirectory: boolean;
12
- readonly bytes: number;
13
- readonly mtimeMs: number;
14
- }
15
- /**
16
- * Everything the service needs from the outside world.
17
- *
18
- * `readHeader` is deliberately the **only** way to learn about a session: the directory name cannot be decoded
19
- * (see ADR-0009), so classification must come from the header.
20
- */
21
- export interface SessionAdminDeps {
22
- /** The platform's sessions root (e.g. `~/.dsh/sessions`). */
23
- readonly sessionsRoot: string;
24
- /** The plugin's own bin root; must **not** be inside {@link sessionsRoot}. */
25
- readonly binRoot: string;
26
- /** List one directory's entries; a missing directory yields an empty list, not a failure. */
27
- readonly listDir: (path: string) => Promise<readonly SessionDirEntry[]>;
28
- /** Read a session header. `undefined` means the log is unreadable (corrupt/unsupported). */
29
- readonly readHeader: (sessionDir: string) => Promise<SessionHeader | undefined>;
30
- /**
31
- * Display title of the workspace that owns a session directory, or `undefined` when none does.
32
- *
33
- * Injected because the mapping lives in the platform's workspace registry, which the domain layer must not
34
- * import (see the repository's red lines). A listing without this resolver still answers: every row keeps
35
- * its `cwd`, so a reader falls back to the directory's own leaf name.
36
- */
37
- readonly resolveWorkspaceTitle?: ((cwd: string | undefined) => string | undefined) | undefined;
38
- /**
39
- * The session's generated title, or `undefined` when it has none.
40
- *
41
- * The header carries no title (it is a projection, not header metadata), so this is the only way a listing
42
- * can label a session by name. Injected for the same reason as {@link resolveWorkspaceTitle}; without it
43
- * every row falls back to its id.
44
- */
45
- readonly resolveSessionTitle?: ((header: SessionHeader) => string | undefined) | undefined;
46
- /** `stat`; `undefined` when the path does not exist. */
47
- readonly stat: (path: string) => Promise<{
48
- readonly isDirectory: boolean;
49
- readonly bytes: number;
50
- } | undefined>;
51
- /** Read a text file. */
52
- readonly readText: (path: string) => Promise<string>;
53
- /** Write a text file (UTF-8, no BOM). */
54
- readonly writeText: (path: string, text: string) => Promise<void>;
55
- /**
56
- * Replace a text file **atomically** (write a temp file, then rename over the target).
57
- *
58
- * Optional, and worth supplying: without it a process killed mid-write leaves a truncated JSON index,
59
- * which the parser then rejects as a hard failure. Atomic replace makes the index either the old or the
60
- * new document, never a fragment.
61
- */
62
- readonly writeTextAtomic?: (path: string, text: string) => Promise<void>;
63
- /**
64
- * Run `operation` while holding a **cross-process** lock for `key`.
65
- *
66
- * The in-process chain cannot see another DSH process; without this, two processes deleting at the same
67
- * time can each read the old index and overwrite the other's entry — leaving bytes in the bin that no
68
- * index mentions (invisible and unrestorable).
69
- *
70
- * A caller-supplied implementation must be **exclusive** and must not deadlock when the previous holder
71
- * died (see `createSessionBinLock`, which reclaims a stale lock by age).
72
- */
73
- readonly withLock?: <T>(key: string, operation: () => Promise<T>) => Promise<T>;
74
- /**
75
- * Move a directory. Must be atomic on one filesystem; the caller supplies the cross-device fallback.
76
- *
77
- * Returning `'copy'` means the implementation copied (cross-device) and the source is already gone.
78
- */
79
- readonly moveDir: (from: string, to: string) => Promise<'rename' | 'copy'>;
80
- /** Recursively remove a directory (used for purge and for rolling back a failed record). */
81
- readonly removeDir: (path: string) => Promise<void>;
82
- /** Copy a directory recursively (the cross-device fallback, when the deps implement it themselves). */
83
- readonly copyDir?: (from: string, to: string) => Promise<void>;
84
- /** Whether a session is currently held by a live agent; never deleted. */
85
- readonly isLive: (sessionId: string) => boolean;
86
- /** Remove a session from workspace bookkeeping (`detachSession`); optional where unavailable. */
87
- readonly detachSession?: (sessionId: string) => Promise<void>;
88
- /** Announce the removal so clients drop the row (`api-session/removed`). */
89
- readonly emitRemoved?: (sessionId: string) => void;
90
- /** Injected clock. */
91
- readonly now: () => number;
92
- /** Who confirmed, for the audit trail (FR-3.10); absent when the caller did not say. */
93
- readonly confirmedBy?: string;
94
- }
95
- /** The parts of a session header this feature needs. */
96
- export interface SessionHeader {
97
- readonly id: string;
98
- /** `cwd` from the header; `undefined` for the platform's no-cwd bucket. */
99
- readonly cwd: string | undefined;
100
- readonly title: string | undefined;
101
- readonly parentSessionId: string | undefined;
102
- /**
103
- * Session format generation, as stored in the log's first line.
104
- *
105
- * Together with {@link createdAt} and {@link isSeeded} this is the **lifecycle identity** a header alone
106
- * witnesses, and it is what the platform's projection cache validates a stored title row against. A
107
- * resolver that skipped it could serve a title from a different lifecycle that reused the same id.
108
- */
109
- readonly version?: number | undefined;
110
- readonly createdAt?: number | undefined;
111
- readonly isSeeded?: boolean | undefined;
112
- }
113
- /** Options shared by the destructive calls. */
114
- export interface SessionAdminOptions {
115
- readonly signal?: AbortSignal;
116
- }
117
- /** Result of a session deletion. */
118
- export interface DeleteSessionResult {
119
- readonly mode: 'recycle' | 'permanent';
120
- /** The bin entry in `recycle` mode; `undefined` for `permanent`. */
121
- readonly entry: SessionTrashEntry | undefined;
122
- /** Whether the content can still be recovered. **Always `false` for `permanent`.** */
123
- readonly recoverable: boolean;
124
- /** True when the move was observed to have landed (store gone + bin present). */
125
- readonly verified: boolean;
126
- /** True when the bytes crossed a filesystem boundary and were copied. */
127
- readonly copied: boolean;
128
- /** Ids that were refused, with the reason (a partial deletion is reported, never hidden). */
129
- readonly refusals: DeleteDecision['refusals'];
130
- readonly bytes: number;
131
- }
132
- /** Result of a restore. */
133
- export interface RestoreSessionResult {
134
- readonly entry: SessionTrashEntry;
135
- /** Absolute path the session directory was moved back to. */
136
- readonly restoredPath: string;
137
- readonly movedBy: 'rename' | 'copy';
138
- }
139
- /** One purge outcome. */
140
- export interface PurgeSessionResult {
141
- readonly id: SessionTrashEntryId;
142
- readonly sessionId: string;
143
- readonly purged: boolean;
144
- /** True when the entry was removed physically but the index could not be updated afterwards. */
145
- readonly indexStale: boolean;
146
- }
147
- /** A retention sweep outcome for the session bin. */
148
- export interface SweepSessionResult {
149
- readonly purged: readonly PurgeSessionResult[];
150
- readonly failed: readonly {
151
- readonly id: SessionTrashEntryId;
152
- readonly reason: string;
153
- }[];
154
- readonly remainingEntries: number;
155
- readonly remainingBytes: number;
156
- }
157
- /** The session-bin retention policy (same three dimensions as the file-level bin). */
158
- export interface SessionBinPolicy {
159
- readonly maxEntries: number;
160
- readonly maxBytes: number;
161
- readonly maxAgeMs: number;
162
- }
163
- export declare function joinPath(base: string, ...segments: readonly string[]): string;
164
- /** The service surface. */
165
- export interface SessionAdminService {
166
- /** Inventory every session in the store (FR-3.3). */
167
- inventory(options?: SessionAdminOptions): Promise<readonly SessionRecord[]>;
168
- /** Preview a deletion without touching anything (FR-3.7). */
169
- previewDelete(ids: readonly string[], options?: SessionAdminOptions & {
170
- readonly keep?: readonly string[];
171
- }): Promise<DeleteDecision>;
172
- /** Delete sessions: into the bin (`recycle`) or irreversibly (`permanent`). */
173
- deleteSession(ids: readonly string[], options?: SessionAdminOptions & {
174
- readonly mode?: 'recycle' | 'permanent';
175
- readonly keep?: readonly string[];
176
- }): Promise<DeleteSessionResult>;
177
- /**
178
- * Delete every session that belongs to one workspace directory, and nothing else.
179
- *
180
- * The workspace itself is **left registered**: the user asked to clear the workspace's sessions, not to
181
- * unregister the workspace (and the platform's `workspaceRegistry.delete` would also be a different,
182
- * separately-confirmed action). Sessions are matched by their header's `cwd` against the given directory,
183
- * folded the same way the label resolver folds paths, so a Windows case/separator difference still matches.
184
- *
185
- * Live sessions are refused by the same rules as {@link deleteSession} (they appear in `refusals`), so a
186
- * workspace containing a running session is deleted **except** for that session rather than failing whole.
187
- *
188
- * @param cwd - the workspace directory whose sessions should go.
189
- * @param options - deletion mode plus cancellation.
190
- * @returns the ids deleted, the per-id refusals, and the bytes freed.
191
- */
192
- deleteWorkspaceSessions(cwd: string, options?: SessionAdminOptions & {
193
- readonly mode?: 'recycle' | 'permanent';
194
- }): Promise<DeleteSessionResult & {
195
- readonly matched: number;
196
- }>;
197
- /** List the bin. */
198
- list(options?: SessionAdminOptions): Promise<readonly SessionTrashEntry[]>;
199
- /** Move one entry back to where it came from. */
200
- restore(entryId: string, options?: SessionAdminOptions): Promise<RestoreSessionResult>;
201
- /** Delete one entry physically (the irreversible step, after the retention period). */
202
- purge(entryId: string, options?: SessionAdminOptions): Promise<PurgeSessionResult>;
203
- /** Apply the retention policy. */
204
- sweep(policy: SessionBinPolicy, options?: SessionAdminOptions): Promise<SweepSessionResult>;
205
- }
206
- /**
207
- * Build the session-administration service.
208
- *
209
- * @param deps - injected I/O.
210
- * @returns the service.
211
- * @throws SshDevError `ROOT_INVALID` when the bin root is inside the sessions root (that placement breaks the
212
- * platform's session listing — see the module note and ADR-0009).
213
- */
214
- //# sourceMappingURL=session-admin-contract.d.ts.map
@@ -1,34 +0,0 @@
1
- /**
2
- * 会话管理的**删除族**:预览、物理删除、移入回收站、批量清理、按工作区删除。
3
- *
4
- * 从 `session-admin-service.ts` 的工厂里抽出(审计 0076):只依赖上下文,不依赖列表/恢复/清扫。
5
- *
6
- * @module dsh-remote-workspace/app/session-admin-delete
7
- */
8
- import { type SessionTrashEntry, type SessionTrashEntryId } from '../domain/session-admin.ts';
9
- import { type SessionAdminContext } from './session-admin-context.ts';
10
- import type { PurgeSessionResult, DeleteSessionResult } from './session-admin-contract.ts';
11
- import type { DeleteDecision } from '../domain/session-admin.ts';
12
- export declare function createSessionAdminDelete(ctx: SessionAdminContext): {
13
- previewDelete: (ids: readonly string[], options?: import("./session-admin-contract.ts").SessionAdminOptions & {
14
- readonly keep?: readonly string[];
15
- }) => Promise<DeleteDecision>;
16
- deleteSession: (ids: readonly string[], options?: import("./session-admin-contract.ts").SessionAdminOptions & {
17
- readonly mode?: "recycle" | "permanent";
18
- readonly keep?: readonly string[];
19
- }) => Promise<DeleteSessionResult>;
20
- deleteWorkspaceSessions: (cwd: string, options?: import("./session-admin-contract.ts").SessionAdminOptions & {
21
- readonly mode?: "recycle" | "permanent";
22
- }) => Promise<DeleteSessionResult & {
23
- readonly matched: number;
24
- }>;
25
- purgeEntry: (entryId: string) => Promise<PurgeSessionResult>;
26
- purgeEntries: (doomed: readonly SessionTrashEntry[], known: readonly SessionTrashEntry[]) => Promise<{
27
- readonly purged: readonly PurgeSessionResult[];
28
- readonly failed: readonly {
29
- readonly id: SessionTrashEntryId;
30
- readonly reason: string;
31
- }[];
32
- }>;
33
- };
34
- //# sourceMappingURL=session-admin-delete.d.ts.map
@@ -1,38 +0,0 @@
1
- /**
2
- * Session administration service: inventory, deletion into the session bin, restore, purge, retention.
3
- *
4
- * The domain decisions live in [`domain/session-admin.ts`](../domain/session-admin.ts); this module wires them to
5
- * injected I/O. Every filesystem and platform call arrives as a function (AGENTS.md 红线 3), so this module is
6
- * testable offline and a test can make a move fail.
7
- *
8
- * ## Three contracts matter more than the rest
9
- *
10
- * 1. **Move first, confirm, then record.** `deleteSession` reports success only after the session directory is
11
- * observed inside the bin **and** gone from the store. A move that throws is confirmed before anything is
12
- * claimed: if it actually landed (a lost response), that counts as success; otherwise the call fails and
13
- * **nothing** is recorded. "Deleted but not in the bin" must never be reported as success.
14
- * 2. **The index write is never swallowed.** If the index cannot be written after a successful move, the move is
15
- * rolled back and the failure is reported. A physical purge has no rollback, so that case is reported with
16
- * `purged: true, indexStale: true` instead of being hidden.
17
- * 3. **Live sessions are never touched.** The decision layer refuses them; this layer re-checks before moving, so
18
- * a session that went live between preview and confirm is refused rather than killed.
19
- *
20
- * ## Where the bin lives (and why not under `sessions/`)
21
- *
22
- * The platform enumerates **every** directory under the sessions root (`listProjectDirs` has no dot-directory
23
- * filter) and fails the whole listing when one session id appears twice. A bin inside `sessions/` that kept the
24
- * original log filename would therefore make deleted sessions reappear *and* break the session list. The bin
25
- * lives in the plugin's own storage instead — see ADR-0009.
26
- *
27
- * @module dsh-remote-workspace/integration/session-admin-service
28
- */
29
- import type { SessionAdminDeps, SessionAdminService } from './session-admin-contract.ts';
30
- export * from './session-admin-contract.ts';
31
- /**
32
- * Build the service.
33
- *
34
- * @param deps - injected platform services.
35
- * @returns the {@link SessionAdminService}.
36
- */
37
- export declare function createSessionAdminService(deps: SessionAdminDeps): SessionAdminService;
38
- //# sourceMappingURL=session-admin-service.d.ts.map
@@ -1,227 +0,0 @@
1
- /**
2
- * 阶段 2「一键接管」的**纯模型**:四行的开关 → 组合状态 / 操作序列 / 运行态核对 / 手动改法。
3
- *
4
- * 本模块没有 I/O、不 import 任何 `@deepseek-ai/*`(AGENTS.md 红线 2),输入只是一张
5
- * `patchId → {enabled, readOnlyReason, fiberPhase}` 表,输出是纯数据。执行器在
6
- * `src/host/integration/takeover/takeover-service.ts`。
7
- *
8
- * ## 身份:`patchId` 才是本插件认识的那一行
9
- *
10
- * 宿主把两套 id 混在同一个行对象里,**不能互相顶替**(`plugin-manager/src/index.ts:256-272`):
11
- *
12
- * | 字段 | 含义 | 真机上的例子 |
13
- * |---|---|---|
14
- * | `entryId` | **Loader 条目身份**。挂在 `include` 下的条目带前缀 | `include:fs-sandbox` |
15
- * | `patchId` | profile patch 里的**行 id**,即 `actual.options.id`(`index.ts:261,270`) | `fs-sandbox` |
16
- * | `moduleName` | 该条目 import 的模块说明符(`entry.options.name`) | `@deepseek-ai/dsh-fs-sandbox` |
17
- *
18
- * 用户在自己的 `cordis.patch.yml` 里看到、也需要改的是 **patchId**;`setPluginEnabled` 收的却是
19
- * **entryId**(宿主自己再去查 `patchId`)。所以:
20
- *
21
- * - 本模块的常量、步骤、UI 一律用 **patchId**(`TAKEOVER_PATCH_IDS`);
22
- * - 真实 `entryId` 只作为诊断信息随行保存(`TakeoverRow.entryId`),**从不**用来判断身份 ——
23
- * 拿它跟 `fs-sandbox` 这种常量比,在真机上永远匹配不上(真值是 `include:fs-sandbox`)。
24
- *
25
- * ## 为什么顺序要单独建模
26
- *
27
- * `ctx.fs` / `ctx.fileReferences` 都是单例服务,两个提供方同时在场时后来者注册会抛
28
- * `service "fs" has been registered at …`(`doc/02-platform/fs-seam.md` §1);而本插件的 `./fs`
29
- * 条目在核心行仍占用时会 warn 后 `return undefined`(`src/fs.ts:55-62`),并且**不会自己重试**。
30
- * 所以 apply 的顺序是正确性的一部分:
31
- *
32
- * 1. 先 enable 我们的两条 —— 核心仍占用时会被跳过(无害);
33
- * 2. 再 disable 两条核心 —— 让出两个服务;
34
- * 3. 最后把我们的两条各做一次 disable + enable —— 强制在核心让位后重新 apply。
35
- *
36
- * revert 反向:先 disable 我们的两条,再 enable 两条核心。
37
- *
38
- * ## 三件它不假装的事
39
- *
40
- * 1. **`enabled` 是配置值,不是运行态。** 宿主 `PluginInfo.enabled` = `!entry.disabled`
41
- * (`packages/host/plugin-inventory/src/index.ts:89-95`),只有 `fiberPhase` 才说明「提供方真的在跑」。
42
- * 两者不一致时 {@link liveMismatch} 会说出来,而不是让面板显示一个漂亮的谎。
43
- * 2. **只读行只挡它真正要碰的行**:`readOnlyReason` 非空的行不能通过 profile patch 改,必须在动第一行
44
- * 之前拒绝;但**已经满足的请求**(空序列)不算「要碰」。
45
- * 3. **幂等**:已处于目标态时步骤序列为空,执行器因此不会为了「确认一下」去写 profile patch。
46
- *
47
- * @module dsh-remote-workspace/app/takeover-plan
48
- */
49
- /** 我们自己的两行(`cordis.patch.yml` 里的 `remote-workspace-fs` 与 `remote-workspace-file-references`)。 */
50
- export declare const OUR_PATCH_IDS: readonly ["remote-workspace-fs", "remote-workspace-file-references"];
51
- /** 核心的两行(bundle patch 里的 `fs-sandbox` 与 `file-reference-local`)。 */
52
- export declare const CORE_PATCH_IDS: readonly ["fs-sandbox", "file-reference-local"];
53
- /** 接管涉及的全部四行,顺序固定:先我们的、后核心的(与 apply 的叙述顺序一致)。 */
54
- export declare const TAKEOVER_PATCH_IDS: readonly ["remote-workspace-fs", "remote-workspace-file-references", "fs-sandbox", "file-reference-local"];
55
- /** 一行属于哪一边。 */
56
- export type TakeoverSide = 'ours' | 'core';
57
- /** 宿主 `PluginInfo.fiberPhase` 的取值(`plugin-inventory/src/types.ts:8-14`);`null` = 没有活着的根 fiber。 */
58
- export type TakeoverFiberPhase = 'pending' | 'loading' | 'active' | 'failed' | 'unloading' | null;
59
- /** 四行之一在宿主 `listPlugins()` 里的最小投影。 */
60
- export interface TakeoverRow {
61
- /** **规范身份**:profile patch 里的行 id。内部判断与 UI 都用它。 */
62
- readonly patchId: string;
63
- /** Loader 条目的真实 id(如 `include:fs-sandbox`)。只作诊断,**不参与身份判断**。 */
64
- readonly entryId?: string | undefined;
65
- /** 该条目 import 的模块说明符,身份交叉校验用。 */
66
- readonly moduleName?: string | undefined;
67
- /** 该行当前是否启用:`PluginInfo.enabled`,即**配置/组合**的开关,不是「fiber 正在跑」。 */
68
- readonly enabled: boolean;
69
- /**
70
- * 非空表示这一行**不能**通过 profile patch 修改(`'management-required'` | `'unaddressable'`)。
71
- * 原样透传,不做枚举校验:宿主将来多一种原因时,这里要如实报告而不是把它当「没有原因」。
72
- */
73
- readonly readOnlyReason?: string | undefined;
74
- /** 该行根 fiber 的运行状态;`undefined` = 宿主没给这个字段(无法判断)。 */
75
- readonly fiberPhase?: TakeoverFiberPhase | undefined;
76
- }
77
- /** 四行组合起来的接管状态。 */
78
- export type TakeoverState =
79
- /** 核心两行在、我们的两行不在:阶段 1(本插件没有接管)。 */
80
- 'off'
81
- /** 我们的两行在、核心两行不在:阶段 2(本插件已接管)。 */
82
- | 'on'
83
- /** 其它组合(含两方同时在场、只有一行切换)。 */
84
- | 'mixed'
85
- /** 这台宿主上无法表达接管:没有 `pluginManager`,或插件清单里缺行。 */
86
- | 'unsupported';
87
- /** 一键接管的两个方向。 */
88
- export type TakeoverAction = 'apply' | 'revert';
89
- /** 一步为什么存在。 */
90
- export type TakeoverStepWhy =
91
- /** apply 的第 1 段:预置我们自己的行。核心仍占用时这一步会被跳过,**按设计无害**。 */
92
- 'enable-ours'
93
- /** apply 的第 2 段:让核心的两行让位。 */
94
- | 'disable-core'
95
- /** apply 的第 3 段:把我们自己的行各做一次 disable + enable,强制重新 apply。 */
96
- | 'reapply-ours'
97
- /** revert 的第 1 段:先撤掉我们自己的两行。 */
98
- | 'disable-ours'
99
- /** revert 的第 2 段:再把核心的两行恢复回来。 */
100
- | 'enable-core';
101
- /** 一条**原始**操作:对某一行调用一次 `setPluginEnabled`。 */
102
- export interface TakeoverStep {
103
- /** 规范身份(patchId)。真正写盘时宿主还要用它自己的 `entryId` 换算,那是执行器的事。 */
104
- readonly patchId: string;
105
- /** 目标值:`true` = 启用,`false` = 禁用。 */
106
- readonly enabled: boolean;
107
- readonly why: TakeoverStepWhy;
108
- }
109
- /** 整次操作被拒绝的原因(在**动第一行之前**就判定,不留半成品)。 */
110
- export type TakeoverRefusal =
111
- /** 计划要碰的行里有 `readOnlyReason` 非空的。 */
112
- 'read-only'
113
- /** 插件清单里找不到四行中的某一行(或身份有歧义,按缺行处理)。 */
114
- | 'rows-missing';
115
- /** 规划结果:要么一串步骤,要么一个拒绝(附原因与涉及的行)。 */
116
- export type TakeoverPlan = {
117
- readonly ok: true;
118
- readonly action: TakeoverAction;
119
- readonly steps: readonly TakeoverStep[];
120
- } | {
121
- readonly ok: false;
122
- readonly refusal: TakeoverRefusal;
123
- /** 造成拒绝的行(patchId)。 */
124
- readonly patchIds: readonly string[];
125
- /** 面向用户的说明,直接可进 HTTP 的 `error` 字段。 */
126
- readonly message: string;
127
- };
128
- /**
129
- * 一行属于哪一边。
130
- *
131
- * @param patchId - profile patch 行 id。
132
- * @returns `'ours'` / `'core'`,不认识的行返回 `undefined`。
133
- */
134
- export declare function sideOf(patchId: string): TakeoverSide | undefined;
135
- /**
136
- * 插件清单里缺了哪几行(按 {@link TAKEOVER_PATCH_IDS} 的顺序)。
137
- *
138
- * 「缺」也包括**身份有歧义**(两行都声称是 `fs-sandbox`):识别层会把歧义行丢掉,
139
- * 于是这里如实报缺 —— 宁可说「没有这一行」,也不猜哪一行是真的。
140
- *
141
- * @param rows - 已投影的四行(可能不全)。
142
- * @returns 缺失的 `patchId` 列表;齐全时为空数组。
143
- */
144
- export declare function missingPatchIds(rows: readonly TakeoverRow[]): readonly string[];
145
- /**
146
- * 四行的当前组合属于哪种接管状态。
147
- *
148
- * @param rows - 已投影的四行(可能不全)。
149
- * @returns {@link TakeoverState};行不齐时是 `'unsupported'`(无法表达,而不是猜一个)。
150
- */
151
- export declare function takeoverState(rows: readonly TakeoverRow[]): TakeoverState;
152
- /**
153
- * 规划一次 apply / revert。
154
- *
155
- * 步骤只包含**真正会改变状态**的操作(幂等),并且严格按模块头注释的顺序排列:
156
- *
157
- * - apply:`enable-ours*` → `disable-core*` → (`reapply-ours` 的 disable+enable)*
158
- * —— 最后一段只在前面确实有动作时追加;已经 `on` 时整串为空。
159
- * - revert:`disable-ours*` → `enable-core*`;已经 `off` 时整串为空。
160
- *
161
- * @param rows - 四行的当前状态(`listPlugins()` 的投影)。
162
- * @param action - `'apply'` 或 `'revert'`。
163
- * @returns 步骤序列,或一个拒绝。
164
- */
165
- export declare function planTakeover(rows: readonly TakeoverRow[], action: TakeoverAction): TakeoverPlan;
166
- /**
167
- * 每一行在这次操作里的目标值。
168
- *
169
- * @param action - `'apply'`(接管)或 `'revert'`(交还)。
170
- * @returns `patchId → enabled` 的目标表。
171
- */
172
- export declare function targetEnabled(action: TakeoverAction): ReadonlyMap<string, boolean>;
173
- /**
174
- * 计划要碰的行里,哪些是只读的。
175
- *
176
- * 只读行不能被 profile patch 改,所以必须在**动第一行之前**拒绝;但只针对真的要改的行 —— 已经满足的
177
- * 请求(空序列)不该因为某行只读而失败。
178
- *
179
- * @param present - 按 `patchId` 索引的四行。
180
- * @param steps - 已排好的步骤。
181
- * @returns 只读且被计划碰到的 `patchId`(按步骤首次出现顺序,去重)。
182
- */
183
- export declare function readOnlyTouched(present: ReadonlyMap<string, TakeoverRow>, steps: readonly TakeoverStep[]): readonly string[];
184
- /**
185
- * 面向用户的拒绝说明(HTTP `error` 字段直接用这一段)。
186
- *
187
- * @param refusal - 拒绝原因。
188
- * @param patchIds - 涉及的行。
189
- * @returns 一句话,说明「为什么不行、下一步怎么办」。
190
- */
191
- export declare function refusalMessage(refusal: TakeoverRefusal, patchIds: readonly string[]): string;
192
- /** 一处「配置说这样、运行态不是这样」。 */
193
- export interface TakeoverLiveMismatch {
194
- readonly patchId: string;
195
- /** 组合状态要求它是什么:提供方该在跑,还是该没有 fiber。 */
196
- readonly expected: 'active' | 'off';
197
- /** 实际看到的 fiber 状态;`undefined` = 宿主没给这个字段(判断不了)。 */
198
- readonly actual: TakeoverFiberPhase | undefined;
199
- }
200
- /**
201
- * 配置状态与运行态不一致的行。
202
- *
203
- * `enabled` 是**配置**(`PluginInfo.enabled` = `!entry.disabled`),`fiberPhase` 才是**运行**。两者不一致
204
- * 的典型场景:改完 profile patch 但没重启(或宿主没有 hmr)—— 面板若只看 `enabled`,会显示「已接管」
205
- * 而实际提供方根本没在跑。
206
- *
207
- * 只对 `on` / `off` 两个自洽形态回答;`mixed` / `unsupported` 没有「应有的运行态」可言,返回空。
208
- *
209
- * @param rows - 四行(含 `fiberPhase`)。
210
- * @returns 不一致的行;全部一致或状态不自洽时为空数组。
211
- */
212
- export declare function liveMismatch(rows: readonly TakeoverRow[]): readonly TakeoverLiveMismatch[];
213
- /**
214
- * 用户自己改 profile patch 时要写的行(YAML 片段,直接可粘贴)。
215
- *
216
- * 为什么需要它:宿主的写入口只接受「一行一个布尔值」,也没有批量/事务接口;本插件不替用户改文件
217
- * (见 `takeover-service.ts` 模块头)。所以这张表就是拒绝时交还给用户的东西 —— 行 id 用的是
218
- * **patchId**,正是他 `cordis.patch.yml` 里写的那一个。
219
- *
220
- * 只列出**需要改**的行:已经是目标值的行不出现(避免用户把无意义的覆盖写进自己的 patch)。
221
- *
222
- * @param rows - 四行的当前状态。
223
- * @param action - `'apply'` 或 `'revert'`。
224
- * @returns YAML 行;已经处于目标态时为空数组。
225
- */
226
- export declare function manualPatchRows(rows: readonly TakeoverRow[], action: TakeoverAction): readonly string[];
227
- //# sourceMappingURL=takeover-plan.d.ts.map
@@ -1,55 +0,0 @@
1
- /**
2
- * `pluginManager.listPlugins()` 的答案 → 本插件认识的四行。
3
- *
4
- * 这一层唯一的职责是**认身份**,而身份在真机上是个坑:宿主行同时带 `entryId`(Loader 条目 id,
5
- * 挂在 `include` 下的条目带前缀,例如 `include:fs-sandbox`)与 `patchId`(profile patch 的行 id,
6
- * 例如 `fs-sandbox`)。用户 `cordis.patch.yml` 里写的是后者,`setPluginEnabled` 收的却是前者。
7
- * 拿 `entryId` 去跟常量比,在真机上**永远匹配不上** —— 那正是这一层要挡住的事。
8
- *
9
- * 识别规则(按顺序,全部 fail closed):
10
- *
11
- * 1. **有 `patchId`**:必须是我们认识的四个之一,且 `moduleName` 与预期一致(防止别的插件复用了同一个
12
- * 行 id);两行声称同一个 `patchId` → 有歧义,两行都不要。
13
- * 2. **没有 `patchId`**(宿主只在不可改的行上省略它):只能靠 `moduleName` 认 —— 该模块名必须**恰好**
14
- * 出现在一行上,出现两行或零行都不认。
15
- * 3. 认不出来就是「缺行」,由上层报 `rows-missing` / `unsupported`,而不是猜一个。
16
- *
17
- * 纯逻辑、无 I/O(AGENTS.md 红线 2),因此可以离线逐字段断言。
18
- *
19
- * @module dsh-remote-workspace/app/takeover-rows
20
- */
21
- import { type TakeoverRow } from './takeover-plan.ts';
22
- /**
23
- * 每个 patch 行应该 import 的模块说明符。
24
- *
25
- * 出处:核心两行在 bundle patch 里声明(`packages/bundle/base/cordis.patch.yml:518-519` 的
26
- * `fs-sandbox`、`packages/bundle/web-app/cordis.patch.yml:97-98` 的 `file-reference-local`),
27
- * 我们两行在本仓库的 `cordis.patch.yml:34-37`。
28
- */
29
- export declare const EXPECTED_MODULE_NAMES: Readonly<Record<string, string>>;
30
- /** 一行离开宿主后允许携带的字段(wire 形态,与 `GET` 的 `rows` 元素一一对应)。 */
31
- export interface PublicTakeoverRow {
32
- /** 规范身份:profile patch 的行 id,UI 显示这个。 */
33
- readonly patchId: string;
34
- /** Loader 条目的真实 id(`include:fs-sandbox`),只作诊断。 */
35
- readonly loaderEntryId?: string;
36
- readonly enabled: boolean;
37
- readonly readOnlyReason?: string;
38
- }
39
- /**
40
- * 把宿主插件清单投影成四行。
41
- *
42
- * @param listed - `pluginManager.listPlugins()` 的返回值(形状未知,逐字段校验)。
43
- * @returns 认出来的那几行,按 {@link TAKEOVER_PATCH_IDS} 的顺序;认不出的、歧义的都丢掉。
44
- */
45
- export declare function readTakeoverRows(listed: unknown): readonly TakeoverRow[];
46
- /**
47
- * 一行的 wire 投影:规范 id + 可选诊断 id,`readOnlyReason` 缺省时不出现。
48
- *
49
- * `fiberPhase` 刻意不出去:客户端按 `enabled` 画开关,运行态差异由 `GET` 的 `reason` 说清楚。
50
- *
51
- * @param row - 内部行。
52
- * @returns `{ patchId, loaderEntryId?, enabled, readOnlyReason? }`。
53
- */
54
- export declare function publicTakeoverRow(row: TakeoverRow): PublicTakeoverRow;
55
- //# sourceMappingURL=takeover-rows.d.ts.map