@rexvane/piweb 0.3.15 → 0.3.17
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/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +4 -4
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/react-loadable-manifest.json +3 -3
- package/.next/required-server-files.js +1 -3
- package/.next/required-server-files.json +1 -3
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
- package/.next/server/app/api/growth/route.js +1 -1
- package/.next/server/app/api/growth/route.js.nft.json +1 -1
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/pi-settings/route.js +1 -1
- package/.next/server/app/api/plugins/route.js.nft.json +1 -1
- package/.next/server/app/api/prompts/route.js.nft.json +1 -1
- package/.next/server/app/api/security/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/import/route.js +3 -3
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/update/route.js +1 -1
- package/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +4 -4
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +4 -4
- package/.next/server/chunks/496.js +1 -1
- package/.next/server/chunks/686.js +4 -4
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2716.93be8ad5c970c516.js +1 -0
- package/.next/static/chunks/4632.112d2e893d48d188.js +1 -0
- package/.next/static/chunks/4673.c1fb1580efc6ace7.js +1 -0
- package/.next/static/chunks/4686-f4a037d609cea3f2.js +1 -0
- package/.next/static/chunks/app/page-b51087831582ee37.js +1 -0
- package/.next/static/chunks/{webpack-42c5aae79b0e5d8c.js → webpack-c31263fd83d75ce6.js} +1 -1
- package/.next/static/css/850c2fd130ffa2fc.css +1 -0
- package/README.md +17 -19
- package/assets/archive.jpg +0 -0
- package/assets/growth-1.jpg +0 -0
- package/assets/growth-2.jpg +0 -0
- package/assets/import.jpg +0 -0
- package/assets/main.jpg +0 -0
- package/assets/outline.jpg +0 -0
- package/assets/prompts-1.jpg +0 -0
- package/assets/prompts-2.jpg +0 -0
- package/assets/providers-1.jpg +0 -0
- package/assets/providers-2.jpg +0 -0
- package/assets/providers-3.jpg +0 -0
- package/assets/trace-1.jpg +0 -0
- package/assets/trace-2.png +0 -0
- package/assets/trace-3.png +0 -0
- package/assets/trace-4.png +0 -0
- package/assets/viewer-1.jpg +0 -0
- package/assets/viewer-2.jpg +0 -0
- package/bin/pi.js +50 -0
- package/next.config.ts +32 -7
- package/package.json +2 -6
- package/scripts/launcher.mjs +1 -1
- package/scripts/verify-package.mjs +0 -53
- package/src/app/api/growth/route.ts +14 -14
- package/src/app/api/models/route.ts +2 -1
- package/src/app/globals.css +90 -0
- package/src/components/AppShell.tsx +30 -16
- package/src/components/ChatWindow.tsx +192 -6
- package/src/components/FileViewer.tsx +10 -9
- package/src/components/ProjectPanel.tsx +111 -94
- package/src/components/SessionImportSection.tsx +20 -36
- package/src/hooks/useGrowth.ts +123 -156
- package/src/hooks/usePiWeb.ts +7 -10
- package/src/i18n.tsx +39 -39
- package/src/lib/agent-manager.ts +10 -8
- package/src/lib/growth-service.ts +390 -166
- package/src/lib/growth-tracker.ts +64 -264
- package/src/lib/growth-turns.ts +31 -1
- package/src/lib/models/model-scope.ts +15 -0
- package/src/lib/models-service.ts +16 -0
- package/src/lib/pi-settings.ts +7 -0
- package/src/lib/session-import/claude.ts +2 -13
- package/src/lib/session-import/codex.ts +8 -44
- package/src/lib/session-import/files.ts +0 -14
- package/src/lib/session-import/grok.ts +24 -54
- package/src/lib/session-import/types.ts +0 -12
- package/src/lib/types.ts +27 -22
- package/tsconfig.json +2 -1
- package/.next/static/chunks/2716.a9e808190a4e2424.js +0 -1
- package/.next/static/chunks/4632.0ed92ae42905ce40.js +0 -1
- package/.next/static/chunks/4673.d3d0a7f2599080fb.js +0 -1
- package/.next/static/chunks/4686-7d694def920ff093.js +0 -1
- package/.next/static/chunks/app/page-9a5440047c5a415c.js +0 -1
- package/.next/static/css/b2d35abc828d4713.css +0 -1
- package/assets/archive.png +0 -0
- package/assets/growth-1.png +0 -0
- package/assets/growth-2.png +0 -0
- package/assets/import.png +0 -0
- package/assets/main.png +0 -0
- package/assets/outline.png +0 -0
- package/assets/prompts-1.png +0 -0
- package/assets/prompts-2.png +0 -0
- package/assets/providers-1.png +0 -0
- package/assets/providers-2.png +0 -0
- package/assets/providers-3.png +0 -0
- package/assets/trace-1.png +0 -0
- package/assets/viewer-1.png +0 -0
- package/assets/viewer-2.png +0 -0
- package/scripts/managed-niubash-assets.mjs +0 -146
- package/scripts/prepare-niubash-packages.mjs +0 -182
- package/scripts/smoke-managed-niubash.mjs +0 -62
- package/src/lib/growth-rounds.ts +0 -84
- package/src/lib/managed-niubash.ts +0 -227
- /package/.next/static/{DdBwPYoHBKtaJ97QIr6Co → zsynuO_9Kx6nrXgkTUJ04}/_buildManifest.js +0 -0
- /package/.next/static/{DdBwPYoHBKtaJ97QIr6Co → zsynuO_9Kx6nrXgkTUJ04}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var e,t,r,o,n,a,i,l,c
|
|
1
|
+
(()=>{"use strict";var e,t,r,o,n,a,i,l,u,c={},s={};function d(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}},o=!0;try{c[e].call(r.exports,r,r.exports,d),o=!1}finally{o&&delete s[e]}return r.exports}d.m=c,e=[],d.O=(t,r,o,n)=>{if(r){n=n||0;for(var a=e.length;a>0&&e[a-1][2]>n;a--)e[a]=e[a-1];e[a]=[r,o,n];return}for(var i=1/0,a=0;a<e.length;a++){for(var[r,o,n]=e[a],l=!0,u=0;u<r.length;u++)(!1&n||i>=n)&&Object.keys(d.O).every(e=>d.O[e](r[u]))?r.splice(u--,1):(l=!1,n<i&&(i=n));if(l){e.splice(a--,1);var c=o();void 0!==c&&(t=c)}}return t},d.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return d.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,d.t=function(e,o){if(1&o&&(e=this(e)),8&o||"object"==typeof e&&e&&(4&o&&e.__esModule||16&o&&"function"==typeof e.then))return e;var n=Object.create(null);d.r(n);var a={};t=t||[null,r({}),r([]),r(r)];for(var i=2&o&&e;"object"==typeof i&&!~t.indexOf(i);i=r(i))Object.getOwnPropertyNames(i).forEach(t=>a[t]=()=>e[t]);return a.default=()=>e,d.d(n,a),n},d.d=(e,t)=>{for(var r in t)d.o(t,r)&&!d.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},d.f={},d.e=e=>Promise.all(Object.keys(d.f).reduce((t,r)=>(d.f[r](e,t),t),[])),d.u=e=>"static/chunks/"+e+"."+({618:"ee5d5bf1c647e483",2155:"2f27fe7098987699",2608:"ec8ff1f5767c9056",2716:"93be8ad5c970c516",4632:"112d2e893d48d188",4673:"c1fb1580efc6ace7"})[e]+".js",d.miniCssF=e=>"static/css/"+({7250:"08815507594e8b8d",8114:"2959bd6b626b7ffe"})[e]+".css",d.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),d.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o={},d.l=(e,t,r,n)=>{if(o[e])return void o[e].push(t);if(void 0!==r)for(var a,i,l=document.getElementsByTagName("script"),u=0;u<l.length;u++){var c=l[u];if(c.getAttribute("src")==e||c.getAttribute("data-webpack")=="_N_E:"+r){a=c;break}}a||(i=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,d.nc&&a.setAttribute("nonce",d.nc),a.setAttribute("data-webpack","_N_E:"+r),a.src=d.tu(e)),o[e]=[t];var s=(t,r)=>{a.onerror=a.onload=null,clearTimeout(f);var n=o[e];if(delete o[e],a.parentNode&&a.parentNode.removeChild(a),n&&n.forEach(e=>e(r)),t)return t(r)},f=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),i&&document.head.appendChild(a)},d.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.tt=()=>(void 0===n&&(n={createScriptURL:e=>e},"u">typeof trustedTypes&&trustedTypes.createPolicy&&(n=trustedTypes.createPolicy("nextjs#bundler",n))),n),d.tu=e=>d.tt().createScriptURL(e),d.p="/_next/",a={8068:0},d.f.miniCss=(e,t)=>{if(a[e])t.push(a[e]);else 0!==a[e]&&({7250:1,8114:1})[e]&&t.push(a[e]=new Promise((t,r)=>{var o=d.miniCssF(e),n=d.p+o;if(((e,t)=>{for(var r=document.getElementsByTagName("link"),o=0;o<r.length;o++){var n=r[o],a=n.getAttribute("data-href")||n.getAttribute("href");if("stylesheet"===n.rel&&(a===e||a===t))return n}for(var i=document.getElementsByTagName("style"),o=0;o<i.length;o++){var n=i[o],a=n.getAttribute("data-href");if(a===e||a===t)return n}})(o,n))return t();((e,t,r,o)=>{var n=document.createElement("link");n.rel="stylesheet",n.type="text/css",n.onerror=n.onload=a=>{if(n.onerror=n.onload=null,"load"===a.type)r();else{var i=a&&("load"===a.type?"missing":a.type),l=a&&a.target&&a.target.href||t,u=Error("Loading CSS chunk "+e+" failed.\n("+l+")");u.code="CSS_CHUNK_LOAD_FAILED",u.type=i,u.request=l,n.parentNode.removeChild(n),o(u)}},n.href=t;if("function"==typeof _N_E_STYLE_LOAD){var a=n.href,i=n.onload,l=n.onerror;_N_E_STYLE_LOAD(0===a.indexOf(window.location.origin)?new URL(a).pathname:a).then(function(){i&&i.call(n,{type:"load"})},function(){l&&l.call(n,{})})}else document.head.appendChild(n)})(e,n,t,r)}).then(()=>{a[e]=0},t=>{throw delete a[e],t}))},i={8068:0,5483:0,7086:0,3334:0},d.f.j=(e,t)=>{var r=d.o(i,e)?i[e]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(3334|5483|7086|7250|8068|8114)$/.test(e))i[e]=0;else{var o=new Promise((t,o)=>r=i[e]=[t,o]);t.push(r[2]=o);var n=d.p+d.u(e),a=Error();d.l(n,t=>{if(d.o(i,e)&&(0!==(r=i[e])&&(i[e]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+o+": "+n+")",a.name="ChunkLoadError",a.type=o,a.request=n,r[1](a)}},"chunk-"+e,e)}},d.O.j=e=>0===i[e],l=(e,t)=>{var r,o,[n,a,l]=t,u=0;if(n.some(e=>0!==i[e])){for(r in a)d.o(a,r)&&(d.m[r]=a[r]);if(l)var c=l(d)}for(e&&e(t);u<n.length;u++)o=n[u],d.o(i,o)&&i[o]&&i[o][0](),i[o]=0;return d.O(c)},(u=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(l.bind(null,0)),u.push=l.bind(null,u.push.bind(u))})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,::backdrop,:after,:before{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:host,:root{--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-bold:700;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,::backdrop,:after,:before{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}:host,html{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}menu,ol,ul{list-style:none}audio,canvas,embed,iframe,img,object,svg,video{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit,::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.\!relative{position:relative!important}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.-top-1{top:calc(var(--spacing) * -1)}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-0{top:0}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\/2{top:50%}.top-3{top:calc(var(--spacing) * 3)}.top-5{top:calc(var(--spacing) * 5)}.top-6{top:calc(var(--spacing) * 6)}.top-8{top:calc(var(--spacing) * 8)}.top-9{top:calc(var(--spacing) * 9)}.top-full{top:100%}.-right-1{right:calc(var(--spacing) * -1)}.-right-1\.5{right:calc(var(--spacing) * -1.5)}.right-0{right:0}.right-1{right:var(--spacing)}.right-2{right:calc(var(--spacing) * 2)}.right-4{right:calc(var(--spacing) * 4)}.right-5{right:calc(var(--spacing) * 5)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-9{bottom:calc(var(--spacing) * 9)}.bottom-10{bottom:calc(var(--spacing) * 10)}.bottom-24{bottom:calc(var(--spacing) * 24)}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.z-20{z-index:20}.z-50{z-index:50}.z-\[70\]{z-index:70}.z-\[80\]{z-index:80}.z-\[85\]{z-index:85}.z-\[95\]{z-index:95}.z-\[100\]{z-index:100}.z-\[105\]{z-index:105}.z-\[110\]{z-index:110}.z-\[120\]{z-index:120}.z-\[130\]{z-index:130}.z-\[9999\]{z-index:9999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:var(--spacing)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2{margin-block:calc(var(--spacing) * 2)}.-mt-3{margin-top:calc(var(--spacing) * -3)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-14{height:calc(var(--spacing) * 14)}.h-\[42px\]{height:42px}.h-full{height:100%}.h-screen{height:100vh}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[70vh\]{max-height:70vh}.max-h-\[340px\]{max-height:340px}.min-h-0{min-height:0}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-36{width:calc(var(--spacing) * 36)}.w-44{width:calc(var(--spacing) * 44)}.w-52{width:calc(var(--spacing) * 52)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-\[260px\]{width:260px}.w-\[312px\]{width:312px}.w-\[calc\(100\%-8px\)\]{width:calc(100% - 8px)}.w-\[min\(92vw\,360px\)\]{width:min(92vw,360px)}.w-\[min\(92vw\,380px\)\]{width:min(92vw,380px)}.w-\[min\(92vw\,480px\)\]{width:min(92vw,480px)}.w-full{width:100%}.w-max{width:max-content}.w-screen{width:100vw}.max-w-\[45\%\]{max-width:45%}.max-w-\[85\%\]{max-width:85%}.max-w-\[90vw\]{max-width:90vw}.max-w-\[180px\]{max-width:180px}.max-w-\[220px\]{max-width:220px}.max-w-\[420px\]{max-width:420px}.max-w-\[calc\(100vw-24px\)\]{max-width:calc(100vw - 24px)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:0}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-\[86px\]{min-width:86px}.flex-1{flex:1}.flex-none{flex:none}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1)}.-translate-x-1\/2,.-translate-y-1\/2{translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-\[6px\]{gap:6px}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1{row-gap:var(--spacing)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-\[10px\]{border-radius:10px}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:3.40282e+38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-\[var\(--dsw-border-l1\)\]{border-color:var(--dsw-border-l1)}.border-\[var\(--dsw-label-tertiary\)\]{border-color:var(--dsw-label-tertiary)}.border-current{border-color:currentColor}.border-transparent{border-color:#0000}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.border-white\/10{border-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.border-white\/15{border-color:#ffffff26}@supports (color:color-mix(in lab,red,red)){.border-white\/15{border-color:color-mix(in oklab,var(--color-white) 15%,transparent)}}.border-t-transparent{border-top-color:#0000}.bg-\[\#2c2c2c\]{background-color:#2c2c2c}.bg-\[\#212121\]{background-color:#212121}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab,red,red)){.bg-black\/60{background-color:color-mix(in oklab,var(--color-black) 60%,transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/\[0\.05\]{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.bg-white\/\[0\.05\]{background-color:color-mix(in oklab,var(--color-white) 5%,transparent)}}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-7{padding:calc(var(--spacing) * 7)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-12{padding-inline:calc(var(--spacing) * 12)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-4{padding-right:calc(var(--spacing) * 4)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-0{padding-bottom:0}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pl-1{padding-left:var(--spacing)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[14\.5px\]{font-size:14.5px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#f87171\]{color:#f87171}.text-\[var\(--dsw-label-primary\)\]{color:var(--dsw-label-primary)}.text-black{color:var(--color-black)}.text-white{color:var(--color-white)}.text-zinc-200{color:var(--color-zinc-200)}.text-zinc-300{color:var(--color-zinc-300)}.text-zinc-400{color:var(--color-zinc-400)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040)}.shadow-2xl,.shadow-xl{box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-focus-within\:flex:is(:where(.group):focus-within *){display:flex}.group-focus-within\:hidden:is(:where(.group):focus-within *){display:none}@media (hover:hover){.group-hover\:block:is(:where(.group):hover *){display:block}.group-hover\:flex:is(:where(.group):hover *){display:flex}.group-hover\:hidden:is(:where(.group):hover *){display:none}.group-hover\/tool\:opacity-100:is(:where(.group\/tool):hover *){opacity:1}}.first\:mt-0:first-child{margin-top:0}@media (hover:hover){.hover\:border-\[\#f87171\]\/40:hover{border-color:oklab(71.0627% .153814 .0628211/.4)}.hover\:border-white\/25:hover{border-color:#ffffff40}@supports (color:color-mix(in lab,red,red)){.hover\:border-white\/25:hover{border-color:color-mix(in oklab,var(--color-white) 25%,transparent)}}.hover\:bg-\[\#383838\]:hover{background-color:#383838}.hover\:bg-\[var\(--dsw-hover\)\]:hover{background-color:var(--dsw-hover)}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.hover\:bg-zinc-200:hover{background-color:var(--color-zinc-200)}.hover\:text-\[\#ef4444\]:hover{color:#ef4444}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-white\/40:focus{border-color:#fff6}@supports (color:color-mix(in lab,red,red)){.focus\:border-white\/40:focus{border-color:color-mix(in oklab,var(--color-white) 40%,transparent)}}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-white\/30:focus{--tw-ring-color:#ffffff4d}@supports (color:color-mix(in lab,red,red)){.focus\:ring-white\/30:focus{--tw-ring-color:color-mix(in oklab,var(--color-white) 30%,transparent)}}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:cursor-wait:disabled{cursor:wait}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}:root{--dsw-deepseek-400:#679efe;--dsw-deepseek-450:#5686fe;--dsw-deepseek-500:#4176e6;--dsw-amber-500:#f59e0b;--dsw-green-500:#22c55e;--dsw-red-600:#ec1313;--dsw-bg-base:#fff;--dsw-bg-elevated:#fff;--dsw-sidebar-fill:#f9fafb;--dsw-input-major:#fff;--dsw-bubble:#eff4ff;--dsw-hover:#0000000a;--dsw-active:#0000000f;--dsw-label-primary:#000;--dsw-label-secondary:#404042;--dsw-label-tertiary:#6e6e73;--dsw-label-caption:#96969b;--dsw-border-l1:#0000000a;--dsw-border-l2:#0000001a;--dsw-border-l3:#0000001f;--dsw-border-l4:#00000029;--dsw-accent:var(--dsw-deepseek-500);--dsw-accent-soft:#4176e61a;--dsw-warn:var(--dsw-amber-500);--dsw-success:var(--dsw-green-500);--dsw-danger:var(--dsw-red-600);--dsw-selector:#0000000d;--dsw-layer-2:#fff;--dsw-layer-3:#fff;--dsw-btn-elevated:#fff;--dsw-btn-floating-hover:#f0f1f3;--dsw-module-platform:#eeeff1;--dsw-border-strong:#adb2b8;--dsw-glass-popover:#fff;--dsw-glass-input:#fff;--dsw-glass-modal:#fff;--dsw-mask:#0000003d;--dsw-mask-blur:blur(6px);--dsw-elevation-stroke:var(--dsw-border-l2);--dsw-elevation-soft:0 0 0 .5px var(--dsw-elevation-stroke),0 4px 16px #00000008,0 0 24px #00000008;--dsw-elevation-panel:0 0 0 .5px var(--dsw-elevation-stroke),0 8px 32px #00000014;--dsw-elevation-prominent:0 0 0 .5px var(--dsw-elevation-stroke),0 16px 48px #00000029;--ds-ease-in-out:cubic-bezier(.4,0,.2,1);--ds-duration-fast:.1s;--ds-duration-normal:.2s;--ds-duration-slow:.3s;--dsh-content-font-size:14px;--dsh-content-font-delta:0px;--dsh-content-font-size-secondary:13px;--piweb-chat-font-size:var(--dsh-content-font-size);--piweb-chat-font-l:calc(var(--piweb-chat-font-size) * .96);--piweb-chat-font-m:calc(var(--piweb-chat-font-size) * .93);--piweb-chat-font-s:calc(var(--piweb-chat-font-size) * .89);--piweb-chat-font-t:calc(var(--piweb-chat-font-size) * .86);--piweb-chat-font-xs:calc(var(--piweb-chat-font-size) * .82);--font-ui:"Maple Mono CN",ui-monospace,SFMono-Regular,Menlo,Consolas,"PingFang SC","Microsoft YaHei",monospace;--font-mono:"Maple Mono CN",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--dsh-chat-content-width:clamp(544px,51.2%,736px);--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px)}@media (prefers-color-scheme:dark){:root:not([data-ds-light-theme]),body:not([data-ds-light-theme]){--dsw-bg-base:#151517;--dsw-bg-elevated:#1e1e20;--dsw-sidebar-fill:#1b1b1c;--dsw-input-major:#2c2c2e;--dsw-bubble:#26282e;--dsw-hover:#ffffff0d;--dsw-active:#ffffff14;--dsw-label-primary:#f9fafb;--dsw-label-secondary:#cfd3d6;--dsw-label-tertiary:#adb2b8;--dsw-label-caption:#81858c;--dsw-border-l1:#ffffff0f;--dsw-border-l2:#ffffff1f;--dsw-border-l3:#ffffff29;--dsw-border-l4:#fff3;--dsw-accent:var(--dsw-deepseek-400);--dsw-accent-soft:#679efe24;--dsw-danger:#f25a5a;--dsw-selector:#ffffff14;--dsw-layer-2:#2c2c2e;--dsw-layer-3:#353638;--dsw-btn-elevated:#43454a;--dsw-btn-floating-hover:#353638;--dsw-module-platform:#353638;--dsw-glass-popover:#353638;--dsw-glass-input:#2c2c2e;--dsw-glass-modal:#2c2c2e;--dsw-mask:#00000080;--dsw-elevation-stroke:var(--dsw-border-l2);--dsw-elevation-soft:0 0 0 .5px var(--dsw-elevation-stroke),0 4px 16px #0003,0 0 24px #0003;--dsw-elevation-panel:0 0 0 .5px var(--dsw-elevation-stroke),0 8px 32px #0006;--dsw-elevation-prominent:0 0 0 .5px var(--dsw-elevation-stroke),0 16px 48px #0000008c}}body[data-ds-dark-theme],html[data-ds-dark-theme]{--dsw-bg-base:#151517;--dsw-bg-elevated:#1e1e20;--dsw-sidebar-fill:#1b1b1c;--dsw-input-major:#2c2c2e;--dsw-bubble:#26282e;--dsw-hover:#ffffff0d;--dsw-active:#ffffff14;--dsw-label-primary:#f9fafb;--dsw-label-secondary:#cfd3d6;--dsw-label-tertiary:#adb2b8;--dsw-label-caption:#81858c;--dsw-border-l1:#ffffff0f;--dsw-border-l2:#ffffff1f;--dsw-border-l3:#ffffff29;--dsw-border-l4:#fff3;--dsw-accent:var(--dsw-deepseek-400);--dsw-accent-soft:#679efe24;--dsw-danger:#f25a5a;--dsw-selector:#ffffff14;--dsw-layer-2:#2c2c2e;--dsw-layer-3:#353638;--dsw-btn-elevated:#43454a;--dsw-btn-floating-hover:#353638;--dsw-module-platform:#353638;--dsw-glass-popover:#353638;--dsw-glass-input:#2c2c2e;--dsw-glass-modal:#2c2c2e;--dsw-mask:#00000080;--dsw-elevation-stroke:var(--dsw-border-l2);--dsw-elevation-soft:0 0 0 .5px var(--dsw-elevation-stroke),0 4px 16px #0003,0 0 24px #0003;--dsw-elevation-panel:0 0 0 .5px var(--dsw-elevation-stroke),0 8px 32px #0006;--dsw-elevation-prominent:0 0 0 .5px var(--dsw-elevation-stroke),0 16px 48px #0000008c}body,html{height:100%}body{background:var(--dsw-bg-base);color:var(--dsw-label-primary);font-family:var(--font-ui);font-size:var(--dsh-content-font-size);line-height:calc(24px + var(--dsh-content-font-delta));-webkit-font-smoothing:antialiased;overflow:hidden}button{font-size:inherit;cursor:pointer;padding:0}button,input,select,textarea{font-family:inherit;color:inherit;background:0 0;border:none}input,select,textarea{outline:none}select{color-scheme:light}select option{background:var(--dsw-layer-2);color:var(--dsw-label-primary)}body[data-ds-dark-theme] select{color-scheme:dark}input::placeholder,textarea::placeholder{color:var(--dsw-label-caption)}*{box-sizing:border-box;corner-shape:superellipse(1.5)}@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}.piweb-conversation-width-handle{z-index:3;cursor:col-resize;touch-action:none;width:12px;position:absolute;top:0;bottom:0}.piweb-conversation-width-handle[data-side=left]{left:calc(50% - var(--dsh-chat-content-width) / 2 - 20px)}.piweb-conversation-width-handle[data-side=right]{right:calc(50% - var(--dsh-chat-content-width) / 2 - 20px)}.piweb-conversation-width-handle:after{content:"";background:var(--dsw-border-l3);opacity:0;width:2px;transition:opacity var(--ds-duration-fast);border-radius:2px;position:absolute;top:0;bottom:0;left:5px}.piweb-conversation-width-handle:focus-visible:after,.piweb-conversation-width-handle:hover:after,.piweb-conversation-width-handle[data-dragging]:after{opacity:1}@media (max-width:840px){:root{--dsh-chat-content-width:100%;--dsh-composer-card-max-width:100%}.piweb-conversation-width-handle{display:none}.pi-main>.hairline-b{padding-left:56px;padding-right:12px}.settings-dialog{flex-direction:column;border-radius:22px!important;width:calc(100vw - 16px)!important;max-width:none!important;height:calc(100vh - 16px)!important}.settings-nav{border-bottom:.5px solid var(--dsw-border-l2);overflow-x:auto;flex-direction:row!important;width:100%!important;padding:10px!important}.settings-nav>button{flex:none;height:36px}.settings-title{display:none}}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:var(--dsw-active);background-clip:content-box;border:2.5px solid #0000;border-radius:8px}::-webkit-scrollbar-thumb:hover{background:var(--dsw-border-l3);background-clip:content-box;border:2px solid #0000}::-webkit-scrollbar-track{background:0 0}.icon-btn{width:28px;height:28px;color:var(--dsw-label-secondary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:8px;justify-content:center;align-items:center;display:inline-flex}.icon-btn:hover{background:var(--dsw-hover)}.chip,.icon-btn:hover{color:var(--dsw-label-primary)}.chip{height:28px;white-space:nowrap;transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:24px;align-items:center;gap:5px;padding:0 10px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.chip:hover{background:var(--dsw-hover);color:var(--dsw-label-primary)}.chip .chevron{color:var(--dsw-label-caption);transition:transform .12s var(--ds-ease-in-out)}.chip[data-open=true] .chevron{transform:rotate(180deg)}.hero-chip{height:28px;color:var(--dsw-label-primary);white-space:nowrap;cursor:pointer;transition:background var(--ds-duration-fast) var(--ds-ease-in-out);background:0 0;border-radius:14px;align-items:center;gap:6px;padding:0 8px;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.hero-chip:hover,.hero-chip[data-open=true]{background:var(--dsw-hover)}.hero-chip .hero-chip-icon{color:var(--dsw-label-primary);flex:none}.hero-chip .chevron{color:var(--dsw-label-caption);transition:transform .12s var(--ds-ease-in-out);flex:none}.hero-chip[data-open=true] .chevron{transform:rotate(180deg)}.btn-outline{border:.5px solid var(--dsw-border-l3);height:36px;color:var(--dsw-label-primary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out);background:0 0;border-radius:18px;justify-content:center;align-items:center;gap:6px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.btn-outline:hover{background:var(--dsw-hover)}.btn-primary-white{background:var(--dsw-label-primary);height:36px;color:var(--dsw-bg-base);transition:opacity var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:18px;justify-content:center;align-items:center;gap:6px;padding:0 14px;font-size:14px;font-weight:500;line-height:22px;display:inline-flex}.btn-primary-white:disabled{opacity:.5;cursor:default}.btn-new-session{border:.5px solid var(--dsw-border-l3);background:var(--dsw-btn-elevated);height:38px;color:var(--dsw-label-primary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:12px;justify-content:center;align-items:center;gap:6px;padding:8px 16px;font-size:14px;font-weight:500;line-height:22px;display:inline-flex}.btn-new-session:hover{background:var(--dsw-btn-floating-hover)}.select-chip{border:.5px solid var(--dsw-border-l2);height:32px;color:var(--dsw-label-primary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:16px;align-items:center;gap:6px;padding:0 12px;font-size:13px;display:inline-flex}.select-chip:hover{background:var(--dsw-hover)}.tab-underline{color:var(--dsw-label-tertiary);transition:color var(--ds-duration-fast) var(--ds-ease-in-out);padding:6px 2px;font-size:13.5px;position:relative}.tab-underline:hover{color:var(--dsw-label-primary)}.tab-underline[data-active=true]{color:var(--dsw-accent);font-weight:600}.tab-underline:after{content:"";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.tab-underline[data-active=true]:after{background:var(--dsw-accent)}.settings-tab-underline{color:var(--dsw-label-tertiary);transition:color var(--ds-duration-fast) var(--ds-ease-in-out);padding:6px 2px 10px;font-size:13.5px;position:relative}.settings-tab-underline:hover{color:var(--dsw-label-primary)}.settings-tab-underline[data-active=true]{color:var(--dsw-label-primary);font-weight:500}.settings-tab-underline:after{content:"";background:0 0;border-radius:2px;height:2px;position:absolute;bottom:-1px;left:0;right:0}.settings-tab-underline[data-active=true]:after{background:var(--dsw-label-primary)}.btn-primary-circle{background:var(--dsw-accent);color:#fff;width:34px;height:34px;transition:opacity var(--ds-duration-fast) var(--ds-ease-in-out),transform var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:999px;flex:none;justify-content:center;align-items:center;margin-top:-3px;margin-bottom:-3px;display:inline-flex;transform:translateY(-2px)}.btn-primary-circle:disabled{opacity:.4;cursor:default}.btn-ghost-circle{width:30px;height:30px;color:var(--dsw-label-secondary);border:.5px solid var(--dsw-border-l2);background:0 0;border-radius:999px;flex:none;justify-content:center;align-items:center;margin-top:-3px;margin-bottom:-3px;display:inline-flex;transform:translateY(-2px)}.btn-ghost-circle:hover{color:var(--dsw-danger);border-color:var(--dsw-danger)}.pw-queue{flex-direction:column;gap:3px;margin:0 14px 8px;font-size:12.5px;display:flex}.pw-queue-row{min-width:0;color:var(--dsw-label-secondary);align-items:center;gap:8px;display:flex}.pw-queue-tag{text-transform:capitalize;color:var(--dsw-label-tertiary);border:.5px solid var(--dsw-border-l2);border-radius:4px;flex:none;padding:0 6px;font-size:10.5px;line-height:16px}.pw-queue-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.pw-queue-foot{color:var(--dsw-label-caption);gap:12px;margin-top:1px;padding-left:2px;font-size:11.5px;display:flex}.pw-queue-foot button:hover{color:var(--dsw-label-secondary)}.pw-busy-hint{color:var(--dsw-label-caption);margin:6px 14px 0;font-size:11.5px;line-height:16px}.hairline-t{border-top:.5px solid var(--dsw-border-l2)}.hairline-b{border-bottom:.5px solid var(--dsw-border-l2)}.hairline-r{border-right:.5px solid var(--dsw-border-l2)}.rail-btn{width:36px;height:36px;color:var(--dsw-label-secondary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:12px;justify-content:center;align-items:center;display:inline-flex}.rail-btn:hover{background:var(--dsw-hover);color:var(--dsw-label-primary)}.state-dot{border-radius:999px;flex:none;width:8px;height:8px;position:relative}.state-dot.running{background:var(--dsw-deepseek-450);animation:dot-breathe 1s ease-in-out infinite}.state-dot.pending{background:var(--dsw-warn);box-shadow:0 0 0 3px #f59e0b1a}.state-dot.done{background:var(--dsw-success)}@keyframes dot-breathe{0%,to{opacity:1}50%{opacity:.45}}.popover{background:var(--dsw-glass-popover);box-shadow:var(--dsw-elevation-prominent);border:.5px solid var(--dsw-border-l1);border-radius:16px;padding:6px;overflow:hidden}.modal-mask{background:var(--dsw-mask);-webkit-backdrop-filter:var(--dsw-mask-blur)}.glass-modal{background:var(--dsw-glass-modal)}.md{overflow-wrap:break-word;min-width:0;font-size:var(--piweb-chat-font-size);line-height:1.65}.md>:first-child{margin-top:0}.md>:last-child{margin-bottom:0}.md p{margin:.5em 0}.md h1,.md h2,.md h3,.md h4{margin:1em 0 .4em;font-weight:600;line-height:1.35}.md h1{font-size:1.35em}.md h2{font-size:1.22em}.md h3{font-size:1.1em}.md ol,.md ul{margin:.5em 0;padding-left:1.5em}.md li{margin:.2em 0}.md a{color:var(--dsw-accent);text-decoration:none}.md a:hover{text-decoration:underline}.md blockquote{border-left:3px solid var(--dsw-border-l3);color:var(--dsw-label-secondary);margin:.6em 0;padding:.1em 0 .1em .9em}.md code{font-family:var(--font-mono);border-radius:5px;padding:.1em .35em;font-size:.9em}.md code,.md pre{background:var(--dsw-selector)}.md pre{border:.5px solid var(--dsw-border-l1);border-radius:12px;margin:.7em 0;padding:12px 14px;overflow-x:auto}.md pre code{background:0 0;padding:0;font-size:13px;line-height:1.55}.md-code-block{position:relative}.md-code-copy{z-index:1;position:absolute;top:12px;right:12px}.md-code-block pre{padding-top:40px}.md table{border-collapse:collapse;width:100%;margin:.7em 0;font-size:.95em}.md td,.md th{border:.5px solid var(--dsw-border-l2);text-align:left;padding:5px 10px}.md th{background:var(--dsw-hover)}.md hr{border:none;border-top:.5px solid var(--dsw-border-l2);margin:1em 0}:root{--hl-comment:#828892;--hl-keyword:#a046c8;--hl-string:#1e825a;--hl-number:#be6414;--hl-func:#3764dc;--hl-type:#148296;--hl-attr:#8c5a1e;--hl-tag:#c8325a;--hl-regex:#c83c28;--hl-meta:#786e28;--hl-punct:var(--dsw-label-tertiary);--hl-variable:#1e64aa}body[data-ds-dark-theme],html[data-ds-dark-theme]{--hl-comment:#78808c;--hl-keyword:#c896ff;--hl-string:#96d2a5;--hl-number:#f0af6e;--hl-func:#8cb9ff;--hl-type:#64c8d2;--hl-attr:#dcc382;--hl-tag:#f08296;--hl-regex:#eb826e;--hl-meta:#c8be78;--hl-punct:var(--dsw-label-tertiary);--hl-variable:#96c8fa}.hljs{color:var(--dsw-label-secondary)}.hljs-comment,.hljs-quote{color:var(--hl-comment);font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-section,.hljs-selector-tag,.hljs-strong{color:var(--hl-keyword)}.hljs-strong{font-weight:600}.hljs-addition,.hljs-bullet,.hljs-link,.hljs-string,.hljs-symbol{color:var(--hl-string)}.hljs-number,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-template-variable{color:var(--hl-number)}.hljs-code,.hljs-name,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:var(--hl-func)}.hljs-built_in,.hljs-builtin-name,.hljs-class .hljs-title,.hljs-type{color:var(--hl-type)}.hljs-attr,.hljs-attribute,.hljs-property{color:var(--hl-attr)}.hljs-deletion,.hljs-selector-attr,.hljs-tag{color:var(--hl-tag)}.hljs-char.escape_,.hljs-regexp,.hljs-subst{color:var(--hl-regex)}.hljs-formula,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:var(--hl-meta)}.hljs-operator,.hljs-params,.hljs-variable,.hljs-variable.language_{color:var(--hl-variable)}.hljs-punctuation{color:var(--hl-punct)}.hljs-emphasis{font-style:italic}.hljs-addition,.hljs-deletion{background:0 0}.msg-user-bubble{background:var(--dsw-input-major);max-width:85%;font-size:var(--piweb-chat-font-size);border-radius:18px;padding:10px 16px;line-height:1.65;display:inline-block}.msg-actions{opacity:.45;transition:opacity var(--ds-duration-fast) var(--ds-ease-in-out);align-items:center;gap:6px;margin-top:6px;display:flex}.msg-actions:hover{opacity:1}.msg-clock{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-label-tertiary)}.msg-clock-start{padding-right:12px}:root{--pw-danger-soft:#ec13131f;--pw-shimmer-hi:#96beff}body[data-ds-dark-theme],html[data-ds-dark-theme]{--pw-danger-soft:#f25a5a29;--pw-shimmer-hi:#e1ecff}.pw-turn{padding:6px 0 2px}.pw-run,.pw-turn{flex-direction:column;gap:1px;display:flex}.pw-step{min-height:26px;animation:pw-in .16s var(--ds-ease-in-out,ease-out) both;align-items:flex-start;gap:10px;display:flex}@keyframes pw-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:none}}.pw-icon{width:16px;height:26px;color:var(--dsw-label-caption);flex:none;justify-content:center;align-items:center;display:inline-flex}.pw-step[data-tone=live] .pw-icon{color:var(--dsw-accent);animation:dot-breathe 1.4s ease-in-out infinite}.pw-step[data-tone=fail] .pw-icon{color:var(--dsw-danger)}.pw-step[data-tone=warn] .pw-icon{color:var(--dsw-warn)}.pw-step[data-kind=retry] .pw-icon{animation:pw-rotate 1.2s linear infinite}@keyframes pw-rotate{to{transform:rotate(1turn)}}.pw-pi{font-family:var(--font-mono);color:var(--dsw-accent);font-size:15px;font-weight:600;line-height:1;transform:translateY(-1px)}.pw-body{flex:1;min-width:0}.pw-line{min-height:26px;line-height:26px;font-size:var(--piweb-chat-font-m);color:var(--dsw-label-tertiary);align-items:center;gap:6px;display:flex}button.pw-line{text-align:left;cursor:pointer;width:100%;font:inherit;font-size:var(--piweb-chat-font-m);background:0 0;border:0;padding:0}button.pw-line:hover{color:var(--dsw-label-secondary)}.pw-verb{flex:none}.pw-verb[data-failed=true]{color:var(--dsw-danger)}.pw-arg{font-family:var(--font-mono);font-size:var(--piweb-chat-font-s);color:var(--dsw-label-secondary);flex:0 auto}.pw-arg,.pw-gist{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.pw-gist{flex:1}.pw-meta{font-size:var(--piweb-chat-font-t);white-space:nowrap}.pw-line .pw-chev,.pw-meta{color:var(--dsw-label-caption);flex:none}.pw-line .pw-chev{transition:transform .12s var(--ds-ease-in-out,ease)}.pw-line[aria-expanded=true] .pw-chev{transform:rotate(90deg)}.pw-summary strong{color:var(--dsw-label-secondary);font-weight:600}.pw-run[data-open]>.pw-step:not(:first-child){margin-left:4px}.pw-shimmer{background:linear-gradient(90deg,var(--dsw-accent) 0,var(--pw-shimmer-hi) 35%,var(--dsw-accent) 70%);color:#0000;background-size:220% 100%;-webkit-background-clip:text;background-clip:text;flex:none;animation:pw-shimmer 2.2s linear infinite}@keyframes pw-shimmer{0%{background-position:120% 0}to{background-position:-100% 0}}.pw-tail{font-size:var(--piweb-chat-font-s);color:var(--dsw-label-caption);word-break:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:-4px 0 5px;line-height:1.5;display:-webkit-box;overflow:hidden}.pw-result{font-family:var(--font-mono);font-size:var(--piweb-chat-font-t);color:var(--dsw-label-tertiary);align-items:flex-start;gap:6px;margin:-4px 0 5px;line-height:1.55;display:flex}.pw-result[role=button]{cursor:pointer}.pw-rail{text-align:center;width:14px;color:var(--dsw-label-caption);-webkit-user-select:none;user-select:none;flex:none}.pw-lines{white-space:pre-wrap;word-break:break-word;flex:1;min-width:0}.pw-lines>div{text-overflow:ellipsis;white-space:pre;overflow:hidden}.pw-lines .pw-head{color:var(--dsw-label-tertiary)}.pw-lines .pw-more{color:var(--dsw-label-caption)}.pw-result[role=button]:hover .pw-more{text-decoration:underline}.pw-result[data-failed=true],.pw-result[data-failed=true] .pw-head,.pw-result[data-failed=true] .pw-rail{color:var(--dsw-danger)}.pw-diff{max-height:420px;margin:-2px 0 6px 20px;padding:6px 8px}.pw-diff,.pw-output{background:var(--dsw-markdown-code-block,var(--dsw-hover));border-radius:10px;overflow:auto}.pw-output{max-height:360px;font-family:var(--font-mono);font-size:var(--piweb-chat-font-t);color:var(--dsw-label-secondary);white-space:pre-wrap;word-break:break-word;margin:0 0 6px 20px;padding:8px 12px;line-height:1.55}.pw-output.pw-think-full{color:var(--dsw-label-tertiary);font-family:inherit}.pw-output .cmdline{color:var(--dsw-label-tertiary);border-bottom:.5px solid var(--dsw-border-l2);white-space:pre-wrap;word-break:break-all;margin-bottom:6px;padding-bottom:6px}.pw-output .cmdline:before{content:"$ ";color:var(--dsw-label-caption)}button.pw-more{font:inherit;font-family:var(--font-mono);font-size:var(--piweb-chat-font-t);color:var(--dsw-label-caption);cursor:pointer;text-align:left;background:0 0;border:0;margin-top:4px;padding:0;display:block}button.pw-more:hover{color:var(--dsw-label-secondary);text-decoration:underline}.pw-narr{font-size:var(--piweb-chat-font-l);color:var(--dsw-label-primary);margin:7px 0 3px;line-height:1.65}.pw-turn>.pw-narr:first-child{margin-top:1px}.pw-narr[data-error=true]{color:var(--dsw-danger)}.pw-narr .md p{margin:0}.pw-narr .md p+p{margin-top:.5em}.pw-narr .md pre{margin:.5em 0}.pw-warn-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-warn);flex:1;overflow:hidden}.pw-step[data-kind=abort] .pw-line,.pw-step[data-kind=context] .pw-line{color:var(--dsw-label-caption);font-size:var(--piweb-chat-font-s)}body[data-pebrel-theme],html[data-pebrel-theme]{--dsw-bg-base:#fff;--dsw-bg-elevated:#fff;--dsw-input-major:#fff;--dsw-bubble:#64748b0d;--dsw-hover:#64748b21;--dsw-active:#64748b33;--dsw-label-primary:#334155;--dsw-label-secondary:#64748b;--dsw-label-tertiary:#94a3b8;--dsw-label-caption:#a3adbb;--dsw-border-l1:#33415514;--dsw-border-l2:#3341551f;--dsw-border-l3:#33415529;--dsw-border-l4:#3341553d;--dsw-warn:#d97706;--dsw-success:#548c9e;--dsw-danger:#b23a48;--dsw-selector:#64748b14;--dsw-layer-2:#fff;--dsw-layer-3:#f5f5f6;--dsw-btn-elevated:#fff;--dsw-btn-floating-hover:#64748b21;--dsw-module-platform:#f5f5f6;--dsw-border-strong:#64748b;--dsw-glass-popover:#fff;--dsw-glass-input:#fff;--dsw-glass-modal:#fff;--dsw-mask:#0f172a38;--dsw-elevation-stroke:var(--dsw-border-l2)}body[data-pebrel-theme=pebrel],body[data-pebrel-theme=silver-steel],html[data-pebrel-theme=pebrel],html[data-pebrel-theme=silver-steel]{--dsw-sidebar-fill:#f3f4f6;--dsw-accent:#495057;--dsw-accent-soft:#4950571f}body[data-pebrel-theme=limestone-coal],html[data-pebrel-theme=limestone-coal]{--dsw-sidebar-fill:#f0efeb;--dsw-layer-3:#f0efeb;--dsw-module-platform:#f0efeb;--dsw-accent:#58554c;--dsw-accent-soft:#58554c1f}body[data-pebrel-theme=linen-moss],html[data-pebrel-theme=linen-moss]{--dsw-sidebar-fill:#f2f2ec;--dsw-layer-3:#f2f2ec;--dsw-module-platform:#f2f2ec;--dsw-accent:#5f635f;--dsw-accent-soft:#5f635f1f}body[data-pebrel-theme=nord-paper],html[data-pebrel-theme=nord-paper]{--dsw-bg-base:#fcfbf9;--dsw-bg-elevated:#f5f4f0;--dsw-sidebar-fill:#f5f4f0;--dsw-input-major:#fcfbf9;--dsw-bubble:#8c8a8014;--dsw-hover:#ebeae5;--dsw-active:#2b5a382e;--dsw-label-primary:#1a1a1a;--dsw-label-secondary:#474646;--dsw-label-tertiary:#8c8a80;--dsw-label-caption:#a8a49a;--dsw-border-l1:#eceae4;--dsw-border-l2:#e0dfd5;--dsw-border-l3:#d5d3c9;--dsw-border-l4:#c1beb5;--dsw-accent:#2b5a38;--dsw-accent-soft:#2b5a382e;--dsw-warn:#a85a20;--dsw-success:#2b5a38;--dsw-danger:#a33a3a;--dsw-selector:#ebeae5;--dsw-layer-2:#fcfbf9;--dsw-layer-3:#f5f4f0;--dsw-btn-elevated:#fcfbf9;--dsw-btn-floating-hover:#ebeae5;--dsw-module-platform:#f0efe9;--dsw-border-strong:#8c8a80;--dsw-glass-popover:#fcfbf9;--dsw-glass-input:#fcfbf9;--dsw-glass-modal:#f5f4f0;--dsw-mask:#1a1a1a30}body[data-pebrel-theme][data-ds-dark-theme],html[data-pebrel-theme][data-ds-dark-theme]{--dsw-label-primary:#e2e8f0;--dsw-label-secondary:#b9c3cf;--dsw-label-tertiary:#94a3b8;--dsw-label-caption:#64748b;--dsw-bubble:#ffffff0d;--dsw-hover:#cbd5e124;--dsw-active:#cbd5e136;--dsw-border-l1:#cbd5e114;--dsw-border-l2:#cbd5e11f;--dsw-border-l3:#cbd5e129;--dsw-border-l4:#cbd5e13d;--dsw-warn:#f59e0b;--dsw-success:#7db2c2;--dsw-danger:#c44a58;--dsw-selector:#cbd5e114;--dsw-border-strong:#94a3b8;--dsw-mask:#02061780;--dsw-elevation-stroke:var(--dsw-border-l2)}body[data-pebrel-theme=silver-steel][data-ds-dark-theme],html[data-pebrel-theme=silver-steel][data-ds-dark-theme]{--dsw-bg-base:#16181e;--dsw-bg-elevated:#1e2129;--dsw-sidebar-fill:#16181e;--dsw-input-major:#1a1c24;--dsw-layer-2:#1e2129;--dsw-layer-3:#343a48;--dsw-btn-elevated:#1e2129;--dsw-btn-floating-hover:#cbd5e124;--dsw-module-platform:#1e2129;--dsw-glass-popover:#1e2129;--dsw-glass-input:#1a1c24;--dsw-glass-modal:#1e2129;--dsw-accent:#94a3b8;--dsw-accent-soft:#94a3b826}body[data-pebrel-theme=limestone-coal][data-ds-dark-theme],html[data-pebrel-theme=limestone-coal][data-ds-dark-theme]{--dsw-bg-base:#161616;--dsw-bg-elevated:#1e1e1e;--dsw-sidebar-fill:#161616;--dsw-input-major:#171717;--dsw-layer-2:#1e1e1e;--dsw-layer-3:#383836;--dsw-btn-elevated:#1e1e1e;--dsw-btn-floating-hover:#cbd5e124;--dsw-module-platform:#1e1e1e;--dsw-glass-popover:#1e1e1e;--dsw-glass-input:#171717;--dsw-glass-modal:#1e1e1e;--dsw-accent:#d4d4d4;--dsw-accent-soft:#d4d4d424;--dsw-warn:#ceb27e}body[data-pebrel-theme=linen-moss][data-ds-dark-theme],html[data-pebrel-theme=linen-moss][data-ds-dark-theme]{--dsw-bg-base:#191c19;--dsw-bg-elevated:#212521;--dsw-sidebar-fill:#191c19;--dsw-input-major:#1e211e;--dsw-layer-2:#212521;--dsw-layer-3:#363d36;--dsw-btn-elevated:#212521;--dsw-btn-floating-hover:#cbd5e124;--dsw-module-platform:#212521;--dsw-glass-popover:#212521;--dsw-glass-input:#1e211e;--dsw-glass-modal:#212521;--dsw-accent:#a3b3a3;--dsw-accent-soft:#a3b3a326}body[data-pebrel-theme=nord-paper][data-ds-dark-theme],html[data-pebrel-theme=nord-paper][data-ds-dark-theme]{--dsw-bg-base:#2e3440;--dsw-bg-elevated:#3b4252;--dsw-sidebar-fill:#2e3440;--dsw-input-major:#3b4252;--dsw-bubble:#3b4252;--dsw-hover:#ffffff0f;--dsw-active:#88c0d02e;--dsw-label-primary:#e5e9f0;--dsw-label-secondary:#c0c7d3;--dsw-label-tertiary:#7b8294;--dsw-label-caption:#6f7688;--dsw-border-l1:#ffffff0d;--dsw-border-l2:#ffffff0f;--dsw-border-l3:#434c5e;--dsw-border-l4:#4c566a;--dsw-accent:#88c0d0;--dsw-accent-soft:#88c0d02e;--dsw-warn:#ebcb8b;--dsw-success:#a3be8c;--dsw-danger:#bf616a;--dsw-selector:#ffffff0f;--dsw-layer-2:#3b4252;--dsw-layer-3:#434c5e;--dsw-btn-elevated:#3b4252;--dsw-btn-floating-hover:#434c5e;--dsw-module-platform:#3b4252;--dsw-border-strong:#7b8294;--dsw-glass-popover:#3b4252;--dsw-glass-input:#3b4252;--dsw-glass-modal:#3b4252;--dsw-mask:#0206175c}body[data-pebrel-theme=pebrel][data-ds-dark-theme],html[data-pebrel-theme=pebrel][data-ds-dark-theme]{--dsw-bg-base:#222630;--dsw-bg-elevated:#2b303b;--dsw-sidebar-fill:#222630;--dsw-input-major:#0f111a;--dsw-layer-2:#2b303b;--dsw-layer-3:#414858;--dsw-btn-elevated:#2b303b;--dsw-btn-floating-hover:#cbd5e124;--dsw-module-platform:#2b303b;--dsw-glass-popover:#2b303b;--dsw-glass-input:#0f111a;--dsw-glass-modal:#2b303b;--dsw-accent:#52a8ff;--dsw-accent-soft:#52a8ff26}@keyframes piweb-spin-kf{to{transform:rotate(1turn)}}.piweb-spin{animation:piweb-spin-kf .8s linear infinite}@keyframes piweb-pulse-kf{0%,to{opacity:1}50%{opacity:.3}}.piweb-pulse{animation:piweb-pulse-kf 1.1s ease-in-out infinite}@keyframes stream-cursor-kf{0%,49%{opacity:1}50%,to{opacity:0}}.stream-cursor{vertical-align:-.15em;background:var(--dsw-accent);width:2px;height:1em;margin-left:2px;animation:stream-cursor-kf 1s step-end infinite;display:inline-block}.pw-seg{background:var(--dsw-hover);border-radius:8px;flex:none;gap:1px;padding:2px;display:inline-flex}.pw-seg>button{height:20px;color:var(--dsw-label-tertiary);white-space:nowrap;transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:6px;padding:0 8px;font-size:11.5px;line-height:20px}.pw-seg>button[data-active=true]{background:var(--dsw-bg-elevated);color:var(--dsw-label-primary);box-shadow:0 0 0 .5px var(--dsw-border-l2),0 1px 2px #0000000f}.pw-chip{border:.5px solid var(--dsw-border-l3);height:20px;color:var(--dsw-label-tertiary);white-space:nowrap;transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out),border-color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:999px;flex:none;padding:0 8px;font-size:11px;line-height:19px}.pw-chip:hover{background:var(--dsw-hover);color:var(--dsw-label-primary)}.pw-chip[data-active=true]{background:var(--dsw-accent-soft);color:var(--dsw-accent);border-color:#0000}.pw-chip:disabled{opacity:.4;pointer-events:none}.pw-project{background:var(--dsw-sidebar-fill);border-right:.5px solid var(--dsw-border-l2)}.pw-project input,.pw-viewer input{color:var(--dsw-label-primary);outline:none}.pw-tree{-webkit-user-select:none;user-select:none;font-size:12.5px;line-height:22px}.pw-tree-row{cursor:pointer;white-space:nowrap;height:22px;color:var(--dsw-label-primary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:6px;align-items:center;gap:4px;padding-right:8px;display:flex;position:absolute;left:0;right:0}.pw-tree-row:hover{background:var(--dsw-hover)}.pw-tree-row[data-focused],.pw-tree-row[data-selected]{background:var(--dsw-active)}.pw-tree:focus-visible .pw-tree-row[data-focused]{box-shadow:inset 0 0 0 1px var(--dsw-accent)}.pw-tree-chevron,.pw-tree-row[data-lazy]>.pw-tree-name{color:var(--dsw-label-caption)}.pw-tree-chevron{width:12px;flex:none;justify-content:center;align-items:center;display:inline-flex}.pw-tree-icon{object-fit:contain;flex:none;width:16px;height:16px}.pw-tree-row>.pw-tree-icon{filter:saturate(.78);transition:filter var(--ds-duration-fast) var(--ds-ease-in-out),opacity var(--ds-duration-fast) var(--ds-ease-in-out)}.pw-tree-row>.pw-tree-icon[data-kind=dir]{opacity:.88;transform:translateY(-.25px)scale(.87)}.pw-tree-row>.pw-tree-icon[data-kind=file]{opacity:.93;transform:scale(.91)}.pw-tree-row:hover>.pw-tree-icon{filter:saturate(.95);opacity:1}.pw-viewer .pw-tree-icon{filter:saturate(.82);opacity:.92;transform:scale(.9)}.pw-tree-name{text-overflow:ellipsis;flex:1;min-width:0;overflow:hidden}.pw-tree-from{color:var(--dsw-label-caption);margin-left:6px;font-size:11px}.pw-tree-stat{font-variant-numeric:tabular-nums;color:var(--dsw-label-caption);flex:none;gap:4px;font-size:10.5px;display:inline-flex}.pw-tree-badge{text-align:center;font-variant-numeric:tabular-nums;border:.5px solid;border-radius:4px;flex:none;min-width:14px;height:14px;padding:0 3px;font-size:10px;font-weight:600;line-height:13px}.pw-tree-actions{flex:none;align-items:center;gap:1px;display:none}.pw-tree-row:hover .pw-tree-actions{display:inline-flex}.pw-tree-row:hover .pw-tree-stat{display:none}.pw-tree-pulse{background:var(--dsw-accent);border-radius:999px;flex:none;width:6px;height:6px;animation:dot-breathe 1s ease-in-out infinite}.pw-tree-row[data-pending]>.pw-tree-name{color:var(--dsw-accent)}@keyframes pw-tree-in{0%{opacity:0;transform:translate(-6px)}to{opacity:1;transform:none}}@keyframes pw-tree-glow-add{0%{background:#22c55e47}to{background:0 0}}@keyframes pw-tree-glow-mod{0%{background:#f59e0b42}to{background:0 0}}@keyframes pw-tree-glow-del{0%{background:#ec13133d}to{background:0 0}}.pw-tree-row[data-fresh]{animation:pw-tree-in .25s var(--ds-ease-in-out) both,pw-tree-glow-mod 2.2s ease-out both}.pw-tree-row[data-fresh=A]{animation-name:pw-tree-in,pw-tree-glow-add}.pw-tree-row[data-fresh=D]{animation-name:pw-tree-in,pw-tree-glow-del}.pw-timeline{flex:none}.pw-tl-rail{scrollbar-width:none;align-items:flex-end;gap:3px;height:34px;padding:6px 10px 2px;display:flex;overflow-x:auto}.pw-tl-rail::-webkit-scrollbar{display:none}.pw-tl-bar{opacity:.5;width:8px;min-height:3px;transition:opacity var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:2px 2px 1px 1px;flex:none}.pw-tl-bar:hover{opacity:.85}.pw-tl-bar[data-active]{opacity:1;box-shadow:0 0 0 1px var(--dsw-sidebar-fill),0 0 0 2px var(--dsw-label-secondary)}.pw-tl-bar[data-kind=user]{width:4px}.pw-tl-bar[data-running]{border:1px dashed var(--dsw-label-caption);height:14px;animation:pw-tl-breathe 1.6s var(--ds-ease-in-out) infinite;background:0 0}@keyframes pw-tl-breathe{50%{opacity:.2}}.pw-viewer{width:80vw;height:80vh;box-shadow:var(--dsw-elevation-prominent);animation:pw-in .16s var(--ds-ease-in-out) both;transition:width var(--ds-duration-normal) var(--ds-ease-in-out),height var(--ds-duration-normal) var(--ds-ease-in-out),border-radius var(--ds-duration-normal) var(--ds-ease-in-out);border-radius:20px}.pw-viewer[data-fullscreen]{border-radius:0;width:100vw;height:100vh}.pw-viewer-tabs{flex:none;height:40px;padding:0 8px 0 10px}.pw-viewer-tabs,.pw-viewer-tabstrip{align-items:center;gap:2px;display:flex}.pw-viewer-tabstrip{scrollbar-width:none;min-width:0;overflow-x:auto}.pw-viewer-tabstrip::-webkit-scrollbar{display:none}.pw-viewer-tab{max-width:200px;height:28px;color:var(--dsw-label-tertiary);transition:background var(--ds-duration-fast) var(--ds-ease-in-out),color var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:8px;flex:none;align-items:center;gap:6px;padding:0 8px;font-size:12.5px;display:inline-flex}.pw-viewer-tab:hover{background:var(--dsw-hover);color:var(--dsw-label-primary)}.pw-viewer-tab[data-active=true]{background:var(--dsw-active);color:var(--dsw-label-primary)}.pw-viewer-tab-main{min-width:0;color:inherit;align-items:center;gap:6px;display:inline-flex}.pw-viewer-tab-close{width:16px;height:16px;color:var(--dsw-label-caption);opacity:0;transition:opacity var(--ds-duration-fast) var(--ds-ease-in-out);border-radius:4px;justify-content:center;align-items:center;margin-right:-4px;display:inline-flex}.pw-viewer-tab-close:focus-visible,.pw-viewer-tab:hover .pw-viewer-tab-close,.pw-viewer-tab[data-active=true] .pw-viewer-tab-close{opacity:1}.pw-viewer-tab-close:hover{background:var(--dsw-hover);color:var(--dsw-label-primary)}.pw-viewer-toolbar{flex:none;gap:6px;height:36px;padding:0 12px}.pw-crumb,.pw-viewer-toolbar{align-items:center;display:flex}.pw-crumb{color:var(--dsw-label-tertiary);white-space:nowrap;flex-wrap:nowrap;font-size:12.5px;overflow:hidden}.pw-crumb button:hover{color:var(--dsw-accent)}.pw-crumb-sep{color:var(--dsw-label-caption);margin:0 4px}.pw-viewer-notice{color:var(--dsw-label-secondary);background:var(--dsw-hover);border-bottom:.5px solid var(--dsw-border-l1);flex:none;padding:4px 14px;font-size:11.5px}.pw-viewer-notice[data-kind=deleted]{color:var(--dsw-danger);background:#ec131314}.pw-viewer-notice[data-kind=warn]{color:var(--dsw-warn)}.pw-viewer .md pre{overflow-x:auto}.pw-quick{z-index:5;background:#00000014;justify-content:center;align-items:flex-start;padding-top:56px;display:flex;position:absolute;inset:0}.pw-quick-box{border-radius:14px;width:min(560px,90%);padding:4px}.pw-quick-list{max-height:50vh;padding:2px;overflow-y:auto}.pw-quick-item{width:100%;height:30px;color:var(--dsw-label-primary);text-align:left;border-radius:8px;align-items:center;gap:8px;padding:0 8px;font-size:12.5px;display:flex}.pw-quick-item[data-active=true]{background:var(--dsw-active)}.pw-fdiff{font-family:var(--font-mono);font-size:12px;line-height:20px}.pw-fdiff-row{white-space:pre;height:20px;color:var(--dsw-label-secondary);align-items:stretch;display:flex;position:absolute;left:0;right:0}.pw-fdiff-row[data-kind=add]{box-shadow:inset 2px 0 0 var(--dsw-success);background:#22c55e24}.pw-fdiff-row[data-kind=del]{box-shadow:inset 2px 0 0 var(--dsw-danger);background:#ec13131f}.pw-fdiff-gutter{color:var(--dsw-label-caption);-webkit-user-select:none;user-select:none;font-variant-numeric:tabular-nums;background:inherit;flex:none;gap:1ch;padding:0 8px 0 10px;display:inline-flex;position:sticky;left:0}.pw-fdiff-gutter>span{display:inline-block}.pw-fdiff-sign{-webkit-user-select:none;user-select:none;width:1.5ch;color:var(--dsw-label-caption);flex:none}.pw-fdiff-row[data-kind=add] .pw-fdiff-sign{color:var(--dsw-success)}.pw-fdiff-row[data-kind=del] .pw-fdiff-sign{color:var(--dsw-danger)}.pw-fdiff-text{background:0 0;flex:1;padding-right:24px}.pw-fdiff-fold{height:20px;color:var(--dsw-label-caption);background:var(--dsw-hover);text-align:center;letter-spacing:.02em;font-size:11px;position:absolute;left:0;right:0}.pw-fdiff-fold:hover{color:var(--dsw-accent)}.pw-fdiff-ticks{pointer-events:none;width:8px;position:absolute;top:0;bottom:0;right:2px}.pw-fdiff-tick{pointer-events:auto;cursor:pointer;background:var(--dsw-success);opacity:.6;border-radius:1px;width:8px;height:3px;position:absolute;right:0}.pw-fdiff-tick[data-kind=del]{background:var(--dsw-danger)}.pw-fdiff-tick[data-current]{opacity:1;box-shadow:0 0 0 1px var(--dsw-label-tertiary)}@media (max-width:840px){.pw-viewer{border-radius:0;width:100vw;height:100vh}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(1turn)}}
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<img src="assets/main.
|
|
12
|
+
<img src="assets/main.jpg" alt="PiWeb UI Showcase" width="840" />
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
---
|
|
@@ -24,48 +24,48 @@ PiWeb and pi are two separate programs, and PiWeb is not another build of pi: it
|
|
|
24
24
|
|
|
25
25
|
### Real-Time Streaming Chat
|
|
26
26
|
|
|
27
|
-
Markdown renders as it streams — headings, lists and code blocks take shape before the answer is finished, not after. Thinking and tool calls appear inline as cards. The layout stays restrained: sessions on the left, outline on the right, both collapsible, leaving the screen to the conversation.
|
|
27
|
+
Markdown renders as it streams — headings, lists and code blocks take shape before the answer is finished, not after. Code blocks can be copied. The conversation column can be dragged wider, and the width is remembered in this browser. Thinking and tool calls appear inline as cards. The layout stays restrained: sessions on the left, outline on the right, both collapsible, leaving the screen to the conversation. The model picker follows `enabledModels` in pi settings; the settings page still shows the full catalog.
|
|
28
28
|
|
|
29
|
-
<p align="center"><img src="assets/main.
|
|
29
|
+
<p align="center"><img src="assets/main.jpg" alt="Main page: streaming chat with tool cards" width="840" /></p>
|
|
30
30
|
|
|
31
31
|
### Chat Navigation
|
|
32
32
|
|
|
33
33
|
The outline on the right of the transcript: **bold entries are messages you sent**, the rest are headings inside the assistant's answers. Collapsed it reads as a column of bars — longer for your messages, shorter the deeper a heading sits; hover to expand the list. It highlights where you are as you scroll, and a click scrolls smoothly to that spot.
|
|
34
34
|
|
|
35
|
-
<p align="center"><img src="assets/outline.
|
|
35
|
+
<p align="center"><img src="assets/outline.jpg" alt="Chat navigation: bold entries are your own messages" width="840" /></p>
|
|
36
36
|
|
|
37
37
|
### Trajectory and Files, In Place
|
|
38
38
|
|
|
39
39
|
Tool cards carry both entry points: **View in trajectory** drops that step into the trajectory panel — a timeline with input / model / tool lanes, laid out by sequence, wall-clock time or duration, searchable, with per-row tokens and timings and detail tabs for summary, preview, raw and source. **Open in editor** jumps straight to the local file that step touched. A card that changed a file also carries the whole diff inline (additions green, deletions red, with +N −M counts), folded to a preview for long changes and expanded on click.
|
|
40
40
|
|
|
41
|
-
<p align="center"><img src="assets/trace-1.
|
|
41
|
+
<p align="center"><img src="assets/trace-1.jpg" alt="工具卡片上的两个入口与内联 diff" width="840" /></p>
|
|
42
42
|
<p align="center"><img src="assets/trace-2.png" alt="轨迹入口按钮" /> <img src="assets/trace-3.png" alt="入口按钮细节" /> <img src="assets/trace-4.png" alt="入口按钮细节" /></p>
|
|
43
43
|
|
|
44
44
|
### Workspaces & Sessions
|
|
45
45
|
|
|
46
46
|
Sessions grouped by project folder, with a native folder picker (Windows / macOS / Linux), rename and archive. Archived conversations live together under "Archived" in the sidebar, ready to reopen or unarchive, and **an archived session is deleted automatically after 30 days of inactivity** — no manual cleanup. Session tree branches, draft recovery, and JSONL / HTML export are there too.
|
|
47
47
|
|
|
48
|
-
<p align="center"><img src="assets/archive.
|
|
48
|
+
<p align="center"><img src="assets/archive.jpg" alt="Archived: archived conversations in one place" width="400" /></p>
|
|
49
49
|
|
|
50
50
|
### Import Local Sessions
|
|
51
51
|
|
|
52
52
|
Bring conversation history from Codex, Claude Code, Grok, ZCode, dsh and opencode on this machine into pi sessions without loss: text, thinking, tool calls and their results, timestamps and usage are all kept, and the source data is **read-only** — nothing in the other tools is modified. Each source lists only its 15 most recent **main** conversations; work the main agent handed to a subagent is ignored, because the conversation you want is your own. If the original project directory still exists locally the session lands in that workspace, otherwise it falls back to one you pick — and anything already imported is marked and never imported twice.
|
|
53
53
|
|
|
54
|
-
<p align="center"><img src="assets/import.
|
|
54
|
+
<p align="center"><img src="assets/import.jpg" alt="Settings → Import sessions: pick a source, tick, import" width="840" /></p>
|
|
55
55
|
|
|
56
56
|
### Project Growth Tree
|
|
57
57
|
|
|
58
58
|
Every file operation pi makes is snapshotted, grouped one round per message you send. Each round shows what changed **relative to the previous one** — files added, modified and deleted, with line-level diffs one click away — so you can review the work round by round, or drill into single steps inside a round. A round with no file changes says so instead of being skipped, and the record is independent of git: it works on a project with no version history at all.
|
|
59
59
|
|
|
60
|
-
<p align="center"><img src="assets/growth-1.
|
|
61
|
-
<p align="center"><img src="assets/growth-2.
|
|
60
|
+
<p align="center"><img src="assets/growth-1.jpg" alt="Project growth tree (1 of 2)" width="840" /></p>
|
|
61
|
+
<p align="center"><img src="assets/growth-2.jpg" alt="Project growth tree (2 of 2)" width="840" /></p>
|
|
62
62
|
|
|
63
63
|
### File Viewer
|
|
64
64
|
|
|
65
65
|
Open project files in the page instead of switching to an editor: a centered window with tabs, and fuzzy search behind the "+". Each file has three views — **Changes** (whole-file diff, additions green and deletions red, with one-click jumps between changes), **Content** (line numbers and syntax highlighting; deleted files show their last content), and **Rendered** (Markdown as a document). Quote a selection into the composer, or open the file in your local editor.
|
|
66
66
|
|
|
67
|
-
<p align="center"><img src="assets/viewer-1.
|
|
68
|
-
<p align="center"><img src="assets/viewer-2.
|
|
67
|
+
<p align="center"><img src="assets/viewer-1.jpg" alt="File viewer (1 of 2)" width="840" /></p>
|
|
68
|
+
<p align="center"><img src="assets/viewer-2.jpg" alt="File viewer (2 of 2)" width="840" /></p>
|
|
69
69
|
|
|
70
70
|
### Context Meter
|
|
71
71
|
|
|
@@ -75,16 +75,16 @@ Click the ring next to the composer to see the context window broken down into 1
|
|
|
75
75
|
|
|
76
76
|
A header button opens a panel listing every prompt that reaches the model's context: the system prompt and its appended sections, project memory (`AGENTS.md`), each skill's `SKILL.md`, prompt templates, tool definitions, plus the assembled prompt actually sent and the compaction summary — each row labelled with where it came from (project / personal / package / extension). Click a row to read the original in the centre viewer. The list is enumerated live for the current workspace, so prompts that arrive with a plugin or package installed later show up on refresh.
|
|
77
77
|
|
|
78
|
-
<p align="center"><img src="assets/prompts-1.
|
|
79
|
-
<p align="center"><img src="assets/prompts-2.
|
|
78
|
+
<p align="center"><img src="assets/prompts-1.jpg" alt="Prompt sources (1 of 2)" width="840" /></p>
|
|
79
|
+
<p align="center"><img src="assets/prompts-2.jpg" alt="Prompt sources (2 of 2)" width="840" /></p>
|
|
80
80
|
|
|
81
81
|
### Model & Provider Management
|
|
82
82
|
|
|
83
83
|
40 built-in providers, signed in with an API key or OAuth — Anthropic, GitHub Copilot, OpenAI Codex, xAI, OpenRouter, Kimi and Radius support one-click OAuth. Anything else works just as well: give a custom provider its base URL, protocol and models, and it lands in `models.json`; local gateways such as Ollama get a placeholder key automatically. Pull the model catalog in one click, and quota or balance reads (Claude, Codex, xAI, DeepSeek and 7 more) sit right on the provider card.
|
|
84
84
|
|
|
85
|
-
<p align="center"><img src="assets/providers-1.
|
|
86
|
-
<p align="center"><img src="assets/providers-2.
|
|
87
|
-
<p align="center"><img src="assets/providers-3.
|
|
85
|
+
<p align="center"><img src="assets/providers-1.jpg" alt="Provider setup (1 of 3)" width="840" /></p>
|
|
86
|
+
<p align="center"><img src="assets/providers-2.jpg" alt="Provider setup (2 of 3)" width="840" /></p>
|
|
87
|
+
<p align="center"><img src="assets/providers-3.jpg" alt="Provider setup (3 of 3)" width="840" /></p>
|
|
88
88
|
|
|
89
89
|
### Plugins & Skills
|
|
90
90
|
|
|
@@ -105,8 +105,6 @@ piweb
|
|
|
105
105
|
|
|
106
106
|
The package registers only the `piweb` command, so it never conflicts with the official `pi` CLI. Requires Node.js ≥ 22.19.0 (24 recommended); Git is needed for growth-history features.
|
|
107
107
|
|
|
108
|
-
On Windows x64 and ARM64, npm automatically installs PiWeb's matching managed [niubash](https://github.com/unixwin/niubash) portable runtime. PiWeb uses it as the `bash` tool through the official Pi SDK—no separate shell install and no changes to `~/.pi/agent/settings.json`. macOS and Linux continue to use Pi's normal system Bash selection. If the optional Windows runtime is omitted or fails integrity validation, PiWeb logs a warning and falls back to Pi's configured/default Bash.
|
|
109
|
-
|
|
110
108
|
### Update
|
|
111
109
|
|
|
112
110
|
```bash
|
|
@@ -148,4 +146,4 @@ Set `PI_WEB_PASSWORD` to enable the login page and HTTP Basic Auth (user `pi`).
|
|
|
148
146
|
|
|
149
147
|
## License
|
|
150
148
|
|
|
151
|
-
[MIT](LICENSE)
|
|
149
|
+
[MIT](LICENSE)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/assets/main.jpg
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/assets/trace-2.png
CHANGED
|
Binary file
|
package/assets/trace-3.png
CHANGED
|
Binary file
|
package/assets/trace-4.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/pi.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Pi CLI Entrypoint:
|
|
4
|
+
* - `pi web [options]`: 启动 Pi Web 界面(支持任意大小写:pi web / PI WEB / Pi Web)
|
|
5
|
+
* - `pi [args...]`: 转发给 pi-coding-agent 命令行交互智能体
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const root = path.resolve(__dirname, "..");
|
|
13
|
+
const utf8Env = {
|
|
14
|
+
...process.env,
|
|
15
|
+
PYTHONUTF8: process.env.PYTHONUTF8 ?? "1",
|
|
16
|
+
PYTHONIOENCODING: process.env.PYTHONIOENCODING ?? "utf-8",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const rawArgs = process.argv.slice(2);
|
|
20
|
+
const firstArg = rawArgs[0]?.trim().toLowerCase();
|
|
21
|
+
|
|
22
|
+
if (firstArg === "web") {
|
|
23
|
+
// 启动 Web 界面
|
|
24
|
+
const subArgs = rawArgs.slice(1);
|
|
25
|
+
const script = path.join(__dirname, "piweb.js");
|
|
26
|
+
const child = spawn(process.execPath, [script, ...subArgs], {
|
|
27
|
+
cwd: root,
|
|
28
|
+
stdio: "inherit",
|
|
29
|
+
env: utf8Env,
|
|
30
|
+
});
|
|
31
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
32
|
+
} else {
|
|
33
|
+
// 转发给 pi-coding-agent
|
|
34
|
+
const piAgentCli = path.join(
|
|
35
|
+
root,
|
|
36
|
+
"node_modules",
|
|
37
|
+
"@earendil-works",
|
|
38
|
+
"pi-coding-agent",
|
|
39
|
+
"dist",
|
|
40
|
+
"bundle",
|
|
41
|
+
"cli.js",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const child = spawn(process.execPath, [piAgentCli, ...rawArgs], {
|
|
45
|
+
cwd: process.cwd(),
|
|
46
|
+
stdio: "inherit",
|
|
47
|
+
env: utf8Env,
|
|
48
|
+
});
|
|
49
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
50
|
+
}
|
package/next.config.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import type { NextConfig } from "next";
|
|
2
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "next/constants";
|
|
3
6
|
import { resolveBuildOutput } from "./scripts/build-output.mjs";
|
|
4
7
|
|
|
8
|
+
/**
|
|
9
|
+
* 让构建期的文件追踪看不到用户主目录。
|
|
10
|
+
*
|
|
11
|
+
* next-trace-entrypoints-plugin 会调 @vercel/nft 静态分析服务端代码,把
|
|
12
|
+
* `fs.readdir()` 的实参求值成绝对路径:session-import 的 `path.join(os.homedir(), ".grok", "sessions")`
|
|
13
|
+
* 一类写法于是变成真实路径,整个 ~/.grok、~/.claude、~/.agents、~/.pi 目录被当成构建资产递归遍历。后果:
|
|
14
|
+
* 1. 目录里任何一个文件读不了(权限/ACL 损坏、被独占)都会让构建以 EPERM 直接失败;
|
|
15
|
+
* 2. 这些绝对路径被写进 .next/**\/*.nft.json,而 .next 随 npm 包一起发布,
|
|
16
|
+
* 等于把构建者的用户名与目录布局发给了所有用户。
|
|
17
|
+
* 构建期把主目录指向一个空目录即可根治:nft 解析出的路径下什么都没有,也就无从追踪。
|
|
18
|
+
*
|
|
19
|
+
* 只在 PHASE_PRODUCTION_BUILD 生效。`next start` 与 `next dev` 必须用真实主目录读取
|
|
20
|
+
* 用户的 pi 配置与会话;dev 也不加载该追踪插件(webpack-config 里限定 !dev)。
|
|
21
|
+
*/
|
|
22
|
+
function isolateHomeFromTracing(): void {
|
|
23
|
+
try {
|
|
24
|
+
const isolated = path.join(os.tmpdir(), "piweb-build-home");
|
|
25
|
+
fs.mkdirSync(isolated, { recursive: true });
|
|
26
|
+
process.env.HOME = isolated;
|
|
27
|
+
process.env.USERPROFILE = isolated;
|
|
28
|
+
} catch {
|
|
29
|
+
// 建不出隔离目录就维持原样:追踪照旧会扫用户目录,构建可能因不可读文件失败。
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
5
33
|
export default (phase: string): NextConfig => {
|
|
6
34
|
const development = phase === PHASE_DEVELOPMENT_SERVER;
|
|
7
35
|
const devAssetId = process.env.PIWEB_DEV_ASSET_ID ?? "unversioned";
|
|
36
|
+
if (phase === PHASE_PRODUCTION_BUILD) isolateHomeFromTracing();
|
|
8
37
|
const buildDir = development ? ".next-dev-webpack" : resolveBuildOutput(process.cwd(), process.env.PIWEB_BUILD_DIR);
|
|
9
38
|
return {
|
|
10
39
|
// Keep dev output separate so `next build` cannot invalidate a running dev server.
|
|
@@ -13,12 +42,8 @@ export default (phase: string): NextConfig => {
|
|
|
13
42
|
// Webpack's dev chunk names are stable. A per-process prefix prevents an older
|
|
14
43
|
// browser cache entry from hydrating HTML emitted by a newer dev server.
|
|
15
44
|
assetPrefix: development ? `/_piweb-dev/${devAssetId}` : undefined,
|
|
16
|
-
// pi SDK
|
|
17
|
-
serverExternalPackages: [
|
|
18
|
-
"@earendil-works/pi-coding-agent",
|
|
19
|
-
"@rexvane/piweb-niubash-win32-x64",
|
|
20
|
-
"@rexvane/piweb-niubash-win32-arm64",
|
|
21
|
-
],
|
|
45
|
+
// pi SDK 与其动态加载的扩展都运行在服务端(Node runtime),不对客户端打包
|
|
46
|
+
serverExternalPackages: ["@earendil-works/pi-coding-agent"],
|
|
22
47
|
// Image prompts allow 268 MB of base64 plus text and JSON framing.
|
|
23
48
|
experimental: { proxyClientMaxBodySize: "272mb" },
|
|
24
49
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rexvane/piweb",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Modern web UI for the pi coding agent, driven by the official pi SDK without modifying pi",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"build": "node --max-old-space-size=8192 node_modules/next/dist/bin/next build --webpack",
|
|
40
40
|
"build:release": "node scripts/release.mjs",
|
|
41
41
|
"postinstall": "node scripts/postinstall.mjs",
|
|
42
|
-
"prepare:niubash": "node scripts/prepare-niubash-packages.mjs",
|
|
43
42
|
"prepublishOnly": "npm run typecheck && npm run test",
|
|
44
43
|
"start": "node bin/piweb.js",
|
|
44
|
+
"web": "node bin/pi.js web",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
46
|
"verify:package": "node scripts/verify-package.mjs",
|
|
47
47
|
"test": "vitest run",
|
|
@@ -73,10 +73,6 @@
|
|
|
73
73
|
"tailwindcss": "^4.2.2",
|
|
74
74
|
"typescript": "^7"
|
|
75
75
|
},
|
|
76
|
-
"optionalDependencies": {
|
|
77
|
-
"@rexvane/piweb-niubash-win32-arm64": "1.1.4-piweb.0",
|
|
78
|
-
"@rexvane/piweb-niubash-win32-x64": "1.1.4-piweb.0"
|
|
79
|
-
},
|
|
80
76
|
"devDependencies": {
|
|
81
77
|
"@testing-library/dom": "^10.4.2",
|
|
82
78
|
"@testing-library/react": "^16.3.3",
|
package/scripts/launcher.mjs
CHANGED
|
@@ -169,7 +169,7 @@ export async function runLauncher({ args = process.argv.slice(2), env = process.
|
|
|
169
169
|
const options = parseLauncherArgs(args, env);
|
|
170
170
|
const log = dependencies.log ?? console.log;
|
|
171
171
|
if (options.help) {
|
|
172
|
-
log("Usage:
|
|
172
|
+
log("Usage: pi web [-p, --port <port>] [-H, --hostname <host>] [--dev] [--no-open]");
|
|
173
173
|
log("默认绑定 127.0.0.1:30141;端口被占自动 +1。开发模式仅允许本机监听。");
|
|
174
174
|
log("对外监听必须使用生产构建与 PI_WEB_PASSWORD。构建/恢复发布:npm run build:release。");
|
|
175
175
|
return 0;
|
|
@@ -13,15 +13,9 @@ import fs from "node:fs";
|
|
|
13
13
|
import os from "node:os";
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import { spawnSync } from "node:child_process";
|
|
16
|
-
import { createRequire } from "node:module";
|
|
17
16
|
import { fileURLToPath } from "node:url";
|
|
18
17
|
import { readProductionBuild } from "./build-output.mjs";
|
|
19
18
|
import { isMainModule } from "./entrypoint.mjs";
|
|
20
|
-
import {
|
|
21
|
-
MANAGED_NIUBASH_ASSETS,
|
|
22
|
-
NIUBASH_DISTRIBUTION_VERSION,
|
|
23
|
-
validateManagedNiubashPackage,
|
|
24
|
-
} from "./managed-niubash-assets.mjs";
|
|
25
19
|
|
|
26
20
|
const DEFAULT_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
27
21
|
|
|
@@ -72,56 +66,9 @@ export function verifyPackedPackage(root, { log = console.log } = {}) {
|
|
|
72
66
|
}
|
|
73
67
|
}
|
|
74
68
|
|
|
75
|
-
/** Pack and inspect one actual OS/CPU package, including every runtime hash and license. */
|
|
76
|
-
export function verifyPackedManagedNiubashPackage(packageRoot, asset, { log = console.log } = {}) {
|
|
77
|
-
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), `piweb-niubash-pack-${asset.arch}-`));
|
|
78
|
-
try {
|
|
79
|
-
const packed = JSON.parse(runNpm(["pack", "--json", "--pack-destination", tmp], { cwd: packageRoot }));
|
|
80
|
-
const entry = Array.isArray(packed) ? packed[0] : packed;
|
|
81
|
-
if (!entry?.filename) throw new Error(`npm pack produced no tarball for ${asset.packageName}`);
|
|
82
|
-
const files = (entry.files ?? []).map((file) => String(file.path).replaceAll("\\", "/").replace(/^package\//, ""));
|
|
83
|
-
for (const required of [
|
|
84
|
-
"package.json", "index.cjs", "runtime-manifest.json", "runtime/niu.exe",
|
|
85
|
-
"runtime/winuxcmd/usr/bin/winuxcmd.exe", "runtime/bundles/oh-my-niu/bundle.toml",
|
|
86
|
-
"licenses/NIUBASH.txt", "licenses/RUBASH.txt", "licenses/WINUXCMD.txt",
|
|
87
|
-
]) {
|
|
88
|
-
if (!files.includes(required)) throw new Error(`${asset.packageName} tarball is missing ${required}`);
|
|
89
|
-
}
|
|
90
|
-
const unpacked = path.join(tmp, "unpacked");
|
|
91
|
-
fs.mkdirSync(unpacked, { recursive: true });
|
|
92
|
-
run("tar", ["-xzf", entry.filename, "-C", "unpacked"], { cwd: tmp });
|
|
93
|
-
const installedRoot = path.join(unpacked, "package");
|
|
94
|
-
const checked = validateManagedNiubashPackage(installedRoot, asset, { allowExtraRuntimeFiles: false });
|
|
95
|
-
const require = createRequire(path.join(installedRoot, "package.json"));
|
|
96
|
-
const exported = require(path.join(installedRoot, "index.cjs"));
|
|
97
|
-
if (exported.packageName !== asset.packageName || exported.arch !== asset.arch
|
|
98
|
-
|| exported.shellPath !== path.join(installedRoot, "runtime", "niu.exe")) {
|
|
99
|
-
throw new Error(`${asset.packageName} has an invalid runtime export`);
|
|
100
|
-
}
|
|
101
|
-
const bytes = fs.statSync(path.join(tmp, entry.filename)).size;
|
|
102
|
-
log(`[piweb] ${entry.filename}: ${checked.files} runtime files, ${(bytes / 1024 / 1024).toFixed(1)} MB.`);
|
|
103
|
-
return { filename: entry.filename, files, bytes, runtimeFiles: checked.files };
|
|
104
|
-
} finally {
|
|
105
|
-
fs.rmSync(tmp, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function verifyManagedNiubashPackages(root, { log = console.log } = {}) {
|
|
110
|
-
const manifest = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
111
|
-
const results = [];
|
|
112
|
-
for (const asset of Object.values(MANAGED_NIUBASH_ASSETS)) {
|
|
113
|
-
if (manifest.optionalDependencies?.[asset.packageName] !== NIUBASH_DISTRIBUTION_VERSION) {
|
|
114
|
-
throw new Error(`PiWeb must use exact optional dependency ${asset.packageName}@${NIUBASH_DISTRIBUTION_VERSION}`);
|
|
115
|
-
}
|
|
116
|
-
results.push(verifyPackedManagedNiubashPackage(path.join(root, "platform-packages", asset.directory), asset, { log }));
|
|
117
|
-
}
|
|
118
|
-
return results;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
69
|
if (isMainModule(import.meta.url)) {
|
|
122
70
|
try {
|
|
123
71
|
verifyPackedPackage(DEFAULT_ROOT);
|
|
124
|
-
verifyManagedNiubashPackages(DEFAULT_ROOT);
|
|
125
72
|
} catch (error) {
|
|
126
73
|
console.error(`[piweb] ${error instanceof Error ? error.message : error}`);
|
|
127
74
|
process.exitCode = 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import { getManaged,
|
|
3
|
-
import { GrowthError, changesBetween, fileContent, filePatch, isAvailable, listTree,
|
|
2
|
+
import { getManaged, growthRecord } from "@/lib/agent-manager";
|
|
3
|
+
import { GrowthError, changesBetween, fileContent, filePatch, isAvailable, listTree, readRounds } from "@/lib/growth-service";
|
|
4
4
|
import { BoundaryError, resolveSessionPath, resolveWorkspacePath } from "@/lib/path-security";
|
|
5
5
|
|
|
6
6
|
export const dynamic = "force-dynamic";
|
|
@@ -12,12 +12,12 @@ function status(err: unknown): number {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
* ?cwd=&session=<jsonl 路径>
|
|
17
|
-
* ?cwd=&tree=<hash>&list=1
|
|
18
|
-
* ?cwd=&from=<tree>&to=<tree>&changes=1
|
|
15
|
+
* 项目生长(每轮一个 git commit)只读接口:
|
|
16
|
+
* ?cwd=&session=<jsonl 路径> 本会话的轮次(省略 session = 工作区全部 commit)
|
|
17
|
+
* ?cwd=&tree=<hash>&list=1 某一轮的文件清单
|
|
18
|
+
* ?cwd=&from=<tree>&to=<tree>&changes=1 两轮之间的变更清单
|
|
19
19
|
* ?cwd=&from=&to=&path=[&renamedFrom=] 单文件整文件上下文的 unified diff
|
|
20
|
-
* ?cwd=&tree=&path=&content=1
|
|
20
|
+
* ?cwd=&tree=&path=&content=1 某一轮里单文件全文
|
|
21
21
|
*/
|
|
22
22
|
export async function GET(req: Request) {
|
|
23
23
|
const url = new URL(req.url);
|
|
@@ -29,21 +29,21 @@ export async function GET(req: Request) {
|
|
|
29
29
|
if (q("content") === "1") return NextResponse.json({ success: true, data: await fileContent(cwd, q("tree"), q("path")) });
|
|
30
30
|
if (q("path") !== null) return NextResponse.json({ success: true, data: await filePatch(cwd, q("from"), q("to"), q("path"), q("renamedFrom") ?? undefined) });
|
|
31
31
|
const available = await isAvailable();
|
|
32
|
-
if (!available) return NextResponse.json({ success: true, data: { available: false,
|
|
33
|
-
return NextResponse.json({ success: true, data: { available: true,
|
|
32
|
+
if (!available) return NextResponse.json({ success: true, data: { available: false, rounds: [] } });
|
|
33
|
+
return NextResponse.json({ success: true, data: { available: true, rounds: await readRounds(cwd, q("session") ?? undefined) } });
|
|
34
34
|
} catch (err: any) {
|
|
35
35
|
return NextResponse.json({ success: false, error: String(err?.message ?? err) }, { status: status(err) });
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/** POST { action: "
|
|
39
|
+
/** POST { action: "record", session: <会话 id> }:立即记录,把当前改动提交为「你的修改」(并广播给会话订阅者) */
|
|
40
40
|
export async function POST(req: Request) {
|
|
41
41
|
try {
|
|
42
|
-
const body = (await req.json()) as { action?: string; session?: unknown
|
|
43
|
-
if (body.action !== "
|
|
42
|
+
const body = (await req.json()) as { action?: string; session?: unknown };
|
|
43
|
+
if (body.action !== "record") return NextResponse.json({ success: false, error: "unknown action" }, { status: 400 });
|
|
44
44
|
const sessionPath = await resolveSessionPath(String(body.session ?? ""), { allowPending: true });
|
|
45
|
-
const
|
|
46
|
-
return NextResponse.json({ success: true, data: {
|
|
45
|
+
const round = await growthRecord(getManaged(sessionPath));
|
|
46
|
+
return NextResponse.json({ success: true, data: { round } });
|
|
47
47
|
} catch (err: any) {
|
|
48
48
|
return NextResponse.json({ success: false, error: String(err?.message ?? err) }, { status: err instanceof SyntaxError ? 400 : status(err) });
|
|
49
49
|
}
|