wiki-viewer 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +6 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +40 -0
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/agent/activity/route.js +6 -6
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js +6 -6
- package/.next/standalone/.next/server/app/api/agent/admin/agents/[agentId]/revoke/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js +6 -6
- package/.next/standalone/.next/server/app/api/agent/admin/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js +7 -7
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/approve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/[regId]/deny/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js +5 -5
- package/.next/standalone/.next/server/app/api/agent/admin/registrations/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js +8 -7
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js +9 -8
- package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +8 -7
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js +7 -7
- package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +6 -5
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/search/route.js +7 -6
- package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/internal/span/route.js +6 -5
- package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/settings/route.js +7 -7
- package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js +8 -7
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js +2 -2
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js +8 -2
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/[...all]/route.js +5 -5
- package/.next/standalone/.next/server/app/api/auth/[...all]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/admins/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/system/admins/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/system/admins/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/system/admins/route.js +14 -0
- package/.next/standalone/.next/server/app/api/system/admins/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/system/admins/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/system/admins/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/system/auth-config/route.js +6 -6
- package/.next/standalone/.next/server/app/api/system/auth-config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/auth-settings/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/auth-settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/browse/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/clear-root/route.js +5 -5
- package/.next/standalone/.next/server/app/api/system/clear-root/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/config/route.js +6 -6
- package/.next/standalone/.next/server/app/api/system/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/pins/route.js +4 -4
- package/.next/standalone/.next/server/app/api/system/pins/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js +6 -6
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/root-status/route.js +5 -5
- package/.next/standalone/.next/server/app/api/system/root-status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/set-root/route.js +6 -6
- package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/users/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/system/users/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/system/users/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/system/users/route.js +14 -0
- package/.next/standalone/.next/server/app/api/system/users/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/system/users/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/system/users/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js +14 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js +14 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js +14 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/system/workspaces/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/upload/[...path]/route.js +8 -2
- package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/app/route.js +5 -5
- package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/content/route.js +6 -6
- package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/download/route.js +7 -7
- package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/file/route.js +8 -2
- package/.next/standalone/.next/server/app/api/wiki/file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js +6 -6
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/move/route.js +6 -6
- package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/new-file/route.js +7 -7
- package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/page/route.js +7 -7
- package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/presence/route.js +7 -7
- package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/route.js +6 -6
- package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/search/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route.js +15 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/wiki/slugs/route.js +6 -6
- package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/upload/route.js +7 -7
- package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js +7 -9
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/signin/page.js +1 -1
- package/.next/standalone/.next/server/app/signin/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +6 -0
- package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0d2jbo5.js +1 -1
- package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0ytral2.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-244bv._.js +16 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xz-_0v._.js → [root-of-the-server]__0-inabx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-ao6a_._.js → [root-of-the-server]__0.-9jt0._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0~-r-8f._.js → [root-of-the-server]__00c1-dr._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00lep-u._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00mtevo._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__00qu86p._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__012753j._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__01hp8ax._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0jhr.ex._.js → [root-of-the-server]__02n6z97._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__036mhjp._.js +5 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03p0ob1._.js +16 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05t~v6l._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__068ni_k._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__082nhm6._.js → [root-of-the-server]__07vphbd._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0pg6dn-._.js → [root-of-the-server]__08lkuwa._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__09cqzem._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0p_ox-k._.js → [root-of-the-server]__09k4q9e._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0_601._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ae3dk6._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0s28.4-._.js → [root-of-the-server]__0af-x45._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cqu-wm._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d75a5q._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7x3e1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d7zxm_._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0e7vs98._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fxzg4v._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gda_iu._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hu~q20._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jk1uf4._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-8clq._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lhka0x._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kdn1le._.js → [root-of-the-server]__0na11h0._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0nd.b_c._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0otb8ra._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0p0-p__._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0piofm3._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rrf-jr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s6_lzw._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sh13v5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ta~flu._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0v4im4p._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0qn8e~s._.js → [root-of-the-server]__0v_kyp-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vatqe-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vdb2nr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wdh63w._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z3wg9x._.js +12 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0mzo03s._.js → [root-of-the-server]__0~.-3yk._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__123._fe._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12800b1._.js → [root-of-the-server]__12ee_s6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12onytt._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04udrya._.js → [root-of-the-server]__12q8ch8._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1377.79._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1378-ox._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13aid91._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13hp4tw._.js +12 -0
- package/.next/standalone/.next/server/chunks/_079xuln._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0dr1r1g._.js +452 -0
- package/.next/standalone/.next/server/chunks/_101exke._.js +452 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_admins_route_actions_0dsm7cx.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_users_route_actions_0whj5cy.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_route_actions_0~h7-8s.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_route_actions_0mkalc3.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_search_route_actions_0inxu93.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules__pnpm_0aj5g-w._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_lib_search_0d-_j3u._.js +46 -0
- package/.next/standalone/.next/server/chunks/src_lib_search_0ymmp0c._.js +46 -0
- package/.next/standalone/.next/server/chunks/ssr/{0~w0_katex_dist_katex_mjs_0b8ra51._.js → 0~w0_katex_dist_katex_mjs_04mhawr._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_erDiagram-TEJ5UH35_mjs_0v6rnqy._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_mermaid_core_mjs_0hj_n-~._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0btcd4o._.js → [root-of-the-server]__02twzph._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ytvlzs._.js → [root-of-the-server]__09~x2v~._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0pqaawz._.js +18 -18
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0c71i8a._.js → node_modules__pnpm_0.96tmo._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0lm8e2c._.js → node_modules__pnpm_011vy_q._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ezm2us._.js → node_modules__pnpm_01o_5qt._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j3mvgg._.js → node_modules__pnpm_04n0h6.._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~ln0by._.js → node_modules__pnpm_093dp2q._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11e~j49._.js → node_modules__pnpm_09ej62_._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0de8xt-._.js → node_modules__pnpm_09ljbdz._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0-x6zex._.js → node_modules__pnpm_09~_ob2._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0yq5z.h._.js → node_modules__pnpm_0a01ng7._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0kwc-vs._.js → node_modules__pnpm_0b8qx0g._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hrbz84._.js → node_modules__pnpm_0bbc---._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hobcbs._.js → node_modules__pnpm_0c.309.._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0rw91-f._.js → node_modules__pnpm_0c8aunj._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0o.c1z8._.js → node_modules__pnpm_0hk6xys._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dboa_e._.js → node_modules__pnpm_0hlzy8f._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j53hti._.js → node_modules__pnpm_0nw5ou2._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0xrmzh1._.js → node_modules__pnpm_0o.dn8o._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cxwhfd._.js → node_modules__pnpm_0s0ur~d._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_07rxv2x._.js → node_modules__pnpm_0shlang._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0i.pw_m._.js → node_modules__pnpm_0sq3c2r._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ajzar9._.js → node_modules__pnpm_0t9jb7d._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_012nt.s._.js → node_modules__pnpm_0wmx9kq._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z~h2ow._.js → node_modules__pnpm_0xfx0sf._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0cbsnwf._.js → node_modules__pnpm_0yiz.-t._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0bum3-3._.js → node_modules__pnpm_11sut1u._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0mdo4i3._.js → node_modules__pnpm_124u4o2._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0il8j.j._.js → node_modules__pnpm_13tajgx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/src_app_signin_00yk0vm._.js +2 -2
- package/.next/standalone/.next/server/edge/chunks/{08yl_next_dist_esm_build_templates_edge-wrapper_0o9h3w_.js → 08yl_next_dist_esm_build_templates_edge-wrapper_0xbpts6.js} +2 -2
- package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0.pmgt2._.js +3 -0
- package/.next/standalone/.next/server/functions-config-manifest.json +6 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +8 -8
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/0c_~zevf2n0r4.css +2 -0
- package/.next/standalone/.next/static/chunks/0l4842ez-0_66.js +129 -0
- package/.next/standalone/README.md +46 -2
- package/.next/standalone/docs/workspacing-plan.md +364 -0
- package/.next/standalone/package.json +2 -2
- package/.next/standalone/src/app/api/agent/activity/route.ts +9 -8
- package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +20 -8
- package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +16 -9
- package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +28 -18
- package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +12 -7
- package/.next/standalone/src/app/api/agent/fs/move/route.ts +16 -11
- package/.next/standalone/src/app/api/agent/fs/search/route.ts +49 -13
- package/.next/standalone/src/app/api/agent/internal/span/route.ts +9 -5
- package/.next/standalone/src/app/api/agent/register/route.ts +9 -1
- package/.next/standalone/src/app/api/agent/settings/route.ts +7 -3
- package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +8 -4
- package/.next/standalone/src/app/api/assets/[...path]/route.ts +9 -4
- package/.next/standalone/src/app/api/system/admins/route.ts +103 -0
- package/.next/standalone/src/app/api/system/reveal/route.ts +7 -6
- package/.next/standalone/src/app/api/system/set-root/route.ts +24 -1
- package/.next/standalone/src/app/api/system/users/route.ts +120 -0
- package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +34 -0
- package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +74 -0
- package/.next/standalone/src/app/api/system/workspaces/route.ts +67 -0
- package/.next/standalone/src/app/api/upload/[...path]/route.ts +10 -5
- package/.next/standalone/src/app/api/wiki/app/route.ts +10 -9
- package/.next/standalone/src/app/api/wiki/content/route.ts +14 -14
- package/.next/standalone/src/app/api/wiki/download/route.ts +7 -6
- package/.next/standalone/src/app/api/wiki/file/route.ts +7 -2
- package/.next/standalone/src/app/api/wiki/folder/route.ts +6 -5
- package/.next/standalone/src/app/api/wiki/move/route.ts +7 -7
- package/.next/standalone/src/app/api/wiki/new-file/route.ts +7 -6
- package/.next/standalone/src/app/api/wiki/page/route.ts +6 -5
- package/.next/standalone/src/app/api/wiki/presence/route.ts +8 -7
- package/.next/standalone/src/app/api/wiki/route.ts +13 -11
- package/.next/standalone/src/app/api/wiki/search/route.ts +44 -0
- package/.next/standalone/src/app/api/wiki/slugs/route.ts +8 -8
- package/.next/standalone/src/app/api/wiki/upload/route.ts +6 -5
- package/.next/standalone/src/app/api/wiki/watch/route.ts +16 -40
- package/.next/standalone/src/app/globals.css +484 -484
- package/.next/standalone/src/app/page.tsx +163 -49
- package/.next/standalone/src/components/auth-settings-sheet.tsx +171 -2
- package/.next/standalone/src/components/dir-picker.tsx +8 -6
- package/.next/standalone/src/components/editor/comment-thread.tsx +2 -1
- package/.next/standalone/src/components/editor/csv-viewer.tsx +3 -2
- package/.next/standalone/src/components/editor/editor-toolbar.tsx +2 -2
- package/.next/standalone/src/components/editor/editor.tsx +6 -5
- package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +3 -2
- package/.next/standalone/src/components/editor/folder-index.tsx +2 -1
- package/.next/standalone/src/components/editor/image-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/media-popover.tsx +2 -1
- package/.next/standalone/src/components/editor/media-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/mermaid-viewer.tsx +3 -2
- package/.next/standalone/src/components/editor/node-app-viewer.tsx +4 -3
- package/.next/standalone/src/components/editor/notebook-viewer.tsx +3 -2
- package/.next/standalone/src/components/editor/office/docx-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/office/office-chrome.tsx +3 -2
- package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/pdf-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/proof-span-popover.tsx +2 -1
- package/.next/standalone/src/components/editor/source-viewer.tsx +3 -2
- package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +2 -1
- package/.next/standalone/src/components/editor/suggestion-card.tsx +2 -1
- package/.next/standalone/src/components/editor/website-viewer.tsx +2 -1
- package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +2 -1
- package/.next/standalone/src/components/search/search-command-dialog.tsx +109 -0
- package/.next/standalone/src/components/search/sidebar-search-box.tsx +121 -0
- package/.next/standalone/src/components/search/snippet-text.tsx +48 -0
- package/.next/standalone/src/components/ui/command.tsx +3 -2
- package/.next/standalone/src/lib/auth/admin.ts +112 -0
- package/.next/standalone/src/lib/auth/server.ts +13 -2
- package/.next/standalone/src/lib/config.ts +56 -4
- package/.next/standalone/src/lib/proof/audit.ts +19 -10
- package/.next/standalone/src/lib/proof/auth.ts +11 -0
- package/.next/standalone/src/lib/proof/collab-state.ts +4 -2
- package/.next/standalone/src/lib/proof/file-lock.ts +5 -0
- package/.next/standalone/src/lib/proof/idempotency.ts +5 -0
- package/.next/standalone/src/lib/proof/lease.ts +40 -27
- package/.next/standalone/src/lib/proof/mutex.ts +4 -0
- package/.next/standalone/src/lib/proof/raw-fs.ts +2 -3
- package/.next/standalone/src/lib/proof/registry.ts +5 -0
- package/.next/standalone/src/lib/search/indexable-exts.ts +25 -0
- package/.next/standalone/src/lib/search/indexer.ts +567 -0
- package/.next/standalone/src/lib/search/sanitize.ts +35 -0
- package/.next/standalone/src/lib/search/search-db.ts +57 -0
- package/.next/standalone/src/lib/search/watcher-pool.ts +79 -0
- package/.next/standalone/src/lib/workspace-client.ts +82 -0
- package/.next/standalone/src/lib/workspace-context.ts +142 -0
- package/.next/standalone/src/lib/workspaces.ts +196 -0
- package/.next/standalone/src/stores/ai-panel-store.ts +3 -2
- package/.next/standalone/src/stores/editor-store.ts +4 -3
- package/.next/standalone/src/stores/proof-store.ts +4 -3
- package/.next/standalone/src/stores/search-store.ts +86 -0
- package/.next/standalone/src/stores/wiki-slugs-store.ts +2 -1
- package/.next/standalone/src/tests/proof/admin-create-user.test.ts +43 -0
- package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +134 -0
- package/.next/standalone/src/tests/proof/collab-state.test.ts +43 -41
- package/.next/standalone/src/tests/proof/preload.ts +21 -0
- package/.next/standalone/src/tests/proof/search-index.test.ts +339 -0
- package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +87 -0
- package/.next/standalone/src/tests/proof/workspaces-api.test.ts +227 -0
- package/.next/standalone/tsconfig.tsbuildinfo +1 -1
- package/README.md +46 -2
- package/package.json +2 -2
- package/.next/standalone/.next/server/chunks/0p91_next_dist_esm_build_templates_app-route_0o~h4zq.js +0 -5
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.hb9q2._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.uux34._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0092hkp._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05f6x0i._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__05idwm9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06-dtd0._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06sek6_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07fpqks._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__094q5bj._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0awzyon._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d_da6q._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0hhhvm7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kk26wc._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0km8suj._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kur4ro._.js +0 -15
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0mkwoul._.js +0 -12
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qc2~6l._.js +0 -15
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qyd-o8._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rkve~v._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rzo40z._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sjocwy._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ssj9~d._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0s~i040._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t220d-._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t5mg.n._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0trsqf4._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xq124z._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__106uw_c._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10w2q~o._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13w-0iy._.js +0 -3
- package/.next/standalone/.next/server/chunks/src_lib_auth_server_ts_00f4e0h._.js +0 -452
- package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__0ug2rvl._.js +0 -3
- package/.next/standalone/.next/static/chunks/0vwkqw_rofm-c.js +0 -129
- package/.next/standalone/.next/static/chunks/0zay6349~v_wc.css +0 -2
- /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{0XvNCOSEq7cbARTLtAolL → t7B6nXaoD1jo9f61t3aeK}/_ssgManifest.js +0 -0
|
@@ -50,8 +50,10 @@ import {
|
|
|
50
50
|
DropdownMenu,
|
|
51
51
|
DropdownMenuContent,
|
|
52
52
|
DropdownMenuItem,
|
|
53
|
+
DropdownMenuSeparator,
|
|
53
54
|
DropdownMenuTrigger,
|
|
54
55
|
} from "@/components/ui/dropdown-menu";
|
|
56
|
+
import { getActiveWorkspaceId, withWs, wsFetch } from "@/lib/workspace-client";
|
|
55
57
|
import { ThemeToggle } from "@/components/theme-toggle";
|
|
56
58
|
import { AuthSettingsSheet } from "@/components/auth-settings-sheet";
|
|
57
59
|
import { Button } from "@/components/ui/button";
|
|
@@ -63,6 +65,8 @@ import { parseFrontmatter } from "@/lib/markdown/parse-frontmatter";
|
|
|
63
65
|
import { showError } from "@/lib/toast";
|
|
64
66
|
import { cn } from "@/lib/utils";
|
|
65
67
|
import { AIPanel } from "@/components/ai-panel/ai-panel";
|
|
68
|
+
import { SearchCommandDialog } from "@/components/search/search-command-dialog";
|
|
69
|
+
import { SidebarSearchBox } from "@/components/search/sidebar-search-box";
|
|
66
70
|
import { useAIPanelStore } from "@/stores/ai-panel-store";
|
|
67
71
|
import { useEditorStore } from "@/stores/editor-store";
|
|
68
72
|
import { useViewWidthStore, VIEW_WIDTH_CLASS } from "@/stores/view-width-store";
|
|
@@ -168,7 +172,7 @@ function isHtmlFile(name: string) {
|
|
|
168
172
|
}
|
|
169
173
|
|
|
170
174
|
async function fetchDir(dir: string): Promise<TreeNode[]> {
|
|
171
|
-
const res = await
|
|
175
|
+
const res = await wsFetch(`/api/wiki?dir=${encodeURIComponent(dir)}`);
|
|
172
176
|
if (!res.ok) return [];
|
|
173
177
|
const data: {
|
|
174
178
|
entries: Array<{
|
|
@@ -219,17 +223,47 @@ export default function Page() {
|
|
|
219
223
|
// null = checking, false = not set, true = ready
|
|
220
224
|
const [rootConfigured, setRootConfigured] = useState<boolean | null>(null);
|
|
221
225
|
const [rootPath, setRootPath] = useState<string | null>(null);
|
|
226
|
+
// Workspace state
|
|
227
|
+
const [activeWorkspaceId, setActiveWorkspaceId] = useState<string | null>(() =>
|
|
228
|
+
typeof window !== "undefined" ? getActiveWorkspaceId() : null
|
|
229
|
+
);
|
|
230
|
+
const [workspaces, setWorkspaces] = useState<Array<{id:string;name:string;rootDir:string;lastOpenedAt?:string;createdAt:string}>>([]);
|
|
231
|
+
const [isWsAdmin, setIsWsAdmin] = useState(false);
|
|
232
|
+
const [addingWorkspace, setAddingWorkspace] = useState(false);
|
|
222
233
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
.
|
|
234
|
+
const loadWorkspaces = useCallback(async () => {
|
|
235
|
+
try {
|
|
236
|
+
const res = await fetch("/api/system/workspaces");
|
|
237
|
+
if (!res.ok) throw new Error("Failed");
|
|
238
|
+
const d: { workspaces: Array<{id:string;name:string;rootDir:string;lastOpenedAt?:string;createdAt:string}>; isAdmin: boolean } = await res.json();
|
|
239
|
+
setWorkspaces(d.workspaces);
|
|
240
|
+
setIsWsAdmin(d.isAdmin);
|
|
241
|
+
if (d.workspaces.length > 0) {
|
|
242
|
+
setRootConfigured(true);
|
|
243
|
+
const urlWsId = new URLSearchParams(window.location.search).get("ws");
|
|
244
|
+
const inList = urlWsId ? d.workspaces.find((w) => w.id === urlWsId) : null;
|
|
245
|
+
const active = inList ?? [...d.workspaces].sort(
|
|
246
|
+
(a, b) => (b.lastOpenedAt ?? b.createdAt).localeCompare(a.lastOpenedAt ?? a.createdAt)
|
|
247
|
+
)[0];
|
|
248
|
+
setActiveWorkspaceId(active.id);
|
|
249
|
+
setRootPath(active.rootDir);
|
|
250
|
+
if (!inList) {
|
|
251
|
+
const u = new URL(location.href);
|
|
252
|
+
u.searchParams.set("ws", active.id);
|
|
253
|
+
history.replaceState(null, "", u.toString());
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
setRootConfigured(false);
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
setRootConfigured(false);
|
|
260
|
+
}
|
|
231
261
|
}, []);
|
|
232
262
|
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
void loadWorkspaces();
|
|
265
|
+
}, [loadWorkspaces]);
|
|
266
|
+
|
|
233
267
|
const editorCurrentPath = useEditorStore((s) => s.currentPath);
|
|
234
268
|
|
|
235
269
|
// Path captured from the URL at first render, before any effect can clear it.
|
|
@@ -407,7 +441,7 @@ export default function Page() {
|
|
|
407
441
|
if (!["editor", "text"].includes(kind) && !isText(openFile.name)) return;
|
|
408
442
|
setFileLoading(true);
|
|
409
443
|
try {
|
|
410
|
-
const res = await
|
|
444
|
+
const res = await wsFetch(
|
|
411
445
|
`/api/wiki/content?path=${encodeURIComponent(openFile.path)}`,
|
|
412
446
|
);
|
|
413
447
|
if (res.ok) {
|
|
@@ -449,7 +483,7 @@ export default function Page() {
|
|
|
449
483
|
);
|
|
450
484
|
}
|
|
451
485
|
|
|
452
|
-
const es = new EventSource("/api/wiki/watch");
|
|
486
|
+
const es = new EventSource(withWs("/api/wiki/watch"));
|
|
453
487
|
|
|
454
488
|
es.onmessage = (event) => {
|
|
455
489
|
let data: { type: string; path: string };
|
|
@@ -544,7 +578,7 @@ export default function Page() {
|
|
|
544
578
|
if (!["editor", "text"].includes(kind) && !isText(node.name)) return;
|
|
545
579
|
setFileLoading(true);
|
|
546
580
|
try {
|
|
547
|
-
const res = await
|
|
581
|
+
const res = await wsFetch(
|
|
548
582
|
`/api/wiki/content?path=${encodeURIComponent(node.path)}`,
|
|
549
583
|
);
|
|
550
584
|
if (res.ok) {
|
|
@@ -558,6 +592,16 @@ export default function Page() {
|
|
|
558
592
|
setFileLoading(false);
|
|
559
593
|
}
|
|
560
594
|
|
|
595
|
+
// Open a file from a search result: reveal it in the tree, then open it.
|
|
596
|
+
const openFromSearch = useCallback(
|
|
597
|
+
(relPath: string) => {
|
|
598
|
+
const name = relPath.split("/").pop() ?? relPath;
|
|
599
|
+
void revealPath(relPath);
|
|
600
|
+
void openViewer({ path: relPath, name, type: "file" } as TreeNode);
|
|
601
|
+
},
|
|
602
|
+
[revealPath],
|
|
603
|
+
);
|
|
604
|
+
|
|
561
605
|
// biome-ignore lint/correctness/useExhaustiveDependencies: only react to editor path changes
|
|
562
606
|
useEffect(() => {
|
|
563
607
|
if (!editorCurrentPath) return;
|
|
@@ -610,23 +654,35 @@ export default function Page() {
|
|
|
610
654
|
})();
|
|
611
655
|
}, [rootLoaded, revealPath]);
|
|
612
656
|
|
|
613
|
-
const
|
|
614
|
-
|
|
657
|
+
const switchWorkspace = useCallback(async (id: string) => {
|
|
658
|
+
if (id === activeWorkspaceId) return;
|
|
659
|
+
try {
|
|
660
|
+
await fetch(`/api/system/workspaces/${id}/open`, { method: "POST" });
|
|
661
|
+
} catch {
|
|
662
|
+
/* best-effort lastOpened bump */
|
|
663
|
+
}
|
|
664
|
+
const u = new URL(location.href);
|
|
665
|
+
u.searchParams.set("ws", id);
|
|
666
|
+
u.searchParams.delete("path");
|
|
667
|
+
history.pushState(null, "", u.toString());
|
|
668
|
+
// Reset open file + caches; the key={activeWorkspaceId} remount clears the rest.
|
|
615
669
|
setOpenFile(null);
|
|
616
670
|
setFileContent(null);
|
|
617
671
|
setEditing(false);
|
|
618
672
|
setRoots([]);
|
|
619
673
|
setRootLoaded(false);
|
|
620
674
|
rootLoadingRef.current = false;
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
675
|
+
useWikiSlugsStore.getState().invalidate();
|
|
676
|
+
const ws = workspaces.find((w) => w.id === id);
|
|
677
|
+
if (ws) setRootPath(ws.rootDir);
|
|
678
|
+
setActiveWorkspaceId(id);
|
|
679
|
+
}, [activeWorkspaceId, workspaces]);
|
|
624
680
|
|
|
625
681
|
async function handleSave() {
|
|
626
682
|
if (!openFile) return;
|
|
627
683
|
setSaving(true);
|
|
628
684
|
setSaveError(null);
|
|
629
|
-
const res = await
|
|
685
|
+
const res = await wsFetch("/api/wiki/content", {
|
|
630
686
|
method: "PUT",
|
|
631
687
|
headers: { "Content-Type": "application/json" },
|
|
632
688
|
body: JSON.stringify({
|
|
@@ -658,7 +714,7 @@ export default function Page() {
|
|
|
658
714
|
const fd = new FormData();
|
|
659
715
|
fd.append("file", file);
|
|
660
716
|
fd.append("dir", dir);
|
|
661
|
-
const res = await
|
|
717
|
+
const res = await wsFetch("/api/wiki/upload", {
|
|
662
718
|
method: "POST",
|
|
663
719
|
body: fd,
|
|
664
720
|
});
|
|
@@ -690,7 +746,7 @@ export default function Page() {
|
|
|
690
746
|
if (!name || newFolderParent === null) return;
|
|
691
747
|
setFolderError(null);
|
|
692
748
|
const rel = newFolderParent ? `${newFolderParent}/${name}` : name;
|
|
693
|
-
const res = await
|
|
749
|
+
const res = await wsFetch("/api/wiki/folder", {
|
|
694
750
|
method: "POST",
|
|
695
751
|
headers: { "Content-Type": "application/json" },
|
|
696
752
|
body: JSON.stringify({ path: rel }),
|
|
@@ -716,7 +772,7 @@ export default function Page() {
|
|
|
716
772
|
setFileCreateError(null);
|
|
717
773
|
const name = raw.includes(".") ? raw : `${raw}.md`;
|
|
718
774
|
const rel = newFileParent ? `${newFileParent}/${name}` : name;
|
|
719
|
-
const res = await
|
|
775
|
+
const res = await wsFetch("/api/wiki/new-file", {
|
|
720
776
|
method: "POST",
|
|
721
777
|
headers: { "Content-Type": "application/json" },
|
|
722
778
|
body: JSON.stringify({ path: rel }),
|
|
@@ -744,7 +800,7 @@ export default function Page() {
|
|
|
744
800
|
}
|
|
745
801
|
|
|
746
802
|
function handleDownload(node: TreeNode) {
|
|
747
|
-
const url = `/api/wiki/download?path=${encodeURIComponent(node.path)}
|
|
803
|
+
const url = withWs(`/api/wiki/download?path=${encodeURIComponent(node.path)}`);
|
|
748
804
|
const a = document.createElement("a");
|
|
749
805
|
a.href = url;
|
|
750
806
|
a.download = node.type === "file" ? node.name : `${node.name}.zip`;
|
|
@@ -755,7 +811,7 @@ export default function Page() {
|
|
|
755
811
|
|
|
756
812
|
async function handleDelete() {
|
|
757
813
|
if (!deletingPath) return;
|
|
758
|
-
await
|
|
814
|
+
await wsFetch("/api/wiki", {
|
|
759
815
|
method: "DELETE",
|
|
760
816
|
headers: { "Content-Type": "application/json" },
|
|
761
817
|
body: JSON.stringify({ path: deletingPath }),
|
|
@@ -811,7 +867,7 @@ export default function Page() {
|
|
|
811
867
|
const newPath = targetDirPath ? `${targetDirPath}/${node.name}` : node.name;
|
|
812
868
|
if (newPath === node.path) return;
|
|
813
869
|
|
|
814
|
-
const res = await
|
|
870
|
+
const res = await wsFetch("/api/wiki/move", {
|
|
815
871
|
method: "POST",
|
|
816
872
|
headers: { "Content-Type": "application/json" },
|
|
817
873
|
body: JSON.stringify({ from: node.path, to: newPath }),
|
|
@@ -876,8 +932,8 @@ export default function Page() {
|
|
|
876
932
|
className={cn(
|
|
877
933
|
"flex items-center gap-1.5 rounded-sm px-2 py-1 text-sm cursor-pointer group transition-colors select-none",
|
|
878
934
|
openFile?.path === node.path
|
|
879
|
-
? "bg-accent text-
|
|
880
|
-
: "hover:bg-
|
|
935
|
+
? "bg-accent-soft text-foreground font-medium"
|
|
936
|
+
: "hover:bg-muted",
|
|
881
937
|
dragOverPath === node.path && "ring-2 ring-primary bg-primary-soft",
|
|
882
938
|
node.name.startsWith(".") && "opacity-40",
|
|
883
939
|
)}
|
|
@@ -907,17 +963,17 @@ export default function Page() {
|
|
|
907
963
|
<Folder className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-warning")} />
|
|
908
964
|
)
|
|
909
965
|
) : node.type === "app" ? (
|
|
910
|
-
<Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-
|
|
966
|
+
<Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/70")} />
|
|
911
967
|
) : node.type === "node-app" ? (
|
|
912
968
|
<Terminal className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-emerald-500")} />
|
|
913
969
|
) : isHtmlFile(node.name) ? (
|
|
914
|
-
<Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-
|
|
970
|
+
<Globe className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/60")} />
|
|
915
971
|
) : isImage(node.name) ? (
|
|
916
972
|
<ImageIcon className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-sunshine-700")} />
|
|
917
973
|
) : isText(node.name) ? (
|
|
918
|
-
<FileText className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-
|
|
974
|
+
<FileText className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/70")} />
|
|
919
975
|
) : (
|
|
920
|
-
<File className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-
|
|
976
|
+
<File className={cn("h-4 w-4 shrink-0", openFile?.path !== node.path && "text-foreground/60")} />
|
|
921
977
|
)}
|
|
922
978
|
|
|
923
979
|
<span className="flex-1 truncate">{node.name}</span>
|
|
@@ -1104,21 +1160,41 @@ export default function Page() {
|
|
|
1104
1160
|
}
|
|
1105
1161
|
|
|
1106
1162
|
return (
|
|
1107
|
-
<div className="flex h-screen gap-0 overflow-hidden bg-background">
|
|
1163
|
+
<div key={activeWorkspaceId ?? "none"} className="flex h-screen gap-0 overflow-hidden bg-background">
|
|
1108
1164
|
{rootConfigured === null && (
|
|
1109
1165
|
<div className="flex-1 flex items-center justify-center">
|
|
1110
1166
|
<Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
|
|
1111
1167
|
</div>
|
|
1112
1168
|
)}
|
|
1113
1169
|
{rootConfigured === false && (
|
|
1114
|
-
<DirPicker onSelect={(
|
|
1170
|
+
<DirPicker onSelect={(workspaceId) => {
|
|
1171
|
+
const u = new URL(location.href);
|
|
1172
|
+
u.searchParams.set("ws", workspaceId);
|
|
1173
|
+
u.searchParams.delete("path");
|
|
1174
|
+
history.replaceState(null, "", u.toString());
|
|
1115
1175
|
setRootLoaded(false);
|
|
1116
1176
|
rootLoadingRef.current = false;
|
|
1117
|
-
|
|
1177
|
+
setActiveWorkspaceId(workspaceId);
|
|
1118
1178
|
setRootConfigured(true);
|
|
1179
|
+
void loadWorkspaces();
|
|
1119
1180
|
}} />
|
|
1120
1181
|
)}
|
|
1121
|
-
{rootConfigured === true &&
|
|
1182
|
+
{rootConfigured === true && addingWorkspace && (
|
|
1183
|
+
<div className="flex-1 flex flex-col">
|
|
1184
|
+
<div className="flex items-center justify-end border-b px-3 py-2 bg-muted shrink-0">
|
|
1185
|
+
<Button size="sm" variant="ghost" className="h-7 gap-1.5 text-xs" onClick={() => setAddingWorkspace(false)}>
|
|
1186
|
+
<X className="h-3.5 w-3.5" /> Cancel
|
|
1187
|
+
</Button>
|
|
1188
|
+
</div>
|
|
1189
|
+
<DirPicker onSelect={(workspaceId) => {
|
|
1190
|
+
setAddingWorkspace(false);
|
|
1191
|
+
void loadWorkspaces();
|
|
1192
|
+
void switchWorkspace(workspaceId);
|
|
1193
|
+
}} />
|
|
1194
|
+
</div>
|
|
1195
|
+
)}
|
|
1196
|
+
{rootConfigured === true && !addingWorkspace && <>
|
|
1197
|
+
<SearchCommandDialog onOpenFile={openFromSearch} />
|
|
1122
1198
|
{/* Tree sidebar */}
|
|
1123
1199
|
{!sidebarCollapsed && (
|
|
1124
1200
|
<Card className="flex flex-col w-72 shrink-0 overflow-hidden rounded-none border-r border-l-0 border-t-0 border-b-0">
|
|
@@ -1318,6 +1394,10 @@ export default function Page() {
|
|
|
1318
1394
|
</div>
|
|
1319
1395
|
)}
|
|
1320
1396
|
|
|
1397
|
+
<div className="border-b">
|
|
1398
|
+
<SidebarSearchBox onOpenFile={openFromSearch} />
|
|
1399
|
+
</div>
|
|
1400
|
+
|
|
1321
1401
|
<div
|
|
1322
1402
|
className={cn(
|
|
1323
1403
|
"flex-1 overflow-auto py-1",
|
|
@@ -1365,21 +1445,55 @@ export default function Page() {
|
|
|
1365
1445
|
renderNodes(roots)
|
|
1366
1446
|
)}
|
|
1367
1447
|
</div>
|
|
1368
|
-
<div className="border-t px-
|
|
1369
|
-
<
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1448
|
+
<div className="border-t px-2 py-2 bg-muted shrink-0">
|
|
1449
|
+
<DropdownMenu>
|
|
1450
|
+
<DropdownMenuTrigger asChild>
|
|
1451
|
+
<Button
|
|
1452
|
+
size="sm"
|
|
1453
|
+
variant="ghost"
|
|
1454
|
+
className="w-full h-auto justify-between gap-2 px-2 py-1.5 text-left"
|
|
1455
|
+
title={rootPath ?? ""}
|
|
1456
|
+
>
|
|
1457
|
+
<span className="flex flex-col min-w-0">
|
|
1458
|
+
<span className="truncate text-xs font-medium">
|
|
1459
|
+
{workspaces.find((w) => w.id === activeWorkspaceId)?.name ?? "Workspace"}
|
|
1460
|
+
</span>
|
|
1461
|
+
<span className="truncate text-[10px] text-muted-foreground font-mono">
|
|
1462
|
+
{rootPath ?? ""}
|
|
1463
|
+
</span>
|
|
1464
|
+
</span>
|
|
1465
|
+
<ChevronDown className="h-3.5 w-3.5 shrink-0 opacity-60" />
|
|
1466
|
+
</Button>
|
|
1467
|
+
</DropdownMenuTrigger>
|
|
1468
|
+
<DropdownMenuContent align="start" className="w-60">
|
|
1469
|
+
{workspaces.map((w) => (
|
|
1470
|
+
<DropdownMenuItem
|
|
1471
|
+
key={w.id}
|
|
1472
|
+
onClick={() => void switchWorkspace(w.id)}
|
|
1473
|
+
className={cn("gap-2", w.id === activeWorkspaceId && "font-medium")}
|
|
1474
|
+
>
|
|
1475
|
+
{w.id === activeWorkspaceId ? (
|
|
1476
|
+
<Check className="h-3.5 w-3.5 shrink-0" />
|
|
1477
|
+
) : (
|
|
1478
|
+
<span className="w-3.5 shrink-0" />
|
|
1479
|
+
)}
|
|
1480
|
+
<span className="flex flex-col min-w-0">
|
|
1481
|
+
<span className="truncate">{w.name}</span>
|
|
1482
|
+
<span className="truncate text-[10px] text-muted-foreground font-mono">{w.rootDir}</span>
|
|
1483
|
+
</span>
|
|
1484
|
+
</DropdownMenuItem>
|
|
1485
|
+
))}
|
|
1486
|
+
{isWsAdmin && (
|
|
1487
|
+
<>
|
|
1488
|
+
<DropdownMenuSeparator />
|
|
1489
|
+
<DropdownMenuItem onClick={() => setAddingWorkspace(true)}>
|
|
1490
|
+
<FolderPlus className="mr-2 h-3.5 w-3.5" />
|
|
1491
|
+
Add workspace…
|
|
1492
|
+
</DropdownMenuItem>
|
|
1493
|
+
</>
|
|
1494
|
+
)}
|
|
1495
|
+
</DropdownMenuContent>
|
|
1496
|
+
</DropdownMenu>
|
|
1383
1497
|
</div>
|
|
1384
1498
|
</Card>
|
|
1385
1499
|
)}
|
|
@@ -43,6 +43,32 @@ export function AuthSettingsSheet({
|
|
|
43
43
|
const [rateLimit, setRateLimit] = useState<number | null>(null);
|
|
44
44
|
const { data: session } = authClient.useSession();
|
|
45
45
|
|
|
46
|
+
// Admin management
|
|
47
|
+
const [isAdmin, setIsAdmin] = useState(false);
|
|
48
|
+
const [admins, setAdmins] = useState<string[]>([]);
|
|
49
|
+
const [adminUsers, setAdminUsers] = useState<Array<{ id: string; email: string; name: string }>>([]);
|
|
50
|
+
const [adminError, setAdminError] = useState<string | null>(null);
|
|
51
|
+
const [adminWorking, setAdminWorking] = useState<string | null>(null);
|
|
52
|
+
// Add-user form
|
|
53
|
+
const [newUserEmail, setNewUserEmail] = useState("");
|
|
54
|
+
const [newUserName, setNewUserName] = useState("");
|
|
55
|
+
const [creatingUser, setCreatingUser] = useState(false);
|
|
56
|
+
const [createdUser, setCreatedUser] = useState<{ email: string; tempPassword: string } | null>(null);
|
|
57
|
+
|
|
58
|
+
const loadAdmins = useCallback(async () => {
|
|
59
|
+
try {
|
|
60
|
+
const res = await fetch("/api/system/admins");
|
|
61
|
+
if (!res.ok) return;
|
|
62
|
+
const d: { admins?: string[]; isAdmin?: boolean; users?: Array<{ id: string; email: string; name: string }> } =
|
|
63
|
+
await res.json();
|
|
64
|
+
setIsAdmin(!!d.isAdmin);
|
|
65
|
+
setAdmins(d.admins ?? []);
|
|
66
|
+
setAdminUsers(d.users ?? []);
|
|
67
|
+
} catch {
|
|
68
|
+
/* ignore */
|
|
69
|
+
}
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
46
72
|
const load = useCallback(async () => {
|
|
47
73
|
setLoading(true);
|
|
48
74
|
setError(null);
|
|
@@ -62,8 +88,11 @@ export function AuthSettingsSheet({
|
|
|
62
88
|
}, []);
|
|
63
89
|
|
|
64
90
|
useEffect(() => {
|
|
65
|
-
if (open)
|
|
66
|
-
|
|
91
|
+
if (open) {
|
|
92
|
+
void load();
|
|
93
|
+
void loadAdmins();
|
|
94
|
+
}
|
|
95
|
+
}, [open, load, loadAdmins]);
|
|
67
96
|
|
|
68
97
|
async function handleSave() {
|
|
69
98
|
setSaving(true);
|
|
@@ -228,6 +257,146 @@ export function AuthSettingsSheet({
|
|
|
228
257
|
)}
|
|
229
258
|
</section>
|
|
230
259
|
|
|
260
|
+
{/* Admins — only visible to admins */}
|
|
261
|
+
{isAdmin && (
|
|
262
|
+
<section className="space-y-2">
|
|
263
|
+
<h3 className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">
|
|
264
|
+
Admins
|
|
265
|
+
</h3>
|
|
266
|
+
<p className="text-xs leading-relaxed text-muted-foreground">
|
|
267
|
+
Admins can create workspaces, add users, and manage access.
|
|
268
|
+
</p>
|
|
269
|
+
{adminError && (
|
|
270
|
+
<div className="flex items-center gap-1.5 text-xs text-destructive">
|
|
271
|
+
<AlertCircle className="h-3.5 w-3.5 shrink-0" />
|
|
272
|
+
{adminError}
|
|
273
|
+
</div>
|
|
274
|
+
)}
|
|
275
|
+
|
|
276
|
+
{/* Add user */}
|
|
277
|
+
<div className="space-y-2 rounded-md border border-border p-3">
|
|
278
|
+
<div className="text-xs font-medium">Add user</div>
|
|
279
|
+
{createdUser ? (
|
|
280
|
+
<div className="space-y-2">
|
|
281
|
+
<p className="text-xs text-muted-foreground">
|
|
282
|
+
Created <span className="font-medium text-foreground">{createdUser.email}</span>. Share this temporary password now, it will not be shown again.
|
|
283
|
+
</p>
|
|
284
|
+
<div className="flex items-center gap-2">
|
|
285
|
+
<code className="flex-1 rounded bg-muted px-2 py-1.5 font-mono text-sm select-all">{createdUser.tempPassword}</code>
|
|
286
|
+
<button
|
|
287
|
+
type="button"
|
|
288
|
+
className="shrink-0 text-xs px-2 py-1 rounded border border-border hover:bg-accent"
|
|
289
|
+
onClick={() => void navigator.clipboard?.writeText(createdUser.tempPassword)}
|
|
290
|
+
>
|
|
291
|
+
Copy
|
|
292
|
+
</button>
|
|
293
|
+
</div>
|
|
294
|
+
<button
|
|
295
|
+
type="button"
|
|
296
|
+
className="text-xs text-muted-foreground hover:text-foreground"
|
|
297
|
+
onClick={() => { setCreatedUser(null); setNewUserEmail(""); setNewUserName(""); void loadAdmins(); }}
|
|
298
|
+
>
|
|
299
|
+
Done
|
|
300
|
+
</button>
|
|
301
|
+
</div>
|
|
302
|
+
) : (
|
|
303
|
+
<div className="space-y-2">
|
|
304
|
+
<input
|
|
305
|
+
type="email"
|
|
306
|
+
value={newUserEmail}
|
|
307
|
+
onChange={(e) => setNewUserEmail(e.target.value)}
|
|
308
|
+
placeholder="email@team.com"
|
|
309
|
+
className="w-full rounded-md border border-border bg-background px-2 py-1.5 text-sm outline-none focus:ring-2 focus:ring-primary"
|
|
310
|
+
/>
|
|
311
|
+
<input
|
|
312
|
+
type="text"
|
|
313
|
+
value={newUserName}
|
|
314
|
+
onChange={(e) => setNewUserName(e.target.value)}
|
|
315
|
+
placeholder="Name (optional)"
|
|
316
|
+
className="w-full rounded-md border border-border bg-background px-2 py-1.5 text-sm outline-none focus:ring-2 focus:ring-primary"
|
|
317
|
+
/>
|
|
318
|
+
<Button
|
|
319
|
+
size="sm"
|
|
320
|
+
className="w-full gap-1.5"
|
|
321
|
+
disabled={creatingUser || !newUserEmail.trim()}
|
|
322
|
+
onClick={async () => {
|
|
323
|
+
setCreatingUser(true);
|
|
324
|
+
setAdminError(null);
|
|
325
|
+
try {
|
|
326
|
+
const res = await fetch("/api/system/users", {
|
|
327
|
+
method: "POST",
|
|
328
|
+
headers: { "Content-Type": "application/json" },
|
|
329
|
+
body: JSON.stringify({ email: newUserEmail.trim(), name: newUserName.trim() }),
|
|
330
|
+
});
|
|
331
|
+
const d: { ok?: boolean; email?: string; tempPassword?: string; error?: string; message?: string } = await res.json();
|
|
332
|
+
if (!res.ok || !d.tempPassword) {
|
|
333
|
+
setAdminError(d.message ?? d.error ?? "Failed to create user");
|
|
334
|
+
} else {
|
|
335
|
+
setCreatedUser({ email: d.email ?? newUserEmail.trim(), tempPassword: d.tempPassword });
|
|
336
|
+
}
|
|
337
|
+
} catch {
|
|
338
|
+
setAdminError("Network error");
|
|
339
|
+
} finally {
|
|
340
|
+
setCreatingUser(false);
|
|
341
|
+
}
|
|
342
|
+
}}
|
|
343
|
+
>
|
|
344
|
+
{creatingUser && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
|
|
345
|
+
Create user
|
|
346
|
+
</Button>
|
|
347
|
+
</div>
|
|
348
|
+
)}
|
|
349
|
+
</div>
|
|
350
|
+
<div className="space-y-1 rounded-md border border-border overflow-hidden">
|
|
351
|
+
{adminUsers.map((u) => {
|
|
352
|
+
const isAdminUser = admins.includes(u.id);
|
|
353
|
+
return (
|
|
354
|
+
<div key={u.id} className="flex items-center justify-between px-3 py-2 bg-muted/40 hover:bg-muted/60 transition-colors">
|
|
355
|
+
<div className="text-sm min-w-0">
|
|
356
|
+
<div className="font-medium truncate">{u.name}</div>
|
|
357
|
+
<div className="text-xs text-muted-foreground truncate">{u.email}</div>
|
|
358
|
+
</div>
|
|
359
|
+
<button
|
|
360
|
+
type="button"
|
|
361
|
+
disabled={adminWorking === u.id}
|
|
362
|
+
className="ml-2 shrink-0 text-xs px-2 py-1 rounded border border-border hover:bg-accent disabled:opacity-50"
|
|
363
|
+
onClick={async () => {
|
|
364
|
+
setAdminWorking(u.id);
|
|
365
|
+
setAdminError(null);
|
|
366
|
+
try {
|
|
367
|
+
const res = await fetch("/api/system/admins", {
|
|
368
|
+
method: isAdminUser ? "DELETE" : "POST",
|
|
369
|
+
headers: { "Content-Type": "application/json" },
|
|
370
|
+
body: JSON.stringify({ userId: u.id }),
|
|
371
|
+
});
|
|
372
|
+
const d: { ok?: boolean; admins?: string[]; error?: string; message?: string } = await res.json();
|
|
373
|
+
if (!res.ok) {
|
|
374
|
+
setAdminError(d.message ?? d.error ?? "Failed");
|
|
375
|
+
} else if (d.admins) {
|
|
376
|
+
setAdmins(d.admins);
|
|
377
|
+
}
|
|
378
|
+
} catch {
|
|
379
|
+
setAdminError("Network error");
|
|
380
|
+
} finally {
|
|
381
|
+
setAdminWorking(null);
|
|
382
|
+
}
|
|
383
|
+
}}
|
|
384
|
+
>
|
|
385
|
+
{adminWorking === u.id ? (
|
|
386
|
+
<Loader2 className="h-3 w-3 animate-spin" />
|
|
387
|
+
) : isAdminUser ? "Demote" : "Promote"}
|
|
388
|
+
</button>
|
|
389
|
+
</div>
|
|
390
|
+
);
|
|
391
|
+
})}
|
|
392
|
+
{adminUsers.length === 0 && (
|
|
393
|
+
<div className="px-3 py-2 text-xs text-muted-foreground">No users yet.</div>
|
|
394
|
+
)}
|
|
395
|
+
</div>
|
|
396
|
+
{/* TODO: per-workspace access editor (PATCH /api/system/workspaces/[id] allowedUserIds) */}
|
|
397
|
+
</section>
|
|
398
|
+
)}
|
|
399
|
+
|
|
231
400
|
{/* Agent rate limit */}
|
|
232
401
|
<section className="space-y-2">
|
|
233
402
|
<h3 className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">
|
|
@@ -29,7 +29,8 @@ interface BrowseResult {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
interface Props {
|
|
32
|
-
|
|
32
|
+
/** Called with the new workspace id after creation */
|
|
33
|
+
onSelect: (workspaceId: string) => void;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export function DirPicker({ onSelect }: Props) {
|
|
@@ -96,17 +97,18 @@ export function DirPicker({ onSelect }: Props) {
|
|
|
96
97
|
if (!target) return;
|
|
97
98
|
setSelecting(true);
|
|
98
99
|
try {
|
|
99
|
-
const res = await fetch("/api/system/
|
|
100
|
+
const res = await fetch("/api/system/workspaces", {
|
|
100
101
|
method: "POST",
|
|
101
102
|
headers: { "Content-Type": "application/json" },
|
|
102
|
-
body: JSON.stringify({
|
|
103
|
+
body: JSON.stringify({ rootDir: target }),
|
|
103
104
|
});
|
|
104
105
|
if (!res.ok) {
|
|
105
|
-
const e: { error?: string } = await res.json();
|
|
106
|
-
setError(e.error ?? "Cannot use that directory");
|
|
106
|
+
const e: { error?: string; message?: string } = await res.json();
|
|
107
|
+
setError(e.message ?? e.error ?? "Cannot use that directory");
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
109
|
-
|
|
110
|
+
const { workspace }: { workspace: { id: string } } = await res.json();
|
|
111
|
+
onSelect(workspace.id);
|
|
110
112
|
} catch {
|
|
111
113
|
setError("Network error");
|
|
112
114
|
} finally {
|
|
@@ -4,6 +4,7 @@ import * as Popover from "@radix-ui/react-popover";
|
|
|
4
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
5
|
import { authHeaders } from "@/lib/proof/client-auth";
|
|
6
6
|
import { useProofStore } from "@/stores/proof-store";
|
|
7
|
+
import { wsFetch } from "@/lib/workspace-client";
|
|
7
8
|
import type { Comment } from "@/lib/proof/types";
|
|
8
9
|
|
|
9
10
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
@@ -28,7 +29,7 @@ async function postOp(
|
|
|
28
29
|
ops: object[],
|
|
29
30
|
): Promise<{ ok: boolean; stale: boolean; newRevision?: number }> {
|
|
30
31
|
const encoded = encodeURIComponent(path).replace(/%2F/g, "/");
|
|
31
|
-
const res = await
|
|
32
|
+
const res = await wsFetch(`/api/agent/files/${encoded}`, {
|
|
32
33
|
method: "POST",
|
|
33
34
|
headers: {
|
|
34
35
|
"Content-Type": "application/json",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Code2, Download, Save } from "lucide-react";
|
|
4
4
|
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { wsFetch } from "@/lib/workspace-client";
|
|
5
6
|
import { ViewerToolbar } from "@/components/layout/viewer-toolbar";
|
|
6
7
|
import { Button } from "@/components/ui/button";
|
|
7
8
|
|
|
@@ -80,7 +81,7 @@ export function CsvViewer({ path }: CsvViewerProps) {
|
|
|
80
81
|
const csvUrl = `/api/assets/${path}`;
|
|
81
82
|
|
|
82
83
|
useEffect(() => {
|
|
83
|
-
|
|
84
|
+
wsFetch(csvUrl)
|
|
84
85
|
.then((r) => r.text())
|
|
85
86
|
.then((text) => {
|
|
86
87
|
setRawText(text);
|
|
@@ -121,7 +122,7 @@ export function CsvViewer({ path }: CsvViewerProps) {
|
|
|
121
122
|
setSaving(true);
|
|
122
123
|
const csv = sourceMode ? rawText : rowsToCsv(rows);
|
|
123
124
|
try {
|
|
124
|
-
await
|
|
125
|
+
await wsFetch(`/api/assets/${path}`, {
|
|
125
126
|
method: "PUT",
|
|
126
127
|
headers: { "Content-Type": "text/plain" },
|
|
127
128
|
body: csv,
|
|
@@ -85,9 +85,9 @@ function ToolButton({
|
|
|
85
85
|
onAction(e);
|
|
86
86
|
}}
|
|
87
87
|
className={cn(
|
|
88
|
-
"h-8 w-8 shrink-0 inline-flex items-center justify-center rounded-md text-foreground/80 hover:bg-accent transition-colors disabled:opacity-40",
|
|
88
|
+
"h-8 w-8 shrink-0 inline-flex items-center justify-center rounded-md text-foreground/80 hover:bg-accent hover:text-accent-foreground transition-colors disabled:opacity-40",
|
|
89
89
|
active &&
|
|
90
|
-
"bg-accent text-foreground ring-1 ring-inset ring-foreground/15",
|
|
90
|
+
"bg-accent text-accent-foreground ring-1 ring-inset ring-foreground/15",
|
|
91
91
|
)}
|
|
92
92
|
>
|
|
93
93
|
<Icon className="h-4 w-4" />
|