@jmfederico/pi-web 1.202608.2 → 1.202609.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 (233) hide show
  1. package/README.md +3 -3
  2. package/dist/.plugins-ready +1 -0
  3. package/dist/cli.js +5 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/apple-touch-icon-dev.png +0 -0
  6. package/dist/client/assets/index-AroYaCLx.js +4130 -0
  7. package/dist/client/assets/vendor-editor-core-YWog6mAR.js +10 -0
  8. package/dist/client/assets/vendor-editor-languages-DOCw3vc9.js +28 -0
  9. package/dist/client/favicon-dev.svg +8 -0
  10. package/dist/client/index.html +5 -5
  11. package/dist/client/pwa-icon-dev-192.png +0 -0
  12. package/dist/client/pwa-icon-dev-512.png +0 -0
  13. package/dist/config.js +20 -0
  14. package/dist/config.js.map +1 -1
  15. package/dist/docker/piWebDockerCommandPlan.js +9 -1
  16. package/dist/docker/piWebDockerCommandPlan.js.map +1 -1
  17. package/dist/nativeServices/installedServiceDefinitions.js +25 -19
  18. package/dist/nativeServices/installedServiceDefinitions.js.map +1 -1
  19. package/dist/nativeServices/serviceAction.js +38 -26
  20. package/dist/nativeServices/serviceAction.js.map +1 -1
  21. package/dist/nativeServices/servicePlan.js +3 -3
  22. package/dist/nativeServices/servicePlan.js.map +1 -1
  23. package/dist/pi-packages/captains-log/README.md +11 -0
  24. package/dist/pi-packages/captains-log/dist/browser/channelProtocol.js +29 -0
  25. package/dist/pi-packages/captains-log/dist/browser/index.js +144 -0
  26. package/dist/pi-packages/captains-log/dist/browser/markdown.js +67 -0
  27. package/dist/pi-packages/captains-log/dist/browser/panel.js +105 -0
  28. package/dist/pi-packages/captains-log/dist/browser/protocol.js +26 -0
  29. package/dist/pi-packages/captains-log/dist/companion.js +126 -0
  30. package/dist/pi-packages/captains-log/dist/roundtrip.js +62 -0
  31. package/dist/pi-packages/captains-log/dist/server.js +210 -0
  32. package/dist/pi-packages/captains-log/dist/store.js +75 -0
  33. package/dist/pi-packages/captains-log/docs/usage.md +30 -0
  34. package/dist/pi-packages/captains-log/package.json +35 -0
  35. package/dist/pi-packages/captains-log/tsconfig.json +21 -0
  36. package/dist/pi-packages/captains-log/vite.config.mjs +28 -0
  37. package/dist/pi-packages/relays/package.json +1 -1
  38. package/dist/pi-packages/relays/pi-web-plugin.js +1 -1
  39. package/dist/pi-packages/relays/prompts/relay-worktree.md +13 -142
  40. package/dist/pi-packages/relays/prompts/relay.md +25 -132
  41. package/dist/pi-packages/relays/relayDiscovery.js +2 -2
  42. package/dist/pi-packages/relays/relaysPanelElement.js +1 -1
  43. package/dist/pi-packages/relays/skills/relay/SKILL.md +59 -88
  44. package/dist/pi-packages/relays/skills/relay-runner/SKILL.md +253 -0
  45. package/dist/pi-web-plugins/files/browser/assets/files-icon-DZObYhxb.svg +3 -0
  46. package/dist/pi-web-plugins/files/browser/pi-web-plugin.js +439 -0
  47. package/dist/pi-web-plugins/files/package.json +15 -0
  48. package/dist/pi-web-plugins/git/browser/git-panel.js +54 -24
  49. package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +1 -1
  50. package/dist/pi-web-plugins/git/git-backend.js +5 -5
  51. package/dist/pi-web-plugins/git/server-plugin.js +5 -3
  52. package/dist/pi-web-plugins/info/pi-web-plugin.js +1 -1
  53. package/dist/pi-web-plugins/mermaid/browser/mermaid-engine.js +3590 -0
  54. package/dist/pi-web-plugins/mermaid/browser/pi-web-plugin.js +6 -0
  55. package/dist/pi-web-plugins/mermaid/package.json +13 -0
  56. package/dist/pi-web-plugins/terminal/browser/pi-web-plugin.js +210 -0
  57. package/dist/pi-web-plugins/terminal/package.json +16 -0
  58. package/dist/pi-web-plugins/terminal/server-plugin.js +365 -0
  59. package/dist/{server/terminals → pi-web-plugins/terminal}/terminalService.js +162 -65
  60. package/dist/pi-web-plugins/updates/pi-web-plugin.js +45 -35
  61. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +1 -1
  62. package/dist/piWebVersionReport.js +12 -4
  63. package/dist/piWebVersionReport.js.map +1 -1
  64. package/dist/plugin-api.d.ts +222 -23
  65. package/dist/plugin-api.js +1 -0
  66. package/dist/pluginRecoveryCli.js +3 -2
  67. package/dist/pluginRecoveryCli.js.map +1 -1
  68. package/dist/server/activity/workspaceActivityService.js.map +1 -1
  69. package/dist/server/app.js +33 -12
  70. package/dist/server/app.js.map +1 -1
  71. package/dist/server/configRoutes.js +6 -1
  72. package/dist/server/configRoutes.js.map +1 -1
  73. package/dist/server/deploymentIdentity.js +67 -0
  74. package/dist/server/deploymentIdentity.js.map +1 -0
  75. package/dist/server/deploymentIdentityRoutes.js +22 -0
  76. package/dist/server/deploymentIdentityRoutes.js.map +1 -0
  77. package/dist/server/knownAutoInstallPiPackages.js +1 -1
  78. package/dist/server/knownAutoInstallPiPackages.js.map +1 -1
  79. package/dist/server/knownPiPackages.js +12 -0
  80. package/dist/server/knownPiPackages.js.map +1 -0
  81. package/dist/server/machines/machineClient.js +2 -2
  82. package/dist/server/machines/machineClient.js.map +1 -1
  83. package/dist/server/machines/machinePluginProxyRoutes.js +53 -11
  84. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
  85. package/dist/server/machines/machineProxyRoutes.js +70 -7
  86. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  87. package/dist/server/notices/serverNoticeRoutes.js +34 -0
  88. package/dist/server/notices/serverNoticeRoutes.js.map +1 -0
  89. package/dist/server/notices/serverNoticeService.js +26 -0
  90. package/dist/server/notices/serverNoticeService.js.map +1 -0
  91. package/dist/server/notices/serverNoticeStore.js +119 -0
  92. package/dist/server/notices/serverNoticeStore.js.map +1 -0
  93. package/dist/server/piPackageService.js +5 -5
  94. package/dist/server/piPackageService.js.map +1 -1
  95. package/dist/server/piWebPluginCatalog.js +46 -12
  96. package/dist/server/piWebPluginCatalog.js.map +1 -1
  97. package/dist/server/piWebPluginLifecycle.js +26 -3
  98. package/dist/server/piWebPluginLifecycle.js.map +1 -1
  99. package/dist/server/piWebPluginService.js +37 -2
  100. package/dist/server/piWebPluginService.js.map +1 -1
  101. package/dist/server/piWebStatus.js +1 -1
  102. package/dist/server/piWebStatus.js.map +1 -1
  103. package/dist/server/pluginCallbackDrain.js +35 -0
  104. package/dist/server/pluginCallbackDrain.js.map +1 -0
  105. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js +84 -0
  106. package/dist/server/plugins/pluginBackendChannelProxyAdmission.js.map +1 -0
  107. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js +234 -0
  108. package/dist/server/plugins/pluginBackendChannelProxyCoordinator.js.map +1 -0
  109. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js +52 -0
  110. package/dist/server/plugins/pluginBackendChannelProxyRoutes.js.map +1 -0
  111. package/dist/server/plugins/pluginBackendProxyRoutes.js +38 -31
  112. package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -1
  113. package/dist/server/plugins/pluginBackendRegistry.js +740 -0
  114. package/dist/server/plugins/pluginBackendRegistry.js.map +1 -0
  115. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js +34 -0
  116. package/dist/server/plugins/serverPluginPiSessionEventsCapability.js.map +1 -0
  117. package/dist/server/plugins/serverPluginPiSessionsCapability.js +185 -0
  118. package/dist/server/plugins/serverPluginPiSessionsCapability.js.map +1 -0
  119. package/dist/server/plugins/serverPluginRuntime.js +1028 -107
  120. package/dist/server/plugins/serverPluginRuntime.js.map +1 -1
  121. package/dist/server/plugins/serverPluginWorkspacesCapability.js +114 -0
  122. package/dist/server/plugins/serverPluginWorkspacesCapability.js.map +1 -0
  123. package/dist/server/sessiond/pluginBackendChannelRoutes.js +393 -0
  124. package/dist/server/sessiond/pluginBackendChannelRoutes.js.map +1 -0
  125. package/dist/server/sessiond/pluginBackendRoutes.js +10 -7
  126. package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -1
  127. package/dist/server/sessiond/sessionDaemonShutdown.js +9 -2
  128. package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -1
  129. package/dist/server/sessiond/sessionProxyRoutes.js +2 -0
  130. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  131. package/dist/server/sessiond/sessionServiceDependencies.js +1 -0
  132. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  133. package/dist/server/sessiond.js +82 -21
  134. package/dist/server/sessiond.js.map +1 -1
  135. package/dist/server/sessions/attachmentService.js +1 -5
  136. package/dist/server/sessions/attachmentService.js.map +1 -1
  137. package/dist/server/sessions/builtinCommands.js +2 -2
  138. package/dist/server/sessions/builtinCommands.js.map +1 -1
  139. package/dist/server/sessions/clientSessionPreview.js +14 -0
  140. package/dist/server/sessions/clientSessionPreview.js.map +1 -0
  141. package/dist/server/sessions/piSessionEventConnections.js +65 -0
  142. package/dist/server/sessions/piSessionEventConnections.js.map +1 -0
  143. package/dist/server/sessions/piSessionManagerGateway.js +171 -1
  144. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
  145. package/dist/server/sessions/piSessionService.js +442 -90
  146. package/dist/server/sessions/piSessionService.js.map +1 -1
  147. package/dist/server/sessions/sessionActivityMarker.js +105 -0
  148. package/dist/server/sessions/sessionActivityMarker.js.map +1 -0
  149. package/dist/server/sessions/sessionEnvironmentFacts.js +5 -4
  150. package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -1
  151. package/dist/server/sessions/sessionNameGenerator.js +3 -2
  152. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  153. package/dist/server/sessions/sessionRoutes.js +18 -0
  154. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  155. package/dist/server/sessions/spawnSessionTool.js +1 -1
  156. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  157. package/dist/server/sessions/spawnSubsessionTool.js +1 -1
  158. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  159. package/dist/server/sessions/transcriptBranchCache.js +81 -0
  160. package/dist/server/sessions/transcriptBranchCache.js.map +1 -0
  161. package/dist/server/sessions/transcriptMessages.js +54 -0
  162. package/dist/server/sessions/transcriptMessages.js.map +1 -0
  163. package/dist/server/terminals/requiredTerminalService.js +103 -0
  164. package/dist/server/terminals/requiredTerminalService.js.map +1 -0
  165. package/dist/server/webSocketBridge.js +339 -0
  166. package/dist/server/webSocketBridge.js.map +1 -1
  167. package/dist/server/workspaces/projectPiWebConfig.js +6 -1
  168. package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
  169. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +23 -3
  170. package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -1
  171. package/dist/server/workspaces/workspaceCatalog.js +3 -1
  172. package/dist/server/workspaces/workspaceCatalog.js.map +1 -1
  173. package/dist/server/workspaces/workspaceProviderRegistry.js +64 -149
  174. package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -1
  175. package/dist/server/workspaces/workspaceRemovalService.js +38 -5
  176. package/dist/server/workspaces/workspaceRemovalService.js.map +1 -1
  177. package/dist/server-plugin-api.d.ts +216 -22
  178. package/dist/server-plugin-api.js +319 -2
  179. package/dist/server-plugin-api.js.map +1 -1
  180. package/dist/serverPluginRecovery.js +4 -0
  181. package/dist/serverPluginRecovery.js.map +1 -1
  182. package/dist/sessiond/sessionDaemonClient.js +3 -3
  183. package/dist/sessiond/sessionDaemonClient.js.map +1 -1
  184. package/dist/shared/apiTypes.js +1 -1
  185. package/dist/shared/apiTypes.js.map +1 -1
  186. package/dist/shared/federatedRoutes.js +47 -17
  187. package/dist/shared/federatedRoutes.js.map +1 -1
  188. package/dist/shared/machinePluginIds.js +28 -7
  189. package/dist/shared/machinePluginIds.js.map +1 -1
  190. package/dist/shared/pluginApiTypes.d.ts +21 -1
  191. package/dist/shared/pluginApiTypes.js +0 -1
  192. package/dist/shared/pluginBackendProtocol.js +163 -2
  193. package/dist/shared/pluginBackendProtocol.js.map +1 -1
  194. package/dist/shared/pluginIds.js +8 -1
  195. package/dist/shared/pluginIds.js.map +1 -1
  196. package/dist/shared/requiredTerminalPlugin.js +6 -0
  197. package/dist/shared/requiredTerminalPlugin.js.map +1 -0
  198. package/dist/shared/serverNoticeContract.js +88 -0
  199. package/dist/shared/serverNoticeContract.js.map +1 -0
  200. package/dist/shared/sessionDefaults.js +41 -0
  201. package/dist/shared/sessionDefaults.js.map +1 -0
  202. package/docs/config.md +77 -37
  203. package/docs/plugins.md +146 -1213
  204. package/examples/session-bridge-plugin/README.md +20 -0
  205. package/examples/session-bridge-plugin/docs/usage.md +54 -0
  206. package/examples/session-bridge-plugin/package.json +26 -0
  207. package/examples/session-bridge-plugin/src/browser/index.ts +84 -0
  208. package/examples/session-bridge-plugin/src/browser/protocol.ts +24 -0
  209. package/examples/session-bridge-plugin/src/companion.ts +65 -0
  210. package/examples/session-bridge-plugin/src/reviewRun.ts +39 -0
  211. package/examples/session-bridge-plugin/src/server.ts +85 -0
  212. package/examples/session-bridge-plugin/src/store.ts +57 -0
  213. package/examples/session-bridge-plugin/tsconfig.json +21 -0
  214. package/examples/workspace-provider-plugin/README.md +4 -4
  215. package/examples/workspace-provider-plugin/package.json +1 -1
  216. package/examples/workspace-provider-plugin/src/browser/index.ts +9 -9
  217. package/examples/workspace-provider-plugin/src/server.ts +15 -11
  218. package/package.json +17 -11
  219. package/dist/client/assets/CodeViewer-BMWwxG7q.js +0 -4
  220. package/dist/client/assets/TerminalPanel-CacQDIYn.js +0 -187
  221. package/dist/client/assets/index-DUW2xnoV.js +0 -4279
  222. package/dist/client/assets/vendor-editor-core-CXO8gGab.js +0 -12
  223. package/dist/client/assets/vendor-editor-languages-CpW4sJsX.js +0 -46
  224. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +0 -1
  225. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +0 -1
  226. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +0 -35
  227. package/dist/server/terminalProxyRoutes.js +0 -141
  228. package/dist/server/terminalProxyRoutes.js.map +0 -1
  229. package/dist/server/terminals/terminalRoutes.js +0 -155
  230. package/dist/server/terminals/terminalRoutes.js.map +0 -1
  231. package/dist/server/terminals/terminalService.js.map +0 -1
  232. package/dist/server/terminals/terminalSize.js +0 -17
  233. package/dist/server/terminals/terminalSize.js.map +0 -1
