@jmfederico/pi-web 1.202606.0 → 1.202606.2

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 (95) hide show
  1. package/README.md +23 -7
  2. package/dist/client/assets/{CodeViewer-N88Bx8F6.js → CodeViewer-iYSv2-dg.js} +1 -1
  3. package/dist/client/assets/{TerminalPanel-DKiL51Xi.js → TerminalPanel-BpFW6j27.js} +4 -4
  4. package/dist/client/assets/index-D4dbiKXF.js +2210 -0
  5. package/dist/client/index.html +1 -1
  6. package/dist/config.js +63 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/pi-web-plugins/info/pi-web-plugin.js +8 -1
  9. package/dist/pi-web-plugins/updates/package.json +9 -0
  10. package/dist/pi-web-plugins/{pi-web → updates}/pi-web-plugin.js +38 -30
  11. package/dist/pi-web-plugins/workspace-tasks/config.js +91 -0
  12. package/dist/pi-web-plugins/workspace-tasks/package.json +9 -0
  13. package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +48 -0
  14. package/dist/pi-web-plugins/workspace-tasks/taskRunner.js +12 -0
  15. package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +292 -0
  16. package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +47 -0
  17. package/dist/plugin-api/unstable.d.ts +22 -0
  18. package/dist/plugin-api.d.ts +169 -0
  19. package/dist/server/app.js +63 -26
  20. package/dist/server/app.js.map +1 -1
  21. package/dist/server/configRoutes.js +123 -0
  22. package/dist/server/configRoutes.js.map +1 -0
  23. package/dist/server/git/gitEnv.js +15 -0
  24. package/dist/server/git/gitEnv.js.map +1 -0
  25. package/dist/server/git/gitService.js +2 -1
  26. package/dist/server/git/gitService.js.map +1 -1
  27. package/dist/server/gitRoutes.js +3 -3
  28. package/dist/server/gitRoutes.js.map +1 -1
  29. package/dist/server/machines/machineClient.js +134 -0
  30. package/dist/server/machines/machineClient.js.map +1 -0
  31. package/dist/server/machines/machinePluginProxyRoutes.js +187 -0
  32. package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
  33. package/dist/server/machines/machineProxyRoutes.js +92 -0
  34. package/dist/server/machines/machineProxyRoutes.js.map +1 -0
  35. package/dist/server/machines/machineRoutes.js +56 -0
  36. package/dist/server/machines/machineRoutes.js.map +1 -0
  37. package/dist/server/machines/machineService.js +260 -0
  38. package/dist/server/machines/machineService.js.map +1 -0
  39. package/dist/server/machines/machineStore.js +128 -0
  40. package/dist/server/machines/machineStore.js.map +1 -0
  41. package/dist/server/piWebPluginService.js +45 -15
  42. package/dist/server/piWebPluginService.js.map +1 -1
  43. package/dist/server/piWebStatus.js +127 -36
  44. package/dist/server/piWebStatus.js.map +1 -1
  45. package/dist/server/piWebStatusCache.js +32 -0
  46. package/dist/server/piWebStatusCache.js.map +1 -0
  47. package/dist/server/sessiond/sessionProxyRoutes.js +17 -14
  48. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  49. package/dist/server/sessiond.js +18 -7
  50. package/dist/server/sessiond.js.map +1 -1
  51. package/dist/server/sessions/piSessionManagerGateway.js +87 -0
  52. package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
  53. package/dist/server/sessions/piSessionService.js +147 -66
  54. package/dist/server/sessions/piSessionService.js.map +1 -1
  55. package/dist/server/sessions/sessionArchiveStore.js +12 -0
  56. package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
  57. package/dist/server/sessions/sessionNameGenerator.js +2 -0
  58. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  59. package/dist/server/sessions/sessionRoutes.js +126 -43
  60. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  61. package/dist/server/terminalProxyRoutes.js +20 -10
  62. package/dist/server/terminalProxyRoutes.js.map +1 -1
  63. package/dist/server/terminals/terminalRoutes.js +11 -0
  64. package/dist/server/terminals/terminalRoutes.js.map +1 -1
  65. package/dist/server/terminals/terminalService.js +6 -0
  66. package/dist/server/terminals/terminalService.js.map +1 -1
  67. package/dist/server/workspaceExplorerRoutes.js +4 -4
  68. package/dist/server/workspaceExplorerRoutes.js.map +1 -1
  69. package/dist/server/workspaces/fileSuggestions.js +98 -17
  70. package/dist/server/workspaces/fileSuggestions.js.map +1 -1
  71. package/dist/server/workspaces/gitWorktreeDiscovery.js +3 -2
  72. package/dist/server/workspaces/gitWorktreeDiscovery.js.map +1 -1
  73. package/dist/server/workspaces/workspaceDeletionRoutes.js +113 -0
  74. package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
  75. package/dist/shared/apiTypes.d.ts +498 -0
  76. package/dist/shared/apiTypes.js +3 -1
  77. package/dist/shared/apiTypes.js.map +1 -1
  78. package/dist/shared/capabilities.js +25 -0
  79. package/dist/shared/capabilities.js.map +1 -0
  80. package/dist/shared/federatedRoutes.js +61 -0
  81. package/dist/shared/federatedRoutes.js.map +1 -0
  82. package/dist/shared/machinePluginIds.js +41 -0
  83. package/dist/shared/machinePluginIds.js.map +1 -0
  84. package/dist/shared/piWebStatusParsing.js +43 -0
  85. package/dist/shared/piWebStatusParsing.js.map +1 -1
  86. package/dist/shared/pluginIds.js +5 -0
  87. package/dist/shared/pluginIds.js.map +1 -0
  88. package/dist/shared/workspaceDeletion.js +12 -0
  89. package/dist/shared/workspaceDeletion.js.map +1 -0
  90. package/docs/plugins.md +278 -71
  91. package/package.json +8 -12
  92. package/plugin-api/unstable.d.ts +1 -0
  93. package/plugin-api.d.ts +1 -148
  94. package/dist/client/assets/index-DeSR1RUE.js +0 -1446
  95. package/dist/pi-web-plugins/pi-web/package.json +0 -9
