@baique/pi-web-sky 0.1.39 → 0.1.40
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/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +9 -14
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/react-loadable-manifest.json +51 -51
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +3 -45
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +3 -3
- package/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/agent/[id]/bash-output/route.js +2 -2
- package/.next/server/app/api/agent/[id]/events/route.js +2 -2
- package/.next/server/app/api/agent/[id]/route.js +2 -2
- package/.next/server/app/api/agent/new/route.js +1 -1
- package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/running/route.js +1 -1
- package/.next/server/app/api/app-update/route.js +1 -1
- package/.next/server/app/api/auth/all-providers/route.js +1 -1
- package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
- package/.next/server/app/api/auth/providers/route.js +1 -1
- package/.next/server/app/api/boards/[id]/reconcile/route.js +1 -0
- package/.next/server/app/api/boards/[id]/reconcile/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/boards/[id]/route.js +1 -1
- package/.next/server/app/api/boards/purge-orphans/route.js +1 -1
- package/.next/server/app/api/boards/reorder/route.js +1 -1
- package/.next/server/app/api/boards/route.js +1 -1
- package/.next/server/app/api/cwd/browse/route.js +1 -1
- package/.next/server/app/api/cwd/validate/route.js +2 -2
- package/.next/server/app/api/default-cwd/route.js +2 -2
- package/.next/server/app/api/file-index/route.js +2 -2
- package/.next/server/app/api/files/[...path]/route.js +3 -3
- package/.next/server/app/api/files/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/git/diff/route.js +1 -1
- package/.next/server/app/api/git/status/route.js +1 -1
- package/.next/server/app/api/home/route.js +1 -1
- package/.next/server/app/api/mcp/route.js +1 -1
- package/.next/server/app/api/models/route.js +2 -2
- package/.next/server/app/api/models-config/catalog/route.js +1 -1
- package/.next/server/app/api/models-config/discover/route.js +1 -1
- package/.next/server/app/api/models-config/route.js +1 -1
- package/.next/server/app/api/models-config/test/route.js +1 -1
- package/.next/server/app/api/plugins/route.js +2 -2
- package/.next/server/app/api/project-trust/route.js +2 -2
- package/.next/server/app/api/quota/route.js +1 -1
- package/.next/server/app/api/search/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/auto-name/route.js +3 -3
- package/.next/server/app/api/sessions/[id]/context/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/export/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/state/route.js +2 -2
- package/.next/server/app/api/sessions/[id]/todos/route.js +2 -2
- package/.next/server/app/api/sessions/route.js +2 -2
- package/.next/server/app/api/skills/check/route.js +1 -1
- package/.next/server/app/api/skills/install/route.js +2 -2
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/search/route.js +1 -1
- package/.next/server/app/api/skills/update/route.js +1 -1
- package/.next/server/app/api/task-card-questions/[id]/answer/route.js +1 -1
- package/.next/server/app/api/task-card-questions/route.js +1 -1
- package/.next/server/app/api/task-cards/[id]/route.js +1 -1
- package/.next/server/app/api/task-cards/route.js +1 -1
- package/.next/server/app/api/task-scheduler/status/route.js +1 -1
- package/.next/server/app/api/tasks/[id]/board/route.js +1 -1
- package/.next/server/app/api/tasks/[id]/route.js +1 -1
- package/.next/server/app/api/tasks/reorder/route.js +1 -1
- package/.next/server/app/api/tasks/route.js +1 -1
- package/.next/server/app/api/terminal/[id]/events/route.js +2 -2
- package/.next/server/app/api/terminal/[id]/route.js +2 -2
- package/.next/server/app/api/terminal/route.js +2 -2
- package/.next/server/app/api/worktrees/route.js +2 -2
- package/.next/server/app/favicon.ico/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +5 -5
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +5 -5
- package/.next/server/app/index.segments/_full.segment.rsc +5 -5
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/.next/server/app/page.js +7 -7
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +9 -14
- package/.next/server/chunks/1094.js +2 -2
- package/.next/server/chunks/1601.js +1 -1
- package/.next/server/chunks/1860.js +1 -1
- package/.next/server/chunks/2075.js +1 -1
- package/.next/server/chunks/2169.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2524.js +1 -0
- package/.next/server/chunks/3012.js +1 -1
- package/.next/server/chunks/{5760.js → 3379.js} +1 -1
- package/.next/server/chunks/3500.js +1 -1
- package/.next/server/chunks/4226.js +5 -2
- package/.next/server/chunks/4267.js +1 -1
- package/.next/server/chunks/4563.js +1 -1
- package/.next/server/chunks/5318.js +1 -1
- package/.next/server/chunks/542.js +3 -44
- package/.next/server/chunks/5794.js +1 -1
- package/.next/server/chunks/6052.js +1 -1
- package/.next/server/chunks/6253.js +1 -1
- package/.next/server/chunks/6288.js +1 -1
- package/.next/server/chunks/6366.js +1 -1
- package/.next/server/chunks/673.js +1 -1
- package/.next/server/chunks/6916.js +2 -2
- package/.next/server/chunks/7128.js +43 -0
- package/.next/server/chunks/7265.js +2 -2
- package/.next/server/chunks/7799.js +1 -1
- package/.next/server/chunks/8106.js +1 -1
- package/.next/server/chunks/8333.js +1 -1
- package/.next/server/chunks/8604.js +1 -1
- package/.next/server/chunks/861.js +1 -0
- package/.next/server/chunks/8713.js +1 -1
- package/.next/server/chunks/8782.js +2 -2
- package/.next/server/chunks/898.js +1 -1
- package/.next/server/chunks/922.js +2 -2
- package/.next/server/chunks/9280.js +6 -6
- package/.next/server/chunks/9510.js +1 -1
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{103.23142a67b02246a8.js → 103.6c91a059aa01d92c.js} +2 -2
- package/.next/static/chunks/{1032.12b382a9096ab2a4.js → 1032.9e8f793d46f463f8.js} +1 -1
- package/.next/static/chunks/{1063.775c442bdbeef08b.js → 1063.470df8a037dc8409.js} +1 -1
- package/.next/static/chunks/1a258343.f4fc2c133917ded8.js +2 -0
- package/.next/static/chunks/{1ba63609.b2ae90f43319a29e.js → 1ba63609.569928c7234f832c.js} +1 -1
- package/.next/static/chunks/{2181.ba21239d3ac39f81.js → 2181.b8dda21843ef5e74.js} +1 -1
- package/.next/static/chunks/{2325.23caf22075e51aa5.js → 2325.23e538886331cf64.js} +1 -1
- package/.next/static/chunks/{2356.523277bb8c6bf72a.js → 2356.b7312589c345edec.js} +1 -1
- package/.next/static/chunks/{268.72794ee2773c2060.js → 268.a1d90aca268be18a.js} +1 -1
- package/.next/static/chunks/{2695.6f49435bae1e6f33.js → 2695.5624aa3aae540e87.js} +1 -1
- package/.next/static/chunks/{2703.495a65ed14b2f094.js → 2703.097bc88286733740.js} +1 -1
- package/.next/static/chunks/{2821.934bcf60fbdc28c6.js → 2821.d2392a93d192fe92.js} +1 -1
- package/.next/static/chunks/3308.2cd6f20e6c0f4e92.js +73 -0
- package/.next/static/chunks/{3336.a76f9485fe7cb762.js → 3336.9b1dc9ec3507d64f.js} +1 -1
- package/.next/static/chunks/3546.779d2c7646aa77cc.js +1 -0
- package/.next/static/chunks/{370.8e8f3cf8eb0e29dd.js → 370.cde2a84caa84054f.js} +1 -1
- package/.next/static/chunks/{3716.72bf4c9d7325debd.js → 3716.5bac496cea32ca8f.js} +1 -1
- package/.next/static/chunks/{3995.eca0f5bef1fc3ae5.js → 3995.cd112debcd64c610.js} +1 -1
- package/.next/static/chunks/{4004.74b9bcf5478b1663.js → 4004.a8f79ef62f32aa30.js} +2 -2
- package/.next/static/chunks/{4202.8440832386f023c7.js → 4202.96f5b1beb8b3e3f5.js} +1 -1
- package/.next/static/chunks/{4238.6f102dcbcf2ae339.js → 4238.28efbf9aa0c82d90.js} +1 -1
- package/.next/static/chunks/{4405.7a19458960a1058e.js → 4405.cda46a596a02aef7.js} +1 -1
- package/.next/static/chunks/54a60aa6.5e4421e7afde4de8.js +78 -0
- package/.next/static/chunks/{6121.eb9023b1cbc78ee2.js → 6121.5e650e714b402b6f.js} +1 -1
- package/.next/static/chunks/{6195.1153369f5f8b13a2.js → 6195.1b7f9dc127381bbc.js} +1 -1
- package/.next/static/chunks/6380.d148a8e2c701ad78.js +68 -0
- package/.next/static/chunks/6582.efef0ed269bacae2.js +1 -0
- package/.next/static/chunks/6be7e44c.00d0163f409986f0.js +1 -0
- package/.next/static/chunks/{7331.2add3c4e125a2dba.js → 7331.4afa66d6353c8e07.js} +1 -1
- package/.next/static/chunks/752.f41a9dcb0e6548eb.js +1 -0
- package/.next/static/chunks/{8200.a36b9f8c983c6b9e.js → 8200.350d650649b977eb.js} +1 -1
- package/.next/static/chunks/{8885.cf60cac98bf8b70c.js → 8885.2c060cb45c85547b.js} +1 -1
- package/.next/static/chunks/{918.6a9bbe564e4a2d0f.js → 918.593eb466d35cb8ad.js} +1 -1
- package/.next/static/chunks/{9698.4d09a99b9d99f3e5.js → 9698.758755d0387e0e22.js} +2 -2
- package/.next/static/chunks/97.fb73c551e14b3612.js +2 -0
- package/.next/static/chunks/{993e5495.8797001fcfcf2889.js → 993e5495.12cdfbc3af5c79e9.js} +1 -1
- package/.next/static/chunks/{9974.9a0f79beca65e8c4.js → 9974.5ee982e074ad047e.js} +1 -1
- package/.next/static/chunks/app/_global-error/page-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/agent/running/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/app-update/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/auth/all-providers/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/auth/login/[provider]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/auth/providers/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/boards/[id]/reconcile/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/boards/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/boards/purge-orphans/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/boards/reorder/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/boards/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/cwd/browse/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/cwd/validate/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/default-cwd/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/file-index/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/files/[...path]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/git/diff/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/git/status/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/home/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/mcp/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/models/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/models-config/catalog/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/models-config/discover/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/models-config/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/models-config/test/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/project-trust/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/quota/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/search/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/context/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/state/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/todos/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/skills/check/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/skills/install/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/skills/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/skills/search/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/skills/update/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/task-card-questions/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/task-cards/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/task-cards/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/task-scheduler/status/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/tasks/[id]/board/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/tasks/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/tasks/reorder/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/tasks/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/terminal/[id]/events/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/terminal/[id]/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/terminal/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/{layout-7761e430ed68b347.js → layout-702d3c97d297c42d.js} +1 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/app/page-fd18462c3c937a50.js +89 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-bb8f79f321e26750.js +1 -0
- package/.next/static/chunks/webpack-d17b4dde91b96c63.js +1 -0
- package/.next/static/css/0c7244f7214af81f.css +1 -0
- package/.next/static/css/12456255969ac8de.css +31 -0
- package/.next/trace +43 -49
- package/.next/trace-build +1 -1
- package/.next/types/app/api/boards/[id]/{reconcile-task-edges → reconcile}/route.ts +3 -3
- package/.next/types/routes.d.ts +2 -7
- package/.next/types/validator.ts +3 -48
- package/README.md +6 -9
- package/THIRD_PARTY_NOTICES.md +10 -82
- package/bin/pi-web-sky.js +3 -3
- package/lib/board-reconcile-scheduler.ts +56 -0
- package/lib/board-reconcile.test.mjs +252 -0
- package/lib/board-reconcile.ts +422 -0
- package/lib/board-store.test.mjs +26 -4
- package/lib/board-store.ts +44 -6
- package/lib/i18n/messages/en.ts +1 -1
- package/lib/i18n/messages/zh-CN.ts +1 -1
- package/lib/session-delete.ts +5 -0
- package/lib/sqlite-db.ts +13 -1
- package/lib/task-card-store.ts +26 -1
- package/lib/task-scheduler.test.mjs +79 -0
- package/lib/task-scheduler.ts +195 -21
- package/lib/yjs-room-server.mjs +139 -0
- package/package.json +12 -9
- package/server.mjs +7 -7
- package/.next/server/app/api/boards/[id]/canvas/route.js +0 -1
- package/.next/server/app/api/boards/[id]/canvas/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/boards/[id]/edges/[eid]/route.js +0 -1
- package/.next/server/app/api/boards/[id]/edges/[eid]/route.js.nft.json +0 -1
- package/.next/server/app/api/boards/[id]/edges/[eid]/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/boards/[id]/edges/route.js +0 -1
- package/.next/server/app/api/boards/[id]/edges/route.js.nft.json +0 -1
- package/.next/server/app/api/boards/[id]/edges/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/boards/[id]/nodes/[nid]/route.js +0 -1
- package/.next/server/app/api/boards/[id]/nodes/[nid]/route.js.nft.json +0 -1
- package/.next/server/app/api/boards/[id]/nodes/[nid]/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/boards/[id]/nodes/route.js +0 -1
- package/.next/server/app/api/boards/[id]/nodes/route.js.nft.json +0 -1
- package/.next/server/app/api/boards/[id]/nodes/route_client-reference-manifest.js +0 -1
- package/.next/server/app/api/boards/[id]/reconcile-task-edges/route.js +0 -1
- package/.next/server/app/api/boards/[id]/reconcile-task-edges/route.js.nft.json +0 -1
- package/.next/server/app/api/boards/[id]/reconcile-task-edges/route_client-reference-manifest.js +0 -1
- package/.next/static/chunks/3308.857c554428b3294e.js +0 -73
- package/.next/static/chunks/333.bf0651c789b2eb33.js +0 -1
- package/.next/static/chunks/5315.dba7515ae6e139ae.js +0 -4
- package/.next/static/chunks/54a60aa6.0e43cde7298ebcb7.js +0 -78
- package/.next/static/chunks/7999.879d5a20e8641752.js +0 -259
- package/.next/static/chunks/app/_global-error/page-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/bash-output/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/events/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/agent/new/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/agent/running/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/app-update/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/auth/all-providers/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/auth/api-key/[provider]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/auth/login/[provider]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/[provider]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/auth/providers/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/canvas/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/edges/[eid]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/edges/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/nodes/[nid]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/nodes/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/reconcile-task-edges/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/purge-orphans/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/reorder/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/boards/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/cwd/browse/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/cwd/validate/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/default-cwd/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/file-index/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/files/[...path]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/git/diff/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/git/status/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/home/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/mcp/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/models/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/models-config/catalog/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/models-config/discover/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/models-config/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/models-config/test/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/plugins/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/project-trust/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/quota/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/search/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/context/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/export/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/state/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/todos/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/skills/check/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/skills/install/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/skills/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/skills/search/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/skills/update/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/task-card-questions/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/task-cards/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/task-cards/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/task-scheduler/status/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/tasks/[id]/board/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/tasks/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/tasks/reorder/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/tasks/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/terminal/[id]/events/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/terminal/[id]/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/terminal/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/app/page-2c87c41e7f848f45.js +0 -89
- package/.next/static/chunks/e3e7ddb2.a35db430b3564999.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d6f52627eddf9119.js +0 -1
- package/.next/static/chunks/webpack-4bbf04891e910713.js +0 -1
- package/.next/static/css/80c818c5781fbadc.css +0 -4
- package/.next/static/css/d3a2b5077b52c727.css +0 -1
- package/.next/types/app/api/boards/[id]/canvas/route.ts +0 -353
- package/.next/types/app/api/boards/[id]/edges/[eid]/route.ts +0 -353
- package/.next/types/app/api/boards/[id]/edges/route.ts +0 -353
- package/.next/types/app/api/boards/[id]/nodes/[nid]/route.ts +0 -353
- package/.next/types/app/api/boards/[id]/nodes/route.ts +0 -353
- package/lib/board-search.test.mjs +0 -110
- package/lib/board-search.ts +0 -63
- package/lib/file-explorer-state.test.mjs +0 -63
- package/lib/file-explorer-state.ts +0 -36
- package/lib/sync-room-server.mjs +0 -137
- /package/.next/server/app/api/boards/[id]/{canvas → reconcile}/route.js.nft.json +0 -0
- /package/.next/static/{IzmOG04jJst1VpUvr_fr5 → 12RFLqhiUZG8Sj49T1KKQ}/_buildManifest.js +0 -0
- /package/.next/static/{IzmOG04jJst1VpUvr_fr5 → 12RFLqhiUZG8Sj49T1KKQ}/_ssgManifest.js +0 -0
package/.next/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-webpack","duration":
|
|
1
|
+
[{"name":"run-webpack","duration":35372491,"timestamp":96021475118,"id":14,"parentId":1,"tags":{},"startTime":1788410688527,"traceId":"f629955da06ea8af"},{"name":"run-typescript","duration":15126563,"timestamp":96056851726,"id":8709,"parentId":1,"tags":{},"startTime":1788410723903,"traceId":"f629955da06ea8af"},{"name":"static-check","duration":2933639,"timestamp":96072041613,"id":8712,"parentId":1,"tags":{},"startTime":1788410739093,"traceId":"f629955da06ea8af"},{"name":"static-generation","duration":4915470,"timestamp":96075314418,"id":8848,"parentId":1,"tags":{},"startTime":1788410742366,"traceId":"f629955da06ea8af"},{"name":"collect-build-traces","duration":47224994,"timestamp":96074977893,"id":8845,"parentId":1,"tags":{},"startTime":1788410742030,"traceId":"f629955da06ea8af"},{"name":"telemetry-flush","duration":41,"timestamp":96122206243,"id":8857,"parentId":1,"tags":{},"startTime":1788410789258,"traceId":"f629955da06ea8af"},{"name":"next-build","duration":100852409,"timestamp":96021353882,"id":1,"tags":{"buildMode":"default","version":"16.3.1","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1788410688406,"traceId":"f629955da06ea8af"}]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
// File: /home/wa/project/pi-web-sky/app/api/boards/[id]/reconcile
|
|
2
|
-
import * as entry from '../../../../../../../app/api/boards/[id]/reconcile
|
|
1
|
+
// File: /home/wa/project/pi-web-sky/app/api/boards/[id]/reconcile/route.ts
|
|
2
|
+
import * as entry from '../../../../../../../app/api/boards/[id]/reconcile/route.js'
|
|
3
3
|
import type { NextRequest } from 'next/server.js'
|
|
4
4
|
|
|
5
5
|
import type { InstantConfigForTypeCheckInternal, Prefetch } from 'next/dist/build/segment-config/app/app-segment-config.js'
|
|
6
6
|
|
|
7
|
-
type TEntry = typeof import('../../../../../../../app/api/boards/[id]/reconcile
|
|
7
|
+
type TEntry = typeof import('../../../../../../../app/api/boards/[id]/reconcile/route.js')
|
|
8
8
|
|
|
9
9
|
type SegmentParams<T extends Object = any> = T extends Record<string, any>
|
|
10
10
|
? { [K in keyof T]: T[K] extends string ? string | string[] | undefined : never }
|
package/.next/types/routes.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Do not edit this file manually
|
|
3
3
|
|
|
4
4
|
type AppRoutes = "/"
|
|
5
|
-
type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/bash-output" | "/api/agent/[id]/events" | "/api/agent/new" | "/api/agent/running" | "/api/app-update" | "/api/auth/all-providers" | "/api/auth/api-key/[provider]" | "/api/auth/login/[provider]" | "/api/auth/logout/[provider]" | "/api/auth/providers" | "/api/boards" | "/api/boards/[id]" | "/api/boards/[id]/
|
|
5
|
+
type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/bash-output" | "/api/agent/[id]/events" | "/api/agent/new" | "/api/agent/running" | "/api/app-update" | "/api/auth/all-providers" | "/api/auth/api-key/[provider]" | "/api/auth/login/[provider]" | "/api/auth/logout/[provider]" | "/api/auth/providers" | "/api/boards" | "/api/boards/[id]" | "/api/boards/[id]/reconcile" | "/api/boards/purge-orphans" | "/api/boards/reorder" | "/api/cwd/browse" | "/api/cwd/validate" | "/api/default-cwd" | "/api/file-index" | "/api/files/[...path]" | "/api/git/diff" | "/api/git/status" | "/api/home" | "/api/mcp" | "/api/models" | "/api/models-config" | "/api/models-config/catalog" | "/api/models-config/discover" | "/api/models-config/test" | "/api/plugins" | "/api/project-trust" | "/api/quota" | "/api/search" | "/api/sessions" | "/api/sessions/[id]" | "/api/sessions/[id]/auto-name" | "/api/sessions/[id]/context" | "/api/sessions/[id]/entries/[entryId]/thinking" | "/api/sessions/[id]/export" | "/api/sessions/[id]/state" | "/api/sessions/[id]/todos" | "/api/skills" | "/api/skills/check" | "/api/skills/install" | "/api/skills/search" | "/api/skills/update" | "/api/task-card-questions" | "/api/task-card-questions/[id]/answer" | "/api/task-cards" | "/api/task-cards/[id]" | "/api/task-scheduler/status" | "/api/tasks" | "/api/tasks/[id]" | "/api/tasks/[id]/board" | "/api/tasks/reorder" | "/api/terminal" | "/api/terminal/[id]" | "/api/terminal/[id]/events" | "/api/worktrees"
|
|
6
6
|
type PageRoutes = never
|
|
7
7
|
type LayoutRoutes = "/"
|
|
8
8
|
type RedirectRoutes = never
|
|
@@ -25,12 +25,7 @@ interface ParamMap {
|
|
|
25
25
|
"/api/auth/providers": {}
|
|
26
26
|
"/api/boards": {}
|
|
27
27
|
"/api/boards/[id]": { "id": string; }
|
|
28
|
-
"/api/boards/[id]/
|
|
29
|
-
"/api/boards/[id]/edges": { "id": string; }
|
|
30
|
-
"/api/boards/[id]/edges/[eid]": { "id": string; "eid": string; }
|
|
31
|
-
"/api/boards/[id]/nodes": { "id": string; }
|
|
32
|
-
"/api/boards/[id]/nodes/[nid]": { "id": string; "nid": string; }
|
|
33
|
-
"/api/boards/[id]/reconcile-task-edges": { "id": string; }
|
|
28
|
+
"/api/boards/[id]/reconcile": { "id": string; }
|
|
34
29
|
"/api/boards/purge-orphans": {}
|
|
35
30
|
"/api/boards/reorder": {}
|
|
36
31
|
"/api/cwd/browse": {}
|
package/.next/types/validator.ts
CHANGED
|
@@ -155,55 +155,10 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
|
|
|
155
155
|
type __Unused = __Check
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
// Validate ../../app/api/boards/[id]/
|
|
158
|
+
// Validate ../../app/api/boards/[id]/reconcile/route.ts
|
|
159
159
|
{
|
|
160
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/
|
|
161
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/
|
|
162
|
-
type __Check = __IsExpected<typeof handler>
|
|
163
|
-
// @ts-ignore
|
|
164
|
-
type __Unused = __Check
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Validate ../../app/api/boards/[id]/edges/[eid]/route.ts
|
|
168
|
-
{
|
|
169
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/edges/[eid]">> = Specific
|
|
170
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/edges/[eid]/route.js")
|
|
171
|
-
type __Check = __IsExpected<typeof handler>
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
type __Unused = __Check
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Validate ../../app/api/boards/[id]/edges/route.ts
|
|
177
|
-
{
|
|
178
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/edges">> = Specific
|
|
179
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/edges/route.js")
|
|
180
|
-
type __Check = __IsExpected<typeof handler>
|
|
181
|
-
// @ts-ignore
|
|
182
|
-
type __Unused = __Check
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Validate ../../app/api/boards/[id]/nodes/[nid]/route.ts
|
|
186
|
-
{
|
|
187
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/nodes/[nid]">> = Specific
|
|
188
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/nodes/[nid]/route.js")
|
|
189
|
-
type __Check = __IsExpected<typeof handler>
|
|
190
|
-
// @ts-ignore
|
|
191
|
-
type __Unused = __Check
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Validate ../../app/api/boards/[id]/nodes/route.ts
|
|
195
|
-
{
|
|
196
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/nodes">> = Specific
|
|
197
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/nodes/route.js")
|
|
198
|
-
type __Check = __IsExpected<typeof handler>
|
|
199
|
-
// @ts-ignore
|
|
200
|
-
type __Unused = __Check
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Validate ../../app/api/boards/[id]/reconcile-task-edges/route.ts
|
|
204
|
-
{
|
|
205
|
-
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/reconcile-task-edges">> = Specific
|
|
206
|
-
const handler = {} as typeof import("../../app/api/boards/[id]/reconcile-task-edges/route.js")
|
|
160
|
+
type __IsExpected<Specific extends RouteHandlerConfig<"/api/boards/[id]/reconcile">> = Specific
|
|
161
|
+
const handler = {} as typeof import("../../app/api/boards/[id]/reconcile/route.js")
|
|
207
162
|
type __Check = __IsExpected<typeof handler>
|
|
208
163
|
// @ts-ignore
|
|
209
164
|
type __Unused = __Check
|
package/README.md
CHANGED
|
@@ -52,6 +52,8 @@ pi-web-sky
|
|
|
52
52
|
- **卡片即工作台**:收合卡显示状态/标题/最后回复,展开卡直接在画布上聊天、看状态、盯统计,展开后仍可拖动、拉伸、连线。
|
|
53
53
|
- **实时状态**:卡片实时显示思考中/执行工具/等待输入(思考球动效);「运行中」看板自动聚合所有正在运行的任务,跨项目一眼看全。
|
|
54
54
|
- **便笺**:随手贴 markdown 便笺,支持颜色与代码块。
|
|
55
|
+
- **派生边**:画布自动绘制连线——会话执行线(虚线,卡到会话)与任务依赖线(实线),随业务状态自动增删,无需手绘。
|
|
56
|
+
- **右键菜单**:卡片/空白处右键弹出玻璃菜单(新建会话、便笺、删除、连线等),删除按节点类型做二次确认。
|
|
55
57
|
- **画布打磨**:缩放/平移/吸附对齐、重叠卡片点击置顶、Ctrl+F 定位节点、看板 URL 持久化,刷新后停在原地。
|
|
56
58
|
|
|
57
59
|
### 内置多会话终端
|
|
@@ -100,13 +102,8 @@ npm test # 单元测试
|
|
|
100
102
|
|
|
101
103
|
本项目代码以 [MIT](./LICENSE) 协议发布。
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
会话看板(画布)自研实现:渲染层基于 [@xyflow/react](https://reactflow.dev)(MIT),
|
|
106
|
+
数据层基于 [yjs](https://yjs.dev)(MIT CRDT)+ [Hocuspocus](https://tiptap.dev/docs/hocuspocus)(MIT)协同服务端,
|
|
107
|
+
均为宽松许可,与 MIT 主协议兼容,无商用限制。
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
- 非商用项目可申请免费 **hobby license**(画布显示 "made with tldraw" 水印);
|
|
108
|
-
- 商用项目须购买 **commercial license**(100 天免费 trial 可用于评估)。
|
|
109
|
-
- 本项目自带功能与自身代码仍为 MIT;tldraw 代码须保持其原许可证,不能被重新声明为 MIT。
|
|
110
|
-
- 本项目的 MIT 许可**不涵盖** tldraw;在非开发环境使用看板功能,请自行向 tldraw 申请相应许可。
|
|
111
|
-
|
|
112
|
-
第三方依赖许可明细见 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)(含 tldraw License 原文)。
|
|
109
|
+
第三方依赖许可明细见 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)。
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,93 +1,21 @@
|
|
|
1
1
|
# Third-Party Notices
|
|
2
2
|
|
|
3
3
|
本发行版(`@baique/pi-web-sky`)自身代码以 MIT 协议发布(见 [LICENSE](./LICENSE)),
|
|
4
|
-
|
|
4
|
+
依赖的第三方组件均为宽松许可(MIT / Apache-2.0 / BSD-2-Clause 等),与 MIT 主协议兼容。
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 画布依赖(会话看板 / 任务即看板)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
| 组件 | 版本 | 许可 | 用途 |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| @xyflow/react | 12.11.6 | MIT | 看板画布渲染(无限画布 / 节点 / 连线) |
|
|
13
|
+
| yjs | 13.6.32 | MIT | 画布文档 CRDT 协同(每看板一个 Y.Doc) |
|
|
14
|
+
| @hocuspocus/server | 4.6.0 | MIT | yjs 协同服务端(WebSocket 房间 + SQLite 持久化) |
|
|
15
|
+
| @hocuspocus/provider | 4.6.0 | MIT | yjs 协同客户端(前端连接) |
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- 非商用项目可申请免费 **hobby license**(画布显示 "made with tldraw" 水印);
|
|
15
|
-
- 商用项目须购买 **commercial license**(100 天免费 trial 可用于评估);
|
|
16
|
-
- tldraw SDK 不能被声明为 MIT 或任何更宽松的开源协议,其代码须保持原许可证。
|
|
17
|
-
- 按 tldraw License 要求,分发本软件时须附 tldraw License 原文,全文如下。
|
|
18
|
-
|
|
19
|
-
### tldraw license(原文)
|
|
20
|
-
|
|
21
|
-
> # tldraw license
|
|
22
|
-
>
|
|
23
|
-
> This License from tldraw, Inc. ("tldraw") governs your use of the accompanying Software. By using the Software, you accept the terms of this License. The tldraw software is copyrighted by tldraw Inc.
|
|
24
|
-
>
|
|
25
|
-
> Alternative licenses are available from tldraw for commercial and non-commercial use. To get an alternative license or to learn more, visit https://tldraw.dev or contact sales@tldraw.com.
|
|
26
|
-
>
|
|
27
|
-
> ## Definitions
|
|
28
|
-
>
|
|
29
|
-
> "Production Environment" means any production deployment of the Software that operates on servers, cloud platforms, web applications, or where the software is used to provide functionality to end users, customers, or the public. Production Environment excludes internal development.
|
|
30
|
-
>
|
|
31
|
-
> "Development Environment" means any internal hosting or deployment of the Software for development, testing, or staging purposes, operated by your organization and not accessible to end users, customers, or the public.
|
|
32
|
-
>
|
|
33
|
-
> "License Key" means the programmatically generated key that controls Software functionality and usage restrictions.
|
|
34
|
-
>
|
|
35
|
-
> ## Permissions
|
|
36
|
-
>
|
|
37
|
-
> Subject to the following conditions, you are permitted to:
|
|
38
|
-
>
|
|
39
|
-
> - Use the Software in Development Environments.
|
|
40
|
-
> - Modify the Software to suit your needs.
|
|
41
|
-
> - Bundle the Software with your own projects.
|
|
42
|
-
> - Submit modifications of the Software to tldraw.
|
|
43
|
-
>
|
|
44
|
-
> ## Conditions
|
|
45
|
-
>
|
|
46
|
-
> In exchange for these permissions, you agree:
|
|
47
|
-
>
|
|
48
|
-
> - Not to use the Software in Production Environments.
|
|
49
|
-
> - Not to disable, change, or interfere with the Software's License Key enforcement.
|
|
50
|
-
> - Not to remove any copyright or other notices from the Software.
|
|
51
|
-
> - Not to make the Software available under a license that supersedes or negates the effect of this License.
|
|
52
|
-
> - Not to distribute the Software or modifications of the Software as a standalone product, but only as part of another application.
|
|
53
|
-
> - To include a verbatim copy of this License in any distribution of the Software.
|
|
54
|
-
> - To comply with tldraw's trademark policy.
|
|
55
|
-
>
|
|
56
|
-
> ## Trial license
|
|
57
|
-
>
|
|
58
|
-
> In the case that tldraw makes the Software available to you on a trial basis, you are permitted to use the Software in Production Environments for the specified period beginning from the date of the trial's License Key issuance. Business units are limited to one trial period unless otherwise approved by tldraw in writing.
|
|
59
|
-
>
|
|
60
|
-
> ## Commercial license
|
|
61
|
-
>
|
|
62
|
-
> In the case that tldraw makes the Software available to you under the terms of a separate commercial agreement, you are permitted to use the Software in Production Environments for the specified period beginning from the date of the agreement's License Key issuance.
|
|
63
|
-
>
|
|
64
|
-
> ## Termination
|
|
65
|
-
>
|
|
66
|
-
> Your license to use the Software will terminate automatically if you breach any terms of this License or initiate a copyright, trade secret, or patent claim against tldraw, any of its affiliates, or any user of the Software (including as modified by you).
|
|
67
|
-
>
|
|
68
|
-
> ## Technical enforcement
|
|
69
|
-
>
|
|
70
|
-
> The Software includes technical measures to verify License Key validity, detect deployment environments, enforce usage restrictions based on license type, and ensure proper watermark display. The Software may collect and transmit usage data to tldraw for license compliance purposes.
|
|
71
|
-
>
|
|
72
|
-
> ## Ownership of intellectual property
|
|
73
|
-
>
|
|
74
|
-
> tldraw retains all right, title, and interest in the Software, including all intellectual property rights therein. This Agreement grants you only the specific, limited rights expressly set forth herein, and tldraw reserves all rights not expressly granted.
|
|
75
|
-
>
|
|
76
|
-
> ## Disclaimer of warranties
|
|
77
|
-
>
|
|
78
|
-
> The Software is provided "AS IS," without any warranties. This includes any implied warranties of merchantability, fitness for a particular purpose, or non-infringement. You must pass this disclaimer on whenever you distribute the Software or derivative works.
|
|
79
|
-
>
|
|
80
|
-
> ## Limitation of liability
|
|
81
|
-
>
|
|
82
|
-
> tldraw is not liable for any damages related to the Software or this License, including direct, indirect, special, or incidental damages, to the fullest extent permitted by law. You must pass this limitation of liability on whenever you distribute the Software or derivative works.
|
|
83
|
-
>
|
|
84
|
-
> ## Governing law
|
|
85
|
-
>
|
|
86
|
-
> This License is governed by the laws of Delaware, and the parties consent to exclusive jurisdiction in Delaware courts. The parties waive all defenses of lack of personal jurisdiction and forum non-conveniens.
|
|
87
|
-
>
|
|
88
|
-
> ## Entire agreement / assignment
|
|
89
|
-
>
|
|
90
|
-
> This License is the entire agreement between the parties, and supersedes any and all prior agreements, understandings or communications, written or oral, between the parties relating to the subject matter hereof. This License may be assigned by tldraw without your prior consent.
|
|
17
|
+
> 说明:历史版本依赖 tldraw SDK(source-available 自有许可)实现画布,已在本版移除,
|
|
18
|
+
> 改用上述 MIT 组件完全自研画布数据层与渲染层。
|
|
91
19
|
|
|
92
20
|
---
|
|
93
21
|
|
package/bin/pi-web-sky.js
CHANGED
|
@@ -50,9 +50,9 @@ if (!loopbackHostnames.has(hostname)) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
// 直接跑自定义 server(server.mjs):HTTP 交 Next,WebSocket upgrade 分流到
|
|
54
|
-
//
|
|
55
|
-
//
|
|
53
|
+
// 直接跑自定义 server(server.mjs):HTTP 交 Next,WebSocket upgrade 分流到
|
|
54
|
+
// 内嵌 yjs 协同房间(/connect,每看板一个 Y.Doc)。不能只跑 `next start`——那样
|
|
55
|
+
// WS 后台不启动,看板永远 loading(0.1.35 生产 bug 根因)。
|
|
56
56
|
const child = spawn(process.execPath, [serverEntry], {
|
|
57
57
|
cwd: pkgDir,
|
|
58
58
|
stdio: ["inherit", "pipe", "inherit"],
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// 看板派生 reconcile 定时兜底调度器
|
|
3
|
+
//
|
|
4
|
+
// 目的:需求「看板实时变更,外部或本页新建的会话自动加入看板(窗口期不宜太久)」。
|
|
5
|
+
// 事件驱动(调度器派发 / assignSessionToTask / 建卡删卡)之外,周期扫描任务看板,
|
|
6
|
+
// 兜底处理事件链路遗漏的场景:
|
|
7
|
+
// - 外部进程(CLI/其他实例)直接写 session_meta 归属任务
|
|
8
|
+
// - 任务卡直接改 sessionId(绕过调度器)
|
|
9
|
+
// - 任务卡依赖变化
|
|
10
|
+
// 周期:与旧前端 reconcile 的 10s 轮询一致(窗口期不变)。
|
|
11
|
+
// ============================================================================
|
|
12
|
+
import { getDb } from "./sqlite-db";
|
|
13
|
+
import { reconcileBoard } from "./board-reconcile";
|
|
14
|
+
|
|
15
|
+
export const BOARD_RECONCILE_INTERVAL_MS = 10_000;
|
|
16
|
+
|
|
17
|
+
/** 列出全部任务看板 id(boards.task_id 非空)。 */
|
|
18
|
+
export function listTaskBoardIds(): string[] {
|
|
19
|
+
return getDb()
|
|
20
|
+
.prepare("SELECT id FROM boards WHERE task_id IS NOT NULL")
|
|
21
|
+
.all()
|
|
22
|
+
.map((r) => (r as { id: string }).id);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare global {
|
|
26
|
+
var __piBoardReconcileScheduler: { timer: ReturnType<typeof setInterval>; startedAt: number } | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 单轮:reconcile 所有任务看板。防重叠(上一轮未跑完则跳过)。 */
|
|
30
|
+
export async function runBoardReconcileTick(): Promise<void> {
|
|
31
|
+
const ids = listTaskBoardIds();
|
|
32
|
+
// 并行 reconcile(各自独立 Y.Doc,互不阻塞)
|
|
33
|
+
await Promise.all(
|
|
34
|
+
ids.map((boardId) =>
|
|
35
|
+
reconcileBoard(boardId).catch((e) => {
|
|
36
|
+
console.warn(`[board-reconcile] ${boardId} 异常:`, e?.message ?? e);
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** 启动定时兜底(instrumentation 注册;globalThis 防热重载重复启动)。 */
|
|
43
|
+
export function startBoardReconcileScheduler(): void {
|
|
44
|
+
if (globalThis.__piBoardReconcileScheduler) return;
|
|
45
|
+
let tickInFlight = false;
|
|
46
|
+
const timer = setInterval(() => {
|
|
47
|
+
if (tickInFlight) return;
|
|
48
|
+
tickInFlight = true;
|
|
49
|
+
void runBoardReconcileTick()
|
|
50
|
+
.catch((e) => console.error("[board-reconcile] tick error:", e?.message ?? e))
|
|
51
|
+
.finally(() => { tickInFlight = false; });
|
|
52
|
+
}, BOARD_RECONCILE_INTERVAL_MS);
|
|
53
|
+
timer.unref?.();
|
|
54
|
+
globalThis.__piBoardReconcileScheduler = { timer, startedAt: Date.now() };
|
|
55
|
+
console.log(`[pi-web] board reconcile scheduler started (interval ${BOARD_RECONCILE_INTERVAL_MS}ms)`);
|
|
56
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { test, beforeEach, afterEach } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { DatabaseSync } from "node:sqlite";
|
|
4
|
+
import { createJiti } from "jiti";
|
|
5
|
+
|
|
6
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true, moduleCache: false });
|
|
7
|
+
const { setDbForTesting, getDb } = await jiti.import("./sqlite-db.ts");
|
|
8
|
+
const { createTask } = await jiti.import("./task-store.ts");
|
|
9
|
+
const { getOrCreateTaskBoard } = await jiti.import("./board-store.ts");
|
|
10
|
+
const { createCard, updateCard } = await jiti.import("./task-card-store.ts");
|
|
11
|
+
const { assignSessionToTask } = await jiti.import("./task-store.ts");
|
|
12
|
+
|
|
13
|
+
const PROJECT = "proj-reconcile";
|
|
14
|
+
|
|
15
|
+
// 注入 mutateBoard mock:捕获每次事务调用(读入当前 Y 状态,执行 transaction 后
|
|
16
|
+
// 记录对 nodes/edges 的增删,模拟服务端权威写)。
|
|
17
|
+
function installYjsMock() {
|
|
18
|
+
const yjs = (globalThis).__yjsBoard ?? {};
|
|
19
|
+
const nodeSets = new Map(); // nodeId -> node obj
|
|
20
|
+
const edgeSets = new Map(); // edgeId -> edge obj
|
|
21
|
+
const mutateLog = [];
|
|
22
|
+
|
|
23
|
+
// 取与真实库同构的 mock:nodes/edges 用普通 Map 承载,transaction 内增删与
|
|
24
|
+
// reconcile 的 nodesMap/edgesMap API 一致(get/set/delete/values/Array.from)。
|
|
25
|
+
const state = { nodes: nodeSets, edges: edgeSets };
|
|
26
|
+
|
|
27
|
+
const mock = {
|
|
28
|
+
async mutateBoard(boardId, transaction) {
|
|
29
|
+
mutateLog.push(boardId);
|
|
30
|
+
const maps = {
|
|
31
|
+
nodes: {
|
|
32
|
+
get: (k) => state.nodes.get(k),
|
|
33
|
+
set: (k, v) => { state.nodes.set(k, v); },
|
|
34
|
+
delete: (k) => { state.nodes.delete(k); },
|
|
35
|
+
has: (k) => state.nodes.has(k),
|
|
36
|
+
values: () => state.nodes.values(),
|
|
37
|
+
},
|
|
38
|
+
edges: {
|
|
39
|
+
get: (k) => state.edges.get(k),
|
|
40
|
+
set: (k, v) => { state.edges.set(k, v); },
|
|
41
|
+
delete: (k) => { state.edges.delete(k); },
|
|
42
|
+
has: (k) => state.edges.has(k),
|
|
43
|
+
values: () => state.edges.values(),
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
transaction(maps, {});
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
(globalThis).__yjsBoard = mock;
|
|
50
|
+
return { nodeSets, edgeSets, mutateLog };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function cardNode(id, sid, extra) {
|
|
54
|
+
return {
|
|
55
|
+
id,
|
|
56
|
+
type: "session-card",
|
|
57
|
+
position: { x: 60, y: 60 },
|
|
58
|
+
style: { width: 340, height: 160 },
|
|
59
|
+
data: { sessionId: sid, cwd: "", ...extra },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let db;
|
|
64
|
+
let mockState;
|
|
65
|
+
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
db = new DatabaseSync(":memory:");
|
|
68
|
+
setDbForTesting(db);
|
|
69
|
+
mockState = installYjsMock();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
db.close();
|
|
74
|
+
delete (globalThis).__yjsBoard;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("窗口期 reconcile 不补同 sid 占位卡(新建会话指定 ID 场景)", async () => {
|
|
78
|
+
const task = createTask(PROJECT, "任务A");
|
|
79
|
+
const board = getOrCreateTaskBoard(task.id, PROJECT, "任务A"); // board.id = task.id
|
|
80
|
+
assert.ok(board.taskId);
|
|
81
|
+
|
|
82
|
+
// 服务端已落库(assignSessionToTask 在 /api/agent/new 中先于前端转正执行)
|
|
83
|
+
const sid = "abc-123";
|
|
84
|
+
assignSessionToTask(sid, task.id);
|
|
85
|
+
|
|
86
|
+
// 画布已存在「新建中占位卡」:cwd 非空 + sessionId = 即将创建/刚创建的会话 UUID
|
|
87
|
+
mockState.nodeSets.set("user-card-1", cardNode("user-card-1", sid, { cwd: "/proj", expanded: true }));
|
|
88
|
+
|
|
89
|
+
const { reconcileBoard } = await jiti.import("./board-reconcile.ts");
|
|
90
|
+
await reconcileBoard(board.id);
|
|
91
|
+
|
|
92
|
+
// 不补第二张卡:窗口期内 reconcile 应把占位卡当作「该 sid 已有卡」
|
|
93
|
+
const nodeIds = [...mockState.nodeSets.keys()];
|
|
94
|
+
assert.deepEqual(nodeIds, ["user-card-1"]);
|
|
95
|
+
assert.equal(mockState.nodeSets.has(`session-${sid}`), false);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("无占位卡时业务表会话正常补卡(回归,不误伤)", async () => {
|
|
99
|
+
const task = createTask(PROJECT, "任务B");
|
|
100
|
+
const board = getOrCreateTaskBoard(task.id, PROJECT, "任务B");
|
|
101
|
+
const sid = "reg-session-1";
|
|
102
|
+
assignSessionToTask(sid, task.id);
|
|
103
|
+
|
|
104
|
+
const { reconcileBoard } = await jiti.import("./board-reconcile.ts");
|
|
105
|
+
await reconcileBoard(board.id);
|
|
106
|
+
|
|
107
|
+
assert.ok(mockState.nodeSets.has(`session-${sid}`), "业务表会话无画布卡 → 应补卡");
|
|
108
|
+
const node = mockState.nodeSets.get(`session-${sid}`);
|
|
109
|
+
assert.equal(node.data.sessionId, sid);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("占位卡不影响其他会话补卡/exec 线(6461a61 语义保留)", async () => {
|
|
113
|
+
const task = createTask(PROJECT, "任务C");
|
|
114
|
+
const board = getOrCreateTaskBoard(task.id, PROJECT, "任务C");
|
|
115
|
+
|
|
116
|
+
// 一个「新建中」占位卡(sid 未落库)
|
|
117
|
+
const pendingSid = "pending-uuid";
|
|
118
|
+
mockState.nodeSets.set("pending-card", cardNode("pending-card", pendingSid, { cwd: "/x" }));
|
|
119
|
+
|
|
120
|
+
// 一个业务表真实会话 + 任务卡执行会话
|
|
121
|
+
const realSid = "real-session";
|
|
122
|
+
assignSessionToTask(realSid, task.id);
|
|
123
|
+
const execSid = "exec-session";
|
|
124
|
+
const card = createCard({ boardId: board.id, projectKey: PROJECT, name: "子任务" });
|
|
125
|
+
updateCard(card.id, { sessionId: execSid });
|
|
126
|
+
assignSessionToTask(execSid, task.id);
|
|
127
|
+
|
|
128
|
+
// 业务表会话都没有对应画布卡 → reconcile 应补齐 realSid/execSid,且建 exec 线
|
|
129
|
+
const { reconcileBoard } = await jiti.import("./board-reconcile.ts");
|
|
130
|
+
await reconcileBoard(board.id);
|
|
131
|
+
|
|
132
|
+
assert.ok(mockState.nodeSets.has(`session-${realSid}`), "真实会话应补卡");
|
|
133
|
+
assert.ok(mockState.nodeSets.has(`session-${execSid}`), "执行会话应补卡");
|
|
134
|
+
// 占位卡 sid 不在业务表 → 不应补(无对应补卡),且占位卡本身不被孤儿删(cwd 非空)
|
|
135
|
+
assert.equal(mockState.nodeSets.has(`session-${pendingSid}`), false);
|
|
136
|
+
assert.ok(mockState.nodeSets.has("pending-card"), "占位卡不被孤儿删");
|
|
137
|
+
|
|
138
|
+
// exec 线:任务卡节点 + 执行会话卡节点都补出后应建线(task-card 由 reconcile 补,节点 id = task-<cardId>)
|
|
139
|
+
const taskNode = [...mockState.nodeSets.values()].find((n) => n.type === "task-card");
|
|
140
|
+
assert.ok(taskNode, "任务卡节点应被补出");
|
|
141
|
+
const execEdge = [...mockState.edgeSets.values()].find((e) => e.data?.execLink);
|
|
142
|
+
assert.ok(execEdge, "exec 线应建立");
|
|
143
|
+
assert.equal(execEdge.source, taskNode.id);
|
|
144
|
+
assert.equal(execEdge.target, `session-${execSid}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ---- 会话删除 → yjs 画布清理(普通看板幽灵卡) ----
|
|
148
|
+
|
|
149
|
+
function installMultiBoardYjsMock() {
|
|
150
|
+
const docs = new Map(); // boardId -> { nodes: Map, edges: Map }
|
|
151
|
+
const mock = {
|
|
152
|
+
async mutateBoard(boardId, transaction) {
|
|
153
|
+
let doc = docs.get(boardId);
|
|
154
|
+
if (!doc) {
|
|
155
|
+
doc = { nodes: new Map(), edges: new Map() };
|
|
156
|
+
docs.set(boardId, doc);
|
|
157
|
+
}
|
|
158
|
+
const maps = {
|
|
159
|
+
nodes: {
|
|
160
|
+
get: (k) => doc.nodes.get(k),
|
|
161
|
+
set: (k, v) => { doc.nodes.set(k, v); },
|
|
162
|
+
delete: (k) => { doc.nodes.delete(k); },
|
|
163
|
+
has: (k) => doc.nodes.has(k),
|
|
164
|
+
values: () => doc.nodes.values(),
|
|
165
|
+
},
|
|
166
|
+
edges: {
|
|
167
|
+
get: (k) => doc.edges.get(k),
|
|
168
|
+
set: (k, v) => { doc.edges.set(k, v); },
|
|
169
|
+
delete: (k) => { doc.edges.delete(k); },
|
|
170
|
+
has: (k) => doc.edges.has(k),
|
|
171
|
+
values: () => doc.edges.values(),
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
transaction(maps, {});
|
|
175
|
+
},
|
|
176
|
+
async destroyBoardDocument(boardId) {
|
|
177
|
+
docs.delete(boardId);
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
(globalThis).__yjsBoard = mock;
|
|
181
|
+
return { docs };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
test("删除会话:普通看板 yjs 会话卡被清理,其余卡保留", async () => {
|
|
185
|
+
const { createBoard } = await jiti.import("./board-store.ts");
|
|
186
|
+
const { removeSessionsFromYjsBoards, destroyBoardYjsDocument } = await jiti.import("./board-reconcile.ts");
|
|
187
|
+
|
|
188
|
+
const { docs } = installMultiBoardYjsMock();
|
|
189
|
+
const boardA = createBoard(PROJECT, "手动看板A");
|
|
190
|
+
const boardB = createBoard(PROJECT, "手动看板B");
|
|
191
|
+
const s1 = "sess-ghost-1";
|
|
192
|
+
const s2 = "sess-keep-2";
|
|
193
|
+
// 看板 A:含 s1 + s2 两张卡
|
|
194
|
+
await globalThis.__yjsBoard.mutateBoard(boardA.id, (maps) => {
|
|
195
|
+
maps.nodes.set("a1", cardNode("a1", s1, {}));
|
|
196
|
+
maps.nodes.set("a2", cardNode("a2", s2, {}));
|
|
197
|
+
});
|
|
198
|
+
// 看板 B:只含 s1
|
|
199
|
+
await globalThis.__yjsBoard.mutateBoard(boardB.id, (maps) => {
|
|
200
|
+
maps.nodes.set("b1", cardNode("b1", s1, {}));
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
await removeSessionsFromYjsBoards([s1]);
|
|
204
|
+
|
|
205
|
+
const keysA = [...docs.get(boardA.id).nodes.keys()];
|
|
206
|
+
const keysB = [...docs.get(boardB.id).nodes.keys()];
|
|
207
|
+
assert.deepEqual(keysA, ["a2"], "boardA 删 s1 卡保留 s2");
|
|
208
|
+
assert.deepEqual(keysB, [], "boardB 删 s1 卡");
|
|
209
|
+
|
|
210
|
+
// destroy:删看板 → 文档移除
|
|
211
|
+
await destroyBoardYjsDocument(boardA.id);
|
|
212
|
+
assert.equal(docs.has(boardA.id), false, "destroy 后看板 yjs 文档移除");
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test("拖入任务看板的会话在归属完成前不被孤儿删(data.taskId 声明归属)", async () => {
|
|
216
|
+
const task = createTask(PROJECT, "任务D");
|
|
217
|
+
const board = getOrCreateTaskBoard(task.id, PROJECT, "任务D");
|
|
218
|
+
|
|
219
|
+
// 拖入一个「已存在但尚未归属本任务」的会话:落卡时 data.taskId = 本板任务
|
|
220
|
+
const draggedSid = "drag-in-progress";
|
|
221
|
+
mockState.nodeSets.set("drag-card", cardNode("drag-card", draggedSid, { taskId: task.id }));
|
|
222
|
+
|
|
223
|
+
const { reconcileBoard } = await jiti.import("./board-reconcile.ts");
|
|
224
|
+
await reconcileBoard(board.id);
|
|
225
|
+
|
|
226
|
+
// 不删:卡声明归属本板 → 放行
|
|
227
|
+
assert.ok(mockState.nodeSets.has("drag-card"), "归属窗口期拖入卡不被孤儿删");
|
|
228
|
+
// 但也不会补第二张(sid 不在业务表,本来就不补)
|
|
229
|
+
assert.equal(mockState.nodeSets.has(`session-${draggedSid}`), false);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("删除会话:普通看板清理级联删除以会话卡为端点的边", async () => {
|
|
233
|
+
const { createBoard } = await jiti.import("./board-store.ts");
|
|
234
|
+
const { removeSessionsFromYjsBoards } = await jiti.import("./board-reconcile.ts");
|
|
235
|
+
|
|
236
|
+
const { docs } = installMultiBoardYjsMock();
|
|
237
|
+
const boardA = createBoard(PROJECT, "手动看板C");
|
|
238
|
+
const s1 = "sess-edge-1";
|
|
239
|
+
const s2 = "sess-edge-2";
|
|
240
|
+
// 板 A:s1、s2 两张卡,中间一条手绘边
|
|
241
|
+
await globalThis.__yjsBoard.mutateBoard(boardA.id, (maps) => {
|
|
242
|
+
maps.nodes.set("a1", cardNode("a1", s1, {}));
|
|
243
|
+
maps.nodes.set("a2", cardNode("a2", s2, {}));
|
|
244
|
+
maps.edges.set("e1", { id: "e1", source: "a1", target: "a2", type: "default" });
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
await removeSessionsFromYjsBoards([s1]);
|
|
248
|
+
|
|
249
|
+
const doc = docs.get(boardA.id);
|
|
250
|
+
assert.deepEqual([...doc.nodes.keys()], ["a2"], "只删 s1 卡");
|
|
251
|
+
assert.deepEqual([...doc.edges.keys()], [], "以 a1 为端点的边级联删除");
|
|
252
|
+
});
|