@schlenkr/ragents 0.1.9 → 0.1.10

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 (82) hide show
  1. package/apps/server/package.json +1 -1
  2. package/apps/server/src/access-projection.ts +6 -36
  3. package/apps/server/src/api/contracts.ts +5 -2
  4. package/apps/server/src/api/core-methods.ts +5 -3
  5. package/apps/server/src/config-file.ts +1 -1
  6. package/apps/server/src/host-api.json +2 -0
  7. package/apps/server/src/plugin-support/process-sandbox.ts +16 -15
  8. package/apps/server/src/provider.ts +2 -2
  9. package/apps/server/src/ragents/engine.ts +2 -1
  10. package/apps/server/src/ragents/global-chat.ts +7 -1
  11. package/apps/server/src/server.ts +3 -1
  12. package/apps/web/dist/assets/{highlighted-body-KPVGNVTW-xXXhTDbh.js → highlighted-body-KPVGNVTW-BO4wLQtE.js} +1 -1
  13. package/apps/web/dist/assets/main-DnnqWHkH.js +11 -0
  14. package/apps/web/dist/assets/mermaid-HWGCJPDP-BLLeth5_.js +568 -0
  15. package/apps/web/dist/assets/{runPanel-ZT6TPDLM.js → runPanel-DPm7s3KM.js} +2 -2
  16. package/apps/web/dist/help/guide-clients.html +17 -7
  17. package/apps/web/dist/help/guide-clients.md +18 -7
  18. package/apps/web/dist/help/index.html +1911 -908
  19. package/apps/web/dist/help/mini-app.css +24 -0
  20. package/apps/web/dist/host-web.json +2 -2
  21. package/apps/web/dist/index.html +2 -2
  22. package/apps/web/dist/run-panel.html +2 -2
  23. package/apps/web/package.json +1 -1
  24. package/apps/web/src/panel/ConnectionsPage.tsx +3 -0
  25. package/apps/web/src/panel/StartPage.tsx +3 -0
  26. package/apps/web/src/panel/contract.ts +7 -0
  27. package/bundles/ragents.activity/ragents-bundle.json +1 -1
  28. package/bundles/ragents.actor-programs/ragents-bundle.json +2 -2
  29. package/bundles/ragents.actor-programs/server/index.js +31 -3
  30. package/bundles/ragents.actor-programs/server/index.js.map +4 -4
  31. package/bundles/ragents.actor-programs/web/index.js.map +1 -1
  32. package/bundles/ragents.ask/ragents-bundle.json +2 -4
  33. package/bundles/ragents.ask/web/chunks/{chunk-V7W3QDVS.js → chunk-MBRPS477.js} +2 -2
  34. package/bundles/ragents.ask/web/chunks/{chunk-V7W3QDVS.js.map → chunk-MBRPS477.js.map} +4 -4
  35. package/bundles/ragents.ask/web/classes.json +1 -1
  36. package/bundles/ragents.ask/web/exports/web/QuestionCard.js +1 -1
  37. package/bundles/ragents.ask/web/index.js +1 -1
  38. package/bundles/ragents.ask/web/index.js.map +4 -4
  39. package/bundles/ragents.browser/ragents-bundle.json +1 -1
  40. package/bundles/ragents.documents/ragents-bundle.json +1 -1
  41. package/bundles/ragents.lsp-fsharp/ragents-bundle.json +1 -1
  42. package/bundles/ragents.lsp-roslyn/ragents-bundle.json +1 -1
  43. package/bundles/ragents.lsp-typescript/ragents-bundle.json +1 -1
  44. package/bundles/ragents.model-relay/ragents-bundle.json +1 -1
  45. package/bundles/ragents.orchestration/ragents-bundle.json +2 -2
  46. package/bundles/ragents.orchestration/web/classes.json +1 -1
  47. package/bundles/ragents.orchestration/web/index.js +6 -6
  48. package/bundles/ragents.orchestration/web/index.js.map +3 -3
  49. package/bundles/ragents.overseer/ragents-bundle.json +2 -2
  50. package/bundles/ragents.overseer/server/index.js +1 -1
  51. package/bundles/ragents.overseer/server/index.js.map +2 -2
  52. package/bundles/ragents.processes/ragents-bundle.json +1 -1
  53. package/bundles/ragents.product/ragents-bundle.json +1 -1
  54. package/bundles/ragents.profile-distribution/ragents-bundle.json +1 -1
  55. package/bundles/ragents.reference/ragents-bundle.json +1 -1
  56. package/bundles/ragents.todo/ragents-bundle.json +1 -1
  57. package/bundles/ragents.transcript/ragents-bundle.json +1 -1
  58. package/bundles/ragents.watch/ragents-bundle.json +1 -1
  59. package/bundles/ragents.workspace/ragents-bundle.json +2 -2
  60. package/bundles/ragents.workspace/server/index.js +4 -2
  61. package/bundles/ragents.workspace/server/index.js.map +2 -2
  62. package/package.json +3 -3
  63. package/packages/agent/dist/core/tools/bash.d.ts +1 -1
  64. package/packages/agent/src/core/tools/bash.ts +1 -1
  65. package/packages/ragents/src/index.ts +1 -0
  66. package/packages/ragents/src/plugin-host.ts +46 -0
  67. package/packages/ragents/src/plugin-types.ts +19 -0
  68. package/packages/workspace-executor/src/managed-process.ts +28 -0
  69. package/packages/workspace-executor/src/sandbox-tools.ts +9 -3
  70. package/plugins/ragents.actor-programs/server/access-projections.ts +31 -0
  71. package/plugins/ragents.actor-programs/server/index.ts +2 -0
  72. package/plugins/ragents.ask/web/index.tsx +0 -6
  73. package/plugins/ragents.orchestration/web/ActorTile.tsx +1 -1
  74. package/plugins/ragents.orchestration/web/run-panel/RunPanel.tsx +8 -7
  75. package/plugins/ragents.orchestration/web/run-panel/sheet-status.ts +3 -3
  76. package/plugins/ragents.overseer/server/api.ts +2 -2
  77. package/plugins/ragents.workspace/client/workspace-client.ts +19 -6
  78. package/plugins/ragents.workspace/server/config.ts +3 -0
  79. package/plugins/ragents.workspace/server/index.ts +3 -2
  80. package/apps/web/dist/assets/main-C7JeZFjs.js +0 -6
  81. package/apps/web/dist/assets/mermaid-HWGCJPDP-DfsU5ofC.js +0 -478
  82. package/plugins/ragents.ask/web/QuestionSection.tsx +0 -48
