tower-studio 0.2.41 → 0.2.43

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 (404) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +3 -0
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/routes-manifest.json +24 -0
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page/react-loadable-manifest.json +3 -3
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +27 -27
  15. package/.next/standalone/.next/server/app/_not-found/page.js +6 -6
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/api/adapters/test/route.js +4 -4
  19. package/.next/standalone/.next/server/app/api/adapters/test/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/browse-fs/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/files/assets/[projectId]/[filename]/route.js +1 -1
  22. package/.next/standalone/.next/server/app/api/files/assets/[projectId]/[filename]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/internal/assets/[projectId]/[filename]/route.js +1 -1
  25. package/.next/standalone/.next/server/app/api/internal/assets/[projectId]/[filename]/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/internal/assets/reveal/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/internal/assistant/attachments/route.js +1 -1
  28. package/.next/standalone/.next/server/app/api/internal/assistant/attachments/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/internal/assistant/chat/route.js +3 -3
  30. package/.next/standalone/.next/server/app/api/internal/assistant/chat/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/internal/assistant/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/internal/assistant/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/internal/assistant/sessions/route.js +1 -1
  34. package/.next/standalone/.next/server/app/api/internal/assistant/sessions/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/internal/backup/import/route.js +1 -1
  36. package/.next/standalone/.next/server/app/api/internal/backup/import/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/internal/cache/[...segments]/route.js +1 -1
  38. package/.next/standalone/.next/server/app/api/internal/cache/[...segments]/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/internal/hooks/install/route.js +1 -1
  40. package/.next/standalone/.next/server/app/api/internal/hooks/install/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/internal/hooks/session/route.js +1 -1
  42. package/.next/standalone/.next/server/app/api/internal/hooks/session/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/internal/hooks/stop/route.js +2 -2
  44. package/.next/standalone/.next/server/app/api/internal/hooks/stop/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/internal/hooks/upload/route.js +2 -2
  46. package/.next/standalone/.next/server/app/api/internal/hooks/upload/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/internal/monaco/[...path]/route.js +1 -1
  48. package/.next/standalone/.next/server/app/api/internal/monaco/[...path]/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/buffer/route.js +1 -1
  50. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/buffer/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/input/route.js +1 -1
  52. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/input/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route/app-paths-manifest.json +3 -0
  54. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route/build-manifest.json +9 -0
  55. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route/server-reference-manifest.json +4 -0
  56. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route.js +8 -0
  57. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route.js.nft.json +1 -0
  58. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route_client-reference-manifest.js +3 -0
  59. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route/app-paths-manifest.json +3 -0
  60. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route/build-manifest.json +9 -0
  61. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route/server-reference-manifest.json +4 -0
  62. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route.js +12 -0
  63. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route.js.nft.json +1 -0
  64. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route_client-reference-manifest.js +3 -0
  65. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/start/route.js +5 -4
  66. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/start/route.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route/app-paths-manifest.json +3 -0
  68. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route/build-manifest.json +9 -0
  69. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route/server-reference-manifest.json +4 -0
  70. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route.js +12 -0
  71. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route.js.nft.json +1 -0
  72. package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route_client-reference-manifest.js +3 -0
  73. package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff/route.js +1 -1
  74. package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff-patch/route.js +1 -1
  76. package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff-patch/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/tasks/[taskId]/merge/route.js +3 -3
  78. package/.next/standalone/.next/server/app/api/tasks/[taskId]/merge/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/missions/page/react-loadable-manifest.json +2 -2
  80. package/.next/standalone/.next/server/app/missions/page/server-reference-manifest.json +120 -120
  81. package/.next/standalone/.next/server/app/missions/page.js +7 -8
  82. package/.next/standalone/.next/server/app/missions/page.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/missions/page_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/onboarding/page/react-loadable-manifest.json +3 -3
  85. package/.next/standalone/.next/server/app/onboarding/page/server-reference-manifest.json +27 -27
  86. package/.next/standalone/.next/server/app/onboarding/page.js +6 -6
  87. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +3 -3
  90. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +27 -27
  91. package/.next/standalone/.next/server/app/page.js +6 -6
  92. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +3 -3
  95. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +44 -44
  96. package/.next/standalone/.next/server/app/settings/page.js +6 -6
  97. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page/react-loadable-manifest.json +3 -3
  100. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page/server-reference-manifest.json +110 -98
  101. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page.js +6 -6
  102. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page/react-loadable-manifest.json +3 -3
  105. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page/server-reference-manifest.json +89 -77
  106. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page.js +6 -6
  107. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page.js.nft.json +1 -1
  108. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page/react-loadable-manifest.json +3 -3
  110. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page/server-reference-manifest.json +74 -62
  111. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page.js +6 -6
  112. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page.js.nft.json +1 -1
  113. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page/react-loadable-manifest.json +3 -3
  115. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page/server-reference-manifest.json +75 -75
  116. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page.js +6 -6
  117. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page/react-loadable-manifest.json +3 -3
  120. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page/server-reference-manifest.json +27 -27
  121. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page.js +7 -7
  122. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page.js.nft.json +1 -1
  123. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page/react-loadable-manifest.json +3 -3
  125. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page/server-reference-manifest.json +69 -69
  126. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page.js +6 -6
  127. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page/react-loadable-manifest.json +4 -4
  130. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page/server-reference-manifest.json +94 -82
  131. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page.js +6 -6
  132. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page.js.nft.json +1 -1
  133. package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/workspaces/page/react-loadable-manifest.json +3 -3
  135. package/.next/standalone/.next/server/app/workspaces/page/server-reference-manifest.json +51 -39
  136. package/.next/standalone/.next/server/app/workspaces/page.js +6 -6
  137. package/.next/standalone/.next/server/app/workspaces/page.js.nft.json +1 -1
  138. package/.next/standalone/.next/server/app/workspaces/page_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app-paths-manifest.json +3 -0
  140. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_03qwlhl.js +1 -1
  141. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_09pca3o.js +1 -1
  142. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0eh8dj_.js +5 -5
  143. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0h5yr8p.js +1 -1
  144. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0m8aavq.js +1 -1
  145. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0yp430z.js +1 -1
  146. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0yzw48x.js +1 -1
  147. package/.next/standalone/.next/server/chunks/0zjb_server_app_api_internal_terminal_[taskId]_paste-image_route_actions_0iegbi4.js +3 -0
  148. package/.next/standalone/.next/server/chunks/0zjb_server_app_api_internal_terminal_[taskId]_resume_route_actions_0uascj..js +3 -0
  149. package/.next/standalone/.next/server/chunks/0zjb_server_app_api_internal_terminal_[taskId]_stop_route_actions_0r3bvc-.js +3 -0
  150. package/.next/standalone/.next/server/chunks/[externals]__0x_wqa7._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-z_a1d._.js +1 -1
  152. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.p6em~._.js +3 -0
  153. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.zmhk-._.js +3 -0
  154. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0042hx5._.js +3 -0
  155. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0b3m.jm._.js → [root-of-the-server]__03ufxqq._.js} +3 -3
  156. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04--bs7._.js +3 -0
  157. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04m2l8a._.js +3 -0
  158. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04r193~._.js +3 -0
  159. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05abzth._.js +3 -0
  160. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0657y50._.js +3 -0
  161. package/.next/standalone/.next/server/chunks/[root-of-the-server]__075a0hk._.js +3 -0
  162. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0az764e._.js → [root-of-the-server]__08yqoti._.js} +2 -2
  163. package/.next/standalone/.next/server/chunks/[root-of-the-server]__098.3z2._.js +3 -0
  164. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0fp8qv9._.js → [root-of-the-server]__0_d.s7s._.js} +3 -3
  165. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__037x-0a._.js → [root-of-the-server]__0ajay8_._.js} +4 -4
  166. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b25v3p._.js +4 -0
  167. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xswbi9._.js → [root-of-the-server]__0clptds._.js} +2 -2
  168. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0ai09na._.js → [root-of-the-server]__0g.k9o~._.js} +2 -2
  169. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gn0ubd._.js +1 -1
  170. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gwztza._.js +1 -1
  171. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0h6bl6t._.js +3 -0
  172. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0iggiij._.js +3 -0
  173. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i~3dwq._.js +3 -0
  174. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0j1px8f._.js +3 -0
  175. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k-5ag7._.js +3 -0
  176. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l1-djp._.js +1 -1
  177. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-~q463._.js → [root-of-the-server]__0lvlooo._.js} +2 -2
  178. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0otyifi._.js +1 -1
  179. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q~uf3u._.js +3 -0
  180. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t31ba_._.js +3 -0
  181. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t_weyi._.js +3 -0
  182. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uptkzd._.js +4 -0
  183. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wkjqrd._.js +3 -0
  184. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x3kws1._.js +3 -0
  185. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xot7fu._.js +1 -1
  186. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0y8w5di._.js +4 -0
  187. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~g6-c~._.js +3 -0
  188. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10fv6tt._.js +3 -0
  189. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1189rd1._.js +4 -0
  190. package/.next/standalone/.next/server/chunks/{_06.mxka._.js → _0jmdgq~._.js} +1 -1
  191. package/.next/standalone/.next/server/chunks/_0q10iet._.js +7 -0
  192. package/.next/standalone/.next/server/chunks/_0qk_esg._.js +4 -0
  193. package/.next/standalone/.next/server/chunks/_0t31z6q._.js +1 -1
  194. package/.next/standalone/.next/server/chunks/_12537g8._.js +7 -0
  195. package/.next/standalone/.next/server/chunks/{src_02ruq-1._.js → src_0fq3zjg._.js} +2 -2
  196. package/.next/standalone/.next/server/chunks/src_0weytpz._.js +1 -1
  197. package/.next/standalone/.next/server/chunks/src_0wlyw0g._.js +3 -0
  198. package/.next/standalone/.next/server/chunks/src_0~ey84y._.js +3 -0
  199. package/.next/standalone/.next/server/chunks/src_actions_agent-actions_ts_10q9r5b._.js +4 -0
  200. package/.next/standalone/.next/server/chunks/ssr/0iu._[workspaceId]_projects_[projectId]_versions_version-timeline-client_tsx_07o_kyi._.js +1 -1
  201. package/.next/standalone/.next/server/chunks/ssr/0se9_next_11h0sx_._.js +1 -1
  202. package/.next/standalone/.next/server/chunks/ssr/{0ws9_lucide-react_dist_esm_icons_10_90yo._.js → 0ws9_lucide-react_dist_esm_icons_0pkla8j._.js} +2 -2
  203. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0nwisa8._.js → [root-of-the-server]__00dh103._.js} +2 -2
  204. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0mmypbn._.js → [root-of-the-server]__00ebsjb._.js} +1 -1
  205. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01vm_46._.js +47 -0
  206. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__025ol9g._.js +3 -0
  207. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__094t44p._.js → [root-of-the-server]__04ednzb._.js} +1 -1
  208. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04wbr9x._.js +1 -1
  209. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__05xg05r._.js +1 -1
  210. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__08w4.zf._.js → [root-of-the-server]__065f3ii._.js} +2 -2
  211. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0pmjob9._.js → [root-of-the-server]__06dfcgo._.js} +1 -1
  212. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__038u_kv._.js → [root-of-the-server]__07xkj1s._.js} +4 -4
  213. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0dn90me._.js → [root-of-the-server]__08k-xb7._.js} +2 -2
  214. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08tzbfh._.js +3 -0
  215. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0.infp2._.js → [root-of-the-server]__0_z5hke._.js} +1 -1
  216. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ce3fpq._.js → [root-of-the-server]__0ecd_1d._.js} +4 -4
  217. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__10s67lq._.js → [root-of-the-server]__0iln7n_._.js} +4 -4
  218. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__09z_ddd._.js → [root-of-the-server]__0j_-qk5._.js} +1 -1
  219. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0jymb~t._.js +1 -1
  220. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02j1enz._.js → [root-of-the-server]__0k6oo0n._.js} +1 -1
  221. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0h589~0._.js → [root-of-the-server]__0lws68d._.js} +4 -4
  222. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0oq-j16._.js → [root-of-the-server]__0oamph.._.js} +4 -4
  223. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0pvaj~l._.js → [root-of-the-server]__0pnv7nd._.js} +1 -1
  224. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0stlq2_._.js +4 -0
  225. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__03fujv7._.js → [root-of-the-server]__0tja~wz._.js} +1 -1
  226. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0mq0f94._.js → [root-of-the-server]__0ug022w._.js} +1 -1
  227. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0l6bt9t._.js → [root-of-the-server]__0x6k.ee._.js} +1 -1
  228. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0xr45lx._.js +3 -0
  229. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__058rbx5._.js → [root-of-the-server]__0xwzk2.._.js} +4 -4
  230. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12w35bx._.js → [root-of-the-server]__0yby8pl._.js} +4 -4
  231. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0z7je5_._.js +1 -1
  232. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rckee~._.js → [root-of-the-server]__0zxc81t._.js} +1 -1
  233. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0.u-t.1._.js → [root-of-the-server]__0zzqn5z._.js} +1 -1
  234. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0.2h0ux._.js → [root-of-the-server]__10c.a3u._.js} +1 -1
  235. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0391jsv._.js → [root-of-the-server]__10n3vn6._.js} +1 -1
  236. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__09t~p.u._.js → [root-of-the-server]__123rmyb._.js} +1 -1
  237. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__124zb~p._.js +30 -0
  238. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0dux7x.._.js → [root-of-the-server]__127w3bm._.js} +1 -1
  239. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12ko8p6._.js +3 -0
  240. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0odeai5._.js → [root-of-the-server]__13ce7v2._.js} +1 -1
  241. package/.next/standalone/.next/server/chunks/ssr/_0-~9em3._.js +1 -1
  242. package/.next/standalone/.next/server/chunks/ssr/{_0dzx554._.js → _00l85fp._.js} +3 -3
  243. package/.next/standalone/.next/server/chunks/ssr/_00odlgv._.js +3 -0
  244. package/.next/standalone/.next/server/chunks/ssr/_0463zy~._.js +3 -0
  245. package/.next/standalone/.next/server/chunks/ssr/{_0_6ss3p._.js → _047dh-f._.js} +2 -2
  246. package/.next/standalone/.next/server/chunks/ssr/{_03lt1_x._.js → _05a2u03._.js} +4 -4
  247. package/.next/standalone/.next/server/chunks/ssr/_05k76ur._.js +3 -0
  248. package/.next/standalone/.next/server/chunks/ssr/{_0t863nl._.js → _060e1u.._.js} +1 -1
  249. package/.next/standalone/.next/server/chunks/ssr/_070t_mh._.js +2 -2
  250. package/.next/standalone/.next/server/chunks/ssr/{_0tvm5af._.js → _07lq-bp._.js} +1 -1
  251. package/.next/standalone/.next/server/chunks/ssr/{_0p6p_68._.js → _07q06~v._.js} +4 -4
  252. package/.next/standalone/.next/server/chunks/ssr/{_0u_uywm._.js → _08-x_rp._.js} +1 -1
  253. package/.next/standalone/.next/server/chunks/ssr/{_0_z-t6g._.js → _08bq4g8._.js} +2 -2
  254. package/.next/standalone/.next/server/chunks/ssr/{_12ca88g._.js → _0_q41~z._.js} +4 -4
  255. package/.next/standalone/.next/server/chunks/ssr/_0b7smy6._.js +3 -0
  256. package/.next/standalone/.next/server/chunks/ssr/_0cj9a7y._.js +1 -1
  257. package/.next/standalone/.next/server/chunks/ssr/{_0u7c6bz._.js → _0dxbp89._.js} +4 -4
  258. package/.next/standalone/.next/server/chunks/ssr/{_0ecu98s._.js → _0dye20y._.js} +2 -2
  259. package/.next/standalone/.next/server/chunks/ssr/_0gkid_a._.js +3 -0
  260. package/.next/standalone/.next/server/chunks/ssr/{_0n5do.z._.js → _0j5.ig_._.js} +1 -1
  261. package/.next/standalone/.next/server/chunks/ssr/{_0mm~wxj._.js → _0nze-e6._.js} +1 -1
  262. package/.next/standalone/.next/server/chunks/ssr/{_0tsu0gq._.js → _0oeih09._.js} +2 -2
  263. package/.next/standalone/.next/server/chunks/ssr/_0rdyrfd._.js +1 -1
  264. package/.next/standalone/.next/server/chunks/ssr/_0rrs.-d._.js +3 -0
  265. package/.next/standalone/.next/server/chunks/ssr/{_0py1s-f._.js → _0rtydyv._.js} +1 -1
  266. package/.next/standalone/.next/server/chunks/ssr/{_0hh17jg._.js → _0rxeqmo._.js} +2 -2
  267. package/.next/standalone/.next/server/chunks/ssr/{_04bt0.3._.js → _0s.h4l2._.js} +1 -1
  268. package/.next/standalone/.next/server/chunks/ssr/{_0n4bq0m._.js → _0s.ik0k._.js} +1 -1
  269. package/.next/standalone/.next/server/chunks/ssr/_0syb503._.js +3 -0
  270. package/.next/standalone/.next/server/chunks/ssr/{_04mn9go._.js → _0uryq~z._.js} +2 -2
  271. package/.next/standalone/.next/server/chunks/ssr/_0wbcp88._.js +1 -1
  272. package/.next/standalone/.next/server/chunks/ssr/{_04~zqvy._.js → _0wqcz3w._.js} +4 -4
  273. package/.next/standalone/.next/server/chunks/ssr/{_0-_yznx._.js → _113957g._.js} +1 -1
  274. package/.next/standalone/.next/server/chunks/ssr/src_0djxlqx._.js +1 -1
  275. package/.next/standalone/.next/server/chunks/ssr/src_0eufeyj._.js +1 -1
  276. package/.next/standalone/.next/server/chunks/ssr/src_actions_agent-actions_ts_0~wc.sy._.js +2 -2
  277. package/.next/standalone/.next/server/chunks/ssr/src_actions_file-actions_ts_0gcvqwm._.js +1 -1
  278. package/.next/standalone/.next/server/chunks/ssr/src_app_missions_missions-client_tsx_11429lj._.js +1 -1
  279. package/.next/standalone/.next/server/chunks/ssr/src_app_onboarding_page_tsx_0xf7hpz._.js +1 -1
  280. package/.next/standalone/.next/server/chunks/ssr/src_app_settings_page_tsx_0h9v7dr._.js +1 -1
  281. package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_assets_assets-page-client_tsx_0wyzpam._.js +1 -1
  282. package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_board-page-client_tsx_0gips66._.js +1 -1
  283. package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_notes_notes-page-client_tsx_10gyo3v._.js +1 -1
  284. package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_tasks_[taskId]_task-page-client_tsx_02t7blt._.js +1 -1
  285. package/.next/standalone/.next/server/chunks/ssr/src_components_ui_select_tsx_0d2ra01._.js +1 -1
  286. package/.next/standalone/.next/server/chunks/ssr/{src_lib_08wv1le._.js → src_lib_0.~.oo-._.js} +1 -1
  287. package/.next/standalone/.next/server/chunks/ssr/{src_lib_0_9avpk._.js → src_lib_005uqbe._.js} +1 -1
  288. package/.next/standalone/.next/server/chunks/ssr/{src_lib_02~3_5t._.js → src_lib_00wjv6n._.js} +1 -1
  289. package/.next/standalone/.next/server/chunks/ssr/{src_lib_04d~c.c._.js → src_lib_01sr8_t._.js} +1 -1
  290. package/.next/standalone/.next/server/chunks/ssr/src_lib_08jql1e._.js +3 -0
  291. package/.next/standalone/.next/server/chunks/ssr/src_lib_0b~j-9d._.js +3 -0
  292. package/.next/standalone/.next/server/chunks/ssr/src_lib_0eymyjf._.js +3 -0
  293. package/.next/standalone/.next/server/chunks/ssr/src_lib_0fkv9z3._.js +3 -0
  294. package/.next/standalone/.next/server/chunks/ssr/src_lib_0n-n0.a._.js +3 -0
  295. package/.next/standalone/.next/server/chunks/ssr/src_lib_0sgt~lv._.js +3 -0
  296. package/.next/standalone/.next/server/chunks/ssr/src_lib_0x-iyl1._.js +3 -0
  297. package/.next/standalone/.next/server/chunks/ssr/src_lib_0yjmty1._.js +3 -0
  298. package/.next/standalone/.next/server/chunks/ssr/src_lib_13aevv6._.js +3 -0
  299. package/.next/standalone/.next/server/functions-config-manifest.json +3 -0
  300. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  301. package/.next/standalone/.next/server/pages/500.html +1 -1
  302. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  303. package/.next/standalone/.next/server/server-reference-manifest.json +340 -298
  304. package/.next/standalone/.next/static/chunks/0-vgfstmpuwnx.js +1 -0
  305. package/.next/standalone/.next/static/chunks/{0oz8sw6j078vm.js → 0.lyp-cx3zt9..js} +2 -2
  306. package/.next/standalone/.next/static/chunks/{0.65.u3zhwau~.js → 00z.kuqsfrxq5.js} +2 -2
  307. package/.next/standalone/.next/static/chunks/01j9m895w64zn.js +1 -0
  308. package/.next/standalone/.next/static/chunks/{0lnsj7fwkprxe.js → 01rbl6a8z.tuw.js} +1 -1
  309. package/.next/standalone/.next/static/chunks/{0ad0ou7l2.r6e.js → 04op7bjge~n4l.js} +1 -1
  310. package/.next/standalone/.next/static/chunks/{1195ux3t_r-rb.js → 05v-c3ir3ik_1.js} +1 -1
  311. package/.next/standalone/.next/static/chunks/{12rj7-g8lxjew.js → 070fs6rmafi.i.js} +1 -1
  312. package/.next/standalone/.next/static/chunks/07i9j5yyg4vs3.js +1 -0
  313. package/.next/standalone/.next/static/chunks/{02o~o8tgt860j.js → 08i9.47-_mxro.js} +1 -1
  314. package/.next/standalone/.next/static/chunks/{11sqt~58g35be.js → 0_yp-y9l0upp~.js} +1 -1
  315. package/.next/standalone/.next/static/chunks/0ddt-snh45031.js +1 -0
  316. package/.next/standalone/.next/static/chunks/{0y3a2-c-i9t~t.js → 0evfu1ozaw5ak.js} +1 -1
  317. package/.next/standalone/.next/static/chunks/0gq65t6au55oa.js +1 -0
  318. package/.next/standalone/.next/static/chunks/{0babmd83h6ejs.js → 0gz71w_~yw2iu.js} +1 -1
  319. package/.next/standalone/.next/static/chunks/0hk3lmsij2x1c.js +1 -0
  320. package/.next/standalone/.next/static/chunks/{0c~~56wny5m2u.js → 0j1hqwmeaqnn2.js} +1 -1
  321. package/.next/standalone/.next/static/chunks/0jrje~1gt6w85.css +1 -0
  322. package/.next/standalone/.next/static/chunks/{062.w.nsp3886.js → 0prrt_bws8ml6.js} +1 -1
  323. package/.next/standalone/.next/static/chunks/0qgqjy.9.-qpi.js +1 -0
  324. package/.next/standalone/.next/static/chunks/{06s-d8my6b9t7.js → 0rfq8fy71hj7c.js} +1 -1
  325. package/.next/standalone/.next/static/chunks/{05zm_-7x0fubq.js → 0rjt_ddd~6t8r.js} +1 -1
  326. package/.next/standalone/.next/static/chunks/{0fz47g1x5o2xj.js → 0rnitheqdpd1..js} +1 -1
  327. package/.next/standalone/.next/static/chunks/{03sdutmq6~3v-.js → 0sr-m2t6vck14.js} +1 -1
  328. package/.next/standalone/.next/static/chunks/{0tfmi08mzcieh.js → 0ts___1ygewqp.js} +1 -1
  329. package/.next/standalone/.next/static/chunks/{00w9dd4fooyic.js → 0vmy6tsqy.xf4.js} +1 -1
  330. package/.next/standalone/.next/static/chunks/{10qltt-r5q91p.js → 0wbq-_8jyxjxm.js} +1 -1
  331. package/.next/standalone/.next/static/chunks/0xejm4ge9~cn..js +1 -0
  332. package/.next/standalone/.next/static/chunks/{05~2gwcex7hv0.js → 0~prx0ure_1i6.js} +1 -1
  333. package/.next/standalone/.next/static/chunks/1107zshxaajt9.js +1 -0
  334. package/.next/standalone/.next/static/chunks/{0v8apmh_d7lz3.js → 11p.r-9wyh7_2.js} +1 -1
  335. package/.next/standalone/.next/static/chunks/11x3_612u8w~9.js +1 -0
  336. package/.next/standalone/.next/static/chunks/{0ev98toavtr6..js → 14mk_a0k99wbg.js} +1 -1
  337. package/.next/standalone/package.json +9 -9
  338. package/README.md +25 -3
  339. package/README.zh.md +25 -3
  340. package/dist/mcp-server.cjs +246 -74
  341. package/next.config.ts +4 -0
  342. package/package.json +9 -9
  343. package/skills/tower/SKILL.md +6 -0
  344. package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0hrprmi.js +0 -4
  345. package/.next/standalone/.next/server/chunks/[externals]__0izylsq._.js +0 -3
  346. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.z8.oi._.js +0 -4
  347. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02jy80j._.js +0 -4
  348. package/.next/standalone/.next/server/chunks/[root-of-the-server]__032d9pl._.js +0 -3
  349. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04jduyo._.js +0 -3
  350. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04u7b2g._.js +0 -3
  351. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05nz.tg._.js +0 -3
  352. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05~g1fm._.js +0 -3
  353. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ag-i9m._.js +0 -3
  354. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0c7z.~a._.js +0 -3
  355. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fey.8j._.js +0 -3
  356. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g2lv9x._.js +0 -3
  357. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0giry~0._.js +0 -3
  358. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kexk71._.js +0 -4
  359. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kuo6q5._.js +0 -4
  360. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0np.553._.js +0 -4
  361. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0r-6wmj._.js +0 -3
  362. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rpck4h._.js +0 -3
  363. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t_yyy8._.js +0 -3
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u_-4~7._.js +0 -3
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z20rmt._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11l3gud._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0.-z9ts._.js +0 -3
  368. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da~mv~._.js +0 -47
  369. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0gtqd5o._.js +0 -4
  370. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ni-_7_._.js +0 -30
  371. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w--i~y._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0y~ooou._.js +0 -3
  373. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zkpwjj._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/ssr/_03v~rg0._.js +0 -3
  375. package/.next/standalone/.next/server/chunks/ssr/_0_9i_x2._.js +0 -3
  376. package/.next/standalone/.next/server/chunks/ssr/_0b.qjaj._.js +0 -3
  377. package/.next/standalone/.next/server/chunks/ssr/_0mdqhxi._.js +0 -3
  378. package/.next/standalone/.next/server/chunks/ssr/_0r-flc_._.js +0 -3
  379. package/.next/standalone/.next/server/chunks/ssr/_0rkdyad._.js +0 -3
  380. package/.next/standalone/.next/server/chunks/ssr/_0rrzd20._.js +0 -43
  381. package/.next/standalone/.next/server/chunks/ssr/_0z6ji0d._.js +0 -3
  382. package/.next/standalone/.next/server/chunks/ssr/src_lib_0a60u40._.js +0 -3
  383. package/.next/standalone/.next/server/chunks/ssr/src_lib_0fu5szn._.js +0 -3
  384. package/.next/standalone/.next/server/chunks/ssr/src_lib_0gve57o._.js +0 -3
  385. package/.next/standalone/.next/server/chunks/ssr/src_lib_0koe0p0._.js +0 -3
  386. package/.next/standalone/.next/server/chunks/ssr/src_lib_0qdh-v4._.js +0 -3
  387. package/.next/standalone/.next/server/chunks/ssr/src_lib_0ramp4w._.js +0 -3
  388. package/.next/standalone/.next/server/chunks/ssr/src_lib_0sn1z-s._.js +0 -3
  389. package/.next/standalone/.next/server/chunks/ssr/src_lib_110am8v._.js +0 -3
  390. package/.next/standalone/.next/server/chunks/ssr/src_lib_11w~.ge._.js +0 -3
  391. package/.next/standalone/.next/static/chunks/0-x5eie9u3i_2.js +0 -1
  392. package/.next/standalone/.next/static/chunks/04zy.uc7eru64.js +0 -1
  393. package/.next/standalone/.next/static/chunks/0651zmy-w~saj.js +0 -1
  394. package/.next/standalone/.next/static/chunks/06lla3jtd~xb4.js +0 -1
  395. package/.next/standalone/.next/static/chunks/0c8c6pcmlzgmi.js +0 -1
  396. package/.next/standalone/.next/static/chunks/0i2soupf1735z.js +0 -1
  397. package/.next/standalone/.next/static/chunks/0l25d0nc5ygyd.js +0 -1
  398. package/.next/standalone/.next/static/chunks/0umi7ddtiv8sw.js +0 -1
  399. package/.next/standalone/.next/static/chunks/0v.l5.sqos562.js +0 -1
  400. package/.next/standalone/.next/static/chunks/0w33dj~dfamnr.css +0 -1
  401. package/.next/standalone/.next/static/chunks/13rq33eiffqaz.js +0 -1
  402. /package/.next/standalone/.next/static/{zSKVtiYaR_yWxx7AopTMR → d-Uhp63kgWdPkhPt7Fzyb}/_buildManifest.js +0 -0
  403. /package/.next/standalone/.next/static/{zSKVtiYaR_yWxx7AopTMR → d-Uhp63kgWdPkhPt7Fzyb}/_clientMiddlewareManifest.js +0 -0
  404. /package/.next/standalone/.next/static/{zSKVtiYaR_yWxx7AopTMR → d-Uhp63kgWdPkhPt7Fzyb}/_ssgManifest.js +0 -0
