@jmfederico/pi-web 1.202608.0 → 1.202608.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +4 -4
  2. package/dist/cli.js +69 -7
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/assets/{CodeViewer-D91Sp61M.js → CodeViewer-mEiBZFA5.js} +2 -2
  5. package/dist/client/assets/{TerminalPanel-fYrKc3jh.js → TerminalPanel-O9381Eme.js} +6 -6
  6. package/dist/client/assets/index-uI2AGFUy.js +4091 -0
  7. package/dist/client/index.html +1 -1
  8. package/dist/config.js +109 -73
  9. package/dist/config.js.map +1 -1
  10. package/dist/docker/piWebDockerCommandPlan.js +4 -3
  11. package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
  12. package/dist/nativeServices/servicePlan.js +1 -1
  13. package/dist/nativeServices/servicePlan.js.map +1 -1
  14. package/dist/pi-web-plugins/git/browser/git-contract.js +108 -0
  15. package/dist/pi-web-plugins/git/browser/git-panel.js +609 -0
  16. package/dist/pi-web-plugins/git/browser/gitFileList.js +43 -0
  17. package/dist/pi-web-plugins/git/browser/gitFileShared.js +16 -0
  18. package/dist/pi-web-plugins/git/browser/gitFileTree.js +81 -0
  19. package/dist/pi-web-plugins/git/browser/gitFileViewPreference.js +35 -0
  20. package/dist/pi-web-plugins/git/browser/gitRoute.js +42 -0
  21. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +10 -0
  22. package/dist/pi-web-plugins/git/browser/unifiedDiff.js +301 -0
  23. package/dist/{server/git/gitService.js → pi-web-plugins/git/git-backend.js} +209 -60
  24. package/dist/pi-web-plugins/git/package.json +16 -0
  25. package/dist/pi-web-plugins/git/server-plugin.js +176 -0
  26. package/dist/pi-web-plugins/info/infoInternals.js +1 -2
  27. package/dist/pi-web-plugins/info/package.json +1 -1
  28. package/dist/pi-web-plugins/info/pi-web-plugin.js +2 -2
  29. package/dist/pi-web-plugins/relays/package.json +1 -1
  30. package/dist/pi-web-plugins/relays/pi-web-plugin.js +3 -3
  31. package/dist/pi-web-plugins/updates/package.json +1 -1
  32. package/dist/pi-web-plugins/updates/pi-web-plugin.js +1 -1
  33. package/dist/pi-web-plugins/workspace-tasks/package.json +1 -1
  34. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +3 -3
  35. package/dist/plugin-api.d.ts +33 -16
  36. package/dist/pluginRecoveryCli.js +172 -0
  37. package/dist/pluginRecoveryCli.js.map +1 -0
  38. package/dist/server/activity/workspaceActivityService.js +27 -19
  39. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  40. package/dist/server/app.js +35 -15
  41. package/dist/server/app.js.map +1 -1
  42. package/dist/server/configRoutes.js +3 -21
  43. package/dist/server/configRoutes.js.map +1 -1
  44. package/dist/server/machines/machineClient.js +23 -4
  45. package/dist/server/machines/machineClient.js.map +1 -1
  46. package/dist/server/machines/machinePluginProxyRoutes.js +74 -17
  47. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  48. package/dist/server/machines/machineProxyRoutes.js +165 -8
  49. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  50. package/dist/server/machines/machineService.js +22 -0
  51. package/dist/server/machines/machineService.js.map +1 -1
  52. package/dist/server/piWebPluginCatalog.js +584 -0
  53. package/dist/server/piWebPluginCatalog.js.map +1 -0
  54. package/dist/server/piWebPluginLifecycle.js +162 -0
  55. package/dist/server/piWebPluginLifecycle.js.map +1 -0
  56. package/dist/server/piWebPluginService.js +159 -261
  57. package/dist/server/piWebPluginService.js.map +1 -1
  58. package/dist/server/piWebStatus.js +28 -7
  59. package/dist/server/piWebStatus.js.map +1 -1
  60. package/dist/server/plugins/pluginBackendProxyRoutes.js +69 -0
  61. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -0
  62. package/dist/server/plugins/serverPluginExec.js +184 -0
  63. package/dist/server/plugins/serverPluginExec.js.map +1 -0
  64. package/dist/server/plugins/serverPluginRuntime.js +480 -0
  65. package/dist/server/plugins/serverPluginRuntime.js.map +1 -0
  66. package/dist/server/realtime/sessionEventHub.js +26 -11
  67. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  68. package/dist/server/requestCancellation.js +32 -0
  69. package/dist/server/requestCancellation.js.map +1 -0
  70. package/dist/server/sessiond/agentProcessEnvironment.js +29 -30
  71. package/dist/server/sessiond/agentProcessEnvironment.js.map +1 -1
  72. package/dist/server/sessiond/pluginBackendRoutes.js +64 -0
  73. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -0
  74. package/dist/server/sessiond/sessionDaemonShutdown.js +24 -0
  75. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
  76. package/dist/server/sessiond/sessionProxyRoutes.js +2 -2
  77. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  78. package/dist/server/sessiond/sessionServiceDependencies.js +2 -1
  79. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  80. package/dist/server/sessiond/sessiondStateOwnership.js +235 -0
  81. package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -0
  82. package/dist/server/sessiond/workspaceCatalogRoutes.js +31 -0
  83. package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -0
  84. package/dist/server/sessiond/workspaceRemovalRoutes.js +41 -0
  85. package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -0
  86. package/dist/server/sessiond.js +265 -99
  87. package/dist/server/sessiond.js.map +1 -1
  88. package/dist/server/sessions/authService.js +15 -54
  89. package/dist/server/sessions/authService.js.map +1 -1
  90. package/dist/server/sessions/dockerEnvironmentFacts.js +254 -0
  91. package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -0
  92. package/dist/server/sessions/modelCatalogRefresher.js +4 -3
  93. package/dist/server/sessions/modelCatalogRefresher.js.map +1 -1
  94. package/dist/server/sessions/piSessionManagerGateway.js +18 -67
  95. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  96. package/dist/server/sessions/piSessionService.js +141 -134
  97. package/dist/server/sessions/piSessionService.js.map +1 -1
  98. package/dist/server/sessions/sessionCommandService.js +24 -1
  99. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  100. package/dist/server/sessions/sessionEnvironmentFacts.js +48 -0
  101. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -0
  102. package/dist/server/sessions/sessionFileFormat.js +27 -0
  103. package/dist/server/sessions/sessionFileFormat.js.map +1 -0
  104. package/dist/server/sessions/sessionFileHeader.js +1 -14
  105. package/dist/server/sessions/sessionFileHeader.js.map +1 -1
  106. package/dist/server/sessions/sessionRoutes.js +14 -0
  107. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  108. package/dist/server/sessions/sessionSummaryScanner.js +96 -224
  109. package/dist/server/sessions/sessionSummaryScanner.js.map +1 -1
  110. package/dist/server/sessions/spawnSubsessionTool.js +5 -9
  111. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  112. package/dist/server/sessions/spawnTargetResolver.js +1 -1
  113. package/dist/server/status/machineStatusRoutes.js +8 -0
  114. package/dist/server/status/machineStatusRoutes.js.map +1 -0
  115. package/dist/server/status/machineStatusService.js +181 -0
  116. package/dist/server/status/machineStatusService.js.map +1 -0
  117. package/dist/server/status/workspaceAttribution.js +87 -0
  118. package/dist/server/status/workspaceAttribution.js.map +1 -0
  119. package/dist/server/terminalProxyRoutes.js +2 -1
  120. package/dist/server/terminalProxyRoutes.js.map +1 -1
  121. package/dist/server/workspaceExplorerRoutes.js +20 -13
  122. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  123. package/dist/server/workspaces/fileContentService.js +18 -9
  124. package/dist/server/workspaces/fileContentService.js.map +1 -1
  125. package/dist/server/workspaces/filePreviewResponseHeaders.js +18 -0
  126. package/dist/server/workspaces/filePreviewResponseHeaders.js.map +1 -0
  127. package/dist/server/workspaces/filePreviewResponsePolicy.js +55 -0
  128. package/dist/server/workspaces/filePreviewResponsePolicy.js.map +1 -0
  129. package/dist/server/workspaces/filePreviewService.js +81 -0
  130. package/dist/server/workspaces/filePreviewService.js.map +1 -0
  131. package/dist/server/workspaces/projectWorkspaceCwds.js +0 -5
  132. package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -1
  133. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +402 -0
  134. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -0
  135. package/dist/server/workspaces/workspaceCatalog.js +47 -0
  136. package/dist/server/workspaces/workspaceCatalog.js.map +1 -0
  137. package/dist/server/workspaces/workspaceContext.js +1 -3
  138. package/dist/server/workspaces/workspaceContext.js.map +1 -1
  139. package/dist/server/workspaces/workspaceDeletionRoutes.js +35 -125
  140. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -1
  141. package/dist/server/workspaces/workspaceProviderRegistry.js +651 -0
  142. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -0
  143. package/dist/server/workspaces/workspaceRemovalService.js +256 -0
  144. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -0
  145. package/dist/server/workspaces/workspaceRouteErrors.js +7 -0
  146. package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -0
  147. package/dist/server/workspaces/worktreePreRemoveHook.js +39 -0
  148. package/dist/server/workspaces/worktreePreRemoveHook.js.map +1 -0
  149. package/dist/server-plugin-api.d.ts +140 -0
  150. package/dist/server-plugin-api.js +2 -0
  151. package/dist/server-plugin-api.js.map +1 -0
  152. package/dist/serverPluginRecovery.js +138 -0
  153. package/dist/serverPluginRecovery.js.map +1 -0
  154. package/dist/sessiond/activeAgentProfile.js +3 -22
  155. package/dist/sessiond/activeAgentProfile.js.map +1 -1
  156. package/dist/sessiond/config.js +11 -0
  157. package/dist/sessiond/config.js.map +1 -1
  158. package/dist/sessiond/sessionDaemonClient.js +11 -9
  159. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  160. package/dist/shared/activeAgentProfile.js +2 -41
  161. package/dist/shared/activeAgentProfile.js.map +1 -1
  162. package/dist/shared/activity.js +0 -3
  163. package/dist/shared/activity.js.map +1 -1
  164. package/dist/shared/apiTypes.js +7 -5
  165. package/dist/shared/apiTypes.js.map +1 -1
  166. package/dist/shared/capabilities.js +8 -6
  167. package/dist/shared/capabilities.js.map +1 -1
  168. package/dist/shared/federatedRoutes.js +28 -5
  169. package/dist/shared/federatedRoutes.js.map +1 -1
  170. package/dist/shared/machinePluginIds.js +4 -2
  171. package/dist/shared/machinePluginIds.js.map +1 -1
  172. package/dist/shared/machineStatus.js +94 -0
  173. package/dist/shared/machineStatus.js.map +1 -0
  174. package/dist/shared/piWebStatusParsing.js +29 -0
  175. package/dist/shared/piWebStatusParsing.js.map +1 -1
  176. package/dist/shared/pluginApiTypes.d.ts +148 -0
  177. package/dist/shared/pluginApiTypes.js +3 -0
  178. package/dist/shared/pluginApiTypes.js.map +1 -0
  179. package/dist/shared/pluginBackendProtocol.js +110 -0
  180. package/dist/shared/pluginBackendProtocol.js.map +1 -0
  181. package/dist/shared/pluginIds.js +5 -0
  182. package/dist/shared/pluginIds.js.map +1 -1
  183. package/dist/shared/pluginRecoveryCommands.js +14 -0
  184. package/dist/shared/pluginRecoveryCommands.js.map +1 -0
  185. package/dist/shared/workspaceFiles.js +41 -2
  186. package/dist/shared/workspaceFiles.js.map +1 -1
  187. package/dist/shared/workspaceRemovalProtocol.js +24 -0
  188. package/dist/shared/workspaceRemovalProtocol.js.map +1 -0
  189. package/docs/config.md +89 -51
  190. package/docs/plugins.md +383 -136
  191. package/examples/workspace-provider-plugin/README.md +52 -0
  192. package/examples/workspace-provider-plugin/package.json +25 -0
  193. package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
  194. package/examples/workspace-provider-plugin/src/server.ts +64 -0
  195. package/examples/workspace-provider-plugin/tsconfig.json +21 -0
  196. package/package.json +29 -10
  197. package/server-plugin-api.d.ts +1 -0
  198. package/dist/client/assets/UnifiedDiffViewer-BafLWGtF.js +0 -39
  199. package/dist/client/assets/index-CA8q9_o7.js +0 -4025
  200. package/dist/plugin-api/unstable.d.ts +0 -22
  201. package/dist/server/activity/workspaceActivityRoutes.js +0 -4
  202. package/dist/server/activity/workspaceActivityRoutes.js.map +0 -1
  203. package/dist/server/git/gitService.js.map +0 -1
  204. package/dist/server/gitRoutes.js +0 -23
  205. package/dist/server/gitRoutes.js.map +0 -1
  206. package/dist/server/sessions/parentSessionLocator.js +0 -75
  207. package/dist/server/sessions/parentSessionLocator.js.map +0 -1
  208. package/dist/server/workspaces/gitWorktreeDiscovery.js +0 -43
  209. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +0 -1
  210. package/dist/server/workspaces/imagePreviewService.js +0 -40
  211. package/dist/server/workspaces/imagePreviewService.js.map +0 -1
  212. package/dist/server/workspaces/workspaceService.js +0 -52
  213. package/dist/server/workspaces/workspaceService.js.map +0 -1
  214. package/dist/shared/apiTypes.d.ts +0 -1217
  215. package/dist/shared/thinkingLevels.d.ts +0 -27
  216. package/plugin-api/unstable.d.ts +0 -1
