tower-studio 0.1.2 → 0.1.3

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 (641) hide show
  1. package/bin/tower.mjs +5 -15
  2. package/next.config.ts +1 -8
  3. package/package.json +10 -11
  4. package/prisma/dev.db +0 -0
  5. package/public/vs/_commonjsHelpers-CT9FvmAN.js +1 -0
  6. package/public/vs/abap-D-t0cyap.js +1 -0
  7. package/public/vs/apex-CcIm7xu6.js +1 -0
  8. package/public/vs/assets/css.worker-HnVq6Ewq.js +93 -0
  9. package/public/vs/assets/editor.worker-Be8ye1pW.js +26 -0
  10. package/public/vs/assets/html.worker-B51mlPHg.js +470 -0
  11. package/public/vs/assets/json.worker-DKiEKt88.js +58 -0
  12. package/public/vs/assets/ts.worker-CMbG-7ft.js +67731 -0
  13. package/public/vs/azcli-BA0tQDCg.js +1 -0
  14. package/public/vs/basic-languages/monaco.contribution.js +1 -0
  15. package/public/vs/bat-C397hTD6.js +1 -0
  16. package/public/vs/bicep-DF5aW17k.js +2 -0
  17. package/public/vs/cameligo-plsz8qhj.js +1 -0
  18. package/public/vs/clojure-Y2auQMzK.js +1 -0
  19. package/public/vs/coffee-Bu45yuWE.js +1 -0
  20. package/public/vs/cpp-CkKPQIni.js +1 -0
  21. package/public/vs/csharp-CX28MZyh.js +1 -0
  22. package/public/vs/csp-D8uWnyxW.js +1 -0
  23. package/public/vs/css-CaeNmE3S.js +3 -0
  24. package/public/vs/cssMode-CjiAH6dQ.js +1 -0
  25. package/public/vs/cypher-DVThT8BS.js +1 -0
  26. package/public/vs/dart-CmGfCvrO.js +1 -0
  27. package/public/vs/dockerfile-CZqqYdch.js +1 -0
  28. package/public/vs/ecl-30fUercY.js +1 -0
  29. package/public/vs/editor/editor.main.css +1 -0
  30. package/public/vs/editor/editor.main.js +5 -0
  31. package/public/vs/editor.api-CalNCsUg.js +903 -0
  32. package/public/vs/elixir-xjPaIfzF.js +1 -0
  33. package/public/vs/flow9-DqtmStfK.js +1 -0
  34. package/public/vs/freemarker2-Cz_sV6Md.js +3 -0
  35. package/public/vs/fsharp-BOMdg4U1.js +1 -0
  36. package/public/vs/go-D_hbi-Jt.js +1 -0
  37. package/public/vs/graphql-CKUU4kLG.js +1 -0
  38. package/public/vs/handlebars-OwglfO-1.js +1 -0
  39. package/public/vs/hcl-DTaboeZW.js +1 -0
  40. package/public/vs/html-Pa1xEWsY.js +1 -0
  41. package/public/vs/htmlMode-Bz67EXwp.js +1 -0
  42. package/public/vs/ini-CsNwO04R.js +1 -0
  43. package/public/vs/java-CI4ZMsH9.js +1 -0
  44. package/public/vs/javascript-PczUCGdz.js +1 -0
  45. package/public/vs/jsonMode-DULH5oaX.js +7 -0
  46. package/public/vs/julia-BwzEvaQw.js +1 -0
  47. package/public/vs/kotlin-IUYPiTV8.js +1 -0
  48. package/public/vs/language/css/monaco.contribution.js +1 -0
  49. package/public/vs/language/html/monaco.contribution.js +1 -0
  50. package/public/vs/language/json/monaco.contribution.js +1 -0
  51. package/public/vs/language/typescript/monaco.contribution.js +1 -0
  52. package/public/vs/less-C0eDYdqa.js +2 -0
  53. package/public/vs/lexon-iON-Kj97.js +1 -0
  54. package/public/vs/liquid-DqKjdPGy.js +1 -0
  55. package/public/vs/loader.js +1368 -0
  56. package/public/vs/lspLanguageFeatures-kM9O9rjY.js +4 -0
  57. package/public/vs/lua-DtygF91M.js +1 -0
  58. package/public/vs/m3-CsR4AuFi.js +1 -0
  59. package/public/vs/markdown-C_rD0bIw.js +1 -0
  60. package/public/vs/mdx-DEWtB1K5.js +1 -0
  61. package/public/vs/mips-CiYP61RB.js +1 -0
  62. package/public/vs/monaco.contribution-D2OdxNBt.js +1 -0
  63. package/public/vs/monaco.contribution-DO3azKX8.js +1 -0
  64. package/public/vs/monaco.contribution-EcChJV6a.js +1 -0
  65. package/public/vs/monaco.contribution-qLAYrEOP.js +1 -0
  66. package/public/vs/msdax-C38-sJlp.js +1 -0
  67. package/public/vs/mysql-CdtbpvbG.js +1 -0
  68. package/public/vs/nls.messages-loader.js +1 -0
  69. package/public/vs/nls.messages.cs.js.js +17 -0
  70. package/public/vs/nls.messages.de.js.js +17 -0
  71. package/public/vs/nls.messages.es.js.js +17 -0
  72. package/public/vs/nls.messages.fr.js.js +15 -0
  73. package/public/vs/nls.messages.it.js.js +15 -0
  74. package/public/vs/nls.messages.ja.js.js +17 -0
  75. package/public/vs/nls.messages.js.js +10 -0
  76. package/public/vs/nls.messages.ko.js.js +25 -0
  77. package/public/vs/nls.messages.pl.js.js +17 -0
  78. package/public/vs/nls.messages.pt-br.js.js +6 -0
  79. package/public/vs/nls.messages.ru.js.js +17 -0
  80. package/public/vs/nls.messages.tr.js.js +15 -0
  81. package/public/vs/nls.messages.zh-cn.js.js +17 -0
  82. package/public/vs/nls.messages.zh-tw.js.js +15 -0
  83. package/public/vs/objective-c-CntZFaHX.js +1 -0
  84. package/public/vs/pascal-r6kuqfl_.js +1 -0
  85. package/public/vs/pascaligo-BiXoTmXh.js +1 -0
  86. package/public/vs/perl-DABw_TcH.js +1 -0
  87. package/public/vs/pgsql-me_jFXeX.js +1 -0
  88. package/public/vs/php-D_kh-9LK.js +1 -0
  89. package/public/vs/pla-VfZjczW0.js +1 -0
  90. package/public/vs/postiats-BBSzz8Pk.js +1 -0
  91. package/public/vs/powerquery-Dt-g_2cc.js +1 -0
  92. package/public/vs/powershell-B-7ap1zc.js +1 -0
  93. package/public/vs/protobuf-BmtuEB1A.js +2 -0
  94. package/public/vs/pug-BRpRNeEb.js +1 -0
  95. package/public/vs/python-Cr0UkIbn.js +1 -0
  96. package/public/vs/qsharp-BzsFaUU9.js +1 -0
  97. package/public/vs/r-f8dDdrp4.js +1 -0
  98. package/public/vs/razor-BYAHOTkz.js +1 -0
  99. package/public/vs/redis-fvZQY4PI.js +1 -0
  100. package/public/vs/redshift-45Et0LQi.js +1 -0
  101. package/public/vs/restructuredtext-C7UUFKFD.js +1 -0
  102. package/public/vs/ruby-CZO8zYTz.js +1 -0
  103. package/public/vs/rust-Bfetafyc.js +1 -0
  104. package/public/vs/sb-3GYllVck.js +1 -0
  105. package/public/vs/scala-foMgrKo1.js +1 -0
  106. package/public/vs/scheme-CHdMtr7p.js +1 -0
  107. package/public/vs/scss-C1cmLt9V.js +3 -0
  108. package/public/vs/shell-ClXCKCEW.js +1 -0
  109. package/public/vs/solidity-MZ6ExpPy.js +1 -0
  110. package/public/vs/sophia-DWkuSsPQ.js +1 -0
  111. package/public/vs/sparql-AUGFYSyk.js +1 -0
  112. package/public/vs/sql-32GpJSV2.js +1 -0
  113. package/public/vs/st-CuDFIVZ_.js +1 -0
  114. package/public/vs/swift-n-2HociN.js +3 -0
  115. package/public/vs/systemverilog-Ch4vA8Yt.js +1 -0
  116. package/public/vs/tcl-D74tq1nH.js +1 -0
  117. package/public/vs/tsMode-CZz1Umrk.js +11 -0
  118. package/public/vs/twig-C6taOxMV.js +1 -0
  119. package/public/vs/typescript-DfOrAzoV.js +1 -0
  120. package/public/vs/typespec-D-PIh9Xw.js +1 -0
  121. package/public/vs/vb-Dyb2648j.js +1 -0
  122. package/public/vs/wgsl-BhLXMOR0.js +298 -0
  123. package/public/vs/workers-DcJshg-q.js +1 -0
  124. package/public/vs/xml-CdsdnY8S.js +1 -0
  125. package/public/vs/yaml-DYGvmE88.js +1 -0
  126. package/src/actions/__tests__/agent-actions-username.test.ts +30 -0
  127. package/src/actions/__tests__/asset-actions.test.ts +251 -0
  128. package/src/actions/__tests__/assistant-actions.test.ts +20 -0
  129. package/src/actions/__tests__/cli-profile-actions.test.ts +243 -0
  130. package/src/actions/__tests__/label-actions.test.ts +187 -0
  131. package/src/actions/__tests__/note-actions.test.ts +237 -0
  132. package/src/actions/__tests__/onboarding-actions.test.ts +265 -0
  133. package/src/actions/__tests__/project-actions.test.ts +179 -0
  134. package/src/actions/__tests__/prompt-actions.test.ts +213 -0
  135. package/src/actions/__tests__/report-actions.test.ts +246 -0
  136. package/src/actions/__tests__/search-code-actions.test.ts +308 -0
  137. package/src/actions/__tests__/task-actions-overview.test.ts +58 -0
  138. package/src/actions/__tests__/task-actions-pin.test.ts +79 -0
  139. package/src/actions/__tests__/workspace-actions.test.ts +256 -0
  140. package/src/components/layout/__tests__/top-bar-username.test.tsx +24 -0
  141. package/src/components/onboarding/__tests__/onboarding-wizard.test.tsx +185 -0
  142. package/src/hooks/__tests__/sse-event-reducer.test.ts +263 -0
  143. package/src/hooks/__tests__/use-assistant-chat.test.ts +34 -0
  144. package/src/hooks/__tests__/use-image-upload.test.ts +443 -0
  145. package/src/lib/__tests__/assistant-message-converter.test.ts +162 -0
  146. package/src/lib/__tests__/assistant-sessions.test.ts +253 -0
  147. package/src/lib/__tests__/build-multimodal-prompt.test.ts +173 -0
  148. package/src/lib/__tests__/config-reader.test.ts +75 -0
  149. package/src/lib/__tests__/diff-parser.test.ts +212 -0
  150. package/src/lib/__tests__/execution-summary.test.ts +237 -0
  151. package/src/lib/__tests__/file-serve.test.ts +178 -0
  152. package/src/lib/__tests__/file-utils.test.ts +177 -0
  153. package/src/lib/__tests__/internal-api-guard.test.ts +151 -0
  154. package/src/lib/__tests__/logger.test.ts +181 -0
  155. package/src/lib/__tests__/platform.test.ts +566 -0
  156. package/src/lib/__tests__/reveal-route-security.test.ts +65 -0
  157. package/src/lib/__tests__/schemas.test.ts +377 -0
  158. package/src/lib/__tests__/terminal-link-provider.test.ts +160 -0
  159. package/src/lib/__tests__/upload-route-security.test.ts +120 -0
  160. package/src/lib/ai/__tests__/capability-resolver.test.ts +71 -0
  161. package/src/lib/ai/__tests__/claude-cli-adapter.test.ts +103 -0
  162. package/src/lib/ai/__tests__/provider-registry.test.ts +74 -0
  163. package/src/lib/pty/__tests__/ws-server-assistant.test.ts +7 -0
  164. package/.next/standalone/tower/.claude/rules/process-lifecycle.md +0 -31
  165. package/.next/standalone/tower/.claude/rules/security.md +0 -29
  166. package/.next/standalone/tower/.claude/rules/ui.md +0 -105
  167. package/.next/standalone/tower/AGENTS.md +0 -325
  168. package/.next/standalone/tower/CHANGELOG.md +0 -63
  169. package/.next/standalone/tower/CLAUDE.md +0 -33
  170. package/.next/standalone/tower/LICENSE +0 -21
  171. package/.next/standalone/tower/README.md +0 -214
  172. package/.next/standalone/tower/README.zh.md +0 -212
  173. package/.next/standalone/tower/bin/tower.mjs +0 -180
  174. package/.next/standalone/tower/docs/README.md +0 -51
  175. package/.next/standalone/tower/docs/ai/README.md +0 -91
  176. package/.next/standalone/tower/docs/ai/cli-abstraction-design.md +0 -398
  177. package/.next/standalone/tower/docs/ai/cli-abstraction-plan.md +0 -1345
  178. package/.next/standalone/tower/docs/assets-notes/README.md +0 -41
  179. package/.next/standalone/tower/docs/assistant/README.md +0 -48
  180. package/.next/standalone/tower/docs/board/README.md +0 -36
  181. package/.next/standalone/tower/docs/diagrams/tower-ai-architecture-en.html +0 -259
  182. package/.next/standalone/tower/docs/diagrams/tower-ai-architecture.html +0 -259
  183. package/.next/standalone/tower/docs/diagrams/tower-data-model-en.html +0 -344
  184. package/.next/standalone/tower/docs/diagrams/tower-data-model.html +0 -344
  185. package/.next/standalone/tower/docs/diagrams/tower-module-map-en.html +0 -176
  186. package/.next/standalone/tower/docs/diagrams/tower-module-map.html +0 -176
  187. package/.next/standalone/tower/docs/diagrams/tower-system-architecture-en.html +0 -336
  188. package/.next/standalone/tower/docs/diagrams/tower-system-architecture.html +0 -336
  189. package/.next/standalone/tower/docs/diagrams/tower-task-lifecycle-en.html +0 -251
  190. package/.next/standalone/tower/docs/diagrams/tower-task-lifecycle.html +0 -251
  191. package/.next/standalone/tower/docs/en/guide/architecture.md +0 -79
  192. package/.next/standalone/tower/docs/en/guide/diagrams.md +0 -24
  193. package/.next/standalone/tower/docs/en/guide/getting-started.md +0 -80
  194. package/.next/standalone/tower/docs/en/guide/introduction.md +0 -84
  195. package/.next/standalone/tower/docs/en/index.md +0 -36
  196. package/.next/standalone/tower/docs/en/modules/ai.md +0 -110
  197. package/.next/standalone/tower/docs/en/modules/assets-notes.md +0 -56
  198. package/.next/standalone/tower/docs/en/modules/assistant.md +0 -63
  199. package/.next/standalone/tower/docs/en/modules/board.md +0 -44
  200. package/.next/standalone/tower/docs/en/modules/git.md +0 -55
  201. package/.next/standalone/tower/docs/en/modules/i18n.md +0 -35
  202. package/.next/standalone/tower/docs/en/modules/mcp.md +0 -62
  203. package/.next/standalone/tower/docs/en/modules/missions.md +0 -47
  204. package/.next/standalone/tower/docs/en/modules/project.md +0 -57
  205. package/.next/standalone/tower/docs/en/modules/search.md +0 -49
  206. package/.next/standalone/tower/docs/en/modules/settings.md +0 -63
  207. package/.next/standalone/tower/docs/en/modules/task.md +0 -82
  208. package/.next/standalone/tower/docs/en/modules/terminal.md +0 -73
  209. package/.next/standalone/tower/docs/en/modules/workspace.md +0 -61
  210. package/.next/standalone/tower/docs/git/README.md +0 -42
  211. package/.next/standalone/tower/docs/guide/architecture.md +0 -29
  212. package/.next/standalone/tower/docs/guide/diagrams.md +0 -24
  213. package/.next/standalone/tower/docs/guide/getting-started.md +0 -80
  214. package/.next/standalone/tower/docs/guide/introduction.md +0 -84
  215. package/.next/standalone/tower/docs/i18n/README.md +0 -23
  216. package/.next/standalone/tower/docs/index.md +0 -36
  217. package/.next/standalone/tower/docs/mcp/README.md +0 -50
  218. package/.next/standalone/tower/docs/missions/README.md +0 -40
  219. package/.next/standalone/tower/docs/modules/ai.md +0 -104
  220. package/.next/standalone/tower/docs/modules/assets-notes.md +0 -68
  221. package/.next/standalone/tower/docs/modules/assistant.md +0 -74
  222. package/.next/standalone/tower/docs/modules/board.md +0 -56
  223. package/.next/standalone/tower/docs/modules/git.md +0 -61
  224. package/.next/standalone/tower/docs/modules/i18n.md +0 -38
  225. package/.next/standalone/tower/docs/modules/mcp.md +0 -68
  226. package/.next/standalone/tower/docs/modules/missions.md +0 -54
  227. package/.next/standalone/tower/docs/modules/project.md +0 -65
  228. package/.next/standalone/tower/docs/modules/search.md +0 -57
  229. package/.next/standalone/tower/docs/modules/settings.md +0 -72
  230. package/.next/standalone/tower/docs/modules/task.md +0 -82
  231. package/.next/standalone/tower/docs/modules/terminal.md +0 -70
  232. package/.next/standalone/tower/docs/modules/workspace.md +0 -68
  233. package/.next/standalone/tower/docs/package.json +0 -11
  234. package/.next/standalone/tower/docs/pnpm-lock.yaml +0 -1620
  235. package/.next/standalone/tower/docs/postcss.config.mjs +0 -2
  236. package/.next/standalone/tower/docs/project/README.md +0 -45
  237. package/.next/standalone/tower/docs/public/banner.png +0 -0
  238. package/.next/standalone/tower/docs/public/diagrams/tower-ai-architecture-en.html +0 -259
  239. package/.next/standalone/tower/docs/public/diagrams/tower-ai-architecture.html +0 -259
  240. package/.next/standalone/tower/docs/public/diagrams/tower-data-model-en.html +0 -344
  241. package/.next/standalone/tower/docs/public/diagrams/tower-data-model.html +0 -344
  242. package/.next/standalone/tower/docs/public/diagrams/tower-module-map-en.html +0 -176
  243. package/.next/standalone/tower/docs/public/diagrams/tower-module-map.html +0 -176
  244. package/.next/standalone/tower/docs/public/diagrams/tower-system-architecture-en.html +0 -336
  245. package/.next/standalone/tower/docs/public/diagrams/tower-system-architecture.html +0 -336
  246. package/.next/standalone/tower/docs/public/diagrams/tower-task-lifecycle-en.html +0 -251
  247. package/.next/standalone/tower/docs/public/diagrams/tower-task-lifecycle.html +0 -251
  248. package/.next/standalone/tower/docs/search/README.md +0 -37
  249. package/.next/standalone/tower/docs/settings/README.md +0 -43
  250. package/.next/standalone/tower/docs/task/README.md +0 -67
  251. package/.next/standalone/tower/docs/terminal/README.md +0 -58
  252. package/.next/standalone/tower/docs/workspace/README.md +0 -50
  253. package/.next/standalone/tower/docs/zh/guide/architecture.md +0 -29
  254. package/.next/standalone/tower/docs/zh/guide/diagrams.md +0 -24
  255. package/.next/standalone/tower/docs/zh/guide/getting-started.md +0 -80
  256. package/.next/standalone/tower/docs/zh/guide/introduction.md +0 -66
  257. package/.next/standalone/tower/docs/zh/index.md +0 -23
  258. package/.next/standalone/tower/docs/zh/modules/ai.md +0 -104
  259. package/.next/standalone/tower/docs/zh/modules/assets-notes.md +0 -68
  260. package/.next/standalone/tower/docs/zh/modules/assistant.md +0 -74
  261. package/.next/standalone/tower/docs/zh/modules/board.md +0 -56
  262. package/.next/standalone/tower/docs/zh/modules/git.md +0 -61
  263. package/.next/standalone/tower/docs/zh/modules/i18n.md +0 -38
  264. package/.next/standalone/tower/docs/zh/modules/mcp.md +0 -68
  265. package/.next/standalone/tower/docs/zh/modules/missions.md +0 -54
  266. package/.next/standalone/tower/docs/zh/modules/project.md +0 -65
  267. package/.next/standalone/tower/docs/zh/modules/search.md +0 -57
  268. package/.next/standalone/tower/docs/zh/modules/settings.md +0 -72
  269. package/.next/standalone/tower/docs/zh/modules/task.md +0 -82
  270. package/.next/standalone/tower/docs/zh/modules/terminal.md +0 -70
  271. package/.next/standalone/tower/docs/zh/modules/workspace.md +0 -68
  272. package/.next/standalone/tower/eslint.config.mjs +0 -18
  273. package/.next/standalone/tower/next.config.ts +0 -15
  274. package/.next/standalone/tower/package.json +0 -117
  275. package/.next/standalone/tower/playwright.config.ts +0 -28
  276. package/.next/standalone/tower/pnpm-lock.yaml +0 -10524
  277. package/.next/standalone/tower/pnpm-workspace.yaml +0 -6
  278. package/.next/standalone/tower/prisma/init-fts.ts +0 -23
  279. package/.next/standalone/tower/prisma/schema.prisma +0 -290
  280. package/.next/standalone/tower/prompts/backend-developer.md +0 -20
  281. package/.next/standalone/tower/prompts/code-reviewer.md +0 -19
  282. package/.next/standalone/tower/prompts/frontend-developer.md +0 -20
  283. package/.next/standalone/tower/prompts/product-manager.md +0 -16
  284. package/.next/standalone/tower/public/banner.jpg +0 -0
  285. package/.next/standalone/tower/public/logo.png +0 -0
  286. package/.next/standalone/tower/scripts/copy-monaco.js +0 -27
  287. package/.next/standalone/tower/scripts/init-db.ts +0 -74
  288. package/.next/standalone/tower/scripts/migrate-data.ts +0 -102
  289. package/.next/standalone/tower/server.js +0 -38
  290. package/.next/standalone/tower/src/app/favicon.ico +0 -0
  291. package/.next/standalone/tower/src/mcp/db.ts +0 -11
  292. package/.next/standalone/tower/src/mcp/index.ts +0 -15
  293. package/.next/standalone/tower/src/mcp/server.ts +0 -52
  294. package/.next/standalone/tower/src/mcp/tools/knowledge-tools.ts +0 -100
  295. package/.next/standalone/tower/src/mcp/tools/label-tools.ts +0 -70
  296. package/.next/standalone/tower/src/mcp/tools/note-asset-tools.ts +0 -271
  297. package/.next/standalone/tower/src/mcp/tools/project-tools.ts +0 -79
  298. package/.next/standalone/tower/src/mcp/tools/report-tools.ts +0 -214
  299. package/.next/standalone/tower/src/mcp/tools/search-tools.ts +0 -32
  300. package/.next/standalone/tower/src/mcp/tools/task-tools.ts +0 -250
  301. package/.next/standalone/tower/src/mcp/tools/terminal-tools.ts +0 -154
  302. package/.next/standalone/tower/src/mcp/tools/workspace-tools.ts +0 -73
  303. package/.next/standalone/tower/tests/e2e/chat-flow.spec.ts +0 -249
  304. package/.next/standalone/tower/tests/e2e/notes-assets.spec.ts +0 -287
  305. package/.next/standalone/tower/tests/e2e/search.spec.ts +0 -186
  306. package/.next/standalone/tower/tests/e2e/settings-flow.spec.ts +0 -250
  307. package/.next/standalone/tower/tests/e2e/settings.spec.ts +0 -261
  308. package/.next/standalone/tower/tests/e2e/smoke.spec.ts +0 -317
  309. package/.next/standalone/tower/tests/e2e/task-flow.spec.ts +0 -287
  310. package/.next/standalone/tower/tests/e2e/workbench.spec.ts +0 -307
  311. package/.next/standalone/tower/tests/setup.ts +0 -15
  312. package/.next/standalone/tower/tests/unit/actions/agent-actions.test.ts +0 -157
  313. package/.next/standalone/tower/tests/unit/actions/config-actions.test.ts +0 -170
  314. package/.next/standalone/tower/tests/unit/actions/file-actions.test.ts +0 -283
  315. package/.next/standalone/tower/tests/unit/actions/git-actions.test.ts +0 -34
  316. package/.next/standalone/tower/tests/unit/actions/preview-actions.test.ts +0 -177
  317. package/.next/standalone/tower/tests/unit/actions/search-actions.test.ts +0 -358
  318. package/.next/standalone/tower/tests/unit/actions/task-actions.test.ts +0 -173
  319. package/.next/standalone/tower/tests/unit/api/diff-route.test.ts +0 -9
  320. package/.next/standalone/tower/tests/unit/api/file-serving.test.ts +0 -88
  321. package/.next/standalone/tower/tests/unit/api/merge-route.test.ts +0 -9
  322. package/.next/standalone/tower/tests/unit/api/stream-persist-result.test.ts +0 -7
  323. package/.next/standalone/tower/tests/unit/api/stream-send-back.test.ts +0 -7
  324. package/.next/standalone/tower/tests/unit/components/asset-item.test.tsx +0 -105
  325. package/.next/standalone/tower/tests/unit/components/asset-list.test.tsx +0 -51
  326. package/.next/standalone/tower/tests/unit/components/assets/asset-upload.test.tsx +0 -70
  327. package/.next/standalone/tower/tests/unit/components/board-stats.test.tsx +0 -32
  328. package/.next/standalone/tower/tests/unit/components/category-filter.test.tsx +0 -58
  329. package/.next/standalone/tower/tests/unit/components/cli-adapter-tester.test.tsx +0 -160
  330. package/.next/standalone/tower/tests/unit/components/create-task-dialog.test.tsx +0 -162
  331. package/.next/standalone/tower/tests/unit/components/file-tree.test.tsx +0 -172
  332. package/.next/standalone/tower/tests/unit/components/note-card.test.tsx +0 -71
  333. package/.next/standalone/tower/tests/unit/components/note-editor.test.tsx +0 -39
  334. package/.next/standalone/tower/tests/unit/components/prompts-config.test.tsx +0 -200
  335. package/.next/standalone/tower/tests/unit/components/search-dialog.test.tsx +0 -223
  336. package/.next/standalone/tower/tests/unit/components/system-config.test.tsx +0 -32
  337. package/.next/standalone/tower/tests/unit/hooks/hook-registration.test.ts +0 -89
  338. package/.next/standalone/tower/tests/unit/hooks/stop-hook.test.ts +0 -108
  339. package/.next/standalone/tower/tests/unit/lib/asset-actions.test.ts +0 -257
  340. package/.next/standalone/tower/tests/unit/lib/file-utils.test.ts +0 -102
  341. package/.next/standalone/tower/tests/unit/lib/fs-security.test.ts +0 -34
  342. package/.next/standalone/tower/tests/unit/lib/fts.test.ts +0 -214
  343. package/.next/standalone/tower/tests/unit/lib/git-url.test.ts +0 -258
  344. package/.next/standalone/tower/tests/unit/lib/instrumentation.test.ts +0 -86
  345. package/.next/standalone/tower/tests/unit/lib/local-path-to-api-url.test.ts +0 -40
  346. package/.next/standalone/tower/tests/unit/lib/mime-magic.test.ts +0 -95
  347. package/.next/standalone/tower/tests/unit/lib/note-actions.test.ts +0 -296
  348. package/.next/standalone/tower/tests/unit/lib/preview-process-manager.test.ts +0 -107
  349. package/.next/standalone/tower/tests/unit/lib/process-manager.test.ts +0 -10
  350. package/.next/standalone/tower/tests/unit/lib/pty-session.test.ts +0 -171
  351. package/.next/standalone/tower/tests/unit/lib/search.test.ts +0 -289
  352. package/.next/standalone/tower/tests/unit/lib/session-store.test.ts +0 -111
  353. package/.next/standalone/tower/tests/unit/lib/utils.test.ts +0 -33
  354. package/.next/standalone/tower/tests/unit/lib/worktree.test.ts +0 -190
  355. package/.next/standalone/tower/tests/unit/mcp/identify-project.test.ts +0 -217
  356. package/.next/standalone/tower/tests/unit/mcp/manage-assets.test.ts +0 -199
  357. package/.next/standalone/tower/tests/unit/mcp/manage-notes.test.ts +0 -304
  358. package/.next/standalone/tower/tests/unit/mcp/search-tools.test.ts +0 -186
  359. package/.next/standalone/tower/tests/unit/missions-merge.test.ts +0 -43
  360. package/.next/standalone/tower/tower-studio-0.1.1.tgz +0 -0
  361. package/.next/standalone/tower/tsconfig.json +0 -34
  362. package/.next/standalone/tower/vitest.config.ts +0 -17
  363. package/.next/static/a6HR9cTK7s4aKfE5dWzjz/_buildManifest.js +0 -11
  364. package/.next/static/a6HR9cTK7s4aKfE5dWzjz/_clientMiddlewareManifest.js +0 -1
  365. package/.next/static/a6HR9cTK7s4aKfE5dWzjz/_ssgManifest.js +0 -1
  366. package/.next/static/chunks/00z-g3x93ngvn.js +0 -1
  367. package/.next/static/chunks/024pdsc27tjdd.js +0 -5
  368. package/.next/static/chunks/02dd83gbiv778.js +0 -1
  369. package/.next/static/chunks/03e.4ymu.j5wl.js +0 -1
  370. package/.next/static/chunks/03~yq9q893hmn.js +0 -1
  371. package/.next/static/chunks/05-b9qqm3av9~.js +0 -1
  372. package/.next/static/chunks/05~v02mkan5z..js +0 -1
  373. package/.next/static/chunks/0abtpeymj-58i.js +0 -1
  374. package/.next/static/chunks/0b6us7uq72u-d.js +0 -1
  375. package/.next/static/chunks/0drgc-oztq6o-.css +0 -1
  376. package/.next/static/chunks/0eaa2lmymh2fx.js +0 -1
  377. package/.next/static/chunks/0gb82g.6g90mn.js +0 -1
  378. package/.next/static/chunks/0gnm22yv~f54b.js +0 -1
  379. package/.next/static/chunks/0j9qriqni_r1..js +0 -2
  380. package/.next/static/chunks/0k.u8sxy~e469.js +0 -4
  381. package/.next/static/chunks/0lnhjf2a~jaco.js +0 -83
  382. package/.next/static/chunks/0lvd52mjiit6s.js +0 -1
  383. package/.next/static/chunks/0mq0uqbbbb1~2.js +0 -1
  384. package/.next/static/chunks/0neevhl_o1ozu.css +0 -2
  385. package/.next/static/chunks/0omj~p3uxkic-.js +0 -1
  386. package/.next/static/chunks/0t-gr6j-c65qb.js +0 -1
  387. package/.next/static/chunks/0t16ai99uv4j3.js +0 -1
  388. package/.next/static/chunks/0tcl81ybuob5i.js +0 -1
  389. package/.next/static/chunks/0uqimvsni_op~.js +0 -1
  390. package/.next/static/chunks/0wt3kws~_yr8z.js +0 -1
  391. package/.next/static/chunks/0xzdu87n_for1.js +0 -5
  392. package/.next/static/chunks/0y0tdl.rl6v1u.js +0 -1
  393. package/.next/static/chunks/0z2bzovqhl2f5.js +0 -1
  394. package/.next/static/chunks/0z4y0x1ifgy.e.js +0 -1
  395. package/.next/static/chunks/0z7bwntvfhxzi.js +0 -12
  396. package/.next/static/chunks/102ijqpvi0z-d.js +0 -1
  397. package/.next/static/chunks/10n23t.1hpb-1.js +0 -1
  398. package/.next/static/chunks/11_e3-j5gzbj4.js +0 -1
  399. package/.next/static/chunks/14.ims4y7osot.js +0 -1
  400. package/.next/static/chunks/14xzmrt5ly6gq.js +0 -31
  401. package/.next/static/chunks/151wr~6x8aclx.js +0 -1
  402. package/.next/static/chunks/169po6_~f3-d5.js +0 -1
  403. package/.next/static/chunks/16w-ap~msrwpj.js +0 -1
  404. package/.next/static/chunks/176n7f13ve~a9.js +0 -1
  405. package/.next/static/chunks/17oc2l.ekcs8b.css +0 -1
  406. package/.next/static/chunks/turbopack-0wjmrsi.z32s0.js +0 -1
  407. package/.next/static/media/4fa387ec64143e14-s.0q3udbd2bu5yp.woff2 +0 -0
  408. package/.next/static/media/7178b3e590c64307-s.11.cyxs5p-0z~.woff2 +0 -0
  409. package/.next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2 +0 -0
  410. package/.next/static/media/8a480f0b521d4e75-s.06d3mdzz5bre_.woff2 +0 -0
  411. package/.next/static/media/apple-icon.16aocl-s-v2qz.png +0 -0
  412. package/.next/static/media/bbc41e54d2fcbd21-s.0gw~uztddq1df.woff2 +0 -0
  413. package/.next/static/media/caa3a2e1cccd8315-s.p.16t1db8_9y2o~.woff2 +0 -0
  414. package/.next/static/media/favicon.0y2d6j9cou~8p.ico +0 -0
  415. package/.next/static/media/icon0.0a6mkq6meyird.svg +0 -1
  416. package/.next/static/media/icon1.04ux133882seb.png +0 -0
  417. /package/{.next/standalone/tower/components.json → components.json} +0 -0
  418. /package/{.next/standalone/tower/postcss.config.mjs → postcss.config.mjs} +0 -0
  419. /package/{.next/standalone/tower/prisma → prisma}/prisma/dev.db +0 -0
  420. /package/{.next/standalone/tower/prisma → prisma}/seed.ts +0 -0
  421. /package/{.next/standalone/tower/docs/public → public}/banner.jpg +0 -0
  422. /package/{.next/standalone/tower/docs/public → public}/logo.png +0 -0
  423. /package/{.next/standalone/tower/public → public}/web-app-manifest-192x192.png +0 -0
  424. /package/{.next/standalone/tower/public → public}/web-app-manifest-512x512.png +0 -0
  425. /package/{.next/standalone/tower/scripts → scripts}/init-tower.ts +0 -0
  426. /package/{.next/standalone/tower/scripts → scripts}/post-tool-hook.js +0 -0
  427. /package/{.next/standalone/tower/scripts → scripts}/session-start-hook.js +0 -0
  428. /package/{.next/standalone/tower/scripts → scripts}/stop-hook.js +0 -0
  429. /package/{.next/standalone/tower/skills → skills}/tower/SKILL.md +0 -0
  430. /package/{.next/standalone/tower/src → src}/actions/agent-actions.ts +0 -0
  431. /package/{.next/standalone/tower/src → src}/actions/agent-config-actions.ts +0 -0
  432. /package/{.next/standalone/tower/src → src}/actions/ai-config-actions.ts +0 -0
  433. /package/{.next/standalone/tower/src → src}/actions/asset-actions.ts +0 -0
  434. /package/{.next/standalone/tower/src → src}/actions/assistant-actions.ts +0 -0
  435. /package/{.next/standalone/tower/src → src}/actions/cli-profile-actions.ts +0 -0
  436. /package/{.next/standalone/tower/src → src}/actions/config-actions.ts +0 -0
  437. /package/{.next/standalone/tower/src → src}/actions/file-actions.ts +0 -0
  438. /package/{.next/standalone/tower/src → src}/actions/git-actions.ts +0 -0
  439. /package/{.next/standalone/tower/src → src}/actions/label-actions.ts +0 -0
  440. /package/{.next/standalone/tower/src → src}/actions/note-actions.ts +0 -0
  441. /package/{.next/standalone/tower/src → src}/actions/onboarding-actions.ts +0 -0
  442. /package/{.next/standalone/tower/src → src}/actions/preview-actions.ts +0 -0
  443. /package/{.next/standalone/tower/src → src}/actions/project-actions.ts +0 -0
  444. /package/{.next/standalone/tower/src → src}/actions/prompt-actions.ts +0 -0
  445. /package/{.next/standalone/tower/src → src}/actions/report-actions.ts +0 -0
  446. /package/{.next/standalone/tower/src → src}/actions/search-actions.ts +0 -0
  447. /package/{.next/standalone/tower/src → src}/actions/search-code-actions.ts +0 -0
  448. /package/{.next/standalone/tower/src → src}/actions/task-actions.ts +0 -0
  449. /package/{.next/standalone/tower/src → src}/actions/workspace-actions.ts +0 -0
  450. /package/{.next/standalone/tower/src → src}/app/api/adapters/test/route.ts +0 -0
  451. /package/{.next/standalone/tower/src → src}/app/api/browse-fs/route.ts +0 -0
  452. /package/{.next/standalone/tower/src → src}/app/api/files/assets/[projectId]/[filename]/route.ts +0 -0
  453. /package/{.next/standalone/tower/src → src}/app/api/git/route.ts +0 -0
  454. /package/{.next/standalone/tower/src → src}/app/api/internal/assets/[projectId]/[filename]/route.ts +0 -0
  455. /package/{.next/standalone/tower/src → src}/app/api/internal/assets/reveal/route.ts +0 -0
  456. /package/{.next/standalone/tower/src → src}/app/api/internal/assistant/chat/route.ts +0 -0
  457. /package/{.next/standalone/tower/src → src}/app/api/internal/assistant/images/route.ts +0 -0
  458. /package/{.next/standalone/tower/src → src}/app/api/internal/assistant/route.ts +0 -0
  459. /package/{.next/standalone/tower/src → src}/app/api/internal/assistant/sessions/route.ts +0 -0
  460. /package/{.next/standalone/tower/src → src}/app/api/internal/cache/[...segments]/route.ts +0 -0
  461. /package/{.next/standalone/tower/src → src}/app/api/internal/hooks/install/route.ts +0 -0
  462. /package/{.next/standalone/tower/src → src}/app/api/internal/hooks/session/route.ts +0 -0
  463. /package/{.next/standalone/tower/src → src}/app/api/internal/hooks/stop/route.ts +0 -0
  464. /package/{.next/standalone/tower/src → src}/app/api/internal/hooks/upload/route.ts +0 -0
  465. /package/{.next/standalone/tower/src → src}/app/api/internal/notifications/pending/route.ts +0 -0
  466. /package/{.next/standalone/tower/src → src}/app/api/internal/terminal/[taskId]/buffer/route.ts +0 -0
  467. /package/{.next/standalone/tower/src → src}/app/api/internal/terminal/[taskId]/input/route.ts +0 -0
  468. /package/{.next/standalone/tower/src → src}/app/api/internal/terminal/[taskId]/start/route.ts +0 -0
  469. /package/{.next/standalone/tower/src → src}/app/api/tasks/[taskId]/diff/route.ts +0 -0
  470. /package/{.next/standalone/tower/src → src}/app/api/tasks/[taskId]/merge/route.ts +0 -0
  471. /package/{.next/standalone/tower/src → src}/app/apple-icon.png +0 -0
  472. /package/{.next/standalone/tower/docs/public → src/app}/favicon.ico +0 -0
  473. /package/{.next/standalone/tower/src → src}/app/globals.css +0 -0
  474. /package/{.next/standalone/tower/src → src}/app/icon0.svg +0 -0
  475. /package/{.next/standalone/tower/src → src}/app/icon1.png +0 -0
  476. /package/{.next/standalone/tower/src → src}/app/layout.tsx +0 -0
  477. /package/{.next/standalone/tower/src → src}/app/manifest.json +0 -0
  478. /package/{.next/standalone/tower/src → src}/app/missions/missions-client.tsx +0 -0
  479. /package/{.next/standalone/tower/src → src}/app/missions/page.tsx +0 -0
  480. /package/{.next/standalone/tower/src → src}/app/onboarding/page.tsx +0 -0
  481. /package/{.next/standalone/tower/src → src}/app/page.tsx +0 -0
  482. /package/{.next/standalone/tower/src → src}/app/settings/page.tsx +0 -0
  483. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/archive/archive-page-client.tsx +0 -0
  484. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/archive/page.tsx +0 -0
  485. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/assets/assets-page-client.tsx +0 -0
  486. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/assets/page.tsx +0 -0
  487. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/board-page-client.tsx +0 -0
  488. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/notes/notes-page-client.tsx +0 -0
  489. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/notes/page.tsx +0 -0
  490. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/page.tsx +0 -0
  491. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/projects/[projectId]/page.tsx +0 -0
  492. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/tasks/[taskId]/page.tsx +0 -0
  493. /package/{.next/standalone/tower/src → src}/app/workspaces/[workspaceId]/tasks/[taskId]/task-page-client.tsx +0 -0
  494. /package/{.next/standalone/tower/src → src}/app/workspaces/page.tsx +0 -0
  495. /package/{.next/standalone/tower/src → src}/components/assets/asset-item.tsx +0 -0
  496. /package/{.next/standalone/tower/src → src}/components/assets/asset-list.tsx +0 -0
  497. /package/{.next/standalone/tower/src → src}/components/assets/asset-upload.tsx +0 -0
  498. /package/{.next/standalone/tower/src → src}/components/assets/image-lightbox.tsx +0 -0
  499. /package/{.next/standalone/tower/src → src}/components/assets/text-preview-dialog.tsx +0 -0
  500. /package/{.next/standalone/tower/src → src}/components/assistant/assistant-chat-bubble.tsx +0 -0
  501. /package/{.next/standalone/tower/src → src}/components/assistant/assistant-chat.tsx +0 -0
  502. /package/{.next/standalone/tower/src → src}/components/assistant/assistant-panel.tsx +0 -0
  503. /package/{.next/standalone/tower/src → src}/components/assistant/assistant-provider.tsx +0 -0
  504. /package/{.next/standalone/tower/src → src}/components/assistant/image-preview-modal.tsx +0 -0
  505. /package/{.next/standalone/tower/src → src}/components/assistant/image-thumbnail-strip.tsx +0 -0
  506. /package/{.next/standalone/tower/src → src}/components/board/board-column.tsx +0 -0
  507. /package/{.next/standalone/tower/src → src}/components/board/board-filters.tsx +0 -0
  508. /package/{.next/standalone/tower/src → src}/components/board/board-stats.tsx +0 -0
  509. /package/{.next/standalone/tower/src → src}/components/board/column-tasks-dialog.tsx +0 -0
  510. /package/{.next/standalone/tower/src → src}/components/board/create-task-dialog.tsx +0 -0
  511. /package/{.next/standalone/tower/src → src}/components/board/kanban-board.tsx +0 -0
  512. /package/{.next/standalone/tower/src → src}/components/board/project-tabs.tsx +0 -0
  513. /package/{.next/standalone/tower/src → src}/components/board/task-card-context-menu.tsx +0 -0
  514. /package/{.next/standalone/tower/src → src}/components/board/task-card.tsx +0 -0
  515. /package/{.next/standalone/tower/src → src}/components/layout/app-sidebar.tsx +0 -0
  516. /package/{.next/standalone/tower/src → src}/components/layout/folder-browser-dialog.tsx +0 -0
  517. /package/{.next/standalone/tower/src → src}/components/layout/layout-client.tsx +0 -0
  518. /package/{.next/standalone/tower/src → src}/components/layout/search-dialog.tsx +0 -0
  519. /package/{.next/standalone/tower/src → src}/components/layout/sub-page-nav.tsx +0 -0
  520. /package/{.next/standalone/tower/src → src}/components/layout/top-bar.tsx +0 -0
  521. /package/{.next/standalone/tower/src → src}/components/missions/grid-layout-presets.ts +0 -0
  522. /package/{.next/standalone/tower/src → src}/components/missions/grid-preset-picker.tsx +0 -0
  523. /package/{.next/standalone/tower/src → src}/components/missions/merge-missions.ts +0 -0
  524. /package/{.next/standalone/tower/src → src}/components/missions/mission-card.tsx +0 -0
  525. /package/{.next/standalone/tower/src → src}/components/missions/task-picker-dialog.tsx +0 -0
  526. /package/{.next/standalone/tower/src → src}/components/notes/category-filter.tsx +0 -0
  527. /package/{.next/standalone/tower/src → src}/components/notes/note-card.tsx +0 -0
  528. /package/{.next/standalone/tower/src → src}/components/notes/note-editor.tsx +0 -0
  529. /package/{.next/standalone/tower/src → src}/components/notes/note-list.tsx +0 -0
  530. /package/{.next/standalone/tower/src → src}/components/notifications/notification-permission-banner.tsx +0 -0
  531. /package/{.next/standalone/tower/src → src}/components/notifications/use-notification-listener.ts +0 -0
  532. /package/{.next/standalone/tower/src → src}/components/onboarding/guided-tour.tsx +0 -0
  533. /package/{.next/standalone/tower/src → src}/components/onboarding/onboarding-wizard.tsx +0 -0
  534. /package/{.next/standalone/tower/src → src}/components/onboarding/wizard-step-cli.tsx +0 -0
  535. /package/{.next/standalone/tower/src → src}/components/onboarding/wizard-step-username.tsx +0 -0
  536. /package/{.next/standalone/tower/src → src}/components/project/create-project-dialog.tsx +0 -0
  537. /package/{.next/standalone/tower/src → src}/components/project/import-project-dialog.tsx +0 -0
  538. /package/{.next/standalone/tower/src → src}/components/providers/theme-provider.tsx +0 -0
  539. /package/{.next/standalone/tower/src → src}/components/repository/create-branch-dialog.tsx +0 -0
  540. /package/{.next/standalone/tower/src → src}/components/repository/git-changes-panel.tsx +0 -0
  541. /package/{.next/standalone/tower/src → src}/components/repository/git-log-panel.tsx +0 -0
  542. /package/{.next/standalone/tower/src → src}/components/repository/git-stash-panel.tsx +0 -0
  543. /package/{.next/standalone/tower/src → src}/components/repository/repo-sidebar.tsx +0 -0
  544. /package/{.next/standalone/tower/src → src}/components/settings/cli-adapter-tester.tsx +0 -0
  545. /package/{.next/standalone/tower/src → src}/components/settings/settings-page.tsx +0 -0
  546. /package/{.next/standalone/tower/src → src}/components/task/code-editor.tsx +0 -0
  547. /package/{.next/standalone/tower/src → src}/components/task/code-search.tsx +0 -0
  548. /package/{.next/standalone/tower/src → src}/components/task/diff-editor.tsx +0 -0
  549. /package/{.next/standalone/tower/src → src}/components/task/editor-git-panel.tsx +0 -0
  550. /package/{.next/standalone/tower/src → src}/components/task/editor-tabs.tsx +0 -0
  551. /package/{.next/standalone/tower/src → src}/components/task/execution-timeline.tsx +0 -0
  552. /package/{.next/standalone/tower/src → src}/components/task/file-tree-context-menu.tsx +0 -0
  553. /package/{.next/standalone/tower/src → src}/components/task/file-tree-node.tsx +0 -0
  554. /package/{.next/standalone/tower/src → src}/components/task/file-tree.tsx +0 -0
  555. /package/{.next/standalone/tower/src → src}/components/task/preview-panel.tsx +0 -0
  556. /package/{.next/standalone/tower/src → src}/components/task/task-detail-panel.tsx +0 -0
  557. /package/{.next/standalone/tower/src → src}/components/task/task-diff-view.tsx +0 -0
  558. /package/{.next/standalone/tower/src → src}/components/task/task-file-changes.tsx +0 -0
  559. /package/{.next/standalone/tower/src → src}/components/task/task-merge-confirm-dialog.tsx +0 -0
  560. /package/{.next/standalone/tower/src → src}/components/task/task-metadata.tsx +0 -0
  561. /package/{.next/standalone/tower/src → src}/components/task/task-notes-panel.tsx +0 -0
  562. /package/{.next/standalone/tower/src → src}/components/task/task-overview-drawer.tsx +0 -0
  563. /package/{.next/standalone/tower/src → src}/components/task/task-terminal.tsx +0 -0
  564. /package/{.next/standalone/tower/src → src}/components/task/terminal-portal.tsx +0 -0
  565. /package/{.next/standalone/tower/src → src}/components/task/types.ts +0 -0
  566. /package/{.next/standalone/tower/src → src}/components/ui/avatar.tsx +0 -0
  567. /package/{.next/standalone/tower/src → src}/components/ui/badge.tsx +0 -0
  568. /package/{.next/standalone/tower/src → src}/components/ui/button.tsx +0 -0
  569. /package/{.next/standalone/tower/src → src}/components/ui/card.tsx +0 -0
  570. /package/{.next/standalone/tower/src → src}/components/ui/command.tsx +0 -0
  571. /package/{.next/standalone/tower/src → src}/components/ui/dialog.tsx +0 -0
  572. /package/{.next/standalone/tower/src → src}/components/ui/dropdown-menu.tsx +0 -0
  573. /package/{.next/standalone/tower/src → src}/components/ui/empty-state.tsx +0 -0
  574. /package/{.next/standalone/tower/src → src}/components/ui/error-boundary.tsx +0 -0
  575. /package/{.next/standalone/tower/src → src}/components/ui/input-group.tsx +0 -0
  576. /package/{.next/standalone/tower/src → src}/components/ui/input.tsx +0 -0
  577. /package/{.next/standalone/tower/src → src}/components/ui/label.tsx +0 -0
  578. /package/{.next/standalone/tower/src → src}/components/ui/popover.tsx +0 -0
  579. /package/{.next/standalone/tower/src → src}/components/ui/scroll-area.tsx +0 -0
  580. /package/{.next/standalone/tower/src → src}/components/ui/segmented-control.tsx +0 -0
  581. /package/{.next/standalone/tower/src → src}/components/ui/select.tsx +0 -0
  582. /package/{.next/standalone/tower/src → src}/components/ui/separator.tsx +0 -0
  583. /package/{.next/standalone/tower/src → src}/components/ui/sheet.tsx +0 -0
  584. /package/{.next/standalone/tower/src → src}/components/ui/sonner.tsx +0 -0
  585. /package/{.next/standalone/tower/src → src}/components/ui/switch.tsx +0 -0
  586. /package/{.next/standalone/tower/src → src}/components/ui/tabs.tsx +0 -0
  587. /package/{.next/standalone/tower/src → src}/components/ui/textarea.tsx +0 -0
  588. /package/{.next/standalone/tower/src → src}/components/ui/toast.tsx +0 -0
  589. /package/{.next/standalone/tower/src → src}/components/ui/tooltip.tsx +0 -0
  590. /package/{.next/standalone/tower/src → src}/hooks/sse-event-reducer.ts +0 -0
  591. /package/{.next/standalone/tower/src → src}/hooks/use-assistant-chat.ts +0 -0
  592. /package/{.next/standalone/tower/src → src}/hooks/use-image-upload.ts +0 -0
  593. /package/{.next/standalone/tower/src → src}/instrumentation.ts +0 -0
  594. /package/{.next/standalone/tower/src → src}/lib/ai/adapters/cli/claude-cli-adapter.ts +0 -0
  595. /package/{.next/standalone/tower/src → src}/lib/ai/capability-resolver.ts +0 -0
  596. /package/{.next/standalone/tower/src → src}/lib/ai/provider-registry.ts +0 -0
  597. /package/{.next/standalone/tower/src → src}/lib/ai/providers/claude.ts +0 -0
  598. /package/{.next/standalone/tower/src → src}/lib/ai/providers/index.ts +0 -0
  599. /package/{.next/standalone/tower/src → src}/lib/ai/types.ts +0 -0
  600. /package/{.next/standalone/tower/src → src}/lib/assistant-constants.ts +0 -0
  601. /package/{.next/standalone/tower/src → src}/lib/assistant-message-converter.ts +0 -0
  602. /package/{.next/standalone/tower/src → src}/lib/assistant-sessions.ts +0 -0
  603. /package/{.next/standalone/tower/src → src}/lib/build-multimodal-prompt.ts +0 -0
  604. /package/{.next/standalone/tower/src → src}/lib/claude-session.ts +0 -0
  605. /package/{.next/standalone/tower/src → src}/lib/cli-test.ts +0 -0
  606. /package/{.next/standalone/tower/src → src}/lib/config-defaults.ts +0 -0
  607. /package/{.next/standalone/tower/src → src}/lib/config-reader.ts +0 -0
  608. /package/{.next/standalone/tower/src → src}/lib/constants.ts +0 -0
  609. /package/{.next/standalone/tower/src → src}/lib/db.ts +0 -0
  610. /package/{.next/standalone/tower/src → src}/lib/diff-parser.ts +0 -0
  611. /package/{.next/standalone/tower/src → src}/lib/execution-summary.ts +0 -0
  612. /package/{.next/standalone/tower/src → src}/lib/file-serve-client.ts +0 -0
  613. /package/{.next/standalone/tower/src → src}/lib/file-serve.ts +0 -0
  614. /package/{.next/standalone/tower/src → src}/lib/file-utils.ts +0 -0
  615. /package/{.next/standalone/tower/src → src}/lib/fs-security.ts +0 -0
  616. /package/{.next/standalone/tower/src → src}/lib/fts.ts +0 -0
  617. /package/{.next/standalone/tower/src → src}/lib/git-api.ts +0 -0
  618. /package/{.next/standalone/tower/src → src}/lib/git-url.ts +0 -0
  619. /package/{.next/standalone/tower/src → src}/lib/i18n/en.ts +0 -0
  620. /package/{.next/standalone/tower/src → src}/lib/i18n/types.ts +0 -0
  621. /package/{.next/standalone/tower/src → src}/lib/i18n/zh.ts +0 -0
  622. /package/{.next/standalone/tower/src → src}/lib/i18n.tsx +0 -0
  623. /package/{.next/standalone/tower/src → src}/lib/init-tower.ts +0 -0
  624. /package/{.next/standalone/tower/src → src}/lib/instrumentation-tasks.ts +0 -0
  625. /package/{.next/standalone/tower/src → src}/lib/internal-api-guard.ts +0 -0
  626. /package/{.next/standalone/tower/src → src}/lib/logger.ts +0 -0
  627. /package/{.next/standalone/tower/src → src}/lib/mime-magic.ts +0 -0
  628. /package/{.next/standalone/tower/src → src}/lib/platform.ts +0 -0
  629. /package/{.next/standalone/tower/src → src}/lib/preview-process.ts +0 -0
  630. /package/{.next/standalone/tower/src → src}/lib/pty/pty-session.ts +0 -0
  631. /package/{.next/standalone/tower/src → src}/lib/pty/session-store.ts +0 -0
  632. /package/{.next/standalone/tower/src → src}/lib/pty/ws-server.ts +0 -0
  633. /package/{.next/standalone/tower/src → src}/lib/schemas.ts +0 -0
  634. /package/{.next/standalone/tower/src → src}/lib/search.ts +0 -0
  635. /package/{.next/standalone/tower/src → src}/lib/terminal-link-provider.ts +0 -0
  636. /package/{.next/standalone/tower/src → src}/lib/tower-dir.ts +0 -0
  637. /package/{.next/standalone/tower/src → src}/lib/utils.ts +0 -0
  638. /package/{.next/standalone/tower/src → src}/lib/worktree.ts +0 -0
  639. /package/{.next/standalone/tower/src → src}/stores/board-store.ts +0 -0
  640. /package/{.next/standalone/tower/src → src}/stores/task-execution-store.ts +0 -0
  641. /package/{.next/standalone/tower/src → src}/types/index.ts +0 -0
