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,439 +0,0 @@
|
|
|
1
|
-
import { create } from "zustand";
|
|
2
|
-
import type { FrontMatter, SaveStatus } from "@/types";
|
|
3
|
-
import { wsFetch } from "@/lib/workspace-client";
|
|
4
|
-
|
|
5
|
-
// Adapter around ccmc's /api/wiki/content endpoints.
|
|
6
|
-
// The API returns { content: string } and accepts { path, content }.
|
|
7
|
-
// We model frontmatter as null since ccmc doesn't expose it from the API.
|
|
8
|
-
|
|
9
|
-
export class FetchPageError extends Error {
|
|
10
|
-
constructor(
|
|
11
|
-
message: string,
|
|
12
|
-
public readonly status: number,
|
|
13
|
-
) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = "FetchPageError";
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface PageData {
|
|
20
|
-
path: string;
|
|
21
|
-
content: string;
|
|
22
|
-
frontmatter: FrontMatter | null;
|
|
23
|
-
revision: number | null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async function fetchPageFromApi(path: string, signal?: AbortSignal): Promise<PageData> {
|
|
27
|
-
const res = await wsFetch(`/api/wiki/content?path=${encodeURIComponent(path)}`, { signal });
|
|
28
|
-
if (!res.ok) {
|
|
29
|
-
throw new FetchPageError(`Failed to fetch page: ${path}`, res.status);
|
|
30
|
-
}
|
|
31
|
-
const data: { content: string } = await res.json();
|
|
32
|
-
const revHeader = res.headers.get("X-Wiki-Revision");
|
|
33
|
-
const revision = revHeader !== null ? Number(revHeader) : null;
|
|
34
|
-
return { path, content: data.content, frontmatter: null, revision };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface SaveResult {
|
|
38
|
-
revision: number | null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Error thrown when the server reports a stale revision (409). */
|
|
42
|
-
export class StaleRevisionError extends Error {
|
|
43
|
-
constructor(
|
|
44
|
-
public readonly currentRevision: number,
|
|
45
|
-
public readonly serverContent: string,
|
|
46
|
-
) {
|
|
47
|
-
super("File was modified externally. Reloaded with latest content.");
|
|
48
|
-
this.name = "StaleRevisionError";
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function savePageToApi(
|
|
53
|
-
path: string,
|
|
54
|
-
content: string,
|
|
55
|
-
baseRevision: number | null,
|
|
56
|
-
): Promise<SaveResult> {
|
|
57
|
-
const body: Record<string, unknown> = { path, content };
|
|
58
|
-
if (baseRevision !== null) body.baseRevision = baseRevision;
|
|
59
|
-
const res = await wsFetch("/api/wiki/content", {
|
|
60
|
-
method: "PUT",
|
|
61
|
-
headers: { "Content-Type": "application/json" },
|
|
62
|
-
body: JSON.stringify(body),
|
|
63
|
-
});
|
|
64
|
-
if (res.status === 409) {
|
|
65
|
-
// Server has a newer revision. Fetch current content and surface the conflict.
|
|
66
|
-
const conflictData = (await res.json()) as { currentRevision?: number };
|
|
67
|
-
const freshRes = await wsFetch(`/api/wiki/content?path=${encodeURIComponent(path)}`);
|
|
68
|
-
const freshContent = freshRes.ok
|
|
69
|
-
? ((await freshRes.json()) as { content: string }).content
|
|
70
|
-
: content;
|
|
71
|
-
throw new StaleRevisionError(conflictData.currentRevision ?? 0, freshContent);
|
|
72
|
-
}
|
|
73
|
-
if (!res.ok) {
|
|
74
|
-
throw new Error("Failed to save page");
|
|
75
|
-
}
|
|
76
|
-
const data = (await res.json()) as { revision?: number };
|
|
77
|
-
return { revision: data.revision ?? null };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async function createPageInApi(path: string, content = ""): Promise<void> {
|
|
81
|
-
// ccmc has no dedicated create endpoint; saving empty content creates the file.
|
|
82
|
-
await savePageToApi(path, content, null);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const PAGE_CACHE_KEY = "kb-page-cache";
|
|
86
|
-
|
|
87
|
-
// In-memory LRU of recently fetched pages. The localStorage cache holds only the
|
|
88
|
-
// single most-recent page; this lets back-and-forth navigation and hover-prefetch
|
|
89
|
-
// paint instantly without a round-trip. Bounded so it can't grow without limit.
|
|
90
|
-
const MEM_CACHE_MAX = 30;
|
|
91
|
-
const pageMemCache = new Map<string, PageData>();
|
|
92
|
-
// Dedups concurrent fetches for the same path (hover-prefetch + click race).
|
|
93
|
-
const inflightPages = new Map<string, Promise<PageData>>();
|
|
94
|
-
|
|
95
|
-
function memCacheGet(path: string): PageData | null {
|
|
96
|
-
const hit = pageMemCache.get(path);
|
|
97
|
-
if (!hit) return null;
|
|
98
|
-
// Refresh LRU recency.
|
|
99
|
-
pageMemCache.delete(path);
|
|
100
|
-
pageMemCache.set(path, hit);
|
|
101
|
-
return hit;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function memCacheSet(page: PageData): void {
|
|
105
|
-
pageMemCache.delete(page.path);
|
|
106
|
-
pageMemCache.set(page.path, page);
|
|
107
|
-
if (pageMemCache.size > MEM_CACHE_MAX) {
|
|
108
|
-
const oldest = pageMemCache.keys().next().value;
|
|
109
|
-
if (oldest !== undefined) pageMemCache.delete(oldest);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Fetch a page into the in-memory cache ahead of an actual open (e.g. on tree
|
|
115
|
-
* hover). Deduped via inflightPages so a hover followed by a click reuses the
|
|
116
|
-
* same request. Best-effort: failures are swallowed.
|
|
117
|
-
*/
|
|
118
|
-
export function prefetchPage(path: string): void {
|
|
119
|
-
if (pageMemCache.has(path) || inflightPages.has(path)) return;
|
|
120
|
-
const p = fetchPageFromApi(path)
|
|
121
|
-
.then((page) => {
|
|
122
|
-
memCacheSet(page);
|
|
123
|
-
return page;
|
|
124
|
-
})
|
|
125
|
-
.finally(() => {
|
|
126
|
-
inflightPages.delete(path);
|
|
127
|
-
});
|
|
128
|
-
inflightPages.set(path, p);
|
|
129
|
-
// Swallow rejections so an unawaited prefetch never throws unhandled.
|
|
130
|
-
p.catch(() => {});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
interface CachedPage {
|
|
134
|
-
path: string;
|
|
135
|
-
content: string;
|
|
136
|
-
frontmatter: FrontMatter | null;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function loadCachedPage(path: string): CachedPage | null {
|
|
140
|
-
if (typeof window === "undefined") return null;
|
|
141
|
-
try {
|
|
142
|
-
const raw = localStorage.getItem(PAGE_CACHE_KEY);
|
|
143
|
-
if (!raw) return null;
|
|
144
|
-
const parsed = JSON.parse(raw) as CachedPage;
|
|
145
|
-
if (parsed.path !== path) return null;
|
|
146
|
-
return parsed;
|
|
147
|
-
} catch {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function saveCachedPage(page: CachedPage) {
|
|
153
|
-
if (typeof window === "undefined") return;
|
|
154
|
-
try {
|
|
155
|
-
localStorage.setItem(PAGE_CACHE_KEY, JSON.stringify(page));
|
|
156
|
-
} catch {
|
|
157
|
-
// quota errors are non-fatal
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export type LoadStatus = "idle" | "loading" | "ok" | "missing" | "error";
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Editor interaction mode.
|
|
165
|
-
* - "editing": human edits write directly to the file (full-file PUT).
|
|
166
|
-
* - "suggesting": human block edits are captured as suggestions (block ops,
|
|
167
|
-
* by: "human") and the editor block reverts to the snapshot. The file is
|
|
168
|
-
* not changed until a suggestion is accepted.
|
|
169
|
-
*/
|
|
170
|
-
export type EditMode = "editing" | "suggesting";
|
|
171
|
-
|
|
172
|
-
interface EditorState {
|
|
173
|
-
currentPath: string | null;
|
|
174
|
-
content: string;
|
|
175
|
-
frontmatter: FrontMatter | null;
|
|
176
|
-
saveStatus: SaveStatus;
|
|
177
|
-
loadStatus: LoadStatus;
|
|
178
|
-
isDirty: boolean;
|
|
179
|
-
isLoading: boolean;
|
|
180
|
-
lastSavedAt: number | null;
|
|
181
|
-
/** Last confirmed revision from the server. null until first save/sync. */
|
|
182
|
-
currentRevision: number | null;
|
|
183
|
-
/** Current interaction mode. Persisted in localStorage. */
|
|
184
|
-
editMode: EditMode;
|
|
185
|
-
|
|
186
|
-
loadPage: (path: string) => Promise<void>;
|
|
187
|
-
updateContent: (content: string) => void;
|
|
188
|
-
updateFrontmatter: (updates: Partial<FrontMatter>) => void;
|
|
189
|
-
save: () => Promise<void>;
|
|
190
|
-
createMissingPage: (title: string) => Promise<void>;
|
|
191
|
-
clear: () => void;
|
|
192
|
-
/** Sync the known revision from an external source (e.g. proof-store snapshot). */
|
|
193
|
-
syncRevision: (revision: number) => void;
|
|
194
|
-
/** Switch interaction mode (editing | suggesting). */
|
|
195
|
-
setEditMode: (mode: EditMode) => void;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const EDIT_MODE_KEY = "kb-edit-mode";
|
|
199
|
-
|
|
200
|
-
function loadEditMode(): EditMode {
|
|
201
|
-
if (typeof window === "undefined") return "editing";
|
|
202
|
-
return localStorage.getItem(EDIT_MODE_KEY) === "suggesting"
|
|
203
|
-
? "suggesting"
|
|
204
|
-
: "editing";
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let saveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
208
|
-
let statusTimer: ReturnType<typeof setTimeout> | null = null;
|
|
209
|
-
// Aborts the in-flight content fetch when a newer loadPage() supersedes it, so
|
|
210
|
-
// rapid navigation doesn't pile up requests behind the browser connection limit.
|
|
211
|
-
let loadAbort: AbortController | null = null;
|
|
212
|
-
|
|
213
|
-
export const useEditorStore = create<EditorState>((set, get) => ({
|
|
214
|
-
currentPath: null,
|
|
215
|
-
content: "",
|
|
216
|
-
frontmatter: null,
|
|
217
|
-
saveStatus: "idle",
|
|
218
|
-
loadStatus: "idle",
|
|
219
|
-
isDirty: false,
|
|
220
|
-
isLoading: false,
|
|
221
|
-
lastSavedAt: null,
|
|
222
|
-
currentRevision: null,
|
|
223
|
-
editMode: loadEditMode(),
|
|
224
|
-
|
|
225
|
-
setEditMode: (mode: EditMode) => {
|
|
226
|
-
if (typeof window !== "undefined") {
|
|
227
|
-
localStorage.setItem(EDIT_MODE_KEY, mode);
|
|
228
|
-
}
|
|
229
|
-
set({ editMode: mode });
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
loadPage: async (path: string) => {
|
|
233
|
-
const currentState = get();
|
|
234
|
-
// If we're switching to a different page, save any pending changes first.
|
|
235
|
-
if (
|
|
236
|
-
currentState.isDirty &&
|
|
237
|
-
currentState.currentPath &&
|
|
238
|
-
currentState.currentPath !== path
|
|
239
|
-
) {
|
|
240
|
-
await get().save();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
set({
|
|
244
|
-
currentPath: path,
|
|
245
|
-
isLoading: true,
|
|
246
|
-
loadStatus: "loading",
|
|
247
|
-
isDirty: false,
|
|
248
|
-
content: "",
|
|
249
|
-
currentRevision: null,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
// Paint from cache immediately so the editor feels instant. In-memory LRU
|
|
253
|
-
// (incl. hover-prefetched pages) wins over the single-slot localStorage cache.
|
|
254
|
-
const mem = memCacheGet(path);
|
|
255
|
-
const cached = mem ?? loadCachedPage(path);
|
|
256
|
-
if (cached) {
|
|
257
|
-
set({
|
|
258
|
-
content: cached.content,
|
|
259
|
-
frontmatter: cached.frontmatter,
|
|
260
|
-
isLoading: false,
|
|
261
|
-
loadStatus: "ok",
|
|
262
|
-
...(mem ? { currentRevision: mem.revision } : {}),
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// If a hover-prefetch for this path is already in flight, ride it instead of
|
|
267
|
-
// firing a second request.
|
|
268
|
-
const pending = inflightPages.get(path);
|
|
269
|
-
if (pending) {
|
|
270
|
-
try {
|
|
271
|
-
const page = await pending;
|
|
272
|
-
if (get().currentPath !== path) return;
|
|
273
|
-
set({
|
|
274
|
-
content: page.content,
|
|
275
|
-
frontmatter: page.frontmatter,
|
|
276
|
-
isLoading: false,
|
|
277
|
-
loadStatus: "ok",
|
|
278
|
-
currentRevision: page.revision,
|
|
279
|
-
});
|
|
280
|
-
saveCachedPage({ path, content: page.content, frontmatter: page.frontmatter });
|
|
281
|
-
return;
|
|
282
|
-
} catch {
|
|
283
|
-
// fall through to a fresh fetch below
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Abort any prior in-flight content fetch — rapid navigation otherwise
|
|
288
|
-
// queues N fetches behind the browser's ~6-connection-per-host limit.
|
|
289
|
-
loadAbort?.abort();
|
|
290
|
-
const ctrl = new AbortController();
|
|
291
|
-
loadAbort = ctrl;
|
|
292
|
-
|
|
293
|
-
try {
|
|
294
|
-
const page = await fetchPageFromApi(path, ctrl.signal);
|
|
295
|
-
memCacheSet(page);
|
|
296
|
-
// A newer loadPage() call may have superseded us.
|
|
297
|
-
if (get().currentPath !== path) return;
|
|
298
|
-
set({
|
|
299
|
-
content: page.content,
|
|
300
|
-
frontmatter: page.frontmatter,
|
|
301
|
-
isLoading: false,
|
|
302
|
-
loadStatus: "ok",
|
|
303
|
-
currentRevision: page.revision,
|
|
304
|
-
});
|
|
305
|
-
saveCachedPage({
|
|
306
|
-
path,
|
|
307
|
-
content: page.content,
|
|
308
|
-
frontmatter: page.frontmatter,
|
|
309
|
-
});
|
|
310
|
-
} catch (err) {
|
|
311
|
-
// Superseded fetch was aborted — newer navigation owns the state now.
|
|
312
|
-
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
313
|
-
if (get().currentPath !== path) return;
|
|
314
|
-
if (err instanceof FetchPageError && err.status === 404) {
|
|
315
|
-
set({ isLoading: false, loadStatus: "missing", content: "" });
|
|
316
|
-
} else {
|
|
317
|
-
// Keep cached content visible; mark as error.
|
|
318
|
-
set({ isLoading: false, loadStatus: "error" });
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
|
|
323
|
-
updateContent: (content: string) => {
|
|
324
|
-
// In suggesting mode, human edits never write the file directly. They are
|
|
325
|
-
// captured as suggestions (block ops) and the editor reverts. Skip the
|
|
326
|
-
// dirty flag + autosave entirely so no full-file PUT is scheduled.
|
|
327
|
-
if (get().editMode === "suggesting") {
|
|
328
|
-
set({ content });
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
set({ content, isDirty: true });
|
|
332
|
-
|
|
333
|
-
// Auto-save after 500 ms of inactivity.
|
|
334
|
-
if (saveTimer) clearTimeout(saveTimer);
|
|
335
|
-
saveTimer = setTimeout(() => {
|
|
336
|
-
get().save();
|
|
337
|
-
}, 500);
|
|
338
|
-
},
|
|
339
|
-
|
|
340
|
-
updateFrontmatter: (updates: Partial<FrontMatter>) => {
|
|
341
|
-
const current = get().frontmatter;
|
|
342
|
-
set({
|
|
343
|
-
frontmatter: { ...current, ...updates } as FrontMatter,
|
|
344
|
-
isDirty: true,
|
|
345
|
-
});
|
|
346
|
-
if (saveTimer) clearTimeout(saveTimer);
|
|
347
|
-
saveTimer = setTimeout(() => {
|
|
348
|
-
get().save();
|
|
349
|
-
}, 500);
|
|
350
|
-
},
|
|
351
|
-
|
|
352
|
-
save: async () => {
|
|
353
|
-
const { currentPath, content, isDirty, currentRevision, editMode } = get();
|
|
354
|
-
if (!currentPath || !isDirty) return;
|
|
355
|
-
// Suggesting mode must never write the file via full-file PUT.
|
|
356
|
-
if (editMode === "suggesting") return;
|
|
357
|
-
|
|
358
|
-
set({ saveStatus: "saving" });
|
|
359
|
-
try {
|
|
360
|
-
const result = await savePageToApi(currentPath, content, currentRevision);
|
|
361
|
-
set({
|
|
362
|
-
saveStatus: "saved",
|
|
363
|
-
isDirty: false,
|
|
364
|
-
lastSavedAt: Date.now(),
|
|
365
|
-
currentRevision: result.revision ?? currentRevision,
|
|
366
|
-
});
|
|
367
|
-
saveCachedPage({
|
|
368
|
-
path: currentPath,
|
|
369
|
-
content,
|
|
370
|
-
frontmatter: get().frontmatter,
|
|
371
|
-
});
|
|
372
|
-
memCacheSet({
|
|
373
|
-
path: currentPath,
|
|
374
|
-
content,
|
|
375
|
-
frontmatter: get().frontmatter,
|
|
376
|
-
revision: result.revision ?? currentRevision,
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
if (statusTimer) clearTimeout(statusTimer);
|
|
380
|
-
statusTimer = setTimeout(() => {
|
|
381
|
-
if (get().saveStatus === "saved") set({ saveStatus: "idle" });
|
|
382
|
-
}, 2000);
|
|
383
|
-
} catch (err) {
|
|
384
|
-
if (err instanceof StaleRevisionError) {
|
|
385
|
-
// Server has a newer revision: reload editor with fresh content.
|
|
386
|
-
set({
|
|
387
|
-
content: err.serverContent,
|
|
388
|
-
isDirty: false,
|
|
389
|
-
saveStatus: "error",
|
|
390
|
-
currentRevision: err.currentRevision,
|
|
391
|
-
});
|
|
392
|
-
saveCachedPage({
|
|
393
|
-
path: currentPath,
|
|
394
|
-
content: err.serverContent,
|
|
395
|
-
frontmatter: get().frontmatter,
|
|
396
|
-
});
|
|
397
|
-
} else {
|
|
398
|
-
set({ saveStatus: "error" });
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
|
|
403
|
-
createMissingPage: async (title: string) => {
|
|
404
|
-
const { currentPath } = get();
|
|
405
|
-
if (!currentPath) return;
|
|
406
|
-
const initialContent = `# ${title}\n\n`;
|
|
407
|
-
try {
|
|
408
|
-
await createPageInApi(`${currentPath}/index.md`, initialContent);
|
|
409
|
-
set({ content: initialContent, isDirty: false, loadStatus: "ok" });
|
|
410
|
-
saveCachedPage({
|
|
411
|
-
path: currentPath,
|
|
412
|
-
content: initialContent,
|
|
413
|
-
frontmatter: null,
|
|
414
|
-
});
|
|
415
|
-
} catch {
|
|
416
|
-
// silently ignore — user can retry
|
|
417
|
-
}
|
|
418
|
-
},
|
|
419
|
-
|
|
420
|
-
clear: () => {
|
|
421
|
-
if (saveTimer) clearTimeout(saveTimer);
|
|
422
|
-
if (statusTimer) clearTimeout(statusTimer);
|
|
423
|
-
set({
|
|
424
|
-
currentPath: null,
|
|
425
|
-
content: "",
|
|
426
|
-
frontmatter: null,
|
|
427
|
-
saveStatus: "idle",
|
|
428
|
-
loadStatus: "idle",
|
|
429
|
-
isDirty: false,
|
|
430
|
-
isLoading: false,
|
|
431
|
-
lastSavedAt: null,
|
|
432
|
-
currentRevision: null,
|
|
433
|
-
});
|
|
434
|
-
},
|
|
435
|
-
|
|
436
|
-
syncRevision: (revision: number) => {
|
|
437
|
-
set({ currentRevision: revision });
|
|
438
|
-
},
|
|
439
|
-
}));
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { create } from "zustand";
|
|
3
|
-
|
|
4
|
-
export interface PinnedEntry {
|
|
5
|
-
path: string;
|
|
6
|
-
name: string;
|
|
7
|
-
type?: "file" | "app" | "node-app";
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface PinState {
|
|
11
|
-
pins: PinnedEntry[];
|
|
12
|
-
loadForWorkspace: (workspaceId: string | null | undefined) => void;
|
|
13
|
-
toggle: (entry: PinnedEntry, workspaceId: string | null | undefined) => void;
|
|
14
|
-
isPinned: (path: string) => boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function storageKey(ws: string | null | undefined): string {
|
|
18
|
-
return ws ? `wiki-pinned-files-${ws}` : "wiki-pinned-files";
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function readStorage(ws: string | null | undefined): PinnedEntry[] {
|
|
22
|
-
if (typeof window === "undefined") return [];
|
|
23
|
-
try {
|
|
24
|
-
const raw = localStorage.getItem(storageKey(ws));
|
|
25
|
-
return raw ? (JSON.parse(raw) as PinnedEntry[]) : [];
|
|
26
|
-
} catch {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function writeStorage(ws: string | null | undefined, items: PinnedEntry[]): void {
|
|
32
|
-
if (typeof window === "undefined") return;
|
|
33
|
-
localStorage.setItem(storageKey(ws), JSON.stringify(items));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const usePinStore = create<PinState>((set, get) => ({
|
|
37
|
-
pins: [],
|
|
38
|
-
|
|
39
|
-
loadForWorkspace: (ws) => {
|
|
40
|
-
set({ pins: readStorage(ws) });
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
toggle: (entry, ws) => {
|
|
44
|
-
const current = readStorage(ws);
|
|
45
|
-
const exists = current.some((p) => p.path === entry.path);
|
|
46
|
-
const next = exists
|
|
47
|
-
? current.filter((p) => p.path !== entry.path)
|
|
48
|
-
: [...current, entry];
|
|
49
|
-
writeStorage(ws, next);
|
|
50
|
-
set({ pins: next });
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
isPinned: (path) => {
|
|
54
|
-
return get().pins.some((p) => p.path === path);
|
|
55
|
-
},
|
|
56
|
-
}));
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { create } from "zustand";
|
|
2
|
-
import { authHeaders } from "@/lib/proof/client-auth";
|
|
3
|
-
import { wsFetch } from "@/lib/workspace-client";
|
|
4
|
-
import { useEditorStore } from "@/stores/editor-store";
|
|
5
|
-
import type { Sidecar, ProofEvent, Block, Snapshot } from "@/lib/proof/types";
|
|
6
|
-
|
|
7
|
-
interface PathEntry {
|
|
8
|
-
sidecar: Sidecar | null;
|
|
9
|
-
snapshotRevision: number;
|
|
10
|
-
lastEventId: number;
|
|
11
|
-
/** Ordered block list from latest GET snapshot. Used to resolve ref→position in editor. */
|
|
12
|
-
snapshotBlocks: Block[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface ProofState {
|
|
16
|
-
byPath: Record<string, PathEntry>;
|
|
17
|
-
loadSidecar(path: string): Promise<void>;
|
|
18
|
-
/** Fetch GET /api/agent/files/<path> to get ordered block list for ref positioning. */
|
|
19
|
-
loadSnapshot(path: string): Promise<void>;
|
|
20
|
-
pollEvents(path: string): Promise<void>;
|
|
21
|
-
applyEvent(path: string, e: ProofEvent): void;
|
|
22
|
-
reset(path: string): void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function defaultEntry(): PathEntry {
|
|
26
|
-
return { sidecar: null, snapshotRevision: 0, lastEventId: 0, snapshotBlocks: [] };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const useProofStore = create<ProofState>((set, get) => ({
|
|
30
|
-
byPath: {},
|
|
31
|
-
|
|
32
|
-
loadSidecar: async (path: string) => {
|
|
33
|
-
const encoded = encodeURIComponent(path).replace(/%2F/g, "/");
|
|
34
|
-
try {
|
|
35
|
-
const res = await wsFetch(`/api/agent/sidecar/${encoded}`, {
|
|
36
|
-
headers: authHeaders(),
|
|
37
|
-
});
|
|
38
|
-
if (!res.ok) return;
|
|
39
|
-
const sidecar = (await res.json()) as Sidecar;
|
|
40
|
-
set((s) => ({
|
|
41
|
-
byPath: {
|
|
42
|
-
...s.byPath,
|
|
43
|
-
[path]: {
|
|
44
|
-
...(s.byPath[path] ?? defaultEntry()),
|
|
45
|
-
sidecar,
|
|
46
|
-
snapshotRevision: sidecar.revision,
|
|
47
|
-
lastEventId: sidecar.nextEventId - 1,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
}));
|
|
51
|
-
} catch {
|
|
52
|
-
// network error — leave stale
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
loadSnapshot: async (path: string) => {
|
|
57
|
-
const encoded = encodeURIComponent(path).replace(/%2F/g, "/");
|
|
58
|
-
try {
|
|
59
|
-
const res = await wsFetch(`/api/agent/files/${encoded}`, {
|
|
60
|
-
headers: authHeaders(),
|
|
61
|
-
});
|
|
62
|
-
if (!res.ok) return;
|
|
63
|
-
const snap = (await res.json()) as Snapshot;
|
|
64
|
-
set((s) => ({
|
|
65
|
-
byPath: {
|
|
66
|
-
...s.byPath,
|
|
67
|
-
[path]: {
|
|
68
|
-
...(s.byPath[path] ?? defaultEntry()),
|
|
69
|
-
snapshotBlocks: snap.blocks,
|
|
70
|
-
snapshotRevision: snap.revision,
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
}));
|
|
74
|
-
// Sync revision into editor-store so saves send correct baseRevision.
|
|
75
|
-
const editorState = useEditorStore.getState();
|
|
76
|
-
if (editorState.currentPath === path) {
|
|
77
|
-
editorState.syncRevision(snap.revision);
|
|
78
|
-
}
|
|
79
|
-
} catch {
|
|
80
|
-
// network error — leave stale
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
pollEvents: async (path: string) => {
|
|
85
|
-
const entry = get().byPath[path] ?? defaultEntry();
|
|
86
|
-
const encoded = encodeURIComponent(path).replace(/%2F/g, "/");
|
|
87
|
-
try {
|
|
88
|
-
const res = await wsFetch(
|
|
89
|
-
`/api/agent/events/${encoded}?after=${entry.lastEventId}`,
|
|
90
|
-
{ headers: authHeaders() },
|
|
91
|
-
);
|
|
92
|
-
if (!res.ok) return;
|
|
93
|
-
const data = (await res.json()) as { events: ProofEvent[]; lastEventId: number };
|
|
94
|
-
for (const e of data.events) {
|
|
95
|
-
get().applyEvent(path, e);
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
// network error — leave stale
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
applyEvent: (path: string, e: ProofEvent) => {
|
|
103
|
-
set((s) => {
|
|
104
|
-
const prev = s.byPath[path] ?? defaultEntry();
|
|
105
|
-
return {
|
|
106
|
-
byPath: {
|
|
107
|
-
...s.byPath,
|
|
108
|
-
[path]: {
|
|
109
|
-
...prev,
|
|
110
|
-
lastEventId: Math.max(prev.lastEventId, e.id),
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
});
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
reset: (path: string) => {
|
|
118
|
-
set((s) => {
|
|
119
|
-
const next = { ...s.byPath };
|
|
120
|
-
delete next[path];
|
|
121
|
-
return { byPath: next };
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
}));
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { create } from "zustand";
|
|
3
|
-
|
|
4
|
-
export interface RecentEntry {
|
|
5
|
-
path: string;
|
|
6
|
-
name: string;
|
|
7
|
-
type?: "file" | "app" | "node-app";
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface RecentState {
|
|
11
|
-
recents: RecentEntry[];
|
|
12
|
-
loadForWorkspace: (workspaceId: string | null | undefined) => void;
|
|
13
|
-
push: (entry: RecentEntry, workspaceId: string | null | undefined) => void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const MAX_RECENTS = 15;
|
|
17
|
-
|
|
18
|
-
function storageKey(ws: string | null | undefined): string {
|
|
19
|
-
return ws ? `wiki-recent-files-${ws}` : "wiki-recent-files";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function readStorage(ws: string | null | undefined): RecentEntry[] {
|
|
23
|
-
if (typeof window === "undefined") return [];
|
|
24
|
-
try {
|
|
25
|
-
const raw = localStorage.getItem(storageKey(ws));
|
|
26
|
-
return raw ? (JSON.parse(raw) as RecentEntry[]) : [];
|
|
27
|
-
} catch {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function writeStorage(ws: string | null | undefined, items: RecentEntry[]): void {
|
|
33
|
-
if (typeof window === "undefined") return;
|
|
34
|
-
localStorage.setItem(storageKey(ws), JSON.stringify(items));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const useRecentStore = create<RecentState>((set) => ({
|
|
38
|
-
recents: [],
|
|
39
|
-
|
|
40
|
-
loadForWorkspace: (ws) => {
|
|
41
|
-
set({ recents: readStorage(ws) });
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
push: (entry, ws) => {
|
|
45
|
-
const current = readStorage(ws);
|
|
46
|
-
const deduped = current.filter((r) => r.path !== entry.path);
|
|
47
|
-
const next = [entry, ...deduped].slice(0, MAX_RECENTS);
|
|
48
|
-
writeStorage(ws, next);
|
|
49
|
-
set({ recents: next });
|
|
50
|
-
},
|
|
51
|
-
}));
|