@loicngr/kobo 1.6.3 → 1.6.5

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 (157) hide show
  1. package/dist/server/routes/workspaces.js +151 -5
  2. package/dist/server/services/agent/engines/claude-code/args-builder.js +10 -4
  3. package/dist/server/services/settings-service.js +25 -1
  4. package/dist/server/services/workspace-service.js +10 -2
  5. package/dist/server/utils/git-ops.js +137 -0
  6. package/package.json +1 -1
  7. package/src/client/dist/spa/assets/ActivityFeed-DETQbE-a.js +7 -0
  8. package/src/client/dist/spa/assets/{ActivityFeed-BCPHgr3p.css → ActivityFeed-GAoo1WOT.css} +1 -1
  9. package/src/client/dist/spa/assets/ClosePopup-DTgXzcoa.js +1 -0
  10. package/src/client/dist/spa/assets/{CreatePage-C2mUAcwE.js → CreatePage-B7e487jg.js} +1 -1
  11. package/src/client/dist/spa/assets/DiffViewer-4-z5gGzs.js +2 -0
  12. package/src/client/dist/spa/assets/DiffViewer-BC81-2me.css +1 -0
  13. package/src/client/dist/spa/assets/{HealthPage-CJDF2_4D.js → HealthPage-Pof_7jsi.js} +1 -1
  14. package/src/client/dist/spa/assets/{MainLayout-K2u9uIOb.js → MainLayout-CJJ8RX8d.js} +17 -17
  15. package/src/client/dist/spa/assets/MainLayout-Cb6_QXbV.css +1 -0
  16. package/src/client/dist/spa/assets/QChip-1nQ_KMFF.js +1 -0
  17. package/src/client/dist/spa/assets/QDialog-G448EJG4.js +1 -0
  18. package/src/client/dist/spa/assets/{QExpansionItem-DCRks-Ra.js → QExpansionItem-HLBjHx-0.js} +1 -1
  19. package/src/client/dist/spa/assets/QScrollArea-CBW6shMb.js +1 -0
  20. package/src/client/dist/spa/assets/{QSeparator-rkjCbX2M.js → QSeparator-DNSiXYrN.js} +1 -1
  21. package/src/client/dist/spa/assets/QTabPanels-Cw4nnIbR.js +1 -0
  22. package/src/client/dist/spa/assets/QTooltip-DbEBexRN.js +1 -0
  23. package/src/client/dist/spa/assets/{SearchPage-Drjd-r_Y.js → SearchPage-Do9kkaR_.js} +1 -1
  24. package/src/client/dist/spa/assets/{SettingsPage-DvqT-ViK.js → SettingsPage-CpvnCfxM.js} +1 -1
  25. package/src/client/dist/spa/assets/TouchPan-Y_Bxzun2.js +1 -0
  26. package/src/client/dist/spa/assets/{WorkspacePage-Bk_SslTv.js → WorkspacePage-De-8vIz8.js} +3 -3
  27. package/src/client/dist/spa/assets/{build-path-tree-BE2FoPWg.js → build-path-tree-DBKR9p4C.js} +1 -1
  28. package/src/client/dist/spa/assets/{cssMode-0GRgcPCL.js → cssMode-D7H4G9u2.js} +1 -1
  29. package/src/client/dist/spa/assets/{documents-BJW_8dHZ.js → documents-CByb0FJM.js} +1 -1
  30. package/src/client/dist/spa/assets/{editor.api-C1-xuJKd.js → editor.api--wqcZBpd.js} +1 -1
  31. package/src/client/dist/spa/assets/{editor.main-C2QDgca3.js → editor.main-BNIb69JB.js} +3 -3
  32. package/src/client/dist/spa/assets/{formatters-BDadphwz.js → formatters-D7eTm7uK.js} +1 -1
  33. package/src/client/dist/spa/assets/{freemarker2-Dgc_0Q23.js → freemarker2-D-thr4Nz.js} +1 -1
  34. package/src/client/dist/spa/assets/{handlebars-DkfsYZsi.js → handlebars-uz-Lnmlq.js} +1 -1
  35. package/src/client/dist/spa/assets/{html-CbSyHFvE.js → html-BrD38Itg.js} +1 -1
  36. package/src/client/dist/spa/assets/{htmlMode-BKR6h-2d.js → htmlMode-DhJl0i4i.js} +1 -1
  37. package/src/client/dist/spa/assets/i18n-DBt4wD57.js +1 -0
  38. package/src/client/dist/spa/assets/index-B0Jj-w-E.js +2 -0
  39. package/src/client/dist/spa/assets/{javascript-QJqA2E1u.js → javascript-PJBbOo9I.js} +1 -1
  40. package/src/client/dist/spa/assets/{jsonMode-D8CXYQiy.js → jsonMode-D4akRBRs.js} +1 -1
  41. package/src/client/dist/spa/assets/{liquid-DLssQpNB.js → liquid-EUlazot7.js} +1 -1
  42. package/src/client/dist/spa/assets/{mdx-4u6l2_x4.js → mdx-BGyD5-MK.js} +1 -1
  43. package/src/client/dist/spa/assets/models-GweeyU2r.js +1 -0
  44. package/src/client/dist/spa/assets/{monaco.contribution-DFCuvXsm.js → monaco.contribution-Ci35AF1I.js} +2 -2
  45. package/src/client/dist/spa/assets/private.use-form-C5G_3nU5.js +1 -0
  46. package/src/client/dist/spa/assets/{python-BFIl5AC4.js → python-BG_aaGdU.js} +1 -1
  47. package/src/client/dist/spa/assets/{razor-BrKtxN6e.js → razor-BWRO_-vh.js} +1 -1
  48. package/src/client/dist/spa/assets/scroll-C-Vz5BD9.js +1 -0
  49. package/src/client/dist/spa/assets/touch-B2uuAH_y.js +1 -0
  50. package/src/client/dist/spa/assets/{tsMode-B7FS-eG8.js → tsMode-CfJ3FSRi.js} +1 -1
  51. package/src/client/dist/spa/assets/{typescript-CpUDqcsF.js → typescript-BD5IT0Pn.js} +1 -1
  52. package/src/client/dist/spa/assets/{use-checkbox-DYiZQsbF.js → use-checkbox-BduGd8xg.js} +1 -1
  53. package/src/client/dist/spa/assets/{use-id-CeduaJbU.js → use-id-BmXMngYX.js} +1 -1
  54. package/src/client/dist/spa/assets/{xml-_L0I3U6m.js → xml-DBx8yQFe.js} +1 -1
  55. package/src/client/dist/spa/assets/{yaml-CY3U_Y-0.js → yaml-DdHKmdlx.js} +1 -1
  56. package/src/client/dist/spa/index.html +8 -9
  57. package/src/client/dist/spa/assets/ActivityFeed-DPg8lZZP.js +0 -7
  58. package/src/client/dist/spa/assets/ClosePopup-DhM1C4Zw.js +0 -1
  59. package/src/client/dist/spa/assets/DiffViewer-BVU58ujc.css +0 -1
  60. package/src/client/dist/spa/assets/DiffViewer-DdLwXeB3.js +0 -2
  61. package/src/client/dist/spa/assets/MainLayout-BiBJtDTk.css +0 -1
  62. package/src/client/dist/spa/assets/QChip-KJoHYE6F.js +0 -1
  63. package/src/client/dist/spa/assets/QDialog-DQeAxY3-.js +0 -1
  64. package/src/client/dist/spa/assets/QScrollArea-e5qTqwcb.js +0 -1
  65. package/src/client/dist/spa/assets/QTabPanels--6cYe2US.js +0 -1
  66. package/src/client/dist/spa/assets/QTooltip-C4CPesBX.js +0 -1
  67. package/src/client/dist/spa/assets/TouchPan-BT6phK1f.js +0 -1
  68. package/src/client/dist/spa/assets/format-Bttc9ToS.js +0 -1
  69. package/src/client/dist/spa/assets/i18n-C03q300x.js +0 -1
  70. package/src/client/dist/spa/assets/index-9vZWx9Bu.js +0 -2
  71. package/src/client/dist/spa/assets/models-BtywKe_m.js +0 -1
  72. package/src/client/dist/spa/assets/private.use-form-D1RuEt2P.js +0 -1
  73. package/src/client/dist/spa/assets/scroll-JVVkg2Ng.js +0 -1
  74. package/src/client/dist/spa/assets/touch-CBLrR6_z.js +0 -1
  75. package/src/client/dist/spa/assets/use-portal-DBe4lcC2.js +0 -1
  76. /package/src/client/dist/spa/assets/{QBadge-DqtcDv8D.js → QBadge-Di02fu2H.js} +0 -0
  77. /package/src/client/dist/spa/assets/{QItemLabel-Codqjisk.js → QItemLabel-Czw5g0px.js} +0 -0
  78. /package/src/client/dist/spa/assets/{QItemSection-CGpX7GcL.js → QItemSection-BzWLL-V-.js} +0 -0
  79. /package/src/client/dist/spa/assets/{QList-B-MkPF7n.js → QList-D2GuTeLl.js} +0 -0
  80. /package/src/client/dist/spa/assets/{QPage-yqdKDG7-.js → QPage-BTzNQlb1.js} +0 -0
  81. /package/src/client/dist/spa/assets/{QSlideTransition-BQxI8l5r.js → QSlideTransition-s6ZkYsLs.js} +0 -0
  82. /package/src/client/dist/spa/assets/{QSpace-BNr0AftG.js → QSpace-0zdF1m5x.js} +0 -0
  83. /package/src/client/dist/spa/assets/{QSpinnerDots-DEiRooBD.js → QSpinnerDots-By20ptst.js} +0 -0
  84. /package/src/client/dist/spa/assets/{_plugin-vue_export-helper-r4mAJOHR.js → _plugin-vue_export-helper-Cj6tcsj6.js} +0 -0
  85. /package/src/client/dist/spa/assets/{abap-Bgec7Keq.js → abap-DiwvWnMr.js} +0 -0
  86. /package/src/client/dist/spa/assets/{apex-VBlPwEoQ.js → apex-CmtZjKlf.js} +0 -0
  87. /package/src/client/dist/spa/assets/{azcli-DKqrEFBx.js → azcli-DL2My_i-.js} +0 -0
  88. /package/src/client/dist/spa/assets/{bat-DdgQWy_0.js → bat-B-nC98wG.js} +0 -0
  89. /package/src/client/dist/spa/assets/{bicep-CRMM43EB.js → bicep-Ju5MwOgh.js} +0 -0
  90. /package/src/client/dist/spa/assets/{cameligo-UatALtML.js → cameligo-8Eu1TyBr.js} +0 -0
  91. /package/src/client/dist/spa/assets/{clojure-D8JU08RA.js → clojure-u-RpMkH3.js} +0 -0
  92. /package/src/client/dist/spa/assets/{coffee-C56wu358.js → coffee-CdA7bbTe.js} +0 -0
  93. /package/src/client/dist/spa/assets/{cpp-CyZLvhJG.js → cpp-CzNFP8ks.js} +0 -0
  94. /package/src/client/dist/spa/assets/{csharp-BJl3ixva.js → csharp-j1LThmcE.js} +0 -0
  95. /package/src/client/dist/spa/assets/{csp-CxEKxmO-.js → csp-CLRC61y6.js} +0 -0
  96. /package/src/client/dist/spa/assets/{css-B0t_muXd.js → css-r6rC_7P2.js} +0 -0
  97. /package/src/client/dist/spa/assets/{cypher-D1hqiMFD.js → cypher-CW08XVUh.js} +0 -0
  98. /package/src/client/dist/spa/assets/{dart-Bz550Pyv.js → dart-Cs9aL5T_.js} +0 -0
  99. /package/src/client/dist/spa/assets/{dockerfile-CIXgVAuA.js → dockerfile-BWM0M184.js} +0 -0
  100. /package/src/client/dist/spa/assets/{ecl-D9qbvZoA.js → ecl-MJJuer5P.js} +0 -0
  101. /package/src/client/dist/spa/assets/{elixir-b2M38fAy.js → elixir-D2AIuXqn.js} +0 -0
  102. /package/src/client/dist/spa/assets/{flow9-Dq1UYMkt.js → flow9-B2H24giC.js} +0 -0
  103. /package/src/client/dist/spa/assets/{fsharp-CFNadkg7.js → fsharp-CMk2OIJN.js} +0 -0
  104. /package/src/client/dist/spa/assets/{go-dSur1iB2.js → go-BrMkuJg0.js} +0 -0
  105. /package/src/client/dist/spa/assets/{graphql-qyhAo11d.js → graphql-PSR1UKGv.js} +0 -0
  106. /package/src/client/dist/spa/assets/{hcl-DFzjMyzm.js → hcl-DAQrbDOW.js} +0 -0
  107. /package/src/client/dist/spa/assets/{ini-TdzA8TIl.js → ini-0TG5BxW0.js} +0 -0
  108. /package/src/client/dist/spa/assets/{java-CSGA9pkE.js → java-rgorz17v.js} +0 -0
  109. /package/src/client/dist/spa/assets/{julia-9izz5OsY.js → julia-C8VMdHm8.js} +0 -0
  110. /package/src/client/dist/spa/assets/{kotlin-DuPK7AtF.js → kotlin-CllWo3gX.js} +0 -0
  111. /package/src/client/dist/spa/assets/{less-B8d93iCg.js → less-Cgca25AP.js} +0 -0
  112. /package/src/client/dist/spa/assets/{lexon-DWtEIyu7.js → lexon-D0GHdBaw.js} +0 -0
  113. /package/src/client/dist/spa/assets/{lua-Ciq0OGgt.js → lua-DmRsNG-P.js} +0 -0
  114. /package/src/client/dist/spa/assets/{m3-Cki6JWj_.js → m3-BgL5dNKT.js} +0 -0
  115. /package/src/client/dist/spa/assets/{markdown-Cu47xwU0.js → markdown-BuJfycGS.js} +0 -0
  116. /package/src/client/dist/spa/assets/{mips-BM8ui995.js → mips-C9m_93PR.js} +0 -0
  117. /package/src/client/dist/spa/assets/{msdax-DqLio0_c.js → msdax-CpFHC9OI.js} +0 -0
  118. /package/src/client/dist/spa/assets/{mysql-v1wbjJOq.js → mysql-qFvltsqN.js} +0 -0
  119. /package/src/client/dist/spa/assets/{objective-c-CQl3PGSB.js → objective-c-Bnmr858J.js} +0 -0
  120. /package/src/client/dist/spa/assets/{pascal-D4iW0ZtD.js → pascal-WP0_D5AO.js} +0 -0
  121. /package/src/client/dist/spa/assets/{pascaligo-BdC9CZdj.js → pascaligo-Blom4Rij.js} +0 -0
  122. /package/src/client/dist/spa/assets/{perl-BL10m4XD.js → perl-B-vk8g64.js} +0 -0
  123. /package/src/client/dist/spa/assets/{pgsql-Be_oqVo3.js → pgsql-Cgvz6v67.js} +0 -0
  124. /package/src/client/dist/spa/assets/{php-BtvXSFRI.js → php-8a3Lrw9m.js} +0 -0
  125. /package/src/client/dist/spa/assets/{pla-B2vUy15C.js → pla-DuFqEZ8V.js} +0 -0
  126. /package/src/client/dist/spa/assets/{postiats-CbmTTfXr.js → postiats-DkLtSgkp.js} +0 -0
  127. /package/src/client/dist/spa/assets/{powerquery-DszLhJGx.js → powerquery-BJ1aNepW.js} +0 -0
  128. /package/src/client/dist/spa/assets/{powershell-B0dYktF6.js → powershell-rE98k687.js} +0 -0
  129. /package/src/client/dist/spa/assets/{protobuf-CZvaj1VX.js → protobuf-CUheFacr.js} +0 -0
  130. /package/src/client/dist/spa/assets/{pug-CPDx1B3S.js → pug-LDcAMD8w.js} +0 -0
  131. /package/src/client/dist/spa/assets/{qsharp-CDP9TFLl.js → qsharp-DUKSQoR1.js} +0 -0
  132. /package/src/client/dist/spa/assets/{r-8DbbFX2l.js → r-D-QApv87.js} +0 -0
  133. /package/src/client/dist/spa/assets/{rate-limit-labels-BoDORKFj.js → rate-limit-labels-Su-L56A2.js} +0 -0
  134. /package/src/client/dist/spa/assets/{redis-DRWj9MtJ.js → redis-SXdDyWR9.js} +0 -0
  135. /package/src/client/dist/spa/assets/{redshift-C6cElE_5.js → redshift-Y6lsCryn.js} +0 -0
  136. /package/src/client/dist/spa/assets/{restructuredtext-W9pS9n3m.js → restructuredtext-edObr9a8.js} +0 -0
  137. /package/src/client/dist/spa/assets/{ruby-BKnzWnk-.js → ruby-CNnUfF-8.js} +0 -0
  138. /package/src/client/dist/spa/assets/{rust-YPCclWwe.js → rust-IHUZWzBr.js} +0 -0
  139. /package/src/client/dist/spa/assets/{sb-BgM4DTFb.js → sb-DrUvY44N.js} +0 -0
  140. /package/src/client/dist/spa/assets/{scala-fz1OPLMl.js → scala-B4hbXGLM.js} +0 -0
  141. /package/src/client/dist/spa/assets/{scheme-8Uz1RIbu.js → scheme-BGrd12j3.js} +0 -0
  142. /package/src/client/dist/spa/assets/{scss-Djo3IYXr.js → scss-x5G1ES4U.js} +0 -0
  143. /package/src/client/dist/spa/assets/{shell-CINF5Tx_.js → shell-DOehe2Y8.js} +0 -0
  144. /package/src/client/dist/spa/assets/{solidity-GgiNEuUm.js → solidity-BeRvcwWV.js} +0 -0
  145. /package/src/client/dist/spa/assets/{sophia-Culj97P9.js → sophia-DZbkUNjy.js} +0 -0
  146. /package/src/client/dist/spa/assets/{sparql-C2ZlpxOY.js → sparql-B7_oi5-h.js} +0 -0
  147. /package/src/client/dist/spa/assets/{sql-BEf5Pg7Y.js → sql-CTlsFWVE.js} +0 -0
  148. /package/src/client/dist/spa/assets/{st-CT6UUoeH.js → st-DJVEJdPE.js} +0 -0
  149. /package/src/client/dist/spa/assets/{swift-B5g0xTG3.js → swift-CwhT3fYa.js} +0 -0
  150. /package/src/client/dist/spa/assets/{systemverilog-CEgQz9DR.js → systemverilog-BQN63pkN.js} +0 -0
  151. /package/src/client/dist/spa/assets/{tcl-D0qL2L0I.js → tcl-DqwfpskA.js} +0 -0
  152. /package/src/client/dist/spa/assets/{twig-BFUAVf1E.js → twig-BiyenUgc.js} +0 -0
  153. /package/src/client/dist/spa/assets/{typespec-CjVVcNKm.js → typespec-CWOJribt.js} +0 -0
  154. /package/src/client/dist/spa/assets/{use-quasar-Ch82z8H5.js → use-quasar-BBrzedjR.js} +0 -0
  155. /package/src/client/dist/spa/assets/{vb-CZJr-DQz.js → vb-Cq5F87m3.js} +0 -0
  156. /package/src/client/dist/spa/assets/{vue-i18n-CeG0hR0Z.js → vue-i18n-eUDnMrPl.js} +0 -0
  157. /package/src/client/dist/spa/assets/{wgsl-ivoXUo2e.js → wgsl-BAvW2lVr.js} +0 -0
