@jmfederico/pi-web 1.202606.7 → 1.202607.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +9 -3
  2. package/dist/client/assets/CodeViewer-tXF3UTsY.js +4 -0
  3. package/dist/client/assets/TerminalPanel-D_ihiWAt.js +187 -0
  4. package/dist/client/assets/UnifiedDiffViewer-BziirXBJ.js +39 -0
  5. package/dist/client/assets/index-Brfk1lwl.js +2950 -0
  6. package/dist/client/assets/vendor-editor-core-vUi74DnD.js +12 -0
  7. package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +46 -0
  8. package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
  9. package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
  10. package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
  11. package/dist/client/index.html +6 -3
  12. package/dist/docker/piWebDockerCommandPlan.js +211 -0
  13. package/dist/docker/piWebDockerCommandPlan.js.map +1 -0
  14. package/dist/pi-web-plugins/updates/pi-web-plugin.js +15 -5
  15. package/dist/pi-web-plugins/updates/updatesLogic.js +37 -5
  16. package/dist/piWebVersionReport.js +4 -0
  17. package/dist/piWebVersionReport.js.map +1 -1
  18. package/dist/plugin-api.d.ts +1 -1
  19. package/dist/server/app.js +16 -1
  20. package/dist/server/app.js.map +1 -1
  21. package/dist/server/browserMessageProjection.js +56 -0
  22. package/dist/server/browserMessageProjection.js.map +1 -0
  23. package/dist/server/configRoutes.js +108 -1
  24. package/dist/server/configRoutes.js.map +1 -1
  25. package/dist/server/machines/machineClient.js +19 -9
  26. package/dist/server/machines/machineClient.js.map +1 -1
  27. package/dist/server/machines/machineProxyRoutes.js +64 -11
  28. package/dist/server/machines/machineProxyRoutes.js.map +1 -1
  29. package/dist/server/machines/machineService.js +4 -26
  30. package/dist/server/machines/machineService.js.map +1 -1
  31. package/dist/server/piPackageRoutes.js +87 -0
  32. package/dist/server/piPackageRoutes.js.map +1 -0
  33. package/dist/server/piPackageService.js +69 -0
  34. package/dist/server/piPackageService.js.map +1 -0
  35. package/dist/server/piWebPluginService.js +43 -8
  36. package/dist/server/piWebPluginService.js.map +1 -1
  37. package/dist/server/piWebStatus.js +57 -0
  38. package/dist/server/piWebStatus.js.map +1 -1
  39. package/dist/server/realtime/sessionEventHub.js +2 -1
  40. package/dist/server/realtime/sessionEventHub.js.map +1 -1
  41. package/dist/server/sessions/builtinCommands.js +1 -1
  42. package/dist/server/sessions/builtinCommands.js.map +1 -1
  43. package/dist/server/sessions/piSessionService.js +503 -104
  44. package/dist/server/sessions/piSessionService.js.map +1 -1
  45. package/dist/server/sessions/sessionArchiveStore.js +51 -22
  46. package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
  47. package/dist/server/sessions/sessionCommandService.js +16 -0
  48. package/dist/server/sessions/sessionCommandService.js.map +1 -1
  49. package/dist/server/sessions/sessionNameGenerator.js +27 -44
  50. package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
  51. package/dist/server/sessions/sessionRoutes.js +38 -1
  52. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  53. package/dist/server/sessions/spawnSessionTool.js +9 -4
  54. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  55. package/dist/server/sessions/spawnSubsessionTool.js +22 -15
  56. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  57. package/dist/server/workspaces/fileSuggestions.js +7 -3
  58. package/dist/server/workspaces/fileSuggestions.js.map +1 -1
  59. package/dist/shared/activity.js +0 -15
  60. package/dist/shared/activity.js.map +1 -1
  61. package/dist/shared/apiTypes.d.ts +63 -1
  62. package/dist/shared/apiTypes.js +4 -0
  63. package/dist/shared/apiTypes.js.map +1 -1
  64. package/dist/shared/capabilities.js +28 -2
  65. package/dist/shared/capabilities.js.map +1 -1
  66. package/dist/shared/federatedRoutes.js +10 -0
  67. package/dist/shared/federatedRoutes.js.map +1 -1
  68. package/dist/shared/piWebStatusParsing.js +20 -8
  69. package/dist/shared/piWebStatusParsing.js.map +1 -1
  70. package/dist/shared/thinkingLevels.d.ts +1 -1
  71. package/dist/shared/thinkingLevels.js +1 -1
  72. package/dist/shared/thinkingLevels.js.map +1 -1
  73. package/docs/config.md +24 -13
  74. package/docs/plugins.md +28 -14
  75. package/package.json +35 -31
  76. package/dist/client/assets/CodeViewer-CQU9mJ74.js +0 -4
  77. package/dist/client/assets/TerminalPanel-DtfVBsqI.js +0 -126
  78. package/dist/client/assets/UnifiedDiffViewer-BZQQK99S.js +0 -34
  79. package/dist/client/assets/index-CbE7df66.js +0 -2742
  80. package/dist/client/assets/vendor-editor-core-C7aWiQy0.js +0 -12
  81. package/dist/client/assets/vendor-editor-languages-EW34FfVy.js +0 -26
  82. package/dist/client/assets/vendor-editor-legacy-B4QLsWF8.js +0 -1
  83. package/dist/client/assets/vendor-terminal-DDGTF8rc.css +0 -1
  84. package/dist/client/assets/vendor-terminal-DjQ08hXu.js +0 -16