package/README.zh.md CHANGED
@@ -135,6 +135,27 @@ Workspace(工作空间)
135
135
  - 项目类型:FRONTEND / BACKEND(影响预览功能可用性)
136
136
  - Git Path Mapping 规则:按 host + owner 自动推算本地路径
137
137
 
138
+ ### Mission Control 任务监控
139
+
140
+ - `/missions` 面板跨工作区监控所有运行中的任务执行,每张卡片内嵌实时终端
141
+ - 网格布局预设(1×1 … 3×3)本地持久化,支持按工作区筛选
142
+ - 点击「启动任务」打开搜索弹窗 — 模糊搜索任务、按「工作区 → 项目」浏览或从最近任务挑选;可启动新执行或恢复历史会话
143
+ - 双导航模式:input(直接在窗格打字)与 nav(居中窗格选择器,`1–9 / A–Z` 快捷定位),`Ctrl+;` 切换
144
+
145
+ ### AI 助手
146
+
147
+ - 内置聊天,基于 Claude Agent SDK,SSE 流式 + 多模态(图片)输入
148
+ - 定位为「任务管理操作员」—— 通过 Tower MCP 工具创建/移动任务、搜索、生成报告
149
+ - 会话历史以磁盘 transcript 为准;resume 失效自动降级重试,MCP 断开自动重连
150
+
151
+ ### 版本时间线
152
+
153
+ - 将任务归纳到项目版本,按版本回顾工作;未指定版本的任务进入 backlog
154
+
155
+ ### 笔记与资产
156
+
157
+ - 按项目维护笔记(支持全文搜索)与资产上传(文件、图片、粘贴截图),UI 或 MCP 工具均可管理
158
+
138
159
  ### 设置
