@geminilight/mindos 0.6.39 → 0.6.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/README.md +31 -15
- package/README_zh.md +31 -15
- package/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +18 -17
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +68 -6
- package/_standalone/.next/routes-manifest.json +6 -0
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +2 -2
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +2 -2
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +3 -3
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +137 -99
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js +3 -3
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js +2 -19
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js +1 -18
- package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js +1 -0
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/init/route.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route.js +1 -1
- package/_standalone/.next/server/app/api/setup/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route.js +2 -2
- package/_standalone/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js +2 -2
- package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +2 -2
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +6 -6
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +2 -2
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +3 -3
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +2 -2
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +2 -2
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +3 -3
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +4 -4
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +18 -17
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/1750.js +1 -0
- package/_standalone/.next/server/chunks/1955.js +11 -0
- package/_standalone/.next/server/chunks/3680.js +1 -0
- package/_standalone/.next/server/chunks/4497.js +219 -0
- package/_standalone/.next/server/chunks/5560.js +2 -0
- package/_standalone/.next/server/chunks/6365.js +52 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8388.js +15 -0
- package/_standalone/.next/server/chunks/953.js +42 -2
- package/_standalone/.next/server/functions-config-manifest.json +2 -1
- package/_standalone/.next/server/instrumentation.js +1 -1
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/next-font-manifest.js +1 -1
- package/_standalone/.next/server/next-font-manifest.json +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/1053-0adaccc98a752a58.js +29 -0
- package/_standalone/.next/static/chunks/1239.10a0710c2772ab34.js +1 -0
- package/_standalone/.next/static/chunks/{1814.e2da5460ded71d71.js → 1814.2ee1d03297c0bccd.js} +1 -1
- package/_standalone/.next/static/chunks/{1a258343-030e4d6735874dd4.js → 1a258343-9803591e4aaee1f6.js} +1 -1
- package/_standalone/.next/static/chunks/2631.dc56e83472bde281.js +1 -0
- package/_standalone/.next/static/chunks/2872.045858d00bd8307f.js +8 -0
- package/_standalone/.next/static/chunks/2968.f10ccee9e7e2324d.js +2 -0
- package/_standalone/.next/static/chunks/3160-83a7e0b94414b3ac.js +1 -0
- package/_standalone/.next/static/chunks/{3637.4bcd01a4db78b894.js → 3637.f9a42cca59fd5bb5.js} +1 -1
- package/_standalone/.next/static/chunks/4033.6666700547b20141.js +1 -0
- package/_standalone/.next/static/chunks/4563-c2afaeacb241d1d0.js +6 -0
- package/_standalone/.next/static/chunks/516.24ee058b1d4b1fed.js +8 -0
- package/_standalone/.next/static/chunks/5627.c4337d7289acb31f.js +1 -0
- package/_standalone/.next/static/chunks/5956.b445072b35915129.js +1 -0
- package/_standalone/.next/static/chunks/6090-c98268ca726a68d3.js +1 -0
- package/_standalone/.next/static/chunks/6357-c645842834c0d4cd.js +1 -0
- package/_standalone/.next/static/chunks/6826.7b7d94dd0fd83812.js +1 -0
- package/_standalone/.next/static/chunks/{8409-de5726a4a278d28f.js → 6926-4af497b83952fa87.js} +1 -1
- package/_standalone/.next/static/chunks/7266-bb7be1128eccd48e.js +13 -0
- package/_standalone/.next/static/chunks/7753.63831cfc54a55fbb.js +1 -0
- package/_standalone/.next/static/chunks/862.9f526e964489e2e5.js +1 -0
- package/_standalone/.next/static/chunks/{1384-55276d40a9da4e88.js → 8663-de911d2d395622be.js} +2 -2
- package/_standalone/.next/static/chunks/9300.118b8c840634383f.js +28 -0
- package/_standalone/.next/static/chunks/9371-575600301da5d6bb.js +1 -0
- package/_standalone/.next/static/chunks/95247769.3b5caae1c1a76ce1.js +4 -0
- package/_standalone/.next/static/chunks/9602-423291fdb36396d1.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/_global-error/page-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-3e08abb495ecd5fd.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-e7e0f87ad3d765ac.js +5 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/page-350992cf5091bc5b.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-addf014fcf23fad5.js +11 -0
- package/_standalone/.next/static/chunks/app/echo/page-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/explore/page-5eb2835e9e3ab4bb.js +4 -0
- package/_standalone/.next/static/chunks/app/help/page-3d0e1ceaa4abc243.js +1 -0
- package/_standalone/.next/static/chunks/app/layout-9378c1c8d3e5761b.js +186 -0
- package/_standalone/.next/static/chunks/app/login/page-24236460fa7c11d0.js +1 -0
- package/_standalone/.next/static/chunks/app/page-9bae420fbbdc5fff.js +7 -0
- package/_standalone/.next/static/chunks/app/setup/page-99ed3d1bb6b8f4ef.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/page-b61ef2d5cd4f8d73.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-61474670d6bb6116.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-44fa78cbea613a78.js +12 -0
- package/_standalone/.next/static/chunks/e71f6c19-4df85185bf989b49.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-400c3c09b1540c14.js +1 -0
- package/_standalone/.next/static/chunks/webpack-c28c55d0a6021a6b.js +1 -0
- package/_standalone/.next/static/css/d300701f384db50d.css +1 -0
- package/_standalone/.next/static/rZLs1krFuduixvcVNe6q3/_buildManifest.js +1 -0
- package/_standalone/.next/trace +63 -53
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- package/_standalone/__tests__/agent/chat-mode.test.ts +103 -0
- package/_standalone/__tests__/agents/agents-content-dashboard.test.tsx +4 -3
- package/_standalone/__tests__/api/bootstrap.test.ts +0 -2
- package/_standalone/__tests__/api/file.test.ts +22 -1
- package/_standalone/__tests__/api/install-skill.test.ts +2 -2
- package/_standalone/__tests__/api/mcp-install.test.ts +9 -10
- package/_standalone/__tests__/api/setup.test.ts +2 -2
- package/_standalone/__tests__/api/test-key.test.ts +73 -147
- package/_standalone/__tests__/ask/ask-content-input-during-run.test.tsx +1 -1
- package/_standalone/__tests__/ask/mode-capsule.test.ts +95 -0
- package/_standalone/__tests__/core/inbox.test.ts +250 -0
- package/_standalone/__tests__/core/skill-install-logic.test.ts +3 -3
- package/_standalone/__tests__/core/sync-status.test.ts +1 -1
- package/_standalone/__tests__/core/tools.test.ts +11 -6
- package/_standalone/__tests__/lib/echo-pages-visual-i18n.test.ts +2 -2
- package/_standalone/__tests__/lib/i18n-new-keys.test.ts +2 -2
- package/_standalone/__tests__/panels/agents-panel-hub.test.tsx +2 -2
- package/_standalone/__tests__/settings/activity-bar-update-badge.test.tsx +1 -1
- package/_standalone/__tests__/settings/settings-update-badge.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-availability-sync.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-browser.test.tsx +1 -1
- package/_standalone/__tests__/settings/update-tab-desktop.test.tsx +1 -1
- package/_standalone/__tests__/setup.ts +3 -5
- package/_standalone/app/globals.css +11 -1
- package/_standalone/components/ActivityBar.tsx +26 -10
- package/_standalone/components/AskFab.tsx +1 -1
- package/_standalone/components/AskModal.tsx +1 -1
- package/_standalone/components/Backlinks.tsx +1 -1
- package/_standalone/components/CreateSpaceModal.tsx +7 -55
- package/_standalone/components/EchoSpotlight.tsx +1 -1
- package/_standalone/components/ExportModal.tsx +1 -1
- package/_standalone/components/FileTree.tsx +64 -79
- package/_standalone/components/FindInPage.tsx +1 -1
- package/_standalone/components/GuideCard.tsx +1 -1
- package/_standalone/components/ImportModal.tsx +1 -1
- package/_standalone/components/KeyboardShortcuts.tsx +1 -1
- package/_standalone/components/MarkdownView.tsx +11 -1
- package/_standalone/components/OnboardingView.tsx +1 -1
- package/_standalone/components/OrganizeToast.tsx +1 -1
- package/_standalone/components/Panel.tsx +82 -4
- package/_standalone/components/QuickSuggestion.tsx +1 -1
- package/_standalone/components/RightAgentDetailPanel.tsx +2 -2
- package/_standalone/components/RightAskPanel.tsx +58 -22
- package/_standalone/components/SearchModal.tsx +1 -1
- package/_standalone/components/Sidebar.tsx +1 -1
- package/_standalone/components/SidebarLayout.tsx +52 -16
- package/_standalone/components/SpaceInitToast.tsx +1 -1
- package/_standalone/components/SyncStatusBar.tsx +2 -2
- package/_standalone/components/SystemPulse.tsx +12 -6
- package/_standalone/components/TableOfContents.tsx +86 -39
- package/_standalone/components/agents/AgentActivitySection.tsx +225 -0
- package/_standalone/components/agents/AgentsMcpSection.tsx +7 -16
- package/_standalone/components/agents/AgentsOverviewSection.tsx +28 -27
- package/_standalone/components/agents/AgentsPanelA2aTab.tsx +1 -1
- package/_standalone/components/agents/AgentsPanelSessionsTab.tsx +6 -1
- package/_standalone/components/agents/AgentsSkillsSection.tsx +1 -1
- package/_standalone/components/agents/DiscoverAgentModal.tsx +1 -1
- package/_standalone/components/agents/RecentActivityFeed.tsx +49 -88
- package/_standalone/components/agents/agent-activity-shared.tsx +110 -0
- package/_standalone/components/ask/AgentSelectorCapsule.tsx +1 -1
- package/_standalone/components/ask/AskContent.tsx +332 -486
- package/_standalone/components/ask/AskHeader.tsx +61 -0
- package/_standalone/components/ask/FileChip.tsx +9 -5
- package/_standalone/components/ask/MessageList.tsx +88 -21
- package/_standalone/components/ask/ModeCapsule.tsx +180 -0
- package/_standalone/components/ask/ProviderModelCapsule.tsx +284 -0
- package/_standalone/components/ask/SessionHistory.tsx +63 -10
- package/_standalone/components/ask/SessionTabBar.tsx +1 -1
- package/_standalone/components/ask/ThinkingBlock.tsx +1 -1
- package/_standalone/components/ask/ToolCallBlock.tsx +28 -24
- package/_standalone/components/changes/ChangesBanner.tsx +1 -1
- package/_standalone/components/echo/EchoInsightCollapsible.tsx +1 -1
- package/_standalone/components/echo/EchoSegmentNav.tsx +1 -1
- package/_standalone/components/home/InboxSection.tsx +268 -0
- package/_standalone/components/panels/AgentsPanel.tsx +3 -2
- package/_standalone/components/panels/AgentsPanelHubNav.tsx +2 -6
- package/_standalone/components/panels/DiscoverPanel.tsx +1 -1
- package/_standalone/components/panels/EchoPanel.tsx +1 -1
- package/_standalone/components/panels/EchoSidebarStats.tsx +1 -1
- package/_standalone/components/panels/ImportHistoryPanel.tsx +1 -1
- package/_standalone/components/panels/PanelHeader.tsx +1 -1
- package/_standalone/components/panels/PluginsPanel.tsx +1 -1
- package/_standalone/components/panels/SearchPanel.tsx +5 -2
- package/_standalone/components/panels/SyncPopover.tsx +1 -1
- package/_standalone/components/panels/WorkflowsPanel.tsx +1 -1
- package/_standalone/components/renderers/agent-inspector/AgentInspectorRenderer.tsx +18 -0
- package/_standalone/components/renderers/agent-inspector/manifest.ts +16 -0
- package/_standalone/components/renderers/todo/TodoRenderer.tsx +489 -75
- package/_standalone/components/settings/AiTab.tsx +198 -127
- package/_standalone/components/settings/AppearanceTab.tsx +48 -50
- package/_standalone/components/settings/KnowledgeTab.tsx +92 -27
- package/_standalone/components/settings/McpAgentInstall.tsx +1 -1
- package/_standalone/components/settings/McpSkillsSection.tsx +1 -1
- package/_standalone/components/settings/McpTab.tsx +145 -7
- package/_standalone/components/settings/PluginsTab.tsx +1 -1
- package/_standalone/components/settings/SettingsContent.tsx +5 -2
- package/_standalone/components/settings/SyncTab.tsx +615 -230
- package/_standalone/components/settings/UninstallTab.tsx +1 -1
- package/_standalone/components/settings/UpdateTab.tsx +2 -2
- package/_standalone/components/settings/types.ts +4 -5
- package/_standalone/components/setup/StepAI.tsx +70 -49
- package/_standalone/components/setup/StepDots.tsx +1 -1
- package/_standalone/components/setup/StepReview.tsx +176 -8
- package/_standalone/components/setup/types.ts +11 -8
- package/_standalone/components/shared/ProviderSelect.tsx +134 -0
- package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +2 -2
- package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +2 -2
- package/_standalone/components/walkthrough/index.ts +1 -1
- package/_standalone/data/skills/mindos/SKILL.md +3 -3
- package/_standalone/data/skills/mindos-zh/SKILL.md +3 -3
- package/_standalone/hooks/useAcpDetection.ts +1 -1
- package/_standalone/hooks/useAskChat.ts +248 -0
- package/_standalone/hooks/useAskPanel.ts +24 -4
- package/_standalone/hooks/useAskSession.ts +15 -0
- package/_standalone/lib/acp/types.ts +1 -1
- package/_standalone/lib/api.ts +3 -1
- package/_standalone/lib/core/types.ts +2 -0
- package/_standalone/lib/i18n/modules/ai-chat.ts +35 -13
- package/_standalone/lib/i18n/modules/features.ts +2 -2
- package/_standalone/lib/i18n/modules/knowledge.ts +82 -2
- package/_standalone/lib/i18n/modules/navigation.ts +6 -2
- package/_standalone/lib/i18n/modules/onboarding.ts +39 -9
- package/_standalone/lib/i18n/modules/panels.ts +78 -29
- package/_standalone/lib/i18n/modules/settings.ts +207 -23
- package/_standalone/lib/inbox-upload.ts +93 -0
- package/_standalone/lib/settings-ai-client.ts +13 -12
- package/_standalone/lib/space-ai-init.ts +66 -0
- package/_standalone/lib/stores/McpStoreInit.tsx +18 -0
- package/_standalone/lib/stores/WalkthroughInit.tsx +20 -0
- package/_standalone/lib/stores/locale-store.ts +55 -0
- package/_standalone/lib/stores/mcp-store.ts +156 -0
- package/_standalone/lib/stores/walkthrough-store.ts +118 -0
- package/_standalone/package-lock.json +40 -8
- package/_standalone/package.json +3 -1
- package/_standalone/tsconfig.json +1 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/acp/detect/route.ts +29 -20
- package/app/app/api/agent-activity/route.ts +1 -1
- package/app/app/api/ask/route.ts +103 -29
- package/app/app/api/ask-sessions/route.ts +1 -0
- package/app/app/api/bootstrap/route.ts +1 -3
- package/app/app/api/file/route.ts +34 -4
- package/app/app/api/inbox/route.ts +61 -0
- package/app/app/api/settings/list-models/route.ts +73 -53
- package/app/app/api/settings/route.ts +46 -55
- package/app/app/api/settings/test-key/route.ts +57 -114
- package/app/app/api/setup/route.ts +31 -21
- package/app/app/api/sync/route.ts +122 -12
- package/app/app/api/update-check/route.ts +2 -2
- package/app/app/globals.css +11 -1
- package/app/app/layout.tsx +2 -3
- package/app/app/login/page.tsx +1 -1
- package/app/app/view/[...path]/ViewPageClient.tsx +10 -10
- package/app/app/view/[...path]/not-found.tsx +1 -1
- package/app/components/ActivityBar.tsx +26 -10
- package/app/components/AskFab.tsx +1 -1
- package/app/components/AskModal.tsx +1 -1
- package/app/components/Backlinks.tsx +1 -1
- package/app/components/CreateSpaceModal.tsx +7 -55
- package/app/components/DirView.tsx +93 -11
- package/app/components/EchoSpotlight.tsx +1 -1
- package/app/components/ExportModal.tsx +1 -1
- package/app/components/FileTree.tsx +64 -79
- package/app/components/FindInPage.tsx +1 -1
- package/app/components/GuideCard.tsx +1 -1
- package/app/components/HomeContent.tsx +21 -14
- package/app/components/ImportModal.tsx +1 -1
- package/app/components/KeyboardShortcuts.tsx +1 -1
- package/app/components/MarkdownView.tsx +11 -1
- package/app/components/OnboardingView.tsx +1 -1
- package/app/components/OrganizeToast.tsx +1 -1
- package/app/components/Panel.tsx +82 -4
- package/app/components/QuickSuggestion.tsx +1 -1
- package/app/components/RightAgentDetailPanel.tsx +2 -2
- package/app/components/RightAskPanel.tsx +58 -22
- package/app/components/SearchModal.tsx +1 -1
- package/app/components/Sidebar.tsx +1 -1
- package/app/components/SidebarLayout.tsx +52 -16
- package/app/components/SpaceInitToast.tsx +1 -1
- package/app/components/SyncStatusBar.tsx +2 -2
- package/app/components/SystemPulse.tsx +12 -6
- package/app/components/TableOfContents.tsx +86 -39
- package/app/components/TrashPageClient.tsx +1 -1
- package/app/components/UpdateOverlay.tsx +2 -2
- package/app/components/agents/AgentActivitySection.tsx +225 -0
- package/app/components/agents/AgentDetailContent.tsx +234 -3
- package/app/components/agents/AgentsContentPage.tsx +13 -2
- package/app/components/agents/AgentsMcpSection.tsx +7 -16
- package/app/components/agents/AgentsOverviewSection.tsx +28 -27
- package/app/components/agents/AgentsPanelA2aTab.tsx +1 -1
- package/app/components/agents/AgentsPanelSessionsTab.tsx +6 -1
- package/app/components/agents/AgentsSkillsSection.tsx +1 -1
- package/app/components/agents/DiscoverAgentModal.tsx +1 -1
- package/app/components/agents/RecentActivityFeed.tsx +49 -88
- package/app/components/agents/agent-activity-shared.tsx +110 -0
- package/app/components/agents/agents-content-model.ts +2 -2
- package/app/components/ask/AgentSelectorCapsule.tsx +1 -1
- package/app/components/ask/AskContent.tsx +332 -486
- package/app/components/ask/AskHeader.tsx +61 -0
- package/app/components/ask/FileChip.tsx +9 -5
- package/app/components/ask/MessageList.tsx +88 -21
- package/app/components/ask/ModeCapsule.tsx +180 -0
- package/app/components/ask/ProviderModelCapsule.tsx +284 -0
- package/app/components/ask/SessionHistory.tsx +63 -10
- package/app/components/ask/SessionTabBar.tsx +1 -1
- package/app/components/ask/ThinkingBlock.tsx +1 -1
- package/app/components/ask/ToolCallBlock.tsx +28 -24
- package/app/components/changes/ChangesBanner.tsx +1 -1
- package/app/components/changes/ChangesContentPage.tsx +1 -1
- package/app/components/echo/EchoInsightCollapsible.tsx +1 -1
- package/app/components/echo/EchoSegmentNav.tsx +1 -1
- package/app/components/echo/EchoSegmentPageClient.tsx +1 -1
- package/app/components/explore/ExploreContent.tsx +1 -1
- package/app/components/help/HelpContent.tsx +1 -1
- package/app/components/home/InboxSection.tsx +268 -0
- package/app/components/panels/AgentsPanel.tsx +3 -2
- package/app/components/panels/AgentsPanelHubNav.tsx +2 -6
- package/app/components/panels/DiscoverPanel.tsx +1 -1
- package/app/components/panels/EchoPanel.tsx +1 -1
- package/app/components/panels/EchoSidebarStats.tsx +1 -1
- package/app/components/panels/ImportHistoryPanel.tsx +1 -1
- package/app/components/panels/PanelHeader.tsx +1 -1
- package/app/components/panels/PluginsPanel.tsx +1 -1
- package/app/components/panels/SearchPanel.tsx +5 -2
- package/app/components/panels/SyncPopover.tsx +1 -1
- package/app/components/panels/WorkflowsPanel.tsx +1 -1
- package/app/components/renderers/agent-inspector/AgentInspectorRenderer.tsx +18 -0
- package/app/components/renderers/todo/TodoRenderer.tsx +489 -75
- package/app/components/settings/AiTab.tsx +198 -127
- package/app/components/settings/AppearanceTab.tsx +48 -50
- package/app/components/settings/KnowledgeTab.tsx +92 -27
- package/app/components/settings/McpAgentInstall.tsx +1 -1
- package/app/components/settings/McpSkillsSection.tsx +1 -1
- package/app/components/settings/McpTab.tsx +145 -7
- package/app/components/settings/PluginsTab.tsx +1 -1
- package/app/components/settings/SettingsContent.tsx +5 -2
- package/app/components/settings/SyncTab.tsx +615 -230
- package/app/components/settings/UninstallTab.tsx +1 -1
- package/app/components/settings/UpdateTab.tsx +2 -2
- package/app/components/settings/types.ts +4 -5
- package/app/components/setup/StepAI.tsx +70 -49
- package/app/components/setup/StepDots.tsx +1 -1
- package/app/components/setup/StepReview.tsx +176 -8
- package/app/components/setup/index.tsx +73 -39
- package/app/components/setup/types.ts +11 -8
- package/app/components/shared/ProviderSelect.tsx +134 -0
- package/app/components/walkthrough/WalkthroughOverlay.tsx +2 -2
- package/app/components/walkthrough/WalkthroughTooltip.tsx +2 -2
- package/app/components/walkthrough/index.ts +1 -1
- package/app/data/skills/mindos/SKILL.md +3 -3
- package/app/data/skills/mindos-zh/SKILL.md +3 -3
- package/app/hooks/useAcpDetection.ts +1 -1
- package/app/hooks/useAskChat.ts +248 -0
- package/app/hooks/useAskPanel.ts +24 -4
- package/app/hooks/useAskSession.ts +15 -0
- package/app/lib/acp/types.ts +1 -1
- package/app/lib/actions.ts +13 -0
- package/app/lib/agent/log.ts +2 -0
- package/app/lib/agent/model.ts +69 -81
- package/app/lib/agent/prompt.ts +27 -0
- package/app/lib/agent/providers.ts +299 -0
- package/app/lib/agent/tools.ts +26 -4
- package/app/lib/api.ts +3 -1
- package/app/lib/core/agent-audit-log.ts +7 -0
- package/app/lib/core/fs-ops.ts +9 -4
- package/app/lib/core/inbox.ts +181 -0
- package/app/lib/core/index.ts +4 -0
- package/app/lib/core/tree.ts +3 -0
- package/app/lib/core/types.ts +2 -0
- package/app/lib/fs.ts +26 -2
- package/app/lib/i18n/modules/ai-chat.ts +35 -13
- package/app/lib/i18n/modules/features.ts +2 -2
- package/app/lib/i18n/modules/knowledge.ts +82 -2
- package/app/lib/i18n/modules/navigation.ts +6 -2
- package/app/lib/i18n/modules/onboarding.ts +39 -9
- package/app/lib/i18n/modules/panels.ts +78 -29
- package/app/lib/i18n/modules/settings.ts +207 -23
- package/app/lib/inbox-upload.ts +93 -0
- package/app/lib/mcp-agents.ts +6 -7
- package/app/lib/renderers/index.ts +1 -2
- package/app/lib/settings-ai-client.ts +13 -12
- package/app/lib/settings.ts +48 -33
- package/app/lib/space-ai-init.ts +66 -0
- package/app/lib/stores/LocaleStoreInit.tsx +18 -0
- package/app/lib/stores/McpStoreInit.tsx +18 -0
- package/app/lib/stores/WalkthroughInit.tsx +20 -0
- package/app/lib/stores/locale-store.ts +55 -0
- package/app/lib/stores/mcp-store.ts +156 -0
- package/app/lib/stores/walkthrough-store.ts +118 -0
- package/app/lib/types.ts +20 -0
- package/app/package.json +3 -1
- package/app/tsconfig.json +1 -1
- package/bin/cli.js +46 -27
- package/bin/commands/file.js +7 -4
- package/bin/commands/space.js +4 -0
- package/bin/lib/mcp-agents.js +26 -2
- package/bin/lib/mcp-install.js +11 -3
- package/bin/lib/sync.js +140 -34
- package/mcp/README.md +2 -2
- package/mcp/dist/index.cjs +43 -43
- package/mcp/package.json +1 -1
- package/mcp/src/index.ts +77 -61
- package/package.json +1 -1
- package/scripts/setup.js +1 -1
- package/skills/mindos/SKILL.md +3 -3
- package/skills/mindos/references/preference-capture.md +4 -4
- package/skills/mindos/references/write-supplement.md +2 -2
- package/skills/mindos-zh/SKILL.md +3 -3
- package/skills/mindos-zh/references/preference-capture.md +4 -4
- package/skills/mindos-zh/references/write-supplement.md +2 -2
- package/templates/empty/INSTRUCTION.md +0 -1
- package/templates/en/INSTRUCTION.md +0 -1
- package/templates/template-generation-skill.md +0 -1
- package/templates/zh/INSTRUCTION.md +0 -1
- package/_standalone/.next/server/chunks/1473.js +0 -52
- package/_standalone/.next/server/chunks/248.js +0 -15
- package/_standalone/.next/server/chunks/359.js +0 -2
- package/_standalone/.next/server/chunks/4931.js +0 -202
- package/_standalone/.next/server/chunks/7670.js +0 -1
- package/_standalone/.next/server/chunks/9414.js +0 -11
- package/_standalone/.next/static/chunks/1038-ed04d6651ec92312.js +0 -1
- package/_standalone/.next/static/chunks/1263-6df1734e4273adb1.js +0 -25
- package/_standalone/.next/static/chunks/275-ebcaaedabe706903.js +0 -1
- package/_standalone/.next/static/chunks/5637-b97c869adf70c82e.js +0 -1
- package/_standalone/.next/static/chunks/5681-a53362a1cd629dc6.js +0 -1
- package/_standalone/.next/static/chunks/9602-35ca17b688f1a4fe.js +0 -1
- package/_standalone/.next/static/chunks/9670-d59e4d45ed705f58.js +0 -6
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/_global-error/page-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-519d4da1142db5ef.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-b709cf3103321609.js +0 -5
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/changes/page-def5210095f8698d.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-be28eff31b1a186e.js +0 -11
- package/_standalone/.next/static/chunks/app/echo/page-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/explore/page-e4b8098dca200389.js +0 -4
- package/_standalone/.next/static/chunks/app/help/page-d5e57d73d94bad19.js +0 -1
- package/_standalone/.next/static/chunks/app/layout-d91cdbe2ecf135e1.js +0 -173
- package/_standalone/.next/static/chunks/app/login/page-321875768b70938a.js +0 -1
- package/_standalone/.next/static/chunks/app/page-718fdf170428b43c.js +0 -7
- package/_standalone/.next/static/chunks/app/setup/page-01ab1f549d636057.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-89b1430cc8a16f18.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-f22c513bbc348cc8.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-6e3dc47699a01de1.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d4762cc48529e566.js +0 -1
- package/_standalone/.next/static/chunks/webpack-3489a2b6c2882b0c.js +0 -1
- package/_standalone/.next/static/css/f16595bc58a16d5d.css +0 -1
- package/_standalone/.next/static/ushZ_NJ8rE3rG5hZfaYOX/_buildManifest.js +0 -1
- package/_standalone/components/walkthrough/WalkthroughProvider.tsx +0 -133
- package/_standalone/hooks/useMcpData.tsx +0 -169
- package/_standalone/lib/i18n-en.ts +0 -2
- package/_standalone/lib/i18n-zh.ts +0 -2
- package/_standalone/lib/types.ts +0 -70
- package/app/components/walkthrough/WalkthroughProvider.tsx +0 -133
- package/app/hooks/useMcpData.tsx +0 -169
- package/app/lib/LocaleContext.tsx +0 -60
- package/app/lib/i18n-en.ts +0 -2
- package/app/lib/i18n-zh.ts +0 -2
- /package/_standalone/.next/static/{ushZ_NJ8rE3rG5hZfaYOX → rZLs1krFuduixvcVNe6q3}/_ssgManifest.js +0 -0
|
@@ -1,61 +1,145 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CheckSquare, Square, ChevronDown, ChevronRight, Plus, Trash2,
|
|
6
|
+
Circle, Clock, Calendar, Filter, X,
|
|
7
|
+
} from 'lucide-react';
|
|
5
8
|
import type { RendererContext } from '@/lib/renderers/registry';
|
|
6
9
|
|
|
7
|
-
// ───
|
|
10
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
type TodoStatus = 'todo' | 'in-progress' | 'done';
|
|
13
|
+
type Priority = 'P0' | 'P1' | 'P2' | null;
|
|
14
|
+
|
|
15
|
+
interface TodoMeta {
|
|
16
|
+
priority: Priority;
|
|
17
|
+
dueDate: string | null;
|
|
18
|
+
tags: string[];
|
|
19
|
+
}
|
|
8
20
|
|
|
9
21
|
interface TodoItem {
|
|
10
22
|
id: string;
|
|
11
23
|
text: string;
|
|
12
|
-
|
|
24
|
+
rawText: string;
|
|
25
|
+
status: TodoStatus;
|
|
13
26
|
indent: number;
|
|
14
27
|
lineIndex: number;
|
|
15
28
|
section: string;
|
|
16
29
|
children: TodoItem[];
|
|
30
|
+
meta: TodoMeta;
|
|
17
31
|
}
|
|
18
32
|
|
|
19
33
|
interface SectionMeta {
|
|
20
34
|
items: TodoItem[];
|
|
21
|
-
lastLineIndex: number;
|
|
35
|
+
lastLineIndex: number;
|
|
36
|
+
headingLineIndex: number;
|
|
22
37
|
}
|
|
23
38
|
|
|
24
|
-
|
|
25
|
-
|
|
39
|
+
// ─── Parser ──────────────────────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
const H2_SECTION_RE = /^##\s+(.+)/;
|
|
42
|
+
const H1_RE = /^#\s+/;
|
|
43
|
+
const H3_PLUS_RE = /^#{3,6}\s+(.+)/;
|
|
44
|
+
const TODO_RE = /^(\s*)- \[([ xX~])\]\s+(.*)$/;
|
|
45
|
+
const PRIORITY_RE = /`(P[012])`/;
|
|
46
|
+
const DATE_RE = /`(\d{4}-\d{2}-\d{2}|\d{2}-\d{2})`/;
|
|
47
|
+
const TAG_RE = /#([a-zA-Z\u4e00-\u9fff][\w\u4e00-\u9fff-]*)/g;
|
|
48
|
+
|
|
49
|
+
function extractMeta(rawText: string): { cleanText: string; meta: TodoMeta } {
|
|
50
|
+
let text = rawText;
|
|
51
|
+
let priority: Priority = null;
|
|
52
|
+
let dueDate: string | null = null;
|
|
53
|
+
const tags: string[] = [];
|
|
54
|
+
|
|
55
|
+
const pMatch = text.match(PRIORITY_RE);
|
|
56
|
+
if (pMatch) {
|
|
57
|
+
priority = pMatch[1] as Priority;
|
|
58
|
+
text = text.replace(PRIORITY_RE, '').trim();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const dMatch = text.match(DATE_RE);
|
|
62
|
+
if (dMatch) {
|
|
63
|
+
dueDate = dMatch[1];
|
|
64
|
+
text = text.replace(DATE_RE, '').trim();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let tMatch: RegExpExecArray | null;
|
|
68
|
+
const tagRe = new RegExp(TAG_RE.source, 'g');
|
|
69
|
+
while ((tMatch = tagRe.exec(text)) !== null) {
|
|
70
|
+
tags.push(tMatch[1]);
|
|
71
|
+
}
|
|
72
|
+
if (tags.length > 0) {
|
|
73
|
+
text = text.replace(/#[a-zA-Z\u4e00-\u9fff][\w\u4e00-\u9fff-]*/g, '').trim();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
text = text.replace(/\*\*(.*?)\*\*/g, '$1').trim();
|
|
77
|
+
|
|
78
|
+
return { cleanText: text, meta: { priority, dueDate, tags } };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseStatus(checkChar: string): TodoStatus {
|
|
82
|
+
if (checkChar === '~') return 'in-progress';
|
|
83
|
+
if (checkChar.toLowerCase() === 'x') return 'done';
|
|
84
|
+
return 'todo';
|
|
85
|
+
}
|
|
26
86
|
|
|
27
87
|
function parseMarkdownTodos(raw: string): {
|
|
28
88
|
sections: Record<string, SectionMeta>;
|
|
29
89
|
lines: string[];
|
|
90
|
+
sectionOrder: string[];
|
|
30
91
|
} {
|
|
31
92
|
const lines = raw.split('\n');
|
|
32
93
|
let currentSection = 'General';
|
|
33
94
|
const sections: Record<string, SectionMeta> = {};
|
|
95
|
+
const sectionOrder: string[] = [];
|
|
34
96
|
const stack: TodoItem[] = [];
|
|
35
97
|
|
|
98
|
+
let inFrontmatter = false;
|
|
99
|
+
let frontmatterDone = false;
|
|
100
|
+
|
|
36
101
|
lines.forEach((line, lineIndex) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
102
|
+
if (!frontmatterDone) {
|
|
103
|
+
if (lineIndex === 0 && line.trim() === '---') { inFrontmatter = true; return; }
|
|
104
|
+
if (inFrontmatter) {
|
|
105
|
+
if (line.trim() === '---') { inFrontmatter = false; frontmatterDone = true; }
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
frontmatterDone = true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (H1_RE.test(line)) return;
|
|
112
|
+
|
|
113
|
+
const h2Match = line.match(H2_SECTION_RE);
|
|
114
|
+
if (h2Match) {
|
|
115
|
+
currentSection = h2Match[1].replace(/^[^\w\s\u4e00-\u9fff]+\s*/, '').trim();
|
|
116
|
+
if (!sections[currentSection]) {
|
|
117
|
+
sections[currentSection] = { items: [], lastLineIndex: -1, headingLineIndex: lineIndex };
|
|
118
|
+
sectionOrder.push(currentSection);
|
|
119
|
+
}
|
|
40
120
|
return;
|
|
41
121
|
}
|
|
42
122
|
|
|
123
|
+
if (H3_PLUS_RE.test(line)) return;
|
|
124
|
+
|
|
43
125
|
const todoMatch = line.match(TODO_RE);
|
|
44
126
|
if (!todoMatch) return;
|
|
45
127
|
|
|
46
128
|
const [, indentStr, checkChar, rawText] = todoMatch;
|
|
47
129
|
const indent = Math.floor(indentStr.length / 2);
|
|
48
|
-
const
|
|
49
|
-
const
|
|
130
|
+
const status = parseStatus(checkChar);
|
|
131
|
+
const { cleanText, meta } = extractMeta(rawText);
|
|
50
132
|
|
|
51
133
|
const item: TodoItem = {
|
|
52
134
|
id: `${lineIndex}`,
|
|
53
|
-
text,
|
|
54
|
-
|
|
135
|
+
text: cleanText,
|
|
136
|
+
rawText,
|
|
137
|
+
status,
|
|
55
138
|
indent,
|
|
56
139
|
lineIndex,
|
|
57
140
|
section: currentSection,
|
|
58
141
|
children: [],
|
|
142
|
+
meta,
|
|
59
143
|
};
|
|
60
144
|
|
|
61
145
|
while (stack.length > 0 && stack[stack.length - 1].indent >= indent) {
|
|
@@ -63,7 +147,8 @@ function parseMarkdownTodos(raw: string): {
|
|
|
63
147
|
}
|
|
64
148
|
|
|
65
149
|
if (!sections[currentSection]) {
|
|
66
|
-
sections[currentSection] = { items: [], lastLineIndex: -1 };
|
|
150
|
+
sections[currentSection] = { items: [], lastLineIndex: -1, headingLineIndex: -1 };
|
|
151
|
+
sectionOrder.push(currentSection);
|
|
67
152
|
}
|
|
68
153
|
|
|
69
154
|
if (stack.length > 0) {
|
|
@@ -72,7 +157,6 @@ function parseMarkdownTodos(raw: string): {
|
|
|
72
157
|
sections[currentSection].items.push(item);
|
|
73
158
|
}
|
|
74
159
|
|
|
75
|
-
// Track the furthest line in this section
|
|
76
160
|
sections[currentSection].lastLineIndex = Math.max(
|
|
77
161
|
sections[currentSection].lastLineIndex,
|
|
78
162
|
lineIndex,
|
|
@@ -81,26 +165,32 @@ function parseMarkdownTodos(raw: string): {
|
|
|
81
165
|
stack.push(item);
|
|
82
166
|
});
|
|
83
167
|
|
|
84
|
-
return { sections, lines };
|
|
168
|
+
return { sections, lines, sectionOrder };
|
|
85
169
|
}
|
|
86
170
|
|
|
171
|
+
// ─── Line operations ─────────────────────────────────────────────────────────
|
|
172
|
+
|
|
87
173
|
function applyLines(lines: string[], ops: (l: string[]) => void): string {
|
|
88
174
|
const next = [...lines];
|
|
89
175
|
ops(next);
|
|
90
176
|
return next.join('\n');
|
|
91
177
|
}
|
|
92
178
|
|
|
93
|
-
function
|
|
179
|
+
function statusChar(s: TodoStatus): string {
|
|
180
|
+
if (s === 'done') return 'x';
|
|
181
|
+
if (s === 'in-progress') return '~';
|
|
182
|
+
return ' ';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function setStatusInLines(lines: string[], lineIndex: number, status: TodoStatus): string {
|
|
94
186
|
return applyLines(lines, (l) => {
|
|
95
|
-
l[lineIndex] =
|
|
96
|
-
? l[lineIndex].replace(/- \[ \]/, '- [x]')
|
|
97
|
-
: l[lineIndex].replace(/- \[[xX]\]/, '- [ ]');
|
|
187
|
+
l[lineIndex] = l[lineIndex].replace(/- \[[ xX~]\]/, `- [${statusChar(status)}]`);
|
|
98
188
|
});
|
|
99
189
|
}
|
|
100
190
|
|
|
101
191
|
function renameInLines(lines: string[], lineIndex: number, newText: string): string {
|
|
102
192
|
return applyLines(lines, (l) => {
|
|
103
|
-
l[lineIndex] = l[lineIndex].replace(/(- \[[ xX]\]\s*)(.*)$/, `$1${newText}`);
|
|
193
|
+
l[lineIndex] = l[lineIndex].replace(/(- \[[ xX~]\]\s*)(.*)$/, `$1${newText}`);
|
|
104
194
|
});
|
|
105
195
|
}
|
|
106
196
|
|
|
@@ -117,12 +207,59 @@ function addInLines(lines: string[], afterLineIndex: number, text: string): stri
|
|
|
117
207
|
});
|
|
118
208
|
}
|
|
119
209
|
|
|
120
|
-
|
|
210
|
+
function cycleStatus(current: TodoStatus): TodoStatus {
|
|
211
|
+
if (current === 'todo') return 'in-progress';
|
|
212
|
+
if (current === 'in-progress') return 'done';
|
|
213
|
+
return 'todo';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ─── Date helpers ────────────────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
function resolveDate(dateStr: string | null): Date | null {
|
|
219
|
+
if (!dateStr) return null;
|
|
220
|
+
const now = new Date();
|
|
221
|
+
if (/^\d{2}-\d{2}$/.test(dateStr)) {
|
|
222
|
+
return new Date(`${now.getFullYear()}-${dateStr}`);
|
|
223
|
+
}
|
|
224
|
+
return new Date(dateStr);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
type DateUrgency = 'overdue' | 'today' | 'soon' | 'future' | null;
|
|
228
|
+
|
|
229
|
+
function dateUrgency(dateStr: string | null): DateUrgency {
|
|
230
|
+
const d = resolveDate(dateStr);
|
|
231
|
+
if (!d || isNaN(d.getTime())) return null;
|
|
232
|
+
const now = new Date();
|
|
233
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
234
|
+
const target = new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
235
|
+
const diff = (target.getTime() - today.getTime()) / (1000 * 60 * 60 * 24);
|
|
236
|
+
if (diff < 0) return 'overdue';
|
|
237
|
+
if (diff === 0) return 'today';
|
|
238
|
+
if (diff <= 3) return 'soon';
|
|
239
|
+
return 'future';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// ─── Style constants ─────────────────────────────────────────────────────────
|
|
243
|
+
|
|
244
|
+
const PRIORITY_STYLES: Record<string, { bg: string; text: string; border: string }> = {
|
|
245
|
+
P0: { bg: 'bg-red-500/10', text: 'text-red-500', border: 'border-red-500/20' },
|
|
246
|
+
P1: { bg: 'bg-amber-500/10', text: 'text-amber-500', border: 'border-amber-500/20' },
|
|
247
|
+
P2: { bg: 'bg-blue-500/10', text: 'text-blue-500', border: 'border-blue-500/20' },
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const DATE_STYLES: Record<string, { text: string; bg: string }> = {
|
|
251
|
+
overdue: { text: 'text-red-500', bg: 'bg-red-500/10' },
|
|
252
|
+
today: { text: 'text-amber-500', bg: 'bg-amber-500/10' },
|
|
253
|
+
soon: { text: 'text-amber-400', bg: 'bg-amber-400/5' },
|
|
254
|
+
future: { text: 'text-muted-foreground', bg: '' },
|
|
255
|
+
};
|
|
121
256
|
|
|
122
257
|
const SECTION_STYLES: Record<string, { dot: string; label: string }> = {
|
|
123
258
|
'TODAY': { dot: 'bg-red-400', label: 'text-red-400' },
|
|
259
|
+
'This Week': { dot: 'bg-orange-400', label: 'text-orange-400' },
|
|
124
260
|
'Workflows': { dot: 'bg-amber-400', label: 'text-amber-400' },
|
|
125
261
|
'Backlog': { dot: 'bg-blue-400', label: 'text-blue-400' },
|
|
262
|
+
'Done': { dot: 'bg-emerald-400', label: 'text-emerald-400' },
|
|
126
263
|
'Maintenance': { dot: 'bg-zinc-400', label: 'text-zinc-400' },
|
|
127
264
|
};
|
|
128
265
|
|
|
@@ -131,23 +268,208 @@ function sectionStyle(name: string) {
|
|
|
131
268
|
return key ? SECTION_STYLES[key] : { dot: 'bg-zinc-500', label: 'text-zinc-400' };
|
|
132
269
|
}
|
|
133
270
|
|
|
134
|
-
|
|
135
|
-
|
|
271
|
+
// ─── Counting ────────────────────────────────────────────────────────────────
|
|
272
|
+
|
|
273
|
+
function countByStatus(items: TodoItem[], status: TodoStatus): number {
|
|
274
|
+
return items.reduce((n, item) => n + (item.status === status ? 1 : 0) + countByStatus(item.children, status), 0);
|
|
136
275
|
}
|
|
137
276
|
|
|
138
277
|
function countTotal(items: TodoItem[]): number {
|
|
139
278
|
return items.reduce((n, item) => n + 1 + countTotal(item.children), 0);
|
|
140
279
|
}
|
|
141
280
|
|
|
281
|
+
function collectAllTags(sections: Record<string, SectionMeta>): string[] {
|
|
282
|
+
const tagSet = new Set<string>();
|
|
283
|
+
function walk(items: TodoItem[]) {
|
|
284
|
+
for (const item of items) {
|
|
285
|
+
for (const tag of item.meta.tags) tagSet.add(tag);
|
|
286
|
+
walk(item.children);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
for (const meta of Object.values(sections)) walk(meta.items);
|
|
290
|
+
return [...tagSet].sort();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function collectAllPriorities(sections: Record<string, SectionMeta>): Priority[] {
|
|
294
|
+
const pSet = new Set<Priority>();
|
|
295
|
+
function walk(items: TodoItem[]) {
|
|
296
|
+
for (const item of items) {
|
|
297
|
+
if (item.meta.priority) pSet.add(item.meta.priority);
|
|
298
|
+
walk(item.children);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
for (const meta of Object.values(sections)) walk(meta.items);
|
|
302
|
+
const order: Priority[] = ['P0', 'P1', 'P2'];
|
|
303
|
+
return order.filter(p => pSet.has(p));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// ─── Filter bar ──────────────────────────────────────────────────────────────
|
|
307
|
+
|
|
308
|
+
interface FilterState {
|
|
309
|
+
priority: Priority | 'all';
|
|
310
|
+
tag: string | 'all';
|
|
311
|
+
status: TodoStatus | 'all';
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function FilterBar({ filters, onFilterChange, allTags, allPriorities, counts }: {
|
|
315
|
+
filters: FilterState;
|
|
316
|
+
onFilterChange: (f: FilterState) => void;
|
|
317
|
+
allTags: string[];
|
|
318
|
+
allPriorities: Priority[];
|
|
319
|
+
counts: { todo: number; inProgress: number; done: number; total: number };
|
|
320
|
+
}) {
|
|
321
|
+
const hasFilters = filters.priority !== 'all' || filters.tag !== 'all' || filters.status !== 'all';
|
|
322
|
+
|
|
323
|
+
if (allTags.length === 0 && allPriorities.length === 0) return null;
|
|
324
|
+
|
|
325
|
+
return (
|
|
326
|
+
<div className="flex flex-wrap items-center gap-2 mb-4">
|
|
327
|
+
<Filter size={12} className="text-muted-foreground shrink-0" />
|
|
328
|
+
|
|
329
|
+
{/* Status filter */}
|
|
330
|
+
<div className="flex items-center rounded-lg border border-border overflow-hidden text-xs">
|
|
331
|
+
<button
|
|
332
|
+
onClick={() => onFilterChange({ ...filters, status: 'all' })}
|
|
333
|
+
className={`px-2.5 py-1 transition-colors ${filters.status === 'all' ? 'bg-muted text-foreground font-medium' : 'text-muted-foreground hover:bg-muted/50'}`}
|
|
334
|
+
>
|
|
335
|
+
All {counts.total}
|
|
336
|
+
</button>
|
|
337
|
+
<button
|
|
338
|
+
onClick={() => onFilterChange({ ...filters, status: 'todo' })}
|
|
339
|
+
className={`px-2.5 py-1 transition-colors border-l border-border ${filters.status === 'todo' ? 'bg-muted text-foreground font-medium' : 'text-muted-foreground hover:bg-muted/50'}`}
|
|
340
|
+
>
|
|
341
|
+
Todo {counts.todo}
|
|
342
|
+
</button>
|
|
343
|
+
<button
|
|
344
|
+
onClick={() => onFilterChange({ ...filters, status: 'in-progress' })}
|
|
345
|
+
className={`px-2.5 py-1 transition-colors border-l border-border ${filters.status === 'in-progress' ? 'bg-amber-500/10 text-amber-500 font-medium' : 'text-muted-foreground hover:bg-muted/50'}`}
|
|
346
|
+
>
|
|
347
|
+
In Progress {counts.inProgress}
|
|
348
|
+
</button>
|
|
349
|
+
<button
|
|
350
|
+
onClick={() => onFilterChange({ ...filters, status: 'done' })}
|
|
351
|
+
className={`px-2.5 py-1 transition-colors border-l border-border ${filters.status === 'done' ? 'bg-emerald-500/10 text-emerald-500 font-medium' : 'text-muted-foreground hover:bg-muted/50'}`}
|
|
352
|
+
>
|
|
353
|
+
Done {counts.done}
|
|
354
|
+
</button>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
{/* Priority filter */}
|
|
358
|
+
{allPriorities.length > 0 && (
|
|
359
|
+
<div className="flex items-center gap-1">
|
|
360
|
+
{allPriorities.map(p => {
|
|
361
|
+
if (!p) return null;
|
|
362
|
+
const s = PRIORITY_STYLES[p];
|
|
363
|
+
const active = filters.priority === p;
|
|
364
|
+
return (
|
|
365
|
+
<button
|
|
366
|
+
key={p}
|
|
367
|
+
onClick={() => onFilterChange({ ...filters, priority: active ? 'all' : p })}
|
|
368
|
+
className={`px-2 py-0.5 rounded text-xs font-mono font-medium border transition-colors ${
|
|
369
|
+
active
|
|
370
|
+
? `${s.bg} ${s.text} ${s.border}`
|
|
371
|
+
: 'border-transparent text-muted-foreground hover:bg-muted'
|
|
372
|
+
}`}
|
|
373
|
+
>
|
|
374
|
+
{p}
|
|
375
|
+
</button>
|
|
376
|
+
);
|
|
377
|
+
})}
|
|
378
|
+
</div>
|
|
379
|
+
)}
|
|
380
|
+
|
|
381
|
+
{/* Tag filter */}
|
|
382
|
+
{allTags.length > 0 && (
|
|
383
|
+
<div className="flex items-center gap-1">
|
|
384
|
+
{allTags.map(tag => {
|
|
385
|
+
const active = filters.tag === tag;
|
|
386
|
+
return (
|
|
387
|
+
<button
|
|
388
|
+
key={tag}
|
|
389
|
+
onClick={() => onFilterChange({ ...filters, tag: active ? 'all' : tag })}
|
|
390
|
+
className={`px-2 py-0.5 rounded-full text-xs transition-colors ${
|
|
391
|
+
active
|
|
392
|
+
? 'bg-[var(--amber)]/15 text-[var(--amber)]'
|
|
393
|
+
: 'text-muted-foreground hover:bg-muted'
|
|
394
|
+
}`}
|
|
395
|
+
>
|
|
396
|
+
#{tag}
|
|
397
|
+
</button>
|
|
398
|
+
);
|
|
399
|
+
})}
|
|
400
|
+
</div>
|
|
401
|
+
)}
|
|
402
|
+
|
|
403
|
+
{hasFilters && (
|
|
404
|
+
<button
|
|
405
|
+
onClick={() => onFilterChange({ priority: 'all', tag: 'all', status: 'all' })}
|
|
406
|
+
className="flex items-center gap-1 px-2 py-0.5 rounded text-xs text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
|
|
407
|
+
>
|
|
408
|
+
<X size={10} /> Clear
|
|
409
|
+
</button>
|
|
410
|
+
)}
|
|
411
|
+
</div>
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// ─── Components ──────────────────────────────────────────────────────────────
|
|
416
|
+
|
|
417
|
+
function PriorityBadge({ priority }: { priority: Priority }) {
|
|
418
|
+
if (!priority) return null;
|
|
419
|
+
const s = PRIORITY_STYLES[priority];
|
|
420
|
+
return (
|
|
421
|
+
<span className={`inline-flex items-center px-1.5 py-0 rounded text-[10px] font-mono font-semibold leading-4 border shrink-0 ${s.bg} ${s.text} ${s.border}`}>
|
|
422
|
+
{priority}
|
|
423
|
+
</span>
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function DueDateBadge({ dateStr, status }: { dateStr: string | null; status: TodoStatus }) {
|
|
428
|
+
if (!dateStr || status === 'done') return null;
|
|
429
|
+
const urgency = dateUrgency(dateStr);
|
|
430
|
+
if (!urgency) return null;
|
|
431
|
+
const s = DATE_STYLES[urgency];
|
|
432
|
+
return (
|
|
433
|
+
<span className={`inline-flex items-center gap-0.5 px-1.5 py-0 rounded text-[10px] leading-4 shrink-0 ${s.text} ${s.bg}`}>
|
|
434
|
+
<Calendar size={9} />
|
|
435
|
+
{dateStr}
|
|
436
|
+
</span>
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function TagBadge({ tag }: { tag: string }) {
|
|
441
|
+
return (
|
|
442
|
+
<span className="inline-flex items-center px-1.5 py-0 rounded-full text-[10px] leading-4 text-muted-foreground bg-muted/60 shrink-0">
|
|
443
|
+
#{tag}
|
|
444
|
+
</span>
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function StatusIcon({ status, onClick }: { status: TodoStatus; onClick: () => void }) {
|
|
449
|
+
return (
|
|
450
|
+
<button onClick={onClick} className="shrink-0 transition-colors" title="Click to cycle status">
|
|
451
|
+
{status === 'done' && (
|
|
452
|
+
<CheckSquare size={15} style={{ color: 'var(--amber)' }} />
|
|
453
|
+
)}
|
|
454
|
+
{status === 'in-progress' && (
|
|
455
|
+
<Circle size={15} className="text-amber-500 fill-amber-500/20" />
|
|
456
|
+
)}
|
|
457
|
+
{status === 'todo' && (
|
|
458
|
+
<Square size={15} style={{ color: 'var(--muted-foreground)' }} />
|
|
459
|
+
)}
|
|
460
|
+
</button>
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
142
464
|
// ─── Inline editable text ────────────────────────────────────────────────────
|
|
143
465
|
|
|
144
466
|
function InlineText({
|
|
145
467
|
text,
|
|
146
|
-
|
|
468
|
+
status,
|
|
147
469
|
onRename,
|
|
148
470
|
}: {
|
|
149
471
|
text: string;
|
|
150
|
-
|
|
472
|
+
status: TodoStatus;
|
|
151
473
|
onRename: (newText: string) => void;
|
|
152
474
|
}) {
|
|
153
475
|
const [editing, setEditing] = useState(false);
|
|
@@ -155,10 +477,7 @@ function InlineText({
|
|
|
155
477
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
156
478
|
|
|
157
479
|
useEffect(() => { setValue(text); }, [text]);
|
|
158
|
-
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
if (editing) inputRef.current?.select();
|
|
161
|
-
}, [editing]);
|
|
480
|
+
useEffect(() => { if (editing) inputRef.current?.select(); }, [editing]);
|
|
162
481
|
|
|
163
482
|
function commit() {
|
|
164
483
|
const trimmed = value.trim();
|
|
@@ -187,7 +506,13 @@ function InlineText({
|
|
|
187
506
|
|
|
188
507
|
return (
|
|
189
508
|
<span
|
|
190
|
-
className={`flex-1 text-sm leading-relaxed cursor-text min-w-0 ${
|
|
509
|
+
className={`flex-1 text-sm leading-relaxed cursor-text min-w-0 ${
|
|
510
|
+
status === 'done'
|
|
511
|
+
? 'line-through text-muted-foreground'
|
|
512
|
+
: status === 'in-progress'
|
|
513
|
+
? 'text-foreground'
|
|
514
|
+
: 'text-foreground'
|
|
515
|
+
}`}
|
|
191
516
|
onDoubleClick={() => setEditing(true)}
|
|
192
517
|
title="Double-click to edit"
|
|
193
518
|
>
|
|
@@ -196,16 +521,14 @@ function InlineText({
|
|
|
196
521
|
);
|
|
197
522
|
}
|
|
198
523
|
|
|
199
|
-
// ─── Add item input
|
|
524
|
+
// ─── Add item input ──────────────────────────────────────────────────────────
|
|
200
525
|
|
|
201
526
|
function AddItemRow({ onAdd }: { onAdd: (text: string) => void }) {
|
|
202
527
|
const [active, setActive] = useState(false);
|
|
203
528
|
const [value, setValue] = useState('');
|
|
204
529
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
205
530
|
|
|
206
|
-
useEffect(() => {
|
|
207
|
-
if (active) inputRef.current?.focus();
|
|
208
|
-
}, [active]);
|
|
531
|
+
useEffect(() => { if (active) inputRef.current?.focus(); }, [active]);
|
|
209
532
|
|
|
210
533
|
function commit() {
|
|
211
534
|
const trimmed = value.trim();
|
|
@@ -242,7 +565,7 @@ function AddItemRow({ onAdd }: { onAdd: (text: string) => void }) {
|
|
|
242
565
|
if (e.key === 'Enter') commit();
|
|
243
566
|
if (e.key === 'Escape') { setValue(''); setActive(false); }
|
|
244
567
|
}}
|
|
245
|
-
placeholder="New item…"
|
|
568
|
+
placeholder="New item… (supports `P0` `03-28` #tag)"
|
|
246
569
|
className="flex-1 bg-transparent border-b text-sm outline-none"
|
|
247
570
|
style={{ borderColor: 'var(--amber)', color: 'var(--foreground)' }}
|
|
248
571
|
/>
|
|
@@ -250,28 +573,51 @@ function AddItemRow({ onAdd }: { onAdd: (text: string) => void }) {
|
|
|
250
573
|
);
|
|
251
574
|
}
|
|
252
575
|
|
|
253
|
-
// ─── Todo item row
|
|
576
|
+
// ─── Todo item row ───────────────────────────────────────────────────────────
|
|
577
|
+
|
|
578
|
+
function matchesFilter(item: TodoItem, filters: FilterState): boolean {
|
|
579
|
+
if (filters.status !== 'all' && item.status !== filters.status) return false;
|
|
580
|
+
if (filters.priority !== 'all' && item.meta.priority !== filters.priority) return false;
|
|
581
|
+
if (filters.tag !== 'all' && !item.meta.tags.includes(filters.tag)) return false;
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function hasMatchingDescendant(item: TodoItem, filters: FilterState): boolean {
|
|
586
|
+
if (matchesFilter(item, filters)) return true;
|
|
587
|
+
return item.children.some(c => hasMatchingDescendant(c, filters));
|
|
588
|
+
}
|
|
254
589
|
|
|
255
590
|
function TodoItemRow({
|
|
256
591
|
item,
|
|
257
592
|
depth,
|
|
258
|
-
|
|
593
|
+
filters,
|
|
594
|
+
onCycleStatus,
|
|
259
595
|
onRename,
|
|
260
596
|
onDelete,
|
|
261
597
|
}: {
|
|
262
598
|
item: TodoItem;
|
|
263
599
|
depth: number;
|
|
264
|
-
|
|
600
|
+
filters: FilterState;
|
|
601
|
+
onCycleStatus: (lineIndex: number, newStatus: TodoStatus) => void;
|
|
265
602
|
onRename: (lineIndex: number, newText: string) => void;
|
|
266
603
|
onDelete: (lineIndex: number) => void;
|
|
267
604
|
}) {
|
|
268
605
|
const [open, setOpen] = useState(true);
|
|
269
606
|
const hasChildren = item.children.length > 0;
|
|
607
|
+
const selfMatch = matchesFilter(item, filters);
|
|
608
|
+
const childMatch = item.children.some(c => hasMatchingDescendant(c, filters));
|
|
609
|
+
const noFilter = filters.status === 'all' && filters.priority === 'all' && filters.tag === 'all';
|
|
610
|
+
|
|
611
|
+
if (!noFilter && !selfMatch && !childMatch) return null;
|
|
612
|
+
|
|
613
|
+
const urgency = dateUrgency(item.meta.dueDate);
|
|
270
614
|
|
|
271
615
|
return (
|
|
272
616
|
<div>
|
|
273
617
|
<div
|
|
274
|
-
className={`group flex items-center gap-2 py-1.5 px-2 rounded-lg transition-colors hover:bg-muted/60 ${
|
|
618
|
+
className={`group flex items-center gap-2 py-1.5 px-2 rounded-lg transition-colors hover:bg-muted/60 ${
|
|
619
|
+
item.status === 'done' ? 'opacity-45' : ''
|
|
620
|
+
} ${urgency === 'overdue' && item.status !== 'done' ? 'bg-red-500/[0.03]' : ''}`}
|
|
275
621
|
style={{ paddingLeft: `${8 + depth * 20}px` }}
|
|
276
622
|
>
|
|
277
623
|
{hasChildren ? (
|
|
@@ -285,20 +631,23 @@ function TodoItemRow({
|
|
|
285
631
|
<span className="w-[13px] shrink-0" />
|
|
286
632
|
)}
|
|
287
633
|
|
|
288
|
-
<
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
>
|
|
293
|
-
{item.checked ? <CheckSquare size={15} /> : <Square size={15} />}
|
|
294
|
-
</button>
|
|
634
|
+
<StatusIcon
|
|
635
|
+
status={item.status}
|
|
636
|
+
onClick={() => onCycleStatus(item.lineIndex, cycleStatus(item.status))}
|
|
637
|
+
/>
|
|
295
638
|
|
|
296
639
|
<InlineText
|
|
297
640
|
text={item.text}
|
|
298
|
-
|
|
641
|
+
status={item.status}
|
|
299
642
|
onRename={(newText) => onRename(item.lineIndex, newText)}
|
|
300
643
|
/>
|
|
301
644
|
|
|
645
|
+
<div className="flex items-center gap-1 shrink-0">
|
|
646
|
+
<PriorityBadge priority={item.meta.priority} />
|
|
647
|
+
<DueDateBadge dateStr={item.meta.dueDate} status={item.status} />
|
|
648
|
+
{item.meta.tags.map(tag => <TagBadge key={tag} tag={tag} />)}
|
|
649
|
+
</div>
|
|
650
|
+
|
|
302
651
|
<button
|
|
303
652
|
onClick={() => onDelete(item.lineIndex)}
|
|
304
653
|
className="shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-0.5 rounded hover:bg-destructive/10"
|
|
@@ -316,7 +665,8 @@ function TodoItemRow({
|
|
|
316
665
|
key={child.id}
|
|
317
666
|
item={child}
|
|
318
667
|
depth={depth + 1}
|
|
319
|
-
|
|
668
|
+
filters={filters}
|
|
669
|
+
onCycleStatus={onCycleStatus}
|
|
320
670
|
onRename={onRename}
|
|
321
671
|
onDelete={onDelete}
|
|
322
672
|
/>
|
|
@@ -327,28 +677,34 @@ function TodoItemRow({
|
|
|
327
677
|
);
|
|
328
678
|
}
|
|
329
679
|
|
|
330
|
-
// ─── Section card
|
|
680
|
+
// ─── Section card ────────────────────────────────────────────────────────────
|
|
331
681
|
|
|
332
682
|
function SectionCard({
|
|
333
683
|
name,
|
|
334
684
|
meta,
|
|
335
|
-
|
|
685
|
+
filters,
|
|
686
|
+
defaultCollapsed,
|
|
687
|
+
onCycleStatus,
|
|
336
688
|
onRename,
|
|
337
689
|
onDelete,
|
|
338
690
|
onAdd,
|
|
339
691
|
}: {
|
|
340
692
|
name: string;
|
|
341
693
|
meta: SectionMeta;
|
|
342
|
-
|
|
694
|
+
filters: FilterState;
|
|
695
|
+
defaultCollapsed?: boolean;
|
|
696
|
+
onCycleStatus: (lineIndex: number, newStatus: TodoStatus) => void;
|
|
343
697
|
onRename: (lineIndex: number, newText: string) => void;
|
|
344
698
|
onDelete: (lineIndex: number) => void;
|
|
345
699
|
onAdd: (afterLineIndex: number, text: string) => void;
|
|
346
700
|
}) {
|
|
347
|
-
const [collapsed, setCollapsed] = useState(false);
|
|
701
|
+
const [collapsed, setCollapsed] = useState(defaultCollapsed ?? false);
|
|
348
702
|
const style = sectionStyle(name);
|
|
349
703
|
const { items, lastLineIndex } = meta;
|
|
350
|
-
const done =
|
|
704
|
+
const done = countByStatus(items, 'done');
|
|
705
|
+
const inProgress = countByStatus(items, 'in-progress');
|
|
351
706
|
const total = countTotal(items);
|
|
707
|
+
const isDoneSection = name.includes('Done');
|
|
352
708
|
|
|
353
709
|
return (
|
|
354
710
|
<div className="border border-border rounded-xl overflow-hidden bg-card">
|
|
@@ -361,15 +717,28 @@ function SectionCard({
|
|
|
361
717
|
<span className={`text-xs font-semibold uppercase tracking-wider ${style.label} font-display`}>
|
|
362
718
|
{name}
|
|
363
719
|
</span>
|
|
364
|
-
<span className="text-xs text-muted-foreground">
|
|
720
|
+
<span className="text-xs text-muted-foreground tabular-nums">
|
|
721
|
+
{done}/{total}
|
|
722
|
+
</span>
|
|
723
|
+
{inProgress > 0 && (
|
|
724
|
+
<span className="flex items-center gap-0.5 text-[10px] text-amber-500">
|
|
725
|
+
<Clock size={9} /> {inProgress}
|
|
726
|
+
</span>
|
|
727
|
+
)}
|
|
365
728
|
</div>
|
|
366
|
-
{collapsed
|
|
729
|
+
{collapsed
|
|
730
|
+
? <ChevronRight size={14} className="text-muted-foreground" />
|
|
731
|
+
: <ChevronDown size={14} className="text-muted-foreground" />
|
|
732
|
+
}
|
|
367
733
|
</button>
|
|
368
734
|
|
|
369
735
|
<div className="h-0.5 bg-muted mx-4">
|
|
370
736
|
<div
|
|
371
737
|
className="h-full rounded-full transition-all duration-500"
|
|
372
|
-
style={{
|
|
738
|
+
style={{
|
|
739
|
+
width: total ? `${(done / total) * 100}%` : '0%',
|
|
740
|
+
background: isDoneSection ? 'var(--success, #22c55e)' : 'var(--amber)',
|
|
741
|
+
}}
|
|
373
742
|
/>
|
|
374
743
|
</div>
|
|
375
744
|
|
|
@@ -380,7 +749,8 @@ function SectionCard({
|
|
|
380
749
|
key={item.id}
|
|
381
750
|
item={item}
|
|
382
751
|
depth={0}
|
|
383
|
-
|
|
752
|
+
filters={filters}
|
|
753
|
+
onCycleStatus={onCycleStatus}
|
|
384
754
|
onRename={onRename}
|
|
385
755
|
onDelete={onDelete}
|
|
386
756
|
/>
|
|
@@ -388,39 +758,50 @@ function SectionCard({
|
|
|
388
758
|
{items.length === 0 && (
|
|
389
759
|
<p className="text-xs text-muted-foreground px-4 py-2">No items</p>
|
|
390
760
|
)}
|
|
391
|
-
|
|
761
|
+
{!isDoneSection && (
|
|
762
|
+
<AddItemRow onAdd={(text) => onAdd(lastLineIndex, text)} />
|
|
763
|
+
)}
|
|
392
764
|
</div>
|
|
393
765
|
)}
|
|
394
766
|
</div>
|
|
395
767
|
);
|
|
396
768
|
}
|
|
397
769
|
|
|
398
|
-
// ─── Main Renderer
|
|
770
|
+
// ─── Main Renderer ───────────────────────────────────────────────────────────
|
|
399
771
|
|
|
400
772
|
export function TodoRenderer({ content, saveAction }: RendererContext) {
|
|
401
773
|
const [localContent, setLocalContent] = useState(content);
|
|
774
|
+
const [filters, setFilters] = useState<FilterState>({ priority: 'all', tag: 'all', status: 'all' });
|
|
402
775
|
|
|
403
|
-
const { sections, lines } = useMemo(
|
|
776
|
+
const { sections, lines, sectionOrder } = useMemo(
|
|
404
777
|
() => parseMarkdownTodos(localContent),
|
|
405
778
|
[localContent],
|
|
406
779
|
);
|
|
407
780
|
|
|
408
781
|
const totalDone = useMemo(
|
|
409
|
-
() => Object.values(sections).reduce((n, m) => n +
|
|
782
|
+
() => Object.values(sections).reduce((n, m) => n + countByStatus(m.items, 'done'), 0),
|
|
783
|
+
[sections],
|
|
784
|
+
);
|
|
785
|
+
const totalInProgress = useMemo(
|
|
786
|
+
() => Object.values(sections).reduce((n, m) => n + countByStatus(m.items, 'in-progress'), 0),
|
|
410
787
|
[sections],
|
|
411
788
|
);
|
|
412
789
|
const totalItems = useMemo(
|
|
413
790
|
() => Object.values(sections).reduce((n, m) => n + countTotal(m.items), 0),
|
|
414
791
|
[sections],
|
|
415
792
|
);
|
|
793
|
+
const totalTodo = totalItems - totalDone - totalInProgress;
|
|
794
|
+
|
|
795
|
+
const allTags = useMemo(() => collectAllTags(sections), [sections]);
|
|
796
|
+
const allPriorities = useMemo(() => collectAllPriorities(sections), [sections]);
|
|
416
797
|
|
|
417
798
|
const persist = useCallback(async (next: string) => {
|
|
418
799
|
setLocalContent(next);
|
|
419
800
|
await saveAction(next);
|
|
420
801
|
}, [saveAction]);
|
|
421
802
|
|
|
422
|
-
const
|
|
423
|
-
await persist(
|
|
803
|
+
const handleCycleStatus = useCallback(async (lineIndex: number, newStatus: TodoStatus) => {
|
|
804
|
+
await persist(setStatusInLines(lines, lineIndex, newStatus));
|
|
424
805
|
}, [lines, persist]);
|
|
425
806
|
|
|
426
807
|
const handleRename = useCallback(async (lineIndex: number, newText: string) => {
|
|
@@ -435,23 +816,54 @@ export function TodoRenderer({ content, saveAction }: RendererContext) {
|
|
|
435
816
|
await persist(addInLines(lines, afterLineIndex, text));
|
|
436
817
|
}, [lines, persist]);
|
|
437
818
|
|
|
438
|
-
const sectionEntries =
|
|
819
|
+
const sectionEntries = sectionOrder
|
|
820
|
+
.filter(name => sections[name])
|
|
821
|
+
.map(name => [name, sections[name]] as [string, SectionMeta]);
|
|
822
|
+
|
|
823
|
+
const pct = totalItems ? Math.round((totalDone / totalItems) * 100) : 0;
|
|
439
824
|
|
|
440
825
|
return (
|
|
441
826
|
<div className="max-w-[900px] mx-auto xl:mr-[220px] px-0 py-2">
|
|
442
827
|
{/* Summary header */}
|
|
443
|
-
<div className="mb-
|
|
444
|
-
<
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
className="
|
|
450
|
-
|
|
451
|
-
|
|
828
|
+
<div className="mb-5 flex items-center gap-4">
|
|
829
|
+
<div className="flex-1">
|
|
830
|
+
<div className="flex items-baseline gap-2">
|
|
831
|
+
<span className="text-lg font-semibold font-display text-foreground tabular-nums">
|
|
832
|
+
{pct}%
|
|
833
|
+
</span>
|
|
834
|
+
<span className="text-xs text-muted-foreground font-display">
|
|
835
|
+
{totalDone}/{totalItems} completed
|
|
836
|
+
</span>
|
|
837
|
+
{totalInProgress > 0 && (
|
|
838
|
+
<span className="flex items-center gap-1 text-xs text-amber-500">
|
|
839
|
+
<Circle size={8} className="fill-amber-500/30" />
|
|
840
|
+
{totalInProgress} in progress
|
|
841
|
+
</span>
|
|
842
|
+
)}
|
|
843
|
+
</div>
|
|
844
|
+
<div className="mt-2 w-full max-w-xs h-1.5 bg-muted rounded-full overflow-hidden">
|
|
845
|
+
<div
|
|
846
|
+
className="h-full rounded-full transition-all duration-500"
|
|
847
|
+
style={{ width: `${pct}%`, background: 'var(--amber)' }}
|
|
848
|
+
/>
|
|
849
|
+
</div>
|
|
452
850
|
</div>
|
|
453
851
|
</div>
|
|
454
852
|
|
|
853
|
+
{/* Filter bar */}
|
|
854
|
+
<FilterBar
|
|
855
|
+
filters={filters}
|
|
856
|
+
onFilterChange={setFilters}
|
|
857
|
+
allTags={allTags}
|
|
858
|
+
allPriorities={allPriorities}
|
|
859
|
+
counts={{
|
|
860
|
+
todo: totalTodo,
|
|
861
|
+
inProgress: totalInProgress,
|
|
862
|
+
done: totalDone,
|
|
863
|
+
total: totalItems,
|
|
864
|
+
}}
|
|
865
|
+
/>
|
|
866
|
+
|
|
455
867
|
{/* Sections */}
|
|
456
868
|
<div className="flex flex-col gap-4">
|
|
457
869
|
{sectionEntries.map(([name, meta]) => (
|
|
@@ -459,7 +871,9 @@ export function TodoRenderer({ content, saveAction }: RendererContext) {
|
|
|
459
871
|
key={name}
|
|
460
872
|
name={name}
|
|
461
873
|
meta={meta}
|
|
462
|
-
|
|
874
|
+
filters={filters}
|
|
875
|
+
defaultCollapsed={name.includes('Done')}
|
|
876
|
+
onCycleStatus={handleCycleStatus}
|
|
463
877
|
onRename={handleRename}
|
|
464
878
|
onDelete={handleDelete}
|
|
465
879
|
onAdd={handleAdd}
|