@@ -0,0 +1,47 @@
1
+ export const WORKSPACE_PROVIDER_RUNTIME_PROTOCOL_VERSION = 1;
2
+ export function createWorkspaceProviderRuntimeSnapshot(records, health, safeStart, diagnostics = []) {
3
+ return Object.freeze({
4
+ protocolVersion: WORKSPACE_PROVIDER_RUNTIME_PROTOCOL_VERSION,
5
+ ...(safeStart === undefined ? {} : { safeStart }),
6
+ records: Object.freeze(records.map((record) => Object.freeze({ ...record }))),
7
+ health: Object.freeze(health.map((inspection) => Object.freeze({
8
+ ...inspection,
9
+ health: Object.freeze({ ...inspection.health }),
10
+ }))),
11
+ diagnostics: Object.freeze(diagnostics.map((diagnostic) => Object.freeze({ ...diagnostic }))),
12
+ });
13
+ }
14
+ export class WorkspaceCatalogUnavailableError extends Error {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.name = "WorkspaceCatalogUnavailableError";
18
+ }
19
+ }
20
+ export class WorkspaceCatalogProtocolError extends Error {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.name = "WorkspaceCatalogProtocolError";
24
+ }
25
+ }
26
+ export class WorkspaceCatalogRequestError extends Error {
27
+ constructor(message, statusCode) {
28
+ super(message);
29
+ this.statusCode = statusCode;
30
+ this.name = "WorkspaceCatalogRequestError";
31
+ }
32
+ }
33
+ /** Preserve route-specific legacy status codes while making authority failures explicit. */
34
+ export function workspaceCatalogHttpStatus(error, fallbackStatus) {
35
+ if (error instanceof WorkspaceCatalogUnavailableError)
36
+ return 503;
37
+ if (error instanceof WorkspaceCatalogProtocolError)
38
+ return 502;
39
+ if (error instanceof WorkspaceCatalogRequestError) {
40
+ if (error.statusCode === 503)
41
+ return 503;
42
+ if (error.statusCode >= 500)
43
+ return 502;
44
+ }
45
+ return fallbackStatus;
46
+ }
47
+ //# sourceMappingURL=workspaceCatalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceCatalog.js","sourceRoot":"","sources":["../../../src/server/workspaces/workspaceCatalog.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,2CAA2C,GAAG,CAAC,CAAC;AAwB7D,MAAM,UAAU,sCAAsC,CACpD,OAA6C,EAC7C,MAA+C,EAC/C,SAAiC,EACjC,cAAuD,EAAE;IAEzD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,eAAe,EAAE,2CAA2C;QAC5D,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;QACjD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;YAC7D,GAAG,UAAU;YACb,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;SAChD,CAAC,CAAC,CAAC;QACJ,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;KAC9F,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,gCAAiC,SAAQ,KAAK;IAA3D;;QACW,SAAI,GAAG,kCAAkC,CAAC;IACrD,CAAC;CAAA;AAED,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAAxD;;QACW,SAAI,GAAG,+BAA+B,CAAC;IAClD,CAAC;CAAA;AAED,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAGrD,YAAY,OAAe,EAAW,UAAkB;QACtD,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,eAAU,GAAV,UAAU,CAAQ;QAF/C,SAAI,GAAG,8BAA8B,CAAC;IAI/C,CAAC;CACF;AAED,4FAA4F;AAC5F,MAAM,UAAU,0BAA0B,CAAC,KAAc,EAAE,cAAsB;IAC/E,IAAI,KAAK,YAAY,gCAAgC;QAAE,OAAO,GAAG,CAAC;IAClE,IAAI,KAAK,YAAY,6BAA6B;QAAE,OAAO,GAAG,CAAC;IAC/D,IAAI,KAAK,YAAY,4BAA4B,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO,GAAG,CAAC;QACzC,IAAI,KAAK,CAAC,UAAU,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;IAC1C,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -1,8 +1,6 @@
1
1
  export async function resolveWorkspaceContext(projects, workspaces, projectId, workspaceId) {
2
2
  const project = await projects.requireProject(projectId);
3
- const workspace = (await workspaces.list(project)).find((candidate) => candidate.id === workspaceId);
4
- if (!workspace)
5
- throw new Error("Workspace not found");
3
+ const workspace = await workspaces.resolve(project.id, workspaceId);
6
4
  return { project, workspace, root: workspace.path };
7
5
  }