@@ -1,4 +1,4 @@
1
- import{a as M,I as H,u as Z,r as i,j as e,B as y,J as De,K as Ae,w as ze,l as Fe,m as Te,v as _e,k as Me,P as He,H as ce,L as Ue,q as K,s as de,i as Be,N as ue,O as re,T as Ve,V as $e,A as ie,Y as qe,Z as Ke,_ as Ze,$ as Ge,t as Je,a0 as We,e as Qe,a1 as Ye,a2 as Xe,y as et,z as tt,a3 as nt,a4 as st,a5 as rt,F as it,Q as ot,a6 as at,a7 as lt,G as ct}from"./mermaid-HWGCJPDP-DfsU5ofC.js";/**
1
+ import{a as M,H,u as Z,r as i,j as e,B as y,I as De,J as Ae,v as ze,l as Fe,m as Te,t as _e,k as Me,P as He,G as ce,K as Ue,p as K,q as de,i as Be,L as ue,N as re,O as Ve,T as $e,A as ie,V as qe,Y as Ke,Z as Ze,_ as Ge,s as Je,$ as We,e as Qe,a0 as Ye,a1 as Xe,x as et,y as tt,a2 as nt,a3 as st,a4 as rt,z as it,Q as ot,a5 as at,a6 as lt,F as ct}from"./mermaid-HWGCJPDP-BLLeth5_.js";/**
2
2
  * @license lucide-react v1.46.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -18,4 +18,4 @@ import{a as M,I as H,u as Z,r as i,j as e,B as y,J as De,K as Ae,w as ze,l as Fe
18
18
  *
19
19
  * This source code is licensed under the ISC license.
20
20
  * See the LICENSE file in the root directory of this source tree.
21
- */const me={name:"log-out",size:24,node:[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]]};me.node;const ht=M(me),$="flex w-full cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 text-left hover:bg-accent focus-visible:outline-2 focus-visible:outline-ring/60 focus-visible:-outline-offset-2 disabled:cursor-default disabled:opacity-50 [&>svg]:size-4 [&>svg]:flex-none [&>svg]:text-muted-foreground";function q({onOpenSettings:t}){const o=H(),r=Z(),[s,a]=i.useState(!1),[l,c]=i.useState(!1),[f,x]=i.useState(),b=i.useRef(null),u=i.useId(),R=d=>{var S;return d.reason==="outside-press"&&d.event.target instanceof Node&&((S=b.current)==null?void 0:S.contains(d.event.target))===!0},E=()=>{if(o.kind==="vscode"){o.requestLogout(),a(!1);return}c(!0),x(void 0),r.logout().then(()=>a(!1)).catch(d=>x(d instanceof Error?d.message:String(d))).finally(()=>c(!1))};return e.jsxs(e.Fragment,{children:[e.jsx(y,{"aria-controls":s?u:void 0,"aria-expanded":s,"aria-haspopup":"dialog","aria-label":"Menü des Panels",className:"self-center",onClick:()=>a(d=>!d),ref:b,size:"icon-lg",title:"Menü",variant:"ghost",children:e.jsx(dt,{})}),e.jsx(De,{onOpenChange:(d,S)=>{!d&&R(S)||a(d)},open:s,children:e.jsxs(Ae,{align:"end",anchor:b,"aria-label":"Menü des Panels",className:"w-[220px] gap-0 p-1 text-[0.8rem]",collisionPadding:8,dim:!0,id:u,role:"dialog",side:"bottom",children:[e.jsxs("button",{className:$,onClick:()=>{a(!1),t()},type:"button",children:[e.jsx(ze,{}),"Einstellungen"]}),o.kind==="vscode"&&e.jsxs("button",{className:$,onClick:()=>{a(!1),o.openExternal(new URL("/",window.location.href).toString())},type:"button",children:[e.jsx(ut,{}),"Im Browser öffnen"]}),r.enabled&&r.user&&e.jsxs("button",{className:$,disabled:l,onClick:E,title:r.user.id,type:"button",children:[e.jsx(ht,{}),e.jsxs("span",{className:"grid min-w-0",children:[e.jsx("span",{children:"Abmelden"}),e.jsx("span",{className:"truncate text-[0.68rem] text-muted-foreground",children:r.user.label})]})]}),f&&e.jsx("p",{className:"px-2 py-1.5 text-[0.72rem] text-destructive",role:"alert",children:f})]})})]})}const xt=5e3;function pe(t){const[o,r]=i.useState([]),[s,a]=i.useState(!1),l=i.useRef(void 0),c=i.useRef(!1),f=i.useCallback(()=>{if(!t)return Promise.resolve();if(l.current)return c.current=!0,l.current;const x=async()=>{do{c.current=!1;try{r(await _e()),a(!1)}catch{a(!0)}}while(c.current)};return l.current=x().finally(()=>{l.current=void 0}),l.current},[t]);return i.useEffect(()=>{if(!t)return;f();const x=Fe.subscribe(Te.channels.runs,{},()=>void f()),b=setInterval(()=>void f(),xt);return()=>{x(),clearInterval(b)}},[t,f]),{sessions:o,unreachable:s,refresh:f}}const ge="relative z-[80] flex h-header flex-none items-stretch border-b border-border bg-shell shadow-bar",oe="max-w-[120px] self-center truncate rounded-full bg-secondary px-2 py-0.5 text-[0.66rem] font-semibold text-muted-foreground",mt="min-w-0 flex-1 self-center truncate px-1.5 text-[0.82rem] font-semibold",pt="Gestoppt im Run-Panel",gt=5e3,v="Neuer Run",vt="relative z-[80] flex h-header flex-none items-center gap-2 border-b border-border bg-shell px-3 shadow-bar",ve="m-auto max-w-[420px] p-6 text-center text-muted-foreground",wt=new Set,bt=()=>({id:crypto.randomUUID(),title:v,updatedAt:Date.now()}),we=(t,o="Run")=>({id:t,title:o,updatedAt:Date.now()}),St={kind:"working",title:"Profil wird geladen",detail:"Die Oberfläche des Servers wird geladen."},jt={kind:"working",title:"Run wird gestartet",detail:"Der neue Run wird angelegt."},ae={kind:"working",title:"Run wird gestartet",detail:"Die Vorlage wird gestartet."},kt={kind:"waiting",title:"Kein Run gewählt",detail:"Auf der Start-Seite startest Du einen neuen Run oder öffnest einen vorhandenen."},yt={kind:"error",title:"Keine Runs freigegeben",detail:"Für dieses Benutzerkonto sind keine Runs freigegeben."};function Rt({location:t}){const o=Me(),r=t.layout==="app";if(o.status==="loading")return e.jsx(w,{headless:r,state:St});if(o.status==="failed")return e.jsx(w,{headless:r,state:{kind:"error",title:"Das Profil konnte nicht geladen werden",detail:o.error},children:e.jsx(y,{onClick:()=>window.location.reload(),size:"sm",variant:"outline",children:"Neu laden"})});const s=t.layout==="app"?e.jsx(It,{elementId:t.elementId,registry:o.registry,runId:t.runId}):e.jsx(Et,{connection:t.connection,initialRunId:t.runId,registry:o.registry});return o.failures.length===0?s:e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsx(He,{failures:o.failures}),e.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:s})]})}function Et({connection:t,initialRunId:o,registry:r}){var se;const s=H(),a=Z(),l=a.can("runs.read"),c=l&&a.can("runs.write"),f=c&&a.can("runs.create"),x=f||c&&r.scriptEntries.some(n=>de(a,n.id)),b=Be((se=a.user)==null?void 0:se.id),[u,R]=i.useState(o),[E,d]=i.useState(),[S,I]=i.useState(),p=i.useCallback(()=>I(n=>n===u?void 0:n),[u]),[Se,G]=i.useState(),[h,N]=i.useState(),[D,J]=i.useState(),U=i.useRef(void 0),g=i.useCallback(n=>{U.current=n==null?void 0:n.runId,J(n)},[]),[W,B]=i.useState(),[P,Q]=i.useState(!1),[Y,X]=i.useState(),V=i.useCallback(()=>Q(!0),[]),{sessions:ee,unreachable:je,refresh:ke}=pe(l&&!h&&!D),[ye,Re]=i.useState(null),[Ee,Ne]=i.useState(null),O=i.useCallback((n,m)=>{var _;const j=(_=r.startEntries.find(Le=>Le.id===m))==null?void 0:_.fixedStartOptions;N({session:bt(),startOptions:n&&ue(n,j),entryId:m})},[r]),Ce=i.useCallback(()=>O(),[O]),L=i.useCallback((n,m)=>{N(void 0),g(void 0),G(m),R(n),I(s.kind==="vscode"?n:void 0)},[s.kind,g]),te=i.useCallback(n=>{N(void 0),g(n),Nt(n,r,a).then(()=>{U.current===n.runId&&L(n.runId)},m=>{U.current===n.runId&&J({...n,error:m instanceof Error?m.message:String(m)})})},[a,L,r,g]),Ie=i.useCallback(n=>{I(void 0),d(void 0),R(n)},[]),A=i.useCallback(()=>{I(void 0),N(void 0),g(void 0),B(void 0),s.kind==="vscode"?s.notify({type:"showStart"}):R(void 0)},[s,g]);i.useLayoutEffect(()=>{if(S){if(P||h){p();return}return window.addEventListener("pointerdown",p,!0),window.addEventListener("keydown",p,!0),window.addEventListener("blur",p),()=>{window.removeEventListener("pointerdown",p,!0),window.removeEventListener("keydown",p,!0),window.removeEventListener("blur",p)}}},[h,S,P,p]),i.useEffect(()=>s.onCommand(n=>{if(n.type==="selectRun"&&(I(void 0),N(void 0),g(void 0),B(void 0),G(void 0),d(void 0),R(n.runId??void 0)),n.type!=="newRun")return;if(s.kind!=="vscode"){x&&O(n.startOptions,n.entryId);return}const m=x?n.entryId===void 0&&!f?"Freie Runs sind für dieses Benutzerkonto nicht freigegeben.":void 0:"Neue Runs sind für dieses Benutzerkonto nicht freigegeben.";if(B(m),m!==void 0)return;const j=r.startEntries.find(_=>_.id===n.entryId);if(d((j==null?void 0:j.title)??v),n.entryId===void 0){L(crypto.randomUUID(),n.startOptions);return}if(j!==void 0&&r.guideFor(j)!==void 0){g(void 0),O(n.startOptions,j.id);return}te({runId:crypto.randomUUID(),entryId:n.entryId,startOptions:n.startOptions})}),[x,f,s,L,r,g,O,te]),i.useEffect(()=>{s.notify({type:"ready"})},[s]),i.useEffect(()=>{s.notify({type:"runChanged",runId:u??null})},[s,u]);const z=P&&e.jsx(Je,{onClose:()=>Q(!1),registry:r}),C=n=>e.jsxs(e.Fragment,{children:[e.jsx(y,{"aria-label":"Zur Start-Seite",className:"self-center",onClick:A,size:"icon-lg",title:"Zur Start-Seite",variant:"ghost",children:e.jsx(re,{})}),e.jsx("strong",{className:mt,children:n}),t&&e.jsx("span",{className:oe,title:`Server ${t}`,children:t}),e.jsx(q,{onOpenSettings:V})]}),F=e.jsx(y,{onClick:A,size:"sm",variant:"outline",children:"Zur Start-Seite"}),ne=h&&e.jsx(K,{initialStartOptions:h.startOptions,onStarted:()=>{L(h.session.id),d(n=>n??v),ke()},registry:r,session:h.session,startDialog:{onClose:s.kind==="vscode"?A:()=>N(void 0),initialEntryId:h.entryId}},h.session.id);if(D)return e.jsxs(e.Fragment,{children:[D.error===void 0?e.jsx(w,{header:C(E??v),state:ae}):e.jsx(w,{header:C(E??v),state:{kind:"error",title:"Der Run konnte nicht gestartet werden",detail:D.error},children:F}),z]});if(s.kind==="vscode"&&h)return e.jsxs(e.Fragment,{children:[e.jsx(w,{header:C(E??v),state:ae}),ne,z]});if(s.kind==="vscode"&&!(l&&u))return e.jsxs(e.Fragment,{children:[l?W!==void 0?e.jsx(w,{header:C(v),state:{kind:"error",title:"Kein neuer Run möglich",detail:W},children:F}):e.jsx(Ct,{header:C(v),children:F}):e.jsx(w,{header:C(v),state:yt,children:F}),z]});const T=ee.find(n=>n.id===u),Pe=()=>{u!==void 0&&(X(void 0),We(u,pt).catch(n=>X(`Stoppen fehlgeschlagen: ${n instanceof Error?n.message:String(n)}`)))},Oe=l?e.jsx(Qe,{activeId:u,onCreate:x?Ce:void 0,onSelect:Ie,onToggleSelected:()=>{},registry:r,seenRevisions:b.revisions,selectMode:!1,selectedIds:wt,sessions:ee}):e.jsx("p",{className:ve,children:"Für dieses Benutzerkonto sind keine Runs freigegeben."});return e.jsxs("div",{className:"flex h-full flex-col bg-[image:var(--surface-backdrop)]",children:[l&&u?e.jsxs(e.Fragment,{children:[e.jsxs("header",{className:ge,children:[e.jsx(y,{"aria-label":"Zur Start-Seite",className:"self-center",onClick:A,size:"icon-lg",title:"Zur Start-Seite",variant:"ghost",children:e.jsx(re,{})}),e.jsx("div",{"aria-label":"Run-Titelleiste",className:"flex min-w-0 flex-1 items-stretch overflow-x-auto no-scrollbar",ref:Re,role:"region"}),t&&e.jsx("span",{className:oe,title:`Server ${t}`,children:t}),e.jsx(Ve,{className:"self-center px-1.5",state:T!=null&&T.running?"running":"idle"}),e.jsx($e,{className:"self-center",disabled:!c,label:"Run stoppen",onClick:Pe,size:"icon-lg",title:"Run mit allen Agenten und Abläufen stoppen"}),e.jsx("div",{"aria-label":"Werkzeuge des Panels",className:"flex flex-none items-center empty:hidden",ref:Ne,role:"toolbar"}),e.jsx(q,{onOpenSettings:V})]}),Y&&e.jsx(ie,{variant:"destructive",children:Y}),e.jsx("main",{className:"relative z-1 flex min-h-0 min-w-0 flex-1 @container/chat-content",children:e.jsx(K,{autoFocusChat:S===u&&!P&&!h,onAutoFocusChatSettled:p,toolbarContainer:Ee,headerContainer:ye,initialStartOptions:Se,layout:"panel",onViewed:b.markViewed,registry:r,session:T??we(u,E),viewing:!h&&!P},u)})]}):e.jsxs(e.Fragment,{children:[e.jsxs("header",{className:vt,children:[e.jsx(ft,{"aria-hidden":!0,className:"size-4 flex-none text-muted-foreground"}),e.jsx("strong",{className:"min-w-0 flex-1 truncate text-[0.82rem] font-semibold",children:r.brand.title}),e.jsx(q,{onOpenSettings:V})]}),e.jsxs("div",{className:"min-h-0 flex-1 overflow-auto p-3",children:[je&&e.jsx(ie,{className:"mb-3",variant:"destructive",children:"Der Server ist nicht erreichbar."}),Oe]})]}),z,ne]})}async function Nt(t,o,r){const s=o.startEntries.find(a=>a.id===t.entryId);if(!s)throw new Error("Diese Vorlage gibt es in diesem Profil nicht.");if(!de(r,s.id))throw new Error(`${s.title} ist für dieses Benutzerkonto nicht freigegeben.`);if(t.startOptions){const a=await qe(t.runId),l=ue(t.startOptions,s.fixedStartOptions);for(const[c,f]of Ke(a,l))await Ze(t.runId,c,f)}await Ge(t.runId,s,null)}function Ct({children:t,header:o}){const[r,s]=i.useState(!1);return i.useEffect(()=>{const a=window.setTimeout(()=>s(!0),gt);return()=>window.clearTimeout(a)},[]),r?e.jsx(w,{header:o,state:kt,children:t}):e.jsx(w,{header:o,state:jt})}function w({children:t,header:o,headless:r=!1,state:s}){return e.jsxs("div",{className:"flex h-full flex-col bg-[image:var(--surface-backdrop)]",children:[!r&&e.jsx("header",{className:ge,children:o}),e.jsx("main",{className:"grid min-h-0 flex-1 place-items-center overflow-hidden p-6",children:e.jsx(Ue,{state:s,children:t})})]})}function It({elementId:t,registry:o,runId:r}){const s=H(),a=Z().can("runs.read"),{sessions:l}=pe(a);return i.useEffect(()=>{s.notify({type:"ready"})},[s]),a?e.jsx("main",{className:"relative flex h-full min-h-0 min-w-0 flex-1 bg-background @container/chat-content",children:e.jsx(K,{layout:{element:t},registry:o,session:l.find(c=>c.id===r)??we(r)},r)}):e.jsx("p",{className:ve,children:"Für dieses Benutzerkonto sind keine Runs freigegeben."})}function Pt(){const t=H();return e.jsxs(ce,{children:[e.jsx("h1",{className:"my-3 text-[1.5rem]",children:"Anmeldung erforderlich"}),e.jsx("p",{className:"mb-6 leading-normal text-muted-foreground",children:"Die Anmeldung läuft über VS Code. Danach lädt das Panel neu."}),e.jsx(y,{className:"w-full",onClick:()=>t.requestLogin(),children:"In VS Code anmelden"})]})}const k=t=>t!=null&&t.trim()?t.trim():void 0,Ot=t=>{if(t==="browser"||t==="vscode")return t;throw new Error(`Unbekannter Host ${JSON.stringify(t)}. Erlaubt sind browser und vscode.`)};function Lt(t){const o=new URLSearchParams(t),r=k(o.get("layout"))??"panel";if(r!=="panel"&&r!=="app")throw new Error(`Unbekanntes Layout ${JSON.stringify(r)}. Erlaubt sind panel und app.`);const s=k(o.get("theme"));if(s!==void 0&&!Ye(s))throw new Error(`Unbekannte Darstellung ${JSON.stringify(s)}. Erlaubt sind light und dark.`);const a={host:Ot(k(o.get("host"))??"browser"),connection:k(o.get("connection")),theme:s,access:k(o.get(Xe))},l=k(o.get("run"));if(r==="panel")return{layout:r,runId:l,...a};const c=k(o.get("element"));if(!l||!c)throw new Error("Das Layout app braucht run und element.");return{layout:r,runId:l,elementId:c,...a}}et();const be=document.getElementById("root");if(!be)throw new Error("Root-Element fehlt");const le=tt.createRoot(be);try{const t=Lt(window.location.search);t.access!==void 0&&nt(t.access);const o=st(t.host,window);if(t.host==="vscode"){const s=rt(window)}const r=it(window);t.theme!==void 0&&r.setPreference(t.theme),o.onCommand(s=>{s.type==="theme"&&r.setPreference(s.theme)}),le.render(e.jsx(i.StrictMode,{children:e.jsx(ot,{children:e.jsx(at,{value:o,children:e.jsx(lt,{value:t.host==="vscode"?{open:o.openPage}:void 0,children:e.jsx(ct,{Login:t.host==="vscode"?Pt:void 0,children:e.jsx(Rt,{location:t})})})})})}))}catch(t){le.render(e.jsxs(ce,{children:[e.jsx("h1",{className:"my-3 text-[1.5rem]",children:"Das RAgents-Panel konnte nicht geladen werden"}),e.jsx("p",{className:"mb-6 leading-normal",role:"alert",children:t instanceof Error?t.message:String(t)}),e.jsx(y,{onClick:()=>window.location.reload(),variant:"outline",children:"Erneut laden"})]}))}
21
+ */const pe={name:"log-out",size:24,node:[["path",{d:"m16 17 5-5-5-5",key:"1bji2h"}],["path",{d:"M21 12H9",key:"dn1m92"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}]]};pe.node;const ht=M(pe),$="flex w-full cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 text-left hover:bg-accent focus-visible:outline-2 focus-visible:outline-ring/60 focus-visible:-outline-offset-2 disabled:cursor-default disabled:opacity-50 [&>svg]:size-4 [&>svg]:flex-none [&>svg]:text-muted-foreground";function q({onOpenSettings:t}){const o=H(),r=Z(),[s,a]=i.useState(!1),[l,c]=i.useState(!1),[f,x]=i.useState(),b=i.useRef(null),u=i.useId(),R=d=>{var S;return d.reason==="outside-press"&&d.event.target instanceof Node&&((S=b.current)==null?void 0:S.contains(d.event.target))===!0},E=()=>{if(o.kind==="vscode"){o.requestLogout(),a(!1);return}c(!0),x(void 0),r.logout().then(()=>a(!1)).catch(d=>x(d instanceof Error?d.message:String(d))).finally(()=>c(!1))};return e.jsxs(e.Fragment,{children:[e.jsx(y,{"aria-controls":s?u:void 0,"aria-expanded":s,"aria-haspopup":"dialog","aria-label":"Menü des Panels",className:"self-center",onClick:()=>a(d=>!d),ref:b,size:"icon-lg",title:"Menü",variant:"ghost",children:e.jsx(dt,{})}),e.jsx(De,{onOpenChange:(d,S)=>{!d&&R(S)||a(d)},open:s,children:e.jsxs(Ae,{align:"end",anchor:b,"aria-label":"Menü des Panels",className:"w-[220px] gap-0 p-1 text-[0.8rem]",collisionPadding:8,dim:!0,id:u,role:"dialog",side:"bottom",children:[e.jsxs("button",{className:$,onClick:()=>{a(!1),t()},type:"button",children:[e.jsx(ze,{}),"Einstellungen"]}),o.kind==="vscode"&&e.jsxs("button",{className:$,onClick:()=>{a(!1),o.openExternal(new URL("/",window.location.href).toString())},type:"button",children:[e.jsx(ut,{}),"Im Browser öffnen"]}),r.enabled&&r.user&&e.jsxs("button",{className:$,disabled:l,onClick:E,title:r.user.id,type:"button",children:[e.jsx(ht,{}),e.jsxs("span",{className:"grid min-w-0",children:[e.jsx("span",{children:"Abmelden"}),e.jsx("span",{className:"truncate text-[0.68rem] text-muted-foreground",children:r.user.label})]})]}),f&&e.jsx("p",{className:"px-2 py-1.5 text-[0.72rem] text-destructive",role:"alert",children:f})]})})]})}const xt=5e3;function me(t){const[o,r]=i.useState([]),[s,a]=i.useState(!1),l=i.useRef(void 0),c=i.useRef(!1),f=i.useCallback(()=>{if(!t)return Promise.resolve();if(l.current)return c.current=!0,l.current;const x=async()=>{do{c.current=!1;try{r(await _e()),a(!1)}catch{a(!0)}}while(c.current)};return l.current=x().finally(()=>{l.current=void 0}),l.current},[t]);return i.useEffect(()=>{if(!t)return;f();const x=Fe.subscribe(Te.channels.runs,{},()=>void f()),b=setInterval(()=>void f(),xt);return()=>{x(),clearInterval(b)}},[t,f]),{sessions:o,unreachable:s,refresh:f}}const ge="relative z-[80] flex h-header flex-none items-stretch border-b border-border bg-shell shadow-bar",oe="max-w-[120px] self-center truncate rounded-full bg-secondary px-2 py-0.5 text-[0.66rem] font-semibold text-muted-foreground",pt="min-w-0 flex-1 self-center truncate px-1.5 text-[0.82rem] font-semibold",mt="Gestoppt im Run-Panel",gt=5e3,v="Neuer Run",vt="relative z-[80] flex h-header flex-none items-center gap-2 border-b border-border bg-shell px-3 shadow-bar",ve="m-auto max-w-[420px] p-6 text-center text-muted-foreground",wt=new Set,bt=()=>({id:crypto.randomUUID(),title:v,updatedAt:Date.now()}),we=(t,o="Run")=>({id:t,title:o,updatedAt:Date.now()}),St={kind:"working",title:"Profil wird geladen",detail:"Die Oberfläche des Servers wird geladen."},jt={kind:"working",title:"Run wird gestartet",detail:"Der neue Run wird angelegt."},ae={kind:"working",title:"Run wird gestartet",detail:"Die Vorlage wird gestartet."},kt={kind:"waiting",title:"Kein Run gewählt",detail:"Auf der Start-Seite startest Du einen neuen Run oder öffnest einen vorhandenen."},yt={kind:"error",title:"Keine Runs freigegeben",detail:"Für dieses Benutzerkonto sind keine Runs freigegeben."};function Rt({location:t}){const o=Me(),r=t.layout==="app";if(o.status==="loading")return e.jsx(w,{headless:r,state:St});if(o.status==="failed")return e.jsx(w,{headless:r,state:{kind:"error",title:"Das Profil konnte nicht geladen werden",detail:o.error},children:e.jsx(y,{onClick:()=>window.location.reload(),size:"sm",variant:"outline",children:"Neu laden"})});const s=t.layout==="app"?e.jsx(It,{elementId:t.elementId,registry:o.registry,runId:t.runId}):e.jsx(Et,{connection:t.connection,initialRunId:t.runId,registry:o.registry});return o.failures.length===0?s:e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsx(He,{failures:o.failures}),e.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:s})]})}function Et({connection:t,initialRunId:o,registry:r}){var se;const s=H(),a=Z(),l=a.can("runs.read"),c=l&&a.can("runs.write"),f=c&&a.can("runs.create"),x=f||c&&r.scriptEntries.some(n=>de(a,n.id)),b=Be((se=a.user)==null?void 0:se.id),[u,R]=i.useState(o),[E,d]=i.useState(),[S,I]=i.useState(),m=i.useCallback(()=>I(n=>n===u?void 0:n),[u]),[Se,G]=i.useState(),[h,N]=i.useState(),[D,J]=i.useState(),U=i.useRef(void 0),g=i.useCallback(n=>{U.current=n==null?void 0:n.runId,J(n)},[]),[W,B]=i.useState(),[P,Q]=i.useState(!1),[Y,X]=i.useState(),V=i.useCallback(()=>Q(!0),[]),{sessions:ee,unreachable:je,refresh:ke}=me(l&&!h&&!D),[ye,Re]=i.useState(null),[Ee,Ne]=i.useState(null),O=i.useCallback((n,p)=>{var _;const j=(_=r.startEntries.find(Le=>Le.id===p))==null?void 0:_.fixedStartOptions;N({session:bt(),startOptions:n&&ue(n,j),entryId:p})},[r]),Ce=i.useCallback(()=>O(),[O]),L=i.useCallback((n,p)=>{N(void 0),g(void 0),G(p),R(n),I(s.kind==="vscode"?n:void 0)},[s.kind,g]),te=i.useCallback(n=>{N(void 0),g(n),Nt(n,r,a).then(()=>{U.current===n.runId&&L(n.runId)},p=>{U.current===n.runId&&J({...n,error:p instanceof Error?p.message:String(p)})})},[a,L,r,g]),Ie=i.useCallback(n=>{I(void 0),d(void 0),R(n)},[]),A=i.useCallback(()=>{I(void 0),N(void 0),g(void 0),B(void 0),s.kind==="vscode"?s.notify({type:"showStart"}):R(void 0)},[s,g]);i.useLayoutEffect(()=>{if(S){if(P||h){m();return}return window.addEventListener("pointerdown",m,!0),window.addEventListener("keydown",m,!0),window.addEventListener("blur",m),()=>{window.removeEventListener("pointerdown",m,!0),window.removeEventListener("keydown",m,!0),window.removeEventListener("blur",m)}}},[h,S,P,m]),i.useEffect(()=>s.onCommand(n=>{if(n.type==="selectRun"&&(I(void 0),N(void 0),g(void 0),B(void 0),G(void 0),d(void 0),R(n.runId??void 0)),n.type!=="newRun")return;if(s.kind!=="vscode"){x&&O(n.startOptions,n.entryId);return}const p=x?n.entryId===void 0&&!f?"Freie Runs sind für dieses Benutzerkonto nicht freigegeben.":void 0:"Neue Runs sind für dieses Benutzerkonto nicht freigegeben.";if(B(p),p!==void 0)return;const j=r.startEntries.find(_=>_.id===n.entryId);if(d((j==null?void 0:j.title)??v),n.entryId===void 0){L(crypto.randomUUID(),n.startOptions);return}if(j!==void 0&&r.guideFor(j)!==void 0){g(void 0),O(n.startOptions,j.id);return}te({runId:crypto.randomUUID(),entryId:n.entryId,startOptions:n.startOptions})}),[x,f,s,L,r,g,O,te]),i.useEffect(()=>{s.notify({type:"ready"})},[s]),i.useEffect(()=>{s.notify({type:"runChanged",runId:u??null})},[s,u]);const z=P&&e.jsx(Je,{onClose:()=>Q(!1),registry:r}),C=n=>e.jsxs(e.Fragment,{children:[e.jsx(y,{"aria-label":"Zur Start-Seite",className:"self-center",onClick:A,size:"icon-lg",title:"Zur Start-Seite",variant:"ghost",children:e.jsx(re,{})}),e.jsx("strong",{className:pt,children:n}),t&&e.jsx("span",{className:oe,title:`Server ${t}`,children:t}),e.jsx(q,{onOpenSettings:V})]}),F=e.jsx(y,{onClick:A,size:"sm",variant:"outline",children:"Zur Start-Seite"}),ne=h&&e.jsx(K,{initialStartOptions:h.startOptions,onStarted:()=>{L(h.session.id),d(n=>n??v),ke()},registry:r,session:h.session,startDialog:{onClose:s.kind==="vscode"?A:()=>N(void 0),initialEntryId:h.entryId}},h.session.id);if(D)return e.jsxs(e.Fragment,{children:[D.error===void 0?e.jsx(w,{header:C(E??v),state:ae}):e.jsx(w,{header:C(E??v),state:{kind:"error",title:"Der Run konnte nicht gestartet werden",detail:D.error},children:F}),z]});if(s.kind==="vscode"&&h)return e.jsxs(e.Fragment,{children:[e.jsx(w,{header:C(E??v),state:ae}),ne,z]});if(s.kind==="vscode"&&!(l&&u))return e.jsxs(e.Fragment,{children:[l?W!==void 0?e.jsx(w,{header:C(v),state:{kind:"error",title:"Kein neuer Run möglich",detail:W},children:F}):e.jsx(Ct,{header:C(v),children:F}):e.jsx(w,{header:C(v),state:yt,children:F}),z]});const T=ee.find(n=>n.id===u),Pe=()=>{u!==void 0&&(X(void 0),We(u,mt).catch(n=>X(`Stoppen fehlgeschlagen: ${n instanceof Error?n.message:String(n)}`)))},Oe=l?e.jsx(Qe,{activeId:u,onCreate:x?Ce:void 0,onSelect:Ie,onToggleSelected:()=>{},registry:r,seenRevisions:b.revisions,selectMode:!1,selectedIds:wt,sessions:ee}):e.jsx("p",{className:ve,children:"Für dieses Benutzerkonto sind keine Runs freigegeben."});return e.jsxs("div",{className:"flex h-full flex-col bg-[image:var(--surface-backdrop)]",children:[l&&u?e.jsxs(e.Fragment,{children:[e.jsxs("header",{className:ge,children:[e.jsx(y,{"aria-label":"Zur Start-Seite",className:"self-center",onClick:A,size:"icon-lg",title:"Zur Start-Seite",variant:"ghost",children:e.jsx(re,{})}),e.jsx("div",{"aria-label":"Run-Titelleiste",className:"flex min-w-0 flex-1 items-stretch overflow-x-auto no-scrollbar",ref:Re,role:"region"}),t&&e.jsx("span",{className:oe,title:`Server ${t}`,children:t}),e.jsx(Ve,{className:"self-center px-1.5",state:T!=null&&T.running?"running":"idle"}),e.jsx($e,{className:"self-center",disabled:!c,label:"Run stoppen",onClick:Pe,size:"icon-lg",title:"Run mit allen Agenten und Abläufen stoppen"}),e.jsx("div",{"aria-label":"Werkzeuge des Panels",className:"flex flex-none items-center empty:hidden",ref:Ne,role:"toolbar"}),e.jsx(q,{onOpenSettings:V})]}),Y&&e.jsx(ie,{variant:"destructive",children:Y}),e.jsx("main",{className:"relative z-1 flex min-h-0 min-w-0 flex-1 @container/chat-content",children:e.jsx(K,{autoFocusChat:S===u&&!P&&!h,onAutoFocusChatSettled:m,toolbarContainer:Ee,headerContainer:ye,initialStartOptions:Se,layout:"panel",onViewed:b.markViewed,registry:r,session:T??we(u,E),viewing:!h&&!P},u)})]}):e.jsxs(e.Fragment,{children:[e.jsxs("header",{className:vt,children:[e.jsx(ft,{"aria-hidden":!0,className:"size-4 flex-none text-muted-foreground"}),e.jsx("strong",{className:"min-w-0 flex-1 truncate text-[0.82rem] font-semibold",children:r.brand.title}),e.jsx(q,{onOpenSettings:V})]}),e.jsxs("div",{className:"min-h-0 flex-1 overflow-auto p-3",children:[je&&e.jsx(ie,{className:"mb-3",variant:"destructive",children:"Der Server ist nicht erreichbar."}),Oe]})]}),z,ne]})}async function Nt(t,o,r){const s=o.startEntries.find(a=>a.id===t.entryId);if(!s)throw new Error("Diese Vorlage gibt es in diesem Profil nicht.");if(!de(r,s.id))throw new Error(`${s.title} ist für dieses Benutzerkonto nicht freigegeben.`);if(t.startOptions){const a=await qe(t.runId),l=ue(t.startOptions,s.fixedStartOptions);for(const[c,f]of Ke(a,l))await Ze(t.runId,c,f)}await Ge(t.runId,s,null)}function Ct({children:t,header:o}){const[r,s]=i.useState(!1);return i.useEffect(()=>{const a=window.setTimeout(()=>s(!0),gt);return()=>window.clearTimeout(a)},[]),r?e.jsx(w,{header:o,state:kt,children:t}):e.jsx(w,{header:o,state:jt})}function w({children:t,header:o,headless:r=!1,state:s}){return e.jsxs("div",{className:"flex h-full flex-col bg-[image:var(--surface-backdrop)]",children:[!r&&e.jsx("header",{className:ge,children:o}),e.jsx("main",{className:"grid min-h-0 flex-1 place-items-center overflow-hidden p-6",children:e.jsx(Ue,{state:s,children:t})})]})}function It({elementId:t,registry:o,runId:r}){const s=H(),a=Z().can("runs.read"),{sessions:l}=me(a);return i.useEffect(()=>{s.notify({type:"ready"})},[s]),a?e.jsx("main",{className:"relative flex h-full min-h-0 min-w-0 flex-1 bg-background @container/chat-content",children:e.jsx(K,{layout:{element:t},registry:o,session:l.find(c=>c.id===r)??we(r)},r)}):e.jsx("p",{className:ve,children:"Für dieses Benutzerkonto sind keine Runs freigegeben."})}function Pt(){const t=H();return e.jsxs(ce,{children:[e.jsx("h1",{className:"my-3 text-[1.5rem]",children:"Anmeldung erforderlich"}),e.jsx("p",{className:"mb-6 leading-normal text-muted-foreground",children:"Die Anmeldung läuft über VS Code. Danach lädt das Panel neu."}),e.jsx(y,{className:"w-full",onClick:()=>t.requestLogin(),children:"In VS Code anmelden"})]})}const k=t=>t!=null&&t.trim()?t.trim():void 0,Ot=t=>{if(t==="browser"||t==="vscode")return t;throw new Error(`Unbekannter Host ${JSON.stringify(t)}. Erlaubt sind browser und vscode.`)};function Lt(t){const o=new URLSearchParams(t),r=k(o.get("layout"))??"panel";if(r!=="panel"&&r!=="app")throw new Error(`Unbekanntes Layout ${JSON.stringify(r)}. Erlaubt sind panel und app.`);const s=k(o.get("theme"));if(s!==void 0&&!Ye(s))throw new Error(`Unbekannte Darstellung ${JSON.stringify(s)}. Erlaubt sind light und dark.`);const a={host:Ot(k(o.get("host"))??"browser"),connection:k(o.get("connection")),theme:s,access:k(o.get(Xe))},l=k(o.get("run"));if(r==="panel")return{layout:r,runId:l,...a};const c=k(o.get("element"));if(!l||!c)throw new Error("Das Layout app braucht run und element.");return{layout:r,runId:l,elementId:c,...a}}et();const be=document.getElementById("root");if(!be)throw new Error("Root-Element fehlt");const le=tt.createRoot(be);try{const t=Lt(window.location.search);t.access!==void 0&&nt(t.access);const o=st(t.host,window);if(t.host==="vscode"){const s=rt(window)}const r=it(window);t.theme!==void 0&&r.setPreference(t.theme),o.onCommand(s=>{s.type==="theme"&&r.setPreference(s.theme)}),le.render(e.jsx(i.StrictMode,{children:e.jsx(ot,{children:e.jsx(at,{value:o,children:e.jsx(lt,{value:t.host==="vscode"?{open:o.openPage}:void 0,children:e.jsx(ct,{Login:t.host==="vscode"?Pt:void 0,children:e.jsx(Rt,{location:t})})})})})}))}catch(t){le.render(e.jsxs(ce,{children:[e.jsx("h1",{className:"my-3 text-[1.5rem]",children:"Das RAgents-Panel konnte nicht geladen werden"}),e.jsx("p",{className:"mb-6 leading-normal",role:"alert",children:t instanceof Error?t.message:String(t)}),e.jsx(y,{onClick:()=>window.location.reload(),variant:"outline",children:"Erneut laden"})]}))}
@@ -156,8 +156,10 @@ mini-app, so unsaved input in it is lost. The choice is stored per run and survi
156
156
  The extension can also open a mini-app as an editor tab in the center, which works well with