@@ -76,6 +76,27 @@ app.post('/', migrationGuard, async (c) => {
76
76
  });
77
77
  let notionContent = null;
78
78
  let sentryContent = null;
79
+ // Auto-tag the workspace based on its creation source — `notion` when
80
+ // imported from a Notion page, `sentry` when bootstrapped from a Sentry
81
+ // issue URL. Pre-seeded in the global tag catalogue via migration v9.
82
+ // Skip any tag the user has removed from the catalogue so we respect
83
+ // their choice (they may have pruned "notion"/"sentry" on purpose).
84
+ const catalogTags = new Set(globalSettings.tags ?? []);
85
+ const autoTags = [];
86
+ if (body.notionUrl && catalogTags.has('notion'))
87
+ autoTags.push('notion');
88
+ if (body.sentryUrl && catalogTags.has('sentry'))
89
+ autoTags.push('sentry');
90
+ if (autoTags.length > 0) {
91
+ try {
92
+ const tagged = workspaceService.setWorkspaceTags(workspace.id, autoTags);
93
+ if (tagged)
94
+ workspace = tagged;
95
+ }
96
+ catch (err) {
97
+ console.error('[workspaces] Failed to apply auto tags:', err);
98
+ }
99
+ }
79
100
  // Extract Notion page content if a URL was provided
