@loicngr/kobo 1.6.0 → 1.6.1
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.
- package/AGENTS.md +6 -1
- package/README.md +29 -16
- package/dist/server/db/index.js +17 -0
- package/dist/server/db/migrations.js +10 -0
- package/dist/server/db/schema.js +2 -1
- package/dist/server/index.js +24 -3
- package/dist/server/middleware/migration-guard.js +15 -0
- package/dist/server/routes/dev-server.js +3 -2
- package/dist/server/routes/engines.js +9 -0
- package/dist/server/routes/migration.js +5 -0
- package/dist/server/routes/workspaces.js +35 -11
- package/dist/server/services/agent/engines/claude-code/args-builder.js +22 -0
- package/dist/server/services/agent/engines/claude-code/capabilities.js +17 -0
- package/dist/server/services/agent/engines/claude-code/engine.js +163 -0
- package/dist/server/services/agent/engines/claude-code/mcp-config.js +23 -0
- package/dist/server/services/agent/engines/claude-code/stream-parser.js +224 -0
- package/dist/server/services/agent/engines/registry.js +21 -0
- package/dist/server/services/agent/engines/types.js +18 -0
- package/dist/server/services/agent/event-router.js +4 -0
- package/dist/server/services/agent/orchestrator.js +582 -0
- package/dist/server/services/agent/session-controller.js +79 -0
- package/dist/server/services/content-migration-service.js +155 -0
- package/dist/server/services/db-backup-service.js +15 -0
- package/dist/server/services/websocket-service.js +81 -50
- package/dist/server/services/workspace-service.js +11 -5
- package/dist/server/utils/paths.js +1 -1
- package/dist/shared/models.js +50 -0
- package/package.json +1 -1
- package/src/client/dist/spa/assets/ActivityFeed-DYtAK49y.js +7 -0
- package/src/client/dist/spa/assets/ActivityFeed-DiwnrdKX.css +1 -0
- package/src/client/dist/spa/assets/ClosePopup-DqhgFbQo.js +1 -0
- package/src/client/dist/spa/assets/CreatePage-DENfwzPL.js +2 -0
- package/src/client/dist/spa/assets/CreatePage-yu2IH7GW.css +1 -0
- package/src/client/dist/spa/assets/DiffViewer-C6q11kmw.js +2 -0
- package/src/client/dist/spa/assets/HealthPage-Cjc79NaA.js +1 -0
- package/src/client/dist/spa/assets/{MainLayout-_oPM07ln.js → MainLayout-CFbMw65L.js} +17 -17
- package/src/client/dist/spa/assets/QBadge-BUkmTO0P.js +1 -0
- package/src/client/dist/spa/assets/QBtn-p1aZtrJH.js +1 -0
- package/src/client/dist/spa/assets/QDialog-D42GLa1i.js +1 -0
- package/src/client/dist/spa/assets/QExpansionItem-5ekmpO-2.js +1 -0
- package/src/client/dist/spa/assets/{QSpinner-CliSLjf8.js → QIcon-B0-pH3Qs.js} +1 -1
- package/src/client/dist/spa/assets/QItemLabel-Czw5g0px.js +1 -0
- package/src/client/dist/spa/assets/QItemSection-GlMrLmz3.js +1 -0
- package/src/client/dist/spa/assets/QList-DNzlynsS.js +1 -0
- package/src/client/dist/spa/assets/QMenu-Q69oVX7b.js +1 -0
- package/src/client/dist/spa/assets/QPage-B09NY4Nf.js +1 -0
- package/src/client/dist/spa/assets/QScrollArea-L6wUiA20.js +1 -0
- package/src/client/dist/spa/assets/QSeparator-rkjCbX2M.js +1 -0
- package/src/client/dist/spa/assets/QSpace-PlDK6Fg3.js +1 -0
- package/src/client/dist/spa/assets/QSpinnerDots-By20ptst.js +1 -0
- package/src/client/dist/spa/assets/QTabPanels-Crs-ujNO.js +1 -0
- package/src/client/dist/spa/assets/QTooltip-Cg9E3Dvw.js +1 -0
- package/src/client/dist/spa/assets/SearchPage-Bf-iZnyE.js +1 -0
- package/src/client/dist/spa/assets/SettingsPage-BdcH3BSs.js +1 -0
- package/src/client/dist/spa/assets/TouchPan-DFx22dM3.js +1 -0
- package/src/client/dist/spa/assets/WorkspacePage-DPGiH02q.css +1 -0
- package/src/client/dist/spa/assets/WorkspacePage-UUE0pPCR.js +4 -0
- package/src/client/dist/spa/assets/{cssMode-DMX8jq8u.js → cssMode-BYtqFZtm.js} +1 -1
- package/src/client/dist/spa/assets/{editor.api-DirOkGGg.js → editor.api-D6ZaO4A_.js} +1 -1
- package/src/client/dist/spa/assets/{editor.main-DC4ezIu0.js → editor.main-Cc_RDKsq.js} +3 -3
- package/src/client/dist/spa/assets/format-uvONOeL4.js +1 -0
- package/src/client/dist/spa/assets/{formatters-BzaS4w0I.js → formatters-DiJ12fKd.js} +1 -1
- package/src/client/dist/spa/assets/{freemarker2-DI9xJfj0.js → freemarker2-CBm--bBd.js} +1 -1
- package/src/client/dist/spa/assets/{handlebars-B9F-pScn.js → handlebars-whX2mkV5.js} +1 -1
- package/src/client/dist/spa/assets/{html-DTe2v8Q8.js → html-D7ga_o6c.js} +1 -1
- package/src/client/dist/spa/assets/{htmlMode-F_XLjWfJ.js → htmlMode-BXImjcsv.js} +1 -1
- package/src/client/dist/spa/assets/i18n-BxLBrD1J.js +1 -0
- package/src/client/dist/spa/assets/index-D997aY4Y.js +2 -0
- package/src/client/dist/spa/assets/{javascript-B9xJRPC6.js → javascript-BwmzNMn5.js} +1 -1
- package/src/client/dist/spa/assets/{jsonMode-DTZ6j6UO.js → jsonMode-CN5Z5bK_.js} +1 -1
- package/src/client/dist/spa/assets/{liquid-BjU5MtW6.js → liquid-CzMNAPor.js} +1 -1
- package/src/client/dist/spa/assets/{marked.esm-DCmk6NO8.js → marked.esm-DW0ulF0a.js} +1 -1
- package/src/client/dist/spa/assets/{mdx-BMUpG7Be.js → mdx-DC_P05Da.js} +1 -1
- package/src/client/dist/spa/assets/models-DMQoi09X.js +1 -0
- package/src/client/dist/spa/assets/{monaco.contribution-D7JUf8DP.js → monaco.contribution-BsBaFOOD.js} +2 -2
- package/src/client/dist/spa/assets/private.use-form-D1RuEt2P.js +1 -0
- package/src/client/dist/spa/assets/{python-Dz0D4uSk.js → python-9DTZ8C3K.js} +1 -1
- package/src/client/dist/spa/assets/{razor-D7CFxuwR.js → razor-B1LfM20o.js} +1 -1
- package/src/client/dist/spa/assets/scroll-Dh2g7BwR.js +1 -0
- package/src/client/dist/spa/assets/touch-D_A29lik.js +1 -0
- package/src/client/dist/spa/assets/{tsMode-DjscaxpS.js → tsMode-DI2bWo8r.js} +1 -1
- package/src/client/dist/spa/assets/{typescript-DozCWZl2.js → typescript-BZ9QJ2_N.js} +1 -1
- package/src/client/dist/spa/assets/use-id-CeduaJbU.js +1 -0
- package/src/client/dist/spa/assets/use-portal-mhLq4Rqk.js +1 -0
- package/src/client/dist/spa/assets/use-quasar-BBrzedjR.js +1 -0
- package/src/client/dist/spa/assets/{xml-DFOJMT39.js → xml-D6qm6rp0.js} +1 -1
- package/src/client/dist/spa/assets/{yaml-yEefnsXm.js → yaml-D2dUr_wY.js} +1 -1
- package/src/client/dist/spa/index.html +11 -14
- package/src/mcp-server/README.md +1 -1
- package/dist/server/services/agent-manager.js +0 -621
- package/src/client/dist/spa/assets/ActivityFeed-0GR1zPoc.js +0 -10
- package/src/client/dist/spa/assets/ActivityFeed-CfsKExt9.css +0 -1
- package/src/client/dist/spa/assets/ClosePopup-CdSn7HO8.js +0 -1
- package/src/client/dist/spa/assets/CreatePage-dMi4xVYN.css +0 -1
- package/src/client/dist/spa/assets/CreatePage-je_7dC5I.js +0 -2
- package/src/client/dist/spa/assets/DiffViewer-DREYX-8k.js +0 -2
- package/src/client/dist/spa/assets/HealthPage-Do8QZdxw.js +0 -1
- package/src/client/dist/spa/assets/QBadge-Bvh-hQ8K.js +0 -1
- package/src/client/dist/spa/assets/QBtn-BsD8vrWq.js +0 -1
- package/src/client/dist/spa/assets/QDialog-CkbLS1If.js +0 -1
- package/src/client/dist/spa/assets/QExpansionItem-UgkE560c.js +0 -1
- package/src/client/dist/spa/assets/QList-D80ms7bw.js +0 -1
- package/src/client/dist/spa/assets/QMenu-DU-wiY_A.js +0 -1
- package/src/client/dist/spa/assets/QPage-BKY2-sf-.js +0 -1
- package/src/client/dist/spa/assets/QSpace-C5Ebr0vq.js +0 -1
- package/src/client/dist/spa/assets/QSpinnerDots-Dp12eHrB.js +0 -1
- package/src/client/dist/spa/assets/QTabPanels-C7lWp1yU.js +0 -1
- package/src/client/dist/spa/assets/QToggle-B0HvuNEg.js +0 -1
- package/src/client/dist/spa/assets/QTooltip-kLXuUa_m.js +0 -1
- package/src/client/dist/spa/assets/SearchPage-CCfyqBKh.js +0 -1
- package/src/client/dist/spa/assets/SettingsPage-CmyIsV-S.js +0 -1
- package/src/client/dist/spa/assets/TouchPan-CVMnGs0y.js +0 -1
- package/src/client/dist/spa/assets/WorkspacePage-CWRMLYs-.css +0 -1
- package/src/client/dist/spa/assets/WorkspacePage-Cl7YrG51.js +0 -4
- package/src/client/dist/spa/assets/focus-manager-DYbz9jFW.js +0 -1
- package/src/client/dist/spa/assets/format-Cyg8IgRi.js +0 -1
- package/src/client/dist/spa/assets/i18n-B13zBh1H.js +0 -1
- package/src/client/dist/spa/assets/i18n-CCWLBc0p.js +0 -1
- package/src/client/dist/spa/assets/index-DoNZ_5QK.js +0 -5
- package/src/client/dist/spa/assets/models-B8fzv7K4.js +0 -1
- package/src/client/dist/spa/assets/pinia-C3JsrLkB.js +0 -1
- package/src/client/dist/spa/assets/private.use-form-BhKyDtO7.js +0 -1
- package/src/client/dist/spa/assets/scroll-CLibRGI-.js +0 -1
- package/src/client/dist/spa/assets/settings-B69lIVX0.js +0 -1
- package/src/client/dist/spa/assets/touch-ChrvzrnI.js +0 -1
- package/src/client/dist/spa/assets/use-dark-DnuCB6tC.js +0 -1
- package/src/client/dist/spa/assets/use-quasar-DBoizHBW.js +0 -1
- /package/src/client/dist/spa/assets/{_plugin-vue_export-helper-Cxt1D8wE.js → _plugin-vue_export-helper-CEhRWsKN.js} +0 -0
- /package/src/client/dist/spa/assets/{abap-CFuyUYKP.js → abap-DiwvWnMr.js} +0 -0
- /package/src/client/dist/spa/assets/{apex-Ctq_xcrv.js → apex-CmtZjKlf.js} +0 -0
- /package/src/client/dist/spa/assets/{azcli-BBQSVn-C.js → azcli-DL2My_i-.js} +0 -0
- /package/src/client/dist/spa/assets/{bat-DbnqAfvr.js → bat-B-nC98wG.js} +0 -0
- /package/src/client/dist/spa/assets/{bicep-BtDlIXop.js → bicep-Ju5MwOgh.js} +0 -0
- /package/src/client/dist/spa/assets/{cameligo-BLeJgKTj.js → cameligo-8Eu1TyBr.js} +0 -0
- /package/src/client/dist/spa/assets/{clojure-aZUQIUKP.js → clojure-u-RpMkH3.js} +0 -0
- /package/src/client/dist/spa/assets/{coffee-Secadq9U.js → coffee-CdA7bbTe.js} +0 -0
- /package/src/client/dist/spa/assets/{cpp-JicRPTRv.js → cpp-CzNFP8ks.js} +0 -0
- /package/src/client/dist/spa/assets/{csharp-C7NSOZyj.js → csharp-j1LThmcE.js} +0 -0
- /package/src/client/dist/spa/assets/{csp-CIje7830.js → csp-CLRC61y6.js} +0 -0
- /package/src/client/dist/spa/assets/{css-G0bm1q_M.js → css-r6rC_7P2.js} +0 -0
- /package/src/client/dist/spa/assets/{cypher-CldD5D0u.js → cypher-CW08XVUh.js} +0 -0
- /package/src/client/dist/spa/assets/{dart-DIK3l8YT.js → dart-Cs9aL5T_.js} +0 -0
- /package/src/client/dist/spa/assets/{dockerfile-czxaGh2L.js → dockerfile-BWM0M184.js} +0 -0
- /package/src/client/dist/spa/assets/{ecl-BqdYhwmw.js → ecl-MJJuer5P.js} +0 -0
- /package/src/client/dist/spa/assets/{elixir-m52LePTW.js → elixir-D2AIuXqn.js} +0 -0
- /package/src/client/dist/spa/assets/{flow9-B5QJ9GvZ.js → flow9-B2H24giC.js} +0 -0
- /package/src/client/dist/spa/assets/{fsharp-B15czHsH.js → fsharp-CMk2OIJN.js} +0 -0
- /package/src/client/dist/spa/assets/{go-BkoQxDo1.js → go-BrMkuJg0.js} +0 -0
- /package/src/client/dist/spa/assets/{graphql-BnI6uRa_.js → graphql-PSR1UKGv.js} +0 -0
- /package/src/client/dist/spa/assets/{hcl-CAwwENT7.js → hcl-DAQrbDOW.js} +0 -0
- /package/src/client/dist/spa/assets/{ini-BHM5zh1H.js → ini-0TG5BxW0.js} +0 -0
- /package/src/client/dist/spa/assets/{java-B5i95QvQ.js → java-rgorz17v.js} +0 -0
- /package/src/client/dist/spa/assets/{julia-DPDm885q.js → julia-C8VMdHm8.js} +0 -0
- /package/src/client/dist/spa/assets/{kotlin-qoccd5BP.js → kotlin-CllWo3gX.js} +0 -0
- /package/src/client/dist/spa/assets/{less-B6RU166D.js → less-Cgca25AP.js} +0 -0
- /package/src/client/dist/spa/assets/{lexon-YfUeoL1V.js → lexon-D0GHdBaw.js} +0 -0
- /package/src/client/dist/spa/assets/{lua-BIUI5y9b.js → lua-DmRsNG-P.js} +0 -0
- /package/src/client/dist/spa/assets/{m3-D5SAbSdU.js → m3-BgL5dNKT.js} +0 -0
- /package/src/client/dist/spa/assets/{markdown-CVJLwHzJ.js → markdown-BuJfycGS.js} +0 -0
- /package/src/client/dist/spa/assets/{mips-R-FZ3zOR.js → mips-C9m_93PR.js} +0 -0
- /package/src/client/dist/spa/assets/{msdax-Blveyl9r.js → msdax-CpFHC9OI.js} +0 -0
- /package/src/client/dist/spa/assets/{mysql-D4mY1AFx.js → mysql-qFvltsqN.js} +0 -0
- /package/src/client/dist/spa/assets/{objective-c-BmXrLr4h.js → objective-c-Bnmr858J.js} +0 -0
- /package/src/client/dist/spa/assets/{pascal-yxckoyvV.js → pascal-WP0_D5AO.js} +0 -0
- /package/src/client/dist/spa/assets/{pascaligo-Q5JCwXMI.js → pascaligo-Blom4Rij.js} +0 -0
- /package/src/client/dist/spa/assets/{perl-BF1Rrs5h.js → perl-B-vk8g64.js} +0 -0
- /package/src/client/dist/spa/assets/{pgsql-CnYB97wm.js → pgsql-Cgvz6v67.js} +0 -0
- /package/src/client/dist/spa/assets/{php-CdDfQfSg.js → php-8a3Lrw9m.js} +0 -0
- /package/src/client/dist/spa/assets/{pla-whj-d71F.js → pla-DuFqEZ8V.js} +0 -0
- /package/src/client/dist/spa/assets/{postiats-ClfLr4I-.js → postiats-DkLtSgkp.js} +0 -0
- /package/src/client/dist/spa/assets/{powerquery-iRaBhuuk.js → powerquery-BJ1aNepW.js} +0 -0
- /package/src/client/dist/spa/assets/{powershell-DjiEt5xK.js → powershell-rE98k687.js} +0 -0
- /package/src/client/dist/spa/assets/{protobuf-B6dcIEUr.js → protobuf-CUheFacr.js} +0 -0
- /package/src/client/dist/spa/assets/{pug-DtmHnjM9.js → pug-LDcAMD8w.js} +0 -0
- /package/src/client/dist/spa/assets/{qsharp-CELCyd79.js → qsharp-DUKSQoR1.js} +0 -0
- /package/src/client/dist/spa/assets/{r-ZpJXWV-o.js → r-D-QApv87.js} +0 -0
- /package/src/client/dist/spa/assets/{rate-limit-labels-dCPVjS61.js → rate-limit-labels-BvYERsho.js} +0 -0
- /package/src/client/dist/spa/assets/{redis-BiHSNkAl.js → redis-SXdDyWR9.js} +0 -0
- /package/src/client/dist/spa/assets/{redshift-DzuwYCHP.js → redshift-Y6lsCryn.js} +0 -0
- /package/src/client/dist/spa/assets/{restructuredtext-YOT94bbS.js → restructuredtext-edObr9a8.js} +0 -0
- /package/src/client/dist/spa/assets/{ruby-BfiHr6Uu.js → ruby-CNnUfF-8.js} +0 -0
- /package/src/client/dist/spa/assets/{rust-JZ-uOoYM.js → rust-IHUZWzBr.js} +0 -0
- /package/src/client/dist/spa/assets/{sb-CBglP1-t.js → sb-DrUvY44N.js} +0 -0
- /package/src/client/dist/spa/assets/{scala-C9l41paw.js → scala-B4hbXGLM.js} +0 -0
- /package/src/client/dist/spa/assets/{scheme-B-InQ6hy.js → scheme-BGrd12j3.js} +0 -0
- /package/src/client/dist/spa/assets/{scss-v6OmJRN9.js → scss-x5G1ES4U.js} +0 -0
- /package/src/client/dist/spa/assets/{shell-Dyp6iwB6.js → shell-DOehe2Y8.js} +0 -0
- /package/src/client/dist/spa/assets/{solidity-D5epNWue.js → solidity-BeRvcwWV.js} +0 -0
- /package/src/client/dist/spa/assets/{sophia-Eva-79sB.js → sophia-DZbkUNjy.js} +0 -0
- /package/src/client/dist/spa/assets/{sparql-gvALLO1w.js → sparql-B7_oi5-h.js} +0 -0
- /package/src/client/dist/spa/assets/{sql-COdamZYI.js → sql-CTlsFWVE.js} +0 -0
- /package/src/client/dist/spa/assets/{st-eMoImIwE.js → st-DJVEJdPE.js} +0 -0
- /package/src/client/dist/spa/assets/{swift-7R_T9RYH.js → swift-CwhT3fYa.js} +0 -0
- /package/src/client/dist/spa/assets/{symbols-CAg-nBkV.js → symbols-DCYodwb2.js} +0 -0
- /package/src/client/dist/spa/assets/{systemverilog-1pCEfaHU.js → systemverilog-BQN63pkN.js} +0 -0
- /package/src/client/dist/spa/assets/{tcl-B_KgnhfE.js → tcl-DqwfpskA.js} +0 -0
- /package/src/client/dist/spa/assets/{twig-CFZUJxb9.js → twig-BiyenUgc.js} +0 -0
- /package/src/client/dist/spa/assets/{typespec-B1ZgHlud.js → typespec-CWOJribt.js} +0 -0
- /package/src/client/dist/spa/assets/{vb-DKdun5tL.js → vb-Cq5F87m3.js} +0 -0
- /package/src/client/dist/spa/assets/{vue-i18n-eUDnMrPl.js → vue-i18n-CeG0hR0Z.js} +0 -0
- /package/src/client/dist/spa/assets/{wgsl-CzNaxTrn.js → wgsl-BAvW2lVr.js} +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
2
|
+
import { createParserState, parseClaudeLine } from './agent/engines/claude-code/stream-parser.js';
|
|
3
|
+
import { createPreMigrationBackup } from './db-backup-service.js';
|
|
4
|
+
import { broadcastAll } from './websocket-service.js';
|
|
5
|
+
const internal = { state: 'idle', total: 0, processed: 0 };
|
|
6
|
+
let isRunning = false;
|
|
7
|
+
function snapshot() {
|
|
8
|
+
switch (internal.state) {
|
|
9
|
+
case 'idle':
|
|
10
|
+
return { state: 'idle' };
|
|
11
|
+
case 'backing-up':
|
|
12
|
+
return { state: 'backing-up', startedAt: internal.startedAt ?? new Date(0).toISOString() };
|
|
13
|
+
case 'running':
|
|
14
|
+
return {
|
|
15
|
+
state: 'running',
|
|
16
|
+
total: internal.total,
|
|
17
|
+
processed: internal.processed,
|
|
18
|
+
startedAt: internal.startedAt ?? new Date(0).toISOString(),
|
|
19
|
+
...(internal.backupPath !== undefined ? { backupPath: internal.backupPath } : {}),
|
|
20
|
+
};
|
|
21
|
+
case 'done':
|
|
22
|
+
return {
|
|
23
|
+
state: 'done',
|
|
24
|
+
total: internal.total,
|
|
25
|
+
processed: internal.processed,
|
|
26
|
+
startedAt: internal.startedAt ?? new Date(0).toISOString(),
|
|
27
|
+
finishedAt: internal.finishedAt ?? new Date(0).toISOString(),
|
|
28
|
+
...(internal.backupPath !== undefined ? { backupPath: internal.backupPath } : {}),
|
|
29
|
+
};
|
|
30
|
+
case 'error':
|
|
31
|
+
return {
|
|
32
|
+
state: 'error',
|
|
33
|
+
errorMessage: internal.errorMessage ?? 'Unknown error',
|
|
34
|
+
...(internal.startedAt !== undefined ? { startedAt: internal.startedAt } : {}),
|
|
35
|
+
...(internal.backupPath !== undefined ? { backupPath: internal.backupPath } : {}),
|
|
36
|
+
...(internal.total > 0 ? { total: internal.total } : {}),
|
|
37
|
+
...(internal.processed > 0 ? { processed: internal.processed } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function getContentMigrationStatus() {
|
|
42
|
+
return snapshot();
|
|
43
|
+
}
|
|
44
|
+
export async function runContentMigrationIfNeeded(db, dbPath) {
|
|
45
|
+
if (isRunning)
|
|
46
|
+
return;
|
|
47
|
+
isRunning = true;
|
|
48
|
+
try {
|
|
49
|
+
const row = db
|
|
50
|
+
.prepare("SELECT COUNT(*) AS c FROM ws_events WHERE type IN ('agent:output', 'agent:stderr', 'agent:status')")
|
|
51
|
+
.get();
|
|
52
|
+
if (row.c === 0) {
|
|
53
|
+
internal.state = 'idle';
|
|
54
|
+
isRunning = false;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
internal.state = 'backing-up';
|
|
58
|
+
internal.startedAt = new Date().toISOString();
|
|
59
|
+
broadcastStatus();
|
|
60
|
+
const backup = await createPreMigrationBackup(db, dbPath, 'v10');
|
|
61
|
+
internal.backupPath = backup.created ?? undefined;
|
|
62
|
+
internal.state = 'running';
|
|
63
|
+
internal.total = row.c;
|
|
64
|
+
internal.processed = 0;
|
|
65
|
+
broadcastStatus();
|
|
66
|
+
await processLoop(db);
|
|
67
|
+
internal.state = 'done';
|
|
68
|
+
internal.finishedAt = new Date().toISOString();
|
|
69
|
+
broadcastStatus();
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
internal.state = 'error';
|
|
73
|
+
internal.errorMessage = err instanceof Error ? err.message : String(err);
|
|
74
|
+
broadcastStatus();
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
isRunning = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function broadcastStatus() {
|
|
82
|
+
// Content-migration events are global (no workspace context) — use broadcastAll so every
|
|
83
|
+
// connected WS client receives them regardless of their workspace subscriptions.
|
|
84
|
+
broadcastAll(internal.state === 'error' ? 'migration:error' : 'migration:progress', getContentMigrationStatus());
|
|
85
|
+
}
|
|
86
|
+
async function processLoop(db) {
|
|
87
|
+
const batchSize = 500;
|
|
88
|
+
const selectStmt = db.prepare("SELECT id, workspace_id, type, payload, session_id, created_at FROM ws_events WHERE type IN ('agent:output', 'agent:stderr', 'agent:status') ORDER BY created_at ASC LIMIT ?");
|
|
89
|
+
const insertStmt = db.prepare('INSERT INTO ws_events (id, workspace_id, type, payload, session_id, created_at) VALUES (?, ?, ?, ?, ?, ?)');
|
|
90
|
+
const deleteStmt = db.prepare('DELETE FROM ws_events WHERE id = ?');
|
|
91
|
+
while (true) {
|
|
92
|
+
const rows = selectStmt.all(batchSize);
|
|
93
|
+
if (rows.length === 0)
|
|
94
|
+
break;
|
|
95
|
+
db.transaction(() => {
|
|
96
|
+
for (const r of rows) {
|
|
97
|
+
const events = convertRow(r.type, r.payload, { workspaceId: r.workspace_id });
|
|
98
|
+
for (const ev of events) {
|
|
99
|
+
insertStmt.run(nanoid(), r.workspace_id, 'agent:event', JSON.stringify(ev), r.session_id, r.created_at);
|
|
100
|
+
}
|
|
101
|
+
deleteStmt.run(r.id);
|
|
102
|
+
}
|
|
103
|
+
})();
|
|
104
|
+
internal.processed += rows.length;
|
|
105
|
+
broadcastStatus();
|
|
106
|
+
// Yield to the event loop
|
|
107
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function convertRow(type, payload, context) {
|
|
111
|
+
if (type === 'agent:status')
|
|
112
|
+
return []; // redundant — re-derivable from session events
|
|
113
|
+
if (type === 'agent:stderr') {
|
|
114
|
+
// Drop: the new engine only logs non-quota stderr via console.warn and
|
|
115
|
+
// does not persist it. Converting legacy stderr rows to error events
|
|
116
|
+
// would surface every historical Claude CLI warning ("no stdin data in
|
|
117
|
+
// 3s…", debug lines) as a UI-blocking banner. Quota-bearing stderr is
|
|
118
|
+
// handled live by the engine's backoff path, not via replay.
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
if (type === 'agent:output') {
|
|
122
|
+
try {
|
|
123
|
+
const parsed = JSON.parse(payload);
|
|
124
|
+
// The legacy payload may be either the raw Claude NDJSON already-parsed object,
|
|
125
|
+
// or a wrapper { type: 'raw', content: '...' } for non-JSON output. Handle both.
|
|
126
|
+
if (parsed && typeof parsed === 'object' && parsed.type === 'raw') {
|
|
127
|
+
return [{ kind: 'message:raw', content: String(parsed.content ?? '') }];
|
|
128
|
+
}
|
|
129
|
+
const state = createParserState();
|
|
130
|
+
const { events } = parseClaudeLine(JSON.stringify(parsed), state);
|
|
131
|
+
return events;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Log enough to debug (first 200 chars of the bad payload + the owning
|
|
135
|
+
// workspace id when the caller passed one). We intentionally do not log
|
|
136
|
+
// the full payload to keep the console readable on noisy migrations.
|
|
137
|
+
const preview = payload.length > 200 ? `${payload.slice(0, 200)}…` : payload;
|
|
138
|
+
const ctx = context?.workspaceId ? ` (workspace=${context.workspaceId})` : '';
|
|
139
|
+
console.warn(`[content-migration] Could not parse agent:output payload${ctx}, falling back to message:raw. Preview: ${preview}`);
|
|
140
|
+
return [{ kind: 'message:raw', content: payload }];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
/** Test-only. */
|
|
146
|
+
export function _resetStatusForTest() {
|
|
147
|
+
internal.state = 'idle';
|
|
148
|
+
internal.total = 0;
|
|
149
|
+
internal.processed = 0;
|
|
150
|
+
internal.errorMessage = undefined;
|
|
151
|
+
internal.startedAt = undefined;
|
|
152
|
+
internal.finishedAt = undefined;
|
|
153
|
+
internal.backupPath = undefined;
|
|
154
|
+
isRunning = false;
|
|
155
|
+
}
|
|
@@ -64,3 +64,18 @@ export async function createDailyDbBackupIfNeeded(db, dbPath, keepCount = DEFAUL
|
|
|
64
64
|
}
|
|
65
65
|
return result;
|
|
66
66
|
}
|
|
67
|
+
const PREMIGRATION_PREFIX = 'kobo.db.premigration-';
|
|
68
|
+
export async function createPreMigrationBackup(db, dbPath, tag) {
|
|
69
|
+
const dir = path.dirname(dbPath);
|
|
70
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
71
|
+
backupSequence += 1;
|
|
72
|
+
const backupPath = path.join(dir, `${PREMIGRATION_PREFIX}${tag}-${stamp}-${backupSequence}`);
|
|
73
|
+
try {
|
|
74
|
+
await db.backup(backupPath);
|
|
75
|
+
return { created: backupPath, deleted: [] };
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.error('[kobo] Pre-migration backup failed:', err);
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -3,9 +3,6 @@ import { getDb } from '../db/index.js';
|
|
|
3
3
|
// ── State ──────────────────────────────────────────────────────────────────────
|
|
4
4
|
/** Maps each WS client to the set of workspaceIds they are subscribed to */
|
|
5
5
|
const clients = new Map();
|
|
6
|
-
/** Per-workspace emit counter for periodic cleanup. */
|
|
7
|
-
const emitCounters = new Map();
|
|
8
|
-
const EMIT_CLEANUP_THRESHOLD = 2000;
|
|
9
6
|
let messageHandler = null;
|
|
10
7
|
/** Register the handler that processes routed WS messages (e.g. chat:message, workspace:start). */
|
|
11
8
|
export function setMessageHandler(handler) {
|
|
@@ -56,7 +53,7 @@ export function handleConnection(ws) {
|
|
|
56
53
|
handleSyncRequest(ws, lastEventId, workspaceIds);
|
|
57
54
|
break;
|
|
58
55
|
}
|
|
59
|
-
// Routed messages — delegated to
|
|
56
|
+
// Routed messages — delegated to the orchestrator via messageHandler
|
|
60
57
|
case 'chat:message':
|
|
61
58
|
case 'workspace:start':
|
|
62
59
|
case 'workspace:stop':
|
|
@@ -102,15 +99,6 @@ export function emit(workspaceId, type, payload, sessionId) {
|
|
|
102
99
|
try {
|
|
103
100
|
const db = getDb();
|
|
104
101
|
db.prepare('INSERT INTO ws_events (id, workspace_id, type, payload, session_id, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(id, workspaceId, type, JSON.stringify(payload), sessionId ?? null, createdAt);
|
|
105
|
-
// Periodic cleanup — trigger when emit threshold is reached
|
|
106
|
-
const count = (emitCounters.get(workspaceId) ?? 0) + 1;
|
|
107
|
-
if (count >= EMIT_CLEANUP_THRESHOLD) {
|
|
108
|
-
cleanupOldEvents(workspaceId);
|
|
109
|
-
emitCounters.set(workspaceId, 0);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
emitCounters.set(workspaceId, count);
|
|
113
|
-
}
|
|
114
102
|
}
|
|
115
103
|
catch (err) {
|
|
116
104
|
console.error(`[websocket-service] Failed to persist event (workspace=${workspaceId}, type=${type}):`, err);
|
|
@@ -118,10 +106,20 @@ export function emit(workspaceId, type, payload, sessionId) {
|
|
|
118
106
|
// Build the event object to send
|
|
119
107
|
const event = { id, workspaceId, type, payload, sessionId, createdAt };
|
|
120
108
|
const message = JSON.stringify(event);
|
|
121
|
-
// Broadcast to subscribed clients
|
|
109
|
+
// Broadcast to subscribed clients. Wrap `.send` in try/catch so a dropped
|
|
110
|
+
// client doesn't throw and abort delivery to the remaining subscribers.
|
|
111
|
+
let emitSendErrorLogged = false;
|
|
122
112
|
for (const [ws, subs] of clients) {
|
|
123
113
|
if (subs.has(workspaceId) && ws.readyState === 1 /* WebSocket.OPEN */) {
|
|
124
|
-
|
|
114
|
+
try {
|
|
115
|
+
ws.send(message);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (!emitSendErrorLogged) {
|
|
119
|
+
console.warn(`[ws] emit send failed (workspace=${workspaceId}, type=${type}):`, err);
|
|
120
|
+
emitSendErrorLogged = true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
125
123
|
}
|
|
126
124
|
}
|
|
127
125
|
return id;
|
|
@@ -135,9 +133,18 @@ export function emitEphemeral(workspaceId, type, payload) {
|
|
|
135
133
|
const createdAt = new Date().toISOString();
|
|
136
134
|
const event = { id, workspaceId, type, payload, createdAt };
|
|
137
135
|
const message = JSON.stringify(event);
|
|
136
|
+
let sendErrorLogged = false;
|
|
138
137
|
for (const [ws, subs] of clients) {
|
|
139
138
|
if (subs.has(workspaceId) && ws.readyState === 1 /* WebSocket.OPEN */) {
|
|
140
|
-
|
|
139
|
+
try {
|
|
140
|
+
ws.send(message);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
if (!sendErrorLogged) {
|
|
144
|
+
console.warn(`[ws] emitEphemeral send failed (workspace=${workspaceId}, type=${type}):`, err);
|
|
145
|
+
sendErrorLogged = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
}
|
|
@@ -161,8 +168,16 @@ export function handleSyncRequest(ws, lastEventId, workspaceIds) {
|
|
|
161
168
|
// Build a query with placeholders for all subscribed workspaces
|
|
162
169
|
const placeholders = resolvedIds.map(() => '?').join(', ');
|
|
163
170
|
let rows;
|
|
171
|
+
// Initial window size: on a fresh connection (no lastEventId), we only
|
|
172
|
+
// replay the most recent slice of history. The client fetches older
|
|
173
|
+
// events on-demand via GET /api/workspaces/:id/events as the user scrolls
|
|
174
|
+
// up. This keeps first-paint fast on long-lived workspaces with tens of
|
|
175
|
+
// thousands of events without ever deleting anything from the DB.
|
|
176
|
+
const INITIAL_WINDOW = 300;
|
|
164
177
|
if (lastEventId) {
|
|
165
|
-
//
|
|
178
|
+
// Resume path: replay every event strictly after the cursor (delta
|
|
179
|
+
// since last seen). If the cursor is stale/unknown, fall back to the
|
|
180
|
+
// recent window rather than streaming the entire history.
|
|
166
181
|
const lastRow = db.prepare('SELECT rowid FROM ws_events WHERE id = ?').get(lastEventId);
|
|
167
182
|
if (lastRow) {
|
|
168
183
|
rows = db
|
|
@@ -170,17 +185,18 @@ export function handleSyncRequest(ws, lastEventId, workspaceIds) {
|
|
|
170
185
|
.all(...resolvedIds, lastRow.rowid);
|
|
171
186
|
}
|
|
172
187
|
else {
|
|
173
|
-
// lastEventId not found — send events capped to avoid unbounded memory usage
|
|
174
188
|
rows = db
|
|
175
|
-
.prepare(`SELECT * FROM ws_events WHERE workspace_id IN (${placeholders}) ORDER BY rowid
|
|
176
|
-
.all(...resolvedIds);
|
|
189
|
+
.prepare(`SELECT * FROM ws_events WHERE workspace_id IN (${placeholders}) ORDER BY rowid DESC LIMIT ?`)
|
|
190
|
+
.all(...resolvedIds, INITIAL_WINDOW);
|
|
191
|
+
rows.reverse();
|
|
177
192
|
}
|
|
178
193
|
}
|
|
179
194
|
else {
|
|
180
|
-
//
|
|
195
|
+
// Fresh connect: most recent INITIAL_WINDOW events, in chronological order.
|
|
181
196
|
rows = db
|
|
182
|
-
.prepare(`SELECT * FROM ws_events WHERE workspace_id IN (${placeholders}) ORDER BY rowid
|
|
183
|
-
.all(...resolvedIds);
|
|
197
|
+
.prepare(`SELECT * FROM ws_events WHERE workspace_id IN (${placeholders}) ORDER BY rowid DESC LIMIT ?`)
|
|
198
|
+
.all(...resolvedIds, INITIAL_WINDOW);
|
|
199
|
+
rows.reverse();
|
|
184
200
|
}
|
|
185
201
|
const events = rows.map((row) => {
|
|
186
202
|
let parsedPayload;
|
|
@@ -188,6 +204,11 @@ export function handleSyncRequest(ws, lastEventId, workspaceIds) {
|
|
|
188
204
|
parsedPayload = JSON.parse(row.payload);
|
|
189
205
|
}
|
|
190
206
|
catch {
|
|
207
|
+
console.error('[ws] corrupt ws_events row, falling back to raw:', {
|
|
208
|
+
id: row.id,
|
|
209
|
+
workspace_id: row.workspace_id,
|
|
210
|
+
type: row.type,
|
|
211
|
+
});
|
|
191
212
|
parsedPayload = { raw: row.payload };
|
|
192
213
|
}
|
|
193
214
|
return {
|
|
@@ -200,30 +221,6 @@ export function handleSyncRequest(ws, lastEventId, workspaceIds) {
|
|
|
200
221
|
};
|
|
201
222
|
});
|
|
202
223
|
ws.send(JSON.stringify({ type: 'sync:response', payload: { events } }));
|
|
203
|
-
// Trigger cleanup when the event count is high to prevent unbounded growth
|
|
204
|
-
const CLEANUP_THRESHOLD = 5000;
|
|
205
|
-
if (rows.length >= CLEANUP_THRESHOLD) {
|
|
206
|
-
for (const wid of resolvedIds) {
|
|
207
|
-
cleanupOldEvents(wid);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
// ── Cleanup ────────────────────────────────────────────────────────────────────
|
|
212
|
-
/**
|
|
213
|
-
* Delete old events keeping only the last N (default 1000) per workspace.
|
|
214
|
-
*/
|
|
215
|
-
export function cleanupOldEvents(workspaceId, keepCount = 1000) {
|
|
216
|
-
const db = getDb();
|
|
217
|
-
db.prepare(`
|
|
218
|
-
DELETE FROM ws_events
|
|
219
|
-
WHERE workspace_id = ?
|
|
220
|
-
AND rowid NOT IN (
|
|
221
|
-
SELECT rowid FROM ws_events
|
|
222
|
-
WHERE workspace_id = ?
|
|
223
|
-
ORDER BY rowid DESC
|
|
224
|
-
LIMIT ?
|
|
225
|
-
)
|
|
226
|
-
`).run(workspaceId, workspaceId, keepCount);
|
|
227
224
|
}
|
|
228
225
|
// ── Utilities ──────────────────────────────────────────────────────────────────
|
|
229
226
|
/**
|
|
@@ -239,10 +236,44 @@ export function getClientCount() {
|
|
|
239
236
|
export function _getClients() {
|
|
240
237
|
return clients;
|
|
241
238
|
}
|
|
239
|
+
// ── Global broadcast ───────────────────────────────────────────────────────────
|
|
240
|
+
/**
|
|
241
|
+
* Broadcast an ephemeral event to every connected WebSocket client,
|
|
242
|
+
* regardless of which workspaces they have subscribed to. Used for
|
|
243
|
+
* global events like migration progress.
|
|
244
|
+
*/
|
|
245
|
+
export function broadcastAll(type, payload) {
|
|
246
|
+
const message = JSON.stringify({ type, payload });
|
|
247
|
+
let sendErrorLogged = false;
|
|
248
|
+
for (const client of clients.keys()) {
|
|
249
|
+
if (client.readyState === 1 /* WebSocket.OPEN */) {
|
|
250
|
+
try {
|
|
251
|
+
client.send(message);
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
// client dropped; next iteration will fail its .readyState check.
|
|
255
|
+
// Log the first occurrence so real regressions surface without
|
|
256
|
+
// flooding the console if many clients die at once.
|
|
257
|
+
if (!sendErrorLogged) {
|
|
258
|
+
console.warn('[ws] broadcastAll send failed:', err);
|
|
259
|
+
sendErrorLogged = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
242
265
|
/**
|
|
243
|
-
*
|
|
266
|
+
* Return a mutable set view of connected clients — exposed for testing only.
|
|
267
|
+
* Adding/removing clients via this handle registers/unregisters them with the
|
|
268
|
+
* internal `clients` map so helpers like `broadcastAll` see them.
|
|
244
269
|
* @internal
|
|
245
270
|
*/
|
|
246
|
-
export function
|
|
247
|
-
return
|
|
271
|
+
export function _connectionsForTest() {
|
|
272
|
+
return {
|
|
273
|
+
add: (ws) => {
|
|
274
|
+
if (!clients.has(ws))
|
|
275
|
+
clients.set(ws, new Set());
|
|
276
|
+
},
|
|
277
|
+
delete: (ws) => clients.delete(ws),
|
|
278
|
+
};
|
|
248
279
|
}
|
|
@@ -11,6 +11,11 @@ const VALID_TRANSITIONS = {
|
|
|
11
11
|
error: ['idle', 'executing', 'brainstorming', 'extracting'],
|
|
12
12
|
quota: ['idle', 'executing'],
|
|
13
13
|
};
|
|
14
|
+
// NOTE: `engine` is stored as a plain TEXT column and returned as a `string` on
|
|
15
|
+
// the `Workspace` interface rather than the stricter `EngineId` union. The DB
|
|
16
|
+
// is untyped, so we intentionally do not narrow here — validation against
|
|
17
|
+
// `listEngines()` is expected to happen at workspace creation (see the
|
|
18
|
+
// routes/engines handler) and when resolving an engine at agent-start time.
|
|
14
19
|
function mapWorkspace(row) {
|
|
15
20
|
return {
|
|
16
21
|
id: row.id,
|
|
@@ -29,6 +34,7 @@ function mapWorkspace(row) {
|
|
|
29
34
|
archivedAt: row.archived_at,
|
|
30
35
|
favoritedAt: row.favorited_at,
|
|
31
36
|
tags: parseTags(row.tags),
|
|
37
|
+
engine: row.engine ?? 'claude-code',
|
|
32
38
|
createdAt: row.created_at,
|
|
33
39
|
updatedAt: row.updated_at,
|
|
34
40
|
};
|
|
@@ -65,9 +71,9 @@ export function createWorkspace(data) {
|
|
|
65
71
|
const now = new Date().toISOString();
|
|
66
72
|
const id = nanoid();
|
|
67
73
|
db.prepare(`
|
|
68
|
-
INSERT INTO workspaces (id, name, project_path, source_branch, working_branch, status, notion_url, notion_page_id, model, reasoning_effort, permission_mode, created_at, updated_at)
|
|
69
|
-
VALUES (?, ?, ?, ?, ?, 'created', ?, ?, ?, ?, ?, ?, ?)
|
|
70
|
-
`).run(id, data.name, data.projectPath, data.sourceBranch, data.workingBranch, data.notionUrl ?? null, data.notionPageId ?? null, data.model ?? 'claude-opus-4-7', data.reasoningEffort ?? 'auto', data.permissionMode ?? 'auto-accept', now, now);
|
|
74
|
+
INSERT INTO workspaces (id, name, project_path, source_branch, working_branch, status, notion_url, notion_page_id, model, reasoning_effort, permission_mode, engine, created_at, updated_at)
|
|
75
|
+
VALUES (?, ?, ?, ?, ?, 'created', ?, ?, ?, ?, ?, ?, ?, ?)
|
|
76
|
+
`).run(id, data.name, data.projectPath, data.sourceBranch, data.workingBranch, data.notionUrl ?? null, data.notionPageId ?? null, data.model ?? 'claude-opus-4-7', data.reasoningEffort ?? 'auto', data.permissionMode ?? 'auto-accept', data.engine ?? 'claude-code', now, now);
|
|
71
77
|
return getWorkspace(id);
|
|
72
78
|
}
|
|
73
79
|
/** Fetch a single workspace by ID, or null if not found. */
|
|
@@ -336,7 +342,7 @@ function mapSession(row) {
|
|
|
336
342
|
id: row.id,
|
|
337
343
|
workspaceId: row.workspace_id,
|
|
338
344
|
pid: row.pid,
|
|
339
|
-
|
|
345
|
+
engineSessionId: row.engine_session_id,
|
|
340
346
|
status: row.status,
|
|
341
347
|
startedAt: row.started_at,
|
|
342
348
|
endedAt: row.ended_at,
|
|
@@ -389,7 +395,7 @@ export function createIdleSession(workspaceId) {
|
|
|
389
395
|
id,
|
|
390
396
|
workspaceId,
|
|
391
397
|
pid: null,
|
|
392
|
-
|
|
398
|
+
engineSessionId: null,
|
|
393
399
|
status: 'idle',
|
|
394
400
|
startedAt: now,
|
|
395
401
|
endedAt: null,
|
|
@@ -99,7 +99,7 @@ export function getTemplatesPath() {
|
|
|
99
99
|
/**
|
|
100
100
|
* Absolute path to the compiled MCP server entry (shipped in the published
|
|
101
101
|
* package as dist/mcp-server/kobo-tasks-server.js). Returns null if not
|
|
102
|
-
* present — callers (
|
|
102
|
+
* present — callers (orchestrator) then fall back to the TS source for dev.
|
|
103
103
|
*/
|
|
104
104
|
export function getCompiledMcpServerPath() {
|
|
105
105
|
const compiled = getPackageAssetPath('dist', 'mcp-server', 'kobo-tasks-server.js');
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const CLAUDE_MODELS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'auto',
|
|
4
|
+
label: 'Auto',
|
|
5
|
+
i18nLabelKey: 'model.auto',
|
|
6
|
+
i18nDescriptionKey: 'model.autoDescription',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
id: 'claude-opus-4-7',
|
|
10
|
+
label: 'Opus 4.7 (Classic)',
|
|
11
|
+
i18nLabelKey: 'model.opus47Classic',
|
|
12
|
+
i18nDescriptionKey: 'model.opus47ClassicDescription',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'claude-opus-4-7[1m]',
|
|
16
|
+
label: 'Opus 4.7 (1M)',
|
|
17
|
+
i18nLabelKey: 'model.opus471m',
|
|
18
|
+
i18nDescriptionKey: 'model.opus471mDescription',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'claude-opus-4-6',
|
|
22
|
+
label: 'Opus 4.6 (Classic)',
|
|
23
|
+
i18nLabelKey: 'model.opusClassic',
|
|
24
|
+
i18nDescriptionKey: 'model.opusClassicDescription',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'claude-opus-4-6[1m]',
|
|
28
|
+
label: 'Opus 4.6 (1M)',
|
|
29
|
+
i18nLabelKey: 'model.opus1m',
|
|
30
|
+
i18nDescriptionKey: 'model.opus1mDescription',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'claude-sonnet-4-6',
|
|
34
|
+
label: 'Sonnet 4.6 (Classic)',
|
|
35
|
+
i18nLabelKey: 'model.sonnetClassic',
|
|
36
|
+
i18nDescriptionKey: 'model.sonnetClassicDescription',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'claude-sonnet-4-6[1m]',
|
|
40
|
+
label: 'Sonnet 4.6 (1M)',
|
|
41
|
+
i18nLabelKey: 'model.sonnet1m',
|
|
42
|
+
i18nDescriptionKey: 'model.sonnet1mDescription',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: 'claude-haiku-4-5-20251001',
|
|
46
|
+
label: 'Haiku 4.5',
|
|
47
|
+
i18nLabelKey: 'model.haiku',
|
|
48
|
+
i18nDescriptionKey: 'model.haikuDescription',
|
|
49
|
+
},
|
|
50
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loicngr/kobo",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Kōbō — multi-workspace agent manager for Claude Code. Orchestrates isolated git worktrees with dev servers, Notion integration, and MCP tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{E as e,F as t,H as n,L as r,M as i,Q as a,U as o,_t as s,bt as c,d as l,f as u,g as d,h as f,l as p,p as m,r as h,rt as g,u as _,v,yt as y}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{L as b,l as x,t as S}from"./QIcon-B0-pH3Qs.js";import{t as C}from"./QBtn-p1aZtrJH.js";import{n as w}from"./vue-i18n-CeG0hR0Z.js";import{S as T,v as E,x as D}from"./index-D997aY4Y.js";import{t as O}from"./QSpinnerDots-By20ptst.js";import{t as k}from"./QExpansionItem-5ekmpO-2.js";import{t as ee}from"./QScrollArea-L6wUiA20.js";import{n as A,t as j}from"./marked.esm-DW0ulF0a.js";import{t as M}from"./_plugin-vue_export-helper-CEhRWsKN.js";function N(e,t,n=!0){let r=[],i=new Map,a=new Map;for(let n=0;n<e.length;n++){let o=e[n],s=t?.[n];switch(o.kind){case`message:text`:{let e=i.get(o.messageId);if(e)e.text+=o.text,e.streaming=o.streaming;else{let e={type:`text`,messageId:o.messageId,text:o.text,streaming:o.streaming,ts:s};i.set(o.messageId,e),r.push(e)}break}case`message:end`:{let e=i.get(o.messageId);e&&(e.streaming=!1);break}case`message:thinking`:r.push({type:`thinking`,messageId:o.messageId,text:o.text,ts:s});break;case`tool:call`:{let e={type:`tool`,toolCallId:o.toolCallId,name:o.name,input:o.input,ts:s};a.set(o.toolCallId,e),r.push(e);break}case`tool:result`:{let e=a.get(o.toolCallId);e&&(e.result={output:o.output,isError:o.isError});break}case`session:started`:r.push({type:`session`,kind:`started`,detail:{engineSessionId:o.engineSessionId,model:o.model},ts:s});break;case`session:ended`:r.push({type:`session`,kind:`ended`,detail:{reason:o.reason,exitCode:o.exitCode},ts:s});break;case`session:compacted`:r.push({type:`session`,kind:`compacted`,ts:s});break;case`session:brainstorm-complete`:case`message:raw`:case`skills:discovered`:case`usage`:case`rate_limit`:case`subagent:progress`:case`error`:break;default:}}let o=null;for(let e of r)e.type===`text`&&e.streaming&&(o&&(o.streaming=!1),o=e);return o&&!n&&(o.streaming=!1),r}function te(e,t){if(t.length===0)return e;let n=t.map(e=>({type:`user`,content:e.content,sender:e.sender,ts:e.ts})),r=[...e,...n];return r.sort((e,t)=>{let n=e.ts??``,r=t.ts??``;return n===r?0:n?r?n<r?-1:1:-1:1}),r}function P(e){switch(e.type){case`user`:return e.sender===`system-prompt`?`system-prompt`:`user`;case`session`:return`session`;default:return`agent`}}function ne(e){let t=[],n=null;for(let r of e){let e=P(r),i=e===`session`||e===`system-prompt`;!n||n.speaker!==e||i?(n={speaker:e,ts:r.ts,items:[r]},t.push(n),i&&(n=null)):n.items.push(r)}return t}var F={class:`text-caption text-grey-6`},I=v({__name:`SessionEventItem`,props:{item:{}},setup(e){let n=e,r=p(()=>{switch(n.item.kind){case`started`:return`session.started`;case`ended`:return`session.ended`;case`compacted`:return`session.compacted`;default:return`session.started`}});return(e,n)=>(t(),m(`span`,F,c(e.$t(r.value)),1))}}),L={class:`markdown-message`},R=[`innerHTML`],z=M(v({__name:`TextMessageItem`,props:{item:{}},setup(e){let n=e,r=p(()=>{let e=j.parse(n.item.text,{async:!1,breaks:!0,gfm:!0});return A.sanitize(e)});return(n,i)=>(t(),m(`div`,L,[_(`div`,{innerHTML:r.value},null,8,R),e.item.streaming?(t(),l(x,{key:0,size:`xs`,class:`q-ml-xs`})):u(``,!0)]))}}),[[`__scopeId`,`data-v-158cbb54`]]),B={key:0,class:`text-caption text-grey-5`,style:{"font-style":`italic`}},V=[`innerHTML`],H={key:1,style:{"white-space":`pre-wrap`}},U=M(v({__name:`ThinkingItem`,props:{item:{}},setup(e){let n=e,r=p(()=>n.item.text.trim().slice(0,100)),i=p(()=>n.item.text.trim().length>0),a=p(()=>n.item.text.trim().length>100),s=p(()=>{let e=j.parse(n.item.text,{async:!1,breaks:!0,gfm:!0});return A.sanitize(e)});return(n,d)=>i.value?(t(),m(`div`,B,[a.value?(t(),l(k,{key:0,dense:``,"dense-toggle":``,label:r.value,"header-class":`text-grey-5 text-caption`,style:{"font-style":`italic`}},{default:o(()=>[_(`div`,{class:`q-py-xs markdown-thinking`,innerHTML:s.value},null,8,V)]),_:1},8,[`label`])):(t(),m(`span`,H,c(e.item.text),1))])):u(``,!0)}}),[[`__scopeId`,`data-v-e9fb9f90`]]);function W(e,t){let n=e.split(`
|
|
2
|
+
`),r=t.split(`
|
|
3
|
+
`),i=n.length,a=r.length,o=Array.from({length:i+1},()=>Array(a+1).fill(0));for(let e=i-1;e>=0;e--)for(let t=a-1;t>=0;t--)n[e]===r[t]?o[e][t]=o[e+1][t+1]+1:o[e][t]=Math.max(o[e+1][t],o[e][t+1]);let s=[],c=0,l=0;for(;c<i&&l<a;)n[c]===r[l]?(s.push({type:`context`,content:n[c]}),c++,l++):o[c+1][l]>=o[c][l+1]?(s.push({type:`del`,content:n[c]}),c++):(s.push({type:`add`,content:r[l]}),l++);for(;c<i;)s.push({type:`del`,content:n[c++]});for(;l<a;)s.push({type:`add`,content:r[l++]});return s}function G(e,t){if(!t||typeof t!=`object`)return null;let n=t;if(e===`Edit`){let e=n.file_path;if(!e)return null;let t=n.old_string??``,r=n.new_string??``;return{toolName:`Edit`,filePath:e,oldString:t,newString:r,replaceAll:n.replace_all??!1,additions:r?r.split(`
|
|
4
|
+
`).length:0,deletions:t?t.split(`
|
|
5
|
+
`).length:0}}if(e===`Write`){let e=n.file_path;if(!e)return null;let t=n.content??``;return{toolName:`Write`,filePath:e,content:t,additions:t?t.split(`
|
|
6
|
+
`).length:0,deletions:0}}if(e===`Bash`){let e=(n.command??``).match(/^\s*rm\s+(?:-[a-zA-Z]*\s+)*(.+)/);if(e)return{toolName:`Bash:rm`,filePath:e[1].trim().replace(/["']/g,``),additions:0,deletions:1}}return null}function K(e,t){if(!e||!t?.projectPath)return e;let n=q(e,`${t.projectPath}/.worktrees/${t.workingBranch}`);return n===e&&(n=q(e,t.projectPath)),n}function q(e,t){if(!t)return e;let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return e.replace(RegExp(`${n}/`,`g`),``).replace(RegExp(`${n}(?=\\s|$|["'\`])`,`g`),`.`)}var J={class:`tool-name`},Y=[`title`],X={key:0,class:`tool-stat-add`},re={key:1,class:`tool-stat-del`},ie={class:`diff-sign`},ae={key:1,class:`tool-row tool-row-generic`},Z={class:`tool-header`},oe={class:`tool-name`},se=[`title`],ce={key:0,class:`tool-output`},le=M(v({__name:`ToolCallItem`,props:{item:{}},setup(e){let n=e,i=a(!1),o=E(),g=p(()=>G(n.item.name,n.item.input)),v=p(()=>g.value?K(g.value.filePath,o.selectedWorkspace):``),y={Bash:`terminal`,Read:`description`,Edit:`edit`,Write:`edit_note`,MultiEdit:`edit`,Glob:`folder_open`,Grep:`manage_search`,LS:`list`,Skill:`auto_awesome`,Task:`hub`,Agent:`hub`,TodoWrite:`checklist`,TodoRead:`checklist`,ToolSearch:`search`,WebFetch:`public`,WebSearch:`travel_explore`,NotebookRead:`book`,NotebookEdit:`edit_note`,SendMessage:`send`,ExitPlanMode:`check_circle_outline`,KillShell:`stop_circle`,BashOutput:`terminal`},x=p(()=>y[n.item.name]??`build`),C=p(()=>{if(g.value)return``;let e=n.item.input,t=w(e);return t?K(t,o.selectedWorkspace):``});function w(e){if(!e||typeof e!=`object`)return typeof e==`string`?e:``;let t=e;for(let e of[`file_path`,`path`,`command`,`pattern`,`query`,`url`,`skill`,`description`,`subject`,`prompt`]){let n=t[e];if(typeof n==`string`&&n.length>0)return n}for(let e of Object.values(t))if(typeof e==`string`&&e.length>0)return e;return``}let T=p(()=>{let e=g.value;return e?e.toolName===`Edit`&&e.oldString!==void 0&&e.newString!==void 0?W(e.oldString,e.newString):e.toolName===`Write`&&e.content!==void 0?e.content.split(`
|
|
7
|
+
`).map(e=>({type:`add`,content:e})):e.toolName===`Bash:rm`?[{type:`del`,content:`File deleted`}]:null:null}),D=p(()=>{let e=n.item.result;if(!e)return``;if(typeof e.output==`string`)return e.output;try{return JSON.stringify(e.output)}catch{return String(e.output)}});function O(){i.value=!i.value}return(n,a)=>g.value?(t(),m(`div`,{key:0,class:s([`tool-row`,{"tool-row-expanded":i.value}])},[_(`div`,{class:`tool-header`,onClick:O},[d(S,{name:x.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),_(`span`,J,c(g.value.toolName===`Bash:rm`?`Bash`:g.value.toolName),1),_(`span`,{class:`tool-path`,title:g.value.filePath},c(v.value),9,Y),g.value.additions>0?(t(),m(`span`,X,`+`+c(g.value.additions),1)):u(``,!0),g.value.deletions>0?(t(),m(`span`,re,`-`+c(g.value.deletions),1)):u(``,!0),e.item.result?.isError?(t(),l(S,{key:2,name:`error_outline`,color:`negative`,size:`xs`,class:`q-ml-xs`})):e.item.result?(t(),l(S,{key:3,name:`check`,color:`positive`,size:`xs`,class:`q-ml-xs`})):u(``,!0),d(S,{name:i.value?`expand_less`:`expand_more`,size:`xs`,class:`q-ml-auto text-grey-6`},null,8,[`name`])]),i.value&&T.value?(t(),m(`div`,{key:0,class:`tool-diff`,onClick:a[0]||=b(()=>{},[`stop`])},[(t(!0),m(h,null,r(T.value,(e,n)=>(t(),m(`div`,{key:n,class:s([`diff-line`,{"diff-del":e.type===`del`,"diff-add":e.type===`add`,"diff-context":e.type===`context`}])},[_(`span`,ie,c(e.type===`del`?`-`:e.type===`add`?`+`:` `),1),f(c(e.content),1)],2))),128))])):u(``,!0)],2)):(t(),m(`div`,ae,[_(`div`,Z,[d(S,{name:x.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),_(`span`,oe,c(e.item.name),1),C.value?(t(),m(`span`,{key:0,class:`tool-arg`,title:w(e.item.input)||C.value},c(C.value),9,se)):u(``,!0),e.item.result?.isError?(t(),l(S,{key:1,name:`error_outline`,color:`negative`,size:`xs`,class:`q-ml-auto`})):e.item.result?(t(),l(S,{key:2,name:`check`,color:`positive`,size:`xs`,class:`q-ml-auto`})):u(``,!0)]),e.item.result&&D.value?(t(),m(`div`,ce,c(D.value),1)):u(``,!0)]))}}),[[`__scopeId`,`data-v-440d2c83`]]),ue=[`innerHTML`],de={key:1,class:`markdown-message`},fe=[`innerHTML`],pe=M(v({__name:`UserMessageItem`,props:{item:{}},setup(e){let n=e,r=p(()=>n.item.sender===`system-prompt`),i=p(()=>{let e=j.parse(n.item.content,{async:!1,breaks:!0,gfm:!0});return A.sanitize(e)});return(e,n)=>r.value?(t(),l(k,{key:0,dense:``,"dense-toggle":``,label:e.$t(`chat.systemPrompt`),"header-class":`text-grey-5 text-caption`},{default:o(()=>[_(`div`,{class:`q-py-xs markdown-user-prompt`,innerHTML:i.value},null,8,ue)]),_:1},8,[`label`])):(t(),m(`div`,de,[_(`div`,{innerHTML:i.value},null,8,fe)]))}}),[[`__scopeId`,`data-v-cb8cec0f`]]),me={class:`turn-header`},he={key:0,class:`turn-time`},ge={key:1,class:`turn-actions`},_e={class:`turn-body`},ve=M(v({__name:`TurnCard`,props:{turn:{}},setup(e){let n=e,{t:i}=w(),a=p(()=>{switch(n.turn.speaker){case`user`:return{label:i(`chat.you`),accent:`#ce93d8`,badgeClass:`turn-badge-user`};case`agent`:return{label:i(`chat.agent`),accent:`#7986cb`,badgeClass:`turn-badge-agent`};case`system-prompt`:return{label:i(`chat.systemPrompt`),accent:`#757575`,badgeClass:`turn-badge-system`};case`session`:return{label:i(`chat.session`),accent:`#616161`,badgeClass:`turn-badge-session`}}}),o=p(()=>{if(!n.turn.ts)return``;let e=new Date(n.turn.ts);return Number.isNaN(e.getTime())?``:e.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}),d=p(()=>n.turn.items.filter(e=>e.type===`tool`).length);return(n,f)=>(t(),m(`div`,{class:s([`turn-card`,{"turn-card--user":e.turn.speaker===`user`}]),style:y({"--turn-accent":a.value.accent})},[_(`div`,me,[_(`span`,{class:s([`turn-badge`,a.value.badgeClass])},c(a.value.label),3),o.value?(t(),m(`span`,he,c(o.value),1)):u(``,!0),d.value>0?(t(),m(`span`,ge,` · `+c(g(i)(`chat.nActions`,{n:d.value})),1)):u(``,!0)]),_(`div`,_e,[(t(!0),m(h,null,r(e.turn.items,(e,n)=>(t(),m(h,{key:n},[e.type===`text`?(t(),l(z,{key:0,item:e},null,8,[`item`])):e.type===`thinking`?(t(),l(U,{key:1,item:e},null,8,[`item`])):e.type===`tool`?(t(),l(le,{key:2,item:e},null,8,[`item`])):e.type===`user`?(t(),l(pe,{key:3,item:e},null,8,[`item`])):e.type===`session`?(t(),l(I,{key:4,item:e},null,8,[`item`])):u(``,!0)],64))),128))])],6))}}),[[`__scopeId`,`data-v-8a9ce6dd`]]),ye={key:0,class:`activity-feed-switching`},be={key:1,class:`activity-feed-wrap`},xe={key:0,class:`text-center q-py-sm text-caption text-grey-6`},Se={class:`q-pa-md`},Ce={key:1,class:`q-px-md q-pb-md`},we=60,Q=200,$=200,Te=400,Ee=200,De=M(v({__name:`ActivityFeed`,props:{workspaceId:{}},setup(s){let g=s,v=T(),y=D(),b=E(),S=p(()=>(b.activityFeeds[g.workspaceId]??[]).filter(e=>e.type===`text`&&typeof e.content==`string`).map(e=>({content:e.content,sender:e.meta?.sender??`user`,ts:e.timestamp,sessionId:e.sessionId}))),w=p(()=>{let e=b.workspaces.find(e=>e.id===g.workspaceId);return e?e.status===`extracting`||e.status===`brainstorming`||e.status===`executing`:!1}),A=p(()=>{let e=te(N(v.eventsFor(g.workspaceId),v.timestampsFor(g.workspaceId),w.value),S.value);return ne(y.showVerboseSystemMessages?e:e.filter(e=>e.type!==`session`))}),j=p(()=>y.showVerboseSystemMessages?v.eventsFor(g.workspaceId).filter(e=>e.kind===`message:raw`).map(e=>e.content):[]),M=a(null),P=!0,F=a(!1),I=!1,L=a(!0);function R(e){P=e.verticalSize-e.verticalPosition-e.verticalContainerSize<=we,I&&e.verticalPosition<=Q&&!F.value&&v.hasMoreOlderFor(g.workspaceId)&&z()}async function z(){let t=g.workspaceId,n=v.oldestIdFor(t);if(!n)return;F.value=!0;let r=Date.now();try{let r=M.value,i=r?.getScroll().verticalSize??0,a=r?.getScroll().verticalPosition??0,o=fetch(`/api/workspaces/${t}/events?before=${encodeURIComponent(n)}&limit=200`),s=new Promise(e=>setTimeout(e,$)),[c]=await Promise.all([o,s]);if(!c.ok){v.prepend(t,[],[],{oldestId:n,hasMoreOlder:!1});return}let l=await c.json(),u=l.events??[],d=u.filter(e=>e.type===`agent:event`&&e.workspaceId===t),f=u.filter(e=>e.type===`user:message`&&e.workspaceId===t),p=d.map(e=>e.payload),m=d.map(e=>e.createdAt),h=d.map(e=>e.sessionId??null),g=u.length>0?u[0].id:n;v.prepend(t,p,m,{oldestId:g,hasMoreOlder:l.hasMore,sessionIds:h});for(let e of f){let n=e.payload;typeof n.content==`string`&&b.addActivityItem(t,{id:e.id,type:`text`,content:n.content,timestamp:e.createdAt,sessionId:e.sessionId??void 0,meta:{sender:n.sender??`user`}})}if(await e(),r){let e=r.getScroll().verticalSize-i,t=Math.max(a+e,Q+50);r.setScrollPosition(`vertical`,t,0)}}catch(e){console.error(`[ActivityFeed] failed to load older events:`,e)}finally{let e=Date.now()-r,t=Math.max(0,$-e);await new Promise(e=>setTimeout(e,t+Te)),F.value=!1}}async function B(t=0){await e();let n=M.value;if(!n)return;let r=n.getScroll();n.setScrollPosition(`vertical`,r.verticalSize,t)}let V=a([]),H=a(null);function U(){let e=A.value,t=V.value,n=[];if(t.length===e.length){for(let r=0;r<e.length;r++){if(e[r].speaker!==`user`)continue;let i=t[r]?.$el;i&&n.push(i)}if(n.length>0)return n}let r=H.value?.parentElement;if(r){let e=r.querySelectorAll(`.turn-card--user`);for(let t of e)n.push(t)}return n}function W(){let e=M.value;if(!e)return null;let t=H.value;if(!t)return null;let n=e.getScroll().verticalPosition,r=t.getBoundingClientRect().top,i=null;for(let e of U()){let t=e.getBoundingClientRect().top-r;if(t<n-40)i=t;else break}return i}async function G(){let t=M.value;if(!t)return;let n=W();if(n===null)for(let t=0;t<15&&v.hasMoreOlderFor(g.workspaceId);t++){for(;F.value;)await new Promise(e=>setTimeout(e,50));if(await z(),await e(),n=W(),n!==null)break}n!==null&&t.setScrollPosition(`vertical`,Math.max(0,n-12),250)}async function K(){I=!1,await e(),await B(0),requestAnimationFrame(()=>{requestAnimationFrame(()=>{I=!0})})}let q=p(()=>v.eventsFor(g.workspaceId).length);async function J(){L.value=!0;let e=Date.now();await new Promise(e=>setTimeout(e,Ee));let t=e+5e3;for(;q.value===0&&Date.now()<t;)await new Promise(e=>setTimeout(e,50));L.value=!1}n(L,async e=>{!e&&q.value>0&&await K()}),i(()=>{J(),q.value>0&&K()});let Y=!1;return n(q,async(e,t)=>{if(!Y&&e>0){Y=!0,await K();return}e>t&&P&&!F.value&&await B(180)}),n(()=>g.workspaceId,()=>{P=!0,Y=!1,I=!1,J(),q.value>0&&K()}),n(()=>b.selectedSessionId,async()=>{P=!0,I=!1,await K()}),n(p(()=>S.value.filter(e=>e.sender!==`system-prompt`).length),async(e,t)=>{e>t&&(P=!0,await B(180))}),(e,n)=>L.value?(t(),m(`div`,ye,[d(O,{size:`40px`,color:`indigo-4`})])):(t(),m(`div`,be,[d(ee,{ref_key:`scrollRef`,ref:M,class:`activity-feed-scroll`,onScroll:R},{default:o(()=>[_(`div`,{ref_key:`contentOriginRef`,ref:H,class:`content-origin-marker`},null,512),F.value?(t(),m(`div`,xe,[d(x,{size:`sm`}),f(` `+c(e.$t(`activity.loading_older`)),1)])):u(``,!0),_(`div`,Se,[(t(!0),m(h,null,r(A.value,(e,n)=>(t(),l(ve,{key:n,ref_for:!0,ref_key:`turnRefs`,ref:V,turn:e},null,8,[`turn`]))),128))]),j.value.length?(t(),m(`div`,Ce,[d(k,{label:e.$t(`activity.raw_lines`,{n:j.value.length}),dense:``},{default:o(()=>[(t(!0),m(h,null,r(j.value,(e,n)=>(t(),m(`div`,{key:n,class:`text-caption text-grey q-pa-xs`},c(e),1))),128))]),_:1},8,[`label`])])):u(``,!0)]),_:1},512),d(C,{round:``,dense:``,unelevated:``,color:`grey-9`,"text-color":`grey-3`,icon:`arrow_upward`,size:`sm`,class:`activity-feed-prev-btn`,title:e.$t(`activity.prev_user_message`),onClick:G},null,8,[`title`])]))}}),[[`__scopeId`,`data-v-51e2c6eb`]]);export{De as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.markdown-message[data-v-158cbb54]{color:#e0e0e0;word-break:break-word;overflow-wrap:anywhere;min-width:0;max-width:100%;font-size:13px;line-height:1.55}.markdown-message[data-v-158cbb54] *{max-width:100%}.markdown-message[data-v-158cbb54] p{margin:0 0 .5em}.markdown-message[data-v-158cbb54] p:last-child{margin-bottom:0}.markdown-message[data-v-158cbb54] pre{background:#00000059;border-radius:4px;margin:.5em 0;padding:.5em .75em;overflow-x:auto}.markdown-message[data-v-158cbb54] code{word-break:break-all;background:#0000004d;border-radius:3px;padding:.1em .3em;font-size:.9em}.markdown-message[data-v-158cbb54] pre code{background:0 0;padding:0}.markdown-message[data-v-158cbb54] ul,.markdown-message[data-v-158cbb54] ol{margin:.25em 0 .5em;padding-left:1.5em}.markdown-message[data-v-158cbb54] li{margin:.15em 0}.markdown-message[data-v-158cbb54] a{color:#7986cb;text-decoration:underline}.markdown-message[data-v-158cbb54] h1,.markdown-message[data-v-158cbb54] h2,.markdown-message[data-v-158cbb54] h3,.markdown-message[data-v-158cbb54] h4,.markdown-message[data-v-158cbb54] h5,.markdown-message[data-v-158cbb54] h6{margin:.5em 0 .3em;font-weight:600;line-height:1.3}.markdown-message[data-v-158cbb54] h1{font-size:1.25em}.markdown-message[data-v-158cbb54] h2{font-size:1.15em}.markdown-message[data-v-158cbb54] h3{font-size:1.08em}.markdown-message[data-v-158cbb54] h4,.markdown-message[data-v-158cbb54] h5,.markdown-message[data-v-158cbb54] h6{font-size:1em}.markdown-message[data-v-158cbb54] blockquote{color:#ffffffb3;border-left:3px solid #fff3;margin:.5em 0;padding-left:.75em}.markdown-message[data-v-158cbb54] table{border-collapse:collapse;margin:.5em 0}.markdown-message[data-v-158cbb54] th,.markdown-message[data-v-158cbb54] td{border:1px solid #ffffff26;padding:.25em .5em}.markdown-thinking[data-v-e9fb9f90] p{margin:0 0 .4em}.markdown-thinking[data-v-e9fb9f90] p:last-child{margin-bottom:0}.markdown-thinking[data-v-e9fb9f90] code{background:#ffffff14;border-radius:3px;padding:.1em .3em}.tool-row[data-v-440d2c83]{border-radius:4px;margin:0;font-size:12px}.tool-header[data-v-440d2c83]{color:#bbb;cursor:default;align-items:center;gap:10px;min-width:0;padding:5px 10px;display:flex}.tool-row:not(.tool-row-generic) .tool-header[data-v-440d2c83]{cursor:pointer}.tool-row:has(.tool-diff) .tool-header[data-v-440d2c83]{cursor:pointer}.tool-row:not(.tool-row-generic) .tool-header[data-v-440d2c83]:hover{background:#ffffff08}.tool-icon[data-v-440d2c83]{color:#9fbce0;flex-shrink:0}.tool-name[data-v-440d2c83]{color:#d0d0d0;flex-shrink:0;font-weight:600}.tool-arg[data-v-440d2c83],.tool-path[data-v-440d2c83]{color:#999;text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:100%;font-family:SF Mono,Menlo,Consolas,monospace;font-size:11.5px;overflow:hidden}.tool-path[data-v-440d2c83],.tool-arg[data-v-440d2c83]{flex:1}.tool-stat-add[data-v-440d2c83]{color:#66bb6a;flex-shrink:0;font-size:11px;font-weight:600}.tool-stat-del[data-v-440d2c83]{color:#ef5350;flex-shrink:0;font-size:11px;font-weight:600}.tool-diff[data-v-440d2c83]{background:#0003;border-radius:4px;max-height:400px;margin-top:4px;padding:8px 0;font-family:SF Mono,Menlo,Consolas,monospace;font-size:11px;line-height:1.5;overflow:auto}.diff-line[data-v-440d2c83]{white-space:pre;color:#bbb;padding:0 12px}.diff-sign[data-v-440d2c83]{color:#555;-webkit-user-select:none;user-select:none;width:14px;display:inline-block}.diff-add[data-v-440d2c83]{color:#c8e6c9;background:#66bb6a1a}.diff-add .diff-sign[data-v-440d2c83]{color:#66bb6a}.diff-del[data-v-440d2c83]{color:#ffcdd2;background:#ef53501a}.diff-del .diff-sign[data-v-440d2c83]{color:#ef5350}.tool-output[data-v-440d2c83]{color:#aaa;white-space:pre-wrap;background:#00000026;border-radius:4px;max-height:8em;margin-top:4px;padding:6px 10px;font-family:SF Mono,Menlo,Consolas,monospace;font-size:11px;overflow:auto}.markdown-message[data-v-cb8cec0f]{color:#e0e0e0;word-break:break-word;overflow-wrap:anywhere;min-width:0;max-width:100%;font-size:13px;line-height:1.55}.markdown-message[data-v-cb8cec0f] *{max-width:100%}.markdown-message[data-v-cb8cec0f] code{word-break:break-all}.markdown-message[data-v-cb8cec0f] p{margin:0 0 .4em}.markdown-message[data-v-cb8cec0f] p:last-child{margin-bottom:0}.markdown-message[data-v-cb8cec0f] code{background:#00000040;border-radius:3px;padding:.1em .3em}.markdown-message[data-v-cb8cec0f] h1,.markdown-message[data-v-cb8cec0f] h2,.markdown-message[data-v-cb8cec0f] h3,.markdown-message[data-v-cb8cec0f] h4,.markdown-message[data-v-cb8cec0f] h5,.markdown-message[data-v-cb8cec0f] h6{margin:.4em 0 .25em;font-weight:600;line-height:1.3}.markdown-message[data-v-cb8cec0f] h1{font-size:1.25em}.markdown-message[data-v-cb8cec0f] h2{font-size:1.15em}.markdown-message[data-v-cb8cec0f] h3{font-size:1.08em}.markdown-message[data-v-cb8cec0f] h4,.markdown-message[data-v-cb8cec0f] h5,.markdown-message[data-v-cb8cec0f] h6{font-size:1em}.markdown-user-prompt[data-v-cb8cec0f]{color:#aaa;font-size:12px;font-style:italic}.markdown-user-prompt[data-v-cb8cec0f] p{margin:0 0 .4em}.markdown-user-prompt[data-v-cb8cec0f] code{background:#ffffff14;border-radius:3px;padding:.1em .3em;font-style:normal}.turn-card[data-v-8a9ce6dd]{border:1px solid #ffffff14;border-left:3px solid var(--turn-accent);background:#ffffff05;border-radius:6px;min-width:0;max-width:100%;margin:14px 0;overflow:hidden}.turn-header[data-v-8a9ce6dd]{color:#888;background:#ffffff08;border-bottom:1px solid #ffffff0d;align-items:center;gap:8px;padding:8px 14px;font-size:11px;display:flex}.turn-badge[data-v-8a9ce6dd]{letter-spacing:.3px;border-radius:3px;padding:2px 8px;font-size:11px;font-weight:700}.turn-badge-user[data-v-8a9ce6dd]{color:#ce93d8;background:#ce93d826}.turn-badge-agent[data-v-8a9ce6dd]{color:#7986cb;background:#7986cb26}.turn-badge-system[data-v-8a9ce6dd]{color:#bdbdbd;background:#75757533;font-style:italic}.turn-badge-session[data-v-8a9ce6dd]{color:#9e9e9e;background:#61616133}.turn-time[data-v-8a9ce6dd]{color:#666;font-family:SF Mono,Menlo,Consolas,monospace;font-size:11px}.turn-actions[data-v-8a9ce6dd]{color:#777;font-size:11px}.turn-body[data-v-8a9ce6dd]{flex-direction:column;gap:12px;min-width:0;padding:14px 18px;display:flex}.turn-body[data-v-8a9ce6dd]>*{min-width:0;max-width:100%}.turn-body[data-v-8a9ce6dd] .tool-row+.tool-row{margin-top:-8px}.activity-feed-wrap[data-v-51e2c6eb]{width:100%;height:100%;position:relative}.activity-feed-scroll[data-v-51e2c6eb]{width:100%;height:100%}.activity-feed-prev-btn[data-v-51e2c6eb]{z-index:2;opacity:.8;transition:opacity .12s;position:absolute;bottom:14px;right:14px}.activity-feed-prev-btn[data-v-51e2c6eb]:hover{opacity:1}.content-origin-marker[data-v-51e2c6eb]{pointer-events:none;width:0;height:0;margin:0;padding:0}.activity-feed-scroll[data-v-51e2c6eb] .q-scrollarea__content{max-width:100%;overflow-x:hidden}.activity-feed-switching[data-v-51e2c6eb]{justify-content:center;align-items:center;width:100%;height:100%;display:flex}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{k as e,m as t}from"./QIcon-B0-pH3Qs.js";import{i as n,r}from"./use-portal-mhLq4Rqk.js";function i(e){if(e===!1)return 0;if(e===!0||e===void 0)return 1;let t=parseInt(e,10);return isNaN(t)?0:t}var a=e({name:`close-popup`,beforeMount(e,{value:a}){let o={depth:i(a),handler(t){o.depth!==0&&setTimeout(()=>{let i=n(e);i!==void 0&&r(i,t,o.depth)})},handlerKey(e){t(e,13)===!0&&o.handler(e)}};e.__qclosepopup=o,e.addEventListener(`click`,o.handler),e.addEventListener(`keyup`,o.handlerKey)},updated(e,{value:t,oldValue:n}){t!==n&&(e.__qclosepopup.depth=i(t))},beforeUnmount(e){let t=e.__qclosepopup;e.removeEventListener(`click`,t.handler),e.removeEventListener(`keyup`,t.handlerKey),delete e.__qclosepopup}});export{a as t};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{F as e,H as t,L as n,M as r,N as i,Q as a,T as ee,U as o,bt as s,d as c,f as l,g as u,h as d,l as f,p,r as m,rt as te,u as h,v as ne,vt as re,x as ie}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{I as g,L as _,M as ae,t as v}from"./QIcon-B0-pH3Qs.js";import{t as y}from"./QSeparator-rkjCbX2M.js";import{t as b}from"./QBtn-p1aZtrJH.js";import{n as oe}from"./vue-i18n-CeG0hR0Z.js";import{g as se,i as x,m as ce,v as le,x as ue}from"./index-D997aY4Y.js";import{n as S,t as C}from"./QItemSection-GlMrLmz3.js";import{t as w}from"./QItemLabel-Czw5g0px.js";import{t as de}from"./QExpansionItem-5ekmpO-2.js";import{t as fe}from"./_plugin-vue_export-helper-CEhRWsKN.js";import{t as pe}from"./QSpace-PlDK6Fg3.js";import{t as T}from"./QTooltip-Cg9E3Dvw.js";import{t as me}from"./use-quasar-BBrzedjR.js";import{n as E,t as he}from"./models-DMQoi09X.js";import{t as ge}from"./QPage-B09NY4Nf.js";var _e={class:`create-inner`},ve={class:`create-title text-center text-weight-bold q-mb-lg text-grey-3`},ye={class:`create-card rounded-borders`},be={class:`card-top-bar row items-center q-px-md q-py-xs`},xe={class:`model-badge cursor-default row items-center q-gutter-xs`},Se={class:`text-indigo-3 text-weight-medium text-caption`},Ce={key:0,class:`notion-url-wrap`},we={key:0,class:`notion-error text-caption q-px-md q-pb-xs text-red-5`},Te={key:1,class:`notion-valid text-caption q-px-md q-pb-xs text-green-4`},Ee={key:0,class:`sentry-url-wrap`},De={key:0,class:`sentry-error text-caption q-px-md q-pb-xs text-red-5`},Oe={key:1,class:`sentry-valid text-caption q-px-md q-pb-xs text-red-4`},ke={class:`card-name-wrap`},Ae={class:`card-textarea-wrap`},je={class:`manual-hint q-px-md q-py-sm text-caption text-grey-6`},Me={class:`q-pa-sm manual-section-body`},Ne={class:`row items-center q-gutter-sm q-mb-sm`},Pe={class:`col text-caption text-grey-4`},Fe={class:`q-pa-sm manual-section-body`},Ie={class:`row items-center q-gutter-sm q-mb-sm`},Le={class:`col text-caption text-grey-4`},Re={class:`card-bottom-bar`},ze={class:`bottom-row bottom-row-agent row items-center q-gutter-xs q-px-sm q-py-xs`},Be={class:`bottom-select-label row items-center no-wrap`},Ve={class:`bottom-select-label row items-center no-wrap`},He={class:`bottom-select-label row items-center no-wrap`},Ue={class:`bottom-select-label row items-center no-wrap`},We={class:`bottom-row bottom-row-git row items-center q-gutter-xs q-px-sm q-py-xs`},Ge={class:`bottom-select-label row items-center no-wrap`},Ke={class:`bottom-select-label row items-center no-wrap`},qe={class:`row justify-center q-px-sm q-py-sm`},Je={class:`create-hint text-center text-body2 q-mt-md text-grey-8`},Ye=fe(ne({__name:`CreatePage`,setup(ne){let fe=ce(),Ye=me(),Xe=le(),D=ue(),{t:O}=oe(),Ze=a([]),k=a(``),A=a(``),j=a(``),M=a(!1),N=a(`claude-opus-4-7`),P=a(`auto`),F=a(``),I=a(null),L=a(`feature`),R=a(!1),Qe=a([]),z=a(`claude-code`),$e=f(()=>Qe.value.find(e=>e.id===z.value)),et=f(()=>Qe.value.map(e=>({value:e.id,label:e.displayName}))),tt=f(()=>($e.value?.capabilities.permissionModes??[`auto-accept`,`plan`]).map(e=>({value:e,label:O(`engine.permission.${e}`)}))),nt=[{label:`feature/`,value:`feature`},{label:`fix/`,value:`fix`},{label:`hotfix/`,value:`hotfix`},{label:`chore/`,value:`chore`},{label:`refactor/`,value:`refactor`},{label:`docs/`,value:`docs`},{label:`test/`,value:`test`}],B=a(D.global.defaultPermissionMode||`plan`),V=a([]),H=a(!1),U=a(!1),rt=f(()=>he.map(e=>({label:O(e.i18nLabelKey),value:e.value,description:O(e.i18nDescriptionKey)})));function W(e){let t=e.indexOf(`:`);return t>=0?e.slice(t+1).trim():e}let it=f(()=>[{label:W(O(`reasoning.auto`)),value:`auto`,description:O(`reasoning.autoDescription`)},{label:W(O(`reasoning.low`)),value:`low`,description:O(`reasoning.lowDescription`)},{label:W(O(`reasoning.medium`)),value:`medium`,description:O(`reasoning.mediumDescription`)},{label:W(O(`reasoning.high`)),value:`high`,description:O(`reasoning.highDescription`)},{label:W(O(`reasoning.xhigh`)),value:`xhigh`,description:O(`reasoning.xhighDescription`)},{label:W(O(`reasoning.max`)),value:`max`,description:O(`reasoning.maxDescription`)}]),G=f(()=>j.value.trim().startsWith(`https://www.notion.so/`)),K=a([]),q=a([]),J=a(``),Y=a(``),at=f(()=>!M.value||!G.value);function ot(){let e=J.value.trim();e&&(K.value.push(e),J.value=``)}function st(e){K.value.splice(e,1)}function ct(){let e=Y.value.trim();e&&(q.value.push(e),Y.value=``)}function lt(e){q.value.splice(e,1)}function ut(){M.value=!M.value,M.value||(j.value=``)}let X=a(!1),Z=a(``),Q=f(()=>/\/issues\/\d+/.test(Z.value.trim()));function dt(){X.value=!X.value,X.value||(Z.value=``)}async function ft(e){if(!e.trim()){V.value=[],I.value=null;return}H.value=!0;try{let t=await fetch(`/api/git/branches?path=${encodeURIComponent(e.trim())}`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();V.value=n.local??n.branches??[],V.value.length>0&&!I.value&&(I.value=V.value[0]??null)}catch{V.value=[],I.value=null}finally{H.value=!1}}function pt(e){let t=D.getProjectByPath(e);t&&(t.defaultSourceBranch&&(I.value=t.defaultSourceBranch),t.defaultModel?N.value=t.defaultModel:D.global.defaultModel&&(N.value=D.global.defaultModel))}let $=null;t(F,e=>{$&&clearTimeout($),$=setTimeout(()=>{I.value=null,ft(e),pt(e)},500)});function mt(e,t){t(()=>{Ze.value=D.projectPaths.filter(t=>t.toLowerCase().includes(e.toLowerCase()))})}r(async()=>{D.fetchSettings();try{let e=await fetch(`/api/engines`);e.ok&&(Qe.value=await e.json())}catch{}}),i(()=>{$&&clearTimeout($)});function ht(e){return e.normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9\s-]/g,``).trim().replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50)}function gt(){return k.value.trim()?k.value.trim().substring(0,80):!M.value&&A.value.trim()&&(A.value.trim().split(`
|
|
2
|
+
`)[0]??``).substring(0,80)||`workspace`}function _t(e){let t=(e.split(`/`).pop()??``).split(`-`);t.length>1&&/^[0-9a-f]{12,}$/i.test(t[t.length-1])&&t.pop();let n=t.join(`-`).toLowerCase(),r=n.match(/tk-(\d+)/);if(r){let e=`TK-${r[1]}`,t=n.replace(/tk-\d+/i,``).replace(/-+/g,`-`).replace(/^-|-$/g,``).substring(0,40);return t?`${e}--${t}`:e}return n.substring(0,50)||`task-${Date.now()}`}function vt(){return M.value&&!G.value?O(`createPage.validationNotionUrl`):X.value&&!Q.value?O(`createPage.sentryValidation`):!M.value&&!X.value&&!A.value.trim()?O(`createPage.validationDescription`):!M.value&&!X.value&&(!gt()||gt()===`workspace`)&&!k.value.trim()&&!A.value.trim()?O(`createPage.validationName`):F.value.trim()?I.value?null:O(`createPage.validationBranch`):O(`createPage.validationPath`)}async function yt(){let e=vt();if(e){Ye.notify({type:`negative`,message:e,position:`top`});return}U.value=!0;try{let e=gt(),t;t=M.value&&G.value?_t(j.value.trim()):e===`workspace`?`task-${Date.now()}`:ht(e);let n=`${L.value}/${t}`,r={name:e,projectPath:F.value.trim(),sourceBranch:I.value,workingBranch:n,engine:z.value,model:N.value,reasoningEffort:P.value,...M.value&&G.value?{notionUrl:j.value.trim()}:{},...X.value&&Q.value?{sentryUrl:Z.value.trim()}:{},...at.value&&K.value.length>0?{tasks:K.value}:{},...at.value&&q.value.length>0?{acceptanceCriteria:q.value}:{},...R.value?{skipSetupScript:!0}:{},...A.value.trim()?{description:A.value.trim()}:{},permissionMode:B.value},i=await Xe.createWorkspace(r);se().subscribe(i.id),Xe.selectWorkspace(i.id),fe.push({name:`workspace`,params:{id:i.id}})}catch{Ye.notify({type:`negative`,message:O(`createPage.errorCreating`),position:`top`})}finally{U.value=!1}}return(t,r)=>(e(),c(ge,{class:`create-page flex flex-center column`},{default:o(()=>[h(`div`,_e,[h(`div`,ve,s(t.$t(`createPage.title`)),1),h(`div`,ye,[h(`div`,be,[h(`span`,xe,[u(v,{name:`auto_awesome`,size:`14px`,color:`indigo-4`}),h(`span`,Se,s($e.value?.displayName??t.$t(`createPage.claudeCode`)),1)]),u(pe),u(b,{flat:``,dense:``,"no-caps":``,size:`sm`,color:M.value?`green-4`:`grey-5`,class:`notion-toggle-btn text-caption rounded-borders`,onClick:ut},{default:o(()=>[u(v,{name:`description`,size:`14px`,class:`q-mr-xs`}),d(` `+s(M.value?t.$t(`createPage.notionEnabled`):t.$t(`createPage.importNotion`)),1)]),_:1},8,[`color`]),u(b,{flat:``,dense:``,"no-caps":``,size:`sm`,color:X.value?`red-4`:`grey-5`,class:`sentry-toggle-btn text-caption rounded-borders q-ml-sm`,onClick:dt},{default:o(()=>[u(v,{name:`bug_report`,size:`14px`,class:`q-mr-xs`}),d(` `+s(X.value?t.$t(`createPage.sentryEnabled`):t.$t(`createPage.importSentry`)),1)]),_:1},8,[`color`])]),u(y,{color:`grey-9`}),u(ae,{name:`slide`},{default:o(()=>[M.value?(e(),p(`div`,Ce,[u(x,{modelValue:j.value,"onUpdate:modelValue":r[0]||=e=>j.value=e,borderless:``,dense:``,placeholder:t.$t(`createPage.notionPlaceholder`),class:`notion-url-input`,"input-class":`notion-url-input-inner`},{prepend:o(()=>[u(v,{name:`link`,size:`16px`,color:G.value?`green-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),j.value.trim()&&!G.value?(e(),p(`div`,we,s(t.$t(`createPage.notionValidation`)),1)):l(``,!0),G.value?(e(),p(`div`,Te,s(t.$t(`createPage.notionAutoExtract`)),1)):l(``,!0)])):l(``,!0)]),_:1}),M.value?(e(),c(y,{key:0,color:`grey-9`})):l(``,!0),u(ae,{name:`slide`},{default:o(()=>[X.value?(e(),p(`div`,Ee,[u(x,{modelValue:Z.value,"onUpdate:modelValue":r[1]||=e=>Z.value=e,borderless:``,dense:``,placeholder:t.$t(`createPage.sentryPlaceholder`),class:`sentry-url-input`,"input-class":`sentry-url-input-inner`},{prepend:o(()=>[u(v,{name:`link`,size:`16px`,color:Q.value?`red-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),Z.value.trim()&&!Q.value?(e(),p(`div`,De,s(t.$t(`createPage.sentryValidation`)),1)):l(``,!0),Q.value?(e(),p(`div`,Oe,s(t.$t(`createPage.sentryAutoExtract`)),1)):l(``,!0)])):l(``,!0)]),_:1}),X.value?(e(),c(y,{key:1,color:`grey-9`})):l(``,!0),h(`div`,ke,[u(x,{modelValue:k.value,"onUpdate:modelValue":r[2]||=e=>k.value=e,borderless:``,dense:``,placeholder:M.value&&G.value?t.$t(`createPage.workspaceName`):t.$t(`createPage.workspaceNamePlaceholder`),class:`name-input`,"input-class":`name-input-inner`},null,8,[`modelValue`,`placeholder`])]),u(y,{color:`grey-9`}),h(`div`,Ae,[u(x,{modelValue:A.value,"onUpdate:modelValue":r[3]||=e=>A.value=e,type:`textarea`,borderless:``,autogrow:``,rows:3,placeholder:M.value?t.$t(`createPage.instructions`):t.$t(`createPage.instructionsPlaceholder`),class:`create-textarea`,"input-class":`create-textarea-input`,onKeydown:[g(_(yt,[`ctrl`]),[`enter`]),g(_(yt,[`meta`]),[`enter`])]},null,8,[`modelValue`,`placeholder`,`onKeydown`])]),u(y,{color:`grey-9`}),at.value?(e(),p(m,{key:2},[h(`div`,je,s(t.$t(`createPage.manualHint`)),1),u(de,{dark:``,dense:``,label:t.$t(`createPage.tasks`,{count:K.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm`},{default:o(()=>[h(`div`,Me,[h(`div`,Ne,[u(x,{modelValue:J.value,"onUpdate:modelValue":r[4]||=e=>J.value=e,dark:``,dense:``,borderless:``,placeholder:t.$t(`createPage.addTask`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:g(_(ot,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),u(b,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!J.value.trim(),onClick:ot},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.addTask`)),1)]),_:1})]),_:1},8,[`disable`])]),(e(!0),p(m,null,n(K.value,(n,r)=>(e(),p(`div`,{key:`task-${r}`,class:`row items-center q-py-xs manual-item`},[h(`span`,Pe,s(n),1),u(b,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>st(r)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.removeTask`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),u(de,{dark:``,dense:``,label:t.$t(`createPage.acceptanceCriteria`,{count:q.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm q-mb-sm`},{default:o(()=>[h(`div`,Fe,[h(`div`,Ie,[u(x,{modelValue:Y.value,"onUpdate:modelValue":r[5]||=e=>Y.value=e,dark:``,dense:``,borderless:``,placeholder:t.$t(`createPage.addCriterion`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:g(_(ct,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),u(b,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!Y.value.trim(),onClick:ct},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.addCriterion`)),1)]),_:1})]),_:1},8,[`disable`])]),(e(!0),p(m,null,n(q.value,(n,r)=>(e(),p(`div`,{key:`crit-${r}`,class:`row items-center q-py-xs manual-item`},[h(`span`,Le,s(n),1),u(b,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>lt(r)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.removeCriterion`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),u(y,{color:`grey-9`})],64)):l(``,!0),h(`div`,Re,[h(`div`,ze,[et.value.length>0?(e(),c(E,{key:0,modelValue:z.value,"onUpdate:modelValue":r[6]||=e=>z.value=e,options:et.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,Be,[u(v,{name:`hub`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(et.value.find(e=>e.value===z.value)?.label??z.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`engine.select`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])):l(``,!0),u(E,{modelValue:N.value,"onUpdate:modelValue":r[7]||=e=>N.value=e,options:rt.value,dense:``,borderless:``,class:`bottom-select rounded-borders model-select`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,Ve,[d(s(rt.value.find(e=>e.value===N.value)?.label??N.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[u(S,ee(t,{class:`model-option`}),{default:o(()=>[u(C,null,{default:o(()=>[u(w,{class:`text-white`},{default:o(()=>[d(s(e.label),1)]),_:2},1024),u(w,{caption:``,class:`text-grey-5`},{default:o(()=>[d(s(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),_:1},8,[`modelValue`,`options`]),u(E,{modelValue:P.value,"onUpdate:modelValue":r[8]||=e=>P.value=e,options:it.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,He,[u(v,{name:`psychology`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(it.value.find(e=>e.value===P.value)?.label??P.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[u(S,re(ie(t)),{default:o(()=>[u(C,null,{default:o(()=>[u(w,{class:`text-white`},{default:o(()=>[d(s(e.label),1)]),_:2},1024),u(w,{caption:``,class:`text-grey-5`},{default:o(()=>[d(s(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),_:1},8,[`modelValue`,`options`]),u(E,{modelValue:B.value,"onUpdate:modelValue":r[9]||=e=>B.value=e,options:tt.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,Ue,[u(v,{name:B.value===`plan`?`visibility`:`flash_on`,size:`12px`,color:`amber-6`,class:`q-mr-xs`},null,8,[`name`]),d(` `+s(tt.value.find(e=>e.value===B.value)?.label??B.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`engine.permission`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`]),u(pe),u(b,{flat:``,dense:``,size:`sm`,"no-caps":``,icon:R.value?`play_disabled`:`play_circle`,color:R.value?`orange-4`:`grey-5`,label:t.$t(`createPage.skipSetupScript`),class:`skip-setup-btn`,onClick:r[10]||=e=>R.value=!R.value},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`createPage.skipSetupScript`)),1)]),_:1})]),_:1},8,[`icon`,`color`,`label`])]),h(`div`,We,[u(E,{modelValue:F.value,"onUpdate:modelValue":r[11]||=e=>F.value=e,options:Ze.value,dense:``,borderless:``,"use-input":``,"fill-input":``,"hide-selected":``,"input-debounce":`0`,"new-value-mode":`add`,class:`bottom-select rounded-borders repo-select`,"hide-dropdown-icon":``,"input-class":F.value?``:`repo-input-empty`,placeholder:t.$t(`createPage.projectPath`),behavior:te(D).projectPaths.length>0?`menu`:`dialog`,onFilter:mt,onInputValue:r[12]||=e=>{F.value=e}},{prepend:o(()=>[u(v,{name:`folder`,size:`14px`,color:`grey-5`})]),"no-option":o(()=>[u(S,null,{default:o(()=>[u(C,{class:`text-grey-6 text-caption`},{default:o(()=>[d(s(t.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`input-class`,`placeholder`,`behavior`]),u(E,{modelValue:L.value,"onUpdate:modelValue":r[13]||=e=>L.value=e,options:nt,"emit-value":``,"map-options":``,dense:``,borderless:``,class:`bottom-select rounded-borders branch-type-select`,"hide-dropdown-icon":``},{selected:o(()=>[h(`span`,Ge,[u(v,{name:`account_tree`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(L.value)+`/ `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`createPage.branchType`)),1)]),_:1})]),_:1},8,[`modelValue`]),u(E,{modelValue:I.value,"onUpdate:modelValue":r[14]||=e=>I.value=e,options:V.value,dense:``,borderless:``,class:`bottom-select rounded-borders branch-select`,"hide-dropdown-icon":``,loading:H.value,disable:!F.value.trim()||H.value},{selected:o(()=>[h(`span`,Ke,[u(v,{name:`call_split`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(I.value??t.$t(`createPage.branch`))+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),"no-option":o(()=>[u(S,null,{default:o(()=>[u(C,{class:`text-grey-6 text-caption`},{default:o(()=>[d(s(F.value.trim()?t.$t(`createPage.noBranches`):t.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`loading`,`disable`])])]),h(`div`,qe,[u(b,{label:t.$t(`createPage.create`),"no-caps":``,unelevated:``,class:`create-btn text-weight-bold rounded-borders`,loading:U.value,onClick:yt},null,8,[`label`,`loading`])])]),h(`div`,Je,s(M.value?t.$t(`createPage.notionExtractHint`):t.$t(`createPage.notionImportHint`)),1)])]),_:1}))}}),[[`__scopeId`,`data-v-4f4da343`]]);export{Ye as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.create-page[data-v-4f4da343]{background-color:#1a1a2e;min-height:100%;padding:48px 24px}.create-inner[data-v-4f4da343]{width:100%;max-width:700px}.create-title[data-v-4f4da343]{font-size:24px;line-height:1.3}.create-card[data-v-4f4da343]{background:#224;border:1px solid #444;overflow:hidden}.card-top-bar[data-v-4f4da343]{background:#1e1e3a;min-height:36px}.card-name-wrap[data-v-4f4da343]{background:#224;padding:8px 16px 4px}.card-name-wrap[data-v-4f4da343] .q-field__control{height:32px;min-height:32px;padding:0}.card-name-wrap[data-v-4f4da343] input{color:#e0e0e0;font-size:15px;font-weight:500}.card-name-wrap[data-v-4f4da343] input::placeholder{color:#555}.card-textarea-wrap[data-v-4f4da343]{background:#224}.repo-select[data-v-4f4da343]{min-width:160px;max-width:260px}.repo-select[data-v-4f4da343] .q-field__prepend{align-items:center;height:auto;padding-top:0}.create-textarea[data-v-4f4da343]{color:#d0d0d0;width:100%;padding:12px 16px 4px}.create-textarea[data-v-4f4da343] .q-field__control{padding:0}.create-textarea[data-v-4f4da343] textarea{color:#d0d0d0;resize:none;min-height:100px;font-size:14px;line-height:1.6}.create-textarea[data-v-4f4da343] textarea::placeholder{color:#666}.notion-toggle-btn[data-v-4f4da343]{background:#333;padding:2px 10px}.notion-url-wrap[data-v-4f4da343]{background:#1e1e3a;padding:8px 0 0}.notion-url-input[data-v-4f4da343]{padding:0 12px}.notion-url-input[data-v-4f4da343] .q-field__control{height:36px;min-height:36px;padding:0}.notion-url-input[data-v-4f4da343] input{color:#d0d0d0;font-size:13px}.notion-url-input[data-v-4f4da343] input::placeholder{color:#555;font-size:12px}.notion-error[data-v-4f4da343],.notion-valid[data-v-4f4da343]{padding-bottom:6px}.sentry-toggle-btn[data-v-4f4da343]{background:#333;padding:2px 10px}.sentry-url-wrap[data-v-4f4da343]{background:#1e1e3a;padding:8px 0 0}.sentry-url-input[data-v-4f4da343]{padding:0 12px}.sentry-url-input[data-v-4f4da343] .q-field__control{height:36px;min-height:36px;padding:0}.sentry-url-input[data-v-4f4da343] input{color:#d0d0d0;font-size:13px}.sentry-url-input[data-v-4f4da343] input::placeholder{color:#555;font-size:12px}.sentry-error[data-v-4f4da343],.sentry-valid[data-v-4f4da343]{padding-bottom:6px}.slide-enter-active[data-v-4f4da343],.slide-leave-active[data-v-4f4da343]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-4f4da343],.slide-leave-to[data-v-4f4da343]{opacity:0;max-height:0}.slide-enter-to[data-v-4f4da343],.slide-leave-from[data-v-4f4da343]{opacity:1;max-height:120px}.card-bottom-bar[data-v-4f4da343]{background:#1e1e3a}.bottom-row[data-v-4f4da343]{flex-wrap:wrap;min-height:40px}.bottom-row-agent[data-v-4f4da343]{border-bottom:1px solid #ffffff0f}.bottom-row-agent+.bottom-row-git[data-v-4f4da343]{background:#00000026}.skip-setup-btn[data-v-4f4da343]{min-height:28px;padding:2px 10px;font-size:11px}.skip-setup-btn[data-v-4f4da343] .q-btn__content{gap:4px}.skip-setup-btn[data-v-4f4da343] .q-icon{font-size:14px}.bottom-row-git .bottom-select.repo-select[data-v-4f4da343]{flex:280px;min-width:220px}.bottom-row-git .bottom-select.repo-select[data-v-4f4da343] input{color:#bbb;padding:0 4px;font-size:11px}.bottom-row-git .bottom-select.repo-select[data-v-4f4da343] input::placeholder{color:#666;font-style:italic}.bottom-row-git .bottom-select.branch-type-select[data-v-4f4da343],.bottom-row-git .bottom-select.branch-select[data-v-4f4da343]{flex:none}.bottom-select[data-v-4f4da343]{background:#333;min-width:60px;height:28px;padding:0 6px}.bottom-select[data-v-4f4da343] .q-field__control{height:28px;min-height:28px;padding:0}.bottom-select[data-v-4f4da343] .q-field__native{min-height:unset;padding:0}.bottom-select-label[data-v-4f4da343]{color:#bbb;gap:2px;font-size:11px}.bottom-sep[data-v-4f4da343]{color:#555;padding:0 2px;font-size:12px;line-height:1}.repo-path-wrap[data-v-4f4da343]{background:#333;border-radius:6px;height:28px;padding:0 8px}.repo-input[data-v-4f4da343]{min-width:140px}.repo-input[data-v-4f4da343] .q-field__control{height:28px;min-height:28px;padding:0}.repo-input[data-v-4f4da343] input{color:#bbb;font-size:11px}.repo-input[data-v-4f4da343] input::placeholder{color:#666;font-size:11px}.branch-select[data-v-4f4da343]{min-width:80px}.create-btn[data-v-4f4da343]{color:#fff;background:#4f46e5;min-width:220px;height:32px;padding:0 32px;font-size:13px}.create-btn[data-v-4f4da343] .q-btn__content{height:32px}.create-hint[data-v-4f4da343]{line-height:1.5}.fade-enter-active[data-v-4f4da343],.fade-leave-active[data-v-4f4da343]{transition:opacity .2s}.fade-enter-from[data-v-4f4da343],.fade-leave-to[data-v-4f4da343]{opacity:0}.manual-hint[data-v-4f4da343]{background:#1e1e3a;line-height:1.4}.manual-expansion[data-v-4f4da343]{background:#1e1e3a;border:1px solid #333;border-radius:4px;margin-top:6px;overflow:hidden}.manual-expansion[data-v-4f4da343] .manual-expansion-header{min-height:32px;padding:4px 10px;font-size:12px}.manual-expansion[data-v-4f4da343] .q-expansion-item__content,.manual-section-body[data-v-4f4da343]{background:#1a1a2e}.manual-input[data-v-4f4da343] .q-field__control{height:26px;min-height:26px;padding:0}.manual-input[data-v-4f4da343] input{color:#e0e0e0;font-size:12px}.manual-input[data-v-4f4da343] input::placeholder{color:#555}.manual-item[data-v-4f4da343]{border-top:1px solid #ffffff0a}.manual-item[data-v-4f4da343]:first-child{border-top:none}
|