package/README.md CHANGED
@@ -34,23 +34,27 @@ PI WEB connects those two worlds. The work stays in the server-side environment
34
34
 
35
35
  ## Core model
36
36
 
37
- PI WEB organizes work into three levels:
37
+ PI WEB organizes work into four levels:
38
38
 
39
39
  ```text
40
- Project a folder on the server
40
+ Machine a local or remote PI WEB runtime endpoint
41
+ Project a folder on that machine
41
42
  Workspace a git worktree, or the project folder for non-git projects
42
43
  Session a chat with Pi Coding Agent running inside a workspace
43
44
  ```
44
45
 
45
46
  This maps naturally to real development work:
46
47
 
47
- - add a project once;
48
+ - select the local machine or another registered PI WEB runtime;
49
+ - add a project once on the selected machine;
48
50
  - use worktrees to separate branches, features, experiments, and reviews;
49
51
  - start one or more agent sessions inside each workspace;
50
52
  - leave sessions running even when the browser disconnects or the UI restarts.
51
53
 
52
54
  ## Features
53
55
 
56
+ - Add and list local or remote PI WEB machines from the action palette.
57
+ - Proxy remote projects, workspaces, files, git state, sessions, and terminals through the currently opened PI WEB server.
54
58
  - Add and list server-side projects.
55
59
  - Discover git worktrees automatically with `git worktree list --porcelain`.
56
60
  - Support non-git folders as single-workspace projects.
@@ -92,16 +96,23 @@ The web process serves the API and browser UI. In development it can autoreload
92
96
 
93
97
  PI WEB keeps its own state intentionally small:
94
98
 
99
+ - Machines: `~/.pi-web/machines.json` stores only opt-in remote machine records; the local machine is synthesized.
95
100
  - Projects: `~/.pi-web/projects.json`
96
101
  - Workspaces: discovered from git worktrees, not stored