@@ -4,25 +4,28 @@ import type {
4
4
  PiWebServerPlugin,
5
5
  ProjectInput,
6
6
  ProviderClaim,
7
- ProviderRequestContext,
8
7
  ProviderWorkspace,
8
+ ServerPluginPeerRequestContext,
9
9
  WorkspaceProvider,
10
10
  } from "@jmfederico/pi-web/server-plugin-api";
11
11
 
12
12
  const markerPath = ".pi-web/example-workspace-provider";
13
13
 
14
14
  const plugin: PiWebServerPlugin = {
15
- apiVersion: 1,
15
+ apiVersion: 3,
16
16
  name: "Example Workspace Provider",
17
17
  activate({ pluginId, logger }) {
18
18
  logger.info("Activating example workspace provider", { pluginId });
19
- return { workspaceProvider: createWorkspaceProvider(pluginId) };
19
+ return {
20
+ workspaceProvider: createWorkspaceProvider(),
21
+ peer: { request: (context) => requestSummary(pluginId, context) },
22
+ };
20
23
  },
21
24
  };
22
25
 
23
26
  export default plugin;
24
27
 
25
- function createWorkspaceProvider(pluginId: string): WorkspaceProvider {
28
+ function createWorkspaceProvider(): WorkspaceProvider {
26
29
  return {
27
30
  async probe(project: ProjectInput, signal: AbortSignal): Promise<ProviderClaim> {
28
31
  signal.throwIfAborted();
@@ -46,16 +49,17 @@ function createWorkspaceProvider(pluginId: string): WorkspaceProvider {
46
49
  publicMetadata: { kind: "example", marker: markerPath },
47
50
  }];
48
51
  },
49
- request(context: ProviderRequestContext) {
50
- context.signal.throwIfAborted();
51
- if (context.operation !== "summary") {
52
- throw new Error(`Unsupported example workspace operation: ${context.operation}`);
53
- }
54
- return Promise.resolve(`${pluginId} owns ${context.workspace.label} at ${context.workspace.path}`);
55
- },
56
52
  };
57
53
  }
58
54
 
