@loicngr/kobo 1.7.4 → 1.7.6

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 (65) hide show
  1. package/README.md +26 -9
  2. package/dist/mcp-server/kobo-tasks-handlers.js +41 -1
  3. package/dist/mcp-server/kobo-tasks-server.js +157 -8
  4. package/dist/server/db/migrations.js +87 -0
  5. package/dist/server/db/schema.js +27 -0
  6. package/dist/server/index.js +9 -1
  7. package/dist/server/routes/health.js +68 -3
  8. package/dist/server/routes/workspaces.js +183 -4
  9. package/dist/server/services/agent/engines/claude-code/engine.js +13 -6
  10. package/dist/server/services/agent/engines/claude-code/event-mapper.js +96 -7
  11. package/dist/server/services/agent/orchestrator.js +113 -71
  12. package/dist/server/services/auto-loop-service.js +16 -3
  13. package/dist/server/services/cron-service.js +279 -0
  14. package/dist/server/services/quota-backoff-service.js +127 -0
  15. package/dist/server/services/wakeup-service.js +1 -1
  16. package/dist/server/services/workspace-service.js +98 -0
  17. package/dist/server/utils/git-ops.js +8 -1
  18. package/package.json +2 -1
  19. package/src/client/dist/spa/assets/{ActivityFeed-ClJLeAXJ.js → ActivityFeed-BboSPm4b.js} +2 -2
  20. package/src/client/dist/spa/assets/{ActivityFeed-DVBfmJWJ.css → ActivityFeed-tE4LVYck.css} +1 -1
  21. package/src/client/dist/spa/assets/AutoLoopChip-w8D77bI5.js +1 -0
  22. package/src/client/dist/spa/assets/{CreatePage-BOkt0Psl.js → CreatePage-BDObLDJc.js} +1 -1
  23. package/src/client/dist/spa/assets/{DiffViewer-Dls1jFCN.js → DiffViewer-CblFgn8w.js} +3 -3
  24. package/src/client/dist/spa/assets/{DiffViewer-wFfQ9tcY.css → DiffViewer-DTdDcKZC.css} +1 -1
  25. package/src/client/dist/spa/assets/HealthPage-CBSw7e5q.js +1 -0
  26. package/src/client/dist/spa/assets/{MainLayout-DHNIerYJ.js → MainLayout-DhaYycak.js} +17 -17
  27. package/src/client/dist/spa/assets/MainLayout-drolsINz.css +1 -0
  28. package/src/client/dist/spa/assets/{SearchPage-BEnZ-CLq.js → SearchPage-cZTwP4Lf.js} +1 -1
  29. package/src/client/dist/spa/assets/{SettingsPage-DeCbWvPb.js → SettingsPage-C1efO0VM.js} +1 -1
  30. package/src/client/dist/spa/assets/WorkspacePage-3jcof896.js +4 -0
  31. package/src/client/dist/spa/assets/{WorkspacePage-eymEd4kx.css → WorkspacePage-CCtIrBiR.css} +1 -1
  32. package/src/client/dist/spa/assets/{cssMode-AlflsawW.js → cssMode-BFLYiiEw.js} +1 -1
  33. package/src/client/dist/spa/assets/{editor.api-DtvjQlUm.js → editor.api-2asmmhth.js} +1 -1
  34. package/src/client/dist/spa/assets/{editor.main-Ccy_gjVD.js → editor.main-ChCYZyez.js} +3 -3
  35. package/src/client/dist/spa/assets/{expand-template-AQsvbQ8_.js → expand-template-CXQFkQOJ.js} +1 -1
  36. package/src/client/dist/spa/assets/{freemarker2-DdQktlXK.js → freemarker2-BaBL9E9G.js} +1 -1
  37. package/src/client/dist/spa/assets/{handlebars-CE3ee2NH.js → handlebars-BxDour4L.js} +1 -1
  38. package/src/client/dist/spa/assets/{html-CCKX8Xv9.js → html-C6hnkfIL.js} +1 -1
  39. package/src/client/dist/spa/assets/{htmlMode-Dh8jDJum.js → htmlMode-9zT3-dmz.js} +1 -1
  40. package/src/client/dist/spa/assets/i18n-CLY0XI9-.js +1 -0
  41. package/src/client/dist/spa/assets/index-D6wj_wQ9.js +2 -0
  42. package/src/client/dist/spa/assets/{javascript-DhmZNdUp.js → javascript-C3YjvKbE.js} +1 -1
  43. package/src/client/dist/spa/assets/{jsonMode-B0xAtnNK.js → jsonMode-DcJDgMzf.js} +1 -1
  44. package/src/client/dist/spa/assets/{liquid-ByL0HpZ0.js → liquid-CsT8SjJM.js} +1 -1
  45. package/src/client/dist/spa/assets/{mdx-DX4pehAZ.js → mdx-CT3yVSyc.js} +1 -1
  46. package/src/client/dist/spa/assets/{models-ClWoqWeC.js → models-BsjWUKqM.js} +1 -1
  47. package/src/client/dist/spa/assets/{monaco.contribution-Fegh8Y1Y.js → monaco.contribution-DKGNz1oQ.js} +2 -2
  48. package/src/client/dist/spa/assets/{purify.es-BWZjBa9F.js → purify.es-CPieV82n.js} +1 -1
  49. package/src/client/dist/spa/assets/{python-COS2MM8n.js → python-Ca5miKgj.js} +1 -1
  50. package/src/client/dist/spa/assets/{razor-Cc3xCJU7.js → razor-7qzusGRc.js} +1 -1
  51. package/src/client/dist/spa/assets/{render-chat-markdown-DcGIpMoe.js → render-chat-markdown-Bqq2G-yI.js} +1 -1
  52. package/src/client/dist/spa/assets/{tsMode-eQIJjERk.js → tsMode-BdvO8jZ2.js} +1 -1
  53. package/src/client/dist/spa/assets/{typescript-DwIlacVU.js → typescript-BfVNzhgs.js} +1 -1
  54. package/src/client/dist/spa/assets/{xml-DP-09Aih.js → xml-DGNXGqXL.js} +1 -1
  55. package/src/client/dist/spa/assets/{yaml-BhrtimeA.js → yaml-CtAtOyt5.js} +1 -1
  56. package/src/client/dist/spa/index.html +1 -1
  57. package/src/mcp-server/kobo-tasks-handlers.ts +55 -1
  58. package/src/mcp-server/kobo-tasks-server.ts +165 -7
  59. package/src/client/dist/spa/assets/HealthPage-CMxH3SBS.js +0 -1
  60. package/src/client/dist/spa/assets/MainLayout-DKurmqtk.css +0 -1
  61. package/src/client/dist/spa/assets/WorkspacePage-DFAFT5OW.js +0 -4
  62. package/src/client/dist/spa/assets/i18n-BOsrrRj4.js +0 -1
  63. package/src/client/dist/spa/assets/index-_ZaIBxd6.js +0 -2
  64. /package/src/client/dist/spa/assets/{QPage-ChUKoaKe.js → QPage-DFi3K093.js} +0 -0
  65. /package/src/client/dist/spa/assets/{formatters-BD0_hovB.js → formatters-DCAQ6ANJ.js} +0 -0
