wiki-viewer 1.7.1 → 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 +7 -0
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +32 -3
- package/.next/standalone/.next/routes-manifest.json +46 -0
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
- 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 +2 -2
- 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 +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +5 -5
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- 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/manifest.webmanifest/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route.js +9 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route.js.map +5 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest.body +1 -0
- package/.next/standalone/.next/server/app/manifest.webmanifest.meta +1 -0
- 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 +7 -0
- package/.next/standalone/.next/server/chunks/0p91_next_dist_1195ub1._.js +18 -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]__06yp.08._.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/_next-internal_server_app_manifest_webmanifest_route_actions_04wfv0d.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/0p91_next_dist_esm_build_templates_app-page_042apsk.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0p91_next_dist_esm_build_templates_app-page_08q3u1e.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0p91_next_dist_esm_build_templates_app-page_0nflz3~.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0p91_next_dist_esm_build_templates_app-page_0p5k29e.js +1 -1
- 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/[root-of-the-server]__0hvvps3._.js +1 -1
- 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/packages/wiki-viewer-mcp/package.json +1 -1
- package/.next/standalone/public/icon-192.png +0 -0
- package/.next/standalone/public/icon-512.png +0 -0
- package/.next/standalone/public/icon-maskable-512.png +0 -0
- 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/layout.tsx +15 -1
- package/.next/standalone/src/app/manifest.ts +30 -0
- 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/{H0E5wVJm9tAuN5CrU6zG2 → t7B6nXaoD1jo9f61t3aeK}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{H0E5wVJm9tAuN5CrU6zG2 → t7B6nXaoD1jo9f61t3aeK}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{H0E5wVJm9tAuN5CrU6zG2 → t7B6nXaoD1jo9f61t3aeK}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Metadata } from "next";
|
|
1
|
+
import type { Metadata, Viewport } from "next";
|
|
2
2
|
import { Inter } from "next/font/google";
|
|
3
3
|
import "./globals.css";
|
|
4
4
|
import { Toaster } from "sonner";
|
|
@@ -9,6 +9,20 @@ const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
|
|
|
9
9
|
export const metadata: Metadata = {
|
|
10
10
|
title: "Wiki Viewer",
|
|
11
11
|
description: "Local file browser, viewer, and editor",
|
|
12
|
+
manifest: "/manifest.webmanifest",
|
|
13
|
+
appleWebApp: {
|
|
14
|
+
capable: true,
|
|
15
|
+
title: "Wiki",
|
|
16
|
+
statusBarStyle: "black-translucent",
|
|
17
|
+
},
|
|
18
|
+
icons: {
|
|
19
|
+
icon: "/icon-192.png",
|
|
20
|
+
apple: "/icon-192.png",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const viewport: Viewport = {
|
|
25
|
+
themeColor: "#0c0a09",
|
|
12
26
|
};
|
|
13
27
|
|
|
14
28
|
export default function RootLayout({
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MetadataRoute } from "next";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Web app manifest. Makes iOS/Android "Add to Home Screen" install a real
|
|
5
|
+
* standalone PWA (display: standalone) with persistent storage, instead of a
|
|
6
|
+
* plain bookmark. Without this, iOS treats the shortcut as ephemeral and evicts
|
|
7
|
+
* its cookie jar, forcing re-login on every reopen.
|
|
8
|
+
*/
|
|
9
|
+
export default function manifest(): MetadataRoute.Manifest {
|
|
10
|
+
return {
|
|
11
|
+
name: "Wiki Viewer",
|
|
12
|
+
short_name: "Wiki",
|
|
13
|
+
description: "Local file browser, viewer, and editor",
|
|
14
|
+
start_url: "/",
|
|
15
|
+
scope: "/",
|
|
16
|
+
display: "standalone",
|
|
17
|
+
background_color: "#0c0a09",
|
|
18
|
+
theme_color: "#0c0a09",
|
|
19
|
+
icons: [
|
|
20
|
+
{ src: "/icon-192.png", sizes: "192x192", type: "image/png", purpose: "any" },
|
|
21
|
+
{ src: "/icon-512.png", sizes: "512x512", type: "image/png", purpose: "any" },
|
|
22
|
+
{
|
|
23
|
+
src: "/icon-maskable-512.png",
|
|
24
|
+
sizes: "512x512",
|
|
25
|
+
type: "image/png",
|
|
26
|
+
purpose: "maskable",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -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 {
|