@@ -1,73 +0,0 @@
1
- import { z } from "zod";
2
- import { db } from "../db";
3
-
4
- export const workspaceTools = {
5
- list_workspaces: {
6
- description: "List all workspaces ordered by last updated, including project count for each.",
7
- schema: z.object({}),
8
- handler: async (_args: Record<string, never>) => {
9
- const workspaces = await db.workspace.findMany({
10
- include: {
11
- projects: {
12
- select: { id: true },
13
- },
14
- },
15
- orderBy: { updatedAt: "desc" },
16
- });
17
-
18
- return workspaces.map(({ projects, ...rest }) => ({
19
- ...rest,
20
- projectCount: projects.length,
21
- }));
22
- },
23
- },
24
-
25
- create_workspace: {
26
- description: "Create a new workspace with a name and optional description.",
27
- schema: z.object({
28
- name: z.string(),
29
- description: z.string().optional(),
30
- }),
31
- handler: async (args: { name: string; description?: string }) => {
32
- return db.workspace.create({
33
- data: {
34
- name: args.name,
35
- description: args.description,
36
- },
37
- });
38
- },
39
- },
40
-
41
- update_workspace: {
42
- description: "Update an existing workspace's name and/or description.",
43
- schema: z.object({
44
- workspaceId: z.string(),
45
- name: z.string().optional(),
46
- description: z.string().optional(),
47
- }),
48
- handler: async (args: { workspaceId: string; name?: string; description?: string }) => {
49
- return db.workspace.update({
50
- where: { id: args.workspaceId },
51
- data: {
52
- name: args.name,
53
- description: args.description,
54
- },
55
- });
56
- },
57
- },
58
-
59
- delete_workspace: {
60
- description: "Delete a workspace by ID. Cascade delete is handled by the Prisma schema.",
61
- schema: z.object({
62
- workspaceId: z.string(),
63
- }),
64
- handler: async (args: { workspaceId: string }) => {
65
- const count = await db.workspace.count();
66
- if (count <= 1) {
67
- throw new Error("Cannot delete the last workspace");
68
- }
69
- await db.workspace.delete({ where: { id: args.workspaceId } });
70
- return { deleted: true, workspaceId: args.workspaceId };
71
- },
72
- },
73
- };
@@ -1,249 +0,0 @@
1
- /**
2
- * E2E-02: Chat Assistant Flow
3
- *
4
- * Covers the global chat assistant: open panel → send message → user bubble visible
5
- * → (response bubble or graceful timeout) → paste image → thumbnail appears.
6
- *
7
- * NOTE: The "receive assistant response" test depends on a running Claude SDK backend
8
- * reachable at /api/internal/assistant/chat. In CI without credentials it will
9
- * either see an error bubble or a timeout — the test handles both gracefully.
10
- */
11
- import { test, expect } from "@playwright/test";
12
-
13
- // ---------------------------------------------------------------------------
14
- // Helper: navigate to settings and switch assistant to chat mode
15
- // ---------------------------------------------------------------------------
16
-
17
- async function ensureChatMode(page: import("@playwright/test").Page) {
18
- await page.goto("/settings");
19
- await page.locator("nav").waitFor({ state: "visible", timeout: 10000 });
20
- // Allow React useEffects to hydrate (locale, mounted state, config values)
21
- await page.waitForTimeout(500);
22
-
23
- // Find the Communication Mode select — look for "Chat" / "聊天模式" option
24
- // The select trigger shows the current mode; if already "Chat" / "聊天模式", skip
25
- const chatOptionText = /Chat|聊天模式/;
26
- const terminalOptionText = /Terminal|终端模式/;
27
-
28
- // The select trigger for communication mode appears after mounting
29
- // We look for a select that currently shows "Terminal" / "终端模式" and switch it to Chat
30
- const deadline = Date.now() + 8000;
31
- while (Date.now() < deadline) {
32
- // Check if any select trigger currently shows terminal mode
33
- const triggers = page.locator("button[role='combobox']");
34
- const count = await triggers.count();
35
- let found = false;
36
- for (let i = 0; i < count; i++) {
37
- const text = await triggers.nth(i).textContent();
38
- if (text && terminalOptionText.test(text)) {
39
- // Click to open the dropdown
40
- await triggers.nth(i).click();
41
- await page.waitForTimeout(200);
42
- // Click the Chat option
43
- const chatItem = page.locator("[role='option']").filter({ hasText: chatOptionText });
44
- if (await chatItem.count() > 0) {
45
- await chatItem.first().click();
46
- await page.waitForTimeout(300);
47
- found = true;
48
- }
49
- break;
50
- }
51
- }
52
- if (found) break;
53
- await page.waitForTimeout(200);
54
- }
55
-
56
- // Navigate away and back to /workspaces to ensure fresh config is picked up
57
- await page.goto("/workspaces");
58
- await page.waitForLoadState("domcontentloaded");
59
- await page.waitForTimeout(500);
60
- }
61
-
62
- // ---------------------------------------------------------------------------
63
- // Helper: open the assistant panel via the top-bar Bot button
64
- // ---------------------------------------------------------------------------
65
-
66
- async function openAssistantPanel(page: import("@playwright/test").Page) {
67
- // Click the Bot icon button in the top-bar
68
- const assistantBtn = page.locator("button[aria-label='助手'], button[aria-label='Assistant']").first();
69
- await assistantBtn.waitFor({ state: "visible", timeout: 8000 });
70
- await assistantBtn.click();
71
-
72
- // Wait for assistant panel to appear — the panel title bar contains a Bot icon
73
- // and a title text "助手" / "Assistant". We wait for the close button to appear
74
- // inside the panel to confirm it opened.
75
- const closeBtn = page.locator("button[aria-label]").filter({ hasText: "" }).filter({
76
- has: page.locator("svg"),
77
- });
78
-
79
- // More reliable: wait for the chat textarea to appear (confirms panel is open + chat mode)
80
- await page
81
- .locator("textarea[placeholder]")
82
- .waitFor({ state: "visible", timeout: 10000 });
83
- }
84
-
85
- // ---------------------------------------------------------------------------
86
- // Test suite
87
- // ---------------------------------------------------------------------------
88
-
89
- test.describe.serial("Chat Assistant Flow", () => {
90
-
91
- // 1. Setup: switch to chat mode
92
- test("0. Switch assistant to chat mode in settings", async ({ page }) => {
93
- await ensureChatMode(page);
94
- // Verify we are back on workspaces page
95
- await expect(page).toHaveURL(/\/workspaces/, { timeout: 5000 });
96
- });
97
-
98
- // 2. Open the assistant panel
99
- test("1. Open assistant panel", async ({ page }) => {
100
- // Navigate to workspaces first
101
- await page.goto("/workspaces");
102
- await page.waitForLoadState("domcontentloaded");
103
- await page.waitForTimeout(500);
104
-
105
- // Click the assistant button (Bot icon in top-bar)
106
- const assistantBtn = page.locator("button[aria-label='助手'], button[aria-label='Assistant']").first();
107
- await assistantBtn.waitFor({ state: "visible", timeout: 8000 });
108
- await assistantBtn.click();
109
-
110
- // Confirm the assistant panel opened: the chat textarea should be visible
111
- const chatInput = page.locator("textarea[placeholder]");
112
- await expect(chatInput).toBeVisible({ timeout: 10000 });
113
- });
114
-
115
- // 3. Send a text message and verify user bubble appears
116
- test("2. Send a text message and verify user bubble appears", async ({ page }) => {
117
- await page.goto("/workspaces");
118
- await page.waitForLoadState("domcontentloaded");
119
- await page.waitForTimeout(500);
120
-
121
- // Open the assistant panel
122
- const assistantBtn = page.locator("button[aria-label='助手'], button[aria-label='Assistant']").first();
123
- await assistantBtn.waitFor({ state: "visible", timeout: 8000 });
124
- await assistantBtn.click();
125
-
126
- // Wait for the chat textarea
127
- const chatInput = page.locator("textarea[placeholder]");
128
- await chatInput.waitFor({ state: "visible", timeout: 10000 });
129
-
130
- // Type a message
131
- const testMessage = "Hello, please respond with just the word OK";
132
- await chatInput.click();
133
- await chatInput.fill(testMessage);
134
-
135
- // Press Enter to send (the AssistantChat keyDown handler sends on Enter without Shift)
136
- await chatInput.press("Enter");
137
-
138
- // Verify the user bubble appears — UserBubble has aria-label="You"
139
- const userBubble = page.locator('[aria-label="You"]').first();
140
- await expect(userBubble).toBeVisible({ timeout: 8000 });
141
-
142
- // Verify the message text is in the bubble
143
- await expect(userBubble).toContainText(testMessage);
144
- });
145
-
146
- // 4. Wait for assistant response (Claude-dependent — graceful skip if unavailable)
147
- //
148
- // NOTE: This test requires a working Claude Agent SDK connection. In CI or
149
- // environments without credentials it will see an error message or thinking
150
- // indicator timeout. The test passes if EITHER a real response OR an error
151
- // message appears within the timeout.
152
- test("3. Receive assistant response or error (Claude SDK dependent)", async ({ page }) => {
153
- test.slow(); // Extends test timeout × 3 (up to 180s with global 60s timeout)
154
-
155
- await page.goto("/workspaces");
156
- await page.waitForLoadState("domcontentloaded");
157
- await page.waitForTimeout(500);
158
-
159
- // Open assistant panel
160
- const assistantBtn = page.locator("button[aria-label='助手'], button[aria-label='Assistant']").first();
161
- await assistantBtn.waitFor({ state: "visible", timeout: 8000 });
162
- await assistantBtn.click();
163
-
164
- const chatInput = page.locator("textarea[placeholder]");
165
- await chatInput.waitFor({ state: "visible", timeout: 10000 });
166
-
167
- // Send a short message
168
- await chatInput.click();
169
- await chatInput.fill("Hi");
170
- await chatInput.press("Enter");
171
-
172
- // Wait for user bubble to appear first
173
- const userBubble = page.locator('[aria-label="You"]').first();
174
- await expect(userBubble).toBeVisible({ timeout: 8000 });
175
-
176
- // Now wait for either:
177
- // a) Assistant response bubble (aria-label="Assistant") — real response
178
- // b) Error message bubble (contains "Error:" or "Connection error:") — no SDK
179
- // c) Thinking bubble (role="status") — still waiting
180
- //
181
- // We wait up to 120s for any non-user, non-thinking bubble
182
- const responseOrError = page.locator('[aria-label="Assistant"], [role="status"]');
183
- await expect(responseOrError.first()).toBeVisible({ timeout: 120_000 });
184
-
185
- // Test passes regardless of whether it's a real response or thinking indicator
186
- // This is intentional — the test verifies the UI pipeline works end to end
187
- });
188
-
189
- // 5. Paste image and verify thumbnail appears in thumbnail strip
190
- test("4. Paste image shows thumbnail in thumbnail strip", async ({ page }) => {
191
- await page.goto("/workspaces");
192
- await page.waitForLoadState("domcontentloaded");
193
- await page.waitForTimeout(500);
194
-
195
- // Open assistant panel
196
- const assistantBtn = page.locator("button[aria-label='助手'], button[aria-label='Assistant']").first();
197
- await assistantBtn.waitFor({ state: "visible", timeout: 8000 });
198
- await assistantBtn.click();
199
-
200
- const chatInput = page.locator("textarea[placeholder]");
201
- await chatInput.waitFor({ state: "visible", timeout: 10000 });
202
- await chatInput.click();
203
-
204
- // Simulate a clipboard paste event with a 1×1 PNG image
205
- // The AssistantChat.handlePaste reads clipboardData.items for image/* files
206
- await page.evaluate(() => {
207
- const textarea = document.querySelector("textarea");
208
- if (!textarea) return;
209
-
210
- // Minimal 1×1 transparent PNG (base64)
211
- const base64 =
212
- "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
213
- const binary = atob(base64);
214
- const bytes = new Uint8Array(binary.length);
215
- for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
216
- const file = new File([bytes], "test-image.png", { type: "image/png" });
217
-
218
- const dt = new DataTransfer();
219
- dt.items.add(file);
220
-
221
- const pasteEvent = new ClipboardEvent("paste", {
222
- clipboardData: dt,
223
- bubbles: true,
224
- cancelable: true,
225
- });
226
-
227
- textarea.dispatchEvent(pasteEvent);
228
- });
229
-
230
- // The ImageThumbnailStrip renders a container with thumbnail images.
231
- // Each thumbnail is an <img> inside a relative h-12 w-12 div.
232
- // Wait for at least one thumbnail image to appear inside the input area.
233
- const thumbnail = page.locator("div.border-t").locator("img").first();
234
-
235
- // Also check for the progress bar (uploading state) — it means paste was handled
236
- // Use a broader check: any img in the assistant panel area
237
- const thumbnailStrip = page.locator('[role="progressbar"], div.flex.flex-row.gap-2 img').first();
238
-
239
- // We wait for either the thumbnail img or the progress bar to appear
240
- // (upload may be fast or slow depending on network / server state)
241
- const imgInPanel = page
242
- .locator("div.border-t")
243
- .locator("div.flex.flex-row.gap-2 img, img[src^='blob:']")
244
- .first();
245
-
246
- await expect(imgInPanel).toBeVisible({ timeout: 10000 });
247
- });
248
-
249
- });
@@ -1,287 +0,0 @@
1
- import { test, expect, type Page } from "@playwright/test";
2
-
3
- test.describe.serial("Phase 7: Notes & Assets Web UI", () => {
4
- // Helper: navigate to a workspace that has projects
5
- async function goToWorkspace(page: Page) {
6
- await page.goto("/workspaces");
7
- const sidebar = page.locator("aside");
8
- // Click first workspace button
9
- const wsBtn = sidebar.locator("button").filter({ hasText: /测试|Test|E2E/ }).first();
10
- if (!await wsBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
11
- // Fallback: click any workspace
12
- const anyWs = sidebar.locator("[data-slot='sidebar-menu-button']").first();
13
- if (await anyWs.isVisible({ timeout: 3000 }).catch(() => false)) {
14
- await anyWs.click();
15
- }
16
- } else {
17
- await wsBtn.click();
18
- }
19
- await page.waitForURL(/\/workspaces\//);
20
- await page.waitForTimeout(500);
21
- }
22
-
23
- // ─── Notes Page ───
24
-
25
- test("7.1 侧边栏显示笔记和资源导航链接", async ({ page }) => {
26
- await goToWorkspace(page);
27
- const sidebar = page.locator("aside");
28
- const notesLink = sidebar.locator("a").filter({ hasText: /笔记|Notes/ });
29
- const assetsLink = sidebar.locator("a").filter({ hasText: /资源|Assets/ });
30
- await expect(notesLink).toBeVisible({ timeout: 3000 });
31
- await expect(assetsLink).toBeVisible({ timeout: 3000 });
32
- });
33
-
34
- test("7.2 点击笔记链接进入笔记页面", async ({ page }) => {
35
- await goToWorkspace(page);
36
- const sidebar = page.locator("aside");
37
- const notesLink = sidebar.locator("a").filter({ hasText: /笔记|Notes/ });
38
- await notesLink.click();
39
- await page.waitForURL(/\/notes/);
40
- // Should see the notes page with a "new note" button
41
- await expect(
42
- page.locator("button").filter({ hasText: /新建笔记|New Note/ })
43
- ).toBeVisible({ timeout: 5000 });
44
- });
45
-
46
- test("7.3 笔记页面显示分类筛选按钮", async ({ page }) => {
47
- await goToWorkspace(page);
48
- const sidebar = page.locator("aside");
49
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
50
- await page.waitForURL(/\/notes/);
51
- await page.waitForTimeout(500);
52
- // Category filter should show preset categories
53
- const allBtn = page.locator("button").filter({ hasText: /全部|All/ });
54
- await expect(allBtn).toBeVisible({ timeout: 3000 });
55
- // Check at least one preset category is visible
56
- const categories = ["账号", "环境", "需求", "备忘"];
57
- let found = false;
58
- for (const cat of categories) {
59
- const btn = page.locator("button").filter({ hasText: cat });
60
- if (await btn.isVisible().catch(() => false)) {
61
- found = true;
62
- break;
63
- }
64
- }
65
- expect(found).toBe(true);
66
- });
67
-
68
- test("7.4 新建笔记:填写表单并保存", async ({ page }) => {
69
- await goToWorkspace(page);
70
- const sidebar = page.locator("aside");
71
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
72
- await page.waitForURL(/\/notes/);
73
- await page.waitForTimeout(500);
74
-
75
- // Click new note button
76
- await page.locator("button").filter({ hasText: /新建笔记|New Note/ }).click();
77
- await page.waitForTimeout(300);
78
-
79
- // Fill title
80
- const titleInput = page.locator("input").filter({ hasNotText: "" }).first();
81
- await titleInput.fill("E2E测试笔记");
82
-
83
- // Fill content in textarea
84
- const textarea = page.locator("textarea");
85
- await textarea.fill("## 测试内容\n\n这是一条E2E自动化测试创建的笔记。");
86
-
87
- // Click save
88
- const saveBtn = page.locator("button").filter({ hasText: /保存|Save/ });
89
- await saveBtn.click();
90
- await page.waitForTimeout(1000);
91
-
92
- // Verify note appears in list
93
- await expect(page.getByText("E2E测试笔记")).toBeVisible({ timeout: 5000 });
94
- });
95
-
96
- test("7.5 笔记卡片显示标题和内容预览", async ({ page }) => {
97
- await goToWorkspace(page);
98
- const sidebar = page.locator("aside");
99
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
100
- await page.waitForURL(/\/notes/);
101
- await page.waitForTimeout(1000);
102
-
103
- // The note we created should show title and content preview
104
- const noteTitle = page.getByText("E2E测试笔记");
105
- if (!await noteTitle.isVisible({ timeout: 3000 }).catch(() => false)) {
106
- test.skip();
107
- return;
108
- }
109
- await expect(noteTitle).toBeVisible();
110
- await expect(page.getByText("测试内容")).toBeVisible();
111
- });
112
-
113
- test("7.6 编辑笔记", async ({ page }) => {
114
- await goToWorkspace(page);
115
- const sidebar = page.locator("aside");
116
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
117
- await page.waitForURL(/\/notes/);
118
- await page.waitForTimeout(1000);
119
-
120
- const noteTitle = page.getByText("E2E测试笔记");
121
- if (!await noteTitle.isVisible({ timeout: 3000 }).catch(() => false)) {
122
- test.skip();
123
- return;
124
- }
125
-
126
- // Find and click edit button (pencil icon) - hover to reveal
127
- const noteCard = noteTitle.locator("xpath=ancestor::div[contains(@class, 'border')]");
128
- await noteCard.hover();
129
- await page.waitForTimeout(200);
130
- const editBtn = noteCard.locator("button[aria-label*='edit'], button:has(svg.lucide-pencil)").first();
131
- if (await editBtn.isVisible().catch(() => false)) {
132
- await editBtn.click();
133
- await page.waitForTimeout(500);
134
-
135
- // Update title
136
- const titleInput = page.locator("input").first();
137
- await titleInput.clear();
138
- await titleInput.fill("E2E已编辑笔记");
139
-
140
- // Save
141
- const saveBtn = page.locator("button").filter({ hasText: /保存|Save/ });
142
- await saveBtn.click();
143
- await page.waitForTimeout(1000);
144
-
145
- await expect(page.getByText("E2E已编辑笔记")).toBeVisible({ timeout: 5000 });
146
- } else {
147
- test.skip();
148
- }
149
- });
150
-
151
- test("7.7 分类筛选功能", async ({ page }) => {
152
- await goToWorkspace(page);
153
- const sidebar = page.locator("aside");
154
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
155
- await page.waitForURL(/\/notes/);
156
- await page.waitForTimeout(1000);
157
-
158
- // Click a specific category filter
159
- const catBtn = page.locator("button").filter({ hasText: "账号" });
160
- if (await catBtn.isVisible().catch(() => false)) {
161
- await catBtn.click();
162
- await page.waitForTimeout(500);
163
- // The button should be active (amber style)
164
- await expect(catBtn).toHaveClass(/amber/);
165
- // Click "All" to reset
166
- const allBtn = page.locator("button").filter({ hasText: /全部|All/ });
167
- await allBtn.click();
168
- await page.waitForTimeout(300);
169
- } else {
170
- test.skip();
171
- }
172
- });
173
-
174
- test("7.8 删除笔记", async ({ page }) => {
175
- await goToWorkspace(page);
176
- const sidebar = page.locator("aside");
177
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
178
- await page.waitForURL(/\/notes/);
179
- await page.waitForTimeout(1000);
180
-
181
- const noteTitle = page.getByText(/E2E.*笔记/);
182
- if (!await noteTitle.isVisible({ timeout: 3000 }).catch(() => false)) {
183
- test.skip();
184
- return;
185
- }
186
-
187
- // Hover and click delete button
188
- const noteCard = noteTitle.locator("xpath=ancestor::div[contains(@class, 'border')]");
189
- await noteCard.hover();
190
- await page.waitForTimeout(200);
191
- const deleteBtn = noteCard.locator("button[aria-label*='delete'], button:has(svg.lucide-trash)").first();
192
- if (await deleteBtn.isVisible().catch(() => false)) {
193
- await deleteBtn.click();
194
- await page.waitForTimeout(2000);
195
- // Note should be gone
196
- await expect(noteTitle).not.toBeVisible({ timeout: 5000 });
197
- } else {
198
- test.skip();
199
- }
200
- });
201
-
202
- test("7.9 返回看板链接可用", async ({ page }) => {
203
- await goToWorkspace(page);
204
- const sidebar = page.locator("aside");
205
- await sidebar.locator("a").filter({ hasText: /笔记|Notes/ }).click();
206
- await page.waitForURL(/\/notes/);
207
- await page.waitForTimeout(500);
208
-
209
- const backLink = page.locator("a").filter({ hasText: /返回看板|Back/ });
210
- await expect(backLink).toBeVisible({ timeout: 3000 });
211
- await backLink.click();
212
- await page.waitForURL(/\/workspaces\/[^/]+$/);
213
- });
214
-
215
- // ─── Assets Page ───
216
-
217
- test("7.10 点击资源链接进入资源页面", async ({ page }) => {
218
- await goToWorkspace(page);
219
- const sidebar = page.locator("aside");
220
- const assetsLink = sidebar.locator("a").filter({ hasText: /资源|Assets/ });
221
- await assetsLink.click();
222
- await page.waitForURL(/\/assets/);
223
- // Should see upload button
224
- await expect(
225
- page.locator("button").filter({ hasText: /上传|Upload/ })
226
- ).toBeVisible({ timeout: 5000 });
227
- });
228
-
229
- test("7.11 资源页面显示空状态或文件列表", async ({ page }) => {
230
- await goToWorkspace(page);
231
- const sidebar = page.locator("aside");
232
- await sidebar.locator("a").filter({ hasText: /资源|Assets/ }).click();
233
- await page.waitForURL(/\/assets/);
234
- await page.waitForTimeout(1000);
235
-
236
- // Either we see asset items or empty state text
237
- const hasAssets = await page.locator("a[aria-label*='download']").count() > 0;
238
- const hasEmpty = await page.getByText(/暂无|No assets|empty/).isVisible().catch(() => false);
239
- expect(hasAssets || hasEmpty).toBe(true);
240
- });
241
-
242
- test("7.12 上传按钮存在且可点击", async ({ page }) => {
243
- await goToWorkspace(page);
244
- const sidebar = page.locator("aside");
245
- await sidebar.locator("a").filter({ hasText: /资源|Assets/ }).click();
246
- await page.waitForURL(/\/assets/);
247
- await page.waitForTimeout(500);
248
-
249
- const uploadBtn = page.locator("button").filter({ hasText: /上传|Upload/ });
250
- await expect(uploadBtn).toBeVisible();
251
- await expect(uploadBtn).toBeEnabled();
252
- });
253
-
254
- test("7.13 资源页面返回看板", async ({ page }) => {
255
- await goToWorkspace(page);
256
- const sidebar = page.locator("aside");
257
- await sidebar.locator("a").filter({ hasText: /资源|Assets/ }).click();
258
- await page.waitForURL(/\/assets/);
259
- await page.waitForTimeout(500);
260
-
261
- const backLink = page.locator("a").filter({ hasText: /返回看板|Back/ });
262
- await expect(backLink).toBeVisible({ timeout: 3000 });
263
- await backLink.click();
264
- await page.waitForURL(/\/workspaces\/[^/]+$/);
265
- });
266
- });
267
-
268
- // ─── File Serving Security ───
269
-
270
- test.describe("Phase 6: File Serving Security", () => {
271
- test("6.1 路径穿越攻击返回400", async ({ page }) => {
272
- const response = await page.goto("/api/files/assets/../../etc/passwd");
273
- expect(response?.status()).toBe(400);
274
- });
275
-
276
- test("6.2 不存在的文件返回404", async ({ page }) => {
277
- const response = await page.goto("/api/files/assets/nonexistent-project/nonexistent-file.txt");
278
- expect(response?.status()).toBe(404);
279
- });
280
-
281
- test("6.3 正常asset路径格式正确(即使文件不存在也返回404而非500)", async ({ page }) => {
282
- const response = await page.goto("/api/files/assets/test-project-id/test.png");
283
- // Should be 400 (invalid path) or 404 (not found), never 500
284
- const status = response?.status();
285
- expect(status === 400 || status === 404).toBe(true);
286
- });
287
- });