@loicngr/kobo 1.7.32 → 1.8.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 (50) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/mcp-server/kobo-tasks-server.js +4 -0
  3. package/dist/server/routes/workspaces.js +11 -9
  4. package/dist/server/services/agent/engines/claude-code/engine.js +37 -4
  5. package/dist/server/services/agent/engines/claude-code/stop-hook.js +56 -0
  6. package/dist/server/services/cron-service.js +12 -6
  7. package/dist/server/services/wakeup-service.js +9 -0
  8. package/package.json +2 -2
  9. package/src/client/dist/spa/assets/{ActivityFeed-COdkQaiZ.js → ActivityFeed-Y1RkIPW1.js} +1 -1
  10. package/src/client/dist/spa/assets/{ChangelogPage-BXD8H3j-.js → ChangelogPage-DcPmypaS.js} +1 -1
  11. package/src/client/dist/spa/assets/{CreatePage-DX4TjLqr.js → CreatePage-DO_pMGS3.js} +1 -1
  12. package/src/client/dist/spa/assets/{DiffViewer-BUjVXGyZ.js → DiffViewer-DRvbmHwK.js} +3 -3
  13. package/src/client/dist/spa/assets/{HealthPage-DM7fvP4v.js → HealthPage-BvOR0B7B.js} +1 -1
  14. package/src/client/dist/spa/assets/{MainLayout-DtTxmFXf.css → MainLayout-KmjhECRT.css} +1 -1
  15. package/src/client/dist/spa/assets/MainLayout-M5TW3GL1.js +37 -0
  16. package/src/client/dist/spa/assets/{QSelect-DERXhq6x.js → QSelect-DgGpVy88.js} +1 -1
  17. package/src/client/dist/spa/assets/{SearchPage-OaTRqd2Q.js → SearchPage-Qc2SXUjf.js} +1 -1
  18. package/src/client/dist/spa/assets/{SettingsPage-BBk3MB8w.js → SettingsPage-G4xXwNwc.js} +1 -1
  19. package/src/client/dist/spa/assets/{WorkspacePage-k_qzLoLC.js → WorkspacePage-DeGm-XQp.js} +3 -3
  20. package/src/client/dist/spa/assets/{cssMode-CdNIff6x.js → cssMode-DfDzxSXu.js} +1 -1
  21. package/src/client/dist/spa/assets/{editor.api2-CEAFHkwY.js → editor.api2-Byu6kw7p.js} +1 -1
  22. package/src/client/dist/spa/assets/{editor.main-DuQa2C4S.js → editor.main-VujCgCtA.js} +2 -2
  23. package/src/client/dist/spa/assets/{engineFeatures-DChekJQO.js → engineFeatures-6A3KLQRO.js} +1 -1
  24. package/src/client/dist/spa/assets/{expand-template-BXNt_oWH.js → expand-template-CRHCd-I8.js} +1 -1
  25. package/src/client/dist/spa/assets/{freemarker2-DXz2Sr_a.js → freemarker2-Ce85qzU_.js} +1 -1
  26. package/src/client/dist/spa/assets/{handlebars-B6DHJ8jd.js → handlebars-BLTKFzzh.js} +1 -1
  27. package/src/client/dist/spa/assets/{html-_UvZHIUo.js → html-Brx-Keq8.js} +1 -1
  28. package/src/client/dist/spa/assets/{htmlMode-DZ0ixGc6.js → htmlMode-Cn-qtgzd.js} +1 -1
  29. package/src/client/dist/spa/assets/i18n-Cl6Gt8Eh.js +1 -0
  30. package/src/client/dist/spa/assets/{index-CNin8jPU.js → index-CyseQlfR.js} +6 -6
  31. package/src/client/dist/spa/assets/{javascript-C6Gf4Ys2.js → javascript-ywvG3uUF.js} +1 -1
  32. package/src/client/dist/spa/assets/{jsonMode-aE8EPidy.js → jsonMode-DjYQF9SH.js} +1 -1
  33. package/src/client/dist/spa/assets/{kobo-commands-Ip0ObeCE.js → kobo-commands-BSkMs22T.js} +1 -1
  34. package/src/client/dist/spa/assets/{liquid-CSp27lUC.js → liquid-CZjmNn4a.js} +1 -1
  35. package/src/client/dist/spa/assets/{lspLanguageFeatures-UxO-LpRp.js → lspLanguageFeatures-DJiFF8Wc.js} +1 -1
  36. package/src/client/dist/spa/assets/{mdx-BSCEgQSy.js → mdx-DPvLr_Xj.js} +1 -1
  37. package/src/client/dist/spa/assets/{monaco.contribution-DqqsS1kc.js → monaco.contribution-rZ1avSXN.js} +2 -2
  38. package/src/client/dist/spa/assets/{python-CA5lSk1U.js → python-agZmzvad.js} +1 -1
  39. package/src/client/dist/spa/assets/{razor-BznM4hXD.js → razor-D-6K3O2-.js} +1 -1
  40. package/src/client/dist/spa/assets/{render-chat-markdown-BJsZCnSw.js → render-chat-markdown-8LO2n7Of.js} +1 -1
  41. package/src/client/dist/spa/assets/{tsMode-NbGeOvoN.js → tsMode-BxYiDnB8.js} +1 -1
  42. package/src/client/dist/spa/assets/{typescript-kHDph5jb.js → typescript-Cv7_rzaO.js} +1 -1
  43. package/src/client/dist/spa/assets/{use-onboarding-C4tGLHsr.js → use-onboarding-Dy-3eSVP.js} +1 -1
  44. package/src/client/dist/spa/assets/{workers-DFjmWZva.js → workers-JYdpxrSy.js} +1 -1
  45. package/src/client/dist/spa/assets/{xml-BXzZhhmL.js → xml-CshFLvoE.js} +1 -1
  46. package/src/client/dist/spa/assets/{yaml-DQNlz7_W.js → yaml-DL8TzVD_.js} +1 -1
  47. package/src/client/dist/spa/index.html +1 -1
  48. package/src/mcp-server/kobo-tasks-server.ts +4 -0
  49. package/src/client/dist/spa/assets/MainLayout-CbUZOTwz.js +0 -37
  50. package/src/client/dist/spa/assets/i18n-DXMuiAyu.js +0 -1
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/MainLayout-CbUZOTwz.js","assets/_plugin-vue_export-helper-BzmG9fMN.js","assets/vue-i18n-C5Tx4bGk.js","assets/vue.runtime.esm-bundler-BAtKyT0Y.js","assets/chunk-DtRyYLXJ.js","assets/render-chat-markdown-BJsZCnSw.js","assets/use-onboarding-C4tGLHsr.js","assets/notifications-C4MxuXC7.js","assets/use-id-By86THzm.js","assets/QIcon-C6C3QeM4.js","assets/QBtn-DwemGTZv.js","assets/use-onboarding-B3l7mx48.css","assets/QBadge-CIC5n8w7.js","assets/build-path-tree-D4_LR3mz.js","assets/QCheckbox-o3UHW596.js","assets/use-checkbox-BnkSQgTJ.js","assets/QInput-CLZtb8E0.js","assets/QTooltip-CyRLTG6i.js","assets/QRadio-B_TurTzx.js","assets/QChip-BpS8c1sW.js","assets/QSelect-DERXhq6x.js","assets/QItemSection-O9WBXftL.js","assets/QItemLabel-BYSjzk-t.js","assets/QMenu-D_9kEp2i.js","assets/QList-DRW_oyZ4.js","assets/QScrollObserver-Cxj52Zfg.js","assets/QSpace-CrVsndpV.js","assets/QToggle-Dwr3hSLw.js","assets/engineFeatures-DChekJQO.js","assets/touch-yfnu5R3D.js","assets/use-quasar-DcJRs0ay.js","assets/ClosePopup-DD10nToj.js","assets/TouchPan-BmfIMD00.js","assets/documents-N8PwB_Gh.js","assets/formatters-wq5wP2If.js","assets/kobo-commands-Ip0ObeCE.js","assets/MainLayout-DtTxmFXf.css","assets/WorkspacePage-k_qzLoLC.js","assets/QBanner-BxBEdhfp.js","assets/QPage-C6xc9fOe.js","assets/QSpinnerDots-atHe_AUn.js","assets/expand-template-BXNt_oWH.js","assets/expand-template-D2yUa54D.css","assets/permissionModes-CJN6Olox.js","assets/WorkspacePage-36QGRRCt.css","assets/CreatePage-DX4TjLqr.js","assets/QExpansionItem-C9vmJqEO.js","assets/CreatePage-CE-ljszo.css","assets/SettingsPage-BBk3MB8w.js","assets/SettingsPage-B7H6sD7r.css","assets/SearchPage-OaTRqd2Q.js","assets/SearchPage-cVwt0DaQ.css","assets/HealthPage-DM7fvP4v.js","assets/ChangelogPage-BXD8H3j-.js","assets/ChangelogPage-CQ33An2f.css"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/MainLayout-M5TW3GL1.js","assets/_plugin-vue_export-helper-BzmG9fMN.js","assets/vue-i18n-C5Tx4bGk.js","assets/vue.runtime.esm-bundler-BAtKyT0Y.js","assets/chunk-DtRyYLXJ.js","assets/render-chat-markdown-8LO2n7Of.js","assets/use-onboarding-Dy-3eSVP.js","assets/notifications-C4MxuXC7.js","assets/use-id-By86THzm.js","assets/QIcon-C6C3QeM4.js","assets/QBtn-DwemGTZv.js","assets/use-onboarding-B3l7mx48.css","assets/QBadge-CIC5n8w7.js","assets/build-path-tree-D4_LR3mz.js","assets/QCheckbox-o3UHW596.js","assets/use-checkbox-BnkSQgTJ.js","assets/QInput-CLZtb8E0.js","assets/QTooltip-CyRLTG6i.js","assets/QRadio-B_TurTzx.js","assets/QChip-BpS8c1sW.js","assets/QSelect-DgGpVy88.js","assets/QItemSection-O9WBXftL.js","assets/QItemLabel-BYSjzk-t.js","assets/QMenu-D_9kEp2i.js","assets/QList-DRW_oyZ4.js","assets/QScrollObserver-Cxj52Zfg.js","assets/QSpace-CrVsndpV.js","assets/QToggle-Dwr3hSLw.js","assets/engineFeatures-6A3KLQRO.js","assets/touch-yfnu5R3D.js","assets/use-quasar-DcJRs0ay.js","assets/ClosePopup-DD10nToj.js","assets/TouchPan-BmfIMD00.js","assets/documents-N8PwB_Gh.js","assets/formatters-wq5wP2If.js","assets/kobo-commands-BSkMs22T.js","assets/MainLayout-KmjhECRT.css","assets/WorkspacePage-DeGm-XQp.js","assets/QBanner-BxBEdhfp.js","assets/QPage-C6xc9fOe.js","assets/QSpinnerDots-atHe_AUn.js","assets/expand-template-CRHCd-I8.js","assets/expand-template-D2yUa54D.css","assets/permissionModes-CJN6Olox.js","assets/WorkspacePage-36QGRRCt.css","assets/CreatePage-DO_pMGS3.js","assets/QExpansionItem-C9vmJqEO.js","assets/CreatePage-CE-ljszo.css","assets/SettingsPage-G4xXwNwc.js","assets/SettingsPage-B7H6sD7r.css","assets/SearchPage-Qc2SXUjf.js","assets/SearchPage-cVwt0DaQ.css","assets/HealthPage-BvOR0B7B.js","assets/ChangelogPage-DcPmypaS.js","assets/ChangelogPage-CQ33An2f.css"])))=>i.map(i=>d[i]);
2
2
  import{$ as e,C as t,D as n,F as r,I as i,M as a,Q as o,R as s,S as c,T as l,U as u,V as d,W as f,X as p,_ as m,b as h,c as g,ct as _,et as v,g as y,h as b,i as x,it as S,k as ee,m as C,n as te,nt as w,p as T,r as E,tt as ne,z as D}from"./vue.runtime.esm-bundler-BAtKyT0Y.js";import{D as O,I as k,L as re,N as ie,O as A,P as j,T as ae,b as oe,l as se,n as M,r as N,s as ce,t as P,x as le}from"./QIcon-C6C3QeM4.js";import{a as F,d as I,f as L,i as ue,o as de,p as fe,r as pe,u as me}from"./use-id-By86THzm.js";import{A as he,C as ge,F as _e,H as ve,I as ye,L as be,M as xe,N as Se,P as Ce,R as we,S as Te,V as R,_ as Ee,d as De,f as Oe,j as ke,k as Ae,l as je,m as Me,p as Ne,r as Pe,t as z,u as Fe,v as Ie,w as Le}from"./notifications-C4MxuXC7.js";import{n as Re,r as ze,t as Be}from"./QRadio-B_TurTzx.js";import{l as Ve,t as He}from"./QBtn-DwemGTZv.js";import{n as Ue,t as We}from"./vue-i18n-C5Tx4bGk.js";import{t as Ge}from"./QInput-CLZtb8E0.js";import{t as Ke}from"./QCheckbox-o3UHW596.js";import{t as qe}from"./QToggle-Dwr3hSLw.js";var Je=[`sm`,`md`,`lg`,`xl`],{passive:Ye}=O,Xe=k({width:0,height:0,name:`xs`,sizes:{sm:600,md:1024,lg:1440,xl:1920},lt:{sm:!0,md:!0,lg:!0,xl:!0},gt:{xs:!1,sm:!1,md:!1,lg:!1},xs:!0,sm:!1,md:!1,lg:!1,xl:!1},{setSizes:A,setDebounce:A,install({$q:e,onSSRHydrated:t}){if(e.screen=this,this.__installed){e.config.screen!==void 0&&(e.config.screen.bodyClasses?this.__update(!0):document.body.classList.remove(`screen--${this.name}`));return}let{visualViewport:n}=window,r=n||window,i=document.scrollingElement||document.documentElement,a=n===void 0||L.is.mobile?()=>[Math.max(window.innerWidth,i.clientWidth),Math.max(window.innerHeight,i.clientHeight)]:()=>[n.width*n.scale+window.innerWidth-i.clientWidth,n.height*n.scale+window.innerHeight-i.clientHeight],o=e.config.screen?.bodyClasses===!0;this.__update=e=>{let[t,n]=a();if(n!==this.height&&(this.height=n),t!==this.width)this.width=t;else if(e!==!0)return;let r=this.sizes;this.gt.xs=t>=r.sm,this.gt.sm=t>=r.md,this.gt.md=t>=r.lg,this.gt.lg=t>=r.xl,this.lt.sm=t<r.sm,this.lt.md=t<r.md,this.lt.lg=t<r.lg,this.lt.xl=t<r.xl,this.xs=this.lt.sm,this.sm=this.gt.xs&&this.lt.md,this.md=this.gt.sm&&this.lt.lg,this.lg=this.gt.md&&this.lt.xl,this.xl=this.gt.lg,r=this.xs&&`xs`||this.sm&&`sm`||this.md&&`md`||this.lg&&`lg`||`xl`,r!==this.name&&(o&&(document.body.classList.remove(`screen--${this.name}`),document.body.classList.add(`screen--${r}`)),this.name=r)};let s,c={},l=16;this.setSizes=e=>{Je.forEach(t=>{e[t]!==void 0&&(c[t]=e[t])})},this.setDebounce=e=>{l=e};let u=()=>{let e=getComputedStyle(document.body);e.getPropertyValue(`--q-size-sm`)&&Je.forEach(t=>{this.sizes[t]=Number.parseInt(e.getPropertyValue(`--q-size-${t}`),10)}),this.setSizes=e=>{Je.forEach(t=>{e[t]&&(this.sizes[t]=e[t])}),this.__update(!0)},this.setDebounce=e=>{s!==void 0&&r.removeEventListener(`resize`,s,Ye),s=e>0?me(this.__update,e):this.__update,r.addEventListener(`resize`,s,Ye)},this.setDebounce(l),Object.keys(c).length===0?this.__update():(this.setSizes(c),c=void 0),o&&this.name===`xs`&&document.body.classList.add(`screen--xs`)};fe.value?t.push(u):u()}}),B=k({isActive:!1,mode:!1},{__media:void 0,set(e){B.mode=e,e===`auto`?(B.__media===void 0&&(B.__media=window.matchMedia(`(prefers-color-scheme: dark)`),B.__updateMedia=()=>{B.set(`auto`)},B.__media.addListener(B.__updateMedia)),e=B.__media.matches):B.__media!==void 0&&(B.__media.removeListener(B.__updateMedia),B.__media=void 0),B.isActive=e===!0,document.body.classList.remove(`body--${e===!0?`light`:`dark`}`),document.body.classList.add(`body--${e===!0?`dark`:`light`}`)},toggle(){B.set(!B.isActive)},install({$q:e,ssrContext:t}){let n=e.config.dark;e.dark=this,this.__installed||this.set(n===void 0?!1:n)}});function Ze(e,t,n=document.body){if(typeof e!=`string`)throw TypeError(`Expected a string as propName`);if(typeof t!=`string`)throw TypeError(`Expected a string as value`);if(!(n instanceof Element))throw TypeError(`Expected a DOM element`);n.style.setProperty(`--q-${e}`,t)}function Qe(e){if(e.ios)return`ios`;if(e.android)return`android`}function $e({is:e,has:t,within:n},r){let i=[e.desktop?`desktop`:`mobile`,`${t.touch?``:`no-`}touch`];if(e.mobile){let t=Qe(e);t!==void 0&&i.push(`platform-`+t)}if(e.nativeMobile){let t=e.nativeMobileWrapper;i.push(t),i.push(`native-mobile`),e.ios&&(r[t]===void 0||r[t].iosStatusBarPadding)&&i.push(`q-ios-padding`)}else e.electron?i.push(`electron`):e.bex&&i.push(`bex`);return n.iframe&&i.push(`within-iframe`),i}function et(){let{is:e}=L,t=document.body.className,n=new Set(t.replaceAll(/ {2}/g,` `).split(` `));if(!e.nativeMobile&&!e.electron&&!e.bex){if(e.desktop)n.delete(`mobile`),n.delete(`platform-ios`),n.delete(`platform-android`),n.add(`desktop`);else if(e.mobile){n.delete(`desktop`),n.add(`mobile`),n.delete(`platform-ios`),n.delete(`platform-android`);let t=Qe(e);t!==void 0&&n.add(`platform-${t}`)}}L.has.touch&&(n.delete(`no-touch`),n.add(`touch`)),L.within.iframe&&n.add(`within-iframe`);let r=[...n].join(` `);t!==r&&(document.body.className=r)}function tt(e){for(let t in e)Ze(t,e[t])}var nt={install(e){if(!this.__installed){if(fe.value)et();else{let{$q:t}=e;t.config.brand!==void 0&&tt(t.config.brand),document.body.classList.add(...$e(L,t.config))}L.is.ios&&document.body.addEventListener(`touchstart`,A),window.addEventListener(`keydown`,le,!0)}}},rt={isoName:`en-US`,nativeName:`English (US)`,label:{clear:`Clear`,ok:`OK`,cancel:`Cancel`,close:`Close`,set:`Set`,select:`Select`,reset:`Reset`,remove:`Remove`,update:`Update`,create:`Create`,search:`Search`,filter:`Filter`,refresh:`Refresh`,expand:e=>e?`Expand "${e}"`:`Expand`,collapse:e=>e?`Collapse "${e}"`:`Collapse`},date:{days:`Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday`.split(`_`),daysShort:`Sun_Mon_Tue_Wed_Thu_Fri_Sat`.split(`_`),months:`January_February_March_April_May_June_July_August_September_October_November_December`.split(`_`),monthsShort:`Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec`.split(`_`),firstDayOfWeek:0,format24h:!1,pluralDay:`days`,prevMonth:`Previous month`,nextMonth:`Next month`,prevYear:`Previous year`,nextYear:`Next year`,today:`Today`,prevRangeYears:e=>`Previous ${e} years`,nextRangeYears:e=>`Next ${e} years`},table:{noData:`No data available`,noResults:`No matching records found`,loading:`Loading...`,selectedRecords:e=>e===1?`1 record selected.`:(e===0?`No`:e)+` records selected.`,recordsPerPage:`Records per page:`,allRows:`All`,pagination:(e,t,n)=>e+` - `+t+` of `+n,columns:`Columns`},pagination:{first:`First page`,prev:`Previous page`,next:`Next page`,last:`Last page`},editor:{url:`URL`,bold:`Bold`,italic:`Italic`,strikethrough:`Strikethrough`,underline:`Underline`,unorderedList:`Unordered List`,orderedList:`Ordered List`,subscript:`Subscript`,superscript:`Superscript`,hyperlink:`Hyperlink`,toggleFullscreen:`Toggle Fullscreen`,quote:`Quote`,left:`Left align`,center:`Center align`,right:`Right align`,justify:`Justify align`,print:`Print`,outdent:`Decrease indentation`,indent:`Increase indentation`,removeFormat:`Remove formatting`,formatting:`Formatting`,fontSize:`Font Size`,align:`Align`,hr:`Insert Horizontal Rule`,undo:`Undo`,redo:`Redo`,heading1:`Heading 1`,heading2:`Heading 2`,heading3:`Heading 3`,heading4:`Heading 4`,heading5:`Heading 5`,heading6:`Heading 6`,paragraph:`Paragraph`,code:`Code`,size1:`Very small`,size2:`A bit small`,size3:`Normal`,size4:`Medium-large`,size5:`Big`,size6:`Very big`,size7:`Maximum`,defaultFont:`Default Font`,viewSource:`View Source`},tree:{noNodes:`No nodes available`,noResults:`No matching nodes found`}};function it(){let e=Array.isArray(navigator.languages)&&navigator.languages.length!==0?navigator.languages[0]:navigator.language;if(typeof e==`string`)return e.split(/[-_]/).map((e,t)=>t===0?e.toLowerCase():t>1||e.length<4?e.toUpperCase():e[0].toUpperCase()+e.slice(1).toLowerCase()).join(`-`)}var V=k({__qLang:{}},{getLocale:it,set(e=rt,t){let n={...e,rtl:e.rtl===!0,getLocale:it};if(n.set=V.set,V.__langConfig===void 0||!V.__langConfig.noHtmlAttrs){let e=document.documentElement;e.setAttribute(`dir`,n.rtl?`rtl`:`ltr`),e.setAttribute(`lang`,n.isoName)}Object.assign(V.__qLang,n)},install({$q:e,lang:t,ssrContext:n}){e.lang=V.__qLang,V.__langConfig=e.config.lang,this.__installed?t!==void 0&&this.set(t):(this.props=new Proxy(this.__qLang,{get:Reflect.get,ownKeys(e){return Reflect.ownKeys(e).filter(e=>e!==`set`&&e!==`getLocale`)}}),this.set(t||rt))}}),at={name:`material-icons`,type:{positive:`check_circle`,negative:`warning`,info:`info`,warning:`priority_high`},arrow:{up:`arrow_upward`,right:`arrow_forward`,down:`arrow_downward`,left:`arrow_back`,dropdown:`arrow_drop_down`},chevron:{left:`chevron_left`,right:`chevron_right`},colorPicker:{spectrum:`gradient`,tune:`tune`,palette:`style`},pullToRefresh:{icon:`refresh`},carousel:{left:`chevron_left`,right:`chevron_right`,up:`keyboard_arrow_up`,down:`keyboard_arrow_down`,navigationIcon:`lens`},chip:{remove:`cancel`,selected:`check`},datetime:{arrowLeft:`chevron_left`,arrowRight:`chevron_right`,now:`access_time`,today:`today`},editor:{bold:`format_bold`,italic:`format_italic`,strikethrough:`strikethrough_s`,underline:`format_underlined`,unorderedList:`format_list_bulleted`,orderedList:`format_list_numbered`,subscript:`vertical_align_bottom`,superscript:`vertical_align_top`,hyperlink:`link`,toggleFullscreen:`fullscreen`,quote:`format_quote`,left:`format_align_left`,center:`format_align_center`,right:`format_align_right`,justify:`format_align_justify`,print:`print`,outdent:`format_indent_decrease`,indent:`format_indent_increase`,removeFormat:`format_clear`,formatting:`text_format`,fontSize:`format_size`,align:`format_align_left`,hr:`remove`,undo:`undo`,redo:`redo`,heading:`format_size`,code:`code`,size:`format_size`,font:`font_download`,viewSource:`code`},expansionItem:{icon:`keyboard_arrow_down`,denseIcon:`arrow_drop_down`},fab:{icon:`add`,activeIcon:`close`},field:{clear:`cancel`,error:`error`},pagination:{first:`first_page`,prev:`keyboard_arrow_left`,next:`keyboard_arrow_right`,last:`last_page`},rating:{icon:`grade`},stepper:{done:`check`,active:`edit`,error:`warning`},tabs:{left:`chevron_left`,right:`chevron_right`,up:`keyboard_arrow_up`,down:`keyboard_arrow_down`},table:{arrowUp:`arrow_upward`,warning:`warning`,firstPage:`first_page`,prevPage:`chevron_left`,nextPage:`chevron_right`,lastPage:`last_page`},tree:{icon:`play_arrow`},uploader:{done:`done`,clear:`clear`,add:`add_box`,upload:`cloud_upload`,removeQueue:`clear_all`,removeUploaded:`done_all`}},ot=k({iconMapFn:null,__qIconSet:{}},{set(e,t){let n={...e};n.set=ot.set,Object.assign(ot.__qIconSet,n)},install({$q:e,iconSet:t,ssrContext:n}){e.config.iconMapFn!==void 0&&(this.iconMapFn=e.config.iconMapFn),e.iconSet=this.__qIconSet,re(e,`iconMapFn`,()=>this.iconMapFn,e=>{this.iconMapFn=e}),this.__installed?t!==void 0&&this.set(t):(this.props=new Proxy(this.__qIconSet,{get:Reflect.get,ownKeys(e){return Reflect.ownKeys(e).filter(e=>e!==`set`)}}),this.set(t||at))}}),st=[I,nt,B,Xe,ve,V,ot];function ct(e,t){let n=x(e);n.config.globalProperties=t.config.globalProperties;let{reload:r,...i}=t._context;return Object.assign(n._context,i),n}function lt(e,t){t.forEach(t=>{t.install(e),t.__installed=!0})}function ut(e,t,n){e.config.globalProperties.$q=n.$q,e.provide(`_q_`,n.$q),lt(n,st),t.components!==void 0&&Object.values(t.components).forEach(t=>{R(t)&&t.name!==void 0&&e.component(t.name,t)}),t.directives!==void 0&&Object.values(t.directives).forEach(t=>{R(t)&&t.name!==void 0&&e.directive(t.name,t)}),t.plugins!==void 0&&lt(n,Object.values(t.plugins).filter(e=>typeof e.install==`function`&&!st.includes(e))),fe.value&&(n.$q.onSSRHydrated=()=>{n.onSSRHydrated.forEach(e=>{e()}),n.$q.onSSRHydrated=()=>{}})}var dt={name:`Quasar`,version:`2.20.0`,install:function(e,t={}){let n={version:`2.20.0`};we?n.config=t.config||{}:(t.config!==void 0&&Object.assign(be,t.config),n.config={...be},ye()),ut(e,t,{parentApp:e,$q:n,lang:t.lang,iconSet:t.iconSet,onSSRHydrated:[]})},lang:V,iconSet:ot},H=j({name:`QCardSection`,props:{tag:{type:String,default:`div`},horizontal:Boolean},setup(e,{slots:t}){let n=T(()=>`q-card__section q-card__section--${e.horizontal?`horiz row no-wrap`:`vert`}`);return()=>l(e.tag,{class:n.value},ce(t.default))}}),ft=j({name:`QCard`,props:{...N,tag:{type:String,default:`div`},square:Boolean,flat:Boolean,bordered:Boolean},setup(e,{slots:n}){let{proxy:{$q:r}}=t(),i=M(e,r),a=T(()=>`q-card`+(i.value?` q-card--dark q-dark`:``)+(e.bordered?` q-card--bordered`:``)+(e.square?` q-card--square no-border-radius`:``)+(e.flat?` q-card--flat no-shadow`:``));return()=>l(e.tag,{class:a.value},ce(n.default))}});function pt(e,t,n){let r;function i(){r!==void 0&&(ve.remove(r),r=void 0)}return a(()=>{e.value&&i()}),{removeFromHistory:i,addToHistory(){r={condition:()=>n.value,handler:t},ve.add(r)}}}var mt=0,ht,gt,_t,vt=!1,yt,bt,xt,U=null;function St(e){Ct(e)&&ie(e)}function Ct(e){if(e.target===document.body||e.target.classList.contains(`q-layout__backdrop`))return!0;let t=ae(e),n=e.shiftKey&&!e.deltaX,r=!n&&Math.abs(e.deltaX)<=Math.abs(e.deltaY),i=n||r?e.deltaY:e.deltaX;for(let e=0;e<t.length;e++){let n=t[e];if(Ie(n,r))return r?i<0&&n.scrollTop===0?!0:i>0&&n.scrollTop+n.clientHeight===n.scrollHeight:i<0&&n.scrollLeft===0?!0:i>0&&n.scrollLeft+n.clientWidth===n.scrollWidth}return!0}function wt(e){e.target===document&&(document.scrollingElement.scrollTop=document.scrollingElement.scrollTop)}function Tt(e){vt||(vt=!0,requestAnimationFrame(()=>{vt=!1;let{height:t}=e.target,{clientHeight:n,scrollTop:r}=document.scrollingElement;(_t===void 0||t!==window.innerHeight)&&(_t=n-t,document.scrollingElement.scrollTop=r),r>_t&&(document.scrollingElement.scrollTop-=Math.ceil((r-_t)/8))}))}function Et(e){let t=document.body,n=window.visualViewport!==void 0;if(e===`add`){let{overflowY:e,overflowX:r}=window.getComputedStyle(t);ht=Me(window),gt=Ee(window),yt=t.style.left,bt=t.style.top,xt=window.location.href,t.style.left=`-${ht}px`,t.style.top=`-${gt}px`,r!==`hidden`&&(r===`scroll`||t.scrollWidth>window.innerWidth)&&t.classList.add(`q-body--force-scrollbar-x`),e!==`hidden`&&(e===`scroll`||t.scrollHeight>window.innerHeight)&&t.classList.add(`q-body--force-scrollbar-y`),t.classList.add(`q-body--prevent-scroll`),document.qScrollPrevented=!0,L.is.ios&&(n?(window.scrollTo(0,0),window.visualViewport.addEventListener(`resize`,Tt,O.passiveCapture),window.visualViewport.addEventListener(`scroll`,Tt,O.passiveCapture),window.scrollTo(0,0)):window.addEventListener(`scroll`,wt,O.passiveCapture))}L.is.desktop&&L.is.mac&&window[`${e}EventListener`](`wheel`,St,O.notPassive),e===`remove`&&(L.is.ios&&(n?(window.visualViewport.removeEventListener(`resize`,Tt,O.passiveCapture),window.visualViewport.removeEventListener(`scroll`,Tt,O.passiveCapture)):window.removeEventListener(`scroll`,wt,O.passiveCapture)),t.classList.remove(`q-body--prevent-scroll`),t.classList.remove(`q-body--force-scrollbar-x`),t.classList.remove(`q-body--force-scrollbar-y`),document.qScrollPrevented=!1,t.style.left=yt,t.style.top=bt,window.location.href===xt&&window.scrollTo(ht,gt),_t=void 0)}function Dt(e){let t=`add`;if(e===!0){if(mt++,U!==null){clearTimeout(U),U=null;return}if(mt>1)return}else{if(mt===0||(mt--,mt>0))return;if(t=`remove`,L.is.ios&&L.is.nativeMobile){U!==null&&clearTimeout(U),U=setTimeout(()=>{Et(t),U=null},100);return}}Et(t)}function Ot(){let e;return{preventBodyScroll(t){t!==e&&(e!==void 0||t)&&(e=t,Dt(t))}}}var kt=0,At={standard:`fixed-full flex-center`,top:`fixed-top justify-center`,bottom:`fixed-bottom justify-center`,right:`fixed-right items-center`,left:`fixed-left items-center`},jt={standard:[`scale`,`scale`],top:[`slide-down`,`slide-up`],bottom:[`slide-up`,`slide-down`],right:[`slide-left`,`slide-right`],left:[`slide-right`,`slide-left`]},Mt=j({name:`QDialog`,inheritAttrs:!1,props:{...Se,...he,transitionShow:String,transitionHide:String,persistent:Boolean,autoClose:Boolean,allowFocusOutside:Boolean,noEscDismiss:Boolean,noBackdropDismiss:Boolean,noRouteDismiss:Boolean,noRefocus:Boolean,noFocus:Boolean,noShake:Boolean,seamless:Boolean,maximized:Boolean,fullWidth:Boolean,fullHeight:Boolean,square:Boolean,backdropFilter:String,position:{type:String,default:`standard`,validator:e=>[`standard`,`top`,`bottom`,`left`,`right`].includes(e)}},emits:[...xe,`shake`,`click`,`escapeKey`],setup(n,{slots:r,emit:i,attrs:o}){let s=t(),c=e(null),d=e(!1),f=e(!1),p=null,m=null,h=!1,g=!1,_=T(()=>!n.persistent&&!n.noRouteDismiss&&!n.seamless),{preventBodyScroll:v}=Ot(),{registerTimeout:y}=_e(),{registerTick:b,removeTick:x}=Ce(),{transitionProps:S,transitionStyle:ee}=Ae(n,()=>jt[n.position][0],()=>jt[n.position][1]),C=T(()=>ee.value+(n.backdropFilter===void 0?``:`;backdrop-filter:${n.backdropFilter};-webkit-backdrop-filter:${n.backdropFilter}`)),{showPortal:w,hidePortal:E,portalIsAccessible:ne,renderPortal:D}=Te(s,c,fe,`dialog`),{hide:O}=ke({showing:d,hideOnRouteChange:_,handleShow:oe,handleHide:se,processOnMount:!0}),{addToHistory:k,removeFromHistory:re}=pt(d,O,_),ie=T(()=>`q-dialog__inner flex no-pointer-events q-dialog__inner--${n.maximized?`maximized`:`minimized`} q-dialog__inner--${n.position} ${At[n.position]}`+(f.value?` q-dialog__inner--animating`:``)+(n.fullWidth?` q-dialog__inner--fullwidth`:``)+(n.fullHeight?` q-dialog__inner--fullheight`:``)+(n.square?` q-dialog__inner--square`:``)),A=T(()=>d.value&&!n.seamless),j=T(()=>n.autoClose?{onClick:I}:{}),ae=T(()=>[`q-dialog fullscreen no-pointer-events q-dialog--${A.value?`modal`:`seamless`}`,o.class]);u(()=>n.maximized,e=>{d.value&&F(e)}),u(A,e=>{v(e),e?(Fe(ue),Oe(P)):(De(ue),Ne(P))});function oe(e){k(),m=!n.noRefocus&&document.activeElement!==null?document.activeElement:null,F(n.maximized),w(),f.value=!0,n.noFocus?x():(document.activeElement?.blur(),b(M)),y(()=>{if(s.proxy.$q.platform.is.ios){if(!n.seamless&&document.activeElement){let{top:e,bottom:t}=document.activeElement.getBoundingClientRect(),{innerHeight:n}=window,r=window.visualViewport===void 0?n:window.visualViewport.height;e>0&&t>r/2&&(document.scrollingElement.scrollTop=Math.min(document.scrollingElement.scrollHeight-r,t>=n?1/0:Math.ceil(document.scrollingElement.scrollTop+t-r/2))),document.activeElement.scrollIntoView()}g=!0,c.value.click(),g=!1}w(!0),f.value=!1,i(`show`,e)},n.transitionDuration)}function se(e){x(),re(),le(!0),f.value=!0,E(),m!==null&&(((e?.type.indexOf(`key`)===0?m.closest(`[tabindex]:not([tabindex^="-"])`):void 0)||m).focus(),m=null),y(()=>{E(!0),f.value=!1,i(`hide`,e)},n.transitionDuration)}function M(e){de(()=>{let t=c.value;if(t!==null){if(e!==void 0){let n=t.querySelector(e);if(n!==null){n.focus({preventScroll:!0});return}}t.contains(document.activeElement)||(t=t.querySelector(`[autofocus][tabindex], [data-autofocus][tabindex]`)||t.querySelector(`[autofocus] [tabindex], [data-autofocus] [tabindex]`)||t.querySelector(`[autofocus], [data-autofocus]`)||t,t.focus({preventScroll:!0}))}})}function N(e){e&&typeof e.focus==`function`?e.focus({preventScroll:!0}):M(),i(`shake`);let t=c.value;t!==null&&(t.classList.remove(`q-animate--scale`),t.classList.add(`q-animate--scale`),p!==null&&clearTimeout(p),p=setTimeout(()=>{p=null,c.value!==null&&(t.classList.remove(`q-animate--scale`),M())},170))}function P(){n.seamless||(n.persistent||n.noEscDismiss?!n.maximized&&!n.noShake&&N():(i(`escapeKey`),O()))}function le(e){p!==null&&(clearTimeout(p),p=null),(e||d.value)&&(F(!1),n.seamless||(v(!1),De(ue),Ne(P))),e||(m=null)}function F(e){e?h||=(kt<1&&document.body.classList.add(`q-body--dialog`),kt++,!0):h&&=(kt<2&&document.body.classList.remove(`q-body--dialog`),kt--,!1)}function I(e){g||(O(e),i(`click`,e))}function L(e){!n.persistent&&!n.noBackdropDismiss?O(e):n.noShake||N()}function ue(e){!n.allowFocusOutside&&ne.value&&!Ve(c.value,e.target)&&M(`[tabindex]:not([tabindex="-1"])`)}Object.assign(s.proxy,{focus:M,shake:N,__updateRefocusTarget(e){m=e||null}}),a(le);function fe(){return l(`div`,{role:`dialog`,"aria-modal":A.value?`true`:`false`,...o,class:ae.value},[l(te,{name:`q-transition--fade`,appear:!0},()=>A.value?l(`div`,{class:`q-dialog__backdrop fixed-full`,style:C.value,"aria-hidden":`true`,tabindex:-1,onClick:L}):null),l(te,S.value,()=>d.value?l(`div`,{ref:c,class:ie.value,style:ee.value,tabindex:-1,...j.value},ce(r.default)):null)])}return D}}),Nt=F(`migration`,()=>{let t=e({state:`idle`});async function n(){try{let e=await fetch(`/api/migration/status`);if(!e.ok)return;t.value=await e.json()}catch{}}function r(e){t.value={...e}}return{status:t,fetchInitial:n,update:r}}),Pt={class:`text-h6`},Ft={class:`text-h6`},It={class:`text-h6 text-negative`},Lt={class:`q-mt-sm`},Rt={key:0,class:`q-mt-md text-caption`},zt={class:`q-mt-md text-caption`},Bt=c({__name:`MigrationOverlay`,setup(e){let{t}=Ue(),n=Nt(),i=T(()=>[`backing-up`,`running`,`error`].includes(n.status.state));return r(()=>{n.fetchInitial()}),(e,r)=>(s(),b(Mt,{modelValue:i.value,"onUpdate:modelValue":r[0]||=e=>i.value=e,persistent:``,"no-backdrop-dismiss":``},{default:f(()=>[h(ft,{style:{"min-width":`400px`}},{default:f(()=>[S(n).status.state===`backing-up`?(s(),b(H,{key:0},{default:f(()=>[C(`div`,Pt,_(S(t)(`migration.backing_up`)),1),h(se,{class:`q-mt-md`})]),_:1})):S(n).status.state===`running`?(s(),b(H,{key:1},{default:f(()=>[C(`div`,Ft,_(S(t)(`migration.running`,{processed:S(n).status.processed,total:S(n).status.total})),1),h(ze,{value:S(n).status.total>0?S(n).status.processed/S(n).status.total:0,class:`q-mt-md`},null,8,[`value`])]),_:1})):S(n).status.state===`error`?(s(),b(H,{key:2},{default:f(()=>[C(`div`,It,_(S(t)(`migration.error`)),1),C(`div`,Lt,_(S(n).status.errorMessage),1),S(n).status.backupPath?(s(),m(`div`,Rt,_(S(t)(`migration.backup_location`,{path:S(n).status.backupPath})),1)):y(``,!0),C(`div`,zt,_(S(t)(`migration.retry`)),1)]),_:1})):y(``,!0)]),_:1})]),_:1},8,[`modelValue`]))}}),Vt=F(`templates`,{state:()=>({templates:[],defaultSlugs:[],loading:!1,loaded:!1}),getters:{isDefault:e=>t=>e.defaultSlugs.includes(t)},actions:{async fetchTemplates(){if(!this.loading){this.loading=!0;try{let e=await fetch(`/api/templates`);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();this.templates=t.templates,this.defaultSlugs=t.defaultSlugs??[],this.loaded=!0}catch(e){console.error(`[templates store] fetchTemplates failed:`,e)}finally{this.loading=!1}}},async createTemplate(e){let t=await fetch(`/api/templates`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}let n=await t.json();return this.templates.push(n),n},async updateTemplate(e,t){let n=await fetch(`/api/templates/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}let r=await n.json(),i=this.templates.findIndex(t=>t.slug===e);return i>=0&&(this.templates[i]=r),r},async reloadDefaults(){let e=await fetch(`/api/templates/reload-defaults`,{method:`POST`});if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t.error??`HTTP ${e.status}`)}let t=await e.json();return t.added.length>0&&await this.fetchTemplates(),t},async deleteTemplate(e){let t=await fetch(`/api/templates/${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}this.templates=this.templates.filter(t=>t.slug!==e)},async resetToDefault(e){let t=await fetch(`/api/templates/${encodeURIComponent(e)}/reset-default`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({error:`Reset failed`}));throw Error(e.error??`Reset failed`)}let{template:n}=await t.json(),r=this.templates.findIndex(t=>t.slug===e);return r>=0?this.templates[r]=n:this.templates.push(n),n}}}),Ht=0,Ut={},Wt={},W={},Gt={},Kt=/^\s*$/,qt=[],Jt=[void 0,null,!0,!1,``],Yt=[`top-left`,`top-right`,`bottom-left`,`bottom-right`,`top`,`bottom`,`left`,`right`,`center`],Xt=[`top-left`,`top-right`,`bottom-left`,`bottom-right`],Zt={positive:{icon:e=>e.iconSet.type.positive,color:`positive`},negative:{icon:e=>e.iconSet.type.negative,color:`negative`},warning:{icon:e=>e.iconSet.type.warning,color:`warning`,textColor:`dark`},info:{icon:e=>e.iconSet.type.info,color:`info`},ongoing:{group:!1,timeout:0,spinner:!0,color:`grey-8`}};function Qt(e,t,n){if(!e)return tn(`parameter required`);let r,i={textColor:`white`};if(e.ignoreDefaults||Object.assign(i,Ut),R(e)||(i.type&&Object.assign(i,Zt[i.type]),e={message:e}),Object.assign(i,Zt[e.type||i.type],e),typeof i.icon==`function`&&(i.icon=i.icon(t)),i.spinner?i.spinner=i.spinner===!0?se:p(i.spinner):i.spinner=!1,i.meta={hasMedia:!!(i.spinner||i.icon||i.avatar),hasText:en(i.message)||en(i.caption)},i.position){if(!Yt.includes(i.position))return tn(`wrong position`,e)}else i.position=`bottom`;if(Jt.includes(i.timeout))i.timeout=5e3;else{let t=Number.parseFloat(i.timeout);if(!Number.isFinite(t)||t<0)return tn(`wrong timeout`,e);i.timeout=t}i.timeout===0?i.progress=!1:i.progress&&(i.meta.progressClass=`q-notification__progress`+(i.progressClass?` ${i.progressClass}`:``),i.meta.progressStyle={animationDuration:`${i.timeout+1e3}ms`});let a=[...Array.isArray(e.actions)?e.actions:[],...!e.ignoreDefaults&&Array.isArray(Ut.actions)?Ut.actions:[],...Array.isArray(Zt[e.type]?.actions)?Zt[e.type].actions:[]],{closeBtn:o}=i;if(o&&a.push({label:typeof o==`string`?o:t.lang.label.close}),i.actions=a.map(({handler:e,noDismiss:t,...n})=>({flat:!0,...n,onClick:typeof e==`function`?()=>{e(),t||s()}:()=>{s()}})),i.multiLine===void 0&&(i.multiLine=i.actions.length>1),Object.assign(i.meta,{class:`q-notification row items-stretch q-notification--${i.multiLine?`multi-line`:`standard`}`+(i.color===void 0?``:` bg-${i.color}`)+(i.textColor===void 0?``:` text-${i.textColor}`)+(i.classes===void 0?``:` ${i.classes}`),wrapperClass:`q-notification__wrapper col relative-position border-radius-inherit `+(i.multiLine?`column no-wrap justify-center`:`row items-center`),contentClass:`q-notification__content row items-center`+(i.multiLine?``:` col`),leftClass:i.meta.hasText?`additional`:`single`,attrs:{role:`alert`,...i.attrs}}),i.group===!1?(i.group=void 0,i.meta.group=void 0):((i.group===void 0||i.group===!0)&&(i.group=[i.message,i.caption,i.multiline,...i.actions.map(e=>`${e.label}*${e.icon}`)].join(`|`)),i.meta.group=i.group+`|`+i.position),i.actions.length===0?i.actions=void 0:i.meta.actionsClass=`q-notification__actions row items-center `+(i.multiLine?`justify-end`:`col-auto`)+(i.meta.hasMedia?` q-notification__actions--with-media`:``),n!==void 0){n.notif.meta.timer&&(clearTimeout(n.notif.meta.timer),n.notif.meta.timer=void 0),i.meta.uid=n.notif.meta.uid;let e=W[i.position].value.indexOf(n.notif);W[i.position].value[e]=i}else{let t=Wt[i.meta.group];if(t===void 0){if(i.meta.uid=Ht++,i.meta.badge=1,[`left`,`right`,`center`].includes(i.position))W[i.position].value.splice(Math.floor(W[i.position].value.length/2),0,i);else{let e=i.position.includes(`top`)?`unshift`:`push`;W[i.position].value[e](i)}i.group!==void 0&&(Wt[i.meta.group]=i)}else{if(t.meta.timer&&(clearTimeout(t.meta.timer),t.meta.timer=void 0),i.badgePosition!==void 0){if(!Xt.includes(i.badgePosition))return tn(`wrong badgePosition`,e)}else i.badgePosition=`top-${i.position.includes(`left`)?`right`:`left`}`;i.meta.uid=t.meta.uid,i.meta.badge=t.meta.badge+1,i.meta.badgeClass=`q-notification__badge q-notification__badge--${i.badgePosition}`+(i.badgeColor===void 0?``:` bg-${i.badgeColor}`)+(i.badgeTextColor===void 0?``:` text-${i.badgeTextColor}`)+(i.badgeClass?` ${i.badgeClass}`:``);let n=W[i.position].value.indexOf(t);W[i.position].value[n]=Wt[i.meta.group]=i}}let s=()=>{$t(i),r=void 0};if(i.timeout>0&&(i.meta.timer=setTimeout(()=>{i.meta.timer=void 0,s()},i.timeout+1e3)),i.group!==void 0)return t=>{t===void 0?s():tn(`trying to update a grouped one which is forbidden`,e)};if(r={dismiss:s,config:e,notif:i},n!==void 0){Object.assign(n,r);return}return e=>{r!==void 0&&(e===void 0?r.dismiss():Qt({...r.config,...e,group:!1,position:i.position},t,r))}}function $t(e){e.meta.timer&&(clearTimeout(e.meta.timer),e.meta.timer=void 0);let t=W[e.position].value.indexOf(e);if(t!==-1){e.group!==void 0&&delete Wt[e.meta.group];let n=qt[String(e.meta.uid)];if(n){let{width:e,height:t}=getComputedStyle(n);n.style.left=`${n.offsetLeft}px`,n.style.width=e,n.style.height=t}W[e.position].value.splice(t,1),typeof e.onDismiss==`function`&&e.onDismiss()}}function en(e){return e!=null&&!Kt.test(e)}function tn(e,t){return console.error(`Notify: ${e}`,t),!1}function nn(){return j({name:`QNotifications`,devtools:{hide:!0},setup(){return()=>l(`div`,{class:`q-notifications`},Yt.map(e=>l(E,{key:e,class:Gt[e],tag:`div`,name:`q-notification--${e}`},()=>W[e].value.map(e=>{let t=e.meta,n=[];if(t.hasMedia&&(e.spinner?n.push(l(e.spinner,{class:`q-notification__spinner q-notification__spinner--`+t.leftClass,color:e.spinnerColor,size:e.spinnerSize})):e.icon?n.push(l(P,{class:`q-notification__icon q-notification__icon--`+t.leftClass,name:e.icon,color:e.iconColor,size:e.iconSize,role:`img`})):e.avatar&&n.push(l(je,{class:`q-notification__avatar q-notification__avatar--`+t.leftClass},()=>l(`img`,{src:e.avatar,"aria-hidden":`true`})))),t.hasText){let t,r={class:`q-notification__message col`};if(e.html)r.innerHTML=e.caption?`<div>${e.message}</div><div class="q-notification__caption">${e.caption}</div>`:e.message;else{let n=[e.message];t=e.caption?[l(`div`,n),l(`div`,{class:`q-notification__caption`},[e.caption])]:n}n.push(l(`div`,r,t))}let r=[l(`div`,{class:t.contentClass},n)];return e.progress&&r.push(l(`div`,{key:`${t.uid}|p|${t.badge}`,class:t.progressClass,style:t.progressStyle})),e.actions&&r.push(l(`div`,{class:t.actionsClass},e.actions.map(e=>l(He,e)))),t.badge>1&&r.push(l(`div`,{key:`${t.uid}|${t.badge}`,class:e.meta.badgeClass,style:e.badgeStyle},[t.badge])),l(`div`,{ref:e=>{qt[String(t.uid)]=e},key:t.uid,class:t.class,...t.attrs},[l(`div`,{class:t.wrapperClass},r)])}))))}})}var rn={setDefaults(e){R(e)&&Object.assign(Ut,e)},registerType(e,t){R(t)&&(Zt[e]=t)},install({$q:t,parentApp:n}){if(t.notify=this.create=e=>Qt(e,t),t.notify.setDefaults=this.setDefaults,t.notify.registerType=this.registerType,t.config.notify!==void 0&&this.setDefaults(t.config.notify),!this.__installed){Yt.forEach(t=>{W[t]=e([]);let n=t===`left`||t===`center`||t===`right`?`center`:t.includes(`top`)?`top`:`bottom`,r=t.includes(`left`)?`start`:t.includes(`right`)?`end`:`center`;Gt[t]=`q-notifications__list q-notifications__list--${n} fixed column no-wrap ${t===`left`||t===`right`?`items-${t===`left`?`start`:`end`} justify-center`:t===`center`?`flex-center`:`items-${r}`}`});let t=ge(`q-notify`);ct(nn(),n).mount(t)}}},an={"common.save":`Speichern`,"common.cancel":`Abbrechen`,"common.delete":`Löschen`,"common.close":`Schließen`,"common.details":`Details`,"whatsNew.title":`Neuigkeiten`,"common.loading":`Laden...`,"common.search":`Suchen...`,"common.refresh":`Aktualisieren`,"common.copy":`Kopieren`,"common.copied":`In die Zwischenablage kopiert`,"common.copyFailed":`Kopieren fehlgeschlagen`,"common.add":`Hinzufügen`,"folderPicker.title":`Ordner auswählen`,"folderPicker.parent":`Übergeordneter Ordner`,"folderPicker.empty":`Keine Unterordner`,"folderPicker.select":`Diesen Ordner auswählen`,"common.start":`Starten`,"common.stop":`Stoppen`,"common.archive":`Archivieren`,"common.unarchive":`Wiederherstellen`,"common.selectWorkspace":`Arbeitsbereich auswählen`,"common.noResults":`Keine Ergebnisse für „{query}"`,"common.send":`senden`,"common.newLine":`neue Zeile`,"common.history":`Verlauf`,"common.justNow":`gerade eben`,"common.minutesAgo":`vor {count}m`,"common.hoursAgo":`vor {count}h`,"common.daysAgo":`vor {count}T`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Leistungsfähigstes Modell — Nachfolger von Opus 4.8, 1M Kontext, adaptive thinking`,"model.mythos5Description":`Fable 5 ohne Sicherheitsklassifikatoren — eingeschränkter Zugriff (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude wählt das optimale Modell`,"model.opus48Description":`Leistungsfähigstes Opus — Long-Horizon-Coding, 1M-Kontext standardmäßig, hoher Effort standardmäßig`,"model.opus47ClassicDescription":`Neuestes Opus, am leistungsfähigsten`,"model.opus471mDescription":`Neuestes Opus, 1M Kontext`,"model.opusClassicDescription":`Am leistungsstärksten`,"model.opus1mDescription":`Am leistungsstärksten, 1M Kontext`,"model.sonnetClassicDescription":`Ausgewogen`,"model.sonnet1mDescription":`Ausgewogen, 1M Kontext`,"model.haikuDescription":`Am schnellsten`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Empfohlen für komplexes Coding (erfordert ChatGPT-Anmeldung)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Standard-Fallback — starkes Reasoning, funktioniert mit API-Key-Authentifizierung`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Schnell und effizient — ideal für reaktive Aufgaben und Subagenten`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Auf Coding spezialisiertes Modell für komplexe Softwareentwicklung`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Engine entscheidet automatisch`,"reasoning.minimalDescription":`Schnellstes, oberflächlichstes Reasoning`,"reasoning.lowDescription":`Schneller, weniger Tiefe`,"reasoning.mediumDescription":`Ausgewogen`,"reasoning.highDescription":`Mehr Tiefe`,"reasoning.xhighDescription":`Erweiterte Tiefe, langfristige Aufgaben`,"reasoning.maxDescription":`Maximale Tiefe`,"agentPermissionMode.label":`Berechtigungsmodus`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Edits akzeptieren`,"agentPermissionMode.interactive":`Interaktiv`,"agentPermissionMode.tooltip":`Wie der Agent Tool-Berechtigungen handhabt. Plan: schreibgeschützt, keine Schreibvorgänge. Bypass: alle Nachfragen überspringen. Strict: Datei-Edits automatisch akzeptieren, allow/deny für den Rest beachten. Interaktiv: vor jedem Tool den Benutzer per Berechtigungs-Panel fragen.`,"agentPermissionMode.autoLoopOverride":`Auto-Loop erzwingt einen Modus außer Plan — Plan blockiert MCP-Tools und Edits, die der Loop benötigt. Wähle stattdessen Bypass, Strict oder Interaktiv.`,"agentPermissionMode.autoLoopLocked":`Auf Bypass gesperrt, solange Auto-Loop aktiv ist — jeder andere Modus würde den Loop bei Berechtigungsabfragen anhalten. AskUserQuestion funktioniert weiterhin.`,"workspaceList.title":`Arbeitsbereiche`,"workspaceList.needsAttention":`Aufmerksamkeit erforderlich`,"workspaceList.running":`Aktiv`,"workspaceList.idle":`Inaktiv`,"workspaceList.archived":`Archiviert`,"workspaceList.noWorkspaces":`Noch keine Arbeitsbereiche`,"workspaceList.footer":`{count} Arbeitsbereich | {count} Arbeitsbereiche`,"workspaceList.footerRunning":`{count} aktiv`,"workspaceList.deleteDialog.title":`Arbeitsbereich löschen?`,"workspaceList.deleteDialog.deleteLocal":`Lokalen Branch löschen`,"workspaceList.deleteDialog.deleteRemote":`Remote-Branch löschen`,"workspaceList.deleteDialog.warning":`Achtung: Diese Aktion ist auf dem Remote unwiderruflich.`,"workspaceList.deleteArchivedDialog.tooltip":`Alle archivierten Arbeitsbereiche löschen`,"workspaceList.deleteArchivedDialog.title":`Alle archivierten Arbeitsbereiche löschen?`,"workspaceList.deleteArchivedDialog.message":`Dadurch werden die {count} archivierten Arbeitsbereiche endgültig gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.`,"workspacePage.selectWorkspace":`Arbeitsbereich auswählen, um zu beginnen`,"workspacePage.session":`Sitzung #{n}`,"workspacePage.newSession":`+ Neue Sitzung`,"workspacePage.renameSession":`Umbenennen`,"workspacePage.renameSessionTitle":`Sitzung umbenennen`,"workspacePage.sessionNameLabel":`Sitzungsname`,"workspacePage.sessionEndedNotice":`Diese Sitzung ist beendet. Erstelle eine neue Sitzung um fortzufahren.`,"workspacePage.renameFailed":`Umbenennung fehlgeschlagen`,"workspacePage.createSessionFailed":`Sitzung konnte nicht erstellt werden`,"workspacePage.startFailed":`Start fehlgeschlagen`,"workspacePage.stopFailed":`Stopp fehlgeschlagen`,"workspacePage.interrupt":`Unterbrechen`,"workspacePage.interrupted":`Agent unterbrochen — wartet auf Ihre nächste Nachricht`,"workspacePage.archivedBanner":`Archivierter Workspace — schreibgeschützt`,"workspacePage.worktreePurgedBanner":`Worktree gelöscht — Verlauf erhalten, keine Wiederherstellung in dieser Version`,"workspacePage.worktreePurgedTooltip":"Der Worktree-Ordner wurde von der Festplatte gelöscht, um Speicherplatz zurückzugewinnen. Chat-Verlauf, Sitzungen und PR-Metadaten bleiben hier abrufbar, aber das Arbeitsverzeichnis existiert lokal nicht mehr. Eine zukünftige Kōbō-Version wird den Worktree aus der gemergten PR wiederherstellen können — vorerst musst du ihn manuell über `gh pr checkout` oder `git worktree add` neu erstellen.","workspacePage.pendingInitialPromptBanner":`Ein anfänglicher Prompt ist ausstehend — der Agent hat ihn nie erhalten (Setup-Script abgestürzt oder Workspace nie gestartet). Klicke auf Start, um ihn jetzt zu senden.`,"workspacePage.unarchived":`Workspace dearchiviert`,"workspacePage.unarchiveFailed":`Dearchivierung fehlgeschlagen`,"workspacePage.interruptFailed":`Unterbrechung fehlgeschlagen`,"workspacePage.interruptTooltip":`Sanfte Unterbrechung (wie Escape) — stoppt das aktuelle Tool, hält die Sitzung aktiv`,"workspacePage.pendingNextRun":`Beim nächsten Start angewendet`,"search.title":`Suche`,"search.tooltip":`Agent-Verlauf durchsuchen`,"search.placeholder":`In allen Agent-Nachrichten suchen…`,"search.includeArchived":`Archivierte Arbeitsbereiche einbeziehen`,"search.loading":`Suche läuft…`,"search.noResults":`Keine Treffer`,"search.error":`Suche fehlgeschlagen: {message}`,"search.resultCount":`{n} Treffer`,"search.eventType.userMessage":`Sie`,"search.eventType.agentOutput":`Agent`,"activityFeed.empty":`Noch keine Aktivität`,"activityFeed.emptyHint":`Starten Sie einen Arbeitsbereich, um die Agentenausgabe hier zu sehen`,"activityFeed.initialPrompt":`Initialer Prompt`,"activityFeed.you":`Sie`,"activityFeed.agent":`Agent`,"activityFeed.question":`Frage`,"activityFeed.goToPrevious":`Zur vorherigen Nachricht`,"activityFeed.scrollToBottom":`Nach unten scrollen`,"activityFeed.sendAnswers":`Antworten senden`,"agentBusy.banner":`Agent ist beschäftigt`,"agentBusy.subagentsRunning":`1 Sub-Agent aktiv | {n} Sub-Agents aktiv`,"agentBusy.viewSubagents":`Sub-Agents anzeigen`,"agentBusy.pendingMessage":`Warten — Agent ist beschäftigt`,"terminal.title":`Terminal`,"terminal.open":`Terminal öffnen`,"terminal.close":`Terminal schließen`,"terminal.noWorkspace":`Workspace auswählen`,"terminal.noWorktree":`Worktree noch nicht erstellt`,"terminal.error":`Terminalfehler`,"terminal.exited":`Terminal beendet`,"chatInput.placeholder":`Nachricht... (/ für Skills)`,"chatInput.fileSearchHint":`Datei suchen`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Bild anhängen`,"chatInput.queueBanner":`Nachricht in Warteschlange — wird gesendet, wenn der Agent fertig ist`,"chatInput.cancelQueue":`Warteschlange abbrechen`,"chatInput.autoLoopBanner":`Auto-Loop läuft — beende ihn, um eine Nachricht zu senden`,"chatInput.awaitingUserBanner":`Der Agent wartet auf deine Antwort oben — antworte über das Fragefenster`,"chatInput.autoLoopStop":`Beenden`,"koboCommand.checkProgressDesc":`Fortschritt bei Aufgaben und Akzeptanzkriterien prüfen`,"chatInput.uploading":`Wird hochgeladen...`,"voice.title":`Sprachtranskription`,"voice.enabled":`Lokale Sprachtranskription aktivieren`,"voice.pttKey":`Push-to-talk-Taste`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Strg+Leertaste`,"voice.language":`Sprache (auto oder Code)`,"voice.model":`Aktives Modell`,"voice.commandPath":`Pfad zur Whisper-Binärdatei (optional)`,"voice.ffmpegPath":`Pfad zur ffmpeg-Binärdatei (optional)`,"voice.temperature":`Temperatur`,"voice.temperatureHint":`Niedriger = deterministischer, höher = flexibler, aber potenziell weniger stabil.`,"voice.initialPrompt":`Initial Prompt (optional)`,"voice.initialPromptHint":`Optionaler Kontext, um Whisper bei Namen, Fachbegriffen oder domänenspezifischem Vokabular zu helfen.`,"voice.translateToEnglish":`Ins Englische übersetzen`,"voice.translateToEnglishHint":`Wenn aktiviert, wird nicht-englische Sprache ins Englische übersetzt statt originalgetreu transkribiert.`,"voice.suppressNst":`Nicht-Sprach-Tokens unterdrücken`,"voice.suppressNstHint":`Versucht, Nicht-Sprach-Artefakte im Transkript zu reduzieren.`,"voice.installLink":`whisper.cpp installieren`,"voice.installGuideTitle":`Installationsanleitung`,"voice.installGuideIntro":`Installiere whisper.cpp und ffmpeg und setze bei Bedarf unten die Binärpfade.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Nach dem CMake-Build liegt die Whisper-Binärdatei üblicherweise hier: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Danach in diesem Bereich „Pfad zur Whisper-Binärdatei“ und „Pfad zur ffmpeg-Binärdatei“ setzen (oder leer lassen, wenn im PATH).`,"voice.noneModel":`Kein aktives Modell`,"voice.notInstalled":`nicht installiert`,"voice.download":`Herunterladen`,"voice.delete":`Löschen`,"voice.holdToTalk":`Zum Sprechen gedrückt halten`,"voice.recording":`Aufnahme...`,"voice.transcribing":`Transkription...`,"voice.notSupported":`Sprachaufnahme wird in diesem Browser nicht unterstützt`,"voice.errorMicPermission":`Mikrofonberechtigung verweigert`,"voice.errorTranscription":`Sprachtranskription fehlgeschlagen`,"voice.downloadFailed":`Modelldownload fehlgeschlagen`,"voice.deleteFailed":`Modell konnte nicht gelöscht werden`,"voice.errorDisabled":`Sprachtranskription ist in den Einstellungen deaktiviert`,"voice.errorModelMissing":`Kein aktives Sprachmodell konfiguriert`,"voice.errorModelNotInstalled":`Das aktive Sprachmodell ist nicht installiert`,"voice.errorAudioInvalid":`Audioaufnahme ist ungültig oder leer`,"voice.errorLanguageInvalid":`Sprachkonfiguration ist ungültig`,"voice.errorRuntimeMissing":`Whisper-Runtime ist nicht installiert oder nicht im PATH`,"voice.maxDurationReached":`Maximale Aufnahmedauer erreicht`,"voice.runtimeReady":`Runtime bereit: {command}`,"voice.runtimeMissing":`Runtime fehlt: {command}`,"voice.ffmpegReady":`ffmpeg bereit`,"voice.ffmpegMissing":`ffmpeg fehlt`,"voice.sectionRuntime":`Runtime-Status`,"voice.sectionActivation":`Aktivierung`,"voice.sectionModels":`Whisper-Modelle`,"voice.sectionAdvanced":`Erweiterte Optionen`,"voice.sectionBehavior":`Transkriptionsverhalten`,"voice.sectionBinaries":`Binärpfade`,"voice.downloadModels":`Modell herunterladen`,"voice.cancelFailed":`Abbrechen des Downloads fehlgeschlagen`,"createPage.title":`Woran möchten Sie arbeiten?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion aktiviert`,"createPage.importNotion":`Aus Notion importieren`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`Die URL muss mit https://www.notion.so/ oder https://app.notion.com/ beginnen`,"createPage.notionAutoExtract":`Unteraufgaben und Akzeptanzkriterien werden automatisch extrahiert.`,"createPage.notionPanelChoiceLabel":`Diese URL verweist auf eine Unterseite (?p=). An welcher möchtest du arbeiten?`,"createPage.notionPanelOption":`Unterseite (Panel)`,"createPage.notionPanelOptionDesc":`Die Seite, die du angesehen hast — empfohlen`,"createPage.notionParentOption":`Übergeordnete Seite`,"createPage.notionParentOptionDesc":`Das Epic / die Datenbank dazu`,"createPage.importSentry":`Sentry importieren`,"createPage.sentryEnabled":`Sentry aktiviert`,"createPage.sentryPlaceholder":`https://ihre-org.sentry.io/issues/123456`,"createPage.sentryValidation":`Die URL muss auf ein Sentry-Issue zeigen (/issues/<id>)`,"createPage.sentryAutoExtract":`Sentry-Issue wird automatisch importiert`,"createPage.sentryExtractHint":`Kobo extrahiert das Issue und schreibt es nach .ai/thoughts/`,"createPage.workspaceName":`Name des Arbeitsbereichs (Standard: Notion-Seitentitel)`,"createPage.workspaceNamePlaceholder":`Name des Arbeitsbereichs...`,"createPage.instructions":`Zusätzliche Anweisungen (optional)...`,"createPage.instructionsPlaceholder":`Aufgabe beschreiben...`,"createPage.manualHint":`Kein Notion-Ticket? Fügen Sie Ihre Aufgaben und Akzeptanzkriterien manuell hinzu — sie werden dem Claude-Agent als Kontext mitgegeben.`,"createPage.tasks":`Aufgaben ({count})`,"createPage.addTask":`Aufgabe hinzufügen...`,"createPage.acceptanceCriteria":`Akzeptanzkriterien ({count})`,"createPage.addCriterion":`Kriterium hinzufügen...`,"createPage.projectPath":`Projektpfad eingeben`,"createPage.branchType":`Branch-Typ`,"createPage.branch":`Branch`,"createPage.noBranches":`Keine Branches gefunden`,"createPage.enterPath":`Projektpfad eingeben`,"createPage.create":`Erstellen`,"createPage.skipSetupScript":`Setup-Skript überspringen`,"createPage.attachWorktreeToggle":`Bestehenden Worktree anhängen`,"createPage.attachWorktreeEnabled":`Bestehenden Worktree wiederverwenden`,"createPage.worktreePickerLabel":`Bestehender Worktree`,"createPage.noOrphanWorktrees":`Kein verwaister Worktree in diesem Projekt`,"createPage.pickWorktreeRequired":`Bitte einen Worktree zum Anhängen auswählen`,"createPage.notionExtractHint":`Unteraufgaben und Akzeptanzkriterien werden aus der Notion-Seite extrahiert.`,"createPage.notionImportHint":`Klicken Sie auf „Aus Notion importieren", um Unteraufgaben automatisch aus einem Ticket zu extrahieren.`,"createPage.errorCreating":`Fehler beim Erstellen des Arbeitsbereichs.`,"createPage.branchAdjusted":"Branch existierte bereits — stattdessen `{branch}` erstellt. Der zugehörige Worktree-Ordner verwendet das gleiche Suffix.","createPage.validationNotionUrl":`Bitte eine gültige Notion-URL einfügen (https://www.notion.so/... oder https://app.notion.com/...).`,"createPage.validationDescription":`Bitte beschreiben Sie die Aufgabe.`,"createPage.validationName":`Bitte geben Sie einen Arbeitsbereichnamen an.`,"createPage.validationPath":`Bitte geben Sie den Projektpfad ein.`,"createPage.validationBranch":`Bitte wählen Sie einen Branch aus.`,"settings.title":`Einstellungen`,"settings.language":`Sprache`,"settings.projectColor":`Farbe`,"settings.projectColorClear":`Löschen`,"settings.projectColorDefault":`Standard (grau)`,"settings.workspaceListSection":`Workspace-Liste`,"settings.flattenWorkspaceList":`Workspace-Liste flach anzeigen`,"settings.flattenWorkspaceListHint":`Zeigt alle Workspaces in einer flachen Liste mit Projekt-Badge, anstatt nach Projekt gruppiert.`,"settings.skillSuite.section":`Skill-Suite`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Benutzerdefiniert`,"settings.skillSuite.superpowersHint":`Opinionierter TDD / Brainstorm / Plan-Workflow (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Garry Tans Suite — /review, /ship, /qa, /office-hours usw. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Beide Suites lassen sich kombinieren — superpowers für Methodik (Brainstorm / TDD / Pläne / Prinzipien-Review), gstack für konkrete Workflows (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Bearbeite die vier Prompts unten selbst. Beginnt mit der agnostischen Basis.`,"settings.skillSuite.reloadDefaults":`Standard wiederherstellen`,"settings.skillSuite.reloadDefaultsConfirm":`Die vier benutzerdefinierten Prompts durch die agnostischen Standardwerte ersetzen?`,"settings.skillSuite.customPrompts":`Benutzerdefinierte Prompts`,"settings.skillSuite.reviewTemplate":`Review-Vorlage`,"settings.skillSuite.autoLoopReviewGate":`Auto-Loop Review-Gate`,"settings.skillSuite.autoLoopGroomingIntro":`Auto-Loop Grooming-Intro`,"settings.skillSuite.qaTemplate":`QA-Vorlage`,"settings.skillSuite.brainstormingInstruction":`Anweisung für die Brainstorming-Phase`,"settings.global":`Allgemein`,"settings.projects":`Projekte`,"settings.globalSettings":`Allgemeine Einstellungen`,"settings.defaultModel":`Standardmodell`,"settings.defaultModelClaude":`Standardmodell (Claude Code)`,"settings.defaultModelCodex":`Standardmodell (OpenAI Codex)`,"settings.agentPermissions":`Agentenberechtigungen`,"settings.skipPermissions":`Berechtigungsabfragen überspringen (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Achtung: Wird diese Option deaktiviert, werden alle Tool-Berechtigungen (Write, Edit, Bash...) im Headless-Modus automatisch abgelehnt. Der Agent kann dann nur lesen.`,"settings.notifications":`Benachrichtigungen`,"settings.browserNotifications":`Browser-Benachrichtigung wenn Agent fertig ist`,"settings.audioNotifications":`Ton-Benachrichtigung wenn Agent fertig ist`,"settings.notificationSound":`Benachrichtigungston`,"settings.notificationSoundPreview":`Anhören`,"settings.notificationVolume":`Lautstärke`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Arbeit erledigt`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Das wird knallen`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Standard-Berechtigungsmodus`,"settings.defaultPermissionModeClaude":`Standard-Berechtigungsmodus (Claude Code)`,"settings.defaultPermissionModeCodex":`Standard-Berechtigungsmodus (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Modus bei der Erstellung eines neuen Workspaces. Plan = nur lesen, Bypass = keine Nachfragen, Strict = Edits automatisch akzeptieren mit allow-list, Interaktiv = vor jedem Tool fragen.`,"settings.activityFeed":`Aktivitätsfeed`,"settings.verboseMessages":`Ausführliche Systemnachrichten anzeigen (task_progress, task_started)`,"settings.availableVariables":`Verfügbare Template-Variablen`,"settings.prPromptTemplate":`PR-Prompt-Vorlage`,"settings.prPromptPlaceholder":`Anweisungen für den Agenten bei der Erstellung von GitHub-PRs...`,"settings.prPromptHint":`Verwenden Sie die oben aufgeführten Platzhalter (doppelte geschweifte Klammern).`,"settings.reviewPromptTemplate":`Review-Prompt-Vorlage`,"settings.reviewPromptPlaceholder":`Anweisungen für den Agenten bei der Review von Branch-Änderungen...`,"settings.ciFixPromptTemplate":`CI-Fix-Prompt-Vorlage`,"settings.ciFixPromptHint":`Wird an den Agenten gesendet, wenn die CI eines Workspaces fehlschlägt. Variablen (doppelte geschweifte Klammern): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Den Agenten bitten, die fehlschlagenden CI-Jobs zu diagnostizieren und zu beheben...`,"settings.finalizationPromptTemplate":`Auto-Loop-Finalisierungs-Prompt`,"settings.finalizationPromptHint":`Standard-Prompt für die letzte Auto-Loop-Iteration (abschließende Qualitätsprüfungen). Wird verwendet, wenn ein Projekt seinen eigenen Finalisierungs-Prompt leer lässt.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Notion-Initial-Prompt`,"settings.notionInitialPrompt.help":`Wird an den Workspace-Erstellungsprompt angehängt, wenn der Workspace ein Notion-Ticket hat. Variablen: {variables}.`,"settings.notionInitialPrompt.project":`Notion-Initial-Prompt (Überschreibung)`,"settings.sentryInitialPrompt":`Sentry-Initial-Prompt`,"settings.sentryInitialPrompt.help":`Wird an den Workspace-Erstellungsprompt angehängt, wenn der Workspace ein Sentry-Issue hat. Variablen: {variables}.`,"settings.sentryInitialPrompt.project":`Sentry-Initial-Prompt (Überschreibung)`,"settings.initialPrompt.inheritHint":`Leer lassen, um zu erben. Geben Sie ein Leerzeichen ein, um die Injektion auf dieser Ebene zu deaktivieren.`,"settings.resetToDefault":`Zurücksetzen`,"settings.resetFailed":`Standardwert konnte nicht geladen werden`,"settings.sentryIntegration":`Sentry-Integration`,"settings.var.prNumber":`PR-Nummer (z. B. 42)`,"settings.var.prUrl":`Vollständige URL der erstellten PR`,"settings.var.branchName":`Name des Arbeitsbranches`,"settings.var.sourceBranch":`Quellbranch, auf den die PR abzielt`,"settings.var.workspaceName":`Workspace-Name`,"settings.var.projectName":`Letztes Segment des Projektpfads`,"settings.var.notionUrl":`Notion-URL falls gesetzt, sonst leer`,"settings.var.commits":`Aufzählung der Commits zwischen Source und Head`,"settings.var.diffStats":`Git-Shortstat-Zusammenfassung (Dateien, Einfügungen, Löschungen)`,"settings.var.tasks":`Reguläre Aufgaben als Checkliste`,"settings.var.acceptanceCriteria":`Akzeptanzkriterien als Checkliste`,"settings.gitConventions":`Git-Konventionen (global)`,"settings.gitConventionsPlaceholder":`# Git-Konventionen...`,"settings.gitConventionsHint":`Diese Konventionen werden in .ai/.git-conventions.md jedes neuen Arbeitsbereichs geschrieben und müssen vom Agenten vor jeder Git-Operation eingehalten werden. Werden durch projektspezifische Konventionen überschrieben, falls definiert.`,"settings.setupScript":`Setup-Skript`,"settings.cleanupScript":`Cleanup-Skript`,"settings.archiveScript":`Archiv-Skript`,"settings.archiveScriptHint":`Shell-Skript, das serverseitig im Worktree ausgeführt wird, wenn ein Workspace archiviert wird. Leer lassen zum Deaktivieren.`,"settings.archiveScriptPlaceholder":`z. B. Container aufräumen, Speicherplatz freigeben…`,"settings.changeSourceBranchScript":`Quellbranch-Wechsel-Skript`,"settings.changeSourceBranchScript.help":`Ersetzt den eingebauten Cherry-Pick, wenn nicht leer. Das Skript verwaltet Git, PR-Basis, Force-Push und Konflikte; Kōbō verweigert nur, solange der Agent läuft, und aktualisiert die Quellbranch-Metadaten bei Exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — neuer Quellbranch aus dem Dialog
3
3
  KOBO_OLD_BASE — vorheriger Quellbranch des Workspaces
4
4
  KOBO_WORKING_BRANCH — Arbeitsbranch des Workspaces
@@ -15,7 +15,7 @@ KOBO_PR_NUMBER — PR-/MR-Nummer auf der aufgelösten Forge (leer wenn kein
15
15
  # Oder direkt über git (funktioniert auf GitHub auch nach Löschen des Branches):
16
16
  git fetch origin pull/[pr-nummer]/head:[branch-name]
17
17
  git worktree add [pfad] [branch-name]`,"settings.purgeDocsRestoreFootnote":`GitHub hält den PR-Head-Ref lange nach dem Löschen des Quellbranches zugänglich (Monate / Jahre). Die automatische Erkennung läuft im 30-Sekunden-Watcher — keine UI-Aktion nötig, sobald der Ordner wieder da ist.`,"settings.purgeDocsPermissionsTitle":`Berechtigungsfehler während der Bereinigung vermeiden`,"settings.purgeDocsPermissionsIntro":`Docker hinterlässt oft root-eigene Dateien in node_modules / vendor innerhalb des Worktrees. Wenn Kōbō versucht, sie zu entfernen, erhältst du EACCES / EPERM und die Bereinigung schlägt fehl. Zwei Vorbeugemöglichkeiten:`,"settings.purgeDocsPermissionsDocker":'Konfiguriere deinen Container so, dass er als dein Host-Benutzer läuft — USER-Direktive im Dockerfile oder `user: "${UID}:${GID}"` in docker-compose (mit UID/GID in deiner Shell exportiert).',"settings.purgeDocsPermissionsAcl":`Bereite das Worktrees-Root mit einer Standard-ACL vor — Sicherheitsnetz, das in den MEISTEN Fällen funktioniert (ext4/btrfs/xfs + Standard-Docker-Bind-Mount). Jede neue Datei erbt dann einen Zugriffseintrag für deinen Benutzer, zusätzlich zum nominalen Besitzer:`,"settings.purgeDocsPermissionsAclCommand":` setfacl -d -m u:$(whoami):rwX [worktrees-root]`,"settings.purgeDocsPermissionsFootnote":"ACL-Einschränkungen: funktionieren NICHT bei benannten Docker-Volumes (nutze einen Bind-Mount), Dateisystemen ohne ACL-Unterstützung (NTFS, exFAT, tmpfs), striktem SELinux mit `:Z` oder wenn Docker `userns-remap` aktiv ist. Die zuverlässigste Lösung bleibt die Konfiguration des Benutzers im Container (Option 1). Tipp: `rwX` (großes X) fügt das Ausführungsbit nur bei Verzeichnissen und bereits ausführbaren Dateien hinzu — sauberer als `rwx`, das jede Textdatei ausführbar machen würde.","settings.purgeDocsPermissionsRecoverTitle":`Einen bereits blockierten Worktree entsperren (bestehende root-eigene Dateien)`,"settings.purgeDocsPermissionsRecoverIntro":`Wenn ein Worktree bereits voll mit root-eigenen Dateien ist (Docker hat schon gelaufen, vendor / node_modules sind blockiert), reicht die präventive ACL oben nicht — du musst die BESTEHENDEN Dateien behandeln. Zwei Ansätze, beide aus dem Worktree-Ordner heraus auszuführen:`,"settings.purgeDocsPermissionsRecoverAclIntro":`Option A — Rekursive ACL (behält root-Ownership für Audit, fügt nur Zugriff für deinen Benutzer parallel hinzu):`,"settings.purgeDocsPermissionsRecoverAclCommand":`# setze Default-ACL für zukünftige Dateien UND gewähre Zugriff auf alles Bestehende
18
- sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Ownership übernehmen (einfacher, verliert die Spur "von root im Container erstellt", spielt in der Praxis selten eine Rolle):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Tipp: Du kannst diese Befehle direkt auf das Worktrees-Root anwenden (z. B. `~/.worktrees/`), um alle bestehenden UND zukünftigen Workspaces auf einmal abzudecken. Danach funktioniert die Kōbō-Bereinigung ohne Berechtigungsfehler.","contextMenu.runSetup":`Setup-Skript ausführen`,"contextMenu.exportEvents":`Events exportieren (CSV)`,"contextMenu.dismissChangesRequested":`Änderungen angefragt als gesehen markieren`,"contextMenu.dismissCiFailure":`CI-Fehler als gesehen markieren`,"contextMenu.restoreChangesRequested":`Änderungen angefragt als ungesehen markieren`,"contextMenu.restoreCiFailure":`CI-Fehler als ungesehen markieren`,"contextMenu.exportingEvents":`Export wird vorbereitet…`,"contextMenu.exportEventsError":`Event-Export fehlgeschlagen`,"contextMenu.openNotion":`In Notion öffnen`,"contextMenu.openSentry":`In Sentry öffnen`,"contextMenu.openPr":`PR öffnen`,"workspace.favorite":`Als Favorit markieren`,"workspace.unfavorite":`Aus Favoriten entfernen`,"workspace.showFavoritesOnly":`Nur Favoriten anzeigen`,"workspace.searchArchivedToggle":`Auch in archivierten Workspaces suchen`,"workspace.descriptionPlaceholder":`Kurze Beschreibung hinzufügen`,"workspace.descriptionDialogHint":`Klartext, max. 200 Zeichen. Leer lassen, um zu löschen.`,"workspace.descriptionTooLong":`Die Beschreibung darf höchstens 200 Zeichen lang sein.`,"workspace.descriptionSaveFailed":`Beschreibung konnte nicht gespeichert werden.`,"workspace.agentDescriptionTooltip":`Live-Status, gepflegt vom Agent`,"mcp.tool.setWorkspaceDescription":`Setzt die Kurzbeschreibung des Workspace (≤ 200 Zeichen).`,"tags.manage":`Tags verwalten`,"tags.manageTitle":`Workspace-Tags verwalten`,"tags.noTagsDefined":`Keine Tags definiert. Füge welche in Einstellungen > Global > Tags hinzu.`,"tags.orphanedHint":`{count} Tag(s) sind nicht mehr im globalen Katalog. Abwählen zum Entfernen.`,"settings.tagsTitle":`Workspace-Tags`,"settings.tagsHint":`Definiere die Tags, die Workspaces zugewiesen werden können. Tippe zum Hinzufügen, klicke auf das Kreuz zum Entfernen.`,"settings.tagsLabel":`Verfügbare Tags`,"settings.branchPrefixesTitle":`Branch-Präfixe`,"settings.branchPrefixesHint":`Verwalten Sie die Git-Branch-Präfixe, die auf der Workspace-Erstellungsseite verfügbar sind. Das erste ist standardmäßig vorausgewählt.`,"settings.branchPrefixesEmpty":`Kein Branch-Präfix definiert. Fügen Sie unten mindestens eines hinzu.`,"settings.branchPrefixesAddLabel":`Neues Präfix`,"settings.branchPrefixesEditHint":`Zum Umbenennen klicken`,"settings.branchPrefixesMoveUp":`Nach oben`,"settings.branchPrefixesMoveDown":`Nach unten`,"settings.worktreesTitle":`Git-Worktrees`,"settings.worktreesHint":`Wähle aus, wo neue Workspace-Worktrees erstellt werden. Relative Pfade sind projektrelativ; absolute Linux/macOS- und Windows-Pfade, $HOME, ~ und %USERPROFILE% werden unterstützt.`,"settings.worktreesPathLabel":`Worktrees-Pfad`,"settings.worktreesPathRequired":`Worktrees-Pfad ist erforderlich.`,"settings.worktreesPrefixByProject":`Worktrees nach Projektname präfixen`,"settings.worktreesPrefixByProjectHint":`Legt jeden Worktree in einem nach dem Projekt benannten Unterordner ab, um Kollisionen zu vermeiden, wenn mehrere Projekte die gleiche Worktree-Wurzel teilen.`,"settings.shareTitle":`Konfiguration teilen`,"settings.shareHint":`Exportiere Einstellungen, Templates und Tags als JSON-Bundle. MCP-Keys werden aus Sicherheitsgründen nicht exportiert.`,"settings.exportConfig":`Exportieren`,"settings.importConfig":`Importieren`,"settings.exportSuccess":`Konfiguration exportiert`,"settings.importSuccess":`Konfiguration importiert`,"settings.importConfirmTitle":`Konfiguration importieren`,"settings.importConfirmMessage":`Dies ersetzt deine aktuellen Einstellungen, Templates und Tags. MCP-Keys bleiben erhalten. Fortfahren?`,"health.title":`Status`,"health.tooltip":`Systemstatus`,"changelog.title":`Änderungsprotokoll`,"changelog.tooltip":`Was ist neu in Kōbō`,"changelog.empty":`Kein Änderungsprotokoll verfügbar.`,"changelog.current":`aktuell`,"changelog.currentVersion":`Aktuelle Version: v{version}`,"health.envTitle":`Umgebung`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Datenbank`,"health.dbPath":`Pfad`,"health.dbSize":`Größe`,"health.schemaVersion":`Schema-Version`,"health.settingsSchemaVersion":`Einstellungs-Schema`,"health.runtimesTitle":`Agent-Laufzeiten`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude nicht im PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`codex-Binärdatei nicht auflösbar`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} gesamt, {archived} archiviert`,"health.worktreesMissing":`{count} Worktree(s) auf der Festplatte fehlen`,"health.sessionsTitle":`Agent-Sitzungen`,"health.sessionsOrphaned":`{n} verwaiste laufende Sitzung(en)`,"health.integrationsTitle":`Integrationen`,"health.integrationConfigured":`konfiguriert`,"health.integrationMissing":`nicht konfiguriert`,"health.activeTitle":`Aktiver Zustand`,"health.activeQuotaBackoffs":`Ausstehende Quota-Backoffs`,"health.activeWakeups":`Geplante Aufweckungen`,"health.activeAutoLoop":`Auto-Loop läuft`,"health.activeAgentSessions":`Aktive Agent-Sessions`,"health.activeDevServers":`Laufende Dev-Server`,"health.noneActive":`Keine.`,"health.quotaResumeAt":`fortgesetzt um {time}`,"health.wakeupAt":`aufgeweckt um {time}`,"health.startedAgo":`gestartet vor {time}`,"health.autoLoopReady":`bereit, iteriert`,"health.autoLoopGrooming":`Grooming läuft`,"session.started":`Sitzung gestartet`,"session.ended":`Sitzung beendet`,"session.compacted":`Kontext komprimiert`,"tool.running":`Läuft...`,"activity.raw_lines":`Rohausgabezeilen ({n})`,"activity.loading_older":`Ältere Nachrichten werden geladen…`,"activity.compacting":`Kontext wird komprimiert…`,"activity.prev_user_message":`Vorherige Nachricht des Benutzers`,"activity.scroll_to_bottom":`Nach unten scrollen`,"chat.systemPrompt":`System-Prompt`,"chat.agent":`Agent`,"chat.cleanupScript":`Cleanup-Skript`,"chat.archiveScript":`Archiv-Skript`,"chat.setupScript":`Setup-Skript`,"chat.scriptDone":`Fertig`,"chat.you":`Du`,"chat.session":`Sitzung`,"chat.nActions":`{n} Aktion | {n} Aktionen`,"chat.lastUpdatedAt":`Zuletzt aktualisiert um {time}`,"chat.scrollToTurnTop":`Zum Nachrichtenanfang scrollen`,"migration.backing_up":`Datenbank wird gesichert…`,"migration.running":`Agent-Daten werden migriert — {processed}/{total}`,"migration.error":`Migration fehlgeschlagen`,"migration.backup_location":`Ein Backup wurde unter {path} gespeichert. Starte Kōbō neu, um erneut zu versuchen.`,"migration.retry":`Starte Kōbō neu, um erneut zu versuchen.`,"engine.select":`Engine`,"engine.model":`Modell`,"engine.effort":`Reasoning-Aufwand`,"wakeup.scheduledIn":`Nächste Weckung in {n}s`,"wakeup.scheduledAt":`Nächste Weckung um {time}`,"wakeup.firing":`Wecke auf...`,"wakeup.reason":`Grund: {reason}`,"wakeup.cancel":`Diese Weckung abbrechen`,"wakeup.pendingIndicator":`Weckung geplant`,"cron.pendingIndicator":`{n} Cron(s) geplant`,"schedule.tabLabel":`Zeitplan`,"schedule.wakeupTitle":`Wakeup ausstehend`,"schedule.cronsTitle":`Wiederkehrende Zeitpläne`,"schedule.noWakeup":`Kein Wakeup geplant`,"schedule.noCrons":`Kein Cron geplant`,"schedule.nextFireAt":`nächstes um {time}`,"schedule.lastFiredAt":`zuletzt vor {time}`,"askUserQuestion.title":`Der Agent stellt eine Frage`,"askUserQuestion.submit":`Antwort senden`,"askUserQuestion.multiSelectHint":`Eine oder mehrere Optionen auswählen`,"askUserQuestion.otherOption":`Sonstiges`,"askUserQuestion.otherOptionHint":`bitte in der nächsten Chat-Nachricht angeben`,"askUserQuestion.noPending":`Keine offene Frage`,"askUserQuestion.next":`Weiter`,"askUserQuestion.previous":`Zurück`,"askUserQuestion.cancel":`Abbrechen`,"askUserQuestion.cancelTooltip":`Diese Frage überspringen — der Agent macht ohne Antwort weiter`,"askUserQuestion.collapse":`Fragebereich einklappen`,"askUserQuestion.expand":`Fragebereich ausklappen`,"permissionRequest.title":`Der Agent möchte ein Tool verwenden`,"permissionRequest.allow":`Erlauben`,"permissionRequest.deny":`Ablehnen`,"permissionRequest.tool":`Tool`,"permissionRequest.input":`Eingabe`,"permissionRequest.denied":`vom Nutzer abgelehnt`,"workspaceStatus.awaitingUser":`wartet auf deine Antwort`,"workspaceList.prOpen":`#{n} — Pull Request offen`,"workspaceList.prChangesRequested":`#{n} — Änderungen angefordert`,"workspaceList.attentionCiFailed":`CI fehlgeschlagen`,"workspaceList.attentionChangesRequested":`Änderungen angefordert`,"workspaceList.attentionReadyToMerge":`Bereit zum Mergen`,"autoLoop.toggle":`Auto-Schleife`,"autoLoop.start":`Auto-Schleife starten`,"autoLoop.prepare":`Auto-Schleife vorbereiten`,"autoLoop.reprepare":`Auto-Schleife erneut vorbereiten`,"autoLoop.reprepareTooltip":`Grooming-Schritt erneut ausführen, um Aufgaben hinzuzufügen oder zu aktualisieren, bevor die Schleife neu gestartet wird`,"autoLoop.prepareBusy":`Warte, bis der Agent fertig ist, bevor du vorbereitest`,"autoLoop.forceReady":`Ich weiß, was ich tue — Grooming überspringen`,"autoLoop.forceReadyConfirm":`Grooming überspringen und Auto-Schleife als bereit markieren? Kann hängen bleiben, wenn Aufgaben nicht atomar sind.`,"autoLoop.stop":`Auto-Schleife stoppen`,"autoLoop.notReady":`Zuerst „Auto-Schleife vorbereiten" ausführen`,"autoLoop.noTasks":`Zuerst Aufgaben hinzufügen`,"autoLoop.progress":`Auto-Schleife · {done}/{total} Aufgaben`,"autoLoop.preparing":`Auto-Schleife · Vorbereitung`,"autoLoop.preparingTooltip":`Grooming läuft — der Agent erstellt / überprüft Aufgaben. Die Schleife startet, sobald mark_auto_loop_ready aufgerufen wird.`,"autoLoop.running":`Auto-Schleife läuft`,"autoLoop.startInMode":`Im Auto-Schleifen-Modus starten`,"koboCommand.prepAutoloopDesc":`Aufgaben für Auto-Schleifen-Modus vorbereiten (auf Atomarität prüfen)`,"staleSessionBanner.title":`Auto-Schleife läuft`,"staleSessionBanner.message":`Du siehst eine ältere Sitzung — der Agent arbeitet gerade in der neuesten.`,"staleSessionBanner.switchToCurrent":`Zur aktuellen wechseln`},on={"common.save":`Save`,"common.cancel":`Cancel`,"common.delete":`Delete`,"common.close":`Close`,"common.details":`Details`,"whatsNew.title":`What's new`,"common.loading":`Loading...`,"common.search":`Search...`,"common.refresh":`Refresh`,"common.copy":`Copy`,"common.copied":`Copied to clipboard`,"common.copyFailed":`Copy failed`,"common.add":`Add`,"folderPicker.title":`Choose a folder`,"folderPicker.parent":`Parent folder`,"folderPicker.empty":`No subfolders`,"folderPicker.select":`Select this folder`,"common.start":`Start`,"common.stop":`Stop`,"common.archive":`Archive`,"common.unarchive":`Unarchive`,"common.selectWorkspace":`Select a workspace`,"common.noResults":`No results for "{query}"`,"common.send":`send`,"common.newLine":`new line`,"common.history":`history`,"common.justNow":`just now`,"common.minutesAgo":`{count}m ago`,"common.hoursAgo":`{count}h ago`,"common.daysAgo":`{count}d ago`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Most capable model — successor to Opus 4.8, 1M context, adaptive thinking`,"model.mythos5Description":`Fable 5 without safety classifiers — limited access (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude picks the optimal model`,"model.opus48Description":`Most capable Opus — long-horizon agentic coding, 1M context by default, high effort default`,"model.opus47ClassicDescription":`Latest Opus, most capable`,"model.opus471mDescription":`Latest Opus, 1M context`,"model.opusClassicDescription":`Most powerful`,"model.opus1mDescription":`Most powerful, 1M context`,"model.sonnetClassicDescription":`Balanced`,"model.sonnet1mDescription":`Balanced, 1M context`,"model.haikuDescription":`Fastest`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recommended for complex coding (requires ChatGPT auth)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Default fallback — strong reasoning, works with API key auth`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Fast and efficient — best for responsive tasks and subagents`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Coding-specialized model for complex software engineering`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Let the engine pick the default`,"reasoning.minimalDescription":`Fastest, shallowest reasoning`,"reasoning.lowDescription":`Faster, less depth`,"reasoning.mediumDescription":`Balanced`,"reasoning.highDescription":`More depth`,"reasoning.xhighDescription":`Extended depth, long-horizon tasks`,"reasoning.maxDescription":`Maximum depth`,"agentPermissionMode.label":`Permission mode`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Accept edits`,"agentPermissionMode.interactive":`Interactive`,"agentPermissionMode.tooltip":`How the agent handles tool permissions. Plan: read-only, no writes. Bypass: skip every prompt. Strict: auto-accept file edits, respect allow/deny lists for the rest. Interactive: ask the user before each tool via the permission panel.`,"agentPermissionMode.autoLoopOverride":`Auto-loop forces a non-plan mode — Plan blocks the MCP tools and edits the loop relies on. Pick Bypass, Strict, or Interactive instead.`,"agentPermissionMode.autoLoopLocked":`Locked to Bypass while auto-loop is on — any other mode would stall the loop on permission prompts. AskUserQuestion still works.`,"workspaceList.title":`Workspaces`,"workspaceList.needsAttention":`Needs Attention`,"workspaceList.running":`Running`,"workspaceList.idle":`Idle`,"workspaceList.archived":`Archived`,"workspaceList.noWorkspaces":`No workspaces yet`,"workspaceList.footer":`{count} workspace | {count} workspaces`,"workspaceList.footerRunning":`{count} running`,"workspaceList.deleteDialog.title":`Delete workspace?`,"workspaceList.deleteDialog.deleteLocal":`Delete local branch`,"workspaceList.deleteDialog.deleteRemote":`Delete remote branch`,"workspaceList.deleteDialog.warning":`Warning: this action is irreversible on the remote.`,"workspaceList.deleteArchivedDialog.tooltip":`Delete all archived workspaces`,"workspaceList.deleteArchivedDialog.title":`Delete all archived workspaces?`,"workspaceList.deleteArchivedDialog.message":`This will permanently delete the {count} archived workspaces. This action cannot be undone.`,"workspacePage.selectWorkspace":`Select a workspace to begin`,"workspacePage.session":`Session #{n}`,"workspacePage.newSession":`+ New session`,"workspacePage.renameSession":`Rename`,"workspacePage.renameSessionTitle":`Rename session`,"workspacePage.sessionNameLabel":`Session name`,"workspacePage.sessionEndedNotice":`This session has ended. Create a new session to continue.`,"workspacePage.renameFailed":`Rename failed`,"workspacePage.createSessionFailed":`Failed to create session`,"workspacePage.startFailed":`Start failed`,"workspacePage.stopFailed":`Stop failed`,"workspacePage.interrupt":`Interrupt`,"workspacePage.interrupted":`Agent interrupted — waiting for your next message`,"workspacePage.archivedBanner":`Archived workspace — read-only`,"workspacePage.worktreePurgedBanner":`Worktree deleted — history kept, no restore available in this version`,"workspacePage.worktreePurgedTooltip":"The worktree folder was deleted from disk to reclaim space. Chat history, sessions and PR metadata remain queryable here, but the working directory no longer exists locally. A future Kōbō version will rebuild the worktree from the merged PR — for now you would need to recreate it manually via `gh pr checkout` or `git worktree add`.","workspacePage.pendingInitialPromptBanner":`An initial prompt is pending — the agent never received it (setup script crashed or the workspace was never started). Click Start to send it now.`,"workspacePage.unarchived":`Workspace unarchived`,"workspacePage.unarchiveFailed":`Unarchive failed`,"workspacePage.interruptFailed":`Interrupt failed`,"workspacePage.interruptTooltip":`Soft interrupt (like Escape) — stops the current tool but keeps the session alive`,"workspacePage.pendingNextRun":`Applied on next start`,"search.title":`Search`,"search.tooltip":`Search across agent history`,"search.placeholder":`Search across all agent messages…`,"search.includeArchived":`Include archived workspaces`,"search.loading":`Searching…`,"search.noResults":`No matches`,"search.error":`Search failed: {message}`,"search.resultCount":`{n} result(s)`,"search.eventType.userMessage":`You`,"search.eventType.agentOutput":`Agent`,"activityFeed.empty":`No activity yet`,"activityFeed.emptyHint":`Start a workspace to see agent output here`,"activityFeed.initialPrompt":`Initial Prompt`,"activityFeed.you":`You`,"activityFeed.agent":`Agent`,"activityFeed.question":`Question`,"activityFeed.goToPrevious":`Go to previous message`,"activityFeed.scrollToBottom":`Scroll to bottom`,"activityFeed.sendAnswers":`Send answers`,"agentBusy.banner":`Agent is busy`,"agentBusy.subagentsRunning":`1 sub-agent running | {n} sub-agents running`,"agentBusy.viewSubagents":`View sub-agents`,"agentBusy.pendingMessage":`Waiting — agent is busy`,"terminal.title":`Terminal`,"terminal.open":`Open terminal`,"terminal.close":`Close terminal`,"terminal.noWorkspace":`Select a workspace`,"terminal.noWorktree":`Worktree not created yet`,"terminal.error":`Terminal error`,"terminal.exited":`Terminal exited`,"chatInput.placeholder":`Message... (/ for skills)`,"chatInput.fileSearchHint":`search a file`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Attach image`,"chatInput.queueBanner":`Message queued — will be sent when the agent finishes`,"chatInput.cancelQueue":`Cancel Queue`,"chatInput.autoLoopBanner":`Auto-loop is running — stop it to send a message`,"chatInput.awaitingUserBanner":`The agent is waiting for your answer above — reply via the question panel`,"chatInput.autoLoopStop":`Stop`,"koboCommand.checkProgressDesc":`Verify progress on tasks and acceptance criteria`,"chatInput.uploading":`Uploading...`,"voice.title":`Voice transcription`,"voice.enabled":`Enable local voice transcription`,"voice.pttKey":`Push-to-talk key`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Space`,"voice.language":`Language (auto or code)`,"voice.model":`Active model`,"voice.commandPath":`Whisper binary path (optional)`,"voice.ffmpegPath":`ffmpeg binary path (optional)`,"voice.temperature":`Temperature`,"voice.temperatureHint":`Lower is more deterministic; higher can be more flexible but less stable.`,"voice.initialPrompt":`Initial prompt (optional)`,"voice.initialPromptHint":`Optional context to help Whisper with names, jargon, or domain vocabulary.`,"voice.translateToEnglish":`Translate to English`,"voice.translateToEnglishHint":`When enabled, non-English speech is translated to English instead of transcribed as-is.`,"voice.suppressNst":`Suppress non-speech tokens`,"voice.suppressNstHint":`Attempts to reduce non-speech artifacts in the transcript.`,"voice.installLink":`Install whisper.cpp`,"voice.installGuideTitle":`Installation guide`,"voice.installGuideIntro":`Install whisper.cpp and ffmpeg, then set the binary paths below if needed.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`After CMake build, the Whisper binary is usually at: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Then set "Whisper binary path" and "ffmpeg binary path" in this section (or leave empty if they are in PATH).`,"voice.noneModel":`No active model`,"voice.notInstalled":`not installed`,"voice.download":`Download`,"voice.delete":`Delete`,"voice.holdToTalk":`Hold to talk`,"voice.recording":`Recording...`,"voice.transcribing":`Transcribing...`,"voice.notSupported":`Voice recording is not supported in this browser`,"voice.errorMicPermission":`Microphone permission denied`,"voice.errorTranscription":`Voice transcription failed`,"voice.downloadFailed":`Model download failed`,"voice.deleteFailed":`Model deletion failed`,"voice.errorDisabled":`Voice transcription is disabled in settings`,"voice.errorModelMissing":`No active voice model is configured`,"voice.errorModelNotInstalled":`The active voice model is not installed`,"voice.errorAudioInvalid":`Audio capture is invalid or empty`,"voice.errorLanguageInvalid":`Voice language configuration is invalid`,"voice.errorRuntimeMissing":`Whisper runtime is not installed or not in PATH`,"voice.maxDurationReached":`Maximum recording duration reached`,"voice.runtimeReady":`Runtime ready: {command}`,"voice.runtimeMissing":`Runtime missing: {command}`,"voice.ffmpegReady":`ffmpeg ready`,"voice.ffmpegMissing":`ffmpeg missing`,"voice.sectionRuntime":`Runtime status`,"voice.sectionActivation":`Activation`,"voice.sectionModels":`Whisper models`,"voice.sectionAdvanced":`Advanced options`,"voice.sectionBehavior":`Transcription behavior`,"voice.sectionBinaries":`Binary paths`,"voice.downloadModels":`Download a model`,"voice.cancelFailed":`Failed to cancel the download`,"createPage.title":`What would you like to work on?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion enabled`,"createPage.importNotion":`Import from Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`URL must start with https://www.notion.so/ or https://app.notion.com/`,"createPage.notionAutoExtract":`Subtasks and acceptance criteria will be extracted automatically.`,"createPage.notionPanelChoiceLabel":`This URL points to a sub-page (?p=). Which one do you want to work on?`,"createPage.notionPanelOption":`Sub-page (panel)`,"createPage.notionPanelOptionDesc":`The page you were viewing — recommended`,"createPage.notionParentOption":`Parent page`,"createPage.notionParentOptionDesc":`The epic / database it belongs to`,"createPage.importSentry":`Import Sentry`,"createPage.sentryEnabled":`Sentry enabled`,"createPage.sentryPlaceholder":`https://your-org.sentry.io/issues/123456`,"createPage.sentryValidation":`URL must point to a Sentry issue (/issues/<id>)`,"createPage.sentryAutoExtract":`Sentry issue will be imported automatically`,"createPage.sentryExtractHint":`Kobo will extract the issue and write it to .ai/thoughts/`,"createPage.workspaceName":`Workspace name (defaults to Notion page title)`,"createPage.workspaceNamePlaceholder":`Workspace name...`,"createPage.instructions":`Additional instructions (optional)...`,"createPage.instructionsPlaceholder":`Describe the task...`,"createPage.manualHint":`No Notion ticket? Add your tasks and acceptance criteria manually — they'll be sent to the Claude agent as context.`,"createPage.tasks":`Tasks ({count})`,"createPage.addTask":`Add a task...`,"createPage.acceptanceCriteria":`Acceptance Criteria ({count})`,"createPage.addCriterion":`Add a criterion...`,"createPage.projectPath":`Enter the project path`,"createPage.branchType":`Branch type`,"createPage.branch":`Branch`,"createPage.noBranches":`No branches found`,"createPage.enterPath":`Enter a project path`,"createPage.create":`Create`,"createPage.skipSetupScript":`Skip setup script`,"createPage.attachWorktreeToggle":`Attach existing worktree`,"createPage.attachWorktreeEnabled":`Reusing existing worktree`,"createPage.worktreePickerLabel":`Existing worktree`,"createPage.noOrphanWorktrees":`No orphan worktrees in this project`,"createPage.pickWorktreeRequired":`Please pick a worktree to attach`,"createPage.notionExtractHint":`Subtasks and acceptance criteria will be extracted from the Notion page.`,"createPage.notionImportHint":`Click "Import from Notion" to automatically extract subtasks from a ticket.`,"createPage.errorCreating":`Error creating workspace.`,"createPage.branchAdjusted":"Branch already existed — created `{branch}` instead. The matching worktree folder uses the same suffix.","createPage.validationNotionUrl":`Please paste a valid Notion URL (https://www.notion.so/... or https://app.notion.com/...).`,"createPage.validationDescription":`Please describe the task.`,"createPage.validationName":`Please provide a workspace name.`,"createPage.validationPath":`Please enter the project path.`,"createPage.validationBranch":`Please select a branch.`,"settings.title":`Settings`,"settings.language":`Language`,"settings.projectColor":`Color`,"settings.projectColorClear":`Clear`,"settings.projectColorDefault":`Default (grey)`,"settings.workspaceListSection":`Workspace list`,"settings.flattenWorkspaceList":`Flatten workspace list`,"settings.flattenWorkspaceListHint":`Show all workspaces in a single flat list with a project badge, instead of grouping by project.`,"settings.skillSuite.section":`Skill suite`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Custom`,"settings.skillSuite.superpowersHint":`Opinionated TDD / brainstorm / plan workflow (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Garry Tan's stack — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Both suites stack — superpowers for process discipline (brainstorm / TDD / plans / principles-level review), gstack for concrete workflows (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Edit the four prompts below yourself. Starts from the agnostic baseline.`,"settings.skillSuite.reloadDefaults":`Reload defaults`,"settings.skillSuite.reloadDefaultsConfirm":`Replace the four custom prompts with the agnostic defaults?`,"settings.skillSuite.customPrompts":`Custom prompts`,"settings.skillSuite.reviewTemplate":`Review template`,"settings.skillSuite.autoLoopReviewGate":`Auto-loop review gate`,"settings.skillSuite.autoLoopGroomingIntro":`Auto-loop grooming intro`,"settings.skillSuite.qaTemplate":`QA template`,"settings.skillSuite.brainstormingInstruction":`Brainstorming-phase instruction`,"settings.global":`Global`,"settings.projects":`Projects`,"settings.globalSettings":`Global Settings`,"settings.defaultModel":`Default model`,"settings.defaultModelClaude":`Default model (Claude Code)`,"settings.defaultModelCodex":`Default model (OpenAI Codex)`,"settings.agentPermissions":`Agent permissions`,"settings.skipPermissions":`Skip permission prompts (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Warning: disabling this will cause all tool permissions (Write, Edit, Bash...) to be auto-denied in headless mode. The agent will only be able to read.`,"settings.notifications":`Notifications`,"settings.browserNotifications":`Browser notifications when agent finishes`,"settings.audioNotifications":`Sound notification when agent finishes`,"settings.notificationSound":`Notification sound`,"settings.notificationSoundPreview":`Preview`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Work done`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`It's gonna blow`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Default permission mode`,"settings.defaultPermissionModeClaude":`Default permission mode (Claude Code)`,"settings.defaultPermissionModeCodex":`Default permission mode (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Mode applied when creating a new workspace. Plan = read-only first, Bypass = skip prompts, Strict = auto-accept edits with allow-list, Interactive = ask before each tool.`,"settings.activityFeed":`Activity feed`,"settings.verboseMessages":`Show verbose system messages (task_progress, task_started)`,"settings.availableVariables":`Available template variables`,"settings.prPromptTemplate":`PR prompt template`,"settings.prPromptPlaceholder":`Instructions for the agent when creating GitHub PRs...`,"settings.prPromptHint":`Use the template variables listed above (double curly brace syntax).`,"settings.reviewPromptTemplate":`Review prompt template`,"settings.reviewPromptPlaceholder":`Instructions for the agent when reviewing branch changes...`,"settings.ciFixPromptTemplate":`CI fix prompt template`,"settings.ciFixPromptHint":`Sent to the agent when a workspace has failing CI. Variables (double-brace syntax): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Ask the agent to diagnose and fix the failing CI jobs...`,"settings.finalizationPromptTemplate":`Auto-loop finalization prompt`,"settings.finalizationPromptHint":`Default prompt for the final auto-loop iteration (last quality checks). Used when a project leaves its own finalization prompt empty.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Notion initial prompt`,"settings.notionInitialPrompt.help":`Appended to the workspace creation prompt when the workspace has a Notion ticket. Variables: {variables}.`,"settings.notionInitialPrompt.project":`Notion initial prompt (override)`,"settings.sentryInitialPrompt":`Sentry initial prompt`,"settings.sentryInitialPrompt.help":`Appended to the workspace creation prompt when the workspace has a Sentry issue. Variables: {variables}.`,"settings.sentryInitialPrompt.project":`Sentry initial prompt (override)`,"settings.initialPrompt.inheritHint":`Leave blank to inherit. Type any whitespace character to disable injection at this level.`,"settings.resetToDefault":`Reset to default`,"settings.resetFailed":`Failed to load default value`,"settings.sentryIntegration":`Sentry integration`,"settings.var.prNumber":`PR number (e.g., 42)`,"settings.var.prUrl":`Full URL of the created PR`,"settings.var.branchName":`Working branch name`,"settings.var.sourceBranch":`Source branch the PR targets`,"settings.var.workspaceName":`Workspace name`,"settings.var.projectName":`Last segment of the project path`,"settings.var.notionUrl":`Notion URL if set, empty otherwise`,"settings.var.commits":`Bulleted commit list between source and head`,"settings.var.diffStats":`Git shortstat summary (files, insertions, deletions)`,"settings.var.tasks":`Regular tasks as a checkbox list`,"settings.var.acceptanceCriteria":`Acceptance criteria as a checkbox list`,"settings.gitConventions":`Git conventions (global)`,"settings.gitConventionsPlaceholder":`# Git conventions...`,"settings.gitConventionsHint":`These conventions are written to .ai/.git-conventions.md in each new workspace and must be followed by the agent before any git operation. Overridden by per-project conventions if defined.`,"settings.setupScript":`Setup script`,"settings.cleanupScript":`Cleanup script`,"settings.archiveScript":`Archive script`,"settings.archiveScriptHint":`Shell script run server-side in the worktree when a workspace is archived. Leave empty to disable.`,"settings.archiveScriptPlaceholder":`e.g. clean up containers, free disk space…`,"settings.changeSourceBranchScript":`Change-source-branch script`,"settings.changeSourceBranchScript.help":`Replaces the built-in cherry-pick when non-empty. The script owns git, PR base, force-push and conflicts; Kōbō still refuses while the agent is running and updates the source-branch metadata on exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — new source branch chosen in the dialog
18
+ sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Ownership übernehmen (einfacher, verliert die Spur "von root im Container erstellt", spielt in der Praxis selten eine Rolle):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Tipp: Du kannst diese Befehle direkt auf das Worktrees-Root anwenden (z. B. `~/.worktrees/`), um alle bestehenden UND zukünftigen Workspaces auf einmal abzudecken. Danach funktioniert die Kōbō-Bereinigung ohne Berechtigungsfehler.","contextMenu.runSetup":`Setup-Skript ausführen`,"contextMenu.exportEvents":`Events exportieren (CSV)`,"contextMenu.dismissChangesRequested":`Änderungen angefragt als gesehen markieren`,"contextMenu.dismissCiFailure":`CI-Fehler als gesehen markieren`,"contextMenu.restoreChangesRequested":`Änderungen angefragt als ungesehen markieren`,"contextMenu.restoreCiFailure":`CI-Fehler als ungesehen markieren`,"contextMenu.exportingEvents":`Export wird vorbereitet…`,"contextMenu.exportEventsError":`Event-Export fehlgeschlagen`,"contextMenu.openNotion":`In Notion öffnen`,"contextMenu.openSentry":`In Sentry öffnen`,"contextMenu.openPr":`PR öffnen`,"workspace.favorite":`Als Favorit markieren`,"workspace.unfavorite":`Aus Favoriten entfernen`,"workspace.showFavoritesOnly":`Nur Favoriten anzeigen`,"workspace.searchArchivedToggle":`Auch in archivierten Workspaces suchen`,"workspace.descriptionPlaceholder":`Kurze Beschreibung hinzufügen`,"workspace.descriptionDialogHint":`Klartext, max. 200 Zeichen. Leer lassen, um zu löschen.`,"workspace.descriptionTooLong":`Die Beschreibung darf höchstens 200 Zeichen lang sein.`,"workspace.descriptionSaveFailed":`Beschreibung konnte nicht gespeichert werden.`,"workspace.agentDescriptionTooltip":`Live-Status, gepflegt vom Agent`,"mcp.tool.setWorkspaceDescription":`Setzt die Kurzbeschreibung des Workspace (≤ 200 Zeichen).`,"tags.manage":`Tags verwalten`,"tags.manageTitle":`Workspace-Tags verwalten`,"tags.noTagsDefined":`Keine Tags definiert. Füge welche in Einstellungen > Global > Tags hinzu.`,"tags.orphanedHint":`{count} Tag(s) sind nicht mehr im globalen Katalog. Abwählen zum Entfernen.`,"settings.tagsTitle":`Workspace-Tags`,"settings.tagsHint":`Definiere die Tags, die Workspaces zugewiesen werden können. Tippe zum Hinzufügen, klicke auf das Kreuz zum Entfernen.`,"settings.tagsLabel":`Verfügbare Tags`,"settings.branchPrefixesTitle":`Branch-Präfixe`,"settings.branchPrefixesHint":`Verwalten Sie die Git-Branch-Präfixe, die auf der Workspace-Erstellungsseite verfügbar sind. Das erste ist standardmäßig vorausgewählt.`,"settings.branchPrefixesEmpty":`Kein Branch-Präfix definiert. Fügen Sie unten mindestens eines hinzu.`,"settings.branchPrefixesAddLabel":`Neues Präfix`,"settings.branchPrefixesEditHint":`Zum Umbenennen klicken`,"settings.branchPrefixesMoveUp":`Nach oben`,"settings.branchPrefixesMoveDown":`Nach unten`,"settings.worktreesTitle":`Git-Worktrees`,"settings.worktreesHint":`Wähle aus, wo neue Workspace-Worktrees erstellt werden. Relative Pfade sind projektrelativ; absolute Linux/macOS- und Windows-Pfade, $HOME, ~ und %USERPROFILE% werden unterstützt.`,"settings.worktreesPathLabel":`Worktrees-Pfad`,"settings.worktreesPathRequired":`Worktrees-Pfad ist erforderlich.`,"settings.worktreesPrefixByProject":`Worktrees nach Projektname präfixen`,"settings.worktreesPrefixByProjectHint":`Legt jeden Worktree in einem nach dem Projekt benannten Unterordner ab, um Kollisionen zu vermeiden, wenn mehrere Projekte die gleiche Worktree-Wurzel teilen.`,"settings.shareTitle":`Konfiguration teilen`,"settings.shareHint":`Exportiere Einstellungen, Templates und Tags als JSON-Bundle. MCP-Keys werden aus Sicherheitsgründen nicht exportiert.`,"settings.exportConfig":`Exportieren`,"settings.importConfig":`Importieren`,"settings.exportSuccess":`Konfiguration exportiert`,"settings.importSuccess":`Konfiguration importiert`,"settings.importConfirmTitle":`Konfiguration importieren`,"settings.importConfirmMessage":`Dies ersetzt deine aktuellen Einstellungen, Templates und Tags. MCP-Keys bleiben erhalten. Fortfahren?`,"health.title":`Status`,"health.tooltip":`Systemstatus`,"changelog.title":`Änderungsprotokoll`,"changelog.tooltip":`Was ist neu in Kōbō`,"changelog.empty":`Kein Änderungsprotokoll verfügbar.`,"changelog.current":`aktuell`,"changelog.currentVersion":`Aktuelle Version: v{version}`,"health.envTitle":`Umgebung`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Datenbank`,"health.dbPath":`Pfad`,"health.dbSize":`Größe`,"health.schemaVersion":`Schema-Version`,"health.settingsSchemaVersion":`Einstellungs-Schema`,"health.runtimesTitle":`Agent-Laufzeiten`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude nicht im PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`codex-Binärdatei nicht auflösbar`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} gesamt, {archived} archiviert`,"health.worktreesMissing":`{count} Worktree(s) auf der Festplatte fehlen`,"health.sessionsTitle":`Agent-Sitzungen`,"health.sessionsOrphaned":`{n} verwaiste laufende Sitzung(en)`,"health.integrationsTitle":`Integrationen`,"health.integrationConfigured":`konfiguriert`,"health.integrationMissing":`nicht konfiguriert`,"health.activeTitle":`Aktiver Zustand`,"health.activeQuotaBackoffs":`Ausstehende Quota-Backoffs`,"health.activeWakeups":`Geplante Aufweckungen`,"health.activeAutoLoop":`Auto-Loop läuft`,"health.activeAgentSessions":`Aktive Agent-Sessions`,"health.activeDevServers":`Laufende Dev-Server`,"health.noneActive":`Keine.`,"health.quotaResumeAt":`fortgesetzt um {time}`,"health.wakeupAt":`aufgeweckt um {time}`,"health.startedAgo":`gestartet vor {time}`,"health.autoLoopReady":`bereit, iteriert`,"health.autoLoopGrooming":`Grooming läuft`,"session.started":`Sitzung gestartet`,"session.ended":`Sitzung beendet`,"session.compacted":`Kontext komprimiert`,"tool.running":`Läuft...`,"activity.raw_lines":`Rohausgabezeilen ({n})`,"activity.loading_older":`Ältere Nachrichten werden geladen…`,"activity.compacting":`Kontext wird komprimiert…`,"activity.prev_user_message":`Vorherige Nachricht des Benutzers`,"activity.scroll_to_bottom":`Nach unten scrollen`,"chat.systemPrompt":`System-Prompt`,"chat.agent":`Agent`,"chat.cleanupScript":`Cleanup-Skript`,"chat.archiveScript":`Archiv-Skript`,"chat.setupScript":`Setup-Skript`,"chat.scriptDone":`Fertig`,"chat.you":`Du`,"chat.session":`Sitzung`,"chat.nActions":`{n} Aktion | {n} Aktionen`,"chat.lastUpdatedAt":`Zuletzt aktualisiert um {time}`,"chat.scrollToTurnTop":`Zum Nachrichtenanfang scrollen`,"migration.backing_up":`Datenbank wird gesichert…`,"migration.running":`Agent-Daten werden migriert — {processed}/{total}`,"migration.error":`Migration fehlgeschlagen`,"migration.backup_location":`Ein Backup wurde unter {path} gespeichert. Starte Kōbō neu, um erneut zu versuchen.`,"migration.retry":`Starte Kōbō neu, um erneut zu versuchen.`,"engine.select":`Engine`,"engine.model":`Modell`,"engine.effort":`Reasoning-Aufwand`,"wakeup.scheduledIn":`Nächste Weckung in {n}s`,"wakeup.scheduledAt":`Nächste Weckung um {time}`,"wakeup.firing":`Wecke auf...`,"wakeup.reason":`Grund: {reason}`,"wakeup.cancel":`Diese Weckung abbrechen`,"wakeup.pendingIndicator":`Weckung geplant`,"cron.pendingIndicator":`{n} Cron(s) geplant`,"schedule.tabLabel":`Zeitplan`,"schedule.wakeupTitle":`Wakeup ausstehend`,"schedule.cronsTitle":`Wiederkehrende Zeitpläne`,"schedule.noWakeup":`Kein Wakeup geplant`,"schedule.noCrons":`Kein Cron geplant`,"schedule.nextFireAt":`nächstes um {time}`,"schedule.lastFiredAt":`zuletzt vor {time}`,"schedule.addCronTitle":`Wiederkehrende Aufgabe hinzufügen`,"schedule.addWakeupTitle":`Wakeup planen`,"schedule.every":`Alle`,"schedule.unitMinutes":`Minuten`,"schedule.unitHours":`Stunden`,"schedule.unitDays":`Tage`,"schedule.advancedExpression":`Erweiterter Ausdruck (optional)`,"schedule.advancedHint":`Roher Cron (z. B. */15 * * * *) oder {'@'}hourly/{'@'}daily — überschreibt die Auswahl, wenn gesetzt.`,"schedule.promptLabel":`Prompt`,"schedule.labelOptional":`Bezeichnung (optional)`,"schedule.delayMinutes":`Verzögerung (Minuten)`,"schedule.modeFresh":`Neue Sitzung`,"schedule.oneShot":`Nur einmal ausführen`,"schedule.addCronBtn":`Cron hinzufügen`,"schedule.addWakeupBtn":`Wakeup planen`,"schedule.cronCreated":`Wiederkehrende Aufgabe hinzugefügt`,"schedule.wakeupCreated":`Wakeup geplant`,"askUserQuestion.title":`Der Agent stellt eine Frage`,"askUserQuestion.submit":`Antwort senden`,"askUserQuestion.multiSelectHint":`Eine oder mehrere Optionen auswählen`,"askUserQuestion.otherOption":`Sonstiges`,"askUserQuestion.otherOptionHint":`bitte in der nächsten Chat-Nachricht angeben`,"askUserQuestion.noPending":`Keine offene Frage`,"askUserQuestion.next":`Weiter`,"askUserQuestion.previous":`Zurück`,"askUserQuestion.cancel":`Abbrechen`,"askUserQuestion.cancelTooltip":`Diese Frage überspringen — der Agent macht ohne Antwort weiter`,"askUserQuestion.collapse":`Fragebereich einklappen`,"askUserQuestion.expand":`Fragebereich ausklappen`,"permissionRequest.title":`Der Agent möchte ein Tool verwenden`,"permissionRequest.allow":`Erlauben`,"permissionRequest.deny":`Ablehnen`,"permissionRequest.tool":`Tool`,"permissionRequest.input":`Eingabe`,"permissionRequest.denied":`vom Nutzer abgelehnt`,"workspaceStatus.awaitingUser":`wartet auf deine Antwort`,"workspaceList.prOpen":`#{n} — Pull Request offen`,"workspaceList.prChangesRequested":`#{n} — Änderungen angefordert`,"workspaceList.attentionCiFailed":`CI fehlgeschlagen`,"workspaceList.attentionChangesRequested":`Änderungen angefordert`,"workspaceList.attentionReadyToMerge":`Bereit zum Mergen`,"autoLoop.toggle":`Auto-Schleife`,"autoLoop.start":`Auto-Schleife starten`,"autoLoop.prepare":`Auto-Schleife vorbereiten`,"autoLoop.reprepare":`Auto-Schleife erneut vorbereiten`,"autoLoop.reprepareTooltip":`Grooming-Schritt erneut ausführen, um Aufgaben hinzuzufügen oder zu aktualisieren, bevor die Schleife neu gestartet wird`,"autoLoop.prepareBusy":`Warte, bis der Agent fertig ist, bevor du vorbereitest`,"autoLoop.forceReady":`Ich weiß, was ich tue — Grooming überspringen`,"autoLoop.forceReadyConfirm":`Grooming überspringen und Auto-Schleife als bereit markieren? Kann hängen bleiben, wenn Aufgaben nicht atomar sind.`,"autoLoop.stop":`Auto-Schleife stoppen`,"autoLoop.notReady":`Zuerst „Auto-Schleife vorbereiten" ausführen`,"autoLoop.noTasks":`Zuerst Aufgaben hinzufügen`,"autoLoop.progress":`Auto-Schleife · {done}/{total} Aufgaben`,"autoLoop.preparing":`Auto-Schleife · Vorbereitung`,"autoLoop.preparingTooltip":`Grooming läuft — der Agent erstellt / überprüft Aufgaben. Die Schleife startet, sobald mark_auto_loop_ready aufgerufen wird.`,"autoLoop.running":`Auto-Schleife läuft`,"autoLoop.startInMode":`Im Auto-Schleifen-Modus starten`,"koboCommand.prepAutoloopDesc":`Aufgaben für Auto-Schleifen-Modus vorbereiten (auf Atomarität prüfen)`,"staleSessionBanner.title":`Auto-Schleife läuft`,"staleSessionBanner.message":`Du siehst eine ältere Sitzung — der Agent arbeitet gerade in der neuesten.`,"staleSessionBanner.staleTitle":`Ältere Sitzung`,"staleSessionBanner.staleMessage":`Du siehst eine ältere Sitzung — gesendete Nachrichten gehen an diese Sitzung, nicht an die neueste.`,"staleSessionBanner.switchToCurrent":`Zur aktuellen wechseln`},on={"common.save":`Save`,"common.cancel":`Cancel`,"common.delete":`Delete`,"common.close":`Close`,"common.details":`Details`,"whatsNew.title":`What's new`,"common.loading":`Loading...`,"common.search":`Search...`,"common.refresh":`Refresh`,"common.copy":`Copy`,"common.copied":`Copied to clipboard`,"common.copyFailed":`Copy failed`,"common.add":`Add`,"folderPicker.title":`Choose a folder`,"folderPicker.parent":`Parent folder`,"folderPicker.empty":`No subfolders`,"folderPicker.select":`Select this folder`,"common.start":`Start`,"common.stop":`Stop`,"common.archive":`Archive`,"common.unarchive":`Unarchive`,"common.selectWorkspace":`Select a workspace`,"common.noResults":`No results for "{query}"`,"common.send":`send`,"common.newLine":`new line`,"common.history":`history`,"common.justNow":`just now`,"common.minutesAgo":`{count}m ago`,"common.hoursAgo":`{count}h ago`,"common.daysAgo":`{count}d ago`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Most capable model — successor to Opus 4.8, 1M context, adaptive thinking`,"model.mythos5Description":`Fable 5 without safety classifiers — limited access (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude picks the optimal model`,"model.opus48Description":`Most capable Opus — long-horizon agentic coding, 1M context by default, high effort default`,"model.opus47ClassicDescription":`Latest Opus, most capable`,"model.opus471mDescription":`Latest Opus, 1M context`,"model.opusClassicDescription":`Most powerful`,"model.opus1mDescription":`Most powerful, 1M context`,"model.sonnetClassicDescription":`Balanced`,"model.sonnet1mDescription":`Balanced, 1M context`,"model.haikuDescription":`Fastest`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recommended for complex coding (requires ChatGPT auth)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Default fallback — strong reasoning, works with API key auth`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Fast and efficient — best for responsive tasks and subagents`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Coding-specialized model for complex software engineering`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Let the engine pick the default`,"reasoning.minimalDescription":`Fastest, shallowest reasoning`,"reasoning.lowDescription":`Faster, less depth`,"reasoning.mediumDescription":`Balanced`,"reasoning.highDescription":`More depth`,"reasoning.xhighDescription":`Extended depth, long-horizon tasks`,"reasoning.maxDescription":`Maximum depth`,"agentPermissionMode.label":`Permission mode`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Accept edits`,"agentPermissionMode.interactive":`Interactive`,"agentPermissionMode.tooltip":`How the agent handles tool permissions. Plan: read-only, no writes. Bypass: skip every prompt. Strict: auto-accept file edits, respect allow/deny lists for the rest. Interactive: ask the user before each tool via the permission panel.`,"agentPermissionMode.autoLoopOverride":`Auto-loop forces a non-plan mode — Plan blocks the MCP tools and edits the loop relies on. Pick Bypass, Strict, or Interactive instead.`,"agentPermissionMode.autoLoopLocked":`Locked to Bypass while auto-loop is on — any other mode would stall the loop on permission prompts. AskUserQuestion still works.`,"workspaceList.title":`Workspaces`,"workspaceList.needsAttention":`Needs Attention`,"workspaceList.running":`Running`,"workspaceList.idle":`Idle`,"workspaceList.archived":`Archived`,"workspaceList.noWorkspaces":`No workspaces yet`,"workspaceList.footer":`{count} workspace | {count} workspaces`,"workspaceList.footerRunning":`{count} running`,"workspaceList.deleteDialog.title":`Delete workspace?`,"workspaceList.deleteDialog.deleteLocal":`Delete local branch`,"workspaceList.deleteDialog.deleteRemote":`Delete remote branch`,"workspaceList.deleteDialog.warning":`Warning: this action is irreversible on the remote.`,"workspaceList.deleteArchivedDialog.tooltip":`Delete all archived workspaces`,"workspaceList.deleteArchivedDialog.title":`Delete all archived workspaces?`,"workspaceList.deleteArchivedDialog.message":`This will permanently delete the {count} archived workspaces. This action cannot be undone.`,"workspacePage.selectWorkspace":`Select a workspace to begin`,"workspacePage.session":`Session #{n}`,"workspacePage.newSession":`+ New session`,"workspacePage.renameSession":`Rename`,"workspacePage.renameSessionTitle":`Rename session`,"workspacePage.sessionNameLabel":`Session name`,"workspacePage.sessionEndedNotice":`This session has ended. Create a new session to continue.`,"workspacePage.renameFailed":`Rename failed`,"workspacePage.createSessionFailed":`Failed to create session`,"workspacePage.startFailed":`Start failed`,"workspacePage.stopFailed":`Stop failed`,"workspacePage.interrupt":`Interrupt`,"workspacePage.interrupted":`Agent interrupted — waiting for your next message`,"workspacePage.archivedBanner":`Archived workspace — read-only`,"workspacePage.worktreePurgedBanner":`Worktree deleted — history kept, no restore available in this version`,"workspacePage.worktreePurgedTooltip":"The worktree folder was deleted from disk to reclaim space. Chat history, sessions and PR metadata remain queryable here, but the working directory no longer exists locally. A future Kōbō version will rebuild the worktree from the merged PR — for now you would need to recreate it manually via `gh pr checkout` or `git worktree add`.","workspacePage.pendingInitialPromptBanner":`An initial prompt is pending — the agent never received it (setup script crashed or the workspace was never started). Click Start to send it now.`,"workspacePage.unarchived":`Workspace unarchived`,"workspacePage.unarchiveFailed":`Unarchive failed`,"workspacePage.interruptFailed":`Interrupt failed`,"workspacePage.interruptTooltip":`Soft interrupt (like Escape) — stops the current tool but keeps the session alive`,"workspacePage.pendingNextRun":`Applied on next start`,"search.title":`Search`,"search.tooltip":`Search across agent history`,"search.placeholder":`Search across all agent messages…`,"search.includeArchived":`Include archived workspaces`,"search.loading":`Searching…`,"search.noResults":`No matches`,"search.error":`Search failed: {message}`,"search.resultCount":`{n} result(s)`,"search.eventType.userMessage":`You`,"search.eventType.agentOutput":`Agent`,"activityFeed.empty":`No activity yet`,"activityFeed.emptyHint":`Start a workspace to see agent output here`,"activityFeed.initialPrompt":`Initial Prompt`,"activityFeed.you":`You`,"activityFeed.agent":`Agent`,"activityFeed.question":`Question`,"activityFeed.goToPrevious":`Go to previous message`,"activityFeed.scrollToBottom":`Scroll to bottom`,"activityFeed.sendAnswers":`Send answers`,"agentBusy.banner":`Agent is busy`,"agentBusy.subagentsRunning":`1 sub-agent running | {n} sub-agents running`,"agentBusy.viewSubagents":`View sub-agents`,"agentBusy.pendingMessage":`Waiting — agent is busy`,"terminal.title":`Terminal`,"terminal.open":`Open terminal`,"terminal.close":`Close terminal`,"terminal.noWorkspace":`Select a workspace`,"terminal.noWorktree":`Worktree not created yet`,"terminal.error":`Terminal error`,"terminal.exited":`Terminal exited`,"chatInput.placeholder":`Message... (/ for skills)`,"chatInput.fileSearchHint":`search a file`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Attach image`,"chatInput.queueBanner":`Message queued — will be sent when the agent finishes`,"chatInput.cancelQueue":`Cancel Queue`,"chatInput.autoLoopBanner":`Auto-loop is running — stop it to send a message`,"chatInput.awaitingUserBanner":`The agent is waiting for your answer above — reply via the question panel`,"chatInput.autoLoopStop":`Stop`,"koboCommand.checkProgressDesc":`Verify progress on tasks and acceptance criteria`,"chatInput.uploading":`Uploading...`,"voice.title":`Voice transcription`,"voice.enabled":`Enable local voice transcription`,"voice.pttKey":`Push-to-talk key`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Space`,"voice.language":`Language (auto or code)`,"voice.model":`Active model`,"voice.commandPath":`Whisper binary path (optional)`,"voice.ffmpegPath":`ffmpeg binary path (optional)`,"voice.temperature":`Temperature`,"voice.temperatureHint":`Lower is more deterministic; higher can be more flexible but less stable.`,"voice.initialPrompt":`Initial prompt (optional)`,"voice.initialPromptHint":`Optional context to help Whisper with names, jargon, or domain vocabulary.`,"voice.translateToEnglish":`Translate to English`,"voice.translateToEnglishHint":`When enabled, non-English speech is translated to English instead of transcribed as-is.`,"voice.suppressNst":`Suppress non-speech tokens`,"voice.suppressNstHint":`Attempts to reduce non-speech artifacts in the transcript.`,"voice.installLink":`Install whisper.cpp`,"voice.installGuideTitle":`Installation guide`,"voice.installGuideIntro":`Install whisper.cpp and ffmpeg, then set the binary paths below if needed.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`After CMake build, the Whisper binary is usually at: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Then set "Whisper binary path" and "ffmpeg binary path" in this section (or leave empty if they are in PATH).`,"voice.noneModel":`No active model`,"voice.notInstalled":`not installed`,"voice.download":`Download`,"voice.delete":`Delete`,"voice.holdToTalk":`Hold to talk`,"voice.recording":`Recording...`,"voice.transcribing":`Transcribing...`,"voice.notSupported":`Voice recording is not supported in this browser`,"voice.errorMicPermission":`Microphone permission denied`,"voice.errorTranscription":`Voice transcription failed`,"voice.downloadFailed":`Model download failed`,"voice.deleteFailed":`Model deletion failed`,"voice.errorDisabled":`Voice transcription is disabled in settings`,"voice.errorModelMissing":`No active voice model is configured`,"voice.errorModelNotInstalled":`The active voice model is not installed`,"voice.errorAudioInvalid":`Audio capture is invalid or empty`,"voice.errorLanguageInvalid":`Voice language configuration is invalid`,"voice.errorRuntimeMissing":`Whisper runtime is not installed or not in PATH`,"voice.maxDurationReached":`Maximum recording duration reached`,"voice.runtimeReady":`Runtime ready: {command}`,"voice.runtimeMissing":`Runtime missing: {command}`,"voice.ffmpegReady":`ffmpeg ready`,"voice.ffmpegMissing":`ffmpeg missing`,"voice.sectionRuntime":`Runtime status`,"voice.sectionActivation":`Activation`,"voice.sectionModels":`Whisper models`,"voice.sectionAdvanced":`Advanced options`,"voice.sectionBehavior":`Transcription behavior`,"voice.sectionBinaries":`Binary paths`,"voice.downloadModels":`Download a model`,"voice.cancelFailed":`Failed to cancel the download`,"createPage.title":`What would you like to work on?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion enabled`,"createPage.importNotion":`Import from Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`URL must start with https://www.notion.so/ or https://app.notion.com/`,"createPage.notionAutoExtract":`Subtasks and acceptance criteria will be extracted automatically.`,"createPage.notionPanelChoiceLabel":`This URL points to a sub-page (?p=). Which one do you want to work on?`,"createPage.notionPanelOption":`Sub-page (panel)`,"createPage.notionPanelOptionDesc":`The page you were viewing — recommended`,"createPage.notionParentOption":`Parent page`,"createPage.notionParentOptionDesc":`The epic / database it belongs to`,"createPage.importSentry":`Import Sentry`,"createPage.sentryEnabled":`Sentry enabled`,"createPage.sentryPlaceholder":`https://your-org.sentry.io/issues/123456`,"createPage.sentryValidation":`URL must point to a Sentry issue (/issues/<id>)`,"createPage.sentryAutoExtract":`Sentry issue will be imported automatically`,"createPage.sentryExtractHint":`Kobo will extract the issue and write it to .ai/thoughts/`,"createPage.workspaceName":`Workspace name (defaults to Notion page title)`,"createPage.workspaceNamePlaceholder":`Workspace name...`,"createPage.instructions":`Additional instructions (optional)...`,"createPage.instructionsPlaceholder":`Describe the task...`,"createPage.manualHint":`No Notion ticket? Add your tasks and acceptance criteria manually — they'll be sent to the Claude agent as context.`,"createPage.tasks":`Tasks ({count})`,"createPage.addTask":`Add a task...`,"createPage.acceptanceCriteria":`Acceptance Criteria ({count})`,"createPage.addCriterion":`Add a criterion...`,"createPage.projectPath":`Enter the project path`,"createPage.branchType":`Branch type`,"createPage.branch":`Branch`,"createPage.noBranches":`No branches found`,"createPage.enterPath":`Enter a project path`,"createPage.create":`Create`,"createPage.skipSetupScript":`Skip setup script`,"createPage.attachWorktreeToggle":`Attach existing worktree`,"createPage.attachWorktreeEnabled":`Reusing existing worktree`,"createPage.worktreePickerLabel":`Existing worktree`,"createPage.noOrphanWorktrees":`No orphan worktrees in this project`,"createPage.pickWorktreeRequired":`Please pick a worktree to attach`,"createPage.notionExtractHint":`Subtasks and acceptance criteria will be extracted from the Notion page.`,"createPage.notionImportHint":`Click "Import from Notion" to automatically extract subtasks from a ticket.`,"createPage.errorCreating":`Error creating workspace.`,"createPage.branchAdjusted":"Branch already existed — created `{branch}` instead. The matching worktree folder uses the same suffix.","createPage.validationNotionUrl":`Please paste a valid Notion URL (https://www.notion.so/... or https://app.notion.com/...).`,"createPage.validationDescription":`Please describe the task.`,"createPage.validationName":`Please provide a workspace name.`,"createPage.validationPath":`Please enter the project path.`,"createPage.validationBranch":`Please select a branch.`,"settings.title":`Settings`,"settings.language":`Language`,"settings.projectColor":`Color`,"settings.projectColorClear":`Clear`,"settings.projectColorDefault":`Default (grey)`,"settings.workspaceListSection":`Workspace list`,"settings.flattenWorkspaceList":`Flatten workspace list`,"settings.flattenWorkspaceListHint":`Show all workspaces in a single flat list with a project badge, instead of grouping by project.`,"settings.skillSuite.section":`Skill suite`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Custom`,"settings.skillSuite.superpowersHint":`Opinionated TDD / brainstorm / plan workflow (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Garry Tan's stack — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Both suites stack — superpowers for process discipline (brainstorm / TDD / plans / principles-level review), gstack for concrete workflows (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Edit the four prompts below yourself. Starts from the agnostic baseline.`,"settings.skillSuite.reloadDefaults":`Reload defaults`,"settings.skillSuite.reloadDefaultsConfirm":`Replace the four custom prompts with the agnostic defaults?`,"settings.skillSuite.customPrompts":`Custom prompts`,"settings.skillSuite.reviewTemplate":`Review template`,"settings.skillSuite.autoLoopReviewGate":`Auto-loop review gate`,"settings.skillSuite.autoLoopGroomingIntro":`Auto-loop grooming intro`,"settings.skillSuite.qaTemplate":`QA template`,"settings.skillSuite.brainstormingInstruction":`Brainstorming-phase instruction`,"settings.global":`Global`,"settings.projects":`Projects`,"settings.globalSettings":`Global Settings`,"settings.defaultModel":`Default model`,"settings.defaultModelClaude":`Default model (Claude Code)`,"settings.defaultModelCodex":`Default model (OpenAI Codex)`,"settings.agentPermissions":`Agent permissions`,"settings.skipPermissions":`Skip permission prompts (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Warning: disabling this will cause all tool permissions (Write, Edit, Bash...) to be auto-denied in headless mode. The agent will only be able to read.`,"settings.notifications":`Notifications`,"settings.browserNotifications":`Browser notifications when agent finishes`,"settings.audioNotifications":`Sound notification when agent finishes`,"settings.notificationSound":`Notification sound`,"settings.notificationSoundPreview":`Preview`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Work done`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`It's gonna blow`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Default permission mode`,"settings.defaultPermissionModeClaude":`Default permission mode (Claude Code)`,"settings.defaultPermissionModeCodex":`Default permission mode (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Mode applied when creating a new workspace. Plan = read-only first, Bypass = skip prompts, Strict = auto-accept edits with allow-list, Interactive = ask before each tool.`,"settings.activityFeed":`Activity feed`,"settings.verboseMessages":`Show verbose system messages (task_progress, task_started)`,"settings.availableVariables":`Available template variables`,"settings.prPromptTemplate":`PR prompt template`,"settings.prPromptPlaceholder":`Instructions for the agent when creating GitHub PRs...`,"settings.prPromptHint":`Use the template variables listed above (double curly brace syntax).`,"settings.reviewPromptTemplate":`Review prompt template`,"settings.reviewPromptPlaceholder":`Instructions for the agent when reviewing branch changes...`,"settings.ciFixPromptTemplate":`CI fix prompt template`,"settings.ciFixPromptHint":`Sent to the agent when a workspace has failing CI. Variables (double-brace syntax): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Ask the agent to diagnose and fix the failing CI jobs...`,"settings.finalizationPromptTemplate":`Auto-loop finalization prompt`,"settings.finalizationPromptHint":`Default prompt for the final auto-loop iteration (last quality checks). Used when a project leaves its own finalization prompt empty.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Notion initial prompt`,"settings.notionInitialPrompt.help":`Appended to the workspace creation prompt when the workspace has a Notion ticket. Variables: {variables}.`,"settings.notionInitialPrompt.project":`Notion initial prompt (override)`,"settings.sentryInitialPrompt":`Sentry initial prompt`,"settings.sentryInitialPrompt.help":`Appended to the workspace creation prompt when the workspace has a Sentry issue. Variables: {variables}.`,"settings.sentryInitialPrompt.project":`Sentry initial prompt (override)`,"settings.initialPrompt.inheritHint":`Leave blank to inherit. Type any whitespace character to disable injection at this level.`,"settings.resetToDefault":`Reset to default`,"settings.resetFailed":`Failed to load default value`,"settings.sentryIntegration":`Sentry integration`,"settings.var.prNumber":`PR number (e.g., 42)`,"settings.var.prUrl":`Full URL of the created PR`,"settings.var.branchName":`Working branch name`,"settings.var.sourceBranch":`Source branch the PR targets`,"settings.var.workspaceName":`Workspace name`,"settings.var.projectName":`Last segment of the project path`,"settings.var.notionUrl":`Notion URL if set, empty otherwise`,"settings.var.commits":`Bulleted commit list between source and head`,"settings.var.diffStats":`Git shortstat summary (files, insertions, deletions)`,"settings.var.tasks":`Regular tasks as a checkbox list`,"settings.var.acceptanceCriteria":`Acceptance criteria as a checkbox list`,"settings.gitConventions":`Git conventions (global)`,"settings.gitConventionsPlaceholder":`# Git conventions...`,"settings.gitConventionsHint":`These conventions are written to .ai/.git-conventions.md in each new workspace and must be followed by the agent before any git operation. Overridden by per-project conventions if defined.`,"settings.setupScript":`Setup script`,"settings.cleanupScript":`Cleanup script`,"settings.archiveScript":`Archive script`,"settings.archiveScriptHint":`Shell script run server-side in the worktree when a workspace is archived. Leave empty to disable.`,"settings.archiveScriptPlaceholder":`e.g. clean up containers, free disk space…`,"settings.changeSourceBranchScript":`Change-source-branch script`,"settings.changeSourceBranchScript.help":`Replaces the built-in cherry-pick when non-empty. The script owns git, PR base, force-push and conflicts; Kōbō still refuses while the agent is running and updates the source-branch metadata on exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — new source branch chosen in the dialog
19
19
  KOBO_OLD_BASE — workspace’s previous source branch
20
20
  KOBO_WORKING_BRANCH — workspace’s working branch
21
21
  KOBO_WORKTREE_PATH — absolute path of the worktree (also cwd)
@@ -31,7 +31,7 @@ KOBO_PR_NUMBER — PR/MR number on the resolved forge (empty if none open)`
31
31
  # Or directly via git (works on GitHub even after branch deletion):
32
32
  git fetch origin pull/[pr-number]/head:[branch-name]
33
33
  git worktree add [path] [branch-name]`,"settings.purgeDocsRestoreFootnote":`GitHub keeps the PR head ref accessible long after the source branch is deleted (months / years). Auto-detection runs in the 30s watcher — no UI action needed once the folder is back.`,"settings.purgeDocsPermissionsTitle":`Avoiding permission errors during purge`,"settings.purgeDocsPermissionsIntro":`Docker often leaves root-owned files in node_modules / vendor inside the worktree. When Kōbō tries to remove them, you hit EACCES / EPERM and the purge fails. Two ways to prevent it:`,"settings.purgeDocsPermissionsDocker":'Configure your container to run as your host user — USER directive in the Dockerfile, or `user: "${UID}:${GID}"` in docker-compose (with UID/GID exported in your shell).',"settings.purgeDocsPermissionsAcl":`Pre-seed the worktrees root with a default ACL — safety net that works in MOST cases (ext4/btrfs/xfs + standard Docker bind mount). Each new file then inherits an access entry for your user, on top of the nominal owner:`,"settings.purgeDocsPermissionsAclCommand":` setfacl -d -m u:$(whoami):rwX [worktrees-root]`,"settings.purgeDocsPermissionsFootnote":"ACL limitations: do NOT work on named Docker volumes (use a bind mount), filesystems without ACL support (NTFS, exFAT, tmpfs), strict SELinux with `:Z`, or when Docker `userns-remap` is enabled. The most reliable solution remains configuring the user inside the container (option 1). Tip: `rwX` (capital X) only adds the executable bit on directories and already-executable files — cleaner than `rwx` which would make every text file executable.","settings.purgeDocsPermissionsRecoverTitle":`Unblock an already-broken worktree (existing root-owned files)`,"settings.purgeDocsPermissionsRecoverIntro":`If you end up with a worktree already full of root-owned files (Docker has run, vendor / node_modules are stuck), the preventive ACL above is not enough — you need to fix EXISTING files. Two approaches, both run from inside the worktree folder:`,"settings.purgeDocsPermissionsRecoverAclIntro":`Option A — Recursive ACL (preserves root ownership for audit, just adds access for your user alongside):`,"settings.purgeDocsPermissionsRecoverAclCommand":`# set default ACL for future files AND grant access to everything existing
34
- sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Take ownership (simpler, loses the "created by root in container" trace but rarely matters):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Tip: you can run these commands directly on the worktrees root (e.g. `~/.worktrees/`) to cover all existing AND future workspaces at once. Once done, Kōbō purge will work without permission errors.","contextMenu.runSetup":`Run setup script`,"contextMenu.exportEvents":`Export events (CSV)`,"contextMenu.dismissChangesRequested":`Mark 'Changes requested' as seen`,"contextMenu.dismissCiFailure":`Mark 'CI failure' as seen`,"contextMenu.restoreChangesRequested":`Mark 'Changes requested' as unseen`,"contextMenu.restoreCiFailure":`Mark 'CI failure' as unseen`,"contextMenu.exportingEvents":`Preparing export…`,"contextMenu.exportEventsError":`Event export failed`,"contextMenu.openNotion":`Open in Notion`,"contextMenu.openSentry":`Open in Sentry`,"contextMenu.openPr":`Open PR`,"workspace.favorite":`Mark as favorite`,"workspace.unfavorite":`Remove from favorites`,"workspace.showFavoritesOnly":`Show favorites only`,"workspace.searchArchivedToggle":`Also search archived workspaces`,"workspace.descriptionPlaceholder":`Add a short description`,"workspace.descriptionDialogHint":`Plain text, 200 characters max. Leave empty to clear.`,"workspace.descriptionTooLong":`Description must be 200 characters or fewer.`,"workspace.descriptionSaveFailed":`Failed to save description.`,"workspace.agentDescriptionTooltip":`Live status maintained by the agent`,"mcp.tool.setWorkspaceDescription":`Set the workspace short description (≤ 200 chars).`,"tags.manage":`Manage tags`,"tags.manageTitle":`Manage workspace tags`,"tags.noTagsDefined":`No tags defined. Add some in Settings > Global > Tags.`,"tags.orphanedHint":`{count} tag(s) are no longer in the global catalog. Uncheck to remove them.`,"settings.tagsTitle":`Workspace tags`,"settings.tagsHint":`Define the tags you can assign to workspaces. Type to add, click the cross to remove.`,"settings.tagsLabel":`Available tags`,"settings.branchPrefixesTitle":`Branch prefixes`,"settings.branchPrefixesHint":`Manage the git branch prefixes available on the workspace creation page. The first one is pre-selected by default.`,"settings.branchPrefixesEmpty":`No branch prefix defined. Add at least one below.`,"settings.branchPrefixesAddLabel":`New prefix`,"settings.branchPrefixesEditHint":`Click to rename`,"settings.branchPrefixesMoveUp":`Move up`,"settings.branchPrefixesMoveDown":`Move down`,"settings.worktreesTitle":`Git worktrees`,"settings.worktreesHint":`Choose where new workspace worktrees are created. Relative paths are project-relative; Linux/macOS and Windows absolute paths, $HOME, ~, and %USERPROFILE% are supported.`,"settings.worktreesPathLabel":`Worktrees path`,"settings.worktreesPathRequired":`Worktrees path is required.`,"settings.worktreesPrefixByProject":`Prefix worktrees by project name`,"settings.worktreesPrefixByProjectHint":`Place each worktree under a sub-directory named after the project, to avoid collisions when multiple projects share the same worktrees root.`,"settings.shareTitle":`Share configuration`,"settings.shareHint":`Export your settings, templates and tags as a JSON bundle. MCP API keys are stripped from exports for security.`,"settings.exportConfig":`Export`,"settings.importConfig":`Import`,"settings.exportSuccess":`Configuration exported`,"settings.importSuccess":`Configuration imported`,"settings.importConfirmTitle":`Import configuration`,"settings.importConfirmMessage":`This will replace your current settings, templates and tags. Your MCP keys are preserved. Continue?`,"health.title":`Health`,"health.tooltip":`System health`,"changelog.title":`Changelog`,"changelog.tooltip":`What's new in Kōbō`,"changelog.empty":`No changelog available.`,"changelog.current":`current`,"changelog.currentVersion":`Current version: v{version}`,"health.envTitle":`Environment`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Database`,"health.dbPath":`Path`,"health.dbSize":`Size`,"health.schemaVersion":`Schema version`,"health.settingsSchemaVersion":`Settings schema`,"health.runtimesTitle":`Agent runtimes`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude not on PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`codex binary not resolvable`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} total, {archived} archived`,"health.worktreesMissing":`{count} worktree(s) missing on disk`,"health.sessionsTitle":`Agent sessions`,"health.sessionsOrphaned":`{n} orphaned running session(s)`,"health.integrationsTitle":`Integrations`,"health.integrationConfigured":`configured`,"health.integrationMissing":`not configured`,"health.activeTitle":`Active state`,"health.activeQuotaBackoffs":`Pending quota backoffs`,"health.activeWakeups":`Scheduled wakeups`,"health.activeAutoLoop":`Auto-loop running`,"health.activeAgentSessions":`Live agent sessions`,"health.activeDevServers":`Running dev servers`,"health.noneActive":`None.`,"health.quotaResumeAt":`resumes at {time}`,"health.wakeupAt":`wakes at {time}`,"health.startedAgo":`started {time} ago`,"health.autoLoopReady":`ready, iterating`,"health.autoLoopGrooming":`grooming in progress`,"session.started":`Session started`,"session.ended":`Session ended`,"session.compacted":`Context compacted`,"tool.running":`Running...`,"activity.raw_lines":`Raw output lines ({n})`,"activity.loading_older":`Loading older messages…`,"activity.compacting":`Compacting context…`,"activity.prev_user_message":`Previous user message`,"activity.scroll_to_bottom":`Scroll to bottom`,"chat.systemPrompt":`System prompt`,"chat.agent":`Agent`,"chat.cleanupScript":`Cleanup script`,"chat.archiveScript":`Archive script`,"chat.setupScript":`Setup script`,"chat.scriptDone":`Done`,"chat.you":`You`,"chat.session":`Session`,"chat.nActions":`{n} action | {n} actions`,"chat.lastUpdatedAt":`Last updated at {time}`,"chat.scrollToTurnTop":`Scroll to top of this message`,"migration.backing_up":`Backing up the database…`,"migration.running":`Migrating agent data — {processed}/{total}`,"migration.error":`Migration failed`,"migration.backup_location":`A backup was saved at {path}. Restart Kōbō to retry.`,"migration.retry":`Restart Kōbō to retry.`,"engine.select":`Engine`,"engine.model":`Model`,"engine.effort":`Reasoning effort`,"wakeup.scheduledIn":`Next wakeup in {n}s`,"wakeup.scheduledAt":`Next wakeup at {time}`,"wakeup.firing":`Waking up...`,"wakeup.reason":`Reason: {reason}`,"wakeup.cancel":`Cancel this wakeup`,"wakeup.pendingIndicator":`Wakeup scheduled`,"cron.pendingIndicator":`{n} cron(s) scheduled`,"schedule.tabLabel":`Schedule`,"schedule.wakeupTitle":`Wakeup pending`,"schedule.cronsTitle":`Recurring schedules`,"schedule.noWakeup":`No wakeup scheduled`,"schedule.noCrons":`No cron scheduled`,"schedule.nextFireAt":`next at {time}`,"schedule.lastFiredAt":`last fired {time} ago`,"askUserQuestion.title":`The agent is asking a question`,"askUserQuestion.submit":`Submit answer`,"askUserQuestion.multiSelectHint":`Select one or more options`,"askUserQuestion.otherOption":`Other`,"askUserQuestion.otherOptionHint":`specify in your next chat message`,"askUserQuestion.noPending":`No pending question`,"askUserQuestion.next":`Next`,"askUserQuestion.previous":`Previous`,"askUserQuestion.cancel":`Cancel`,"askUserQuestion.cancelTooltip":`Skip this question — the agent will proceed without an answer`,"askUserQuestion.collapse":`Collapse the question panel`,"askUserQuestion.expand":`Expand the question panel`,"permissionRequest.title":`The agent wants to use a tool`,"permissionRequest.allow":`Allow`,"permissionRequest.deny":`Deny`,"permissionRequest.tool":`Tool`,"permissionRequest.input":`Input`,"permissionRequest.denied":`denied by user`,"workspaceStatus.awaitingUser":`awaiting your answer`,"workspaceList.prOpen":`#{n} — Pull request open`,"workspaceList.prChangesRequested":`#{n} — Changes requested`,"workspaceList.attentionCiFailed":`CI failed`,"workspaceList.attentionChangesRequested":`Changes requested`,"workspaceList.attentionReadyToMerge":`Ready to merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Start auto-loop`,"autoLoop.prepare":`Prepare for auto-loop`,"autoLoop.reprepare":`Re-prepare for auto-loop`,"autoLoop.reprepareTooltip":`Re-run the grooming pass to add or refresh tasks before resuming the loop`,"autoLoop.prepareBusy":`Wait for the agent to finish before preparing`,"autoLoop.forceReady":`I know what I'm doing — skip grooming`,"autoLoop.forceReadyConfirm":`Skip grooming and mark auto-loop ready? This may cause the loop to stall if tasks aren't atomic.`,"autoLoop.stop":`Stop auto-loop`,"autoLoop.notReady":`Run 'Prepare for auto-loop' first`,"autoLoop.noTasks":`Add tasks first`,"autoLoop.progress":`Auto-loop · {done}/{total} tasks`,"autoLoop.preparing":`Auto-loop · preparing`,"autoLoop.preparingTooltip":`Grooming in progress — the agent is creating / reviewing tasks. The loop will start running once it calls mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop running`,"autoLoop.startInMode":`Start in auto-loop mode`,"koboCommand.prepAutoloopDesc":`Prepare tasks for auto-loop mode (groom for atomicity)`,"staleSessionBanner.title":`Auto-loop running`,"staleSessionBanner.message":`You're viewing an older session — the agent is currently working in the latest one.`,"staleSessionBanner.switchToCurrent":`Switch to current`},sn={"common.save":`Guardar`,"common.cancel":`Cancelar`,"common.delete":`Eliminar`,"common.close":`Cerrar`,"common.details":`Detalles`,"whatsNew.title":`Novedades`,"common.loading":`Cargando...`,"common.search":`Buscar...`,"common.refresh":`Actualizar`,"common.copy":`Copiar`,"common.copied":`Copiado al portapapeles`,"common.copyFailed":`Error al copiar`,"common.add":`Añadir`,"folderPicker.title":`Elegir una carpeta`,"folderPicker.parent":`Carpeta superior`,"folderPicker.empty":`Sin subcarpetas`,"folderPicker.select":`Elegir esta carpeta`,"common.start":`Iniciar`,"common.stop":`Detener`,"common.archive":`Archivar`,"common.unarchive":`Desarchivar`,"common.selectWorkspace":`Selecciona un workspace`,"common.noResults":`Sin resultados para "{query}"`,"common.send":`enviar`,"common.newLine":`nueva línea`,"common.history":`historial`,"common.justNow":`ahora mismo`,"common.minutesAgo":`hace {count}m`,"common.hoursAgo":`hace {count}h`,"common.daysAgo":`hace {count}d`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`El modelo más capaz — sucesor de Opus 4.8, contexto 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 sin clasificadores de seguridad — acceso limitado (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude elige el modelo óptimo`,"model.opus48Description":`Opus más capaz — coding agéntico long-horizon, contexto 1M por defecto, esfuerzo high por defecto`,"model.opus47ClassicDescription":`Último Opus, el más capaz`,"model.opus471mDescription":`Último Opus, contexto 1M`,"model.opusClassicDescription":`El más potente`,"model.opus1mDescription":`El más potente, contexto 1M`,"model.sonnetClassicDescription":`Equilibrado`,"model.sonnet1mDescription":`Equilibrado, contexto 1M`,"model.haikuDescription":`El más rápido`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recomendado para código complejo (requiere autenticación ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Alternativa por defecto — razonamiento sólido, compatible con clave API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Rápido y eficiente — ideal para tareas reactivas y subagentes`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modelo especializado en código para ingeniería de software compleja`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Deja que el motor decida`,"reasoning.minimalDescription":`Razonamiento más rápido y superficial`,"reasoning.lowDescription":`Más rápido, menos profundidad`,"reasoning.mediumDescription":`Equilibrado`,"reasoning.highDescription":`Más profundidad`,"reasoning.xhighDescription":`Profundidad extendida, tareas largas`,"reasoning.maxDescription":`Profundidad máxima`,"agentPermissionMode.label":`Modo de permisos`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Aceptar ediciones`,"agentPermissionMode.interactive":`Interactivo`,"agentPermissionMode.tooltip":`Cómo gestiona el agente los permisos de las herramientas. Plan: solo lectura, sin escrituras. Bypass: omitir todas las preguntas. Estricto: auto-aceptar ediciones de archivos, respetar allow/deny para el resto. Interactivo: preguntar al usuario antes de cada herramienta mediante el panel de permisos.`,"agentPermissionMode.autoLoopOverride":`El auto-loop fuerza un modo distinto a Plan — Plan bloquea las herramientas MCP y las ediciones que el bucle necesita. Elige Bypass, Estricto o Interactivo.`,"agentPermissionMode.autoLoopLocked":`Bloqueado en Bypass mientras el auto-loop está activo — cualquier otro modo detendría el bucle en las preguntas de permiso. AskUserQuestion sigue funcionando.`,"workspaceList.title":`Workspaces`,"workspaceList.needsAttention":`Requiere atención`,"workspaceList.running":`En ejecución`,"workspaceList.idle":`Inactivo`,"workspaceList.archived":`Archivados`,"workspaceList.noWorkspaces":`Aún no hay workspaces`,"workspaceList.footer":`{count} workspace | {count} workspaces`,"workspaceList.footerRunning":`{count} en ejecución`,"workspaceList.deleteDialog.title":`¿Eliminar workspace?`,"workspaceList.deleteDialog.deleteLocal":`Eliminar rama local`,"workspaceList.deleteDialog.deleteRemote":`Eliminar rama remota`,"workspaceList.deleteDialog.warning":`Advertencia: esta acción es irreversible en el remoto.`,"workspaceList.deleteArchivedDialog.tooltip":`Eliminar todos los workspaces archivados`,"workspaceList.deleteArchivedDialog.title":`¿Eliminar todos los workspaces archivados?`,"workspaceList.deleteArchivedDialog.message":`Esto eliminará permanentemente los {count} workspaces archivados. Esta acción no se puede deshacer.`,"workspacePage.selectWorkspace":`Selecciona un workspace para comenzar`,"workspacePage.session":`Sesión #{n}`,"workspacePage.newSession":`+ Nueva sesión`,"workspacePage.renameSession":`Renombrar`,"workspacePage.renameSessionTitle":`Renombrar sesión`,"workspacePage.sessionNameLabel":`Nombre de sesión`,"workspacePage.sessionEndedNotice":`Esta sesión ha terminado. Crea una nueva sesión para continuar.`,"workspacePage.renameFailed":`Error al renombrar`,"workspacePage.createSessionFailed":`Error al crear la sesión`,"workspacePage.startFailed":`Error al iniciar`,"workspacePage.stopFailed":`Error al detener`,"workspacePage.interrupt":`Interrumpir`,"workspacePage.interrupted":`Agente interrumpido — esperando tu próximo mensaje`,"workspacePage.archivedBanner":`Workspace archivado — solo lectura`,"workspacePage.worktreePurgedBanner":`Worktree eliminado — historial conservado, restauración no disponible en esta versión`,"workspacePage.worktreePurgedTooltip":"La carpeta del worktree fue eliminada del disco para recuperar espacio. El historial de mensajes, sesiones y metadatos de la PR siguen consultables aquí, pero el directorio de trabajo ya no existe localmente. Una futura versión de Kōbō podrá reconstruir el worktree desde la PR mergeada — por ahora, recréalo manualmente con `gh pr checkout` o `git worktree add`.","workspacePage.pendingInitialPromptBanner":`Hay un prompt inicial pendiente — el agente nunca lo recibió (el script de setup falló o el workspace nunca se inició). Haz clic en Iniciar para enviarlo ahora.`,"workspacePage.unarchived":`Workspace desarchivado`,"workspacePage.unarchiveFailed":`Error al desarchivar`,"workspacePage.interruptFailed":`Error al interrumpir`,"workspacePage.interruptTooltip":`Interrupción suave (como Escape) — detiene la herramienta actual pero mantiene la sesión activa`,"workspacePage.pendingNextRun":`Se aplicará en el próximo inicio`,"search.title":`Búsqueda`,"search.tooltip":`Buscar en el historial de agentes`,"search.placeholder":`Buscar en todos los mensajes de agentes…`,"search.includeArchived":`Incluir workspaces archivados`,"search.loading":`Buscando…`,"search.noResults":`Sin resultados`,"search.error":`Búsqueda fallida: {message}`,"search.resultCount":`{n} resultado(s)`,"search.eventType.userMessage":`Tú`,"search.eventType.agentOutput":`Agente`,"activityFeed.empty":`Aún no hay actividad`,"activityFeed.emptyHint":`Inicia un workspace para ver la salida del agente aquí`,"activityFeed.initialPrompt":`Prompt inicial`,"activityFeed.you":`Tú`,"activityFeed.agent":`Agente`,"activityFeed.question":`Pregunta`,"activityFeed.goToPrevious":`Ir al mensaje anterior`,"activityFeed.scrollToBottom":`Ir al final`,"activityFeed.sendAnswers":`Enviar respuestas`,"agentBusy.banner":`El agente está ocupado`,"agentBusy.subagentsRunning":`1 sub-agente en ejecución | {n} sub-agentes en ejecución`,"agentBusy.viewSubagents":`Ver sub-agentes`,"agentBusy.pendingMessage":`Esperando — el agente está ocupado`,"terminal.title":`Terminal`,"terminal.open":`Abrir terminal`,"terminal.close":`Cerrar terminal`,"terminal.noWorkspace":`Seleccione un espacio de trabajo`,"terminal.noWorktree":`Worktree aún no creado`,"terminal.error":`Error del terminal`,"terminal.exited":`Terminal cerrado`,"chatInput.placeholder":`Mensaje... (/ para skills)`,"chatInput.fileSearchHint":`buscar un archivo`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Adjuntar imagen`,"chatInput.queueBanner":`Mensaje en cola — se enviará cuando el agente termine`,"chatInput.cancelQueue":`Cancelar cola`,"chatInput.autoLoopBanner":`Auto-loop activo — deténlo para enviar un mensaje`,"chatInput.awaitingUserBanner":`El agente espera tu respuesta arriba — responde mediante el panel de la pregunta`,"chatInput.autoLoopStop":`Detener`,"koboCommand.checkProgressDesc":`Verificar el progreso de las tareas y criterios de aceptación`,"chatInput.uploading":`Subiendo...`,"voice.title":`Transcripción de voz`,"voice.enabled":`Activar transcripción de voz local`,"voice.pttKey":`Tecla push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Espacio`,"voice.language":`Idioma (auto o código)`,"voice.model":`Modelo activo`,"voice.commandPath":`Ruta del binario Whisper (opcional)`,"voice.ffmpegPath":`Ruta del binario ffmpeg (opcional)`,"voice.temperature":`Temperatura`,"voice.temperatureHint":`Más bajo = más determinista; más alto = más flexible pero potencialmente menos estable.`,"voice.initialPrompt":`Prompt inicial (opcional)`,"voice.initialPromptHint":`Contexto opcional para ayudar a Whisper con nombres, siglas o vocabulario técnico.`,"voice.translateToEnglish":`Traducir al inglés`,"voice.translateToEnglishHint":`Si se activa, el audio no inglés se traduce al inglés en lugar de transcribirse tal cual.`,"voice.suppressNst":`Suprimir tokens no vocales`,"voice.suppressNstHint":`Intenta reducir artefactos no vocales en la transcripción.`,"voice.installLink":`Instalar whisper.cpp`,"voice.installGuideTitle":`Guía de instalación`,"voice.installGuideIntro":`Instala whisper.cpp y ffmpeg, luego configura las rutas de binarios abajo si hace falta.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Después del build con CMake, el binario de Whisper suele estar en: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Después, configura “Ruta del binario Whisper” y “Ruta del binario ffmpeg” en esta sección (o déjalo vacío si están en PATH).`,"voice.noneModel":`Sin modelo activo`,"voice.notInstalled":`no instalado`,"voice.download":`Descargar`,"voice.delete":`Eliminar`,"voice.holdToTalk":`Mantén pulsado para hablar`,"voice.recording":`Grabando...`,"voice.transcribing":`Transcribiendo...`,"voice.notSupported":`La grabación de voz no es compatible con este navegador`,"voice.errorMicPermission":`Permiso de micrófono denegado`,"voice.errorTranscription":`Falló la transcripción de voz`,"voice.downloadFailed":`Falló la descarga del modelo`,"voice.deleteFailed":`Falló la eliminación del modelo`,"voice.errorDisabled":`La transcripción de voz está desactivada en ajustes`,"voice.errorModelMissing":`No hay un modelo de voz activo configurado`,"voice.errorModelNotInstalled":`El modelo de voz activo no está instalado`,"voice.errorAudioInvalid":`La captura de audio es inválida o vacía`,"voice.errorLanguageInvalid":`La configuración del idioma de voz es inválida`,"voice.errorRuntimeMissing":`El runtime de Whisper no está instalado o no está en el PATH`,"voice.maxDurationReached":`Se alcanzó la duración máxima de grabación`,"voice.runtimeReady":`Runtime listo: {command}`,"voice.runtimeMissing":`Falta runtime: {command}`,"voice.ffmpegReady":`ffmpeg listo`,"voice.ffmpegMissing":`falta ffmpeg`,"voice.sectionRuntime":`Estado del runtime`,"voice.sectionActivation":`Activación`,"voice.sectionModels":`Modelos Whisper`,"voice.sectionAdvanced":`Opciones avanzadas`,"voice.sectionBehavior":`Comportamiento de la transcripción`,"voice.sectionBinaries":`Rutas de los binarios`,"voice.downloadModels":`Descargar un modelo`,"voice.cancelFailed":`No se pudo cancelar la descarga`,"createPage.title":`¿En qué te gustaría trabajar?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion activado`,"createPage.importNotion":`Importar desde Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`La URL debe empezar por https://www.notion.so/ o https://app.notion.com/`,"createPage.notionAutoExtract":`Las subtareas y criterios de aceptación se extraerán automáticamente.`,"createPage.notionPanelChoiceLabel":`Esta URL apunta a una subpágina (?p=). ¿Sobre cuál quieres trabajar?`,"createPage.notionPanelOption":`Subpágina (panel)`,"createPage.notionPanelOptionDesc":`La página que estabas viendo — recomendado`,"createPage.notionParentOption":`Página principal`,"createPage.notionParentOptionDesc":`La épica / base de datos a la que pertenece`,"createPage.importSentry":`Importar Sentry`,"createPage.sentryEnabled":`Sentry activado`,"createPage.sentryPlaceholder":`https://tu-org.sentry.io/issues/123456`,"createPage.sentryValidation":`La URL debe apuntar a una issue de Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`La issue de Sentry se importará automáticamente`,"createPage.sentryExtractHint":`Kobo extraerá la issue y la escribirá en .ai/thoughts/`,"createPage.workspaceName":`Nombre del workspace (por defecto el título de la página Notion)`,"createPage.workspaceNamePlaceholder":`Nombre del workspace...`,"createPage.instructions":`Instrucciones adicionales (opcional)...`,"createPage.instructionsPlaceholder":`Describe la tarea...`,"createPage.manualHint":`¿Sin ticket Notion? Añade tus tareas y criterios de aceptación manualmente — se enviarán al agente Claude como contexto.`,"createPage.tasks":`Tareas ({count})`,"createPage.addTask":`Añadir una tarea...`,"createPage.acceptanceCriteria":`Criterios de aceptación ({count})`,"createPage.addCriterion":`Añadir un criterio...`,"createPage.projectPath":`Introduce la ruta del proyecto`,"createPage.branchType":`Tipo de rama`,"createPage.branch":`Rama`,"createPage.noBranches":`No se encontraron ramas`,"createPage.enterPath":`Introduce la ruta del proyecto`,"createPage.create":`Crear`,"createPage.skipSetupScript":`Omitir script de setup`,"createPage.attachWorktreeToggle":`Adjuntar worktree existente`,"createPage.attachWorktreeEnabled":`Reutilizando worktree existente`,"createPage.worktreePickerLabel":`Worktree existente`,"createPage.noOrphanWorktrees":`No hay worktrees huérfanos en este proyecto`,"createPage.pickWorktreeRequired":`Selecciona un worktree para adjuntar`,"createPage.notionExtractHint":`Las subtareas y criterios de aceptación se extraerán de la página Notion.`,"createPage.notionImportHint":`Haz clic en "Importar desde Notion" para extraer automáticamente las subtareas de un ticket.`,"createPage.errorCreating":`Error al crear el workspace.`,"createPage.branchAdjusted":"La rama ya existía — se creó `{branch}` en su lugar. La carpeta worktree correspondiente usa el mismo sufijo.","createPage.validationNotionUrl":`Introduce una URL de Notion válida (https://www.notion.so/... o https://app.notion.com/...).`,"createPage.validationDescription":`Describe la tarea.`,"createPage.validationName":`Indica un nombre para el workspace.`,"createPage.validationPath":`Introduce la ruta del proyecto.`,"createPage.validationBranch":`Selecciona una rama.`,"settings.title":`Ajustes`,"settings.language":`Idioma`,"settings.projectColor":`Color`,"settings.projectColorClear":`Borrar`,"settings.projectColorDefault":`Por defecto (gris)`,"settings.workspaceListSection":`Lista de workspaces`,"settings.flattenWorkspaceList":`Lista plana de workspaces`,"settings.flattenWorkspaceListHint":`Muestra todos los workspaces en una lista plana con una etiqueta de proyecto, en lugar de agruparlos por proyecto.`,"settings.skillSuite.section":`Suite de skills`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personalizado`,"settings.skillSuite.superpowersHint":`Workflow opinado TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite de Garry Tan — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Ambas suites se combinan — superpowers para la metodología (brainstorm / TDD / planes / revisión a nivel de principios), gstack para flujos concretos (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Edita los cuatro prompts a continuación tú mismo. Parte de la base agnóstica.`,"settings.skillSuite.reloadDefaults":`Restaurar predeterminados`,"settings.skillSuite.reloadDefaultsConfirm":`¿Reemplazar los cuatro prompts personalizados con los valores agnósticos predeterminados?`,"settings.skillSuite.customPrompts":`Prompts personalizados`,"settings.skillSuite.reviewTemplate":`Template de revisión`,"settings.skillSuite.autoLoopReviewGate":`Compuerta de revisión auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro de grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Instrucción de la fase de brainstorming`,"settings.global":`Global`,"settings.projects":`Proyectos`,"settings.globalSettings":`Ajustes globales`,"settings.defaultModel":`Modelo por defecto`,"settings.defaultModelClaude":`Modelo por defecto (Claude Code)`,"settings.defaultModelCodex":`Modelo por defecto (OpenAI Codex)`,"settings.agentPermissions":`Permisos del agente`,"settings.skipPermissions":`Omitir solicitudes de permisos (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Advertencia: desactivar esto hará que todos los permisos de herramientas (Write, Edit, Bash...) se denieguen automáticamente en modo headless. El agente solo podrá leer.`,"settings.notifications":`Notificaciones`,"settings.browserNotifications":`Notificación del navegador cuando el agente termina`,"settings.audioNotifications":`Notificación sonora cuando el agente termina`,"settings.notificationSound":`Sonido de notificación`,"settings.notificationSoundPreview":`Escuchar`,"settings.notificationVolume":`Volumen`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Trabajo terminado`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Va a explotar`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Modo de permisos por defecto`,"settings.defaultPermissionModeClaude":`Modo de permisos por defecto (Claude Code)`,"settings.defaultPermissionModeCodex":`Modo de permisos por defecto (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Modo aplicado al crear un workspace. Plan = solo lectura, Bypass = sin avisos, Estricto = auto-aceptar ediciones con allow-list, Interactivo = preguntar antes de cada herramienta.`,"settings.activityFeed":`Feed de actividad`,"settings.verboseMessages":`Mostrar mensajes detallados del sistema (task_progress, task_started)`,"settings.availableVariables":`Variables disponibles en las plantillas de prompt`,"settings.prPromptTemplate":`Plantilla de prompt PR`,"settings.prPromptPlaceholder":`Instrucciones para el agente al crear PRs en GitHub...`,"settings.prPromptHint":`Usa las variables listadas arriba (sintaxis de dobles llaves).`,"settings.reviewPromptTemplate":`Plantilla de prompt de revisión`,"settings.reviewPromptPlaceholder":`Instrucciones para el agente al revisar los cambios de la rama...`,"settings.ciFixPromptTemplate":`Plantilla de prompt «Reparar CI»`,"settings.ciFixPromptHint":`Se envía al agente cuando un workspace tiene la CI fallando. Variables (sintaxis con dobles llaves): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Pedir al agente que diagnostique y arregle los jobs de CI que fallan...`,"settings.finalizationPromptTemplate":`Prompt de finalización del auto-loop`,"settings.finalizationPromptHint":`Prompt por defecto para la última iteración del auto-loop (controles de calidad finales). Se usa cuando un proyecto deja vacío su propio prompt de finalización.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt inicial de Notion`,"settings.notionInitialPrompt.help":`Se añade al prompt de creación del workspace cuando el workspace tiene un ticket de Notion. Variables: {variables}.`,"settings.notionInitialPrompt.project":`Prompt inicial de Notion (anulación)`,"settings.sentryInitialPrompt":`Prompt inicial de Sentry`,"settings.sentryInitialPrompt.help":`Se añade al prompt de creación del workspace cuando el workspace tiene una issue de Sentry. Variables: {variables}.`,"settings.sentryInitialPrompt.project":`Prompt inicial de Sentry (anulación)`,"settings.initialPrompt.inheritHint":`Dejar en blanco para heredar. Escribe un carácter en blanco para desactivar la inyección a este nivel.`,"settings.resetToDefault":`Restablecer`,"settings.resetFailed":`No se pudo cargar el valor por defecto`,"settings.sentryIntegration":`Integración Sentry`,"settings.var.prNumber":`Número de PR (ej: 42)`,"settings.var.prUrl":`URL completa de la PR creada`,"settings.var.branchName":`Nombre de la rama de trabajo`,"settings.var.sourceBranch":`Rama fuente a la que apunta la PR`,"settings.var.workspaceName":`Nombre del workspace`,"settings.var.projectName":`Último segmento de la ruta del proyecto`,"settings.var.notionUrl":`URL de Notion si está definida, vacía en caso contrario`,"settings.var.commits":`Lista de commits entre source y head`,"settings.var.diffStats":`Resumen shortstat de Git (archivos, inserciones, eliminaciones)`,"settings.var.tasks":`Tareas regulares como lista de verificación`,"settings.var.acceptanceCriteria":`Criterios de aceptación como lista de verificación`,"settings.gitConventions":`Convenciones Git (global)`,"settings.gitConventionsPlaceholder":`# Convenciones Git...`,"settings.gitConventionsHint":`Estas convenciones se escriben en .ai/.git-conventions.md en cada nuevo workspace y deben ser seguidas por el agente antes de cualquier operación Git. Se anulan con convenciones por proyecto si están definidas.`,"settings.setupScript":`Script de setup`,"settings.cleanupScript":`Script de limpieza`,"settings.archiveScript":`Script de archivado`,"settings.archiveScriptHint":`Script de shell ejecutado en el servidor en el worktree cuando se archiva un workspace. Dejar vacío para desactivar.`,"settings.archiveScriptPlaceholder":`p. ej. limpiar contenedores, liberar espacio en disco…`,"settings.changeSourceBranchScript":`Script para cambiar la rama de origen`,"settings.changeSourceBranchScript.help":`Reemplaza el cherry-pick integrado cuando no está vacío. El script gestiona git, base de la PR, force-push y conflictos; Kōbō solo rechaza si el agente está corriendo y actualiza los metadatos de la rama de origen en exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nueva rama de origen elegida en el diálogo
34
+ sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Take ownership (simpler, loses the "created by root in container" trace but rarely matters):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Tip: you can run these commands directly on the worktrees root (e.g. `~/.worktrees/`) to cover all existing AND future workspaces at once. Once done, Kōbō purge will work without permission errors.","contextMenu.runSetup":`Run setup script`,"contextMenu.exportEvents":`Export events (CSV)`,"contextMenu.dismissChangesRequested":`Mark 'Changes requested' as seen`,"contextMenu.dismissCiFailure":`Mark 'CI failure' as seen`,"contextMenu.restoreChangesRequested":`Mark 'Changes requested' as unseen`,"contextMenu.restoreCiFailure":`Mark 'CI failure' as unseen`,"contextMenu.exportingEvents":`Preparing export…`,"contextMenu.exportEventsError":`Event export failed`,"contextMenu.openNotion":`Open in Notion`,"contextMenu.openSentry":`Open in Sentry`,"contextMenu.openPr":`Open PR`,"workspace.favorite":`Mark as favorite`,"workspace.unfavorite":`Remove from favorites`,"workspace.showFavoritesOnly":`Show favorites only`,"workspace.searchArchivedToggle":`Also search archived workspaces`,"workspace.descriptionPlaceholder":`Add a short description`,"workspace.descriptionDialogHint":`Plain text, 200 characters max. Leave empty to clear.`,"workspace.descriptionTooLong":`Description must be 200 characters or fewer.`,"workspace.descriptionSaveFailed":`Failed to save description.`,"workspace.agentDescriptionTooltip":`Live status maintained by the agent`,"mcp.tool.setWorkspaceDescription":`Set the workspace short description (≤ 200 chars).`,"tags.manage":`Manage tags`,"tags.manageTitle":`Manage workspace tags`,"tags.noTagsDefined":`No tags defined. Add some in Settings > Global > Tags.`,"tags.orphanedHint":`{count} tag(s) are no longer in the global catalog. Uncheck to remove them.`,"settings.tagsTitle":`Workspace tags`,"settings.tagsHint":`Define the tags you can assign to workspaces. Type to add, click the cross to remove.`,"settings.tagsLabel":`Available tags`,"settings.branchPrefixesTitle":`Branch prefixes`,"settings.branchPrefixesHint":`Manage the git branch prefixes available on the workspace creation page. The first one is pre-selected by default.`,"settings.branchPrefixesEmpty":`No branch prefix defined. Add at least one below.`,"settings.branchPrefixesAddLabel":`New prefix`,"settings.branchPrefixesEditHint":`Click to rename`,"settings.branchPrefixesMoveUp":`Move up`,"settings.branchPrefixesMoveDown":`Move down`,"settings.worktreesTitle":`Git worktrees`,"settings.worktreesHint":`Choose where new workspace worktrees are created. Relative paths are project-relative; Linux/macOS and Windows absolute paths, $HOME, ~, and %USERPROFILE% are supported.`,"settings.worktreesPathLabel":`Worktrees path`,"settings.worktreesPathRequired":`Worktrees path is required.`,"settings.worktreesPrefixByProject":`Prefix worktrees by project name`,"settings.worktreesPrefixByProjectHint":`Place each worktree under a sub-directory named after the project, to avoid collisions when multiple projects share the same worktrees root.`,"settings.shareTitle":`Share configuration`,"settings.shareHint":`Export your settings, templates and tags as a JSON bundle. MCP API keys are stripped from exports for security.`,"settings.exportConfig":`Export`,"settings.importConfig":`Import`,"settings.exportSuccess":`Configuration exported`,"settings.importSuccess":`Configuration imported`,"settings.importConfirmTitle":`Import configuration`,"settings.importConfirmMessage":`This will replace your current settings, templates and tags. Your MCP keys are preserved. Continue?`,"health.title":`Health`,"health.tooltip":`System health`,"changelog.title":`Changelog`,"changelog.tooltip":`What's new in Kōbō`,"changelog.empty":`No changelog available.`,"changelog.current":`current`,"changelog.currentVersion":`Current version: v{version}`,"health.envTitle":`Environment`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Database`,"health.dbPath":`Path`,"health.dbSize":`Size`,"health.schemaVersion":`Schema version`,"health.settingsSchemaVersion":`Settings schema`,"health.runtimesTitle":`Agent runtimes`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude not on PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`codex binary not resolvable`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} total, {archived} archived`,"health.worktreesMissing":`{count} worktree(s) missing on disk`,"health.sessionsTitle":`Agent sessions`,"health.sessionsOrphaned":`{n} orphaned running session(s)`,"health.integrationsTitle":`Integrations`,"health.integrationConfigured":`configured`,"health.integrationMissing":`not configured`,"health.activeTitle":`Active state`,"health.activeQuotaBackoffs":`Pending quota backoffs`,"health.activeWakeups":`Scheduled wakeups`,"health.activeAutoLoop":`Auto-loop running`,"health.activeAgentSessions":`Live agent sessions`,"health.activeDevServers":`Running dev servers`,"health.noneActive":`None.`,"health.quotaResumeAt":`resumes at {time}`,"health.wakeupAt":`wakes at {time}`,"health.startedAgo":`started {time} ago`,"health.autoLoopReady":`ready, iterating`,"health.autoLoopGrooming":`grooming in progress`,"session.started":`Session started`,"session.ended":`Session ended`,"session.compacted":`Context compacted`,"tool.running":`Running...`,"activity.raw_lines":`Raw output lines ({n})`,"activity.loading_older":`Loading older messages…`,"activity.compacting":`Compacting context…`,"activity.prev_user_message":`Previous user message`,"activity.scroll_to_bottom":`Scroll to bottom`,"chat.systemPrompt":`System prompt`,"chat.agent":`Agent`,"chat.cleanupScript":`Cleanup script`,"chat.archiveScript":`Archive script`,"chat.setupScript":`Setup script`,"chat.scriptDone":`Done`,"chat.you":`You`,"chat.session":`Session`,"chat.nActions":`{n} action | {n} actions`,"chat.lastUpdatedAt":`Last updated at {time}`,"chat.scrollToTurnTop":`Scroll to top of this message`,"migration.backing_up":`Backing up the database…`,"migration.running":`Migrating agent data — {processed}/{total}`,"migration.error":`Migration failed`,"migration.backup_location":`A backup was saved at {path}. Restart Kōbō to retry.`,"migration.retry":`Restart Kōbō to retry.`,"engine.select":`Engine`,"engine.model":`Model`,"engine.effort":`Reasoning effort`,"wakeup.scheduledIn":`Next wakeup in {n}s`,"wakeup.scheduledAt":`Next wakeup at {time}`,"wakeup.firing":`Waking up...`,"wakeup.reason":`Reason: {reason}`,"wakeup.cancel":`Cancel this wakeup`,"wakeup.pendingIndicator":`Wakeup scheduled`,"cron.pendingIndicator":`{n} cron(s) scheduled`,"schedule.tabLabel":`Schedule`,"schedule.wakeupTitle":`Wakeup pending`,"schedule.cronsTitle":`Recurring schedules`,"schedule.noWakeup":`No wakeup scheduled`,"schedule.noCrons":`No cron scheduled`,"schedule.nextFireAt":`next at {time}`,"schedule.lastFiredAt":`last fired {time} ago`,"schedule.addCronTitle":`Add a recurring task`,"schedule.addWakeupTitle":`Schedule a wakeup`,"schedule.every":`Every`,"schedule.unitMinutes":`minutes`,"schedule.unitHours":`hours`,"schedule.unitDays":`days`,"schedule.advancedExpression":`Advanced expression (optional)`,"schedule.advancedHint":`Raw cron (e.g. */15 * * * *) or {'@'}hourly/{'@'}daily — overrides the picker when set.`,"schedule.promptLabel":`Prompt`,"schedule.labelOptional":`Label (optional)`,"schedule.delayMinutes":`Delay (minutes)`,"schedule.modeFresh":`New session`,"schedule.oneShot":`Run only once`,"schedule.addCronBtn":`Add cron`,"schedule.addWakeupBtn":`Schedule wakeup`,"schedule.cronCreated":`Recurring task added`,"schedule.wakeupCreated":`Wakeup scheduled`,"askUserQuestion.title":`The agent is asking a question`,"askUserQuestion.submit":`Submit answer`,"askUserQuestion.multiSelectHint":`Select one or more options`,"askUserQuestion.otherOption":`Other`,"askUserQuestion.otherOptionHint":`specify in your next chat message`,"askUserQuestion.noPending":`No pending question`,"askUserQuestion.next":`Next`,"askUserQuestion.previous":`Previous`,"askUserQuestion.cancel":`Cancel`,"askUserQuestion.cancelTooltip":`Skip this question — the agent will proceed without an answer`,"askUserQuestion.collapse":`Collapse the question panel`,"askUserQuestion.expand":`Expand the question panel`,"permissionRequest.title":`The agent wants to use a tool`,"permissionRequest.allow":`Allow`,"permissionRequest.deny":`Deny`,"permissionRequest.tool":`Tool`,"permissionRequest.input":`Input`,"permissionRequest.denied":`denied by user`,"workspaceStatus.awaitingUser":`awaiting your answer`,"workspaceList.prOpen":`#{n} — Pull request open`,"workspaceList.prChangesRequested":`#{n} — Changes requested`,"workspaceList.attentionCiFailed":`CI failed`,"workspaceList.attentionChangesRequested":`Changes requested`,"workspaceList.attentionReadyToMerge":`Ready to merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Start auto-loop`,"autoLoop.prepare":`Prepare for auto-loop`,"autoLoop.reprepare":`Re-prepare for auto-loop`,"autoLoop.reprepareTooltip":`Re-run the grooming pass to add or refresh tasks before resuming the loop`,"autoLoop.prepareBusy":`Wait for the agent to finish before preparing`,"autoLoop.forceReady":`I know what I'm doing — skip grooming`,"autoLoop.forceReadyConfirm":`Skip grooming and mark auto-loop ready? This may cause the loop to stall if tasks aren't atomic.`,"autoLoop.stop":`Stop auto-loop`,"autoLoop.notReady":`Run 'Prepare for auto-loop' first`,"autoLoop.noTasks":`Add tasks first`,"autoLoop.progress":`Auto-loop · {done}/{total} tasks`,"autoLoop.preparing":`Auto-loop · preparing`,"autoLoop.preparingTooltip":`Grooming in progress — the agent is creating / reviewing tasks. The loop will start running once it calls mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop running`,"autoLoop.startInMode":`Start in auto-loop mode`,"koboCommand.prepAutoloopDesc":`Prepare tasks for auto-loop mode (groom for atomicity)`,"staleSessionBanner.title":`Auto-loop running`,"staleSessionBanner.message":`You're viewing an older session — the agent is currently working in the latest one.`,"staleSessionBanner.staleTitle":`Older session`,"staleSessionBanner.staleMessage":`You're viewing an older session — messages you send go to this session, not the latest one.`,"staleSessionBanner.switchToCurrent":`Switch to current`},sn={"common.save":`Guardar`,"common.cancel":`Cancelar`,"common.delete":`Eliminar`,"common.close":`Cerrar`,"common.details":`Detalles`,"whatsNew.title":`Novedades`,"common.loading":`Cargando...`,"common.search":`Buscar...`,"common.refresh":`Actualizar`,"common.copy":`Copiar`,"common.copied":`Copiado al portapapeles`,"common.copyFailed":`Error al copiar`,"common.add":`Añadir`,"folderPicker.title":`Elegir una carpeta`,"folderPicker.parent":`Carpeta superior`,"folderPicker.empty":`Sin subcarpetas`,"folderPicker.select":`Elegir esta carpeta`,"common.start":`Iniciar`,"common.stop":`Detener`,"common.archive":`Archivar`,"common.unarchive":`Desarchivar`,"common.selectWorkspace":`Selecciona un workspace`,"common.noResults":`Sin resultados para "{query}"`,"common.send":`enviar`,"common.newLine":`nueva línea`,"common.history":`historial`,"common.justNow":`ahora mismo`,"common.minutesAgo":`hace {count}m`,"common.hoursAgo":`hace {count}h`,"common.daysAgo":`hace {count}d`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`El modelo más capaz — sucesor de Opus 4.8, contexto 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 sin clasificadores de seguridad — acceso limitado (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude elige el modelo óptimo`,"model.opus48Description":`Opus más capaz — coding agéntico long-horizon, contexto 1M por defecto, esfuerzo high por defecto`,"model.opus47ClassicDescription":`Último Opus, el más capaz`,"model.opus471mDescription":`Último Opus, contexto 1M`,"model.opusClassicDescription":`El más potente`,"model.opus1mDescription":`El más potente, contexto 1M`,"model.sonnetClassicDescription":`Equilibrado`,"model.sonnet1mDescription":`Equilibrado, contexto 1M`,"model.haikuDescription":`El más rápido`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recomendado para código complejo (requiere autenticación ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Alternativa por defecto — razonamiento sólido, compatible con clave API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Rápido y eficiente — ideal para tareas reactivas y subagentes`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modelo especializado en código para ingeniería de software compleja`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Deja que el motor decida`,"reasoning.minimalDescription":`Razonamiento más rápido y superficial`,"reasoning.lowDescription":`Más rápido, menos profundidad`,"reasoning.mediumDescription":`Equilibrado`,"reasoning.highDescription":`Más profundidad`,"reasoning.xhighDescription":`Profundidad extendida, tareas largas`,"reasoning.maxDescription":`Profundidad máxima`,"agentPermissionMode.label":`Modo de permisos`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Aceptar ediciones`,"agentPermissionMode.interactive":`Interactivo`,"agentPermissionMode.tooltip":`Cómo gestiona el agente los permisos de las herramientas. Plan: solo lectura, sin escrituras. Bypass: omitir todas las preguntas. Estricto: auto-aceptar ediciones de archivos, respetar allow/deny para el resto. Interactivo: preguntar al usuario antes de cada herramienta mediante el panel de permisos.`,"agentPermissionMode.autoLoopOverride":`El auto-loop fuerza un modo distinto a Plan — Plan bloquea las herramientas MCP y las ediciones que el bucle necesita. Elige Bypass, Estricto o Interactivo.`,"agentPermissionMode.autoLoopLocked":`Bloqueado en Bypass mientras el auto-loop está activo — cualquier otro modo detendría el bucle en las preguntas de permiso. AskUserQuestion sigue funcionando.`,"workspaceList.title":`Workspaces`,"workspaceList.needsAttention":`Requiere atención`,"workspaceList.running":`En ejecución`,"workspaceList.idle":`Inactivo`,"workspaceList.archived":`Archivados`,"workspaceList.noWorkspaces":`Aún no hay workspaces`,"workspaceList.footer":`{count} workspace | {count} workspaces`,"workspaceList.footerRunning":`{count} en ejecución`,"workspaceList.deleteDialog.title":`¿Eliminar workspace?`,"workspaceList.deleteDialog.deleteLocal":`Eliminar rama local`,"workspaceList.deleteDialog.deleteRemote":`Eliminar rama remota`,"workspaceList.deleteDialog.warning":`Advertencia: esta acción es irreversible en el remoto.`,"workspaceList.deleteArchivedDialog.tooltip":`Eliminar todos los workspaces archivados`,"workspaceList.deleteArchivedDialog.title":`¿Eliminar todos los workspaces archivados?`,"workspaceList.deleteArchivedDialog.message":`Esto eliminará permanentemente los {count} workspaces archivados. Esta acción no se puede deshacer.`,"workspacePage.selectWorkspace":`Selecciona un workspace para comenzar`,"workspacePage.session":`Sesión #{n}`,"workspacePage.newSession":`+ Nueva sesión`,"workspacePage.renameSession":`Renombrar`,"workspacePage.renameSessionTitle":`Renombrar sesión`,"workspacePage.sessionNameLabel":`Nombre de sesión`,"workspacePage.sessionEndedNotice":`Esta sesión ha terminado. Crea una nueva sesión para continuar.`,"workspacePage.renameFailed":`Error al renombrar`,"workspacePage.createSessionFailed":`Error al crear la sesión`,"workspacePage.startFailed":`Error al iniciar`,"workspacePage.stopFailed":`Error al detener`,"workspacePage.interrupt":`Interrumpir`,"workspacePage.interrupted":`Agente interrumpido — esperando tu próximo mensaje`,"workspacePage.archivedBanner":`Workspace archivado — solo lectura`,"workspacePage.worktreePurgedBanner":`Worktree eliminado — historial conservado, restauración no disponible en esta versión`,"workspacePage.worktreePurgedTooltip":"La carpeta del worktree fue eliminada del disco para recuperar espacio. El historial de mensajes, sesiones y metadatos de la PR siguen consultables aquí, pero el directorio de trabajo ya no existe localmente. Una futura versión de Kōbō podrá reconstruir el worktree desde la PR mergeada — por ahora, recréalo manualmente con `gh pr checkout` o `git worktree add`.","workspacePage.pendingInitialPromptBanner":`Hay un prompt inicial pendiente — el agente nunca lo recibió (el script de setup falló o el workspace nunca se inició). Haz clic en Iniciar para enviarlo ahora.`,"workspacePage.unarchived":`Workspace desarchivado`,"workspacePage.unarchiveFailed":`Error al desarchivar`,"workspacePage.interruptFailed":`Error al interrumpir`,"workspacePage.interruptTooltip":`Interrupción suave (como Escape) — detiene la herramienta actual pero mantiene la sesión activa`,"workspacePage.pendingNextRun":`Se aplicará en el próximo inicio`,"search.title":`Búsqueda`,"search.tooltip":`Buscar en el historial de agentes`,"search.placeholder":`Buscar en todos los mensajes de agentes…`,"search.includeArchived":`Incluir workspaces archivados`,"search.loading":`Buscando…`,"search.noResults":`Sin resultados`,"search.error":`Búsqueda fallida: {message}`,"search.resultCount":`{n} resultado(s)`,"search.eventType.userMessage":`Tú`,"search.eventType.agentOutput":`Agente`,"activityFeed.empty":`Aún no hay actividad`,"activityFeed.emptyHint":`Inicia un workspace para ver la salida del agente aquí`,"activityFeed.initialPrompt":`Prompt inicial`,"activityFeed.you":`Tú`,"activityFeed.agent":`Agente`,"activityFeed.question":`Pregunta`,"activityFeed.goToPrevious":`Ir al mensaje anterior`,"activityFeed.scrollToBottom":`Ir al final`,"activityFeed.sendAnswers":`Enviar respuestas`,"agentBusy.banner":`El agente está ocupado`,"agentBusy.subagentsRunning":`1 sub-agente en ejecución | {n} sub-agentes en ejecución`,"agentBusy.viewSubagents":`Ver sub-agentes`,"agentBusy.pendingMessage":`Esperando — el agente está ocupado`,"terminal.title":`Terminal`,"terminal.open":`Abrir terminal`,"terminal.close":`Cerrar terminal`,"terminal.noWorkspace":`Seleccione un espacio de trabajo`,"terminal.noWorktree":`Worktree aún no creado`,"terminal.error":`Error del terminal`,"terminal.exited":`Terminal cerrado`,"chatInput.placeholder":`Mensaje... (/ para skills)`,"chatInput.fileSearchHint":`buscar un archivo`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Adjuntar imagen`,"chatInput.queueBanner":`Mensaje en cola — se enviará cuando el agente termine`,"chatInput.cancelQueue":`Cancelar cola`,"chatInput.autoLoopBanner":`Auto-loop activo — deténlo para enviar un mensaje`,"chatInput.awaitingUserBanner":`El agente espera tu respuesta arriba — responde mediante el panel de la pregunta`,"chatInput.autoLoopStop":`Detener`,"koboCommand.checkProgressDesc":`Verificar el progreso de las tareas y criterios de aceptación`,"chatInput.uploading":`Subiendo...`,"voice.title":`Transcripción de voz`,"voice.enabled":`Activar transcripción de voz local`,"voice.pttKey":`Tecla push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Espacio`,"voice.language":`Idioma (auto o código)`,"voice.model":`Modelo activo`,"voice.commandPath":`Ruta del binario Whisper (opcional)`,"voice.ffmpegPath":`Ruta del binario ffmpeg (opcional)`,"voice.temperature":`Temperatura`,"voice.temperatureHint":`Más bajo = más determinista; más alto = más flexible pero potencialmente menos estable.`,"voice.initialPrompt":`Prompt inicial (opcional)`,"voice.initialPromptHint":`Contexto opcional para ayudar a Whisper con nombres, siglas o vocabulario técnico.`,"voice.translateToEnglish":`Traducir al inglés`,"voice.translateToEnglishHint":`Si se activa, el audio no inglés se traduce al inglés en lugar de transcribirse tal cual.`,"voice.suppressNst":`Suprimir tokens no vocales`,"voice.suppressNstHint":`Intenta reducir artefactos no vocales en la transcripción.`,"voice.installLink":`Instalar whisper.cpp`,"voice.installGuideTitle":`Guía de instalación`,"voice.installGuideIntro":`Instala whisper.cpp y ffmpeg, luego configura las rutas de binarios abajo si hace falta.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Después del build con CMake, el binario de Whisper suele estar en: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Después, configura “Ruta del binario Whisper” y “Ruta del binario ffmpeg” en esta sección (o déjalo vacío si están en PATH).`,"voice.noneModel":`Sin modelo activo`,"voice.notInstalled":`no instalado`,"voice.download":`Descargar`,"voice.delete":`Eliminar`,"voice.holdToTalk":`Mantén pulsado para hablar`,"voice.recording":`Grabando...`,"voice.transcribing":`Transcribiendo...`,"voice.notSupported":`La grabación de voz no es compatible con este navegador`,"voice.errorMicPermission":`Permiso de micrófono denegado`,"voice.errorTranscription":`Falló la transcripción de voz`,"voice.downloadFailed":`Falló la descarga del modelo`,"voice.deleteFailed":`Falló la eliminación del modelo`,"voice.errorDisabled":`La transcripción de voz está desactivada en ajustes`,"voice.errorModelMissing":`No hay un modelo de voz activo configurado`,"voice.errorModelNotInstalled":`El modelo de voz activo no está instalado`,"voice.errorAudioInvalid":`La captura de audio es inválida o vacía`,"voice.errorLanguageInvalid":`La configuración del idioma de voz es inválida`,"voice.errorRuntimeMissing":`El runtime de Whisper no está instalado o no está en el PATH`,"voice.maxDurationReached":`Se alcanzó la duración máxima de grabación`,"voice.runtimeReady":`Runtime listo: {command}`,"voice.runtimeMissing":`Falta runtime: {command}`,"voice.ffmpegReady":`ffmpeg listo`,"voice.ffmpegMissing":`falta ffmpeg`,"voice.sectionRuntime":`Estado del runtime`,"voice.sectionActivation":`Activación`,"voice.sectionModels":`Modelos Whisper`,"voice.sectionAdvanced":`Opciones avanzadas`,"voice.sectionBehavior":`Comportamiento de la transcripción`,"voice.sectionBinaries":`Rutas de los binarios`,"voice.downloadModels":`Descargar un modelo`,"voice.cancelFailed":`No se pudo cancelar la descarga`,"createPage.title":`¿En qué te gustaría trabajar?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion activado`,"createPage.importNotion":`Importar desde Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`La URL debe empezar por https://www.notion.so/ o https://app.notion.com/`,"createPage.notionAutoExtract":`Las subtareas y criterios de aceptación se extraerán automáticamente.`,"createPage.notionPanelChoiceLabel":`Esta URL apunta a una subpágina (?p=). ¿Sobre cuál quieres trabajar?`,"createPage.notionPanelOption":`Subpágina (panel)`,"createPage.notionPanelOptionDesc":`La página que estabas viendo — recomendado`,"createPage.notionParentOption":`Página principal`,"createPage.notionParentOptionDesc":`La épica / base de datos a la que pertenece`,"createPage.importSentry":`Importar Sentry`,"createPage.sentryEnabled":`Sentry activado`,"createPage.sentryPlaceholder":`https://tu-org.sentry.io/issues/123456`,"createPage.sentryValidation":`La URL debe apuntar a una issue de Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`La issue de Sentry se importará automáticamente`,"createPage.sentryExtractHint":`Kobo extraerá la issue y la escribirá en .ai/thoughts/`,"createPage.workspaceName":`Nombre del workspace (por defecto el título de la página Notion)`,"createPage.workspaceNamePlaceholder":`Nombre del workspace...`,"createPage.instructions":`Instrucciones adicionales (opcional)...`,"createPage.instructionsPlaceholder":`Describe la tarea...`,"createPage.manualHint":`¿Sin ticket Notion? Añade tus tareas y criterios de aceptación manualmente — se enviarán al agente Claude como contexto.`,"createPage.tasks":`Tareas ({count})`,"createPage.addTask":`Añadir una tarea...`,"createPage.acceptanceCriteria":`Criterios de aceptación ({count})`,"createPage.addCriterion":`Añadir un criterio...`,"createPage.projectPath":`Introduce la ruta del proyecto`,"createPage.branchType":`Tipo de rama`,"createPage.branch":`Rama`,"createPage.noBranches":`No se encontraron ramas`,"createPage.enterPath":`Introduce la ruta del proyecto`,"createPage.create":`Crear`,"createPage.skipSetupScript":`Omitir script de setup`,"createPage.attachWorktreeToggle":`Adjuntar worktree existente`,"createPage.attachWorktreeEnabled":`Reutilizando worktree existente`,"createPage.worktreePickerLabel":`Worktree existente`,"createPage.noOrphanWorktrees":`No hay worktrees huérfanos en este proyecto`,"createPage.pickWorktreeRequired":`Selecciona un worktree para adjuntar`,"createPage.notionExtractHint":`Las subtareas y criterios de aceptación se extraerán de la página Notion.`,"createPage.notionImportHint":`Haz clic en "Importar desde Notion" para extraer automáticamente las subtareas de un ticket.`,"createPage.errorCreating":`Error al crear el workspace.`,"createPage.branchAdjusted":"La rama ya existía — se creó `{branch}` en su lugar. La carpeta worktree correspondiente usa el mismo sufijo.","createPage.validationNotionUrl":`Introduce una URL de Notion válida (https://www.notion.so/... o https://app.notion.com/...).`,"createPage.validationDescription":`Describe la tarea.`,"createPage.validationName":`Indica un nombre para el workspace.`,"createPage.validationPath":`Introduce la ruta del proyecto.`,"createPage.validationBranch":`Selecciona una rama.`,"settings.title":`Ajustes`,"settings.language":`Idioma`,"settings.projectColor":`Color`,"settings.projectColorClear":`Borrar`,"settings.projectColorDefault":`Por defecto (gris)`,"settings.workspaceListSection":`Lista de workspaces`,"settings.flattenWorkspaceList":`Lista plana de workspaces`,"settings.flattenWorkspaceListHint":`Muestra todos los workspaces en una lista plana con una etiqueta de proyecto, en lugar de agruparlos por proyecto.`,"settings.skillSuite.section":`Suite de skills`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personalizado`,"settings.skillSuite.superpowersHint":`Workflow opinado TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite de Garry Tan — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Ambas suites se combinan — superpowers para la metodología (brainstorm / TDD / planes / revisión a nivel de principios), gstack para flujos concretos (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Edita los cuatro prompts a continuación tú mismo. Parte de la base agnóstica.`,"settings.skillSuite.reloadDefaults":`Restaurar predeterminados`,"settings.skillSuite.reloadDefaultsConfirm":`¿Reemplazar los cuatro prompts personalizados con los valores agnósticos predeterminados?`,"settings.skillSuite.customPrompts":`Prompts personalizados`,"settings.skillSuite.reviewTemplate":`Template de revisión`,"settings.skillSuite.autoLoopReviewGate":`Compuerta de revisión auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro de grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Instrucción de la fase de brainstorming`,"settings.global":`Global`,"settings.projects":`Proyectos`,"settings.globalSettings":`Ajustes globales`,"settings.defaultModel":`Modelo por defecto`,"settings.defaultModelClaude":`Modelo por defecto (Claude Code)`,"settings.defaultModelCodex":`Modelo por defecto (OpenAI Codex)`,"settings.agentPermissions":`Permisos del agente`,"settings.skipPermissions":`Omitir solicitudes de permisos (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Advertencia: desactivar esto hará que todos los permisos de herramientas (Write, Edit, Bash...) se denieguen automáticamente en modo headless. El agente solo podrá leer.`,"settings.notifications":`Notificaciones`,"settings.browserNotifications":`Notificación del navegador cuando el agente termina`,"settings.audioNotifications":`Notificación sonora cuando el agente termina`,"settings.notificationSound":`Sonido de notificación`,"settings.notificationSoundPreview":`Escuchar`,"settings.notificationVolume":`Volumen`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Trabajo terminado`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Va a explotar`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Modo de permisos por defecto`,"settings.defaultPermissionModeClaude":`Modo de permisos por defecto (Claude Code)`,"settings.defaultPermissionModeCodex":`Modo de permisos por defecto (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Modo aplicado al crear un workspace. Plan = solo lectura, Bypass = sin avisos, Estricto = auto-aceptar ediciones con allow-list, Interactivo = preguntar antes de cada herramienta.`,"settings.activityFeed":`Feed de actividad`,"settings.verboseMessages":`Mostrar mensajes detallados del sistema (task_progress, task_started)`,"settings.availableVariables":`Variables disponibles en las plantillas de prompt`,"settings.prPromptTemplate":`Plantilla de prompt PR`,"settings.prPromptPlaceholder":`Instrucciones para el agente al crear PRs en GitHub...`,"settings.prPromptHint":`Usa las variables listadas arriba (sintaxis de dobles llaves).`,"settings.reviewPromptTemplate":`Plantilla de prompt de revisión`,"settings.reviewPromptPlaceholder":`Instrucciones para el agente al revisar los cambios de la rama...`,"settings.ciFixPromptTemplate":`Plantilla de prompt «Reparar CI»`,"settings.ciFixPromptHint":`Se envía al agente cuando un workspace tiene la CI fallando. Variables (sintaxis con dobles llaves): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Pedir al agente que diagnostique y arregle los jobs de CI que fallan...`,"settings.finalizationPromptTemplate":`Prompt de finalización del auto-loop`,"settings.finalizationPromptHint":`Prompt por defecto para la última iteración del auto-loop (controles de calidad finales). Se usa cuando un proyecto deja vacío su propio prompt de finalización.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt inicial de Notion`,"settings.notionInitialPrompt.help":`Se añade al prompt de creación del workspace cuando el workspace tiene un ticket de Notion. Variables: {variables}.`,"settings.notionInitialPrompt.project":`Prompt inicial de Notion (anulación)`,"settings.sentryInitialPrompt":`Prompt inicial de Sentry`,"settings.sentryInitialPrompt.help":`Se añade al prompt de creación del workspace cuando el workspace tiene una issue de Sentry. Variables: {variables}.`,"settings.sentryInitialPrompt.project":`Prompt inicial de Sentry (anulación)`,"settings.initialPrompt.inheritHint":`Dejar en blanco para heredar. Escribe un carácter en blanco para desactivar la inyección a este nivel.`,"settings.resetToDefault":`Restablecer`,"settings.resetFailed":`No se pudo cargar el valor por defecto`,"settings.sentryIntegration":`Integración Sentry`,"settings.var.prNumber":`Número de PR (ej: 42)`,"settings.var.prUrl":`URL completa de la PR creada`,"settings.var.branchName":`Nombre de la rama de trabajo`,"settings.var.sourceBranch":`Rama fuente a la que apunta la PR`,"settings.var.workspaceName":`Nombre del workspace`,"settings.var.projectName":`Último segmento de la ruta del proyecto`,"settings.var.notionUrl":`URL de Notion si está definida, vacía en caso contrario`,"settings.var.commits":`Lista de commits entre source y head`,"settings.var.diffStats":`Resumen shortstat de Git (archivos, inserciones, eliminaciones)`,"settings.var.tasks":`Tareas regulares como lista de verificación`,"settings.var.acceptanceCriteria":`Criterios de aceptación como lista de verificación`,"settings.gitConventions":`Convenciones Git (global)`,"settings.gitConventionsPlaceholder":`# Convenciones Git...`,"settings.gitConventionsHint":`Estas convenciones se escriben en .ai/.git-conventions.md en cada nuevo workspace y deben ser seguidas por el agente antes de cualquier operación Git. Se anulan con convenciones por proyecto si están definidas.`,"settings.setupScript":`Script de setup`,"settings.cleanupScript":`Script de limpieza`,"settings.archiveScript":`Script de archivado`,"settings.archiveScriptHint":`Script de shell ejecutado en el servidor en el worktree cuando se archiva un workspace. Dejar vacío para desactivar.`,"settings.archiveScriptPlaceholder":`p. ej. limpiar contenedores, liberar espacio en disco…`,"settings.changeSourceBranchScript":`Script para cambiar la rama de origen`,"settings.changeSourceBranchScript.help":`Reemplaza el cherry-pick integrado cuando no está vacío. El script gestiona git, base de la PR, force-push y conflictos; Kōbō solo rechaza si el agente está corriendo y actualiza los metadatos de la rama de origen en exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nueva rama de origen elegida en el diálogo
35
35
  KOBO_OLD_BASE — rama de origen anterior del workspace
36
36
  KOBO_WORKING_BRANCH — rama de trabajo del workspace
37
37
  KOBO_WORKTREE_PATH — ruta absoluta del worktree (también cwd)
@@ -47,7 +47,7 @@ KOBO_PR_NUMBER — número de PR/MR en la forge resuelta (vacío si no hay
47
47
  # O directamente con git (funciona en GitHub aunque la rama se haya borrado):
48
48
  git fetch origin pull/[número-pr]/head:[nombre-rama]
49
49
  git worktree add [ruta] [nombre-rama]`,"settings.purgeDocsRestoreFootnote":`GitHub mantiene la ref HEAD de la PR accesible mucho tiempo después de borrar la rama origen (meses / años). La autodetección corre en el watcher de 30 s — no hay que tocar la UI una vez que la carpeta vuelve a existir.`,"settings.purgeDocsPermissionsTitle":`Evitar errores de permisos durante el borrado`,"settings.purgeDocsPermissionsIntro":`Docker suele dejar archivos root-owned en node_modules / vendor dentro del worktree. Cuando Kōbō intenta borrarlos, te topas con EACCES / EPERM y el borrado falla. Dos formas de prevenirlo:`,"settings.purgeDocsPermissionsDocker":'Configurar tu contenedor para que se ejecute como tu usuario host — directiva USER en el Dockerfile, o `user: "${UID}:${GID}"` en docker-compose (con UID/GID exportados en tu shell).',"settings.purgeDocsPermissionsAcl":`Pre-establecer una ACL por defecto en la raíz de los worktrees — red de seguridad que funciona en la MAYORÍA de los casos (ext4/btrfs/xfs + bind mount Docker clásico). Cada archivo nuevo hereda entonces una entrada de acceso para tu usuario, además del propietario nominal:`,"settings.purgeDocsPermissionsAclCommand":` setfacl -d -m u:$(whoami):rwX [raíz-worktrees]`,"settings.purgeDocsPermissionsFootnote":"Limitaciones de las ACL: NO funcionan con volúmenes Docker con nombre (usa un bind mount), sistemas de archivos sin soporte ACL (NTFS, exFAT, tmpfs), SELinux estricto con `:Z`, o cuando Docker `userns-remap` está activado. La solución más fiable sigue siendo configurar el usuario dentro del contenedor (opción 1). Consejo: `rwX` (X mayúscula) solo añade el bit de ejecución en directorios y archivos ya ejecutables — más limpio que `rwx` que haría ejecutable cualquier archivo de texto.","settings.purgeDocsPermissionsRecoverTitle":`Desbloquear un worktree ya roto (archivos root-owned existentes)`,"settings.purgeDocsPermissionsRecoverIntro":`Si te encuentras con un worktree ya lleno de archivos root-owned (Docker ya ha ejecutado, vendor / node_modules están bloqueados), las ACL preventivas de arriba no son suficientes — hay que tratar los archivos EXISTENTES. Dos enfoques, a ejecutar dentro de la carpeta del worktree:`,"settings.purgeDocsPermissionsRecoverAclIntro":`Opción A — ACL recursiva (preserva la propiedad root para auditoría, solo añade acceso para tu usuario en paralelo):`,"settings.purgeDocsPermissionsRecoverAclCommand":`# establece ACL por defecto para archivos futuros Y otorga acceso a todo lo existente
50
- sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Opción B — Tomar la propiedad (más simple, pierde la huella "creado por root en el contenedor" pero rara vez importa):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Consejo: puedes ejecutar estos comandos directamente sobre la raíz de tus worktrees (ej. `~/.worktrees/`) para cubrir todos los workspaces existentes Y futuros de una sola vez. Una vez hecho, el borrado de Kōbō funcionará sin errores de permisos.","contextMenu.runSetup":`Ejecutar script de setup`,"contextMenu.exportEvents":`Exportar eventos (CSV)`,"contextMenu.dismissChangesRequested":`Marcar «Cambios solicitados» como visto`,"contextMenu.dismissCiFailure":`Marcar «CI en error» como visto`,"contextMenu.restoreChangesRequested":`Marcar «Cambios solicitados» como no visto`,"contextMenu.restoreCiFailure":`Marcar «CI en error» como no visto`,"contextMenu.exportingEvents":`Preparando la exportación…`,"contextMenu.exportEventsError":`Error al exportar los eventos`,"contextMenu.openNotion":`Abrir en Notion`,"contextMenu.openSentry":`Abrir en Sentry`,"contextMenu.openPr":`Abrir PR`,"workspace.favorite":`Marcar como favorito`,"workspace.unfavorite":`Quitar de favoritos`,"workspace.showFavoritesOnly":`Mostrar solo favoritos`,"workspace.searchArchivedToggle":`Buscar también en workspaces archivados`,"workspace.descriptionPlaceholder":`Añadir una breve descripción`,"workspace.descriptionDialogHint":`Texto sin formato, máximo 200 caracteres. Dejar vacío para borrar.`,"workspace.descriptionTooLong":`La descripción debe tener 200 caracteres o menos.`,"workspace.descriptionSaveFailed":`No se pudo guardar la descripción.`,"workspace.agentDescriptionTooltip":`Estado en vivo mantenido por el agente`,"mcp.tool.setWorkspaceDescription":`Establece la breve descripción del workspace (≤ 200 caracteres).`,"tags.manage":`Gestionar etiquetas`,"tags.manageTitle":`Gestionar etiquetas del workspace`,"tags.noTagsDefined":`Sin etiquetas. Añádelas en Ajustes > Global > Etiquetas.`,"tags.orphanedHint":`{count} etiqueta(s) ya no están en el catálogo global. Desmárcalas para quitarlas.`,"settings.tagsTitle":`Etiquetas de workspace`,"settings.tagsHint":`Define las etiquetas asignables a los workspaces. Escribe para añadir, clic en la cruz para quitar.`,"settings.tagsLabel":`Etiquetas disponibles`,"settings.branchPrefixesTitle":`Prefijos de rama`,"settings.branchPrefixesHint":`Gestiona los prefijos de rama de Git disponibles en la página de creación de workspaces. El primero se preselecciona por defecto.`,"settings.branchPrefixesEmpty":`No hay ningún prefijo de rama definido. Añade al menos uno abajo.`,"settings.branchPrefixesAddLabel":`Nuevo prefijo`,"settings.branchPrefixesEditHint":`Haz clic para renombrar`,"settings.branchPrefixesMoveUp":`Subir`,"settings.branchPrefixesMoveDown":`Bajar`,"settings.worktreesTitle":`Worktrees Git`,"settings.worktreesHint":`Elige dónde se crean los worktrees de nuevos workspaces. Las rutas relativas se resuelven desde el proyecto; se admiten rutas absolutas Linux/macOS y Windows, $HOME, ~ y %USERPROFILE%.`,"settings.worktreesPathLabel":`Ruta de worktrees`,"settings.worktreesPathRequired":`La ruta de worktrees es obligatoria.`,"settings.worktreesPrefixByProject":`Prefijar los worktrees con el nombre del proyecto`,"settings.worktreesPrefixByProjectHint":`Coloca cada worktree en un subdirectorio con el nombre del proyecto para evitar colisiones cuando varios proyectos comparten la misma raíz.`,"settings.shareTitle":`Compartir configuración`,"settings.shareHint":`Exporta tus ajustes, plantillas y etiquetas en un bundle JSON. Las claves MCP no se incluyen por seguridad.`,"settings.exportConfig":`Exportar`,"settings.importConfig":`Importar`,"settings.exportSuccess":`Configuración exportada`,"settings.importSuccess":`Configuración importada`,"settings.importConfirmTitle":`Importar configuración`,"settings.importConfirmMessage":`Esto reemplazará tus ajustes, plantillas y etiquetas actuales. Las claves MCP se conservan. ¿Continuar?`,"health.title":`Salud`,"health.tooltip":`Estado del sistema`,"changelog.title":`Changelog`,"changelog.tooltip":`Novedades de Kōbō`,"changelog.empty":`Ningún changelog disponible.`,"changelog.current":`actual`,"changelog.currentVersion":`Versión actual: v{version}`,"health.envTitle":`Entorno`,"health.version":`Versión`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Base de datos`,"health.dbPath":`Ruta`,"health.dbSize":`Tamaño`,"health.schemaVersion":`Versión del esquema`,"health.settingsSchemaVersion":`Esquema de ajustes`,"health.runtimesTitle":`Motores de agente`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude no encontrado en PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binario codex no resoluble`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} en total, {archived} archivados`,"health.worktreesMissing":`{count} worktree(s) faltan en el disco`,"health.sessionsTitle":`Sesiones de agente`,"health.sessionsOrphaned":`{n} sesión/sesiones huérfana(s) en ejecución`,"health.integrationsTitle":`Integraciones`,"health.integrationConfigured":`configurada`,"health.integrationMissing":`sin configurar`,"health.activeTitle":`Estado activo`,"health.activeQuotaBackoffs":`Quota backoffs pendientes`,"health.activeWakeups":`Despertares programados`,"health.activeAutoLoop":`Auto-loop en ejecución`,"health.activeAgentSessions":`Sesiones de agente activas`,"health.activeDevServers":`Servidores de desarrollo activos`,"health.noneActive":`Ninguno.`,"health.quotaResumeAt":`reanuda a las {time}`,"health.wakeupAt":`despierta a las {time}`,"health.startedAgo":`iniciada hace {time}`,"health.autoLoopReady":`listo, iterando`,"health.autoLoopGrooming":`grooming en curso`,"session.started":`Sesión iniciada`,"session.ended":`Sesión finalizada`,"session.compacted":`Contexto compactado`,"tool.running":`Ejecutando...`,"activity.raw_lines":`Líneas de salida brutas ({n})`,"activity.loading_older":`Cargando mensajes anteriores…`,"activity.compacting":`Compactando el contexto…`,"activity.prev_user_message":`Mensaje anterior del usuario`,"activity.scroll_to_bottom":`Desplazar al final`,"chat.systemPrompt":`Prompt del sistema`,"chat.agent":`Agente`,"chat.cleanupScript":`Script de limpieza`,"chat.archiveScript":`Script de archivado`,"chat.setupScript":`Script de setup`,"chat.scriptDone":`Hecho`,"chat.you":`Tú`,"chat.session":`Sesión`,"chat.nActions":`{n} acción | {n} acciones`,"chat.lastUpdatedAt":`Última actualización a las {time}`,"chat.scrollToTurnTop":`Desplazar al inicio del mensaje`,"migration.backing_up":`Haciendo copia de seguridad de la base de datos…`,"migration.running":`Migrando datos del agente — {processed}/{total}`,"migration.error":`La migración falló`,"migration.backup_location":`Se guardó una copia de seguridad en {path}. Reinicia Kōbō para reintentar.`,"migration.retry":`Reinicia Kōbō para reintentar.`,"engine.select":`Motor`,"engine.model":`Modelo`,"engine.effort":`Esfuerzo de razonamiento`,"wakeup.scheduledIn":`Próximo despertar en {n}s`,"wakeup.scheduledAt":`Próximo despertar a las {time}`,"wakeup.firing":`Despertando...`,"wakeup.reason":`Razón: {reason}`,"wakeup.cancel":`Cancelar este despertar`,"wakeup.pendingIndicator":`Despertar programado`,"cron.pendingIndicator":`{n} cron(s) programado(s)`,"schedule.tabLabel":`Programación`,"schedule.wakeupTitle":`Wakeup pendiente`,"schedule.cronsTitle":`Programaciones recurrentes`,"schedule.noWakeup":`Sin wakeup programado`,"schedule.noCrons":`Sin cron programado`,"schedule.nextFireAt":`próximo a las {time}`,"schedule.lastFiredAt":`último hace {time}`,"askUserQuestion.title":`El agente hace una pregunta`,"askUserQuestion.submit":`Enviar respuesta`,"askUserQuestion.multiSelectHint":`Selecciona una o más opciones`,"askUserQuestion.otherOption":`Otro`,"askUserQuestion.otherOptionHint":`especifíquelo en su próximo mensaje`,"askUserQuestion.noPending":`Ninguna pregunta pendiente`,"askUserQuestion.next":`Siguiente`,"askUserQuestion.previous":`Anterior`,"askUserQuestion.cancel":`Cancelar`,"askUserQuestion.cancelTooltip":`Saltar esta pregunta — el agente continuará sin respuesta`,"askUserQuestion.collapse":`Contraer el panel de pregunta`,"askUserQuestion.expand":`Expandir el panel de pregunta`,"permissionRequest.title":`El agente quiere usar una herramienta`,"permissionRequest.allow":`Permitir`,"permissionRequest.deny":`Denegar`,"permissionRequest.tool":`Herramienta`,"permissionRequest.input":`Entrada`,"permissionRequest.denied":`denegado por el usuario`,"workspaceStatus.awaitingUser":`esperando tu respuesta`,"workspaceList.prOpen":`#{n} — Pull request abierta`,"workspaceList.prChangesRequested":`#{n} — Cambios solicitados`,"workspaceList.attentionCiFailed":`CI fallida`,"workspaceList.attentionChangesRequested":`Cambios solicitados`,"workspaceList.attentionReadyToMerge":`Listo para merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Iniciar auto-loop`,"autoLoop.prepare":`Preparar para auto-loop`,"autoLoop.reprepare":`Volver a preparar para auto-loop`,"autoLoop.reprepareTooltip":`Volver a ejecutar la fase de grooming para añadir o refrescar tareas antes de reanudar el bucle`,"autoLoop.prepareBusy":`Espera a que el agente termine antes de preparar`,"autoLoop.forceReady":`Sé lo que hago — omitir preparación`,"autoLoop.forceReadyConfirm":`¿Omitir la preparación y marcar auto-loop listo? El loop puede quedarse bloqueado si las tareas no son atómicas.`,"autoLoop.stop":`Detener auto-loop`,"autoLoop.notReady":`Ejecute primero 'Preparar para auto-loop'`,"autoLoop.noTasks":`Añada tareas primero`,"autoLoop.progress":`Auto-loop · {done}/{total} tareas`,"autoLoop.preparing":`Auto-loop · preparando`,"autoLoop.preparingTooltip":`Preparación en curso — el agente está creando / revisando tareas. El bucle arrancará cuando llame a mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop en ejecución`,"autoLoop.startInMode":`Iniciar en modo auto-loop`,"koboCommand.prepAutoloopDesc":`Preparar tareas para modo auto-loop (atomicidad)`,"staleSessionBanner.title":`Auto-loop en curso`,"staleSessionBanner.message":`Estás viendo una sesión anterior — el agente está trabajando en la más reciente.`,"staleSessionBanner.switchToCurrent":`Cambiar a la actual`},cn={"common.save":`Enregistrer`,"common.cancel":`Annuler`,"common.delete":`Supprimer`,"common.close":`Fermer`,"common.details":`Détails`,"whatsNew.title":`Quoi de neuf`,"common.loading":`Chargement...`,"common.search":`Rechercher...`,"common.refresh":`Actualiser`,"common.copy":`Copier`,"common.copied":`Copié dans le presse-papiers`,"common.copyFailed":`Échec de la copie`,"common.add":`Ajouter`,"folderPicker.title":`Choisir un dossier`,"folderPicker.parent":`Dossier parent`,"folderPicker.empty":`Aucun sous-dossier`,"folderPicker.select":`Choisir ce dossier`,"common.start":`Démarrer`,"common.stop":`Arrêter`,"common.archive":`Archiver`,"common.unarchive":`Désarchiver`,"common.selectWorkspace":`Sélectionnez un espace de travail`,"common.noResults":`Aucun résultat pour « {query} »`,"common.send":`envoyer`,"common.newLine":`nouvelle ligne`,"common.history":`historique`,"common.justNow":`a l'instant`,"common.minutesAgo":`il y a {count}m`,"common.hoursAgo":`il y a {count}h`,"common.daysAgo":`il y a {count}j`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Modèle le plus capable — succède à Opus 4.8, contexte 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 sans classificateurs de sécurité — accès limité (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude choisit le modèle optimal`,"model.opus48Description":`Opus le plus capable — coding agentique long-horizon, contexte 1M par défaut, effort high par défaut`,"model.opus47ClassicDescription":`Dernier Opus, le plus capable`,"model.opus471mDescription":`Dernier Opus, contexte 1M`,"model.opusClassicDescription":`Le plus puissant`,"model.opus1mDescription":`Le plus puissant, contexte 1M`,"model.sonnetClassicDescription":`Équilibré`,"model.sonnet1mDescription":`Équilibré, contexte 1M`,"model.haikuDescription":`Le plus rapide`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recommandé pour le code complexe (nécessite une authentification ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Repli par défaut — raisonnement solide, compatible avec une clé API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Rapide et efficient — idéal pour les tâches réactives et les sous-agents`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modèle spécialisé code pour l'ingénierie logicielle complexe`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Laisse le moteur choisir`,"reasoning.minimalDescription":`Raisonnement le plus rapide et superficiel`,"reasoning.lowDescription":`Plus rapide, moins profond`,"reasoning.mediumDescription":`Équilibré`,"reasoning.highDescription":`Plus de profondeur`,"reasoning.xhighDescription":`Profondeur étendue, tâches longues`,"reasoning.maxDescription":`Profondeur maximale`,"agentPermissionMode.label":`Mode de permission`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Strict (édits)`,"agentPermissionMode.interactive":`Interactif`,"agentPermissionMode.tooltip":`Comment l'agent gère les permissions d'outils. Plan : lecture seule, aucune écriture. Bypass : aucune demande. Strict : auto-accept des éditions de fichiers, respect des allow/deny pour le reste. Interactif : demande à l'utilisateur avant chaque outil via le panneau de permission.`,"agentPermissionMode.autoLoopOverride":`L'auto-loop force un mode autre que Plan — Plan bloque les outils MCP et les éditions dont la boucle a besoin. Choisis Bypass, Strict ou Interactif.`,"agentPermissionMode.autoLoopLocked":`Verrouillé sur Bypass tant que l'auto-loop est activé — un autre mode bloquerait la boucle sur les demandes de permission. AskUserQuestion fonctionne toujours.`,"workspaceList.title":`Espaces de travail`,"workspaceList.needsAttention":`Attention requise`,"workspaceList.running":`En cours`,"workspaceList.idle":`Inactif`,"workspaceList.archived":`Archivés`,"workspaceList.noWorkspaces":`Aucun espace de travail`,"workspaceList.footer":`{count} espace de travail | {count} espaces de travail`,"workspaceList.footerRunning":`{count} en cours`,"workspaceList.deleteDialog.title":`Supprimer l'espace de travail ?`,"workspaceList.deleteDialog.deleteLocal":`Supprimer la branche locale`,"workspaceList.deleteDialog.deleteRemote":`Supprimer la branche distante`,"workspaceList.deleteDialog.warning":`Attention : cette action est irréversible sur le dépôt distant.`,"workspaceList.deleteArchivedDialog.tooltip":`Supprimer tous les espaces de travail archivés`,"workspaceList.deleteArchivedDialog.title":`Supprimer tous les espaces archivés ?`,"workspaceList.deleteArchivedDialog.message":`Cela supprimera définitivement les {count} espaces de travail archivés. Cette action est irréversible.`,"workspacePage.selectWorkspace":`Sélectionnez un espace de travail pour commencer`,"workspacePage.session":`Session #{n}`,"workspacePage.newSession":`+ Nouvelle session`,"workspacePage.renameSession":`Renommer`,"workspacePage.renameSessionTitle":`Renommer la session`,"workspacePage.sessionNameLabel":`Nom de la session`,"workspacePage.sessionEndedNotice":`Cette session est terminée. Crée une nouvelle session pour continuer.`,"workspacePage.renameFailed":`Échec du renommage`,"workspacePage.createSessionFailed":`Échec de la création de la session`,"workspacePage.startFailed":`Échec du démarrage`,"workspacePage.stopFailed":`Échec de l'arrêt`,"workspacePage.interrupt":`Interrompre`,"workspacePage.interrupted":`Agent interrompu — en attente de votre prochain message`,"workspacePage.archivedBanner":`Workspace archivé — lecture seule`,"workspacePage.worktreePurgedBanner":`Worktree supprimé — historique conservé, restauration indisponible dans cette version`,"workspacePage.worktreePurgedTooltip":"Le dossier worktree a été supprimé du disque pour libérer de l'espace. L'historique des messages, sessions et métadonnées PR reste consultable ici, mais le répertoire de travail n'existe plus localement. Une future version de Kōbō pourra reconstruire le worktree à partir de la PR mergée — pour l'instant, recrée-le manuellement via `gh pr checkout` ou `git worktree add`.","workspacePage.pendingInitialPromptBanner":`Un prompt initial est en attente — l'agent ne l'a jamais reçu (le script de setup a planté ou le workspace n'a jamais été démarré). Cliquez sur Démarrer pour l'envoyer.`,"workspacePage.unarchived":`Workspace désarchivé`,"workspacePage.unarchiveFailed":`Échec du désarchivage`,"workspacePage.interruptFailed":`Échec de l'interruption`,"workspacePage.interruptTooltip":`Interruption douce (comme Escape) — arrête le tool en cours mais garde la session active`,"workspacePage.pendingNextRun":`Appliqué au prochain démarrage`,"search.title":`Recherche`,"search.tooltip":`Rechercher dans l'historique des agents`,"search.placeholder":`Rechercher dans tous les messages agents…`,"search.includeArchived":`Inclure les workspaces archivés`,"search.loading":`Recherche en cours…`,"search.noResults":`Aucun résultat`,"search.error":`Échec de la recherche : {message}`,"search.resultCount":`{n} résultat(s)`,"search.eventType.userMessage":`Vous`,"search.eventType.agentOutput":`Agent`,"activityFeed.empty":`Aucune activité`,"activityFeed.emptyHint":`Démarrez un espace de travail pour voir la sortie de l'agent ici`,"activityFeed.initialPrompt":`Prompt initial`,"activityFeed.you":`Vous`,"activityFeed.agent":`Agent`,"activityFeed.question":`Question`,"activityFeed.goToPrevious":`Aller au message précédent`,"activityFeed.scrollToBottom":`Défiler vers le bas`,"activityFeed.sendAnswers":`Envoyer les réponses`,"agentBusy.banner":`L'agent est occupé`,"agentBusy.subagentsRunning":`1 sub-agent en cours | {n} sub-agents en cours`,"agentBusy.viewSubagents":`Voir les sub-agents`,"agentBusy.pendingMessage":`En attente — l'agent est occupé`,"terminal.title":`Terminal`,"terminal.open":`Ouvrir le terminal`,"terminal.close":`Fermer le terminal`,"terminal.noWorkspace":`Sélectionnez un espace de travail`,"terminal.noWorktree":`Worktree pas encore créé`,"terminal.error":`Erreur du terminal`,"terminal.exited":`Terminal fermé`,"chatInput.placeholder":`Message... (/ pour les skills)`,"chatInput.fileSearchHint":`chercher un fichier`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Joindre une image`,"chatInput.queueBanner":`Message en file d'attente — sera envoyé quand l'agent aura terminé`,"chatInput.cancelQueue":`Annuler la file d'attente`,"chatInput.autoLoopBanner":`L'auto-loop tourne — arrête-le pour envoyer un message`,"chatInput.awaitingUserBanner":`L'agent attend ta réponse ci-dessus — réponds via le panneau de question`,"chatInput.autoLoopStop":`Arrêter`,"koboCommand.checkProgressDesc":`Vérifier la progression des tâches et critères d'acceptation`,"chatInput.uploading":`Envoi en cours...`,"voice.title":`Transcription vocale`,"voice.enabled":`Activer la transcription vocale locale`,"voice.pttKey":`Touche push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Espace`,"voice.language":`Langue (auto ou code)`,"voice.model":`Modèle actif`,"voice.commandPath":`Chemin du binaire Whisper (optionnel)`,"voice.ffmpegPath":`Chemin du binaire ffmpeg (optionnel)`,"voice.temperature":`Température`,"voice.temperatureHint":`Plus bas = plus déterministe ; plus haut = plus flexible mais moins stable.`,"voice.initialPrompt":`Prompt initial (optionnel)`,"voice.initialPromptHint":`Contexte optionnel pour aider Whisper sur les noms, acronymes ou jargon métier.`,"voice.translateToEnglish":`Traduire vers anglais`,"voice.translateToEnglishHint":`Si activé, la parole non anglaise est traduite en anglais au lieu d’être transcrite telle quelle.`,"voice.suppressNst":`Supprimer les tokens non vocaux`,"voice.suppressNstHint":`Essaie de réduire les artefacts non vocaux dans la transcription.`,"voice.installLink":`Installer whisper.cpp`,"voice.installGuideTitle":`Guide d'installation`,"voice.installGuideIntro":`Installe whisper.cpp et ffmpeg, puis renseigne les chemins binaires ci-dessous si nécessaire.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Après le build CMake, le binaire Whisper est généralement ici : whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Ensuite, renseigne "Chemin du binaire Whisper" et "Chemin du binaire ffmpeg" dans cette section (ou laisse vide si c’est dans le PATH).`,"voice.noneModel":`Aucun modèle actif`,"voice.notInstalled":`non installé`,"voice.download":`Télécharger`,"voice.delete":`Supprimer`,"voice.holdToTalk":`Maintiens pour parler`,"voice.recording":`Enregistrement...`,"voice.transcribing":`Transcription...`,"voice.notSupported":`L'enregistrement vocal n'est pas supporté par ce navigateur`,"voice.errorMicPermission":`Permission micro refusée`,"voice.errorTranscription":`La transcription vocale a échoué`,"voice.downloadFailed":`Échec du téléchargement du modèle`,"voice.deleteFailed":`Échec de la suppression du modèle`,"voice.errorDisabled":`La transcription vocale est désactivée dans les réglages`,"voice.errorModelMissing":`Aucun modèle vocal actif n'est configuré`,"voice.errorModelNotInstalled":`Le modèle vocal actif n'est pas installé`,"voice.errorAudioInvalid":`La capture audio est invalide ou vide`,"voice.errorLanguageInvalid":`La configuration de langue vocale est invalide`,"voice.errorRuntimeMissing":`Le runtime Whisper n'est pas installé ou pas dans le PATH`,"voice.maxDurationReached":`Durée maximale d'enregistrement atteinte`,"voice.runtimeReady":`Runtime prêt : {command}`,"voice.runtimeMissing":`Runtime manquant : {command}`,"voice.ffmpegReady":`ffmpeg prêt`,"voice.ffmpegMissing":`ffmpeg manquant`,"voice.sectionRuntime":`État du runtime`,"voice.sectionActivation":`Activation`,"voice.sectionModels":`Modèles Whisper`,"voice.sectionAdvanced":`Options avancées`,"voice.sectionBehavior":`Comportement de la transcription`,"voice.sectionBinaries":`Chemins des binaires`,"voice.downloadModels":`Télécharger un modèle`,"voice.cancelFailed":`Échec de l'annulation du téléchargement`,"createPage.title":`Sur quoi souhaitez-vous travailler ?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion activé`,"createPage.importNotion":`Importer depuis Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`L'URL doit commencer par https://www.notion.so/ ou https://app.notion.com/`,"createPage.notionAutoExtract":`Les sous-tâches et critères d'acceptation seront extraits automatiquement.`,"createPage.notionPanelChoiceLabel":`Cette URL pointe vers une sous-page (?p=). Sur laquelle veux-tu travailler ?`,"createPage.notionPanelOption":`Sous-page (panel)`,"createPage.notionPanelOptionDesc":`La page que tu consultais — recommandé`,"createPage.notionParentOption":`Page parente`,"createPage.notionParentOptionDesc":`L'epic / database qui la contient`,"createPage.importSentry":`Importer Sentry`,"createPage.sentryEnabled":`Sentry activé`,"createPage.sentryPlaceholder":`https://votre-org.sentry.io/issues/123456`,"createPage.sentryValidation":`L'URL doit pointer vers une issue Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`L'issue Sentry sera importée automatiquement`,"createPage.sentryExtractHint":`Kobo va extraire l'issue et l'écrire dans .ai/thoughts/`,"createPage.workspaceName":`Nom de l'espace de travail (par défaut le titre de la page Notion)`,"createPage.workspaceNamePlaceholder":`Nom de l'espace de travail...`,"createPage.instructions":`Instructions supplémentaires (optionnel)...`,"createPage.instructionsPlaceholder":`Décrivez la tâche...`,"createPage.manualHint":`Pas de ticket Notion ? Ajoutez vos tâches et critères d'acceptation manuellement — ils seront envoyés à l'agent Claude comme contexte.`,"createPage.tasks":`Tâches ({count})`,"createPage.addTask":`Ajouter une tâche...`,"createPage.acceptanceCriteria":`Critères d'acceptation ({count})`,"createPage.addCriterion":`Ajouter un critère...`,"createPage.projectPath":`Chemin du projet`,"createPage.branchType":`Type de branche`,"createPage.branch":`Branche`,"createPage.noBranches":`Aucune branche trouvée`,"createPage.enterPath":`Entrez le chemin du projet`,"createPage.create":`Créer`,"createPage.skipSetupScript":`Ignorer le script de setup`,"createPage.attachWorktreeToggle":`Réutiliser un worktree existant`,"createPage.attachWorktreeEnabled":`Worktree existant sélectionné`,"createPage.worktreePickerLabel":`Worktree existant`,"createPage.noOrphanWorktrees":`Aucun worktree orphelin pour ce projet`,"createPage.pickWorktreeRequired":`Sélectionne un worktree à réutiliser`,"createPage.notionExtractHint":`Les sous-tâches et critères d'acceptation seront extraits de la page Notion.`,"createPage.notionImportHint":`Cliquez sur « Importer depuis Notion » pour extraire automatiquement les sous-tâches d'un ticket.`,"createPage.errorCreating":`Erreur lors de la création de l'espace de travail.`,"createPage.branchAdjusted":"Branche déjà existante — création de `{branch}` à la place. Le dossier worktree correspondant utilise le même suffixe.","createPage.validationNotionUrl":`Veuillez coller une URL Notion valide (https://www.notion.so/... ou https://app.notion.com/...).`,"createPage.validationDescription":`Veuillez décrire la tâche.`,"createPage.validationName":`Veuillez fournir un nom d'espace de travail.`,"createPage.validationPath":`Veuillez entrer le chemin du projet.`,"createPage.validationBranch":`Veuillez sélectionner une branche.`,"settings.title":`Paramètres`,"settings.language":`Langue`,"settings.projectColor":`Couleur`,"settings.projectColorClear":`Effacer`,"settings.projectColorDefault":`Par défaut (gris)`,"settings.workspaceListSection":`Liste des workspaces`,"settings.flattenWorkspaceList":`Afficher en liste plate`,"settings.flattenWorkspaceListHint":`Affiche tous les espaces de travail en liste plate avec un badge projet, plutôt que regroupés par projet.`,"settings.skillSuite.section":`Suite de skills`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personnalisé`,"settings.skillSuite.superpowersHint":`Workflow opiné TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite de Garry Tan — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Les deux suites s'empilent — superpowers pour la méthodo (brainstorm / TDD / plans / review au niveau principes), gstack pour les workflows concrets (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Édite les quatre prompts ci-dessous toi-même. Démarre depuis la base agnostique.`,"settings.skillSuite.reloadDefaults":`Recharger les valeurs par défaut`,"settings.skillSuite.reloadDefaultsConfirm":`Remplacer les quatre prompts personnalisés par les valeurs agnostiques par défaut ?`,"settings.skillSuite.customPrompts":`Prompts personnalisés`,"settings.skillSuite.reviewTemplate":`Template de relecture`,"settings.skillSuite.autoLoopReviewGate":`Gate de relecture auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro de grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Instruction phase brainstorming`,"settings.global":`Général`,"settings.projects":`Projets`,"settings.globalSettings":`Paramètres généraux`,"settings.defaultModel":`Modèle par défaut`,"settings.defaultModelClaude":`Modèle par défaut (Claude Code)`,"settings.defaultModelCodex":`Modèle par défaut (OpenAI Codex)`,"settings.agentPermissions":`Permissions de l'agent`,"settings.skipPermissions":`Ignorer les invites de permission (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Attention : désactiver cette option entraînera le refus automatique de toutes les permissions d'outils (Write, Edit, Bash...) en mode headless. L'agent ne pourra que lire.`,"settings.notifications":`Notifications`,"settings.browserNotifications":`Notification navigateur quand l'agent termine`,"settings.audioNotifications":`Notification sonore quand l'agent termine`,"settings.notificationSound":`Son de notification`,"settings.notificationSoundPreview":`Écouter`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Travail terminé`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Ça va péter`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Mode de permission par défaut`,"settings.defaultPermissionModeClaude":`Mode de permission par défaut (Claude Code)`,"settings.defaultPermissionModeCodex":`Mode de permission par défaut (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Mode appliqué à la création d'un workspace. Plan = lecture seule, Bypass = sans prompt, Strict = auto-accept des éditions avec allow-list, Interactif = demande avant chaque outil.`,"settings.activityFeed":`Flux d'activité`,"settings.verboseMessages":`Afficher les messages système détaillés (task_progress, task_started)`,"settings.availableVariables":`Variables disponibles dans les modèles de prompt`,"settings.prPromptTemplate":`Modèle de prompt PR`,"settings.prPromptPlaceholder":`Instructions pour l'agent lors de la création de PR GitHub...`,"settings.prPromptHint":`Utilisez les variables listées ci-dessus (syntaxe doubles accolades).`,"settings.reviewPromptTemplate":`Modèle de prompt de review`,"settings.reviewPromptPlaceholder":`Instructions pour l'agent lors de la review des changes de la branche...`,"settings.ciFixPromptTemplate":`Modèle de prompt « Fix CI »`,"settings.ciFixPromptHint":`Envoyé à l'agent quand un workspace voit sa CI échouer. Variables (syntaxe double-accolades) : pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Demande à l'agent de diagnostiquer et de corriger les jobs CI en échec...`,"settings.finalizationPromptTemplate":`Prompt de finalisation de l'auto-loop`,"settings.finalizationPromptHint":`Prompt par défaut pour la dernière itération de l'auto-loop (contrôles qualité finaux). Utilisé quand un projet laisse son propre prompt de finalisation vide.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt initial Notion`,"settings.notionInitialPrompt.help":`Ajouté au prompt de création de workspace quand le workspace a un ticket Notion. Variables : {variables}.`,"settings.notionInitialPrompt.project":`Prompt initial Notion (override)`,"settings.sentryInitialPrompt":`Prompt initial Sentry`,"settings.sentryInitialPrompt.help":`Ajouté au prompt de création de workspace quand le workspace a une issue Sentry. Variables : {variables}.`,"settings.sentryInitialPrompt.project":`Prompt initial Sentry (override)`,"settings.initialPrompt.inheritHint":`Laisser vide pour hériter. Saisir un caractère d'espacement pour désactiver l'injection à ce niveau.`,"settings.resetToDefault":`Réinitialiser`,"settings.resetFailed":`Échec du chargement de la valeur par défaut`,"settings.sentryIntegration":`Intégration Sentry`,"settings.var.prNumber":`Numéro de PR (ex : 42)`,"settings.var.prUrl":`URL complète de la PR créée`,"settings.var.branchName":`Nom de la branche de travail`,"settings.var.sourceBranch":`Branche source ciblée par la PR`,"settings.var.workspaceName":`Nom du workspace`,"settings.var.projectName":`Dernier segment du chemin du projet`,"settings.var.notionUrl":`URL Notion si définie, vide sinon`,"settings.var.commits":`Liste à puces des commits entre source et head`,"settings.var.diffStats":`Résumé shortstat Git (fichiers, insertions, suppressions)`,"settings.var.tasks":`Tâches classiques en liste à cocher`,"settings.var.acceptanceCriteria":`Critères d'acceptation en liste à cocher`,"settings.gitConventions":`Conventions Git (global)`,"settings.gitConventionsPlaceholder":`# Conventions Git...`,"settings.gitConventionsHint":`Ces conventions sont écrites dans .ai/.git-conventions.md pour chaque nouvel espace de travail et doivent être respectées par l'agent avant toute opération Git. Remplacées par les conventions par projet si définies.`,"settings.setupScript":`Script de setup`,"settings.cleanupScript":`Script de cleanup`,"settings.archiveScript":`Script d'archivage`,"settings.archiveScriptHint":`Script shell exécuté côté serveur dans le worktree quand un workspace est archivé. Laisser vide pour désactiver.`,"settings.archiveScriptPlaceholder":`ex. nettoyer des conteneurs, libérer de l'espace disque…`,"settings.changeSourceBranchScript":`Script de changement de branche source`,"settings.changeSourceBranchScript.help":`Remplace le cherry-pick intégré quand non vide. Le script possède git, base de PR, force-push et conflits ; Kōbō refuse seulement si l'agent tourne et met à jour la métadonnée source à exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nouvelle branche source choisie dans le dialogue
50
+ sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Opción B — Tomar la propiedad (más simple, pierde la huella "creado por root en el contenedor" pero rara vez importa):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Consejo: puedes ejecutar estos comandos directamente sobre la raíz de tus worktrees (ej. `~/.worktrees/`) para cubrir todos los workspaces existentes Y futuros de una sola vez. Una vez hecho, el borrado de Kōbō funcionará sin errores de permisos.","contextMenu.runSetup":`Ejecutar script de setup`,"contextMenu.exportEvents":`Exportar eventos (CSV)`,"contextMenu.dismissChangesRequested":`Marcar «Cambios solicitados» como visto`,"contextMenu.dismissCiFailure":`Marcar «CI en error» como visto`,"contextMenu.restoreChangesRequested":`Marcar «Cambios solicitados» como no visto`,"contextMenu.restoreCiFailure":`Marcar «CI en error» como no visto`,"contextMenu.exportingEvents":`Preparando la exportación…`,"contextMenu.exportEventsError":`Error al exportar los eventos`,"contextMenu.openNotion":`Abrir en Notion`,"contextMenu.openSentry":`Abrir en Sentry`,"contextMenu.openPr":`Abrir PR`,"workspace.favorite":`Marcar como favorito`,"workspace.unfavorite":`Quitar de favoritos`,"workspace.showFavoritesOnly":`Mostrar solo favoritos`,"workspace.searchArchivedToggle":`Buscar también en workspaces archivados`,"workspace.descriptionPlaceholder":`Añadir una breve descripción`,"workspace.descriptionDialogHint":`Texto sin formato, máximo 200 caracteres. Dejar vacío para borrar.`,"workspace.descriptionTooLong":`La descripción debe tener 200 caracteres o menos.`,"workspace.descriptionSaveFailed":`No se pudo guardar la descripción.`,"workspace.agentDescriptionTooltip":`Estado en vivo mantenido por el agente`,"mcp.tool.setWorkspaceDescription":`Establece la breve descripción del workspace (≤ 200 caracteres).`,"tags.manage":`Gestionar etiquetas`,"tags.manageTitle":`Gestionar etiquetas del workspace`,"tags.noTagsDefined":`Sin etiquetas. Añádelas en Ajustes > Global > Etiquetas.`,"tags.orphanedHint":`{count} etiqueta(s) ya no están en el catálogo global. Desmárcalas para quitarlas.`,"settings.tagsTitle":`Etiquetas de workspace`,"settings.tagsHint":`Define las etiquetas asignables a los workspaces. Escribe para añadir, clic en la cruz para quitar.`,"settings.tagsLabel":`Etiquetas disponibles`,"settings.branchPrefixesTitle":`Prefijos de rama`,"settings.branchPrefixesHint":`Gestiona los prefijos de rama de Git disponibles en la página de creación de workspaces. El primero se preselecciona por defecto.`,"settings.branchPrefixesEmpty":`No hay ningún prefijo de rama definido. Añade al menos uno abajo.`,"settings.branchPrefixesAddLabel":`Nuevo prefijo`,"settings.branchPrefixesEditHint":`Haz clic para renombrar`,"settings.branchPrefixesMoveUp":`Subir`,"settings.branchPrefixesMoveDown":`Bajar`,"settings.worktreesTitle":`Worktrees Git`,"settings.worktreesHint":`Elige dónde se crean los worktrees de nuevos workspaces. Las rutas relativas se resuelven desde el proyecto; se admiten rutas absolutas Linux/macOS y Windows, $HOME, ~ y %USERPROFILE%.`,"settings.worktreesPathLabel":`Ruta de worktrees`,"settings.worktreesPathRequired":`La ruta de worktrees es obligatoria.`,"settings.worktreesPrefixByProject":`Prefijar los worktrees con el nombre del proyecto`,"settings.worktreesPrefixByProjectHint":`Coloca cada worktree en un subdirectorio con el nombre del proyecto para evitar colisiones cuando varios proyectos comparten la misma raíz.`,"settings.shareTitle":`Compartir configuración`,"settings.shareHint":`Exporta tus ajustes, plantillas y etiquetas en un bundle JSON. Las claves MCP no se incluyen por seguridad.`,"settings.exportConfig":`Exportar`,"settings.importConfig":`Importar`,"settings.exportSuccess":`Configuración exportada`,"settings.importSuccess":`Configuración importada`,"settings.importConfirmTitle":`Importar configuración`,"settings.importConfirmMessage":`Esto reemplazará tus ajustes, plantillas y etiquetas actuales. Las claves MCP se conservan. ¿Continuar?`,"health.title":`Salud`,"health.tooltip":`Estado del sistema`,"changelog.title":`Changelog`,"changelog.tooltip":`Novedades de Kōbō`,"changelog.empty":`Ningún changelog disponible.`,"changelog.current":`actual`,"changelog.currentVersion":`Versión actual: v{version}`,"health.envTitle":`Entorno`,"health.version":`Versión`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Base de datos`,"health.dbPath":`Ruta`,"health.dbSize":`Tamaño`,"health.schemaVersion":`Versión del esquema`,"health.settingsSchemaVersion":`Esquema de ajustes`,"health.runtimesTitle":`Motores de agente`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude no encontrado en PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binario codex no resoluble`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} en total, {archived} archivados`,"health.worktreesMissing":`{count} worktree(s) faltan en el disco`,"health.sessionsTitle":`Sesiones de agente`,"health.sessionsOrphaned":`{n} sesión/sesiones huérfana(s) en ejecución`,"health.integrationsTitle":`Integraciones`,"health.integrationConfigured":`configurada`,"health.integrationMissing":`sin configurar`,"health.activeTitle":`Estado activo`,"health.activeQuotaBackoffs":`Quota backoffs pendientes`,"health.activeWakeups":`Despertares programados`,"health.activeAutoLoop":`Auto-loop en ejecución`,"health.activeAgentSessions":`Sesiones de agente activas`,"health.activeDevServers":`Servidores de desarrollo activos`,"health.noneActive":`Ninguno.`,"health.quotaResumeAt":`reanuda a las {time}`,"health.wakeupAt":`despierta a las {time}`,"health.startedAgo":`iniciada hace {time}`,"health.autoLoopReady":`listo, iterando`,"health.autoLoopGrooming":`grooming en curso`,"session.started":`Sesión iniciada`,"session.ended":`Sesión finalizada`,"session.compacted":`Contexto compactado`,"tool.running":`Ejecutando...`,"activity.raw_lines":`Líneas de salida brutas ({n})`,"activity.loading_older":`Cargando mensajes anteriores…`,"activity.compacting":`Compactando el contexto…`,"activity.prev_user_message":`Mensaje anterior del usuario`,"activity.scroll_to_bottom":`Desplazar al final`,"chat.systemPrompt":`Prompt del sistema`,"chat.agent":`Agente`,"chat.cleanupScript":`Script de limpieza`,"chat.archiveScript":`Script de archivado`,"chat.setupScript":`Script de setup`,"chat.scriptDone":`Hecho`,"chat.you":`Tú`,"chat.session":`Sesión`,"chat.nActions":`{n} acción | {n} acciones`,"chat.lastUpdatedAt":`Última actualización a las {time}`,"chat.scrollToTurnTop":`Desplazar al inicio del mensaje`,"migration.backing_up":`Haciendo copia de seguridad de la base de datos…`,"migration.running":`Migrando datos del agente — {processed}/{total}`,"migration.error":`La migración falló`,"migration.backup_location":`Se guardó una copia de seguridad en {path}. Reinicia Kōbō para reintentar.`,"migration.retry":`Reinicia Kōbō para reintentar.`,"engine.select":`Motor`,"engine.model":`Modelo`,"engine.effort":`Esfuerzo de razonamiento`,"wakeup.scheduledIn":`Próximo despertar en {n}s`,"wakeup.scheduledAt":`Próximo despertar a las {time}`,"wakeup.firing":`Despertando...`,"wakeup.reason":`Razón: {reason}`,"wakeup.cancel":`Cancelar este despertar`,"wakeup.pendingIndicator":`Despertar programado`,"cron.pendingIndicator":`{n} cron(s) programado(s)`,"schedule.tabLabel":`Programación`,"schedule.wakeupTitle":`Wakeup pendiente`,"schedule.cronsTitle":`Programaciones recurrentes`,"schedule.noWakeup":`Sin wakeup programado`,"schedule.noCrons":`Sin cron programado`,"schedule.nextFireAt":`próximo a las {time}`,"schedule.lastFiredAt":`último hace {time}`,"schedule.addCronTitle":`Añadir una tarea recurrente`,"schedule.addWakeupTitle":`Programar un wakeup`,"schedule.every":`Cada`,"schedule.unitMinutes":`minutos`,"schedule.unitHours":`horas`,"schedule.unitDays":`días`,"schedule.advancedExpression":`Expresión avanzada (opcional)`,"schedule.advancedHint":`Cron sin procesar (p. ej. */15 * * * *) o {'@'}hourly/{'@'}daily — anula el selector si se rellena.`,"schedule.promptLabel":`Prompt`,"schedule.labelOptional":`Etiqueta (opcional)`,"schedule.delayMinutes":`Retraso (minutos)`,"schedule.modeFresh":`Nueva sesión`,"schedule.oneShot":`Ejecutar solo una vez`,"schedule.addCronBtn":`Añadir cron`,"schedule.addWakeupBtn":`Programar wakeup`,"schedule.cronCreated":`Tarea recurrente añadida`,"schedule.wakeupCreated":`Wakeup programado`,"askUserQuestion.title":`El agente hace una pregunta`,"askUserQuestion.submit":`Enviar respuesta`,"askUserQuestion.multiSelectHint":`Selecciona una o más opciones`,"askUserQuestion.otherOption":`Otro`,"askUserQuestion.otherOptionHint":`especifíquelo en su próximo mensaje`,"askUserQuestion.noPending":`Ninguna pregunta pendiente`,"askUserQuestion.next":`Siguiente`,"askUserQuestion.previous":`Anterior`,"askUserQuestion.cancel":`Cancelar`,"askUserQuestion.cancelTooltip":`Saltar esta pregunta — el agente continuará sin respuesta`,"askUserQuestion.collapse":`Contraer el panel de pregunta`,"askUserQuestion.expand":`Expandir el panel de pregunta`,"permissionRequest.title":`El agente quiere usar una herramienta`,"permissionRequest.allow":`Permitir`,"permissionRequest.deny":`Denegar`,"permissionRequest.tool":`Herramienta`,"permissionRequest.input":`Entrada`,"permissionRequest.denied":`denegado por el usuario`,"workspaceStatus.awaitingUser":`esperando tu respuesta`,"workspaceList.prOpen":`#{n} — Pull request abierta`,"workspaceList.prChangesRequested":`#{n} — Cambios solicitados`,"workspaceList.attentionCiFailed":`CI fallida`,"workspaceList.attentionChangesRequested":`Cambios solicitados`,"workspaceList.attentionReadyToMerge":`Listo para merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Iniciar auto-loop`,"autoLoop.prepare":`Preparar para auto-loop`,"autoLoop.reprepare":`Volver a preparar para auto-loop`,"autoLoop.reprepareTooltip":`Volver a ejecutar la fase de grooming para añadir o refrescar tareas antes de reanudar el bucle`,"autoLoop.prepareBusy":`Espera a que el agente termine antes de preparar`,"autoLoop.forceReady":`Sé lo que hago — omitir preparación`,"autoLoop.forceReadyConfirm":`¿Omitir la preparación y marcar auto-loop listo? El loop puede quedarse bloqueado si las tareas no son atómicas.`,"autoLoop.stop":`Detener auto-loop`,"autoLoop.notReady":`Ejecute primero 'Preparar para auto-loop'`,"autoLoop.noTasks":`Añada tareas primero`,"autoLoop.progress":`Auto-loop · {done}/{total} tareas`,"autoLoop.preparing":`Auto-loop · preparando`,"autoLoop.preparingTooltip":`Preparación en curso — el agente está creando / revisando tareas. El bucle arrancará cuando llame a mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop en ejecución`,"autoLoop.startInMode":`Iniciar en modo auto-loop`,"koboCommand.prepAutoloopDesc":`Preparar tareas para modo auto-loop (atomicidad)`,"staleSessionBanner.title":`Auto-loop en curso`,"staleSessionBanner.message":`Estás viendo una sesión anterior — el agente está trabajando en la más reciente.`,"staleSessionBanner.staleTitle":`Sesión anterior`,"staleSessionBanner.staleMessage":`Estás viendo una sesión anterior — los mensajes que envíes irán a esta sesión, no a la más reciente.`,"staleSessionBanner.switchToCurrent":`Cambiar a la actual`},cn={"common.save":`Enregistrer`,"common.cancel":`Annuler`,"common.delete":`Supprimer`,"common.close":`Fermer`,"common.details":`Détails`,"whatsNew.title":`Quoi de neuf`,"common.loading":`Chargement...`,"common.search":`Rechercher...`,"common.refresh":`Actualiser`,"common.copy":`Copier`,"common.copied":`Copié dans le presse-papiers`,"common.copyFailed":`Échec de la copie`,"common.add":`Ajouter`,"folderPicker.title":`Choisir un dossier`,"folderPicker.parent":`Dossier parent`,"folderPicker.empty":`Aucun sous-dossier`,"folderPicker.select":`Choisir ce dossier`,"common.start":`Démarrer`,"common.stop":`Arrêter`,"common.archive":`Archiver`,"common.unarchive":`Désarchiver`,"common.selectWorkspace":`Sélectionnez un espace de travail`,"common.noResults":`Aucun résultat pour « {query} »`,"common.send":`envoyer`,"common.newLine":`nouvelle ligne`,"common.history":`historique`,"common.justNow":`a l'instant`,"common.minutesAgo":`il y a {count}m`,"common.hoursAgo":`il y a {count}h`,"common.daysAgo":`il y a {count}j`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Modèle le plus capable — succède à Opus 4.8, contexte 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 sans classificateurs de sécurité — accès limité (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude choisit le modèle optimal`,"model.opus48Description":`Opus le plus capable — coding agentique long-horizon, contexte 1M par défaut, effort high par défaut`,"model.opus47ClassicDescription":`Dernier Opus, le plus capable`,"model.opus471mDescription":`Dernier Opus, contexte 1M`,"model.opusClassicDescription":`Le plus puissant`,"model.opus1mDescription":`Le plus puissant, contexte 1M`,"model.sonnetClassicDescription":`Équilibré`,"model.sonnet1mDescription":`Équilibré, contexte 1M`,"model.haikuDescription":`Le plus rapide`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Recommandé pour le code complexe (nécessite une authentification ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Repli par défaut — raisonnement solide, compatible avec une clé API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Rapide et efficient — idéal pour les tâches réactives et les sous-agents`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modèle spécialisé code pour l'ingénierie logicielle complexe`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Laisse le moteur choisir`,"reasoning.minimalDescription":`Raisonnement le plus rapide et superficiel`,"reasoning.lowDescription":`Plus rapide, moins profond`,"reasoning.mediumDescription":`Équilibré`,"reasoning.highDescription":`Plus de profondeur`,"reasoning.xhighDescription":`Profondeur étendue, tâches longues`,"reasoning.maxDescription":`Profondeur maximale`,"agentPermissionMode.label":`Mode de permission`,"agentPermissionMode.plan":`Plan`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Strict (édits)`,"agentPermissionMode.interactive":`Interactif`,"agentPermissionMode.tooltip":`Comment l'agent gère les permissions d'outils. Plan : lecture seule, aucune écriture. Bypass : aucune demande. Strict : auto-accept des éditions de fichiers, respect des allow/deny pour le reste. Interactif : demande à l'utilisateur avant chaque outil via le panneau de permission.`,"agentPermissionMode.autoLoopOverride":`L'auto-loop force un mode autre que Plan — Plan bloque les outils MCP et les éditions dont la boucle a besoin. Choisis Bypass, Strict ou Interactif.`,"agentPermissionMode.autoLoopLocked":`Verrouillé sur Bypass tant que l'auto-loop est activé — un autre mode bloquerait la boucle sur les demandes de permission. AskUserQuestion fonctionne toujours.`,"workspaceList.title":`Espaces de travail`,"workspaceList.needsAttention":`Attention requise`,"workspaceList.running":`En cours`,"workspaceList.idle":`Inactif`,"workspaceList.archived":`Archivés`,"workspaceList.noWorkspaces":`Aucun espace de travail`,"workspaceList.footer":`{count} espace de travail | {count} espaces de travail`,"workspaceList.footerRunning":`{count} en cours`,"workspaceList.deleteDialog.title":`Supprimer l'espace de travail ?`,"workspaceList.deleteDialog.deleteLocal":`Supprimer la branche locale`,"workspaceList.deleteDialog.deleteRemote":`Supprimer la branche distante`,"workspaceList.deleteDialog.warning":`Attention : cette action est irréversible sur le dépôt distant.`,"workspaceList.deleteArchivedDialog.tooltip":`Supprimer tous les espaces de travail archivés`,"workspaceList.deleteArchivedDialog.title":`Supprimer tous les espaces archivés ?`,"workspaceList.deleteArchivedDialog.message":`Cela supprimera définitivement les {count} espaces de travail archivés. Cette action est irréversible.`,"workspacePage.selectWorkspace":`Sélectionnez un espace de travail pour commencer`,"workspacePage.session":`Session #{n}`,"workspacePage.newSession":`+ Nouvelle session`,"workspacePage.renameSession":`Renommer`,"workspacePage.renameSessionTitle":`Renommer la session`,"workspacePage.sessionNameLabel":`Nom de la session`,"workspacePage.sessionEndedNotice":`Cette session est terminée. Crée une nouvelle session pour continuer.`,"workspacePage.renameFailed":`Échec du renommage`,"workspacePage.createSessionFailed":`Échec de la création de la session`,"workspacePage.startFailed":`Échec du démarrage`,"workspacePage.stopFailed":`Échec de l'arrêt`,"workspacePage.interrupt":`Interrompre`,"workspacePage.interrupted":`Agent interrompu — en attente de votre prochain message`,"workspacePage.archivedBanner":`Workspace archivé — lecture seule`,"workspacePage.worktreePurgedBanner":`Worktree supprimé — historique conservé, restauration indisponible dans cette version`,"workspacePage.worktreePurgedTooltip":"Le dossier worktree a été supprimé du disque pour libérer de l'espace. L'historique des messages, sessions et métadonnées PR reste consultable ici, mais le répertoire de travail n'existe plus localement. Une future version de Kōbō pourra reconstruire le worktree à partir de la PR mergée — pour l'instant, recrée-le manuellement via `gh pr checkout` ou `git worktree add`.","workspacePage.pendingInitialPromptBanner":`Un prompt initial est en attente — l'agent ne l'a jamais reçu (le script de setup a planté ou le workspace n'a jamais été démarré). Cliquez sur Démarrer pour l'envoyer.`,"workspacePage.unarchived":`Workspace désarchivé`,"workspacePage.unarchiveFailed":`Échec du désarchivage`,"workspacePage.interruptFailed":`Échec de l'interruption`,"workspacePage.interruptTooltip":`Interruption douce (comme Escape) — arrête le tool en cours mais garde la session active`,"workspacePage.pendingNextRun":`Appliqué au prochain démarrage`,"search.title":`Recherche`,"search.tooltip":`Rechercher dans l'historique des agents`,"search.placeholder":`Rechercher dans tous les messages agents…`,"search.includeArchived":`Inclure les workspaces archivés`,"search.loading":`Recherche en cours…`,"search.noResults":`Aucun résultat`,"search.error":`Échec de la recherche : {message}`,"search.resultCount":`{n} résultat(s)`,"search.eventType.userMessage":`Vous`,"search.eventType.agentOutput":`Agent`,"activityFeed.empty":`Aucune activité`,"activityFeed.emptyHint":`Démarrez un espace de travail pour voir la sortie de l'agent ici`,"activityFeed.initialPrompt":`Prompt initial`,"activityFeed.you":`Vous`,"activityFeed.agent":`Agent`,"activityFeed.question":`Question`,"activityFeed.goToPrevious":`Aller au message précédent`,"activityFeed.scrollToBottom":`Défiler vers le bas`,"activityFeed.sendAnswers":`Envoyer les réponses`,"agentBusy.banner":`L'agent est occupé`,"agentBusy.subagentsRunning":`1 sub-agent en cours | {n} sub-agents en cours`,"agentBusy.viewSubagents":`Voir les sub-agents`,"agentBusy.pendingMessage":`En attente — l'agent est occupé`,"terminal.title":`Terminal`,"terminal.open":`Ouvrir le terminal`,"terminal.close":`Fermer le terminal`,"terminal.noWorkspace":`Sélectionnez un espace de travail`,"terminal.noWorktree":`Worktree pas encore créé`,"terminal.error":`Erreur du terminal`,"terminal.exited":`Terminal fermé`,"chatInput.placeholder":`Message... (/ pour les skills)`,"chatInput.fileSearchHint":`chercher un fichier`,"chatInput.skills":`Skills`,"chatInput.attachImage":`Joindre une image`,"chatInput.queueBanner":`Message en file d'attente — sera envoyé quand l'agent aura terminé`,"chatInput.cancelQueue":`Annuler la file d'attente`,"chatInput.autoLoopBanner":`L'auto-loop tourne — arrête-le pour envoyer un message`,"chatInput.awaitingUserBanner":`L'agent attend ta réponse ci-dessus — réponds via le panneau de question`,"chatInput.autoLoopStop":`Arrêter`,"koboCommand.checkProgressDesc":`Vérifier la progression des tâches et critères d'acceptation`,"chatInput.uploading":`Envoi en cours...`,"voice.title":`Transcription vocale`,"voice.enabled":`Activer la transcription vocale locale`,"voice.pttKey":`Touche push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Espace`,"voice.language":`Langue (auto ou code)`,"voice.model":`Modèle actif`,"voice.commandPath":`Chemin du binaire Whisper (optionnel)`,"voice.ffmpegPath":`Chemin du binaire ffmpeg (optionnel)`,"voice.temperature":`Température`,"voice.temperatureHint":`Plus bas = plus déterministe ; plus haut = plus flexible mais moins stable.`,"voice.initialPrompt":`Prompt initial (optionnel)`,"voice.initialPromptHint":`Contexte optionnel pour aider Whisper sur les noms, acronymes ou jargon métier.`,"voice.translateToEnglish":`Traduire vers anglais`,"voice.translateToEnglishHint":`Si activé, la parole non anglaise est traduite en anglais au lieu d’être transcrite telle quelle.`,"voice.suppressNst":`Supprimer les tokens non vocaux`,"voice.suppressNstHint":`Essaie de réduire les artefacts non vocaux dans la transcription.`,"voice.installLink":`Installer whisper.cpp`,"voice.installGuideTitle":`Guide d'installation`,"voice.installGuideIntro":`Installe whisper.cpp et ffmpeg, puis renseigne les chemins binaires ci-dessous si nécessaire.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Après le build CMake, le binaire Whisper est généralement ici : whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Ensuite, renseigne "Chemin du binaire Whisper" et "Chemin du binaire ffmpeg" dans cette section (ou laisse vide si c’est dans le PATH).`,"voice.noneModel":`Aucun modèle actif`,"voice.notInstalled":`non installé`,"voice.download":`Télécharger`,"voice.delete":`Supprimer`,"voice.holdToTalk":`Maintiens pour parler`,"voice.recording":`Enregistrement...`,"voice.transcribing":`Transcription...`,"voice.notSupported":`L'enregistrement vocal n'est pas supporté par ce navigateur`,"voice.errorMicPermission":`Permission micro refusée`,"voice.errorTranscription":`La transcription vocale a échoué`,"voice.downloadFailed":`Échec du téléchargement du modèle`,"voice.deleteFailed":`Échec de la suppression du modèle`,"voice.errorDisabled":`La transcription vocale est désactivée dans les réglages`,"voice.errorModelMissing":`Aucun modèle vocal actif n'est configuré`,"voice.errorModelNotInstalled":`Le modèle vocal actif n'est pas installé`,"voice.errorAudioInvalid":`La capture audio est invalide ou vide`,"voice.errorLanguageInvalid":`La configuration de langue vocale est invalide`,"voice.errorRuntimeMissing":`Le runtime Whisper n'est pas installé ou pas dans le PATH`,"voice.maxDurationReached":`Durée maximale d'enregistrement atteinte`,"voice.runtimeReady":`Runtime prêt : {command}`,"voice.runtimeMissing":`Runtime manquant : {command}`,"voice.ffmpegReady":`ffmpeg prêt`,"voice.ffmpegMissing":`ffmpeg manquant`,"voice.sectionRuntime":`État du runtime`,"voice.sectionActivation":`Activation`,"voice.sectionModels":`Modèles Whisper`,"voice.sectionAdvanced":`Options avancées`,"voice.sectionBehavior":`Comportement de la transcription`,"voice.sectionBinaries":`Chemins des binaires`,"voice.downloadModels":`Télécharger un modèle`,"voice.cancelFailed":`Échec de l'annulation du téléchargement`,"createPage.title":`Sur quoi souhaitez-vous travailler ?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion activé`,"createPage.importNotion":`Importer depuis Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`L'URL doit commencer par https://www.notion.so/ ou https://app.notion.com/`,"createPage.notionAutoExtract":`Les sous-tâches et critères d'acceptation seront extraits automatiquement.`,"createPage.notionPanelChoiceLabel":`Cette URL pointe vers une sous-page (?p=). Sur laquelle veux-tu travailler ?`,"createPage.notionPanelOption":`Sous-page (panel)`,"createPage.notionPanelOptionDesc":`La page que tu consultais — recommandé`,"createPage.notionParentOption":`Page parente`,"createPage.notionParentOptionDesc":`L'epic / database qui la contient`,"createPage.importSentry":`Importer Sentry`,"createPage.sentryEnabled":`Sentry activé`,"createPage.sentryPlaceholder":`https://votre-org.sentry.io/issues/123456`,"createPage.sentryValidation":`L'URL doit pointer vers une issue Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`L'issue Sentry sera importée automatiquement`,"createPage.sentryExtractHint":`Kobo va extraire l'issue et l'écrire dans .ai/thoughts/`,"createPage.workspaceName":`Nom de l'espace de travail (par défaut le titre de la page Notion)`,"createPage.workspaceNamePlaceholder":`Nom de l'espace de travail...`,"createPage.instructions":`Instructions supplémentaires (optionnel)...`,"createPage.instructionsPlaceholder":`Décrivez la tâche...`,"createPage.manualHint":`Pas de ticket Notion ? Ajoutez vos tâches et critères d'acceptation manuellement — ils seront envoyés à l'agent Claude comme contexte.`,"createPage.tasks":`Tâches ({count})`,"createPage.addTask":`Ajouter une tâche...`,"createPage.acceptanceCriteria":`Critères d'acceptation ({count})`,"createPage.addCriterion":`Ajouter un critère...`,"createPage.projectPath":`Chemin du projet`,"createPage.branchType":`Type de branche`,"createPage.branch":`Branche`,"createPage.noBranches":`Aucune branche trouvée`,"createPage.enterPath":`Entrez le chemin du projet`,"createPage.create":`Créer`,"createPage.skipSetupScript":`Ignorer le script de setup`,"createPage.attachWorktreeToggle":`Réutiliser un worktree existant`,"createPage.attachWorktreeEnabled":`Worktree existant sélectionné`,"createPage.worktreePickerLabel":`Worktree existant`,"createPage.noOrphanWorktrees":`Aucun worktree orphelin pour ce projet`,"createPage.pickWorktreeRequired":`Sélectionne un worktree à réutiliser`,"createPage.notionExtractHint":`Les sous-tâches et critères d'acceptation seront extraits de la page Notion.`,"createPage.notionImportHint":`Cliquez sur « Importer depuis Notion » pour extraire automatiquement les sous-tâches d'un ticket.`,"createPage.errorCreating":`Erreur lors de la création de l'espace de travail.`,"createPage.branchAdjusted":"Branche déjà existante — création de `{branch}` à la place. Le dossier worktree correspondant utilise le même suffixe.","createPage.validationNotionUrl":`Veuillez coller une URL Notion valide (https://www.notion.so/... ou https://app.notion.com/...).`,"createPage.validationDescription":`Veuillez décrire la tâche.`,"createPage.validationName":`Veuillez fournir un nom d'espace de travail.`,"createPage.validationPath":`Veuillez entrer le chemin du projet.`,"createPage.validationBranch":`Veuillez sélectionner une branche.`,"settings.title":`Paramètres`,"settings.language":`Langue`,"settings.projectColor":`Couleur`,"settings.projectColorClear":`Effacer`,"settings.projectColorDefault":`Par défaut (gris)`,"settings.workspaceListSection":`Liste des workspaces`,"settings.flattenWorkspaceList":`Afficher en liste plate`,"settings.flattenWorkspaceListHint":`Affiche tous les espaces de travail en liste plate avec un badge projet, plutôt que regroupés par projet.`,"settings.skillSuite.section":`Suite de skills`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personnalisé`,"settings.skillSuite.superpowersHint":`Workflow opiné TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite de Garry Tan — /review, /ship, /qa, /office-hours, etc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Les deux suites s'empilent — superpowers pour la méthodo (brainstorm / TDD / plans / review au niveau principes), gstack pour les workflows concrets (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Édite les quatre prompts ci-dessous toi-même. Démarre depuis la base agnostique.`,"settings.skillSuite.reloadDefaults":`Recharger les valeurs par défaut`,"settings.skillSuite.reloadDefaultsConfirm":`Remplacer les quatre prompts personnalisés par les valeurs agnostiques par défaut ?`,"settings.skillSuite.customPrompts":`Prompts personnalisés`,"settings.skillSuite.reviewTemplate":`Template de relecture`,"settings.skillSuite.autoLoopReviewGate":`Gate de relecture auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro de grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Instruction phase brainstorming`,"settings.global":`Général`,"settings.projects":`Projets`,"settings.globalSettings":`Paramètres généraux`,"settings.defaultModel":`Modèle par défaut`,"settings.defaultModelClaude":`Modèle par défaut (Claude Code)`,"settings.defaultModelCodex":`Modèle par défaut (OpenAI Codex)`,"settings.agentPermissions":`Permissions de l'agent`,"settings.skipPermissions":`Ignorer les invites de permission (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Attention : désactiver cette option entraînera le refus automatique de toutes les permissions d'outils (Write, Edit, Bash...) en mode headless. L'agent ne pourra que lire.`,"settings.notifications":`Notifications`,"settings.browserNotifications":`Notification navigateur quand l'agent termine`,"settings.audioNotifications":`Notification sonore quand l'agent termine`,"settings.notificationSound":`Son de notification`,"settings.notificationSoundPreview":`Écouter`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Travail terminé`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Ça va péter`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Mode de permission par défaut`,"settings.defaultPermissionModeClaude":`Mode de permission par défaut (Claude Code)`,"settings.defaultPermissionModeCodex":`Mode de permission par défaut (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Mode appliqué à la création d'un workspace. Plan = lecture seule, Bypass = sans prompt, Strict = auto-accept des éditions avec allow-list, Interactif = demande avant chaque outil.`,"settings.activityFeed":`Flux d'activité`,"settings.verboseMessages":`Afficher les messages système détaillés (task_progress, task_started)`,"settings.availableVariables":`Variables disponibles dans les modèles de prompt`,"settings.prPromptTemplate":`Modèle de prompt PR`,"settings.prPromptPlaceholder":`Instructions pour l'agent lors de la création de PR GitHub...`,"settings.prPromptHint":`Utilisez les variables listées ci-dessus (syntaxe doubles accolades).`,"settings.reviewPromptTemplate":`Modèle de prompt de review`,"settings.reviewPromptPlaceholder":`Instructions pour l'agent lors de la review des changes de la branche...`,"settings.ciFixPromptTemplate":`Modèle de prompt « Fix CI »`,"settings.ciFixPromptHint":`Envoyé à l'agent quand un workspace voit sa CI échouer. Variables (syntaxe double-accolades) : pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Demande à l'agent de diagnostiquer et de corriger les jobs CI en échec...`,"settings.finalizationPromptTemplate":`Prompt de finalisation de l'auto-loop`,"settings.finalizationPromptHint":`Prompt par défaut pour la dernière itération de l'auto-loop (contrôles qualité finaux). Utilisé quand un projet laisse son propre prompt de finalisation vide.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt initial Notion`,"settings.notionInitialPrompt.help":`Ajouté au prompt de création de workspace quand le workspace a un ticket Notion. Variables : {variables}.`,"settings.notionInitialPrompt.project":`Prompt initial Notion (override)`,"settings.sentryInitialPrompt":`Prompt initial Sentry`,"settings.sentryInitialPrompt.help":`Ajouté au prompt de création de workspace quand le workspace a une issue Sentry. Variables : {variables}.`,"settings.sentryInitialPrompt.project":`Prompt initial Sentry (override)`,"settings.initialPrompt.inheritHint":`Laisser vide pour hériter. Saisir un caractère d'espacement pour désactiver l'injection à ce niveau.`,"settings.resetToDefault":`Réinitialiser`,"settings.resetFailed":`Échec du chargement de la valeur par défaut`,"settings.sentryIntegration":`Intégration Sentry`,"settings.var.prNumber":`Numéro de PR (ex : 42)`,"settings.var.prUrl":`URL complète de la PR créée`,"settings.var.branchName":`Nom de la branche de travail`,"settings.var.sourceBranch":`Branche source ciblée par la PR`,"settings.var.workspaceName":`Nom du workspace`,"settings.var.projectName":`Dernier segment du chemin du projet`,"settings.var.notionUrl":`URL Notion si définie, vide sinon`,"settings.var.commits":`Liste à puces des commits entre source et head`,"settings.var.diffStats":`Résumé shortstat Git (fichiers, insertions, suppressions)`,"settings.var.tasks":`Tâches classiques en liste à cocher`,"settings.var.acceptanceCriteria":`Critères d'acceptation en liste à cocher`,"settings.gitConventions":`Conventions Git (global)`,"settings.gitConventionsPlaceholder":`# Conventions Git...`,"settings.gitConventionsHint":`Ces conventions sont écrites dans .ai/.git-conventions.md pour chaque nouvel espace de travail et doivent être respectées par l'agent avant toute opération Git. Remplacées par les conventions par projet si définies.`,"settings.setupScript":`Script de setup`,"settings.cleanupScript":`Script de cleanup`,"settings.archiveScript":`Script d'archivage`,"settings.archiveScriptHint":`Script shell exécuté côté serveur dans le worktree quand un workspace est archivé. Laisser vide pour désactiver.`,"settings.archiveScriptPlaceholder":`ex. nettoyer des conteneurs, libérer de l'espace disque…`,"settings.changeSourceBranchScript":`Script de changement de branche source`,"settings.changeSourceBranchScript.help":`Remplace le cherry-pick intégré quand non vide. Le script possède git, base de PR, force-push et conflits ; Kōbō refuse seulement si l'agent tourne et met à jour la métadonnée source à exit 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nouvelle branche source choisie dans le dialogue
51
51
  KOBO_OLD_BASE — précédente branche source du workspace
52
52
  KOBO_WORKING_BRANCH — branche de travail du workspace
53
53
  KOBO_WORKTREE_PATH — chemin absolu du worktree (et cwd)
@@ -63,7 +63,7 @@ KOBO_PR_NUMBER — numéro de PR/MR sur la forge résolue (vide si aucune o
63
63
  # Ou directement via git (fonctionne sur GitHub même après suppression de la branche) :
64
64
  git fetch origin pull/[numéro-pr]/head:[nom-branche]
65
65
  git worktree add [chemin] [nom-branche]`,"settings.purgeDocsRestoreFootnote":`GitHub conserve la ref HEAD de la PR bien après la suppression de la branche source (mois / années). L'auto-détection tourne dans le watcher 30s — pas besoin d'action dans l'UI une fois le dossier recréé.`,"settings.purgeDocsPermissionsTitle":`Éviter les erreurs de permissions pendant la suppression`,"settings.purgeDocsPermissionsIntro":`Docker laisse souvent des fichiers root-owned dans node_modules / vendor à l'intérieur du worktree. Quand Kōbō essaie de les supprimer, tu tombes sur EACCES / EPERM et la purge échoue. Deux moyens de prévenir :`,"settings.purgeDocsPermissionsDocker":'Configurer ton conteneur pour qu\'il tourne sous ton utilisateur hôte — directive USER dans le Dockerfile, ou `user: "${UID}:${GID}"` dans docker-compose (avec UID/GID exportés dans ton shell).',"settings.purgeDocsPermissionsAcl":`Pré-définir un ACL par défaut sur la racine des worktrees — filet de sécurité qui marche dans la PLUPART des cas (ext4/btrfs/xfs + bind mount Docker classique). Chaque nouveau fichier hérite alors d'une entrée d'accès pour ton user, en plus du propriétaire nominal :`,"settings.purgeDocsPermissionsAclCommand":` setfacl -d -m u:$(whoami):rwX [racine-worktrees]`,"settings.purgeDocsPermissionsFootnote":"Limites des ACL : ne marchent PAS sur les volumes Docker nommés (utilise un bind mount), filesystems sans support ACL (NTFS, exFAT, tmpfs), SELinux strict avec `:Z`, ou `userns-remap` Docker activé. La solution la plus fiable reste de configurer le user dans le conteneur (option 1). Astuce : `rwX` (X majuscule) n'ajoute le bit exécutable qu'aux dossiers et fichiers déjà exécutables — plus propre que `rwx` qui rendrait exécutables tous les fichiers texte.","settings.purgeDocsPermissionsRecoverTitle":`Débloquer un worktree déjà cassé (fichiers root-owned existants)`,"settings.purgeDocsPermissionsRecoverIntro":`Si tu te retrouves avec un worktree déjà rempli de fichiers root-owned (Docker a déjà tourné, vendor / node_modules sont coincés), les ACL préventives ci-dessus ne suffisent pas — il faut traiter les fichiers EXISTANTS. Deux approches, à exécuter dans le dossier du worktree :`,"settings.purgeDocsPermissionsRecoverAclIntro":`Option A — ACL récursive (préserve l'ownership root pour audit, t'ajoute juste un accès en parallèle) :`,"settings.purgeDocsPermissionsRecoverAclCommand":`# pose l'ACL par défaut pour les futurs fichiers ET donne accès à tout l'existant
66
- sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Reprendre la propriété (plus simple, perd l'info "créé par root dans le conteneur" mais osef en pratique) :`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Astuce : tu peux exécuter ces commandes directement sur la racine de tes worktrees (ex. `~/.worktrees/`) pour couvrir tous les workspaces existants ET futurs d'un seul coup. Une fois fait, la purge Kōbō fonctionnera sans erreur de permission.","contextMenu.runSetup":`Lancer le script de setup`,"contextMenu.exportEvents":`Exporter les events (CSV)`,"contextMenu.dismissChangesRequested":`Marquer « Modifications demandées » comme vu`,"contextMenu.dismissCiFailure":`Marquer « CI en échec » comme vu`,"contextMenu.restoreChangesRequested":`Marquer « Modifications demandées » comme non vu`,"contextMenu.restoreCiFailure":`Marquer « CI en échec » comme non vu`,"contextMenu.exportingEvents":`Préparation de l'export…`,"contextMenu.exportEventsError":`Échec de l'export des events`,"contextMenu.openNotion":`Ouvrir dans Notion`,"contextMenu.openSentry":`Ouvrir dans Sentry`,"contextMenu.openPr":`Ouvrir la PR`,"workspace.favorite":`Ajouter aux favoris`,"workspace.unfavorite":`Retirer des favoris`,"workspace.showFavoritesOnly":`Afficher uniquement les favoris`,"workspace.searchArchivedToggle":`Inclure les workspaces archivés dans la recherche`,"workspace.descriptionPlaceholder":`Ajouter une courte description`,"workspace.descriptionDialogHint":`Texte brut, 200 caractères maximum. Laisser vide pour effacer.`,"workspace.descriptionTooLong":`La description doit faire 200 caractères ou moins.`,"workspace.descriptionSaveFailed":`Échec de l'enregistrement de la description.`,"workspace.agentDescriptionTooltip":`État en direct maintenu par l'agent`,"mcp.tool.setWorkspaceDescription":`Définit la courte description du workspace (≤ 200 caractères).`,"tags.manage":`Gérer les tags`,"tags.manageTitle":`Gérer les tags du workspace`,"tags.noTagsDefined":`Aucun tag défini. Ajoutes-en dans Paramètres > Global > Tags.`,"tags.orphanedHint":`{count} tag(s) ne sont plus dans le catalogue global. Décoche-les pour les retirer.`,"settings.tagsTitle":`Tags des workspaces`,"settings.tagsHint":`Définis les tags assignables aux workspaces. Tape pour ajouter, clique la croix pour retirer.`,"settings.tagsLabel":`Tags disponibles`,"settings.branchPrefixesTitle":`Préfixes de branche`,"settings.branchPrefixesHint":`Gérez les préfixes de branche Git disponibles sur la page de création. Le premier est présélectionné par défaut.`,"settings.branchPrefixesEmpty":`Aucun préfixe de branche défini. Ajoutez-en au moins un ci-dessous.`,"settings.branchPrefixesAddLabel":`Nouveau préfixe`,"settings.branchPrefixesEditHint":`Cliquer pour renommer`,"settings.branchPrefixesMoveUp":`Monter`,"settings.branchPrefixesMoveDown":`Descendre`,"settings.worktreesTitle":`Worktrees Git`,"settings.worktreesHint":`Choisis où créer les worktrees des nouveaux workspaces. Les chemins relatifs sont résolus depuis le projet ; les chemins absolus Linux/macOS et Windows, $HOME, ~ et %USERPROFILE% sont supportés.`,"settings.worktreesPathLabel":`Chemin des worktrees`,"settings.worktreesPathRequired":`Le chemin des worktrees est requis.`,"settings.worktreesPrefixByProject":`Préfixer les worktrees par le nom du projet`,"settings.worktreesPrefixByProjectHint":`Place chaque worktree dans un sous-dossier nommé d'après le projet, pour éviter les collisions quand plusieurs projets partagent la même racine.`,"settings.shareTitle":`Partager la configuration`,"settings.shareHint":`Exporte tes paramètres, templates et tags en bundle JSON. Les clés MCP sont retirées à l’export pour la sécurité.`,"settings.exportConfig":`Exporter`,"settings.importConfig":`Importer`,"settings.exportSuccess":`Configuration exportée`,"settings.importSuccess":`Configuration importée`,"settings.importConfirmTitle":`Importer la configuration`,"settings.importConfirmMessage":`Cela remplacera tes paramètres, templates et tags actuels. Tes clés MCP seront conservées. Continuer ?`,"health.title":`Santé`,"health.tooltip":`Santé du système`,"changelog.title":`Journal des changements`,"changelog.tooltip":`Quoi de neuf dans Kōbō`,"changelog.empty":`Aucun changelog disponible.`,"changelog.current":`actuelle`,"changelog.currentVersion":`Version actuelle : v{version}`,"health.envTitle":`Environnement`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Base de données`,"health.dbPath":`Chemin`,"health.dbSize":`Taille`,"health.schemaVersion":`Version du schéma`,"health.settingsSchemaVersion":`Schéma settings`,"health.runtimesTitle":`Moteurs d'agent`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude introuvable dans le PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binaire codex introuvable`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} au total, {archived} archivés`,"health.worktreesMissing":`{count} worktree(s) manquant(s) sur le disque`,"health.sessionsTitle":`Sessions agent`,"health.sessionsOrphaned":`{n} session(s) orpheline(s) marquées running`,"health.integrationsTitle":`Intégrations`,"health.integrationConfigured":`configurée`,"health.integrationMissing":`non configurée`,"health.activeTitle":`État actif`,"health.activeQuotaBackoffs":`Quota backoffs en attente`,"health.activeWakeups":`Wakeups programmés`,"health.activeAutoLoop":`Auto-loop en cours`,"health.activeAgentSessions":`Sessions agent en cours`,"health.activeDevServers":`Serveurs de dev lancés`,"health.noneActive":`Aucun.`,"health.quotaResumeAt":`reprise à {time}`,"health.wakeupAt":`réveil à {time}`,"health.startedAgo":`démarré il y a {time}`,"health.autoLoopReady":`prêt, itération en cours`,"health.autoLoopGrooming":`grooming en cours`,"session.started":`Session démarrée`,"session.ended":`Session terminée`,"session.compacted":`Contexte compacté`,"tool.running":`En cours...`,"activity.raw_lines":`Lignes de sortie brutes ({n})`,"activity.loading_older":`Chargement des messages plus anciens…`,"activity.compacting":`Compaction du contexte…`,"activity.prev_user_message":`Message utilisateur précédent`,"activity.scroll_to_bottom":`Défiler vers le bas`,"chat.systemPrompt":`Prompt système`,"chat.agent":`Agent`,"chat.cleanupScript":`Script de cleanup`,"chat.archiveScript":`Script d'archivage`,"chat.setupScript":`Script de setup`,"chat.scriptDone":`Fait`,"chat.you":`Vous`,"chat.session":`Session`,"chat.nActions":`{n} action | {n} actions`,"chat.lastUpdatedAt":`Dernière mise à jour à {time}`,"chat.scrollToTurnTop":`Défiler vers le haut du message`,"migration.backing_up":`Sauvegarde de la base de données…`,"migration.running":`Migration des données d'agent — {processed}/{total}`,"migration.error":`Échec de la migration`,"migration.backup_location":`Une sauvegarde a été enregistrée à {path}. Redémarre Kōbō pour réessayer.`,"migration.retry":`Redémarre Kōbō pour réessayer.`,"engine.select":`Moteur`,"engine.model":`Modèle`,"engine.effort":`Effort de réflexion`,"wakeup.scheduledIn":`Prochain réveil dans {n}s`,"wakeup.scheduledAt":`Prochain réveil à {time}`,"wakeup.firing":`Réveil en cours…`,"wakeup.reason":`Raison : {reason}`,"wakeup.cancel":`Annuler ce réveil`,"wakeup.pendingIndicator":`Réveil programmé`,"cron.pendingIndicator":`{n} cron(s) programmé(s)`,"schedule.tabLabel":`Programmation`,"schedule.wakeupTitle":`Wakeup en attente`,"schedule.cronsTitle":`Tâches récurrentes`,"schedule.noWakeup":`Aucun wakeup programmé`,"schedule.noCrons":`Aucun cron programmé`,"schedule.nextFireAt":`prochain à {time}`,"schedule.lastFiredAt":`dernier fire il y a {time}`,"askUserQuestion.title":`L'agent te pose une question`,"askUserQuestion.submit":`Envoyer la réponse`,"askUserQuestion.multiSelectHint":`Sélectionne une ou plusieurs options`,"askUserQuestion.otherOption":`Autre`,"askUserQuestion.otherOptionHint":`précisez dans votre prochain message`,"askUserQuestion.noPending":`Aucune question en attente`,"askUserQuestion.next":`Suivant`,"askUserQuestion.previous":`Précédent`,"askUserQuestion.cancel":`Annuler`,"askUserQuestion.cancelTooltip":`Sauter cette question — l'agent continuera sans réponse`,"askUserQuestion.collapse":`Réduire le panneau de question`,"askUserQuestion.expand":`Agrandir le panneau de question`,"permissionRequest.title":`L'agent veut utiliser un outil`,"permissionRequest.allow":`Autoriser`,"permissionRequest.deny":`Refuser`,"permissionRequest.tool":`Outil`,"permissionRequest.input":`Entrée`,"permissionRequest.denied":`refusé par l'utilisateur`,"workspaceStatus.awaitingUser":`en attente de ta réponse`,"workspaceList.prOpen":`#{n} — Pull request ouverte`,"workspaceList.prChangesRequested":`#{n} — Modifications demandées`,"workspaceList.attentionCiFailed":`CI en échec`,"workspaceList.attentionChangesRequested":`Modifications demandées`,"workspaceList.attentionReadyToMerge":`Prêt à merger`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Démarrer l'auto-loop`,"autoLoop.prepare":`Préparer pour auto-loop`,"autoLoop.reprepare":`Re-préparer pour auto-loop`,"autoLoop.reprepareTooltip":`Relancer la phase de grooming pour ajouter ou rafraîchir les tâches avant de relancer la boucle`,"autoLoop.prepareBusy":`Attendre la fin de l'agent avant de préparer`,"autoLoop.forceReady":`Je sais ce que je fais — passer le grooming`,"autoLoop.forceReadyConfirm":`Passer le grooming et marquer auto-loop prêt ? La boucle peut stagner si les tâches ne sont pas atomiques.`,"autoLoop.stop":`Arrêter l'auto-loop`,"autoLoop.notReady":`Lancer d'abord « Préparer pour auto-loop »`,"autoLoop.noTasks":`Ajouter d'abord des tâches`,"autoLoop.progress":`Auto-loop · {done}/{total} tâches`,"autoLoop.preparing":`Auto-loop · préparation`,"autoLoop.preparingTooltip":`Grooming en cours — l'agent crée / révise les tâches. La boucle démarrera quand il appellera mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop en cours`,"autoLoop.startInMode":`Démarrer en mode auto-loop`,"koboCommand.prepAutoloopDesc":`Préparer les tâches pour le mode auto-loop (atomicité)`,"staleSessionBanner.title":`Auto-loop en cours`,"staleSessionBanner.message":`Vous consultez une ancienne session — l'agent travaille actuellement dans la dernière.`,"staleSessionBanner.switchToCurrent":`Basculer sur la session active`},ln={"common.save":`Salva`,"common.cancel":`Annulla`,"common.delete":`Elimina`,"common.close":`Chiudi`,"common.details":`Dettagli`,"whatsNew.title":`Novità`,"common.loading":`Caricamento...`,"common.search":`Cerca...`,"common.refresh":`Aggiorna`,"common.copy":`Copia`,"common.copied":`Copiato negli appunti`,"common.copyFailed":`Copia non riuscita`,"common.add":`Aggiungi`,"folderPicker.title":`Scegli una cartella`,"folderPicker.parent":`Cartella superiore`,"folderPicker.empty":`Nessuna sottocartella`,"folderPicker.select":`Scegli questa cartella`,"common.start":`Avvia`,"common.stop":`Arresta`,"common.archive":`Archivia`,"common.unarchive":`Ripristina`,"common.selectWorkspace":`Seleziona un workspace`,"common.noResults":`Nessun risultato per "{query}"`,"common.send":`invia`,"common.newLine":`nuova riga`,"common.history":`cronologia`,"common.justNow":`adesso`,"common.minutesAgo":`{count}m fa`,"common.hoursAgo":`{count}h fa`,"common.daysAgo":`{count}g fa`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Modello più capace — successore di Opus 4.8, contesto 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 senza classificatori di sicurezza — accesso limitato (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude sceglie il modello ottimale`,"model.opus48Description":`Opus più capace — coding agentico long-horizon, contesto 1M di default, effort high di default`,"model.opus47ClassicDescription":`Ultimo Opus, il più capace`,"model.opus471mDescription":`Ultimo Opus, contesto 1M`,"model.opusClassicDescription":`Più potente`,"model.opus1mDescription":`Più potente, contesto 1M`,"model.sonnetClassicDescription":`Bilanciato`,"model.sonnet1mDescription":`Bilanciato, contesto 1M`,"model.haikuDescription":`Più veloce`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Consigliato per codice complesso (richiede autenticazione ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Ripiego predefinito — ragionamento solido, compatibile con chiave API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Veloce ed efficiente — ideale per attività reattive e subagenti`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modello specializzato in codice per ingegneria software complessa`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Lascia decidere al motore`,"reasoning.minimalDescription":`Ragionamento più veloce e superficiale`,"reasoning.lowDescription":`Più veloce, meno profondità`,"reasoning.mediumDescription":`Bilanciato`,"reasoning.highDescription":`Più profondità`,"reasoning.xhighDescription":`Profondità estesa, attività lunghe`,"reasoning.maxDescription":`Profondità massima`,"agentPermissionMode.label":`Modalità permessi`,"agentPermissionMode.plan":`Piano`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Accetta edit`,"agentPermissionMode.interactive":`Interattivo`,"agentPermissionMode.tooltip":`Come l'agente gestisce i permessi degli strumenti. Piano: sola lettura, nessuna scrittura. Bypass: salta tutte le richieste. Stretto: auto-accetta le edit dei file, rispetta le allow/deny per il resto. Interattivo: chiedi all'utente prima di ogni strumento tramite il pannello dei permessi.`,"agentPermissionMode.autoLoopOverride":`L'auto-loop forza una modalità diversa da Piano — Piano blocca gli strumenti MCP e le edit di cui il loop ha bisogno. Scegli Bypass, Stretto o Interattivo.`,"agentPermissionMode.autoLoopLocked":`Bloccato su Bypass finché l'auto-loop è attivo — qualsiasi altra modalità fermerebbe il loop sulle richieste di permesso. AskUserQuestion funziona comunque.`,"workspaceList.title":`Workspace`,"workspaceList.needsAttention":`Richiede attenzione`,"workspaceList.running":`In esecuzione`,"workspaceList.idle":`Inattivo`,"workspaceList.archived":`Archiviati`,"workspaceList.noWorkspaces":`Nessun workspace ancora`,"workspaceList.footer":`{count} workspace | {count} workspace`,"workspaceList.footerRunning":`{count} in esecuzione`,"workspaceList.deleteDialog.title":`Eliminare il workspace?`,"workspaceList.deleteDialog.deleteLocal":`Elimina branch locale`,"workspaceList.deleteDialog.deleteRemote":`Elimina branch remoto`,"workspaceList.deleteDialog.warning":`Attenzione: questa azione è irreversibile sul remoto.`,"workspaceList.deleteArchivedDialog.tooltip":`Elimina tutti i workspace archiviati`,"workspaceList.deleteArchivedDialog.title":`Eliminare tutti i workspace archiviati?`,"workspaceList.deleteArchivedDialog.message":`Questa operazione eliminerà definitivamente i {count} workspace archiviati. L'azione è irreversibile.`,"workspacePage.selectWorkspace":`Seleziona un workspace per iniziare`,"workspacePage.session":`Sessione #{n}`,"workspacePage.newSession":`+ Nuova sessione`,"workspacePage.renameSession":`Rinomina`,"workspacePage.renameSessionTitle":`Rinomina sessione`,"workspacePage.sessionNameLabel":`Nome sessione`,"workspacePage.sessionEndedNotice":`Questa sessione è terminata. Crea una nuova sessione per continuare.`,"workspacePage.renameFailed":`Rinomina fallita`,"workspacePage.createSessionFailed":`Creazione sessione fallita`,"workspacePage.startFailed":`Avvio fallito`,"workspacePage.stopFailed":`Arresto fallito`,"workspacePage.interrupt":`Interrompi`,"workspacePage.interrupted":`Agente interrotto — in attesa del tuo prossimo messaggio`,"workspacePage.archivedBanner":`Workspace archiviato — sola lettura`,"workspacePage.worktreePurgedBanner":`Worktree eliminato — cronologia conservata, ripristino non disponibile in questa versione`,"workspacePage.worktreePurgedTooltip":"La cartella del worktree è stata eliminata dal disco per recuperare spazio. Cronologia di chat, sessioni e metadati della PR restano consultabili qui, ma la directory di lavoro non esiste più localmente. Una versione futura di Kōbō ricostruirà il worktree dalla PR mergiata — per ora ricrealo manualmente con `gh pr checkout` o `git worktree add`.","workspacePage.pendingInitialPromptBanner":`C'è un prompt iniziale in attesa — l'agente non l'ha mai ricevuto (lo script di setup è crashato o il workspace non è mai stato avviato). Clicca Avvia per inviarlo ora.`,"workspacePage.unarchived":`Workspace ripristinato`,"workspacePage.unarchiveFailed":`Ripristino fallito`,"workspacePage.interruptFailed":`Interruzione fallita`,"workspacePage.interruptTooltip":`Interruzione leggera (come Escape) — ferma lo strumento corrente ma mantiene la sessione attiva`,"workspacePage.pendingNextRun":`Applicato al prossimo avvio`,"search.title":`Ricerca`,"search.tooltip":`Cerca nella cronologia degli agenti`,"search.placeholder":`Cerca in tutti i messaggi degli agenti…`,"search.includeArchived":`Includi workspace archiviati`,"search.loading":`Ricerca in corso…`,"search.noResults":`Nessun risultato`,"search.error":`Ricerca fallita: {message}`,"search.resultCount":`{n} risultato/i`,"search.eventType.userMessage":`Tu`,"search.eventType.agentOutput":`Agente`,"activityFeed.empty":`Nessuna attività ancora`,"activityFeed.emptyHint":`Avvia un workspace per vedere l'output dell'agente qui`,"activityFeed.initialPrompt":`Prompt iniziale`,"activityFeed.you":`Tu`,"activityFeed.agent":`Agente`,"activityFeed.question":`Domanda`,"activityFeed.goToPrevious":`Vai al messaggio precedente`,"activityFeed.scrollToBottom":`Vai in fondo`,"activityFeed.sendAnswers":`Invia risposte`,"agentBusy.banner":`L'agente è occupato`,"agentBusy.subagentsRunning":`1 sub-agente in esecuzione | {n} sub-agenti in esecuzione`,"agentBusy.viewSubagents":`Vedi sub-agenti`,"agentBusy.pendingMessage":`In attesa — l'agente è occupato`,"terminal.title":`Terminale`,"terminal.open":`Apri terminale`,"terminal.close":`Chiudi terminale`,"terminal.noWorkspace":`Seleziona un workspace`,"terminal.noWorktree":`Worktree non ancora creato`,"terminal.error":`Errore del terminale`,"terminal.exited":`Terminale chiuso`,"chatInput.placeholder":`Messaggio... (/ per le skill)`,"chatInput.fileSearchHint":`cercare un file`,"chatInput.skills":`Skill`,"chatInput.attachImage":`Allega immagine`,"chatInput.queueBanner":`Messaggio in coda — verrà inviato quando l'agente avrà terminato`,"chatInput.cancelQueue":`Annulla coda`,"chatInput.autoLoopBanner":`Auto-loop attivo — fermalo per inviare un messaggio`,"chatInput.awaitingUserBanner":`L'agente attende la tua risposta sopra — rispondi tramite il pannello della domanda`,"chatInput.autoLoopStop":`Ferma`,"koboCommand.checkProgressDesc":`Verificare il progresso delle attività e dei criteri di accettazione`,"chatInput.uploading":`Caricamento...`,"voice.title":`Trascrizione vocale`,"voice.enabled":`Abilita trascrizione vocale locale`,"voice.pttKey":`Tasto push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Spazio`,"voice.language":`Lingua (auto o codice)`,"voice.model":`Modello attivo`,"voice.commandPath":`Percorso binario Whisper (opzionale)`,"voice.ffmpegPath":`Percorso binario ffmpeg (opzionale)`,"voice.temperature":`Temperatura`,"voice.temperatureHint":`Più basso = più deterministico; più alto = più flessibile ma potenzialmente meno stabile.`,"voice.initialPrompt":`Prompt iniziale (opzionale)`,"voice.initialPromptHint":`Contesto opzionale per aiutare Whisper con nomi propri, sigle o vocabolario tecnico.`,"voice.translateToEnglish":`Traduci in inglese`,"voice.translateToEnglishHint":`Se attivo, il parlato non inglese viene tradotto in inglese invece di essere trascritto così com’è.`,"voice.suppressNst":`Sopprimi token non vocali`,"voice.suppressNstHint":`Prova a ridurre artefatti non vocali nella trascrizione.`,"voice.installLink":`Installa whisper.cpp`,"voice.installGuideTitle":`Guida installazione`,"voice.installGuideIntro":`Installa whisper.cpp e ffmpeg, poi imposta i percorsi dei binari qui sotto se necessario.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Dopo il build con CMake, il binario Whisper di solito è in: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Poi imposta “Percorso binario Whisper” e “Percorso binario ffmpeg” in questa sezione (o lascia vuoto se sono nel PATH).`,"voice.noneModel":`Nessun modello attivo`,"voice.notInstalled":`non installato`,"voice.download":`Scarica`,"voice.delete":`Elimina`,"voice.holdToTalk":`Tieni premuto per parlare`,"voice.recording":`Registrazione...`,"voice.transcribing":`Trascrizione...`,"voice.notSupported":`La registrazione vocale non è supportata da questo browser`,"voice.errorMicPermission":`Permesso microfono negato`,"voice.errorTranscription":`Trascrizione vocale non riuscita`,"voice.downloadFailed":`Download del modello non riuscito`,"voice.deleteFailed":`Eliminazione del modello non riuscita`,"voice.errorDisabled":`La trascrizione vocale è disattivata nelle impostazioni`,"voice.errorModelMissing":`Nessun modello vocale attivo configurato`,"voice.errorModelNotInstalled":`Il modello vocale attivo non è installato`,"voice.errorAudioInvalid":`La cattura audio è non valida o vuota`,"voice.errorLanguageInvalid":`La configurazione lingua vocale non è valida`,"voice.errorRuntimeMissing":`Il runtime Whisper non è installato o non è nel PATH`,"voice.maxDurationReached":`Durata massima di registrazione raggiunta`,"voice.runtimeReady":`Runtime pronto: {command}`,"voice.runtimeMissing":`Runtime mancante: {command}`,"voice.ffmpegReady":`ffmpeg pronto`,"voice.ffmpegMissing":`ffmpeg mancante`,"voice.sectionRuntime":`Stato del runtime`,"voice.sectionActivation":`Attivazione`,"voice.sectionModels":`Modelli Whisper`,"voice.sectionAdvanced":`Opzioni avanzate`,"voice.sectionBehavior":`Comportamento della trascrizione`,"voice.sectionBinaries":`Percorsi dei binari`,"voice.downloadModels":`Scarica un modello`,"voice.cancelFailed":`Annullamento del download non riuscito`,"createPage.title":`Su cosa vorresti lavorare?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion attivato`,"createPage.importNotion":`Importa da Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`L'URL deve iniziare con https://www.notion.so/ o https://app.notion.com/`,"createPage.notionAutoExtract":`Le sottotask e i criteri di accettazione verranno estratti automaticamente.`,"createPage.notionPanelChoiceLabel":`Questo URL punta a una sotto-pagina (?p=). Su quale vuoi lavorare?`,"createPage.notionPanelOption":`Sotto-pagina (panel)`,"createPage.notionPanelOptionDesc":`La pagina che stavi visualizzando — consigliato`,"createPage.notionParentOption":`Pagina principale`,"createPage.notionParentOptionDesc":`L'epic / database a cui appartiene`,"createPage.importSentry":`Importa Sentry`,"createPage.sentryEnabled":`Sentry attivato`,"createPage.sentryPlaceholder":`https://tua-org.sentry.io/issues/123456`,"createPage.sentryValidation":`L'URL deve puntare a una issue di Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`L'issue di Sentry verrà importata automaticamente`,"createPage.sentryExtractHint":`Kobo estrarrà l'issue e la scriverà in .ai/thoughts/`,"createPage.workspaceName":`Nome del workspace (predefinito: titolo della pagina Notion)`,"createPage.workspaceNamePlaceholder":`Nome del workspace...`,"createPage.instructions":`Istruzioni aggiuntive (opzionale)...`,"createPage.instructionsPlaceholder":`Descrivi il task...`,"createPage.manualHint":`Nessun ticket Notion? Aggiungi i tuoi task e criteri di accettazione manualmente — verranno inviati all'agente Claude come contesto.`,"createPage.tasks":`Task ({count})`,"createPage.addTask":`Aggiungi un task...`,"createPage.acceptanceCriteria":`Criteri di accettazione ({count})`,"createPage.addCriterion":`Aggiungi un criterio...`,"createPage.projectPath":`Inserisci il percorso del progetto`,"createPage.branchType":`Tipo di branch`,"createPage.branch":`Branch`,"createPage.noBranches":`Nessun branch trovato`,"createPage.enterPath":`Inserisci il percorso del progetto`,"createPage.create":`Crea`,"createPage.skipSetupScript":`Salta script di setup`,"createPage.attachWorktreeToggle":`Aggancia worktree esistente`,"createPage.attachWorktreeEnabled":`Riutilizzo worktree esistente`,"createPage.worktreePickerLabel":`Worktree esistente`,"createPage.noOrphanWorktrees":`Nessun worktree orfano in questo progetto`,"createPage.pickWorktreeRequired":`Seleziona un worktree da agganciare`,"createPage.notionExtractHint":`Le sottotask e i criteri di accettazione verranno estratti dalla pagina Notion.`,"createPage.notionImportHint":`Clicca su "Importa da Notion" per estrarre automaticamente le sottotask da un ticket.`,"createPage.errorCreating":`Errore durante la creazione del workspace.`,"createPage.branchAdjusted":"Il branch esisteva già — creato `{branch}` al suo posto. La cartella worktree corrispondente usa lo stesso suffisso.","createPage.validationNotionUrl":`Inserisci un URL Notion valido (https://www.notion.so/... o https://app.notion.com/...).`,"createPage.validationDescription":`Descrivi il task.`,"createPage.validationName":`Indica un nome per il workspace.`,"createPage.validationPath":`Inserisci il percorso del progetto.`,"createPage.validationBranch":`Seleziona un branch.`,"settings.title":`Impostazioni`,"settings.language":`Lingua`,"settings.projectColor":`Colore`,"settings.projectColorClear":`Cancella`,"settings.projectColorDefault":`Predefinito (grigio)`,"settings.workspaceListSection":`Lista dei workspace`,"settings.flattenWorkspaceList":`Lista piatta dei workspace`,"settings.flattenWorkspaceListHint":`Mostra tutti i workspace in una lista piatta con un badge progetto, invece di raggrupparli per progetto.`,"settings.skillSuite.section":`Suite di skill`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personalizzato`,"settings.skillSuite.superpowersHint":`Workflow opinionato TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite di Garry Tan — /review, /ship, /qa, /office-hours, ecc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Le due suite si combinano — superpowers per la metodologia (brainstorm / TDD / piani / review a livello di principi), gstack per i flussi concreti (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Modifica i quattro prompt qui sotto tu stesso. Parte dalla base agnostica.`,"settings.skillSuite.reloadDefaults":`Ripristina predefiniti`,"settings.skillSuite.reloadDefaultsConfirm":`Sostituire i quattro prompt personalizzati con i valori agnostici predefiniti?`,"settings.skillSuite.customPrompts":`Prompt personalizzati`,"settings.skillSuite.reviewTemplate":`Template di review`,"settings.skillSuite.autoLoopReviewGate":`Gate di review auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro di grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Istruzione fase di brainstorming`,"settings.global":`Globale`,"settings.projects":`Progetti`,"settings.globalSettings":`Impostazioni globali`,"settings.defaultModel":`Modello predefinito`,"settings.defaultModelClaude":`Modello predefinito (Claude Code)`,"settings.defaultModelCodex":`Modello predefinito (OpenAI Codex)`,"settings.agentPermissions":`Permessi dell'agente`,"settings.skipPermissions":`Salta le richieste di permesso (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Attenzione: disattivando questa opzione, tutti i permessi degli strumenti (Write, Edit, Bash...) verranno negati automaticamente in modalità headless. L'agente potrà solo leggere.`,"settings.notifications":`Notifiche`,"settings.browserNotifications":`Notifica browser quando l'agente termina`,"settings.audioNotifications":`Notifica sonora quando l'agente termina`,"settings.notificationSound":`Suono di notifica`,"settings.notificationSoundPreview":`Ascolta`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Lavoro finito`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Sta per esplodere`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Modalità permessi predefinita`,"settings.defaultPermissionModeClaude":`Modalità permessi predefinita (Claude Code)`,"settings.defaultPermissionModeCodex":`Modalità permessi predefinita (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Modalità applicata alla creazione di un workspace. Piano = sola lettura, Bypass = senza richieste, Stretto = auto-accetta le edit con allow-list, Interattivo = chiedi prima di ogni strumento.`,"settings.activityFeed":`Feed attività`,"settings.verboseMessages":`Mostra messaggi di sistema dettagliati (task_progress, task_started)`,"settings.availableVariables":`Variabili disponibili nei template del prompt`,"settings.prPromptTemplate":`Template del prompt PR`,"settings.prPromptPlaceholder":`Istruzioni per l'agente durante la creazione di PR su GitHub...`,"settings.prPromptHint":`Usa le variabili elencate sopra (sintassi doppia parentesi graffa).`,"settings.reviewPromptTemplate":`Template del prompt di revisione`,"settings.reviewPromptPlaceholder":`Istruzioni per l'agente durante la revisione delle modifiche del branch...`,"settings.ciFixPromptTemplate":`Template del prompt «Ripara CI»`,"settings.ciFixPromptHint":`Inviato all'agente quando un workspace ha la CI in errore. Variabili (sintassi doppie graffe): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Chiedi all'agente di diagnosticare e correggere i job di CI in errore...`,"settings.finalizationPromptTemplate":`Prompt di finalizzazione dell'auto-loop`,"settings.finalizationPromptHint":`Prompt predefinito per l'ultima iterazione dell'auto-loop (controlli di qualità finali). Usato quando un progetto lascia vuoto il proprio prompt di finalizzazione.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt iniziale Notion`,"settings.notionInitialPrompt.help":`Aggiunto al prompt di creazione del workspace quando il workspace ha un ticket Notion. Variabili: {variables}.`,"settings.notionInitialPrompt.project":`Prompt iniziale Notion (override)`,"settings.sentryInitialPrompt":`Prompt iniziale Sentry`,"settings.sentryInitialPrompt.help":`Aggiunto al prompt di creazione del workspace quando il workspace ha una issue Sentry. Variabili: {variables}.`,"settings.sentryInitialPrompt.project":`Prompt iniziale Sentry (override)`,"settings.initialPrompt.inheritHint":`Lasciare vuoto per ereditare. Digita un carattere di spazio bianco per disattivare l'iniezione a questo livello.`,"settings.resetToDefault":`Ripristina`,"settings.resetFailed":`Impossibile caricare il valore predefinito`,"settings.sentryIntegration":`Integrazione Sentry`,"settings.var.prNumber":`Numero della PR (es: 42)`,"settings.var.prUrl":`URL completo della PR creata`,"settings.var.branchName":`Nome del branch di lavoro`,"settings.var.sourceBranch":`Branch sorgente a cui punta la PR`,"settings.var.workspaceName":`Nome del workspace`,"settings.var.projectName":`Ultimo segmento del percorso del progetto`,"settings.var.notionUrl":`URL Notion se impostato, vuoto altrimenti`,"settings.var.commits":`Elenco puntato dei commit tra source e head`,"settings.var.diffStats":`Riepilogo shortstat Git (file, inserimenti, eliminazioni)`,"settings.var.tasks":`Attività regolari come lista di controllo`,"settings.var.acceptanceCriteria":`Criteri di accettazione come lista di controllo`,"settings.gitConventions":`Convenzioni Git (globale)`,"settings.gitConventionsPlaceholder":`# Convenzioni Git...`,"settings.gitConventionsHint":`Queste convenzioni vengono scritte in .ai/.git-conventions.md in ogni nuovo workspace e devono essere seguite dall'agente prima di qualsiasi operazione Git. Sovrascritte dalle convenzioni per progetto se definite.`,"settings.setupScript":`Script di setup`,"settings.cleanupScript":`Script di pulizia`,"settings.archiveScript":`Script di archiviazione`,"settings.archiveScriptHint":`Script di shell eseguito lato server nel worktree quando un workspace viene archiviato. Lascia vuoto per disattivare.`,"settings.archiveScriptPlaceholder":`es. pulire container, liberare spazio su disco…`,"settings.changeSourceBranchScript":`Script di cambio del branch di origine`,"settings.changeSourceBranchScript.help":`Sostituisce il cherry-pick integrato quando non vuoto. Lo script gestisce git, base della PR, force-push e conflitti; Kōbō rifiuta solo se l'agente è in esecuzione e aggiorna i metadati del branch di origine all'uscita 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nuovo branch di origine scelto nella finestra di dialogo
66
+ sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Option B — Reprendre la propriété (plus simple, perd l'info "créé par root dans le conteneur" mais osef en pratique) :`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Astuce : tu peux exécuter ces commandes directement sur la racine de tes worktrees (ex. `~/.worktrees/`) pour couvrir tous les workspaces existants ET futurs d'un seul coup. Une fois fait, la purge Kōbō fonctionnera sans erreur de permission.","contextMenu.runSetup":`Lancer le script de setup`,"contextMenu.exportEvents":`Exporter les events (CSV)`,"contextMenu.dismissChangesRequested":`Marquer « Modifications demandées » comme vu`,"contextMenu.dismissCiFailure":`Marquer « CI en échec » comme vu`,"contextMenu.restoreChangesRequested":`Marquer « Modifications demandées » comme non vu`,"contextMenu.restoreCiFailure":`Marquer « CI en échec » comme non vu`,"contextMenu.exportingEvents":`Préparation de l'export…`,"contextMenu.exportEventsError":`Échec de l'export des events`,"contextMenu.openNotion":`Ouvrir dans Notion`,"contextMenu.openSentry":`Ouvrir dans Sentry`,"contextMenu.openPr":`Ouvrir la PR`,"workspace.favorite":`Ajouter aux favoris`,"workspace.unfavorite":`Retirer des favoris`,"workspace.showFavoritesOnly":`Afficher uniquement les favoris`,"workspace.searchArchivedToggle":`Inclure les workspaces archivés dans la recherche`,"workspace.descriptionPlaceholder":`Ajouter une courte description`,"workspace.descriptionDialogHint":`Texte brut, 200 caractères maximum. Laisser vide pour effacer.`,"workspace.descriptionTooLong":`La description doit faire 200 caractères ou moins.`,"workspace.descriptionSaveFailed":`Échec de l'enregistrement de la description.`,"workspace.agentDescriptionTooltip":`État en direct maintenu par l'agent`,"mcp.tool.setWorkspaceDescription":`Définit la courte description du workspace (≤ 200 caractères).`,"tags.manage":`Gérer les tags`,"tags.manageTitle":`Gérer les tags du workspace`,"tags.noTagsDefined":`Aucun tag défini. Ajoutes-en dans Paramètres > Global > Tags.`,"tags.orphanedHint":`{count} tag(s) ne sont plus dans le catalogue global. Décoche-les pour les retirer.`,"settings.tagsTitle":`Tags des workspaces`,"settings.tagsHint":`Définis les tags assignables aux workspaces. Tape pour ajouter, clique la croix pour retirer.`,"settings.tagsLabel":`Tags disponibles`,"settings.branchPrefixesTitle":`Préfixes de branche`,"settings.branchPrefixesHint":`Gérez les préfixes de branche Git disponibles sur la page de création. Le premier est présélectionné par défaut.`,"settings.branchPrefixesEmpty":`Aucun préfixe de branche défini. Ajoutez-en au moins un ci-dessous.`,"settings.branchPrefixesAddLabel":`Nouveau préfixe`,"settings.branchPrefixesEditHint":`Cliquer pour renommer`,"settings.branchPrefixesMoveUp":`Monter`,"settings.branchPrefixesMoveDown":`Descendre`,"settings.worktreesTitle":`Worktrees Git`,"settings.worktreesHint":`Choisis où créer les worktrees des nouveaux workspaces. Les chemins relatifs sont résolus depuis le projet ; les chemins absolus Linux/macOS et Windows, $HOME, ~ et %USERPROFILE% sont supportés.`,"settings.worktreesPathLabel":`Chemin des worktrees`,"settings.worktreesPathRequired":`Le chemin des worktrees est requis.`,"settings.worktreesPrefixByProject":`Préfixer les worktrees par le nom du projet`,"settings.worktreesPrefixByProjectHint":`Place chaque worktree dans un sous-dossier nommé d'après le projet, pour éviter les collisions quand plusieurs projets partagent la même racine.`,"settings.shareTitle":`Partager la configuration`,"settings.shareHint":`Exporte tes paramètres, templates et tags en bundle JSON. Les clés MCP sont retirées à l’export pour la sécurité.`,"settings.exportConfig":`Exporter`,"settings.importConfig":`Importer`,"settings.exportSuccess":`Configuration exportée`,"settings.importSuccess":`Configuration importée`,"settings.importConfirmTitle":`Importer la configuration`,"settings.importConfirmMessage":`Cela remplacera tes paramètres, templates et tags actuels. Tes clés MCP seront conservées. Continuer ?`,"health.title":`Santé`,"health.tooltip":`Santé du système`,"changelog.title":`Journal des changements`,"changelog.tooltip":`Quoi de neuf dans Kōbō`,"changelog.empty":`Aucun changelog disponible.`,"changelog.current":`actuelle`,"changelog.currentVersion":`Version actuelle : v{version}`,"health.envTitle":`Environnement`,"health.version":`Version`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Base de données`,"health.dbPath":`Chemin`,"health.dbSize":`Taille`,"health.schemaVersion":`Version du schéma`,"health.settingsSchemaVersion":`Schéma settings`,"health.runtimesTitle":`Moteurs d'agent`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude introuvable dans le PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binaire codex introuvable`,"health.workspacesTitle":`Workspaces`,"health.workspacesCount":`{total} au total, {archived} archivés`,"health.worktreesMissing":`{count} worktree(s) manquant(s) sur le disque`,"health.sessionsTitle":`Sessions agent`,"health.sessionsOrphaned":`{n} session(s) orpheline(s) marquées running`,"health.integrationsTitle":`Intégrations`,"health.integrationConfigured":`configurée`,"health.integrationMissing":`non configurée`,"health.activeTitle":`État actif`,"health.activeQuotaBackoffs":`Quota backoffs en attente`,"health.activeWakeups":`Wakeups programmés`,"health.activeAutoLoop":`Auto-loop en cours`,"health.activeAgentSessions":`Sessions agent en cours`,"health.activeDevServers":`Serveurs de dev lancés`,"health.noneActive":`Aucun.`,"health.quotaResumeAt":`reprise à {time}`,"health.wakeupAt":`réveil à {time}`,"health.startedAgo":`démarré il y a {time}`,"health.autoLoopReady":`prêt, itération en cours`,"health.autoLoopGrooming":`grooming en cours`,"session.started":`Session démarrée`,"session.ended":`Session terminée`,"session.compacted":`Contexte compacté`,"tool.running":`En cours...`,"activity.raw_lines":`Lignes de sortie brutes ({n})`,"activity.loading_older":`Chargement des messages plus anciens…`,"activity.compacting":`Compaction du contexte…`,"activity.prev_user_message":`Message utilisateur précédent`,"activity.scroll_to_bottom":`Défiler vers le bas`,"chat.systemPrompt":`Prompt système`,"chat.agent":`Agent`,"chat.cleanupScript":`Script de cleanup`,"chat.archiveScript":`Script d'archivage`,"chat.setupScript":`Script de setup`,"chat.scriptDone":`Fait`,"chat.you":`Vous`,"chat.session":`Session`,"chat.nActions":`{n} action | {n} actions`,"chat.lastUpdatedAt":`Dernière mise à jour à {time}`,"chat.scrollToTurnTop":`Défiler vers le haut du message`,"migration.backing_up":`Sauvegarde de la base de données…`,"migration.running":`Migration des données d'agent — {processed}/{total}`,"migration.error":`Échec de la migration`,"migration.backup_location":`Une sauvegarde a été enregistrée à {path}. Redémarre Kōbō pour réessayer.`,"migration.retry":`Redémarre Kōbō pour réessayer.`,"engine.select":`Moteur`,"engine.model":`Modèle`,"engine.effort":`Effort de réflexion`,"wakeup.scheduledIn":`Prochain réveil dans {n}s`,"wakeup.scheduledAt":`Prochain réveil à {time}`,"wakeup.firing":`Réveil en cours…`,"wakeup.reason":`Raison : {reason}`,"wakeup.cancel":`Annuler ce réveil`,"wakeup.pendingIndicator":`Réveil programmé`,"cron.pendingIndicator":`{n} cron(s) programmé(s)`,"schedule.tabLabel":`Programmation`,"schedule.wakeupTitle":`Wakeup en attente`,"schedule.cronsTitle":`Tâches récurrentes`,"schedule.noWakeup":`Aucun wakeup programmé`,"schedule.noCrons":`Aucun cron programmé`,"schedule.nextFireAt":`prochain à {time}`,"schedule.lastFiredAt":`dernier fire il y a {time}`,"schedule.addCronTitle":`Ajouter une tâche récurrente`,"schedule.addWakeupTitle":`Programmer un réveil`,"schedule.every":`Toutes les`,"schedule.unitMinutes":`minutes`,"schedule.unitHours":`heures`,"schedule.unitDays":`jours`,"schedule.advancedExpression":`Expression avancée (optionnel)`,"schedule.advancedHint":`Cron brut (ex. */15 * * * *) ou {'@'}hourly/{'@'}daily — remplace le sélecteur si rempli.`,"schedule.promptLabel":`Prompt`,"schedule.labelOptional":`Libellé (optionnel)`,"schedule.delayMinutes":`Délai (minutes)`,"schedule.modeFresh":`Nouvelle session`,"schedule.oneShot":`Une seule fois`,"schedule.addCronBtn":`Ajouter le cron`,"schedule.addWakeupBtn":`Programmer le réveil`,"schedule.cronCreated":`Tâche récurrente ajoutée`,"schedule.wakeupCreated":`Réveil programmé`,"askUserQuestion.title":`L'agent te pose une question`,"askUserQuestion.submit":`Envoyer la réponse`,"askUserQuestion.multiSelectHint":`Sélectionne une ou plusieurs options`,"askUserQuestion.otherOption":`Autre`,"askUserQuestion.otherOptionHint":`précisez dans votre prochain message`,"askUserQuestion.noPending":`Aucune question en attente`,"askUserQuestion.next":`Suivant`,"askUserQuestion.previous":`Précédent`,"askUserQuestion.cancel":`Annuler`,"askUserQuestion.cancelTooltip":`Sauter cette question — l'agent continuera sans réponse`,"askUserQuestion.collapse":`Réduire le panneau de question`,"askUserQuestion.expand":`Agrandir le panneau de question`,"permissionRequest.title":`L'agent veut utiliser un outil`,"permissionRequest.allow":`Autoriser`,"permissionRequest.deny":`Refuser`,"permissionRequest.tool":`Outil`,"permissionRequest.input":`Entrée`,"permissionRequest.denied":`refusé par l'utilisateur`,"workspaceStatus.awaitingUser":`en attente de ta réponse`,"workspaceList.prOpen":`#{n} — Pull request ouverte`,"workspaceList.prChangesRequested":`#{n} — Modifications demandées`,"workspaceList.attentionCiFailed":`CI en échec`,"workspaceList.attentionChangesRequested":`Modifications demandées`,"workspaceList.attentionReadyToMerge":`Prêt à merger`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Démarrer l'auto-loop`,"autoLoop.prepare":`Préparer pour auto-loop`,"autoLoop.reprepare":`Re-préparer pour auto-loop`,"autoLoop.reprepareTooltip":`Relancer la phase de grooming pour ajouter ou rafraîchir les tâches avant de relancer la boucle`,"autoLoop.prepareBusy":`Attendre la fin de l'agent avant de préparer`,"autoLoop.forceReady":`Je sais ce que je fais — passer le grooming`,"autoLoop.forceReadyConfirm":`Passer le grooming et marquer auto-loop prêt ? La boucle peut stagner si les tâches ne sont pas atomiques.`,"autoLoop.stop":`Arrêter l'auto-loop`,"autoLoop.notReady":`Lancer d'abord « Préparer pour auto-loop »`,"autoLoop.noTasks":`Ajouter d'abord des tâches`,"autoLoop.progress":`Auto-loop · {done}/{total} tâches`,"autoLoop.preparing":`Auto-loop · préparation`,"autoLoop.preparingTooltip":`Grooming en cours — l'agent crée / révise les tâches. La boucle démarrera quand il appellera mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop en cours`,"autoLoop.startInMode":`Démarrer en mode auto-loop`,"koboCommand.prepAutoloopDesc":`Préparer les tâches pour le mode auto-loop (atomicité)`,"staleSessionBanner.title":`Auto-loop en cours`,"staleSessionBanner.message":`Vous consultez une ancienne session — l'agent travaille actuellement dans la dernière.`,"staleSessionBanner.staleTitle":`Session précédente`,"staleSessionBanner.staleMessage":`Vous consultez une ancienne session — les messages envoyés iront dans cette session, pas la dernière.`,"staleSessionBanner.switchToCurrent":`Basculer sur la session active`},ln={"common.save":`Salva`,"common.cancel":`Annulla`,"common.delete":`Elimina`,"common.close":`Chiudi`,"common.details":`Dettagli`,"whatsNew.title":`Novità`,"common.loading":`Caricamento...`,"common.search":`Cerca...`,"common.refresh":`Aggiorna`,"common.copy":`Copia`,"common.copied":`Copiato negli appunti`,"common.copyFailed":`Copia non riuscita`,"common.add":`Aggiungi`,"folderPicker.title":`Scegli una cartella`,"folderPicker.parent":`Cartella superiore`,"folderPicker.empty":`Nessuna sottocartella`,"folderPicker.select":`Scegli questa cartella`,"common.start":`Avvia`,"common.stop":`Arresta`,"common.archive":`Archivia`,"common.unarchive":`Ripristina`,"common.selectWorkspace":`Seleziona un workspace`,"common.noResults":`Nessun risultato per "{query}"`,"common.send":`invia`,"common.newLine":`nuova riga`,"common.history":`cronologia`,"common.justNow":`adesso`,"common.minutesAgo":`{count}m fa`,"common.hoursAgo":`{count}h fa`,"common.daysAgo":`{count}g fa`,"model.auto":`Auto`,"model.fable5":`Fable 5`,"model.mythos5":`Mythos 5 (Glasswing)`,"model.fable5Description":`Modello più capace — successore di Opus 4.8, contesto 1M, adaptive thinking`,"model.mythos5Description":`Fable 5 senza classificatori di sicurezza — accesso limitato (Project Glasswing)`,"model.opus":`Opus 4.6`,"model.sonnet":`Sonnet 4.6`,"model.opus48":`Opus 4.8`,"model.opus47Classic":`Opus 4.7 (Classic)`,"model.opus471m":`Opus 4.7 (1M)`,"model.opusClassic":`Opus 4.6 (Classic)`,"model.opus1m":`Opus 4.6 (1M)`,"model.sonnetClassic":`Sonnet 4.6 (Classic)`,"model.sonnet1m":`Sonnet 4.6 (1M)`,"model.haiku":`Haiku 4.5`,"model.autoDescription":`Claude sceglie il modello ottimale`,"model.opus48Description":`Opus più capace — coding agentico long-horizon, contesto 1M di default, effort high di default`,"model.opus47ClassicDescription":`Ultimo Opus, il più capace`,"model.opus471mDescription":`Ultimo Opus, contesto 1M`,"model.opusClassicDescription":`Più potente`,"model.opus1mDescription":`Più potente, contesto 1M`,"model.sonnetClassicDescription":`Bilanciato`,"model.sonnet1mDescription":`Bilanciato, contesto 1M`,"model.haikuDescription":`Più veloce`,"model.gpt55":`GPT-5.5`,"model.gpt55Description":`Consigliato per codice complesso (richiede autenticazione ChatGPT)`,"model.gpt54":`GPT-5.4`,"model.gpt54Description":`Ripiego predefinito — ragionamento solido, compatibile con chiave API`,"model.gpt54mini":`GPT-5.4 mini`,"model.gpt54miniDescription":`Veloce ed efficiente — ideale per attività reattive e subagenti`,"model.gpt53codex":`GPT-5.3 Codex`,"model.gpt53codexDescription":`Modello specializzato in codice per ingegneria software complessa`,"reasoning.auto":`auto`,"reasoning.minimal":`minimal`,"reasoning.low":`low`,"reasoning.medium":`medium`,"reasoning.high":`high`,"reasoning.xhigh":`xhigh`,"reasoning.max":`max`,"reasoning.autoDescription":`Lascia decidere al motore`,"reasoning.minimalDescription":`Ragionamento più veloce e superficiale`,"reasoning.lowDescription":`Più veloce, meno profondità`,"reasoning.mediumDescription":`Bilanciato`,"reasoning.highDescription":`Più profondità`,"reasoning.xhighDescription":`Profondità estesa, attività lunghe`,"reasoning.maxDescription":`Profondità massima`,"agentPermissionMode.label":`Modalità permessi`,"agentPermissionMode.plan":`Piano`,"agentPermissionMode.bypass":`Bypass`,"agentPermissionMode.strict":`Accetta edit`,"agentPermissionMode.interactive":`Interattivo`,"agentPermissionMode.tooltip":`Come l'agente gestisce i permessi degli strumenti. Piano: sola lettura, nessuna scrittura. Bypass: salta tutte le richieste. Stretto: auto-accetta le edit dei file, rispetta le allow/deny per il resto. Interattivo: chiedi all'utente prima di ogni strumento tramite il pannello dei permessi.`,"agentPermissionMode.autoLoopOverride":`L'auto-loop forza una modalità diversa da Piano — Piano blocca gli strumenti MCP e le edit di cui il loop ha bisogno. Scegli Bypass, Stretto o Interattivo.`,"agentPermissionMode.autoLoopLocked":`Bloccato su Bypass finché l'auto-loop è attivo — qualsiasi altra modalità fermerebbe il loop sulle richieste di permesso. AskUserQuestion funziona comunque.`,"workspaceList.title":`Workspace`,"workspaceList.needsAttention":`Richiede attenzione`,"workspaceList.running":`In esecuzione`,"workspaceList.idle":`Inattivo`,"workspaceList.archived":`Archiviati`,"workspaceList.noWorkspaces":`Nessun workspace ancora`,"workspaceList.footer":`{count} workspace | {count} workspace`,"workspaceList.footerRunning":`{count} in esecuzione`,"workspaceList.deleteDialog.title":`Eliminare il workspace?`,"workspaceList.deleteDialog.deleteLocal":`Elimina branch locale`,"workspaceList.deleteDialog.deleteRemote":`Elimina branch remoto`,"workspaceList.deleteDialog.warning":`Attenzione: questa azione è irreversibile sul remoto.`,"workspaceList.deleteArchivedDialog.tooltip":`Elimina tutti i workspace archiviati`,"workspaceList.deleteArchivedDialog.title":`Eliminare tutti i workspace archiviati?`,"workspaceList.deleteArchivedDialog.message":`Questa operazione eliminerà definitivamente i {count} workspace archiviati. L'azione è irreversibile.`,"workspacePage.selectWorkspace":`Seleziona un workspace per iniziare`,"workspacePage.session":`Sessione #{n}`,"workspacePage.newSession":`+ Nuova sessione`,"workspacePage.renameSession":`Rinomina`,"workspacePage.renameSessionTitle":`Rinomina sessione`,"workspacePage.sessionNameLabel":`Nome sessione`,"workspacePage.sessionEndedNotice":`Questa sessione è terminata. Crea una nuova sessione per continuare.`,"workspacePage.renameFailed":`Rinomina fallita`,"workspacePage.createSessionFailed":`Creazione sessione fallita`,"workspacePage.startFailed":`Avvio fallito`,"workspacePage.stopFailed":`Arresto fallito`,"workspacePage.interrupt":`Interrompi`,"workspacePage.interrupted":`Agente interrotto — in attesa del tuo prossimo messaggio`,"workspacePage.archivedBanner":`Workspace archiviato — sola lettura`,"workspacePage.worktreePurgedBanner":`Worktree eliminato — cronologia conservata, ripristino non disponibile in questa versione`,"workspacePage.worktreePurgedTooltip":"La cartella del worktree è stata eliminata dal disco per recuperare spazio. Cronologia di chat, sessioni e metadati della PR restano consultabili qui, ma la directory di lavoro non esiste più localmente. Una versione futura di Kōbō ricostruirà il worktree dalla PR mergiata — per ora ricrealo manualmente con `gh pr checkout` o `git worktree add`.","workspacePage.pendingInitialPromptBanner":`C'è un prompt iniziale in attesa — l'agente non l'ha mai ricevuto (lo script di setup è crashato o il workspace non è mai stato avviato). Clicca Avvia per inviarlo ora.`,"workspacePage.unarchived":`Workspace ripristinato`,"workspacePage.unarchiveFailed":`Ripristino fallito`,"workspacePage.interruptFailed":`Interruzione fallita`,"workspacePage.interruptTooltip":`Interruzione leggera (come Escape) — ferma lo strumento corrente ma mantiene la sessione attiva`,"workspacePage.pendingNextRun":`Applicato al prossimo avvio`,"search.title":`Ricerca`,"search.tooltip":`Cerca nella cronologia degli agenti`,"search.placeholder":`Cerca in tutti i messaggi degli agenti…`,"search.includeArchived":`Includi workspace archiviati`,"search.loading":`Ricerca in corso…`,"search.noResults":`Nessun risultato`,"search.error":`Ricerca fallita: {message}`,"search.resultCount":`{n} risultato/i`,"search.eventType.userMessage":`Tu`,"search.eventType.agentOutput":`Agente`,"activityFeed.empty":`Nessuna attività ancora`,"activityFeed.emptyHint":`Avvia un workspace per vedere l'output dell'agente qui`,"activityFeed.initialPrompt":`Prompt iniziale`,"activityFeed.you":`Tu`,"activityFeed.agent":`Agente`,"activityFeed.question":`Domanda`,"activityFeed.goToPrevious":`Vai al messaggio precedente`,"activityFeed.scrollToBottom":`Vai in fondo`,"activityFeed.sendAnswers":`Invia risposte`,"agentBusy.banner":`L'agente è occupato`,"agentBusy.subagentsRunning":`1 sub-agente in esecuzione | {n} sub-agenti in esecuzione`,"agentBusy.viewSubagents":`Vedi sub-agenti`,"agentBusy.pendingMessage":`In attesa — l'agente è occupato`,"terminal.title":`Terminale`,"terminal.open":`Apri terminale`,"terminal.close":`Chiudi terminale`,"terminal.noWorkspace":`Seleziona un workspace`,"terminal.noWorktree":`Worktree non ancora creato`,"terminal.error":`Errore del terminale`,"terminal.exited":`Terminale chiuso`,"chatInput.placeholder":`Messaggio... (/ per le skill)`,"chatInput.fileSearchHint":`cercare un file`,"chatInput.skills":`Skill`,"chatInput.attachImage":`Allega immagine`,"chatInput.queueBanner":`Messaggio in coda — verrà inviato quando l'agente avrà terminato`,"chatInput.cancelQueue":`Annulla coda`,"chatInput.autoLoopBanner":`Auto-loop attivo — fermalo per inviare un messaggio`,"chatInput.awaitingUserBanner":`L'agente attende la tua risposta sopra — rispondi tramite il pannello della domanda`,"chatInput.autoLoopStop":`Ferma`,"koboCommand.checkProgressDesc":`Verificare il progresso delle attività e dei criteri di accettazione`,"chatInput.uploading":`Caricamento...`,"voice.title":`Trascrizione vocale`,"voice.enabled":`Abilita trascrizione vocale locale`,"voice.pttKey":`Tasto push-to-talk`,"voice.pttAlt":`Alt`,"voice.pttCtrlSpace":`Ctrl+Spazio`,"voice.language":`Lingua (auto o codice)`,"voice.model":`Modello attivo`,"voice.commandPath":`Percorso binario Whisper (opzionale)`,"voice.ffmpegPath":`Percorso binario ffmpeg (opzionale)`,"voice.temperature":`Temperatura`,"voice.temperatureHint":`Più basso = più deterministico; più alto = più flessibile ma potenzialmente meno stabile.`,"voice.initialPrompt":`Prompt iniziale (opzionale)`,"voice.initialPromptHint":`Contesto opzionale per aiutare Whisper con nomi propri, sigle o vocabolario tecnico.`,"voice.translateToEnglish":`Traduci in inglese`,"voice.translateToEnglishHint":`Se attivo, il parlato non inglese viene tradotto in inglese invece di essere trascritto così com’è.`,"voice.suppressNst":`Sopprimi token non vocali`,"voice.suppressNstHint":`Prova a ridurre artefatti non vocali nella trascrizione.`,"voice.installLink":`Installa whisper.cpp`,"voice.installGuideTitle":`Guida installazione`,"voice.installGuideIntro":`Installa whisper.cpp e ffmpeg, poi imposta i percorsi dei binari qui sotto se necessario.`,"voice.installGuideUbuntuTitle":`Ubuntu / Debian`,"voice.installGuideWindowsTitle":`Windows`,"voice.installGuideBinaryPathHint":`Dopo il build con CMake, il binario Whisper di solito è in: whisper.cpp/build/bin/whisper-cli`,"voice.installGuideSettingsHint":`Poi imposta “Percorso binario Whisper” e “Percorso binario ffmpeg” in questa sezione (o lascia vuoto se sono nel PATH).`,"voice.noneModel":`Nessun modello attivo`,"voice.notInstalled":`non installato`,"voice.download":`Scarica`,"voice.delete":`Elimina`,"voice.holdToTalk":`Tieni premuto per parlare`,"voice.recording":`Registrazione...`,"voice.transcribing":`Trascrizione...`,"voice.notSupported":`La registrazione vocale non è supportata da questo browser`,"voice.errorMicPermission":`Permesso microfono negato`,"voice.errorTranscription":`Trascrizione vocale non riuscita`,"voice.downloadFailed":`Download del modello non riuscito`,"voice.deleteFailed":`Eliminazione del modello non riuscita`,"voice.errorDisabled":`La trascrizione vocale è disattivata nelle impostazioni`,"voice.errorModelMissing":`Nessun modello vocale attivo configurato`,"voice.errorModelNotInstalled":`Il modello vocale attivo non è installato`,"voice.errorAudioInvalid":`La cattura audio è non valida o vuota`,"voice.errorLanguageInvalid":`La configurazione lingua vocale non è valida`,"voice.errorRuntimeMissing":`Il runtime Whisper non è installato o non è nel PATH`,"voice.maxDurationReached":`Durata massima di registrazione raggiunta`,"voice.runtimeReady":`Runtime pronto: {command}`,"voice.runtimeMissing":`Runtime mancante: {command}`,"voice.ffmpegReady":`ffmpeg pronto`,"voice.ffmpegMissing":`ffmpeg mancante`,"voice.sectionRuntime":`Stato del runtime`,"voice.sectionActivation":`Attivazione`,"voice.sectionModels":`Modelli Whisper`,"voice.sectionAdvanced":`Opzioni avanzate`,"voice.sectionBehavior":`Comportamento della trascrizione`,"voice.sectionBinaries":`Percorsi dei binari`,"voice.downloadModels":`Scarica un modello`,"voice.cancelFailed":`Annullamento del download non riuscito`,"createPage.title":`Su cosa vorresti lavorare?`,"createPage.claudeCode":`Claude Code`,"createPage.notionEnabled":`Notion attivato`,"createPage.importNotion":`Importa da Notion`,"createPage.notionPlaceholder":`https://www.notion.so/workspace/Page-title-abc123...`,"createPage.notionValidation":`L'URL deve iniziare con https://www.notion.so/ o https://app.notion.com/`,"createPage.notionAutoExtract":`Le sottotask e i criteri di accettazione verranno estratti automaticamente.`,"createPage.notionPanelChoiceLabel":`Questo URL punta a una sotto-pagina (?p=). Su quale vuoi lavorare?`,"createPage.notionPanelOption":`Sotto-pagina (panel)`,"createPage.notionPanelOptionDesc":`La pagina che stavi visualizzando — consigliato`,"createPage.notionParentOption":`Pagina principale`,"createPage.notionParentOptionDesc":`L'epic / database a cui appartiene`,"createPage.importSentry":`Importa Sentry`,"createPage.sentryEnabled":`Sentry attivato`,"createPage.sentryPlaceholder":`https://tua-org.sentry.io/issues/123456`,"createPage.sentryValidation":`L'URL deve puntare a una issue di Sentry (/issues/<id>)`,"createPage.sentryAutoExtract":`L'issue di Sentry verrà importata automaticamente`,"createPage.sentryExtractHint":`Kobo estrarrà l'issue e la scriverà in .ai/thoughts/`,"createPage.workspaceName":`Nome del workspace (predefinito: titolo della pagina Notion)`,"createPage.workspaceNamePlaceholder":`Nome del workspace...`,"createPage.instructions":`Istruzioni aggiuntive (opzionale)...`,"createPage.instructionsPlaceholder":`Descrivi il task...`,"createPage.manualHint":`Nessun ticket Notion? Aggiungi i tuoi task e criteri di accettazione manualmente — verranno inviati all'agente Claude come contesto.`,"createPage.tasks":`Task ({count})`,"createPage.addTask":`Aggiungi un task...`,"createPage.acceptanceCriteria":`Criteri di accettazione ({count})`,"createPage.addCriterion":`Aggiungi un criterio...`,"createPage.projectPath":`Inserisci il percorso del progetto`,"createPage.branchType":`Tipo di branch`,"createPage.branch":`Branch`,"createPage.noBranches":`Nessun branch trovato`,"createPage.enterPath":`Inserisci il percorso del progetto`,"createPage.create":`Crea`,"createPage.skipSetupScript":`Salta script di setup`,"createPage.attachWorktreeToggle":`Aggancia worktree esistente`,"createPage.attachWorktreeEnabled":`Riutilizzo worktree esistente`,"createPage.worktreePickerLabel":`Worktree esistente`,"createPage.noOrphanWorktrees":`Nessun worktree orfano in questo progetto`,"createPage.pickWorktreeRequired":`Seleziona un worktree da agganciare`,"createPage.notionExtractHint":`Le sottotask e i criteri di accettazione verranno estratti dalla pagina Notion.`,"createPage.notionImportHint":`Clicca su "Importa da Notion" per estrarre automaticamente le sottotask da un ticket.`,"createPage.errorCreating":`Errore durante la creazione del workspace.`,"createPage.branchAdjusted":"Il branch esisteva già — creato `{branch}` al suo posto. La cartella worktree corrispondente usa lo stesso suffisso.","createPage.validationNotionUrl":`Inserisci un URL Notion valido (https://www.notion.so/... o https://app.notion.com/...).`,"createPage.validationDescription":`Descrivi il task.`,"createPage.validationName":`Indica un nome per il workspace.`,"createPage.validationPath":`Inserisci il percorso del progetto.`,"createPage.validationBranch":`Seleziona un branch.`,"settings.title":`Impostazioni`,"settings.language":`Lingua`,"settings.projectColor":`Colore`,"settings.projectColorClear":`Cancella`,"settings.projectColorDefault":`Predefinito (grigio)`,"settings.workspaceListSection":`Lista dei workspace`,"settings.flattenWorkspaceList":`Lista piatta dei workspace`,"settings.flattenWorkspaceListHint":`Mostra tutti i workspace in una lista piatta con un badge progetto, invece di raggrupparli per progetto.`,"settings.skillSuite.section":`Suite di skill`,"settings.skillSuite.superpowers":`Superpowers`,"settings.skillSuite.gstack":`gstack`,"settings.skillSuite.custom":`Personalizzato`,"settings.skillSuite.superpowersHint":`Workflow opinionato TDD / brainstorm / plan (github.com/obra/superpowers).`,"settings.skillSuite.gstackHint":`Suite di Garry Tan — /review, /ship, /qa, /office-hours, ecc. (github.com/garrytan/gstack).`,"settings.skillSuite.superpowersGstack":`Superpowers + gstack`,"settings.skillSuite.superpowersGstackHint":`Le due suite si combinano — superpowers per la metodologia (brainstorm / TDD / piani / review a livello di principi), gstack per i flussi concreti (/review, /qa, /browse, /design-review, /investigate).`,"settings.skillSuite.customHint":`Modifica i quattro prompt qui sotto tu stesso. Parte dalla base agnostica.`,"settings.skillSuite.reloadDefaults":`Ripristina predefiniti`,"settings.skillSuite.reloadDefaultsConfirm":`Sostituire i quattro prompt personalizzati con i valori agnostici predefiniti?`,"settings.skillSuite.customPrompts":`Prompt personalizzati`,"settings.skillSuite.reviewTemplate":`Template di review`,"settings.skillSuite.autoLoopReviewGate":`Gate di review auto-loop`,"settings.skillSuite.autoLoopGroomingIntro":`Intro di grooming auto-loop`,"settings.skillSuite.qaTemplate":`Template QA`,"settings.skillSuite.brainstormingInstruction":`Istruzione fase di brainstorming`,"settings.global":`Globale`,"settings.projects":`Progetti`,"settings.globalSettings":`Impostazioni globali`,"settings.defaultModel":`Modello predefinito`,"settings.defaultModelClaude":`Modello predefinito (Claude Code)`,"settings.defaultModelCodex":`Modello predefinito (OpenAI Codex)`,"settings.agentPermissions":`Permessi dell'agente`,"settings.skipPermissions":`Salta le richieste di permesso (--dangerously-skip-permissions)`,"settings.skipPermissionsWarning":`Attenzione: disattivando questa opzione, tutti i permessi degli strumenti (Write, Edit, Bash...) verranno negati automaticamente in modalità headless. L'agente potrà solo leggere.`,"settings.notifications":`Notifiche`,"settings.browserNotifications":`Notifica browser quando l'agente termina`,"settings.audioNotifications":`Notifica sonora quando l'agente termina`,"settings.notificationSound":`Suono di notifica`,"settings.notificationSoundPreview":`Ascolta`,"settings.notificationVolume":`Volume`,"settings.notificationSoundHey":`Hey`,"settings.notificationSoundTravailTermine":`Lavoro finito`,"settings.notificationSoundFaaah":`Faaah`,"settings.notificationSoundCaVaPeter":`Sta per esplodere`,"settings.notificationSoundDryFart":`Dry fart`,"settings.notificationSoundForShure":`For shure`,"settings.defaultPermissionMode":`Modalità permessi predefinita`,"settings.defaultPermissionModeClaude":`Modalità permessi predefinita (Claude Code)`,"settings.defaultPermissionModeCodex":`Modalità permessi predefinita (OpenAI Codex)`,"settings.defaultPermissionModeHint":`Modalità applicata alla creazione di un workspace. Piano = sola lettura, Bypass = senza richieste, Stretto = auto-accetta le edit con allow-list, Interattivo = chiedi prima di ogni strumento.`,"settings.activityFeed":`Feed attività`,"settings.verboseMessages":`Mostra messaggi di sistema dettagliati (task_progress, task_started)`,"settings.availableVariables":`Variabili disponibili nei template del prompt`,"settings.prPromptTemplate":`Template del prompt PR`,"settings.prPromptPlaceholder":`Istruzioni per l'agente durante la creazione di PR su GitHub...`,"settings.prPromptHint":`Usa le variabili elencate sopra (sintassi doppia parentesi graffa).`,"settings.reviewPromptTemplate":`Template del prompt di revisione`,"settings.reviewPromptPlaceholder":`Istruzioni per l'agente durante la revisione delle modifiche del branch...`,"settings.ciFixPromptTemplate":`Template del prompt «Ripara CI»`,"settings.ciFixPromptHint":`Inviato all'agente quando un workspace ha la CI in errore. Variabili (sintassi doppie graffe): pr_url, pr_number, pr_title, branch_name, source_branch, workspace_name, workspace_id, project_name, failed_jobs, ci_run_url.`,"settings.ciFixPromptPlaceholder":`Chiedi all'agente di diagnosticare e correggere i job di CI in errore...`,"settings.finalizationPromptTemplate":`Prompt di finalizzazione dell'auto-loop`,"settings.finalizationPromptHint":`Prompt predefinito per l'ultima iterazione dell'auto-loop (controlli di qualità finali). Usato quando un progetto lascia vuoto il proprio prompt di finalizzazione.`,"settings.finalizationPromptPlaceholder":`Run final quality checks before closing the workspace...`,"settings.notionInitialPrompt":`Prompt iniziale Notion`,"settings.notionInitialPrompt.help":`Aggiunto al prompt di creazione del workspace quando il workspace ha un ticket Notion. Variabili: {variables}.`,"settings.notionInitialPrompt.project":`Prompt iniziale Notion (override)`,"settings.sentryInitialPrompt":`Prompt iniziale Sentry`,"settings.sentryInitialPrompt.help":`Aggiunto al prompt di creazione del workspace quando il workspace ha una issue Sentry. Variabili: {variables}.`,"settings.sentryInitialPrompt.project":`Prompt iniziale Sentry (override)`,"settings.initialPrompt.inheritHint":`Lasciare vuoto per ereditare. Digita un carattere di spazio bianco per disattivare l'iniezione a questo livello.`,"settings.resetToDefault":`Ripristina`,"settings.resetFailed":`Impossibile caricare il valore predefinito`,"settings.sentryIntegration":`Integrazione Sentry`,"settings.var.prNumber":`Numero della PR (es: 42)`,"settings.var.prUrl":`URL completo della PR creata`,"settings.var.branchName":`Nome del branch di lavoro`,"settings.var.sourceBranch":`Branch sorgente a cui punta la PR`,"settings.var.workspaceName":`Nome del workspace`,"settings.var.projectName":`Ultimo segmento del percorso del progetto`,"settings.var.notionUrl":`URL Notion se impostato, vuoto altrimenti`,"settings.var.commits":`Elenco puntato dei commit tra source e head`,"settings.var.diffStats":`Riepilogo shortstat Git (file, inserimenti, eliminazioni)`,"settings.var.tasks":`Attività regolari come lista di controllo`,"settings.var.acceptanceCriteria":`Criteri di accettazione come lista di controllo`,"settings.gitConventions":`Convenzioni Git (globale)`,"settings.gitConventionsPlaceholder":`# Convenzioni Git...`,"settings.gitConventionsHint":`Queste convenzioni vengono scritte in .ai/.git-conventions.md in ogni nuovo workspace e devono essere seguite dall'agente prima di qualsiasi operazione Git. Sovrascritte dalle convenzioni per progetto se definite.`,"settings.setupScript":`Script di setup`,"settings.cleanupScript":`Script di pulizia`,"settings.archiveScript":`Script di archiviazione`,"settings.archiveScriptHint":`Script di shell eseguito lato server nel worktree quando un workspace viene archiviato. Lascia vuoto per disattivare.`,"settings.archiveScriptPlaceholder":`es. pulire container, liberare spazio su disco…`,"settings.changeSourceBranchScript":`Script di cambio del branch di origine`,"settings.changeSourceBranchScript.help":`Sostituisce il cherry-pick integrato quando non vuoto. Lo script gestisce git, base della PR, force-push e conflitti; Kōbō rifiuta solo se l'agente è in esecuzione e aggiorna i metadati del branch di origine all'uscita 0.`,"settings.changeSourceBranchScript.envHelp":`KOBO_NEW_BASE — nuovo branch di origine scelto nella finestra di dialogo
67
67
  KOBO_OLD_BASE — branch di origine precedente del workspace
68
68
  KOBO_WORKING_BRANCH — branch di lavoro del workspace
69
69
  KOBO_WORKTREE_PATH — percorso assoluto del worktree (anche cwd)
@@ -79,4 +79,4 @@ KOBO_PR_NUMBER — numero della PR/MR sulla forge risolta (vuoto se nessuna
79
79
  # Oppure direttamente con git (funziona su GitHub anche dopo eliminazione del branch):
80
80
  git fetch origin pull/[numero-pr]/head:[nome-branch]
81
81
  git worktree add [percorso] [nome-branch]`,"settings.purgeDocsRestoreFootnote":`GitHub mantiene il ref HEAD della PR accessibile a lungo dopo l'eliminazione del branch sorgente (mesi / anni). Il rilevamento automatico gira nel watcher 30 s — nessuna azione UI necessaria una volta che la cartella riappare.`,"settings.purgeDocsPermissionsTitle":`Evitare errori di permessi durante la pulizia`,"settings.purgeDocsPermissionsIntro":`Docker spesso lascia file root-owned in node_modules / vendor dentro il worktree. Quando Kōbō prova a rimuoverli, ricevi EACCES / EPERM e la pulizia fallisce. Due modi per prevenirlo:`,"settings.purgeDocsPermissionsDocker":'Configurare il container per girare come utente host — direttiva USER nel Dockerfile, o `user: "${UID}:${GID}"` in docker-compose (con UID/GID esportati nella shell).',"settings.purgeDocsPermissionsAcl":`Pre-impostare una ACL di default sulla root dei worktrees — rete di sicurezza che funziona nella MAGGIOR PARTE dei casi (ext4/btrfs/xfs + bind mount Docker classico). Ogni nuovo file eredita allora una voce di accesso per il tuo utente, oltre al proprietario nominale:`,"settings.purgeDocsPermissionsAclCommand":` setfacl -d -m u:$(whoami):rwX [root-worktrees]`,"settings.purgeDocsPermissionsFootnote":"Limiti delle ACL: NON funzionano sui volumi Docker con nome (usa un bind mount), filesystem senza supporto ACL (NTFS, exFAT, tmpfs), SELinux strict con `:Z`, o quando Docker `userns-remap` è attivato. La soluzione più affidabile resta configurare l'utente nel container (opzione 1). Suggerimento: `rwX` (X maiuscola) aggiunge il bit eseguibile solo a directory e file già eseguibili — più pulito di `rwx` che renderebbe eseguibile ogni file di testo.","settings.purgeDocsPermissionsRecoverTitle":`Sbloccare un worktree già rotto (file root-owned esistenti)`,"settings.purgeDocsPermissionsRecoverIntro":`Se ti ritrovi con un worktree già pieno di file root-owned (Docker ha già girato, vendor / node_modules sono bloccati), l'ACL preventiva sopra non basta — devi sistemare i file ESISTENTI. Due approcci, entrambi da eseguire dentro la cartella del worktree:`,"settings.purgeDocsPermissionsRecoverAclIntro":`Opzione A — ACL ricorsiva (preserva l'ownership root per audit, aggiunge solo accesso per il tuo utente in parallelo):`,"settings.purgeDocsPermissionsRecoverAclCommand":`# imposta ACL di default per i file futuri E concede accesso a tutto l'esistente
82
- sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Opzione B — Prendere la proprietà (più semplice, perde la traccia "creato da root nel container" ma raramente conta):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Suggerimento: puoi eseguire questi comandi direttamente sulla root dei worktrees (es. `~/.worktrees/`) per coprire tutti i workspace esistenti E futuri in un colpo solo. Una volta fatto, la pulizia Kōbō funzionerà senza errori di permessi.","contextMenu.runSetup":`Esegui script di setup`,"contextMenu.exportEvents":`Esporta eventi (CSV)`,"contextMenu.dismissChangesRequested":`Segna «Modifiche richieste» come visto`,"contextMenu.dismissCiFailure":`Segna «CI in errore» come visto`,"contextMenu.restoreChangesRequested":`Segna «Modifiche richieste» come non visto`,"contextMenu.restoreCiFailure":`Segna «CI in errore» come non visto`,"contextMenu.exportingEvents":`Preparazione dell'esportazione…`,"contextMenu.exportEventsError":`Esportazione degli eventi non riuscita`,"contextMenu.openNotion":`Apri in Notion`,"contextMenu.openSentry":`Apri in Sentry`,"contextMenu.openPr":`Apri PR`,"workspace.favorite":`Segna come preferito`,"workspace.unfavorite":`Rimuovi dai preferiti`,"workspace.showFavoritesOnly":`Mostra solo i preferiti`,"workspace.searchArchivedToggle":`Cerca anche nei workspace archiviati`,"workspace.descriptionPlaceholder":`Aggiungi una breve descrizione`,"workspace.descriptionDialogHint":`Testo semplice, massimo 200 caratteri. Lasciare vuoto per cancellare.`,"workspace.descriptionTooLong":`La descrizione deve avere al massimo 200 caratteri.`,"workspace.descriptionSaveFailed":`Impossibile salvare la descrizione.`,"workspace.agentDescriptionTooltip":`Stato live mantenuto dall'agente`,"mcp.tool.setWorkspaceDescription":`Imposta la breve descrizione del workspace (≤ 200 caratteri).`,"tags.manage":`Gestisci tag`,"tags.manageTitle":`Gestisci i tag del workspace`,"tags.noTagsDefined":`Nessun tag definito. Aggiungine in Impostazioni > Globale > Tag.`,"tags.orphanedHint":`{count} tag non sono più nel catalogo globale. Deseleziona per rimuoverli.`,"settings.tagsTitle":`Tag dei workspace`,"settings.tagsHint":`Definisci i tag assegnabili ai workspace. Digita per aggiungere, clicca la croce per rimuovere.`,"settings.tagsLabel":`Tag disponibili`,"settings.branchPrefixesTitle":`Prefissi di branch`,"settings.branchPrefixesHint":`Gestisci i prefissi di branch Git disponibili nella pagina di creazione del workspace. Il primo è preselezionato per impostazione predefinita.`,"settings.branchPrefixesEmpty":`Nessun prefisso di branch definito. Aggiungine almeno uno qui sotto.`,"settings.branchPrefixesAddLabel":`Nuovo prefisso`,"settings.branchPrefixesEditHint":`Clicca per rinominare`,"settings.branchPrefixesMoveUp":`Sposta su`,"settings.branchPrefixesMoveDown":`Sposta giù`,"settings.worktreesTitle":`Worktree Git`,"settings.worktreesHint":`Scegli dove creare i worktree dei nuovi workspace. I percorsi relativi sono risolti dal progetto; sono supportati percorsi assoluti Linux/macOS e Windows, $HOME, ~ e %USERPROFILE%.`,"settings.worktreesPathLabel":`Percorso worktree`,"settings.worktreesPathRequired":`Il percorso worktree è obbligatorio.`,"settings.worktreesPrefixByProject":`Aggiungi il nome del progetto come prefisso ai worktree`,"settings.worktreesPrefixByProjectHint":`Posiziona ogni worktree in una sottocartella con il nome del progetto per evitare collisioni quando più progetti condividono la stessa radice.`,"settings.shareTitle":`Condividi configurazione`,"settings.shareHint":`Esporta impostazioni, template e tag come bundle JSON. Le chiavi MCP sono escluse per sicurezza.`,"settings.exportConfig":`Esporta`,"settings.importConfig":`Importa`,"settings.exportSuccess":`Configurazione esportata`,"settings.importSuccess":`Configurazione importata`,"settings.importConfirmTitle":`Importa configurazione`,"settings.importConfirmMessage":`Questo sostituirà le tue impostazioni, template e tag attuali. Le chiavi MCP vengono preservate. Continuare?`,"health.title":`Stato`,"health.tooltip":`Stato del sistema`,"changelog.title":`Changelog`,"changelog.tooltip":`Novità di Kōbō`,"changelog.empty":`Nessun changelog disponibile.`,"changelog.current":`corrente`,"changelog.currentVersion":`Versione corrente: v{version}`,"health.envTitle":`Ambiente`,"health.version":`Versione`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Database`,"health.dbPath":`Percorso`,"health.dbSize":`Dimensione`,"health.schemaVersion":`Versione schema`,"health.settingsSchemaVersion":`Schema impostazioni`,"health.runtimesTitle":`Runtime agente`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude non trovato nel PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binario codex non risolvibile`,"health.workspacesTitle":`Workspace`,"health.workspacesCount":`{total} totali, {archived} archiviati`,"health.worktreesMissing":`{count} worktree mancanti sul disco`,"health.sessionsTitle":`Sessioni agente`,"health.sessionsOrphaned":`{n} sessione/sessioni orfana/e in esecuzione`,"health.integrationsTitle":`Integrazioni`,"health.integrationConfigured":`configurata`,"health.integrationMissing":`non configurata`,"health.activeTitle":`Stato attivo`,"health.activeQuotaBackoffs":`Quota backoff in attesa`,"health.activeWakeups":`Wakeup programmati`,"health.activeAutoLoop":`Auto-loop in esecuzione`,"health.activeAgentSessions":`Sessioni agente attive`,"health.activeDevServers":`Dev server in esecuzione`,"health.noneActive":`Nessuno.`,"health.quotaResumeAt":`riprende alle {time}`,"health.wakeupAt":`sveglia alle {time}`,"health.startedAgo":`avviata {time} fa`,"health.autoLoopReady":`pronto, in iterazione`,"health.autoLoopGrooming":`grooming in corso`,"session.started":`Sessione avviata`,"session.ended":`Sessione terminata`,"session.compacted":`Contesto compattato`,"tool.running":`In corso...`,"activity.raw_lines":`Righe di output grezze ({n})`,"activity.loading_older":`Caricamento messaggi precedenti…`,"activity.compacting":`Compattazione del contesto…`,"activity.prev_user_message":`Messaggio utente precedente`,"activity.scroll_to_bottom":`Scorri in fondo`,"chat.systemPrompt":`Prompt di sistema`,"chat.agent":`Agente`,"chat.cleanupScript":`Script di pulizia`,"chat.archiveScript":`Script di archiviazione`,"chat.setupScript":`Script di setup`,"chat.scriptDone":`Fatto`,"chat.you":`Tu`,"chat.session":`Sessione`,"chat.nActions":`{n} azione | {n} azioni`,"chat.lastUpdatedAt":`Ultimo aggiornamento alle {time}`,"chat.scrollToTurnTop":`Scorri all'inizio del messaggio`,"migration.backing_up":`Backup del database in corso…`,"migration.running":`Migrazione dei dati dell'agente — {processed}/{total}`,"migration.error":`Migrazione non riuscita`,"migration.backup_location":`Un backup è stato salvato in {path}. Riavvia Kōbō per riprovare.`,"migration.retry":`Riavvia Kōbō per riprovare.`,"engine.select":`Engine`,"engine.model":`Modello`,"engine.effort":`Livello di ragionamento`,"wakeup.scheduledIn":`Prossimo risveglio tra {n}s`,"wakeup.scheduledAt":`Prossimo risveglio alle {time}`,"wakeup.firing":`Risveglio in corso...`,"wakeup.reason":`Motivo: {reason}`,"wakeup.cancel":`Annulla questo risveglio`,"wakeup.pendingIndicator":`Risveglio programmato`,"cron.pendingIndicator":`{n} cron programmato/i`,"schedule.tabLabel":`Pianificazione`,"schedule.wakeupTitle":`Wakeup in attesa`,"schedule.cronsTitle":`Pianificazioni ricorrenti`,"schedule.noWakeup":`Nessun wakeup pianificato`,"schedule.noCrons":`Nessun cron pianificato`,"schedule.nextFireAt":`prossimo alle {time}`,"schedule.lastFiredAt":`ultimo {time} fa`,"askUserQuestion.title":`L'agente sta facendo una domanda`,"askUserQuestion.submit":`Invia risposta`,"askUserQuestion.multiSelectHint":`Seleziona una o più opzioni`,"askUserQuestion.otherOption":`Altro`,"askUserQuestion.otherOptionHint":`specifica nel prossimo messaggio`,"askUserQuestion.noPending":`Nessuna domanda in attesa`,"askUserQuestion.next":`Avanti`,"askUserQuestion.previous":`Indietro`,"askUserQuestion.cancel":`Annulla`,"askUserQuestion.cancelTooltip":`Salta questa domanda — l'agente proseguirà senza risposta`,"askUserQuestion.collapse":`Riduci il pannello della domanda`,"askUserQuestion.expand":`Espandi il pannello della domanda`,"permissionRequest.title":`L'agente vuole usare uno strumento`,"permissionRequest.allow":`Consenti`,"permissionRequest.deny":`Nega`,"permissionRequest.tool":`Strumento`,"permissionRequest.input":`Input`,"permissionRequest.denied":`negato dall'utente`,"workspaceStatus.awaitingUser":`in attesa della tua risposta`,"workspaceList.prOpen":`#{n} — Pull request aperta`,"workspaceList.prChangesRequested":`#{n} — Modifiche richieste`,"workspaceList.attentionCiFailed":`CI fallita`,"workspaceList.attentionChangesRequested":`Modifiche richieste`,"workspaceList.attentionReadyToMerge":`Pronto per il merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Avvia l'auto-loop`,"autoLoop.prepare":`Prepara per l'auto-loop`,"autoLoop.reprepare":`Ri-prepara per l'auto-loop`,"autoLoop.reprepareTooltip":`Rilancia la fase di grooming per aggiungere o aggiornare le attività prima di riavviare il loop`,"autoLoop.prepareBusy":`Attendi che l'agente finisca prima di preparare`,"autoLoop.forceReady":`So cosa faccio — salta la preparazione`,"autoLoop.forceReadyConfirm":`Saltare la preparazione e segnare auto-loop pronto? Il loop potrebbe bloccarsi se le attività non sono atomiche.`,"autoLoop.stop":`Ferma l'auto-loop`,"autoLoop.notReady":`Esegui prima «Prepara per l'auto-loop»`,"autoLoop.noTasks":`Aggiungi prima delle attività`,"autoLoop.progress":`Auto-loop · {done}/{total} attività`,"autoLoop.preparing":`Auto-loop · preparazione`,"autoLoop.preparingTooltip":`Grooming in corso — l'agente sta creando / revisionando le attività. Il loop partirà quando chiamerà mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop in corso`,"autoLoop.startInMode":`Avvia in modalità auto-loop`,"koboCommand.prepAutoloopDesc":`Preparare le attività per la modalità auto-loop (atomicità)`,"staleSessionBanner.title":`Auto-loop in corso`,"staleSessionBanner.message":`Stai visualizzando una sessione precedente — l'agente sta lavorando nella più recente.`,"staleSessionBanner.switchToCurrent":`Passa a quella corrente`},un=`kobo:locale`,dn=[`en`,`fr`,`de`,`es`,`it`];function fn(e){return dn.includes(e)}function pn(){let e=localStorage.getItem(un);if(e&&fn(e))return e;let t=navigator.language.split(`-`)[0];return t&&fn(t)?(localStorage.setItem(un,t),t):(localStorage.setItem(un,`en`),`en`)}var mn=We({legacy:!1,locale:pn(),fallbackLocale:`en`,messages:{en:on,fr:cn,de:an,es:sn,it:ln}}),hn=F(`agent-stream`,()=>{let t=e(new Map),n=e(new Map),r=e(new Map),i=e(new Map),a=e(new Map),o=e(new Map),s=e(new Map),c=e(0);function l(e){return c.value,s.value.get(e)??!1}function u(e,t){(s.value.get(e)??!1)!==t&&(s.value.set(e,t),c.value++)}function d(e){return c.value,t.value.get(e)??[]}function f(e){return c.value,n.value.get(e)??[]}function p(e){return c.value,r.value.get(e)??[]}function m(e){return c.value,i.value.get(e)??[]}function h(e){return c.value,a.value.get(e)}function g(e){return c.value,o.value.get(e)??!0}function _(e,o,s,l,u){let d=t.value.get(e)??[],f=n.value.get(e)??[],p=r.value.get(e)??[],m=i.value.get(e)??[],h=d.length===0;d.push(o),f.push(s??new Date().toISOString()),p.push(u??null),m.push(l??null),t.value.set(e,d),n.value.set(e,f),r.value.set(e,p),i.value.set(e,m),h&&l&&a.value.set(e,l),c.value++}function v(e,s,l,u){t.value.set(e,[...s]),n.value.set(e,l?[...l]:s.map(()=>new Date().toISOString())),r.value.set(e,u?.sessionIds?[...u.sessionIds]:s.map(()=>null)),i.value.set(e,u?.eventIds?[...u.eventIds]:s.map(()=>null)),u?.oldestId?a.value.set(e,u.oldestId):a.value.delete(e),u&&typeof u.hasMoreOlder==`boolean`?o.value.set(e,u.hasMoreOlder):o.value.delete(e),c.value++}function y(e,s,l,u){if(s.length===0){o.value.set(e,u.hasMoreOlder),c.value++;return}let d=t.value.get(e)??[],f=n.value.get(e)??[],p=r.value.get(e)??[],m=i.value.get(e)??[],h=u.sessionIds??s.map(()=>null),g=u.eventIds??s.map(()=>null);t.value.set(e,[...s,...d]),n.value.set(e,[...l,...f]),r.value.set(e,[...h,...p]),i.value.set(e,[...g,...m]),u.oldestId&&a.value.set(e,u.oldestId),o.value.set(e,u.hasMoreOlder),c.value++}function b(e,a){let o=t.value.get(e),s=i.value.get(e);if(!o||!s)return;let l=s.indexOf(a);if(l===-1)return;let u=n.value.get(e),d=r.value.get(e);o.splice(l,1),s.splice(l,1),u&&u.splice(l,1),d&&d.splice(l,1),c.value++}function x(e){t.value.delete(e),n.value.delete(e),r.value.delete(e),i.value.delete(e),a.value.delete(e),o.value.delete(e),s.value.delete(e),c.value++}return{events:t,timestamps:n,sessionIds:r,eventIds:i,version:c,eventsFor:d,timestampsFor:f,sessionIdsFor:p,eventIdsFor:m,oldestIdFor:h,hasMoreOlderFor:g,isCompacting:l,setCompacting:u,append:_,reset:v,prepend:y,removeByEventId:b,clear:x}}),gn=F(`devServer`,{state:()=>({statuses:{},logs:{}}),getters:{getStatus:e=>t=>e.statuses[t]??null},actions:{async fetchStatus(e){try{let t=await fetch(`/api/dev-server/${e}/status`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){console.error(`[dev-server store] fetchStatus failed:`,e)}},async startDevServer(e){try{let t=await fetch(`/api/dev-server/${e}/start`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){throw console.error(`[dev-server store] startDevServer failed:`,e),e}},async stopDevServer(e){try{let t=await fetch(`/api/dev-server/${e}/stop`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){throw console.error(`[dev-server store] stopDevServer failed:`,e),e}},async fetchLogs(e,t=200){try{let n=await fetch(`/api/dev-server/${e}/logs?tail=${t}`);if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json();return this.logs[e]=r.logs,r.logs}catch(e){return console.error(`[dev-server store] fetchLogs failed:`,e),``}},updateFromWsEvent(e,t){this.statuses[e]=t}}});function _n(e){return e.state===`OPEN`&&e.reviewDecision===`CHANGES_REQUESTED`&&e.reviewers.some(e=>e.state===`CHANGES_REQUESTED`)}function vn(e){return e.state===`OPEN`&&e.ci.rollup===`FAILURE`}function yn(e){return e?vn(e)||_n(e):!1}var bn=[`executing`,`extracting`,`brainstorming`];function xn(e){return!!e&&bn.includes(e)}function Sn(e){"@babel/helpers - typeof";return Sn=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},Sn(e)}function Cn(e,t){if(Sn(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(Sn(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function wn(e){var t=Cn(e,`string`);return Sn(t)==`symbol`?t:t+``}function Tn(e,t,n){return(t=wn(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var En=class extends Error{constructor(e,t){super(e),Tn(this,`code`,void 0),this.name=`WorkspaceActionError`,this.code=t}};function Dn(e){return e===`running`?`in_progress`:e}var On=5e3,kn=500,An=null;function jn(e){return e===`claude-code`?`claude-code`:null}var G=F(`workspace`,{state:()=>({workspaces:[],selectedWorkspaceId:null,tasks:[],activityFeeds:{},activityFeedIds:{},activityCounts:{},subagents:{},agentTodos:{},sessions:[],selectedSessionId:null,archivedWorkspaces:[],archivedLoaded:!1,loading:!1,loadingOlderEvents:!1,hasMoreEvents:{},providerUsage:{},chatDraft:``,queuedMessages:{},gitRefreshTrigger:0,gitStatsCache:{},pendingWakeups:{},pendingQuotaBackoffs:{},pendingDeferred:{},pendingQueue:{},prSnapshots:{},autoLoopStates:{},crons:{}}),getters:{selectedWorkspace:e=>e.workspaces.find(t=>t.id===e.selectedWorkspaceId)??e.archivedWorkspaces.find(t=>t.id===e.selectedWorkspaceId)??null,needsAttention(e){return e.workspaces.filter(t=>[`error`,`quota`,`awaiting-user`].includes(t.status)||yn(e.prSnapshots[t.id])||!xn(t.status)&&!!e.prSnapshots[t.id]?.readyToMerge)},running(e){return e.workspaces.filter(t=>xn(t.status)&&!yn(e.prSnapshots[t.id]))},idle(e){return e.workspaces.filter(t=>[`completed`,`idle`,`created`].includes(t.status)&&!yn(e.prSnapshots[t.id])&&!e.prSnapshots[t.id]?.readyToMerge)},favorites(e){return e.workspaces.filter(e=>e.favoritedAt!==null)},currentAgentTodos:e=>e.selectedWorkspaceId?e.agentTodos[e.selectedWorkspaceId]??[]:[],currentSubagents:e=>{if(!e.selectedWorkspaceId)return[];let t=e.subagents[e.selectedWorkspaceId]??{};return Object.values(t).sort((e,t)=>e.startedAt.localeCompare(t.startedAt))},activityFeed:e=>{if(!e.selectedWorkspaceId)return[];let t=e.activityFeeds[e.selectedWorkspaceId]??[];if(!e.selectedSessionId)return e.sessions.length===0?t:[];let n=e.sessions.find(t=>t.id===e.selectedSessionId)?.engineSessionId??null,r=e.sessions.length>0?e.sessions[e.sessions.length-1].id:null,i=e.selectedSessionId===r;return t.filter(t=>t.sessionId?t.sessionId===e.selectedSessionId||n!==null&&t.sessionId===n:i)},acceptanceCriteria:e=>e.tasks.filter(e=>e.isAcceptanceCriterion),archived:e=>e.archivedWorkspaces,currentProviderUsage(e){let t=e.workspaces.find(t=>t.id===e.selectedWorkspaceId);if(!t)return null;let n=jn(t.engine);return n?e.providerUsage[n]??null:null}},actions:{async toggleFavorite(e){let t=this.workspaces.find(t=>t.id===e);if(!t)return;let n=t.favoritedAt,r=n===null,i=r?new Date().toISOString():null;this.workspaces=this.workspaces.map(t=>t.id===e?{...t,favoritedAt:i}:t);try{let t=await fetch(`/api/workspaces/${e}/favorite`,{method:r?`POST`:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.workspaces=this.workspaces.map(t=>t.id===e?n:t)}catch(t){throw this.workspaces=this.workspaces.map(t=>t.id===e?{...t,favoritedAt:n}:t),t}},async setWorkspaceTags(e,t){let n=this.workspaces.find(t=>t.id===e);if(!n)return;let r=n.tags,i=[...t];this.workspaces=this.workspaces.map(t=>t.id===e?{...t,tags:i}:t);try{let n=await fetch(`/api/workspaces/${e}/tags`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({tags:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json();this.workspaces=this.workspaces.map(t=>t.id===e?r:t)}catch(t){throw this.workspaces=this.workspaces.map(t=>t.id===e?{...t,tags:r}:t),t}},async fetchOrphanWorktrees(e){let t=`/api/git/orphan-worktrees?projectPath=${encodeURIComponent(e)}`,n=await fetch(t,{cache:`no-store`});if(!n.ok)throw Error(`HTTP ${n.status}`);return n.json()},async fetchWorkspaces(){this.loading=!0;try{let e=await fetch(`/api/workspaces`);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();this.workspaces=t.workspaces??t;for(let e of this.workspaces)[`completed`,`idle`,`error`,`quota`].includes(e.status)&&this.finalizeRunningSubagents(e.id)}catch(e){console.error(`[workspace store] fetchWorkspaces failed:`,e)}finally{this.loading=!1}},async fetchArchivedWorkspaces(){try{let e=await fetch(`/api/workspaces/archived`);if(!e.ok)throw Error(`HTTP ${e.status}`);this.archivedWorkspaces=await e.json(),this.archivedLoaded=!0}catch(e){console.error(`[workspace store] fetchArchivedWorkspaces failed:`,e)}},async fetchWorkspaceDetails(e){try{let t=await fetch(`/api/workspaces/${e}`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(this.selectedWorkspaceId!==e)return;let r=n.workspace??n,i=this.workspaces.findIndex(t=>t.id===e);if(i>=0)this.workspaces[i]={...this.workspaces[i],...r};else{let t=this.archivedWorkspaces.findIndex(t=>t.id===e);t>=0?this.archivedWorkspaces[t]={...this.archivedWorkspaces[t],...r}:r?.archivedAt&&this.archivedWorkspaces.unshift(r)}n.tasks&&(this.tasks=n.tasks)}catch(e){console.error(`[workspace store] fetchWorkspaceDetails failed:`,e)}},async createWorkspace(e){try{let t=await fetch(`/api/workspaces`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=t.headers.get(`X-Kobo-Branch-Adjusted`)===`1`,r=await t.json(),i=r.workspace??r,a=this.workspaces.findIndex(e=>e.id===i.id);return a>=0?this.workspaces[a]=i:this.workspaces.push(i),e.autoLoop&&this.fetchAutoLoopStates(),i._branchAdjusted=n,i}catch(e){throw console.error(`[workspace store] createWorkspace failed:`,e),e}},async startWorkspace(e,t,n,r){try{let i=await fetch(`/api/workspaces/${e}/start`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:t,agentSessionId:n,resume:r})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await this.fetchWorkspaces()}catch(e){throw console.error(`[workspace store] startWorkspace failed:`,e),e}},async stopWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/stop`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);await this.fetchWorkspaces()}catch(e){throw console.error(`[workspace store] stopWorkspace failed:`,e),e}},async interruptAgent(e){try{let t=await fetch(`/api/workspaces/${e}/interrupt`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}}catch(e){throw console.error(`[workspace store] interruptAgent failed:`,e),e}},async deleteWorkspace(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t??{})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=[];if(n.status===200){let e=await n.json().catch(()=>({}));r=Array.isArray(e.warnings)?e.warnings:[]}return this.workspaces=this.workspaces.filter(t=>t.id!==e),this.archivedWorkspaces=this.archivedWorkspaces.filter(t=>t.id!==e),delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e],delete this.subagents[e],delete this.agentTodos[e],this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]),{warnings:r}}catch(e){throw console.error(`[workspace store] deleteWorkspace failed:`,e),e}},async deleteAllArchived(e){try{let t=this.archivedWorkspaces.map(e=>e.id),n=await fetch(`/api/workspaces/archived`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e??{})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json().catch(()=>({})),i=typeof r.deleted==`number`?r.deleted:0,a=Array.isArray(r.warnings)?r.warnings:[];this.archivedWorkspaces=[];for(let e of t)delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e],delete this.subagents[e],delete this.agentTodos[e],this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]);return{deleted:i,warnings:a,ids:t}}catch(e){throw console.error(`[workspace store] deleteAllArchived failed:`,e),e}},async updateModel(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({model:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateModel failed:`,e),e}},async updateWorkspaceDescription(e,t){let n=this.workspaces.findIndex(t=>t.id===e);if(n<0)throw Error(`Workspace '${e}' not found in store`);let r=this.workspaces[n].description;this.workspaces[n]={...this.workspaces[n],description:t};try{let r=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({description:t})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error??`HTTP ${r.status}`)}let i=await r.json();this.workspaces[n]={...this.workspaces[n],...i}}catch(t){let n=this.workspaces.findIndex(t=>t.id===e);throw n>=0&&(this.workspaces[n]={...this.workspaces[n],description:r}),t}},async updateReasoningEffort(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({reasoningEffort:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateReasoningEffort failed:`,e),e}},async renameWorkspaceBranch(e,t){let n=await fetch(`/api/workspaces/${e}/rename-branch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({newName:t})}),r=await n.json().catch(()=>null);if(!n.ok)throw new En(r?.error??`Rename failed`,r?.code);let i=r,a=this.workspaces.findIndex(t=>t.id===e);return a>=0&&(this.workspaces[a]=i),i},async resyncWorkspaceBranch(e){let t=await fetch(`/api/workspaces/${e}/resync-branch`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(n.changed){let t=this.workspaces.findIndex(t=>t.id===e);t>=0&&(this.workspaces[t]={...this.workspaces[t],workingBranch:n.workingBranch})}return n},async updateAgentPermissionMode(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agentPermissionMode:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateAgentPermissionMode failed:`,e),e}},async pushBranch(e,t={}){let n=await fetch(`/api/workspaces/${e}/push`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({force:t.force===!0})});if(!n.ok){let e=await n.json().catch(()=>({error:`Push failed`}));throw new En(e.error??`Push failed`,e.code)}},async fetchGitStats(e,t={}){let n=`/api/workspaces/${e}/git-stats${t.freshFetch?`?freshFetch=1`:``}`,r=await fetch(n,{signal:t.signal});if(!r.ok)throw Error(`HTTP ${r.status}`);let i=await r.json();return this.gitStatsCache[e]=i,i},async fetchBranchDivergence(e,t={}){let n=`/api/workspaces/${e}/branch-divergence?limit=${t.limit??50}`,r=await fetch(n,{signal:t.signal});if(!r.ok)throw Error(`HTTP ${r.status}`);return await r.json()},async openPullRequest(e){let t=await fetch(`/api/workspaces/${e}/open-pr`,{method:`POST`}),n=await t.json().catch(()=>null);if(!t.ok)throw new En(n?.error??`Open PR failed`,n?.code);return n},async archiveWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/archive`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();return this.workspaces=this.workspaces.filter(t=>t.id!==e),this.archivedLoaded&&this.archivedWorkspaces.unshift(n),this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]),n}catch(e){throw console.error(`[workspace store] archiveWorkspace failed:`,e),e}},async unarchiveWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/unarchive`,{method:`POST`});if(!t.ok){if(t.status===409){let e=await t.json().catch(()=>({})),n=Error(e.error??`worktree-purged`);throw n.code=`worktree-purged`,n}throw Error(`HTTP ${t.status}`)}let n=await t.json();return this.archivedWorkspaces=this.archivedWorkspaces.filter(t=>t.id!==e),this.workspaces.unshift(n),n}catch(e){throw console.error(`[workspace store] unarchiveWorkspace failed:`,e),e}},async createTask(e,t,n){try{let r=await fetch(`/api/workspaces/${e}/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:t,isAcceptanceCriterion:n})});if(!r.ok)throw Error(`HTTP ${r.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] createTask failed:`,e),e}},async updateTaskTitle(e,t,n){try{let r=await fetch(`/api/workspaces/${e}/tasks/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:n})});if(!r.ok)throw Error(`HTTP ${r.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] updateTaskTitle failed:`,e),e}},async deleteTask(e,t){try{let n=await fetch(`/api/workspaces/${e}/tasks/${t}`,{method:`DELETE`});if(!n.ok)throw Error(`HTTP ${n.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] deleteTask failed:`,e),e}},selectWorkspace(e){this.selectedWorkspaceId=e,this.selectedSessionId=null,this.tasks=[],this.markRead(e),this.fetchWorkspaceDetails(e),this.fetchSessions(e),this.fetchPendingQuotaBackoff(e),this.fetchGitStats(e).catch(()=>{}),this.activityFeeds[e]?.length||zn().subscribe(e)},async fetchSessions(e,t){try{let n=await fetch(`/api/workspaces/${e}/sessions`);if(!n.ok)throw Error(`HTTP ${n.status}`);if(this.selectedWorkspaceId!==e)return;if(this.sessions=await n.json(),t&&this.sessions.some(e=>e.id===t)){this.selectSession(t);return}let r=this.selectedSessionId&&this.sessions.some(e=>e.id===this.selectedSessionId);if(this.sessions.length>0&&!r){let t=localStorage.getItem(`kobo:session:${e}`),n=t?this.sessions.find(e=>e.id===t):null;this.selectSession(n?n.id:this.sessions[0].id)}}catch(e){console.error(`[workspace store] fetchSessions failed:`,e)}},async fetchOlderEvents(e){if(this.loadingOlderEvents||this.hasMoreEvents[e]===!1)return!1;let t=this.activityFeeds[e];if(!t?.length)return!1;let n=t[0].id;this.loadingOlderEvents=!0;try{let t=await fetch(`/api/workspaces/${e}/events?before=${encodeURIComponent(n)}&limit=100`);if(!t.ok)throw Error(`HTTP ${t.status}`);let r=await t.json();if(this.hasMoreEvents[e]=r.hasMore,r.events.length>0){let e=zn();for(let t of r.events)e._routeMessage(t)}return r.events.length>0}catch(e){return console.error(`[workspace store] fetchOlderEvents failed:`,e),!1}finally{this.loadingOlderEvents=!1}},selectSession(e){this.selectedSessionId=e,this.selectedWorkspaceId&&localStorage.setItem(`kobo:session:${this.selectedWorkspaceId}`,e)},async createSession(e){try{let t=await fetch(`/api/workspaces/${e}/sessions`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}let n=await t.json();return this.sessions.unshift(n),this.selectSession(n.id),n}catch(e){throw console.error(`[workspace store] createSession failed:`,e),e}},async renameWorkspace(e,t){let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]={...this.workspaces[i],...r});let a=this.archivedWorkspaces.findIndex(t=>t.id===e);a>=0&&(this.archivedWorkspaces[a]={...this.archivedWorkspaces[a],...r})},async renameSession(e,t,n){let r=await fetch(`/api/workspaces/${e}/sessions/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:n})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error??`HTTP ${r.status}`)}let i=await r.json().catch(()=>null),a=this.sessions.find(e=>e.id===t);a&&(a.name=i?.name??n)},addActivityItem(e,t){if(this.activityFeeds[e]||(this.activityFeeds[e]=[]),this.activityFeedIds[e]||(this.activityFeedIds[e]=new Set),this.activityCounts[e]||(this.activityCounts[e]={toolUses:0,agentMessages:0,userMessages:0,errors:0}),t.meta?.sender!==`user`&&t.meta?.sender!==`system-prompt`)for(let t of this.activityFeeds[e])t.meta?.pending&&(t.meta.pending=!1);if(!this.activityFeedIds[e].has(t.id)){this.activityFeedIds[e].add(t.id),this.activityFeeds[e].push(t);let n=this.activityCounts[e];t.type===`tool_use`?n.toolUses++:t.type===`error`&&n.errors++,t.meta?.sender===`user`?n.userMessages++:t.type===`text`&&t.meta?.sender!==`system-prompt`&&n.agentMessages++}let n=this.activityFeeds[e];if(n.length>On){let t=n.splice(0,n.length-On),r=this.activityFeedIds[e];for(let e of t)r.delete(e.id)}},removeActivityItem(e,t){let n=this.activityFeeds[e],r=this.activityFeedIds[e];if(!n||!r)return;let i=n.findIndex(e=>e.id===t);if(i<0)return;let[a]=n.splice(i,1);r.delete(t);let o=this.activityCounts[e];o&&a&&(a.type===`tool_use`?o.toolUses=Math.max(0,o.toolUses-1):a.type===`error`&&(o.errors=Math.max(0,o.errors-1)),a.meta?.sender===`user`?o.userMessages=Math.max(0,o.userMessages-1):a.type===`text`&&a.meta?.sender!==`system-prompt`&&(o.agentMessages=Math.max(0,o.agentMessages-1)))},clearActivityFeed(e){e?(delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e]):(this.activityFeeds={},this.activityFeedIds={},this.activityCounts={})},applyUsageSnapshot(e){this.providerUsage[e.providerId]=e.snapshot},async requestUsageRefresh(e){try{await fetch(`/api/usage/${e}/refresh`,{method:`POST`})}catch(e){console.error(`[workspace store] requestUsageRefresh failed:`,e)}},triggerGitRefresh(){this.gitRefreshTrigger++,this.schedulePrSnapshotsRefresh()},schedulePrSnapshotsRefresh(){An!==null&&clearTimeout(An),An=setTimeout(()=>{An=null,this.fetchPrSnapshots()},kn)},async fetchPrSnapshots(){try{let e=await fetch(`/api/workspaces/pr-states`,{cache:`no-store`});if(!e.ok)return;this.prSnapshots=await e.json()}catch(e){console.error(`[workspace-store] fetchPrSnapshots failed:`,e)}},async fetchWorkspacesInfo(){try{let e=await fetch(`/api/workspaces/info`,{cache:`no-store`});if(!e.ok)return;let t=await e.json();this.workspaces=t.workspaces;for(let e of this.workspaces)[`completed`,`idle`,`error`,`quota`].includes(e.status)&&this.finalizeRunningSubagents(e.id);this.prSnapshots=t.prSnapshots,this.gitStatsCache={...this.gitStatsCache,...t.gitStats}}catch(e){console.error(`[workspace-store] fetchWorkspacesInfo failed:`,e)}},async refreshPrSnapshot(e){try{let t=await fetch(`/api/workspaces/pr-snapshot/refresh/${e}`,{method:`POST`});if(t.status===404){let t={...this.prSnapshots};return delete t[e],this.prSnapshots=t,null}if(!t.ok)return console.error(`[workspace-store] refreshPrSnapshot non-OK:`,t.status),null;let n=await t.json();return this.prSnapshots={...this.prSnapshots,[e]:n.snapshot},n.snapshot}catch(e){return console.error(`[workspace-store] refreshPrSnapshot failed:`,e),null}},async fetchAutoLoopStates(){try{let e=await fetch(`/api/workspaces/auto-loop-states`,{cache:`no-store`});if(!e.ok)return;this.autoLoopStates=await e.json()}catch(e){console.error(`[workspace-store] fetchAutoLoopStates failed:`,e)}},async enableAutoLoop(e){let t=this.workspaces.find(t=>t.id===e);if(t&&t.agentPermissionMode===`plan`)try{await this.updateAgentPermissionMode(e,`bypass`)}catch{}let n=await fetch(`/api/workspaces/${e}/auto-loop`,{method:`POST`});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}await this.fetchAutoLoopStates()},async disableAutoLoop(e){let t=await fetch(`/api/workspaces/${e}/auto-loop`,{method:`DELETE`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}await this.fetchAutoLoopStates()},async forceAutoLoopReady(e){let t=await fetch(`/api/workspaces/${e}/auto-loop-ready`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);await this.fetchAutoLoopStates()},setAutoLoopState(e,t){this.autoLoopStates[e]=t},clearAutoLoopState(e){delete this.autoLoopStates[e]},async fetchCrons(e){try{let t=await fetch(`/api/workspaces/${e}/crons`);if(!t.ok)return;let n=await t.json();this.crons[e]=n.crons}catch(e){console.error(`[workspace-store] fetchCrons failed:`,e)}},async cancelCron(e,t){let n=this.crons[e]??[];this.crons[e]=n.filter(e=>e.id!==t);try{let n=await fetch(`/api/workspaces/${e}/crons/${t}`,{method:`DELETE`});if(!n.ok)throw Error(`HTTP ${n.status}`)}catch(t){throw this.crons[e]=n,t}},async fetchPendingWakeup(e){try{let t=await fetch(`/api/workspaces/${e}/pending-wakeup`,{cache:`no-store`});if(!t.ok)return;let n=await t.json();n?this.pendingWakeups[e]=n:delete this.pendingWakeups[e]}catch(e){console.error(`[workspace-store] fetchPendingWakeup failed:`,e)}},setPendingWakeup(e,t){this.pendingWakeups[e]=t},clearPendingWakeup(e){delete this.pendingWakeups[e]},async cancelPendingWakeup(e){let t=this.pendingWakeups[e]!==void 0;delete this.pendingWakeups[e];try{let t=await fetch(`/api/workspaces/${e}/pending-wakeup`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`)}catch(n){console.error(`[workspace-store] cancelPendingWakeup failed:`,n),t&&await this.fetchPendingWakeup(e)}},async fetchPendingQuotaBackoff(e){try{let t=await fetch(`/api/workspaces/${e}/quota-backoff`,{cache:`no-store`});if(!t.ok)return;let n=await t.json();n?this.pendingQuotaBackoffs[e]=n:delete this.pendingQuotaBackoffs[e]}catch(e){console.error(`[workspace-store] fetchPendingQuotaBackoff failed:`,e)}},setPendingQuotaBackoff(e,t){this.pendingQuotaBackoffs[e]=t},clearPendingQuotaBackoff(e){delete this.pendingQuotaBackoffs[e]},async cancelQuotaBackoff(e){let t=this.pendingQuotaBackoffs[e]!==void 0;delete this.pendingQuotaBackoffs[e];try{let t=await fetch(`/api/workspaces/${e}/quota-backoff`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`)}catch(n){console.error(`[workspace-store] cancelQuotaBackoff failed:`,n),t&&await this.fetchPendingQuotaBackoff(e)}},enqueuePending(e,t){let n=this.pendingQueue[e]??[];n.some(e=>e.toolCallId===t.toolCallId)||(n.push(t),this.pendingQueue[e]=n,t.kind===`question`&&(this.pendingDeferred[e]={toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,agentSessionId:t.agentSessionId}))},peekPending(e){return this.pendingQueue[e]?.[0]},dequeuePending(e){let t=this.pendingQueue[e];if(!t||t.length===0)return;let n=t.shift();t.length===0&&delete this.pendingQueue[e];let r=this.pendingQueue[e]?.[0];return r&&r.kind===`question`?this.pendingDeferred[e]={toolCallId:r.toolCallId,toolName:r.toolName,input:r.input,agentSessionId:r.agentSessionId}:delete this.pendingDeferred[e],n},clearPendingForSession(e,t){if(t===null)return;let n=this.pendingQueue[e];if(!n)return;let r=n.filter(e=>e.agentSessionId!==t);r.length===0?delete this.pendingQueue[e]:this.pendingQueue[e]=r;let i=this.pendingDeferred[e];i&&i.agentSessionId===t&&delete this.pendingDeferred[e]},clearAllPending(e){delete this.pendingQueue[e],delete this.pendingDeferred[e]},setPendingDeferred(e,t){this.enqueuePending(e,{kind:`question`,agentSessionId:t.agentSessionId,toolCallId:t.toolCallId,toolName:t.toolName,input:t.input})},clearPendingDeferred(e,t=null){if(t===null){this.clearAllPending(e);return}this.clearPendingForSession(e,t)},getPendingDeferred(e){let t=this.peekPending(e);if(!(!t||t.kind!==`question`))return{toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,agentSessionId:t.agentSessionId}},async submitDeferredAnswer(e,t,n){let r=await fetch(`/api/workspaces/${e}/deferred-tool-use/answer`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answers:t,toolCallId:n})});if(!r.ok){let t=(await r.json().catch(()=>({}))).error??`HTTP ${r.status}`;if(/no deferred tool use pending/i.test(t)){console.warn(`[workspace] submitDeferredAnswer: backend has no pending — clearing zombie panel locally`),this.dequeuePending(e),this.fetchWorkspaces();return}throw Error(t)}this.dequeuePending(e),this.fetchWorkspaces()},async cancelDeferredAnswer(e,t,n){let r=await fetch(`/api/workspaces/${e}/deferred-tool-use/cancel`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({reason:t,toolCallId:n})});if(!r.ok){let t=(await r.json().catch(()=>({}))).error??`HTTP ${r.status}`;if(/no deferred tool use pending/i.test(t)){console.warn(`[workspace] cancelDeferredAnswer: backend has no pending — clearing zombie panel locally`),this.dequeuePending(e),this.fetchWorkspaces();return}throw Error(t)}this.dequeuePending(e),this.fetchWorkspaces()},async submitDeferredPermission(e,t,n,r){let i=await fetch(`/api/workspaces/${e}/deferred-permission/decision`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({toolCallId:t,decision:n,reason:r})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}this.dequeuePending(e),this.fetchWorkspaces()},updateAgentTodos(e,t){this.agentTodos[e]=t},agentTaskCreate(e,t,n){let r=this.agentTodos[e]?[...this.agentTodos[e]]:[];r.some(e=>e.id===t)||(r.push({id:t,content:n.subject||n.description||``,status:`pending`,activeForm:n.activeForm}),this.agentTodos[e]=r)},agentTaskSetNumber(e,t,n){let r=this.agentTodos[e];r&&(this.agentTodos[e]=r.map(e=>e.id===t?{...e,taskNumber:n}:e))},agentTaskUpdate(e,t,n){let r=this.agentTodos[e];if(r){if(n.status===`deleted`){this.agentTodos[e]=r.filter(e=>e.taskNumber!==t);return}this.agentTodos[e]=r.map(e=>e.taskNumber===t?{...e,status:n.status?Dn(n.status):e.status,content:n.content??e.content,activeForm:n.activeForm??e.activeForm}:e)}},finalizeRunningSubagents(e){let t=this.subagents[e];if(!t)return;let n=new Date().toISOString();for(let e of Object.keys(t)){let r=t[e];r.status===`running`&&(t[e]={...r,status:`done`,updatedAt:n})}},upsertSubagent(e,t){this.subagents[e]||(this.subagents[e]={});let n=this.subagents[e][t.toolUseId],r=new Date().toISOString(),i=n?.status===`done`?`done`:t.status??n?.status??`running`;this.subagents[e][t.toolUseId]={toolUseId:t.toolUseId,description:t.description??n?.description??``,taskType:t.taskType??n?.taskType,status:i,lastToolName:t.lastToolName??n?.lastToolName,lastDescription:t.lastDescription??n?.lastDescription,totalTokens:t.totalTokens??n?.totalTokens,toolUses:t.toolUses??n?.toolUses,durationMs:t.durationMs??n?.durationMs,startedAt:n?.startedAt??r,updatedAt:r}},async markRead(e){try{let t=await fetch(`/api/workspaces/${e}/mark-read`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=this.workspaces.findIndex(t=>t.id===e);n>=0&&(this.workspaces[n]={...this.workspaces[n],hasUnread:!1})}catch(e){console.error(`[workspace store] markRead failed:`,e)}},async purgeWorktree(e){try{let t=await fetch(`/api/workspaces/${e}/purge-worktree`,{method:`POST`}),n=await t.json();if(!t.ok)return{ok:!1,error:n.error??`HTTP ${t.status}`};let r=n.workspace;return r&&(this.updateWorkspaceFromEvent(e,{archivedAt:r.archivedAt,worktreePurgedAt:r.worktreePurgedAt,worktreePurgeRestoreData:r.worktreePurgeRestoreData}),r.archivedAt&&this.archivedLoaded&&(this.archivedWorkspaces.some(t=>t.id===e)||this.archivedWorkspaces.unshift(r),this.workspaces=this.workspaces.filter(t=>t.id!==e),this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]))),{ok:!0,warnings:n.warnings??[]}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async dismissPrAttention(e,t){let n=this.prSnapshots[e];if(n)try{let r=await fetch(`/api/workspaces/${e}/dismiss-pr-attention`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kind:t,prUpdatedAt:n.updatedAt})});if(!r.ok)throw Error(`HTTP ${r.status}`);let i=t===`changes-requested`?{prChangesDismissedAt:n.updatedAt}:{prCiFailureDismissedAt:n.updatedAt};this.updateWorkspaceFromEvent(e,i)}catch(e){console.error(`[workspace store] dismissPrAttention failed:`,e)}},async restorePrAttention(e,t){try{let n=await fetch(`/api/workspaces/${e}/restore-pr-attention`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kind:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=t===`changes-requested`?{prChangesDismissedAt:null}:{prCiFailureDismissedAt:null};this.updateWorkspaceFromEvent(e,r)}catch(e){console.error(`[workspace store] restorePrAttention failed:`,e)}},queueMessage(e,t,n){this.queuedMessages[e]={content:t,sessionId:n}},cancelQueuedMessage(e){delete this.queuedMessages[e]},updateWorkspaceFromEvent(e,t){let n=this.workspaces.findIndex(t=>t.id===e);if(n>=0&&(this.workspaces[n]={...this.workspaces[n],...t}),t.status&&[`completed`,`idle`,`error`,`quota`].includes(t.status)){let n=this.activityFeeds[e];if(n)for(let e of n)e.meta?.pending&&(e.meta.pending=!1);let r=this.subagents[e];if(r)for(let[e,t]of Object.entries(r))t.status===`running`&&(r[e]={...t,status:`done`});let i=this.queuedMessages[e];(t.status===`completed`||t.status===`idle`)&&i&&(delete this.queuedMessages[e],zn().sendChatMessage(e,i.content,i.sessionId),this.addActivityItem(e,{id:`user-${Date.now()}`,type:`text`,content:i.content,timestamp:new Date().toISOString(),sessionId:i.sessionId,meta:{sender:`user`,pending:!0}}))}}}}),K=mn.global.t,q=null,Mn=null,Nn=0,Pn=!1;function Fn(e){Pn=e}function In(e,t,n){if(t.kind!==`session:started`)return;let r=G();if(n){let t=r.peekPending(e);t&&t.agentSessionId===n&&r.dequeuePending(e)}let i=r.workspaces.find(t=>t.id===e);i&&(i.status===`completed`||i.status===`idle`||i.status===`error`||i.status===`quota`)&&r.updateWorkspaceFromEvent(e,{status:`executing`}),!Pn&&n&&r.selectedWorkspaceId===e&&r.selectedSessionId!==n&&r.fetchSessions(e,n).catch(e=>{console.error(`[websocket] fetchSessions on session:started failed:`,e)})}function Ln(e,t){let n=G();if(t.kind===`tool:call`&&t.name===`TodoWrite`){let r=t.input?.todos;return Array.isArray(r)&&n.updateAgentTodos(e,r.map(e=>({content:typeof e.content==`string`?e.content:``,status:typeof e.status==`string`?e.status:`pending`,activeForm:typeof e.activeForm==`string`?e.activeForm:void 0}))),!0}if(t.kind===`tool:call`&&t.name===`TaskCreate`){let r=t.input??{};return n.agentTaskCreate(e,t.toolCallId,{subject:typeof r.subject==`string`?r.subject:void 0,description:typeof r.description==`string`?r.description:void 0,activeForm:typeof r.activeForm==`string`?r.activeForm:void 0}),!0}if(t.kind===`tool:result`&&typeof t.output==`string`){let r=t.output.match(/^Task #(\d+) created successfully/);if(r)return n.agentTaskSetNumber(e,t.toolCallId,Number(r[1])),!0}if(t.kind===`tool:call`&&t.name===`TaskUpdate`){let r=t.input??{},i=r.task_id??r.taskId??r.id,a=typeof i==`number`?i:typeof i==`string`?Number(i):NaN;return Number.isFinite(a)&&n.agentTaskUpdate(e,a,{status:typeof r.status==`string`?r.status:void 0,content:typeof r.subject==`string`?r.subject:void 0,activeForm:typeof r.activeForm==`string`?r.activeForm:void 0}),!0}return!1}function Rn(e,t,n,r,i){let a=hn();if(t.kind===`session:compacting`){a.setCompacting(e,t.active);return}a.append(e,t,n,r,i),(t.kind===`session:compacted`||t.kind===`session:ended`||t.kind===`message:text`||t.kind===`tool:call`)&&a.setCompacting(e,!1),In(e,t,i??void 0);let o=G();if(t.kind===`session:user-input-requested`){if(t.requestKind===`question`?o.enqueuePending(e,{kind:`question`,agentSessionId:i??null,toolCallId:t.toolCallId,toolName:t.toolName,input:t.payload}):o.enqueuePending(e,{kind:`permission`,agentSessionId:i??null,toolCallId:t.toolCallId,toolName:t.toolName,toolInput:t.payload}),o.updateWorkspaceFromEvent(e,{status:`awaiting-user`}),!Pn){let n=o.workspaces.find(t=>t.id===e)?.name??``;z(t.requestKind===`question`?K(`notification.agentQuestion`,{name:n}):K(`notification.agentPermissionRequest`,{name:n}),void 0,e)}return}if(t.kind===`subagent:progress`){o.upsertSubagent(e,{toolUseId:t.toolCallId,status:t.status,description:t.description,taskType:t.taskType,lastToolName:t.lastToolName,totalTokens:t.totalTokens,toolUses:t.toolUses,durationMs:t.durationMs});return}if(!Ln(e,t)){if(t.kind===`tool:call`&&t.name===`Bash`){let n=t.input,r=`${n?.command??``} ${n?.description??``}`;/\bgit\b|commit|push|pull|merge|rebase|checkout|branch/i.test(r)&&o.triggerGitRefresh(),/\bgit\s+branch\s+-m\b/i.test(r)&&setTimeout(()=>{o.resyncWorkspaceBranch(e).catch(e=>{console.error(`[websocket] Branch resync failed:`,e)})},2500),/\bgh\s+pr\s+create\b/i.test(r)&&setTimeout(()=>o.triggerGitRefresh(),3e3)}if(t.kind===`tool:call`&&t.name===`ExitPlanMode`&&o.workspaces.find(t=>t.id===e)?.agentPermissionMode===`plan`&&(o.updateWorkspaceFromEvent(e,{agentPermissionMode:`bypass`}),o.updateAgentPermissionMode(e,`bypass`).catch(e=>{console.error(`[websocket] failed to persist ExitPlanMode flip:`,e)})),t.kind!==`session:started`){if(t.kind===`session:ended`){i&&o.clearPendingForSession(e,i);let n=o.workspaces.find(t=>t.id===e)?.status===`quota`?`quota`:t.reason===`completed`?`completed`:t.reason===`error`?`error`:`idle`;if(o.updateWorkspaceFromEvent(e,{status:n}),o.finalizeRunningSubagents(e),o.fetchWorkspaces(),!Pn&&t.reason!==`killed`&&o.autoLoopStates[e]?.auto_loop!==!0){let n=o.workspaces.find(t=>t.id===e)?.name??``;z(t.reason===`error`?K(`notification.agentError`,{name:n}):K(`notification.agentFinished`,{name:n}),void 0,e)}return}t.kind===`error`&&t.category===`quota`&&(o.updateWorkspaceFromEvent(e,{status:`quota`}),o.fetchWorkspaces())}}}var zn=F(`websocket`,{state:()=>({connected:!1,lastEventId:null,_replaying:!1}),actions:{connect(){if(q)return;let e=`${window.location.protocol===`https:`?`wss:`:`ws:`}//${window.location.host}/ws`,t=new WebSocket(e);q=t,t.addEventListener(`open`,()=>{this.connected=!0,Nn=0;let e=G().workspaces.map(e=>e.id);for(let t of e)this._send({type:`subscribe`,payload:{workspaceId:t}});this.lastEventId&&this._send({type:`sync:request`,payload:{lastEventId:this.lastEventId,workspaceIds:e}})}),t.addEventListener(`message`,e=>{try{let t=JSON.parse(e.data);this._routeMessage(t)}catch{}}),t.addEventListener(`close`,()=>{this.connected=!1,q=null,this._scheduleReconnect()}),t.addEventListener(`error`,()=>{})},disconnect(){Mn&&=(clearTimeout(Mn),null),q&&=(q.close(),null),this.connected=!1},subscribe(e){this._send({type:`subscribe`,payload:{workspaceId:e}}),this._send({type:`sync:request`,payload:{workspaceIds:[e]}})},unsubscribe(e){this._send({type:`unsubscribe`,payload:{workspaceId:e}})},sendChatMessage(e,t,n,r){this._send({type:`chat:message`,payload:{workspaceId:e,content:t,sessionId:n,agentPermissionModeOverride:r}}),/^\/compact(\s|$)/.test(t.trim())&&hn().setCompacting(e,!0);let i=G(),a=i.workspaces.find(t=>t.id===e);a&&(a.status===`completed`||a.status===`idle`||a.status===`error`||a.status===`quota`)&&i.updateWorkspaceFromEvent(e,{status:`executing`})},_send(e){q&&q.readyState===WebSocket.OPEN&&q.send(JSON.stringify(e))},isConnected(){return q!==null&&q.readyState===WebSocket.OPEN},_scheduleReconnect(){if(Mn)return;let e=Math.min(1e3*2**Nn,3e4);Nn++,Mn=setTimeout(()=>{Mn=null,this.connect()},e)},_routeMessage(e){let t=G();e.id?this.lastEventId=e.id:e.eventId&&(this.lastEventId=e.eventId);let n=e.payload??{},r=e.workspaceId??n.workspaceId??``;switch(e.type){case`agent:event`:{if(!r)break;let t=e.createdAt;Rn(r,n,t,e.id??e.eventId,e.sessionId??null);break}case`agent:progress`:n.tasks&&Array.isArray(n.tasks)&&(t.tasks=n.tasks);break;case`user:message`:if(r&&n.content){let i=n.content,a=n.sender??`user`,o=e.sessionId,s=e.id??e.eventId??`user-${Date.now()}`,c=e.createdAt??new Date().toISOString(),l=t.activityFeeds[r]??[];if(a===`user`&&l.some(e=>e.meta?.sender===`user`&&e.content===i&&e.meta?.pending)){let e=l.findIndex(e=>e.meta?.sender===`user`&&e.content===i&&e.meta?.pending);e>=0&&(l[e]={...l[e],id:s,sessionId:o})}else t.addActivityItem(r,{id:s,type:`text`,content:i,timestamp:c,sessionId:o,meta:{sender:a}})}break;case`sync:response`:this._replaying=!0,Fn(!0);try{let e=n.events??[],t=new Map;for(let n of e)if(n.type!==`sync:response`){if(n.type===`agent:event`&&n.workspaceId){let e=t.get(n.workspaceId)??{events:[],timestamps:[],sessionIds:[],eventIds:[],oldestId:void 0};e.events.push(n.payload),e.timestamps.push(n.createdAt),e.sessionIds.push(n.sessionId??null),e.eventIds.push(n.id??null),e.oldestId||=n.id,t.set(n.workspaceId,e);continue}this._routeMessage(n)}if(t.size>0){let e=hn();for(let[n,{events:r,timestamps:i,sessionIds:a,eventIds:o,oldestId:s}]of t){e.reset(n,r,i,{oldestId:s,hasMoreOlder:!0,sessionIds:a,eventIds:o}),G().updateAgentTodos(n,[]);for(let e=0;e<r.length;e++){let t=r[e];if(!t)continue;let i=a[e]??null;if(t.kind===`session:user-input-requested`){t.requestKind===`question`?G().enqueuePending(n,{kind:`question`,agentSessionId:i,toolCallId:t.toolCallId,toolName:t.toolName,input:t.payload}):G().enqueuePending(n,{kind:`permission`,agentSessionId:i,toolCallId:t.toolCallId,toolName:t.toolName,toolInput:t.payload});continue}if(t.kind===`session:started`){if(i){let e=G(),t=e.peekPending(n);t&&t.agentSessionId===i&&e.dequeuePending(n)}continue}if(t.kind===`session:ended`){i&&G().clearPendingForSession(n,i);continue}if(t.kind===`subagent:progress`){G().upsertSubagent(n,{toolUseId:t.toolCallId,status:t.status,description:t.description,taskType:t.taskType,lastToolName:t.lastToolName,totalTokens:t.totalTokens,toolUses:t.toolUses,durationMs:t.durationMs});continue}Ln(n,t)}}}}finally{this._replaying=!1,Fn(!1)}break;case`usage:snapshot`:{let e=n;e.providerId&&e.snapshot&&t.applyUsageSnapshot({providerId:e.providerId,snapshot:e.snapshot});break}case`devserver:status`:{let e=gn();r&&e.updateFromWsEvent(r,n);break}case`task:updated`:r&&t.fetchWorkspaceDetails(r);break;case`setup:output`:t.addActivityItem(r,{id:e.id??`setup-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`setup:complete`:t.addActivityItem(r,{id:e.id??`setup-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[setup] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`setup:error`:t.addActivityItem(r,{id:e.id??`setup-error-${Date.now()}`,type:`text`,content:`[setup] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`cleanup:output`:t.addActivityItem(r,{id:e.id??`cleanup-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`cleanup:complete`:t.addActivityItem(r,{id:e.id??`cleanup-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[cleanup] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`cleanup:error`:t.addActivityItem(r,{id:e.id??`cleanup-error-${Date.now()}`,type:`text`,content:`[cleanup] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`archive:output`:t.addActivityItem(r,{id:e.id??`archive-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`archive:complete`:t.addActivityItem(r,{id:e.id??`archive-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[archive] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`archive:error`:t.addActivityItem(r,{id:e.id??`archive-error-${Date.now()}`,type:`text`,content:`[archive] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`workspace:unread`:if(r){let e=n.hasUnread??!1;t.updateWorkspaceFromEvent(r,{hasUnread:e})}break;case`workspace:pr-attention-dismissed`:if(r){let e=n.kind,i=n.prUpdatedAt;e&&i&&t.updateWorkspaceFromEvent(r,e===`changes-requested`?{prChangesDismissedAt:i}:{prCiFailureDismissedAt:i})}break;case`workspace:description-updated`:{if(!r)break;let e=n.description??null;t.updateWorkspaceFromEvent(r,{description:e});break}case`workspace:agent-description-updated`:{if(!r)break;let e=n.agentDescription??null;t.updateWorkspaceFromEvent(r,{agentDescription:e});break}case`cron:created`:{if(!r)break;let e=n.cron;if(!e)break;let i=t.crons[r]??[];i.some(t=>t.id===e.id)||(t.crons[r]=[...i,e]);let a=t.autoLoopStates[r];a&&(a.crons_count=t.crons[r].length);break}case`cron:fired`:{if(!r)break;let e=n,i=t.crons[r]??[];t.crons[r]=i.map(t=>t.id===e.id?{...t,nextFireAt:e.nextFireAt??t.nextFireAt,lastFiredAt:e.lastFiredAt??new Date().toISOString()}:t);break}case`cron:cancelled`:{if(!r)break;let e=n.id;if(!e)break;t.crons[r]=(t.crons[r]??[]).filter(t=>t.id!==e);let i=t.autoLoopStates[r];i&&(i.crons_count=t.crons[r].length);break}case`cron:updated`:{if(!r)break;let e=n.crons;if(Array.isArray(e)){t.crons[r]=e;let n=t.autoLoopStates[r];n&&(n.crons_count=e.length)}break}case`workspace:archived`:case`workspace:unarchived`:case`workspace:worktree-restored`:e.type===`workspace:archived`&&r&&t.selectedWorkspaceId===r&&(t.selectedWorkspaceId=null),t.fetchWorkspaces(),t.archivedLoaded&&t.fetchArchivedWorkspaces();break;case`pr:base-changed`:{if(!r)break;let e=n,i=e.oldBase??``,a=e.newBase??``;t.updateWorkspaceFromEvent(r,{sourceBranch:a});let o=[];e.prUrl&&o.push({label:K(`pr.openPr`),color:`white`,noDismiss:!0,handler:()=>window.open(e.prUrl,`_blank`)}),o.push({label:K(`pr.dismiss`),color:`white`}),rn.create({type:`info`,position:`top`,timeout:0,message:K(`pr.baseChanged`,{oldBase:i,newBase:a}),actions:o}),z(K(`pr.baseChanged`,{oldBase:i,newBase:a}),void 0,r);break}case`pr:changes-requested`:{if(!r)break;let e=n,i=K(`toast.prChangesRequested`,{n:e.prNumber??0}),a=[];e.prUrl&&a.push({label:K(`pr.openPr`),color:`white`,noDismiss:!0,handler:()=>window.open(e.prUrl,`_blank`)}),a.push({label:K(`pr.dismiss`),color:`white`}),rn.create({type:`warning`,position:`top`,timeout:0,message:i,actions:a}),z(i,void 0,r),t.refreshPrSnapshot(r);break}case`pr:approved`:{if(!r)break;let e=K(`toast.prApproved`,{n:n.prNumber??0});rn.create({type:`positive`,position:`top`,timeout:5e3,message:e}),z(e,void 0,r),t.refreshPrSnapshot(r);break}case`pr:ready-to-merge`:{if(!r)break;let e=K(`toast.prReadyToMerge`,{n:n.prNumber??0});rn.create({type:`positive`,position:`top`,timeout:5e3,message:e}),z(e,void 0,r),t.refreshPrSnapshot(r);break}case`wakeup:scheduled`:if(r){let e=n;typeof e.targetAt==`string`&&t.setPendingWakeup(r,{targetAt:e.targetAt,reason:e.reason})}break;case`wakeup:cancelled`:case`wakeup:fired`:case`wakeup:skipped`:r&&t.clearPendingWakeup(r);break;case`agent:quota-backoff`:{if(!r)break;let e=n;typeof e.targetAt==`string`&&typeof e.source==`string`&&t.setPendingQuotaBackoff(r,{targetAt:e.targetAt,resetsAt:e.resetsAt??null,source:e.source});break}case`agent:quota-backoff-cancelled`:r&&t.clearPendingQuotaBackoff(r);break;case`autoloop:enabled`:case`autoloop:iteration-started`:case`autoloop:ready-flipped`:t.fetchAutoLoopStates();break;case`autoloop:permission-overridden`:r&&z(K(`notification.autoLoopPermissionOverridden`,{name:t.workspaces.find(e=>e.id===r)?.name??``}),void 0,r);break;case`autoloop:disabled`:if(t.fetchAutoLoopStates(),r){let e=n?.reason,i=t.workspaces.find(e=>e.id===r)?.name??``,a=e===`error`?`notification.autoLoopError`:e===`stall`?`notification.autoLoopStalled`:e===`completed`?`notification.autoLoopCompleted`:null;a&&z(K(a,{name:i}),void 0,r)}break;case`migration:progress`:case`migration:error`:Nt().update(n);break}}}}),Bn=c({__name:`App`,setup(e){let t=zn(),n=Vt();return r(()=>{t.connect(),n.fetchTemplates(),Pe()}),i(()=>{t.disconnect()}),(e,t)=>{let n=d(`router-view`);return s(),m(g,null,[h(n),h(Bt)],64)}}});function Vn(e){return e}function Hn(e){return e}function Un(e){return e}var Wn=Un(()=>ue()),Gn=typeof document<`u`;function Kn(e){return typeof e==`object`||`displayName`in e||`props`in e||`__vccOpts`in e}function qn(e){return e.__esModule||e[Symbol.toStringTag]===`Module`||e.default&&Kn(e.default)}var J=Object.assign;function Jn(e,t){let n={};for(let r in t){let i=t[r];n[r]=Y(i)?i.map(e):e(i)}return n}var Yn=()=>{},Y=Array.isArray;function Xn(e,t){let n={};for(let r in e)n[r]=r in t?t[r]:e[r];return n}var Zn=Symbol(``);function Qn(e,t){return J(Error(),{type:e,[Zn]:!0},t)}function X(e,t){return e instanceof Error&&Zn in e&&(t==null||!!(e.type&t))}var $n=Symbol(``),er=Symbol(``),tr=Symbol(``),nr=Symbol(``),rr=Symbol(``);function ir(){return n(tr)}function ar(e){return n(nr)}var or=/#/g,sr=/&/g,cr=/\//g,lr=/=/g,ur=/\?/g,dr=/\+/g,fr=/%5B/g,pr=/%5D/g,mr=/%5E/g,hr=/%60/g,gr=/%7B/g,_r=/%7C/g,vr=/%7D/g,yr=/%20/g;function br(e){return e==null?``:encodeURI(``+e).replace(_r,`|`).replace(fr,`[`).replace(pr,`]`)}function xr(e){return br(e).replace(gr,`{`).replace(vr,`}`).replace(mr,`^`)}function Sr(e){return br(e).replace(dr,`%2B`).replace(yr,`+`).replace(or,`%23`).replace(sr,`%26`).replace(hr,"`").replace(gr,`{`).replace(vr,`}`).replace(mr,`^`)}function Cr(e){return Sr(e).replace(lr,`%3D`)}function wr(e){return br(e).replace(or,`%23`).replace(ur,`%3F`)}function Tr(e){return wr(e).replace(cr,`%2F`)}function Er(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var Dr=/\/$/,Or=e=>e.replace(Dr,``);function kr(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=Lr(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:Er(o)}}function Ar(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function jr(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function Mr(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&Nr(t.matched[r],n.matched[i])&&Pr(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Nr(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Pr(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!Fr(e[n],t[n]))return!1;return!0}function Fr(e,t){return Y(e)?Ir(e,t):Y(t)?Ir(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function Ir(e,t){return Y(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function Lr(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o<r.length;o++)if(s=r[o],s!==`.`)if(s===`..`)a>1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var Z={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function Rr(e){if(!e)if(Gn){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),Or(e)}var zr=/^[^#]+#/;function Br(e,t){return e.replace(zr,`#`)+t}function Vr(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var Hr=()=>({left:window.scrollX,top:window.scrollY});function Ur(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=Vr(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function Wr(e,t){return(history.state?history.state.position-t:-1)+e}var Gr=new Map;function Kr(e,t){Gr.set(e,t)}function qr(e){let t=Gr.get(e);return Gr.delete(e),t}function Jr(e){return typeof e==`string`||e&&typeof e==`object`}function Yr(e){return typeof e==`string`||typeof e==`symbol`}function Xr(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;e<n.length;++e){let r=n[e].replace(dr,` `),i=r.indexOf(`=`),a=Er(i<0?r:r.slice(0,i)),o=i<0?null:Er(r.slice(i+1));if(a in t){let e=t[a];Y(e)||(e=t[a]=[e]),e.push(o)}else t[a]=o}return t}function Zr(e){let t=``;for(let n in e){let r=e[n];if(n=Cr(n),r==null){r!==void 0&&(t+=(t.length?`&`:``)+n);continue}(Y(r)?r.map(e=>e&&Sr(e)):[r&&Sr(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function Qr(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=Y(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function $r(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Q(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(Qn(4,{from:n,to:t})):e instanceof Error?c(e):Jr(e)?c(Qn(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function ei(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(Kn(s)){let c=(s.__vccOpts||s)[t];c&&a.push(Q(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=qn(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&Q(c,n,r,o,e,i)()}))}}return a}function ti(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o<a;o++){let a=t.matched[o];a&&(e.matched.find(e=>Nr(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>Nr(e,s))||i.push(s))}return[n,r,i]}var ni=()=>location.protocol+`//`+location.host;function ri(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),jr(n,``)}return jr(n,e)+r+i}function ii(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=ri(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(J({},e.state,{scroll:Hr()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function ai(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?Hr():null}}function oi(e){let{history:t,location:n}=window,r={value:ri(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:ni()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,J({},t.state,ai(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=J({},i.value,t.state,{forward:e,scroll:Hr()});a(o.current,o,!0),a(e,J({},ai(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function si(e){e=Rr(e);let t=oi(e),n=ii(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=J({location:``,base:e,go:r,createHref:Br.bind(null,e)},t,n);return Object.defineProperty(i,`location`,{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,`state`,{enumerable:!0,get:()=>t.state.value}),i}function ci(e){return e=location.host?e||location.pathname+location.search:``,e.includes(`#`)||(e+=`#`),si(e)}var li={type:0,value:``},ui=/[a-zA-Z0-9_]/;function di(e){if(!e)return[[]];if(e===`/`)return[[li]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;s<e.length;)switch(c=e[s++],n){case 0:c===`\\`?(r=n,n=4):c===`/`?(l&&d(),o()):c===`:`?(d(),n=1):f();break;case 4:f(),n=r;break;case 1:c===`(`?n=2:ui.test(c)?f():(d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--);break;case 2:c===`)`?u[u.length-1]==`\\`?u=u.slice(0,-1)+c:n=3:u+=c;break;case 3:d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--,u=``;break;default:t(`Unknown state`);break}return n===2&&t(`Unfinished custom RegExp for param "${l}"`),d(),o(),i}var fi=`[^/]+?`,pi={sensitive:!1,strict:!1,start:!0,end:!0},mi=/[.+*?^${}()[\]/\\]/g;function hi(e,t){let n=J({},pi,t),r=[],i=n.start?`^`:``,a=[];for(let t of e){let e=t.length?[]:[90];n.strict&&!t.length&&(i+=`/`);for(let r=0;r<t.length;r++){let o=t[r],s=40+(n.sensitive?.25:0);if(o.type===0)r||(i+=`/`),i+=o.value.replace(mi,`\\$&`),s+=40;else if(o.type===1){let{value:e,repeatable:n,optional:c,regexp:l}=o;a.push({name:e,repeatable:n,optional:c});let u=l||fi;if(u!==fi){s+=10;try{RegExp(`(${u})`)}catch(t){throw Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let d=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(d=c&&t.length<2?`(?:/${d})`:`/`+d),c&&(d+=`?`),i+=d,s+=20,c&&(s+=-8),n&&(s+=-20),u===`.*`&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){let e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(i+=`/?`),n.end?i+=`$`:n.strict&&!i.endsWith(`/`)&&(i+=`(?:/|$)`);let o=new RegExp(i,n.sensitive?``:`i`);function s(e){let t=e.match(o),n={};if(!t)return null;for(let e=1;e<t.length;e++){let r=t[e]||``,i=a[e-1];n[i.name]=r&&i.repeatable?r.split(`/`):r}return n}function c(t){let n=``,r=!1;for(let i of e){(!r||!n.endsWith(`/`))&&(n+=`/`),r=!1;for(let e of i)if(e.type===0)n+=e.value;else if(e.type===1){let{value:a,repeatable:o,optional:s}=e,c=a in t?t[a]:``;if(Y(c)&&!o)throw Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);let l=Y(c)?c.join(`/`):c;if(!l)if(s)i.length<2&&(n.endsWith(`/`)?n=n.slice(0,-1):r=!0);else throw Error(`Missing required param "${a}"`);n+=l}}return n||`/`}return{re:o,score:r,keys:a,parse:s,stringify:c}}function gi(e,t){let n=0;for(;n<e.length&&n<t.length;){let r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?e.length===1&&e[0]===80?-1:1:e.length>t.length?t.length===1&&t[0]===80?1:-1:0}function _i(e,t){let n=0,r=e.score,i=t.score;for(;n<r.length&&n<i.length;){let e=gi(r[n],i[n]);if(e)return e;n++}if(Math.abs(i.length-r.length)===1){if(vi(r))return 1;if(vi(i))return-1}return i.length-r.length}function vi(e){let t=e[e.length-1];return e.length>0&&t[t.length-1]<0}var yi={strict:!1,end:!0,sensitive:!1};function bi(e,t,n){let r=J(hi(di(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function xi(e,t){let n=[],r=new Map;t=Xn(yi,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=Ci(e);s.aliasOf=r&&r.record;let l=Xn(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(Ci(J({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=bi(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!Ti(d)&&o(e.name)),ki(d)&&c(d),s.children){let e=s.children;for(let t=0;t<e.length;t++)a(e[t],d,r&&r.children[t])}r||=d}return f?()=>{o(f)}:Yn}function o(e){if(Yr(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=Di(e,n);n.splice(t,0,e),e.record.name&&!Ti(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw Qn(1,{location:e});s=i.record.name,a=J(Si(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&Si(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw Qn(1,{location:e,currentLocation:t});s=i.record.name,a=J({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:Ei(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function Si(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function Ci(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:wi(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,`mods`,{value:{}}),t}function wi(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function Ti(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ei(e){return e.reduce((e,t)=>J(e,t.meta),{})}function Di(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;_i(e,t[i])<0?r=i:n=i+1}let i=Oi(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function Oi(e){let t=e;for(;t=t.parent;)if(ki(t)&&_i(e,t)===0)return t}function ki({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Ai(e){let t=n(tr),r=n(nr),i=T(()=>{let n=S(e.to);return t.resolve(n)}),a=T(()=>{let{matched:e}=i.value,{length:t}=e,n=e[t-1],a=r.matched;if(!n||!a.length)return-1;let o=a.findIndex(Nr.bind(null,n));if(o>-1)return o;let s=Fi(e[t-2]);return t>1&&Fi(n)===s&&a[a.length-1].path!==s?a.findIndex(Nr.bind(null,e[t-2])):o}),o=T(()=>a.value>-1&&Pi(r.params,i.value.params)),s=T(()=>a.value>-1&&a.value===r.matched.length-1&&Pr(r.params,i.value.params));function c(n={}){if(Ni(n)){let n=t[S(e.replace)?`replace`:`push`](S(e.to)).catch(Yn);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:i,href:T(()=>i.value.href),isActive:o,isExactActive:s,navigate:c}}function ji(e){return e.length===1?e[0]:e}var Mi=c({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:Ai,setup(e,{slots:t}){let r=o(Ai(e)),{options:i}=n(tr),a=T(()=>({[Ii(e.activeClass,i.linkActiveClass,`router-link-active`)]:r.isActive,[Ii(e.exactActiveClass,i.linkExactActiveClass,`router-link-exact-active`)]:r.isExactActive}));return()=>{let n=t.default&&ji(t.default(r));return e.custom?n:l(`a`,{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},n)}}});function Ni(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Pi(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!Y(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function Fi(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var Ii=(e,t,n)=>e??t??n,Li=c({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(t,{attrs:r,slots:i}){let a=n(rr),o=T(()=>t.route||a.value),s=n(er,0),c=T(()=>{let e=S(s),{matched:t}=o.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),d=T(()=>o.value.matched[c.value]);D(er,T(()=>c.value+1)),D($n,d),D(rr,o);let f=e();return u(()=>[f.value,d.value,t.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!Nr(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let e=o.value,n=t.name,a=d.value,s=a&&a.components[n];if(!s)return Ri(i.default,{Component:s,route:e});let c=a.props[n],u=l(s,J({},c?c===!0?e.params:typeof c==`function`?c(e):c:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(a.instances[n]=null)},ref:f}));return Ri(i.default,{Component:u,route:e})||u}}});function Ri(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var zi=Li;function Bi(e){let t=xi(e.routes,e),n=e.parseQuery||Xr,r=e.stringifyQuery||Zr,i=e.history,a=$r(),o=$r(),s=$r(),c=ne(Z),l=Z;Gn&&e.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let u=Jn.bind(null,e=>``+e),d=Jn.bind(null,Tr),f=Jn.bind(null,Er);function p(e,n){let r,i;return Yr(e)?(r=t.getRecordMatcher(e),i=n):i=e,t.addRoute(i,r)}function m(e){let n=t.getRecordMatcher(e);n&&t.removeRoute(n)}function h(){return t.getRoutes().map(e=>e.record)}function g(e){return!!t.getRecordMatcher(e)}function _(e,a){if(a=J({},a||c.value),typeof e==`string`){let r=kr(n,e,a.path),o=t.resolve({path:r.path},a),s=i.createHref(r.fullPath);return J(r,o,{params:f(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=J({},e,{path:kr(n,e.path,a.path).path});else{let t=J({},e.params);for(let e in t)t[e]??delete t[e];o=J({},e,{params:d(t)}),a.params=d(a.params)}let s=t.resolve(o,a),l=e.hash||``;s.params=u(f(s.params));let p=Ar(r,J({},e,{hash:xr(l),path:s.path})),m=i.createHref(p);return J({fullPath:p,hash:l,query:r===Zr?Qr(e.query):e.query||{}},s,{redirectedFrom:void 0,href:m})}function y(e){return typeof e==`string`?kr(n,e,c.value.path):J({},e)}function b(e,t){if(l!==e)return Qn(8,{from:t,to:e})}function x(e){return w(e)}function C(e){return x(J(y(e),{replace:!0}))}function te(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=y(i):{path:i},i.params={}),J({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function w(e,t){let n=l=_(e),i=c.value,a=e.state,o=e.force,s=e.replace===!0,u=te(n,i);if(u)return w(J(y(u),{state:typeof u==`object`?J({},a,u.state):a,force:o,replace:s}),t||n);let d=n;d.redirectedFrom=t;let f;return!o&&Mr(r,i,n)&&(f=Qn(16,{to:d,from:i}),N(i,i,!0,!1)),(f?Promise.resolve(f):D(d,i)).catch(e=>X(e)?X(e,2)?e:M(e):oe(e,d,i)).then(e=>{if(e){if(X(e,2))return w(J({replace:s},y(e.to),{state:typeof e.to==`object`?J({},a,e.to.state):a,force:o}),t||d)}else e=k(d,i,!0,s,a);return O(d,i,e),e})}function T(e,t){let n=b(e,t);return n?Promise.reject(n):Promise.resolve()}function E(e){let t=le.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function D(e,t){let n,[r,i,s]=ti(e,t);n=ei(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push(Q(r,e,t))});let c=T.bind(null,e,t);return n.push(c),I(n).then(()=>{n=[];for(let r of a.list())n.push(Q(r,e,t));return n.push(c),I(n)}).then(()=>{n=ei(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push(Q(r,e,t))});return n.push(c),I(n)}).then(()=>{n=[];for(let r of s)if(r.beforeEnter)if(Y(r.beforeEnter))for(let i of r.beforeEnter)n.push(Q(i,e,t));else n.push(Q(r.beforeEnter,e,t));return n.push(c),I(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=ei(s,`beforeRouteEnter`,e,t,E),n.push(c),I(n))).then(()=>{n=[];for(let r of o.list())n.push(Q(r,e,t));return n.push(c),I(n)}).catch(e=>X(e,8)?e:Promise.reject(e))}function O(e,t,n){s.list().forEach(r=>E(()=>r(e,t,n)))}function k(e,t,n,r,a){let o=b(e,t);if(o)return o;let s=t===Z,l=Gn?history.state:{};n&&(r||s?i.replace(e.fullPath,J({scroll:s&&l&&l.scroll},a)):i.push(e.fullPath,a)),c.value=e,N(e,t,n,s),M()}let re;function ie(){re||=i.listen((e,t,n)=>{if(!F.listening)return;let r=_(e),a=te(r,F.currentRoute.value);if(a){w(J(a,{replace:!0,force:!0}),r).catch(Yn);return}l=r;let o=c.value;Gn&&Kr(Wr(o.fullPath,n.delta),Hr()),D(r,o).catch(e=>X(e,12)?e:X(e,2)?(w(J(y(e.to),{force:!0}),r).then(e=>{X(e,20)&&!n.delta&&n.type===`pop`&&i.go(-1,!1)}).catch(Yn),Promise.reject()):(n.delta&&i.go(-n.delta,!1),oe(e,r,o))).then(e=>{e||=k(r,o,!1),e&&(n.delta&&!X(e,8)?i.go(-n.delta,!1):n.type===`pop`&&X(e,20)&&i.go(-1,!1)),O(r,o,e)}).catch(Yn)})}let A=$r(),j=$r(),ae;function oe(e,t,n){M(e);let r=j.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function se(){return ae&&c.value!==Z?Promise.resolve():new Promise((e,t)=>{A.add([e,t])})}function M(e){return ae||(ae=!e,ie(),A.list().forEach(([t,n])=>e?n(e):t()),A.reset()),e}function N(t,n,r,i){let{scrollBehavior:a}=e;if(!Gn||!a)return Promise.resolve();let o=!r&&qr(Wr(t.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return ee().then(()=>a(t,n,o)).then(e=>e&&Ur(e)).catch(e=>oe(e,t,n))}let ce=e=>i.go(e),P,le=new Set,F={currentRoute:c,listening:!0,addRoute:p,removeRoute:m,clearRoutes:t.clearRoutes,hasRoute:g,getRoutes:h,resolve:_,options:e,push:x,replace:C,go:ce,back:()=>ce(-1),forward:()=>ce(1),beforeEach:a.add,beforeResolve:o.add,afterEach:s.add,onError:j.add,isReady:se,install(e){e.component(`RouterLink`,Mi),e.component(`RouterView`,zi),e.config.globalProperties.$router=F,Object.defineProperty(e.config.globalProperties,`$route`,{enumerable:!0,get:()=>S(c)}),Gn&&!P&&c.value===Z&&(P=!0,x(i.location).catch(e=>{}));let t={};for(let e in Z)Object.defineProperty(t,e,{get:()=>c.value[e],enumerable:!0});e.provide(tr,F),e.provide(nr,v(t)),e.provide(rr,c);let n=e.unmount;le.add(e),e.unmount=function(){le.delete(e),le.size<1&&(l=Z,re&&re(),re=null,c.value=Z,P=!1,ae=!1),n()}}};function I(e){return e.reduce((e,t)=>e.then(()=>E(t)),Promise.resolve())}return F}var Vi=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Hi=function(e){return`/`+e},Ui={},$=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=Hi(t,n),t in Ui)return;Ui[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:Vi,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Wi=[{path:`/`,component:()=>$(()=>import(`./MainLayout-CbUZOTwz.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36])),children:[{path:``,redirect:{name:`workspace`}},{path:`workspace/:id?`,name:`workspace`,component:()=>$(()=>import(`./WorkspacePage-k_qzLoLC.js`),__vite__mapDeps([37,1,2,3,4,8,9,7,10,12,38,18,15,16,14,20,19,21,22,23,17,24,39,26,40,28,29,30,31,41,35,42,43,34,44]))},{path:`create`,name:`create`,component:()=>$(()=>import(`./CreatePage-DX4TjLqr.js`),__vite__mapDeps([45,1,2,3,4,8,9,7,10,46,21,22,17,20,19,16,23,39,26,40,30,41,35,42,43,47]))},{path:`settings`,name:`settings`,component:()=>$(()=>import(`./SettingsPage-BBk3MB8w.js`),__vite__mapDeps([48,1,2,3,4,6,7,8,9,10,11,38,18,15,16,14,19,46,21,22,17,20,23,24,39,26,27,30,31,32,29,43,49]))},{path:`search`,name:`search`,component:()=>$(()=>import(`./SearchPage-OaTRqd2Q.js`),__vite__mapDeps([50,1,2,3,4,8,9,12,16,39,26,27,15,34,51]))},{path:`health`,name:`health`,component:()=>$(()=>import(`./HealthPage-DM7fvP4v.js`),__vite__mapDeps([52,3,4,12,9,10,21,24,39,26,30]))},{path:`changelog`,name:`changelog`,component:()=>$(()=>import(`./ChangelogPage-BXD8H3j-.js`),__vite__mapDeps([53,1,3,4,5,10,9,19,39,26,54]))}]},{path:`/:catchAll(.*)*`,redirect:`/`}],Gi=Hn(()=>Bi({scrollBehavior:()=>({left:0,top:0}),routes:Wi,history:ci()}));async function Ki(e,t){let n=e(Bn);n.use(dt,t);let r=typeof Wn==`function`?await Wn({}):Wn;n.use(r);let i=p(typeof Gi==`function`?await Gi({store:r}):Gi);return r.use(({store:e})=>{e.router=i}),{app:n,store:r,router:i}}var qi={radio:Be,checkbox:Ke,toggle:qe},Ji=Object.keys(qi);function Yi(e,t){if(typeof e==`function`)return e;let n=e===void 0?t:e;return e=>e[n]}var Xi=j({name:`QOptionGroup`,props:{...N,modelValue:{required:!0},options:{type:Array,validator:e=>e.every(R),default:()=>[]},optionValue:[Function,String],optionLabel:[Function,String],optionDisable:[Function,String],name:String,type:{type:String,default:`radio`,validator:e=>Ji.includes(e)},color:String,keepColor:Boolean,dense:Boolean,size:String,leftLabel:Boolean,inline:Boolean,disable:Boolean},emits:[`update:modelValue`],setup(e,{emit:n,slots:r}){let{proxy:{$q:i}}=t(),a=Array.isArray(e.modelValue);e.type===`radio`?a&&console.error(`q-option-group: model should not be array`):a||console.error(`q-option-group: model should be array in your case`);let o=M(e,i),s=T(()=>qi[e.type]),c=T(()=>Yi(e.optionValue,`value`)),u=T(()=>Yi(e.optionLabel,`label`)),d=T(()=>Yi(e.optionDisable,`disable`)),f=T(()=>e.options.map(t=>({val:c.value(t),name:t.name===void 0?e.name:t.name,disable:e.disable||d.value(t),leftLabel:t.leftLabel===void 0?e.leftLabel:t.leftLabel,color:t.color===void 0?e.color:t.color,checkedIcon:t.checkedIcon,uncheckedIcon:t.uncheckedIcon,dark:t.dark===void 0?o.value:t.dark,size:t.size===void 0?e.size:t.size,dense:e.dense,keepColor:t.keepColor===void 0?e.keepColor:t.keepColor}))),p=T(()=>`q-option-group q-gutter-x-sm`+(e.inline?` q-option-group--inline`:``)),m=T(()=>{let t={role:`group`};return e.type===`radio`&&(t.role=`radiogroup`,e.disable&&(t[`aria-disabled`]=`true`)),t});function h(e){n(`update:modelValue`,e)}return()=>l(`div`,{class:p.value,...m.value},e.options.map((t,n)=>{let i=r[`label-`+n]===void 0?r.label===void 0?void 0:()=>r.label(t):()=>r[`label-`+n](t);return l(`div`,[l(s.value,{label:i===void 0?u.value(t):null,modelValue:e.modelValue,"onUpdate:modelValue":h,...f.value[n]},i)])}))}}),Zi=j({name:`DialogPluginComponent`,props:{...N,title:String,message:String,prompt:Object,options:Object,progress:[Boolean,Object],html:Boolean,ok:{type:[String,Object,Boolean],default:!0},cancel:[String,Object,Boolean],focus:{type:String,default:`ok`,validator:e=>[`ok`,`cancel`,`none`].includes(e)},stackButtons:Boolean,color:String,cardClass:[String,Array,Object],cardStyle:[String,Array,Object]},emits:[`ok`,`hide`],setup(n,{emit:r}){let{proxy:i}=t(),{$q:a}=i,o=M(n,a),s=e(null),c=e(n.prompt===void 0?n.options===void 0?void 0:n.options.model:n.prompt.model),d=T(()=>`q-dialog-plugin`+(o.value?` q-dialog-plugin--dark q-dark`:``)+(n.progress===!1?``:` q-dialog-plugin--progress`)),f=T(()=>n.color||(o.value?`amber`:`primary`)),p=T(()=>n.progress===!1?null:R(n.progress)?{component:n.progress.spinner||se,props:{color:n.progress.color||f.value}}:{component:se,props:{color:f.value}}),m=T(()=>n.prompt!==void 0||n.options!==void 0),h=T(()=>{if(!m.value)return{};let{model:e,isValid:t,items:r,...i}=n.prompt===void 0?n.options:n.prompt;return i}),g=T(()=>R(n.ok)||n.ok===!0?a.lang.label.ok:n.ok),_=T(()=>R(n.cancel)||n.cancel===!0?a.lang.label.cancel:n.cancel),v=T(()=>n.prompt===void 0?n.options===void 0?!1:n.options.isValid!==void 0&&!n.options.isValid(c.value):n.prompt.isValid!==void 0&&!n.prompt.isValid(c.value)),y=T(()=>({color:f.value,label:g.value,ripple:!1,disable:v.value,...R(n.ok)?n.ok:{flat:!0},"data-autofocus":n.focus===`ok`&&!m.value||void 0,onClick:ee})),b=T(()=>({color:f.value,label:_.value,ripple:!1,...R(n.cancel)?n.cancel:{flat:!0},"data-autofocus":n.focus===`cancel`&&!m.value||void 0,onClick:C}));u(()=>n.prompt&&n.prompt.model,E),u(()=>n.options&&n.options.model,E);function x(){s.value.show()}function S(){s.value.hide()}function ee(){r(`ok`,w(c.value)),S()}function C(){S()}function te(){r(`hide`)}function E(e){c.value=e}function ne(e){!v.value&&n.prompt.type!==`textarea`&&oe(e,13)&&ee()}function D(e,t){return n.html?l(H,{class:e,innerHTML:t}):l(H,{class:e},()=>t)}function O(){return[l(Ge,{color:f.value,dense:!0,autofocus:!0,dark:o.value,...h.value,modelValue:c.value,"onUpdate:modelValue":E,onKeyup:ne})]}function k(){return[l(Xi,{color:f.value,options:n.options.items,dark:o.value,...h.value,modelValue:c.value,"onUpdate:modelValue":E})]}function re(){let e=[];return n.cancel&&e.push(l(He,b.value)),n.ok&&e.push(l(He,y.value)),l(Re,{class:n.stackButtons?`items-end`:``,vertical:n.stackButtons,align:`right`},()=>e)}function ie(){let e=[];return n.title&&e.push(D(`q-dialog__title`,n.title)),n.progress!==!1&&e.push(l(H,{class:`q-dialog__progress`},()=>l(p.value.component,p.value.props))),n.message&&e.push(D(`q-dialog__message`,n.message)),n.prompt===void 0?n.options!==void 0&&e.push(l(pe,{dark:o.value}),l(H,{class:`scroll q-dialog-plugin__form`},k),l(pe,{dark:o.value})):e.push(l(H,{class:`scroll q-dialog-plugin__form`},O)),(n.ok||n.cancel)&&e.push(re()),e}function A(){return[l(ft,{class:[d.value,n.cardClass],style:n.cardStyle,dark:o.value},ie)]}return Object.assign(i,{show:x,hide:S}),()=>l(Mt,{ref:s,onHide:te},A)}});function Qi(e,t){for(let n in t)n!==`spinner`&&Object(t[n])===t[n]?(e[n]=Object(e[n])===e[n]?{...e[n]}:{},Qi(e[n],t[n])):e[n]=t[n]}function $i(t,n,r){return i=>{let a,o,s=n&&i.component!==void 0;if(s){let{component:e,componentProps:t}=i;a=typeof e==`string`?r.component(e):e,o=t||{}}else{let{class:e,style:n,...r}=i;a=t,o=r,e!==void 0&&(r.cardClass=e),n!==void 0&&(r.cardStyle=n)}let c,u=!1,d=e(null),f=ge(!1,`dialog`),p=e=>{if(d.value?.[e]!==void 0){d.value[e]();return}let t=c.$.subTree;if(t?.component){if(t.component.proxy&&t.component.proxy[e]){t.component.proxy[e]();return}if(t.component.subTree&&t.component.subTree.component&&t.component.subTree.component.proxy&&t.component.subTree.component.proxy[e]){t.component.subTree.component.proxy[e]();return}}console.error(`[Quasar] Incorrectly defined Dialog component`)},m=[],h=[],g={onOk(e){return m.push(e),g},onCancel(e){return h.push(e),g},onDismiss(e){return m.push(e),h.push(e),g},hide(){return p(`hide`),g},update(e){if(c!==null){if(s)Object.assign(o,e);else{let{class:t,style:n,...r}=e;t!==void 0&&(r.cardClass=t),n!==void 0&&(r.cardStyle=n),Qi(o,r)}c.$forceUpdate()}return g}},_=e=>{u=!0,m.forEach(t=>{t(e)})},v=()=>{y.unmount(f),Le(f),y=null,c=null,u||h.forEach(e=>{e()})},y=ct({name:`QGlobalDialog`,setup:()=>()=>l(a,{...o,ref:d,onOk:_,onHide:v,onVnodeMounted(...e){typeof o.onVnodeMounted==`function`&&o.onVnodeMounted(...e),ee(()=>p(`show`))}})},r);return c=y.mount(f),g}}var ea={install({$q:e,parentApp:t}){e.dialog=this.create=$i(Zi,!0,t)}},ta={config:{dark:!0,brand:{primary:`#6c63ff`,secondary:`#26a69a`,accent:`#9c27b0`,dark:`#1a1a2e`,"dark-page":`#1a1a2e`,positive:`#21ba45`,negative:`#c10015`,info:`#31ccec`,warning:`#f2c037`}},plugins:{Notify:rn,Dialog:ea}},na=`/`;async function ra({app:e,router:t,store:n},r){let i=!1,a=e=>{try{return t.resolve(e).href}catch{}return Object(e)===e?null:e},o=e=>{if(i=!0,typeof e==`string`&&/^https?:\/\//.test(e)){window.location.href=e;return}let t=a(e);t!==null&&(window.location.href=t,window.location.reload())},s=window.location.href.replace(window.location.origin,``);for(let a=0;i===!1&&a<r.length;a++)try{await r[a]({app:e,router:t,store:n,ssrContext:null,redirect:o,urlPath:s,publicPath:na})}catch(e){if(e&&e.url){o(e.url);return}console.error(`[Quasar] boot error:`,e);return}i!==!0&&(e.use(t),e.mount(`#q-app`))}Ki(x,ta).then(e=>{let[t,n]=Promise.allSettled===void 0?[`all`,e=>e.map(e=>e.default)]:[`allSettled`,e=>e.map(e=>{if(e.status===`rejected`){console.error(`[Quasar] boot error:`,e.reason);return}return e.value.default})];return Promise[t]([$(()=>import(`./i18n-DXMuiAyu.js`),[])]).then(t=>{ra(e,n(t).filter(e=>typeof e==`function`))})});export{Mt as _,Vn as a,ft as b,G as c,_n as d,vn as f,Vt as g,mn as h,ir as i,Tn as l,hn as m,$ as n,zn as o,gn as p,ar as r,En as s,Xi as t,xn as u,Ot as v,H as x,pt as y};
82
+ sudo setfacl -Rd -m u:$(whoami):rwX . && sudo setfacl -R -m u:$(whoami):rwX .`,"settings.purgeDocsPermissionsRecoverChownIntro":`Opzione B — Prendere la proprietà (più semplice, perde la traccia "creato da root nel container" ma raramente conta):`,"settings.purgeDocsPermissionsRecoverChownCommand":` sudo chown -R $(whoami):$(whoami) .`,"settings.purgeDocsPermissionsRecoverFootnote":"Suggerimento: puoi eseguire questi comandi direttamente sulla root dei worktrees (es. `~/.worktrees/`) per coprire tutti i workspace esistenti E futuri in un colpo solo. Una volta fatto, la pulizia Kōbō funzionerà senza errori di permessi.","contextMenu.runSetup":`Esegui script di setup`,"contextMenu.exportEvents":`Esporta eventi (CSV)`,"contextMenu.dismissChangesRequested":`Segna «Modifiche richieste» come visto`,"contextMenu.dismissCiFailure":`Segna «CI in errore» come visto`,"contextMenu.restoreChangesRequested":`Segna «Modifiche richieste» come non visto`,"contextMenu.restoreCiFailure":`Segna «CI in errore» come non visto`,"contextMenu.exportingEvents":`Preparazione dell'esportazione…`,"contextMenu.exportEventsError":`Esportazione degli eventi non riuscita`,"contextMenu.openNotion":`Apri in Notion`,"contextMenu.openSentry":`Apri in Sentry`,"contextMenu.openPr":`Apri PR`,"workspace.favorite":`Segna come preferito`,"workspace.unfavorite":`Rimuovi dai preferiti`,"workspace.showFavoritesOnly":`Mostra solo i preferiti`,"workspace.searchArchivedToggle":`Cerca anche nei workspace archiviati`,"workspace.descriptionPlaceholder":`Aggiungi una breve descrizione`,"workspace.descriptionDialogHint":`Testo semplice, massimo 200 caratteri. Lasciare vuoto per cancellare.`,"workspace.descriptionTooLong":`La descrizione deve avere al massimo 200 caratteri.`,"workspace.descriptionSaveFailed":`Impossibile salvare la descrizione.`,"workspace.agentDescriptionTooltip":`Stato live mantenuto dall'agente`,"mcp.tool.setWorkspaceDescription":`Imposta la breve descrizione del workspace (≤ 200 caratteri).`,"tags.manage":`Gestisci tag`,"tags.manageTitle":`Gestisci i tag del workspace`,"tags.noTagsDefined":`Nessun tag definito. Aggiungine in Impostazioni > Globale > Tag.`,"tags.orphanedHint":`{count} tag non sono più nel catalogo globale. Deseleziona per rimuoverli.`,"settings.tagsTitle":`Tag dei workspace`,"settings.tagsHint":`Definisci i tag assegnabili ai workspace. Digita per aggiungere, clicca la croce per rimuovere.`,"settings.tagsLabel":`Tag disponibili`,"settings.branchPrefixesTitle":`Prefissi di branch`,"settings.branchPrefixesHint":`Gestisci i prefissi di branch Git disponibili nella pagina di creazione del workspace. Il primo è preselezionato per impostazione predefinita.`,"settings.branchPrefixesEmpty":`Nessun prefisso di branch definito. Aggiungine almeno uno qui sotto.`,"settings.branchPrefixesAddLabel":`Nuovo prefisso`,"settings.branchPrefixesEditHint":`Clicca per rinominare`,"settings.branchPrefixesMoveUp":`Sposta su`,"settings.branchPrefixesMoveDown":`Sposta giù`,"settings.worktreesTitle":`Worktree Git`,"settings.worktreesHint":`Scegli dove creare i worktree dei nuovi workspace. I percorsi relativi sono risolti dal progetto; sono supportati percorsi assoluti Linux/macOS e Windows, $HOME, ~ e %USERPROFILE%.`,"settings.worktreesPathLabel":`Percorso worktree`,"settings.worktreesPathRequired":`Il percorso worktree è obbligatorio.`,"settings.worktreesPrefixByProject":`Aggiungi il nome del progetto come prefisso ai worktree`,"settings.worktreesPrefixByProjectHint":`Posiziona ogni worktree in una sottocartella con il nome del progetto per evitare collisioni quando più progetti condividono la stessa radice.`,"settings.shareTitle":`Condividi configurazione`,"settings.shareHint":`Esporta impostazioni, template e tag come bundle JSON. Le chiavi MCP sono escluse per sicurezza.`,"settings.exportConfig":`Esporta`,"settings.importConfig":`Importa`,"settings.exportSuccess":`Configurazione esportata`,"settings.importSuccess":`Configurazione importata`,"settings.importConfirmTitle":`Importa configurazione`,"settings.importConfirmMessage":`Questo sostituirà le tue impostazioni, template e tag attuali. Le chiavi MCP vengono preservate. Continuare?`,"health.title":`Stato`,"health.tooltip":`Stato del sistema`,"changelog.title":`Changelog`,"changelog.tooltip":`Novità di Kōbō`,"changelog.empty":`Nessun changelog disponibile.`,"changelog.current":`corrente`,"changelog.currentVersion":`Versione corrente: v{version}`,"health.envTitle":`Ambiente`,"health.version":`Versione`,"health.koboHome":`Kōbō home`,"health.dbTitle":`Database`,"health.dbPath":`Percorso`,"health.dbSize":`Dimensione`,"health.schemaVersion":`Versione schema`,"health.settingsSchemaVersion":`Schema impostazioni`,"health.runtimesTitle":`Runtime agente`,"health.claudeCliTitle":`Claude Code`,"health.claudeCliMissing":`claude non trovato nel PATH`,"health.codexCliTitle":`OpenAI Codex`,"health.codexCliMissing":`binario codex non risolvibile`,"health.workspacesTitle":`Workspace`,"health.workspacesCount":`{total} totali, {archived} archiviati`,"health.worktreesMissing":`{count} worktree mancanti sul disco`,"health.sessionsTitle":`Sessioni agente`,"health.sessionsOrphaned":`{n} sessione/sessioni orfana/e in esecuzione`,"health.integrationsTitle":`Integrazioni`,"health.integrationConfigured":`configurata`,"health.integrationMissing":`non configurata`,"health.activeTitle":`Stato attivo`,"health.activeQuotaBackoffs":`Quota backoff in attesa`,"health.activeWakeups":`Wakeup programmati`,"health.activeAutoLoop":`Auto-loop in esecuzione`,"health.activeAgentSessions":`Sessioni agente attive`,"health.activeDevServers":`Dev server in esecuzione`,"health.noneActive":`Nessuno.`,"health.quotaResumeAt":`riprende alle {time}`,"health.wakeupAt":`sveglia alle {time}`,"health.startedAgo":`avviata {time} fa`,"health.autoLoopReady":`pronto, in iterazione`,"health.autoLoopGrooming":`grooming in corso`,"session.started":`Sessione avviata`,"session.ended":`Sessione terminata`,"session.compacted":`Contesto compattato`,"tool.running":`In corso...`,"activity.raw_lines":`Righe di output grezze ({n})`,"activity.loading_older":`Caricamento messaggi precedenti…`,"activity.compacting":`Compattazione del contesto…`,"activity.prev_user_message":`Messaggio utente precedente`,"activity.scroll_to_bottom":`Scorri in fondo`,"chat.systemPrompt":`Prompt di sistema`,"chat.agent":`Agente`,"chat.cleanupScript":`Script di pulizia`,"chat.archiveScript":`Script di archiviazione`,"chat.setupScript":`Script di setup`,"chat.scriptDone":`Fatto`,"chat.you":`Tu`,"chat.session":`Sessione`,"chat.nActions":`{n} azione | {n} azioni`,"chat.lastUpdatedAt":`Ultimo aggiornamento alle {time}`,"chat.scrollToTurnTop":`Scorri all'inizio del messaggio`,"migration.backing_up":`Backup del database in corso…`,"migration.running":`Migrazione dei dati dell'agente — {processed}/{total}`,"migration.error":`Migrazione non riuscita`,"migration.backup_location":`Un backup è stato salvato in {path}. Riavvia Kōbō per riprovare.`,"migration.retry":`Riavvia Kōbō per riprovare.`,"engine.select":`Engine`,"engine.model":`Modello`,"engine.effort":`Livello di ragionamento`,"wakeup.scheduledIn":`Prossimo risveglio tra {n}s`,"wakeup.scheduledAt":`Prossimo risveglio alle {time}`,"wakeup.firing":`Risveglio in corso...`,"wakeup.reason":`Motivo: {reason}`,"wakeup.cancel":`Annulla questo risveglio`,"wakeup.pendingIndicator":`Risveglio programmato`,"cron.pendingIndicator":`{n} cron programmato/i`,"schedule.tabLabel":`Pianificazione`,"schedule.wakeupTitle":`Wakeup in attesa`,"schedule.cronsTitle":`Pianificazioni ricorrenti`,"schedule.noWakeup":`Nessun wakeup pianificato`,"schedule.noCrons":`Nessun cron pianificato`,"schedule.nextFireAt":`prossimo alle {time}`,"schedule.lastFiredAt":`ultimo {time} fa`,"schedule.addCronTitle":`Aggiungi un'attività ricorrente`,"schedule.addWakeupTitle":`Programma un wakeup`,"schedule.every":`Ogni`,"schedule.unitMinutes":`minuti`,"schedule.unitHours":`ore`,"schedule.unitDays":`giorni`,"schedule.advancedExpression":`Espressione avanzata (opzionale)`,"schedule.advancedHint":`Cron grezzo (es. */15 * * * *) o {'@'}hourly/{'@'}daily — sostituisce il selettore se compilato.`,"schedule.promptLabel":`Prompt`,"schedule.labelOptional":`Etichetta (opzionale)`,"schedule.delayMinutes":`Ritardo (minuti)`,"schedule.modeFresh":`Nuova sessione`,"schedule.oneShot":`Esegui una sola volta`,"schedule.addCronBtn":`Aggiungi cron`,"schedule.addWakeupBtn":`Programma wakeup`,"schedule.cronCreated":`Attività ricorrente aggiunta`,"schedule.wakeupCreated":`Wakeup programmato`,"askUserQuestion.title":`L'agente sta facendo una domanda`,"askUserQuestion.submit":`Invia risposta`,"askUserQuestion.multiSelectHint":`Seleziona una o più opzioni`,"askUserQuestion.otherOption":`Altro`,"askUserQuestion.otherOptionHint":`specifica nel prossimo messaggio`,"askUserQuestion.noPending":`Nessuna domanda in attesa`,"askUserQuestion.next":`Avanti`,"askUserQuestion.previous":`Indietro`,"askUserQuestion.cancel":`Annulla`,"askUserQuestion.cancelTooltip":`Salta questa domanda — l'agente proseguirà senza risposta`,"askUserQuestion.collapse":`Riduci il pannello della domanda`,"askUserQuestion.expand":`Espandi il pannello della domanda`,"permissionRequest.title":`L'agente vuole usare uno strumento`,"permissionRequest.allow":`Consenti`,"permissionRequest.deny":`Nega`,"permissionRequest.tool":`Strumento`,"permissionRequest.input":`Input`,"permissionRequest.denied":`negato dall'utente`,"workspaceStatus.awaitingUser":`in attesa della tua risposta`,"workspaceList.prOpen":`#{n} — Pull request aperta`,"workspaceList.prChangesRequested":`#{n} — Modifiche richieste`,"workspaceList.attentionCiFailed":`CI fallita`,"workspaceList.attentionChangesRequested":`Modifiche richieste`,"workspaceList.attentionReadyToMerge":`Pronto per il merge`,"autoLoop.toggle":`Auto-loop`,"autoLoop.start":`Avvia l'auto-loop`,"autoLoop.prepare":`Prepara per l'auto-loop`,"autoLoop.reprepare":`Ri-prepara per l'auto-loop`,"autoLoop.reprepareTooltip":`Rilancia la fase di grooming per aggiungere o aggiornare le attività prima di riavviare il loop`,"autoLoop.prepareBusy":`Attendi che l'agente finisca prima di preparare`,"autoLoop.forceReady":`So cosa faccio — salta la preparazione`,"autoLoop.forceReadyConfirm":`Saltare la preparazione e segnare auto-loop pronto? Il loop potrebbe bloccarsi se le attività non sono atomiche.`,"autoLoop.stop":`Ferma l'auto-loop`,"autoLoop.notReady":`Esegui prima «Prepara per l'auto-loop»`,"autoLoop.noTasks":`Aggiungi prima delle attività`,"autoLoop.progress":`Auto-loop · {done}/{total} attività`,"autoLoop.preparing":`Auto-loop · preparazione`,"autoLoop.preparingTooltip":`Grooming in corso — l'agente sta creando / revisionando le attività. Il loop partirà quando chiamerà mark_auto_loop_ready.`,"autoLoop.running":`Auto-loop in corso`,"autoLoop.startInMode":`Avvia in modalità auto-loop`,"koboCommand.prepAutoloopDesc":`Preparare le attività per la modalità auto-loop (atomicità)`,"staleSessionBanner.title":`Auto-loop in corso`,"staleSessionBanner.message":`Stai visualizzando una sessione precedente — l'agente sta lavorando nella più recente.`,"staleSessionBanner.staleTitle":`Sessione precedente`,"staleSessionBanner.staleMessage":`Stai visualizzando una sessione precedente — i messaggi inviati andranno a questa sessione, non alla più recente.`,"staleSessionBanner.switchToCurrent":`Passa a quella corrente`},un=`kobo:locale`,dn=[`en`,`fr`,`de`,`es`,`it`];function fn(e){return dn.includes(e)}function pn(){let e=localStorage.getItem(un);if(e&&fn(e))return e;let t=navigator.language.split(`-`)[0];return t&&fn(t)?(localStorage.setItem(un,t),t):(localStorage.setItem(un,`en`),`en`)}var mn=We({legacy:!1,locale:pn(),fallbackLocale:`en`,messages:{en:on,fr:cn,de:an,es:sn,it:ln}}),hn=F(`agent-stream`,()=>{let t=e(new Map),n=e(new Map),r=e(new Map),i=e(new Map),a=e(new Map),o=e(new Map),s=e(new Map),c=e(0);function l(e){return c.value,s.value.get(e)??!1}function u(e,t){(s.value.get(e)??!1)!==t&&(s.value.set(e,t),c.value++)}function d(e){return c.value,t.value.get(e)??[]}function f(e){return c.value,n.value.get(e)??[]}function p(e){return c.value,r.value.get(e)??[]}function m(e){return c.value,i.value.get(e)??[]}function h(e){return c.value,a.value.get(e)}function g(e){return c.value,o.value.get(e)??!0}function _(e,o,s,l,u){let d=t.value.get(e)??[],f=n.value.get(e)??[],p=r.value.get(e)??[],m=i.value.get(e)??[],h=d.length===0;d.push(o),f.push(s??new Date().toISOString()),p.push(u??null),m.push(l??null),t.value.set(e,d),n.value.set(e,f),r.value.set(e,p),i.value.set(e,m),h&&l&&a.value.set(e,l),c.value++}function v(e,s,l,u){t.value.set(e,[...s]),n.value.set(e,l?[...l]:s.map(()=>new Date().toISOString())),r.value.set(e,u?.sessionIds?[...u.sessionIds]:s.map(()=>null)),i.value.set(e,u?.eventIds?[...u.eventIds]:s.map(()=>null)),u?.oldestId?a.value.set(e,u.oldestId):a.value.delete(e),u&&typeof u.hasMoreOlder==`boolean`?o.value.set(e,u.hasMoreOlder):o.value.delete(e),c.value++}function y(e,s,l,u){if(s.length===0){o.value.set(e,u.hasMoreOlder),c.value++;return}let d=t.value.get(e)??[],f=n.value.get(e)??[],p=r.value.get(e)??[],m=i.value.get(e)??[],h=u.sessionIds??s.map(()=>null),g=u.eventIds??s.map(()=>null);t.value.set(e,[...s,...d]),n.value.set(e,[...l,...f]),r.value.set(e,[...h,...p]),i.value.set(e,[...g,...m]),u.oldestId&&a.value.set(e,u.oldestId),o.value.set(e,u.hasMoreOlder),c.value++}function b(e,a){let o=t.value.get(e),s=i.value.get(e);if(!o||!s)return;let l=s.indexOf(a);if(l===-1)return;let u=n.value.get(e),d=r.value.get(e);o.splice(l,1),s.splice(l,1),u&&u.splice(l,1),d&&d.splice(l,1),c.value++}function x(e){t.value.delete(e),n.value.delete(e),r.value.delete(e),i.value.delete(e),a.value.delete(e),o.value.delete(e),s.value.delete(e),c.value++}return{events:t,timestamps:n,sessionIds:r,eventIds:i,version:c,eventsFor:d,timestampsFor:f,sessionIdsFor:p,eventIdsFor:m,oldestIdFor:h,hasMoreOlderFor:g,isCompacting:l,setCompacting:u,append:_,reset:v,prepend:y,removeByEventId:b,clear:x}}),gn=F(`devServer`,{state:()=>({statuses:{},logs:{}}),getters:{getStatus:e=>t=>e.statuses[t]??null},actions:{async fetchStatus(e){try{let t=await fetch(`/api/dev-server/${e}/status`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){console.error(`[dev-server store] fetchStatus failed:`,e)}},async startDevServer(e){try{let t=await fetch(`/api/dev-server/${e}/start`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){throw console.error(`[dev-server store] startDevServer failed:`,e),e}},async stopDevServer(e){try{let t=await fetch(`/api/dev-server/${e}/stop`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.statuses[e]=n}catch(e){throw console.error(`[dev-server store] stopDevServer failed:`,e),e}},async fetchLogs(e,t=200){try{let n=await fetch(`/api/dev-server/${e}/logs?tail=${t}`);if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json();return this.logs[e]=r.logs,r.logs}catch(e){return console.error(`[dev-server store] fetchLogs failed:`,e),``}},updateFromWsEvent(e,t){this.statuses[e]=t}}});function _n(e){return e.state===`OPEN`&&e.reviewDecision===`CHANGES_REQUESTED`&&e.reviewers.some(e=>e.state===`CHANGES_REQUESTED`)}function vn(e){return e.state===`OPEN`&&e.ci.rollup===`FAILURE`}function yn(e){return e?vn(e)||_n(e):!1}var bn=[`executing`,`extracting`,`brainstorming`];function xn(e){return!!e&&bn.includes(e)}function Sn(e){"@babel/helpers - typeof";return Sn=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},Sn(e)}function Cn(e,t){if(Sn(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(Sn(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function wn(e){var t=Cn(e,`string`);return Sn(t)==`symbol`?t:t+``}function Tn(e,t,n){return(t=wn(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var En=class extends Error{constructor(e,t){super(e),Tn(this,`code`,void 0),this.name=`WorkspaceActionError`,this.code=t}};function Dn(e){return e===`running`?`in_progress`:e}var On=5e3,kn=500,An=null;function jn(e){return e===`claude-code`?`claude-code`:null}var G=F(`workspace`,{state:()=>({workspaces:[],selectedWorkspaceId:null,tasks:[],activityFeeds:{},activityFeedIds:{},activityCounts:{},subagents:{},agentTodos:{},sessions:[],selectedSessionId:null,archivedWorkspaces:[],archivedLoaded:!1,loading:!1,loadingOlderEvents:!1,hasMoreEvents:{},providerUsage:{},chatDraft:``,queuedMessages:{},gitRefreshTrigger:0,gitStatsCache:{},pendingWakeups:{},pendingQuotaBackoffs:{},pendingDeferred:{},pendingQueue:{},prSnapshots:{},autoLoopStates:{},crons:{}}),getters:{selectedWorkspace:e=>e.workspaces.find(t=>t.id===e.selectedWorkspaceId)??e.archivedWorkspaces.find(t=>t.id===e.selectedWorkspaceId)??null,needsAttention(e){return e.workspaces.filter(t=>[`error`,`quota`,`awaiting-user`].includes(t.status)||yn(e.prSnapshots[t.id])||!xn(t.status)&&!!e.prSnapshots[t.id]?.readyToMerge)},running(e){return e.workspaces.filter(t=>xn(t.status)&&!yn(e.prSnapshots[t.id]))},idle(e){return e.workspaces.filter(t=>[`completed`,`idle`,`created`].includes(t.status)&&!yn(e.prSnapshots[t.id])&&!e.prSnapshots[t.id]?.readyToMerge)},favorites(e){return e.workspaces.filter(e=>e.favoritedAt!==null)},currentAgentTodos:e=>e.selectedWorkspaceId?e.agentTodos[e.selectedWorkspaceId]??[]:[],currentSubagents:e=>{if(!e.selectedWorkspaceId)return[];let t=e.subagents[e.selectedWorkspaceId]??{};return Object.values(t).sort((e,t)=>e.startedAt.localeCompare(t.startedAt))},activityFeed:e=>{if(!e.selectedWorkspaceId)return[];let t=e.activityFeeds[e.selectedWorkspaceId]??[];if(!e.selectedSessionId)return e.sessions.length===0?t:[];let n=e.sessions.find(t=>t.id===e.selectedSessionId)?.engineSessionId??null,r=e.sessions.length>0?e.sessions[e.sessions.length-1].id:null,i=e.selectedSessionId===r;return t.filter(t=>t.sessionId?t.sessionId===e.selectedSessionId||n!==null&&t.sessionId===n:i)},acceptanceCriteria:e=>e.tasks.filter(e=>e.isAcceptanceCriterion),archived:e=>e.archivedWorkspaces,currentProviderUsage(e){let t=e.workspaces.find(t=>t.id===e.selectedWorkspaceId);if(!t)return null;let n=jn(t.engine);return n?e.providerUsage[n]??null:null}},actions:{async toggleFavorite(e){let t=this.workspaces.find(t=>t.id===e);if(!t)return;let n=t.favoritedAt,r=n===null,i=r?new Date().toISOString():null;this.workspaces=this.workspaces.map(t=>t.id===e?{...t,favoritedAt:i}:t);try{let t=await fetch(`/api/workspaces/${e}/favorite`,{method:r?`POST`:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();this.workspaces=this.workspaces.map(t=>t.id===e?n:t)}catch(t){throw this.workspaces=this.workspaces.map(t=>t.id===e?{...t,favoritedAt:n}:t),t}},async setWorkspaceTags(e,t){let n=this.workspaces.find(t=>t.id===e);if(!n)return;let r=n.tags,i=[...t];this.workspaces=this.workspaces.map(t=>t.id===e?{...t,tags:i}:t);try{let n=await fetch(`/api/workspaces/${e}/tags`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({tags:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json();this.workspaces=this.workspaces.map(t=>t.id===e?r:t)}catch(t){throw this.workspaces=this.workspaces.map(t=>t.id===e?{...t,tags:r}:t),t}},async fetchOrphanWorktrees(e){let t=`/api/git/orphan-worktrees?projectPath=${encodeURIComponent(e)}`,n=await fetch(t,{cache:`no-store`});if(!n.ok)throw Error(`HTTP ${n.status}`);return n.json()},async fetchWorkspaces(){this.loading=!0;try{let e=await fetch(`/api/workspaces`);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();this.workspaces=t.workspaces??t;for(let e of this.workspaces)[`completed`,`idle`,`error`,`quota`].includes(e.status)&&this.finalizeRunningSubagents(e.id)}catch(e){console.error(`[workspace store] fetchWorkspaces failed:`,e)}finally{this.loading=!1}},async fetchArchivedWorkspaces(){try{let e=await fetch(`/api/workspaces/archived`);if(!e.ok)throw Error(`HTTP ${e.status}`);this.archivedWorkspaces=await e.json(),this.archivedLoaded=!0}catch(e){console.error(`[workspace store] fetchArchivedWorkspaces failed:`,e)}},async fetchWorkspaceDetails(e){try{let t=await fetch(`/api/workspaces/${e}`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(this.selectedWorkspaceId!==e)return;let r=n.workspace??n,i=this.workspaces.findIndex(t=>t.id===e);if(i>=0)this.workspaces[i]={...this.workspaces[i],...r};else{let t=this.archivedWorkspaces.findIndex(t=>t.id===e);t>=0?this.archivedWorkspaces[t]={...this.archivedWorkspaces[t],...r}:r?.archivedAt&&this.archivedWorkspaces.unshift(r)}n.tasks&&(this.tasks=n.tasks)}catch(e){console.error(`[workspace store] fetchWorkspaceDetails failed:`,e)}},async createWorkspace(e){try{let t=await fetch(`/api/workspaces`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=t.headers.get(`X-Kobo-Branch-Adjusted`)===`1`,r=await t.json(),i=r.workspace??r,a=this.workspaces.findIndex(e=>e.id===i.id);return a>=0?this.workspaces[a]=i:this.workspaces.push(i),e.autoLoop&&this.fetchAutoLoopStates(),i._branchAdjusted=n,i}catch(e){throw console.error(`[workspace store] createWorkspace failed:`,e),e}},async startWorkspace(e,t,n,r){try{let i=await fetch(`/api/workspaces/${e}/start`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:t,agentSessionId:n,resume:r})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await this.fetchWorkspaces()}catch(e){throw console.error(`[workspace store] startWorkspace failed:`,e),e}},async stopWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/stop`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);await this.fetchWorkspaces()}catch(e){throw console.error(`[workspace store] stopWorkspace failed:`,e),e}},async interruptAgent(e){try{let t=await fetch(`/api/workspaces/${e}/interrupt`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}}catch(e){throw console.error(`[workspace store] interruptAgent failed:`,e),e}},async deleteWorkspace(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t??{})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=[];if(n.status===200){let e=await n.json().catch(()=>({}));r=Array.isArray(e.warnings)?e.warnings:[]}return this.workspaces=this.workspaces.filter(t=>t.id!==e),this.archivedWorkspaces=this.archivedWorkspaces.filter(t=>t.id!==e),delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e],delete this.subagents[e],delete this.agentTodos[e],this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]),{warnings:r}}catch(e){throw console.error(`[workspace store] deleteWorkspace failed:`,e),e}},async deleteAllArchived(e){try{let t=this.archivedWorkspaces.map(e=>e.id),n=await fetch(`/api/workspaces/archived`,{method:`DELETE`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e??{})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json().catch(()=>({})),i=typeof r.deleted==`number`?r.deleted:0,a=Array.isArray(r.warnings)?r.warnings:[];this.archivedWorkspaces=[];for(let e of t)delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e],delete this.subagents[e],delete this.agentTodos[e],this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]);return{deleted:i,warnings:a,ids:t}}catch(e){throw console.error(`[workspace store] deleteAllArchived failed:`,e),e}},async updateModel(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({model:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateModel failed:`,e),e}},async updateWorkspaceDescription(e,t){let n=this.workspaces.findIndex(t=>t.id===e);if(n<0)throw Error(`Workspace '${e}' not found in store`);let r=this.workspaces[n].description;this.workspaces[n]={...this.workspaces[n],description:t};try{let r=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({description:t})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error??`HTTP ${r.status}`)}let i=await r.json();this.workspaces[n]={...this.workspaces[n],...i}}catch(t){let n=this.workspaces.findIndex(t=>t.id===e);throw n>=0&&(this.workspaces[n]={...this.workspaces[n],description:r}),t}},async updateReasoningEffort(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({reasoningEffort:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateReasoningEffort failed:`,e),e}},async renameWorkspaceBranch(e,t){let n=await fetch(`/api/workspaces/${e}/rename-branch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({newName:t})}),r=await n.json().catch(()=>null);if(!n.ok)throw new En(r?.error??`Rename failed`,r?.code);let i=r,a=this.workspaces.findIndex(t=>t.id===e);return a>=0&&(this.workspaces[a]=i),i},async resyncWorkspaceBranch(e){let t=await fetch(`/api/workspaces/${e}/resync-branch`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();if(n.changed){let t=this.workspaces.findIndex(t=>t.id===e);t>=0&&(this.workspaces[t]={...this.workspaces[t],workingBranch:n.workingBranch})}return n},async updateAgentPermissionMode(e,t){try{let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({agentPermissionMode:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]=r)}catch(e){throw console.error(`[workspace store] updateAgentPermissionMode failed:`,e),e}},async pushBranch(e,t={}){let n=await fetch(`/api/workspaces/${e}/push`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({force:t.force===!0})});if(!n.ok){let e=await n.json().catch(()=>({error:`Push failed`}));throw new En(e.error??`Push failed`,e.code)}},async fetchGitStats(e,t={}){let n=`/api/workspaces/${e}/git-stats${t.freshFetch?`?freshFetch=1`:``}`,r=await fetch(n,{signal:t.signal});if(!r.ok)throw Error(`HTTP ${r.status}`);let i=await r.json();return this.gitStatsCache[e]=i,i},async fetchBranchDivergence(e,t={}){let n=`/api/workspaces/${e}/branch-divergence?limit=${t.limit??50}`,r=await fetch(n,{signal:t.signal});if(!r.ok)throw Error(`HTTP ${r.status}`);return await r.json()},async openPullRequest(e){let t=await fetch(`/api/workspaces/${e}/open-pr`,{method:`POST`}),n=await t.json().catch(()=>null);if(!t.ok)throw new En(n?.error??`Open PR failed`,n?.code);return n},async archiveWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/archive`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();return this.workspaces=this.workspaces.filter(t=>t.id!==e),this.archivedLoaded&&this.archivedWorkspaces.unshift(n),this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]),n}catch(e){throw console.error(`[workspace store] archiveWorkspace failed:`,e),e}},async unarchiveWorkspace(e){try{let t=await fetch(`/api/workspaces/${e}/unarchive`,{method:`POST`});if(!t.ok){if(t.status===409){let e=await t.json().catch(()=>({})),n=Error(e.error??`worktree-purged`);throw n.code=`worktree-purged`,n}throw Error(`HTTP ${t.status}`)}let n=await t.json();return this.archivedWorkspaces=this.archivedWorkspaces.filter(t=>t.id!==e),this.workspaces.unshift(n),n}catch(e){throw console.error(`[workspace store] unarchiveWorkspace failed:`,e),e}},async createTask(e,t,n){try{let r=await fetch(`/api/workspaces/${e}/tasks`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:t,isAcceptanceCriterion:n})});if(!r.ok)throw Error(`HTTP ${r.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] createTask failed:`,e),e}},async updateTaskTitle(e,t,n){try{let r=await fetch(`/api/workspaces/${e}/tasks/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:n})});if(!r.ok)throw Error(`HTTP ${r.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] updateTaskTitle failed:`,e),e}},async deleteTask(e,t){try{let n=await fetch(`/api/workspaces/${e}/tasks/${t}`,{method:`DELETE`});if(!n.ok)throw Error(`HTTP ${n.status}`);await this.fetchWorkspaceDetails(e)}catch(e){throw console.error(`[workspace store] deleteTask failed:`,e),e}},selectWorkspace(e){this.selectedWorkspaceId=e,this.selectedSessionId=null,this.tasks=[],this.markRead(e),this.fetchWorkspaceDetails(e),this.fetchSessions(e),this.fetchPendingQuotaBackoff(e),this.fetchGitStats(e).catch(()=>{}),this.activityFeeds[e]?.length||zn().subscribe(e)},async fetchSessions(e,t){try{let n=await fetch(`/api/workspaces/${e}/sessions`);if(!n.ok)throw Error(`HTTP ${n.status}`);if(this.selectedWorkspaceId!==e)return;if(this.sessions=await n.json(),t&&this.sessions.some(e=>e.id===t)){this.selectSession(t);return}let r=this.selectedSessionId&&this.sessions.some(e=>e.id===this.selectedSessionId);if(this.sessions.length>0&&!r){let t=localStorage.getItem(`kobo:session:${e}`),n=t?this.sessions.find(e=>e.id===t):null;this.selectSession(n?n.id:this.sessions[0].id)}}catch(e){console.error(`[workspace store] fetchSessions failed:`,e)}},async fetchOlderEvents(e){if(this.loadingOlderEvents||this.hasMoreEvents[e]===!1)return!1;let t=this.activityFeeds[e];if(!t?.length)return!1;let n=t[0].id;this.loadingOlderEvents=!0;try{let t=await fetch(`/api/workspaces/${e}/events?before=${encodeURIComponent(n)}&limit=100`);if(!t.ok)throw Error(`HTTP ${t.status}`);let r=await t.json();if(this.hasMoreEvents[e]=r.hasMore,r.events.length>0){let e=zn();for(let t of r.events)e._routeMessage(t)}return r.events.length>0}catch(e){return console.error(`[workspace store] fetchOlderEvents failed:`,e),!1}finally{this.loadingOlderEvents=!1}},selectSession(e){this.selectedSessionId=e,this.selectedWorkspaceId&&localStorage.setItem(`kobo:session:${this.selectedWorkspaceId}`,e)},async createSession(e){try{let t=await fetch(`/api/workspaces/${e}/sessions`,{method:`POST`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}let n=await t.json();return this.sessions.unshift(n),this.selectSession(n.id),n}catch(e){throw console.error(`[workspace store] createSession failed:`,e),e}},async renameWorkspace(e,t){let n=await fetch(`/api/workspaces/${e}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t})});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}let r=await n.json(),i=this.workspaces.findIndex(t=>t.id===e);i>=0&&(this.workspaces[i]={...this.workspaces[i],...r});let a=this.archivedWorkspaces.findIndex(t=>t.id===e);a>=0&&(this.archivedWorkspaces[a]={...this.archivedWorkspaces[a],...r})},async renameSession(e,t,n){let r=await fetch(`/api/workspaces/${e}/sessions/${t}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:n})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error??`HTTP ${r.status}`)}let i=await r.json().catch(()=>null),a=this.sessions.find(e=>e.id===t);a&&(a.name=i?.name??n)},addActivityItem(e,t){if(this.activityFeeds[e]||(this.activityFeeds[e]=[]),this.activityFeedIds[e]||(this.activityFeedIds[e]=new Set),this.activityCounts[e]||(this.activityCounts[e]={toolUses:0,agentMessages:0,userMessages:0,errors:0}),t.meta?.sender!==`user`&&t.meta?.sender!==`system-prompt`)for(let t of this.activityFeeds[e])t.meta?.pending&&(t.meta.pending=!1);if(!this.activityFeedIds[e].has(t.id)){this.activityFeedIds[e].add(t.id),this.activityFeeds[e].push(t);let n=this.activityCounts[e];t.type===`tool_use`?n.toolUses++:t.type===`error`&&n.errors++,t.meta?.sender===`user`?n.userMessages++:t.type===`text`&&t.meta?.sender!==`system-prompt`&&n.agentMessages++}let n=this.activityFeeds[e];if(n.length>On){let t=n.splice(0,n.length-On),r=this.activityFeedIds[e];for(let e of t)r.delete(e.id)}},removeActivityItem(e,t){let n=this.activityFeeds[e],r=this.activityFeedIds[e];if(!n||!r)return;let i=n.findIndex(e=>e.id===t);if(i<0)return;let[a]=n.splice(i,1);r.delete(t);let o=this.activityCounts[e];o&&a&&(a.type===`tool_use`?o.toolUses=Math.max(0,o.toolUses-1):a.type===`error`&&(o.errors=Math.max(0,o.errors-1)),a.meta?.sender===`user`?o.userMessages=Math.max(0,o.userMessages-1):a.type===`text`&&a.meta?.sender!==`system-prompt`&&(o.agentMessages=Math.max(0,o.agentMessages-1)))},clearActivityFeed(e){e?(delete this.activityFeeds[e],delete this.activityFeedIds[e],delete this.activityCounts[e]):(this.activityFeeds={},this.activityFeedIds={},this.activityCounts={})},applyUsageSnapshot(e){this.providerUsage[e.providerId]=e.snapshot},async requestUsageRefresh(e){try{await fetch(`/api/usage/${e}/refresh`,{method:`POST`})}catch(e){console.error(`[workspace store] requestUsageRefresh failed:`,e)}},triggerGitRefresh(){this.gitRefreshTrigger++,this.schedulePrSnapshotsRefresh()},schedulePrSnapshotsRefresh(){An!==null&&clearTimeout(An),An=setTimeout(()=>{An=null,this.fetchPrSnapshots()},kn)},async fetchPrSnapshots(){try{let e=await fetch(`/api/workspaces/pr-states`,{cache:`no-store`});if(!e.ok)return;this.prSnapshots=await e.json()}catch(e){console.error(`[workspace-store] fetchPrSnapshots failed:`,e)}},async fetchWorkspacesInfo(){try{let e=await fetch(`/api/workspaces/info`,{cache:`no-store`});if(!e.ok)return;let t=await e.json();this.workspaces=t.workspaces;for(let e of this.workspaces)[`completed`,`idle`,`error`,`quota`].includes(e.status)&&this.finalizeRunningSubagents(e.id);this.prSnapshots=t.prSnapshots,this.gitStatsCache={...this.gitStatsCache,...t.gitStats}}catch(e){console.error(`[workspace-store] fetchWorkspacesInfo failed:`,e)}},async refreshPrSnapshot(e){try{let t=await fetch(`/api/workspaces/pr-snapshot/refresh/${e}`,{method:`POST`});if(t.status===404){let t={...this.prSnapshots};return delete t[e],this.prSnapshots=t,null}if(!t.ok)return console.error(`[workspace-store] refreshPrSnapshot non-OK:`,t.status),null;let n=await t.json();return this.prSnapshots={...this.prSnapshots,[e]:n.snapshot},n.snapshot}catch(e){return console.error(`[workspace-store] refreshPrSnapshot failed:`,e),null}},async fetchAutoLoopStates(){try{let e=await fetch(`/api/workspaces/auto-loop-states`,{cache:`no-store`});if(!e.ok)return;this.autoLoopStates=await e.json()}catch(e){console.error(`[workspace-store] fetchAutoLoopStates failed:`,e)}},async enableAutoLoop(e){let t=this.workspaces.find(t=>t.id===e);if(t&&t.agentPermissionMode===`plan`)try{await this.updateAgentPermissionMode(e,`bypass`)}catch{}let n=await fetch(`/api/workspaces/${e}/auto-loop`,{method:`POST`});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}await this.fetchAutoLoopStates()},async disableAutoLoop(e){let t=await fetch(`/api/workspaces/${e}/auto-loop`,{method:`DELETE`});if(!t.ok){let e=await t.json().catch(()=>({}));throw Error(e.error??`HTTP ${t.status}`)}await this.fetchAutoLoopStates()},async forceAutoLoopReady(e){let t=await fetch(`/api/workspaces/${e}/auto-loop-ready`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);await this.fetchAutoLoopStates()},setAutoLoopState(e,t){this.autoLoopStates[e]=t},clearAutoLoopState(e){delete this.autoLoopStates[e]},async fetchCrons(e){try{let t=await fetch(`/api/workspaces/${e}/crons`);if(!t.ok)return;let n=await t.json();this.crons[e]=n.crons}catch(e){console.error(`[workspace-store] fetchCrons failed:`,e)}},async cancelCron(e,t){let n=this.crons[e]??[];this.crons[e]=n.filter(e=>e.id!==t);try{let n=await fetch(`/api/workspaces/${e}/crons/${t}`,{method:`DELETE`});if(!n.ok)throw Error(`HTTP ${n.status}`)}catch(t){throw this.crons[e]=n,t}},async createCron(e,t){let n=await fetch(`/api/workspaces/${e}/crons`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}await this.fetchCrons(e)},async scheduleManualWakeup(e,t){let n=await fetch(`/api/workspaces/${e}/pending-wakeup`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??`HTTP ${n.status}`)}let r=await n.json();r.pending&&(this.pendingWakeups[e]=r.pending)},async fetchPendingWakeup(e){try{let t=await fetch(`/api/workspaces/${e}/pending-wakeup`,{cache:`no-store`});if(!t.ok)return;let n=await t.json();n?this.pendingWakeups[e]=n:delete this.pendingWakeups[e]}catch(e){console.error(`[workspace-store] fetchPendingWakeup failed:`,e)}},setPendingWakeup(e,t){this.pendingWakeups[e]=t},clearPendingWakeup(e){delete this.pendingWakeups[e]},async cancelPendingWakeup(e){let t=this.pendingWakeups[e]!==void 0;delete this.pendingWakeups[e];try{let t=await fetch(`/api/workspaces/${e}/pending-wakeup`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`)}catch(n){console.error(`[workspace-store] cancelPendingWakeup failed:`,n),t&&await this.fetchPendingWakeup(e)}},async fetchPendingQuotaBackoff(e){try{let t=await fetch(`/api/workspaces/${e}/quota-backoff`,{cache:`no-store`});if(!t.ok)return;let n=await t.json();n?this.pendingQuotaBackoffs[e]=n:delete this.pendingQuotaBackoffs[e]}catch(e){console.error(`[workspace-store] fetchPendingQuotaBackoff failed:`,e)}},setPendingQuotaBackoff(e,t){this.pendingQuotaBackoffs[e]=t},clearPendingQuotaBackoff(e){delete this.pendingQuotaBackoffs[e]},async cancelQuotaBackoff(e){let t=this.pendingQuotaBackoffs[e]!==void 0;delete this.pendingQuotaBackoffs[e];try{let t=await fetch(`/api/workspaces/${e}/quota-backoff`,{method:`DELETE`});if(!t.ok)throw Error(`HTTP ${t.status}`)}catch(n){console.error(`[workspace-store] cancelQuotaBackoff failed:`,n),t&&await this.fetchPendingQuotaBackoff(e)}},enqueuePending(e,t){let n=this.pendingQueue[e]??[];n.some(e=>e.toolCallId===t.toolCallId)||(n.push(t),this.pendingQueue[e]=n,t.kind===`question`&&(this.pendingDeferred[e]={toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,agentSessionId:t.agentSessionId}))},peekPending(e){return this.pendingQueue[e]?.[0]},dequeuePending(e){let t=this.pendingQueue[e];if(!t||t.length===0)return;let n=t.shift();t.length===0&&delete this.pendingQueue[e];let r=this.pendingQueue[e]?.[0];return r&&r.kind===`question`?this.pendingDeferred[e]={toolCallId:r.toolCallId,toolName:r.toolName,input:r.input,agentSessionId:r.agentSessionId}:delete this.pendingDeferred[e],n},clearPendingForSession(e,t){if(t===null)return;let n=this.pendingQueue[e];if(!n)return;let r=n.filter(e=>e.agentSessionId!==t);r.length===0?delete this.pendingQueue[e]:this.pendingQueue[e]=r;let i=this.pendingDeferred[e];i&&i.agentSessionId===t&&delete this.pendingDeferred[e]},clearAllPending(e){delete this.pendingQueue[e],delete this.pendingDeferred[e]},setPendingDeferred(e,t){this.enqueuePending(e,{kind:`question`,agentSessionId:t.agentSessionId,toolCallId:t.toolCallId,toolName:t.toolName,input:t.input})},clearPendingDeferred(e,t=null){if(t===null){this.clearAllPending(e);return}this.clearPendingForSession(e,t)},getPendingDeferred(e){let t=this.peekPending(e);if(!(!t||t.kind!==`question`))return{toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,agentSessionId:t.agentSessionId}},async submitDeferredAnswer(e,t,n){let r=await fetch(`/api/workspaces/${e}/deferred-tool-use/answer`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({answers:t,toolCallId:n})});if(!r.ok){let t=(await r.json().catch(()=>({}))).error??`HTTP ${r.status}`;if(/no deferred tool use pending/i.test(t)){console.warn(`[workspace] submitDeferredAnswer: backend has no pending — clearing zombie panel locally`),this.dequeuePending(e),this.fetchWorkspaces();return}throw Error(t)}this.dequeuePending(e),this.fetchWorkspaces()},async cancelDeferredAnswer(e,t,n){let r=await fetch(`/api/workspaces/${e}/deferred-tool-use/cancel`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({reason:t,toolCallId:n})});if(!r.ok){let t=(await r.json().catch(()=>({}))).error??`HTTP ${r.status}`;if(/no deferred tool use pending/i.test(t)){console.warn(`[workspace] cancelDeferredAnswer: backend has no pending — clearing zombie panel locally`),this.dequeuePending(e),this.fetchWorkspaces();return}throw Error(t)}this.dequeuePending(e),this.fetchWorkspaces()},async submitDeferredPermission(e,t,n,r){let i=await fetch(`/api/workspaces/${e}/deferred-permission/decision`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({toolCallId:t,decision:n,reason:r})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}this.dequeuePending(e),this.fetchWorkspaces()},updateAgentTodos(e,t){this.agentTodos[e]=t},agentTaskCreate(e,t,n){let r=this.agentTodos[e]?[...this.agentTodos[e]]:[];r.some(e=>e.id===t)||(r.push({id:t,content:n.subject||n.description||``,status:`pending`,activeForm:n.activeForm}),this.agentTodos[e]=r)},agentTaskSetNumber(e,t,n){let r=this.agentTodos[e];r&&(this.agentTodos[e]=r.map(e=>e.id===t?{...e,taskNumber:n}:e))},agentTaskUpdate(e,t,n){let r=this.agentTodos[e];if(r){if(n.status===`deleted`){this.agentTodos[e]=r.filter(e=>e.taskNumber!==t);return}this.agentTodos[e]=r.map(e=>e.taskNumber===t?{...e,status:n.status?Dn(n.status):e.status,content:n.content??e.content,activeForm:n.activeForm??e.activeForm}:e)}},finalizeRunningSubagents(e){let t=this.subagents[e];if(!t)return;let n=new Date().toISOString();for(let e of Object.keys(t)){let r=t[e];r.status===`running`&&(t[e]={...r,status:`done`,updatedAt:n})}},upsertSubagent(e,t){this.subagents[e]||(this.subagents[e]={});let n=this.subagents[e][t.toolUseId],r=new Date().toISOString(),i=n?.status===`done`?`done`:t.status??n?.status??`running`;this.subagents[e][t.toolUseId]={toolUseId:t.toolUseId,description:t.description??n?.description??``,taskType:t.taskType??n?.taskType,status:i,lastToolName:t.lastToolName??n?.lastToolName,lastDescription:t.lastDescription??n?.lastDescription,totalTokens:t.totalTokens??n?.totalTokens,toolUses:t.toolUses??n?.toolUses,durationMs:t.durationMs??n?.durationMs,startedAt:n?.startedAt??r,updatedAt:r}},async markRead(e){try{let t=await fetch(`/api/workspaces/${e}/mark-read`,{method:`POST`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=this.workspaces.findIndex(t=>t.id===e);n>=0&&(this.workspaces[n]={...this.workspaces[n],hasUnread:!1})}catch(e){console.error(`[workspace store] markRead failed:`,e)}},async purgeWorktree(e){try{let t=await fetch(`/api/workspaces/${e}/purge-worktree`,{method:`POST`}),n=await t.json();if(!t.ok)return{ok:!1,error:n.error??`HTTP ${t.status}`};let r=n.workspace;return r&&(this.updateWorkspaceFromEvent(e,{archivedAt:r.archivedAt,worktreePurgedAt:r.worktreePurgedAt,worktreePurgeRestoreData:r.worktreePurgeRestoreData}),r.archivedAt&&this.archivedLoaded&&(this.archivedWorkspaces.some(t=>t.id===e)||this.archivedWorkspaces.unshift(r),this.workspaces=this.workspaces.filter(t=>t.id!==e),this.selectedWorkspaceId===e&&(this.selectedWorkspaceId=null,this.tasks=[]))),{ok:!0,warnings:n.warnings??[]}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async dismissPrAttention(e,t){let n=this.prSnapshots[e];if(n)try{let r=await fetch(`/api/workspaces/${e}/dismiss-pr-attention`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kind:t,prUpdatedAt:n.updatedAt})});if(!r.ok)throw Error(`HTTP ${r.status}`);let i=t===`changes-requested`?{prChangesDismissedAt:n.updatedAt}:{prCiFailureDismissedAt:n.updatedAt};this.updateWorkspaceFromEvent(e,i)}catch(e){console.error(`[workspace store] dismissPrAttention failed:`,e)}},async restorePrAttention(e,t){try{let n=await fetch(`/api/workspaces/${e}/restore-pr-attention`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({kind:t})});if(!n.ok)throw Error(`HTTP ${n.status}`);let r=t===`changes-requested`?{prChangesDismissedAt:null}:{prCiFailureDismissedAt:null};this.updateWorkspaceFromEvent(e,r)}catch(e){console.error(`[workspace store] restorePrAttention failed:`,e)}},queueMessage(e,t,n){this.queuedMessages[e]={content:t,sessionId:n}},cancelQueuedMessage(e){delete this.queuedMessages[e]},updateWorkspaceFromEvent(e,t){let n=this.workspaces.findIndex(t=>t.id===e);if(n>=0&&(this.workspaces[n]={...this.workspaces[n],...t}),t.status&&[`completed`,`idle`,`error`,`quota`].includes(t.status)){let n=this.activityFeeds[e];if(n)for(let e of n)e.meta?.pending&&(e.meta.pending=!1);let r=this.subagents[e];if(r)for(let[e,t]of Object.entries(r))t.status===`running`&&(r[e]={...t,status:`done`});let i=this.queuedMessages[e];(t.status===`completed`||t.status===`idle`)&&i&&(delete this.queuedMessages[e],zn().sendChatMessage(e,i.content,i.sessionId),this.addActivityItem(e,{id:`user-${Date.now()}`,type:`text`,content:i.content,timestamp:new Date().toISOString(),sessionId:i.sessionId,meta:{sender:`user`,pending:!0}}))}}}}),K=mn.global.t,q=null,Mn=null,Nn=0,Pn=!1;function Fn(e){Pn=e}function In(e,t,n){if(t.kind!==`session:started`)return;let r=G();if(n){let t=r.peekPending(e);t&&t.agentSessionId===n&&r.dequeuePending(e)}let i=r.workspaces.find(t=>t.id===e);i&&(i.status===`completed`||i.status===`idle`||i.status===`error`||i.status===`quota`)&&r.updateWorkspaceFromEvent(e,{status:`executing`}),!Pn&&n&&r.selectedWorkspaceId===e&&r.selectedSessionId!==n&&r.fetchSessions(e,n).catch(e=>{console.error(`[websocket] fetchSessions on session:started failed:`,e)})}function Ln(e,t){let n=G();if(t.kind===`tool:call`&&t.name===`TodoWrite`){let r=t.input?.todos;return Array.isArray(r)&&n.updateAgentTodos(e,r.map(e=>({content:typeof e.content==`string`?e.content:``,status:typeof e.status==`string`?e.status:`pending`,activeForm:typeof e.activeForm==`string`?e.activeForm:void 0}))),!0}if(t.kind===`tool:call`&&t.name===`TaskCreate`){let r=t.input??{};return n.agentTaskCreate(e,t.toolCallId,{subject:typeof r.subject==`string`?r.subject:void 0,description:typeof r.description==`string`?r.description:void 0,activeForm:typeof r.activeForm==`string`?r.activeForm:void 0}),!0}if(t.kind===`tool:result`&&typeof t.output==`string`){let r=t.output.match(/^Task #(\d+) created successfully/);if(r)return n.agentTaskSetNumber(e,t.toolCallId,Number(r[1])),!0}if(t.kind===`tool:call`&&t.name===`TaskUpdate`){let r=t.input??{},i=r.task_id??r.taskId??r.id,a=typeof i==`number`?i:typeof i==`string`?Number(i):NaN;return Number.isFinite(a)&&n.agentTaskUpdate(e,a,{status:typeof r.status==`string`?r.status:void 0,content:typeof r.subject==`string`?r.subject:void 0,activeForm:typeof r.activeForm==`string`?r.activeForm:void 0}),!0}return!1}function Rn(e,t,n,r,i){let a=hn();if(t.kind===`session:compacting`){a.setCompacting(e,t.active);return}a.append(e,t,n,r,i),(t.kind===`session:compacted`||t.kind===`session:ended`||t.kind===`message:text`||t.kind===`tool:call`)&&a.setCompacting(e,!1),In(e,t,i??void 0);let o=G();if(t.kind===`session:user-input-requested`){if(t.requestKind===`question`?o.enqueuePending(e,{kind:`question`,agentSessionId:i??null,toolCallId:t.toolCallId,toolName:t.toolName,input:t.payload}):o.enqueuePending(e,{kind:`permission`,agentSessionId:i??null,toolCallId:t.toolCallId,toolName:t.toolName,toolInput:t.payload}),o.updateWorkspaceFromEvent(e,{status:`awaiting-user`}),!Pn){let n=o.workspaces.find(t=>t.id===e)?.name??``;z(t.requestKind===`question`?K(`notification.agentQuestion`,{name:n}):K(`notification.agentPermissionRequest`,{name:n}),void 0,e)}return}if(t.kind===`subagent:progress`){o.upsertSubagent(e,{toolUseId:t.toolCallId,status:t.status,description:t.description,taskType:t.taskType,lastToolName:t.lastToolName,totalTokens:t.totalTokens,toolUses:t.toolUses,durationMs:t.durationMs});return}if(!Ln(e,t)){if(t.kind===`tool:call`&&t.name===`Bash`){let n=t.input,r=`${n?.command??``} ${n?.description??``}`;/\bgit\b|commit|push|pull|merge|rebase|checkout|branch/i.test(r)&&o.triggerGitRefresh(),/\bgit\s+branch\s+-m\b/i.test(r)&&setTimeout(()=>{o.resyncWorkspaceBranch(e).catch(e=>{console.error(`[websocket] Branch resync failed:`,e)})},2500),/\bgh\s+pr\s+create\b/i.test(r)&&setTimeout(()=>o.triggerGitRefresh(),3e3)}if(t.kind===`tool:call`&&t.name===`ExitPlanMode`&&o.workspaces.find(t=>t.id===e)?.agentPermissionMode===`plan`&&(o.updateWorkspaceFromEvent(e,{agentPermissionMode:`bypass`}),o.updateAgentPermissionMode(e,`bypass`).catch(e=>{console.error(`[websocket] failed to persist ExitPlanMode flip:`,e)})),t.kind!==`session:started`){if(t.kind===`session:ended`){i&&o.clearPendingForSession(e,i);let n=o.workspaces.find(t=>t.id===e)?.status===`quota`?`quota`:t.reason===`completed`?`completed`:t.reason===`error`?`error`:`idle`;if(o.updateWorkspaceFromEvent(e,{status:n}),o.finalizeRunningSubagents(e),o.fetchWorkspaces(),!Pn&&t.reason!==`killed`&&o.autoLoopStates[e]?.auto_loop!==!0){let n=o.workspaces.find(t=>t.id===e)?.name??``;z(t.reason===`error`?K(`notification.agentError`,{name:n}):K(`notification.agentFinished`,{name:n}),void 0,e)}return}t.kind===`error`&&t.category===`quota`&&(o.updateWorkspaceFromEvent(e,{status:`quota`}),o.fetchWorkspaces())}}}var zn=F(`websocket`,{state:()=>({connected:!1,lastEventId:null,_replaying:!1}),actions:{connect(){if(q)return;let e=`${window.location.protocol===`https:`?`wss:`:`ws:`}//${window.location.host}/ws`,t=new WebSocket(e);q=t,t.addEventListener(`open`,()=>{this.connected=!0,Nn=0;let e=G().workspaces.map(e=>e.id);for(let t of e)this._send({type:`subscribe`,payload:{workspaceId:t}});this.lastEventId&&this._send({type:`sync:request`,payload:{lastEventId:this.lastEventId,workspaceIds:e}})}),t.addEventListener(`message`,e=>{try{let t=JSON.parse(e.data);this._routeMessage(t)}catch{}}),t.addEventListener(`close`,()=>{this.connected=!1,q=null,this._scheduleReconnect()}),t.addEventListener(`error`,()=>{})},disconnect(){Mn&&=(clearTimeout(Mn),null),q&&=(q.close(),null),this.connected=!1},subscribe(e){this._send({type:`subscribe`,payload:{workspaceId:e}}),this._send({type:`sync:request`,payload:{workspaceIds:[e]}})},unsubscribe(e){this._send({type:`unsubscribe`,payload:{workspaceId:e}})},sendChatMessage(e,t,n,r){this._send({type:`chat:message`,payload:{workspaceId:e,content:t,sessionId:n,agentPermissionModeOverride:r}}),/^\/compact(\s|$)/.test(t.trim())&&hn().setCompacting(e,!0);let i=G(),a=i.workspaces.find(t=>t.id===e);a&&(a.status===`completed`||a.status===`idle`||a.status===`error`||a.status===`quota`)&&i.updateWorkspaceFromEvent(e,{status:`executing`})},_send(e){q&&q.readyState===WebSocket.OPEN&&q.send(JSON.stringify(e))},isConnected(){return q!==null&&q.readyState===WebSocket.OPEN},_scheduleReconnect(){if(Mn)return;let e=Math.min(1e3*2**Nn,3e4);Nn++,Mn=setTimeout(()=>{Mn=null,this.connect()},e)},_routeMessage(e){let t=G();e.id?this.lastEventId=e.id:e.eventId&&(this.lastEventId=e.eventId);let n=e.payload??{},r=e.workspaceId??n.workspaceId??``;switch(e.type){case`agent:event`:{if(!r)break;let t=e.createdAt;Rn(r,n,t,e.id??e.eventId,e.sessionId??null);break}case`agent:progress`:n.tasks&&Array.isArray(n.tasks)&&(t.tasks=n.tasks);break;case`user:message`:if(r&&n.content){let i=n.content,a=n.sender??`user`,o=e.sessionId,s=e.id??e.eventId??`user-${Date.now()}`,c=e.createdAt??new Date().toISOString(),l=t.activityFeeds[r]??[];if(a===`user`&&l.some(e=>e.meta?.sender===`user`&&e.content===i&&e.meta?.pending)){let e=l.findIndex(e=>e.meta?.sender===`user`&&e.content===i&&e.meta?.pending);e>=0&&(l[e]={...l[e],id:s,sessionId:o})}else t.addActivityItem(r,{id:s,type:`text`,content:i,timestamp:c,sessionId:o,meta:{sender:a}})}break;case`sync:response`:this._replaying=!0,Fn(!0);try{let e=n.events??[],t=new Map;for(let n of e)if(n.type!==`sync:response`){if(n.type===`agent:event`&&n.workspaceId){let e=t.get(n.workspaceId)??{events:[],timestamps:[],sessionIds:[],eventIds:[],oldestId:void 0};e.events.push(n.payload),e.timestamps.push(n.createdAt),e.sessionIds.push(n.sessionId??null),e.eventIds.push(n.id??null),e.oldestId||=n.id,t.set(n.workspaceId,e);continue}this._routeMessage(n)}if(t.size>0){let e=hn();for(let[n,{events:r,timestamps:i,sessionIds:a,eventIds:o,oldestId:s}]of t){e.reset(n,r,i,{oldestId:s,hasMoreOlder:!0,sessionIds:a,eventIds:o}),G().updateAgentTodos(n,[]);for(let e=0;e<r.length;e++){let t=r[e];if(!t)continue;let i=a[e]??null;if(t.kind===`session:user-input-requested`){t.requestKind===`question`?G().enqueuePending(n,{kind:`question`,agentSessionId:i,toolCallId:t.toolCallId,toolName:t.toolName,input:t.payload}):G().enqueuePending(n,{kind:`permission`,agentSessionId:i,toolCallId:t.toolCallId,toolName:t.toolName,toolInput:t.payload});continue}if(t.kind===`session:started`){if(i){let e=G(),t=e.peekPending(n);t&&t.agentSessionId===i&&e.dequeuePending(n)}continue}if(t.kind===`session:ended`){i&&G().clearPendingForSession(n,i);continue}if(t.kind===`subagent:progress`){G().upsertSubagent(n,{toolUseId:t.toolCallId,status:t.status,description:t.description,taskType:t.taskType,lastToolName:t.lastToolName,totalTokens:t.totalTokens,toolUses:t.toolUses,durationMs:t.durationMs});continue}Ln(n,t)}}}}finally{this._replaying=!1,Fn(!1)}break;case`usage:snapshot`:{let e=n;e.providerId&&e.snapshot&&t.applyUsageSnapshot({providerId:e.providerId,snapshot:e.snapshot});break}case`devserver:status`:{let e=gn();r&&e.updateFromWsEvent(r,n);break}case`task:updated`:r&&t.fetchWorkspaceDetails(r);break;case`setup:output`:t.addActivityItem(r,{id:e.id??`setup-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`setup:complete`:t.addActivityItem(r,{id:e.id??`setup-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[setup] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`setup:error`:t.addActivityItem(r,{id:e.id??`setup-error-${Date.now()}`,type:`text`,content:`[setup] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`setup`}});break;case`cleanup:output`:t.addActivityItem(r,{id:e.id??`cleanup-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`cleanup:complete`:t.addActivityItem(r,{id:e.id??`cleanup-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[cleanup] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`cleanup:error`:t.addActivityItem(r,{id:e.id??`cleanup-error-${Date.now()}`,type:`text`,content:`[cleanup] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`cleanup`}});break;case`archive:output`:t.addActivityItem(r,{id:e.id??`archive-${Date.now()}`,type:`text`,content:e.payload?.text??``,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`archive:complete`:t.addActivityItem(r,{id:e.id??`archive-complete-${Date.now()}`,type:`text`,content:e.payload?.hadOutput===!1?K(`chat.scriptDone`):`[archive] Complete`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`archive:error`:t.addActivityItem(r,{id:e.id??`archive-error-${Date.now()}`,type:`text`,content:`[archive] Error: ${e.payload?.message??`unknown`}`,timestamp:e.createdAt??new Date().toISOString(),meta:{sender:`archive`}});break;case`workspace:unread`:if(r){let e=n.hasUnread??!1;t.updateWorkspaceFromEvent(r,{hasUnread:e})}break;case`workspace:pr-attention-dismissed`:if(r){let e=n.kind,i=n.prUpdatedAt;e&&i&&t.updateWorkspaceFromEvent(r,e===`changes-requested`?{prChangesDismissedAt:i}:{prCiFailureDismissedAt:i})}break;case`workspace:description-updated`:{if(!r)break;let e=n.description??null;t.updateWorkspaceFromEvent(r,{description:e});break}case`workspace:agent-description-updated`:{if(!r)break;let e=n.agentDescription??null;t.updateWorkspaceFromEvent(r,{agentDescription:e});break}case`cron:created`:{if(!r)break;let e=n.cron;if(!e)break;let i=t.crons[r]??[];i.some(t=>t.id===e.id)||(t.crons[r]=[...i,e]);let a=t.autoLoopStates[r];a&&(a.crons_count=t.crons[r].length);break}case`cron:fired`:{if(!r)break;let e=n,i=t.crons[r]??[];t.crons[r]=i.map(t=>t.id===e.id?{...t,nextFireAt:e.nextFireAt??t.nextFireAt,lastFiredAt:e.lastFiredAt??new Date().toISOString()}:t);break}case`cron:cancelled`:{if(!r)break;let e=n.id;if(!e)break;t.crons[r]=(t.crons[r]??[]).filter(t=>t.id!==e);let i=t.autoLoopStates[r];i&&(i.crons_count=t.crons[r].length);break}case`cron:updated`:{if(!r)break;let e=n.crons;if(Array.isArray(e)){t.crons[r]=e;let n=t.autoLoopStates[r];n&&(n.crons_count=e.length)}break}case`workspace:archived`:case`workspace:unarchived`:case`workspace:worktree-restored`:e.type===`workspace:archived`&&r&&t.selectedWorkspaceId===r&&(t.selectedWorkspaceId=null),t.fetchWorkspaces(),t.archivedLoaded&&t.fetchArchivedWorkspaces();break;case`pr:base-changed`:{if(!r)break;let e=n,i=e.oldBase??``,a=e.newBase??``;t.updateWorkspaceFromEvent(r,{sourceBranch:a});let o=[];e.prUrl&&o.push({label:K(`pr.openPr`),color:`white`,noDismiss:!0,handler:()=>window.open(e.prUrl,`_blank`)}),o.push({label:K(`pr.dismiss`),color:`white`}),rn.create({type:`info`,position:`top`,timeout:0,message:K(`pr.baseChanged`,{oldBase:i,newBase:a}),actions:o}),z(K(`pr.baseChanged`,{oldBase:i,newBase:a}),void 0,r);break}case`pr:changes-requested`:{if(!r)break;let e=n,i=K(`toast.prChangesRequested`,{n:e.prNumber??0}),a=[];e.prUrl&&a.push({label:K(`pr.openPr`),color:`white`,noDismiss:!0,handler:()=>window.open(e.prUrl,`_blank`)}),a.push({label:K(`pr.dismiss`),color:`white`}),rn.create({type:`warning`,position:`top`,timeout:0,message:i,actions:a}),z(i,void 0,r),t.refreshPrSnapshot(r);break}case`pr:approved`:{if(!r)break;let e=K(`toast.prApproved`,{n:n.prNumber??0});rn.create({type:`positive`,position:`top`,timeout:5e3,message:e}),z(e,void 0,r),t.refreshPrSnapshot(r);break}case`pr:ready-to-merge`:{if(!r)break;let e=K(`toast.prReadyToMerge`,{n:n.prNumber??0});rn.create({type:`positive`,position:`top`,timeout:5e3,message:e}),z(e,void 0,r),t.refreshPrSnapshot(r);break}case`wakeup:scheduled`:if(r){let e=n;typeof e.targetAt==`string`&&t.setPendingWakeup(r,{targetAt:e.targetAt,reason:e.reason})}break;case`wakeup:cancelled`:case`wakeup:fired`:case`wakeup:skipped`:r&&t.clearPendingWakeup(r);break;case`agent:quota-backoff`:{if(!r)break;let e=n;typeof e.targetAt==`string`&&typeof e.source==`string`&&t.setPendingQuotaBackoff(r,{targetAt:e.targetAt,resetsAt:e.resetsAt??null,source:e.source});break}case`agent:quota-backoff-cancelled`:r&&t.clearPendingQuotaBackoff(r);break;case`autoloop:enabled`:case`autoloop:iteration-started`:case`autoloop:ready-flipped`:t.fetchAutoLoopStates();break;case`autoloop:permission-overridden`:r&&z(K(`notification.autoLoopPermissionOverridden`,{name:t.workspaces.find(e=>e.id===r)?.name??``}),void 0,r);break;case`autoloop:disabled`:if(t.fetchAutoLoopStates(),r){let e=n?.reason,i=t.workspaces.find(e=>e.id===r)?.name??``,a=e===`error`?`notification.autoLoopError`:e===`stall`?`notification.autoLoopStalled`:e===`completed`?`notification.autoLoopCompleted`:null;a&&z(K(a,{name:i}),void 0,r)}break;case`migration:progress`:case`migration:error`:Nt().update(n);break}}}}),Bn=c({__name:`App`,setup(e){let t=zn(),n=Vt();return r(()=>{t.connect(),n.fetchTemplates(),Pe()}),i(()=>{t.disconnect()}),(e,t)=>{let n=d(`router-view`);return s(),m(g,null,[h(n),h(Bt)],64)}}});function Vn(e){return e}function Hn(e){return e}function Un(e){return e}var Wn=Un(()=>ue()),Gn=typeof document<`u`;function Kn(e){return typeof e==`object`||`displayName`in e||`props`in e||`__vccOpts`in e}function qn(e){return e.__esModule||e[Symbol.toStringTag]===`Module`||e.default&&Kn(e.default)}var J=Object.assign;function Jn(e,t){let n={};for(let r in t){let i=t[r];n[r]=Y(i)?i.map(e):e(i)}return n}var Yn=()=>{},Y=Array.isArray;function Xn(e,t){let n={};for(let r in e)n[r]=r in t?t[r]:e[r];return n}var Zn=Symbol(``);function Qn(e,t){return J(Error(),{type:e,[Zn]:!0},t)}function X(e,t){return e instanceof Error&&Zn in e&&(t==null||!!(e.type&t))}var $n=Symbol(``),er=Symbol(``),tr=Symbol(``),nr=Symbol(``),rr=Symbol(``);function ir(){return n(tr)}function ar(e){return n(nr)}var or=/#/g,sr=/&/g,cr=/\//g,lr=/=/g,ur=/\?/g,dr=/\+/g,fr=/%5B/g,pr=/%5D/g,mr=/%5E/g,hr=/%60/g,gr=/%7B/g,_r=/%7C/g,vr=/%7D/g,yr=/%20/g;function br(e){return e==null?``:encodeURI(``+e).replace(_r,`|`).replace(fr,`[`).replace(pr,`]`)}function xr(e){return br(e).replace(gr,`{`).replace(vr,`}`).replace(mr,`^`)}function Sr(e){return br(e).replace(dr,`%2B`).replace(yr,`+`).replace(or,`%23`).replace(sr,`%26`).replace(hr,"`").replace(gr,`{`).replace(vr,`}`).replace(mr,`^`)}function Cr(e){return Sr(e).replace(lr,`%3D`)}function wr(e){return br(e).replace(or,`%23`).replace(ur,`%3F`)}function Tr(e){return wr(e).replace(cr,`%2F`)}function Er(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var Dr=/\/$/,Or=e=>e.replace(Dr,``);function kr(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=Lr(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:Er(o)}}function Ar(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function jr(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function Mr(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&Nr(t.matched[r],n.matched[i])&&Pr(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function Nr(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function Pr(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!Fr(e[n],t[n]))return!1;return!0}function Fr(e,t){return Y(e)?Ir(e,t):Y(t)?Ir(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function Ir(e,t){return Y(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function Lr(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o<r.length;o++)if(s=r[o],s!==`.`)if(s===`..`)a>1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var Z={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function Rr(e){if(!e)if(Gn){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),Or(e)}var zr=/^[^#]+#/;function Br(e,t){return e.replace(zr,`#`)+t}function Vr(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var Hr=()=>({left:window.scrollX,top:window.scrollY});function Ur(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=Vr(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function Wr(e,t){return(history.state?history.state.position-t:-1)+e}var Gr=new Map;function Kr(e,t){Gr.set(e,t)}function qr(e){let t=Gr.get(e);return Gr.delete(e),t}function Jr(e){return typeof e==`string`||e&&typeof e==`object`}function Yr(e){return typeof e==`string`||typeof e==`symbol`}function Xr(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;e<n.length;++e){let r=n[e].replace(dr,` `),i=r.indexOf(`=`),a=Er(i<0?r:r.slice(0,i)),o=i<0?null:Er(r.slice(i+1));if(a in t){let e=t[a];Y(e)||(e=t[a]=[e]),e.push(o)}else t[a]=o}return t}function Zr(e){let t=``;for(let n in e){let r=e[n];if(n=Cr(n),r==null){r!==void 0&&(t+=(t.length?`&`:``)+n);continue}(Y(r)?r.map(e=>e&&Sr(e)):[r&&Sr(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function Qr(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=Y(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function $r(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function Q(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(Qn(4,{from:n,to:t})):e instanceof Error?c(e):Jr(e)?c(Qn(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function ei(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(Kn(s)){let c=(s.__vccOpts||s)[t];c&&a.push(Q(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=qn(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&Q(c,n,r,o,e,i)()}))}}return a}function ti(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o<a;o++){let a=t.matched[o];a&&(e.matched.find(e=>Nr(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>Nr(e,s))||i.push(s))}return[n,r,i]}var ni=()=>location.protocol+`//`+location.host;function ri(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),jr(n,``)}return jr(n,e)+r+i}function ii(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=ri(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(J({},e.state,{scroll:Hr()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function ai(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?Hr():null}}function oi(e){let{history:t,location:n}=window,r={value:ri(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:ni()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,J({},t.state,ai(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=J({},i.value,t.state,{forward:e,scroll:Hr()});a(o.current,o,!0),a(e,J({},ai(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function si(e){e=Rr(e);let t=oi(e),n=ii(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=J({location:``,base:e,go:r,createHref:Br.bind(null,e)},t,n);return Object.defineProperty(i,`location`,{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,`state`,{enumerable:!0,get:()=>t.state.value}),i}function ci(e){return e=location.host?e||location.pathname+location.search:``,e.includes(`#`)||(e+=`#`),si(e)}var li={type:0,value:``},ui=/[a-zA-Z0-9_]/;function di(e){if(!e)return[[]];if(e===`/`)return[[li]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;s<e.length;)switch(c=e[s++],n){case 0:c===`\\`?(r=n,n=4):c===`/`?(l&&d(),o()):c===`:`?(d(),n=1):f();break;case 4:f(),n=r;break;case 1:c===`(`?n=2:ui.test(c)?f():(d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--);break;case 2:c===`)`?u[u.length-1]==`\\`?u=u.slice(0,-1)+c:n=3:u+=c;break;case 3:d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--,u=``;break;default:t(`Unknown state`);break}return n===2&&t(`Unfinished custom RegExp for param "${l}"`),d(),o(),i}var fi=`[^/]+?`,pi={sensitive:!1,strict:!1,start:!0,end:!0},mi=/[.+*?^${}()[\]/\\]/g;function hi(e,t){let n=J({},pi,t),r=[],i=n.start?`^`:``,a=[];for(let t of e){let e=t.length?[]:[90];n.strict&&!t.length&&(i+=`/`);for(let r=0;r<t.length;r++){let o=t[r],s=40+(n.sensitive?.25:0);if(o.type===0)r||(i+=`/`),i+=o.value.replace(mi,`\\$&`),s+=40;else if(o.type===1){let{value:e,repeatable:n,optional:c,regexp:l}=o;a.push({name:e,repeatable:n,optional:c});let u=l||fi;if(u!==fi){s+=10;try{RegExp(`(${u})`)}catch(t){throw Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let d=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(d=c&&t.length<2?`(?:/${d})`:`/`+d),c&&(d+=`?`),i+=d,s+=20,c&&(s+=-8),n&&(s+=-20),u===`.*`&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){let e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(i+=`/?`),n.end?i+=`$`:n.strict&&!i.endsWith(`/`)&&(i+=`(?:/|$)`);let o=new RegExp(i,n.sensitive?``:`i`);function s(e){let t=e.match(o),n={};if(!t)return null;for(let e=1;e<t.length;e++){let r=t[e]||``,i=a[e-1];n[i.name]=r&&i.repeatable?r.split(`/`):r}return n}function c(t){let n=``,r=!1;for(let i of e){(!r||!n.endsWith(`/`))&&(n+=`/`),r=!1;for(let e of i)if(e.type===0)n+=e.value;else if(e.type===1){let{value:a,repeatable:o,optional:s}=e,c=a in t?t[a]:``;if(Y(c)&&!o)throw Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);let l=Y(c)?c.join(`/`):c;if(!l)if(s)i.length<2&&(n.endsWith(`/`)?n=n.slice(0,-1):r=!0);else throw Error(`Missing required param "${a}"`);n+=l}}return n||`/`}return{re:o,score:r,keys:a,parse:s,stringify:c}}function gi(e,t){let n=0;for(;n<e.length&&n<t.length;){let r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?e.length===1&&e[0]===80?-1:1:e.length>t.length?t.length===1&&t[0]===80?1:-1:0}function _i(e,t){let n=0,r=e.score,i=t.score;for(;n<r.length&&n<i.length;){let e=gi(r[n],i[n]);if(e)return e;n++}if(Math.abs(i.length-r.length)===1){if(vi(r))return 1;if(vi(i))return-1}return i.length-r.length}function vi(e){let t=e[e.length-1];return e.length>0&&t[t.length-1]<0}var yi={strict:!1,end:!0,sensitive:!1};function bi(e,t,n){let r=J(hi(di(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function xi(e,t){let n=[],r=new Map;t=Xn(yi,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=Ci(e);s.aliasOf=r&&r.record;let l=Xn(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(Ci(J({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=bi(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!Ti(d)&&o(e.name)),ki(d)&&c(d),s.children){let e=s.children;for(let t=0;t<e.length;t++)a(e[t],d,r&&r.children[t])}r||=d}return f?()=>{o(f)}:Yn}function o(e){if(Yr(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=Di(e,n);n.splice(t,0,e),e.record.name&&!Ti(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw Qn(1,{location:e});s=i.record.name,a=J(Si(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&Si(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw Qn(1,{location:e,currentLocation:t});s=i.record.name,a=J({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:Ei(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function Si(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function Ci(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:wi(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,`mods`,{value:{}}),t}function wi(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function Ti(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Ei(e){return e.reduce((e,t)=>J(e,t.meta),{})}function Di(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;_i(e,t[i])<0?r=i:n=i+1}let i=Oi(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function Oi(e){let t=e;for(;t=t.parent;)if(ki(t)&&_i(e,t)===0)return t}function ki({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Ai(e){let t=n(tr),r=n(nr),i=T(()=>{let n=S(e.to);return t.resolve(n)}),a=T(()=>{let{matched:e}=i.value,{length:t}=e,n=e[t-1],a=r.matched;if(!n||!a.length)return-1;let o=a.findIndex(Nr.bind(null,n));if(o>-1)return o;let s=Fi(e[t-2]);return t>1&&Fi(n)===s&&a[a.length-1].path!==s?a.findIndex(Nr.bind(null,e[t-2])):o}),o=T(()=>a.value>-1&&Pi(r.params,i.value.params)),s=T(()=>a.value>-1&&a.value===r.matched.length-1&&Pr(r.params,i.value.params));function c(n={}){if(Ni(n)){let n=t[S(e.replace)?`replace`:`push`](S(e.to)).catch(Yn);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:i,href:T(()=>i.value.href),isActive:o,isExactActive:s,navigate:c}}function ji(e){return e.length===1?e[0]:e}var Mi=c({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:Ai,setup(e,{slots:t}){let r=o(Ai(e)),{options:i}=n(tr),a=T(()=>({[Ii(e.activeClass,i.linkActiveClass,`router-link-active`)]:r.isActive,[Ii(e.exactActiveClass,i.linkExactActiveClass,`router-link-exact-active`)]:r.isExactActive}));return()=>{let n=t.default&&ji(t.default(r));return e.custom?n:l(`a`,{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},n)}}});function Ni(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function Pi(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!Y(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function Fi(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var Ii=(e,t,n)=>e??t??n,Li=c({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(t,{attrs:r,slots:i}){let a=n(rr),o=T(()=>t.route||a.value),s=n(er,0),c=T(()=>{let e=S(s),{matched:t}=o.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),d=T(()=>o.value.matched[c.value]);D(er,T(()=>c.value+1)),D($n,d),D(rr,o);let f=e();return u(()=>[f.value,d.value,t.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!Nr(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let e=o.value,n=t.name,a=d.value,s=a&&a.components[n];if(!s)return Ri(i.default,{Component:s,route:e});let c=a.props[n],u=l(s,J({},c?c===!0?e.params:typeof c==`function`?c(e):c:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(a.instances[n]=null)},ref:f}));return Ri(i.default,{Component:u,route:e})||u}}});function Ri(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var zi=Li;function Bi(e){let t=xi(e.routes,e),n=e.parseQuery||Xr,r=e.stringifyQuery||Zr,i=e.history,a=$r(),o=$r(),s=$r(),c=ne(Z),l=Z;Gn&&e.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let u=Jn.bind(null,e=>``+e),d=Jn.bind(null,Tr),f=Jn.bind(null,Er);function p(e,n){let r,i;return Yr(e)?(r=t.getRecordMatcher(e),i=n):i=e,t.addRoute(i,r)}function m(e){let n=t.getRecordMatcher(e);n&&t.removeRoute(n)}function h(){return t.getRoutes().map(e=>e.record)}function g(e){return!!t.getRecordMatcher(e)}function _(e,a){if(a=J({},a||c.value),typeof e==`string`){let r=kr(n,e,a.path),o=t.resolve({path:r.path},a),s=i.createHref(r.fullPath);return J(r,o,{params:f(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=J({},e,{path:kr(n,e.path,a.path).path});else{let t=J({},e.params);for(let e in t)t[e]??delete t[e];o=J({},e,{params:d(t)}),a.params=d(a.params)}let s=t.resolve(o,a),l=e.hash||``;s.params=u(f(s.params));let p=Ar(r,J({},e,{hash:xr(l),path:s.path})),m=i.createHref(p);return J({fullPath:p,hash:l,query:r===Zr?Qr(e.query):e.query||{}},s,{redirectedFrom:void 0,href:m})}function y(e){return typeof e==`string`?kr(n,e,c.value.path):J({},e)}function b(e,t){if(l!==e)return Qn(8,{from:t,to:e})}function x(e){return w(e)}function C(e){return x(J(y(e),{replace:!0}))}function te(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=y(i):{path:i},i.params={}),J({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function w(e,t){let n=l=_(e),i=c.value,a=e.state,o=e.force,s=e.replace===!0,u=te(n,i);if(u)return w(J(y(u),{state:typeof u==`object`?J({},a,u.state):a,force:o,replace:s}),t||n);let d=n;d.redirectedFrom=t;let f;return!o&&Mr(r,i,n)&&(f=Qn(16,{to:d,from:i}),N(i,i,!0,!1)),(f?Promise.resolve(f):D(d,i)).catch(e=>X(e)?X(e,2)?e:M(e):oe(e,d,i)).then(e=>{if(e){if(X(e,2))return w(J({replace:s},y(e.to),{state:typeof e.to==`object`?J({},a,e.to.state):a,force:o}),t||d)}else e=k(d,i,!0,s,a);return O(d,i,e),e})}function T(e,t){let n=b(e,t);return n?Promise.reject(n):Promise.resolve()}function E(e){let t=le.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function D(e,t){let n,[r,i,s]=ti(e,t);n=ei(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push(Q(r,e,t))});let c=T.bind(null,e,t);return n.push(c),I(n).then(()=>{n=[];for(let r of a.list())n.push(Q(r,e,t));return n.push(c),I(n)}).then(()=>{n=ei(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push(Q(r,e,t))});return n.push(c),I(n)}).then(()=>{n=[];for(let r of s)if(r.beforeEnter)if(Y(r.beforeEnter))for(let i of r.beforeEnter)n.push(Q(i,e,t));else n.push(Q(r.beforeEnter,e,t));return n.push(c),I(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=ei(s,`beforeRouteEnter`,e,t,E),n.push(c),I(n))).then(()=>{n=[];for(let r of o.list())n.push(Q(r,e,t));return n.push(c),I(n)}).catch(e=>X(e,8)?e:Promise.reject(e))}function O(e,t,n){s.list().forEach(r=>E(()=>r(e,t,n)))}function k(e,t,n,r,a){let o=b(e,t);if(o)return o;let s=t===Z,l=Gn?history.state:{};n&&(r||s?i.replace(e.fullPath,J({scroll:s&&l&&l.scroll},a)):i.push(e.fullPath,a)),c.value=e,N(e,t,n,s),M()}let re;function ie(){re||=i.listen((e,t,n)=>{if(!F.listening)return;let r=_(e),a=te(r,F.currentRoute.value);if(a){w(J(a,{replace:!0,force:!0}),r).catch(Yn);return}l=r;let o=c.value;Gn&&Kr(Wr(o.fullPath,n.delta),Hr()),D(r,o).catch(e=>X(e,12)?e:X(e,2)?(w(J(y(e.to),{force:!0}),r).then(e=>{X(e,20)&&!n.delta&&n.type===`pop`&&i.go(-1,!1)}).catch(Yn),Promise.reject()):(n.delta&&i.go(-n.delta,!1),oe(e,r,o))).then(e=>{e||=k(r,o,!1),e&&(n.delta&&!X(e,8)?i.go(-n.delta,!1):n.type===`pop`&&X(e,20)&&i.go(-1,!1)),O(r,o,e)}).catch(Yn)})}let A=$r(),j=$r(),ae;function oe(e,t,n){M(e);let r=j.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function se(){return ae&&c.value!==Z?Promise.resolve():new Promise((e,t)=>{A.add([e,t])})}function M(e){return ae||(ae=!e,ie(),A.list().forEach(([t,n])=>e?n(e):t()),A.reset()),e}function N(t,n,r,i){let{scrollBehavior:a}=e;if(!Gn||!a)return Promise.resolve();let o=!r&&qr(Wr(t.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return ee().then(()=>a(t,n,o)).then(e=>e&&Ur(e)).catch(e=>oe(e,t,n))}let ce=e=>i.go(e),P,le=new Set,F={currentRoute:c,listening:!0,addRoute:p,removeRoute:m,clearRoutes:t.clearRoutes,hasRoute:g,getRoutes:h,resolve:_,options:e,push:x,replace:C,go:ce,back:()=>ce(-1),forward:()=>ce(1),beforeEach:a.add,beforeResolve:o.add,afterEach:s.add,onError:j.add,isReady:se,install(e){e.component(`RouterLink`,Mi),e.component(`RouterView`,zi),e.config.globalProperties.$router=F,Object.defineProperty(e.config.globalProperties,`$route`,{enumerable:!0,get:()=>S(c)}),Gn&&!P&&c.value===Z&&(P=!0,x(i.location).catch(e=>{}));let t={};for(let e in Z)Object.defineProperty(t,e,{get:()=>c.value[e],enumerable:!0});e.provide(tr,F),e.provide(nr,v(t)),e.provide(rr,c);let n=e.unmount;le.add(e),e.unmount=function(){le.delete(e),le.size<1&&(l=Z,re&&re(),re=null,c.value=Z,P=!1,ae=!1),n()}}};function I(e){return e.reduce((e,t)=>e.then(()=>E(t)),Promise.resolve())}return F}var Vi=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Hi=function(e){return`/`+e},Ui={},$=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=Hi(t,n),t in Ui)return;Ui[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:Vi,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Wi=[{path:`/`,component:()=>$(()=>import(`./MainLayout-M5TW3GL1.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36])),children:[{path:``,redirect:{name:`workspace`}},{path:`workspace/:id?`,name:`workspace`,component:()=>$(()=>import(`./WorkspacePage-DeGm-XQp.js`),__vite__mapDeps([37,1,2,3,4,8,9,7,10,12,38,18,15,16,14,20,19,21,22,23,17,24,39,26,40,28,29,30,31,41,35,42,43,34,44]))},{path:`create`,name:`create`,component:()=>$(()=>import(`./CreatePage-DO_pMGS3.js`),__vite__mapDeps([45,1,2,3,4,8,9,7,10,46,21,22,17,20,19,16,23,39,26,40,30,41,35,42,43,47]))},{path:`settings`,name:`settings`,component:()=>$(()=>import(`./SettingsPage-G4xXwNwc.js`),__vite__mapDeps([48,1,2,3,4,6,7,8,9,10,11,38,18,15,16,14,19,46,21,22,17,20,23,24,39,26,27,30,31,32,29,43,49]))},{path:`search`,name:`search`,component:()=>$(()=>import(`./SearchPage-Qc2SXUjf.js`),__vite__mapDeps([50,1,2,3,4,8,9,12,16,39,26,27,15,34,51]))},{path:`health`,name:`health`,component:()=>$(()=>import(`./HealthPage-BvOR0B7B.js`),__vite__mapDeps([52,3,4,12,9,10,21,24,39,26,30]))},{path:`changelog`,name:`changelog`,component:()=>$(()=>import(`./ChangelogPage-DcPmypaS.js`),__vite__mapDeps([53,1,3,4,5,10,9,19,39,26,54]))}]},{path:`/:catchAll(.*)*`,redirect:`/`}],Gi=Hn(()=>Bi({scrollBehavior:()=>({left:0,top:0}),routes:Wi,history:ci()}));async function Ki(e,t){let n=e(Bn);n.use(dt,t);let r=typeof Wn==`function`?await Wn({}):Wn;n.use(r);let i=p(typeof Gi==`function`?await Gi({store:r}):Gi);return r.use(({store:e})=>{e.router=i}),{app:n,store:r,router:i}}var qi={radio:Be,checkbox:Ke,toggle:qe},Ji=Object.keys(qi);function Yi(e,t){if(typeof e==`function`)return e;let n=e===void 0?t:e;return e=>e[n]}var Xi=j({name:`QOptionGroup`,props:{...N,modelValue:{required:!0},options:{type:Array,validator:e=>e.every(R),default:()=>[]},optionValue:[Function,String],optionLabel:[Function,String],optionDisable:[Function,String],name:String,type:{type:String,default:`radio`,validator:e=>Ji.includes(e)},color:String,keepColor:Boolean,dense:Boolean,size:String,leftLabel:Boolean,inline:Boolean,disable:Boolean},emits:[`update:modelValue`],setup(e,{emit:n,slots:r}){let{proxy:{$q:i}}=t(),a=Array.isArray(e.modelValue);e.type===`radio`?a&&console.error(`q-option-group: model should not be array`):a||console.error(`q-option-group: model should be array in your case`);let o=M(e,i),s=T(()=>qi[e.type]),c=T(()=>Yi(e.optionValue,`value`)),u=T(()=>Yi(e.optionLabel,`label`)),d=T(()=>Yi(e.optionDisable,`disable`)),f=T(()=>e.options.map(t=>({val:c.value(t),name:t.name===void 0?e.name:t.name,disable:e.disable||d.value(t),leftLabel:t.leftLabel===void 0?e.leftLabel:t.leftLabel,color:t.color===void 0?e.color:t.color,checkedIcon:t.checkedIcon,uncheckedIcon:t.uncheckedIcon,dark:t.dark===void 0?o.value:t.dark,size:t.size===void 0?e.size:t.size,dense:e.dense,keepColor:t.keepColor===void 0?e.keepColor:t.keepColor}))),p=T(()=>`q-option-group q-gutter-x-sm`+(e.inline?` q-option-group--inline`:``)),m=T(()=>{let t={role:`group`};return e.type===`radio`&&(t.role=`radiogroup`,e.disable&&(t[`aria-disabled`]=`true`)),t});function h(e){n(`update:modelValue`,e)}return()=>l(`div`,{class:p.value,...m.value},e.options.map((t,n)=>{let i=r[`label-`+n]===void 0?r.label===void 0?void 0:()=>r.label(t):()=>r[`label-`+n](t);return l(`div`,[l(s.value,{label:i===void 0?u.value(t):null,modelValue:e.modelValue,"onUpdate:modelValue":h,...f.value[n]},i)])}))}}),Zi=j({name:`DialogPluginComponent`,props:{...N,title:String,message:String,prompt:Object,options:Object,progress:[Boolean,Object],html:Boolean,ok:{type:[String,Object,Boolean],default:!0},cancel:[String,Object,Boolean],focus:{type:String,default:`ok`,validator:e=>[`ok`,`cancel`,`none`].includes(e)},stackButtons:Boolean,color:String,cardClass:[String,Array,Object],cardStyle:[String,Array,Object]},emits:[`ok`,`hide`],setup(n,{emit:r}){let{proxy:i}=t(),{$q:a}=i,o=M(n,a),s=e(null),c=e(n.prompt===void 0?n.options===void 0?void 0:n.options.model:n.prompt.model),d=T(()=>`q-dialog-plugin`+(o.value?` q-dialog-plugin--dark q-dark`:``)+(n.progress===!1?``:` q-dialog-plugin--progress`)),f=T(()=>n.color||(o.value?`amber`:`primary`)),p=T(()=>n.progress===!1?null:R(n.progress)?{component:n.progress.spinner||se,props:{color:n.progress.color||f.value}}:{component:se,props:{color:f.value}}),m=T(()=>n.prompt!==void 0||n.options!==void 0),h=T(()=>{if(!m.value)return{};let{model:e,isValid:t,items:r,...i}=n.prompt===void 0?n.options:n.prompt;return i}),g=T(()=>R(n.ok)||n.ok===!0?a.lang.label.ok:n.ok),_=T(()=>R(n.cancel)||n.cancel===!0?a.lang.label.cancel:n.cancel),v=T(()=>n.prompt===void 0?n.options===void 0?!1:n.options.isValid!==void 0&&!n.options.isValid(c.value):n.prompt.isValid!==void 0&&!n.prompt.isValid(c.value)),y=T(()=>({color:f.value,label:g.value,ripple:!1,disable:v.value,...R(n.ok)?n.ok:{flat:!0},"data-autofocus":n.focus===`ok`&&!m.value||void 0,onClick:ee})),b=T(()=>({color:f.value,label:_.value,ripple:!1,...R(n.cancel)?n.cancel:{flat:!0},"data-autofocus":n.focus===`cancel`&&!m.value||void 0,onClick:C}));u(()=>n.prompt&&n.prompt.model,E),u(()=>n.options&&n.options.model,E);function x(){s.value.show()}function S(){s.value.hide()}function ee(){r(`ok`,w(c.value)),S()}function C(){S()}function te(){r(`hide`)}function E(e){c.value=e}function ne(e){!v.value&&n.prompt.type!==`textarea`&&oe(e,13)&&ee()}function D(e,t){return n.html?l(H,{class:e,innerHTML:t}):l(H,{class:e},()=>t)}function O(){return[l(Ge,{color:f.value,dense:!0,autofocus:!0,dark:o.value,...h.value,modelValue:c.value,"onUpdate:modelValue":E,onKeyup:ne})]}function k(){return[l(Xi,{color:f.value,options:n.options.items,dark:o.value,...h.value,modelValue:c.value,"onUpdate:modelValue":E})]}function re(){let e=[];return n.cancel&&e.push(l(He,b.value)),n.ok&&e.push(l(He,y.value)),l(Re,{class:n.stackButtons?`items-end`:``,vertical:n.stackButtons,align:`right`},()=>e)}function ie(){let e=[];return n.title&&e.push(D(`q-dialog__title`,n.title)),n.progress!==!1&&e.push(l(H,{class:`q-dialog__progress`},()=>l(p.value.component,p.value.props))),n.message&&e.push(D(`q-dialog__message`,n.message)),n.prompt===void 0?n.options!==void 0&&e.push(l(pe,{dark:o.value}),l(H,{class:`scroll q-dialog-plugin__form`},k),l(pe,{dark:o.value})):e.push(l(H,{class:`scroll q-dialog-plugin__form`},O)),(n.ok||n.cancel)&&e.push(re()),e}function A(){return[l(ft,{class:[d.value,n.cardClass],style:n.cardStyle,dark:o.value},ie)]}return Object.assign(i,{show:x,hide:S}),()=>l(Mt,{ref:s,onHide:te},A)}});function Qi(e,t){for(let n in t)n!==`spinner`&&Object(t[n])===t[n]?(e[n]=Object(e[n])===e[n]?{...e[n]}:{},Qi(e[n],t[n])):e[n]=t[n]}function $i(t,n,r){return i=>{let a,o,s=n&&i.component!==void 0;if(s){let{component:e,componentProps:t}=i;a=typeof e==`string`?r.component(e):e,o=t||{}}else{let{class:e,style:n,...r}=i;a=t,o=r,e!==void 0&&(r.cardClass=e),n!==void 0&&(r.cardStyle=n)}let c,u=!1,d=e(null),f=ge(!1,`dialog`),p=e=>{if(d.value?.[e]!==void 0){d.value[e]();return}let t=c.$.subTree;if(t?.component){if(t.component.proxy&&t.component.proxy[e]){t.component.proxy[e]();return}if(t.component.subTree&&t.component.subTree.component&&t.component.subTree.component.proxy&&t.component.subTree.component.proxy[e]){t.component.subTree.component.proxy[e]();return}}console.error(`[Quasar] Incorrectly defined Dialog component`)},m=[],h=[],g={onOk(e){return m.push(e),g},onCancel(e){return h.push(e),g},onDismiss(e){return m.push(e),h.push(e),g},hide(){return p(`hide`),g},update(e){if(c!==null){if(s)Object.assign(o,e);else{let{class:t,style:n,...r}=e;t!==void 0&&(r.cardClass=t),n!==void 0&&(r.cardStyle=n),Qi(o,r)}c.$forceUpdate()}return g}},_=e=>{u=!0,m.forEach(t=>{t(e)})},v=()=>{y.unmount(f),Le(f),y=null,c=null,u||h.forEach(e=>{e()})},y=ct({name:`QGlobalDialog`,setup:()=>()=>l(a,{...o,ref:d,onOk:_,onHide:v,onVnodeMounted(...e){typeof o.onVnodeMounted==`function`&&o.onVnodeMounted(...e),ee(()=>p(`show`))}})},r);return c=y.mount(f),g}}var ea={install({$q:e,parentApp:t}){e.dialog=this.create=$i(Zi,!0,t)}},ta={config:{dark:!0,brand:{primary:`#6c63ff`,secondary:`#26a69a`,accent:`#9c27b0`,dark:`#1a1a2e`,"dark-page":`#1a1a2e`,positive:`#21ba45`,negative:`#c10015`,info:`#31ccec`,warning:`#f2c037`}},plugins:{Notify:rn,Dialog:ea}},na=`/`;async function ra({app:e,router:t,store:n},r){let i=!1,a=e=>{try{return t.resolve(e).href}catch{}return Object(e)===e?null:e},o=e=>{if(i=!0,typeof e==`string`&&/^https?:\/\//.test(e)){window.location.href=e;return}let t=a(e);t!==null&&(window.location.href=t,window.location.reload())},s=window.location.href.replace(window.location.origin,``);for(let a=0;i===!1&&a<r.length;a++)try{await r[a]({app:e,router:t,store:n,ssrContext:null,redirect:o,urlPath:s,publicPath:na})}catch(e){if(e&&e.url){o(e.url);return}console.error(`[Quasar] boot error:`,e);return}i!==!0&&(e.use(t),e.mount(`#q-app`))}Ki(x,ta).then(e=>{let[t,n]=Promise.allSettled===void 0?[`all`,e=>e.map(e=>e.default)]:[`allSettled`,e=>e.map(e=>{if(e.status===`rejected`){console.error(`[Quasar] boot error:`,e.reason);return}return e.value.default})];return Promise[t]([$(()=>import(`./i18n-Cl6Gt8Eh.js`),[])]).then(t=>{ra(e,n(t).filter(e=>typeof e==`function`))})});export{Mt as _,Vn as a,ft as b,G as c,_n as d,vn as f,Vt as g,mn as h,ir as i,Tn as l,hn as m,$ as n,zn as o,gn as p,ar as r,En as s,Xi as t,xn as u,Ot as v,H as x,pt as y};