tower-studio 0.2.44 → 0.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +6 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +38 -0
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +133 -85
- package/.next/standalone/.next/server/app/_not-found/page.js +8 -9
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/adapters/test/route.js +2 -2
- package/.next/standalone/.next/server/app/api/adapters/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/browse-fs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/files/assets/[projectId]/[filename]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/files/assets/[projectId]/[filename]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/git/route.js +1 -1
- package/.next/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assets/[projectId]/[filename]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/assets/[projectId]/[filename]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assets/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assistant/attachments/route.js +2 -3
- package/.next/standalone/.next/server/app/api/internal/assistant/attachments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assistant/chat/route.js +2 -2
- package/.next/standalone/.next/server/app/api/internal/assistant/chat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assistant/route.js +5 -4
- package/.next/standalone/.next/server/app/api/internal/assistant/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/assistant/sessions/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/assistant/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/backup/import/route.js +3 -4
- package/.next/standalone/.next/server/app/api/internal/backup/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/cache/[...segments]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/cache/[...segments]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route.js +7 -0
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/internal/harness/ask/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route.js +7 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/internal/harness/notify/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route.js +7 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/internal/harness/pending/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route.js +12 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/internal/harness/reply/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/internal/hooks/install/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/hooks/install/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/hooks/session/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/hooks/session/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/hooks/stop/route.js +3 -3
- package/.next/standalone/.next/server/app/api/internal/hooks/stop/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/hooks/upload/route.js +2 -2
- package/.next/standalone/.next/server/app/api/internal/hooks/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/monaco/[...path]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/monaco/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/buffer/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/buffer/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/input/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/input/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route.js +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/paste-image/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route.js +5 -4
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/resume/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/start/route.js +6 -5
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/start/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route.js +5 -4
- package/.next/standalone/.next/server/app/api/internal/terminal/[taskId]/stop/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff/route.js +2 -2
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff-patch/route.js +2 -2
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/diff-patch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/merge/route.js +5 -3
- package/.next/standalone/.next/server/app/api/tasks/[taskId]/merge/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/harness/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/harness/page/build-manifest.json +18 -0
- package/.next/standalone/.next/server/app/harness/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/harness/page/react-loadable-manifest.json +18 -0
- package/.next/standalone/.next/server/app/harness/page/server-reference-manifest.json +437 -0
- package/.next/standalone/.next/server/app/harness/page.js +24 -0
- package/.next/standalone/.next/server/app/harness/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/harness/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/missions/page/react-loadable-manifest.json +3 -2
- package/.next/standalone/.next/server/app/missions/page/server-reference-manifest.json +244 -160
- package/.next/standalone/.next/server/app/missions/page.js +11 -11
- package/.next/standalone/.next/server/app/missions/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/missions/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/onboarding/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/onboarding/page/server-reference-manifest.json +133 -85
- package/.next/standalone/.next/server/app/onboarding/page.js +8 -9
- package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +133 -85
- package/.next/standalone/.next/server/app/page.js +8 -9
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +260 -140
- package/.next/standalone/.next/server/app/settings/page.js +10 -11
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page/server-reference-manifest.json +284 -248
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page.js +9 -10
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/archive/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page/server-reference-manifest.json +247 -211
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page.js +9 -10
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/assets/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page/build-manifest.json +18 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page/next-font-manifest.json +11 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page/react-loadable-manifest.json +18 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page/server-reference-manifest.json +401 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page.js +24 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/groups/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page/server-reference-manifest.json +222 -186
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page.js +9 -10
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/notes/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page/server-reference-manifest.json +257 -209
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page.js +10 -11
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page/server-reference-manifest.json +133 -85
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page.js +9 -10
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page/server-reference-manifest.json +219 -171
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page.js +9 -10
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/projects/[projectId]/versions/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page/react-loadable-manifest.json +4 -4
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page/server-reference-manifest.json +269 -221
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page.js +11 -12
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/[workspaceId]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/workspaces/page/react-loadable-manifest.json +3 -3
- package/.next/standalone/.next/server/app/workspaces/page/server-reference-manifest.json +169 -133
- package/.next/standalone/.next/server/app/workspaces/page.js +8 -9
- package/.next/standalone/.next/server/app/workspaces/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/workspaces/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +6 -0
- package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_09ikw5j.js +5 -0
- package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0eh8dj_.js +9 -5
- package/.next/standalone/.next/server/chunks/0se9_next_dist_esm_build_templates_app-route_0gr2wxq.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-1~xqo._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0lvlooo._.js → [root-of-the-server]__0-kboke._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.3n3t.._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.wsvr6._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.yf1mx._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00xe-t8._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02r7j6y._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02yvm55._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__09arklv._.js → [root-of-the-server]__04-ty51._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__065hi6e._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06iuq17._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06x1zwj._.js +28 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06~wmlx._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08-bq72._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08clp-r._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__092475e._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__095t6ga._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_7_w.g._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0atap--._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0c3je91._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0dz.knv._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ehwsa1._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0esywxf._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fd9z.r._.js +30 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gbyryz._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gcg7i.._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0iyp~.k._.js +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0khq-k0._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kkrbn-._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l1-djp._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0m8t3vi._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nt7c0f._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nv83.p._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0pr~t0y._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qcpe0l._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qfcg6k._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sq5irw._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0squ613._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u8tl88._.js +28 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wjr-72._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wugb-9._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0yeg1kp._.js +4 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zchqv1._.js +43 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zcy11y._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~1-i5h._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~ju4-d._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10aw_67._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10ci~o9._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10qclz-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12fmxq0._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__136ty69._.js +3 -0
- package/.next/standalone/.next/server/chunks/_02hac5p._.js +30 -0
- package/.next/standalone/.next/server/chunks/_0_w835g._.js +4 -0
- package/.next/standalone/.next/server/chunks/_0je3dz2._.js +30 -0
- package/.next/standalone/.next/server/chunks/_0tidm8l._.js +30 -0
- package/.next/standalone/.next/server/chunks/_0zok2an._.js +30 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_internal_harness_ask_route_actions_0_c62hg.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_internal_harness_notify_route_actions_08hof6m.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_internal_harness_pending_route_actions_0w9t_9m.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_internal_harness_reply_route_actions_0qatz~a.js +3 -0
- package/.next/standalone/.next/server/chunks/src_05balzk._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_0aygchu._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_0gif-f5._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_0pg9w-x._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_0vp6.co._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_11k6i~l._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_actions_agent-actions_ts_10q9r5b._.js +8 -2
- package/.next/standalone/.next/server/chunks/src_lib_02llcit._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_0aowbzy._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_0d~1~wz._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_lib_0ylel_1._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_lib_ai_0xx6y51._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_ai_providers_index_ts_0.y.3vp._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_config-defaults_ts_10ayktg._.js +3 -0
- package/.next/standalone/.next/server/chunks/src_lib_config-reader_ts_0e5f7vk._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/0iu._[workspaceId]_projects_[projectId]_versions_version-timeline-client_tsx_07o_kyi._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0se9_next_dist_0i5qmqd._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0se9_next_dist_esm_build_templates_app-page_04~dhws.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/0se9_next_dist_esm_build_templates_app-page_0fro4ex.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/0ws9_lucide-react_dist_esm_icons_0gv_cwy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/12k._sonner_dist_index_mjs_0-vmpk5._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-geq20._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0.0m12b._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00qzvly._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bz3_g._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02~hdzx._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06sew6r._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07rk6ic._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__090y_.y._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b.ej5q._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b6fbjv._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b6hugs._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0br5e7w._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bx_h2u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0dhq_gl._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e79g0v._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0esg88l._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h_pt4a._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hzwoy5._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0idkp76._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0j4m.1s._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0jymb~t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kmonje._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kqp70x._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0l0~scn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lh3mlq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0m8m7vc._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0muf4wq._.js +49 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n02kfa._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n3uc.v._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0o5ohqy._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_q09t._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s~4y3y._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s~ak20._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ta_mpj._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0trmndk._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3~-.g._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vyl8to._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ws0_c1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0x7br99._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0xnuz05._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ynq8ty._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zsnp~d._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0~edc3d._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0~mhv4m._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1013v_g._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11fp64w._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__123rmn-._.js +30 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0_z5hke._.js → [root-of-the-server]__12viys4._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0-5.hgb._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0dye20y._.js → _0-wp_zu._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0-~9em3._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0..h3hk._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_08bq4g8._.js → _00_h2nx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_02p-udo._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_05~lqg-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/_0771b4a._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/{_113957g._.js → _0ak77.u._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{_11osha9._.js → _0ami9yt._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0r4_qn~._.js → _0awn2mm._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_07lq-bp._.js → _0b660g4._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0j5.ig_._.js → _0czsddm._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0fmko25._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0_nhdgs._.js → _0gomvsp._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0g~p9_x._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0hg~.4w._.js +6 -0
- package/.next/standalone/.next/server/chunks/ssr/_0hsuip_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0zr81mw._.js → _0hx2o_8._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0s.ik0k._.js → _0j7m~u6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_08-x_rp._.js → _0l6byg1._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0i4xdso._.js → _0mmy~98._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0nrxhfb._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/{_02vz78l._.js → _0o_c3b2._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0os43sb._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0nze-e6._.js → _0p5ft59._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0q2pep_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_060e1u.._.js → _0snv7nt._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0ty4xe6._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/_0vkl7.h._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/_0wbcp88._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0x09t_o._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/_0z5~opf._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0zn.4bi._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/_1086w4p._.js +47 -0
- package/.next/standalone/.next/server/chunks/ssr/_10q2mbe._.js +17 -0
- package/.next/standalone/.next/server/chunks/ssr/_11.knhq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1118hto._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0rtydyv._.js → _12s8n8g._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_11j0qlp._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_actions_agent-actions_ts_0~wc.sy._.js +8 -2
- package/.next/standalone/.next/server/chunks/ssr/src_actions_file-actions_ts_0gcvqwm._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_missions_missions-client_tsx_11429lj._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_onboarding_page_tsx_0xf7hpz._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_settings_page_tsx_0h9v7dr._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_assets_assets-page-client_tsx_0wyzpam._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_board-page-client_tsx_0gips66._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_notes_notes-page-client_tsx_10gyo3v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_app_workspaces_[workspaceId]_tasks_[taskId]_task-page-client_tsx_02t7blt._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_components_0rowjw~._.js +7 -0
- package/.next/standalone/.next/server/chunks/ssr/{src_lib_00wjv6n._.js → src_lib_04nzvfd._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{src_lib_0.~.oo-._.js → src_lib_0_px2pz._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0a.zy31._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0b73q0a._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0cld9rt._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{src_lib_005uqbe._.js → src_lib_0dbf2qa._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0er7rzd._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0f0v8_~._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0fr6fzy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{src_lib_01sr8_t._.js → src_lib_0h2u7a0._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0k04rl3._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0lpxsj~._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0sq6aqm._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0ui-~7g._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0y5zzg-._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0z-gn78._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_13c4a4g._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_harness_harness-message_ts_0_3ygf9._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_pty_11~ojr2._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_lib_pty_orphan-reaper_ts_0a0qmlo._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0ng0eku._.js → src_lib_schemas_ts_0ph~1ak._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_worktree_ts_06cucy3._.js +1 -1
- package/.next/standalone/.next/server/functions-config-manifest.json +6 -0
- package/.next/standalone/.next/server/instrumentation.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +8 -0
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +2368 -1528
- package/.next/standalone/.next/static/chunks/0-kkc.ibted8y.js +1 -0
- package/.next/standalone/.next/static/chunks/{0xejm4ge9~cn..js → 0.2y9uc38xso-.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0346xrw6i2bwo.js → 0.gedys.tq.~k.js} +1 -1
- package/.next/standalone/.next/static/chunks/00g58.es_hxli.js +1 -0
- package/.next/standalone/.next/static/chunks/00o_eiv12t~.1.js +1 -0
- package/.next/standalone/.next/static/chunks/01qtgj0xv1fsm.js +2 -0
- package/.next/standalone/.next/static/chunks/024euw7po0d0w.js +1 -0
- package/.next/standalone/.next/static/chunks/02v-9v~885t9c.js +1 -0
- package/.next/standalone/.next/static/chunks/03ct4d8znb7tp.js +1 -0
- package/.next/standalone/.next/static/chunks/03uix~1ru.ovv.js +1 -0
- package/.next/standalone/.next/static/chunks/04.2m8l~ws19v.js +1 -0
- package/.next/standalone/.next/static/chunks/06x7oq8_iu~9d.js +1 -0
- package/.next/standalone/.next/static/chunks/07c4b1kp_85qg.js +1 -0
- package/.next/standalone/.next/static/chunks/07qijq9o5jccu.js +1 -0
- package/.next/standalone/.next/static/chunks/{0uj-3ckujwaiy.js → 09om2gfwimh7k.js} +1 -1
- package/.next/standalone/.next/static/chunks/0alhq.h4~iogi.js +1 -0
- package/.next/standalone/.next/static/chunks/{0rcuiuax31_uh.js → 0cf7e1scao3zk.js} +1 -1
- package/.next/standalone/.next/static/chunks/0ck~sr0nkabl~.js +1 -0
- package/.next/standalone/.next/static/chunks/0d1ok-v-u-xe~.js +1 -0
- package/.next/standalone/.next/static/chunks/0d9u2xspag~4h.js +5 -0
- package/.next/standalone/.next/static/chunks/0ftptcpntzaux.js +1 -0
- package/.next/standalone/.next/static/chunks/0gk~m5bwgoafi.js +1 -0
- package/.next/standalone/.next/static/chunks/0in_7s8n4lmfr.js +1 -0
- package/.next/standalone/.next/static/chunks/0ix28r65.7o_r.js +12 -0
- package/.next/standalone/.next/static/chunks/0j5olwb~d3~3j.js +1 -0
- package/.next/standalone/.next/static/chunks/0mtrtl-jl46in.js +2 -0
- package/.next/standalone/.next/static/chunks/0ov_akpudbv96.js +5 -0
- package/.next/standalone/.next/static/chunks/0oyskd~8~j.j7.js +1 -0
- package/.next/standalone/.next/static/chunks/0q1872yhybt55.js +1 -0
- package/.next/standalone/.next/static/chunks/0seo-lerjdkbn.js +1 -0
- package/.next/standalone/.next/static/chunks/0t1awv68pnn-e.js +1 -0
- package/.next/standalone/.next/static/chunks/0wl8cpmvyhv0l.js +1 -0
- package/.next/standalone/.next/static/chunks/0~2l3wz-gxs2j.js +1 -0
- package/.next/standalone/.next/static/chunks/0~7h_a_dofg-4.js +1 -0
- package/.next/standalone/.next/static/chunks/11yhe31en~dvt.js +1 -0
- package/.next/standalone/.next/static/chunks/12-mlz2vukuga.js +1 -0
- package/.next/standalone/.next/static/chunks/14fch6~swodjf.css +1 -0
- package/.next/standalone/.next/static/chunks/15gztq9f12uhe.js +1 -0
- package/.next/standalone/.next/static/chunks/15ue90qe1sh-9.js +1 -0
- package/.next/standalone/.next/static/chunks/17z9uivez~kp3.js +1 -0
- package/.next/standalone/package.json +5 -6
- package/dist/mcp-server.cjs +1597 -4545
- package/package.json +5 -6
- package/prisma/schema.prisma +83 -5
- package/scripts/migrations/0005-add-parent-task-id.ts +29 -0
- package/scripts/migrations/0006-project-knowledge.ts +58 -0
- package/scripts/migrations/0007-product-group.ts +67 -0
- package/scripts/{stop-hook.js → tower-stop-hook.js} +42 -3
- package/skills/tower/SKILL.md +36 -75
- package/skills/tower/references/task-source.md +80 -0
- package/skills/tower/references/unattended-messaging.md +95 -0
- package/tsconfig.json +14 -4
- package/.next/standalone/.next/server/chunks/[externals]__0x_wqa7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.p6em~._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.zmhk-._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0042hx5._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03ufxqq._.js +0 -28
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04--bs7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04m2l8a._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04r193~._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0657y50._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06ndn7a._.js +0 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08yqoti._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__098.3z2._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_d.s7s._.js +0 -28
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zfnj0._.js +0 -20
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0clptds._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g.k9o~._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i34gbs._.js +0 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0iggiij._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i~3dwq._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0j05vlm._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0j1px8f._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k-5ag7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0otyifi._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0pl.c5.._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0r~9.7c._.js +0 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t31ba_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t_weyi._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uptkzd._.js +0 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x3kws1._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0y8w5di._.js +0 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zi3~a8._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0~g6-c~._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10fv6tt._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1189rd1._.js +0 -4
- package/.next/standalone/.next/server/chunks/_0jmdgq~._.js +0 -7
- package/.next/standalone/.next/server/chunks/_0q10iet._.js +0 -7
- package/.next/standalone/.next/server/chunks/_0qk_esg._.js +0 -4
- package/.next/standalone/.next/server/chunks/_0t31z6q._.js +0 -5
- package/.next/standalone/.next/server/chunks/_12537g8._.js +0 -7
- package/.next/standalone/.next/server/chunks/src_0fq3zjg._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_0weytpz._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_0wlyw0g._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_0~ey84y._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_lib_0i2.v2d._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_lib_0nw5n~t._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_lib_12xey8u._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/0ws9_lucide-react_dist_esm_icons_0pkla8j._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00ebsjb._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01fmnse._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01vm_46._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__025ol9g._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__049n47u._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04ednzb._.js +0 -43
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04wbr9x._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__05xg05r._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06dfcgo._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07xkj1s._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__081e5n~._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08tzbfh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ecd_1d._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0iln7n_._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0j_-qk5._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0k6oo0n._.js +0 -43
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lws68d._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mpjat-._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oamph.._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pnv7nd._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0tja~wz._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ug022w._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ugledi._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vxlsec._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0.sdz._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0x6k.ee._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0xwzk2.._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yby8pl._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0z7je5_._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zxc81t._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zzqn5z._.js +0 -43
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__10c.a3u._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__10n3vn6._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__123rmyb._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__124zb~p._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__127w3bm._.js +0 -43
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13ce7v2._.js +0 -30
- package/.next/standalone/.next/server/chunks/ssr/_04~mjmb._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_05a2u03._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/_070t_mh._.js +0 -6
- package/.next/standalone/.next/server/chunks/ssr/_07q06~v._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/_0_q41~z._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/_0cj9a7y._.js +0 -7
- package/.next/standalone/.next/server/chunks/ssr/_0dxbp89._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/_0foto06._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0kojxno._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0rdyrfd._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0rxeqmo._.js +0 -17
- package/.next/standalone/.next/server/chunks/ssr/_0s.h4l2._.js +0 -43
- package/.next/standalone/.next/server/chunks/ssr/_0u3yt.5._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/_0wqcz3w._.js +0 -47
- package/.next/standalone/.next/server/chunks/ssr/_0ye1-r-._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_03r.9go._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_06f0dao._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_0djxlqx._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_0eufeyj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_components_ui_select_tsx_0d2ra01._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_08jql1e._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0b~j-9d._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0eymyjf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0fkv9z3._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0n-n0.a._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0sgt~lv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0sms4xl._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0x-iyl1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_0yjmty1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_lib_13aevv6._.js +0 -3
- package/.next/standalone/.next/static/chunks/0-tuek2jqf0el.js +0 -1
- package/.next/standalone/.next/static/chunks/0.-.jc~0b~hy0.js +0 -1
- package/.next/standalone/.next/static/chunks/0.lqb7y9kz5z6.js +0 -1
- package/.next/standalone/.next/static/chunks/0.nsmn6shzidu.js +0 -2
- package/.next/standalone/.next/static/chunks/0.~03w.uxge40.js +0 -1
- package/.next/standalone/.next/static/chunks/01hdj_kw4z2zq.js +0 -2
- package/.next/standalone/.next/static/chunks/01j9m895w64zn.js +0 -1
- package/.next/standalone/.next/static/chunks/01yoibobkdz3x.js +0 -1
- package/.next/standalone/.next/static/chunks/041o.dh2lc-k3.js +0 -1
- package/.next/standalone/.next/static/chunks/07i9j5yyg4vs3.js +0 -1
- package/.next/standalone/.next/static/chunks/08ooaq~-.8fzu.js +0 -1
- package/.next/standalone/.next/static/chunks/0bylodlncwfpb.js +0 -5
- package/.next/standalone/.next/static/chunks/0clewc5ifaruu.js +0 -12
- package/.next/standalone/.next/static/chunks/0cpwtqzrjdgvs.js +0 -1
- package/.next/standalone/.next/static/chunks/0c~e1-nst-ze-.js +0 -1
- package/.next/standalone/.next/static/chunks/0ddt-snh45031.js +0 -1
- package/.next/standalone/.next/static/chunks/0dv4anj-j523o.js +0 -1
- package/.next/standalone/.next/static/chunks/0gf~0e3xpa0fj.js +0 -5
- package/.next/standalone/.next/static/chunks/0gvfb.b8m_i8t.js +0 -1
- package/.next/standalone/.next/static/chunks/0h77-u2vvr-a1.js +0 -1
- package/.next/standalone/.next/static/chunks/0jrje~1gt6w85.css +0 -1
- package/.next/standalone/.next/static/chunks/0lqp~-dlfenad.js +0 -1
- package/.next/standalone/.next/static/chunks/0p4w5b_p_yju8.js +0 -1
- package/.next/standalone/.next/static/chunks/0qkr26yz3bocs.js +0 -1
- package/.next/standalone/.next/static/chunks/0uf~7eqel0zra.js +0 -1
- package/.next/standalone/.next/static/chunks/0w71r_sj_fibx.js +0 -1
- package/.next/standalone/.next/static/chunks/0xg6rcq6g4bbh.js +0 -1
- package/.next/standalone/.next/static/chunks/0yff8rwmrl5m4.js +0 -1
- package/.next/standalone/.next/static/chunks/0ymipmkk2uqby.js +0 -1
- package/.next/standalone/.next/static/chunks/0znfclapbniaa.js +0 -1
- package/.next/standalone/.next/static/chunks/11pe3kpxuj33f.js +0 -1
- package/.next/standalone/.next/static/chunks/172s9cg35qt7i.js +0 -1
- package/.next/standalone/.next/static/chunks/17m4o~gdsvuo3.js +0 -1
- package/.next/standalone/.next/static/chunks/184-zu89wwa4u.js +0 -1
- package/next.config.ts +0 -18
- /package/.next/standalone/.next/static/{dinNvsaC6aoPK_B7ZTeBv → Pf_z-PYy0CJhvcyPEi-LM}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{dinNvsaC6aoPK_B7ZTeBv → Pf_z-PYy0CJhvcyPEi-LM}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{dinNvsaC6aoPK_B7ZTeBv → Pf_z-PYy0CJhvcyPEi-LM}/_ssgManifest.js +0 -0
- /package/scripts/{post-tool-hook.js → tower-post-tool-hook.js} +0 -0
- /package/scripts/{session-start-hook.js → tower-session-start-hook.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tower-studio",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.46",
|
|
4
4
|
"description": "AI Task Orchestration Platform — Kanban + Terminal + Code Editor + MCP",
|
|
5
5
|
"bin": {
|
|
6
6
|
"tower": "bin/tower.mjs"
|
|
@@ -20,17 +20,16 @@
|
|
|
20
20
|
"scripts/migrate-data.ts",
|
|
21
21
|
"scripts/run-migrations.ts",
|
|
22
22
|
"scripts/migrations/",
|
|
23
|
-
"scripts/post-tool-hook.js",
|
|
24
|
-
"scripts/session-start-hook.js",
|
|
25
|
-
"scripts/stop-hook.js",
|
|
23
|
+
"scripts/tower-post-tool-hook.js",
|
|
24
|
+
"scripts/tower-session-start-hook.js",
|
|
25
|
+
"scripts/tower-stop-hook.js",
|
|
26
26
|
"dist/mcp-server.cjs",
|
|
27
27
|
"skills/",
|
|
28
|
-
"next.config.ts",
|
|
29
28
|
"tsconfig.json"
|
|
30
29
|
],
|
|
31
30
|
"scripts": {
|
|
32
31
|
"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",
|
|
32
|
+
"dev": "NEXT_DISTDIR=.next-dev TOWER_DATA_DIR=\"$HOME/.tower-dev\" DATABASE_URL=\"file:$HOME/.tower-dev/database/tower.db\" env -u TURBOPACK next dev --webpack -p 9022",
|
|
34
33
|
"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
34
|
"release": "pnpm build && npm pack",
|
|
36
35
|
"release:smoke": "node scripts/release-smoke.js",
|
package/prisma/schema.prisma
CHANGED
|
@@ -15,10 +15,11 @@ model Workspace {
|
|
|
15
15
|
createdAt DateTime @default(now())
|
|
16
16
|
updatedAt DateTime @updatedAt
|
|
17
17
|
|
|
18
|
-
projects
|
|
19
|
-
labels
|
|
20
|
-
prompts
|
|
21
|
-
versionTypes
|
|
18
|
+
projects Project[]
|
|
19
|
+
labels Label[]
|
|
20
|
+
prompts AgentPrompt[]
|
|
21
|
+
versionTypes VersionType[]
|
|
22
|
+
productGroups ProductGroup[]
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
model Project {
|
|
@@ -34,18 +35,58 @@ model Project {
|
|
|
34
35
|
previewPort Int?
|
|
35
36
|
previewPreset String?
|
|
36
37
|
previewInstallCommand String?
|
|
38
|
+
// 知识库:groupId 把同一产品的多个仓库(前后端/trace/需求)归入一个 ProductGroup,
|
|
39
|
+
// 问答时自动把同组兄弟项目一起纳入检索。knowledgeDir 是 repo 内知识库目录(相对 localPath),
|
|
40
|
+
// 留空则用约定默认(见 src/lib/knowledge.ts DEFAULT_KNOWLEDGE_DIR)。
|
|
41
|
+
groupId String?
|
|
42
|
+
knowledgeDir String?
|
|
37
43
|
workspaceId String
|
|
38
44
|
createdAt DateTime @default(now())
|
|
39
45
|
updatedAt DateTime @updatedAt
|
|
40
46
|
|
|
41
|
-
workspace Workspace
|
|
47
|
+
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
48
|
+
group ProductGroup? @relation(fields: [groupId], references: [id], onDelete: SetNull)
|
|
42
49
|
tasks Task[]
|
|
43
50
|
repositories Repository[]
|
|
44
51
|
notes ProjectNote[]
|
|
45
52
|
assets ProjectAsset[]
|
|
46
53
|
versions Version[]
|
|
54
|
+
facts ProjectFact[]
|
|
47
55
|
|
|
48
56
|
@@index([workspaceId])
|
|
57
|
+
@@index([groupId])
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// 产品组:把同一产品的多个仓库(前后端 / trace 静态知识库 / 需求)归为一组。
|
|
61
|
+
/// 组内成员的知识(repo 知识目录 + 事实卡 + 版本/commit + 笔记)在问答时一起检索。
|
|
62
|
+
model ProductGroup {
|
|
63
|
+
id String @id @default(cuid())
|
|
64
|
+
name String
|
|
65
|
+
description String?
|
|
66
|
+
workspaceId String
|
|
67
|
+
createdAt DateTime @default(now())
|
|
68
|
+
updatedAt DateTime @updatedAt
|
|
69
|
+
|
|
70
|
+
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
71
|
+
projects Project[]
|
|
72
|
+
|
|
73
|
+
@@unique([workspaceId, name])
|
|
74
|
+
@@index([workspaceId])
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 结构化「事实卡」:机器拿不到、需人工/AI 填的项目级 key-value(生产环境路径、
|
|
78
|
+
// CICD 路径、域名等)。知识库问答的精确命中源之一。key 在项目内唯一(upsert)。
|
|
79
|
+
model ProjectFact {
|
|
80
|
+
id String @id @default(cuid())
|
|
81
|
+
projectId String
|
|
82
|
+
key String
|
|
83
|
+
value String
|
|
84
|
+
updatedAt DateTime @updatedAt
|
|
85
|
+
|
|
86
|
+
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
87
|
+
|
|
88
|
+
@@unique([projectId, key])
|
|
89
|
+
@@index([projectId])
|
|
49
90
|
}
|
|
50
91
|
|
|
51
92
|
model Label {
|
|
@@ -83,6 +124,7 @@ model Task {
|
|
|
83
124
|
promptId String?
|
|
84
125
|
baseBranch String?
|
|
85
126
|
subPath String?
|
|
127
|
+
parentTaskId String? // 派生来源:派生此任务的父任务 id(父任务终端注入的 TOWER_TASK_ID)。裸字符串无 relation,与 promptId 同惯例
|
|
86
128
|
previewCommandOverride String?
|
|
87
129
|
previewPortOverride Int?
|
|
88
130
|
projectId String
|
|
@@ -91,17 +133,23 @@ model Task {
|
|
|
91
133
|
updatedAt DateTime @updatedAt
|
|
92
134
|
doneAt DateTime? // 进入 DONE 的时间戳,用于「归档期限」判定(离开 DONE 时清空)
|
|
93
135
|
|
|
136
|
+
// 无人值守:开启后 agent 遇阻塞主动 ask_human/notify_human(经 tower-ask 技能用平台 MCP 外推);
|
|
137
|
+
// 关闭则只在 /harness 面板内显示等待。Tower 只记录+park/resume,不发消息、不存平台绑定。
|
|
138
|
+
unattended Boolean @default(false)
|
|
139
|
+
|
|
94
140
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
95
141
|
executions TaskExecution[]
|
|
96
142
|
messages TaskMessage[]
|
|
97
143
|
labels TaskLabel[]
|
|
98
144
|
notes ProjectNote[]
|
|
99
145
|
assets ProjectAsset[]
|
|
146
|
+
harnessMessages HarnessMessage[]
|
|
100
147
|
version Version? @relation(fields: [versionId], references: [id], onDelete: SetNull)
|
|
101
148
|
|
|
102
149
|
@@index([projectId])
|
|
103
150
|
@@index([status])
|
|
104
151
|
@@index([versionId])
|
|
152
|
+
@@index([parentTaskId])
|
|
105
153
|
}
|
|
106
154
|
|
|
107
155
|
model TaskExecution {
|
|
@@ -137,6 +185,36 @@ model TaskExecution {
|
|
|
137
185
|
@@index([insightNoteId])
|
|
138
186
|
}
|
|
139
187
|
|
|
188
|
+
// 无人值守:一张表记所有 harness→人 的消息(ask/notify/done/failed)—— 纯记录/日志,Tower 不发送。
|
|
189
|
+
// - kind='ask' 是 park/resume 闭环载体,带生命周期 state:OPEN→ANSWERED|CANCELLED|IGNORED|EXPIRED。
|
|
190
|
+
// - notify/done/failed 是日志行,出生即 CLOSED,不参与「待回复」过滤。
|
|
191
|
+
// - 不变量:待回复 = kind='ask' AND state='OPEN'。回复内容记在 replyText(reply_to_ask 写入)。
|
|
192
|
+
model HarnessMessage {
|
|
193
|
+
id String @id @default(cuid())
|
|
194
|
+
taskId String
|
|
195
|
+
executionId String?
|
|
196
|
+
kind String // "ask" | "notify" | "done" | "failed"(映射 OutboundKind)
|
|
197
|
+
content String
|
|
198
|
+
replyText String?
|
|
199
|
+
repliedAt DateTime?
|
|
200
|
+
state HarnessState @default(OPEN)
|
|
201
|
+
createdAt DateTime @default(now())
|
|
202
|
+
|
|
203
|
+
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
204
|
+
|
|
205
|
+
@@index([taskId, kind, state])
|
|
206
|
+
@@index([state])
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
enum HarnessState {
|
|
210
|
+
OPEN
|
|
211
|
+
ANSWERED
|
|
212
|
+
CANCELLED
|
|
213
|
+
IGNORED
|
|
214
|
+
EXPIRED
|
|
215
|
+
CLOSED
|
|
216
|
+
}
|
|
217
|
+
|
|
140
218
|
model TaskMessage {
|
|
141
219
|
id String @id @default(cuid())
|
|
142
220
|
role MessageRole
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Add Task.parentTaskId — 派生中枢的父任务链。
|
|
3
|
+
*
|
|
4
|
+
* 子任务由父任务终端的 claude 调 create_task 创建时,写入派生它的父任务 id
|
|
5
|
+
* (父任务 PTY 注入的 TOWER_TASK_ID)。用于完成回推(子任务 stop → 通知父任务
|
|
6
|
+
* review)及将来的派生子任务展示。裸字符串列、无 FK relation(与 promptId 同惯例)。
|
|
7
|
+
*
|
|
8
|
+
* 加性 raw SQL —— 绝不碰 notes_fts 虚表(prisma db push 会卡死)。
|
|
9
|
+
* 幂等:SQLite 无 ADD COLUMN IF NOT EXISTS,先 PRAGMA 检查列是否存在。
|
|
10
|
+
*
|
|
11
|
+
* Table/column names hardcoded on purpose — a migration is a point-in-time
|
|
12
|
+
* snapshot and must keep doing exactly what it did the day it shipped.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { PrismaClient } from "@prisma/client";
|
|
16
|
+
|
|
17
|
+
export async function up(prisma: PrismaClient): Promise<void> {
|
|
18
|
+
const cols = await prisma.$queryRawUnsafe<Array<{ name: string }>>(
|
|
19
|
+
`PRAGMA table_info("Task")`
|
|
20
|
+
);
|
|
21
|
+
const hasCol = Array.isArray(cols) && cols.some((c) => c.name === "parentTaskId");
|
|
22
|
+
if (!hasCol) {
|
|
23
|
+
await prisma.$executeRawUnsafe(`ALTER TABLE "Task" ADD COLUMN "parentTaskId" TEXT`);
|
|
24
|
+
console.log(" added Task.parentTaskId");
|
|
25
|
+
}
|
|
26
|
+
await prisma.$executeRawUnsafe(
|
|
27
|
+
`CREATE INDEX IF NOT EXISTS "Task_parentTaskId_idx" ON "Task"("parentTaskId")`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 项目知识库地基:Project.productKey / Project.knowledgeDir + ProjectFact 表。
|
|
3
|
+
*
|
|
4
|
+
* - productKey: 产品组归一(前后端 a/b 填同值即成组),问答时兄弟项目一起检索。
|
|
5
|
+
* - knowledgeDir: repo 内知识库目录(相对 localPath),留空走约定默认。
|
|
6
|
+
* - ProjectFact: 机器拿不到的项目级事实卡(生产/CICD 路径等),key 项目内唯一。
|
|
7
|
+
*
|
|
8
|
+
* 加性 raw SQL —— 绝不碰 notes_fts 虚表(prisma db push 会卡死)。
|
|
9
|
+
* 幂等:SQLite 无 ADD COLUMN IF NOT EXISTS,先 PRAGMA 检查列是否存在。
|
|
10
|
+
*
|
|
11
|
+
* Table/column names hardcoded on purpose — a migration is a point-in-time
|
|
12
|
+
* snapshot and must keep doing exactly what it did the day it shipped.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { PrismaClient } from "@prisma/client";
|
|
16
|
+
|
|
17
|
+
async function addColumnIfMissing(
|
|
18
|
+
prisma: PrismaClient,
|
|
19
|
+
table: string,
|
|
20
|
+
column: string,
|
|
21
|
+
ddlType: string
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const cols = await prisma.$queryRawUnsafe<Array<{ name: string }>>(
|
|
24
|
+
`PRAGMA table_info("${table}")`
|
|
25
|
+
);
|
|
26
|
+
const hasCol = Array.isArray(cols) && cols.some((c) => c.name === column);
|
|
27
|
+
if (!hasCol) {
|
|
28
|
+
await prisma.$executeRawUnsafe(
|
|
29
|
+
`ALTER TABLE "${table}" ADD COLUMN "${column}" ${ddlType}`
|
|
30
|
+
);
|
|
31
|
+
console.log(` added ${table}.${column}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function up(prisma: PrismaClient): Promise<void> {
|
|
36
|
+
await addColumnIfMissing(prisma, "Project", "productKey", "TEXT");
|
|
37
|
+
await addColumnIfMissing(prisma, "Project", "knowledgeDir", "TEXT");
|
|
38
|
+
await prisma.$executeRawUnsafe(
|
|
39
|
+
`CREATE INDEX IF NOT EXISTS "Project_productKey_idx" ON "Project"("productKey")`
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await prisma.$executeRawUnsafe(
|
|
43
|
+
`CREATE TABLE IF NOT EXISTS "ProjectFact" (` +
|
|
44
|
+
`"id" TEXT NOT NULL PRIMARY KEY, ` +
|
|
45
|
+
`"projectId" TEXT NOT NULL, ` +
|
|
46
|
+
`"key" TEXT NOT NULL, ` +
|
|
47
|
+
`"value" TEXT NOT NULL, ` +
|
|
48
|
+
`"updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ` +
|
|
49
|
+
`CONSTRAINT "ProjectFact_projectId_fkey" FOREIGN KEY ("projectId") ` +
|
|
50
|
+
`REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE)`
|
|
51
|
+
);
|
|
52
|
+
await prisma.$executeRawUnsafe(
|
|
53
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS "ProjectFact_projectId_key_key" ON "ProjectFact"("projectId", "key")`
|
|
54
|
+
);
|
|
55
|
+
await prisma.$executeRawUnsafe(
|
|
56
|
+
`CREATE INDEX IF NOT EXISTS "ProjectFact_projectId_idx" ON "ProjectFact"("projectId")`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 产品组一等实体:ProductGroup 表 + Project.groupId,取代平级字符串 Project.productKey。
|
|
3
|
+
*
|
|
4
|
+
* 加性 raw SQL —— 绝不碰 notes_fts 虚表。幂等:建表/建索引用 IF NOT EXISTS,加列先 PRAGMA 查。
|
|
5
|
+
*
|
|
6
|
+
* 为什么没有 productKey→组的数据回填:
|
|
7
|
+
* 1. productKey 从未发布(无真实数据)。
|
|
8
|
+
* 2. Tower 升级生命周期(bin/tower.mjs preStart)**先** `db push --accept-data-loss`
|
|
9
|
+
* 按新 schema 同步、**再**跑本迁移。新 schema 已删 productKey,故 db push 会先
|
|
10
|
+
* 把该列连数据一起丢掉——等本迁移执行时 productKey 早已不存在,回填必成死代码。
|
|
11
|
+
* 迁移只负责把 groupId/ProductGroup 幂等建出来(供不走 db push 的 dev/迁移路径),
|
|
12
|
+
* 并清掉遗留的 productKey 列。删组时的「成员解绑」由 group-actions 在应用层做
|
|
13
|
+
* (ADD COLUMN 不带外键,不能靠 DB 级 onDelete: SetNull)。
|
|
14
|
+
*
|
|
15
|
+
* Table/column names hardcoded on purpose — a migration is a point-in-time snapshot.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { PrismaClient } from "@prisma/client";
|
|
19
|
+
|
|
20
|
+
async function hasColumn(prisma: PrismaClient, table: string, column: string): Promise<boolean> {
|
|
21
|
+
const cols = await prisma.$queryRawUnsafe<Array<{ name: string }>>(
|
|
22
|
+
`PRAGMA table_info("${table}")`
|
|
23
|
+
);
|
|
24
|
+
return Array.isArray(cols) && cols.some((c) => c.name === column);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function up(prisma: PrismaClient): Promise<void> {
|
|
28
|
+
// 1. ProductGroup 表
|
|
29
|
+
await prisma.$executeRawUnsafe(
|
|
30
|
+
`CREATE TABLE IF NOT EXISTS "ProductGroup" (` +
|
|
31
|
+
`"id" TEXT NOT NULL PRIMARY KEY, ` +
|
|
32
|
+
`"name" TEXT NOT NULL, ` +
|
|
33
|
+
`"description" TEXT, ` +
|
|
34
|
+
`"workspaceId" TEXT NOT NULL, ` +
|
|
35
|
+
`"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ` +
|
|
36
|
+
`"updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ` +
|
|
37
|
+
`CONSTRAINT "ProductGroup_workspaceId_fkey" FOREIGN KEY ("workspaceId") ` +
|
|
38
|
+
`REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE)`
|
|
39
|
+
);
|
|
40
|
+
await prisma.$executeRawUnsafe(
|
|
41
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS "ProductGroup_workspaceId_name_key" ON "ProductGroup"("workspaceId", "name")`
|
|
42
|
+
);
|
|
43
|
+
await prisma.$executeRawUnsafe(
|
|
44
|
+
`CREATE INDEX IF NOT EXISTS "ProductGroup_workspaceId_idx" ON "ProductGroup"("workspaceId")`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// 2. Project.groupId 列 + 索引
|
|
48
|
+
if (!(await hasColumn(prisma, "Project", "groupId"))) {
|
|
49
|
+
await prisma.$executeRawUnsafe(`ALTER TABLE "Project" ADD COLUMN "groupId" TEXT`);
|
|
50
|
+
console.log(" added Project.groupId");
|
|
51
|
+
}
|
|
52
|
+
await prisma.$executeRawUnsafe(
|
|
53
|
+
`CREATE INDEX IF NOT EXISTS "Project_groupId_idx" ON "Project"("groupId")`
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// 3. 清掉遗留 productKey 列(先删其索引)。无回填——见文件头说明。
|
|
57
|
+
// SQLite <3.35 不支持 DROP COLUMN → 留孤儿列,Prisma 忽略,无害。
|
|
58
|
+
await prisma.$executeRawUnsafe(`DROP INDEX IF EXISTS "Project_productKey_idx"`);
|
|
59
|
+
if (await hasColumn(prisma, "Project", "productKey")) {
|
|
60
|
+
try {
|
|
61
|
+
await prisma.$executeRawUnsafe(`ALTER TABLE "Project" DROP COLUMN "productKey"`);
|
|
62
|
+
console.log(" dropped Project.productKey");
|
|
63
|
+
} catch {
|
|
64
|
+
console.log(" DROP COLUMN productKey unsupported (old SQLite) — left orphaned, harmless");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
* Tower Stop Hook
|
|
4
4
|
*
|
|
5
5
|
* Claude Code Stop hook that fires when Claude finishes responding.
|
|
6
|
-
* Notifies Tower so the UI can show a "response complete" indicator
|
|
6
|
+
* Notifies Tower so the UI can show a "response complete" indicator, and so a
|
|
7
|
+
* derived child task can hand its turn back to the parent task for review.
|
|
7
8
|
*
|
|
8
9
|
* Environment:
|
|
9
10
|
* TOWER_TASK_ID - Required. Skip if absent (not a Tower session).
|
|
10
11
|
* TOWER_API_URL - Required. Base URL of the Tower server.
|
|
11
12
|
*
|
|
12
|
-
* Stdin: JSON object from Claude Code with { session_id, cwd, ... }
|
|
13
|
+
* Stdin: JSON object from Claude Code with { session_id, transcript_path, cwd, ... }
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
16
|
"use strict";
|
|
@@ -17,6 +18,43 @@
|
|
|
17
18
|
const http = require("http");
|
|
18
19
|
const https = require("https");
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* 从 Claude Code 的 transcript 提取最后一条 assistant 回复(截断 2000 字)。
|
|
23
|
+
* 用于完成回推:父任务据此 review,不必读整个终端缓冲。best-effort,失败返回空串。
|
|
24
|
+
* transcript 是 jsonl,行格式随 CC 版本略有差异,这里兼容 obj.message.content / obj.content。
|
|
25
|
+
*/
|
|
26
|
+
function extractLastAssistantText(transcriptPath) {
|
|
27
|
+
if (!transcriptPath) return "";
|
|
28
|
+
try {
|
|
29
|
+
const fs = require("fs");
|
|
30
|
+
const raw = fs.readFileSync(transcriptPath, "utf8");
|
|
31
|
+
const lines = raw.split("\n");
|
|
32
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
33
|
+
const line = lines[i].trim();
|
|
34
|
+
if (!line) continue;
|
|
35
|
+
let obj;
|
|
36
|
+
try { obj = JSON.parse(line); } catch { continue; }
|
|
37
|
+
const msg = obj.message || obj;
|
|
38
|
+
const role = msg.role || obj.type;
|
|
39
|
+
if (role !== "assistant" || !msg.content) continue;
|
|
40
|
+
let text = "";
|
|
41
|
+
if (Array.isArray(msg.content)) {
|
|
42
|
+
text = msg.content
|
|
43
|
+
.filter((c) => c && c.type === "text" && typeof c.text === "string")
|
|
44
|
+
.map((c) => c.text)
|
|
45
|
+
.join("\n")
|
|
46
|
+
.trim();
|
|
47
|
+
} else if (typeof msg.content === "string") {
|
|
48
|
+
text = msg.content.trim();
|
|
49
|
+
}
|
|
50
|
+
if (text) return text.slice(0, 2000);
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
/* best effort — transcript unreadable */
|
|
54
|
+
}
|
|
55
|
+
return "";
|
|
56
|
+
}
|
|
57
|
+
|
|
20
58
|
function main() {
|
|
21
59
|
// Always drain stdin first — Claude Code writes the hook payload there
|
|
22
60
|
// and if we exit before reading it, Windows libuv can crash the parent
|
|
@@ -52,10 +90,11 @@ function main() {
|
|
|
52
90
|
try { data = JSON.parse(input); } catch { process.exit(0); }
|
|
53
91
|
|
|
54
92
|
const sessionId = data.session_id || "";
|
|
93
|
+
const lastReply = extractLastAssistantText(data.transcript_path);
|
|
55
94
|
|
|
56
95
|
// POST to Tower
|
|
57
96
|
const url = new URL("/api/internal/hooks/stop", apiUrl);
|
|
58
|
-
const payload = JSON.stringify({ taskId, sessionId });
|
|
97
|
+
const payload = JSON.stringify({ taskId, sessionId, lastReply });
|
|
59
98
|
const mod = url.protocol === "https:" ? https : http;
|
|
60
99
|
|
|
61
100
|
const req = mod.request({
|
package/skills/tower/SKILL.md
CHANGED
|
@@ -39,6 +39,7 @@ Use Tower tools when the user wants to:
|
|
|
39
39
|
- Organize tasks with labels or status changes
|
|
40
40
|
- Get daily work summary or pending todo list
|
|
41
41
|
- Check what was done today or what's left to do
|
|
42
|
+
- **Run or relay unattended tasks** — when `TOWER_UNATTENDED=1`, or you need to push an `ask_human` / `notify_human` to a person, or relay a human's reply back into a parked task (`reply_to_ask`): read [`references/unattended-messaging.md`](references/unattended-messaging.md) for the send/receive contract.
|
|
42
43
|
|
|
43
44
|
---
|
|
44
45
|
|
|
@@ -51,6 +52,16 @@ to keep asking. If information is missing, ask a **specific** question instead o
|
|
|
51
52
|
vaguely promising to act. If the user prods you ("did you create it?", "创建了吗"),
|
|
52
53
|
it means your previous turn produced no tool call — issue the tool call now.
|
|
53
54
|
|
|
55
|
+
## Session default scope
|
|
56
|
+
|
|
57
|
+
If a turn opens with `[当前会话默认范围:…]`, the user has bound this chat to a
|
|
58
|
+
workspace/project. Treat it as the **default scope**: for scope-needing actions
|
|
59
|
+
(create/list/search within a project, label, version…) use those ids directly
|
|
60
|
+
and skip resolving with `identify_project`/`search`. No binding present → resolve
|
|
61
|
+
scope the usual way. It's a soft default, **not a hard filter** — global requests
|
|
62
|
+
(daily summary, cross-workspace search, list all workspaces) ignore it. The user
|
|
63
|
+
switching workspace/project mid-chat overrides it; the latest prefix always wins.
|
|
64
|
+
|
|
54
65
|
## Scenarios
|
|
55
66
|
|
|
56
67
|
### "Show me my workspaces" / "List projects"
|
|
@@ -78,7 +89,7 @@ it means your previous turn produced no tool call — issue the tool call now.
|
|
|
78
89
|
- **Pasted images with known paths**: if the platform provides file paths for pasted media (e.g. OpenClaw's `{{MediaPaths}}`, Claude Code temp files), pass those paths directly — they are local files
|
|
79
90
|
- **Base64 only (no file path)**: if you only have base64 data with no local path, upload first via `manage_assets` with `action: "upload"`, `projectId`, `base64`, `mimeType`. Get back `{ id: assetId, path }`. Then pass the returned `path` in `references` — `create_task` will automatically copy and link the asset, no separate `link_task` needed
|
|
80
91
|
- **`link_task` only for retroactive linking**: use `manage_assets` with `action: "link_task"` only when you need to associate existing assets with an already-created task (e.g. user wants to add references after task creation)
|
|
81
|
-
8. **Source (`## 来源`)** — ALWAYS
|
|
92
|
+
8. **Source (`## 来源`)** — ALWAYS end the `description` with a `## 来源` section (it's the last section of the description format — see **Task Description Format** for the rule and [references/task-source.md](references/task-source.md) for the full rendering). No source info → literally `## 来源\n无`. Source present (a `<task-source>` bridge block or `TOWER_TASK_ID`) → standardize into a detailed, traceable record.
|
|
82
93
|
9. Call `create_task` with projectId, title, and optional description/priority/labelIds/subPath/versionId/useWorktree/baseBranch/references
|
|
83
94
|
10. After creating: if `autoStart` resolved to true the task starts immediately (check the response's `execution` field — `autoStart` intent does not guarantee it actually started); otherwise the task stays TODO.
|
|
84
95
|
|
|
@@ -184,6 +195,9 @@ The `description` field supports Markdown. **Never copy the user's raw message a
|
|
|
184
195
|
|
|
185
196
|
## 备注
|
|
186
197
|
- <constraints, edge cases, things to watch out for>
|
|
198
|
+
|
|
199
|
+
## 来源
|
|
200
|
+
无
|
|
187
201
|
```
|
|
188
202
|
|
|
189
203
|
Rules:
|
|
@@ -192,6 +206,14 @@ Rules:
|
|
|
192
206
|
- Extract actionable requirements from the user's natural language
|
|
193
207
|
- Omit sections that have no content (e.g. skip 备注 if nothing to note)
|
|
194
208
|
- If user provides file paths, put them in 参考 section AND in `references` parameter
|
|
209
|
+
- **`## 来源` is mandatory and always the LAST section** — it traces *why* the task
|
|
210
|
+
exists and *who* asked. Every creation path (助手 / 飞书 / 父子派生 / 终端) ends here:
|
|
211
|
+
- **No source info** → write exactly `## 来源` + `无` (as shown above).
|
|
212
|
+
- **Source present** → standardize into a human-readable record, then read
|
|
213
|
+
[references/task-source.md](references/task-source.md) for the exact rendering.
|
|
214
|
+
Two triggers: `TOWER_TASK_ID` set (parent-derived child) or a `<task-source>`
|
|
215
|
+
block (bridge like Feishu). Keep hard locators (chat/msg id, link) verbatim; if
|
|
216
|
+
a `<task-source>` block is present, DROP the raw block from the description.
|
|
195
217
|
|
|
196
218
|
---
|
|
197
219
|
|
|
@@ -239,80 +261,6 @@ Note: the response does not include workspace name. Use the workspace name from
|
|
|
239
261
|
| {id (first 8 chars)} | {title} | {status} | {priority} | {labels} |
|
|
240
262
|
```
|
|
241
263
|
|
|
242
|
-
### Task Source (`## 来源`)
|
|
243
|
-
|
|
244
|
-
Every task created through this skill MUST end its `description` with a `## 来源`
|
|
245
|
-
section so we can always trace **why** a task exists and **who** asked for it.
|
|
246
|
-
|
|
247
|
-
**No source info in the prompt** → write exactly:
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
## 来源
|
|
251
|
-
无
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Source info present** → standardize it into a human-readable record. Keep the
|
|
255
|
-
hard locators (chat id / message id / link) verbatim — they are what makes the
|
|
256
|
-
task traceable later.
|
|
257
|
-
|
|
258
|
-
#### Bridge metadata contract (`<task-source>` block)
|
|
259
|
-
|
|
260
|
-
External bridges (Feishu/Lark, etc.) inject a machine-readable block into the
|
|
261
|
-
message. When you see it, parse it, render the standardized `## 来源`, and then
|
|
262
|
-
DROP the raw block from the description (don't store the tags):
|
|
263
|
-
|
|
264
|
-
```
|
|
265
|
-
<task-source>
|
|
266
|
-
channel: feishu # 渠道 (feishu | openclaw | manual | ...)
|
|
267
|
-
chat_name: 南京招生报名讨论群 # 群显示名
|
|
268
|
-
chat_id: oc_xxxxxxxx # 群 ID(硬定位符,必带)
|
|
269
|
-
occurred_at: 2026-06-16 17:49 +08:00 # 讨论/触发时间,带时区(用于进群后定位到具体那条)
|
|
270
|
-
chat_link: https://applink.feishu.cn/client/chat/open?openChatId=oc_xxxxxxxx # 打开「群」的链接(群级,飞书无法精确到单条消息)
|
|
271
|
-
trigger_message_id: om_xxxxxxxx # 触发那条消息的 ID(不可点,但唯一绑定该消息,必带;用于程序回读/去重/兜底)
|
|
272
|
-
thread_root_id: om_yyyyyyyy # (可选)话题根消息 ID
|
|
273
|
-
participants: # 参与者:显示名 + open_id + 角色
|
|
274
|
-
- name: 张斯佳, open_id: ou_aaa, role: 讨论
|
|
275
|
-
- name: 张瑶, open_id: ou_bbb, role: 讨论
|
|
276
|
-
- name: 刘俊平, open_id: ou_ccc, role: 确认
|
|
277
|
-
transcript: | # 相关消息原文(按时间)—— 人真正要看的内容,必带
|
|
278
|
-
17:49 张斯佳:有线下核验点,但无可预约时间,这里需要加提示么?
|
|
279
|
-
17:5x 张瑶:建议合并提示语「目前暂无线下审核点或没有可预约的时间…」
|
|
280
|
-
17:5x 刘俊平:可以处理
|
|
281
|
-
summary: 线下核验点无可预约时间,确认合并提示语后处理 # (可选)一句话结论;缺省时由模型从 transcript 推
|
|
282
|
-
</task-source>
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
Roles are not required to be pre-computed by the bridge — if `role` is missing,
|
|
286
|
-
infer it from the `transcript` (谁提出 / 谁讨论 / 谁拍板"可以处理"). If a
|
|
287
|
-
`summary` is absent, derive it from the `transcript`.
|
|
288
|
-
|
|
289
|
-
**Feishu reality** — `chat_link` only opens the **group**, not a single message.
|
|
290
|
-
So the practical "go back and find it" combo is **群链接 + occurred_at + transcript**:
|
|
291
|
-
open the group, jump to that time, the transcript is the actual content. Label the
|
|
292
|
-
link line **打开群** (never "原始消息") so nobody expects a one-click jump to the
|
|
293
|
-
exact message. `trigger_message_id` is kept as the only hard anchor to that
|
|
294
|
-
message (not clickable — for programmatic re-read / dedup / fallback).
|
|
295
|
-
|
|
296
|
-
#### Rendered `## 来源` format
|
|
297
|
-
|
|
298
|
-
```
|
|
299
|
-
## 来源
|
|
300
|
-
|
|
301
|
-
- 渠道:飞书群「{chat_name}」
|
|
302
|
-
- 时间:{occurred_at}
|
|
303
|
-
- 参与者:{讨论者们}(讨论),{确认者}(确认可处理)
|
|
304
|
-
- 讨论要点:{summary}
|
|
305
|
-
- 打开群:{chat_link}
|
|
306
|
-
- 溯源 ID:chat={chat_id} · msg={trigger_message_id}{ thread_root_id 时追加 · thread={thread_root_id}}
|
|
307
|
-
|
|
308
|
-
讨论摘录(按时间):
|
|
309
|
-
{transcript}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
Only render lines whose data is present (e.g. omit `打开群` if there is no
|
|
313
|
-
`chat_link`). Always keep `chat_id` + `trigger_message_id` (hard anchors) and the
|
|
314
|
-
`讨论摘录`/`transcript` (the content humans actually read).
|
|
315
|
-
|
|
316
264
|
### Task Creation Confirmation
|
|
317
265
|
|
|
318
266
|
After `create_task` succeeds, render based on the **response** (not the input
|
|
@@ -468,6 +416,19 @@ Categories: `task`, `project`, `repository`, `note`, `asset`, `all`. Result coun
|
|
|
468
416
|
|
|
469
417
|
---
|
|
470
418
|
|
|
419
|
+
## 无人值守收发消息(Unattended messaging)
|
|
420
|
+
|
|
421
|
+
When operating in unattended mode (`TOWER_UNATTENDED=1`) or acting as the bridge that relays a
|
|
422
|
+
human's reply back to a parked task, follow the send/receive contract in
|
|
423
|
+
[`references/unattended-messaging.md`](references/unattended-messaging.md). Key points:
|
|
424
|
+
|
|
425
|
+
- Tower **only records + parks/resumes** — it never sends platform messages. You (the agent/bridge)
|
|
426
|
+
send via the platform's own MCP (Feishu/WeChat/OpenClaw…).
|
|
427
|
+
- Every outbound ask/notify **must** carry the correlation token `[[tower:task=<taskId>]]`.
|
|
428
|
+
- Relay a human's reply with the **`reply_to_ask(taskId, text)`** MCP tool (not raw
|
|
429
|
+
`send_task_terminal_input`) so Tower records the reply. If it returns `{ no_pending: true }`,
|
|
430
|
+
handle the message as an ordinary request.
|
|
431
|
+
|
|
471
432
|
## Important Rules
|
|
472
433
|
|
|
473
434
|
- **Scope boundary**: You are a **task management operator only**. If the user asks you to write code, explain code, debug, search the web, read/write files, or anything outside Tower task management, reply: "抱歉,我只能帮你管理工作区、项目和任务。编码、调试等操作请在任务终端中完成。" Do NOT attempt to answer out-of-scope questions.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Task Source (`## 来源`) — detailed rendering
|
|
2
|
+
|
|
3
|
+
Read this when the incoming prompt carries real source info — a parent-task
|
|
4
|
+
derivation (`TOWER_TASK_ID` set) or a `<task-source>` bridge block. For the
|
|
5
|
+
common "no source" case you don't need this file: just write `## 来源\n无`.
|
|
6
|
+
|
|
7
|
+
## Parent task derivation (派生子任务)
|
|
8
|
+
|
|
9
|
+
If `TOWER_TASK_ID` is set in your environment (run `echo $TOWER_TASK_ID` to check),
|
|
10
|
+
you are operating **inside a Tower task terminal** — so any task you create here is
|
|
11
|
+
a **child task derived from the current (parent) task**. Render its source as:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
## 来源
|
|
15
|
+
|
|
16
|
+
- 渠道:父任务派生
|
|
17
|
+
- 父任务:{当前任务标题,知道就填}(id: $TOWER_TASK_ID)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Tower also records this link structurally on the new task's `parentTaskId`
|
|
21
|
+
automatically (used for parent→child completion notifications) — this `## 来源`
|
|
22
|
+
is just the human-readable mirror. The id alone is enough if you don't know the title.
|
|
23
|
+
|
|
24
|
+
## Bridge metadata contract (`<task-source>` block)
|
|
25
|
+
|
|
26
|
+
External bridges (Feishu/Lark, etc.) inject a machine-readable block into the
|
|
27
|
+
message. When you see it, parse it, render the standardized `## 来源`, and then
|
|
28
|
+
DROP the raw block from the description (don't store the tags):
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
<task-source>
|
|
32
|
+
channel: feishu # 渠道 (feishu | openclaw | manual | ...)
|
|
33
|
+
chat_name: 南京招生报名讨论群 # 群显示名
|
|
34
|
+
chat_id: oc_xxxxxxxx # 群 ID(硬定位符,必带)
|
|
35
|
+
occurred_at: 2026-06-16 17:49 +08:00 # 讨论/触发时间,带时区(用于进群后定位到具体那条)
|
|
36
|
+
chat_link: https://applink.feishu.cn/client/chat/open?openChatId=oc_xxxxxxxx # 打开「群」的链接(群级,飞书无法精确到单条消息)
|
|
37
|
+
trigger_message_id: om_xxxxxxxx # 触发那条消息的 ID(不可点,但唯一绑定该消息,必带;用于程序回读/去重/兜底)
|
|
38
|
+
thread_root_id: om_yyyyyyyy # (可选)话题根消息 ID
|
|
39
|
+
participants: # 参与者:显示名 + open_id + 角色
|
|
40
|
+
- name: 张斯佳, open_id: ou_aaa, role: 讨论
|
|
41
|
+
- name: 张瑶, open_id: ou_bbb, role: 讨论
|
|
42
|
+
- name: 刘俊平, open_id: ou_ccc, role: 确认
|
|
43
|
+
transcript: | # 相关消息原文(按时间)—— 人真正要看的内容,必带
|
|
44
|
+
17:49 张斯佳:有线下核验点,但无可预约时间,这里需要加提示么?
|
|
45
|
+
17:5x 张瑶:建议合并提示语「目前暂无线下审核点或没有可预约的时间…」
|
|
46
|
+
17:5x 刘俊平:可以处理
|
|
47
|
+
summary: 线下核验点无可预约时间,确认合并提示语后处理 # (可选)一句话结论;缺省时由模型从 transcript 推
|
|
48
|
+
</task-source>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Roles are not required to be pre-computed by the bridge — if `role` is missing,
|
|
52
|
+
infer it from the `transcript` (谁提出 / 谁讨论 / 谁拍板"可以处理"). If a
|
|
53
|
+
`summary` is absent, derive it from the `transcript`.
|
|
54
|
+
|
|
55
|
+
**Feishu reality** — `chat_link` only opens the **group**, not a single message.
|
|
56
|
+
So the practical "go back and find it" combo is **群链接 + occurred_at + transcript**:
|
|
57
|
+
open the group, jump to that time, the transcript is the actual content. Label the
|
|
58
|
+
link line **打开群** (never "原始消息") so nobody expects a one-click jump to the
|
|
59
|
+
exact message. `trigger_message_id` is kept as the only hard anchor to that
|
|
60
|
+
message (not clickable — for programmatic re-read / dedup / fallback).
|
|
61
|
+
|
|
62
|
+
## Rendered `## 来源` format
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
## 来源
|
|
66
|
+
|
|
67
|
+
- 渠道:飞书群「{chat_name}」
|
|
68
|
+
- 时间:{occurred_at}
|
|
69
|
+
- 参与者:{讨论者们}(讨论),{确认者}(确认可处理)
|
|
70
|
+
- 讨论要点:{summary}
|
|
71
|
+
- 打开群:{chat_link}
|
|
72
|
+
- 溯源 ID:chat={chat_id} · msg={trigger_message_id}{ thread_root_id 时追加 · thread={thread_root_id}}
|
|
73
|
+
|
|
74
|
+
讨论摘录(按时间):
|
|
75
|
+
{transcript}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Only render lines whose data is present (e.g. omit `打开群` if there is no
|
|
79
|
+
`chat_link`). Always keep `chat_id` + `trigger_message_id` (hard anchors) and the
|
|
80
|
+
`讨论摘录`/`transcript` (the content humans actually read).
|