80
101
  if (body.notionUrl) {
81
102
  workspaceService.updateWorkspaceStatus(workspace.id, 'extracting');
@@ -1143,18 +1164,27 @@ app.get('/:id/git-stats', async (c) => {
1143
1164
  return c.json({ error: message }, 500);
1144
1165
  }
1145
1166
  });
1146
- // GET /api/workspaces/:id/diff — list changed files
1167
+ // GET /api/workspaces/:id/diff?mode=branch|unpushed — list changed files
1168
+ // - `branch` (default): committed + working tree changes vs sourceBranch,
1169
+ // i.e. what the PR will contain.
1170
+ // - `unpushed`: committed-only changes vs `origin/<workingBranch>`,
1171
+ // i.e. what the next `git push` will send.
1147
1172
  app.get('/:id/diff', (c) => {
1148
1173
  try {
1149
1174
  const id = c.req.param('id');
1175
+ const mode = c.req.query('mode') === 'unpushed' ? 'unpushed' : 'branch';
1150
1176
  const workspace = workspaceService.getWorkspace(id);
1151
1177
  if (!workspace) {
1152
1178
  return c.json({ error: `Workspace '${id}' not found` }, 404);
1153
1179
  }
1154
1180
  const worktreePath = path.join(workspace.projectPath, '.worktrees', workspace.workingBranch);
1155
- const files = gitOps.getChangedFiles(worktreePath, workspace.sourceBranch);
1181
+ const files = mode === 'unpushed'
1182
+ ? gitOps.getUnpushedChangedFiles(worktreePath, workspace.workingBranch)
1183
+ : gitOps.getChangedFiles(worktreePath, workspace.sourceBranch);
1184
+ c.header('Cache-Control', 'no-store');
1156
1185
  return c.json({
1157
1186
  files,
1187
+ mode,
1158
1188
  sourceBranch: workspace.sourceBranch,
1159
1189
  workingBranch: workspace.workingBranch,
1160
1190
  });
@@ -1164,11 +1194,16 @@ app.get('/:id/diff', (c) => {
1164
1194
  return c.json({ error: message }, 500);
1165
1195
  }
1166
1196
  });
1167
- // GET /api/workspaces/:id/diff/:filePath — get original and modified content for a file
1197
+ // GET /api/workspaces/:id/diff-file?path=...&mode=branch|unpushed
1198
+ // Resolves `original` at the appropriate base ref:
1199
+ // - `branch` → sourceBranch
1200
+ // - `unpushed` → origin/<workingBranch>
1201
+ // `modified` is always the current worktree content.
1168
1202
  app.get('/:id/diff-file', (c) => {
1169
1203
  try {
1170
1204
  const id = c.req.param('id');
1171
1205
  const filePath = c.req.query('path');
1206
+ const mode = c.req.query('mode') === 'unpushed' ? 'unpushed' : 'branch';
1172
1207
  if (!filePath) {
1173
1208
  return c.json({ error: 'Missing path query parameter' }, 400);
1174
1209
  }
@@ -1177,9 +1212,120 @@ app.get('/:id/diff-file', (c) => {
1177
1212
  return c.json({ error: `Workspace '${id}' not found` }, 404);
1178
1213
  }
1179
1214
  const worktreePath = path.join(workspace.projectPath, '.worktrees', workspace.workingBranch);
1180
- const original = gitOps.getFileAtRef(worktreePath, workspace.sourceBranch, filePath);
1215
+ const baseRef = mode === 'unpushed' ? `origin/${workspace.workingBranch}` : workspace.sourceBranch;
1216
+ const original = gitOps.getFileAtRef(worktreePath, baseRef, filePath);
1181
1217
  const modified = gitOps.getFileContent(worktreePath, filePath);
1182
- return c.json({ original: original ?? '', modified: modified ?? '', filePath });
1218
+ c.header('Cache-Control', 'no-store');
1219
+ return c.json({ original: original ?? '', modified: modified ?? '', filePath, mode });
1220
+ }
1221
+ catch (err) {
1222
+ const message = err instanceof Error ? err.message : String(err);
1223
+ return c.json({ error: message }, 500);
1224
+ }
1225
+ });
1226
+ // GET /api/workspaces/:id/commits?limit=50 — list commits between sourceBranch
1227
+ // and HEAD, each tagged with whether it's already pushed to origin/<branch>.
1228
+ app.get('/:id/commits', (c) => {
1229
+ try {
1230
+ const id = c.req.param('id');
1231
+ const workspace = workspaceService.getWorkspace(id);
1232
+ if (!workspace) {
1233
+ return c.json({ error: `Workspace '${id}' not found` }, 404);
1234
+ }
1235
+ const limitRaw = c.req.query('limit');
1236
+ const limit = Math.min(Math.max(1, parseInt(limitRaw ?? '50', 10) || 50), 200);
1237
+ const worktreePath = path.join(workspace.projectPath, '.worktrees', workspace.workingBranch);
1238
+ const commits = gitOps.listBranchCommits(worktreePath, workspace.sourceBranch, workspace.workingBranch, limit);
1239
+ c.header('Cache-Control', 'no-store');
1240
+ return c.json({ commits, sourceBranch: workspace.sourceBranch, workingBranch: workspace.workingBranch });
1241
+ }
1242
+ catch (err) {
1243
+ const message = err instanceof Error ? err.message : String(err);
1244
+ return c.json({ error: message }, 500);
1245
+ }
1246
+ });
1247
+ // POST /api/workspaces/:id/rename-branch { newName }
1248
+ // Rename the working branch in git, move the worktree dir to match, and
1249
+ // update the DB. Run as one atomic operation from the UI "Rename branch"
1250
+ // action. If the worktree move fails (dirty tree, etc.) the branch rename
1251
+ // is kept — the DB is still updated so Kōbō tracks the current name.
1252
+ app.post('/:id/rename-branch', async (c) => {
1253
+ try {
1254
+ const id = c.req.param('id');
1255
+ const body = (await c.req.json().catch(() => ({})));
1256
+ const newName = typeof body.newName === 'string' ? body.newName.trim() : '';
1257
+ if (!newName) {
1258
+ return c.json({ error: 'newName is required' }, 400);
1259
+ }
1260
+ if (!/^[A-Za-z0-9/_\-.]+$/.test(newName)) {
1261
+ return c.json({ error: 'Invalid branch name (only letters, digits, /, _, -, . allowed)' }, 400);
1262
+ }
1263
+ const workspace = workspaceService.getWorkspace(id);
1264
+ if (!workspace) {
1265
+ return c.json({ error: `Workspace '${id}' not found` }, 404);
1266
+ }
1267
+ if (newName === workspace.workingBranch) {
1268
+ return c.json(workspace); // no-op
1269
+ }
1270
+ const oldWorktreePath = path.join(workspace.projectPath, '.worktrees', workspace.workingBranch);
1271
+ const newWorktreePath = path.join(workspace.projectPath, '.worktrees', newName);
1272
+ // Reject early if the target name is already in use — either as a local
1273
+ // branch or on origin. Avoids git's generic "already exists" error and
1274
+ // protects against the same silent-fallback trap the create flow has.
1275
+ if (gitOps.branchExists(oldWorktreePath, newName)) {
1276
+ return c.json({ error: `Branch '${newName}' already exists (locally or on origin)`, code: 'branch_exists' }, 409);
1277
+ }
1278
+ try {
1279
+ gitOps.renameBranch(oldWorktreePath, workspace.workingBranch, newName);
1280
+ }
1281
+ catch (err) {
1282
+ const message = err instanceof Error ? err.message : String(err);
1283
+ return c.json({ error: `Failed to rename git branch: ${message}` }, 500);
1284
+ }
1285
+ // Best-effort: align the worktree dir with the new branch name. If the
1286
+ // tree is dirty or another process holds a lock, skip silently — the
1287
+ // worktree keeps working under its old path, and Kōbō uses the ref name,
1288
+ // not the dir, for git operations.
1289
+ try {
1290
+ gitOps.moveWorktree(workspace.projectPath, oldWorktreePath, newWorktreePath);
1291
+ }
1292
+ catch (err) {
1293
+ console.error('[workspaces] Failed to move worktree dir (branch renamed anyway):', err);
1294
+ }
1295
+ const updated = workspaceService.updateWorkingBranch(id, newName);
1296
+ return c.json(updated);
1297
+ }
1298
+ catch (err) {
1299
+ const message = err instanceof Error ? err.message : String(err);
1300
+ return c.json({ error: message }, 500);
1301
+ }
1302
+ });
1303
+ // POST /api/workspaces/:id/resync-branch
1304
+ // Read the real current branch name inside the worktree (via
1305
+ // `git rev-parse --abbrev-ref HEAD`) and update the DB if it drifted. Used
1306
+ // after the agent renames the branch from the chat (`git branch -m …`).
1307
+ app.post('/:id/resync-branch', (c) => {
1308
+ try {
1309
+ const id = c.req.param('id');
1310
+ const workspace = workspaceService.getWorkspace(id);
1311
+ if (!workspace) {
1312
+ return c.json({ error: `Workspace '${id}' not found` }, 404);
1313
+ }
1314
+ const worktreePath = path.join(workspace.projectPath, '.worktrees', workspace.workingBranch);
1315
+ let actual;
1316
+ try {
1317
+ actual = gitOps.getCurrentBranch(worktreePath).trim();
1318
+ }
1319
+ catch (err) {
1320
+ // Could mean the dir was moved too — try scanning worktrees.
1321
+ const message = err instanceof Error ? err.message : String(err);
1322
+ return c.json({ error: `Could not read HEAD: ${message}` }, 500);
1323
+ }
1324
+ if (!actual || actual === workspace.workingBranch) {
1325
+ return c.json({ ok: true, changed: false, workingBranch: workspace.workingBranch });
1326
+ }
1327
+ const updated = workspaceService.updateWorkingBranch(id, actual);
1328
+ return c.json({ ok: true, changed: true, workingBranch: updated.workingBranch });
1183
1329
  }
1184
1330
  catch (err) {
1185
1331
  const message = err instanceof Error ? err.message : String(err);
@@ -16,17 +16,23 @@ const KOBO_MCP_BRIEF = [
16
16
  ].join('\n');
17
17
  export function buildClaudeArgs(input) {
18
18
  const args = ['--output-format', 'stream-json', '--verbose'];
19
- if (input.skipPermissions)
19
+ // `plan` mode is handled by Claude Code natively via `--permission-mode plan`.
20
+ // Under plan mode, Claude restricts itself to read-only tools and surfaces an
21
+ // `ExitPlanMode` tool call when the plan is ready for the user to approve.
22
+ // `--dangerously-skip-permissions` is incompatible with plan mode (it would
23
+ // bypass the very restriction plan mode enforces), so we skip it here.
24
+ if (input.permissionMode === 'plan') {
25
+ args.push('--permission-mode', 'plan');
26
+ }
27
+ else if (input.skipPermissions) {
20
28
  args.push('--dangerously-skip-permissions');
29
+ }
21
30
  let prompt = input.prompt;
22
31
  // Only prepend the MCP brief on a fresh session — on --resume, the previous
23
32
  // turn's context already contains it, and re-prepending would spam.
24
33
  if (!input.resumeFromEngineSessionId) {
25
34
  prompt = `${KOBO_MCP_BRIEF}\n\n${prompt}`;
26
35
  }
27
- if (input.permissionMode === 'plan') {
28
- prompt = `[PLAN MODE] You are in PLAN/READ-ONLY mode. You MUST NOT create, edit, write, or delete any files. Only use read-only tools (Read, Grep, Glob, LS, Bash for read-only commands). Analyze the codebase, plan your approach, and present your findings — but do NOT execute any changes.\n\n${prompt}`;
29
- }
30
36
  if (input.model && input.model !== 'auto')
31
37
  args.push('--model', input.model);
32
38
  if (input.effort && input.effort !== 'auto')
@@ -54,7 +54,17 @@ Please:
54
54
  4. Do NOT add a "Generated with Claude Code" footer or any AI attribution to the PR description
55
55
  `;
56
56
  /** Default workspace tags seeded on fresh install and on settings upgrade. */
57
- export const DEFAULT_WORKSPACE_TAGS = ['bug', 'feature', 'refactor', 'docs', 'wip', 'urgent', 'blocked'];
57
+ export const DEFAULT_WORKSPACE_TAGS = [
58
+ 'bug',
59
+ 'feature',
60
+ 'refactor',
61
+ 'docs',
62
+ 'wip',
63
+ 'urgent',
64
+ 'blocked',
65
+ 'notion',
66
+ 'sentry',
67
+ ];
58
68
  const settingsMigrations = [
59
69
  {
60
70
  version: 1,
@@ -146,6 +156,20 @@ const settingsMigrations = [
146
156
  global.tags = [...DEFAULT_WORKSPACE_TAGS];
147
157
  },
148
158
  },
159
+ {
160
+ version: 9,
161
+ name: 'add-notion-sentry-default-tags',
162
+ migrate({ global }) {
163
+ if (!Array.isArray(global.tags)) {
164
+ global.tags = [...DEFAULT_WORKSPACE_TAGS];
165
+ return;
166
+ }
167
+ for (const t of ['notion', 'sentry']) {
168
+ if (!global.tags.includes(t))
169
+ global.tags.push(t);
170
+ }
171
+ },
172
+ },
149
173
  ];
150
174
  /** Current settings schema version — always equals the highest migration version. */
151
175
  export const SETTINGS_SCHEMA_VERSION = settingsMigrations.length > 0 ? settingsMigrations[settingsMigrations.length - 1].version : 0;
@@ -159,13 +159,21 @@ export function updateWorkspaceReasoningEffort(id, reasoningEffort) {
159
159
  }
160
160
  return getWorkspace(id);
161
161
  }
162
- /** Update the working branch for a workspace (e.g. after ticket ID injection). */
162
+ /**
163
+ * Update the working branch for a workspace. Used both after ticket-ID
164
+ * injection at creation time and after the rename-branch / resync-branch
165
+ * endpoints. Rejects empty / whitespace-only names.
166
+ */
163
167
  export function updateWorkingBranch(id, workingBranch) {
168
+ const sanitized = workingBranch.trim();
169
+ if (!sanitized) {
170
+ throw new Error('Branch name cannot be empty');
171
+ }
164
172
  const db = getDb();
165
173
  const now = new Date().toISOString();
166
174
  const result = db
167
175
  .prepare('UPDATE workspaces SET working_branch = ?, updated_at = ? WHERE id = ?')
168
- .run(workingBranch, now, id);
176
+ .run(sanitized, now, id);
169
177
  if (result.changes === 0) {
170
178
  throw new Error(`Workspace '${id}' not found`);
171
179
  }
@@ -273,6 +273,58 @@ export function getCommitsBetween(repoPath, base, head) {
273
273
  return '';
274
274
  }
275
275
  }
276
+ /**
277
+ * List commits between the source branch and HEAD, each flagged with whether
278
+ * it's already present on `origin/<workingBranch>`. Used by the Git panel
279
+ * to surface "commits waiting to be pushed" vs "commits already pushed".
280
+ * Up to `limit` commits (most recent first).
281
+ */
282
+ export function listBranchCommits(repoPath, sourceBranch, workingBranch, limit = 50, remote = 'origin') {
283
+ const sourceRef = resolveBase(repoPath, sourceBranch);
284
+ const remoteRef = `${remote}/${workingBranch}`;
285
+ // NUL-delimited format: sha \0 shortSha \0 subject \0 author \0 iso date \n
286
+ const FORMAT = '--pretty=format:%H%x00%h%x00%s%x00%an%x00%aI';
287
+ let raw;
288
+ try {
289
+ raw = git(repoPath, ['log', `${sourceRef}..HEAD`, `--max-count=${limit}`, FORMAT]);
290
+ }
291
+ catch {
292
+ return [];
293
+ }
294
+ if (!raw)
295
+ return [];
296
+ // Figure out which commits are already on the remote — bail out quietly if
297
+ // the remote ref doesn't exist (branch never pushed → every commit is unpushed).
298
+ const pushedShas = new Set();
299
+ try {
300
+ git(repoPath, ['rev-parse', '--verify', remoteRef]);
301
+ const pushedRaw = git(repoPath, ['log', `${sourceRef}..${remoteRef}`, '--pretty=format:%H']);
302
+ for (const line of pushedRaw.split('\n')) {
303
+ if (line)
304
+ pushedShas.add(line.trim());
305
+ }
306
+ }
307
+ catch {
308
+ // remote ref unknown → leave pushedShas empty
309
+ }
310
+ const commits = [];
311
+ for (const line of raw.split('\n')) {
312
+ if (!line)
313
+ continue;
314
+ const [sha, shortSha, subject, author, date] = line.split('\x00');
315
+ if (!sha)
316
+ continue;
317
+ commits.push({
318
+ sha,
319
+ shortSha: shortSha ?? '',
320
+ subject: subject ?? '',
321
+ author: author ?? '',
322
+ date: date ?? '',
323
+ isPushed: pushedShas.has(sha),
324
+ });
325
+ }
326
+ return commits;
327
+ }
276
328
  /** Get the GitHub PR URL for a branch using `gh pr view`. Returns null if no PR exists. */
277
329
  export function getPrUrl(repoPath, branchName) {
278
330
  try {
@@ -301,6 +353,47 @@ export function getPrStatus(repoPath, branchName) {
301
353
  return null;
302
354
  }
303
355
  }
356
+ /**
357
+ * Rename a branch in-place (`git branch -m <old> <new>`). Must be run inside
358
+ * the worktree (or any directory tracking the repo) — the new name replaces
359
+ * the old one locally. The remote still has the old name; the caller is
360
+ * responsible for pushing the renamed branch if needed.
361
+ */
362
+ export function renameBranch(repoPath, oldName, newName) {
363
+ git(repoPath, ['branch', '-m', oldName, newName]);
364
+ }
365
+ /**
366
+ * Check whether a branch name is already in use — either as a local branch
367
+ * or a remote tracking branch on the given remote. Used before renaming a
368
+ * branch to fail early with a clear error instead of letting git throw a
369
+ * generic "already exists" message.
370
+ */
371
+ export function branchExists(repoPath, name, remote = 'origin') {
372
+ try {
373
+ git(repoPath, ['rev-parse', '--verify', '--quiet', `refs/heads/${name}`]);
374
+ return true;
375
+ }
376
+ catch {
377
+ // not a local branch
378
+ }
379
+ try {
380
+ git(repoPath, ['rev-parse', '--verify', '--quiet', `refs/remotes/${remote}/${name}`]);
381
+ return true;
382
+ }
383
+ catch {
384
+ // not a remote branch either
385
+ }
386
+ return false;
387
+ }
388
+ /**
389
+ * Move a worktree directory on disk via `git worktree move`. Both the
390
+ * filesystem layout and the `worktrees` metadata file are updated atomically.
391
+ * Throws if the destination exists, the worktree is dirty, or the source
392
+ * is the main working tree.
393
+ */
394
+ export function moveWorktree(projectPath, oldPath, newPath) {
395
+ git(projectPath, ['worktree', 'move', oldPath, newPath]);
396
+ }
304
397
  /** List files changed between base and HEAD (committed), plus working tree changes. */
305
398
  export function getChangedFiles(repoPath, base) {
306
399
  const ref = resolveBase(repoPath, base);
@@ -361,6 +454,50 @@ export function getChangedFiles(repoPath, base) {
361
454
  }
362
455
  return files;
363
456
  }
457
+ /**
458
+ * List committed files between `origin/<branch>` and local HEAD — the set
459
+ * of files the next `git push` would send. Working tree changes are NOT
460
+ * included: uncommitted edits aren't about to be pushed. Returns an empty
461
+ * list if there is no remote tracking branch yet.
462
+ */
463
+ export function getUnpushedChangedFiles(repoPath, branchName, remote = 'origin') {
464
+ const remoteRef = `${remote}/${branchName}`;
465
+ // Bail out cleanly if the remote branch doesn't exist (branch never pushed).
466
+ try {
467
+ git(repoPath, ['rev-parse', '--verify', remoteRef]);
468
+ }
469
+ catch {
470
+ return [];
471
+ }
472
+ const files = [];
473
+ try {
474
+ const output = git(repoPath, ['diff', '--name-status', `${remoteRef}..HEAD`]);
475
+ for (const line of output.split('\n')) {
476
+ if (!line)
477
+ continue;
478
+ const [statusCode, ...pathParts] = line.split('\t');
479
+ if (!statusCode || pathParts.length === 0)
480
+ continue;
481
+ const filePath = (statusCode.startsWith('R') || statusCode.startsWith('C')
482
+ ? pathParts[pathParts.length - 1]
483
+ : pathParts[0])?.replace(/\/$/, '') ?? '';
484
+ if (!filePath)
485
+ continue;
486
+ let status = 'modified';
487
+ if (statusCode.startsWith('A'))
488
+ status = 'added';
489
+ else if (statusCode.startsWith('D'))
490
+ status = 'deleted';
491
+ else if (statusCode.startsWith('R'))
492
+ status = 'renamed';
493
+ files.push({ path: filePath, status });
494
+ }
495
+ }
496
+ catch {
497
+ // Unlikely after the rev-parse check, but keep the happy path robust.
498
+ }
499
+ return files;
500
+ }
364
501
  /** Get the original content of a file at a given ref. Returns null if the file didn't exist. */
365
502
  export function getFileAtRef(repoPath, ref, filePath) {
366
503
  const resolvedRef = resolveBase(repoPath, ref);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loicngr/kobo",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
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-CyzfM9-_.js";import{n as w}from"./vue-i18n-eUDnMrPl.js";import{S as T,v as E,x as D}from"./index-B0Jj-w-E.js";import{t as O}from"./QSpinnerDots-By20ptst.js";import{t as k}from"./QExpansionItem-HLBjHx-0.js";import{t as A}from"./QScrollArea-CBW6shMb.js";import{t as j}from"./QTooltip-DbEBexRN.js";import{n as M,r as N,t as P}from"./documents-CByb0FJM.js";import{t as F}from"./_plugin-vue_export-helper-Cj6tcsj6.js";function ee(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];r.sort((e,t)=>{let n=e.ts??``,r=t.ts??``;return n===r?0:n?r?n<r?-1:1:-1:1});let i;for(let e of r)e.type===`user`&&e.sender!==`system-prompt`&&e.ts&&(!i||e.ts>i)&&(i=e.ts);if(i)for(let e of r)e.type===`text`&&e.streaming&&(!e.ts||e.ts<i)&&(e.streaming=!1);return r}function I(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=I(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 L={class:`text-caption text-grey-6`},R=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`,L,c(e.$t(r.value)),1))}});function z(e,t){if(t.length===0||e.length===0)return e;let n=[...t].sort((e,t)=>t.length-e.length),r=new DOMParser().parseFromString(`<div>${e}</div>`,`text/html`),i=r.body.firstChild;if(!i)return e;function a(e){if(e.nodeType===Node.TEXT_NODE){B(e,n,r);return}if(e.nodeName===`A`)return;let t=Array.from(e.childNodes);for(let e of t)a(e)}return a(i),i.innerHTML}function B(e,t,n){let r=e.textContent??``;if(!t.some(e=>r.includes(e)))return;let i=n.createDocumentFragment(),a=0;for(;a<r.length;){let e=V(r,a,t);if(!e){i.appendChild(n.createTextNode(r.slice(a)));break}e.index>a&&i.appendChild(n.createTextNode(r.slice(a,e.index)));let o=n.createElement(`a`);o.className=`document-link`,o.setAttribute(`data-document-path`,e.path),o.setAttribute(`href`,`#`),o.textContent=e.path,i.appendChild(o),a=e.index+e.path.length}e.parentNode?.replaceChild(i,e)}function V(e,t,n){let r=null;for(let i of n){let n=e.indexOf(i,t);n<0||(!r||n<r.index||n===r.index&&i.length>r.path.length)&&(r={index:n,path:i})}return r}var H=[`innerHTML`],U=F(v({__name:`TextMessageItem`,props:{item:{}},setup(e){let n=e,r=P(),i=E(),a=p(()=>{let e=i.selectedWorkspaceId;return e?r.documentsFor(e).map(e=>e.path):[]}),o=p(()=>{let e=z(M.parse(n.item.text,{async:!1,breaks:!0,gfm:!0}),a.value);return N.sanitize(e,{ADD_ATTR:[`data-document-path`]})});function s(e){let t=e.target?.closest(`.document-link`);if(!t)return;e.preventDefault();let n=t.getAttribute(`data-document-path`),a=i.selectedWorkspaceId;!n||!a||r.openDocumentByPath(a,n)}return(n,r)=>(t(),m(`div`,{class:`markdown-message`,onClick:s},[_(`div`,{innerHTML:o.value},null,8,H),e.item.streaming?(t(),l(x,{key:0,size:`xs`,class:`q-ml-xs`})):u(``,!0)]))}}),[[`__scopeId`,`data-v-0ac5a3e4`]]),W={key:0,class:`text-caption text-grey-5`,style:{"font-style":`italic`}},G=[`innerHTML`],K={key:1,style:{"white-space":`pre-wrap`}},q=F(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=M.parse(n.item.text,{async:!1,breaks:!0,gfm:!0});return N.sanitize(e)});return(n,d)=>i.value?(t(),m(`div`,W,[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,G)]),_:1},8,[`label`])):(t(),m(`span`,K,c(e.item.text),1))])):u(``,!0)}}),[[`__scopeId`,`data-v-e9fb9f90`]]);function J(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 Y(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 X(e,t){if(!e||!t?.projectPath)return e;let n=Z(e,`${t.projectPath}/.worktrees/${t.workingBranch}`);return n===e&&(n=Z(e,t.projectPath)),n}function Z(e,t){if(!t)return e;let n=t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);return e.replace(RegExp(`${n}/`,`g`),``).replace(RegExp(`${n}(?=\\s|$|["'\`])`,`g`),`.`)}var re={class:`tool-name`},ie=[`title`],ae={key:0,class:`tool-stat-add`},oe={key:1,class:`tool-stat-del`},se={class:`diff-sign`},ce={class:`tool-name`},le=[`title`],ue=F(v({__name:`ToolCallItem`,props:{item:{}},setup(e){let i=e,o=a(!1),g=E(),v=p(()=>Y(i.item.name,i.item.input)),y=p(()=>v.value?X(v.value.filePath,g.selectedWorkspace):``),x={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`},C=p(()=>x[i.item.name]??`build`),w=p(()=>{if(v.value)return``;let e=i.item.input,t=T(e);return t?X(t,g.selectedWorkspace):``});function T(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 D=p(()=>{let e=v.value;return e?e.toolName===`Edit`&&e.oldString!==void 0&&e.newString!==void 0?J(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}),O=p(()=>{let e=i.item.result;if(!e)return``;if(typeof e.output==`string`)return e.output;try{return JSON.stringify(e.output)}catch{return String(e.output)}}),k=new Set([`Read`]),A=p(()=>!!(i.item.result&&O.value)&&(!k.has(i.item.name)||i.item.result?.isError===!0));function j(){o.value=!o.value}return n(()=>i.item.result?.isError===!0,e=>{e&&(o.value=!0)},{immediate:!0}),(n,i)=>v.value?(t(),m(`div`,{key:0,class:s([`tool-row`,{"tool-row-expanded":o.value}])},[_(`div`,{class:`tool-header`,onClick:j},[d(S,{name:C.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),_(`span`,re,c(v.value.toolName===`Bash:rm`?`Bash`:v.value.toolName),1),_(`span`,{class:`tool-path`,title:v.value.filePath},c(y.value),9,ie),v.value.additions>0?(t(),m(`span`,ae,`+`+c(v.value.additions),1)):u(``,!0),v.value.deletions>0?(t(),m(`span`,oe,`-`+c(v.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:o.value?`expand_less`:`expand_more`,size:`xs`,class:`q-ml-auto text-grey-6`},null,8,[`name`])]),o.value&&D.value?(t(),m(`div`,{key:0,class:`tool-diff`,onClick:i[0]||=b(()=>{},[`stop`])},[(t(!0),m(h,null,r(D.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`,se,c(e.type===`del`?`-`:e.type===`add`?`+`:` `),1),f(c(e.content),1)],2))),128))])):u(``,!0)],2)):(t(),m(`div`,{key:1,class:s([`tool-row tool-row-generic`,{"tool-row-expanded":o.value,"tool-row--toggleable":A.value}])},[_(`div`,{class:`tool-header`,onClick:i[1]||=e=>A.value&&j()},[d(S,{name:C.value,size:`14px`,class:`tool-icon`},null,8,[`name`]),_(`span`,ce,c(e.item.name),1),w.value?(t(),m(`span`,{key:0,class:`tool-arg`,title:T(e.item.input)||w.value},c(w.value),9,le)):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),A.value?(t(),l(S,{key:3,name:o.value?`expand_less`:`expand_more`,size:`xs`,class:`q-ml-xs text-grey-6`},null,8,[`name`])):u(``,!0)]),o.value&&A.value?(t(),m(`div`,{key:0,class:`tool-output`,onClick:i[2]||=b(()=>{},[`stop`])},c(O.value),1)):u(``,!0)],2))}}),[[`__scopeId`,`data-v-b1ed78cb`]]),de=[`innerHTML`],fe={key:1,class:`markdown-message`},pe=[`innerHTML`],me=F(v({__name:`UserMessageItem`,props:{item:{}},setup(e){let n=e,r=p(()=>n.item.sender===`system-prompt`),i=p(()=>{let e=M.parse(n.item.content,{async:!1,breaks:!0,gfm:!0});return N.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,de)]),_:1},8,[`label`])):(t(),m(`div`,fe,[_(`div`,{innerHTML:i.value},null,8,pe)]))}}),[[`__scopeId`,`data-v-cb8cec0f`]]),he={class:`turn-header`},ge={key:0,class:`turn-time`},_e={class:`turn-time turn-time-updated`},ve={key:2,class:`turn-actions`},ye={class:`turn-body`},be={key:0,class:`turn-scroll-top`},xe=F(v({__name:`TurnCard`,props:{turn:{}},emits:[`scrollTo`],setup(e,{emit:n}){let i=e,v=n,{t:b}=w(),x=a(null);function T(){let e=x.value;if(!e)return;let t=e.closest(`.q-scrollarea`)?.querySelector(`.q-scrollarea__content`);if(!t){e.scrollIntoView({behavior:`smooth`,block:`start`});return}let n=e.getBoundingClientRect().top-t.getBoundingClientRect().top;v(`scrollTo`,Math.max(0,n-8))}let E=p(()=>{switch(i.turn.speaker){case`user`:return{label:b(`chat.you`),accent:`#ce93d8`,badgeClass:`turn-badge-user`};case`agent`:return{label:b(`chat.agent`),accent:`#7986cb`,badgeClass:`turn-badge-agent`};case`system-prompt`:return{label:b(`chat.systemPrompt`),accent:`#757575`,badgeClass:`turn-badge-system`};case`session`:return{label:b(`chat.session`),accent:`#616161`,badgeClass:`turn-badge-session`}}});function D(e,t=!1){if(!e)return``;let n=new Date(e);return Number.isNaN(n.getTime())?``:n.toLocaleTimeString(void 0,t?{hour:`2-digit`,minute:`2-digit`,second:`2-digit`}:{hour:`2-digit`,minute:`2-digit`})}let O=p(()=>D(i.turn.ts)),k=p(()=>{let e=i.turn.items;if(e.length===0)return null;for(let t=e.length-1;t>=0;t--){let n=e[t].ts;if(n)return n}return null}),A=p(()=>{let e=i.turn.ts,t=k.value;if(!t||!e||t===e)return``;let n=new Date(e).getTime(),r=new Date(t).getTime();return Number.isNaN(n)||Number.isNaN(r)||r<=n?``:D(t,r-n<6e4)}),M=p(()=>A.value!==``),N=p(()=>i.turn.items.filter(e=>e.type===`tool`).length);return(n,i)=>(t(),m(`div`,{ref_key:`cardEl`,ref:x,class:s([`turn-card`,{"turn-card--user":e.turn.speaker===`user`}]),style:y({"--turn-accent":E.value.accent})},[_(`div`,he,[_(`span`,{class:s([`turn-badge`,E.value.badgeClass])},c(E.value.label),3),O.value?(t(),m(`span`,ge,c(O.value),1)):u(``,!0),M.value?(t(),m(h,{key:1},[d(S,{name:`arrow_forward`,size:`10px`,color:`grey-7`,class:`turn-time-arrow`}),_(`span`,_e,[f(c(A.value)+` `,1),d(j,null,{default:o(()=>[f(c(g(b)(`chat.lastUpdatedAt`,{time:A.value})),1)]),_:1})])],64)):u(``,!0),N.value>0?(t(),m(`span`,ve,` · `+c(g(b)(`chat.nActions`,{n:N.value})),1)):u(``,!0)]),_(`div`,ye,[(t(!0),m(h,null,r(e.turn.items,(e,n)=>(t(),m(h,{key:n},[e.type===`text`?(t(),l(U,{key:0,item:e},null,8,[`item`])):e.type===`thinking`?(t(),l(q,{key:1,item:e},null,8,[`item`])):e.type===`tool`?(t(),l(ue,{key:2,item:e},null,8,[`item`])):e.type===`user`?(t(),l(me,{key:3,item:e},null,8,[`item`])):e.type===`session`?(t(),l(R,{key:4,item:e},null,8,[`item`])):u(``,!0)],64))),128))]),e.turn.items.length>4?(t(),m(`div`,be,[d(C,{flat:``,round:``,dense:``,size:`xs`,icon:`arrow_upward`,color:`grey-6`,class:`turn-scroll-top-btn`,onClick:T},{default:o(()=>[d(j,null,{default:o(()=>[f(c(g(b)(`chat.scrollToTurnTop`)),1)]),_:1})]),_:1})])):u(``,!0)],6))}}),[[`__scopeId`,`data-v-50994916`]]),Se={key:0,class:`activity-feed-switching`},Ce={key:1,class:`activity-feed-wrap`},we={key:0,class:`text-center q-py-sm text-caption text-grey-6`},Te={class:`q-pa-md`},Ee={key:1,class:`q-px-md q-pb-md`},De={class:`activity-feed-nav-cluster`},Oe=60,Q=200,$=200,ke=400,Ae=200,je=F(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}),j=p(()=>{let e=te(ee(v.eventsFor(g.workspaceId),v.timestampsFor(g.workspaceId),w.value),S.value);return ne(y.showVerboseSystemMessages?e:e.filter(e=>e.type!==`session`))}),M=p(()=>y.showVerboseSystemMessages?v.eventsFor(g.workspaceId).filter(e=>e.kind===`message:raw`).map(e=>e.content):[]),N=a(null),P=a(!0),F=a(!1),I=!1,L=a(!0);function R(e){P.value=e.verticalSize-e.verticalPosition-e.verticalContainerSize<=Oe,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=N.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+ke)),F.value=!1}}async function B(t=0){await e();let n=N.value;if(!n)return;let r=n.getScroll();n.setScrollPosition(`vertical`,r.verticalSize,t)}function V(e){let t=N.value;t&&t.setScrollPosition(`vertical`,Math.max(0,e),250)}let H=a([]),U=a(null);function W(){let e=j.value,t=H.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=U.value?.parentElement;if(r){let e=r.querySelectorAll(`.turn-card--user`);for(let t of e)n.push(t)}return n}function G(){let e=N.value;if(!e)return null;let t=U.value;if(!t)return null;let n=e.getScroll().verticalPosition,r=t.getBoundingClientRect().top,i=null;for(let e of W()){let t=e.getBoundingClientRect().top-r;if(t<n-40)i=t;else break}return i}async function K(){let t=N.value;if(!t)return;let n=G();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=G(),n!==null)break}n!==null&&t.setScrollPosition(`vertical`,Math.max(0,n-12),250)}async function q(){I=!1,await e(),await B(0),requestAnimationFrame(()=>{requestAnimationFrame(()=>{I=!0})})}let J=p(()=>v.eventsFor(g.workspaceId).length);async function Y(){L.value=!0;let e=Date.now();await new Promise(e=>setTimeout(e,Ae));let t=e+5e3;for(;J.value===0&&Date.now()<t;)await new Promise(e=>setTimeout(e,50));L.value=!1}n(L,async e=>{!e&&J.value>0&&await q()}),i(()=>{Y(),J.value>0&&q()});let X=!1;n(J,async(e,t)=>{if(!X&&e>0){X=!0,await q();return}e>t&&P.value&&!F.value&&await B(180)}),n(()=>g.workspaceId,()=>{P.value=!0,X=!1,I=!1,Y(),J.value>0&&q()}),n(()=>b.selectedSessionId,async()=>{P.value=!0,I=!1,await q()}),n(p(()=>S.value.filter(e=>e.sender!==`system-prompt`).length),async(e,t)=>{e>t&&(P.value=!0,await B(180))});async function Z(){P.value=!0,await B(250)}return(e,n)=>L.value?(t(),m(`div`,Se,[d(O,{size:`40px`,color:`indigo-4`})])):(t(),m(`div`,Ce,[d(A,{ref_key:`scrollRef`,ref:N,class:`activity-feed-scroll`,onScroll:R},{default:o(()=>[_(`div`,{ref_key:`contentOriginRef`,ref:U,class:`content-origin-marker`},null,512),F.value?(t(),m(`div`,we,[d(x,{size:`sm`}),f(` `+c(e.$t(`activity.loading_older`)),1)])):u(``,!0),_(`div`,Te,[(t(!0),m(h,null,r(j.value,(e,n)=>(t(),l(xe,{key:n,ref_for:!0,ref_key:`turnRefs`,ref:H,turn:e,onScrollTo:V},null,8,[`turn`]))),128))]),M.value.length?(t(),m(`div`,Ee,[d(k,{label:e.$t(`activity.raw_lines`,{n:M.value.length}),dense:``},{default:o(()=>[(t(!0),m(h,null,r(M.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),_(`div`,De,[P.value?u(``,!0):(t(),l(C,{key:0,round:``,dense:``,unelevated:``,color:`grey-9`,"text-color":`grey-3`,icon:`arrow_downward`,size:`sm`,class:`activity-feed-nav-btn`,title:e.$t(`activity.scroll_to_bottom`),onClick:Z},null,8,[`title`])),d(C,{round:``,dense:``,unelevated:``,color:`grey-9`,"text-color":`grey-3`,icon:`arrow_upward`,size:`sm`,class:`activity-feed-nav-btn`,title:e.$t(`activity.prev_user_message`),onClick:K},null,8,[`title`])])]))}}),[[`__scopeId`,`data-v-3ac19953`]]);export{je as default};
@@ -1 +1 @@
1
- .markdown-message[data-v-0ac5a3e4]{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-0ac5a3e4] *{max-width:100%}.markdown-message[data-v-0ac5a3e4] p{margin:0 0 .5em}.markdown-message[data-v-0ac5a3e4] p:last-child{margin-bottom:0}.markdown-message[data-v-0ac5a3e4] pre{background:#00000059;border-radius:4px;margin:.5em 0;padding:.5em .75em;overflow-x:auto}.markdown-message[data-v-0ac5a3e4] code{word-break:break-all;background:#0000004d;border-radius:3px;padding:.1em .3em;font-size:.9em}.markdown-message[data-v-0ac5a3e4] pre code{background:0 0;padding:0}.markdown-message[data-v-0ac5a3e4] ul,.markdown-message[data-v-0ac5a3e4] ol{margin:.25em 0 .5em;padding-left:1.5em}.markdown-message[data-v-0ac5a3e4] li{margin:.15em 0}.markdown-message[data-v-0ac5a3e4] a{color:#7986cb;text-decoration:underline}.markdown-message[data-v-0ac5a3e4] .document-link{color:#9fa8da;cursor:pointer;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.markdown-message[data-v-0ac5a3e4] .document-link:hover{color:#c5cae9;-webkit-text-decoration:underline;text-decoration:underline}.markdown-message[data-v-0ac5a3e4] h1,.markdown-message[data-v-0ac5a3e4] h2,.markdown-message[data-v-0ac5a3e4] h3,.markdown-message[data-v-0ac5a3e4] h4,.markdown-message[data-v-0ac5a3e4] h5,.markdown-message[data-v-0ac5a3e4] h6{margin:.5em 0 .3em;font-weight:600;line-height:1.3}.markdown-message[data-v-0ac5a3e4] h1{font-size:1.25em}.markdown-message[data-v-0ac5a3e4] h2{font-size:1.15em}.markdown-message[data-v-0ac5a3e4] h3{font-size:1.08em}.markdown-message[data-v-0ac5a3e4] h4,.markdown-message[data-v-0ac5a3e4] h5,.markdown-message[data-v-0ac5a3e4] h6{font-size:1em}.markdown-message[data-v-0ac5a3e4] blockquote{color:#ffffffb3;border-left:3px solid #fff3;margin:.5em 0;padding-left:.75em}.markdown-message[data-v-0ac5a3e4] table{border-collapse:collapse;margin:.5em 0}.markdown-message[data-v-0ac5a3e4] th,.markdown-message[data-v-0ac5a3e4] 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-b1ed78cb]{border-radius:4px;margin:0;font-size:12px}.tool-header[data-v-b1ed78cb]{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-b1ed78cb],.tool-row--toggleable .tool-header[data-v-b1ed78cb]{cursor:pointer}.tool-row:has(.tool-diff) .tool-header[data-v-b1ed78cb]{cursor:pointer}.tool-row:not(.tool-row-generic) .tool-header[data-v-b1ed78cb]:hover,.tool-row--toggleable .tool-header[data-v-b1ed78cb]:hover{background:#ffffff08}.tool-icon[data-v-b1ed78cb]{color:#9fbce0;flex-shrink:0}.tool-name[data-v-b1ed78cb]{color:#d0d0d0;flex-shrink:0;font-weight:600}.tool-arg[data-v-b1ed78cb],.tool-path[data-v-b1ed78cb]{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-b1ed78cb],.tool-arg[data-v-b1ed78cb]{flex:1}.tool-stat-add[data-v-b1ed78cb]{color:#66bb6a;flex-shrink:0;font-size:11px;font-weight:600}.tool-stat-del[data-v-b1ed78cb]{color:#ef5350;flex-shrink:0;font-size:11px;font-weight:600}.tool-diff[data-v-b1ed78cb]{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-b1ed78cb]{white-space:pre;color:#bbb;padding:0 12px}.diff-sign[data-v-b1ed78cb]{color:#555;-webkit-user-select:none;user-select:none;width:14px;display:inline-block}.diff-add[data-v-b1ed78cb]{color:#c8e6c9;background:#66bb6a1a}.diff-add .diff-sign[data-v-b1ed78cb]{color:#66bb6a}.diff-del[data-v-b1ed78cb]{color:#ffcdd2;background:#ef53501a}.diff-del .diff-sign[data-v-b1ed78cb]{color:#ef5350}.tool-output[data-v-b1ed78cb]{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}
1
+ .markdown-message[data-v-0ac5a3e4]{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-0ac5a3e4] *{max-width:100%}.markdown-message[data-v-0ac5a3e4] p{margin:0 0 .5em}.markdown-message[data-v-0ac5a3e4] p:last-child{margin-bottom:0}.markdown-message[data-v-0ac5a3e4] pre{background:#00000059;border-radius:4px;margin:.5em 0;padding:.5em .75em;overflow-x:auto}.markdown-message[data-v-0ac5a3e4] code{word-break:break-all;background:#0000004d;border-radius:3px;padding:.1em .3em;font-size:.9em}.markdown-message[data-v-0ac5a3e4] pre code{background:0 0;padding:0}.markdown-message[data-v-0ac5a3e4] ul,.markdown-message[data-v-0ac5a3e4] ol{margin:.25em 0 .5em;padding-left:1.5em}.markdown-message[data-v-0ac5a3e4] li{margin:.15em 0}.markdown-message[data-v-0ac5a3e4] a{color:#7986cb;text-decoration:underline}.markdown-message[data-v-0ac5a3e4] .document-link{color:#9fa8da;cursor:pointer;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.markdown-message[data-v-0ac5a3e4] .document-link:hover{color:#c5cae9;-webkit-text-decoration:underline;text-decoration:underline}.markdown-message[data-v-0ac5a3e4] h1,.markdown-message[data-v-0ac5a3e4] h2,.markdown-message[data-v-0ac5a3e4] h3,.markdown-message[data-v-0ac5a3e4] h4,.markdown-message[data-v-0ac5a3e4] h5,.markdown-message[data-v-0ac5a3e4] h6{margin:.5em 0 .3em;font-weight:600;line-height:1.3}.markdown-message[data-v-0ac5a3e4] h1{font-size:1.25em}.markdown-message[data-v-0ac5a3e4] h2{font-size:1.15em}.markdown-message[data-v-0ac5a3e4] h3{font-size:1.08em}.markdown-message[data-v-0ac5a3e4] h4,.markdown-message[data-v-0ac5a3e4] h5,.markdown-message[data-v-0ac5a3e4] h6{font-size:1em}.markdown-message[data-v-0ac5a3e4] blockquote{color:#ffffffb3;border-left:3px solid #fff3;margin:.5em 0;padding-left:.75em}.markdown-message[data-v-0ac5a3e4] table{border-collapse:collapse;margin:.5em 0}.markdown-message[data-v-0ac5a3e4] th,.markdown-message[data-v-0ac5a3e4] 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-b1ed78cb]{border-radius:4px;margin:0;font-size:12px}.tool-header[data-v-b1ed78cb]{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-b1ed78cb],.tool-row--toggleable .tool-header[data-v-b1ed78cb]{cursor:pointer}.tool-row:has(.tool-diff) .tool-header[data-v-b1ed78cb]{cursor:pointer}.tool-row:not(.tool-row-generic) .tool-header[data-v-b1ed78cb]:hover,.tool-row--toggleable .tool-header[data-v-b1ed78cb]:hover{background:#ffffff08}.tool-icon[data-v-b1ed78cb]{color:#9fbce0;flex-shrink:0}.tool-name[data-v-b1ed78cb]{color:#d0d0d0;flex-shrink:0;font-weight:600}.tool-arg[data-v-b1ed78cb],.tool-path[data-v-b1ed78cb]{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-b1ed78cb],.tool-arg[data-v-b1ed78cb]{flex:1}.tool-stat-add[data-v-b1ed78cb]{color:#66bb6a;flex-shrink:0;font-size:11px;font-weight:600}.tool-stat-del[data-v-b1ed78cb]{color:#ef5350;flex-shrink:0;font-size:11px;font-weight:600}.tool-diff[data-v-b1ed78cb]{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-b1ed78cb]{white-space:pre;color:#bbb;padding:0 12px}.diff-sign[data-v-b1ed78cb]{color:#555;-webkit-user-select:none;user-select:none;width:14px;display:inline-block}.diff-add[data-v-b1ed78cb]{color:#c8e6c9;background:#66bb6a1a}.diff-add .diff-sign[data-v-b1ed78cb]{color:#66bb6a}.diff-del[data-v-b1ed78cb]{color:#ffcdd2;background:#ef53501a}.diff-del .diff-sign[data-v-b1ed78cb]{color:#ef5350}.tool-output[data-v-b1ed78cb]{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-50994916]{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-50994916]{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-50994916]{letter-spacing:.3px;border-radius:3px;padding:2px 8px;font-size:11px;font-weight:700}.turn-badge-user[data-v-50994916]{color:#ce93d8;background:#ce93d826}.turn-badge-agent[data-v-50994916]{color:#7986cb;background:#7986cb26}.turn-badge-system[data-v-50994916]{color:#bdbdbd;background:#75757533;font-style:italic}.turn-badge-session[data-v-50994916]{color:#9e9e9e;background:#61616133}.turn-time[data-v-50994916]{color:#666;font-family:SF Mono,Menlo,Consolas,monospace;font-size:11px}.turn-time-arrow[data-v-50994916]{opacity:.7;margin:0 -2px}.turn-time-updated[data-v-50994916]{color:#8891a3}.turn-actions[data-v-50994916]{color:#777;font-size:11px}.turn-body[data-v-50994916]{flex-direction:column;gap:12px;min-width:0;padding:14px 18px;display:flex}.turn-body[data-v-50994916]>*{min-width:0;max-width:100%}.turn-body[data-v-50994916] .tool-row+.tool-row{margin-top:-8px}.turn-scroll-top[data-v-50994916]{justify-content:flex-start;padding:0 8px 6px;display:flex}.turn-scroll-top-btn[data-v-50994916]{opacity:.5;transition:opacity .15s}.turn-scroll-top-btn[data-v-50994916]:hover{opacity:1}.activity-feed-wrap[data-v-3ac19953]{width:100%;height:100%;position:relative}.activity-feed-scroll[data-v-3ac19953]{width:100%;height:100%}.activity-feed-nav-cluster[data-v-3ac19953]{z-index:2;align-items:center;gap:8px;display:flex;position:absolute;bottom:14px;right:14px}.activity-feed-nav-btn[data-v-3ac19953]{opacity:.8;transition:opacity .12s}.activity-feed-nav-btn[data-v-3ac19953]:hover{opacity:1}.content-origin-marker[data-v-3ac19953]{pointer-events:none;width:0;height:0;margin:0;padding:0}.activity-feed-scroll[data-v-3ac19953] .q-scrollarea__content{max-width:100%;overflow-x:hidden}.activity-feed-switching[data-v-3ac19953]{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{d as n,f as r}from"./scroll-C-Vz5BD9.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=r(e);i!==void 0&&n(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};
@@ -1,2 +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-CyzfM9-_.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-9vZWx9Bu.js";import{n as S,t as C}from"./QItemSection-CGpX7GcL.js";import{t as w}from"./QItemLabel-Codqjisk.js";import{t as de}from"./QExpansionItem-DCRks-Ra.js";import{t as fe}from"./_plugin-vue_export-helper-r4mAJOHR.js";import{t as pe}from"./QSpace-BNr0AftG.js";import{t as T}from"./QTooltip-C4CPesBX.js";import{t as me}from"./use-quasar-Ch82z8H5.js";import{n as E,t as he}from"./models-BtywKe_m.js";import{t as ge}from"./QPage-yqdKDG7-.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(`
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-DNSiXYrN.js";import{t as b}from"./QBtn-CyzfM9-_.js";import{n as oe}from"./vue-i18n-eUDnMrPl.js";import{g as se,i as x,m as ce,v as le,x as ue}from"./index-B0Jj-w-E.js";import{n as S,t as C}from"./QItemSection-BzWLL-V-.js";import{t as w}from"./QItemLabel-Czw5g0px.js";import{t as de}from"./QExpansionItem-HLBjHx-0.js";import{t as T}from"./QTooltip-DbEBexRN.js";import{t as fe}from"./_plugin-vue_export-helper-Cj6tcsj6.js";import{t as pe}from"./QSpace-0zdF1m5x.js";import{t as me}from"./use-quasar-BBrzedjR.js";import{n as E,t as he}from"./models-GweeyU2r.js";import{t as ge}from"./QPage-BTzNQlb1.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
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};