55
+ function requestSummary(pluginId: string, context: ServerPluginPeerRequestContext): string {
56
+ context.signal.throwIfAborted();
57
+ if (context.operation !== "summary") {
58
+ throw new Error(`Unsupported example workspace operation: ${context.operation}`);
59
+ }
60
+ return `${pluginId} owns ${context.workspace.label} at ${context.workspace.path}`;
61
+ }
62
+
59
63
  function isMissingFile(error: unknown): boolean {
60
64
  return typeof error === "object"
61
65
  && error !== null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmfederico/pi-web",
3
- "version": "1.202608.2",
3
+ "version": "1.202609.1",
4
4
  "description": "Web UI for persistent Pi Coding Agent sessions in real workspaces.",
5
5
  "license": "MIT",
6
6
  "author": "Federico Jaramillo Martinez",
@@ -10,7 +10,8 @@
10
10
  "types": "./dist/plugin-api.d.ts"
11
11
  },
12
12
  "./server-plugin-api": {
13
- "types": "./dist/server-plugin-api.d.ts"
13
+ "types": "./dist/server-plugin-api.d.ts",
14
+ "import": "./dist/server-plugin-api.js"
14
15
  }
15
16
  },
16
17
  "typesVersions": {
@@ -36,6 +37,9 @@
36
37
  "LICENSE",
37
38
  "extensions",
38
39
  "examples/workspace-provider-plugin",
40
+ "examples/session-bridge-plugin",
41
+ "!examples/**/node_modules",
42
+ "!examples/**/dist",
39
43
  "docs/plugins.md",
40
44
  "docs/config.md",
41
45
  "docs/assets",
@@ -44,8 +48,8 @@
44
48
  ],
45
49
  "scripts": {
46
50
  "dev": "bash -c 'trap \"kill 0\" EXIT; npm run dev:sessiond & npm run dev:web & npm run dev:client & wait'",
47
- "dev:sessiond": "npm run build:plugins && tsx watch src/server/sessiond.ts",
48
- "dev:web": "bash -c 'set -e; npm run build:plugins; trap \"kill 0\" EXIT; npm run dev:plugins & tsx watch src/server/index.ts & wait'",
51
+ "dev:sessiond": "node scripts/dev-sessiond.mjs --watch",
52
+ "dev:web": "tsc -p tsconfig.plugins.json && node scripts/dev-web.mjs",
49
53
  "dev:server": "npm run dev:web",
50
54
  "dev:client": "vite --host 0.0.0.0",
51
55
  "dev:plugins": "node scripts/build-plugins.mjs --watch",
@@ -61,7 +65,7 @@
61
65
  "verify": "npm run typecheck && npm run lint && npm run knip && npm test",
62
66
  "verify:staged": "node scripts/verify-staged.mjs",
63
67
  "start": "tsx src/server/index.ts",
64
- "start:sessiond": "npm run build:plugins && tsx src/server/sessiond.ts",
68
+ "start:sessiond": "node scripts/dev-sessiond.mjs",
65
69
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
66
70
  "prepack": "npm run build",
67
71
  "pack:dry": "npm pack --dry-run",
@@ -103,16 +107,18 @@
103
107
  },