@@ -1,4 +1,4 @@
1
- import{m as e}from"./editor.api-DtvjQlUm.js";import{t}from"./monaco.contribution-Fegh8Y1Y.js";var n,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,s=(e,t,n,s)=>{if(t&&typeof t==`object`||typeof t==`function`)for(let c of a(t))!o.call(e,c)&&c!==n&&r(e,c,{get:()=>t[c],enumerable:!(s=i(t,c))||s.enumerable});return e},c=(e,t,n)=>(s(e,t,`default`),n&&s(n,t,`default`)),l={};c(l,e);function u(e,t){let n=globalThis.MonacoEnvironment;if(n?.createTrustedTypesPolicy)try{return n.createTrustedTypesPolicy(e,t)}catch(e){console.error(e);return}try{return globalThis.trustedTypes?.createPolicy(e,t)}catch(e){console.error(e);return}}var d=typeof self==`object`&&self.constructor&&self.constructor.name===`DedicatedWorkerGlobalScope`&&globalThis.workerttPolicy!==void 0?globalThis.workerttPolicy:u(`defaultWorkerFactory`,{createScriptURL:e=>e});function f(e){let t=e.label,n=globalThis.MonacoEnvironment;if(n){if(typeof n.getWorker==`function`)return n.getWorker(`workerMain.js`,t);if(typeof n.getWorkerUrl==`function`){let e=n.getWorkerUrl(`workerMain.js`,t);return new Worker(d?d.createScriptURL(e):e,{name:t,type:`module`})}}throw Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`)}function p(e){let t=Promise.resolve(f({label:e.label??`monaco-editor-worker`,moduleId:e.moduleId})).then(t=>(t.postMessage(`ignore`),t.postMessage(e.createData),t));return l.editor.createWebWorker({worker:t,host:e.host,keepIdleModels:e.keepIdleModels})}var m=class{constructor(e,t){this._modeId=e,this._defaults=t,this._worker=null,this._client=null,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker()),this._updateExtraLibsToken=0,this._extraLibsChangeListener=this._defaults.onDidExtraLibsChange(()=>this._updateExtraLibs())}dispose(){this._configChangeListener.dispose(),this._extraLibsChangeListener.dispose(),this._stopWorker()}_stopWorker(){this._worker&&=(this._worker.dispose(),null),this._client=null}async _updateExtraLibs(){if(!this._worker)return;let e=++this._updateExtraLibsToken,t=await this._worker.getProxy();this._updateExtraLibsToken===e&&t.updateExtraLibs(this._defaults.getExtraLibs())}_getClient(){return this._client||=(async()=>(this._worker=p({moduleId:`vs/language/typescript/tsWorker`,label:this._modeId,keepIdleModels:!0,createData:{compilerOptions:this._defaults.getCompilerOptions(),extraLibs:this._defaults.getExtraLibs(),customWorkerPath:this._defaults.workerOptions.customWorkerPath,inlayHintsOptions:this._defaults.inlayHintsOptions}}),this._defaults.getEagerModelSync()?await this._worker.withSyncedResources(l.editor.getModels().filter(e=>e.getLanguageId()===this._modeId).map(e=>e.uri)):await this._worker.getProxy()))(),this._client}async getLanguageServiceWorker(...e){let t=await this._getClient();return this._worker&&await this._worker.withSyncedResources(e),t}},h={};h[`lib.d.ts`]=!0,h[`lib.decorators.d.ts`]=!0,h[`lib.decorators.legacy.d.ts`]=!0,h[`lib.dom.asynciterable.d.ts`]=!0,h[`lib.dom.d.ts`]=!0,h[`lib.dom.iterable.d.ts`]=!0,h[`lib.es2015.collection.d.ts`]=!0,h[`lib.es2015.core.d.ts`]=!0,h[`lib.es2015.d.ts`]=!0,h[`lib.es2015.generator.d.ts`]=!0,h[`lib.es2015.iterable.d.ts`]=!0,h[`lib.es2015.promise.d.ts`]=!0,h[`lib.es2015.proxy.d.ts`]=!0,h[`lib.es2015.reflect.d.ts`]=!0,h[`lib.es2015.symbol.d.ts`]=!0,h[`lib.es2015.symbol.wellknown.d.ts`]=!0,h[`lib.es2016.array.include.d.ts`]=!0,h[`lib.es2016.d.ts`]=!0,h[`lib.es2016.full.d.ts`]=!0,h[`lib.es2016.intl.d.ts`]=!0,h[`lib.es2017.d.ts`]=!0,h[`lib.es2017.date.d.ts`]=!0,h[`lib.es2017.full.d.ts`]=!0,h[`lib.es2017.intl.d.ts`]=!0,h[`lib.es2017.object.d.ts`]=!0,h[`lib.es2017.sharedmemory.d.ts`]=!0,h[`lib.es2017.string.d.ts`]=!0,h[`lib.es2017.typedarrays.d.ts`]=!0,h[`lib.es2018.asyncgenerator.d.ts`]=!0,h[`lib.es2018.asynciterable.d.ts`]=!0,h[`lib.es2018.d.ts`]=!0,h[`lib.es2018.full.d.ts`]=!0,h[`lib.es2018.intl.d.ts`]=!0,h[`lib.es2018.promise.d.ts`]=!0,h[`lib.es2018.regexp.d.ts`]=!0,h[`lib.es2019.array.d.ts`]=!0,h[`lib.es2019.d.ts`]=!0,h[`lib.es2019.full.d.ts`]=!0,h[`lib.es2019.intl.d.ts`]=!0,h[`lib.es2019.object.d.ts`]=!0,h[`lib.es2019.string.d.ts`]=!0,h[`lib.es2019.symbol.d.ts`]=!0,h[`lib.es2020.bigint.d.ts`]=!0,h[`lib.es2020.d.ts`]=!0,h[`lib.es2020.date.d.ts`]=!0,h[`lib.es2020.full.d.ts`]=!0,h[`lib.es2020.intl.d.ts`]=!0,h[`lib.es2020.number.d.ts`]=!0,h[`lib.es2020.promise.d.ts`]=!0,h[`lib.es2020.sharedmemory.d.ts`]=!0,h[`lib.es2020.string.d.ts`]=!0,h[`lib.es2020.symbol.wellknown.d.ts`]=!0,h[`lib.es2021.d.ts`]=!0,h[`lib.es2021.full.d.ts`]=!0,h[`lib.es2021.intl.d.ts`]=!0,h[`lib.es2021.promise.d.ts`]=!0,h[`lib.es2021.string.d.ts`]=!0,h[`lib.es2021.weakref.d.ts`]=!0,h[`lib.es2022.array.d.ts`]=!0,h[`lib.es2022.d.ts`]=!0,h[`lib.es2022.error.d.ts`]=!0,h[`lib.es2022.full.d.ts`]=!0,h[`lib.es2022.intl.d.ts`]=!0,h[`lib.es2022.object.d.ts`]=!0,h[`lib.es2022.regexp.d.ts`]=!0,h[`lib.es2022.sharedmemory.d.ts`]=!0,h[`lib.es2022.string.d.ts`]=!0,h[`lib.es2023.array.d.ts`]=!0,h[`lib.es2023.collection.d.ts`]=!0,h[`lib.es2023.d.ts`]=!0,h[`lib.es2023.full.d.ts`]=!0,h[`lib.es5.d.ts`]=!0,h[`lib.es6.d.ts`]=!0,h[`lib.esnext.collection.d.ts`]=!0,h[`lib.esnext.d.ts`]=!0,h[`lib.esnext.decorators.d.ts`]=!0,h[`lib.esnext.disposable.d.ts`]=!0,h[`lib.esnext.full.d.ts`]=!0,h[`lib.esnext.intl.d.ts`]=!0,h[`lib.esnext.object.d.ts`]=!0,h[`lib.esnext.promise.d.ts`]=!0,h[`lib.scripthost.d.ts`]=!0,h[`lib.webworker.asynciterable.d.ts`]=!0,h[`lib.webworker.d.ts`]=!0,h[`lib.webworker.importscripts.d.ts`]=!0,h[`lib.webworker.iterable.d.ts`]=!0;function g(e,t,n=0){if(typeof e==`string`)return e;if(e===void 0)return``;let r=``;if(n){r+=t;for(let e=0;e<n;e++)r+=` `}if(r+=e.messageText,n++,e.next)for(let i of e.next)r+=g(i,t,n);return r}function _(e){return e?e.map(e=>e.text).join(``):``}var v=class{constructor(e){this._worker=e}_textSpanToRange(e,t){let n=e.getPositionAt(t.start),r=e.getPositionAt(t.start+t.length),{lineNumber:i,column:a}=n,{lineNumber:o,column:s}=r;return{startLineNumber:i,startColumn:a,endLineNumber:o,endColumn:s}}},y=class{constructor(e){this._worker=e,this._libFiles={},this._hasFetchedLibFiles=!1,this._fetchLibFilesPromise=null}isLibFile(e){return e&&e.path.indexOf(`/lib.`)===0?!!h[e.path.slice(1)]:!1}getOrCreateModel(e){let n=l.Uri.parse(e),r=l.editor.getModel(n);if(r)return r;if(this.isLibFile(n)&&this._hasFetchedLibFiles)return l.editor.createModel(this._libFiles[n.path.slice(1)],`typescript`,n);let i=t.getExtraLibs()[e];return i?l.editor.createModel(i.content,`typescript`,n):null}_containsLibFile(e){for(let t of e)if(this.isLibFile(t))return!0;return!1}async fetchLibFilesIfNecessary(e){this._containsLibFile(e)&&await this._fetchLibFiles()}_fetchLibFiles(){return this._fetchLibFilesPromise||=this._worker().then(e=>e.getLibFiles()).then(e=>{this._hasFetchedLibFiles=!0,this._libFiles=e}),this._fetchLibFilesPromise}},b=class extends v{constructor(e,t,n,r){super(r),this._libFiles=e,this._defaults=t,this._selector=n,this._disposables=[],this._listener=Object.create(null);let i=e=>{if(e.getLanguageId()!==n)return;let t=()=>{let{onlyVisible:t}=this._defaults.getDiagnosticsOptions();t?e.isAttachedToEditor()&&this._doValidate(e):this._doValidate(e)},r,i=e.onDidChangeContent(()=>{clearTimeout(r),r=window.setTimeout(t,500)}),a=e.onDidChangeAttached(()=>{let{onlyVisible:n}=this._defaults.getDiagnosticsOptions();n&&(e.isAttachedToEditor()?t():l.editor.setModelMarkers(e,this._selector,[]))});this._listener[e.uri.toString()]={dispose(){i.dispose(),a.dispose(),clearTimeout(r)}},t()},a=e=>{l.editor.setModelMarkers(e,this._selector,[]);let t=e.uri.toString();this._listener[t]&&(this._listener[t].dispose(),delete this._listener[t])};this._disposables.push(l.editor.onDidCreateModel(e=>i(e))),this._disposables.push(l.editor.onWillDisposeModel(a)),this._disposables.push(l.editor.onDidChangeModelLanguage(e=>{a(e.model),i(e.model)})),this._disposables.push({dispose(){for(let e of l.editor.getModels())a(e)}});let o=()=>{for(let e of l.editor.getModels())a(e),i(e)};this._disposables.push(this._defaults.onDidChange(o)),this._disposables.push(this._defaults.onDidExtraLibsChange(o)),l.editor.getModels().forEach(e=>i(e))}dispose(){this._disposables.forEach(e=>e&&e.dispose()),this._disposables=[]}async _doValidate(e){let t=await this._worker(e.uri);if(e.isDisposed())return;let n=[],{noSyntaxValidation:r,noSemanticValidation:i,noSuggestionDiagnostics:a}=this._defaults.getDiagnosticsOptions();r||n.push(t.getSyntacticDiagnostics(e.uri.toString())),i||n.push(t.getSemanticDiagnostics(e.uri.toString())),a||n.push(t.getSuggestionDiagnostics(e.uri.toString()));let o=await Promise.all(n);if(!o||e.isDisposed())return;let s=o.reduce((e,t)=>t.concat(e),[]).filter(e=>(this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore||[]).indexOf(e.code)===-1),c=s.map(e=>e.relatedInformation||[]).reduce((e,t)=>t.concat(e),[]).map(e=>e.file?l.Uri.parse(e.file.fileName):null);await this._libFiles.fetchLibFilesIfNecessary(c),!e.isDisposed()&&l.editor.setModelMarkers(e,this._selector,s.map(t=>this._convertDiagnostics(e,t)))}_convertDiagnostics(e,t){let n=t.start||0,r=t.length||1,{lineNumber:i,column:a}=e.getPositionAt(n),{lineNumber:o,column:s}=e.getPositionAt(n+r),c=[];return t.reportsUnnecessary&&c.push(l.MarkerTag.Unnecessary),t.reportsDeprecated&&c.push(l.MarkerTag.Deprecated),{severity:this._tsDiagnosticCategoryToMarkerSeverity(t.category),startLineNumber:i,startColumn:a,endLineNumber:o,endColumn:s,message:g(t.messageText,`
1
+ import{m as e}from"./editor.api-2asmmhth.js";import{t}from"./monaco.contribution-DKGNz1oQ.js";var n,r=Object.defineProperty,i=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,s=(e,t,n,s)=>{if(t&&typeof t==`object`||typeof t==`function`)for(let c of a(t))!o.call(e,c)&&c!==n&&r(e,c,{get:()=>t[c],enumerable:!(s=i(t,c))||s.enumerable});return e},c=(e,t,n)=>(s(e,t,`default`),n&&s(n,t,`default`)),l={};c(l,e);function u(e,t){let n=globalThis.MonacoEnvironment;if(n?.createTrustedTypesPolicy)try{return n.createTrustedTypesPolicy(e,t)}catch(e){console.error(e);return}try{return globalThis.trustedTypes?.createPolicy(e,t)}catch(e){console.error(e);return}}var d=typeof self==`object`&&self.constructor&&self.constructor.name===`DedicatedWorkerGlobalScope`&&globalThis.workerttPolicy!==void 0?globalThis.workerttPolicy:u(`defaultWorkerFactory`,{createScriptURL:e=>e});function f(e){let t=e.label,n=globalThis.MonacoEnvironment;if(n){if(typeof n.getWorker==`function`)return n.getWorker(`workerMain.js`,t);if(typeof n.getWorkerUrl==`function`){let e=n.getWorkerUrl(`workerMain.js`,t);return new Worker(d?d.createScriptURL(e):e,{name:t,type:`module`})}}throw Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`)}function p(e){let t=Promise.resolve(f({label:e.label??`monaco-editor-worker`,moduleId:e.moduleId})).then(t=>(t.postMessage(`ignore`),t.postMessage(e.createData),t));return l.editor.createWebWorker({worker:t,host:e.host,keepIdleModels:e.keepIdleModels})}var m=class{constructor(e,t){this._modeId=e,this._defaults=t,this._worker=null,this._client=null,this._configChangeListener=this._defaults.onDidChange(()=>this._stopWorker()),this._updateExtraLibsToken=0,this._extraLibsChangeListener=this._defaults.onDidExtraLibsChange(()=>this._updateExtraLibs())}dispose(){this._configChangeListener.dispose(),this._extraLibsChangeListener.dispose(),this._stopWorker()}_stopWorker(){this._worker&&=(this._worker.dispose(),null),this._client=null}async _updateExtraLibs(){if(!this._worker)return;let e=++this._updateExtraLibsToken,t=await this._worker.getProxy();this._updateExtraLibsToken===e&&t.updateExtraLibs(this._defaults.getExtraLibs())}_getClient(){return this._client||=(async()=>(this._worker=p({moduleId:`vs/language/typescript/tsWorker`,label:this._modeId,keepIdleModels:!0,createData:{compilerOptions:this._defaults.getCompilerOptions(),extraLibs:this._defaults.getExtraLibs(),customWorkerPath:this._defaults.workerOptions.customWorkerPath,inlayHintsOptions:this._defaults.inlayHintsOptions}}),this._defaults.getEagerModelSync()?await this._worker.withSyncedResources(l.editor.getModels().filter(e=>e.getLanguageId()===this._modeId).map(e=>e.uri)):await this._worker.getProxy()))(),this._client}async getLanguageServiceWorker(...e){let t=await this._getClient();return this._worker&&await this._worker.withSyncedResources(e),t}},h={};h[`lib.d.ts`]=!0,h[`lib.decorators.d.ts`]=!0,h[`lib.decorators.legacy.d.ts`]=!0,h[`lib.dom.asynciterable.d.ts`]=!0,h[`lib.dom.d.ts`]=!0,h[`lib.dom.iterable.d.ts`]=!0,h[`lib.es2015.collection.d.ts`]=!0,h[`lib.es2015.core.d.ts`]=!0,h[`lib.es2015.d.ts`]=!0,h[`lib.es2015.generator.d.ts`]=!0,h[`lib.es2015.iterable.d.ts`]=!0,h[`lib.es2015.promise.d.ts`]=!0,h[`lib.es2015.proxy.d.ts`]=!0,h[`lib.es2015.reflect.d.ts`]=!0,h[`lib.es2015.symbol.d.ts`]=!0,h[`lib.es2015.symbol.wellknown.d.ts`]=!0,h[`lib.es2016.array.include.d.ts`]=!0,h[`lib.es2016.d.ts`]=!0,h[`lib.es2016.full.d.ts`]=!0,h[`lib.es2016.intl.d.ts`]=!0,h[`lib.es2017.d.ts`]=!0,h[`lib.es2017.date.d.ts`]=!0,h[`lib.es2017.full.d.ts`]=!0,h[`lib.es2017.intl.d.ts`]=!0,h[`lib.es2017.object.d.ts`]=!0,h[`lib.es2017.sharedmemory.d.ts`]=!0,h[`lib.es2017.string.d.ts`]=!0,h[`lib.es2017.typedarrays.d.ts`]=!0,h[`lib.es2018.asyncgenerator.d.ts`]=!0,h[`lib.es2018.asynciterable.d.ts`]=!0,h[`lib.es2018.d.ts`]=!0,h[`lib.es2018.full.d.ts`]=!0,h[`lib.es2018.intl.d.ts`]=!0,h[`lib.es2018.promise.d.ts`]=!0,h[`lib.es2018.regexp.d.ts`]=!0,h[`lib.es2019.array.d.ts`]=!0,h[`lib.es2019.d.ts`]=!0,h[`lib.es2019.full.d.ts`]=!0,h[`lib.es2019.intl.d.ts`]=!0,h[`lib.es2019.object.d.ts`]=!0,h[`lib.es2019.string.d.ts`]=!0,h[`lib.es2019.symbol.d.ts`]=!0,h[`lib.es2020.bigint.d.ts`]=!0,h[`lib.es2020.d.ts`]=!0,h[`lib.es2020.date.d.ts`]=!0,h[`lib.es2020.full.d.ts`]=!0,h[`lib.es2020.intl.d.ts`]=!0,h[`lib.es2020.number.d.ts`]=!0,h[`lib.es2020.promise.d.ts`]=!0,h[`lib.es2020.sharedmemory.d.ts`]=!0,h[`lib.es2020.string.d.ts`]=!0,h[`lib.es2020.symbol.wellknown.d.ts`]=!0,h[`lib.es2021.d.ts`]=!0,h[`lib.es2021.full.d.ts`]=!0,h[`lib.es2021.intl.d.ts`]=!0,h[`lib.es2021.promise.d.ts`]=!0,h[`lib.es2021.string.d.ts`]=!0,h[`lib.es2021.weakref.d.ts`]=!0,h[`lib.es2022.array.d.ts`]=!0,h[`lib.es2022.d.ts`]=!0,h[`lib.es2022.error.d.ts`]=!0,h[`lib.es2022.full.d.ts`]=!0,h[`lib.es2022.intl.d.ts`]=!0,h[`lib.es2022.object.d.ts`]=!0,h[`lib.es2022.regexp.d.ts`]=!0,h[`lib.es2022.sharedmemory.d.ts`]=!0,h[`lib.es2022.string.d.ts`]=!0,h[`lib.es2023.array.d.ts`]=!0,h[`lib.es2023.collection.d.ts`]=!0,h[`lib.es2023.d.ts`]=!0,h[`lib.es2023.full.d.ts`]=!0,h[`lib.es5.d.ts`]=!0,h[`lib.es6.d.ts`]=!0,h[`lib.esnext.collection.d.ts`]=!0,h[`lib.esnext.d.ts`]=!0,h[`lib.esnext.decorators.d.ts`]=!0,h[`lib.esnext.disposable.d.ts`]=!0,h[`lib.esnext.full.d.ts`]=!0,h[`lib.esnext.intl.d.ts`]=!0,h[`lib.esnext.object.d.ts`]=!0,h[`lib.esnext.promise.d.ts`]=!0,h[`lib.scripthost.d.ts`]=!0,h[`lib.webworker.asynciterable.d.ts`]=!0,h[`lib.webworker.d.ts`]=!0,h[`lib.webworker.importscripts.d.ts`]=!0,h[`lib.webworker.iterable.d.ts`]=!0;function g(e,t,n=0){if(typeof e==`string`)return e;if(e===void 0)return``;let r=``;if(n){r+=t;for(let e=0;e<n;e++)r+=` `}if(r+=e.messageText,n++,e.next)for(let i of e.next)r+=g(i,t,n);return r}function _(e){return e?e.map(e=>e.text).join(``):``}var v=class{constructor(e){this._worker=e}_textSpanToRange(e,t){let n=e.getPositionAt(t.start),r=e.getPositionAt(t.start+t.length),{lineNumber:i,column:a}=n,{lineNumber:o,column:s}=r;return{startLineNumber:i,startColumn:a,endLineNumber:o,endColumn:s}}},y=class{constructor(e){this._worker=e,this._libFiles={},this._hasFetchedLibFiles=!1,this._fetchLibFilesPromise=null}isLibFile(e){return e&&e.path.indexOf(`/lib.`)===0?!!h[e.path.slice(1)]:!1}getOrCreateModel(e){let n=l.Uri.parse(e),r=l.editor.getModel(n);if(r)return r;if(this.isLibFile(n)&&this._hasFetchedLibFiles)return l.editor.createModel(this._libFiles[n.path.slice(1)],`typescript`,n);let i=t.getExtraLibs()[e];return i?l.editor.createModel(i.content,`typescript`,n):null}_containsLibFile(e){for(let t of e)if(this.isLibFile(t))return!0;return!1}async fetchLibFilesIfNecessary(e){this._containsLibFile(e)&&await this._fetchLibFiles()}_fetchLibFiles(){return this._fetchLibFilesPromise||=this._worker().then(e=>e.getLibFiles()).then(e=>{this._hasFetchedLibFiles=!0,this._libFiles=e}),this._fetchLibFilesPromise}},b=class extends v{constructor(e,t,n,r){super(r),this._libFiles=e,this._defaults=t,this._selector=n,this._disposables=[],this._listener=Object.create(null);let i=e=>{if(e.getLanguageId()!==n)return;let t=()=>{let{onlyVisible:t}=this._defaults.getDiagnosticsOptions();t?e.isAttachedToEditor()&&this._doValidate(e):this._doValidate(e)},r,i=e.onDidChangeContent(()=>{clearTimeout(r),r=window.setTimeout(t,500)}),a=e.onDidChangeAttached(()=>{let{onlyVisible:n}=this._defaults.getDiagnosticsOptions();n&&(e.isAttachedToEditor()?t():l.editor.setModelMarkers(e,this._selector,[]))});this._listener[e.uri.toString()]={dispose(){i.dispose(),a.dispose(),clearTimeout(r)}},t()},a=e=>{l.editor.setModelMarkers(e,this._selector,[]);let t=e.uri.toString();this._listener[t]&&(this._listener[t].dispose(),delete this._listener[t])};this._disposables.push(l.editor.onDidCreateModel(e=>i(e))),this._disposables.push(l.editor.onWillDisposeModel(a)),this._disposables.push(l.editor.onDidChangeModelLanguage(e=>{a(e.model),i(e.model)})),this._disposables.push({dispose(){for(let e of l.editor.getModels())a(e)}});let o=()=>{for(let e of l.editor.getModels())a(e),i(e)};this._disposables.push(this._defaults.onDidChange(o)),this._disposables.push(this._defaults.onDidExtraLibsChange(o)),l.editor.getModels().forEach(e=>i(e))}dispose(){this._disposables.forEach(e=>e&&e.dispose()),this._disposables=[]}async _doValidate(e){let t=await this._worker(e.uri);if(e.isDisposed())return;let n=[],{noSyntaxValidation:r,noSemanticValidation:i,noSuggestionDiagnostics:a}=this._defaults.getDiagnosticsOptions();r||n.push(t.getSyntacticDiagnostics(e.uri.toString())),i||n.push(t.getSemanticDiagnostics(e.uri.toString())),a||n.push(t.getSuggestionDiagnostics(e.uri.toString()));let o=await Promise.all(n);if(!o||e.isDisposed())return;let s=o.reduce((e,t)=>t.concat(e),[]).filter(e=>(this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore||[]).indexOf(e.code)===-1),c=s.map(e=>e.relatedInformation||[]).reduce((e,t)=>t.concat(e),[]).map(e=>e.file?l.Uri.parse(e.file.fileName):null);await this._libFiles.fetchLibFilesIfNecessary(c),!e.isDisposed()&&l.editor.setModelMarkers(e,this._selector,s.map(t=>this._convertDiagnostics(e,t)))}_convertDiagnostics(e,t){let n=t.start||0,r=t.length||1,{lineNumber:i,column:a}=e.getPositionAt(n),{lineNumber:o,column:s}=e.getPositionAt(n+r),c=[];return t.reportsUnnecessary&&c.push(l.MarkerTag.Unnecessary),t.reportsDeprecated&&c.push(l.MarkerTag.Deprecated),{severity:this._tsDiagnosticCategoryToMarkerSeverity(t.category),startLineNumber:i,startColumn:a,endLineNumber:o,endColumn:s,message:g(t.messageText,`
2
2
  `),code:t.code.toString(),tags:c,relatedInformation:this._convertRelatedInformation(e,t.relatedInformation)}}_convertRelatedInformation(e,t){if(!t)return[];let n=[];return t.forEach(t=>{let r=e;if(t.file&&(r=this._libFiles.getOrCreateModel(t.file.fileName)),!r)return;let i=t.start||0,a=t.length||1,{lineNumber:o,column:s}=r.getPositionAt(i),{lineNumber:c,column:l}=r.getPositionAt(i+a);n.push({resource:r.uri,startLineNumber:o,startColumn:s,endLineNumber:c,endColumn:l,message:g(t.messageText,`
3
3
  `)})}),n}_tsDiagnosticCategoryToMarkerSeverity(e){switch(e){case 1:return l.MarkerSeverity.Error;case 3:return l.MarkerSeverity.Info;case 0:return l.MarkerSeverity.Warning;case 2:return l.MarkerSeverity.Hint}return l.MarkerSeverity.Info}},x=class e extends v{get triggerCharacters(){return[`.`]}async provideCompletionItems(t,n,r,i){let a=t.getWordUntilPosition(n),o=new l.Range(n.lineNumber,a.startColumn,n.lineNumber,a.endColumn),s=t.uri,c=t.getOffsetAt(n),u=await this._worker(s);if(t.isDisposed())return;let d=await u.getCompletionsAtPosition(s.toString(),c);if(!(!d||t.isDisposed()))return{suggestions:d.entries.map(r=>{let i=o;if(r.replacementSpan){let e=t.getPositionAt(r.replacementSpan.start),n=t.getPositionAt(r.replacementSpan.start+r.replacementSpan.length);i=new l.Range(e.lineNumber,e.column,n.lineNumber,n.column)}let a=[];return r.kindModifiers!==void 0&&r.kindModifiers.indexOf(`deprecated`)!==-1&&a.push(l.languages.CompletionItemTag.Deprecated),{uri:s,position:n,offset:c,range:i,label:r.name,insertText:r.name,sortText:r.sortText,kind:e.convertKind(r.kind),tags:a}})}}async resolveCompletionItem(t,n){let r=t,i=r.uri,a=r.position,o=r.offset,s=await(await this._worker(i)).getCompletionEntryDetails(i.toString(),o,r.label);return s?{uri:i,position:a,label:s.name,kind:e.convertKind(s.kind),detail:_(s.displayParts),documentation:{value:e.createDocumentationString(s)}}:r}static convertKind(e){switch(e){case k.primitiveType:case k.keyword:return l.languages.CompletionItemKind.Keyword;case k.variable:case k.localVariable:return l.languages.CompletionItemKind.Variable;case k.memberVariable:case k.memberGetAccessor:case k.memberSetAccessor:return l.languages.CompletionItemKind.Field;case k.function:case k.memberFunction:case k.constructSignature:case k.callSignature:case k.indexSignature:return l.languages.CompletionItemKind.Function;case k.enum:return l.languages.CompletionItemKind.Enum;case k.module:return l.languages.CompletionItemKind.Module;case k.class:return l.languages.CompletionItemKind.Class;case k.interface:return l.languages.CompletionItemKind.Interface;case k.warning:return l.languages.CompletionItemKind.File}return l.languages.CompletionItemKind.Property}static createDocumentationString(e){let t=_(e.documentation);if(e.tags)for(let n of e.tags)t+=`
4
4
 
@@ -1 +1 @@
1
- import{m as e}from"./editor.api-DtvjQlUm.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:`//`,blockComment:[`/*`,`*/`]},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],onEnterRules:[{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,afterText:/^\s*\*\/$/,action:{indentAction:s.languages.IndentAction.IndentOutdent,appendText:` * `}},{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,action:{indentAction:s.languages.IndentAction.None,appendText:` * `}},{beforeText:/^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,action:{indentAction:s.languages.IndentAction.None,appendText:`* `}},{beforeText:/^(\t|(\ \ ))*\ \*\/\s*$/,action:{indentAction:s.languages.IndentAction.None,removeText:1}}],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`,notIn:[`string`]},{open:`'`,close:`'`,notIn:[`string`,`comment`]},{open:"`",close:"`",notIn:[`string`,`comment`]},{open:`/**`,close:` */`,notIn:[`string`]}],folding:{markers:{start:RegExp(`^\\s*//\\s*#?region\\b`),end:RegExp(`^\\s*//\\s*#?endregion\\b`)}}},l={defaultToken:`invalid`,tokenPostfix:`.ts`,keywords:`abstract.any.as.asserts.bigint.boolean.break.case.catch.class.continue.const.constructor.debugger.declare.default.delete.do.else.enum.export.extends.false.finally.for.from.function.get.if.implements.import.in.infer.instanceof.interface.is.keyof.let.module.namespace.never.new.null.number.object.out.package.private.protected.public.override.readonly.require.global.return.satisfies.set.static.string.super.switch.symbol.this.throw.true.try.type.typeof.undefined.unique.unknown.var.void.while.with.yield.async.await.of`.split(`.`),operators:`<=.>=.==.!=.===.!==.=>.+.-.**.*./.%.++.--.<<.</.>>.>>>.&.|.^.!.~.&&.||.??.?.:.=.+=.-=.*=.**=./=.%=.<<=.>>=.>>>=.&=.|=.^=.@`.split(`.`),symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,regexpctl:/[(){}\[\]\$\^|\-*+?\.]/,regexpesc:/\\(?:[bBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,tokenizer:{root:[[/[{}]/,`delimiter.bracket`],{include:`common`}],common:[[/#?[a-z_$][\w$]*/,{cases:{"@keywords":`keyword`,"@default":`identifier`}}],[/[A-Z][\w\$]*/,`type.identifier`],{include:`@whitespace`},[/\/(?=([^\\\/]|\\.)+\/([dgimsuy]*)(\s*)(\.|;|,|\)|\]|\}|$))/,{token:`regexp`,bracket:`@open`,next:`@regexp`}],[/[()\[\]]/,`@brackets`],[/[<>](?!@symbols)/,`@brackets`],[/!(?=([^=]|$))/,`delimiter`],[/@symbols/,{cases:{"@operators":`delimiter`,"@default":``}}],[/(@digits)[eE]([\-+]?(@digits))?/,`number.float`],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,`number.float`],[/0[xX](@hexdigits)n?/,`number.hex`],[/0[oO]?(@octaldigits)n?/,`number.octal`],[/0[bB](@binarydigits)n?/,`number.binary`],[/(@digits)n?/,`number`],[/[;,.]/,`delimiter`],[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/"/,`string`,`@string_double`],[/'/,`string`,`@string_single`],[/`/,`string`,`@string_backtick`]],whitespace:[[/[ \t\r\n]+/,``],[/\/\*\*(?!\/)/,`comment.doc`,`@jsdoc`],[/\/\*/,`comment`,`@comment`],[/\/\/.*$/,`comment`]],comment:[[/[^\/*]+/,`comment`],[/\*\//,`comment`,`@pop`],[/[\/*]/,`comment`]],jsdoc:[[/[^\/*]+/,`comment.doc`],[/\*\//,`comment.doc`,`@pop`],[/[\/*]/,`comment.doc`]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,[`regexp.escape.control`,`regexp.escape.control`,`regexp.escape.control`]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,[`regexp.escape.control`,{token:`regexp.escape.control`,next:`@regexrange`}]],[/(\()(\?:|\?=|\?!)/,[`regexp.escape.control`,`regexp.escape.control`]],[/[()]/,`regexp.escape.control`],[/@regexpctl/,`regexp.escape.control`],[/[^\\\/]/,`regexp`],[/@regexpesc/,`regexp.escape`],[/\\\./,`regexp.invalid`],[/(\/)([dgimsuy]*)/,[{token:`regexp`,bracket:`@close`,next:`@pop`},`keyword.other`]]],regexrange:[[/-/,`regexp.escape.control`],[/\^/,`regexp.invalid`],[/@regexpesc/,`regexp.escape`],[/[^\]]/,`regexp`],[/\]/,{token:`regexp.escape.control`,next:`@pop`,bracket:`@close`}]],string_double:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],string_single:[[/[^\\']+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/'/,`string`,`@pop`]],string_backtick:[[/\$\{/,{token:`delimiter.bracket`,next:`@bracketCounting`}],[/[^\\`$]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/`/,`string`,`@pop`]],bracketCounting:[[/\{/,`delimiter.bracket`,`@bracketCounting`],[/\}/,`delimiter.bracket`,`@pop`],{include:`common`}]}};export{c as conf,l as language};
1
+ import{m as e}from"./editor.api-2asmmhth.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={wordPattern:/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,comments:{lineComment:`//`,blockComment:[`/*`,`*/`]},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],onEnterRules:[{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,afterText:/^\s*\*\/$/,action:{indentAction:s.languages.IndentAction.IndentOutdent,appendText:` * `}},{beforeText:/^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,action:{indentAction:s.languages.IndentAction.None,appendText:` * `}},{beforeText:/^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,action:{indentAction:s.languages.IndentAction.None,appendText:`* `}},{beforeText:/^(\t|(\ \ ))*\ \*\/\s*$/,action:{indentAction:s.languages.IndentAction.None,removeText:1}}],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`,notIn:[`string`]},{open:`'`,close:`'`,notIn:[`string`,`comment`]},{open:"`",close:"`",notIn:[`string`,`comment`]},{open:`/**`,close:` */`,notIn:[`string`]}],folding:{markers:{start:RegExp(`^\\s*//\\s*#?region\\b`),end:RegExp(`^\\s*//\\s*#?endregion\\b`)}}},l={defaultToken:`invalid`,tokenPostfix:`.ts`,keywords:`abstract.any.as.asserts.bigint.boolean.break.case.catch.class.continue.const.constructor.debugger.declare.default.delete.do.else.enum.export.extends.false.finally.for.from.function.get.if.implements.import.in.infer.instanceof.interface.is.keyof.let.module.namespace.never.new.null.number.object.out.package.private.protected.public.override.readonly.require.global.return.satisfies.set.static.string.super.switch.symbol.this.throw.true.try.type.typeof.undefined.unique.unknown.var.void.while.with.yield.async.await.of`.split(`.`),operators:`<=.>=.==.!=.===.!==.=>.+.-.**.*./.%.++.--.<<.</.>>.>>>.&.|.^.!.~.&&.||.??.?.:.=.+=.-=.*=.**=./=.%=.<<=.>>=.>>>=.&=.|=.^=.@`.split(`.`),symbols:/[=><!~?:&|+\-*\/\^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,digits:/\d+(_+\d+)*/,octaldigits:/[0-7]+(_+[0-7]+)*/,binarydigits:/[0-1]+(_+[0-1]+)*/,hexdigits:/[[0-9a-fA-F]+(_+[0-9a-fA-F]+)*/,regexpctl:/[(){}\[\]\$\^|\-*+?\.]/,regexpesc:/\\(?:[bBdDfnrstvwWn0\\\/]|@regexpctl|c[A-Z]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/,tokenizer:{root:[[/[{}]/,`delimiter.bracket`],{include:`common`}],common:[[/#?[a-z_$][\w$]*/,{cases:{"@keywords":`keyword`,"@default":`identifier`}}],[/[A-Z][\w\$]*/,`type.identifier`],{include:`@whitespace`},[/\/(?=([^\\\/]|\\.)+\/([dgimsuy]*)(\s*)(\.|;|,|\)|\]|\}|$))/,{token:`regexp`,bracket:`@open`,next:`@regexp`}],[/[()\[\]]/,`@brackets`],[/[<>](?!@symbols)/,`@brackets`],[/!(?=([^=]|$))/,`delimiter`],[/@symbols/,{cases:{"@operators":`delimiter`,"@default":``}}],[/(@digits)[eE]([\-+]?(@digits))?/,`number.float`],[/(@digits)\.(@digits)([eE][\-+]?(@digits))?/,`number.float`],[/0[xX](@hexdigits)n?/,`number.hex`],[/0[oO]?(@octaldigits)n?/,`number.octal`],[/0[bB](@binarydigits)n?/,`number.binary`],[/(@digits)n?/,`number`],[/[;,.]/,`delimiter`],[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/"/,`string`,`@string_double`],[/'/,`string`,`@string_single`],[/`/,`string`,`@string_backtick`]],whitespace:[[/[ \t\r\n]+/,``],[/\/\*\*(?!\/)/,`comment.doc`,`@jsdoc`],[/\/\*/,`comment`,`@comment`],[/\/\/.*$/,`comment`]],comment:[[/[^\/*]+/,`comment`],[/\*\//,`comment`,`@pop`],[/[\/*]/,`comment`]],jsdoc:[[/[^\/*]+/,`comment.doc`],[/\*\//,`comment.doc`,`@pop`],[/[\/*]/,`comment.doc`]],regexp:[[/(\{)(\d+(?:,\d*)?)(\})/,[`regexp.escape.control`,`regexp.escape.control`,`regexp.escape.control`]],[/(\[)(\^?)(?=(?:[^\]\\\/]|\\.)+)/,[`regexp.escape.control`,{token:`regexp.escape.control`,next:`@regexrange`}]],[/(\()(\?:|\?=|\?!)/,[`regexp.escape.control`,`regexp.escape.control`]],[/[()]/,`regexp.escape.control`],[/@regexpctl/,`regexp.escape.control`],[/[^\\\/]/,`regexp`],[/@regexpesc/,`regexp.escape`],[/\\\./,`regexp.invalid`],[/(\/)([dgimsuy]*)/,[{token:`regexp`,bracket:`@close`,next:`@pop`},`keyword.other`]]],regexrange:[[/-/,`regexp.escape.control`],[/\^/,`regexp.invalid`],[/@regexpesc/,`regexp.escape`],[/[^\]]/,`regexp`],[/\]/,{token:`regexp.escape.control`,next:`@pop`,bracket:`@close`}]],string_double:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],string_single:[[/[^\\']+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/'/,`string`,`@pop`]],string_backtick:[[/\$\{/,{token:`delimiter.bracket`,next:`@bracketCounting`}],[/[^\\`$]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/`/,`string`,`@pop`]],bracketCounting:[[/\{/,`delimiter.bracket`,`@bracketCounting`],[/\}/,`delimiter.bracket`,`@pop`],{include:`common`}]}};export{c as conf,l as language};
@@ -1 +1 @@
1
- import{m as e}from"./editor.api-DtvjQlUm.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={comments:{blockComment:[`<!--`,`-->`]},brackets:[[`<`,`>`]],autoClosingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],surroundingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],onEnterRules:[{beforeText:RegExp(`<([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:s.languages.IndentAction.IndentOutdent}},{beforeText:RegExp(`<(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),action:{indentAction:s.languages.IndentAction.Indent}}]},l={defaultToken:``,tokenPostfix:`.xml`,ignoreCase:!0,qualifiedName:/(?:[\w\.\-]+:)?[\w\.\-]+/,tokenizer:{root:[[/[^<&]+/,``],{include:`@whitespace`},[/(<)(@qualifiedName)/,[{token:`delimiter`},{token:`tag`,next:`@tag`}]],[/(<\/)(@qualifiedName)(\s*)(>)/,[{token:`delimiter`},{token:`tag`},``,{token:`delimiter`}]],[/(<\?)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/(<\!)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/<\!\[CDATA\[/,{token:`delimiter.cdata`,next:`@cdata`}],[/&\w+;/,`string.escape`]],cdata:[[/[^\]]+/,``],[/\]\]>/,{token:`delimiter.cdata`,next:`@pop`}],[/\]/,``]],tag:[[/[ \t\r\n]+/,``],[/(@qualifiedName)(\s*=\s*)("[^"]*"|'[^']*')/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">?\/]*|'[^'>?\/]*)(?=[\?\/]\>)/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">]*|'[^'>]*)/,[`attribute.name`,``,`attribute.value`]],[/@qualifiedName/,`attribute.name`],[/\?>/,{token:`delimiter`,next:`@pop`}],[/(\/)(>)/,[{token:`tag`},{token:`delimiter`,next:`@pop`}]],[/>/,{token:`delimiter`,next:`@pop`}]],whitespace:[[/[ \t\r\n]+/,``],[/<!--/,{token:`comment`,next:`@comment`}]],comment:[[/[^<\-]+/,`comment.content`],[/-->/,{token:`comment`,next:`@pop`}],[/<!--/,`comment.content.invalid`],[/[<\-]/,`comment.content`]]}};export{c as conf,l as language};
1
+ import{m as e}from"./editor.api-2asmmhth.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={comments:{blockComment:[`<!--`,`-->`]},brackets:[[`<`,`>`]],autoClosingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],surroundingPairs:[{open:`<`,close:`>`},{open:`'`,close:`'`},{open:`"`,close:`"`}],onEnterRules:[{beforeText:RegExp(`<([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),afterText:/^<\/([_:\w][_:\w-.\d]*)\s*>$/i,action:{indentAction:s.languages.IndentAction.IndentOutdent}},{beforeText:RegExp(`<(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`,`i`),action:{indentAction:s.languages.IndentAction.Indent}}]},l={defaultToken:``,tokenPostfix:`.xml`,ignoreCase:!0,qualifiedName:/(?:[\w\.\-]+:)?[\w\.\-]+/,tokenizer:{root:[[/[^<&]+/,``],{include:`@whitespace`},[/(<)(@qualifiedName)/,[{token:`delimiter`},{token:`tag`,next:`@tag`}]],[/(<\/)(@qualifiedName)(\s*)(>)/,[{token:`delimiter`},{token:`tag`},``,{token:`delimiter`}]],[/(<\?)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/(<\!)(@qualifiedName)/,[{token:`delimiter`},{token:`metatag`,next:`@tag`}]],[/<\!\[CDATA\[/,{token:`delimiter.cdata`,next:`@cdata`}],[/&\w+;/,`string.escape`]],cdata:[[/[^\]]+/,``],[/\]\]>/,{token:`delimiter.cdata`,next:`@pop`}],[/\]/,``]],tag:[[/[ \t\r\n]+/,``],[/(@qualifiedName)(\s*=\s*)("[^"]*"|'[^']*')/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">?\/]*|'[^'>?\/]*)(?=[\?\/]\>)/,[`attribute.name`,``,`attribute.value`]],[/(@qualifiedName)(\s*=\s*)("[^">]*|'[^'>]*)/,[`attribute.name`,``,`attribute.value`]],[/@qualifiedName/,`attribute.name`],[/\?>/,{token:`delimiter`,next:`@pop`}],[/(\/)(>)/,[{token:`tag`},{token:`delimiter`,next:`@pop`}]],[/>/,{token:`delimiter`,next:`@pop`}]],whitespace:[[/[ \t\r\n]+/,``],[/<!--/,{token:`comment`,next:`@comment`}]],comment:[[/[^<\-]+/,`comment.content`],[/-->/,{token:`comment`,next:`@pop`}],[/<!--/,`comment.content.invalid`],[/[<\-]/,`comment.content`]]}};export{c as conf,l as language};
@@ -1 +1 @@
1
- import{m as e}from"./editor.api-DtvjQlUm.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={comments:{lineComment:`#`},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],surroundingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],folding:{offSide:!0},onEnterRules:[{beforeText:/:\s*$/,action:{indentAction:s.languages.IndentAction.Indent}}]},l={tokenPostfix:`.yaml`,brackets:[{token:`delimiter.bracket`,open:`{`,close:`}`},{token:`delimiter.square`,open:`[`,close:`]`}],keywords:[`true`,`True`,`TRUE`,`false`,`False`,`FALSE`,`null`,`Null`,`Null`,`~`],numberInteger:/(?:0|[+-]?[0-9]+)/,numberFloat:/(?:0|[+-]?[0-9]+)(?:\.[0-9]+)?(?:e[-+][1-9][0-9]*)?/,numberOctal:/0o[0-7]+/,numberHex:/0x[0-9a-fA-F]+/,numberInfinity:/[+-]?\.(?:inf|Inf|INF)/,numberNaN:/\.(?:nan|Nan|NAN)/,numberDate:/\d{4}-\d\d-\d\d([Tt ]\d\d:\d\d:\d\d(\.\d+)?(( ?[+-]\d\d?(:\d\d)?)|Z)?)?/,escapes:/\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,tokenizer:{root:[{include:`@whitespace`},{include:`@comment`},[/%[^ ]+.*$/,`meta.directive`],[/---/,`operators.directivesEnd`],[/\.{3}/,`operators.documentEnd`],[/[-?:](?= )/,`operators`],{include:`@anchor`},{include:`@tagHandle`},{include:`@flowCollections`},{include:`@blockStyle`},[/@numberInteger(?![ \t]*\S+)/,`number`],[/@numberFloat(?![ \t]*\S+)/,`number.float`],[/@numberOctal(?![ \t]*\S+)/,`number.octal`],[/@numberHex(?![ \t]*\S+)/,`number.hex`],[/@numberInfinity(?![ \t]*\S+)/,`number.infinity`],[/@numberNaN(?![ \t]*\S+)/,`number.nan`],[/@numberDate(?![ \t]*\S+)/,`number.date`],[/(".*?"|'.*?'|[^#'"]*?)([ \t]*)(:)( |$)/,[`type`,`white`,`operators`,`white`]],{include:`@flowScalars`},[/.+?(?=(\s+#|$))/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],object:[{include:`@whitespace`},{include:`@comment`},[/\}/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],[/:(?= )/,`operators`],[/(?:".*?"|'.*?'|[^,\{\[]+?)(?=: )/,`type`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\},]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],array:[{include:`@whitespace`},{include:`@comment`},[/\]/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\],]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],multiString:[[/^( +).+$/,`string`,`@multiStringContinued.$1`]],multiStringContinued:[[/^( *).+$/,{cases:{"$1==$S2":`string`,"@default":{token:`@rematch`,next:`@popall`}}}]],whitespace:[[/[ \t\r\n]+/,`white`]],comment:[[/#.*$/,`comment`]],flowCollections:[[/\[/,`@brackets`,`@array`],[/\{/,`@brackets`,`@object`]],flowScalars:[[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/'[^']*'/,`string`],[/"/,`string`,`@doubleQuotedString`]],doubleQuotedString:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],blockStyle:[[/[>|][0-9]*[+-]?$/,`operators`,`@multiString`]],flowNumber:[[/@numberInteger(?=[ \t]*[,\]\}])/,`number`],[/@numberFloat(?=[ \t]*[,\]\}])/,`number.float`],[/@numberOctal(?=[ \t]*[,\]\}])/,`number.octal`],[/@numberHex(?=[ \t]*[,\]\}])/,`number.hex`],[/@numberInfinity(?=[ \t]*[,\]\}])/,`number.infinity`],[/@numberNaN(?=[ \t]*[,\]\}])/,`number.nan`],[/@numberDate(?=[ \t]*[,\]\}])/,`number.date`]],tagHandle:[[/\![^ ]*/,`tag`]],anchor:[[/[&*][^ ]+/,`namespace`]]}};export{c as conf,l as language};
1
+ import{m as e}from"./editor.api-2asmmhth.js";var t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a=(e,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(let c of r(a))!i.call(e,c)&&c!==o&&t(e,c,{get:()=>a[c],enumerable:!(s=n(a,c))||s.enumerable});return e},o=(e,t,n)=>(a(e,t,`default`),n&&a(n,t,`default`)),s={};o(s,e);var c={comments:{lineComment:`#`},brackets:[[`{`,`}`],[`[`,`]`],[`(`,`)`]],autoClosingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],surroundingPairs:[{open:`{`,close:`}`},{open:`[`,close:`]`},{open:`(`,close:`)`},{open:`"`,close:`"`},{open:`'`,close:`'`}],folding:{offSide:!0},onEnterRules:[{beforeText:/:\s*$/,action:{indentAction:s.languages.IndentAction.Indent}}]},l={tokenPostfix:`.yaml`,brackets:[{token:`delimiter.bracket`,open:`{`,close:`}`},{token:`delimiter.square`,open:`[`,close:`]`}],keywords:[`true`,`True`,`TRUE`,`false`,`False`,`FALSE`,`null`,`Null`,`Null`,`~`],numberInteger:/(?:0|[+-]?[0-9]+)/,numberFloat:/(?:0|[+-]?[0-9]+)(?:\.[0-9]+)?(?:e[-+][1-9][0-9]*)?/,numberOctal:/0o[0-7]+/,numberHex:/0x[0-9a-fA-F]+/,numberInfinity:/[+-]?\.(?:inf|Inf|INF)/,numberNaN:/\.(?:nan|Nan|NAN)/,numberDate:/\d{4}-\d\d-\d\d([Tt ]\d\d:\d\d:\d\d(\.\d+)?(( ?[+-]\d\d?(:\d\d)?)|Z)?)?/,escapes:/\\(?:[btnfr\\"']|[0-7][0-7]?|[0-3][0-7]{2})/,tokenizer:{root:[{include:`@whitespace`},{include:`@comment`},[/%[^ ]+.*$/,`meta.directive`],[/---/,`operators.directivesEnd`],[/\.{3}/,`operators.documentEnd`],[/[-?:](?= )/,`operators`],{include:`@anchor`},{include:`@tagHandle`},{include:`@flowCollections`},{include:`@blockStyle`},[/@numberInteger(?![ \t]*\S+)/,`number`],[/@numberFloat(?![ \t]*\S+)/,`number.float`],[/@numberOctal(?![ \t]*\S+)/,`number.octal`],[/@numberHex(?![ \t]*\S+)/,`number.hex`],[/@numberInfinity(?![ \t]*\S+)/,`number.infinity`],[/@numberNaN(?![ \t]*\S+)/,`number.nan`],[/@numberDate(?![ \t]*\S+)/,`number.date`],[/(".*?"|'.*?'|[^#'"]*?)([ \t]*)(:)( |$)/,[`type`,`white`,`operators`,`white`]],{include:`@flowScalars`},[/.+?(?=(\s+#|$))/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],object:[{include:`@whitespace`},{include:`@comment`},[/\}/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],[/:(?= )/,`operators`],[/(?:".*?"|'.*?'|[^,\{\[]+?)(?=: )/,`type`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\},]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],array:[{include:`@whitespace`},{include:`@comment`},[/\]/,`@brackets`,`@pop`],[/,/,`delimiter.comma`],{include:`@flowCollections`},{include:`@flowScalars`},{include:`@tagHandle`},{include:`@anchor`},{include:`@flowNumber`},[/[^\],]+/,{cases:{"@keywords":`keyword`,"@default":`string`}}]],multiString:[[/^( +).+$/,`string`,`@multiStringContinued.$1`]],multiStringContinued:[[/^( *).+$/,{cases:{"$1==$S2":`string`,"@default":{token:`@rematch`,next:`@popall`}}}]],whitespace:[[/[ \t\r\n]+/,`white`]],comment:[[/#.*$/,`comment`]],flowCollections:[[/\[/,`@brackets`,`@array`],[/\{/,`@brackets`,`@object`]],flowScalars:[[/"([^"\\]|\\.)*$/,`string.invalid`],[/'([^'\\]|\\.)*$/,`string.invalid`],[/'[^']*'/,`string`],[/"/,`string`,`@doubleQuotedString`]],doubleQuotedString:[[/[^\\"]+/,`string`],[/@escapes/,`string.escape`],[/\\./,`string.escape.invalid`],[/"/,`string`,`@pop`]],blockStyle:[[/[>|][0-9]*[+-]?$/,`operators`,`@multiString`]],flowNumber:[[/@numberInteger(?=[ \t]*[,\]\}])/,`number`],[/@numberFloat(?=[ \t]*[,\]\}])/,`number.float`],[/@numberOctal(?=[ \t]*[,\]\}])/,`number.octal`],[/@numberHex(?=[ \t]*[,\]\}])/,`number.hex`],[/@numberInfinity(?=[ \t]*[,\]\}])/,`number.infinity`],[/@numberNaN(?=[ \t]*[,\]\}])/,`number.nan`],[/@numberDate(?=[ \t]*[,\]\}])/,`number.date`]],tagHandle:[[/\![^ ]*/,`tag`]],anchor:[[/[&*][^ ]+/,`namespace`]]}};export{c as conf,l as language};
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html><head><title>Kōbō</title><link rel=icon type=image/svg+xml href=/favicon.svg><meta charset=utf-8><meta name=description content="Kōbō — multi-workspace agent manager for Claude Code"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width,height=device-height"> <script type="module" crossorigin src="/assets/index-_ZaIBxd6.js"></script>
1
+ <!DOCTYPE html><html><head><title>Kōbō</title><link rel=icon type=image/svg+xml href=/favicon.svg><meta charset=utf-8><meta name=description content="Kōbō — multi-workspace agent manager for Claude Code"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width,height=device-height"> <script type="module" crossorigin src="/assets/index-D6wj_wQ9.js"></script>
2
2
  <link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-C3IgBgY5.js">
3
3
  <link rel="modulepreload" crossorigin href="/assets/vue-i18n-BcfTCFFS.js">
4
4
  <link rel="modulepreload" crossorigin href="/assets/QIcon-BJuyqdsT.js">
@@ -2,6 +2,7 @@ import fs from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import type Database from 'better-sqlite3'
4
4
  import { nanoid } from 'nanoid'
5
+ import * as cronService from '../server/services/cron-service.js'
5
6
  import * as settingsService from '../server/services/settings-service.js'
6
7
  import { slugifyProjectName } from '../server/utils/project-slug.js'
7
8
  import { resolveWorkspaceWorktreePath } from '../server/utils/worktree-paths.js'
@@ -75,6 +76,34 @@ export function markAutoLoopReadyHandler(db: Database.Database, workspaceId: str
75
76
  return { ok: true }
76
77
  }
77
78
 
79
+ /**
80
+ * Update the workspace's agent-side short description (≤ 200 chars). Empty /
81
+ * whitespace-only input clears the field (stored as NULL). This writes the
82
+ * `agent_description` column — a live status line owned by the agent — and
83
+ * leaves the user-side `description` column untouched. The handler does NOT
84
+ * emit a WS event; that's the route/service layer's responsibility. Live UI
85
+ * refresh on agent-driven updates is therefore deferred until next read.
86
+ */
87
+ export function setWorkspaceAgentDescriptionHandler(
88
+ db: Database.Database,
89
+ workspaceId: string,
90
+ args: { description: string },
91
+ ): { ok: true; description: string | null } | { ok: false; error: string } {
92
+ const raw = typeof args?.description === 'string' ? args.description : ''
93
+ const trimmed = raw.trim()
94
+ if (trimmed.length > 200) {
95
+ return { ok: false, error: `Description must be 200 characters or fewer (got ${trimmed.length})` }
96
+ }
97
+ const stored = trimmed.length > 0 ? trimmed : null
98
+ const result = db
99
+ .prepare('UPDATE workspaces SET agent_description = ?, updated_at = ? WHERE id = ?')
100
+ .run(stored, new Date().toISOString(), workspaceId)
101
+ if (result.changes === 0) {
102
+ return { ok: false, error: `Workspace '${workspaceId}' not found` }
103
+ }
104
+ return { ok: true, description: stored }
105
+ }
106
+
78
107
  /** Set a task's status to "done" and return the updated task. */
79
108
  export function markTaskDoneHandler(db: Database.Database, workspaceId: string, taskId: string): MarkDoneResult {
80
109
  const now = new Date().toISOString()
@@ -240,6 +269,8 @@ export interface WorkspaceInfoDto {
240
269
  model: string
241
270
  notionUrl: string | null
242
271
  notionPageId: string | null
272
+ description: string | null
273
+ agentDescription: string | null
243
274
  devServerStatus: string
244
275
  hasUnread: boolean
245
276
  autoLoop: boolean
@@ -258,6 +289,8 @@ interface WorkspaceRow {
258
289
  status: string
259
290
  notion_url: string | null
260
291
  notion_page_id: string | null
292
+ description: string | null
293
+ agent_description: string | null
261
294
  model: string
262
295
  dev_server_status: string
263
296
  has_unread: number
@@ -271,7 +304,7 @@ interface WorkspaceRow {
271
304
  export function getWorkspaceInfoHandler(db: Database.Database, workspaceId: string): WorkspaceInfoDto {
272
305
  const row = db
273
306
  .prepare(
274
- 'SELECT id, name, project_path, source_branch, working_branch, worktree_path, status, notion_url, notion_page_id, model, dev_server_status, has_unread, auto_loop, auto_loop_ready, created_at, updated_at FROM workspaces WHERE id = ?',
307
+ 'SELECT id, name, project_path, source_branch, working_branch, worktree_path, status, notion_url, notion_page_id, description, agent_description, model, dev_server_status, has_unread, auto_loop, auto_loop_ready, created_at, updated_at FROM workspaces WHERE id = ?',
275
308
  )
276
309
  .get(workspaceId) as WorkspaceRow | undefined
277
310
 
@@ -297,6 +330,8 @@ export function getWorkspaceInfoHandler(db: Database.Database, workspaceId: stri
297
330
  model: row.model,
298
331
  notionUrl: row.notion_url,
299
332
  notionPageId: row.notion_page_id,
333
+ description: row.description ?? null,
334
+ agentDescription: row.agent_description ?? null,
300
335
  devServerStatus: row.dev_server_status,
301
336
  hasUnread: row.has_unread === 1,
302
337
  autoLoop: row.auto_loop === 1,
@@ -531,3 +566,22 @@ export function getSessionUsageHandler(db: Database.Database, workspaceId: strin
531
566
  currentSession: { sessionId: currentSessionId, ...current },
532
567
  }
533
568
  }
569
+
570
+ // ── Crons ────────────────────────────────────────────────────────────────────
571
+
572
+ /**
573
+ * List every cron currently armed for a workspace.
574
+ *
575
+ * Note: cron_create and cron_delete are NOT exposed as handlers — they route
576
+ * through the backend HTTP API (`POST/DELETE /api/workspaces/:id/crons`)
577
+ * because their `setTimeout` must live in the backend process (which owns
578
+ * the orchestrator). Handlers here would arm timers in the MCP sub-process,
579
+ * which dies with the agent session, and fires would never reach a real
580
+ * session resume. The list handler is a pure read so it's safe to keep local.
581
+ */
582
+ export function cronListHandler(
583
+ _db: Database.Database,
584
+ workspaceId: string,
585
+ ): { ok: true; crons: cronService.PendingCron[] } {
586
+ return { ok: true, crons: cronService.listForWorkspace(workspaceId) }
587
+ }
@@ -4,9 +4,12 @@ import path from 'node:path'
4
4
  import { Server } from '@modelcontextprotocol/sdk/server/index.js'
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
6
6
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
7
- import Database from 'better-sqlite3'
7
+ import type Database from 'better-sqlite3'
8
+ import { getDb } from '../server/db/index.js'
9
+ import { runMigrations } from '../server/db/migrations.js'
8
10
  import {
9
11
  createTaskHandler,
12
+ cronListHandler,
10
13
  deleteTaskHandler,
11
14
  getDevServerStatusHandler,
12
15
  getSessionUsageHandler,
@@ -19,6 +22,7 @@ import {
19
22
  markAutoLoopReadyHandler,
20
23
  markTaskDoneHandler,
21
24
  readDocumentHandler,
25
+ setWorkspaceAgentDescriptionHandler,
22
26
  updateTaskHandler,
23
27
  } from './kobo-tasks-handlers.js'
24
28
 
@@ -39,10 +43,21 @@ if (!dbPath) {
39
43
 
40
44
  let db: Database.Database
41
45
  try {
42
- db = new Database(dbPath, { readonly: false })
43
- db.pragma('journal_mode = WAL')
44
- db.pragma('busy_timeout = 5000')
45
- db.pragma('foreign_keys = ON')
46
+ // Use the shared `getDb` singleton so any service that calls `getDb()`
47
+ // internally (e.g. cron-service.arm) hits the SAME connection as this
48
+ // MCP server, against the SAME DB file. Without this bootstrap, the
49
+ // singleton would resolve via getDbPath() getKoboHome() → KOBO_HOME
50
+ // env var, which the agent SDK does NOT pass to the MCP server (only
51
+ // KOBO_DB_PATH is passed). That would silently open a second connection
52
+ // against the user's prod DB at ~/.config/kobo/kobo.db, which may not
53
+ // even have the same schema as the dev DB the backend is using.
54
+ db = getDb(dbPath)
55
+ // Defensive: run migrations to ensure the schema is at the latest version.
56
+ // The backend already ran them at boot, but this MCP server might be the
57
+ // first to touch the DB (e.g. tests, race at first boot, or KOBO_DB_PATH
58
+ // pointing somewhere the backend hasn't migrated). Idempotent — no-op if
59
+ // the DB is already at SCHEMA_VERSION.
60
+ runMigrations(db)
46
61
  } catch (err) {
47
62
  console.error('[kobo-tasks-server] Failed to open database:', err)
48
63
  process.exit(1)
@@ -87,6 +102,22 @@ async function notifyAutoLoopReady(): Promise<void> {
87
102
  }
88
103
  }
89
104
 
105
+ /**
106
+ * Fire-and-forget POST that lands on `/agent-description/notify-updated`,
107
+ * which emits the `workspace:agent-description-updated` WS event so the
108
+ * sidebar fallback display + the workspace header italic line refresh live
109
+ * across every connected client. The handler already wrote the column to DB;
110
+ * this call is ONLY for the event emission.
111
+ */
112
+ async function notifyAgentDescriptionUpdated(): Promise<void> {
113
+ try {
114
+ const url = `${backendUrl}/api/workspaces/${workspaceId}/agent-description/notify-updated`
115
+ await fetch(url, { method: 'POST' })
116
+ } catch (err) {
117
+ console.error('[kobo-tasks-server] notify-agent-description-updated failed:', err)
118
+ }
119
+ }
120
+
90
121
  /** Generic HTTP request to the Kobo backend, returning parsed JSON or null. */
91
122
  async function backendRequest(
92
123
  method: 'GET' | 'POST' | 'PATCH' | 'DELETE',
@@ -192,6 +223,73 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
192
223
  'CALL EARLY in a session to confirm project path, working/source branch, worktree path, model, and notion link. Cheap read — useful when the user refers to "this workspace" or when you need the worktree path to locate files.',
193
224
  inputSchema: { type: 'object', properties: {}, required: [] },
194
225
  },
226
+ {
227
+ name: 'set_workspace_agent_description',
228
+ description:
229
+ "Set or clear the workspace's agent-side description (≤ 200 chars). Pass an empty string to clear. The user sees this string under the workspace title in the sidebar (it takes precedence over the user-controlled `description` field). Plain text only. The current value is available via get_workspace_info as agentDescription. NOTE: there is a separate user-controlled `description` field — do NOT try to write it; it has no MCP tool.",
230
+ inputSchema: {
231
+ type: 'object',
232
+ properties: {
233
+ description: {
234
+ type: 'string',
235
+ description: 'Plain text, max 200 characters. Empty string clears the description.',
236
+ },
237
+ },
238
+ required: ['description'],
239
+ },
240
+ },
241
+ {
242
+ name: 'cron_create',
243
+ description:
244
+ 'Schedule a recurring trigger on THIS workspace. At each fire, Kōbō waits for the workspace to be idle (no active session) and then resumes the same conversation by injecting `prompt` as the next user message — same UX as `schedule_wakeup` but recurring. Skip-if-active: if a session is already running when the timer fires, that occurrence is skipped, the next occurrence is computed, and the cron continues. The cron persists across server restarts (skip-missed semantics on boot — no catchup spam). Delete with `cron_delete(id)`. Multiple crons per workspace are allowed.',
245
+ inputSchema: {
246
+ type: 'object',
247
+ properties: {
248
+ expression: {
249
+ type: 'string',
250
+ description:
251
+ 'Standard 5-field cron expression (`min hour dom month dow`) or one of the helpers `@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`. Example: `*/30 * * * *` = every 30 minutes; `0 9 * * 1` = every Monday at 9am. Validated at create time.',
252
+ },
253
+ prompt: {
254
+ type: 'string',
255
+ description: 'The prompt to inject as the next user message at each fire.',
256
+ },
257
+ label: {
258
+ type: 'string',
259
+ description: 'Optional human-readable label for the cron (shown in the UI).',
260
+ },
261
+ mode: {
262
+ type: 'string',
263
+ enum: ['resume', 'fresh'],
264
+ description:
265
+ "How each fire is handled. 'resume' (default) pins the cron to the session you're calling from, so every fire continues THAT conversation by injecting `prompt` as the next user message — use this when the cron should follow up on ongoing work. 'fresh' starts a brand-new session at every fire with a clean context — use this for periodic checks (e.g. CI watch, daily standup) that don't need conversation continuity.",
266
+ },
267
+ oneShot: {
268
+ type: 'boolean',
269
+ description:
270
+ "When true, the cron cancels itself after the first real fire (default false = recurring). Use this to schedule a single trigger at a specific cron-expressible time (e.g. `0 14 7 6 *` = next 7 June at 14:00) without it repeating yearly. Skip-active fires don't consume the one-shot — the cron retries at the next occurrence until it actually runs once.",
271
+ },
272
+ },
273
+ required: ['expression', 'prompt'],
274
+ },
275
+ },
276
+ {
277
+ name: 'cron_delete',
278
+ description:
279
+ "Cancel a previously-armed cron by id. Idempotent — returns ok=true even if the id is unknown. Only the workspace's own crons can be cancelled (cron_list to see them).",
280
+ inputSchema: {
281
+ type: 'object',
282
+ properties: {
283
+ id: { type: 'string', description: 'The cron id returned by cron_create.' },
284
+ },
285
+ required: ['id'],
286
+ },
287
+ },
288
+ {
289
+ name: 'cron_list',
290
+ description: 'List all crons currently armed on THIS workspace, including their next and last fire times.',
291
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false },
292
+ },
195
293
  {
196
294
  name: 'get_git_info',
197
295
  description:
@@ -341,13 +439,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
341
439
  {
342
440
  name: 'schedule_wakeup',
343
441
  description:
344
- 'CALL to schedule a follow-up turn on THIS workspace after a delay. End the current turn normally; once it finishes and the workspace is idle, Kōbō waits `delaySeconds`, then resumes the same conversation by injecting `prompt` as the next user message. The wakeup is scoped to the current workspace and resumes its latest session — you cannot target another workspace or another session. If a turn is still active when the timer fires, the wakeup is skipped (status: `session-active`). Replaces any previously pending wakeup on this workspace. Delay is clamped to [60, 3600] seconds. Prefer this over the built-in `ScheduleWakeup` tool — it is the SDK-supported entry point.',
442
+ 'CALL to schedule a follow-up turn on THIS workspace after a delay. End the current turn normally; once it finishes and the workspace is idle, Kōbō waits `delaySeconds`, then resumes the same conversation by injecting `prompt` as the next user message. The wakeup is scoped to the current workspace and resumes its latest session — you cannot target another workspace or another session. If a turn is still active when the timer fires, the wakeup is skipped (status: `session-active`). Replaces any previously pending wakeup on this workspace. Delay is clamped to [60, 21600] seconds (1min to 6h). Prefer this over the built-in `ScheduleWakeup` tool — it is the SDK-supported entry point.',
345
443
  inputSchema: {
346
444
  type: 'object',
347
445
  properties: {
348
446
  delaySeconds: {
349
447
  type: 'number',
350
- description: 'Seconds from now until the wakeup fires. Clamped to [60, 3600].',
448
+ description: 'Seconds from now until the wakeup fires. Clamped to [60, 21600] (1min to 6h).',
351
449
  },
352
450
  prompt: {
353
451
  type: 'string',
@@ -452,6 +550,66 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
452
550
  return ok(getWorkspaceInfoHandler(db, workspaceId!))
453
551
  }
454
552
 
553
+ if (name === 'set_workspace_agent_description') {
554
+ const description = a.description as string | undefined
555
+ if (typeof description !== 'string') return fail('description parameter is required')
556
+ const result = setWorkspaceAgentDescriptionHandler(db, workspaceId!, { description })
557
+ if ('ok' in result && result.ok) {
558
+ void notifyAgentDescriptionUpdated()
559
+ }
560
+ return ok(result)
561
+ }
562
+
563
+ if (name === 'cron_create') {
564
+ const expression = a.expression as string | undefined
565
+ const prompt = a.prompt as string | undefined
566
+ const label = typeof a.label === 'string' ? (a.label as string) : undefined
567
+ const mode = typeof a.mode === 'string' ? (a.mode as string) : undefined
568
+ const oneShot = typeof a.oneShot === 'boolean' ? (a.oneShot as boolean) : undefined
569
+ if (typeof expression !== 'string' || typeof prompt !== 'string') {
570
+ return fail('expression and prompt parameters are required')
571
+ }
572
+ if (mode !== undefined && mode !== 'resume' && mode !== 'fresh') {
573
+ return fail("mode must be 'resume' or 'fresh'")
574
+ }
575
+ // Route through the backend so the in-memory `setTimeout` lives in the
576
+ // backend process (which owns orchestrator + WS broadcast). Calling
577
+ // cron-service.arm() directly here would persist the row but arm the
578
+ // timer in the MCP server sub-process, which dies with the agent
579
+ // session — fires would never trigger a real session resume.
580
+ try {
581
+ const created = (await backendRequest('POST', `/api/workspaces/${workspaceId}/crons`, {
582
+ expression,
583
+ prompt,
584
+ label,
585
+ mode,
586
+ oneShot,
587
+ })) as { cron: unknown }
588
+ return ok({ ok: true, cron: created.cron })
589
+ } catch (err) {
590
+ const message = err instanceof Error ? err.message : String(err)
591
+ return ok({ ok: false, error: message })
592
+ }
593
+ }
594
+
595
+ if (name === 'cron_delete') {
596
+ const id = a.id as string | undefined
597
+ if (typeof id !== 'string') return fail('id parameter is required')
598
+ // Same reason as cron_create — the backend owns the timer Map.
599
+ try {
600
+ await backendRequest('DELETE', `/api/workspaces/${workspaceId}/crons/${id}`)
601
+ return ok({ ok: true })
602
+ } catch (err) {
603
+ const message = err instanceof Error ? err.message : String(err)
604
+ return ok({ ok: false, error: message })
605
+ }
606
+ }
607
+
608
+ if (name === 'cron_list') {
609
+ const result = cronListHandler(db, workspaceId!)
610
+ return ok(result)
611
+ }
612
+
455
613
  if (name === 'start_dev_server') {
456
614
  const result = await backendRequest('POST', `/api/dev-server/${workspaceId}/start`)
457
615
  return ok(result)
@@ -1 +0,0 @@
1
- import{F as e,L as t,M as n,Q as r,U as i,_t as ee,bt as a,d as o,f as s,g as c,l,p as u,r as te,rt as ne,u as d,v as re}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{t as f}from"./QIcon-BJuyqdsT.js";import{t as p}from"./QBtn-a6jxWjmW.js";import{a as m,b as h,y as g}from"./index-_ZaIBxd6.js";import{n as ie,t as ae}from"./QItemSection-5YpFpPDm.js";import{t as _}from"./QSpace-CLtL3aPy.js";import{t as oe}from"./QList-D0FtnQJI.js";import{t as v}from"./use-quasar-Sdcq6zzV.js";import{t as y}from"./QPage-ChUKoaKe.js";var b={class:`row items-center q-mb-md`},x={class:`text-h6 q-ml-sm`},S={key:0,class:`text-grey-6 text-center q-pa-lg`},C={key:1,class:`column q-gutter-md`},w={class:`text-subtitle2 q-mb-sm`},T={class:`text-caption text-grey-6`},E={class:`text-body2`},D={class:`row items-center`},O={class:`text-subtitle2`},k={class:`row q-col-gutter-md q-mt-xs`},A={class:`col`},j={class:`text-caption text-grey-6`},M={class:`text-body2`},N={class:`col-auto`},P={class:`text-caption text-grey-6`},F={class:`text-body2`},I={class:`col-auto`},L={class:`text-caption text-grey-6`},R={class:`text-body2`},z={class:`row items-center`},B={class:`text-subtitle2`},V={key:0,class:`text-caption text-grey-5 q-mt-xs`},se={key:1,class:`text-caption text-negative q-mt-xs`},H={class:`row items-center`},U={class:`text-subtitle2`},W={class:`text-caption text-grey-6 q-mt-xs`},G={key:0,class:`q-mt-sm`},K={class:`text-caption text-negative q-mb-xs`},ce={class:`text-body2`},le={class:`text-caption text-grey-6`},ue={class:`row items-center`},de={class:`text-subtitle2`},fe={class:`text-subtitle2 q-mb-sm`},pe={class:`column q-gutter-xs`},me={class:`row items-center`},he={class:`q-ml-sm text-caption text-grey-6`},ge={class:`row items-center`},_e={class:`q-ml-sm text-caption text-grey-6`},ve={class:`row items-center`},ye={class:`q-ml-sm text-caption text-grey-6`},q=re({__name:`HealthPage`,setup(re){let q=v(),be=m(),J=r(null),Y=r(!1);async function X(){Y.value=!0;try{let e=await fetch(`/api/health/report`);if(!e.ok)throw Error(`HTTP ${e.status}`);J.value=await e.json()}catch(e){q.notify({type:`negative`,message:String(e),position:`top`,timeout:4e3})}finally{Y.value=!1}}n(X);let xe=l(()=>{let e=J.value?.db.sizeBytes;return e==null?`—`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}),Z=l(()=>{let e=J.value;return e?e.db.schemaVersion===e.db.currentSchemaVersion:!1});function Q(e){return e?`check_circle`:`error`}function $(e){return e?`positive`:`negative`}return(n,r)=>(e(),o(y,{class:`q-pa-md`,style:{"max-width":`900px`,margin:`0 auto`}},{default:i(()=>[d(`div`,b,[c(p,{flat:``,dense:``,round:``,icon:`arrow_back`,onClick:r[0]||=e=>ne(be).back()}),d(`div`,x,a(n.$t(`health.title`)),1),c(_),c(p,{flat:``,dense:``,icon:`refresh`,loading:Y.value,label:n.$t(`common.refresh`),onClick:X},null,8,[`loading`,`label`])]),!J.value&&Y.value?(e(),u(`div`,S,a(n.$t(`common.loading`)),1)):J.value?(e(),u(`div`,C,[c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,w,a(n.$t(`health.envTitle`)),1),d(`div`,T,a(n.$t(`health.koboHome`)),1),d(`div`,E,a(J.value.koboHome),1)]),_:1})]),_:1}),c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,D,[d(`div`,O,a(n.$t(`health.dbTitle`)),1),c(_),c(f,{name:Q(Z.value),color:$(Z.value)},null,8,[`name`,`color`])]),d(`div`,k,[d(`div`,A,[d(`div`,j,a(n.$t(`health.dbPath`)),1),d(`div`,M,a(J.value.db.path),1)]),d(`div`,N,[d(`div`,P,a(n.$t(`health.dbSize`)),1),d(`div`,F,a(xe.value),1)]),d(`div`,I,[d(`div`,L,a(n.$t(`health.schemaVersion`)),1),d(`div`,R,a(J.value.db.schemaVersion)+` / `+a(J.value.db.currentSchemaVersion),1)])])]),_:1})]),_:1}),c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,z,[d(`div`,B,a(n.$t(`health.cliTitle`)),1),c(_),c(f,{name:Q(J.value.claudeCli.available),color:$(J.value.claudeCli.available)},null,8,[`name`,`color`])]),J.value.claudeCli.available?(e(),u(`div`,V,a(J.value.claudeCli.version),1)):(e(),u(`div`,se,a(n.$t(`health.cliMissing`)),1))]),_:1})]),_:1}),c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,H,[d(`div`,U,a(n.$t(`health.workspacesTitle`)),1),c(_),c(f,{name:Q(J.value.workspaces.worktreesMissing.length===0),color:$(J.value.workspaces.worktreesMissing.length===0)},null,8,[`name`,`color`])]),d(`div`,W,a(n.$t(`health.workspacesCount`,{total:J.value.workspaces.total,archived:J.value.workspaces.archived})),1),J.value.workspaces.worktreesMissing.length>0?(e(),u(`div`,G,[d(`div`,K,a(n.$t(`health.worktreesMissing`,{count:J.value.workspaces.worktreesMissing.length})),1),c(oe,{dense:``,dark:``},{default:i(()=>[(e(!0),u(te,null,t(J.value.workspaces.worktreesMissing,t=>(e(),o(ie,{key:t.workspaceId},{default:i(()=>[c(ae,null,{default:i(()=>[d(`div`,ce,a(t.name),1),d(`div`,le,a(t.path),1)]),_:2},1024)]),_:2},1024))),128))]),_:1})])):s(``,!0)]),_:1})]),_:1}),c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,ue,[d(`div`,de,a(n.$t(`health.sessionsTitle`)),1),c(_),c(f,{name:Q(J.value.agentSessions.orphaned===0),color:$(J.value.agentSessions.orphaned===0)},null,8,[`name`,`color`])]),d(`div`,{class:ee([`text-caption q-mt-xs`,J.value.agentSessions.orphaned>0?`text-negative`:`text-grey-6`])},a(n.$t(`health.sessionsOrphaned`,{n:J.value.agentSessions.orphaned})),3)]),_:1})]),_:1}),c(g,{dark:``,flat:``,bordered:``},{default:i(()=>[c(h,null,{default:i(()=>[d(`div`,fe,a(n.$t(`health.integrationsTitle`)),1),d(`div`,pe,[d(`div`,me,[c(f,{name:Q(J.value.integrations.notion.configured),color:$(J.value.integrations.notion.configured),size:`sm`},null,8,[`name`,`color`]),r[1]||=d(`span`,{class:`q-ml-sm text-body2`},`Notion`,-1),d(`span`,he,a(J.value.integrations.notion.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)]),d(`div`,ge,[c(f,{name:Q(J.value.integrations.sentry.configured),color:$(J.value.integrations.sentry.configured),size:`sm`},null,8,[`name`,`color`]),r[2]||=d(`span`,{class:`q-ml-sm text-body2`},`Sentry`,-1),d(`span`,_e,a(J.value.integrations.sentry.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)]),d(`div`,ve,[c(f,{name:Q(J.value.integrations.editor.configured),color:$(J.value.integrations.editor.configured),size:`sm`},null,8,[`name`,`color`]),r[3]||=d(`span`,{class:`q-ml-sm text-body2`},`Editor`,-1),d(`span`,ye,a(J.value.integrations.editor.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)])])]),_:1})]),_:1})])):s(``,!0)]),_:1}))}});export{q as default};
@@ -1 +0,0 @@
1
- .acceptance-item[data-v-20a94a3d]{padding:2px 0}.acceptance-item[data-v-20a94a3d]:hover{background-color:#ffffff08}.acceptance-item:hover .criterion-delete-btn[data-v-20a94a3d]{opacity:1}.criterion-delete-btn[data-v-20a94a3d]{opacity:0;transition:opacity .15s}.acceptance-title[data-v-20a94a3d]{word-break:break-word;cursor:text;line-height:1.4}.text-strike[data-v-20a94a3d]{opacity:.7;text-decoration:line-through}.criterion-input[data-v-20a94a3d] .q-field__control{height:22px;min-height:22px;padding:0}.criterion-input[data-v-20a94a3d] input{color:#e0e0e0;font-size:12px}.criterion-input[data-v-20a94a3d] input::placeholder{color:#555}.criterion-add-row[data-v-20a94a3d],.todo-item[data-v-6a3613f7]{padding:2px 0}.todo-title[data-v-6a3613f7]{word-break:break-word;line-height:1.4}.text-strike[data-v-6a3613f7]{opacity:.7;text-decoration:line-through}.documents-tree[data-v-89e5de13] .q-tree__node--selected>.q-tree__node-header{background:#7986cb26}.documents-tree[data-v-89e5de13] .q-tree__node-header{padding:2px 4px}.document-content[data-v-89e5de13]{color:#d0d0d0;overflow-wrap:break-word;font-size:12px;line-height:1.6}.document-content[data-v-89e5de13] h1{color:#e0e0e0;margin:16px 0 8px;font-size:16px}.document-content[data-v-89e5de13] h2{color:#e0e0e0;margin:14px 0 6px;font-size:14px}.document-content[data-v-89e5de13] h3{color:#e0e0e0;margin:12px 0 4px;font-size:13px}.document-content[data-v-89e5de13] code{background:#1a1a2e;border-radius:3px;padding:1px 4px;font-family:Roboto Mono,monospace;font-size:11px}.document-content[data-v-89e5de13] pre{background:#1a1a2e;border-radius:6px;padding:8px 12px;font-size:11px;overflow-x:auto}.document-content[data-v-89e5de13] pre code{background:0 0;padding:0}.document-content[data-v-89e5de13] ul,.document-content[data-v-89e5de13] ol{padding-left:20px}.document-content[data-v-89e5de13] li{margin-bottom:2px}.document-content[data-v-89e5de13] input[type=checkbox]{pointer-events:none;margin-right:6px}.document-content[data-v-89e5de13] table{border-collapse:collapse;width:100%;margin:8px 0;font-size:11px}.document-content[data-v-89e5de13] th,.document-content[data-v-89e5de13] td{text-align:left;border:1px solid #2a2a4a;padding:4px 8px}.document-content[data-v-89e5de13] th{color:#e0e0e0;background:#1a1a2e}.document-content[data-v-89e5de13] blockquote{color:#a0a0b0;border-left:3px solid #4a4a6a;margin:8px 0;padding:4px 12px}.document-content[data-v-89e5de13] a{color:#818cf8}.document-content[data-v-89e5de13] hr{border:none;border-top:1px solid #2a2a4a;margin:12px 0}.commit-item[data-v-fd1cc184]:hover{background:#ffffff0a}.commit-sha[data-v-fd1cc184]{font-family:Roboto Mono,monospace;font-size:11px}.commit-subject[data-v-fd1cc184]{max-width:480px;font-size:12px}.git-btn[data-v-ff606b69]{padding:2px 8px;font-size:11px}.git-sync-btn[data-v-ff606b69]{padding:2px 0}.git-sync-btn[data-v-ff606b69] .q-btn__content{padding:0 8px}.git-sync-btn[data-v-ff606b69] .q-btn-dropdown__arrow-container{border-left:1px solid #ffffff1f;padding:0 4px}.git-sync-btn[data-v-ff606b69] .q-btn-dropdown--split{gap:0}.commit-toggle[data-v-ff606b69]:hover{background-color:#ffffff08;border-radius:3px}.commit-list[data-v-ff606b69]{border-left:2px solid #ffffff0a;max-height:260px;margin-left:7px;padding-left:6px;overflow-y:auto}.commit-item[data-v-ff606b69]{border-radius:3px;padding:3px 4px;font-size:11px;line-height:1.3;transition:background-color .1s}.commit-item[data-v-ff606b69]:hover{background-color:#818cf814}.commit-item-icon[data-v-ff606b69]{flex-shrink:0}.commit-sha[data-v-ff606b69]{flex-shrink:0;font-family:Roboto Mono,monospace;font-size:10.5px}.commit-subject[data-v-ff606b69]{min-width:0;font-size:11px}.arrow-clickable[data-v-ff606b69]{transition:opacity .15s}.arrow-clickable[data-v-ff606b69]:hover{opacity:.75;text-decoration:underline}.git-branch-code{color:#c7d2fe;white-space:nowrap;background-color:#818cf824;border-radius:3px;padding:1px 5px;font-family:Roboto Mono,monospace;font-size:11px}.subagents-panel[data-v-dd805632]{overflow-y:auto}.subagent-item[data-v-dd805632]{background:#1e1e3a;border:1px solid #2a2a4a}.task-item[data-v-4bc9713a]{padding:2px 0}.task-item[data-v-4bc9713a]:hover{background-color:#ffffff08}.task-item:hover .task-delete-btn[data-v-4bc9713a]{opacity:1}.task-delete-btn[data-v-4bc9713a]{opacity:0;transition:opacity .15s}.task-title[data-v-4bc9713a]{word-break:break-word;cursor:text;line-height:1.4}.text-strike[data-v-4bc9713a]{opacity:.7;text-decoration:line-through}.task-input[data-v-4bc9713a] .q-field__control{height:22px;min-height:22px;padding:0}.task-input[data-v-4bc9713a] input{color:#e0e0e0;font-size:12px}.task-input[data-v-4bc9713a] input::placeholder{color:#555}.task-add-row[data-v-4bc9713a]{padding:2px 0}.xterm{cursor:text;-webkit-user-select:none;user-select:none;position:relative}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{z-index:5;position:absolute;top:0}.xterm .xterm-helper-textarea{opacity:0;z-index:-5;white-space:nowrap;resize:none;border:0;width:0;height:0;margin:0;padding:0;position:absolute;top:0;left:-9999em;overflow:hidden}.xterm .composition-view{color:#fff;white-space:nowrap;z-index:1;background:#000;display:none;position:absolute}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{cursor:default;background-color:#000;position:absolute;top:0;bottom:0;left:0;right:0;overflow-y:scroll}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm-char-measure-element{visibility:hidden;line-height:normal;display:inline-block;position:absolute;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{z-index:10;color:#0000;pointer-events:none;position:absolute;top:0;bottom:0;left:0;right:0}.xterm .xterm-accessibility-tree:not(.debug) ::-moz-selection{color:#0000}.xterm .xterm-accessibility-tree:not(.debug) ::selection{color:#0000}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre;font-family:monospace}.xterm .xterm-accessibility-tree>div{transform-origin:0;width:-moz-fit-content;width:fit-content}.xterm .live-region{width:1px;height:1px;position:absolute;left:-9999px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{-webkit-text-decoration:underline double;text-decoration:underline double}.xterm-underline-3{-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.xterm-underline-4{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.xterm-underline-5{-webkit-text-decoration:underline dashed;text-decoration:underline dashed}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:underline overline}.xterm-overline.xterm-underline-2{-webkit-text-decoration:overline double underline;-webkit-text-decoration:overline double underline;text-decoration:overline double underline}.xterm-overline.xterm-underline-3{-webkit-text-decoration:overline wavy underline;-webkit-text-decoration:overline wavy underline;text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{-webkit-text-decoration:overline dotted underline;-webkit-text-decoration:overline dotted underline;text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{-webkit-text-decoration:overline dashed underline;-webkit-text-decoration:overline dashed underline;text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;pointer-events:none;position:absolute;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;z-index:11;background:0 0;transition:opacity .1s linear}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{display:none;position:absolute}.xterm .xterm-scrollable-element>.shadow.top{width:100%;height:3px;box-shadow:var(--vscode-scrollbar-shadow,#000) 0 6px 6px -6px inset;display:block;top:0;left:3px}.xterm .xterm-scrollable-element>.shadow.left{width:3px;height:100%;box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset;display:block;top:3px;left:0}.xterm .xterm-scrollable-element>.shadow.top-left-corner{width:3px;height:3px;display:block;top:0;left:0}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow,#000) 6px 0 6px -6px inset}.log-content[data-v-d988f9ab]{max-height:60vh;overflow-y:auto}.log-text[data-v-d988f9ab]{color:#ccc;white-space:pre-wrap;word-break:break-all;background:#0d0d1a;margin:0;font-family:JetBrains Mono,Fira Code,monospace;font-size:11px}.dd-panel[data-v-9d25d6ee],.tools-panel[data-v-88a83f94]{min-height:48px}.auto-loop-spin[data-v-5bfef979]{animation:2s linear infinite auto-loop-spin-5bfef979}@keyframes auto-loop-spin-5bfef979{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.workspace-list[data-v-45541376]{background-color:#16162a;overflow-x:hidden}.wl-search[data-v-45541376]{background-color:#224;padding:0 8px}.wl-search[data-v-45541376] .q-field__control{height:32px}.wl-search[data-v-45541376] input{color:#ccc;font-size:12px}.wl-group-header[data-v-45541376]:hover{background-color:#ffffff08}.wl-project-group+.wl-project-group[data-v-45541376]{margin-top:6px}.wl-project-label[data-v-45541376]{align-items:center;padding-bottom:2px;font-size:11px;display:flex}.wl-item[data-v-45541376]{background-color:#224;margin-bottom:4px;transition:background-color .15s,box-shadow .15s;position:relative}.wl-item[data-v-45541376]:last-child{margin-bottom:0}.wl-item[data-v-45541376]:hover{background-color:#2a2a4a}.wl-item--selected[data-v-45541376]{background-color:#393969;outline:1.5px solid #6c63fff2;box-shadow:0 0 0 1px #6c63ff4d,0 2px 8px #6c63ff40}.wl-item--selected[data-v-45541376]:hover{background-color:#41417a}.wl-item--selected .wl-item-name[data-v-45541376]{color:#fff!important;opacity:1!important}.wl-item-action[data-v-45541376]{position:absolute;top:4px;right:4px}.wl-item--archived .wl-item-action[data-v-45541376]{opacity:0;transition:opacity .15s}.wl-item--archived:hover .wl-item-action[data-v-45541376]{opacity:1}.wl-item-unarchive[data-v-45541376]{right:28px}.wl-item-delete[data-v-45541376]{right:4px}.wl-item--archived[data-v-45541376]{opacity:.6;background-color:#1a1a30}.wl-item--archived[data-v-45541376]:hover{opacity:.85}.wl-item--archived.wl-item--selected[data-v-45541376]{opacity:1}.dd-dot[data-v-45541376]{border-radius:50%;flex-shrink:0;width:6px;height:6px}.dd-dot--running[data-v-45541376]{background-color:#22c55e;box-shadow:0 0 4px #22c55e80}.bg-dark[data-v-e27e1c92]{background-color:#16162a!important;border-color:#2a2a4a!important}.resize-handle[data-v-e27e1c92]{cursor:col-resize;z-index:10;width:4px;height:100%;transition:background-color .15s;position:absolute;top:0;right:-2px}.resize-handle[data-v-e27e1c92]:hover,.resize-handle[data-v-e27e1c92]:active{background-color:#6c63ff80}.resize-handle--right[data-v-e27e1c92]{left:-2px;right:auto}.vertical-resize-handle[data-v-e27e1c92]{cursor:row-resize;background-color:#2a2a4a;height:4px;transition:background-color .15s}.vertical-resize-handle[data-v-e27e1c92]:hover,.vertical-resize-handle[data-v-e27e1c92]:active{background-color:#6c63ff80}