157
157
  &quot;Nur Chat&quot; in the run panel.</p>
158
158
  <p>In &quot;Chat unten&quot;, the handle controls the expanded chat height. Dragging up makes it taller;
159
- dragging down makes it shorter. The chosen height is stored per run. The collapsed chat always
160
- shows only the handle, status, and complete input, including multiple input lines. Hovering or
159
+ dragging down makes it shorter. The chosen height is stored per run. The collapsed chat shows the
160
+ handle, status, and complete input, including multiple input lines. An open question sits
161
+ completely above the input there as well: the collapsed chat grows by its height, up to half of
162
+ the panel, and the status line reads &quot;Wartet auf Eingabe&quot; (waiting for input). Hovering or
161
163
  writing opens the chat to the chosen height (90 percent of the panel by default). Dragging leaves
162
164
  the chat open at its new height. Clicking the handle opens or closes it. With
163
165
  keyboard focus on the handle, up and down change the height, Home and End select its limits, and
@@ -267,11 +269,19 @@ tooltip names the cause; it does not open, but the selection mode deletes it.</p
267
269
  <p><strong>Server</strong> is the configuration page. You can add, edit, sign in, sign out, connect,
268
270
  disconnect, and remove servers with confirmation, then open <code>settings.json</code> from the link
269
271
  at the bottom. If a connected server does not accept this window&#39;s folders as a workstation, its