104
108
  "devDependencies": {
105
109
  "@changesets/cli": "^2.31.0",
106
- "@earendil-works/pi-agent-core": "^0.84.1",
107
- "@earendil-works/pi-ai": "^0.84.1",
108
- "@earendil-works/pi-coding-agent": "^0.84.1",
110
+ "@earendil-works/pi-agent-core": "^0.87.0",
111
+ "@earendil-works/pi-ai": "^0.87.0",
112
+ "@earendil-works/pi-coding-agent": "^0.87.0",
109
113
  "@eslint/js": "^10.0.1",
110
114
  "@types/node": "^24.13.3",
111
115
  "@types/ws": "^8.18.1",
116
+ "dompurify": "^3.4.15",
112
117
  "eslint": "^10.6.0",
113
118
  "globals": "^17.7.0",
114
119
  "happy-dom": "^20.11.1",
115
120
  "knip": "^6.25.0",
121
+ "mermaid": "^11.17.2",
116
122
  "tsx": "^4.23.0",
117
123
  "typescript": "^6.0.3",
118
124
  "typescript-eslint": "^8.63.0",
@@ -135,9 +141,9 @@
135
141
  "homepage": "https://pi-web.dev/",
136
142
  "packageManager": "npm@11.11.0",
137
143
  "peerDependencies": {
138
- "@earendil-works/pi-agent-core": ">=0.84.0",
139
- "@earendil-works/pi-ai": ">=0.84.0",
140
- "@earendil-works/pi-coding-agent": ">=0.84.0"
144
+ "@earendil-works/pi-agent-core": ">=0.87.0",
145
+ "@earendil-works/pi-ai": ">=0.87.0",
146
+ "@earendil-works/pi-coding-agent": ">=0.87.0"
141
147
  },
142
148
  "keywords": [
143
149
  "pi-package",
@@ -1,4 +0,0 @@
1
- import{P as e,S as t,X as n,Y as r,et as i,l as a,q as o,y as s}from"./vendor-editor-core-CXO8gGab.js";import{c,i as l,l as u,n as d,r as f,s as p,t as m,u as h}from"./vendor-editor-languages-CpW4sJsX.js";import{_ as g,f as _,g as v,m as y,n as b,p as x,u as S}from"./index-DUW2xnoV.js";import{t as C}from"./vendor-editor-legacy-CYBnW6ZU.js";var w=class extends y{constructor(...e){super(...e),this.content=``}firstUpdated(){this.recreateEditor()}updated(e){(e.has(`content`)||e.has(`language`))&&this.recreateEditor()}disconnectedCallback(){this.view?.destroy(),this.view=void 0,super.disconnectedCallback()}render(){return v`<div class="host"></div>`}recreateEditor(){this.editorHost&&(this.view?.destroy(),this.view=new o({parent:this.editorHost,state:i.create({doc:this.content,extensions:[n(),r.of(a),e(t,{fallback:!0}),i.readOnly.of(!0),o.editable.of(!1),o.lineWrapping,T,...D(this.language),...O(this.language)]})}))}static{this.styles=g`
2
- :host { display: block; min-height: 0; height: 100%; }
3
- .host { height: 100%; min-height: 0; overflow: auto; }
4
- `}};b([_()],w.prototype,`content`,void 0),b([_()],w.prototype,`language`,void 0),b([S(`.host`)],w.prototype,`editorHost`,void 0),w=b([x(`code-viewer`)],w);var T=o.theme({"&":{height:`100%`,color:`var(--pi-text)`,backgroundColor:`var(--pi-bg)`,fontSize:`12px`},".cm-scroller":{fontFamily:`ui-monospace, SFMono-Regular, Menlo, Consolas, monospace`,lineHeight:`1.45`},".cm-gutters":{backgroundColor:`var(--pi-bg)`,color:`var(--pi-dim)`,borderRight:`1px solid var(--pi-border-muted)`},".cm-activeLineGutter":{backgroundColor:`transparent`},".cm-activeLine":{backgroundColor:`transparent`},".cm-content":{caretColor:`transparent`},"&.cm-focused":{outline:`none`}}),E=o.theme({".cm-content":{textAlign:`start`},".cm-line":{unicodeBidi:`plaintext`}});function D(e){return e===`markdown`?[o.contentAttributes.of({dir:`auto`}),E]:[]}function O(e){if(e===void 0)return[];switch(e){case`typescript`:return[u({typescript:!0})];case`javascript`:return[u()];case`json`:return[l()];case`markdown`:return[p()];case`css`:return[h()];case`html`:return[c()];case`python`:return[f()];case`rust`:return[d()];case`go`:return[m()];case`diff`:return[s.define(C)];default:return[]}}export{w as CodeViewer};
@@ -1,187 +0,0 @@
1
- import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as ee,u as h}from"./index-DUW2xnoV.js";import{n as g,t as _}from"./vendor-terminal-D8k4UKM2.js";var te=`important`,ne=` !important`,v=p(class extends s{constructor(e){if(super(e),e.type!==t.ATTRIBUTE||e.name!==`style`||e.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(e){return Object.keys(e).reduce((t,n)=>{let r=e[n];return r==null?t:t+`${n=n.includes(`-`)?n:n.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,`-$&`).toLowerCase()}:${r};`},``)}update(e,[t]){let{style:n}=e.element;if(this.ft===void 0)return this.ft=new Set(Object.keys(t)),this.render(t);for(let e of this.ft)t[e]??(this.ft.delete(e),e.includes(`-`)?n.removeProperty(e):n[e]=null);for(let e in t){let r=t[e];if(r!=null){this.ft.add(e);let t=typeof r==`string`&&r.endsWith(ne);e.includes(`-`)||t?n.setProperty(e,t?r.slice(0,-11):r,t?te:``):n[e]=r}}return o}}),y=`#ffffff`,re=`#000000`,b=[`#2e3436`,`#cc0000`,`#4e9a06`,`#c4a000`,`#3465a4`,`#75507b`,`#06989a`,`#d3d7cf`,`#555753`,`#ef2929`,`#8ae234`,`#fce94f`,`#729fcf`,`#ad7fa8`,`#34e2e2`,`#eeeeec`],x=[`black`,`red`,`green`,`yellow`,`blue`,`magenta`,`cyan`,`white`,`brightBlack`,`brightRed`,`brightGreen`,`brightYellow`,`brightBlue`,`brightMagenta`,`brightCyan`,`brightWhite`],ie={black:b[0],red:b[1],green:b[2],yellow:b[3],blue:b[4],magenta:b[5],cyan:b[6],white:b[7],brightBlack:b[8],brightRed:b[9],brightGreen:b[10],brightYellow:b[11],brightBlue:b[12],brightMagenta:b[13],brightCyan:b[14],brightWhite:b[15]};function S(e,t,n={}){let r=Math.max(0,Math.floor(t));if(e.length<=0||r===0)return{text:``,lines:[],physicalLineCount:0,viewportLine:0};let i=ce(n.theme),a=n.theme?.foreground??y,o=n.theme?.background??re,s=[],c=e.getNullCell(),l=-1;for(let t=0;t<e.length;t+=1){let u=e.getLine(t);if(u===void 0){s.push({text:``,runs:[],wrapped:!1});continue}let d=ae(u,r,c,{palette:i,foreground:a,background:o,drawBoldTextInBrightColors:n.drawBoldTextInBrightColors!==!1});s.push(d),(d.text!==``||d.runs.some(e=>e.style.background!==o))&&(l=t)}let u=Math.min(e.length-1,Math.max(0,e.baseY+e.cursorY)),d=Math.max(l,u),f=s.slice(0,d+1),p=[];for(let e of f){let t=p.at(-1);if(e.wrapped&&t!==void 0){t.text+=e.text,T(t.runs,e.runs);continue}p.push({text:e.text,runs:e.runs.map(e=>({text:e.text,style:e.style}))})}return{text:p.map(e=>e.text).join(`
2
- `),lines:p,physicalLineCount:f.length,viewportLine:Math.min(d,Math.max(0,e.viewportY))}}function ae(e,t,n,r){let i=[],a=Math.min(t,e.length);for(let t=0;t<a;t+=1){let a=e.getCell(t,n);if(a===void 0){i.push({text:` `,meaningful:!1,style:w(r)});continue}let o=a.getWidth();if(o===0)continue;let s=a.getChars();i.push({text:s===``?` `.repeat(Math.max(1,o)):s,meaningful:s!==``||!a.isAttributeDefault(),style:oe(a,r)})}let o=i.length-1;for(;o>=0&&i[o]?.meaningful!==!0;)--o;let s=[],c=``;for(let e=0;e<=o;e+=1){let t=i[e];t!==void 0&&(c+=t.text,E(s,{text:t.text,style:t.style}))}return{text:c,runs:s,wrapped:e.isWrapped}}function oe(e,t){let n=e.isInverse()!==0,r=C(e,`foreground`,t),i=C(e,`background`,t);if(n&&([r,i]=[i,r]),e.isBold()!==0&&t.drawBoldTextInBrightColors){let i=n?e.isBgPalette()?e.getBgColor():void 0:e.isFgPalette()?e.getFgColor():void 0;i!==void 0&&i>=0&&i<8&&(r=t.palette[i+8]??r)}return{foreground:r,background:i,bold:e.isBold()!==0,italic:e.isItalic()!==0,dim:e.isDim()!==0,underline:e.isUnderline()!==0,invisible:e.isInvisible()!==0,strikethrough:e.isStrikethrough()!==0,overline:e.isOverline()!==0}}function C(e,t,n){let r=t===`foreground`?e.isFgRGB():e.isBgRGB(),i=t===`foreground`?e.isFgPalette():e.isBgPalette(),a=t===`foreground`?e.getFgColor():e.getBgColor();return r?le(a):i?n.palette[a]??(t===`foreground`?n.foreground:n.background):t===`foreground`?n.foreground:n.background}function w(e){return{foreground:e.foreground,background:e.background,bold:!1,italic:!1,dim:!1,underline:!1,invisible:!1,strikethrough:!1,overline:!1}}function T(e,t){for(let n of t)E(e,n)}function E(e,t){if(t.text===``)return;let n=e.at(-1);if(n!==void 0&&se(n.style,t.style)){n.text+=t.text;return}e.push({text:t.text,style:t.style})}function se(e,t){return e.foreground===t.foreground&&e.background===t.background&&e.bold===t.bold&&e.italic===t.italic&&e.dim===t.dim&&e.underline===t.underline&&e.invisible===t.invisible&&e.strikethrough===t.strikethrough&&e.overline===t.overline}function ce(e){let t=[...b];for(let n=0;n<x.length;n+=1){let r=x[n];if(r===void 0)continue;let i=e?.[r];typeof i==`string`&&(t[n]=i)}let n=[0,95,135,175,215,255];for(let e=0;e<216;e+=1){let r=n[Math.floor(e/36)%6]??0,i=n[Math.floor(e/6)%6]??0,a=n[e%6]??0;t.push(D(r,i,a))}for(let e=0;e<24;e+=1){let n=8+e*10;t.push(D(n,n,n))}for(let n=0;n<Math.min(e?.extendedAnsi?.length??0,240);n+=1){let r=e?.extendedAnsi?.[n];r!==void 0&&(t[n+16]=r)}return t}function le(e){return`#${(e&16777215).toString(16).padStart(6,`0`)}`}function D(e,t,n){return`#${e.toString(16).padStart(2,`0`)}${t.toString(16).padStart(2,`0`)}${n.toString(16).padStart(2,`0`)}`}var O=`pi-web.terminal.softKeys`,ue=`(pointer: coarse), (max-width: 760px)`;function de(e,t){return e??t}function fe(e){if(e===`true`)return!0;if(e===`false`)return!1}function k(){return typeof window<`u`&&`matchMedia`in window?window.matchMedia(ue):void 0}function A(e){return e?.matches===!0}function j(e=k()){return de(N(),A(e))}function M(){return N()!==void 0}function N(e=F()){if(e!==void 0)try{return fe(e.getItem(O))}catch{return}}function P(e,t=F()){if(t!==void 0)try{t.setItem(O,String(e))}catch{}}function F(){if(!(typeof window>`u`))try{return window.localStorage}catch{return}}var I=[{id:`escape`,label:`Esc`,ariaLabel:`Escape`,title:`Send Escape`},{id:`tab`,label:`Tab`,ariaLabel:`Tab`,title:`Send Tab`},{id:`ctrl-c`,label:`Ctrl+C`,ariaLabel:`Control C`,title:`Interrupt the foreground process`},{id:`ctrl-d`,label:`Ctrl+D`,ariaLabel:`Control D`,title:`Send EOF / close input`},{id:`ctrl-z`,label:`Ctrl+Z`,ariaLabel:`Control Z`,title:`Suspend the foreground process`},{id:`ctrl-l`,label:`Ctrl+L`,ariaLabel:`Control L`,title:`Clear / redraw the terminal`},{id:`ctrl-r`,label:`Ctrl+R`,ariaLabel:`Control R`,title:`Reverse search history`},{id:`ctrl-u`,label:`Ctrl+U`,ariaLabel:`Control U`,title:`Delete to the start of the line`},{id:`ctrl-w`,label:`Ctrl+W`,ariaLabel:`Control W`,title:`Delete the previous word`},{id:`arrow-left`,label:`←`,ariaLabel:`Left arrow`,title:`Move left`},{id:`arrow-up`,label:`↑`,ariaLabel:`Up arrow`,title:`Move up / previous command`},{id:`arrow-down`,label:`↓`,ariaLabel:`Down arrow`,title:`Move down / next command`},{id:`arrow-right`,label:`→`,ariaLabel:`Right arrow`,title:`Move right`},{id:`home`,label:`Home`,ariaLabel:`Home`,title:`Move to the start`},{id:`end`,label:`End`,ariaLabel:`End`,title:`Move to the end`},{id:`page-up`,label:`PgUp`,ariaLabel:`Page up`,title:`Page up`},{id:`page-down`,label:`PgDn`,ariaLabel:`Page down`,title:`Page down`},{id:`delete`,label:`Del`,ariaLabel:`Delete`,title:`Delete forward`},{id:`backspace`,label:`⌫`,ariaLabel:`Backspace`,title:`Backspace`},{id:`meta-backward-word`,label:`M-B`,ariaLabel:`Meta B`,title:`Move backward one word`},{id:`meta-forward-word`,label:`M-F`,ariaLabel:`Meta F`,title:`Move forward one word`}],L=`\x1B`,R=``;function z(e,t){switch(e){case`escape`:return L;case`tab`:return` `;case`ctrl-c`:return B(`c`);case`ctrl-d`:return B(`d`);case`ctrl-z`:return B(`z`);case`ctrl-l`:return B(`l`);case`ctrl-r`:return B(`r`);case`ctrl-u`:return B(`u`);case`ctrl-w`:return B(`w`);case`arrow-left`:return V(`D`,t);case`arrow-up`:return V(`A`,t);case`arrow-down`:return V(`B`,t);case`arrow-right`:return V(`C`,t);case`home`:return H(`H`,t);case`end`:return H(`F`,t);case`page-up`:return`${L}[5~`;case`page-down`:return`${L}[6~`;case`delete`:return`${L}[3~`;case`backspace`:return R;case`meta-backward-word`:return`${L}b`;case`meta-forward-word`:return`${L}f`}}function B(e){return String.fromCharCode(e.toUpperCase().charCodeAt(0)-64)}function V(e,t){return t?.applicationCursorKeysMode===!0?`${L}O${e}`:`${L}[${e}`}function H(e,t){return t?.applicationCursorKeysMode===!0?`${L}O${e}`:`${L}[${e}`}var pe=8,me=500,U=class extends l{constructor(...e){super(...e),this.refocusOnClick=!0,this.onInput=()=>void 0,this.lastPointerFinishedAt=0}sendSoftKey(e,t){this.onInput(z(e.id,this.modes),t)}onSoftKeyPointerDown(e,t){e.pointerType===`mouse`&&e.button!==0||(e.preventDefault(),this.pointerStart={pointerId:e.pointerId,key:t,clientX:e.clientX,clientY:e.clientY})}onSoftKeyPointerMove(e){let t=this.pointerStart;t?.pointerId===e.pointerId&&W(t,e)&&this.finishSoftKeyPointer()}onSoftKeyPointerUp(e,t){let n=this.pointerStart;n?.pointerId===e.pointerId&&(e.preventDefault(),this.finishSoftKeyPointer(),!(n.key.id!==t.id||W(n,e))&&this.sendSoftKey(t,{refocus:e.pointerType===`mouse`}))}onSoftKeyPointerCancel(e){this.pointerStart?.pointerId===e.pointerId&&this.finishSoftKeyPointer()}finishSoftKeyPointer(){this.pointerStart=void 0,this.lastPointerFinishedAt=Date.now()}onSoftKeyClick(e,t){if(Date.now()-this.lastPointerFinishedAt<me){e.preventDefault();return}this.sendSoftKey(t,{refocus:this.refocusOnClick})}render(){return a`
3
- <div class="terminal-soft-keys" role="toolbar" aria-label="Terminal soft keys">
4
- ${I.map(e=>a`
5
- <button
6
- type="button"
7
- class="soft-key"
8
- title=${e.title}
9
- aria-label=${e.ariaLabel}
10
- @pointerdown=${t=>{this.onSoftKeyPointerDown(t,e)}}
11
- @pointermove=${e=>{this.onSoftKeyPointerMove(e)}}
12
- @pointerup=${t=>{this.onSoftKeyPointerUp(t,e)}}
13
- @pointercancel=${e=>{this.onSoftKeyPointerCancel(e)}}
14
- @click=${t=>{this.onSoftKeyClick(t,e)}}
15
- >${e.label}</button>
16
- `)}
17
- </div>
18
- `}static{this.styles=e`
19
- :host { flex: 0 0 auto; display: block; }
20
- .terminal-soft-keys { display: flex; gap: 6px; align-items: center; padding: 6px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; touch-action: pan-x; }
21
- .terminal-soft-keys::-webkit-scrollbar { display: none; }
22
- button { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; max-width: none; min-height: 34px; border: 1px solid var(--pi-border); border-radius: 7px; background: var(--pi-surface); color: var(--pi-text); padding: 6px 9px; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; cursor: pointer; touch-action: pan-x; -webkit-touch-callout: none; user-select: none; }
23
- button:disabled { opacity: .5; cursor: not-allowed; }
24
- `}};u([i({attribute:!1})],U.prototype,`modes`,void 0),u([i({type:Boolean})],U.prototype,`refocusOnClick`,void 0),u([i({attribute:!1})],U.prototype,`onInput`,void 0),U=u([f(`terminal-soft-keys`)],U);function W(e,t){return Math.hypot(t.clientX-e.clientX,t.clientY-e.clientY)>pe}var he={cursorBlink:!0,convertEol:!0,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Consolas, monospace`,fontSize:13},ge={cols:100,rows:30},_e=1e3,G=class extends l{constructor(...e){super(...e),this.machineId=`local`,this.autoStart=!1,this.onSelectTerminal=()=>void 0,this.terminals=[],this.commandRuns=[],this.loading=!1,this.visible=!1,this.cancellingRunIds=[],this.continuingTerminalIds=[],this.defaultSoftKeysEnvironment=!1,this.softKeysEnabled=j(),this.suppressTerminalInput=!1,this.softKeysDefaultEnvironmentMedia=k(),this.softKeysPreferenceStored=M(),this.onSoftKeysDefaultEnvironmentChange=()=>{this.syncDefaultSoftKeysEnvironment()}}connectedCallback(){super.connectedCallback(),this.syncDefaultSoftKeysEnvironment(),this.softKeysDefaultEnvironmentMedia?.addEventListener(`change`,this.onSoftKeysDefaultEnvironmentChange),this.themeObserver=new MutationObserver(()=>{this.applyTerminalTheme()}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`,`style`,`data-theme`]})}firstUpdated(){this.intersectionObserver=new IntersectionObserver(e=>{this.visible=e[0]?.isIntersecting===!0}),this.intersectionObserver.observe(this)}disconnectedCallback(){this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0,this.themeObserver?.disconnect(),this.themeObserver=void 0,this.softKeysDefaultEnvironmentMedia?.removeEventListener(`change`,this.onSoftKeysDefaultEnvironmentChange),this.updateCommandRunPolling(!1),this.disposeTerminalView(),super.disconnectedCallback()}syncDefaultSoftKeysEnvironment(){let e=A(this.softKeysDefaultEnvironmentMedia),t=this.softKeysEnabled;this.defaultSoftKeysEnvironment=e,this.softKeysPreferenceStored||(this.softKeysEnabled=e),this.softKeysEnabled!==t&&this.scheduleFitAndNotify()}scheduleFitAndNotify(){this.updateComplete.then(()=>{this.fitAndNotify()})}willUpdate(e){let t=this.workspace===void 0?void 0:JSON.stringify([this.machineId,this.workspace.path]);if(t!==this.observedWorkspaceScope){this.observedWorkspaceScope=t,this.loadedCwd=void 0,this.autoStartConsumedCwd=void 0,this.terminals=[],this.commandRuns=[],this.selectedId=void 0,this.cancellingRunIds=[],this.continuingTerminalIds=[],this.updateCommandRunPolling(!1),this.disposeTerminalView();return}if(e.has(`selectedTerminalId`)){if(e.get(`selectedTerminalId`)!==void 0&&this.selectedTerminalId===void 0){this.loadedCwd=void 0,this.selectTerminalIdInView(void 0);return}this.applyRequestedTerminalSelection()}}updated(e){this.visible?this.hasPendingCommandRuns()&&this.updateCommandRunPolling(!0):this.updateCommandRunPolling(!1),this.loadVisibleWorkspaceTerminals(),e.has(`selectedTerminalId`)&&this.shouldReloadForRequestedTerminal()&&this.loadTerminals(),this.ensureTerminalView()}loadVisibleWorkspaceTerminals(){let e=this.workspace?.path;!this.visible||e===void 0||e===this.loadedCwd||(this.loadedCwd=e,this.loadTerminals())}async loadTerminals(){this.loading=!0,this.error=void 0;try{let e=this.workspace;if(e===void 0)return;let t=this.consumeAutoStart(),[n,r]=await Promise.all([c.terminals(e.projectId,e.id,this.machineId),c.listCommandRuns({projectId:e.projectId,workspaceId:e.id},this.machineId)]);this.terminals=n,this.commandRuns=r,this.selectPreferredLoadedTerminal({replaceUrl:!0}),this.updateCommandRunPolling(this.hasPendingCommandRuns(r)),n.length===0&&t&&await this.startTerminal()}catch(e){this.error=e instanceof Error?e.message:String(e)}finally{this.loading=!1}}applyRequestedTerminalSelection(){this.selectedTerminalId!==void 0&&!this.terminals.some(e=>e.id===this.selectedTerminalId)||this.selectPreferredLoadedTerminal({replaceUrl:!0})}consumeAutoStart(){let e=this.workspace?.path;return!this.autoStart||e===void 0||this.autoStartConsumedCwd===e?!1:(this.autoStartConsumedCwd=e,!0)}shouldReloadForRequestedTerminal(){let e=this.workspace?.path;return this.visible&&e!==void 0&&e===this.loadedCwd&&this.selectedTerminalId!==void 0&&!this.loading&&!this.terminals.some(e=>e.id===this.selectedTerminalId)}selectPreferredLoadedTerminal(e){let t=m(this.terminals,{targetTerminalId:this.selectedTerminalId});t===void 0&&this.selectedTerminalId!==void 0&&(t=d(this.terminals)),this.selectTerminalIdInView(t?.id),(t?.id!==this.selectedTerminalId||t===void 0&&this.selectedTerminalId!==void 0)&&this.onSelectTerminal(t?.id,{replace:e?.replaceUrl===!0})}selectTerminalIdInView(e){this.selectedId!==e&&(this.selectedId=e,this.disposeTerminalView())}async startTerminal(){if(this.workspace!==void 0){this.error=void 0;try{let e=this.measureTerminalSize()??ge,t=await c.startTerminal(this.workspace.projectId,this.workspace.id,e,this.machineId);this.terminals=[...this.terminals,t],this.selectTerminal(t.id)}catch(e){this.error=e instanceof Error?e.message:String(e)}}}async closeTerminal(e,t){t.stopPropagation();try{if(this.workspace===void 0)return;await c.closeTerminal(this.workspace.projectId,this.workspace.id,e,this.machineId);let t=this.terminals.filter(t=>t.id!==e);if(this.terminals=t,this.selectedId===e||this.selectedTerminalId===e){let e=d(t)?.id;this.selectTerminalIdInView(e),this.onSelectTerminal(e,{replace:!0})}}catch(e){this.error=e instanceof Error?e.message:String(e)}}selectTerminal(e){this.selectedId!==e&&this.selectTerminalIdInView(e),this.onSelectTerminal(e)}selectedTerminalInfo(){return this.terminals.find(e=>e.id===this.selectedId)}selectedCommandRun(){let e=this.selectedTerminalInfo()?.commandRunId;if(e!==void 0)return this.commandRuns.find(t=>t.id===e)}async loadCommandRuns(){let e=this.workspace;if(e!==void 0)try{let t=await c.listCommandRuns({projectId:e.projectId,workspaceId:e.id},this.machineId);this.commandRuns=t,this.cancellingRunIds=this.cancellingRunIds.filter(e=>t.some(t=>t.id===e&&J(t))),this.updateCommandRunPolling(this.hasPendingCommandRuns(t))}catch(e){this.error=e instanceof Error?e.message:String(e)}}updateCommandRunPolling(e){if(e&&this.commandRunPollTimer===void 0){this.commandRunPollTimer=window.setInterval(()=>{this.loadCommandRuns()},_e);return}!e&&this.commandRunPollTimer!==void 0&&(window.clearInterval(this.commandRunPollTimer),this.commandRunPollTimer=void 0)}hasPendingCommandRuns(e=this.commandRuns){return e.some(J)}async cancelCommandRun(e){if(!(!J(e)||this.cancellingRunIds.includes(e.id))){this.error=void 0,this.cancellingRunIds=[...this.cancellingRunIds,e.id];try{await c.cancelCommandRun(e.id,this.machineId),await this.loadCommandRuns()}catch(e){this.error=e instanceof Error?e.message:String(e)}finally{this.cancellingRunIds=this.cancellingRunIds.filter(t=>t!==e.id)}}}async continueTerminal(e){if(!(this.workspace===void 0||this.continuingTerminalIds.includes(e))){this.error=void 0,this.continuingTerminalIds=[...this.continuingTerminalIds,e];try{let t=await c.continueTerminal(this.workspace.projectId,this.workspace.id,e,this.machineId);this.terminals=this.terminals.map(n=>n.id===e?t:n),this.socket===void 0&&this.disposeTerminalView(),this.fitAndNotify(),this.terminal?.focus()}catch(e){this.error=e instanceof Error?e.message:String(e)}finally{this.continuingTerminalIds=this.continuingTerminalIds.filter(t=>t!==e)}}}ensureTerminalView(){let e=this.workspace,t=this.terminalHostElement();if(!this.visible||this.terminal!==void 0||this.selectedId===void 0||t===void 0||e===void 0)return;let n=new g(X(this)),r=new _;n.loadAddon(r),n.open(t),this.terminal=n,this.fitAddon=r,this.resizeObserver=new ResizeObserver(()=>{this.fitAndNotify()}),this.resizeObserver.observe(t),n.onData(e=>{this.suppressTerminalInput||this.copySnapshot!==void 0||this.sendTerminalInput(e)});let i=this.fitTerminal();this.connectSocket(e.projectId,e.id,this.selectedId,n,i),requestAnimationFrame(()=>{this.fitAndNotify()}),n.focus()}connectSocket(e,t,r,i,a){let o=n(e,t,r,a,this.machineId);o.binaryType=`arraybuffer`,this.socket=o,o.addEventListener(`open`,()=>{this.fitAndNotify()}),o.addEventListener(`message`,e=>{this.handleSocketMessage(e.data,r,i)}),o.addEventListener(`close`,()=>{this.socket===o&&(this.socket=void 0)})}async handleSocketMessage(e,t,n){try{let r=be(await xe(e));r.type===`output`&&this.writeTerminalOutput(n,r.data,r.replay===!0),r.type===`exit`&&(n.writeln(`\r\n[process exited${r.exitCode===void 0?``:` with code ${String(r.exitCode)}`}]`),this.terminals=this.terminals.map(e=>e.id===t?{...e,exited:!0,...r.exitCode===void 0?{}:{exitCode:r.exitCode}}:e),this.loadCommandRuns()),r.type===`error`&&n.writeln(`\r\n[terminal error: ${r.message}]`)}catch(e){n.writeln(`\r\n[terminal error: ${e instanceof Error?e.message:String(e)}]`)}}writeTerminalOutput(e,t,n){if(!n){e.write(t);return}this.suppressTerminalInput=!0,e.write(t,()=>{this.suppressTerminalInput=!1})}fitAndNotify(){let e=this.fitTerminal();e!==void 0&&this.send({type:`resize`,...e})}fitTerminal(){if(this.fitAddon===void 0||this.terminal===void 0)return;let e=$(this.fitAddon.proposeDimensions());if(e!==void 0)return this.fitAddon.fit(),e}measureTerminalSize(){let e=this.fitTerminal();if(e!==void 0)return e;let t=this.terminalHostElement();if(this.terminal!==void 0||t===void 0)return;let n=new g(X(this)),r=new _;n.loadAddon(r),n.open(t);let i=$(r.proposeDimensions());return n.dispose(),i}terminalHostElement(){let e=this.terminalHost;return e instanceof HTMLDivElement?e:void 0}applyTerminalTheme(){this.terminal!==void 0&&(this.terminal.options.theme=Z(this))}sendTerminalInput(e){let t=Y(e);t!==``&&this.send({type:`input`,data:t})}sendSoftKeyInput(e,t){this.copySnapshot===void 0&&(this.sendTerminalInput(e),t.refocus&&this.focusTerminal())}focusTerminal(){let e=this.terminal;e!==void 0&&(e.focus(),requestAnimationFrame(()=>{e.focus()}))}send(e){this.socket?.readyState===WebSocket.OPEN&&this.socket.send(JSON.stringify(e))}disposeTerminalView(){this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.socket?.close(),this.socket=void 0,this.terminal?.dispose(),this.terminal=void 0,this.fitAddon=void 0,this.copySnapshot=void 0,this.copyStatus=void 0}renderCommandRunNotice(){let e=this.selectedCommandRun();if(e===void 0)return null;let t=this.selectedTerminalInfo();if(J(e)){let t=this.cancellingRunIds.includes(e.id);return a`
25
- <section class="command-run-notice running">
26
- <div>
27
- <strong>${e.title}</strong>
28
- <p>Command is running. Press <kbd>Ctrl</kbd>+<kbd>C</kbd> or use the button to cancel.</p>
29
- <code>${e.command}</code>
30
- </div>
31
- <button class="danger" ?disabled=${t} @click=${()=>{this.cancelCommandRun(e)}}>${t?`Cancel sent…`:`Cancel command`}</button>
32
- </section>
33
- `}if(t?.exited===!0){let n=this.continuingTerminalIds.includes(t.id);return a`
34
- <section class=${`command-run-notice ${e.status}`}>
35
- <div>
36
- <strong>${ye(e)}</strong>
37
- <p>Output is preserved. Continue in a shell to inspect or run follow-up commands.</p>
38
- <code>${e.command}</code>
39
- </div>
40
- <button ?disabled=${n} @click=${()=>{this.continueTerminal(t.id)}}>${n?`Starting shell…`:`Continue in shell`}</button>
41
- </section>
42
- `}return null}enterCopyMode(){this.copySnapshot===void 0&&this.captureCopySnapshot()}refreshCopyMode(){this.copySnapshot!==void 0&&this.captureCopySnapshot()}captureCopySnapshot(){let e=this.terminal;if(e===void 0)return;let t=S(e.buffer.active,e.cols,{theme:e.options.theme,drawBoldTextInBrightColors:e.options.drawBoldTextInBrightColors});this.copySnapshot=t,this.copyStatus=void 0,e.blur(),this.updateComplete.then(()=>{let n=this.terminalCopySelector;if(n==null)return;let r=Math.max(0,t.physicalLineCount-e.rows),i=Math.min(r,t.viewportLine);n.scrollTop=(r===0?0:i/r)*Math.max(0,n.scrollHeight-n.clientHeight),this.syncCopySnapshotScroll()})}exitCopyMode(){this.copySnapshot!==void 0&&(this.copySnapshot=void 0,this.copyStatus=void 0)}syncCopySnapshotScroll(){let e=this.terminalCopySelector,t=this.terminalCopyContent;if(e==null||t==null)return;let n=Math.max(0,e.scrollHeight-e.clientHeight),r=Math.max(0,t.scrollHeight-t.clientHeight),i=Math.max(0,e.scrollWidth-e.clientWidth),a=Math.max(0,t.scrollWidth-t.clientWidth);t.scrollTop=K(e.scrollTop,n,r),t.scrollLeft=K(e.scrollLeft,i,a)}async copyAllSnapshotText(){let e=this.copySnapshot?.text??``;if(e===``){this.copyStatus=`No terminal output to copy.`;return}this.copyStatus=await ee(e)?`Copied all terminal output.`:`Unable to copy terminal output.`}renderCopyModeToggle(){if(this.selectedId===void 0)return null;let e=this.copySnapshot!==void 0;return a`
43
- <button
44
- type="button"
45
- class=${e?`copy-mode-toggle selected`:`copy-mode-toggle`}
46
- title=${e?`Return to the interactive terminal`:`Select and copy terminal output`}
47
- aria-label=${e?`Close terminal copy mode`:`Open terminal copy mode`}
48
- aria-pressed=${String(e)}
49
- @click=${()=>{e?this.exitCopyMode():this.enterCopyMode()}}
50
- >
51
- <span>${e?`Done`:`Select`}</span>
52
- </button>
53
- `}renderCopyModeToolbar(){let e=this.copySnapshot;return e===void 0?null:a`
54
- <div class="terminal-copy-toolbar" role="toolbar" aria-label="Terminal copy controls">
55
- <span aria-live="polite">${this.copyStatus??`Snapshot · long-press and select text`}</span>
56
- <small>${e.physicalLineCount} ${e.physicalLineCount===1?`row`:`rows`}</small>
57
- <button type="button" @click=${()=>{this.refreshCopyMode()}}>Refresh</button>
58
- <button type="button" @click=${()=>{this.copyAllSnapshotText()}}>Copy all</button>
59
- </div>
60
- `}renderCopyMode(){let e=this.copySnapshot;return e===void 0?null:a`
61
- <section class="terminal-copy-view" aria-label="Terminal copy mode">
62
- ${this.copyToolbarReplacesSoftKeys()?null:this.renderCopyModeToolbar()}
63
- <div class="terminal-copy-layers">
64
- <pre class="terminal-copy-content" aria-hidden="true">${e.lines.map((e,t)=>a`${t===0?null:`
65
- `}${e.runs.map(e=>a`<span style=${v(q(e.style))}>${e.text}</span>`)}`)}</pre>
66
- <textarea
67
- class="terminal-copy-selector"
68
- readonly
69
- inputmode="none"
70
- wrap="soft"
71
- spellcheck="false"
72
- autocapitalize="off"
73
- autocomplete="off"
74
- aria-label="Selectable terminal output"
75
- .value=${e.text}
76
- @scroll=${()=>{this.syncCopySnapshotScroll()}}
77
- ></textarea>
78
- </div>
79
- </section>
80
- `}selectedTerminalAcceptsInput(){let e=this.selectedTerminalInfo();return e!==void 0&&!e.exited}copyToolbarReplacesSoftKeys(){return this.copySnapshot!==void 0&&this.selectedTerminalAcceptsInput()&&this.softKeysEnabled}renderTerminalAccessoryBar(){return this.copySnapshot===void 0?this.shouldShowSoftKeys()?this.renderSoftKeys():null:this.copyToolbarReplacesSoftKeys()?this.renderCopyModeToolbar():null}shouldShowSoftKeys(){return this.selectedTerminalAcceptsInput()&&this.softKeysEnabled}shouldShowSoftKeysToggle(){return this.copySnapshot===void 0&&this.selectedTerminalAcceptsInput()}toggleSoftKeys(){this.copySnapshot===void 0&&(this.softKeysEnabled=!this.softKeysEnabled,this.softKeysPreferenceStored=!0,P(this.softKeysEnabled),this.scheduleFitAndNotify())}renderSoftKeysToggle(){return this.shouldShowSoftKeysToggle()?a`
81
- <button
82
- type="button"
83
- class=${this.softKeysEnabled?`soft-keys-toggle selected`:`soft-keys-toggle`}
84
- title=${this.softKeysEnabled?`Hide terminal soft keys`:`Show terminal soft keys`}
85
- aria-label=${this.softKeysEnabled?`Hide terminal soft keys`:`Show terminal soft keys`}
86
- aria-pressed=${String(this.softKeysEnabled)}
87
- @click=${()=>{this.toggleSoftKeys()}}
88
- >
89
- <svg class="keyboard-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
90
- <rect x="3" y="5" width="18" height="14" rx="2"></rect>
91
- <path d="M7 9h.01M10 9h.01M13 9h.01M16 9h.01M7 12h.01M10 12h.01M13 12h.01M16 12h.01M8 16h8"></path>
92
- </svg>
93
- <span>Keys</span>
94
- </button>
95
- `:null}renderSoftKeys(){return a`
96
- <terminal-soft-keys
97
- .modes=${this.terminal?.modes}
98
- .refocusOnClick=${!this.defaultSoftKeysEnvironment}
99
- .onInput=${(e,t)=>{this.sendSoftKeyInput(e,t)}}
100
- ></terminal-soft-keys>
101
- `}render(){return a`
102
- <section class="terminal-shell">
103
- <div class="terminal-tabs">
104
- ${this.renderCopyModeToggle()}
105
- ${this.renderSoftKeysToggle()}
106
- ${this.terminals.map(e=>a`
107
- <button class=${this.selectedId===e.id?`selected`:``} @click=${()=>{this.selectTerminal(e.id)}}>
108
- <span>${e.name}${e.exited?` · exited`:``}</span>
109
- <small @click=${t=>{this.closeTerminal(e.id,t)}}>×</small>
110
- </button>
111
- `)}
112
- <button class="new" ?disabled=${this.workspace===void 0} @click=${()=>{this.startTerminal()}}>+ Shell</button>
113
- </div>
114
- ${this.error===void 0?null:a`<p class="error">${this.error}</p>`}
115
- ${this.renderCommandRunNotice()}
116
- ${this.renderTerminalAccessoryBar()}
117
- ${this.loading?a`<p class="muted">Loading terminals…</p>`:null}
118
- <div class="terminal-stage">
119
- <div class=${this.copySnapshot===void 0?`terminal-host`:`terminal-host copying`} ?inert=${this.copySnapshot!==void 0}></div>
120
- ${this.renderCopyMode()}
121
- </div>
122
- </section>
123
- `}static{this.styles=e`
124
- :host { flex: 1 1 auto; min-height: 0; display: flex; }
125
- .terminal-shell { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; background: var(--pi-terminal-bg); }
126
- .terminal-tabs { flex: 0 0 auto; display: flex; gap: 6px; align-items: center; padding: 6px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); overflow: auto; }
127
- .terminal-tabs > button { box-sizing: border-box; height: 30px; line-height: 16px; }
128
- /* Desktop xterm already has mouse selection and hardware keys; keep touch controls to touch/narrow layouts. */
129
- .copy-mode-toggle, .soft-keys-toggle, terminal-soft-keys { display: none; }
130
- .copy-mode-toggle.selected { display: inline-flex; }
131
- @media (pointer: coarse), (max-width: 760px) {
132
- .copy-mode-toggle, .soft-keys-toggle { display: inline-flex; }
133
- terminal-soft-keys { display: block; }
134
- }
135
- button { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 180px; border: 1px solid var(--pi-border); border-radius: 7px; background: var(--pi-surface); color: var(--pi-text); padding: 5px 7px; cursor: pointer; }
136
- button.selected { border-color: var(--pi-accent); background: var(--pi-selection-bg); }
137
- button.new { flex: 0 0 auto; color: var(--pi-muted); }
138
- .soft-keys-toggle { flex: 0 0 auto; }
139
- .soft-keys-toggle .keyboard-icon { display: block; flex: 0 0 auto; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
140
- button span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
141
- button small { color: var(--pi-muted); font-size: 14px; line-height: 1; }
142
- button small:hover { color: var(--pi-danger); }
143
- button.danger { color: var(--pi-danger); }
144
- button:disabled { opacity: .5; cursor: not-allowed; }
145
- .command-run-notice { flex: 0 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 8px 10px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-surface); color: var(--pi-text); }
146
- .command-run-notice.running { border-color: var(--pi-warning-border); }
147
- .command-run-notice.succeeded { border-color: var(--pi-success-border); }
148
- .command-run-notice.failed { border-color: var(--pi-danger); }
149
- .command-run-notice p { margin: 3px 0; color: var(--pi-muted); }
150
- .command-run-notice code { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--pi-text-secondary); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
151
- .command-run-notice kbd { border: 1px solid var(--pi-border); border-radius: 4px; background: var(--pi-bg); padding: 0 4px; font: 11px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
152
- .command-run-notice button { justify-self: end; max-width: none; }
153
- .terminal-stage { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: var(--pi-terminal-bg); }
154
- .terminal-host { position: absolute; inset: 0; padding: 6px; box-sizing: border-box; overflow: hidden; }
155
- .terminal-host.copying { visibility: hidden; pointer-events: none; }
156
- .terminal-copy-view { position: absolute; inset: 0; display: flex; flex-direction: column; min-height: 0; background: var(--pi-terminal-bg); color: var(--pi-terminal-text); }
157
- .terminal-copy-toolbar { box-sizing: border-box; flex: 0 0 auto; display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 47px; padding: 6px; border-bottom: 1px solid var(--pi-border-muted); background: var(--pi-bg); color: var(--pi-muted); font: 12px system-ui, sans-serif; }
158
- .terminal-copy-toolbar > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
159
- .terminal-copy-toolbar small { margin-left: auto; white-space: nowrap; color: var(--pi-dim); }
160
- .terminal-copy-toolbar button { flex: 0 0 auto; width: auto; min-height: 34px; padding: 6px 9px; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
161
- .terminal-copy-layers { flex: 1 1 auto; min-height: 0; display: grid; overflow: hidden; background: var(--pi-terminal-bg); }
162
- /* xterm renders the configured 13px terminal font in 17px-high cells. */
163
- .terminal-copy-content, .terminal-copy-selector { grid-area: 1 / 1; box-sizing: border-box; min-width: 0; min-height: 0; width: 100%; height: 100%; margin: 0; padding: 6px; border: 0; border-radius: 0; font: 13px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 17px; letter-spacing: normal; font-variant-ligatures: none; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-all; }
164
- .terminal-copy-content { overflow: auto; pointer-events: none; background: var(--pi-terminal-bg); color: var(--pi-terminal-text); -webkit-user-select: none; user-select: none; }
165
- .terminal-copy-selector { z-index: 1; overflow: auto; resize: none; outline: none; appearance: none; background: transparent; color: transparent; caret-color: var(--pi-accent); -webkit-text-fill-color: transparent; cursor: text; -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; touch-action: auto; }
166
- .terminal-copy-selector::selection { background: var(--pi-terminal-selection); color: transparent; -webkit-text-fill-color: transparent; }
167
- .terminal-host .xterm { height: 100%; cursor: text; position: relative; user-select: none; }
168
- .terminal-host .xterm.focus, .terminal-host .xterm:focus { outline: none; }
169
- .terminal-host .xterm-helpers { position: absolute; top: 0; z-index: 5; }
170
- /* Hide the helper textarea without using !important on the positional properties (left/top/width/height/z-index). xterm sets those inline during IME/dead-key composition (e.g. "~" on a Swedish layout) so the composition is positioned at the cursor and committed correctly; forcing them here would pin the textarea off-screen with zero size and break composition. */
171
- .terminal-host .xterm-helper-textarea { position: absolute; left: -9999em; top: 0; width: 0; height: 0; padding: 0 !important; border: 0 !important; margin: 0 !important; opacity: 0 !important; z-index: -5; white-space: nowrap !important; overflow: hidden !important; resize: none !important; outline: 0 !important; appearance: none !important; }
172
- /* The composition view shows pending dead-key/IME input. Without these rules it renders as a static block in the top-left corner instead of overlaying the cursor. */
173
- .terminal-host .composition-view { position: absolute; display: none; white-space: nowrap; z-index: 1; background: var(--pi-terminal-bg, #000); color: var(--pi-terminal-text, #fff); }
174
- .terminal-host .composition-view.active { display: block; }
175
- .terminal-host .xterm-viewport { position: absolute; inset: 0; overflow-y: scroll; cursor: default; background-color: var(--pi-terminal-bg); }
176
- .terminal-host .xterm-screen { position: relative; }
177
- .terminal-host .xterm-screen canvas { position: absolute; left: 0; top: 0; }
178
- .terminal-host .xterm-char-measure-element { display: inline-block; visibility: hidden; position: absolute; top: 0; left: -9999em; line-height: normal; }
179
- .terminal-host .xterm-accessibility:not(.debug), .terminal-host .xterm-message { position: absolute; inset: 0; z-index: 10; color: transparent; pointer-events: none; }
180
- .terminal-host .xterm-accessibility-tree:not(.debug) *::selection { color: transparent; }
181
- .terminal-host .xterm-accessibility-tree { font-family: monospace; user-select: text; white-space: pre; }
182
- .terminal-host .xterm-accessibility-tree > div { transform-origin: left; width: fit-content; }
183
- .terminal-host .live-region { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
184
- .error { flex: 0 0 auto; margin: 0; padding: 8px; color: var(--pi-danger); border-bottom: 1px solid var(--pi-border); background: var(--pi-surface); }
185
- .muted { margin: 10px; color: var(--pi-muted); }
186
- .xterm { height: 100%; }
187
- `}};u([i({attribute:!1})],G.prototype,`workspace`,void 0),u([i()],G.prototype,`machineId`,void 0),u([i({attribute:!1})],G.prototype,`selectedTerminalId`,void 0),u([i({type:Boolean})],G.prototype,`autoStart`,void 0),u([i({attribute:!1})],G.prototype,`onSelectTerminal`,void 0),u([h(`.terminal-host`)],G.prototype,`terminalHost`,void 0),u([h(`.terminal-copy-content`)],G.prototype,`terminalCopyContent`,void 0),u([h(`.terminal-copy-selector`)],G.prototype,`terminalCopySelector`,void 0),u([r()],G.prototype,`terminals`,void 0),u([r()],G.prototype,`commandRuns`,void 0),u([r()],G.prototype,`selectedId`,void 0),u([r()],G.prototype,`loading`,void 0),u([r()],G.prototype,`error`,void 0),u([r()],G.prototype,`visible`,void 0),u([r()],G.prototype,`cancellingRunIds`,void 0),u([r()],G.prototype,`continuingTerminalIds`,void 0),u([r()],G.prototype,`defaultSoftKeysEnvironment`,void 0),u([r()],G.prototype,`softKeysEnabled`,void 0),u([r()],G.prototype,`copySnapshot`,void 0),u([r()],G.prototype,`copyStatus`,void 0),G=u([f(`terminal-panel`)],G);function K(e,t,n){return t<=0||n<=0?0:Math.min(1,Math.max(0,e/t))*n}function ve(e){return/^#[\da-f]{6}$/i.test(e)?`${e}80`:`color-mix(in srgb, ${e} 50%, transparent)`}function q(e){let t=[e.underline?`underline`:void 0,e.strikethrough?`line-through`:void 0,e.overline?`overline`:void 0].filter(e=>e!==void 0).join(` `);return{color:e.invisible?`transparent`:e.dim?ve(e.foreground):e.foreground,backgroundColor:e.background,fontWeight:e.bold?`700`:void 0,fontStyle:e.italic?`italic`:void 0,textDecorationLine:t===``?void 0:t}}function J(e){return e.status===`queued`||e.status===`running`}function ye(e){return e.status===`succeeded`?`Command succeeded${e.exitCode===void 0?``:` with exit code ${String(e.exitCode)}`}`:`Command failed${e.exitCode===void 0?``:` with exit code ${String(e.exitCode)}`}`}function be(e){let t=JSON.parse(e);if(!Ce(t))return{type:`error`,message:`Invalid terminal message`};let n=t;return n.type===`output`&&typeof n.data==`string`?{type:`output`,data:n.data,...typeof n.replay==`boolean`?{replay:n.replay}:{}}:n.type===`exit`?{type:`exit`,...typeof n.exitCode==`number`?{exitCode:n.exitCode}:{}}:n.type===`error`&&typeof n.message==`string`?{type:`error`,message:n.message}:{type:`error`,message:`Invalid terminal message`}}function Y(e){return e.replaceAll(`\x1B[I`,``).replaceAll(`\x1B[O`,``)}async function xe(e){return typeof e==`string`?e:e instanceof ArrayBuffer?new TextDecoder().decode(e):e instanceof Blob?await e.text():String(e)}function X(e){return{...he,theme:Z(e)}}function Z(e){return{...ie,background:Q(e,`--pi-terminal-bg`,`#05070a`),foreground:Q(e,`--pi-terminal-text`,`#e6edf3`),cursor:Q(e,`--pi-accent`,`#58a6ff`),selectionBackground:Q(e,`--pi-terminal-selection`,`#264f78`)}}function Q(e,t,n){let r=getComputedStyle(e).getPropertyValue(t).trim();return r===``?n:r}function $(e){if(!(e===void 0||!Se(e.cols,e.rows)))return{cols:Math.floor(e.cols),rows:Math.floor(e.rows)}}function Se(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e>0&&t>0}function Ce(e){return typeof e==`object`&&!!e}export{G as TerminalPanel,Y as filterTerminalInput};