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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +4 -4
- package/.next/standalone/.next/routes-manifest.json +6 -0
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/internal/span/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/install/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/install/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/skill/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/skill/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/skill.tar.gz/route.js +1 -1
- package/.next/standalone/.next/server/app/api/agents/skill.tar.gz/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/pdf/save/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/asset/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/route.js +3 -4
- package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/route.js +1 -1
- package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/scratch/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route.js +16 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/wiki/scratch/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/wiki/search/route.js +1 -1
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/s/[token]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/signin/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0pyc~jf._.js → [root-of-the-server]__05o3qcm._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kuwuwk._.js → [root-of-the-server]__07wa2lq._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0bpv09n._.js +20 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0269d2e._.js → [root-of-the-server]__0mgvfb5._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0_5~w8k._.js → [root-of-the-server]__0n2r6u9._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0qpqspq._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__05tbv~.._.js → [root-of-the-server]__0q~ky91._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uja7sb._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__00sn-o5._.js → [root-of-the-server]__0xoz8e8._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0t4nr00._.js → [root-of-the-server]__10pak1_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +1 -1
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wiki_scratch_route_actions_07i6~7z.js +3 -0
- package/.next/standalone/.next/server/chunks/src_0pwns~4._.js +3 -0
- 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
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-5ZQYHXKU_mjs_0z1.978._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-KSCS5N6A_mjs_0v4oeem._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0vp_6mg._.js → [root-of-the-server]__0~4py6h._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0oq8kwv._.js +18 -18
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0mlbfkr._.js → node_modules__pnpm_0.xieh4._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0j.6d4e._.js → node_modules__pnpm_01~03ak._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0ko9~5a._.js → node_modules__pnpm_02qa21p._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0wks2mj._.js → node_modules__pnpm_05c~go7._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0z3vu9g._.js → node_modules__pnpm_07hg43b._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0c7mg2j._.js → node_modules__pnpm_09y5c~i._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_04.xdv4._.js → node_modules__pnpm_0_g0a7t._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0e_u7-~._.js → node_modules__pnpm_0_zd0nt._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0a4su30._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_03z~hj.._.js → node_modules__pnpm_0b6_242._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_01vjz.e._.js → node_modules__pnpm_0c6q9~6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05xxz0p._.js → node_modules__pnpm_0d4-t2b._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0pq4fcx._.js → node_modules__pnpm_0f0qocb._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0m4ord.._.js → node_modules__pnpm_0f6r-u~._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0k1lm~x._.js → node_modules__pnpm_0f9artj._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0l-zh.x._.js → node_modules__pnpm_0g_tlt-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0dkpe61._.js → node_modules__pnpm_0ghm84g._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0y~gqyx._.js → node_modules__pnpm_0k6yfdh._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0yw839x._.js → node_modules__pnpm_0kib6pw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0o~d81.._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0.a-6pb._.js → node_modules__pnpm_0pggrwu._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0d_jgm8._.js → node_modules__pnpm_0q9s5k5._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0~1a~df._.js → node_modules__pnpm_0q_v1_2._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0hlvme9._.js → node_modules__pnpm_0sdy2lv._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_077radr._.js → node_modules__pnpm_0tvmv0e._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_0e7k2ai._.js → node_modules__pnpm_0v7wopg._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05b80e_._.js → node_modules__pnpm_0vahm7l._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_11e33_1._.js → node_modules__pnpm_0zdl7-7._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules__pnpm_05-ipmg._.js → node_modules__pnpm_0~wqhb9._.js} +1 -1
- package/.next/standalone/.next/server/instrumentation.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/0gogvjz6oxo51.css +1 -0
- package/.next/standalone/.next/static/chunks/{08usk_~k6d0yf.js → 0k31ncl7m_j9q.js} +2 -2
- package/.next/standalone/.next/static/chunks/{0x6s~jkd4xkpx.js → 11ehczv8yax~_.js} +23 -23
- package/.next/standalone/.next/static/chunks/{turbopack-0~8fsjmdvb_1i.js → turbopack-1105gjd__15ti.js} +1 -1
- package/.next/standalone/.test-floor +1 -1
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/specs/changes/scratchpad/design.md +156 -0
- package/.next/standalone/specs/changes/scratchpad/proposal.md +82 -0
- package/.next/standalone/specs/changes/scratchpad/requirements.md +83 -0
- package/.next/standalone/specs/changes/scratchpad/tasks.md +45 -0
- package/package.json +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k46u9j._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__11ltgmp._.js +0 -20
- package/.next/standalone/.next/server/chunks/src_0ks~u~e._.js +0 -3
- package/.next/standalone/.next/static/chunks/0h9okx8g~3~jd.css +0 -1
- /package/.next/standalone/.next/static/{N4JUwvz_xf2GOGFJN02sZ → AsrmwC0YfrYEMAXj2s0Wx}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{N4JUwvz_xf2GOGFJN02sZ → AsrmwC0YfrYEMAXj2s0Wx}/_clientMiddlewareManifest.js +0 -0
- /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
|
-
|
|
1
|
+
648
|
|
@@ -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.
|
|
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,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
|