97
- - Sessions and chat history: Pi's default JSONL session storage
98
- - Active session runtimes and WebSockets: memory in the session daemon
102
+ - Sessions and chat history: Pi's default JSONL session storage on the selected machine
103
+ - Active session runtimes and WebSockets: memory in each selected machine's session daemon
104
+
105
+ ## Machine federation
106
+
107
+ The Machines section lets one PI WEB instance act as a gateway to other PI WEB runtimes. Register a remote machine from **Actions → Add Machine** with the remote PI WEB base URL, for example a URL reachable over NetBird, Tailscale, WireGuard, an SSH tunnel, or a trusted reverse proxy. The browser continues talking to the local PI WEB origin; project, workspace, file, git, session, activity, and terminal HTTP/WebSocket traffic is proxied server-to-server. See the [Fleet guide](https://pi-web.dev/machines.html) for setup, trust model, and troubleshooting details.
108
+
109
+ Remote model-provider credentials and OAuth state stay on the target machine. API-key provider configuration can be proxied, but OAuth login should be completed by opening the remote PI WEB directly. Register remote machines only when you trust the endpoint and the network path: adding a machine gives this PI WEB server permission to contact that URL with the optional bearer token you configured.
99
110
 
100
111
  ## Plugins
101
112
 
102
- PI WEB production installs can load trusted local UI plugins without rebuilding PI WEB. Plugins are browser-side ES modules that can add action-palette actions, workspace panels, and workspace-label metadata. They do not run in the session daemon and are not sandboxed.
113
+ PI WEB production installs can load trusted local UI plugins without rebuilding PI WEB. Plugins are browser-side ES modules that can add action-palette actions, workspace panels, and workspace-label metadata, using documented context helpers for workspace files and terminals. They do not run in the session daemon and are not sandboxed.
103
114
 
104
- The supported package shape is intentionally singular: `piWeb.plugins` entries with explicit `id` and `module`, plus a browser module that exports `{ apiVersion: 1, name, activate }`. The bundled `pi-web-plugins/info` TypeScript source is the canonical minimal real example, and `pi-web-plugins/pi-web` demonstrates a dynamic status panel.
115
+ The supported package shape is intentionally singular: `piWeb.plugins` entries with explicit `id` and `module` plus optional `machineSpecific` metadata, and a browser module that exports `{ apiVersion: 1, name, activate }`. The bundled `pi-web-plugins/info` TypeScript source is the canonical minimal real example, `pi-web-plugins/updates` demonstrates a dynamic status panel, and built-in [Workspace Tasks](docs/plugins.md#workspace-tasks) adds a workspace tab for running configured shell commands in PI WEB terminals.
105
116
 
106
117
  A useful prompt for AI agents:
107
118
 
@@ -113,6 +124,8 @@ Validate with /pi-web-plugins/manifest.json and explain reload/debug steps.
113
124
  Do not modify PI WEB itself.
114
125
  ```
115
126
 
127
+ Manage discovered plugins in **Settings → Plugins** or with the top-level `plugins` config key. Plugins are enabled by default; set `plugins.<plugin-id>.enabled` to `false` and reload the browser tab to prevent PI WEB from importing that plugin.
128
+
116
129
  Reload the browser tab after adding or editing a plugin. If `PI_WEB_DATA_DIR` is set, use `$PI_WEB_DATA_DIR/plugins` instead of `~/.pi-web/plugins`. Check discovery with:
117
130
 
118
131
  ```bash
@@ -258,6 +271,9 @@ Environment variables:
258
271
  - `PI_WEB_SESSIOND_HOST` — daemon TCP bind host when `PI_WEB_SESSIOND_PORT` is set. Defaults to `127.0.0.1`.
259
272
  - `PI_WEB_SESSIOND_URL` — daemon URL used by the web process when connecting over TCP, for example `http://127.0.0.1:3001`. If you set `PI_WEB_SESSIOND_PORT`, set this for the web process too.
260
273
  - `PI_WEB_PROJECTS_FILE` — optional override for the projects storage JSON file. Defaults to `$PI_WEB_DATA_DIR/projects.json`.
274
+ - `PI_WEB_MACHINES_FILE` — optional override for the remote machine registry JSON file. Defaults to `$PI_WEB_DATA_DIR/machines.json`.
275
+ - `PI_CODING_AGENT_SESSION_DIR` — Pi session storage directory. PI WEB follows the same session-location priority as Pi for web sessions: this environment variable, then `sessionDir` in Pi settings for the selected workspace, then Pi's default session directory.
276
+ - `PI_CODING_AGENT_DIR` — Pi agent config directory. PI WEB uses this for Pi auth, settings, resources, and default session storage, matching Pi's own configuration layout.
261
277
 
262
278
  ## Development services
263
279
 
@@ -1,4 +1,4 @@
1
- import{w as a,J as p,$ as h,A as m,X as g,U as f,_ as v,a0 as b}from"./vendor-editor-core-B4Sq6exx.js";import{g as y,r as w,p as C,h as x,c as j,m as _,j as k,a as u}from"./vendor-editor-languages-DznYbTkJ.js";import{d as E}from"./vendor-editor-legacy-B4QLsWF8.js";import{i as H,b as O,a as S,n as d,e as P,t as L}from"./index-DeSR1RUE.js";var D=Object.defineProperty,F=Object.getOwnPropertyDescriptor,i=(e,o,n,s)=>{for(var t=s>1?void 0:s?F(o,n):o,c=e.length-1,l;c>=0;c--)(l=e[c])&&(t=(s?l(o,n,t):l(t))||t);return s&&t&&D(o,n,t),t};let r=class extends H{constructor(){super(...arguments),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 O`<div class="host"></div>`}recreateEditor(){this.editorHost&&(this.view?.destroy(),this.view=new a({parent:this.editorHost,state:p.create({doc:this.content,extensions:[h(),m.of(g),f(v,{fallback:!0}),p.readOnly.of(!0),a.editable.of(!1),a.lineWrapping,M,...R(this.language)]})}))}};r.styles=S`
1
+ import{w as a,J as p,$ as h,A as m,X as g,U as f,_ as v,a0 as b}from"./vendor-editor-core-B4Sq6exx.js";import{g as y,r as w,p as C,h as x,c as j,m as _,j as k,a as u}from"./vendor-editor-languages-DznYbTkJ.js";import{d as E}from"./vendor-editor-legacy-B4QLsWF8.js";import{i as H,b as O,a as S,n as d,e as P,t as L}from"./index-D4dbiKXF.js";var D=Object.defineProperty,F=Object.getOwnPropertyDescriptor,i=(e,o,n,s)=>{for(var t=s>1?void 0:s?F(o,n):o,c=e.length-1,l;c>=0;c--)(l=e[c])&&(t=(s?l(o,n,t):l(t))||t);return s&&t&&D(o,n,t),t};let r=class extends H{constructor(){super(...arguments),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 O`<div class="host"></div>`}recreateEditor(){this.editorHost&&(this.view?.destroy(),this.view=new a({parent:this.editorHost,state:p.create({doc:this.content,extensions:[h(),m.of(g),f(v,{fallback:!0}),p.readOnly.of(!0),a.editable.of(!1),a.lineWrapping,M,...R(this.language)]})}))}};r.styles=S`
2
2
  :host { display: block; min-height: 0; height: 100%; }
3
3
  .host { height: 100%; min-height: 0; overflow: auto; }
4
4
  `;i([d()],r.prototype,"content",2);i([d()],r.prototype,"language",2);i([P(".host")],r.prototype,"editorHost",2);r=i([L("code-viewer")],r);const M=a.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"}});function R(e){if(e===void 0)return[];switch(e){case"typescript":return[u({typescript:!0})];case"javascript":return[u()];case"json":return[k()];case"markdown":return[_()];case"css":return[j()];case"html":return[x()];case"python":return[C()];case"rust":return[w()];case"go":return[y()];case"diff":return[b.define(E)];default:return[]}}export{r as CodeViewer};
@@ -1,4 +1,4 @@
1
- import{a as E,n as p,i as K,b as l,t as R,c as m,s as A,d as w,f as _,e as F,r as c}from"./index-DeSR1RUE.js";import{D as T,o as S}from"./vendor-terminal-DjQ08hXu.js";import"./vendor-editor-core-B4Sq6exx.js";import"./vendor-editor-languages-DznYbTkJ.js";const P="pi-web.terminal.softKeys",N="(pointer: coarse), (max-width: 760px)";function z(e,t){return e??t}function V(e){if(e==="true")return!0;if(e==="false")return!1}function $(){return typeof window<"u"&&"matchMedia"in window?window.matchMedia(N):void 0}function M(e){return e?.matches===!0}function B(e=$()){return z(O(),M(e))}function H(){return O()!==void 0}function O(e=D()){if(e!==void 0)try{return V(e.getItem(P))}catch{return}}function j(e,t=D()){if(t!==void 0)try{t.setItem(P,String(e))}catch{}}function D(){if(!(typeof window>"u"))try{return window.localStorage}catch{return}}const U=[{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"}],d="\x1B",q="";function Y(e,t){switch(e){case"escape":return d;case"tab":return" ";case"ctrl-c":return h("c");case"ctrl-d":return h("d");case"ctrl-z":return h("z");case"ctrl-l":return h("l");case"ctrl-r":return h("r");case"ctrl-u":return h("u");case"ctrl-w":return h("w");case"arrow-left":return b("D",t);case"arrow-up":return b("A",t);case"arrow-down":return b("B",t);case"arrow-right":return b("C",t);case"home":return x("H",t);case"end":return x("F",t);case"page-up":return`${d}[5~`;case"page-down":return`${d}[6~`;case"delete":return`${d}[3~`;case"backspace":return q;case"meta-backward-word":return`${d}b`;case"meta-forward-word":return`${d}f`}}function h(e){return String.fromCharCode(e.toUpperCase().charCodeAt(0)-64)}function b(e,t){return t?.applicationCursorKeysMode===!0?`${d}O${e}`:`${d}[${e}`}function x(e,t){return t?.applicationCursorKeysMode===!0?`${d}O${e}`:`${d}[${e}`}var W=Object.defineProperty,X=Object.getOwnPropertyDescriptor,y=(e,t,i,r)=>{for(var n=r>1?void 0:r?X(t,i):t,s=e.length-1,u;s>=0;s--)(u=e[s])&&(n=(r?u(t,i,n):u(n))||n);return r&&n&&W(t,i,n),n};const Z=8,J=500;let f=class extends K{constructor(){super(...arguments),this.refocusOnClick=!0,this.onInput=()=>{},this.lastPointerFinishedAt=0}sendSoftKey(e,t){this.onInput(Y(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){const t=this.pointerStart;t?.pointerId===e.pointerId&&I(t,e)&&this.finishSoftKeyPointer()}onSoftKeyPointerUp(e,t){const i=this.pointerStart;i?.pointerId===e.pointerId&&(e.preventDefault(),this.finishSoftKeyPointer(),!(i.key.id!==t.id||I(i,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<J){e.preventDefault();return}this.sendSoftKey(t,{refocus:this.refocusOnClick})}render(){return l`
1
+ import{a as E,n as m,i as K,b as l,t as R,c as h,s as A,d as w,f as _,e as F,r as c}from"./index-D4dbiKXF.js";import{D as S,o as T}from"./vendor-terminal-DjQ08hXu.js";import"./vendor-editor-core-B4Sq6exx.js";import"./vendor-editor-languages-DznYbTkJ.js";const P="pi-web.terminal.softKeys",N="(pointer: coarse), (max-width: 760px)";function z(e,t){return e??t}function V(e){if(e==="true")return!0;if(e==="false")return!1}function $(){return typeof window<"u"&&"matchMedia"in window?window.matchMedia(N):void 0}function M(e){return e?.matches===!0}function B(e=$()){return z(O(),M(e))}function H(){return O()!==void 0}function O(e=D()){if(e!==void 0)try{return V(e.getItem(P))}catch{return}}function j(e,t=D()){if(t!==void 0)try{t.setItem(P,String(e))}catch{}}function D(){if(!(typeof window>"u"))try{return window.localStorage}catch{return}}const U=[{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"}],d="\x1B",q="";function Y(e,t){switch(e){case"escape":return d;case"tab":return" ";case"ctrl-c":return p("c");case"ctrl-d":return p("d");case"ctrl-z":return p("z");case"ctrl-l":return p("l");case"ctrl-r":return p("r");case"ctrl-u":return p("u");case"ctrl-w":return p("w");case"arrow-left":return b("D",t);case"arrow-up":return b("A",t);case"arrow-down":return b("B",t);case"arrow-right":return b("C",t);case"home":return x("H",t);case"end":return x("F",t);case"page-up":return`${d}[5~`;case"page-down":return`${d}[6~`;case"delete":return`${d}[3~`;case"backspace":return q;case"meta-backward-word":return`${d}b`;case"meta-forward-word":return`${d}f`}}function p(e){return String.fromCharCode(e.toUpperCase().charCodeAt(0)-64)}function b(e,t){return t?.applicationCursorKeysMode===!0?`${d}O${e}`:`${d}[${e}`}function x(e,t){return t?.applicationCursorKeysMode===!0?`${d}O${e}`:`${d}[${e}`}var W=Object.defineProperty,X=Object.getOwnPropertyDescriptor,y=(e,t,i,r)=>{for(var n=r>1?void 0:r?X(t,i):t,a=e.length-1,u;a>=0;a--)(u=e[a])&&(n=(r?u(t,i,n):u(n))||n);return r&&n&&W(t,i,n),n};const J=8,Z=500;let f=class extends K{constructor(){super(...arguments),this.refocusOnClick=!0,this.onInput=()=>{},this.lastPointerFinishedAt=0}sendSoftKey(e,t){this.onInput(Y(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){const t=this.pointerStart;t?.pointerId===e.pointerId&&I(t,e)&&this.finishSoftKeyPointer()}onSoftKeyPointerUp(e,t){const i=this.pointerStart;i?.pointerId===e.pointerId&&(e.preventDefault(),this.finishSoftKeyPointer(),!(i.key.id!==t.id||I(i,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<Z){e.preventDefault();return}this.sendSoftKey(t,{refocus:this.refocusOnClick})}render(){return l`
2
2
  <div class="terminal-soft-keys" role="toolbar" aria-label="Terminal soft keys">
3
3
  ${U.map(e=>l`
4
4
  <button
@@ -20,10 +20,10 @@ import{a as E,n as p,i as K,b as l,t as R,c as m,s as A,d as w,f as _,e as F,r a
20
20
  .terminal-soft-keys::-webkit-scrollbar { display: none; }
21
21
  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; }
22
22
  button:disabled { opacity: .5; cursor: not-allowed; }
23
- `;y([p({attribute:!1})],f.prototype,"modes",2);y([p({type:Boolean})],f.prototype,"refocusOnClick",2);y([p({attribute:!1})],f.prototype,"onInput",2);f=y([R("terminal-soft-keys")],f);function I(e,t){return Math.hypot(t.clientX-e.clientX,t.clientY-e.clientY)>Z}var G=Object.defineProperty,Q=Object.getOwnPropertyDescriptor,a=(e,t,i,r)=>{for(var n=r>1?void 0:r?Q(t,i):t,s=e.length-1,u;s>=0;s--)(u=e[s])&&(n=(r?u(t,i,n):u(n))||n);return r&&n&&G(t,i,n),n};const ee={cursorBlink:!0,convertEol:!0,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontSize:13},te={cols:100,rows:30},ie=1e3;let o=class extends K{constructor(){super(...arguments),this.autoStart=!1,this.onSelectTerminal=()=>{},this.terminals=[],this.commandRuns=[],this.loading=!1,this.visible=!1,this.cancellingRunIds=[],this.continuingTerminalIds=[],this.defaultSoftKeysEnvironment=!1,this.softKeysEnabled=B(),this.suppressTerminalInput=!1,this.softKeysDefaultEnvironmentMedia=$(),this.softKeysPreferenceStored=H(),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(){const e=M(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){const t=this.workspace?.path;if(t!==this.observedCwd){this.observedCwd=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(){const 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{const e=this.workspace;if(e===void 0)return;const t=this.consumeAutoStart(),[i,r]=await Promise.all([m.terminals(e.projectId,e.id),m.listCommandRuns({projectId:e.projectId,workspaceId:e.id})]);this.terminals=i,this.commandRuns=r,this.selectPreferredLoadedTerminal({replaceUrl:!0}),this.updateCommandRunPolling(this.hasPendingCommandRuns(r)),i.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(){const e=this.workspace?.path;return!this.autoStart||e===void 0||this.autoStartConsumedCwd===e?!1:(this.autoStartConsumedCwd=e,!0)}shouldReloadForRequestedTerminal(){const e=this.workspace?.path;return this.visible&&e!==void 0&&e===this.loadedCwd&&this.selectedTerminalId!==void 0&&!this.loading&&!this.terminals.some(t=>t.id===this.selectedTerminalId)}selectPreferredLoadedTerminal(e){let t=A(this.terminals,{targetTerminalId:this.selectedTerminalId});t===void 0&&this.selectedTerminalId!==void 0&&(t=w(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{const e=this.measureTerminalSize()??te,t=await m.startTerminal(this.workspace.projectId,this.workspace.id,e);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 m.closeTerminal(this.workspace.projectId,this.workspace.id,e);const i=this.terminals.filter(r=>r.id!==e);if(this.terminals=i,this.selectedId===e||this.selectedTerminalId===e){const r=w(i)?.id;this.selectTerminalIdInView(r),this.onSelectTerminal(r,{replace:!0})}}catch(i){this.error=i instanceof Error?i.message:String(i)}}selectTerminal(e){this.selectedId!==e&&this.selectTerminalIdInView(e),this.onSelectTerminal(e)}selectedTerminalInfo(){return this.terminals.find(e=>e.id===this.selectedId)}selectedCommandRun(){const e=this.selectedTerminalInfo()?.commandRunId;if(e!==void 0)return this.commandRuns.find(t=>t.id===e)}async loadCommandRuns(){const e=this.workspace;if(e!==void 0)try{const t=await m.listCommandRuns({projectId:e.projectId,workspaceId:e.id});this.commandRuns=t,this.cancellingRunIds=this.cancellingRunIds.filter(i=>t.some(r=>r.id===i&&v(r))),this.updateCommandRunPolling(this.hasPendingCommandRuns(t))}catch(t){this.error=t instanceof Error?t.message:String(t)}}updateCommandRunPolling(e){if(e&&this.commandRunPollTimer===void 0){this.commandRunPollTimer=window.setInterval(()=>{this.loadCommandRuns()},ie);return}!e&&this.commandRunPollTimer!==void 0&&(window.clearInterval(this.commandRunPollTimer),this.commandRunPollTimer=void 0)}hasPendingCommandRuns(e=this.commandRuns){return e.some(v)}async cancelCommandRun(e){if(!(!v(e)||this.cancellingRunIds.includes(e.id))){this.error=void 0,this.cancellingRunIds=[...this.cancellingRunIds,e.id];try{await m.cancelCommandRun(e.id),await this.loadCommandRuns()}catch(t){this.error=t instanceof Error?t.message:String(t)}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{const t=await m.continueTerminal(this.workspace.projectId,this.workspace.id,e);this.terminals=this.terminals.map(i=>i.id===e?t:i),this.socket===void 0&&this.disposeTerminalView(),this.fitAndNotify(),this.terminal?.focus()}catch(t){this.error=t instanceof Error?t.message:String(t)}finally{this.continuingTerminalIds=this.continuingTerminalIds.filter(t=>t!==e)}}}ensureTerminalView(){const e=this.workspace,t=this.terminalHostElement();if(!this.visible||this.terminal!==void 0||this.selectedId===void 0||t===void 0||e===void 0)return;const i=new T(C(this)),r=new S;i.loadAddon(r),i.open(t),this.terminal=i,this.fitAddon=r,this.resizeObserver=new ResizeObserver(()=>{this.fitAndNotify()}),this.resizeObserver.observe(t),i.onData(s=>{this.suppressTerminalInput||this.sendTerminalInput(s)});const n=this.fitTerminal();this.connectSocket(e.projectId,e.id,this.selectedId,i,n),requestAnimationFrame(()=>{this.fitAndNotify()}),i.focus()}connectSocket(e,t,i,r,n){const s=_(e,t,i,n);s.binaryType="arraybuffer",this.socket=s,s.addEventListener("open",()=>{this.fitAndNotify()}),s.addEventListener("message",u=>{this.handleSocketMessage(u.data,i,r)}),s.addEventListener("close",()=>{this.socket===s&&(this.socket=void 0)})}async handleSocketMessage(e,t,i){try{const r=ne(await se(e));r.type==="output"&&this.writeTerminalOutput(i,r.data,r.replay===!0),r.type==="exit"&&(i.writeln(`\r
23
+ `;y([m({attribute:!1})],f.prototype,"modes",2);y([m({type:Boolean})],f.prototype,"refocusOnClick",2);y([m({attribute:!1})],f.prototype,"onInput",2);f=y([R("terminal-soft-keys")],f);function I(e,t){return Math.hypot(t.clientX-e.clientX,t.clientY-e.clientY)>J}var G=Object.defineProperty,Q=Object.getOwnPropertyDescriptor,s=(e,t,i,r)=>{for(var n=r>1?void 0:r?Q(t,i):t,a=e.length-1,u;a>=0;a--)(u=e[a])&&(n=(r?u(t,i,n):u(n))||n);return r&&n&&G(t,i,n),n};const ee={cursorBlink:!0,convertEol:!0,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",fontSize:13},te={cols:100,rows:30},ie=1e3;let o=class extends K{constructor(){super(...arguments),this.machineId="local",this.autoStart=!1,this.onSelectTerminal=()=>{},this.terminals=[],this.commandRuns=[],this.loading=!1,this.visible=!1,this.cancellingRunIds=[],this.continuingTerminalIds=[],this.defaultSoftKeysEnvironment=!1,this.softKeysEnabled=B(),this.suppressTerminalInput=!1,this.softKeysDefaultEnvironmentMedia=$(),this.softKeysPreferenceStored=H(),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(){const e=M(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){const 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(){const 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{const e=this.workspace;if(e===void 0)return;const t=this.consumeAutoStart(),[i,r]=await Promise.all([h.terminals(e.projectId,e.id,this.machineId),h.listCommandRuns({projectId:e.projectId,workspaceId:e.id},this.machineId)]);this.terminals=i,this.commandRuns=r,this.selectPreferredLoadedTerminal({replaceUrl:!0}),this.updateCommandRunPolling(this.hasPendingCommandRuns(r)),i.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(){const e=this.workspace?.path;return!this.autoStart||e===void 0||this.autoStartConsumedCwd===e?!1:(this.autoStartConsumedCwd=e,!0)}shouldReloadForRequestedTerminal(){const e=this.workspace?.path;return this.visible&&e!==void 0&&e===this.loadedCwd&&this.selectedTerminalId!==void 0&&!this.loading&&!this.terminals.some(t=>t.id===this.selectedTerminalId)}selectPreferredLoadedTerminal(e){let t=A(this.terminals,{targetTerminalId:this.selectedTerminalId});t===void 0&&this.selectedTerminalId!==void 0&&(t=w(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{const e=this.measureTerminalSize()??te,t=await h.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 h.closeTerminal(this.workspace.projectId,this.workspace.id,e,this.machineId);const i=this.terminals.filter(r=>r.id!==e);if(this.terminals=i,this.selectedId===e||this.selectedTerminalId===e){const r=w(i)?.id;this.selectTerminalIdInView(r),this.onSelectTerminal(r,{replace:!0})}}catch(i){this.error=i instanceof Error?i.message:String(i)}}selectTerminal(e){this.selectedId!==e&&this.selectTerminalIdInView(e),this.onSelectTerminal(e)}selectedTerminalInfo(){return this.terminals.find(e=>e.id===this.selectedId)}selectedCommandRun(){const e=this.selectedTerminalInfo()?.commandRunId;if(e!==void 0)return this.commandRuns.find(t=>t.id===e)}async loadCommandRuns(){const e=this.workspace;if(e!==void 0)try{const t=await h.listCommandRuns({projectId:e.projectId,workspaceId:e.id},this.machineId);this.commandRuns=t,this.cancellingRunIds=this.cancellingRunIds.filter(i=>t.some(r=>r.id===i&&v(r))),this.updateCommandRunPolling(this.hasPendingCommandRuns(t))}catch(t){this.error=t instanceof Error?t.message:String(t)}}updateCommandRunPolling(e){if(e&&this.commandRunPollTimer===void 0){this.commandRunPollTimer=window.setInterval(()=>{this.loadCommandRuns()},ie);return}!e&&this.commandRunPollTimer!==void 0&&(window.clearInterval(this.commandRunPollTimer),this.commandRunPollTimer=void 0)}hasPendingCommandRuns(e=this.commandRuns){return e.some(v)}async cancelCommandRun(e){if(!(!v(e)||this.cancellingRunIds.includes(e.id))){this.error=void 0,this.cancellingRunIds=[...this.cancellingRunIds,e.id];try{await h.cancelCommandRun(e.id,this.machineId),await this.loadCommandRuns()}catch(t){this.error=t instanceof Error?t.message:String(t)}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{const t=await h.continueTerminal(this.workspace.projectId,this.workspace.id,e,this.machineId);this.terminals=this.terminals.map(i=>i.id===e?t:i),this.socket===void 0&&this.disposeTerminalView(),this.fitAndNotify(),this.terminal?.focus()}catch(t){this.error=t instanceof Error?t.message:String(t)}finally{this.continuingTerminalIds=this.continuingTerminalIds.filter(t=>t!==e)}}}ensureTerminalView(){const e=this.workspace,t=this.terminalHostElement();if(!this.visible||this.terminal!==void 0||this.selectedId===void 0||t===void 0||e===void 0)return;const i=new S(C(this)),r=new T;i.loadAddon(r),i.open(t),this.terminal=i,this.fitAddon=r,this.resizeObserver=new ResizeObserver(()=>{this.fitAndNotify()}),this.resizeObserver.observe(t),i.onData(a=>{this.suppressTerminalInput||this.sendTerminalInput(a)});const n=this.fitTerminal();this.connectSocket(e.projectId,e.id,this.selectedId,i,n),requestAnimationFrame(()=>{this.fitAndNotify()}),i.focus()}connectSocket(e,t,i,r,n){const a=_(e,t,i,n,this.machineId);a.binaryType="arraybuffer",this.socket=a,a.addEventListener("open",()=>{this.fitAndNotify()}),a.addEventListener("message",u=>{this.handleSocketMessage(u.data,i,r)}),a.addEventListener("close",()=>{this.socket===a&&(this.socket=void 0)})}async handleSocketMessage(e,t,i){try{const r=ne(await se(e));r.type==="output"&&this.writeTerminalOutput(i,r.data,r.replay===!0),r.type==="exit"&&(i.writeln(`\r
24
24
  [process exited${r.exitCode===void 0?"":` with code ${String(r.exitCode)}`}]`),this.terminals=this.terminals.map(n=>n.id===t?{...n,exited:!0,...r.exitCode===void 0?{}:{exitCode:r.exitCode}}:n),this.loadCommandRuns()),r.type==="error"&&i.writeln(`\r
25
25
  [terminal error: ${r.message}]`)}catch(r){i.writeln(`\r
26
- [terminal error: ${r instanceof Error?r.message:String(r)}]`)}}writeTerminalOutput(e,t,i){if(!i){e.write(t);return}this.suppressTerminalInput=!0,e.write(t,()=>{this.suppressTerminalInput=!1})}fitAndNotify(){const e=this.fitTerminal();e!==void 0&&this.send({type:"resize",...e})}fitTerminal(){if(this.fitAddon===void 0||this.terminal===void 0)return;const e=this.fitAddon.proposeDimensions(),t=k(e);if(t!==void 0)return this.fitAddon.fit(),t}measureTerminalSize(){const e=this.fitTerminal();if(e!==void 0)return e;const t=this.terminalHostElement();if(this.terminal!==void 0||t===void 0)return;const i=new T(C(this)),r=new S;i.loadAddon(r),i.open(t);const n=k(r.proposeDimensions());return i.dispose(),n}terminalHostElement(){const e=this.terminalHost;return e instanceof HTMLDivElement?e:void 0}applyTerminalTheme(){this.terminal!==void 0&&(this.terminal.options.theme=L(this))}sendTerminalInput(e){const t=oe(e);t!==""&&this.send({type:"input",data:t})}sendSoftKeyInput(e,t){this.sendTerminalInput(e),t.refocus&&this.focusTerminal()}focusTerminal(){const 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}renderCommandRunNotice(){const e=this.selectedCommandRun();if(e===void 0)return null;const t=this.selectedTerminalInfo();if(v(e)){const i=this.cancellingRunIds.includes(e.id);return l`
26
+ [terminal error: ${r instanceof Error?r.message:String(r)}]`)}}writeTerminalOutput(e,t,i){if(!i){e.write(t);return}this.suppressTerminalInput=!0,e.write(t,()=>{this.suppressTerminalInput=!1})}fitAndNotify(){const e=this.fitTerminal();e!==void 0&&this.send({type:"resize",...e})}fitTerminal(){if(this.fitAddon===void 0||this.terminal===void 0)return;const e=this.fitAddon.proposeDimensions(),t=k(e);if(t!==void 0)return this.fitAddon.fit(),t}measureTerminalSize(){const e=this.fitTerminal();if(e!==void 0)return e;const t=this.terminalHostElement();if(this.terminal!==void 0||t===void 0)return;const i=new S(C(this)),r=new T;i.loadAddon(r),i.open(t);const n=k(r.proposeDimensions());return i.dispose(),n}terminalHostElement(){const e=this.terminalHost;return e instanceof HTMLDivElement?e:void 0}applyTerminalTheme(){this.terminal!==void 0&&(this.terminal.options.theme=L(this))}sendTerminalInput(e){const t=oe(e);t!==""&&this.send({type:"input",data:t})}sendSoftKeyInput(e,t){this.sendTerminalInput(e),t.refocus&&this.focusTerminal()}focusTerminal(){const 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}renderCommandRunNotice(){const e=this.selectedCommandRun();if(e===void 0)return null;const t=this.selectedTerminalInfo();if(v(e)){const i=this.cancellingRunIds.includes(e.id);return l`
27
27
  <section class="command-run-notice running">
28
28
  <div>
29
29
  <strong>${e.title}</strong>
@@ -119,4 +119,4 @@ import{a as E,n as p,i as K,b as l,t as R,c as m,s as A,d as w,f as _,e as F,r a
119
119
  .error { flex: 0 0 auto; margin: 0; padding: 8px; color: var(--pi-danger); border-bottom: 1px solid var(--pi-border); background: var(--pi-surface); }
120
120
  .muted { margin: 10px; color: var(--pi-muted); }
121
121
  .xterm { height: 100%; }
122
- `;a([p({attribute:!1})],o.prototype,"workspace",2);a([p({attribute:!1})],o.prototype,"selectedTerminalId",2);a([p({type:Boolean})],o.prototype,"autoStart",2);a([p({attribute:!1})],o.prototype,"onSelectTerminal",2);a([F(".terminal-host")],o.prototype,"terminalHost",2);a([c()],o.prototype,"terminals",2);a([c()],o.prototype,"commandRuns",2);a([c()],o.prototype,"selectedId",2);a([c()],o.prototype,"loading",2);a([c()],o.prototype,"error",2);a([c()],o.prototype,"visible",2);a([c()],o.prototype,"cancellingRunIds",2);a([c()],o.prototype,"continuingTerminalIds",2);a([c()],o.prototype,"defaultSoftKeysEnvironment",2);a([c()],o.prototype,"softKeysEnabled",2);o=a([R("terminal-panel")],o);function v(e){return e.status==="queued"||e.status==="running"}function re(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 ne(e){const t=JSON.parse(e);if(!le(t))return{type:"error",message:"Invalid terminal message"};const i=t;return i.type==="output"&&typeof i.data=="string"?{type:"output",data:i.data,...typeof i.replay=="boolean"?{replay:i.replay}:{}}:i.type==="exit"?{type:"exit",...typeof i.exitCode=="number"?{exitCode:i.exitCode}:{}}:i.type==="error"&&typeof i.message=="string"?{type:"error",message:i.message}:{type:"error",message:"Invalid terminal message"}}function oe(e){return e.replaceAll("\x1B[I","").replaceAll("\x1B[O","")}async function se(e){return typeof e=="string"?e:e instanceof ArrayBuffer?new TextDecoder().decode(e):e instanceof Blob?await e.text():String(e)}function C(e){return{...ee,theme:L(e)}}function L(e){return{background:g(e,"--pi-terminal-bg","#05070a"),foreground:g(e,"--pi-terminal-text","#e6edf3"),cursor:g(e,"--pi-accent","#58a6ff"),selectionBackground:g(e,"--pi-terminal-selection","#264f78")}}function g(e,t,i){const r=getComputedStyle(e).getPropertyValue(t).trim();return r===""?i:r}function k(e){if(!(e===void 0||!ae(e.cols,e.rows)))return{cols:Math.floor(e.cols),rows:Math.floor(e.rows)}}function ae(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e>0&&t>0}function le(e){return typeof e=="object"&&e!==null}export{o as TerminalPanel,oe as filterTerminalInput};
122
+ `;s([m({attribute:!1})],o.prototype,"workspace",2);s([m()],o.prototype,"machineId",2);s([m({attribute:!1})],o.prototype,"selectedTerminalId",2);s([m({type:Boolean})],o.prototype,"autoStart",2);s([m({attribute:!1})],o.prototype,"onSelectTerminal",2);s([F(".terminal-host")],o.prototype,"terminalHost",2);s([c()],o.prototype,"terminals",2);s([c()],o.prototype,"commandRuns",2);s([c()],o.prototype,"selectedId",2);s([c()],o.prototype,"loading",2);s([c()],o.prototype,"error",2);s([c()],o.prototype,"visible",2);s([c()],o.prototype,"cancellingRunIds",2);s([c()],o.prototype,"continuingTerminalIds",2);s([c()],o.prototype,"defaultSoftKeysEnvironment",2);s([c()],o.prototype,"softKeysEnabled",2);o=s([R("terminal-panel")],o);function v(e){return e.status==="queued"||e.status==="running"}function re(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 ne(e){const t=JSON.parse(e);if(!le(t))return{type:"error",message:"Invalid terminal message"};const i=t;return i.type==="output"&&typeof i.data=="string"?{type:"output",data:i.data,...typeof i.replay=="boolean"?{replay:i.replay}:{}}:i.type==="exit"?{type:"exit",...typeof i.exitCode=="number"?{exitCode:i.exitCode}:{}}:i.type==="error"&&typeof i.message=="string"?{type:"error",message:i.message}:{type:"error",message:"Invalid terminal message"}}function oe(e){return e.replaceAll("\x1B[I","").replaceAll("\x1B[O","")}async function se(e){return typeof e=="string"?e:e instanceof ArrayBuffer?new TextDecoder().decode(e):e instanceof Blob?await e.text():String(e)}function C(e){return{...ee,theme:L(e)}}function L(e){return{background:g(e,"--pi-terminal-bg","#05070a"),foreground:g(e,"--pi-terminal-text","#e6edf3"),cursor:g(e,"--pi-accent","#58a6ff"),selectionBackground:g(e,"--pi-terminal-selection","#264f78")}}function g(e,t,i){const r=getComputedStyle(e).getPropertyValue(t).trim();return r===""?i:r}function k(e){if(!(e===void 0||!ae(e.cols,e.rows)))return{cols:Math.floor(e.cols),rows:Math.floor(e.rows)}}function ae(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e>0&&t>0}function le(e){return typeof e=="object"&&e!==null}export{o as TerminalPanel,oe as filterTerminalInput};