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
|
@@ -11,7 +11,8 @@ import { readFile, stat, unlink, rm } from "node:fs/promises";
|
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { NextResponse } from "next/server";
|
|
13
13
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
14
|
-
import {
|
|
14
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
15
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
15
16
|
import { withFileMutex } from "@/lib/proof/mutex";
|
|
16
17
|
import { readSidecar, emptySidecar, deleteSidecar } from "@/lib/proof/sidecar";
|
|
17
18
|
import { reconcileSidecar } from "@/lib/proof/ops-applier";
|
|
@@ -50,13 +51,17 @@ export async function GET(
|
|
|
50
51
|
const { path: segments } = await params;
|
|
51
52
|
const relPath = rel(segments);
|
|
52
53
|
|
|
53
|
-
const
|
|
54
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
55
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
56
|
+
const { ws, rootDir } = wsx;
|
|
57
|
+
|
|
58
|
+
const basic = safeWorkspacePath(rootDir, relPath);
|
|
54
59
|
if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
|
|
55
60
|
|
|
56
|
-
const absPath = await safeAbsPath(relPath);
|
|
61
|
+
const absPath = await safeAbsPath(rootDir, relPath);
|
|
57
62
|
if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
|
|
58
63
|
|
|
59
|
-
const scope = enforceScope(auth.agent, { filePath: relPath, op: "read" });
|
|
64
|
+
const scope = enforceScope(auth.agent, { filePath: relPath, op: "read", workspaceId: ws.id });
|
|
60
65
|
if (!scope.ok) return errJson(scope.code, scope.message, 403);
|
|
61
66
|
|
|
62
67
|
let data: Buffer;
|
|
@@ -84,7 +89,6 @@ export async function GET(
|
|
|
84
89
|
};
|
|
85
90
|
|
|
86
91
|
// X-Collab-* headers (§3.5 mode signal)
|
|
87
|
-
const rootDir = getRootDir();
|
|
88
92
|
const collab = await computeCollabState(rootDir, relPath);
|
|
89
93
|
if (collab.state !== "not-markdown") {
|
|
90
94
|
baseHeaders["X-Collab-State"] = collab.state;
|
|
@@ -148,23 +152,26 @@ async function applyMutation(
|
|
|
148
152
|
const auth = await checkAuth(req);
|
|
149
153
|
if (!auth.ok) return errJson("UNAUTHORIZED", auth.message ?? "Unauthorized", 401);
|
|
150
154
|
|
|
155
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
156
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
157
|
+
const { ws, rootDir } = wsx;
|
|
158
|
+
|
|
151
159
|
const relPath = rel(segments);
|
|
152
160
|
const url = new URL(req.url);
|
|
153
161
|
const mkdirs = url.searchParams.get("mkdirs") === "true";
|
|
154
162
|
const force = url.searchParams.get("force") === "true";
|
|
155
163
|
|
|
156
|
-
const basic =
|
|
164
|
+
const basic = safeWorkspacePath(rootDir, relPath);
|
|
157
165
|
if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
|
|
158
166
|
|
|
159
|
-
const absPath = await safeAbsPath(relPath);
|
|
167
|
+
const absPath = await safeAbsPath(rootDir, relPath);
|
|
160
168
|
if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
|
|
161
169
|
|
|
162
|
-
const scope = enforceScope(auth.agent, { filePath: relPath, op: "mutate" });
|
|
170
|
+
const scope = enforceScope(auth.agent, { filePath: relPath, op: "mutate", workspaceId: ws.id });
|
|
163
171
|
if (!scope.ok) return errJson(scope.code, scope.message, 403);
|
|
164
172
|
|
|
165
173
|
const ifMatch = req.headers.get("if-match");
|
|
166
174
|
const ifCollabMatch = req.headers.get("if-collab-match");
|
|
167
|
-
const rootDir = getRootDir();
|
|
168
175
|
|
|
169
176
|
// The whole read-existing → precondition → compute → write → reconcile → audit
|
|
170
177
|
// sequence runs inside the mutex for .md (so R6 and reconcile are atomic with
|
|
@@ -256,6 +263,7 @@ async function applyMutation(
|
|
|
256
263
|
oldSha: existingSha,
|
|
257
264
|
newSha,
|
|
258
265
|
forced: force,
|
|
266
|
+
workspaceId: ws.id,
|
|
259
267
|
});
|
|
260
268
|
|
|
261
269
|
const st = await stat(absPath);
|
|
@@ -268,7 +276,7 @@ async function applyMutation(
|
|
|
268
276
|
});
|
|
269
277
|
};
|
|
270
278
|
|
|
271
|
-
return isMarkdown(relPath) ? withFileMutex(relPath
|
|
279
|
+
return isMarkdown(relPath) ? withFileMutex(`${rootDir}\u0000${relPath}`, doMutation) : doMutation();
|
|
272
280
|
}
|
|
273
281
|
|
|
274
282
|
// ── PUT ──────────────────────────────────────────────────────────────────────
|
|
@@ -377,14 +385,18 @@ export async function DELETE(
|
|
|
377
385
|
const url = new URL(req.url);
|
|
378
386
|
const recursive = url.searchParams.get("recursive") === "true";
|
|
379
387
|
|
|
380
|
-
const
|
|
388
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
389
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
390
|
+
const { ws, rootDir } = wsx;
|
|
391
|
+
|
|
392
|
+
const basic = safeWorkspacePath(rootDir, relPath);
|
|
381
393
|
if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
|
|
382
394
|
|
|
383
|
-
const absPath = await safeAbsPath(relPath);
|
|
395
|
+
const absPath = await safeAbsPath(rootDir, relPath);
|
|
384
396
|
if (!absPath) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
|
|
385
397
|
|
|
386
398
|
// Requires "delete" scope op
|
|
387
|
-
const scope = enforceScope(auth.agent, { filePath: relPath, op: "delete" });
|
|
399
|
+
const scope = enforceScope(auth.agent, { filePath: relPath, op: "delete", workspaceId: ws.id });
|
|
388
400
|
if (!scope.ok) return errJson(scope.code, scope.message, 403);
|
|
389
401
|
|
|
390
402
|
const ifMatch = req.headers.get("if-match");
|
|
@@ -405,7 +417,7 @@ export async function DELETE(
|
|
|
405
417
|
}
|
|
406
418
|
// Directory delete — no single sha, skip If-Match; require recursive flag as confirmation
|
|
407
419
|
await rm(absPath, { recursive: true, force: true });
|
|
408
|
-
writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, forced: false });
|
|
420
|
+
writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, forced: false, workspaceId: ws.id });
|
|
409
421
|
return NextResponse.json({ deleted: relPath });
|
|
410
422
|
}
|
|
411
423
|
|
|
@@ -420,10 +432,8 @@ export async function DELETE(
|
|
|
420
432
|
return errJson("PRECONDITION_FAILED", "If-Match sha256 mismatch", 412);
|
|
421
433
|
}
|
|
422
434
|
|
|
423
|
-
const rootDir = getRootDir();
|
|
424
|
-
|
|
425
435
|
if (isMarkdown(relPath)) {
|
|
426
|
-
await withFileMutex(relPath
|
|
436
|
+
await withFileMutex(`${rootDir}\u0000${relPath}`, async () => {
|
|
427
437
|
await unlink(absPath);
|
|
428
438
|
await deleteSidecar(rootDir, relPath);
|
|
429
439
|
});
|
|
@@ -431,6 +441,6 @@ export async function DELETE(
|
|
|
431
441
|
await unlink(absPath);
|
|
432
442
|
}
|
|
433
443
|
|
|
434
|
-
writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, oldSha: existingSha, forced: false });
|
|
444
|
+
writeAuditRow({ agentId: auth.agent.id, op: "delete", path: relPath, oldSha: existingSha, forced: false, workspaceId: ws.id });
|
|
435
445
|
return NextResponse.json({ deleted: relPath });
|
|
436
446
|
}
|
|
@@ -13,7 +13,8 @@ import { readdir, stat } from "node:fs/promises";
|
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
import { NextResponse } from "next/server";
|
|
15
15
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
16
|
-
import {
|
|
16
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
17
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
17
18
|
import { safeAbsPath } from "@/lib/proof/raw-fs";
|
|
18
19
|
import type { Agent } from "@/lib/proof/registry";
|
|
19
20
|
|
|
@@ -44,6 +45,7 @@ async function walkDir(
|
|
|
44
45
|
maxDepth: number,
|
|
45
46
|
limit: number,
|
|
46
47
|
results: LsEntry[],
|
|
48
|
+
workspaceId?: string,
|
|
47
49
|
): Promise<void> {
|
|
48
50
|
if (depth > maxDepth || results.length >= limit) return;
|
|
49
51
|
|
|
@@ -63,7 +65,7 @@ async function walkDir(
|
|
|
63
65
|
const childRel = relDir ? `${relDir}/${item.name}` : item.name;
|
|
64
66
|
|
|
65
67
|
// Scope check per entry
|
|
66
|
-
const sc = enforceScope(agent, { filePath: childRel, op: "read" });
|
|
68
|
+
const sc = enforceScope(agent, { filePath: childRel, op: "read", workspaceId });
|
|
67
69
|
if (!sc.ok) continue;
|
|
68
70
|
|
|
69
71
|
let type: LsEntry["type"];
|
|
@@ -88,7 +90,7 @@ async function walkDir(
|
|
|
88
90
|
results.push({ name: item.name, path: childRel, type, size, mtime });
|
|
89
91
|
|
|
90
92
|
if (recursive && type === "dir") {
|
|
91
|
-
await walkDir(rootDir, childRel, agent, recursive, depth + 1, maxDepth, limit, results);
|
|
93
|
+
await walkDir(rootDir, childRel, agent, recursive, depth + 1, maxDepth, limit, results, workspaceId);
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
}
|
|
@@ -103,10 +105,14 @@ export async function GET(
|
|
|
103
105
|
const { path: segments } = await params;
|
|
104
106
|
const relPath = segments ? segments.join("/") : "";
|
|
105
107
|
|
|
108
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
109
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
110
|
+
const { ws, rootDir } = wsx;
|
|
111
|
+
|
|
106
112
|
if (relPath) {
|
|
107
|
-
const basic =
|
|
113
|
+
const basic = safeWorkspacePath(rootDir, relPath);
|
|
108
114
|
if (!basic) return errJson("INVALID_PATH", "Path traversal rejected", 400);
|
|
109
|
-
const safe = await safeAbsPath(relPath);
|
|
115
|
+
const safe = await safeAbsPath(rootDir, relPath);
|
|
110
116
|
if (!safe) return errJson("INVALID_PATH", "Path rejected (symlink escape or denied)", 400);
|
|
111
117
|
}
|
|
112
118
|
|
|
@@ -122,7 +128,6 @@ export async function GET(
|
|
|
122
128
|
);
|
|
123
129
|
|
|
124
130
|
// Verify the dir actually exists
|
|
125
|
-
const rootDir = getRootDir();
|
|
126
131
|
const absDir = relPath ? path.join(rootDir, relPath) : rootDir;
|
|
127
132
|
try {
|
|
128
133
|
const st = await stat(absDir);
|
|
@@ -137,7 +142,7 @@ export async function GET(
|
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
const entries: LsEntry[] = [];
|
|
140
|
-
await walkDir(rootDir, relPath, auth.agent, recursive, 0, depth, limit, entries);
|
|
145
|
+
await walkDir(rootDir, relPath, auth.agent, recursive, 0, depth, limit, entries, ws.id);
|
|
141
146
|
|
|
142
147
|
return NextResponse.json({
|
|
143
148
|
path: relPath,
|
|
@@ -14,7 +14,8 @@ import { rename, stat } from "node:fs/promises";
|
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import { NextResponse } from "next/server";
|
|
16
16
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
17
|
-
import {
|
|
17
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
18
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
18
19
|
import { withFileMutex } from "@/lib/proof/mutex";
|
|
19
20
|
import { moveSidecar } from "@/lib/proof/sidecar";
|
|
20
21
|
import { writeAuditRow } from "@/lib/proof/audit";
|
|
@@ -47,13 +48,17 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
47
48
|
const toRel = body.to;
|
|
48
49
|
const ifMatch = typeof body.ifMatch === "string" ? body.ifMatch : undefined;
|
|
49
50
|
|
|
51
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
52
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
53
|
+
const { ws, rootDir } = wsx;
|
|
54
|
+
|
|
50
55
|
// Basic traversal
|
|
51
|
-
if (!
|
|
52
|
-
if (!
|
|
56
|
+
if (!safeWorkspacePath(rootDir, fromRel)) return errJson("INVALID_PATH", "from: path traversal rejected", 400);
|
|
57
|
+
if (!safeWorkspacePath(rootDir, toRel)) return errJson("INVALID_PATH", "to: path traversal rejected", 400);
|
|
53
58
|
|
|
54
|
-
const fromAbs = await safeAbsPath(fromRel);
|
|
59
|
+
const fromAbs = await safeAbsPath(rootDir, fromRel);
|
|
55
60
|
if (!fromAbs) return errJson("INVALID_PATH", "from: path rejected (symlink escape or denied)", 400);
|
|
56
|
-
const toAbs = await safeAbsPath(toRel);
|
|
61
|
+
const toAbs = await safeAbsPath(rootDir, toRel);
|
|
57
62
|
if (!toAbs) return errJson("INVALID_PATH", "to: path rejected (symlink escape or denied)", 400);
|
|
58
63
|
|
|
59
64
|
// Self-move guard
|
|
@@ -63,11 +68,11 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
// Scope: source requires read+mutate; dest requires mutate
|
|
66
|
-
const sc1 = enforceScope(auth.agent, { filePath: fromRel, op: "read" });
|
|
71
|
+
const sc1 = enforceScope(auth.agent, { filePath: fromRel, op: "read", workspaceId: ws.id });
|
|
67
72
|
if (!sc1.ok) return errJson(sc1.code, sc1.message, 403);
|
|
68
|
-
const sc2 = enforceScope(auth.agent, { filePath: fromRel, op: "mutate" });
|
|
73
|
+
const sc2 = enforceScope(auth.agent, { filePath: fromRel, op: "mutate", workspaceId: ws.id });
|
|
69
74
|
if (!sc2.ok) return errJson(sc2.code, sc2.message, 403);
|
|
70
|
-
const sc3 = enforceScope(auth.agent, { filePath: toRel, op: "mutate" });
|
|
75
|
+
const sc3 = enforceScope(auth.agent, { filePath: toRel, op: "mutate", workspaceId: ws.id });
|
|
71
76
|
if (!sc3.ok) return errJson(sc3.code, sc3.message, 403);
|
|
72
77
|
|
|
73
78
|
// Verify source exists
|
|
@@ -95,7 +100,6 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
const rootDir = getRootDir();
|
|
99
103
|
const isMd = isMarkdown(fromRel);
|
|
100
104
|
|
|
101
105
|
// Lock source + dest in sorted order to avoid deadlock
|
|
@@ -112,13 +116,14 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
112
116
|
path: fromRel,
|
|
113
117
|
newSha: toRel, // store destination in newSha field for audit trail
|
|
114
118
|
forced: false,
|
|
119
|
+
workspaceId: ws.id,
|
|
115
120
|
});
|
|
116
121
|
};
|
|
117
122
|
|
|
118
123
|
if (first === fromRel) {
|
|
119
|
-
await withFileMutex(first
|
|
124
|
+
await withFileMutex(`${rootDir}\u0000${first}`, () => withFileMutex(`${rootDir}\u0000${second}`, doMove));
|
|
120
125
|
} else {
|
|
121
|
-
await withFileMutex(first
|
|
126
|
+
await withFileMutex(`${rootDir}\u0000${first}`, () => withFileMutex(`${rootDir}\u0000${second}`, doMove));
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
return NextResponse.json({ from: fromRel, to: toRel });
|
|
@@ -19,10 +19,12 @@
|
|
|
19
19
|
export const runtime = "nodejs";
|
|
20
20
|
|
|
21
21
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
22
|
+
import { ensureIndexer, ftsSearch } from "@/lib/search/indexer";
|
|
22
23
|
import path from "node:path";
|
|
23
24
|
import { NextResponse } from "next/server";
|
|
24
25
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
25
|
-
import {
|
|
26
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
27
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
26
28
|
import { safeAbsPath, looksLikeBinary } from "@/lib/proof/raw-fs";
|
|
27
29
|
import { matchGlob } from "@/lib/proof/glob";
|
|
28
30
|
import type { Agent } from "@/lib/proof/registry";
|
|
@@ -36,6 +38,8 @@ export interface SearchMatch {
|
|
|
36
38
|
line?: number;
|
|
37
39
|
col?: number;
|
|
38
40
|
text?: string;
|
|
41
|
+
score?: number;
|
|
42
|
+
snippet?: string;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
function errJson(code: string, message: string, status: number): NextResponse {
|
|
@@ -74,6 +78,7 @@ async function grepSearch(
|
|
|
74
78
|
limit: number,
|
|
75
79
|
agent: Agent,
|
|
76
80
|
deadline: number,
|
|
81
|
+
workspaceId?: string,
|
|
77
82
|
): Promise<{ matches: SearchMatch[]; truncated: boolean }> {
|
|
78
83
|
let regex: RegExp;
|
|
79
84
|
try {
|
|
@@ -94,7 +99,7 @@ async function grepSearch(
|
|
|
94
99
|
if (matches.length >= limit) return { matches, truncated: true };
|
|
95
100
|
if (Date.now() > deadline) return { matches, truncated: true };
|
|
96
101
|
|
|
97
|
-
const sc = enforceScope(agent, { filePath: fileRel, op: "read" });
|
|
102
|
+
const sc = enforceScope(agent, { filePath: fileRel, op: "read", workspaceId });
|
|
98
103
|
if (!sc.ok) continue;
|
|
99
104
|
|
|
100
105
|
let buf: Buffer;
|
|
@@ -140,6 +145,7 @@ async function globSearch(
|
|
|
140
145
|
limit: number,
|
|
141
146
|
agent: Agent,
|
|
142
147
|
deadline: number,
|
|
148
|
+
workspaceId?: string,
|
|
143
149
|
): Promise<{ matches: SearchMatch[]; truncated: boolean }> {
|
|
144
150
|
const matches: SearchMatch[] = [];
|
|
145
151
|
|
|
@@ -151,7 +157,7 @@ async function globSearch(
|
|
|
151
157
|
const baseName = path.basename(fileRel);
|
|
152
158
|
if (!matchGlob(pattern, fileRel) && !matchGlob(pattern, baseName)) continue;
|
|
153
159
|
|
|
154
|
-
const sc = enforceScope(agent, { filePath: fileRel, op: "read" });
|
|
160
|
+
const sc = enforceScope(agent, { filePath: fileRel, op: "read", workspaceId });
|
|
155
161
|
if (!sc.ok) continue;
|
|
156
162
|
|
|
157
163
|
matches.push({ path: fileRel });
|
|
@@ -173,14 +179,17 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
173
179
|
return errJson("INVALID_PAYLOAD", "Invalid JSON body", 400);
|
|
174
180
|
}
|
|
175
181
|
|
|
176
|
-
if (body.kind !== "grep" && body.kind !== "glob") {
|
|
177
|
-
return errJson("INVALID_PAYLOAD", 'kind must be "grep" or "
|
|
182
|
+
if (body.kind !== "grep" && body.kind !== "glob" && body.kind !== "fts") {
|
|
183
|
+
return errJson("INVALID_PAYLOAD", 'kind must be "grep", "glob", or "fts"', 400);
|
|
178
184
|
}
|
|
179
|
-
if (typeof body.query !== "string"
|
|
185
|
+
if (typeof body.query !== "string") {
|
|
186
|
+
return errJson("INVALID_PAYLOAD", "query (string) required", 400);
|
|
187
|
+
}
|
|
188
|
+
if (body.kind !== "fts" && !body.query) {
|
|
180
189
|
return errJson("INVALID_PAYLOAD", "query (string) required", 400);
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
const kind = body.kind as "grep" | "glob";
|
|
192
|
+
const kind = body.kind as "grep" | "glob" | "fts";
|
|
184
193
|
const query = body.query as string;
|
|
185
194
|
const startRelRaw = typeof body.path === "string" ? body.path : "";
|
|
186
195
|
const limit = Math.min(
|
|
@@ -188,17 +197,19 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
188
197
|
HARD_MAX_MATCHES,
|
|
189
198
|
);
|
|
190
199
|
|
|
200
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
201
|
+
if (!wsx.ok) return errJson(wsx.code, wsx.code, wsx.status);
|
|
202
|
+
const { ws, rootDir } = wsx;
|
|
203
|
+
|
|
191
204
|
// Validate start path
|
|
192
205
|
if (startRelRaw) {
|
|
193
|
-
if (!
|
|
206
|
+
if (!safeWorkspacePath(rootDir, startRelRaw)) {
|
|
194
207
|
return errJson("INVALID_PATH", "path: traversal rejected", 400);
|
|
195
208
|
}
|
|
196
|
-
const safe = await safeAbsPath(startRelRaw);
|
|
209
|
+
const safe = await safeAbsPath(rootDir, startRelRaw);
|
|
197
210
|
if (!safe) return errJson("INVALID_PATH", "path: rejected (symlink escape or denied)", 400);
|
|
198
211
|
}
|
|
199
212
|
|
|
200
|
-
const rootDir = getRootDir();
|
|
201
|
-
|
|
202
213
|
// Verify start path is a directory
|
|
203
214
|
if (startRelRaw) {
|
|
204
215
|
try {
|
|
@@ -214,14 +225,39 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
214
225
|
}
|
|
215
226
|
}
|
|
216
227
|
|
|
228
|
+
// FTS branch -- handled before the grep/glob path validation below.
|
|
229
|
+
if (kind === "fts") {
|
|
230
|
+
const sc = enforceScope(auth.agent, { op: "read", workspaceId: ws.id });
|
|
231
|
+
if (!sc.ok) return errJson("FORBIDDEN", sc.message ?? "Forbidden", 403);
|
|
232
|
+
|
|
233
|
+
ensureIndexer(ws.id, rootDir).catch((e) =>
|
|
234
|
+
console.error("[search] ensureIndexer failed", e),
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
// Over-fetch so the post-filter (path scope + start-path restriction) can
|
|
238
|
+
// still return up to `limit` results when some top-ranked hits are denied.
|
|
239
|
+
const startPrefix = startRelRaw ? `${startRelRaw.replace(/\/+$/, "")}/` : "";
|
|
240
|
+
const fts = ftsSearch(ws.id, query, Math.min(limit * 4, HARD_MAX_MATCHES));
|
|
241
|
+
const filtered = fts.matches.filter((m) => {
|
|
242
|
+
if (startPrefix && !m.path.startsWith(startPrefix)) return false;
|
|
243
|
+
return enforceScope(auth.agent, { filePath: m.path, op: "read", workspaceId: ws.id }).ok;
|
|
244
|
+
});
|
|
245
|
+
const matches = filtered
|
|
246
|
+
.slice(0, limit)
|
|
247
|
+
.map((m) => ({ path: m.path, score: m.score, snippet: m.snippet }));
|
|
248
|
+
// truncated if the DB itself capped, or the scoped set still exceeds limit.
|
|
249
|
+
const truncated = fts.truncated || filtered.length > limit;
|
|
250
|
+
return NextResponse.json({ kind, query, matches, truncated });
|
|
251
|
+
}
|
|
252
|
+
|
|
217
253
|
const deadline = Date.now() + SEARCH_TIMEOUT_MS;
|
|
218
254
|
let result: { matches: SearchMatch[]; truncated: boolean };
|
|
219
255
|
|
|
220
256
|
try {
|
|
221
257
|
if (kind === "grep") {
|
|
222
|
-
result = await grepSearch(rootDir, startRelRaw, query, limit, auth.agent, deadline);
|
|
258
|
+
result = await grepSearch(rootDir, startRelRaw, query, limit, auth.agent, deadline, ws.id);
|
|
223
259
|
} else {
|
|
224
|
-
result = await globSearch(rootDir, startRelRaw, query, limit, auth.agent, deadline);
|
|
260
|
+
result = await globSearch(rootDir, startRelRaw, query, limit, auth.agent, deadline, ws.id);
|
|
225
261
|
}
|
|
226
262
|
} catch (e) {
|
|
227
263
|
return errJson("SEARCH_ERROR", (e as Error).message, 400);
|
|
@@ -8,7 +8,8 @@ import { revertProofSpan } from "@/lib/proof/proof-span";
|
|
|
8
8
|
import { readSidecar, writeSidecar, emptySidecar } from "@/lib/proof/sidecar";
|
|
9
9
|
import { withFileMutex } from "@/lib/proof/mutex";
|
|
10
10
|
import { emitEvents } from "@/lib/proof/event-bus";
|
|
11
|
-
import {
|
|
11
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
12
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
12
13
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
13
14
|
|
|
14
15
|
export const runtime = "nodejs";
|
|
@@ -63,22 +64,25 @@ export async function POST(req: Request): Promise<NextResponse> {
|
|
|
63
64
|
return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
const
|
|
67
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
68
|
+
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
69
|
+
const { ws, rootDir } = wsx;
|
|
70
|
+
|
|
71
|
+
const absPath = safeWorkspacePath(rootDir, rel);
|
|
67
72
|
if (!absPath) {
|
|
68
73
|
return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
const scopeCheck = enforceScope(authResult.agent, { filePath: rel, op: "mutate" });
|
|
76
|
+
const scopeCheck = enforceScope(authResult.agent, { filePath: rel, op: "mutate", workspaceId: ws.id });
|
|
72
77
|
if (!scopeCheck.ok) {
|
|
73
78
|
return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
|
|
74
79
|
}
|
|
75
80
|
|
|
76
|
-
const rootDir = getRootDir();
|
|
77
81
|
const actorId = authResult.agent.id;
|
|
78
82
|
|
|
79
83
|
let notFound = false;
|
|
80
84
|
try {
|
|
81
|
-
await withFileMutex(rel
|
|
85
|
+
await withFileMutex(`${rootDir}\u0000${rel}`, async () => {
|
|
82
86
|
let content: string;
|
|
83
87
|
try {
|
|
84
88
|
content = await readFile(absPath, "utf-8");
|
|
@@ -31,7 +31,15 @@ function validateScope(s: Record<string, unknown>): AgentScope | { error: string
|
|
|
31
31
|
return { error: `scope.ops values must be "read", "mutate", or "delete"` };
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// Optional workspaceId: if present must be a non-empty string ≤ 64 chars.
|
|
35
|
+
let workspaceId: string | undefined;
|
|
36
|
+
if (s.workspaceId !== undefined) {
|
|
37
|
+
if (typeof s.workspaceId !== "string" || s.workspaceId.length < 1 || s.workspaceId.length > 64) {
|
|
38
|
+
return { error: "scope.workspaceId must be a string of 1\u201364 characters" };
|
|
39
|
+
}
|
|
40
|
+
workspaceId = s.workspaceId;
|
|
41
|
+
}
|
|
42
|
+
return { paths: s.paths as string[], ops: s.ops as Array<"read" | "mutate" | "delete">, ...(workspaceId !== undefined ? { workspaceId } : {}) };
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
/** Exported for reuse in approve route. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
4
4
|
import { readRegistry } from "@/lib/proof/registry";
|
|
5
5
|
import { listPendingRegistrations } from "@/lib/proof/pending";
|
|
6
6
|
|
|
@@ -12,7 +12,11 @@ export async function GET(req: Request): Promise<NextResponse> {
|
|
|
12
12
|
return NextResponse.json({ error: "UNAUTHORIZED" }, { status: 401 });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
16
|
+
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
17
|
+
const { ws, rootDir } = wsx;
|
|
18
|
+
|
|
19
|
+
const scopeCheck = enforceScope(auth.agent, { op: "read", workspaceId: ws.id });
|
|
16
20
|
if (!scopeCheck.ok) {
|
|
17
21
|
return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
|
|
18
22
|
}
|
|
@@ -23,7 +27,7 @@ export async function GET(req: Request): Promise<NextResponse> {
|
|
|
23
27
|
|
|
24
28
|
return NextResponse.json({
|
|
25
29
|
rateLimit: Number(process.env.AGENT_RATE_LIMIT) || 60,
|
|
26
|
-
root:
|
|
30
|
+
root: rootDir,
|
|
27
31
|
registeredAgents,
|
|
28
32
|
pendingRegistrations,
|
|
29
33
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { checkAuth, enforceScope } from "@/lib/proof/auth";
|
|
3
3
|
import { readSidecar, emptySidecar } from "@/lib/proof/sidecar";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
5
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
5
6
|
|
|
6
7
|
export const runtime = "nodejs";
|
|
7
8
|
|
|
@@ -32,17 +33,20 @@ export async function GET(
|
|
|
32
33
|
return NextResponse.json({ error: "INVALID_PATH", message: "Path must be .md or .markdown" }, { status: 400 });
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
const
|
|
36
|
+
const wsx = await resolveWorkspaceForAgent(req);
|
|
37
|
+
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
38
|
+
const { ws, rootDir } = wsx;
|
|
39
|
+
|
|
40
|
+
const absPath = safeWorkspacePath(rootDir, rel);
|
|
36
41
|
if (!absPath) {
|
|
37
42
|
return NextResponse.json({ error: "INVALID_PATH", message: "Path traversal rejected" }, { status: 400 });
|
|
38
43
|
}
|
|
39
44
|
|
|
40
|
-
const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "read" });
|
|
45
|
+
const scopeCheck = enforceScope(auth.agent, { filePath: rel, op: "read", workspaceId: ws.id });
|
|
41
46
|
if (!scopeCheck.ok) {
|
|
42
47
|
return NextResponse.json({ error: scopeCheck.code, message: scopeCheck.message }, { status: 403 });
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
const rootDir = getRootDir();
|
|
46
50
|
const sidecar = (await readSidecar(rootDir, rel)) ?? emptySidecar(rel);
|
|
47
51
|
|
|
48
52
|
return NextResponse.json(sidecar);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { NextResponse } from "next/server";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
5
|
+
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
5
6
|
|
|
6
7
|
const MIME_MAP: Record<string, string> = {
|
|
7
8
|
jpg: "image/jpeg",
|
|
@@ -38,15 +39,19 @@ const MIME_MAP: Record<string, string> = {
|
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
export async function GET(
|
|
41
|
-
|
|
42
|
+
request: Request,
|
|
42
43
|
{ params }: { params: Promise<{ path: string[] }> },
|
|
43
44
|
) {
|
|
45
|
+
const wsx = await resolveWorkspaceForAgent(request);
|
|
46
|
+
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
47
|
+
const { rootDir } = wsx;
|
|
48
|
+
|
|
44
49
|
const segments = (await params).path;
|
|
45
50
|
const rel = segments.join("/");
|
|
46
51
|
|
|
47
52
|
// Path traversal guard
|
|
48
|
-
const resolved =
|
|
49
|
-
if (
|
|
53
|
+
const resolved = safeWorkspacePath(rootDir, rel);
|
|
54
|
+
if (!resolved) {
|
|
50
55
|
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
51
56
|
}
|
|
52
57
|
|