270
- entry says &quot;Arbeitsplatz nicht angemeldet&quot; (workstation not registered) with the cause. When the
271
- extension and the server carry different workspace executor versions, the cause names both and
272
- what to update: the extension if it is older, the server if it is newer. The same applies when the
273
- host the extension uses lacks a plugin bundle the server&#39;s executor carries, such as a language
274
- server, or carries it in another version: the cause names the plugin and the host to update.</p>
272
+ entry says &quot;Arbeitsplatz nicht angemeldet&quot; (workstation not registered) with the cause.</p>
273
+ <p>The extension compares its own RAgents version with the version each server reports. If they
274
+ differ, the server row, the top of Start, the status bar, and a notification show &quot;RAgents-Fassung
275
+ passt nicht: Erweiterung 0.1.9, Server 0.1.8 - ...&quot; (RAgents version does not match), followed by
276
+ what to update: the extension if it is older, the server if it is older, or the host in
277
+ <code>ragents.hostPath</code> for a local profile. A server that reports no version counts as older. While the
278
+ workstation stays registered, this is a warning and everything keeps working. When the server
279
+ rejects the workstation for the same reason, because the workspace executor versions differ or the
280
+ host the extension uses lacks a plugin bundle the server&#39;s executor carries, or carries it in
281
+ another version, it is an error that also names the server&#39;s cause; the same error appears when
282
+ both report the same version but their builds differ. The notification appears once per server
283
+ and message; &quot;Erweiterung zeigen&quot; (show extension) opens the extension page for the update, and
284
+ &quot;Server zeigen&quot; (show server) opens the Server page.</p>
275
285
  <p>Every status uses a colored icon and a tooltip with the same vocabulary everywhere. A run is