8
6
  //# sourceMappingURL=workspaceContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceContext.js","sourceRoot":"","sources":["../../../src/server/workspaces/workspaceContext.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,QAAwB,EAAE,UAA4B,EAAE,SAAiB,EAAE,WAAmB;IAC1I,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;IACrG,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACvD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"workspaceContext.js","sourceRoot":"","sources":["../../../src/server/workspaces/workspaceContext.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAwB,EACxB,UAA4B,EAC5B,SAAiB,EACjB,WAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IACpE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC"}
@@ -1,139 +1,49 @@
1
- import { access, constants } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { workspaceDeletionMetadata } from "../../shared/workspaceDeletion.js";
1
+ import { parseWorkspaceRemovalRequest, WORKSPACE_REMOVAL_REQUEST_BODY_MAX_BYTES, } from "../../shared/workspaceRemovalProtocol.js";
4
2
  import { SessionDaemonClient } from "../../sessiond/sessionDaemonClient.js";
5
- import { isNodeErrorWithCode } from "./pathSafety.js";
6
- /** Relative path, from a workspace root, of the optional repo-provided hook that runs before `git worktree remove`. */
7
- export const WORKTREE_PRE_REMOVE_HOOK_RELATIVE_PATH = ".pi-web/hooks/worktree-pre-remove";
8
- const realWorktreePreRemoveHookProbe = {
9
- async isExecutable(path) {
3
+ import { requestCancellation } from "../requestCancellation.js";
4
+ /** Browser-facing adapter; sessiond owns all workspace removal decisions and effects. */
5
+ export function registerWorkspaceDeletionRoutes(app, daemon = new SessionDaemonClient(), prefix = "/api") {
6
+ app.delete(`${prefix}/projects/:projectId/workspaces/:workspaceId`, { bodyLimit: WORKSPACE_REMOVAL_REQUEST_BODY_MAX_BYTES }, async (request, reply) => {
7
+ let body;
10
8
  try {
11
- await access(path, constants.X_OK);
12
- return true;
9
+ body = parseWorkspaceRemovalRequest(request.body);
13
10
  }
14
11
  catch (error) {
15
- if (isNodeErrorWithCode(error, "ENOENT") || isNodeErrorWithCode(error, "ENOTDIR") || isNodeErrorWithCode(error, "EACCES") || isNodeErrorWithCode(error, "EPERM"))
16
- return false;
17
- throw error;
12
+ return reply.code(400).send({ error: errorMessage(error) });
18
13
  }
19
- },
20
- };
21
- export function registerWorkspaceDeletionRoutes(app, projects, workspaces, daemon = new SessionDaemonClient(), prefix = "/api", preRemoveHook = realWorktreePreRemoveHookProbe) {
22
- app.delete(`${prefix}/projects/:projectId/workspaces/:workspaceId`, async (request, reply) => {
14
+ const cancellation = requestCancellation(request, reply);
23
15
  try {
24
- return await deleteWorkspace(projects, workspaces, daemon, preRemoveHook, request.params.projectId, request.params.workspaceId);
16
+ const upstream = await daemon.request("DELETE", `/workspace-removals/projects/${encodeURIComponent(request.params.projectId)}/workspaces/${encodeURIComponent(request.params.workspaceId)}`, body, { signal: cancellation.signal });
17
+ return await proxyJsonResponse(reply, upstream);
25
18
  }
26
19
  catch (error) {
27
- return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
20
+ return await reply.code(502).send({
21
+ error: `Session daemon unavailable: ${errorMessage(error)}`,
22
+ });
23
+ }
24
+ finally {
25
+ cancellation.dispose();
28
26
  }
29
27
  });
30
28
  }
31
- async function deleteWorkspace(projects, workspaces, daemon, preRemoveHook, projectId, workspaceId) {
32
- const project = await projects.requireProject(projectId);
33
- const projectWorkspaces = await workspaces.list(project);
34
- const targetWorkspace = projectWorkspaces.find((workspace) => workspace.id === workspaceId);
35
- if (targetWorkspace === undefined)
36
- throw new Error("Workspace not found");
37
- if (!canDeleteWorkspace(targetWorkspace))
38
- throw new Error("Only secondary Git worktrees can be deleted");
39
- const commandWorkspace = projectWorkspaces.find((workspace) => workspace.isMain) ?? projectWorkspaces.find((workspace) => workspace.id !== targetWorkspace.id);
40
- if (commandWorkspace === undefined)
41
- throw new Error("Project main workspace not found");
42
- // Probe before any side effect so an unexpected filesystem failure aborts before terminals are closed.
43
- const hookPath = join(commandWorkspace.path, WORKTREE_PRE_REMOVE_HOOK_RELATIVE_PATH);
44
- const hookExecutable = await preRemoveHook.isExecutable(hookPath);
45
- const closeResponse = await requestJson(daemon, "DELETE", `/terminals?cwd=${encodeURIComponent(targetWorkspace.path)}`);
46
- if (closeResponse.statusCode < 200 || closeResponse.statusCode >= 300)
47
- throw new Error(`Failed to close workspace terminals: ${responseError(closeResponse.body, closeResponse.statusCode)}`);
48
- // Single composed command: `&&` is the fail-closed guarantee — a non-zero hook exit prevents the removal.
49
- const quotedTargetPath = shellQuote(targetWorkspace.path);
50
- const command = hookExecutable
51
- ? `${shellQuote(hookPath)} ${quotedTargetPath} && git worktree remove ${quotedTargetPath}`
52
- : `git worktree remove ${quotedTargetPath}`;
53
- const deleteResponse = await requestJson(daemon, "POST", "/terminal-command-runs", {
54
- origin: "core",
55
- projectId: project.id,
56
- workspaceId: commandWorkspace.id,
57
- cwd: commandWorkspace.path,
58
- title: `Delete workspace: ${workspaceLabel(targetWorkspace)}`,
59
- command,
60
- metadata: workspaceDeletionMetadata(targetWorkspace),
61
- });
62
- if (deleteResponse.statusCode < 200 || deleteResponse.statusCode >= 300)
63
- throw new Error(`Failed to start workspace deletion: ${responseError(deleteResponse.body, deleteResponse.statusCode)}`);
64
- return parseTerminalCommandRun(deleteResponse.body);
65
- }
66
- function canDeleteWorkspace(workspace) {
67
- return workspace.isGitWorktree && !workspace.isMain;
68
- }
69
- function workspaceLabel(workspace) {
70
- return workspace.branch ?? workspace.label;
71
- }
72
- async function requestJson(daemon, method, path, body) {
73
- const response = await daemon.request(method, path, body);
74
- return { statusCode: response.statusCode, body: response.body === "" ? undefined : JSON.parse(response.body) };
75
- }
76
- function responseError(body, statusCode) {
77
- if (isRecord(body) && typeof body["error"] === "string")
78
- return body["error"];
79
- return `HTTP ${String(statusCode)}`;
80
- }
81
- function parseTerminalCommandRun(value) {
82
- if (!isRecord(value))
83
- throw new Error("Invalid terminal command run response");
84
- const metadata = value["metadata"];
85
- if (!isRecord(metadata))
86
- throw new Error("Invalid terminal command run response");
87
- const startedAt = optionalString(value, "startedAt");
88
- const exitCode = optionalNumber(value, "exitCode");
89
- const completedAt = optionalString(value, "completedAt");
90
- return {
91
- id: requireString(value, "id"),
92
- origin: requireString(value, "origin"),
93
- projectId: requireString(value, "projectId"),
94
- workspaceId: requireString(value, "workspaceId"),
95
- terminalId: requireString(value, "terminalId"),
96
- title: requireString(value, "title"),
97
- command: requireString(value, "command"),
98
- status: parseStatus(value["status"]),
99
- createdAt: requireString(value, "createdAt"),
100
- metadata: Object.fromEntries(Object.entries(metadata).filter((entry) => typeof entry[1] === "string")),
101
- ...(startedAt === undefined ? {} : { startedAt }),
102
- ...(exitCode === undefined ? {} : { exitCode }),
103
- ...(completedAt === undefined ? {} : { completedAt }),
104
- };
105
- }
106
- function parseStatus(value) {
107
- if (value === "queued" || value === "running" || value === "succeeded" || value === "failed")
108
- return value;
109
- throw new Error("Invalid terminal command run response");
110
- }
111
- function requireString(record, field) {
112
- const value = record[field];
113
- if (typeof value !== "string")
114
- throw new Error("Invalid terminal command run response");
115
- return value;
116
- }
117
- function optionalString(record, field) {
118
- const value = record[field];
119
- if (value === undefined)
120
- return undefined;
121
- if (typeof value !== "string")
122
- throw new Error("Invalid terminal command run response");
123
- return value;
124
- }
125
- function optionalNumber(record, field) {
126
- const value = record[field];
127
- if (value === undefined)
29
+ function proxyJsonResponse(reply, upstream) {
30
+ reply.code(upstream.statusCode);
31
+ const contentType = upstream.headers["content-type"];
32
+ if (contentType !== undefined && contentType !== "")
33
+ reply.header("content-type", contentType);
34
+ if (upstream.body === "")
128
35
  return undefined;
129
- if (typeof value !== "number")
130
- throw new Error("Invalid terminal command run response");
131
- return value;
132
- }
133
- function shellQuote(value) {
134
- return `'${value.replaceAll("'", "'\\''")}'`;
135
- }
136
- function isRecord(value) {
137
- return typeof value === "object" && value !== null && !Array.isArray(value);
36
+ try {
37
+ const value = JSON.parse(upstream.body);
38
+ return value;
39
+ }
40
+ catch (error) {
41
+ return reply.code(502).send({
42
+ error: `Invalid session daemon workspace removal response: ${errorMessage(error)}`,
43
+ });
44
+ }
45
+ }
46
+ function errorMessage(error) {
47
+ return error instanceof Error ? error.message : String(error);
138
48
  }
139
49
  //# sourceMappingURL=workspaceDeletionRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceDeletionRoutes.js","sourceRoot":"","sources":["../../../src/server/workspaces/workspaceDeletionRoutes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspaceDeletionRoutes.js","sourceRoot":"","sources":["../../../src/server/workspaces/workspaceDeletionRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EACL,4BAA4B,EAC5B,wCAAwC,GACzC,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGhE,yFAAyF;AACzF,MAAM,UAAU,+BAA+B,CAC7C,GAAoB,EACpB,SAA6B,IAAI,mBAAmB,EAAE,EACtD,MAAM,GAAG,MAAM;IAEf,GAAG,CAAC,MAAM,CACR,GAAG,MAAM,8CAA8C,EACvD,EAAE,SAAS,EAAE,wCAAwC,EAAE,EACvD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,IAAI,IAAqD,CAAC;QAC1D,IAAI,CAAC;YACH,IAAI,GAAG,4BAA4B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CACnC,QAAQ,EACR,gCAAgC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAC3I,IAAI,EACJ,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,CAChC,CAAC;YACF,OAAO,MAAM,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAChC,KAAK,EAAE,+BAA+B,YAAY,CAAC,KAAK,CAAC,EAAE;aAC5D,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAmB,EACnB,QAA+E;IAE/E,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrD,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE;QAAE,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC/F,IAAI,QAAQ,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,sDAAsD,YAAY,CAAC,KAAK,CAAC,EAAE;SACnF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}