139
160
 
140
161
  | 分类 | 配置项 |
@@ -166,18 +187,19 @@ Tower 提供 MCP Server,可被外部 AI Agent 调用:
166
187
  }
167
188
  ```
168
189
 
169
- ### 可用工具(24 个)
190
+ ### 可用工具(31 个)
170
191
 
171
192
  | 分类 | 工具 |
172
193
  |------|------|
173
194
  | Workspace | list_workspaces, create_workspace, update_workspace, delete_workspace |
174
195
  | Project | list_projects, create_project, update_project, delete_project |
175
- | Task | list_tasks, create_task, update_task, delete_task, move_task |
196
+ | Task | list_tasks, create_task, update_task, move_task, delete_task, set_task_defaults, list_versions |
176
197
  | Label | list_labels, create_label, delete_label, set_task_labels |
177
198
  | Search | search(全局搜索任务/项目/仓库) |
178
- | Terminal | get_task_terminal_output, send_task_terminal_input, get_task_execution_status |
179
199
  | Knowledge | identify_project |
180
200
  | Notes/Assets | manage_notes, manage_assets |
201
+ | Terminal | start_task_execution, get_task_terminal_output, send_task_terminal_input, get_task_execution_status, stop_task_execution, resume_task_execution |
202
+ | Report | daily_summary, daily_todo |
181
203
 
182
204
  ## 开发命令
183
205
 
@@ -14347,14 +14347,64 @@ var init_zod = __esm({
14347
14347
  }
14348
14348
  });
14349
14349
 
14350
+ // src/lib/tower-dir.ts
14351
+ function getTowerDir() {
14352
+ if (_dir) return _dir;
14353
+ _dir = process.env.TOWER_DATA_DIR || (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".tower");
14354
+ if (!(0, import_node_fs.existsSync)(_dir)) {
14355
+ (0, import_node_fs.mkdirSync)(_dir, { recursive: true });
14356
+ }
14357
+ return _dir;
14358
+ }
14359
+ function getDatabaseDir() {
14360
+ const dir = (0, import_node_path2.join)(getTowerDir(), "database");
14361
+ if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
14362
+ return dir;
14363
+ }
14364
+ function getTowerDbFilePath() {
14365
+ const root = process.env.TOWER_DATA_DIR || (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".tower");
14366
+ return (0, import_node_path2.join)(root, "database", "tower.db");
14367
+ }
14368
+ function getDefaultStorageDir() {
14369
+ return (0, import_node_path2.join)(getTowerDir(), "storage");
14370
+ }
14371
+ function getStoragePointerFile() {
14372
+ return (0, import_node_path2.join)(getTowerDir(), "storage-location");
14373
+ }
14374
+ function readStoragePointer() {
14375
+ try {
14376
+ const p2 = (0, import_node_fs.readFileSync)(getStoragePointerFile(), "utf-8").trim();
14377
+ return p2.length > 0 ? p2 : null;
14378
+ } catch {
14379
+ return null;
14380
+ }
14381
+ }
14382
+ function getStorageDir() {
14383
+ const override = process.env.TOWER_STORAGE_DIR || readStoragePointer();
14384
+ const dir = override && override.length > 0 ? override : getDefaultStorageDir();
14385
+ if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
14386
+ return dir;
14387
+ }
14388
+ var import_node_path2, import_node_os2, import_node_fs, _dir;
14389
+ var init_tower_dir = __esm({
14390
+ "src/lib/tower-dir.ts"() {
14391
+ "use strict";
14392
+ import_node_path2 = require("node:path");
14393
+ import_node_os2 = require("node:os");
14394
+ import_node_fs = require("node:fs");
14395
+ }
14396
+ });
14397
+
14350
14398
  // src/lib/db.ts
14351
14399
  var import_client2, globalForPrisma, db2;
14352
14400
  var init_db = __esm({
14353
14401
  "src/lib/db.ts"() {
14354
14402
  "use strict";
14355
14403
  import_client2 = require("@prisma/client");
14404
+ init_tower_dir();
14356
14405
  globalForPrisma = globalThis;
14357
14406
  db2 = globalForPrisma.prisma ?? new import_client2.PrismaClient({
14407
+ datasourceUrl: `file:${getTowerDbFilePath()}`,
14358
14408
  log: []
14359
14409
  });
14360
14410
  if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db2;
@@ -26592,7 +26642,7 @@ function isWindows(platform = process.platform) {
26592
26642
  return platform === "win32";
26593
26643
  }
26594
26644
  function normalizePath(p2, platform = process.platform) {
26595
- const normalized = import_node_path2.default.normalize(p2);
26645
+ const normalized = import_node_path3.default.normalize(p2);
26596
26646
  if (isWindows(platform)) {
26597
26647
  return normalized.replace(/\//g, "\\");
26598
26648
  }
@@ -26643,16 +26693,16 @@ async function resolveCommandPath(command, opts = {}) {
26643
26693
  const platform = opts.platform ?? process.platform;
26644
26694
  const hasPathSeparator = command.includes("/") || command.includes("\\");
26645
26695
  if (hasPathSeparator) {
26646
- const absolute = import_node_path2.default.isAbsolute(command) ? command : import_node_path2.default.resolve(cwd, command);
26696
+ const absolute = import_node_path3.default.isAbsolute(command) ? command : import_node_path3.default.resolve(cwd, command);
26647
26697
  return await pathExists(absolute, platform) ? absolute : null;
26648
26698
  }
26649
26699
  const pathValue = env.PATH ?? env.Path ?? "";
26650
26700
  const delimiter = isWindows(platform) ? ";" : ":";
26651
26701
  const dirs = pathValue.split(delimiter).filter(Boolean);
26652
26702
  const exts = isWindows(platform) ? windowsPathExts(env) : [""];
26653
- const hasExtension = isWindows(platform) && import_node_path2.default.extname(command).length > 0;
26703
+ const hasExtension = isWindows(platform) && import_node_path3.default.extname(command).length > 0;
26654
26704
  for (const dir of dirs) {
26655
- const candidates = isWindows(platform) ? hasExtension ? [import_node_path2.default.join(dir, command)] : exts.map((ext) => import_node_path2.default.join(dir, `${command}${ext}`)) : [import_node_path2.default.join(dir, command)];
26705
+ const candidates = isWindows(platform) ? hasExtension ? [import_node_path3.default.join(dir, command)] : exts.map((ext) => import_node_path3.default.join(dir, `${command}${ext}`)) : [import_node_path3.default.join(dir, command)];
26656
26706
  for (const candidate of candidates) {
26657
26707
  if (await pathExists(candidate, platform)) return candidate;
26658
26708
  }
@@ -26660,7 +26710,7 @@ async function resolveCommandPath(command, opts = {}) {
26660
26710
  return null;
26661
26711
  }
26662
26712
  function resolveCommandPathSync(command, platform = process.platform, exec = defaultExecSync) {
26663
- if (import_node_path2.default.extname(command) || command.includes("/") || command.includes("\\")) {
26713
+ if (import_node_path3.default.extname(command) || command.includes("/") || command.includes("\\")) {
26664
26714
  return command;
26665
26715
  }
26666
26716
  if (!isWindows(platform)) {
@@ -26687,13 +26737,13 @@ function resolveCommandPathSync(command, platform = process.platform, exec = def
26687
26737
  }
26688
26738
  function resolveSdkExecutable(command, platform = process.platform, readFile2 = (p2) => (0, import_node_fs2.readFileSync)(p2, "utf-8"), fileExists = (p2) => (0, import_node_fs2.existsSync)(p2)) {
26689
26739
  if (!isWindows(platform)) return command;
26690
- const ext = import_node_path2.default.extname(command).toLowerCase();
26740
+ const ext = import_node_path3.default.extname(command).toLowerCase();
26691
26741
  if (ext !== ".cmd" && ext !== ".bat") return command;
26692
- const dir = import_node_path2.default.win32.dirname(command);
26742
+ const dir = import_node_path3.default.win32.dirname(command);
26693
26743
  let shimSnippet = "";
26694
26744
  const expand = (raw) => {
26695
26745
  const p2 = raw.replace(/%~?dp0%/gi, dir).replace(/\//g, "\\");
26696
- return import_node_path2.default.win32.isAbsolute(p2) ? import_node_path2.default.win32.normalize(p2) : import_node_path2.default.win32.resolve(dir, p2);
26746
+ return import_node_path3.default.win32.isAbsolute(p2) ? import_node_path3.default.win32.normalize(p2) : import_node_path3.default.win32.resolve(dir, p2);
26697
26747
  };
26698
26748
  try {
26699
26749
  const shim = readFile2(command);
@@ -26706,17 +26756,17 @@ function resolveSdkExecutable(command, platform = process.platform, readFile2 =
26706
26756
  }
26707
26757
  for (const m2 of shim.matchAll(/"([^"]*\.exe)"/gi)) {
26708
26758
  const resolved = expand(m2[1]);
26709
- if (import_node_path2.default.win32.basename(resolved).toLowerCase() === "node.exe") continue;
26759
+ if (import_node_path3.default.win32.basename(resolved).toLowerCase() === "node.exe") continue;
26710
26760
  if (fileExists(resolved)) return resolved;
26711
26761
  }
26712
26762
  } catch (e2) {
26713
26763
  console.error(`[resolveSdkExecutable] shim read failed: ${e2 instanceof Error ? e2.message : e2}`);
26714
26764
  }
26715
- const pkgDir = import_node_path2.default.win32.join(dir, "node_modules", "@anthropic-ai", "claude-code");
26716
- const base = import_node_path2.default.win32.basename(command, import_node_path2.default.win32.extname(command));
26765
+ const pkgDir = import_node_path3.default.win32.join(dir, "node_modules", "@anthropic-ai", "claude-code");
26766
+ const base = import_node_path3.default.win32.basename(command, import_node_path3.default.win32.extname(command));
26717
26767
  const guesses = [
26718
- import_node_path2.default.win32.join(pkgDir, "cli.js"),
26719
- import_node_path2.default.win32.join(pkgDir, "bin", `${base}.exe`)
26768
+ import_node_path3.default.win32.join(pkgDir, "cli.js"),
26769
+ import_node_path3.default.win32.join(pkgDir, "bin", `${base}.exe`)
26720
26770
  ];
26721
26771
  for (const g10 of guesses) {
26722
26772
  if (fileExists(g10)) return g10;
@@ -26748,7 +26798,7 @@ function wrapForPlatform(executable, args, env, platform) {
26748
26798
  if (!isWindows(platform)) {
26749
26799
  return { command: executable, args };
26750
26800
  }
26751
- const ext = import_node_path2.default.extname(executable).toLowerCase();
26801
+ const ext = import_node_path3.default.extname(executable).toLowerCase();
26752
26802
  if (ext === ".cmd" || ext === ".bat" || ext === ".com") {
26753
26803
  const shell = env.ComSpec || "cmd.exe";
26754
26804
  const commandLine = [quoteForCmd(executable), ...args.map(quoteForCmd)].join(" ");
@@ -26782,7 +26832,7 @@ async function detectUnixShells() {
26782
26832
  const line = raw.replace(/#.*/, "").trim();
26783
26833
  if (!line || !line.startsWith("/")) continue;
26784
26834
  if (!await pathExists(line)) continue;
26785
- let name = import_node_path2.default.basename(line);
26835
+ let name = import_node_path3.default.basename(line);
26786
26836
  const count = seen.get(name) ?? 0;
26787
26837
  seen.set(name, count + 1);
26788
26838
  if (count > 0) name = `${name} (${count + 1})`;
@@ -26793,7 +26843,7 @@ async function detectUnixShells() {
26793
26843
  const defaults = ["/bin/zsh", "/bin/bash", "/bin/sh"];
26794
26844
  const shells = [];
26795
26845
  for (const p2 of defaults) {
26796
- if (await pathExists(p2)) shells.push({ name: import_node_path2.default.basename(p2), path: p2 });
26846
+ if (await pathExists(p2)) shells.push({ name: import_node_path3.default.basename(p2), path: p2 });
26797
26847
  }
26798
26848
  return shells;
26799
26849
  }
@@ -26803,28 +26853,28 @@ async function detectWindowsShells() {
26803
26853
  const gitBashCandidates = [];
26804
26854
  const gitPath = await resolveCommandPath("git", { platform: "win32" });
26805
26855
  if (gitPath) {
26806
- const gitRoot = import_node_path2.default.resolve(import_node_path2.default.dirname(gitPath), "..", "..");
26856
+ const gitRoot = import_node_path3.default.resolve(import_node_path3.default.dirname(gitPath), "..", "..");
26807
26857
  gitBashCandidates.push(
26808
- import_node_path2.default.join(gitRoot, "bin", "bash.exe"),
26809
- import_node_path2.default.join(gitRoot, "usr", "bin", "bash.exe")
26858
+ import_node_path3.default.join(gitRoot, "bin", "bash.exe"),
26859
+ import_node_path3.default.join(gitRoot, "usr", "bin", "bash.exe")
26810
26860
  );
26811
26861
  }
26812
26862
  const programDirs = [
26813
26863
  process.env.ProgramW6432,
26814
26864
  process.env.ProgramFiles,
26815
26865
  process.env["ProgramFiles(x86)"],
26816
- process.env.LocalAppData ? import_node_path2.default.join(process.env.LocalAppData, "Programs") : null
26866
+ process.env.LocalAppData ? import_node_path3.default.join(process.env.LocalAppData, "Programs") : null
26817
26867
  ].filter(Boolean);
26818
26868
  for (const dir of programDirs) {
26819
26869
  gitBashCandidates.push(
26820
- import_node_path2.default.join(dir, "Git", "bin", "bash.exe"),
26821
- import_node_path2.default.join(dir, "Git", "usr", "bin", "bash.exe")
26870
+ import_node_path3.default.join(dir, "Git", "bin", "bash.exe"),
26871
+ import_node_path3.default.join(dir, "Git", "usr", "bin", "bash.exe")
26822
26872
  );
26823
26873
  }
26824
26874
  const home = process.env.USERPROFILE ?? "";
26825
26875
  if (home) {
26826
26876
  gitBashCandidates.push(
26827
- import_node_path2.default.join(home, "scoop", "apps", "git", "current", "bin", "bash.exe")
26877
+ import_node_path3.default.join(home, "scoop", "apps", "git", "current", "bin", "bash.exe")
26828
26878
  );
26829
26879
  }
26830
26880
  if (process.env.CLAUDE_CODE_GIT_BASH_PATH) {
@@ -26841,11 +26891,11 @@ async function detectWindowsShells() {
26841
26891
  shells.push({ name: "PowerShell", path: pwshPath });
26842
26892
  }
26843
26893
  const winDir = process.env.windir ?? "C:\\WINDOWS";
26844
- const legacyPs = import_node_path2.default.join(winDir, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
26894
+ const legacyPs = import_node_path3.default.join(winDir, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
26845
26895
  if (await pathExists(legacyPs, "win32")) {
26846
26896
  shells.push({ name: "Windows PowerShell", path: legacyPs });
26847
26897
  }
26848
- const cmd = process.env.ComSpec ?? import_node_path2.default.join(winDir, "System32", "cmd.exe");
26898
+ const cmd = process.env.ComSpec ?? import_node_path3.default.join(winDir, "System32", "cmd.exe");
26849
26899
  if (await pathExists(cmd, "win32")) {
26850
26900
  shells.push({ name: "Command Prompt", path: cmd });
26851
26901
  }
@@ -26898,13 +26948,13 @@ async function detectEditors(platform = process.platform) {
26898
26948
  }
26899
26949
  return results;
26900
26950
  }
26901
- var import_node_fs2, import_node_child_process, import_node_path2, CLAUDE_NESTING_VARS, SENSITIVE_KEY_RE, defaultExecSync, MAC_TERMINAL_APPS, KNOWN_EDITORS, EDITOR_FALLBACK_PATHS;
26951
+ var import_node_fs2, import_node_child_process, import_node_path3, CLAUDE_NESTING_VARS, SENSITIVE_KEY_RE, defaultExecSync, MAC_TERMINAL_APPS, KNOWN_EDITORS, EDITOR_FALLBACK_PATHS;
26902
26952
  var init_platform = __esm({
26903
26953
  "src/lib/platform.ts"() {
26904
26954
  "use strict";
26905
26955
  import_node_fs2 = require("node:fs");
26906
26956
  import_node_child_process = require("node:child_process");
26907
- import_node_path2 = __toESM(require("node:path"));
26957
+ import_node_path3 = __toESM(require("node:path"));
26908
26958
  CLAUDE_NESTING_VARS = [
26909
26959
  "CLAUDECODE",
26910
26960
  "CLAUDE_CODE_ENTRYPOINT",
@@ -32133,7 +32183,7 @@ var init_pty_session = __esm({
32133
32183
 
32134
32184
  // src/lib/pty/orphan-reaper.ts
32135
32185
  function pidFilePath(sessionKey) {
32136
- return (0, import_node_path3.join)(SIGNAL_DIR, `${PID_PREFIX}${sessionKey}`);
32186
+ return (0, import_node_path4.join)(SIGNAL_DIR, `${PID_PREFIX}${sessionKey}`);
32137
32187
  }
32138
32188
  async function recordSessionPid(sessionKey, pid) {
32139
32189
  try {
@@ -32148,14 +32198,14 @@ async function clearSessionPid(sessionKey) {
32148
32198
  } catch {
32149
32199
  }
32150
32200
  }
32151
- var import_promises, import_node_os2, import_node_path3, SIGNAL_DIR, PID_PREFIX;
32201
+ var import_promises, import_node_os3, import_node_path4, SIGNAL_DIR, PID_PREFIX;
32152
32202
  var init_orphan_reaper = __esm({
32153
32203
  "src/lib/pty/orphan-reaper.ts"() {
32154
32204
  "use strict";
32155
32205
  import_promises = require("node:fs/promises");
32156
- import_node_os2 = require("node:os");
32157
- import_node_path3 = require("node:path");
32158
- SIGNAL_DIR = (0, import_node_path3.join)((0, import_node_os2.tmpdir)(), "tower-signals");
32206
+ import_node_os3 = require("node:os");
32207
+ import_node_path4 = require("node:path");
32208
+ SIGNAL_DIR = (0, import_node_path4.join)((0, import_node_os3.tmpdir)(), "tower-signals");
32159
32209
  PID_PREFIX = "pid-";
32160
32210
  }
32161
32211
  });
@@ -53957,6 +54007,23 @@ var init_task_actions = __esm({
53957
54007
  }
53958
54008
  });
53959
54009
 
54010
+ // src/mcp/env-guard.ts
54011
+ var import_node_path = require("node:path");
54012
+ var import_node_os = require("node:os");
54013
+ function resolveTowerDataDir(env) {
54014
+ if (env.TOWER_DATA_DIR) return env.TOWER_DATA_DIR;
54015
+ const dbUrl = env.DATABASE_URL;
54016
+ if (dbUrl && dbUrl.startsWith("file:")) {
54017
+ const dbPath = dbUrl.slice("file:".length);
54018
+ return (0, import_node_path.dirname)((0, import_node_path.dirname)(dbPath));
54019
+ }
54020
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), ".tower");
54021
+ }
54022
+ process.env.TOWER_DATA_DIR = resolveTowerDataDir({
54023
+ TOWER_DATA_DIR: process.env.TOWER_DATA_DIR,
54024
+ DATABASE_URL: process.env.DATABASE_URL
54025
+ });
54026
+
53960
54027
  // src/mcp/index.ts
53961
54028
  var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
53962
54029
 
@@ -53968,8 +54035,10 @@ init_zod();
53968
54035
 
53969
54036
  // src/mcp/db.ts
53970
54037
  var import_client = require("@prisma/client");
53971
- var db = new import_client.PrismaClient();
54038
+ init_tower_dir();
54039
+ var db = new import_client.PrismaClient({ datasourceUrl: `file:${getTowerDbFilePath()}` });
53972
54040
  async function initDb() {
54041
+ getDatabaseDir();
53973
54042
  await db.$connect();
53974
54043
  await db.$queryRaw(import_client.Prisma.sql`PRAGMA journal_mode=WAL`);
53975
54044
  await db.$queryRaw(import_client.Prisma.sql`PRAGMA busy_timeout=5000`);
@@ -54129,42 +54198,7 @@ init_config_reader();
54129
54198
  // src/lib/file-utils.ts
54130
54199
  var fs = __toESM(require("node:fs"));
54131
54200
  var path = __toESM(require("node:path"));
54132
-
54133
- // src/lib/tower-dir.ts
54134
- var import_node_path = require("node:path");
54135
- var import_node_os = require("node:os");
54136
- var import_node_fs = require("node:fs");
54137
- var _dir;
54138
- function getTowerDir() {
54139
- if (_dir) return _dir;
54140
- _dir = process.env.TOWER_DATA_DIR || (0, import_node_path.join)((0, import_node_os.homedir)(), ".tower");
54141
- if (!(0, import_node_fs.existsSync)(_dir)) {
54142
- (0, import_node_fs.mkdirSync)(_dir, { recursive: true });
54143
- }
54144
- return _dir;
54145
- }
54146
- function getDefaultStorageDir() {
54147
- return (0, import_node_path.join)(getTowerDir(), "storage");
54148
- }
54149
- function getStoragePointerFile() {
54150
- return (0, import_node_path.join)(getTowerDir(), "storage-location");
54151
- }
54152
- function readStoragePointer() {
54153
- try {
54154
- const p2 = (0, import_node_fs.readFileSync)(getStoragePointerFile(), "utf-8").trim();
54155
- return p2.length > 0 ? p2 : null;
54156
- } catch {
54157
- return null;
54158
- }
54159
- }
54160
- function getStorageDir() {
54161
- const override = process.env.TOWER_STORAGE_DIR || readStoragePointer();
54162
- const dir = override && override.length > 0 ? override : getDefaultStorageDir();
54163
- if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
54164
- return dir;
54165
- }
54166
-
54167
- // src/lib/file-utils.ts
54201
+ init_tower_dir();
54168
54202
  function assertWithinDataRoot(resolved) {
54169
54203
  if (!resolved.startsWith(getStorageDir() + path.sep)) {
54170
54204
  throw new Error("Path traversal detected");
@@ -54420,21 +54454,44 @@ ${refText}`;
54420
54454
  }
