wiki-viewer 1.14.1 → 1.14.2
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/build-manifest.json +3 -3
- 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.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- 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.nft.json +1 -1
- 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.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/set-root/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- 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 +1 -1
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware-manifest.json +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/package.json +1 -1
- package/bin/postbuild.js +21 -0
- package/package.json +1 -1
- package/.next/standalone/.github/workflows/publish.yml +0 -37
- package/.next/standalone/.handoffs/archive/handoff-20260612-113332.md +0 -98
- package/.next/standalone/.handoffs/archive/handoff-20260612-141032.md +0 -73
- package/.next/standalone/.pi/ownership.json +0 -3
- package/.next/standalone/AGENTS.md +0 -114
- package/.next/standalone/DESIGN.md +0 -521
- package/.next/standalone/README.md +0 -821
- package/.next/standalone/TODO.md +0 -20
- package/.next/standalone/agents/bootstrap-prompt.md +0 -14
- package/.next/standalone/agents/wiki-viewer-skill/SKILL.md +0 -456
- package/.next/standalone/bin/postbuild.js +0 -78
- package/.next/standalone/bin/wiki-viewer.js +0 -922
- package/.next/standalone/certificates/localhost-key.pem +0 -28
- package/.next/standalone/certificates/localhost.pem +0 -24
- package/.next/standalone/docs/agent-collab-plan.md +0 -1615
- package/.next/standalone/docs/agent-collab-v2-plan.md +0 -771
- package/.next/standalone/docs/agent-fs-plan.md +0 -232
- package/.next/standalone/docs/editorial-skin-spec.md +0 -242
- package/.next/standalone/docs/file-vs-collab-authority.md +0 -124
- package/.next/standalone/docs/mobile-readiness-spec.md +0 -229
- package/.next/standalone/docs/workspacing-plan.md +0 -364
- package/.next/standalone/packages/wiki-viewer-mcp/README.md +0 -195
- package/.next/standalone/packages/wiki-viewer-mcp/bench-e2e.mjs +0 -166
- package/.next/standalone/packages/wiki-viewer-mcp/bench-latency.mjs +0 -87
- package/.next/standalone/packages/wiki-viewer-mcp/bench-payload.mjs +0 -45
- package/.next/standalone/packages/wiki-viewer-mcp/dist/http-client.js +0 -331
- package/.next/standalone/packages/wiki-viewer-mcp/dist/index.js +0 -531
- package/.next/standalone/packages/wiki-viewer-mcp/dist/register.js +0 -94
- package/.next/standalone/packages/wiki-viewer-mcp/dist/state-cache.js +0 -28
- package/.next/standalone/packages/wiki-viewer-mcp/package-lock.json +0 -1716
- package/.next/standalone/packages/wiki-viewer-mcp/package.json +0 -41
- package/.next/standalone/packages/wiki-viewer-mcp/src/http-client.ts +0 -459
- package/.next/standalone/packages/wiki-viewer-mcp/src/index.ts +0 -638
- package/.next/standalone/packages/wiki-viewer-mcp/src/register.ts +0 -144
- package/.next/standalone/packages/wiki-viewer-mcp/src/state-cache.ts +0 -55
- package/.next/standalone/packages/wiki-viewer-mcp/tsconfig.json +0 -19
- package/.next/standalone/pnpm-lock.yaml +0 -6697
- package/.next/standalone/pnpm-workspace.yaml +0 -8
- package/.next/standalone/postcss.config.mjs +0 -2
- package/.next/standalone/src/app/api/agent/activity/route.ts +0 -59
- package/.next/standalone/src/app/api/agent/admin/agents/[agentId]/revoke/route.ts +0 -40
- package/.next/standalone/src/app/api/agent/admin/agents/route.ts +0 -33
- package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/approve/route.ts +0 -83
- package/.next/standalone/src/app/api/agent/admin/registrations/[regId]/deny/route.ts +0 -36
- package/.next/standalone/src/app/api/agent/admin/registrations/route.ts +0 -27
- package/.next/standalone/src/app/api/agent/events/[...path]/route.ts +0 -148
- package/.next/standalone/src/app/api/agent/files/[...path]/route.ts +0 -219
- package/.next/standalone/src/app/api/agent/fs/file/[...path]/route.ts +0 -446
- package/.next/standalone/src/app/api/agent/fs/ls/[[...path]]/route.ts +0 -152
- package/.next/standalone/src/app/api/agent/fs/move/route.ts +0 -130
- package/.next/standalone/src/app/api/agent/fs/search/route.ts +0 -272
- package/.next/standalone/src/app/api/agent/internal/span/route.ts +0 -121
- package/.next/standalone/src/app/api/agent/register/[regId]/route.ts +0 -50
- package/.next/standalone/src/app/api/agent/register/route.ts +0 -118
- package/.next/standalone/src/app/api/agent/settings/route.ts +0 -34
- package/.next/standalone/src/app/api/agent/settings/token/regenerate/route.ts +0 -20
- package/.next/standalone/src/app/api/agent/sidecar/[...path]/route.ts +0 -53
- package/.next/standalone/src/app/api/agents/install/route.ts +0 -143
- package/.next/standalone/src/app/api/agents/skill/route.ts +0 -20
- package/.next/standalone/src/app/api/agents/skill.tar.gz/route.ts +0 -87
- package/.next/standalone/src/app/api/app-proxy/[...path]/route.ts +0 -247
- package/.next/standalone/src/app/api/assets/[...path]/route.ts +0 -75
- package/.next/standalone/src/app/api/auth/[...all]/route.ts +0 -7
- package/.next/standalone/src/app/api/owner/init/route.ts +0 -14
- package/.next/standalone/src/app/api/share/[token]/route.ts +0 -269
- package/.next/standalone/src/app/api/share/route.ts +0 -127
- package/.next/standalone/src/app/api/system/admins/route.ts +0 -103
- package/.next/standalone/src/app/api/system/auth-config/route.ts +0 -22
- package/.next/standalone/src/app/api/system/auth-settings/route.ts +0 -86
- package/.next/standalone/src/app/api/system/browse/route.ts +0 -82
- package/.next/standalone/src/app/api/system/clear-root/route.ts +0 -16
- package/.next/standalone/src/app/api/system/config/route.ts +0 -14
- package/.next/standalone/src/app/api/system/pins/route.ts +0 -38
- package/.next/standalone/src/app/api/system/reveal/route.ts +0 -36
- package/.next/standalone/src/app/api/system/root-status/route.ts +0 -13
- package/.next/standalone/src/app/api/system/set-root/route.ts +0 -53
- package/.next/standalone/src/app/api/system/users/route.ts +0 -120
- package/.next/standalone/src/app/api/system/workspaces/[id]/open/route.ts +0 -34
- package/.next/standalone/src/app/api/system/workspaces/[id]/refresh/route.ts +0 -32
- package/.next/standalone/src/app/api/system/workspaces/[id]/route.ts +0 -78
- package/.next/standalone/src/app/api/system/workspaces/route.ts +0 -128
- package/.next/standalone/src/app/api/upload/[...path]/route.ts +0 -85
- package/.next/standalone/src/app/api/wiki/app/route.ts +0 -60
- package/.next/standalone/src/app/api/wiki/backlinks/route.ts +0 -29
- package/.next/standalone/src/app/api/wiki/content/route.ts +0 -159
- package/.next/standalone/src/app/api/wiki/download/route.ts +0 -100
- package/.next/standalone/src/app/api/wiki/file/route.ts +0 -57
- package/.next/standalone/src/app/api/wiki/folder/route.ts +0 -34
- package/.next/standalone/src/app/api/wiki/git-branches/route.ts +0 -32
- package/.next/standalone/src/app/api/wiki/git-checkout/route.ts +0 -45
- package/.next/standalone/src/app/api/wiki/git-diff/route.ts +0 -33
- package/.next/standalone/src/app/api/wiki/git-file-info/route.ts +0 -27
- package/.next/standalone/src/app/api/wiki/git-history/route.ts +0 -27
- package/.next/standalone/src/app/api/wiki/git-pull/route.ts +0 -48
- package/.next/standalone/src/app/api/wiki/move/route.ts +0 -61
- package/.next/standalone/src/app/api/wiki/new-file/route.ts +0 -56
- package/.next/standalone/src/app/api/wiki/outlinks/route.ts +0 -76
- package/.next/standalone/src/app/api/wiki/page/route.ts +0 -92
- package/.next/standalone/src/app/api/wiki/presence/route.ts +0 -56
- package/.next/standalone/src/app/api/wiki/route.ts +0 -116
- package/.next/standalone/src/app/api/wiki/search/route.ts +0 -44
- package/.next/standalone/src/app/api/wiki/slugs/route.ts +0 -54
- package/.next/standalone/src/app/api/wiki/upload/route.ts +0 -95
- package/.next/standalone/src/app/api/wiki/watch/route.ts +0 -67
- package/.next/standalone/src/app/globals.css +0 -1249
- package/.next/standalone/src/app/icon.svg +0 -11
- package/.next/standalone/src/app/layout.tsx +0 -78
- package/.next/standalone/src/app/manifest.ts +0 -30
- package/.next/standalone/src/app/page.tsx +0 -3260
- package/.next/standalone/src/app/s/[token]/page.tsx +0 -357
- package/.next/standalone/src/app/signin/page.tsx +0 -16
- package/.next/standalone/src/app/signin/signin-form.tsx +0 -238
- package/.next/standalone/src/components/ai-panel/activity-row.tsx +0 -284
- package/.next/standalone/src/components/ai-panel/ai-panel.tsx +0 -311
- package/.next/standalone/src/components/ai-panel/token-section.tsx +0 -313
- package/.next/standalone/src/components/auth-settings-sheet.tsx +0 -474
- package/.next/standalone/src/components/confirm-dialog.tsx +0 -56
- package/.next/standalone/src/components/dir-picker.tsx +0 -606
- package/.next/standalone/src/components/editor/backlinks-panel.tsx +0 -139
- package/.next/standalone/src/components/editor/bubble-menu.tsx +0 -346
- package/.next/standalone/src/components/editor/callout-extension.ts +0 -36
- package/.next/standalone/src/components/editor/comment-pip.tsx +0 -56
- package/.next/standalone/src/components/editor/comment-thread.tsx +0 -254
- package/.next/standalone/src/components/editor/csv-viewer.tsx +0 -379
- package/.next/standalone/src/components/editor/document-outline.tsx +0 -230
- package/.next/standalone/src/components/editor/editor-toolbar.tsx +0 -564
- package/.next/standalone/src/components/editor/editor.tsx +0 -1327
- package/.next/standalone/src/components/editor/extensions/drag-handle.ts +0 -325
- package/.next/standalone/src/components/editor/extensions/heading-anchors.ts +0 -55
- package/.next/standalone/src/components/editor/extensions/proof-span.ts +0 -60
- package/.next/standalone/src/components/editor/extensions/resizable-image.tsx +0 -159
- package/.next/standalone/src/components/editor/extensions.ts +0 -150
- package/.next/standalone/src/components/editor/file-fallback-viewer.tsx +0 -75
- package/.next/standalone/src/components/editor/folder-index.tsx +0 -236
- package/.next/standalone/src/components/editor/google-doc-viewer.tsx +0 -73
- package/.next/standalone/src/components/editor/image-viewer.tsx +0 -57
- package/.next/standalone/src/components/editor/large-file-gate.tsx +0 -108
- package/.next/standalone/src/components/editor/link-popover.tsx +0 -111
- package/.next/standalone/src/components/editor/media-popover.tsx +0 -212
- package/.next/standalone/src/components/editor/media-viewer.tsx +0 -70
- package/.next/standalone/src/components/editor/mermaid-viewer.tsx +0 -286
- package/.next/standalone/src/components/editor/node-app-viewer.tsx +0 -328
- package/.next/standalone/src/components/editor/notebook-viewer.tsx +0 -371
- package/.next/standalone/src/components/editor/office/docx-viewer.tsx +0 -93
- package/.next/standalone/src/components/editor/office/office-chrome.tsx +0 -83
- package/.next/standalone/src/components/editor/office/pptx-viewer.tsx +0 -104
- package/.next/standalone/src/components/editor/office/xlsx-viewer.tsx +0 -192
- package/.next/standalone/src/components/editor/pdf-viewer.tsx +0 -32
- package/.next/standalone/src/components/editor/proof-span-popover.tsx +0 -162
- package/.next/standalone/src/components/editor/slash-commands.tsx +0 -629
- package/.next/standalone/src/components/editor/source-viewer.tsx +0 -289
- package/.next/standalone/src/components/editor/suggest-edit-popover.tsx +0 -229
- package/.next/standalone/src/components/editor/suggestion-card.tsx +0 -206
- package/.next/standalone/src/components/editor/table-menu.tsx +0 -232
- package/.next/standalone/src/components/editor/view-mode-comment-button.tsx +0 -77
- package/.next/standalone/src/components/editor/website-viewer.tsx +0 -75
- package/.next/standalone/src/components/editor/wiki-link-create-dialog.tsx +0 -189
- package/.next/standalone/src/components/editor/wiki-link-decorator.ts +0 -79
- package/.next/standalone/src/components/editor/wiki-link-extension.ts +0 -120
- package/.next/standalone/src/components/editor/wiki-link-picker.tsx +0 -250
- package/.next/standalone/src/components/layout/viewer-toolbar.tsx +0 -54
- package/.next/standalone/src/components/search/search-command-dialog.tsx +0 -246
- package/.next/standalone/src/components/search/sidebar-search-box.tsx +0 -121
- package/.next/standalone/src/components/search/snippet-text.tsx +0 -48
- package/.next/standalone/src/components/share-dialog.tsx +0 -307
- package/.next/standalone/src/components/theme-provider.tsx +0 -16
- package/.next/standalone/src/components/theme-toggle.tsx +0 -24
- package/.next/standalone/src/components/ui/badge.tsx +0 -35
- package/.next/standalone/src/components/ui/button.tsx +0 -56
- package/.next/standalone/src/components/ui/card.tsx +0 -63
- package/.next/standalone/src/components/ui/collapsible.tsx +0 -9
- package/.next/standalone/src/components/ui/command.tsx +0 -151
- package/.next/standalone/src/components/ui/context-menu.tsx +0 -191
- package/.next/standalone/src/components/ui/dialog.tsx +0 -119
- package/.next/standalone/src/components/ui/dropdown-menu.tsx +0 -194
- package/.next/standalone/src/components/ui/input.tsx +0 -22
- package/.next/standalone/src/components/ui/label.tsx +0 -25
- package/.next/standalone/src/components/ui/popover.tsx +0 -33
- package/.next/standalone/src/components/ui/scroll-area.tsx +0 -47
- package/.next/standalone/src/components/ui/select.tsx +0 -156
- package/.next/standalone/src/components/ui/separator.tsx +0 -30
- package/.next/standalone/src/components/ui/sheet.tsx +0 -140
- package/.next/standalone/src/components/ui/skeleton.tsx +0 -15
- package/.next/standalone/src/components/ui/switch.tsx +0 -28
- package/.next/standalone/src/components/ui/tabs.tsx +0 -54
- package/.next/standalone/src/components/ui/textarea.tsx +0 -21
- package/.next/standalone/src/components/ui/tip.tsx +0 -23
- package/.next/standalone/src/components/ui/toggle-group.tsx +0 -41
- package/.next/standalone/src/components/ui/tooltip.tsx +0 -27
- package/.next/standalone/src/components/view-width-toggle.tsx +0 -70
- package/.next/standalone/src/components/wiki/frontmatter-header.tsx +0 -164
- package/.next/standalone/src/hooks/use-is-mobile.ts +0 -14
- package/.next/standalone/src/lib/app-runner.ts +0 -272
- package/.next/standalone/src/lib/auth/admin.ts +0 -120
- package/.next/standalone/src/lib/auth/allowlist.ts +0 -50
- package/.next/standalone/src/lib/auth/client.ts +0 -4
- package/.next/standalone/src/lib/auth/csrf.ts +0 -68
- package/.next/standalone/src/lib/auth/server.ts +0 -215
- package/.next/standalone/src/lib/cabinets/tree.ts +0 -75
- package/.next/standalone/src/lib/config.ts +0 -114
- package/.next/standalone/src/lib/embeds/detect.ts +0 -142
- package/.next/standalone/src/lib/git-secrets.ts +0 -65
- package/.next/standalone/src/lib/git.ts +0 -503
- package/.next/standalone/src/lib/google/detect.ts +0 -107
- package/.next/standalone/src/lib/markdown/parse-frontmatter.ts +0 -104
- package/.next/standalone/src/lib/markdown/remark-wikilinks.ts +0 -100
- package/.next/standalone/src/lib/markdown/sanitize-schema.ts +0 -106
- package/.next/standalone/src/lib/markdown/to-html.ts +0 -282
- package/.next/standalone/src/lib/markdown/to-markdown.ts +0 -252
- package/.next/standalone/src/lib/proof/activity-shared.ts +0 -31
- package/.next/standalone/src/lib/proof/activity.ts +0 -74
- package/.next/standalone/src/lib/proof/audit.ts +0 -88
- package/.next/standalone/src/lib/proof/auth.ts +0 -143
- package/.next/standalone/src/lib/proof/block-refs.ts +0 -133
- package/.next/standalone/src/lib/proof/blocks.ts +0 -73
- package/.next/standalone/src/lib/proof/client-auth.ts +0 -23
- package/.next/standalone/src/lib/proof/collab-state.ts +0 -81
- package/.next/standalone/src/lib/proof/event-bus.ts +0 -47
- package/.next/standalone/src/lib/proof/file-lock.ts +0 -43
- package/.next/standalone/src/lib/proof/glob.ts +0 -51
- package/.next/standalone/src/lib/proof/idempotency.ts +0 -37
- package/.next/standalone/src/lib/proof/lease.ts +0 -117
- package/.next/standalone/src/lib/proof/mutex.ts +0 -36
- package/.next/standalone/src/lib/proof/ops-applier.ts +0 -727
- package/.next/standalone/src/lib/proof/owner-auth.ts +0 -2
- package/.next/standalone/src/lib/proof/pending.ts +0 -97
- package/.next/standalone/src/lib/proof/proof-span.ts +0 -141
- package/.next/standalone/src/lib/proof/rate-limit.ts +0 -53
- package/.next/standalone/src/lib/proof/raw-fs.ts +0 -197
- package/.next/standalone/src/lib/proof/register-rate-limit.ts +0 -53
- package/.next/standalone/src/lib/proof/registry.ts +0 -195
- package/.next/standalone/src/lib/proof/sidecar.ts +0 -103
- package/.next/standalone/src/lib/proof/suggest-capture.ts +0 -69
- package/.next/standalone/src/lib/proof/types.ts +0 -182
- package/.next/standalone/src/lib/proof-config.ts +0 -14
- package/.next/standalone/src/lib/root-dir.ts +0 -35
- package/.next/standalone/src/lib/search/indexable-exts.ts +0 -25
- package/.next/standalone/src/lib/search/indexer.ts +0 -634
- package/.next/standalone/src/lib/search/sanitize.ts +0 -35
- package/.next/standalone/src/lib/search/search-db.ts +0 -57
- package/.next/standalone/src/lib/search/watcher-pool.ts +0 -79
- package/.next/standalone/src/lib/shared-docs/db.ts +0 -177
- package/.next/standalone/src/lib/toast.ts +0 -9
- package/.next/standalone/src/lib/utils.ts +0 -6
- package/.next/standalone/src/lib/wiki-helpers.ts +0 -36
- package/.next/standalone/src/lib/workspace-client.ts +0 -82
- package/.next/standalone/src/lib/workspace-context.ts +0 -173
- package/.next/standalone/src/lib/workspaces.ts +0 -400
- package/.next/standalone/src/middleware.ts +0 -44
- package/.next/standalone/src/stores/ai-panel-store.ts +0 -79
- package/.next/standalone/src/stores/editor-store.ts +0 -439
- package/.next/standalone/src/stores/pin-store.ts +0 -56
- package/.next/standalone/src/stores/proof-store.ts +0 -124
- package/.next/standalone/src/stores/recent-store.ts +0 -51
- package/.next/standalone/src/stores/search-store.ts +0 -104
- package/.next/standalone/src/stores/show-hidden-store.ts +0 -26
- package/.next/standalone/src/stores/sidebar-width-store.ts +0 -39
- package/.next/standalone/src/stores/skin-store.ts +0 -42
- package/.next/standalone/src/stores/tree-store.ts +0 -52
- package/.next/standalone/src/stores/view-width-store.ts +0 -101
- package/.next/standalone/src/stores/wiki-slugs-store.ts +0 -75
- package/.next/standalone/src/tests/proof/activity-aggregator.test.ts +0 -146
- package/.next/standalone/src/tests/proof/admin-create-user.test.ts +0 -43
- package/.next/standalone/src/tests/proof/agent-fs.test.ts +0 -973
- package/.next/standalone/src/tests/proof/agent-ownership.test.ts +0 -140
- package/.next/standalone/src/tests/proof/agent-workspace-scope.test.ts +0 -134
- package/.next/standalone/src/tests/proof/agents-install.test.ts +0 -110
- package/.next/standalone/src/tests/proof/bench-write.ts +0 -179
- package/.next/standalone/src/tests/proof/better-auth.test.ts +0 -68
- package/.next/standalone/src/tests/proof/block-refs.test.ts +0 -108
- package/.next/standalone/src/tests/proof/blocks.test.ts +0 -92
- package/.next/standalone/src/tests/proof/collab-state.test.ts +0 -501
- package/.next/standalone/src/tests/proof/comments-ops.test.ts +0 -177
- package/.next/standalone/src/tests/proof/editor-roundtrip.test.ts +0 -85
- package/.next/standalone/src/tests/proof/external-edit.test.ts +0 -58
- package/.next/standalone/src/tests/proof/file-lock.test.ts +0 -80
- package/.next/standalone/src/tests/proof/git-branches-checkout.test.ts +0 -136
- package/.next/standalone/src/tests/proof/git-read-features.test.ts +0 -473
- package/.next/standalone/src/tests/proof/git-secrets.test.ts +0 -138
- package/.next/standalone/src/tests/proof/git-sparse.test.ts +0 -257
- package/.next/standalone/src/tests/proof/git-workspace.test.ts +0 -135
- package/.next/standalone/src/tests/proof/git.test.ts +0 -243
- package/.next/standalone/src/tests/proof/glob.test.ts +0 -82
- package/.next/standalone/src/tests/proof/helpers/auth-session.ts +0 -27
- package/.next/standalone/src/tests/proof/markdown-to-html.test.ts +0 -46
- package/.next/standalone/src/tests/proof/ops-applier.test.ts +0 -368
- package/.next/standalone/src/tests/proof/owner-init.test.ts +0 -2
- package/.next/standalone/src/tests/proof/parse-frontmatter.test.ts +0 -60
- package/.next/standalone/src/tests/proof/preload.ts +0 -21
- package/.next/standalone/src/tests/proof/proof-span.test.ts +0 -98
- package/.next/standalone/src/tests/proof/rate-limit.test.ts +0 -54
- package/.next/standalone/src/tests/proof/readonly-enforcement.test.ts +0 -161
- package/.next/standalone/src/tests/proof/reconcile-sidecar.test.ts +0 -195
- package/.next/standalone/src/tests/proof/registration-flow.test.ts +0 -330
- package/.next/standalone/src/tests/proof/registry.test.ts +0 -169
- package/.next/standalone/src/tests/proof/routes.test.ts +0 -516
- package/.next/standalone/src/tests/proof/search-index.test.ts +0 -376
- package/.next/standalone/src/tests/proof/sidecar-lifecycle.test.ts +0 -177
- package/.next/standalone/src/tests/proof/sidecar-trim.test.ts +0 -58
- package/.next/standalone/src/tests/proof/suggestion-ops.test.ts +0 -280
- package/.next/standalone/src/tests/proof/wiki-content-put.test.ts +0 -140
- package/.next/standalone/src/tests/proof/wiki-routes-auth.test.ts +0 -208
- package/.next/standalone/src/tests/proof/workspace-isolation.test.ts +0 -87
- package/.next/standalone/src/tests/proof/workspaces-api.test.ts +0 -227
- package/.next/standalone/src/types/index.ts +0 -47
- package/.next/standalone/tailwind.config.ts +0 -191
- package/.next/standalone/tsconfig.json +0 -41
- package/.next/standalone/tsconfig.tsbuildinfo +0 -1
- /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{WMOTgfV82apmdovxzgbMx → rRyvFORvJoc5OWbCR2A_P}/_ssgManifest.js +0 -0
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { mkdir, stat, writeFile } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { NextResponse } from "next/server";
|
|
4
|
-
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
5
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
6
|
-
|
|
7
|
-
const MAX_UPLOAD_BYTES = 50 * 1024 * 1024;
|
|
8
|
-
|
|
9
|
-
function sanitizeFilename(name: string): string {
|
|
10
|
-
const lowered = name.toLowerCase();
|
|
11
|
-
const cleaned = lowered.replace(/[^a-z0-9._-]+/g, "-").replace(/-+/g, "-");
|
|
12
|
-
const trimmed = cleaned.replace(/^[-.]+/, "").replace(/-+$/, "");
|
|
13
|
-
return trimmed || "file";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async function pickAvailableName(dir: string, filename: string): Promise<string> {
|
|
17
|
-
const ext = path.extname(filename);
|
|
18
|
-
const stem = filename.slice(0, filename.length - ext.length);
|
|
19
|
-
let candidate = filename;
|
|
20
|
-
let n = 2;
|
|
21
|
-
while (true) {
|
|
22
|
-
try {
|
|
23
|
-
await stat(path.join(dir, candidate));
|
|
24
|
-
candidate = `${stem}-${n}${ext}`;
|
|
25
|
-
n += 1;
|
|
26
|
-
} catch {
|
|
27
|
-
return candidate;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export async function POST(
|
|
33
|
-
request: Request,
|
|
34
|
-
{ params }: { params: Promise<{ path: string[] }> },
|
|
35
|
-
) {
|
|
36
|
-
const wsx = await resolveWorkspaceForAgent(request, "write");
|
|
37
|
-
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
38
|
-
const { rootDir } = wsx;
|
|
39
|
-
|
|
40
|
-
const { path: segments } = await params;
|
|
41
|
-
const subPath = (segments ?? []).join("/");
|
|
42
|
-
|
|
43
|
-
// Save images in _uploads/ within rootDir, mirroring the page path
|
|
44
|
-
const uploadsDir = path.join(rootDir, "_uploads", subPath);
|
|
45
|
-
const resolved = safeWorkspacePath(rootDir, path.join("_uploads", subPath));
|
|
46
|
-
if (!resolved)
|
|
47
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
48
|
-
|
|
49
|
-
let form: FormData;
|
|
50
|
-
try {
|
|
51
|
-
form = await request.formData();
|
|
52
|
-
} catch {
|
|
53
|
-
return NextResponse.json({ error: "Expected multipart/form-data" }, { status: 400 });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const file = form.get("file");
|
|
57
|
-
if (!(file instanceof File))
|
|
58
|
-
return NextResponse.json({ error: "Missing file field" }, { status: 400 });
|
|
59
|
-
if (file.size > MAX_UPLOAD_BYTES)
|
|
60
|
-
return NextResponse.json({ error: "File exceeds 50MB limit" }, { status: 413 });
|
|
61
|
-
|
|
62
|
-
const filename = sanitizeFilename(file.name || "file");
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
await mkdir(uploadsDir, { recursive: true });
|
|
66
|
-
const finalName = await pickAvailableName(uploadsDir, filename);
|
|
67
|
-
const targetPath = path.join(uploadsDir, finalName);
|
|
68
|
-
const bytes = Buffer.from(await file.arrayBuffer());
|
|
69
|
-
await writeFile(targetPath, bytes);
|
|
70
|
-
|
|
71
|
-
const relParts = ["_uploads", subPath, finalName].filter(Boolean);
|
|
72
|
-
const relUrl = relParts.map(encodeURIComponent).join("/");
|
|
73
|
-
const relPath = relParts.join("/");
|
|
74
|
-
return NextResponse.json({
|
|
75
|
-
url: `/api/assets/${relUrl}`,
|
|
76
|
-
path: relPath,
|
|
77
|
-
absolutePath: targetPath,
|
|
78
|
-
size: bytes.length,
|
|
79
|
-
mimeType: file.type || "application/octet-stream",
|
|
80
|
-
});
|
|
81
|
-
} catch (err) {
|
|
82
|
-
const message = err instanceof Error ? err.message : "Write failed";
|
|
83
|
-
return NextResponse.json({ error: message }, { status: 500 });
|
|
84
|
-
}
|
|
85
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { NextResponse } from "next/server";
|
|
3
|
-
import { checkOrigin } from "@/lib/auth/csrf";
|
|
4
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
5
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
6
|
-
import { getScripts, getStatus, startApp, stopApp } from "@/lib/app-runner";
|
|
7
|
-
|
|
8
|
-
// GET /api/wiki/app?path=relative/path
|
|
9
|
-
export async function GET(request: Request) {
|
|
10
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
11
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
12
|
-
|
|
13
|
-
const { searchParams } = new URL(request.url);
|
|
14
|
-
const rel = searchParams.get("path") ?? "";
|
|
15
|
-
const status = getStatus(rel);
|
|
16
|
-
const abs = safeWorkspacePath(ctx.rootDir, rel);
|
|
17
|
-
const scripts = abs ? getScripts(abs) : { scripts: [], defaultScript: null };
|
|
18
|
-
return NextResponse.json({ ...status, ...scripts });
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// POST /api/wiki/app { path: "relative/path" }
|
|
22
|
-
export async function POST(request: Request) {
|
|
23
|
-
const csrf = checkOrigin(request);
|
|
24
|
-
if (csrf) return csrf;
|
|
25
|
-
const ctx = await resolveWorkspaceForUser(request, "write");
|
|
26
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
27
|
-
const { rootDir } = ctx;
|
|
28
|
-
|
|
29
|
-
const body: { path?: string; script?: string } = await request.json();
|
|
30
|
-
const rel = body.path;
|
|
31
|
-
if (!rel || typeof rel !== "string")
|
|
32
|
-
return NextResponse.json({ error: "Missing path" }, { status: 400 });
|
|
33
|
-
|
|
34
|
-
const abs = safeWorkspacePath(rootDir, rel);
|
|
35
|
-
if (!abs)
|
|
36
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const result = await startApp(rel, abs, body.script);
|
|
40
|
-
return NextResponse.json(result);
|
|
41
|
-
} catch (e) {
|
|
42
|
-
return NextResponse.json({ error: String(e) }, { status: 500 });
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// DELETE /api/wiki/app { path: "relative/path" }
|
|
47
|
-
export async function DELETE(request: Request) {
|
|
48
|
-
const csrf = checkOrigin(request);
|
|
49
|
-
if (csrf) return csrf;
|
|
50
|
-
const ctx = await resolveWorkspaceForUser(request, "write");
|
|
51
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
52
|
-
|
|
53
|
-
const body: { path?: string } = await request.json();
|
|
54
|
-
const rel = body.path;
|
|
55
|
-
if (!rel || typeof rel !== "string")
|
|
56
|
-
return NextResponse.json({ error: "Missing path" }, { status: 400 });
|
|
57
|
-
|
|
58
|
-
stopApp(rel);
|
|
59
|
-
return NextResponse.json({ ok: true });
|
|
60
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export const runtime = "nodejs";
|
|
2
|
-
|
|
3
|
-
import { NextResponse } from "next/server";
|
|
4
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
5
|
-
import { ensureIndexer, resolveBacklinks } from "@/lib/search/indexer";
|
|
6
|
-
|
|
7
|
-
/** Last path segment, sans .md, used as the wiki-link slug. */
|
|
8
|
-
function slugFromPath(filePath: string): string {
|
|
9
|
-
const base = filePath.split("/").pop() ?? filePath;
|
|
10
|
-
return base.replace(/\.md$/i, "");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export async function GET(request: Request) {
|
|
14
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
15
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
16
|
-
|
|
17
|
-
const url = new URL(request.url);
|
|
18
|
-
const path = url.searchParams.get("path") ?? "";
|
|
19
|
-
const slug = slugFromPath(path);
|
|
20
|
-
if (!slug) return NextResponse.json({ backlinks: [] });
|
|
21
|
-
|
|
22
|
-
// Lazy init: returns whatever is already indexed; warms up in background.
|
|
23
|
-
ensureIndexer(ctx.ws.id, ctx.rootDir).catch((e) =>
|
|
24
|
-
console.error("[backlinks] ensureIndexer failed", e),
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const backlinks = resolveBacklinks(ctx.ws.id, slug, path, 50);
|
|
28
|
-
return NextResponse.json({ backlinks });
|
|
29
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { NextResponse } from "next/server";
|
|
5
|
-
import { checkOrigin } from "@/lib/auth/csrf";
|
|
6
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
7
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
8
|
-
import { emitEvents, trimEvents } from "@/lib/proof/event-bus";
|
|
9
|
-
import { withFileMutex } from "@/lib/proof/mutex";
|
|
10
|
-
import { emptySidecar, readSidecar, writeSidecar } from "@/lib/proof/sidecar";
|
|
11
|
-
import { SIDECAR_EVENT_TRIM_SIZE } from "@/lib/proof-config";
|
|
12
|
-
|
|
13
|
-
const TEXT_EXTS = new Set([
|
|
14
|
-
"txt", "md", "markdown", "json", "yaml", "yml", "toml", "csv", "tsv",
|
|
15
|
-
"xml", "html", "css", "js", "ts", "tsx", "jsx", "sh", "bash",
|
|
16
|
-
"zsh", "rb", "py", "go", "rs", "java", "c", "cpp", "h", "php",
|
|
17
|
-
"swift", "kt", "lua", "sql", "scss", "mmd", "mermaid", "ini",
|
|
18
|
-
"env", "log", "conf",
|
|
19
|
-
]);
|
|
20
|
-
const MARKDOWN_EXTS = new Set(["md", "markdown"]);
|
|
21
|
-
const MAX_EDIT_SIZE = 1 * 1024 * 1024; // 1MB
|
|
22
|
-
|
|
23
|
-
function isTextFile(filename: string): boolean {
|
|
24
|
-
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
25
|
-
return TEXT_EXTS.has(ext);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function isMarkdownFile(filename: string): boolean {
|
|
29
|
-
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
30
|
-
return MARKDOWN_EXTS.has(ext);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function sha256content(content: string): string {
|
|
34
|
-
return "sha256:" + createHash("sha256").update(content, "utf8").digest("hex");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function GET(request: Request) {
|
|
38
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
39
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
40
|
-
const { rootDir } = ctx;
|
|
41
|
-
|
|
42
|
-
const { searchParams } = new URL(request.url);
|
|
43
|
-
const rel = searchParams.get("path") ?? "";
|
|
44
|
-
const filePath = safeWorkspacePath(rootDir, rel);
|
|
45
|
-
if (!filePath)
|
|
46
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
47
|
-
if (!isTextFile(path.basename(filePath)))
|
|
48
|
-
return NextResponse.json({ error: "Not a text file" }, { status: 400 });
|
|
49
|
-
try {
|
|
50
|
-
const buffer = await readFile(filePath);
|
|
51
|
-
if (buffer.length > MAX_EDIT_SIZE)
|
|
52
|
-
return NextResponse.json(
|
|
53
|
-
{ error: "File too large (max 1MB)" },
|
|
54
|
-
{ status: 413 },
|
|
55
|
-
);
|
|
56
|
-
const content = buffer.toString("utf-8");
|
|
57
|
-
const headers: Record<string, string> = {};
|
|
58
|
-
if (isMarkdownFile(path.basename(filePath))) {
|
|
59
|
-
const sc = await readSidecar(rootDir, rel);
|
|
60
|
-
if (sc) {
|
|
61
|
-
headers["X-Wiki-Revision"] = String(sc.revision);
|
|
62
|
-
headers["X-Wiki-Fingerprint"] = sc.fingerprint;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return NextResponse.json({ content }, { headers });
|
|
66
|
-
} catch {
|
|
67
|
-
return NextResponse.json({ error: "File not found" }, { status: 404 });
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export async function PUT(request: Request) {
|
|
72
|
-
const csrf = checkOrigin(request);
|
|
73
|
-
if (csrf) return csrf;
|
|
74
|
-
const ctx = await resolveWorkspaceForUser(request, "write");
|
|
75
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
76
|
-
const { rootDir } = ctx;
|
|
77
|
-
|
|
78
|
-
const body: { path?: string; content?: string; baseRevision?: number } =
|
|
79
|
-
await request.json();
|
|
80
|
-
const rel = body.path;
|
|
81
|
-
const content = body.content;
|
|
82
|
-
if (!rel || typeof rel !== "string")
|
|
83
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
84
|
-
if (typeof content !== "string")
|
|
85
|
-
return NextResponse.json({ error: "Missing content" }, { status: 400 });
|
|
86
|
-
const filePath = safeWorkspacePath(rootDir, rel);
|
|
87
|
-
if (!filePath)
|
|
88
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
89
|
-
if (!isTextFile(path.basename(filePath)))
|
|
90
|
-
return NextResponse.json({ error: "Not a text file" }, { status: 400 });
|
|
91
|
-
|
|
92
|
-
// Non-markdown files: plain write, no revision tracking.
|
|
93
|
-
if (!isMarkdownFile(path.basename(filePath))) {
|
|
94
|
-
try {
|
|
95
|
-
await mkdir(path.dirname(filePath), { recursive: true });
|
|
96
|
-
await writeFile(filePath, content, "utf-8");
|
|
97
|
-
return NextResponse.json({ ok: true });
|
|
98
|
-
} catch {
|
|
99
|
-
return NextResponse.json({ error: "Failed to save" }, { status: 500 });
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Markdown files: mutex + sidecar revision check + fingerprint update + event.
|
|
104
|
-
// Use the same key format as the agent routes (`${rootDir}\0${rel}`) so a doc
|
|
105
|
-
// edited via both the editor and the agent fs API shares one lock.
|
|
106
|
-
return withFileMutex(`${rootDir}\u0000${rel}`, async () => {
|
|
107
|
-
const sc = (await readSidecar(rootDir, rel)) ?? emptySidecar(rel);
|
|
108
|
-
|
|
109
|
-
// baseRevision is required for markdown to prevent lost writes.
|
|
110
|
-
if (body.baseRevision === undefined || typeof body.baseRevision !== "number") {
|
|
111
|
-
return NextResponse.json(
|
|
112
|
-
{ error: "BASE_REVISION_REQUIRED", message: "baseRevision is required when saving markdown files." },
|
|
113
|
-
{ status: 400 },
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Enforce staleness check.
|
|
118
|
-
if (
|
|
119
|
-
body.baseRevision !== sc.revision
|
|
120
|
-
) {
|
|
121
|
-
return NextResponse.json(
|
|
122
|
-
{
|
|
123
|
-
error: "STALE_REVISION",
|
|
124
|
-
currentRevision: sc.revision,
|
|
125
|
-
message: "File was modified since your last read. Reload and retry.",
|
|
126
|
-
},
|
|
127
|
-
{ status: 409 },
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
try {
|
|
132
|
-
await mkdir(path.dirname(filePath), { recursive: true });
|
|
133
|
-
await writeFile(filePath, content, "utf-8");
|
|
134
|
-
} catch {
|
|
135
|
-
return NextResponse.json({ error: "Failed to save" }, { status: 500 });
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Update sidecar metadata.
|
|
139
|
-
const newRevision = sc.revision + 1;
|
|
140
|
-
sc.revision = newRevision;
|
|
141
|
-
sc.fingerprint = sha256content(content);
|
|
142
|
-
sc.updatedAt = new Date().toISOString();
|
|
143
|
-
|
|
144
|
-
// Emit a human-edit event so agents can see the change.
|
|
145
|
-
emitEvents(sc, [
|
|
146
|
-
{
|
|
147
|
-
type: "file.edited",
|
|
148
|
-
at: new Date().toISOString(),
|
|
149
|
-
by: `user:${ctx.userId}`,
|
|
150
|
-
revision: newRevision,
|
|
151
|
-
},
|
|
152
|
-
]);
|
|
153
|
-
trimEvents(sc, SIDECAR_EVENT_TRIM_SIZE);
|
|
154
|
-
|
|
155
|
-
await writeSidecar(rootDir, rel, sc);
|
|
156
|
-
|
|
157
|
-
return NextResponse.json({ ok: true, revision: newRevision });
|
|
158
|
-
});
|
|
159
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { createReadStream } from "node:fs";
|
|
2
|
-
import { readdir, readFile, stat } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { Readable } from "node:stream";
|
|
5
|
-
import JSZip from "jszip";
|
|
6
|
-
import { NextResponse } from "next/server";
|
|
7
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
8
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
9
|
-
|
|
10
|
-
// Skip noise that should never end up in a downloaded archive.
|
|
11
|
-
const SKIP_DIRS = new Set([".git", "node_modules", ".next", ".proof"]);
|
|
12
|
-
|
|
13
|
-
function contentDisposition(filename: string): string {
|
|
14
|
-
// RFC 5987: ASCII fallback + UTF-8 encoded form for non-ASCII names.
|
|
15
|
-
const ascii = filename.replace(/[^\x20-\x7e]/g, "_").replace(/"/g, "'");
|
|
16
|
-
const encoded = encodeURIComponent(filename);
|
|
17
|
-
return `attachment; filename="${ascii}"; filename*=UTF-8''${encoded}`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function addDirToZip(
|
|
21
|
-
zip: JSZip,
|
|
22
|
-
absDir: string,
|
|
23
|
-
zipPrefix: string,
|
|
24
|
-
): Promise<void> {
|
|
25
|
-
const names = await readdir(absDir);
|
|
26
|
-
for (const name of names) {
|
|
27
|
-
if (SKIP_DIRS.has(name)) continue;
|
|
28
|
-
const abs = path.join(absDir, name);
|
|
29
|
-
const info = await stat(abs);
|
|
30
|
-
const zipPath = zipPrefix ? `${zipPrefix}/${name}` : name;
|
|
31
|
-
if (info.isDirectory()) {
|
|
32
|
-
await addDirToZip(zip, abs, zipPath);
|
|
33
|
-
} else if (info.isFile()) {
|
|
34
|
-
zip.file(zipPath, await readFile(abs));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export async function GET(request: Request) {
|
|
40
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
41
|
-
if (!ctx.ok)
|
|
42
|
-
return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
43
|
-
const { rootDir } = ctx;
|
|
44
|
-
|
|
45
|
-
const { searchParams } = new URL(request.url);
|
|
46
|
-
const rel = searchParams.get("path") ?? "";
|
|
47
|
-
const target = safeWorkspacePath(rootDir, rel);
|
|
48
|
-
if (!target)
|
|
49
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
50
|
-
|
|
51
|
-
let info: Awaited<ReturnType<typeof stat>>;
|
|
52
|
-
try {
|
|
53
|
-
info = await stat(target);
|
|
54
|
-
} catch {
|
|
55
|
-
return NextResponse.json({ error: "Not found" }, { status: 404 });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const baseName = path.basename(target) || "download";
|
|
59
|
-
|
|
60
|
-
if (info.isFile()) {
|
|
61
|
-
const webStream = Readable.toWeb(
|
|
62
|
-
createReadStream(target),
|
|
63
|
-
) as ReadableStream;
|
|
64
|
-
return new Response(webStream, {
|
|
65
|
-
headers: {
|
|
66
|
-
"Content-Type": "application/octet-stream",
|
|
67
|
-
"Content-Length": String(info.size),
|
|
68
|
-
"Content-Disposition": contentDisposition(baseName),
|
|
69
|
-
"Cache-Control": "private, no-store",
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (info.isDirectory()) {
|
|
75
|
-
const zip = new JSZip();
|
|
76
|
-
try {
|
|
77
|
-
await addDirToZip(zip, target, "");
|
|
78
|
-
} catch {
|
|
79
|
-
return NextResponse.json(
|
|
80
|
-
{ error: "Failed to read folder" },
|
|
81
|
-
{ status: 500 },
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
const buffer = await zip.generateAsync({
|
|
85
|
-
type: "nodebuffer",
|
|
86
|
-
compression: "DEFLATE",
|
|
87
|
-
compressionOptions: { level: 6 },
|
|
88
|
-
});
|
|
89
|
-
return new Response(new Uint8Array(buffer), {
|
|
90
|
-
headers: {
|
|
91
|
-
"Content-Type": "application/zip",
|
|
92
|
-
"Content-Length": String(buffer.length),
|
|
93
|
-
"Content-Disposition": contentDisposition(`${baseName}.zip`),
|
|
94
|
-
"Cache-Control": "private, no-store",
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return NextResponse.json({ error: "Unsupported path" }, { status: 400 });
|
|
100
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { readFile, stat } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { NextResponse } from "next/server";
|
|
4
|
-
import { resolveWorkspaceForAgent } from "@/lib/workspace-context";
|
|
5
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
6
|
-
|
|
7
|
-
const MIME_MAP: Record<string, string> = {
|
|
8
|
-
jpg: "image/jpeg",
|
|
9
|
-
jpeg: "image/jpeg",
|
|
10
|
-
png: "image/png",
|
|
11
|
-
gif: "image/gif",
|
|
12
|
-
webp: "image/webp",
|
|
13
|
-
svg: "image/svg+xml",
|
|
14
|
-
avif: "image/avif",
|
|
15
|
-
ico: "image/x-icon",
|
|
16
|
-
bmp: "image/bmp",
|
|
17
|
-
pdf: "application/pdf",
|
|
18
|
-
txt: "text/plain; charset=utf-8",
|
|
19
|
-
md: "text/markdown; charset=utf-8",
|
|
20
|
-
mp4: "video/mp4",
|
|
21
|
-
webm: "video/webm",
|
|
22
|
-
mov: "video/quicktime",
|
|
23
|
-
m4v: "video/mp4",
|
|
24
|
-
mp3: "audio/mpeg",
|
|
25
|
-
wav: "audio/wav",
|
|
26
|
-
ogg: "audio/ogg",
|
|
27
|
-
m4a: "audio/mp4",
|
|
28
|
-
aac: "audio/aac",
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export async function GET(request: Request) {
|
|
32
|
-
const wsx = await resolveWorkspaceForAgent(request);
|
|
33
|
-
if (!wsx.ok) return NextResponse.json({ error: wsx.code }, { status: wsx.status });
|
|
34
|
-
const { rootDir } = wsx;
|
|
35
|
-
|
|
36
|
-
const { searchParams } = new URL(request.url);
|
|
37
|
-
const rel = searchParams.get("path") ?? "";
|
|
38
|
-
const filePath = safeWorkspacePath(rootDir, rel);
|
|
39
|
-
if (!filePath)
|
|
40
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
41
|
-
try {
|
|
42
|
-
const info = await stat(filePath);
|
|
43
|
-
if (info.isDirectory())
|
|
44
|
-
return NextResponse.json({ error: "Not a file" }, { status: 400 });
|
|
45
|
-
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
46
|
-
const contentType = MIME_MAP[ext] ?? "application/octet-stream";
|
|
47
|
-
const buffer = await readFile(filePath);
|
|
48
|
-
return new Response(buffer, {
|
|
49
|
-
headers: {
|
|
50
|
-
"Content-Type": contentType,
|
|
51
|
-
"Cache-Control": "private, max-age=60",
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
} catch {
|
|
55
|
-
return NextResponse.json({ error: "File not found" }, { status: 404 });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { mkdir } from "node:fs/promises";
|
|
2
|
-
import { NextResponse } from "next/server";
|
|
3
|
-
import { checkOrigin } from "@/lib/auth/csrf";
|
|
4
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
5
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
6
|
-
|
|
7
|
-
export async function POST(request: Request) {
|
|
8
|
-
const csrf = checkOrigin(request);
|
|
9
|
-
if (csrf) return csrf;
|
|
10
|
-
const ctx = await resolveWorkspaceForUser(request, "write");
|
|
11
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
12
|
-
const { rootDir } = ctx;
|
|
13
|
-
|
|
14
|
-
const body: { path?: string } = await request.json();
|
|
15
|
-
const rel = body.path;
|
|
16
|
-
|
|
17
|
-
if (!rel || typeof rel !== "string" || /[<>:"|?*]/.test(rel)) {
|
|
18
|
-
return NextResponse.json({ error: "Invalid folder path" }, { status: 400 });
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const folderPath = safeWorkspacePath(rootDir, rel);
|
|
22
|
-
if (!folderPath)
|
|
23
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
await mkdir(folderPath, { recursive: true });
|
|
27
|
-
return NextResponse.json({ ok: true });
|
|
28
|
-
} catch {
|
|
29
|
-
return NextResponse.json(
|
|
30
|
-
{ error: "Failed to create folder" },
|
|
31
|
-
{ status: 500 },
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import { detectGitRepo, gitBranches } from "@/lib/git";
|
|
3
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
4
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
5
|
-
|
|
6
|
-
export async function GET(request: Request) {
|
|
7
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
8
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
9
|
-
const { rootDir } = ctx;
|
|
10
|
-
|
|
11
|
-
const { searchParams } = new URL(request.url);
|
|
12
|
-
const rel = searchParams.get("path") ?? "";
|
|
13
|
-
if (!rel) return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
14
|
-
|
|
15
|
-
const repoDir = safeWorkspacePath(rootDir, rel);
|
|
16
|
-
if (!repoDir || repoDir === rootDir)
|
|
17
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
18
|
-
|
|
19
|
-
if (!(await detectGitRepo(repoDir)))
|
|
20
|
-
return NextResponse.json({ error: "Not a git repository" }, { status: 400 });
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const branches = await gitBranches(repoDir);
|
|
24
|
-
const current = branches.find((b) => b.current)?.name ?? "";
|
|
25
|
-
return NextResponse.json({ branches, current });
|
|
26
|
-
} catch {
|
|
27
|
-
return NextResponse.json(
|
|
28
|
-
{ error: "Failed to list branches" },
|
|
29
|
-
{ status: 500 },
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import { detectGitRepo, gitCheckout } from "@/lib/git";
|
|
3
|
-
import { checkOrigin } from "@/lib/auth/csrf";
|
|
4
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
5
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
6
|
-
|
|
7
|
-
export async function POST(request: Request) {
|
|
8
|
-
const csrf = checkOrigin(request);
|
|
9
|
-
if (csrf) return csrf;
|
|
10
|
-
|
|
11
|
-
const ctx = await resolveWorkspaceForUser(request, "write");
|
|
12
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
13
|
-
const { rootDir } = ctx;
|
|
14
|
-
|
|
15
|
-
const body: { path?: string; branch?: string } = await request.json();
|
|
16
|
-
const rel = body.path;
|
|
17
|
-
const branch = body.branch;
|
|
18
|
-
|
|
19
|
-
if (!rel || typeof rel !== "string" || !branch || typeof branch !== "string")
|
|
20
|
-
return NextResponse.json({ error: "Invalid params" }, { status: 400 });
|
|
21
|
-
|
|
22
|
-
const repoDir = safeWorkspacePath(rootDir, rel);
|
|
23
|
-
if (!repoDir || repoDir === rootDir)
|
|
24
|
-
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
25
|
-
|
|
26
|
-
if (!(await detectGitRepo(repoDir)))
|
|
27
|
-
return NextResponse.json({ error: "Not a git repository" }, { status: 400 });
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const result = await gitCheckout(repoDir, branch);
|
|
31
|
-
return NextResponse.json({ ok: true, ...result });
|
|
32
|
-
} catch (err: unknown) {
|
|
33
|
-
if (err instanceof Error && (err as Error & { dirty?: boolean }).dirty) {
|
|
34
|
-
return NextResponse.json(
|
|
35
|
-
{ error: "DIRTY", message: "Repository has uncommitted changes" },
|
|
36
|
-
{ status: 409 },
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
if (err instanceof Error && (err as Error & { invalidBranch?: boolean }).invalidBranch) {
|
|
40
|
-
return NextResponse.json({ error: "Invalid branch name" }, { status: 400 });
|
|
41
|
-
}
|
|
42
|
-
const message = err instanceof Error ? err.message : "Checkout failed";
|
|
43
|
-
return NextResponse.json({ error: "Checkout failed", message }, { status: 500 });
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import { findEnclosingGitRepo, gitFileDiff } from "@/lib/git";
|
|
3
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
4
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
5
|
-
|
|
6
|
-
export async function GET(request: Request) {
|
|
7
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
8
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
9
|
-
const { rootDir } = ctx;
|
|
10
|
-
|
|
11
|
-
const { searchParams } = new URL(request.url);
|
|
12
|
-
const rel = searchParams.get("path") ?? "";
|
|
13
|
-
const sha = searchParams.get("sha") ?? "";
|
|
14
|
-
|
|
15
|
-
if (!rel || !sha) return NextResponse.json({ error: "Invalid params" }, { status: 400 });
|
|
16
|
-
// Reject anything that is not a valid abbreviated or full SHA
|
|
17
|
-
if (!/^[0-9a-f]{7,40}$/i.test(sha))
|
|
18
|
-
return NextResponse.json({ error: "Invalid sha" }, { status: 400 });
|
|
19
|
-
|
|
20
|
-
const filePath = safeWorkspacePath(rootDir, rel);
|
|
21
|
-
if (!filePath) return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
22
|
-
|
|
23
|
-
const repo = await findEnclosingGitRepo(rootDir, rel);
|
|
24
|
-
if (!repo)
|
|
25
|
-
return NextResponse.json({ error: "Not in a git repository" }, { status: 404 });
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const diff = await gitFileDiff(repo.repoDir, repo.relFromRepo, sha);
|
|
29
|
-
return NextResponse.json({ diff });
|
|
30
|
-
} catch {
|
|
31
|
-
return NextResponse.json({ error: "Diff failed" }, { status: 500 });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import { findEnclosingGitRepo, gitFileInfo } from "@/lib/git";
|
|
3
|
-
import { resolveWorkspaceForUser } from "@/lib/workspace-context";
|
|
4
|
-
import { safeWorkspacePath } from "@/lib/workspaces";
|
|
5
|
-
|
|
6
|
-
export async function GET(request: Request) {
|
|
7
|
-
const ctx = await resolveWorkspaceForUser(request);
|
|
8
|
-
if (!ctx.ok) return NextResponse.json({ error: ctx.code }, { status: ctx.status });
|
|
9
|
-
const { rootDir } = ctx;
|
|
10
|
-
|
|
11
|
-
const { searchParams } = new URL(request.url);
|
|
12
|
-
const rel = searchParams.get("path") ?? "";
|
|
13
|
-
if (!rel) return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
14
|
-
|
|
15
|
-
const filePath = safeWorkspacePath(rootDir, rel);
|
|
16
|
-
if (!filePath) return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
17
|
-
|
|
18
|
-
const repo = await findEnclosingGitRepo(rootDir, rel);
|
|
19
|
-
if (!repo) return NextResponse.json({ info: null });
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
const info = await gitFileInfo(repo.repoDir, repo.relFromRepo);
|
|
23
|
-
return NextResponse.json({ info });
|
|
24
|
-
} catch {
|
|
25
|
-
return NextResponse.json({ info: null });
|
|
26
|
-
}
|
|
27
|
-
}
|