package/README.md CHANGED
@@ -97,13 +97,19 @@ Read more: [Remote-first development](https://pi-web.dev/remote-first)
97
97
 
98
98
  ## Machines and fleets
99
99
 
100
- PI WEB can register other PI WEB runtimes as remote machines. One browser-facing PI WEB instance can proxy projects, files, git state, sessions, terminals, and activity from trusted remote machines.
100
+ PI WEB can register other PI WEB runtimes as remote machines. One browser-facing PI WEB instance can proxy projects, files, git state, sessions, terminals, activity, Pi package management, and selected-machine settings from trusted remote machines.
101
+
102
+ When a remote machine is selected, Settings tabs label their target. Pi packages, PI WEB plugin enablement, session daemon toggles, external file access, and upload defaults target the selected machine. Gateway/server settings such as host, port, allowed hosts, registered machines/tokens, and keyboard shortcuts stay local to the gateway/browser.
101
103
 
102
104
  Read more: [Fleet and machines guide](https://pi-web.dev/machines)
103
105
 
104
106
  ## Plugins
105
107
 
106
- PI WEB supports trusted local browser-side plugins that can add actions, workspace panels, and workspace metadata.
108
+ PI WEB supports trusted browser-side PI WEB plugins that can add actions, workspace panels, and workspace metadata.
109
+
110
+ Pi packages are managed separately through Pi's package manager or **Settings → Pi packages**. In a federated setup, the Pi packages panel targets the selected machine and labels where installs, updates, or removals will run. Use **Settings → PI WEB plugins** to enable or disable discovered browser plugins on the selected machine.
111
+
112
+ After installing, updating, or removing a Pi package, type `/reload` in each idle PI WEB session on that machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files. Reload the browser page separately for newly discovered or changed PI WEB plugins.
107
113
 
108
114
  Read more: [Plugin API](https://pi-web.dev/plugins)
109
115
 
@@ -122,7 +128,7 @@ Project-local PI WEB config lives at:
122
128
  <project>/.pi-web/config.json
123
129
  ```
124
130
 
125
- Common configuration includes host/port, path access, uploads, plugins, shortcuts, and session daemon options.
131
+ Common configuration includes host/port, path access, uploads, PI WEB plugin enablement, shortcuts, and session daemon options. In Settings, machine-affecting config targets the selected machine; gateway host/port/allowed-hosts, remote machine registration, tokens, and keyboard shortcuts stay local.
126
132
 
127
133
  Read more: [Configuration reference](https://pi-web.dev/config)
128
134
 
@@ -0,0 +1,4 @@
1
+ import{$ as e,J as t,P as n,S as r,Y as i,l as a,q as o,y as s}from"./vendor-editor-core-vUi74DnD.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-DoaXUodB.js";import{_ as g,a as _,f as v,g as y,m as b,p as x,u as S}from"./index-Brfk1lwl.js";import{t as C}from"./vendor-editor-legacy-CYBnW6ZU.js";var w=class extends b{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 y`<div class="host"></div>`}recreateEditor(){this.editorHost&&(this.view?.destroy(),this.view=new o({parent:this.editorHost,state:e.create({doc:this.content,extensions:[i(),t.of(a),n(r,{fallback:!0}),e.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
+ `}};_([v()],w.prototype,`content`,void 0),_([v()],w.prototype,`language`,void 0),_([S(`.host`)],w.prototype,`editorHost`,void 0),w=_([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};
@@ -0,0 +1,187 @@
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 ee,t as te,u as m}from"./index-Brfk1lwl.js";import{n as h,t as g}from"./vendor-terminal-D8k4UKM2.js";var ne=`important`,re=` !important`,_=u(class extends p{constructor(e){if(super(e),e.type!==s.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(re);e.includes(`-`)||t?n.setProperty(e,t?r.slice(0,-11):r,t?ne:``):n[e]=r}}return o}}),ie=`#ffffff`,ae=`#000000`,v=[`#2e3436`,`#cc0000`,`#4e9a06`,`#c4a000`,`#3465a4`,`#75507b`,`#06989a`,`#d3d7cf`,`#555753`,`#ef2929`,`#8ae234`,`#fce94f`,`#729fcf`,`#ad7fa8`,`#34e2e2`,`#eeeeec`],y=[`black`,`red`,`green`,`yellow`,`blue`,`magenta`,`cyan`,`white`,`brightBlack`,`brightRed`,`brightGreen`,`brightYellow`,`brightBlue`,`brightMagenta`,`brightCyan`,`brightWhite`],b={black:v[0],red:v[1],green:v[2],yellow:v[3],blue:v[4],magenta:v[5],cyan:v[6],white:v[7],brightBlack:v[8],brightRed:v[9],brightGreen:v[10],brightYellow:v[11],brightBlue:v[12],brightMagenta:v[13],brightCyan:v[14],brightWhite:v[15]};function x(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??ie,o=n.theme?.background??ae,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=S(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,oe(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 S(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:T(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:C(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 C(e,t){let n=e.isInverse()!==0,r=w(e,`foreground`,t),i=w(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 w(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 T(e){return{foreground:e.foreground,background:e.background,bold:!1,italic:!1,dim:!1,underline:!1,invisible:!1,strikethrough:!1,overline:!1}}function oe(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=[...v];for(let n=0;n<y.length;n+=1){let r=y[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
+ `}};t([i({attribute:!1})],U.prototype,`modes`,void 0),t([i({type:Boolean})],U.prototype,`refocusOnClick`,void 0),t([i({attribute:!1})],U.prototype,`onInput`,void 0),U=t([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=ee(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 h(X(this)),r=new g;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 h(X(this)),r=new g;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=x(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 te(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=${_(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
+ `}};t([i({attribute:!1})],G.prototype,`workspace`,void 0),t([i()],G.prototype,`machineId`,void 0),t([i({attribute:!1})],G.prototype,`selectedTerminalId`,void 0),t([i({type:Boolean})],G.prototype,`autoStart`,void 0),t([i({attribute:!1})],G.prototype,`onSelectTerminal`,void 0),t([m(`.terminal-host`)],G.prototype,`terminalHost`,void 0),t([m(`.terminal-copy-content`)],G.prototype,`terminalCopyContent`,void 0),t([m(`.terminal-copy-selector`)],G.prototype,`terminalCopySelector`,void 0),t([r()],G.prototype,`terminals`,void 0),t([r()],G.prototype,`commandRuns`,void 0),t([r()],G.prototype,`selectedId`,void 0),t([r()],G.prototype,`loading`,void 0),t([r()],G.prototype,`error`,void 0),t([r()],G.prototype,`visible`,void 0),t([r()],G.prototype,`cancellingRunIds`,void 0),t([r()],G.prototype,`continuingTerminalIds`,void 0),t([r()],G.prototype,`defaultSoftKeysEnvironment`,void 0),t([r()],G.prototype,`softKeysEnabled`,void 0),t([r()],G.prototype,`copySnapshot`,void 0),t([r()],G.prototype,`copyStatus`,void 0),G=t([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{...b,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};
@@ -0,0 +1,39 @@
1
+ import{_ as e,a as t,f as n,g as r,m as i,p as a}from"./index-Brfk1lwl.js";var o=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r){setTimeout(function(){r(e)},0);return}else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,h=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let h=c&&c.oldPos+1<o;if(!u&&!h){d[r]=void 0;continue}if(s=!h||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);h()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=h();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}},s=new class extends o{};function c(e,t,n){return s.diff(e,t,n)}function l(e,t){let n;for(n=0;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function u(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function d(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function f(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function p(e,t){return d(e,t,``)}function m(e,t){return f(e,t,``)}function h(e,t){return t.slice(0,g(e,t))}function g(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function _(e,t){let n=[];for(let r of Array.from(t.segment(e))){let e=r.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}return n}function v(e,t){if(t)return b(e,t)[1];let n;for(n=e.length-1;n>=0&&e[n].match(/\s/);n--);return e.substring(n+1)}function y(e,t){if(t)return b(e,t)[0];let n=e.match(/^\s*/);return n?n[0]:``}function b(e,t){if(!t)return[y(e),v(e)];if(t.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);let n=_(e,t),r=n[0],i=n[n.length-1];return[/\s/.test(r)?r:``,/\s/.test(i)?i:``]}var x=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,S=RegExp(`[${x}]+|\\s+|[^${x}]`,`ug`);new class extends o{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=_(e,r)}else n=e.match(S)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&C(n,i,r,e,t.intlSegmenter),n=e,r=null,i=null)}),(r||i)&&C(n,i,r,null,t.intlSegmenter),e}};function C(e,t,n,r,i){if(t&&n){let[a,o]=b(t.value,i),[s,c]=b(n.value,i);if(e){let r=l(a,s);e.value=f(e.value,s,r),t.value=p(t.value,r),n.value=p(n.value,r)}if(r){let e=u(o,c);r.value=d(r.value,c,e),t.value=m(t.value,e),n.value=m(n.value,e)}}else if(n){if(e){let e=y(n.value,i);n.value=n.value.substring(e.length)}if(r){let e=y(r.value,i);r.value=r.value.substring(e.length)}}else if(e&&r){let n=y(r.value,i),[a,o]=b(t.value,i),s=l(n,a);t.value=p(t.value,s);let c=u(p(n,s),o);t.value=m(t.value,c),r.value=d(r.value,n,c),e.value=f(e.value,n,n.slice(0,n.length-c.length))}else if(r){let e=y(r.value,i),n=h(v(t.value,i),e);t.value=m(t.value,n)}else if(e){let n=h(v(e.value,i),y(t.value,i));t.value=p(t.value,n)}}new class extends o{tokenize(e){let t=RegExp(`(\\r?\\n)|[${x}]+|[^\\S\\n\\r]+|[^${x}]`,`ug`);return e.match(t)||[]}},new class extends o{constructor(){super(...arguments),this.tokenize=w}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
2
+ `))&&(e=e.trim()),(!n.newlineIsToken||!t.includes(`
3
+ `))&&(t=t.trim())):n.ignoreNewlineAtEof&&!n.newlineIsToken&&(e.endsWith(`
4
+ `)&&(e=e.slice(0,-1)),t.endsWith(`
5
+ `)&&(t=t.slice(0,-1))),super.equals(e,t,n)}};function w(e,t){t.stripTrailingCr&&(e=e.replace(/\r\n/g,`
6
+ `));let n=[],r=e.split(/(\n|\r\n)/);r[r.length-1]||r.pop();for(let e=0;e<r.length;e++){let i=r[e];e%2&&!t.newlineIsToken?n[n.length-1]+=i:n.push(i)}return n}function T(e){return e==`.`||e==`!`||e==`?`}new class extends o{tokenize(e){let t=[],n=0;for(let r=0;r<e.length;r++){if(r==e.length-1){t.push(e.slice(n));break}if(T(e[r])&&e[r+1].match(/\s/)){for(t.push(e.slice(n,r+1)),r=n=r+1;e[r+1]?.match(/\s/);)r++;t.push(e.slice(n,r+1)),n=r+1}}return t}},new class extends o{tokenize(e){return e.split(/([{}:;,]|\s+)/)}},new class extends o{constructor(){super(...arguments),this.tokenize=w}get useLongestToken(){return!0}castInput(e,t){let{undefinedReplacement:n,stringifyReplacer:r=(e,t)=>t===void 0?n:t}=t;return typeof e==`string`?e:JSON.stringify(E(e,null,null,r),null,` `)}equals(e,t,n){return super.equals(e.replace(/,([\r\n])/g,`$1`),t.replace(/,([\r\n])/g,`$1`),n)}};function E(e,t,n,r,i){t||=[],n||=[],r&&(e=r(i===void 0?``:i,e));let a;for(a=0;a<t.length;a+=1)if(t[a]===e)return n[a];let o;if(Object.prototype.toString.call(e)===`[object Array]`){for(t.push(e),o=Array(e.length),n.push(o),a=0;a<e.length;a+=1)o[a]=E(e[a],t,n,r,String(a));return t.pop(),n.pop(),o}if(e&&e.toJSON&&(e=e.toJSON()),typeof e==`object`&&e){t.push(e),o={},n.push(o);let i=[],s;for(s in e)Object.prototype.hasOwnProperty.call(e,s)&&i.push(s);for(i.sort(),a=0;a<i.length;a+=1)s=i[a],o[s]=E(e[s],t,n,r,s);t.pop(),n.pop()}else o=e;return o}new class extends o{tokenize(e){return e.slice()}join(e){return e}removeEmpty(e){return e}};var D=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/,O=5e3,k=20,A=.2,j=.25;function M(e){let t=N(e);return I(t),t}function N(e){let t=P(e),n=[],r,i;for(let e of t){let t=D.exec(e);if(t!==null){r=Number(t[1]),i=Number(t[2]),n.push(F(`hunk`,``,e));continue}if(r!==void 0&&i!==void 0){if(e.startsWith(`+`)){n.push(F(`add`,`+`,e.slice(1),{newLineNumber:i})),i++;continue}if(e.startsWith(`-`)){n.push(F(`remove`,`-`,e.slice(1),{oldLineNumber:r})),r++;continue}if(e.startsWith(` `)){n.push(F(`context`,` `,e.slice(1),{oldLineNumber:r,newLineNumber:i})),r++,i++;continue}if(e.startsWith(`\\`)){n.push(F(`marker`,``,e));continue}}r=void 0,i=void 0,n.push(F(`meta`,``,e))}return n}function P(e){if(e===``)return[];let t=e.replace(/\r\n/g,`
7
+ `).replace(/\r/g,`
8
+ `).split(`
9
+ `);return t.at(-1)===``&&t.pop(),t}function F(e,t,n,r={}){return{kind:e,prefix:t,text:n,spans:n===``?[]:[{text:n,changed:!1}],...r}}function I(e){let t=0;for(;t<e.length;){if(e[t]?.kind!==`remove`){t++;continue}let n=t;for(;e[t]?.kind===`remove`;)t++;let r=t;for(;e[t]?.kind===`add`;)t++;r!==t&&L(e.slice(n,r),e.slice(r,t))}}function L(e,t){if(!(e.length+t.length>k))for(let n of R(e,t)){let e=U(n.removed.text,n.added.text);e!==void 0&&(n.removed.spans=e.removed,n.added.spans=e.added)}}function R(e,t){if(e.length===t.length)return e.map((e,n)=>({removed:e,added:t[n]})).filter(z);if(e.length===1)return B(e[0],t);if(t.length===1)return V(e,t[0]);let n=[],r=Math.min(e.length,t.length);for(let i=0;i<r;i++){let r=e[i],a=t[i];r===void 0||a===void 0||W(r.text,a.text)>=j&&n.push({removed:r,added:a})}return n}function z(e){return e.added!==void 0}function B(e,t){if(e===void 0)return[];let n=H(e.text,t);return n===void 0?[]:[{removed:e,added:n}]}function V(e,t){if(t===void 0)return[];let n=H(t.text,e);return n===void 0?[]:[{removed:n,added:t}]}function H(e,t){let n,r=j;for(let i of t){let t=W(e,i.text);t<=r||(n=i,r=t)}return n}function U(e,t){if(e===t||e.length>O||t.length>O)return;let n=c(e,t),r=G(n,e,t);if(Math.max(e.length,t.length)>=20&&r<A)return;let i=[],a=[];for(let e of n)e.value!==``&&(e.added?a.push({text:e.value,changed:!0}):e.removed?i.push({text:e.value,changed:!0}):(i.push({text:e.value,changed:!1}),a.push({text:e.value,changed:!1})));if(!(!i.some(e=>e.changed)&&!a.some(e=>e.changed)))return{removed:K(i),added:K(a)}}function W(e,t){return e===t?1:e.length>O||t.length>O?0:G(c(e,t),e,t)}function G(e,t,n){let r=Math.max(t.length,n.length);return r===0?1:e.reduce((e,t)=>t.added||t.removed?e:e+t.value.length,0)/r}function K(e){let t=[];for(let n of e){let e=t[t.length-1];e?.changed===n.changed?e.text+=n.text:t.push({...n})}return t}var q=class extends i{constructor(...e){super(...e),this.diff=``}render(){let e=M(this.diff);return e.length===0?r`<p class="empty">No diff.</p>`:r`
10
+ <div class="scroller">
11
+ <div class="diff-grid" role="table" aria-label="Unified diff">
12
+ ${e.map(e=>this.renderLine(e))}
13
+ </div>
14
+ </div>
15
+ `}renderLine(e){let t=e.kind;return r`
16
+ <div class="line" role="row">
17
+ <span class=${`cell line-number old ${t}`} role="cell">${Y(e.oldLineNumber)}</span>
18
+ <span class=${`cell line-number new ${t}`} role="cell">${Y(e.newLineNumber)}</span>
19
+ <span class=${`cell prefix ${t}`} role="cell">${e.prefix}</span>
20
+ <span class=${`cell content ${t}`} role="cell">${J(e.spans)}</span>
21
+ </div>
22
+ `}static{this.styles=e`
23
+ :host { display: block; min-height: 0; height: 100%; color: var(--pi-text); background: var(--pi-bg); }
24
+ .empty { box-sizing: border-box; margin: 0; padding: 10px; color: var(--pi-muted); }
25
+ .scroller { height: 100%; min-height: 0; overflow: auto; background: var(--pi-bg); }
26
+ .diff-grid { display: grid; grid-template-columns: max-content max-content 2ch max-content; width: max-content; min-width: 100%; padding: 6px 0; font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; line-height: 1.45; }
27
+ .line { display: contents; }
28
+ .cell { min-height: 1.45em; white-space: pre; }
29
+ .line-number { min-width: 4ch; padding: 0 8px; border-right: 1px solid var(--pi-border-muted); color: var(--pi-dim); text-align: right; user-select: none; }
30
+ .prefix { padding: 0 4px; color: var(--pi-dim); text-align: center; user-select: none; }
31
+ .content { padding: 0 12px 0 4px; }
32
+ .meta { color: var(--pi-dim); }
33
+ .hunk { background: color-mix(in srgb, var(--pi-accent) 9%, transparent); color: var(--pi-accent); }
34
+ .add { background: color-mix(in srgb, var(--pi-success) 12%, transparent); }
35
+ .remove { background: color-mix(in srgb, var(--pi-danger) 12%, transparent); }
36
+ .marker { color: var(--pi-dim); }
37
+ .content.add .inline-change { border-radius: 2px; background: color-mix(in srgb, var(--pi-success) 36%, transparent); color: var(--pi-text); }
38
+ .content.remove .inline-change { border-radius: 2px; background: color-mix(in srgb, var(--pi-danger) 36%, transparent); color: var(--pi-text); }
39
+ `}};t([n()],q.prototype,`diff`,void 0),q=t([a(`unified-diff-viewer`)],q);function J(e){return e.map(e=>r`<span class=${e.changed?`inline-change`:``}>${e.text}</span>`)}function Y(e){return e===void 0?``:String(e)}export{q as UnifiedDiffViewer};