54421
54455
  },
54422
54456
  update_task: {
54423
- description: "Update a task's title, description, priority, labels, and/or subPath. If labelIds is provided, replaces all existing labels.",
54457
+ description: "Update a task's title, description, priority, labels, subPath, and/or version. If labelIds is provided, replaces all existing labels. Pass versionId to file the task under a project version (use list_versions to discover options); pass null or an empty string to move it back to the backlog (no version).",
54424
54458
  schema: external_exports.object({
54425
54459
  taskId: external_exports.string(),
54426
54460
  title: external_exports.string().optional(),
54427
54461
  description: external_exports.string().optional(),
54428
54462
  priority: Priority.optional(),
54429
54463
  labelIds: external_exports.array(external_exports.string()).optional(),
54430
- subPath: external_exports.string().optional()
54464
+ subPath: external_exports.string().optional(),
54465
+ versionId: external_exports.string().nullable().optional().describe('Version to assign the task to. Use list_versions to find valid IDs for the project. Pass null or "" to move the task to the backlog (no version).')
54431
54466
  }),
54432
54467
  handler: async (args) => {
54433
- const { labelIds, taskId, ...updateData } = args;
54468
+ const { labelIds, taskId, versionId, ...updateData } = args;
54469
+ const versionProvided = "versionId" in args;
54434
54470
  return db.$transaction(async (tx) => {
54471
+ let versionData = {};
54472
+ if (versionProvided) {
54473
+ let resolved = null;
54474
+ if (versionId) {
54475
+ const current = await tx.task.findUnique({
54476
+ where: { id: taskId },
54477
+ select: { projectId: true }
54478
+ });
54479
+ if (current) {
54480
+ const v2 = await tx.version.findFirst({
54481
+ where: { id: versionId, projectId: current.projectId },
54482
+ select: { id: true }
54483
+ });
54484
+ resolved = v2?.id ?? null;
54485
+ }
54486
+ }
54487
+ versionData = { versionId: resolved };
54488
+ }
54435
54489
  const task = await tx.task.update({
54436
54490
  where: { id: taskId },
54437
- data: updateData
54491
+ data: {
54492
+ ...updateData,
54493
+ ...versionData
54494
+ }
54438
54495
  });
54439
54496
  if (labelIds !== void 0) {
54440
54497
  await tx.taskLabel.deleteMany({ where: { taskId } });
@@ -54488,7 +54545,7 @@ ${refText}`;
54488
54545
  }
54489
54546
  },
54490
54547
  list_versions: {
54491
- description: "List a project's active versions (excludes RELEASED) for assigning a task via create_task's versionId. Returns id, number, name, status, isCurrent.",
54548
+ description: "List a project's active versions (excludes RELEASED) for assigning a task via create_task's or update_task's versionId. Returns id, number, name, status, isCurrent.",
54492
54549
  schema: external_exports.object({ projectId: external_exports.string() }),
54493
54550
  handler: async (args) => {
54494
54551
  return db.version.findMany({
@@ -55083,6 +55140,52 @@ function validateMcpTaskId(taskId) {
55083
55140
  if (!CUID_RE.test(taskId)) return "Invalid taskId format \u2014 expected CUID";
55084
55141
  return null;
55085
55142
  }
55143
+ async function resolveTaskTarget(args) {
55144
+ const name = args.taskName?.trim();
55145
+ if (!args.taskId && !name) {
55146
+ return { error: "Provide either taskId or taskName" };
55147
+ }
55148
+ if (args.taskId) {
55149
+ const err = validateMcpTaskId(args.taskId);
55150
+ if (err) return { error: err, taskId: args.taskId };
55151
+ const task = await db.task.findUnique({
55152
+ where: { id: args.taskId },
55153
+ select: { id: true, title: true }
55154
+ });
55155
+ if (!task) return { error: "Task not found", taskId: args.taskId };
55156
+ return { targetId: task.id, targetTitle: task.title };
55157
+ }
55158
+ const matches = await db.task.findMany({
55159
+ where: { title: { contains: name } },
55160
+ select: {
55161
+ id: true,
55162
+ title: true,
55163
+ status: true,
55164
+ project: { select: { name: true, workspace: { select: { name: true } } } }
55165
+ },
55166
+ orderBy: { updatedAt: "desc" },
55167
+ take: 20
55168
+ });
55169
+ if (matches.length === 0) {
55170
+ return { error: "No task found matching the given name", taskName: name };
55171
+ }
55172
+ const exact = matches.filter((m2) => m2.title.toLowerCase() === name.toLowerCase());
55173
+ const resolved = matches.length === 1 ? matches[0] : exact.length === 1 ? exact[0] : null;
55174
+ if (!resolved) {
55175
+ return {
55176
+ needsSelection: true,
55177
+ message: `Multiple tasks match "${name}". Call again with one of these taskId values.`,
55178
+ candidates: matches.map((m2) => ({
55179
+ taskId: m2.id,
55180
+ title: m2.title,
55181
+ status: m2.status,
55182
+ project: m2.project.name,
55183
+ workspace: m2.project.workspace.name
55184
+ }))
55185
+ };
55186
+ }
55187
+ return { targetId: resolved.id, targetTitle: resolved.title };
55188
+ }
55086
55189
  var terminalTools = {
55087
55190
  start_task_execution: {
55088
55191
  description: "Start a Claude CLI terminal session for a task. The prompt is sent as the initial instruction. The task status will change to IN_PROGRESS. Returns executionId and worktreePath (if worktree mode).",
@@ -55157,6 +55260,75 @@ var terminalTools = {
55157
55260
  return { error: "Bridge request failed", status: response.status };
55158
55261
  }
55159
55262
  },
55263
+ stop_task_execution: {
55264
+ description: "Stop (close) a task's terminal/PTY session \u2014 the same action as the Stop button. Identify the task either by exact `taskId` or by a fuzzy `taskName`. If the terminal is running it is closed; if it was never started this is a no-op. Both cases report success. When `taskName` matches multiple tasks it does NOT stop any of them \u2014 it returns `needsSelection` with the candidate list (id, title, status, project) so you can pick one and call again with that `taskId`. A unique name match or an exact `taskId` is closed directly.",
55265
+ schema: external_exports.object({
55266
+ taskId: external_exports.string().optional(),
55267
+ taskName: external_exports.string().optional()
55268
+ }),
55269
+ handler: async (args) => {
55270
+ const target = await resolveTaskTarget(args);
55271
+ if (!("targetId" in target)) return target;
55272
+ const { targetId, targetTitle } = target;
55273
+ const tid = encodeURIComponent(targetId);
55274
+ const response = await bridgeFetch(`/${tid}/stop`, { method: "POST" });
55275
+ if (!response.ok) {
55276
+ const errData = await response.json().catch(() => ({}));
55277
+ return {
55278
+ error: errData.error ?? "Failed to stop terminal",
55279
+ status: response.status,
55280
+ taskId: targetId
55281
+ };
55282
+ }
55283
+ const data = await response.json().catch(() => ({}));
55284
+ const wasRunning = data.wasRunning ?? false;
55285
+ return {
55286
+ ok: true,
55287
+ taskId: targetId,
55288
+ title: targetTitle,
55289
+ wasRunning,
55290
+ message: wasRunning ? "Terminal closed" : "No active terminal for this task \u2014 nothing to close"
55291
+ };
55292
+ }
55293
+ },
55294
+ resume_task_execution: {
55295
+ description: "Start (launch) a task's terminal so you can interact with it \u2014 e.g. when a related task needs to notify a sibling that hasn't been started yet. By default it resumes the latest history session (the Continue/Retry button); a task with no prior runs is started fresh with its task context (the Launch button). If a terminal is already running this is a no-op and reports `mode: already_running`. Identify the task by exact `taskId` or fuzzy `taskName` (ambiguous name \u2192 `needsSelection` with candidates; unique match or exact id \u2192 started directly). After it is running, use `send_task_terminal_input` to send the actual message.",
55296
+ schema: external_exports.object({
55297
+ taskId: external_exports.string().optional(),
55298
+ taskName: external_exports.string().optional()
55299
+ }),
55300
+ handler: async (args) => {
55301
+ const target = await resolveTaskTarget(args);
55302
+ if (!("targetId" in target)) return target;
55303
+ const { targetId, targetTitle } = target;
55304
+ const tid = encodeURIComponent(targetId);
55305
+ const response = await bridgeFetch(`/${tid}/resume`, { method: "POST" });
55306
+ if (!response.ok) {
55307
+ const errData = await response.json().catch(() => ({}));
55308
+ return {
55309
+ error: errData.error ?? "Failed to start terminal",
55310
+ status: response.status,
55311
+ taskId: targetId
55312
+ };
55313
+ }
55314
+ const data = await response.json().catch(() => ({}));
55315
+ const mode = data.mode ?? "started";
55316
+ const messages = {
55317
+ already_running: "Terminal already running \u2014 ready for input",
55318
+ continued: "Terminal resumed from latest history",
55319
+ started: "Terminal started fresh"
55320
+ };
55321
+ return {
55322
+ ok: true,
55323
+ taskId: targetId,
55324
+ title: targetTitle,
55325
+ mode,
55326
+ executionId: data.executionId ?? null,
55327
+ worktreePath: data.worktreePath ?? null,
55328
+ message: messages[mode] ?? "Terminal started"
55329
+ };
55330
+ }
55331
+ },
55160
55332
  get_task_execution_status: {
55161
55333
  description: "Get the execution status of a task including whether its terminal is running, idle, or exited. Also returns a snippet of recent output.",
55162
55334
  schema: external_exports.object({
package/next.config.ts CHANGED
@@ -4,6 +4,10 @@ const nextConfig: NextConfig = {
4
4
  // Self-contained build: traced deps land in `.next/standalone/node_modules/`,
5
5
  // so `npm i tower-studio -g` no longer re-downloads the dependency graph.
6
6
  output: "standalone",
7
+ // Dev and prod must not share a build dir, or `pnpm dev` clobbers the prod
8
+ // `.next/standalone` that `pnpm start` (bin/tower.mjs) loads. The `dev` script
9
+ // sets NEXT_DISTDIR=.next-dev; prod build/start keep the default `.next`.
10
+ distDir: process.env.NEXT_DISTDIR || ".next",
7
11
  // Pin the workspace root — without this Next.js infers it from the nearest
8
12
  // lockfile and can wrongly pick a stray ~/package-lock.json in $HOME.
9
13
  outputFileTracingRoot: __dirname,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tower-studio",
3
- "version": "0.2.41",
3
+ "version": "0.2.43",
4
4
  "description": "AI Task Orchestration Platform — Kanban + Terminal + Code Editor + MCP",
5
5
  "bin": {
6
6
  "tower": "bin/tower.mjs"
@@ -29,8 +29,8 @@
29
29
  "tsconfig.json"
30
30
  ],
31
31
  "scripts": {
32
- "predev": "node scripts/ensure-dev-db.js && pnpm db:migrate && pnpm mcp:build",
33
- "dev": "next dev --webpack -p 9022",
32
+ "predev": "TOWER_DATA_DIR=\"$HOME/.tower-dev\" DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" node scripts/ensure-dev-db.js && pnpm db:migrate && pnpm mcp:build",
33
+ "dev": "NEXT_DISTDIR=.next-dev TOWER_DATA_DIR=\"$HOME/.tower-dev\" DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" next dev --webpack -p 9022",
34
34
  "build": "pnpm mcp:build && rm -rf .next && next build && find .next -name '*.map' -delete && cp -R .next/static .next/standalone/.next/ && cp -R public .next/standalone/ && node scripts/prune-standalone-natives.js",
35
35
  "release": "pnpm build && npm pack",
36
36
  "release:smoke": "node scripts/release-smoke.js",
@@ -39,12 +39,12 @@
39
39
  "start": "node bin/tower.mjs",
40
40
  "lint": "eslint",
41
41
  "db:generate": "prisma generate",
42
- "db:push": "prisma db push",
43
- "db:seed": "tsx prisma/seed.ts",
44
- "db:studio": "prisma studio",
45
- "db:init": "tsx scripts/init-db.ts",
46
- "db:init-fts": "tsx prisma/init-fts.ts",
47
- "db:migrate": "tsx scripts/run-migrations.ts",
42
+ "db:push": "DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" prisma db push",
43
+ "db:seed": "DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" tsx prisma/seed.ts",
44
+ "db:studio": "DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" prisma studio",
45
+ "db:init": "TOWER_DATA_DIR=\"$HOME/.tower-dev\" DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" tsx scripts/init-db.ts",
46
+ "db:init-fts": "DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" tsx prisma/init-fts.ts",
47
+ "db:migrate": "TOWER_DATA_DIR=\"$HOME/.tower-dev\" DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" tsx scripts/run-migrations.ts",
48
48
  "test": "vitest",
49
49
  "test:run": "vitest run",
50
50
  "test:e2e": "NO_PROXY=localhost,127.0.0.1 no_proxy=localhost,127.0.0.1 playwright test",
@@ -103,6 +103,12 @@ it means your previous turn produced no tool call — issue the tool call now.
103
103
 
104
104
  1. Call `move_task` with taskId and the target status (DONE, CANCELLED, etc.)
105
105
 
106
+ ### "Edit a task" / "Change its title/description/priority/labels/version"
107
+
108
+ 1. Call `update_task` with `taskId` plus any of: `title`, `description`, `priority`, `labelIds`, `subPath`, `versionId`. Only the fields you pass are changed.
109
+ 2. **Labels** (`labelIds`): full replace, not a merge — pass the complete desired set (omit to leave labels untouched).
110
+ 3. **Version** (`versionId`): to move a task into a version, call `list_versions` with the task's projectId, let the user pick, then pass `versionId`. To move the task back to the **backlog** (no version), pass `versionId: null` (or an empty string). A `versionId` that doesn't belong to the task's project is ignored and the task falls back to backlog. Omit `versionId` entirely to leave the version unchanged.
111
+
106
112
  ### "Search for ..." / "Find tasks about ..."
107
113
 
108
114
  1. Call `search` with the query string