wiki-viewer 2.11.7 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/standalone/.next/build-manifest.json +5 -5
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +4 -4
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  16. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +1 -1
  21. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +1 -1
  24. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/agents/install/route.js +1 -1
  30. package/.next/standalone/.next/server/app/api/agents/install/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/agents/skill/route.js +1 -1
  32. package/.next/standalone/.next/server/app/api/agents/skill/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/agents/skill.tar.gz/route.js +1 -1
  34. package/.next/standalone/.next/server/app/api/agents/skill.tar.gz/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/pdf/save/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/share/[token]/asset/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/share/[token]/route.js +3 -4
  40. package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/share/route.js +1 -1
  42. package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  63. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/wiki/scratch/route/app-paths-manifest.json +3 -0
  69. package/.next/standalone/.next/server/app/api/wiki/scratch/route/build-manifest.json +9 -0
  70. package/.next/standalone/.next/server/app/api/wiki/scratch/route/server-reference-manifest.json +4 -0
  71. package/.next/standalone/.next/server/app/api/wiki/scratch/route.js +16 -0
  72. package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.map +5 -0
  73. package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.nft.json +1 -0
  74. package/.next/standalone/.next/server/app/api/wiki/scratch/route_client-reference-manifest.js +3 -0
  75. package/.next/standalone/.next/server/app/api/wiki/search/route.js +1 -1
  76. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  81. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/s/[token]/page/build-manifest.json +2 -2
  84. package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/signin/page/build-manifest.json +2 -2
  86. package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  88. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0pyc~jf._.js → [root-of-the-server]__05o3qcm._.js} +2 -2
  89. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kuwuwk._.js → [root-of-the-server]__07wa2lq._.js} +2 -2
  90. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bpv09n._.js +20 -0
  91. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0269d2e._.js → [root-of-the-server]__0mgvfb5._.js} +2 -2
  92. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0_5~w8k._.js → [root-of-the-server]__0n2r6u9._.js} +2 -2
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qpqspq._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__05tbv~.._.js → [root-of-the-server]__0q~ky91._.js} +2 -2
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uja7sb._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__00sn-o5._.js → [root-of-the-server]__0xoz8e8._.js} +2 -2
  97. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0t4nr00._.js → [root-of-the-server]__10pak1_._.js} +2 -2
  98. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +1 -1
  99. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_scratch_route_actions_07i6~7z.js +3 -0
  100. package/.next/standalone/.next/server/chunks/src_0pwns~4._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/ssr/{0~w0_katex_dist_katex_mjs_12tyg_2._.js → 0~w0_katex_dist_katex_mjs_0-fyxoz._.js} +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-5ZQYHXKU_mjs_0z1.978._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-KSCS5N6A_mjs_0v4oeem._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0vp_6mg._.js → [root-of-the-server]__0~4py6h._.js} +2 -2
  105. package/.next/standalone/.next/server/chunks/ssr/_0oq8kwv._.js +18 -18
  106. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0mlbfkr._.js → node_modules__pnpm_0.xieh4._.js} +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j.6d4e._.js → node_modules__pnpm_01~03ak._.js} +1 -1
  108. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ko9~5a._.js → node_modules__pnpm_02qa21p._.js} +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0wks2mj._.js → node_modules__pnpm_05c~go7._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z3vu9g._.js → node_modules__pnpm_07hg43b._.js} +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0c7mg2j._.js → node_modules__pnpm_09y5c~i._.js} +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_04.xdv4._.js → node_modules__pnpm_0_g0a7t._.js} +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0e_u7-~._.js → node_modules__pnpm_0_zd0nt._.js} +1 -1
  114. package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0a4su30._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_03z~hj.._.js → node_modules__pnpm_0b6_242._.js} +1 -1
  116. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_01vjz.e._.js → node_modules__pnpm_0c6q9~6._.js} +1 -1
  117. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05xxz0p._.js → node_modules__pnpm_0d4-t2b._.js} +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0pq4fcx._.js → node_modules__pnpm_0f0qocb._.js} +1 -1
  119. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0m4ord.._.js → node_modules__pnpm_0f6r-u~._.js} +2 -2
  120. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0k1lm~x._.js → node_modules__pnpm_0f9artj._.js} +2 -2
  121. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0l-zh.x._.js → node_modules__pnpm_0g_tlt-._.js} +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dkpe61._.js → node_modules__pnpm_0ghm84g._.js} +2 -2
  123. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0y~gqyx._.js → node_modules__pnpm_0k6yfdh._.js} +2 -2
  124. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0yw839x._.js → node_modules__pnpm_0kib6pw._.js} +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0o~d81.._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0.a-6pb._.js → node_modules__pnpm_0pggrwu._.js} +2 -2
  127. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0d_jgm8._.js → node_modules__pnpm_0q9s5k5._.js} +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~1a~df._.js → node_modules__pnpm_0q_v1_2._.js} +1 -1
  129. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hlvme9._.js → node_modules__pnpm_0sdy2lv._.js} +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_077radr._.js → node_modules__pnpm_0tvmv0e._.js} +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0e7k2ai._.js → node_modules__pnpm_0v7wopg._.js} +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05b80e_._.js → node_modules__pnpm_0vahm7l._.js} +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11e33_1._.js → node_modules__pnpm_0zdl7-7._.js} +1 -1
  134. package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05-ipmg._.js → node_modules__pnpm_0~wqhb9._.js} +1 -1
  135. package/.next/standalone/.next/server/instrumentation.js +1 -1
  136. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  137. package/.next/standalone/.next/server/pages/500.html +1 -1
  138. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  140. package/.next/standalone/.next/static/chunks/0gogvjz6oxo51.css +1 -0
  141. package/.next/standalone/.next/static/chunks/{08usk_~k6d0yf.js → 0k31ncl7m_j9q.js} +2 -2
  142. package/.next/standalone/.next/static/chunks/{0x6s~jkd4xkpx.js → 11ehczv8yax~_.js} +23 -23
  143. package/.next/standalone/.next/static/chunks/{turbopack-0~8fsjmdvb_1i.js → turbopack-1105gjd__15ti.js} +1 -1
  144. package/.next/standalone/.test-floor +1 -1
  145. package/.next/standalone/package.json +1 -1
  146. package/.next/standalone/server.js +1 -1
  147. package/.next/standalone/specs/changes/scratchpad/design.md +156 -0
  148. package/.next/standalone/specs/changes/scratchpad/proposal.md +82 -0
  149. package/.next/standalone/specs/changes/scratchpad/requirements.md +83 -0
  150. package/.next/standalone/specs/changes/scratchpad/tasks.md +45 -0
  151. package/package.json +1 -1
  152. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k46u9j._.js +0 -3
  153. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11ltgmp._.js +0 -20
  154. package/.next/standalone/.next/server/chunks/src_0ks~u~e._.js +0 -3
  155. package/.next/standalone/.next/static/chunks/0h9okx8g~3~jd.css +0 -1
  156. /package/.next/standalone/.next/static/{N4JUwvz_xf2GOGFJN02sZ → AsrmwC0YfrYEMAXj2s0Wx}/_buildManifest.js +0 -0
  157. /package/.next/standalone/.next/static/{N4JUwvz_xf2GOGFJN02sZ → AsrmwC0YfrYEMAXj2s0Wx}/_clientMiddlewareManifest.js +0 -0
  158. /package/.next/standalone/.next/static/{N4JUwvz_xf2GOGFJN02sZ → AsrmwC0YfrYEMAXj2s0Wx}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,{otherChunks:["static/chunks/057l2ju6dh43x.js","static/chunks/08usk_~k6d0yf.js","static/chunks/0vp-ahhagxptc.js"],runtimeModuleIds:[569959]}]),(()=>{let e;if(!Array.isArray(globalThis.TURBOPACK))return;let t="/_next/",r=function(){if(null!=self.TURBOPACK_ASSET_SUFFIX)return self.TURBOPACK_ASSET_SUFFIX;let e=document?.currentScript?.getAttribute?.("src")??"",t=e.indexOf("?");return t>=0?e.slice(t):""}(),n=["NEXT_DEPLOYMENT_ID","NEXT_CLIENT_ASSET_SUFFIX"];var o,l=((o=l||{})[o.Runtime=0]="Runtime",o[o.Parent=1]="Parent",o[o.Update=2]="Update",o);let i=new WeakMap;function s(e,t){this.m=e,this.e=t}let u=s.prototype,a=Object.prototype.hasOwnProperty,c="u">typeof Symbol&&Symbol.toStringTag;function f(e,t,r){a.call(e,t)||Object.defineProperty(e,t,r)}function p(e,t){let r=e[t];return r||(r=h(t),e[t]=r),r}function h(e){return{exports:{},error:void 0,id:e,namespaceObject:void 0}}function d(e,t){f(e,"__esModule",{value:!0}),c&&f(e,c,{value:"Module"});let r=0;for(;r<t.length;){let n=t[r++],o=t[r++];if("number"==typeof o)if(0===o)f(e,n,{value:t[r++],enumerable:!0,writable:!1});else throw Error(`unexpected tag: ${o}`);else"function"==typeof t[r]?f(e,n,{get:o,set:t[r++],enumerable:!0}):f(e,n,{get:o,enumerable:!0})}Object.seal(e)}function m(e,t){(null!=t?p(this.c,t):this.m).exports=e}u.s=function(e,t){let r,n;null!=t?n=(r=p(this.c,t)).exports:(r=this.m,n=this.e),r.namespaceObject=n,d(n,e)},u.j=function(e,t){var r,n;let o,l,s;null!=t?l=(o=p(this.c,t)).exports:(o=this.m,l=this.e);let u=(r=o,n=l,(s=i.get(r))||(i.set(r,s=[]),r.exports=r.namespaceObject=new Proxy(n,{get(e,t){if(a.call(e,t)||"default"===t||"__esModule"===t)return Reflect.get(e,t);for(let e of s){let r=Reflect.get(e,t);if(void 0!==r)return r}},ownKeys(e){let t=Reflect.ownKeys(e);for(let e of s)for(let r of Reflect.ownKeys(e))"default"===r||t.includes(r)||t.push(r);return t}})),s);"object"==typeof e&&null!==e&&u.push(e)},u.v=m,u.n=function(e,t){let r;(r=null!=t?p(this.c,t):this.m).exports=r.namespaceObject=e};let b=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,y=[null,b({}),b([]),b(b)];function g(e,t,r){let n=[],o=-1;for(let t=e;("object"==typeof t||"function"==typeof t)&&!y.includes(t);t=b(t))for(let r of Object.getOwnPropertyNames(t))n.push(r,function(e,t){return()=>e[t]}(e,r)),-1===o&&"default"===r&&(o=n.length-1);return r&&o>=0||(o>=0?n.splice(o,1,0,e):n.push("default",0,e)),d(t,n),t}function O(e){let t=B(e,this.m);if(t.namespaceObject)return t.namespaceObject;let r=t.exports;return t.namespaceObject=g(r,"function"==typeof r?function(...e){return r.apply(this,e)}:Object.create(null),r&&r.__esModule)}function w(e){let t=e.indexOf("#");-1!==t&&(e=e.substring(0,t));let r=e.indexOf("?");return -1!==r&&(e=e.substring(0,r)),e}function k(){let e,t;return{promise:new Promise((r,n)=>{t=n,e=r}),resolve:e,reject:t}}u.i=O,u.A=function(e){return this.r(e)(O.bind(this))},u.t="function"==typeof require?require:function(){throw Error("Unexpected use of runtime require")},u.r=function(e){return B(e,this.m).exports},u.f=function(e){function t(t){if(t=w(t),a.call(e,t))return e[t].module();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r}return t.keys=()=>Object.keys(e),t.resolve=t=>{if(t=w(t),a.call(e,t))return e[t].id();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r},t.import=async e=>await t(e),t};let j=Symbol("turbopack queues"),U=Symbol("turbopack exports"),v=Symbol("turbopack error");function C(e){e&&1!==e.status&&(e.status=1,e.forEach(e=>e.queueCount--),e.forEach(e=>e.queueCount--?e.queueCount++:e()))}u.a=function(e,t){let r=this.m,n=t?Object.assign([],{status:-1}):void 0,o=new Set,{resolve:l,reject:i,promise:s}=k(),u=Object.assign(s,{[U]:r.exports,[j]:e=>{n&&e(n),o.forEach(e),u.catch(()=>{})}}),a={get:()=>u,set(e){e!==u&&(u[U]=e)}};Object.defineProperty(r,"exports",a),Object.defineProperty(r,"namespaceObject",a),e(function(e){let t=e.map(e=>{if(null!==e&&"object"==typeof e){if(j in e)return e;if(null!=e&&"object"==typeof e&&"then"in e&&"function"==typeof e.then){let t=Object.assign([],{status:0}),r={[U]:{},[j]:e=>e(t)};return e.then(e=>{r[U]=e,C(t)},e=>{r[v]=e,C(t)}),r}}return{[U]:e,[j]:()=>{}}}),r=()=>t.map(e=>{if(e[v])throw e[v];return e[U]}),{promise:l,resolve:i}=k(),s=Object.assign(()=>i(r),{queueCount:0});function u(e){e!==n&&!o.has(e)&&(o.add(e),e&&0===e.status&&(s.queueCount++,e.push(s)))}return t.map(e=>e[j](u)),s.queueCount?l:r()},function(e){e?i(u[v]=e):l(u[U]),C(n)}),n&&-1===n.status&&(n.status=0)};let P=function(e){let t=new URL(e,"x:/"),r={};for(let e in t)r[e]=t[e];for(let t in r.href=e,r.pathname=e.replace(/[?#].*/,""),r.origin=r.protocol="",r.toString=r.toJSON=(...t)=>e,r)Object.defineProperty(this,t,{enumerable:!0,configurable:!0,value:r[t]})};function R(e,t){throw Error(`Invariant: ${t(e)}`)}P.prototype=URL.prototype,u.U=P,u.z=function(e){throw Error("dynamic usage of require is not supported")},u.g=globalThis;let S=s.prototype,$=new Map;u.M=$;let _=new Map,E=new Map;async function T(e,t,r){let n;if("string"==typeof r)return M(e,t,N(r));let o=r.included||[],l=o.map(e=>!!$.has(e)||_.get(e));if(l.length>0&&l.every(e=>e))return void await Promise.all(l);let i=r.moduleChunks||[],s=i.map(e=>E.get(e)).filter(e=>e);if(s.length>0){if(s.length===i.length)return void await Promise.all(s);let r=new Set;for(let e of i)E.has(e)||r.add(e);for(let n of r){let r=M(e,t,N(n));E.set(n,r),s.push(r)}n=Promise.all(s)}else{for(let o of(n=M(e,t,N(r.path)),i))E.has(o)||E.set(o,n)}for(let e of o)_.has(e)||_.set(e,n);await n}S.l=function(e){return T(l.Parent,this.m.id,e)};let A=Promise.resolve(void 0),x=new WeakMap;function M(t,r,n){let o=e.loadChunkCached(t,n),i=x.get(o);if(void 0===i){let e=x.set.bind(x,o,A);i=o.then(e).catch(e=>{let o;switch(t){case l.Runtime:o=`as a runtime dependency of chunk ${r}`;break;case l.Parent:o=`from module ${r}`;break;case l.Update:o="from an HMR update";break;default:R(t,e=>`Unknown source type: ${e}`)}let i=Error(`Failed to load chunk ${n} ${o}${e?`: ${e}`:""}`,e?{cause:e}:void 0);throw i.name="ChunkLoadError",i}),x.set(o,i)}return i}function N(e){return`${t}${e.split("/").map(e=>encodeURIComponent(e)).join("/")}${r}`}S.L=function(e){return M(l.Parent,this.m.id,e)},S.R=function(e){let t=this.r(e);return t?.default??t},S.P=function(e){return`/ROOT/${e??""}`},S.q=function(e,t){m.call(this,`${e}${r}`,t)},S.b=function(e,t,o,l){let i="SharedWorker"===e.name,s=[o.map(e=>N(e)).reverse(),r];for(let e of n)s.push(globalThis[e]);let u=new URL(N(t),location.origin),a=JSON.stringify(s);return i?u.searchParams.set("params",a):u.hash="#params="+encodeURIComponent(a),new e(u,l?{...l,type:void 0}:void 0)};let K=/\.js(?:\?[^#]*)?(?:#.*)?$/,q=/\.css(?:\?[^#]*)?(?:#.*)?$/;function L(e){return q.test(e)}u.w=function(t,r,n){return e.loadWebAssembly(l.Parent,this.m.id,t,r,n)},u.u=function(t,r){return e.loadWebAssemblyModule(l.Parent,this.m.id,t,r)};let I={};u.c=I;let B=(e,t)=>{let r=I[e];if(r){if(r.error)throw r.error;return r}return W(e,l.Parent,t.id)};function W(e,t,r){let n=$.get(e);if("function"!=typeof n)throw Error(function(e,t,r){let n;switch(t){case 0:n=`as a runtime entry of chunk ${r}`;break;case 1:n=`because it was required from module ${r}`;break;case 2:n="because of an HMR update";break;default:R(t,e=>`Unknown source type: ${e}`)}return`Module ${e} was instantiated ${n}, but the module factory is not available.`}(e,t,r));let o=h(e),l=o.exports;I[e]=o;let i=new s(o,l);try{n(i,o,l)}catch(e){throw o.error=e,e}return o.namespaceObject&&o.exports!==o.namespaceObject&&g(o.exports,o.namespaceObject),o}function F(t){let r,n=function(e){if("string"==typeof e)return e;if(e)return{src:e.getAttribute("src")};if("u">typeof TURBOPACK_NEXT_CHUNK_URLS)return{src:TURBOPACK_NEXT_CHUNK_URLS.pop()};throw Error("chunk path empty but not in a worker")}(t[0]);return 2===t.length?r=t[1]:(r=void 0,!function(e,t){let r=1;for(;r<e.length;){let n,o=r+1;for(;o<e.length&&"function"!=typeof e[o];)o++;if(o===e.length)throw Error("malformed chunk format, expected a factory function");let l=e[o];for(let l=r;l<o;l++){let r=e[l],o=t.get(r);if(o){n=o;break}}let i=n??l,s=!1;for(let n=r;n<o;n++){let r=e[n];t.has(r)||(s||(i===l&&Object.defineProperty(l,"name",{value:"module evaluation"}),s=!0),t.set(r,i))}r=o+1}}(t,$)),e.registerChunk(n,r)}let X=new Map;function D(e){let t=X.get(e);if(!t){let r,n;t={resolved:!1,loadingStarted:!1,promise:new Promise((e,t)=>{r=e,n=t}),resolve:()=>{t.resolved=!0,r()},reject:n},X.set(e,t)}return t}e={async registerChunk(e,r){let n=function(e){if("string"==typeof e)return e;let r=decodeURIComponent(e.src.replace(/[?#].*$/,""));return r.startsWith(t)?r.slice(t.length):r}(e);if(D("string"==typeof e?N(e):e.src).resolve(),null!=r){for(let e of r.otherChunks)D(N("string"==typeof e?e:e.path));if(await Promise.all(r.otherChunks.map(e=>T(l.Runtime,n,e))),r.runtimeModuleIds.length>0)for(let e of r.runtimeModuleIds)!function(e,t){let r=I[t];if(r){if(r.error)throw r.error;return}W(t,l.Runtime,e)}(n,e)}},loadChunkCached:(e,t)=>(function(e,t){let r=D(t);if(r.loadingStarted)return r.promise;if(e===l.Runtime)return r.loadingStarted=!0,L(t)&&r.resolve(),r.promise;if("function"==typeof importScripts)if(L(t));else if(K.test(t))self.TURBOPACK_NEXT_CHUNK_URLS.push(t),importScripts(t);else throw Error(`can't infer type of chunk from URL ${t} in worker`);else{let e=decodeURI(t);if(L(t))if(document.querySelectorAll(`link[rel=stylesheet][href="${t}"],link[rel=stylesheet][href^="${t}?"],link[rel=stylesheet][href="${e}"],link[rel=stylesheet][href^="${e}?"]`).length>0)r.resolve();else{let e=document.createElement("link");e.rel="stylesheet",e.href=t,e.onerror=()=>{r.reject()},e.onload=()=>{r.resolve()},document.head.appendChild(e)}else if(K.test(t)){let n=document.querySelectorAll(`script[src="${t}"],script[src^="${t}?"],script[src="${e}"],script[src^="${e}?"]`);if(n.length>0)for(let e of Array.from(n))e.addEventListener("error",()=>{r.reject()});else{let e=document.createElement("script");e.src=t,e.onerror=()=>{r.reject()},document.head.appendChild(e)}}else throw Error(`can't infer type of chunk from URL ${t}`)}return r.loadingStarted=!0,r.promise})(e,t),async loadWebAssembly(e,t,r,n,o){let l=fetch(N(r)),{instance:i}=await WebAssembly.instantiateStreaming(l,o);return i.exports},async loadWebAssemblyModule(e,t,r,n){let o=fetch(N(r));return await WebAssembly.compileStreaming(o)}};let H=globalThis.TURBOPACK;globalThis.TURBOPACK={push:F},H.forEach(F)})();
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,{otherChunks:["static/chunks/057l2ju6dh43x.js","static/chunks/0k31ncl7m_j9q.js","static/chunks/0vp-ahhagxptc.js"],runtimeModuleIds:[569959]}]),(()=>{let e;if(!Array.isArray(globalThis.TURBOPACK))return;let t="/_next/",r=function(){if(null!=self.TURBOPACK_ASSET_SUFFIX)return self.TURBOPACK_ASSET_SUFFIX;let e=document?.currentScript?.getAttribute?.("src")??"",t=e.indexOf("?");return t>=0?e.slice(t):""}(),n=["NEXT_DEPLOYMENT_ID","NEXT_CLIENT_ASSET_SUFFIX"];var o,l=((o=l||{})[o.Runtime=0]="Runtime",o[o.Parent=1]="Parent",o[o.Update=2]="Update",o);let i=new WeakMap;function s(e,t){this.m=e,this.e=t}let u=s.prototype,a=Object.prototype.hasOwnProperty,c="u">typeof Symbol&&Symbol.toStringTag;function f(e,t,r){a.call(e,t)||Object.defineProperty(e,t,r)}function p(e,t){let r=e[t];return r||(r=h(t),e[t]=r),r}function h(e){return{exports:{},error:void 0,id:e,namespaceObject:void 0}}function d(e,t){f(e,"__esModule",{value:!0}),c&&f(e,c,{value:"Module"});let r=0;for(;r<t.length;){let n=t[r++],o=t[r++];if("number"==typeof o)if(0===o)f(e,n,{value:t[r++],enumerable:!0,writable:!1});else throw Error(`unexpected tag: ${o}`);else"function"==typeof t[r]?f(e,n,{get:o,set:t[r++],enumerable:!0}):f(e,n,{get:o,enumerable:!0})}Object.seal(e)}function m(e,t){(null!=t?p(this.c,t):this.m).exports=e}u.s=function(e,t){let r,n;null!=t?n=(r=p(this.c,t)).exports:(r=this.m,n=this.e),r.namespaceObject=n,d(n,e)},u.j=function(e,t){var r,n;let o,l,s;null!=t?l=(o=p(this.c,t)).exports:(o=this.m,l=this.e);let u=(r=o,n=l,(s=i.get(r))||(i.set(r,s=[]),r.exports=r.namespaceObject=new Proxy(n,{get(e,t){if(a.call(e,t)||"default"===t||"__esModule"===t)return Reflect.get(e,t);for(let e of s){let r=Reflect.get(e,t);if(void 0!==r)return r}},ownKeys(e){let t=Reflect.ownKeys(e);for(let e of s)for(let r of Reflect.ownKeys(e))"default"===r||t.includes(r)||t.push(r);return t}})),s);"object"==typeof e&&null!==e&&u.push(e)},u.v=m,u.n=function(e,t){let r;(r=null!=t?p(this.c,t):this.m).exports=r.namespaceObject=e};let b=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,y=[null,b({}),b([]),b(b)];function g(e,t,r){let n=[],o=-1;for(let t=e;("object"==typeof t||"function"==typeof t)&&!y.includes(t);t=b(t))for(let r of Object.getOwnPropertyNames(t))n.push(r,function(e,t){return()=>e[t]}(e,r)),-1===o&&"default"===r&&(o=n.length-1);return r&&o>=0||(o>=0?n.splice(o,1,0,e):n.push("default",0,e)),d(t,n),t}function O(e){let t=B(e,this.m);if(t.namespaceObject)return t.namespaceObject;let r=t.exports;return t.namespaceObject=g(r,"function"==typeof r?function(...e){return r.apply(this,e)}:Object.create(null),r&&r.__esModule)}function w(e){let t=e.indexOf("#");-1!==t&&(e=e.substring(0,t));let r=e.indexOf("?");return -1!==r&&(e=e.substring(0,r)),e}function j(){let e,t;return{promise:new Promise((r,n)=>{t=n,e=r}),resolve:e,reject:t}}u.i=O,u.A=function(e){return this.r(e)(O.bind(this))},u.t="function"==typeof require?require:function(){throw Error("Unexpected use of runtime require")},u.r=function(e){return B(e,this.m).exports},u.f=function(e){function t(t){if(t=w(t),a.call(e,t))return e[t].module();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r}return t.keys=()=>Object.keys(e),t.resolve=t=>{if(t=w(t),a.call(e,t))return e[t].id();let r=Error(`Cannot find module '${t}'`);throw r.code="MODULE_NOT_FOUND",r},t.import=async e=>await t(e),t};let k=Symbol("turbopack queues"),U=Symbol("turbopack exports"),v=Symbol("turbopack error");function C(e){e&&1!==e.status&&(e.status=1,e.forEach(e=>e.queueCount--),e.forEach(e=>e.queueCount--?e.queueCount++:e()))}u.a=function(e,t){let r=this.m,n=t?Object.assign([],{status:-1}):void 0,o=new Set,{resolve:l,reject:i,promise:s}=j(),u=Object.assign(s,{[U]:r.exports,[k]:e=>{n&&e(n),o.forEach(e),u.catch(()=>{})}}),a={get:()=>u,set(e){e!==u&&(u[U]=e)}};Object.defineProperty(r,"exports",a),Object.defineProperty(r,"namespaceObject",a),e(function(e){let t=e.map(e=>{if(null!==e&&"object"==typeof e){if(k in e)return e;if(null!=e&&"object"==typeof e&&"then"in e&&"function"==typeof e.then){let t=Object.assign([],{status:0}),r={[U]:{},[k]:e=>e(t)};return e.then(e=>{r[U]=e,C(t)},e=>{r[v]=e,C(t)}),r}}return{[U]:e,[k]:()=>{}}}),r=()=>t.map(e=>{if(e[v])throw e[v];return e[U]}),{promise:l,resolve:i}=j(),s=Object.assign(()=>i(r),{queueCount:0});function u(e){e!==n&&!o.has(e)&&(o.add(e),e&&0===e.status&&(s.queueCount++,e.push(s)))}return t.map(e=>e[k](u)),s.queueCount?l:r()},function(e){e?i(u[v]=e):l(u[U]),C(n)}),n&&-1===n.status&&(n.status=0)};let P=function(e){let t=new URL(e,"x:/"),r={};for(let e in t)r[e]=t[e];for(let t in r.href=e,r.pathname=e.replace(/[?#].*/,""),r.origin=r.protocol="",r.toString=r.toJSON=(...t)=>e,r)Object.defineProperty(this,t,{enumerable:!0,configurable:!0,value:r[t]})};function R(e,t){throw Error(`Invariant: ${t(e)}`)}P.prototype=URL.prototype,u.U=P,u.z=function(e){throw Error("dynamic usage of require is not supported")},u.g=globalThis;let S=s.prototype,$=new Map;u.M=$;let _=new Map,E=new Map;async function T(e,t,r){let n;if("string"==typeof r)return M(e,t,N(r));let o=r.included||[],l=o.map(e=>!!$.has(e)||_.get(e));if(l.length>0&&l.every(e=>e))return void await Promise.all(l);let i=r.moduleChunks||[],s=i.map(e=>E.get(e)).filter(e=>e);if(s.length>0){if(s.length===i.length)return void await Promise.all(s);let r=new Set;for(let e of i)E.has(e)||r.add(e);for(let n of r){let r=M(e,t,N(n));E.set(n,r),s.push(r)}n=Promise.all(s)}else{for(let o of(n=M(e,t,N(r.path)),i))E.has(o)||E.set(o,n)}for(let e of o)_.has(e)||_.set(e,n);await n}S.l=function(e){return T(l.Parent,this.m.id,e)};let A=Promise.resolve(void 0),x=new WeakMap;function M(t,r,n){let o=e.loadChunkCached(t,n),i=x.get(o);if(void 0===i){let e=x.set.bind(x,o,A);i=o.then(e).catch(e=>{let o;switch(t){case l.Runtime:o=`as a runtime dependency of chunk ${r}`;break;case l.Parent:o=`from module ${r}`;break;case l.Update:o="from an HMR update";break;default:R(t,e=>`Unknown source type: ${e}`)}let i=Error(`Failed to load chunk ${n} ${o}${e?`: ${e}`:""}`,e?{cause:e}:void 0);throw i.name="ChunkLoadError",i}),x.set(o,i)}return i}function N(e){return`${t}${e.split("/").map(e=>encodeURIComponent(e)).join("/")}${r}`}S.L=function(e){return M(l.Parent,this.m.id,e)},S.R=function(e){let t=this.r(e);return t?.default??t},S.P=function(e){return`/ROOT/${e??""}`},S.q=function(e,t){m.call(this,`${e}${r}`,t)},S.b=function(e,t,o,l){let i="SharedWorker"===e.name,s=[o.map(e=>N(e)).reverse(),r];for(let e of n)s.push(globalThis[e]);let u=new URL(N(t),location.origin),a=JSON.stringify(s);return i?u.searchParams.set("params",a):u.hash="#params="+encodeURIComponent(a),new e(u,l?{...l,type:void 0}:void 0)};let q=/\.js(?:\?[^#]*)?(?:#.*)?$/,K=/\.css(?:\?[^#]*)?(?:#.*)?$/;function L(e){return K.test(e)}u.w=function(t,r,n){return e.loadWebAssembly(l.Parent,this.m.id,t,r,n)},u.u=function(t,r){return e.loadWebAssemblyModule(l.Parent,this.m.id,t,r)};let I={};u.c=I;let B=(e,t)=>{let r=I[e];if(r){if(r.error)throw r.error;return r}return W(e,l.Parent,t.id)};function W(e,t,r){let n=$.get(e);if("function"!=typeof n)throw Error(function(e,t,r){let n;switch(t){case 0:n=`as a runtime entry of chunk ${r}`;break;case 1:n=`because it was required from module ${r}`;break;case 2:n="because of an HMR update";break;default:R(t,e=>`Unknown source type: ${e}`)}return`Module ${e} was instantiated ${n}, but the module factory is not available.`}(e,t,r));let o=h(e),l=o.exports;I[e]=o;let i=new s(o,l);try{n(i,o,l)}catch(e){throw o.error=e,e}return o.namespaceObject&&o.exports!==o.namespaceObject&&g(o.exports,o.namespaceObject),o}function F(t){let r,n=function(e){if("string"==typeof e)return e;if(e)return{src:e.getAttribute("src")};if("u">typeof TURBOPACK_NEXT_CHUNK_URLS)return{src:TURBOPACK_NEXT_CHUNK_URLS.pop()};throw Error("chunk path empty but not in a worker")}(t[0]);return 2===t.length?r=t[1]:(r=void 0,!function(e,t){let r=1;for(;r<e.length;){let n,o=r+1;for(;o<e.length&&"function"!=typeof e[o];)o++;if(o===e.length)throw Error("malformed chunk format, expected a factory function");let l=e[o];for(let l=r;l<o;l++){let r=e[l],o=t.get(r);if(o){n=o;break}}let i=n??l,s=!1;for(let n=r;n<o;n++){let r=e[n];t.has(r)||(s||(i===l&&Object.defineProperty(l,"name",{value:"module evaluation"}),s=!0),t.set(r,i))}r=o+1}}(t,$)),e.registerChunk(n,r)}let X=new Map;function D(e){let t=X.get(e);if(!t){let r,n;t={resolved:!1,loadingStarted:!1,promise:new Promise((e,t)=>{r=e,n=t}),resolve:()=>{t.resolved=!0,r()},reject:n},X.set(e,t)}return t}e={async registerChunk(e,r){let n=function(e){if("string"==typeof e)return e;let r=decodeURIComponent(e.src.replace(/[?#].*$/,""));return r.startsWith(t)?r.slice(t.length):r}(e);if(D("string"==typeof e?N(e):e.src).resolve(),null!=r){for(let e of r.otherChunks)D(N("string"==typeof e?e:e.path));if(await Promise.all(r.otherChunks.map(e=>T(l.Runtime,n,e))),r.runtimeModuleIds.length>0)for(let e of r.runtimeModuleIds)!function(e,t){let r=I[t];if(r){if(r.error)throw r.error;return}W(t,l.Runtime,e)}(n,e)}},loadChunkCached:(e,t)=>(function(e,t){let r=D(t);if(r.loadingStarted)return r.promise;if(e===l.Runtime)return r.loadingStarted=!0,L(t)&&r.resolve(),r.promise;if("function"==typeof importScripts)if(L(t));else if(q.test(t))self.TURBOPACK_NEXT_CHUNK_URLS.push(t),importScripts(t);else throw Error(`can't infer type of chunk from URL ${t} in worker`);else{let e=decodeURI(t);if(L(t))if(document.querySelectorAll(`link[rel=stylesheet][href="${t}"],link[rel=stylesheet][href^="${t}?"],link[rel=stylesheet][href="${e}"],link[rel=stylesheet][href^="${e}?"]`).length>0)r.resolve();else{let e=document.createElement("link");e.rel="stylesheet",e.href=t,e.onerror=()=>{r.reject()},e.onload=()=>{r.resolve()},document.head.appendChild(e)}else if(q.test(t)){let n=document.querySelectorAll(`script[src="${t}"],script[src^="${t}?"],script[src="${e}"],script[src^="${e}?"]`);if(n.length>0)for(let e of Array.from(n))e.addEventListener("error",()=>{r.reject()});else{let e=document.createElement("script");e.src=t,e.onerror=()=>{r.reject()},document.head.appendChild(e)}}else throw Error(`can't infer type of chunk from URL ${t}`)}return r.loadingStarted=!0,r.promise})(e,t),async loadWebAssembly(e,t,r,n,o){let l=fetch(N(r)),{instance:i}=await WebAssembly.instantiateStreaming(l,o);return i.exports},async loadWebAssemblyModule(e,t,r,n){let o=fetch(N(r));return await WebAssembly.compileStreaming(o)}};let H=globalThis.TURBOPACK;globalThis.TURBOPACK={push:F},H.forEach(F)})();
@@ -1 +1 @@
1
- 624
1
+ 648
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-viewer",
3
- "version": "2.11.7",
3
+ "version": "2.12.0",
4
4
  "description": "Local file viewer and wiki — view markdown, HTML, PDFs, notebooks, office docs, and more from any directory",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.11.7"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/sil/wiki-viewer","allowedDevOrigins":["localhost"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/sil/wiki-viewer"},"distDirRoot":".next"}
18
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.12.0"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/wiki-viewer/wiki-viewer","allowedDevOrigins":["localhost"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/wiki-viewer/wiki-viewer"},"distDirRoot":".next"}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21
 
@@ -0,0 +1,156 @@
1
+ # Scratchpad — Design
2
+
3
+ ## Overview
4
+
5
+ Scratch content is stored as hidden files under `<workspace-root>/.scratch/`
6
+ and opened through the existing open-file pipeline, so all viewers/editors work
7
+ unchanged. Only two genuinely new pieces: a server route to create/cleanup
8
+ scratch files, and client UI to capture paste/drop/URL and open the result.
9
+
10
+ ## Storage
11
+
12
+ - Directory: `.scratch/` at the workspace root (hidden, not a denied segment).
13
+ - Filenames: `scratch-<epochMs>-<rand6>.<ext>`.
14
+ - Reachable by `/api/wiki/content` (text edit/read) and `/api/assets` (binary
15
+ viewers) because it lives inside the root and `.scratch` is not denied.
16
+ - Containment via existing `resolveWorkspacePath`. We do NOT add `.scratch` to
17
+ `DENIED_SEGMENTS` (that list stays `[".proof", ".git"]`); scratch paths are
18
+ normal reachable paths.
19
+
20
+ ## Server: `POST /api/wiki/scratch`
21
+
22
+ New route `src/app/api/wiki/scratch/route.ts`. CSRF + `resolveWorkspaceForUser(..,"write")`.
23
+
24
+ Two request shapes:
25
+
26
+ 1. **Text** — `Content-Type: application/json`
27
+ Body `{ ext: string, content: string }`.
28
+ - Sanitize `ext` (alphanumeric, length-capped; fallback `txt`).
29
+ - Compute `rel = .scratch/scratch-<ts>-<rand>.<ext>`.
30
+ - `resolveWorkspacePath(root, rel, { allowMissing: true, deniedSegments: [".proof",".git"] })`.
31
+ - mkdir `.scratch`, write UTF-8.
32
+ - Return `{ path: rel, name }`.
33
+
34
+ 2. **Binary** — `Content-Type: multipart/form-data`
35
+ Field `file`.
36
+ - Derive extension from the uploaded filename (sanitized).
37
+ - Size cap (reuse the 50MB upload ceiling).
38
+ - Write `Buffer` bytes (not UTF-8) to `.scratch/...`.
39
+ - Return `{ path, name }`.
40
+
41
+ On every POST, run a **TTL sweep**: delete `.scratch` entries older than
42
+ `SCRATCH_TTL_MS` (default 7 days) before creating the new one. Best-effort;
43
+ ignore per-file errors.
44
+
45
+ Server-start sweep: add a call in `src/instrumentation.ts` (or the existing
46
+ startup hook) to purge stale scratch files across known workspace roots. If a
47
+ per-root registry isn't cheaply available at startup, the POST-time sweep is the
48
+ primary mechanism and the startup sweep is best-effort over the seeded root.
49
+
50
+ ## Text sniffing (client)
51
+
52
+ Helper `src/lib/scratch/detect.ts`:
53
+
54
+ ```
55
+ detectScratchExt(text): "html" | "md" | "txt"
56
+ ```
57
+
58
+ - HTML if it matches a leading `<!doctype html`, `<html`, or has multiple
59
+ balanced tags near the start.
60
+ - Markdown if it has md signals (`^#{1,6} `, `](`, ```` ``` ````, `- ` lists).
61
+ - Else `txt`.
62
+
63
+ Code paste: v1 does not language-classify; unknown code lands in `.txt` and the
64
+ source viewer sniffs. (A future enhancement could offer an explicit language
65
+ picker.) The "code with syntax view" criterion is met because the source viewer
66
+ already renders and syntax-handles arbitrary text, and the user can rename via
67
+ "Save to real file" with a chosen extension.
68
+
69
+ ## Client entry points
70
+
71
+ `src/hooks/use-scratchpad.ts` — orchestrates create+open. Exposes:
72
+
73
+ - `openCreateSurface()` — reveals the create UI.
74
+ - `createFromText(text)` — sniff, POST text, open resulting path.
75
+ - `createFromFile(file)` — POST multipart, open resulting path.
76
+ - `openUrl(url)` — open the website viewer at an external URL (no file).
77
+ - `promote(destPath)` — move scratch → real path, reopen.
78
+
79
+ Wiring in `src/app/page.tsx`:
80
+
81
+ - Keyboard: `keydown` listener for Cmd/Ctrl+Shift+N → `openCreateSurface()`.
82
+ - Button: add a scratchpad button near the existing new-file affordance
83
+ (header or sidebar).
84
+ - Drop: the empty-viewer state (`page.tsx` "Select a file" block) becomes a
85
+ drop target; dropping a file calls `createFromFile`.
86
+
87
+ ## Create surface UI
88
+
89
+ `src/components/wiki/scratchpad-create.tsx` — replaces the empty-viewer
90
+ placeholder when active. Three quick inputs:
91
+
92
+ - A large textarea: "Paste or type…" → on paste/submit calls `createFromText`.
93
+ - A URL input: "Open a link…" → `openUrl`.
94
+ - A drop zone / file button → `createFromFile`.
95
+
96
+ After creation, the surface closes and the normal `ViewerPane` renders the
97
+ opened scratch file.
98
+
99
+ ## Opening the created scratch
100
+
101
+ Reuse `useOpenFile.openViewer` via a synthesized `TreeNode`:
102
+ `{ path, name, type: "file", modifiedAt: "" }`. This runs the exact same code
103
+ path as clicking a file in the tree, so markdown → editor-store, binary →
104
+ native viewer.
105
+
106
+ ## Web URL viewing (no file)
107
+
108
+ `OpenFile` gains an optional field `externalUrl?: string`. When set:
109
+
110
+ - `viewer-pane.tsx`: for the website/html branch, prefer `openFile.externalUrl`
111
+ as the iframe `src` when present (bypassing `/api/assets`).
112
+ - `use-open-file.ts`: add an `openExternalUrl(url)` that sets
113
+ `openFile = { path: "", name: url, nodeType: "app", externalUrl: url }` and
114
+ forces the website viewer. Keep it minimal; no file written.
115
+
116
+ This is the only change to existing viewer code and it is additive/optional.
117
+
118
+ ## Promote to real file
119
+
120
+ Reuse `POST /api/wiki/move` (`from = scratchRel`, `to = destRel`). Add a
121
+ "Save to real file…" action in the viewer toolbar/menu, visible only when the
122
+ open file's path starts with `.scratch/`. It opens a destination picker
123
+ (reuse `DirPicker`/new-file naming), calls move, then reopens `destRel`.
124
+
125
+ ## Files touched
126
+
127
+ New:
128
+ - `src/app/api/wiki/scratch/route.ts`
129
+ - `src/lib/scratch/detect.ts`
130
+ - `src/lib/scratch/config.ts` (TTL, dir name, filename gen)
131
+ - `src/hooks/use-scratchpad.ts`
132
+ - `src/components/wiki/scratchpad-create.tsx`
133
+ - `src/tests/proof/scratch.test.ts`
134
+
135
+ Edited (small, additive):
136
+ - `src/types/wiki.ts` — `OpenFile.externalUrl?`
137
+ - `src/hooks/use-open-file.ts` — `openExternalUrl`, expose promote/open helpers
138
+ - `src/components/wiki/viewer-pane.tsx` — external URL src + "Save to real file"
139
+ - `src/app/page.tsx` — shortcut, button, empty-viewer drop, render create surface
140
+ - `src/instrumentation.ts` — startup sweep (best-effort)
141
+
142
+ ## Alternatives rejected
143
+
144
+ - **In-memory docs**: rewrites every viewer; disproportionate risk.
145
+ - **OS temp dir outside workspace**: viewers fetch by workspace-relative path;
146
+ files outside the root are unreachable and would violate containment.
147
+ - **`.scratch` as denied segment**: would make scratch files unreachable by the
148
+ very viewers we need. So it stays reachable, protected only by root containment.
149
+
150
+ ## Security notes
151
+
152
+ - All writes go through `resolveWorkspacePath`; traversal/symlink escapes
153
+ rejected exactly as other routes.
154
+ - Binary writes use raw buffers, avoiding UTF-8 corruption.
155
+ - Website viewer keeps its existing sandbox; external URLs get no extra powers.
156
+ - Scratch files are subject to the same auth/workspace scoping as any file.
@@ -0,0 +1,82 @@
1
+ # Scratchpad — Proposal
2
+
3
+ ## Problem
4
+
5
+ Viewing or editing arbitrary content today requires creating a real file first:
6
+ pick a folder, name it, choose an extension, then open it. For quick throwaway
7
+ work (paste a log, preview some HTML, skim a PDF, check a URL, jot markdown)
8
+ that ceremony is friction and pollutes the workspace with junk files.
9
+
10
+ ## Desired outcome
11
+
12
+ A "scratchpad": one shortcut/button that opens an instant view+edit surface.
13
+ Drop or paste anything (text, markdown, HTML, code, CSV, PDF, images, office
14
+ docs) or a web URL, and it renders immediately in the existing viewer/editor
15
+ with no manual file creation. Optionally promote a scratchpad to a real file
16
+ with one click.
17
+
18
+ ## Chosen approach (decided with user)
19
+
20
+ **Hidden temp files inside the workspace.** Scratch content is written to a
21
+ hidden `.scratch/` directory at the workspace root, then opened through the
22
+ normal open-file pipeline. This reuses every existing viewer/editor unchanged
23
+ (all viewers already fetch by workspace-relative path via `/api/wiki/content`
24
+ and `/api/assets`). No viewer rewrite, low risk.
25
+
26
+ Rejected: true in-memory (no-fs) docs — every viewer only accepts a `path` and
27
+ fetches server bytes; supporting inline content/blobs would require rewriting
28
+ CSV/PDF/image/docx/xlsx/pptx/html/source viewers and the editor-store save
29
+ path. Weeks-scale, high regression risk, out of proportion to the value.
30
+
31
+ ## Scope
32
+
33
+ - New hidden `.scratch/` workspace dir holding scratch files.
34
+ - Scratchpad entry points: keyboard shortcut (Cmd/Ctrl+Shift+N), sidebar/header
35
+ button, and drop-file-on-empty-viewer.
36
+ - Create-scratch flow: paste text (auto-detect md/html/code by sniffing),
37
+ markdown editing, HTML preview, code with syntax view, drop any file type,
38
+ and open a web URL in the website viewer.
39
+ - Ephemeral by default with a one-click "Save to real file" (promote) action.
40
+ - Cleanup of stale scratch files.
41
+
42
+ ## Non-goals
43
+
44
+ - No true in-memory / zero-fs rendering.
45
+ - No multi-tab scratchpad manager UI in v1 (one active scratch at a time is
46
+ fine; multiple scratch files may coexist on disk but no dedicated manager).
47
+ - No collaboration/sidecar/proof provenance for scratch markdown beyond what
48
+ the normal editor already does.
49
+ - No sharing of scratch files via public share links in v1.
50
+ - No sync of scratch content across devices/servers.
51
+
52
+ ## Risks
53
+
54
+ - **Containment.** `.scratch/` must stay inside the workspace and never escape.
55
+ Mitigated: reuse `resolveWorkspacePath`; add `.scratch` handling that keeps it
56
+ a normal (reachable) segment, not a denied one.
57
+ - **Clutter/leaks.** Scratch files accumulate. Mitigated: hidden dir + age-based
58
+ cleanup on server start and on scratch open.
59
+ - **Tree noise.** `.scratch/` shows in the file tree when "show hidden" is on.
60
+ Acceptable; it is a real hidden dir.
61
+ - **Binary via URL.** Dropped binary files (pdf/image/docx) must be written
62
+ byte-accurately, not as UTF-8 text. Mitigated: use the upload/binary write
63
+ path, not the text content PUT.
64
+ - **Web URL viewing.** Cross-origin iframes may refuse to load (X-Frame-Options).
65
+ Acceptable: show the same sandboxed iframe the website viewer already uses;
66
+ failures are the remote site's choice, surface a fallback "open in new tab".
67
+
68
+ ## Acceptance criteria
69
+
70
+ 1. A shortcut and a visible button both open a scratchpad create surface.
71
+ 2. Pasting markdown/HTML/code opens the correct viewer/editor instantly with no
72
+ manual filename step.
73
+ 3. Dropping a file (pdf, png, csv, docx) on the empty viewer opens it in its
74
+ native viewer.
75
+ 4. Entering a web URL opens it in the website viewer.
76
+ 5. Scratch files live under `.scratch/` and are reachable by all viewers.
77
+ 6. "Save to real file" moves/copies a scratch file to a user-chosen workspace
78
+ path and reopens it there.
79
+ 7. Scratch files are never written outside the workspace root; traversal and
80
+ symlink escapes are rejected.
81
+ 8. Stale scratch files are cleaned up automatically.
82
+ 9. `pnpm typecheck`, `pnpm lint`, and `pnpm test` pass (test floor held).
@@ -0,0 +1,83 @@
1
+ # Scratchpad — Requirements
2
+
3
+ Each requirement is observable behavior.
4
+
5
+ ## R1 — Open scratchpad create surface
6
+
7
+ GIVEN the app is loaded
8
+ WHEN the user presses Cmd/Ctrl+Shift+N OR clicks the scratchpad button
9
+ THEN a scratchpad create surface appears without selecting an existing file.
10
+
11
+ ## R2 — Paste text auto-detected
12
+
13
+ GIVEN the scratchpad create surface is open
14
+ WHEN the user pastes text
15
+ THEN the type is sniffed (HTML if it looks like HTML, markdown if md-ish,
16
+ otherwise plain/code) and a scratch file with the matching extension is
17
+ created and opened in the correct viewer/editor.
18
+
19
+ ## R3 — Markdown editing
20
+
21
+ GIVEN a scratch `.md` file is opened
22
+ WHEN the user edits it
23
+ THEN it behaves like any markdown page (TipTap editor, autosave to the scratch
24
+ file), with revision tracking as normal.
25
+
26
+ ## R4 — HTML preview
27
+
28
+ GIVEN pasted or dropped HTML content
29
+ WHEN the scratch `.html` file is opened
30
+ THEN it renders in the sandboxed website viewer, with the existing
31
+ source/preview toggle available.
32
+
33
+ ## R5 — Code with syntax view
34
+
35
+ GIVEN pasted code (e.g. `.ts`, `.py`, or unknown → `.txt`)
36
+ WHEN the scratch file is opened
37
+ THEN it opens in the source viewer with syntax handling and is editable.
38
+
39
+ ## R6 — Drop a file on empty viewer
40
+
41
+ GIVEN no file is open (empty viewer state)
42
+ WHEN the user drops a file (pdf, png, csv, docx, xlsx, pptx, md, txt, ...)
43
+ THEN the bytes are written to a scratch file preserving the original extension
44
+ and the file opens in its native viewer.
45
+
46
+ ## R7 — Web URL viewing
47
+
48
+ GIVEN the scratchpad create surface
49
+ WHEN the user enters an http(s) URL and submits
50
+ THEN it opens in the website viewer pointed at that URL (sandboxed iframe), with
51
+ an "open in new tab" fallback.
52
+
53
+ ## R8 — Scratch storage location
54
+
55
+ GIVEN any scratch is created
56
+ WHEN it is written
57
+ THEN it lives under `<workspace-root>/.scratch/` with a generated unique name,
58
+ reachable by `/api/wiki/content` and `/api/assets`.
59
+
60
+ ## R9 — Promote to real file
61
+
62
+ GIVEN a scratch file is open
63
+ WHEN the user clicks "Save to real file" and picks a destination path
64
+ THEN the scratch content is written to that workspace path, the scratch file is
65
+ removed, and the viewer reopens the new real file.
66
+
67
+ ## R10 — Containment
68
+
69
+ GIVEN any scratch create/promote request
70
+ WHEN a path would traverse (`..`), be absolute, or escape via symlink
71
+ THEN the request is rejected (400) and nothing is written outside the workspace.
72
+
73
+ ## R11 — Cleanup
74
+
75
+ GIVEN scratch files older than a TTL exist
76
+ WHEN the server starts OR a new scratch is created
77
+ THEN stale scratch files (and their sidecars, if any) are deleted.
78
+
79
+ ## R12 — Quality gates
80
+
81
+ GIVEN the change is complete
82
+ WHEN `pnpm typecheck`, `pnpm lint`, and `pnpm test` run
83
+ THEN all pass and the test floor is held or raised.
@@ -0,0 +1,45 @@
1
+ # Scratchpad — Tasks
2
+
3
+ Ordered, checkable. Mark complete only after verification.
4
+
5
+ ## Backend
6
+
7
+ - [ ] T1. `src/lib/scratch/config.ts`: `SCRATCH_DIR = ".scratch"`,
8
+ `SCRATCH_TTL_MS`, `newScratchName(ext)`, `sanitizeExt(ext)`.
9
+ - [ ] T2. `src/lib/scratch/detect.ts`: `detectScratchExt(text)` → html|md|txt.
10
+ - [ ] T3. `src/app/api/wiki/scratch/route.ts`: POST text + multipart, containment
11
+ via `resolveWorkspacePath`, TTL sweep, returns `{ path, name }`.
12
+ - [ ] T4. Startup sweep hook in `src/instrumentation.ts` (best-effort).
13
+
14
+ ## Types + open pipeline
15
+
16
+ - [ ] T5. `src/types/wiki.ts`: add `OpenFile.externalUrl?: string`.
17
+ - [ ] T6. `src/hooks/use-open-file.ts`: `openExternalUrl(url)`, and a
18
+ `openScratchByPath(path)` that opens a synthesized TreeNode. Expose a
19
+ `promoteScratch(destPath)` that calls `/api/wiki/move` then reopens.
20
+
21
+ ## Viewer
22
+
23
+ - [ ] T7. `src/components/wiki/viewer-pane.tsx`: use `openFile.externalUrl` as
24
+ iframe `src` when present; add "Save to real file…" menu item shown only
25
+ for paths under `.scratch/`.
26
+
27
+ ## Client UI
28
+
29
+ - [ ] T8. `src/hooks/use-scratchpad.ts`: create surface state + create/open/promote.
30
+ - [ ] T9. `src/components/wiki/scratchpad-create.tsx`: paste textarea, URL input,
31
+ drop zone/file button.
32
+ - [ ] T10. `src/app/page.tsx`: Cmd/Ctrl+Shift+N shortcut, scratchpad button,
33
+ empty-viewer drop target, render create surface when active.
34
+
35
+ ## Tests + gates
36
+
37
+ - [ ] T11. `src/tests/proof/scratch.test.ts`: text create, binary create,
38
+ traversal rejection, TTL sweep, promote via move.
39
+ - [ ] T12. Run `pnpm typecheck`, `pnpm lint`, `pnpm test`; hold/raise floor.
40
+ - [ ] T13. Manual smoke: paste md/html/code, drop pdf+png+csv, open URL, promote.
41
+
42
+ ## Docs
43
+
44
+ - [ ] T14. Note scratchpad in README/AGENTS if user-facing behavior needs it.
45
+ - [ ] T15. Archive spec to `specs/changes/archive/<date>-scratchpad/` on close.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-viewer",
3
- "version": "2.11.7",
3
+ "version": "2.12.0",
4
4
  "description": "Local file viewer and wiki — view markdown, HTML, PDFs, notebooks, office docs, and more from any directory",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,3 +0,0 @@
1
- module.exports=[402662,e=>{"use strict";var t=e.i(702414);e.s(["checkOrigin",0,function(e){let r=e.method.toUpperCase();if("GET"===r||"HEAD"===r||"OPTIONS"===r)return null;let s=e.headers.get("origin"),a=e.headers.get("referer");if(!s&&!a)return null;let n=function(e){let t=Array.from(new Set(["localhost","127.0.0.1",e.split(":")[0],...(process.env.WIKI_OWNER_HOSTS??"").split(",").map(e=>e.trim()).filter(Boolean)])),r=["",":3000",":3003"];e.includes(":")&&r.push(":"+e.split(":")[1]);let s=new Set;for(let e of t)for(let t of["http","https"])for(let a of r)s.add(`${t}://${e}${a}`);return s}(e.headers.get("host")??"");if(s)return n.has(s)?null:t.NextResponse.json({error:"FORBIDDEN",message:"Bad origin"},{status:403});if(a){try{let{protocol:e,host:t}=new URL(a);if(n.has(`${e}//${t}`))return null}catch{}return t.NextResponse.json({error:"FORBIDDEN",message:"Bad referer"},{status:403})}return null}])},794776,e=>{"use strict";let t,r=Number.isFinite(t=parseInt(process.env.AGENT_RATE_LIMIT??"",10))&&t>0?t:60;e.s(["OPS_PER_MINUTE",0,r,"SIDECAR_EVENT_TRIM_SIZE",0,1e3,"SIDECAR_TRIM_EVERY_N_MUTATIONS",0,100])},517387,e=>{"use strict";var t=e.i(794776);let r=new Map;e.s(["checkAndConsume",0,function(e,s=1){let a=Date.now(),n=t.OPS_PER_MINUTE,o=r.get(e);o||(o={tokens:n,lastRefill:a},r.set(e,o));let i=Math.floor((a-o.lastRefill)/1e3);return(i>0&&(o.tokens=Math.min(n,o.tokens+i),o.lastRefill=o.lastRefill+1e3*i),o.tokens<s)?{ok:!1,retryAfterMs:Math.max(1,1e3*(s-o.tokens)-(a-o.lastRefill))}:(o.tokens-=s,{ok:!0})}])},211451,63467,e=>{"use strict";var t=e.i(702414),r=e.i(912714),s=e.i(97082),a=e.i(359211),n=e.i(719126);async function o(e){let o,i=(0,s.getShareByToken)(e);if(!i)return{ok:!1,response:t.NextResponse.json({error:"not_found",message:"Share link not found"},{status:404})};if(i.isRevoked)return{ok:!1,response:t.NextResponse.json({error:"revoked",message:"Share link has been revoked"},{status:410})};if((0,s.isExpired)(i))return{ok:!1,response:t.NextResponse.json({error:"expired",message:"Share link has expired"},{status:410})};let l=await (0,a.getWorkspace)(i.workspaceId);if(!l)return{ok:!1,response:t.NextResponse.json({error:"workspace_gone",message:"Workspace no longer exists"},{status:410})};let u=await (0,n.safeAbsPath)(l.rootDir,i.filePath);if(!u)return{ok:!1,response:t.NextResponse.json({error:"path_invalid",message:"Invalid file path"},{status:400})};try{o=await (0,r.stat)(u)}catch{return{ok:!1,response:t.NextResponse.json({error:"file_gone",message:"File no longer exists"},{status:410})}}if(o.isDirectory())return{ok:!1,response:t.NextResponse.json({error:"path_invalid",message:"Directories cannot be shared"},{status:400})};let d=i.filePath.split("/").pop()??i.filePath;return{ok:!0,target:{share:i,absPath:u,filename:d}}}e.s(["resolveShareTarget",0,o],211451);var i=e.i(666680);function l(e){let t=(0,i.createHash)("sha256").update(e).digest("hex").slice(0,24);return`wv_share_${t}`}function u(e,t){let r=`${e.e}|${e.t}`;return(0,i.createHmac)("sha256",t).update(r).digest("hex")}e.s(["inlineContentDisposition",0,function(e){let t=e.replace(/[\x00-\x1f\x7f]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"');return`inline; filename="${t}"`},"isUnlocked",0,function(e,t,r){let s=function(e,t){let r=e.headers.get("cookie")??"",s=l(t);for(let e of r.split(";")){let t=e.indexOf("=");if(!(t<=0)&&e.slice(0,t).trim()===s)return e.slice(t+1).trim()}}(e,t);return!!s&&function(e,t,r){let s,a=t.indexOf(".");if(-1===a)return!1;let n=t.slice(0,a),o=t.slice(a+1);try{s=JSON.parse(Buffer.from(n,"base64url").toString("utf8"))}catch{return!1}if(s.t!==e||"number"!=typeof s.e||s.e<=Date.now())return!1;let l=u(s,r),d=Buffer.from(l,"hex"),p=Buffer.from(o,"hex");return d.length===p.length&&(0,i.timingSafeEqual)(d,p)}(t,s,r)},"serializeUnlockCookie",0,function(e,t,r){let s,a,n,{name:o,value:i}=(a=u(s={t:t,e:Date.now()+9e5},r),n=`${Buffer.from(JSON.stringify(s)).toString("base64url")}.${a}`,{name:l(t),value:n}),d=new URL(e.url),p=[`${o}=${i}`,"HttpOnly","SameSite=Strict",`Path=${d.pathname}`,"Max-Age=900"];return"https:"===d.protocol&&p.push("Secure"),p.join("; ")}],63467)},687458,e=>{"use strict";var t=e.i(364564),r=e.i(102095),s=e.i(691091),a=e.i(475331),n=e.i(490301),o=e.i(670943),i=e.i(690324),l=e.i(243133),u=e.i(404870),d=e.i(420180),p=e.i(867883),c=e.i(336708),h=e.i(682278),f=e.i(157569),m=e.i(844146),g=e.i(193695);e.i(105888);var R=e.i(530564),_=e.i(702414),v=e.i(402662),w=e.i(254226),k=e.i(517387),x=e.i(97082),E=e.i(211451),N=e.i(63467);let y={"Cache-Control":"private, no-store"};async function S(t){let{readFile:r,stat:s}=await e.A(687903);try{if((await s(t)).size>1048576)return null;return(await r(t)).toString("utf-8")}catch(e){return console.error("[share] readFile(%s) %s",t,e instanceof Error?e.message:String(e)),null}}async function C(e,{params:t}){let{token:r}=await t,s=(0,k.checkAndConsume)(`share:${r}`,1);if(!s.ok)return _.NextResponse.json({error:"rate_limited",message:"Too many requests"},{status:429,headers:{"Retry-After":String(Math.ceil(s.retryAfterMs/1e3))}});let a=(0,x.getShareByToken)(r);if(!a)return _.NextResponse.json({error:"not_found",message:"Share link not found"},{status:404,headers:y});if(a.isRevoked)return _.NextResponse.json({error:"revoked",message:"Share link has been revoked"},{status:410,headers:y});if((0,x.isExpired)(a))return _.NextResponse.json({error:"expired",message:"Share link has expired"},{status:410,headers:y});if(a.passwordHash&&!(0,N.isUnlocked)(e,r,a.passwordHash))return _.NextResponse.json({protected:!0,message:"This document is password-protected"},{status:401,headers:y});let n=await (0,E.resolveShareTarget)(r);if(!n.ok)return n.response;let o=await S(n.target.absPath);return null===o?_.NextResponse.json({error:"read_error",message:"Failed to read file"},{status:500,headers:y}):((0,x.incrementViewCount)(r),_.NextResponse.json({content:o,filename:n.target.filename,filePath:n.target.share.filePath,viewCount:n.target.share.viewCount+1},{headers:a.passwordHash?y:void 0}))}async function T(e,{params:t}){let{token:r}=await t,s=(0,x.getShareByToken)(r);if(!s)return _.NextResponse.json({error:"not_found"},{status:404});if(s.isRevoked)return _.NextResponse.json({error:"revoked"},{status:410});if((0,x.isExpired)(s))return _.NextResponse.json({error:"expired"},{status:410});if(!s.passwordHash)return _.NextResponse.json({error:"not_protected"},{status:400});let a=(0,k.checkAndConsume)(`share-pwd:${r}`,1);if(!a.ok)return _.NextResponse.json({error:"rate_limited",message:"Too many attempts. Try again later."},{status:429,headers:{"Retry-After":String(Math.ceil(a.retryAfterMs/1e3))}});let n=await e.json();if(!n.password||"string"!=typeof n.password)return _.NextResponse.json({error:"missing_password"},{status:400});if(!(0,x.verifyPassword)(n.password,s.passwordHash))return _.NextResponse.json({error:"wrong_password",message:"Incorrect password"},{status:403,headers:y});let o=await (0,E.resolveShareTarget)(r);if(!o.ok)return o.response;let i=await S(o.target.absPath);if(null===i)return _.NextResponse.json({error:"read_error",message:"Failed to read file"},{status:500,headers:y});(0,x.incrementViewCount)(r);let l=(0,N.serializeUnlockCookie)(e,r,s.passwordHash);return _.NextResponse.json({content:i,filename:o.target.filename,filePath:o.target.share.filePath,viewCount:o.target.share.viewCount+1},{headers:{...y,"Set-Cookie":l}})}async function j(t,{params:r}){let{token:s}=await r,a=(0,v.checkOrigin)(t);if(a)return a;let n=await (0,w.requireUser)(t);if(!n.ok)return _.NextResponse.json({error:"UNAUTHORIZED"},{status:401});let o=(0,x.getShareByToken)(s);if(!o)return _.NextResponse.json({error:"not_found"},{status:404});if(o.createdBy!==n.user.id){let{isAdmin:t}=await e.A(919623);if(!await t(n.user.id,n.user.email))return _.NextResponse.json({error:"FORBIDDEN"},{status:403})}return(0,x.revokeShare)(o.id),_.NextResponse.json({ok:!0})}e.s(["DELETE",0,j,"GET",0,C,"POST",0,T],998553);var P=e.i(998553);let A=new t.AppRouteRouteModule({definition:{kind:r.RouteKind.APP_ROUTE,page:"/api/share/[token]/route",pathname:"/api/share/[token]",filename:"route",bundlePath:""},distDir:".next",relativeProjectDir:"",resolvedPagePath:"[project]/src/app/api/share/[token]/route.ts",nextConfigOutput:"standalone",userland:P,...{}}),{workAsyncStorage:b,workUnitAsyncStorage:O,serverHooks:I}=A;async function D(e,t,s){s.requestMeta&&(0,a.setRequestMeta)(e,s.requestMeta),A.isDev&&(0,a.addRequestMeta)(e,"devRequestTimingInternalsEnd",process.hrtime.bigint());let _="/api/share/[token]/route";_=_.replace(/\/index$/,"")||"/";let v=await A.prepare(e,t,{srcPage:_,multiZoneDraftMode:!1});if(!v)return t.statusCode=400,t.end("Bad Request"),null==s.waitUntil||s.waitUntil.call(s,Promise.resolve()),null;let{buildId:w,params:k,nextConfig:x,parsedUrl:E,isDraftMode:N,prerenderManifest:y,routerServerContext:S,isOnDemandRevalidate:C,revalidateOnlyGenerated:T,resolvedPathname:j,clientReferenceManifest:P,serverActionsManifest:b}=v,O=(0,i.normalizeAppPath)(_),I=!!(y.dynamicRoutes[O]||y.routes[j]),D=async()=>((null==S?void 0:S.render404)?await S.render404(e,t,E,!1):t.end("This page could not be found"),null);if(I&&!N){let e=!!y.routes[j],t=y.dynamicRoutes[O];if(t&&!1===t.fallback&&!e){if(x.adapterPath)return await D();throw new g.NoFallbackError}}let M=null;!I||A.isDev||N||(M="/index"===(M=j)?"/":M);let q=!0===A.isDev||!I,H=I&&!q;b&&P&&(0,o.setManifestsSingleton)({page:_,clientReferenceManifest:P,serverActionsManifest:b});let U=e.method||"GET",$=(0,n.getTracer)(),B=$.getActiveScopeSpan(),F=!!(null==S?void 0:S.isWrappedByNextServer),K=!!(0,a.getRequestMeta)(e,"minimalMode"),z=(0,a.getRequestMeta)(e,"incrementalCache")||await A.getIncrementalCache(e,x,y,K);null==z||z.resetRequestCache(),globalThis.__incrementalCache=z;let L={params:k,previewProps:y.preview,renderOpts:{experimental:{authInterrupts:!!x.experimental.authInterrupts},cacheComponents:!!x.cacheComponents,supportsDynamicResponse:q,incrementalCache:z,cacheLifeProfiles:x.cacheLife,waitUntil:s.waitUntil,onClose:e=>{t.on("close",e)},onAfterTaskError:void 0,onInstrumentationRequestError:(t,r,s,a)=>A.onRequestError(e,t,s,a,S)},sharedContext:{buildId:w}},V=new l.NodeNextRequest(e),W=new l.NodeNextResponse(t),G=u.NextRequestAdapter.fromNodeNextRequest(V,(0,u.signalFromNodeResponse)(t));try{let a,o=async e=>A.handle(G,L).finally(()=>{if(!e)return;e.setAttributes({"http.status_code":t.statusCode,"next.rsc":!1});let r=$.getRootSpanAttributes();if(!r)return;if(r.get("next.span_type")!==d.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${r.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let s=r.get("next.route");if(s){let t=`${U} ${s}`;e.setAttributes({"next.route":s,"http.route":s,"next.span_name":t}),e.updateName(t),a&&a!==e&&(a.setAttribute("http.route",s),a.updateName(t))}else e.updateName(`${U} ${_}`)}),i=async a=>{var n,i;let l=async({previousCacheEntry:r})=>{try{if(!K&&C&&T&&!r)return t.statusCode=404,t.setHeader("x-nextjs-cache","REVALIDATED"),t.end("This page could not be found"),null;let n=await o(a);e.fetchMetrics=L.renderOpts.fetchMetrics;let i=L.renderOpts.pendingWaitUntil;i&&s.waitUntil&&(s.waitUntil(i),i=void 0);let l=L.renderOpts.collectedTags;if(!I)return await (0,c.sendResponse)(V,W,n,L.renderOpts.pendingWaitUntil),null;{let e=await n.blob(),t=(0,h.toNodeOutgoingHttpHeaders)(n.headers);l&&(t[m.NEXT_CACHE_TAGS_HEADER]=l),!t["content-type"]&&e.type&&(t["content-type"]=e.type);let r=void 0!==L.renderOpts.collectedRevalidate&&!(L.renderOpts.collectedRevalidate>=m.INFINITE_CACHE)&&L.renderOpts.collectedRevalidate,s=void 0===L.renderOpts.collectedExpire||L.renderOpts.collectedExpire>=m.INFINITE_CACHE?void 0:L.renderOpts.collectedExpire;return{value:{kind:R.CachedRouteKind.APP_ROUTE,status:n.status,body:Buffer.from(await e.arrayBuffer()),headers:t},cacheControl:{revalidate:r,expire:s}}}}catch(t){throw(null==r?void 0:r.isStale)&&await A.onRequestError(e,t,{routerKind:"App Router",routePath:_,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:H,isOnDemandRevalidate:C})},!1,S),t}},u=await A.handleResponse({req:e,nextConfig:x,cacheKey:M,routeKind:r.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:y,isRoutePPREnabled:!1,isOnDemandRevalidate:C,revalidateOnlyGenerated:T,responseGenerator:l,waitUntil:s.waitUntil,isMinimalMode:K});if(!I)return null;if((null==u||null==(n=u.value)?void 0:n.kind)!==R.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==u||null==(i=u.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});K||t.setHeader("x-nextjs-cache",C?"REVALIDATED":u.isMiss?"MISS":u.isStale?"STALE":"HIT"),N&&t.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let d=(0,h.fromNodeOutgoingHttpHeaders)(u.value.headers);return K&&I||d.delete(m.NEXT_CACHE_TAGS_HEADER),!u.cacheControl||t.getHeader("Cache-Control")||d.get("Cache-Control")||d.set("Cache-Control",(0,f.getCacheControlHeader)(u.cacheControl)),await (0,c.sendResponse)(V,W,new Response(u.value.body,{headers:d,status:u.value.status||200})),null};F&&B?await i(B):(a=$.getActiveScopeSpan(),await $.withPropagatedContext(e.headers,()=>$.trace(d.BaseServerSpan.handleRequest,{spanName:`${U} ${_}`,kind:n.SpanKind.SERVER,attributes:{"http.method":U,"http.target":e.url}},i),void 0,!F))}catch(t){if(t instanceof g.NoFallbackError||await A.onRequestError(e,t,{routerKind:"App Router",routePath:O,routeType:"route",revalidateReason:(0,p.getRevalidateReason)({isStaticGeneration:H,isOnDemandRevalidate:C})},!1,S),I)throw t;return await (0,c.sendResponse)(V,W,new Response(null,{status:500})),null}}e.s(["handler",0,D,"patchFetch",0,function(){return(0,s.patchFetch)({workAsyncStorage:b,workUnitAsyncStorage:O})},"routeModule",0,A,"serverHooks",0,I,"workAsyncStorage",0,b,"workUnitAsyncStorage",0,O],687458)},168315,e=>{e.v(t=>Promise.all(["server/chunks/0sag_@better-auth_memory-adapter_dist_index_mjs_0pvj6im._.js"].map(t=>e.l(t))).then(()=>t(862112)))},396690,e=>{e.v(t=>Promise.all(["server/chunks/032z_better-auth_dist_adapters_kysely-adapter_index_mjs_0.uqexi._.js"].map(t=>e.l(t))).then(()=>t(320652)))},580632,e=>{e.v(e=>Promise.resolve().then(()=>e(270406)))},947559,e=>{e.v(t=>Promise.all(["server/chunks/0ugq_@better-auth_kysely-adapter_dist_bun-sqlite-dialect-DzNwOpKv_mjs_0z1z6m4._.js"].map(t=>e.l(t))).then(()=>t(495181)))},715018,e=>{e.v(t=>Promise.all(["server/chunks/0ugq_@better-auth_kysely-adapter_dist_node-sqlite-dialect_mjs_0qqlvhl._.js"].map(t=>e.l(t))).then(()=>t(698370)))},146843,e=>{e.v(t=>Promise.all(["server/chunks/0ugq_@better-auth_kysely-adapter_dist_d1-sqlite-dialect-C2B7YsIT_mjs_0wynrz3._.js"].map(t=>e.l(t))).then(()=>t(143740)))},84040,e=>{e.v(t=>Promise.all(["server/chunks/0p91_next_0h94sj1._.js"].map(t=>e.l(t))).then(()=>t(815068)))},526888,e=>{e.v(e=>Promise.resolve().then(()=>e(28962)))},893412,e=>{e.v(t=>Promise.all(["server/chunks/src_lib_auth_api-key_ts_0t_ma-t._.js"].map(t=>e.l(t))).then(()=>t(499465)))},687903,e=>{e.v(e=>Promise.resolve().then(()=>e(912714)))},919623,e=>{e.v(t=>Promise.all(["server/chunks/src_lib_auth_admin_ts_0g4i6v_._.js"].map(t=>e.l(t))).then(()=>t(583627)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__0k46u9j._.js.map
@@ -1,20 +0,0 @@
1
- module.exports=[874533,(t,e,r)=>{e.exports=t.x("node:child_process",()=>require("node:child_process"))},812057,(t,e,r)=>{e.exports=t.x("node:util",()=>require("node:util"))},256294,296555,t=>{"use strict";let e;var r=t.i(874533),s=t.i(812057),a=t.i(912714),i=t.i(750227),n=t.i(660526);t.i(902157);let o=RegExp("[;|&$`<>(){}\\n\\r\\0]");function u(t){let{target:e,mountpoint:r,port:s}=t,a=e.user?`${e.user}@`:"",i=[`${a}${e.host}:${e.remotePath}`,r];s&&Number.isInteger(Number(s))&&Number(s)>0&&65536>Number(s)&&i.push("-p",String(s));let n=t.authMethod??"agent";!t.authMethod&&(null!=t.password?n="password":t.keyPath&&(n="keyfile"));let o=["reconnect","ServerAliveInterval=15","ServerAliveCountMax=3","compression=yes","cache=yes","kernel_cache","StrictHostKeyChecking=accept-new","BatchMode=yes"];if(t.readOnly&&o.push("ro"),"keyfile"===n&&t.keyPath&&(o.push(`IdentityFile=${t.keyPath}`),o.push("IdentitiesOnly=yes")),"password"===n){let t=o.indexOf("BatchMode=yes");t>=0&&o.splice(t,1),o.push("password_stdin"),o.push("PreferredAuthentications=password,keyboard-interactive"),o.push("PubkeyAuthentication=no"),o.push("NumberOfPasswordPrompts=1")}return t.extraOptions&&o.push(...t.extraOptions),i.push("-o",o.join(",")),i}t.s(["buildSshfsArgs",0,u,"isValidKeyPath",0,function(t){return!(!t||o.test(t)||t.includes(".."))&&(t.startsWith("/")||t.startsWith("~/"))},"parseSshTarget",0,function(t){let e;if(!t||o.test(t))return null;let r=t.trim(),s=r.indexOf(":");if(s<=0)return null;let a=r.slice(0,s),i=r.slice(s+1);if(!i.startsWith("/")||i.includes(".."))return null;let n=a,u=a.indexOf("@");return u>=0&&(e=a.slice(0,u),n=a.slice(u+1),!e)?null:n&&/^[a-zA-Z0-9.\-]+$/.test(n)&&(!e||/^[a-zA-Z0-9._\-]+$/.test(e))?{user:e,host:n,remotePath:i}:null}],296555);let l=(0,s.promisify)(r.execFile);function c(){return i.default.join(n.default.homedir(),".wiki-viewer","mounts")}async function d(){if(!0!==e)try{await l("sshfs",["--version"]),e=!0}catch{throw Error("sshfs binary not found. Install sshfs + FUSE (e.g. `apt install sshfs`, `brew install macfuse sshfs`) and ensure it is on PATH.")}}async function p(e){var r;let s=i.default.resolve(e),n=!1;try{n=(await (0,a.readFile)("/proc/mounts","utf8")).split("\n").some(t=>{let e=t.split(" ");return e[1]===s&&/fuse/.test(e[2]??"")})}catch{n=!1}return!!n&&(r=s,new Promise(e=>{let s=!1,a=setTimeout(()=>{s||(s=!0,e(!1))},4e3);t.A(687903).then(({readdir:t})=>t(r)).then(()=>{s||(s=!0,clearTimeout(a),e(!0))}).catch(()=>{s||(s=!0,clearTimeout(a),e(!1))})}))}async function h(t){await d(),await (0,a.mkdir)(t.mountpoint,{recursive:!0});let e=u(t);if(await new Promise((s,a)=>{let i=(0,r.spawn)("sshfs",e,{stdio:["pipe","ignore","pipe"]}),n="",o=setTimeout(()=>{i.kill("SIGKILL"),a(Error("sshfs mount timed out after 25s."))},25e3);i.stderr?.on("data",t=>{n+=t.toString()}),i.on("error",t=>{clearTimeout(o),a(t.message.includes("ENOENT")?Error("sshfs binary not found on PATH."):t)}),i.on("close",t=>{clearTimeout(o),0===t?s():a(Error(`sshfs exited ${t}: ${n.trim()||"mount failed"}`))}),"password"===t.authMethod&&i.stdin?.write((t.password??"")+"\n"),i.stdin?.end()}),!await p(t.mountpoint))throw Error("sshfs reported success but the mount is not live.")}async function f(t){let e=i.default.resolve(t);for(let[t,r]of[["fusermount",["-u","-z",e]],["umount",[e]]])try{await l(t,r);break}catch{}try{await (0,a.rmdir)(e)}catch{}}t.s(["assertSshfsAvailable",0,d,"isMounted",0,p,"mountSshfs",0,h,"mountpointFor",0,function(t){return i.default.join(c(),t)},"mountsDir",0,c,"unmountSshfs",0,f],256294)},536654,t=>{"use strict";var e=t.i(912714),r=t.i(750227);function s(t){return!!(r.default.isAbsolute(t)||".."===t||t.startsWith(".."+r.default.sep)||t.startsWith("../"))}async function a(t,i,n={}){let o;if(!t)return null;let u=function(t){if(t.includes("\0")||r.default.isAbsolute(t))return null;let e=t.replace(/\\/g,"/");return(("."===(e=r.default.posix.normalize(e))||"./"===e)&&(e=""),".."===e||e.startsWith("../")||/^[a-zA-Z]:\//.test(e)||e.startsWith("/"))?null:e}(i);if(null===u)return null;if(n.deniedSegments?.length){for(let t of u.split("/").filter(Boolean))if(n.deniedSegments.includes(t))return null}try{o=await (0,e.realpath)(t)}catch{return null}let l=u?r.default.join(o,u):o;try{let t=await (0,e.realpath)(l),a=r.default.relative(o,t);if(s(a))return null;return{relPath:u,absolutePath:t}}catch{if(!n.allowMissing)return null;let t=l;for(;;){let a=r.default.dirname(t);if(a===t)break;try{let t=await (0,e.realpath)(a),i=r.default.relative(o,t);if(s(i))return null;return{relPath:u,absolutePath:l}}catch{t=a}}return null}}t.s(["resolveWorkspacePath",0,a])},848475,t=>{"use strict";var e=t.i(750227);let r={".md":"text/markdown; charset=utf-8",".markdown":"text/markdown; charset=utf-8",".txt":"text/plain; charset=utf-8",".json":"application/json; charset=utf-8",".jsonc":"application/json; charset=utf-8",".ts":"text/typescript; charset=utf-8",".tsx":"text/typescript; charset=utf-8",".mts":"text/typescript; charset=utf-8",".js":"text/javascript; charset=utf-8",".jsx":"text/javascript; charset=utf-8",".mjs":"text/javascript; charset=utf-8",".html":"text/html; charset=utf-8",".htm":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".yaml":"text/yaml; charset=utf-8",".yml":"text/yaml; charset=utf-8",".toml":"text/toml; charset=utf-8",".xml":"application/xml; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".avif":"image/avif",".ico":"image/x-icon",".bmp":"image/bmp",".pdf":"application/pdf",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".py":"text/x-python; charset=utf-8",".rs":"text/x-rustsrc; charset=utf-8",".go":"text/x-go; charset=utf-8",".sh":"text/x-shellscript; charset=utf-8",".csv":"text/csv; charset=utf-8",".tsv":"text/tab-separated-values; charset=utf-8",".env":"text/plain; charset=utf-8",".log":"text/plain; charset=utf-8",".ini":"text/plain; charset=utf-8",".conf":"text/plain; charset=utf-8",".mmd":"text/plain; charset=utf-8",".ipynb":"application/json; charset=utf-8",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".doc":"application/msword",".xls":"application/vnd.ms-excel",".ppt":"application/vnd.ms-powerpoint",".mp4":"video/mp4",".webm":"video/webm",".mov":"video/quicktime",".m4v":"video/mp4",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".m4a":"audio/mp4",".aac":"audio/aac"};t.s(["contentTypeForPath",0,function(t){return r[e.default.extname(t).toLowerCase()]??"application/octet-stream"}])},719126,t=>{"use strict";var e=t.i(666680),r=t.i(912714),s=t.i(750227),a=t.i(536654),i=t.i(848475);async function n(t,e){if(!t)return null;let r=await (0,a.resolveWorkspacePath)(t,e,{allowMissing:!0,deniedSegments:[".proof",".git"]});return r?.absolutePath??null}async function o(t,e){let s=420;try{let e=await (0,r.stat)(t);s=511&e.mode}catch{}let a=t+".~"+process.pid+"."+Date.now()+".tmp",i=await (0,r.open)(a,"w",s);try{await i.write(e),await i.datasync()}finally{await i.close()}await (0,r.rename)(a,t)}async function u(t,e){let a=s.default.dirname(t);if(e)return await (0,r.mkdir)(a,{recursive:!0}),!0;try{return await (0,r.stat)(a),!0}catch{return!1}}t.s(["atomicWrite",0,o,"ensureParentDir",0,u,"extractShaHex",0,function(t){return t.replace(/^"/,"").replace(/"$/,"").replace(/^sha256:/,"")},"isDeniedRelPath",0,function(t){let e=t.replace(/\\/g,"/");return".proof"===e||e.startsWith(".proof/")||".git"===e||e.startsWith(".git/")},"isMarkdown",0,function(t){return t.endsWith(".md")||t.endsWith(".markdown")},"looksLikeBinary",0,function(t){return t.slice(0,Math.min(t.length,8192)).includes(0)},"mimeByExt",0,function(t){return(0,i.contentTypeForPath)(t)},"safeAbsPath",0,n,"sha256ofBuf",0,function(t){return"sha256:"+(0,e.createHash)("sha256").update(t).digest("hex")}])},487018,t=>{"use strict";var e=t.x("node:sqlite",()=>require("node:sqlite"),!0);function r(t){return 1===t.length&&Array.isArray(t[0])?t[0]:t}class s{stmt;constructor(t){this.stmt=t}get reader(){return this.stmt.columns().length>0}all(...t){let e=r(t);return this.stmt.all(...e)}get(...t){let e=r(t);return this.stmt.get(...e)}run(...t){let e=r(t),s=this.stmt.run(...e);return{changes:Number(s.changes),lastInsertRowid:Number(s.lastInsertRowid)}}iterate(...t){let e=r(t);return this.stmt.iterate(...e)}}class a{db;constructor(t){this.db=new e.DatabaseSync(t),this.db.exec("PRAGMA busy_timeout = 5000"),this.db.exec("PRAGMA journal_mode = WAL")}prepare(t){return new s(this.db.prepare(t))}exec(t){this.db.exec(t)}close(){this.db.close()}pragma(t){this.db.exec(`PRAGMA ${t}`)}}t.s(["default",()=>a])},97082,t=>{"use strict";var e=t.i(487018),r=t.i(750227),s=t.i(660526),a=t.i(902157),i=t.i(666680);let n=null;function o(){if(n)return n;let t=r.default.join(process.env.HOME??s.default.homedir(),".wiki-viewer");return(0,a.mkdirSync)(t,{recursive:!0}),(n=new e.default(r.default.join(t,"shared.db"))).pragma("journal_mode = WAL"),n.pragma("synchronous = NORMAL"),n.exec(`
2
- CREATE TABLE IF NOT EXISTS shared_docs (
3
- id TEXT PRIMARY KEY,
4
- workspace_id TEXT NOT NULL,
5
- file_path TEXT NOT NULL,
6
- token TEXT NOT NULL UNIQUE,
7
- password_hash TEXT,
8
- expires_at TEXT,
9
- created_by TEXT NOT NULL,
10
- created_at TEXT NOT NULL,
11
- view_count INTEGER NOT NULL DEFAULT 0,
12
- is_revoked INTEGER NOT NULL DEFAULT 0
13
- );
14
- CREATE INDEX IF NOT EXISTS shared_docs_token_idx ON shared_docs(token);
15
- CREATE INDEX IF NOT EXISTS shared_docs_file_idx ON shared_docs(workspace_id, file_path);
16
- `),n}function u(t){return{id:t.id,workspaceId:t.workspace_id,filePath:t.file_path,token:t.token,passwordHash:t.password_hash??null,expiresAt:t.expires_at??null,createdBy:t.created_by,createdAt:t.created_at,viewCount:t.view_count??0,isRevoked:1===t.is_revoked}}t.s(["createShare",0,function(t){var e;let r,s,a=o(),n="shr_"+(0,i.randomBytes)(8).toString("base64url"),u=(0,i.randomBytes)(16).toString("base64url"),l=t.password?(e=t.password,r=(0,i.randomBytes)(16).toString("hex"),s=(0,i.scryptSync)(e,r,64).toString("hex"),`${r}:${s}`):null,c={id:n,workspaceId:t.workspaceId,filePath:t.filePath,token:u,passwordHash:l,expiresAt:t.expiresAt??null,createdBy:t.createdBy,createdAt:new Date().toISOString(),viewCount:0,isRevoked:!1},d={...c,isRevoked:+!!c.isRevoked};return a.prepare(`INSERT INTO shared_docs
17
- (id, workspace_id, file_path, token, password_hash, expires_at, created_by, created_at, view_count, is_revoked)
18
- VALUES (@id, @workspaceId, @filePath, @token, @passwordHash, @expiresAt, @createdBy, @createdAt, @viewCount, @isRevoked)`).run(d),c},"getShareByToken",0,function(t){let e=o().prepare("SELECT * FROM shared_docs WHERE token = ?").get(t);return e?u(e):null},"incrementViewCount",0,function(t){o().prepare("UPDATE shared_docs SET view_count = view_count + 1 WHERE token = ?").run(t)},"isExpired",0,function(t){return!!t.expiresAt&&new Date(t.expiresAt)<new Date},"listSharesForFile",0,function(t,e){return o().prepare("SELECT * FROM shared_docs WHERE workspace_id = ? AND file_path = ? AND is_revoked = 0 ORDER BY created_at DESC").all(t,e).map(u)},"revokeShare",0,function(t){o().prepare("UPDATE shared_docs SET is_revoked = 1 WHERE id = ?").run(t)},"verifyPassword",0,function(t,e){let[r,s]=e.split(":"),a=(0,i.scryptSync)(t,r,64),n=Buffer.from(s,"hex");return a.length===n.length&&(0,i.timingSafeEqual)(a,n)}])}];
19
-
20
- //# sourceMappingURL=%5Broot-of-the-server%5D__11ltgmp._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[397998,e=>{"use strict";async function r(){{let{ensureApiKey:r}=await e.A(613146);r();let{deleteLegacySearchDb:s}=await e.A(566560);s()}}e.s(["register",0,r])},613146,e=>{e.v(r=>Promise.all(["server/chunks/[root-of-the-server]__0er9oof._.js"].map(r=>e.l(r))).then(()=>r(504263)))},566560,e=>{e.v(r=>Promise.all(["server/chunks/[root-of-the-server]__0ifw4.q._.js"].map(r=>e.l(r))).then(()=>r(717372)))}];
2
-
3
- //# sourceMappingURL=src_0ks~u~e._.js.map