276
286
  &quot;läuft&quot; (running), &quot;wartet auf Eingabe&quot; (waiting for input, with the number of open inputs),
277
287
  &quot;ruht&quot; (idle), &quot;beendet&quot; (ended), &quot;fehlgeschlagen&quot; (failed), or &quot;abgebrochen&quot; (cancelled). A
@@ -32,8 +32,10 @@ The extension can also open a mini-app as an editor tab in the center, which wor
32
32
  "Nur Chat" in the run panel.
33
33
 
34
34
  In "Chat unten", the handle controls the expanded chat height. Dragging up makes it taller;
35
- dragging down makes it shorter. The chosen height is stored per run. The collapsed chat always
36
- shows only the handle, status, and complete input, including multiple input lines. Hovering or
35
+ dragging down makes it shorter. The chosen height is stored per run. The collapsed chat shows the
36
+ handle, status, and complete input, including multiple input lines. An open question sits
37
+ completely above the input there as well: the collapsed chat grows by its height, up to half of
38
+ the panel, and the status line reads "Wartet auf Eingabe" (waiting for input). Hovering or
37
39
  writing opens the chat to the chosen height (90 percent of the panel by default). Dragging leaves
38
40
  the chat open at its new height. Clicking the handle opens or closes it. With
39
41
  keyboard focus on the handle, up and down change the height, Home and End select its limits, and
@@ -154,11 +156,20 @@ tooltip names the cause; it does not open, but the selection mode deletes it.
154
156
  **Server** is the configuration page. You can add, edit, sign in, sign out, connect,
155
157
  disconnect, and remove servers with confirmation, then open `settings.json` from the link
156
158
  at the bottom. If a connected server does not accept this window's folders as a workstation, its
157
- entry says "Arbeitsplatz nicht angemeldet" (workstation not registered) with the cause. When the
158
- extension and the server carry different workspace executor versions, the cause names both and
159
- what to update: the extension if it is older, the server if it is newer. The same applies when the
160
- host the extension uses lacks a plugin bundle the server's executor carries, such as a language
161
- server, or carries it in another version: the cause names the plugin and the host to update.
159
+ entry says "Arbeitsplatz nicht angemeldet" (workstation not registered) with the cause.
160
+
161
+ The extension compares its own RAgents version with the version each server reports. If they
162
+ differ, the server row, the top of Start, the status bar, and a notification show "RAgents-Fassung
163
+ passt nicht: Erweiterung 0.1.9, Server 0.1.8 - ..." (RAgents version does not match), followed by
164
+ what to update: the extension if it is older, the server if it is older, or the host in
165
+ `ragents.hostPath` for a local profile. A server that reports no version counts as older. While the
166
+ workstation stays registered, this is a warning and everything keeps working. When the server
167
+ rejects the workstation for the same reason, because the workspace executor versions differ or the
168
+ host the extension uses lacks a plugin bundle the server's executor carries, or carries it in
169
+ another version, it is an error that also names the server's cause; the same error appears when
170
+ both report the same version but their builds differ. The notification appears once per server
171
+ and message; "Erweiterung zeigen" (show extension) opens the extension page for the update, and
172
+ "Server zeigen" (show server) opens the Server page.
162
173
 
163
174
  Every status uses a colored icon and a tooltip with the same vocabulary everywhere. A run is
164
175
  "läuft" (running), "wartet auf Eingabe" (waiting for input, with the number of open inputs),