@teammy/server 0.1.6 → 0.1.7
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/README.md +2 -2
- package/dist/main.js +1410 -350
- package/dist/project-pi-entry.js +5 -3
- package/dist/web/assets/Assistant-BeYamS0w.js +1 -0
- package/dist/web/assets/Assistant-C7QfFYLo.css +1 -0
- package/dist/web/assets/Dashboard-BzmrE4Xv.js +1 -0
- package/dist/web/assets/Files-BvCYgjVV.js +1 -0
- package/dist/web/assets/{Markdown-D3cU0ani.js → Markdown-BRPMsc7D.js} +4 -4
- package/dist/web/assets/Materials-DK3CkLr0.js +6 -0
- package/dist/web/assets/Sessions-D_579m-e.js +1 -0
- package/dist/web/assets/WorkspaceTree-fMDtGIFa.js +1 -0
- package/dist/web/assets/{file-links-GfCXWkEh.js → file-links-I1K8CwVK.js} +1 -1
- package/dist/web/assets/index-DQsx-e5d.js +66 -0
- package/dist/web/downloads/teammy-skill.zip +0 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/assets/Assistant-4yZWjYm-.css +0 -1
- package/dist/web/assets/Assistant-BNVXOHQZ.js +0 -1
- package/dist/web/assets/Dashboard-zKTK6EZD.js +0 -1
- package/dist/web/assets/Files-DI98WkdW.js +0 -1
- package/dist/web/assets/Materials-CWptgAHz.js +0 -6
- package/dist/web/assets/Sessions-DiDwqXLI.js +0 -1
- package/dist/web/assets/WorkspaceTree-DeAA1QtV.js +0 -1
- package/dist/web/assets/index-BwEl1PIa.js +0 -66
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{$ as e,A as t,D as n,H as r,J as i,K as a,M as o,N as s,O as c,Q as l,R as u,S as d,U as f,V as p,X as m,Z as h,_ as g,d as _,et as v,g as y,l as b,q as x,u as S,v as C,x as w,y as T,z as E}from"./index-DQsx-e5d.js";import{n as D,r as O,t as k}from"./Markdown-BRPMsc7D.js";import{i as ee,r as A}from"./WorkspaceTree-fMDtGIFa.js";function j(e){return l(p,e)}var M=e(),N=i().regex(/^R\d{6,}$/),P=x({name:i().min(1),sha256:u,size:a().int().nonnegative()}),F=m().refine(e=>/^https?:\/\//i.test(e),`Use an HTTP or HTTPS URL.`);x({operationId:h(),title:i().trim().default(``),text:i().optional(),url:F.optional(),originals:f(P).default([])}).strict().refine(e=>!!e.text?.trim()||!!e.url||e.originals.length>0,`Provide text, a link or a file.`),x({expectedRevision:E,title:i().trim().min(1).optional(),content:i().optional(),summary:i().optional(),sourceVersion:i().optional(),contentDate:i().optional(),originals:f(P).optional()}).strict();var I=x({id:N,projectId:i(),title:i(),submittedBy:i(),createdAt:i(),revision:E,source:x({kind:r([`web`,`chat`,`group`]),url:i().nullable(),groupId:i().optional(),messageId:i().optional(),sourceVersion:i().optional(),contentDate:i().optional()}),originals:f(P),content:i().nullable(),summary:i().nullable(),state:r([`waiting`,`running`,`ready`,`failed`]),error:i().nullable(),url:i()}),L=x({materials:f(I),nextCursor:a().nullable()});x({query:i().trim().min(1),scope:r([`all`,`workspace`,`materials`]).default(`all`),materialId:N.optional(),originalHash:u.optional(),after:i().default(``),limit:j().int().min(1).max(200).default(30)}).strict();var R=x({items:f(x({key:i(),kind:r([`workspace`,`materials`]),title:i(),snippet:i(),url:i(),path:i()})),nextCursor:i().nullable()}),z=t();function te(e){let t=(e.content??``).trimStart().split(`
|
|
2
|
+
`);return t[0]?.replace(/^#\s+/,``).trim()===e.title.trim()&&t[0].startsWith(`# `)&&t.shift(),t.join(`
|
|
3
|
+
`).trimStart()}function B(){let e=new URLSearchParams(location.search),t=e.get(`id`);return t?{id:t,...e.get(`original`)?{original:e.get(`original`)}:{},...e.get(`revision`)?{revision:e.get(`revision`)}:{}}:void 0}function V(){let{request:e,projectId:t}=S(),[r,i]=(0,M.useState)(B),[a,s]=(0,M.useState)(r),[l,u]=(0,M.useState)(()=>new Set(r?[r.id]:[])),[f,p]=(0,M.useState)(!1),[m,h]=(0,M.useState)(``),[g,x]=(0,M.useState)(``),[w,E]=(0,M.useState)(``),[D,O]=(0,M.useState)([]),[j,N]=(0,M.useState)(),[P,F]=(0,M.useState)(!1),[R,V]=(0,M.useState)(``),U=(0,M.useRef)(null),W=(0,M.useCallback)(t=>e(`materials`,L,{signal:t}),[e]),G=n(W,5e3,c(t,`materials`)),ie=(0,M.useCallback)(t=>r?e(`materials/${encodeURIComponent(r.id)}${r.revision?`?revision=${encodeURIComponent(r.revision)}`:``}`,I,{signal:t}):Promise.resolve(null),[e,r?.id,r?.revision]),K=n(ie,5e3),q=K.data?.id===r?.id?K.data:null,J=[...new Map([...D,...G.data?.materials??[],...q?[q]:[]].map(e=>[e.id,e])).values()].sort((e,t)=>t.createdAt.localeCompare(e.createdAt)||t.id.localeCompare(e.id)),Y=j===void 0?G.data?.nextCursor:j;function X(e,n=``){i(e),s(e),x(``),E(n),p(!1),u(t=>new Set([...t,e.id])),history.replaceState(null,``,v(`/projects/${t}/materials?${new URLSearchParams({...e})}`))}(0,M.useEffect)(()=>{let e=()=>{let e=B();i(e),s(e),x(``),h(``),E(``),p(!1),e&&u(t=>new Set([...t,e.id]))};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);async function ae(){if(Y&&!P){F(!0),V(``);try{let t=await e(`materials?before=${Y}`,L);O(e=>[...e,...t.materials]),N(t.nextCursor)}catch(e){V(o(e))}finally{F(!1)}}}let Z=J.find(e=>e.id===a?.id),Q=Z?.originals.find(e=>e.sha256===a?.original)?.name??Z?.title??`当前资料`;function $(){s(void 0),E(``),U.current?.focus()}return(0,z.jsxs)(`div`,{className:`split-layout file-explorer session-explorer`,"data-testid":`materials-page`,children:[(0,z.jsxs)(`aside`,{className:`file-tree-pane`,"aria-label":`资料目录`,children:[(0,z.jsx)(b,{title:`资料`,icon:`materials`,children:(0,z.jsx)(T,{icon:`plus`,label:`新增资料`,onClick:()=>{p(!0),V(``)}})}),(0,z.jsx)(d,{error:!0,children:G.error||R}),G.data?J.length===0?(0,z.jsx)(`p`,{className:`tree-status`,children:`暂无资料`}):(0,z.jsx)(`div`,{role:`tree`,"aria-label":`项目资料`,onKeyDown:A,children:J.map(e=>(0,z.jsxs)(`div`,{role:`none`,children:[(0,z.jsxs)(_,{role:`treeitem`,"aria-level":1,"aria-expanded":l.has(e.id),"aria-selected":!f&&r?.id===e.id&&!r.original,className:`tree-item tree-folder`,style:{"--tree-level":1},"data-testid":`material-folder`,title:e.title,onClick:()=>{let t=l.has(e.id);X({id:e.id}),t&&u(t=>{let n=new Set(t);return n.delete(e.id),n})},leading:(0,z.jsx)(`span`,{className:`tree-chevron ${l.has(e.id)?`expanded`:``}`,children:(0,z.jsx)(C,{name:`chevron`,size:`small`})}),children:[(0,z.jsx)(C,{name:`files`}),(0,z.jsx)(`span`,{className:`tree-name`,children:e.title})]}),l.has(e.id)&&(0,z.jsx)(`div`,{role:`group`,children:[...e.originals].sort((e,t)=>ee(e.name,t.name)).map((t,n)=>(0,z.jsxs)(_,{role:`treeitem`,"aria-level":2,"aria-selected":!f&&r?.id===e.id&&r.original===t.sha256,className:`tree-item`,style:{"--tree-level":2},"data-testid":`material-original`,title:t.name,onClick:()=>X({id:e.id,original:t.sha256,...e.id===r?.id&&r.revision?{revision:r.revision}:{}}),leading:(0,z.jsx)(`span`,{className:`tree-chevron`}),children:[(0,z.jsx)(C,{name:`file`}),(0,z.jsx)(`span`,{className:`tree-name`,children:t.name})]},`${t.sha256}:${n}`))})]},e.id))}):(0,z.jsx)(`p`,{className:`tree-status`,children:`加载中…`}),Y&&(0,z.jsx)(`button`,{className:`tree-action`,disabled:P,onClick:()=>void ae(),children:P?`加载中…`:`加载更多`})]}),(0,z.jsxs)(`section`,{className:`session-reader`,"aria-label":`资料内容与搜索`,children:[(0,z.jsx)(`div`,{className:`session-reader-content`,children:f?(0,z.jsx)(re,{onCancel:()=>p(!1),onSaved:e=>{X({id:e}),G.reload()}}):g?(0,z.jsx)(ne,{query:g,scope:a,onSelect:e=>X(e,g)},`${g}/${a?.id}/${a?.original}`):r?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(d,{error:!0,children:K.error}),q?r.original?(0,z.jsx)(H,{material:q,hash:r.original,highlight:w}):(0,z.jsxs)(`article`,{className:`material-body`,children:[(0,z.jsx)(`h1`,{children:q.title}),r.revision&&(0,z.jsx)(`button`,{className:`material-link`,onClick:()=>X({id:r.id}),children:`查看最新内容`}),!r.revision&&(q.state===`waiting`||q.state===`running`)?(0,z.jsx)(`p`,{className:`muted`,role:`status`,children:`正在整理…`}):null,(0,z.jsx)(d,{error:!0,children:q.error??``}),!r.revision&&q.state===`failed`&&(0,z.jsx)(`button`,{onClick:()=>void e(`materials/${r.id}/retry`,I,{method:`POST`}).then(()=>K.reload()).catch(e=>V(o(e))),children:`重试整理`}),q.content?(0,z.jsx)(`div`,{className:`markdown`,children:(0,z.jsx)(k,{highlight:w,children:te(q)})}):(0,z.jsx)(`p`,{className:`muted`,children:`正文尚未整理,可以先查看左侧原件。`})]}):(0,z.jsx)(`p`,{role:`status`,children:`加载中…`})]}):(0,z.jsx)(y,{mascot:!0,title:`选择资料开始阅读`,description:`也可以在下方搜索资料内容。`})}),!f&&(0,z.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`material-search-form`,onSubmit:e=>{e.preventDefault(),x(m.trim()),E(``)},children:[a&&(0,z.jsxs)(`button`,{type:`button`,className:`search-scope-chip`,title:`清除搜索范围`,"aria-label":`清除范围:${Q}`,onClick:$,children:[(0,z.jsxs)(`span`,{className:`scope-label`,children:[`搜索:`,Q]}),(0,z.jsx)(`span`,{"aria-hidden":`true`,children:`×`})]}),(0,z.jsxs)(`div`,{className:`session-search-input-row`,children:[(0,z.jsx)(`input`,{ref:U,"aria-label":`搜索资料`,placeholder:`搜索资料内容`,value:m,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!m&&a&&(e.preventDefault(),$())}}),(g||m||w)&&(0,z.jsx)(T,{icon:`close`,label:`清空搜索`,onClick:()=>{h(``),x(``),E(``),U.current?.focus()}}),(0,z.jsx)(T,{icon:`search`,type:`submit`,label:`搜索`,disabled:!m.trim()})]})]})]})]})}function ne({query:e,scope:t,onSelect:r}){let{request:i}=S(),[a,o]=(0,M.useState)(``),s=(0,M.useCallback)(n=>i(`resources/search?${new URLSearchParams({query:e,scope:`materials`,after:a,...t?{materialId:t.id}:{},...t?.original?{originalHash:t.original}:{}})}`,R,{signal:n}),[i,e,t?.id,t?.original,a]),c=n(s);return(0,z.jsxs)(`section`,{className:`session-results stack`,"aria-label":`搜索结果`,children:[(0,z.jsx)(d,{error:!0,children:c.error}),c.loading?(0,z.jsx)(`p`,{role:`status`,children:`正在搜索…`}):c.data?.items.length===0?(0,z.jsx)(`p`,{className:`empty`,children:`没有找到匹配的资料`}):c.data?.items.map(t=>(0,z.jsxs)(`button`,{className:`session-item`,"data-testid":`material-match`,onClick:()=>{let e=new URL(t.url,location.origin).searchParams;r({id:e.get(`id`),...e.get(`original`)?{original:e.get(`original`)}:{},...e.get(`revision`)?{revision:e.get(`revision`)}:{}})},children:[(0,z.jsx)(`strong`,{children:t.title.replace(/^R\d+ · /,``)}),(0,z.jsx)(`span`,{className:`session-excerpt`,children:(0,z.jsx)(D,{value:O(t.snippet,e),query:e})})]},t.key)),c.data?.nextCursor&&(0,z.jsx)(`button`,{disabled:c.loading,onClick:()=>o(c.data.nextCursor),children:`下一页`})]})}function H({material:e,hash:t,highlight:r}){let{projectId:i}=S(),a=e.originals.find(e=>e.sha256===t),o=v(`/api/v1/projects/${i}/materials/${e.id}/originals/${t}?revision=${e.revision}`),[s,l]=(0,M.useState)(!1),u=(0,M.useCallback)(async e=>{let t=await fetch(o,{signal:e});if(!t.ok)throw Error(`原件暂时无法读取。`);let n=await t.arrayBuffer();try{let e=new TextDecoder(`utf8`,{fatal:!0}).decode(n);return e.includes(`\0`)?null:e}catch{return null}},[o]),f=n(u,!1,c(i,`material-original`,t));if(!a)return(0,z.jsx)(d,{error:!0,children:`找不到此原件。`});let p=/\.(md|markdown)$/i.test(a.name);return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`header`,{className:`file-detail-header`,children:[(0,z.jsx)(`span`,{className:`file-detail-path`,children:a.name}),(0,z.jsxs)(`div`,{className:`toolbar-actions`,children:[p&&(0,z.jsx)(T,{icon:s?`preview`:`code`,label:s?`切换为预览`:`切换为原文`,onClick:()=>l(!s)}),(0,z.jsx)(`a`,{className:`icon-button`,"aria-label":`下载原件`,title:`下载原件`,href:o,download:a.name,children:(0,z.jsx)(C,{name:`download`})})]})]}),(0,z.jsx)(d,{error:!0,children:f.error}),f.loading?(0,z.jsx)(`p`,{role:`status`,children:`加载中…`}):f.data===null?(0,z.jsx)(`p`,{className:`muted`,children:`此格式请下载后查看。`}):f.data!==void 0&&(0,z.jsx)(`div`,{className:`preview-body`,"data-testid":`material-original-content`,children:p&&!s?(0,z.jsx)(`article`,{className:`markdown`,children:(0,z.jsx)(k,{highlight:r,children:f.data})}):(0,z.jsx)(`pre`,{className:`raw`,children:(0,z.jsx)(D,{value:f.data,query:r})})})]})}function U(e){if(e.kind===`text`){try{if([`http:`,`https:`].includes(new URL(e.text.trim()).protocol))return`link`}catch{}return`text`}let{name:t,type:n}=e.file;return n.startsWith(`image/`)||/\.(png|jpe?g|gif|webp|svg|heic|avif)$/i.test(t)?`imageFile`:/\.(csv|tsv|xlsx?|ods)$/i.test(t)?`spreadsheetFile`:/\.(json|ya?ml|xml|html?|css|[cm]?[jt]sx?|py|go|rs|sh|sql)$/i.test(t)?`codeFile`:n.startsWith(`text/`)||/\.(pdf|docx?|odt|rtf|md|txt)$/i.test(t)?`file`:`attachment`}function W(e){try{return new URL(e.trim()).hostname}catch{return e.trim().split(`
|
|
4
|
+
`)[0]?.slice(0,80)||`文本`}}function G(e){try{return new URL(e.trim()).href}catch{return e.trim().split(`
|
|
5
|
+
`).slice(1).join(`
|
|
6
|
+
`)}}function re({onSaved:e,onCancel:t}){let{request:n,projectId:r}=S(),[i,a]=(0,M.useState)([]),[c,l]=(0,M.useState)(),[u,f]=(0,M.useState)(!1),[p,m]=(0,M.useState)(``),h=(0,M.useRef)(null),_=(0,M.useRef)(s()),y=(0,M.useRef)(new Map);function b(e){a(e),_.current=s(),m(``)}async function x(){f(!0),m(``);try{let t=[];for(let[e,n]of i.entries()){let i=y.current.get(n.id);if(!i){let t=n.kind===`file`?n.file.name:`${W(n.text)}.txt`,a=await fetch(v(`/api/v1/projects/${r}/materials/uploads`),{method:`POST`,headers:{"content-type":`application/octet-stream`,"x-teammy-web":`1`},body:n.kind===`file`?n.file:new Blob([n.text],{type:`text/plain`})}),o=await a.json();if(!a.ok)throw Error(o.error?.message??`第 ${e+1} 项上传失败。`);i={name:t,sha256:o.sha256,size:o.size},y.current.set(n.id,i)}t.push(i)}let a=i.length===1&&i[0]?.kind===`text`?i[0].text.trim():``,o;try{let e=new URL(a);[`http:`,`https:`].includes(e.protocol)&&(o=e.href)}catch{}e((await n(`materials`,I,{method:`POST`,body:{operationId:_.current,originals:t,...o?{url:o}:{}}})).id)}catch(e){m(o(e))}finally{f(!1)}}return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`form`,{className:`material-form`,onSubmit:e=>{e.preventDefault(),x()},children:[(0,z.jsx)(`h1`,{children:`新增资料`}),(0,z.jsx)(`p`,{className:`muted`,children:`上传附件到项目,以便于Tim进行理解`}),(0,z.jsx)(d,{error:!0,children:p}),(0,z.jsxs)(`fieldset`,{disabled:u,children:[(0,z.jsxs)(`div`,{className:`attachment-grid`,children:[i.map(e=>(0,z.jsxs)(`article`,{className:`attachment-card`,"data-testid":`attachment-card`,children:[e.kind===`text`?(0,z.jsxs)(`button`,{type:`button`,className:`attachment-content`,"aria-label":`编辑:${W(e.text)}`,onClick:()=>l({id:e.id,text:e.text}),children:[(0,z.jsx)(C,{name:U(e)}),(0,z.jsx)(`span`,{className:`attachment-name`,children:W(e.text)}),G(e.text)&&(0,z.jsx)(`span`,{className:`attachment-excerpt`,children:G(e.text)})]}):(0,z.jsxs)(`div`,{className:`attachment-content`,children:[(0,z.jsx)(C,{name:U(e)}),(0,z.jsx)(`span`,{className:`attachment-name`,children:e.file.name})]}),(0,z.jsx)(T,{className:`attachment-remove`,icon:`close`,label:`移除:${e.kind===`file`?e.file.name:W(e.text)}`,onClick:()=>{y.current.delete(e.id),b(i.filter(t=>t.id!==e.id))}})]},e.id)),(0,z.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>l({text:``}),children:[(0,z.jsx)(C,{name:`addText`}),(0,z.jsx)(`span`,{children:`添加文本/链接`})]}),(0,z.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>h.current?.click(),children:[(0,z.jsx)(C,{name:`addFile`}),(0,z.jsx)(`span`,{children:`添加文件`})]})]}),(0,z.jsx)(`input`,{ref:h,type:`file`,multiple:!0,hidden:!0,"aria-label":`原始文件`,onChange:e=>{b([...i,...[...e.target.files??[]].map(e=>({id:s(),kind:`file`,file:e}))]),e.target.value=``}}),(0,z.jsxs)(`div`,{className:`actions attachment-actions`,children:[(0,z.jsx)(`button`,{type:`button`,onClick:t,children:`取消`}),(0,z.jsx)(`button`,{type:`submit`,className:`primary`,disabled:!i.length,children:u?`上传中…`:`提交资料`})]})]})]}),c&&(0,z.jsx)(w,{id:`material-text-editor`,title:`添加文本/链接`,onClose:()=>l(void 0),children:(0,z.jsxs)(`form`,{className:`stack`,onSubmit:e=>{if(e.preventDefault(),!c.text.trim())return;let t={id:c.id??s(),kind:`text`,text:c.text};y.current.delete(t.id),b(c.id?i.map(e=>e.id===c.id?t:e):[...i,t]),l(void 0)},children:[(0,z.jsx)(g,{id:`material-attachment-text`,label:`文本或链接`,children:(0,z.jsx)(`textarea`,{autoFocus:!0,rows:8,value:c.text,onChange:e=>l({...c,text:e.target.value}),placeholder:`粘贴文本或网页链接`})}),(0,z.jsx)(`div`,{className:`actions`,children:(0,z.jsx)(`button`,{type:`submit`,className:`primary`,disabled:!c.text.trim(),children:c.id?`保存`:`添加`})})]})})]})}export{V as Materials};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$ as e,A as t,B as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,M as d,O as f,P as p,R as m,S as h,T as g,U as _,W as v,Y as y,Z as b,d as x,et as S,g as C,j as w,l as T,q as E,u as D,v as O,y as k,z as A}from"./index-DQsx-e5d.js";import{n as j,r as M,t as N}from"./Markdown-BRPMsc7D.js";import{n as P}from"./project-links-XbF78Bal.js";import{i as F,r as I}from"./WorkspaceTree-fMDtGIFa.js";var L=e(),R=s([`overview`,`handoff`]),z=E({title:l().trim().min(1),summary:l().trim().min(1)}).strict(),B=E({markdown:l().trim().min(1)}).strict(),V=z.extend({sourceRevision:A,sourceHash:m,generatedAt:l(),stale:v()}),H=E({kind:R,status:s([`absent`,`queued`,`running`,`succeeded`,`failed`]),available:v(),currentRevision:A,sourceRevision:A.nullable(),stale:v(),result:y([z,B]).nullable(),generatedAt:l().nullable(),error:l().nullable()}),U=s([`claude-code`,`codex`,`cursor`,`pi`,`dsh`]),W=E({formatVersion:o(1),adapterVersion:o(1),agent:U,nativeId:l().min(1).max(512),cwd:l().min(1).max(4096),messages:_(E({id:l().min(1).max(1024),role:s([`user`,`assistant`]),text:l().min(1),source:l().min(1).max(1024)}).strict())}).strict().refine(e=>new Set(e.messages.map(e=>e.id)).size===e.messages.length,`Duplicate message IDs.`);E({operationId:b(),sessionKey:m,parentRevision:A,blob:c}).strict(),E({revision:A,hash:m.nullable(),cleared:v()});var G=E({owner:n,sessionKey:m,agent:U,nativeId:l(),cwd:l(),title:l(),revision:A,updatedAt:l(),messageCount:u().int().nonnegative(),blob:c,overview:V.optional()}),K=E({sessions:_(G),nextCursor:A.nullable()}),q=E({totalSessions:u().int().nonnegative(),totalMessages:u().int().nonnegative(),memberCount:u().int().nonnegative(),updatedAt:l().nullable()});E({owner:n.optional(),sessionKey:m.optional()}).strict().refine(e=>!e.sessionKey||!!e.owner,`A session scope requires an owner.`);var J=E({matches:_(E({owner:n,sessionKey:m,revision:A,messageId:l(),role:s([`user`,`assistant`]),snippet:l(),title:l()})),nextCursor:A.nullable()}),Y=E({owner:n,key:m,revision:A.refine(e=>e>0).optional(),messageId:l().min(1).optional()});function X(e){let t=new URLSearchParams(e);if(![`owner`,`sessionKey`,`revision`,`messageId`].some(e=>t.has(e)))return{};let n=Y.safeParse({owner:t.get(`owner`),key:t.get(`sessionKey`),...t.has(`revision`)?{revision:Number(t.get(`revision`))}:{},...t.has(`messageId`)?{messageId:t.get(`messageId`)}:{}});return n.success?{target:n.data}:{error:`对话链接不完整或已损坏。`}}var Z=t();function Q({members:e,refresh:t,selected:n,onOwner:r,onSession:i}){let[a,o]=(0,L.useState)(()=>new Set(n?.key?[n.owner]:[])),[s,c]=(0,L.useState)(e[0]?.id??``);return(0,Z.jsx)(`div`,{role:`tree`,"aria-label":`成员对话`,"data-testid":`session-tree`,onKeyDown:I,children:[...e].sort((e,t)=>F(e.id,t.id)).map(e=>(0,Z.jsxs)(`div`,{role:`none`,children:[(0,Z.jsxs)(x,{type:`button`,role:`treeitem`,"aria-level":1,"aria-expanded":a.has(e.id),"aria-selected":n?.owner===e.id&&!n.key,className:`tree-item tree-folder`,style:{"--tree-level":1},tabIndex:s===e.id?0:-1,"data-testid":`session-owner`,"data-owner-id":e.id,onFocus:()=>c(e.id),onClick:()=>{o(t=>{let n=new Set(t);return n.has(e.id)?n.delete(e.id):n.add(e.id),n}),r(e.id)},leading:(0,Z.jsx)(`span`,{className:`tree-chevron ${a.has(e.id)?`expanded`:``}`,children:(0,Z.jsx)(O,{name:`chevron`,size:`small`})}),children:[(0,Z.jsx)(O,{name:`files`}),(0,Z.jsx)(`span`,{className:`tree-name`,title:e.id,children:e.id})]}),a.has(e.id)&&(0,Z.jsx)($,{owner:e.id,selected:n,onSession:i,focused:s,onFocus:c},`${e.id}/${t}`)]},e.id))})}function $({owner:e,selected:t,onSession:n,focused:i,onFocus:a}){let{request:o,projectId:s}=D(),c=(0,L.useCallback)(t=>o(`sessions?${new URLSearchParams({owner:e,limit:`50`,order:`updated`})}`,K,{signal:t}),[e,o]),l=r(c,15e3,f(s,`session-tree`,e)),[u,m]=(0,L.useState)(),[g,_]=(0,L.useState)(!1),[v,y]=(0,L.useState)(``),b=(0,L.useRef)(null);(0,L.useEffect)(()=>()=>b.current?.abort(),[]);let S=u?u.nextCursor:l.data?.nextCursor;return(0,Z.jsxs)(`div`,{role:`group`,"aria-busy":l.loading||g,children:[(0,Z.jsx)(h,{error:!0,children:l.error||v}),l.error&&(0,Z.jsx)(`button`,{onClick:()=>void l.reload(),children:`重试`}),l.loading&&!l.data&&(0,Z.jsx)(`span`,{className:`tree-status`,role:`status`,children:`正在加载…`}),[...new Map([...u?.sessions??[],...l.data?.sessions??[]].map(e=>[e.sessionKey,e])).values()].sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt)||e.sessionKey.localeCompare(t.sessionKey)).map(r=>(0,Z.jsxs)(x,{type:`button`,role:`treeitem`,"aria-level":2,"aria-selected":t?.owner===e&&t.key===r.sessionKey,className:`tree-item`,style:{"--tree-level":2},tabIndex:i===`${e}/${r.sessionKey}`?0:-1,"data-testid":`session-row`,"data-owner-id":e,"data-session-key":r.sessionKey,title:p(r.title||r.nativeId),onFocus:()=>a(`${e}/${r.sessionKey}`),onClick:()=>n({owner:e,key:r.sessionKey,title:r.title||r.nativeId}),leading:(0,Z.jsx)(`span`,{className:`tree-chevron`}),children:[(0,Z.jsx)(O,{name:`sessions`}),(0,Z.jsx)(`span`,{className:`tree-name`,children:p(r.title||r.nativeId)})]},r.sessionKey)),S!=null&&(0,Z.jsx)(`button`,{className:`tree-action`,"data-testid":`session-tree-more`,disabled:g,onClick:async()=>{_(!0),y(``);let t=new AbortController;b.current=t;try{let n=await o(`sessions?${new URLSearchParams({owner:e,after:String(S),limit:`50`,order:`updated`})}`,K,{signal:t.signal});m(e=>({sessions:[...e?.sessions??[],...n.sessions],nextCursor:n.nextCursor}))}catch(e){t.signal.aborted||y(d(e))}finally{t.signal.aborted||_(!1)}},children:`加载更多`})]})}function ee({info:e}){let[t,n]=(0,L.useState)(!1);return(0,Z.jsxs)(`details`,{className:`session-handoff`,onToggle:e=>n(e.currentTarget.open),children:[(0,Z.jsx)(`summary`,{children:`交接说明`}),t&&(0,Z.jsx)(te,{info:e})]})}function te({info:e}){let{request:t}=D(),n=`sessions/${encodeURIComponent(e.owner)}/${e.sessionKey}`,a=(0,L.useCallback)(e=>t(`${n}/analysis/handoff`,H,{signal:e}),[t,n]),o=r(a,5e3),s=i(),[c,l]=(0,L.useState)(!1),[u,f]=(0,L.useState)(``),p=o.data,m=c||p?.status===`queued`||p?.status===`running`,_=p?.result&&`markdown`in p.result?p.result.markdown:void 0;return(0,Z.jsxs)(`div`,{className:`stack`,"data-testid":`session-handoff`,children:[(0,Z.jsx)(h,{error:!0,children:u||o.error}),p&&(0,Z.jsxs)(`div`,{className:`inline-actions`,children:[(!_||p.stale)&&(0,Z.jsx)(`button`,{"data-testid":`session-handoff-generate`,disabled:m||!p.available,onClick:async()=>{l(!0),f(``);try{await t(`${n}/handoff`,H,{method:`POST`,signal:s}),await o.reload()}catch(e){s.aborted||f(d(e))}finally{s.aborted||l(!1)}},children:m?`正在整理…`:p.status===`failed`?`重新生成`:_?`更新交接说明`:`生成交接说明`}),!p.available&&(0,Z.jsx)(`small`,{children:`请先配置项目模型接入点`}),p.status===`failed`&&(0,Z.jsx)(`small`,{children:`整理未完成,可重试`}),p.stale&&(0,Z.jsx)(`small`,{children:`对话已有新内容`}),p.currentRevision!==e.revision&&(0,Z.jsx)(`small`,{children:`交接说明使用最新对话;当前阅读的是历史原文`})]}),_&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`small`,{children:[`基于版本 `,p.sourceRevision,` · `,(0,Z.jsx)(g,{value:p.generatedAt})]}),(0,Z.jsx)(`div`,{className:`markdown`,"data-testid":`session-handoff-body`,children:(0,Z.jsx)(N,{children:_})})]})]})}function ne({members:e}){let{request:t,projectId:n,api:i}=D(),o=(0,L.useCallback)(async e=>{let[n,r]=await Promise.all([t(`sessions/stats`,q,{signal:e}),i.members(e)]);return{...n,members:r.members}},[t,i]),s=r(o,!0,f(n,`session-stats`)),[c,l]=(0,L.useState)(``),[u,d]=(0,L.useState)(``),[m,g]=(0,L.useState)(0),[_]=(0,L.useState)(()=>X(location.search)),[v,y]=(0,L.useState)(_.target),[b,x]=(0,L.useState)(_.target),[w,E]=(0,L.useState)(_.error??``),[O,A]=(0,L.useState)(``),j=(0,L.useRef)(null),M=v?.key?v.title?`搜索对话:${p(v.title)}`:`搜索当前对话`:v?`搜索:${v.owner} 的对话内容`:``,N=()=>{y(void 0),A(``),F(),j.current?.focus()};function F(){if(!b?.messageId)return;let{messageId:e,...t}=b;x(t),history.replaceState(null,``,S(P(n,t.owner,t.key,t)))}let I=(0,L.useCallback)(e=>{y(t=>t?.owner===e.owner&&t.key===e.sessionKey&&t.title!==e.title?{...t,title:e.title}:t)},[]);(0,L.useEffect)(()=>{let e=()=>{let e=X(location.search);x(e.target),y(e.target),E(e.error??``),d(``),l(``),A(``)};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);let R=(e,t=``)=>{x(e),y(e),d(``),A(t),E(``),history.replaceState(null,``,S(P(n,e.owner,e.key,e)))};return(0,Z.jsxs)(`div`,{className:`split-layout file-explorer session-explorer`,children:[(0,Z.jsxs)(`section`,{className:`file-tree-pane`,"aria-label":`${a.sessions}目录`,children:[(0,Z.jsx)(T,{title:a.sessions,icon:`sessions`,count:(0,Z.jsx)(`span`,{"data-testid":`session-total`,children:s.data?.totalSessions??`—`}),children:(0,Z.jsx)(k,{icon:`refresh`,label:`刷新${a.sessions}`,"data-testid":`sessions-refresh`,disabled:s.loading,onClick:()=>{s.reload(),g(e=>e+1)}})}),(0,Z.jsx)(h,{error:!0,children:s.error}),(0,Z.jsx)(Q,{members:(s.data?.members??e).filter(e=>e.hasSessions),refresh:m,selected:v,onOwner:e=>{y({owner:e}),x(void 0),d(``),A(``),E(``),history.replaceState(null,``,S(`/projects/${encodeURIComponent(n)}/sessions`))},onSession:R})]}),(0,Z.jsxs)(`section`,{className:`session-reader`,"aria-label":`对话内容与搜索`,children:[(0,Z.jsx)(`div`,{className:`session-reader-content`,children:w?(0,Z.jsx)(h,{error:!0,children:w}):u?(0,Z.jsx)(re,{query:u,refresh:m,scope:{...v?{owner:v.owner}:{},...v?.key?{sessionKey:v.key}:{}},onSelect:e=>R(e,u)},`${u}/${v?.owner??``}/${v?.key??``}`):b?(0,Z.jsx)(ie,{selection:b,highlight:O,onLoaded:I,onLatest:()=>R({owner:b.owner,key:b.key})},`${b.owner}/${b.key}/${b.revision}/${m}`):(0,Z.jsx)(C,{mascot:!0,title:`选择对话开始阅读`,description:`也可以在下方搜索会话库内容。`})}),(0,Z.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`session-search-form`,onSubmit:e=>{e.preventDefault(),d(c.trim()),A(``),E(``),g(e=>e+1)},children:[v&&(0,Z.jsxs)(`button`,{type:`button`,className:`search-scope-chip`,"data-testid":`session-search-scope`,title:`清除搜索范围`,"aria-label":`清除范围:${M}`,onClick:N,children:[(0,Z.jsx)(`span`,{className:`scope-label`,children:M}),(0,Z.jsx)(`span`,{"aria-hidden":`true`,children:`×`})]}),(0,Z.jsxs)(`div`,{className:`session-search-input-row`,children:[(0,Z.jsx)(`input`,{ref:j,"aria-label":`搜索对话`,"data-testid":`session-query`,value:c,maxLength:500,placeholder:`搜索会话库内容`,onChange:e=>l(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!c&&v&&(e.preventDefault(),N())}}),(u||c||O)&&(0,Z.jsx)(k,{icon:`close`,label:`清空搜索`,"data-testid":`session-search-clear`,onClick:()=>{l(``),d(``),A(``),F(),j.current?.focus()}}),(0,Z.jsx)(k,{icon:`search`,type:`submit`,label:`搜索`,"data-testid":`session-search`,disabled:!c.trim()})]})]})]})]})}function re({query:e,refresh:t,scope:n,onSelect:i}){let{request:a}=D(),[o,s]=(0,L.useState)(0),c=(0,L.useCallback)(t=>a(`sessions/search?${new URLSearchParams({q:e,after:String(o),limit:`30`,order:`updated`,...n.owner?{owner:n.owner}:{},...n.sessionKey?{sessionKey:n.sessionKey}:{}})}`,J,{signal:t}),[a,e,o,t,n.owner,n.sessionKey]),l=r(c);return(0,Z.jsxs)(`section`,{className:`session-results stack`,"aria-label":`搜索结果`,"aria-busy":l.loading,children:[(0,Z.jsx)(h,{error:!0,children:l.error}),l.error&&(0,Z.jsx)(`button`,{onClick:()=>void l.reload(),children:`重试`}),l.loading&&(0,Z.jsx)(`p`,{role:`status`,children:`正在搜索…`}),!l.loading&&l.data?.matches.map(t=>(0,Z.jsxs)(`button`,{className:`session-item`,"data-testid":`session-match`,"data-message-id":t.messageId,onClick:()=>i({owner:t.owner,key:t.sessionKey,revision:t.revision,messageId:t.messageId,title:t.title}),children:[(0,Z.jsx)(`strong`,{children:p(t.title)}),(0,Z.jsxs)(`small`,{children:[t.owner,` · `,t.role===`user`?`用户`:`助手`]}),(0,Z.jsx)(`span`,{className:`session-excerpt`,children:(0,Z.jsx)(j,{value:M(t.snippet,e),query:e})})]},`${t.owner}:${t.sessionKey}:${t.revision}:${t.messageId}`)),!l.loading&&l.data?.matches.length===0&&(0,Z.jsx)(`p`,{className:`empty`,children:`没有找到匹配的对话`}),l.data?.nextCursor!=null&&(0,Z.jsx)(`button`,{"data-testid":`sessions-next`,disabled:l.loading,onClick:()=>s(l.data.nextCursor),children:`下一页`}),o>0&&(0,Z.jsx)(`button`,{disabled:l.loading,onClick:()=>s(0),children:`返回第一页`})]})}function ie({selection:e,highlight:t,onLoaded:n,onLatest:i}){let{request:a}=D(),o=(0,L.useCallback)(async t=>{try{return await a(`sessions/${encodeURIComponent(e.owner)}/${e.key}${e.revision===void 0?``:`?revision=${e.revision}`}`,G,{signal:t})}catch(e){throw e instanceof w&&e.code===`SESSION_NOT_FOUND`?Error(`找不到这条对话或引用的版本,原链接可能已失效。`):e}},[a,e.owner,e.key,e.revision]),s=r(o,5e3);return(0,L.useEffect)(()=>{s.data&&n(s.data)},[s.data,n]),(0,Z.jsxs)(`section`,{className:`session-conversation stack`,"data-testid":`session-detail`,children:[(0,Z.jsx)(h,{error:!0,children:s.error}),s.error&&(0,Z.jsx)(`button`,{onClick:()=>void s.reload(),children:`重试`}),s.loading&&!s.data&&(0,Z.jsx)(`p`,{role:`status`,children:`正在读取对话…`}),s.data&&(0,Z.jsx)(ae,{info:s.data,messageId:e.messageId,highlight:t,pinned:e.revision!==void 0,onLatest:i},s.data.blob.sha256)]})}function ae({info:e,messageId:t,highlight:n,pinned:i,onLatest:a}){let{readTextBlob:o,projectId:s}=D(),c=(0,L.useCallback)(async t=>W.parse(JSON.parse(await o(e.blob,t))),[e.blob.sha256,e.blob.size]),l=r(c),u=(0,L.useRef)(null);return(0,L.useEffect)(()=>{l.data&&t&&u.current?.scrollIntoView({block:`center`})},[l.data,t]),(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`header`,{className:`conversation-header`,children:[(0,Z.jsx)(`h2`,{className:`session-title`,children:p(e.title||e.nativeId)}),(0,Z.jsxs)(`p`,{children:[e.owner,` · `,e.agent,` · `,e.messageCount,` 条消息`]}),(0,Z.jsxs)(`small`,{children:[(0,Z.jsx)(g,{value:e.updatedAt}),i&&(0,Z.jsxs)(Z.Fragment,{children:[` `,`· 引用版本 `,e.revision,` ·`,` `,(0,Z.jsx)(`a`,{href:S(P(s,e.owner,e.sessionKey)),onClick:e=>{e.preventDefault(),a()},children:`查看最新`})]})]}),e.overview&&(0,Z.jsx)(`p`,{"data-testid":`session-summary`,children:e.overview.summary}),e.overview?.stale&&(0,Z.jsx)(`small`,{children:`摘要待更新`})]}),(0,Z.jsx)(ee,{info:e}),(0,Z.jsx)(h,{error:!0,children:l.error}),l.error&&(0,Z.jsx)(`button`,{onClick:()=>void l.reload(),children:`重新读取`}),l.loading&&(0,Z.jsx)(`p`,{role:`status`,children:`正在读取对话…`}),l.data&&(0,Z.jsxs)(Z.Fragment,{children:[t&&!l.data.messages.some(e=>e.id===t)&&(0,Z.jsx)(h,{children:`该版本中找不到引用的消息,已打开对话原文。`}),(0,Z.jsx)(`div`,{className:`session-messages`,children:l.data.messages.map(e=>(0,Z.jsxs)(`article`,{className:`session-message ${e.role} ${e.id===t?`matched`:``}`,"data-testid":`session-message`,"data-message-id":e.id,ref:e.id===t?u:void 0,children:[(0,Z.jsx)(`div`,{className:`message-role`,children:e.role===`user`?`用户`:`助手`}),(0,Z.jsx)(`div`,{className:`markdown`,children:(0,Z.jsx)(N,{highlight:n,children:e.text})})]},e.id))})]})]})}export{ne as Sessions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$ as e,A as t,D as n,M as r,O as i,S as a,c as o,d as s,s as c,u as l,v as u}from"./index-DQsx-e5d.js";var d=e(),f=new Intl.Collator(`zh-CN`,{numeric:!0,sensitivity:`base`});function p(e,t){return f.compare(e,t)||(e<t?-1:+(e>t))}var m=t();function h(e){let t=e.target.closest(`[role="treeitem"]`);if(!t)return;let n=[...e.currentTarget.querySelectorAll(`[role="treeitem"]`)],r=n.indexOf(t),i=Number(t.getAttribute(`aria-level`)),a;switch(e.key){case`ArrowDown`:a=n[r+1];break;case`ArrowUp`:a=n[r-1];break;case`Home`:a=n[0];break;case`End`:a=n.at(-1);break;case`ArrowRight`:t.getAttribute(`aria-expanded`)===`false`?t.click():Number(n[r+1]?.getAttribute(`aria-level`))>i&&(a=n[r+1]);break;case`ArrowLeft`:t.getAttribute(`aria-expanded`)===`true`?t.click():a=n.slice(0,r).reverse().find(e=>Number(e.getAttribute(`aria-level`))<i);break;default:return}e.preventDefault(),a?.focus()}var g=(e,t)=>`${e}/${t}`,_=e=>({"--tree-level":e});function v({members:e,...t}){let[n,r]=(0,d.useState)(`folder:${g(e[0]?.id??``,``)}`);return(0,m.jsx)(`div`,{role:`tree`,"aria-label":`工作区文件`,"data-testid":`workspace-tree`,onKeyDown:h,children:(0,m.jsx)(b,{owner:c,path:``,level:1,members:e.filter(e=>e.hasFiles),context:{...t,focused:n,onFocus:r}})})}function y({owner:e,path:t,level:n,context:r}){let i=r.expanded.has(g(e,t)),a=`folder:${g(e,t)}`;return(0,m.jsxs)(`div`,{role:`none`,children:[(0,m.jsxs)(s,{type:`button`,role:`treeitem`,className:`tree-item tree-folder`,style:_(n),"aria-label":t||e,"aria-level":n,"aria-expanded":i,"aria-selected":r.selected?.kind===`directory`&&r.selected.owner===e&&r.selected.path===t,tabIndex:r.focused===a?0:-1,"data-testid":`directory-row`,"data-owner-id":e,"data-directory-path":t,onFocus:()=>r.onFocus(a),onClick:()=>r.onToggle(e,t),leading:(0,m.jsx)(`span`,{className:`tree-chevron ${i?`expanded`:``}`,children:(0,m.jsx)(u,{name:`chevron`,size:`small`})}),children:[(0,m.jsx)(u,{name:`files`}),(0,m.jsx)(`span`,{className:`tree-name`,children:t.split(`/`).at(-1)||e})]}),i&&(0,m.jsx)(b,{owner:e,path:t,level:n+1,context:r})]})}function b({owner:e,path:t,level:c,context:f,members:h=[]}){let{api:v,projectId:b}=l(),x=(0,d.useCallback)(n=>v.tree(e,t,void 0,``,n),[e,t]),S=n(x,!1,i(b,`file-tree`,e,t)),[C,w]=(0,d.useState)(),[T,E]=(0,d.useState)(!1),[D,O]=(0,d.useState)(``),k=(0,d.useRef)(null);(0,d.useEffect)(()=>()=>k.current?.abort(),[]);let A=C?.revision===S.data?.revision?C:void 0,j=A?A.nextCursor:S.data?.nextCursor;async function M(){if(!j||!S.data||T)return;E(!0),O(``);let n=new AbortController;k.current=n;try{let r=await v.tree(e,t,S.data.revision,j,n.signal);n.signal.aborted||w({...r,entries:[...A?.entries??[],...r.entries]})}catch(e){n.signal.aborted||O(r(e))}finally{n.signal.aborted||E(!1)}}let N=[...(S.data?.entries??[]).filter(e=>!o(e.path)),...(A?.entries??[]).filter(e=>!o(e.path))],P=f.revealed;if(P?.owner===e&&!o(P.path)&&(!t||P.path.startsWith(t+`/`))){let e=t?P.path.slice(t.length+1):P.path,n=e.indexOf(`/`),r=n<0?P.path:[t,e.slice(0,n)].filter(Boolean).join(`/`);N.some(e=>e.path===r)||N.push(n<0?{...P.file,kind:`file`}:{kind:`directory`,path:r})}let F=[...N.map(t=>({...t,owner:e})),...h.map(e=>({kind:`directory`,path:``,owner:e.id}))].sort((e,t)=>e.kind===t.kind?p(e.path.split(`/`).at(-1)||e.owner,t.path.split(`/`).at(-1)||t.owner):e.kind===`directory`?-1:1);return(0,m.jsxs)(`div`,{role:`group`,"aria-label":g(e===`_project`?`workspaces`:e,t),"aria-busy":S.loading||T,children:[S.loading&&(0,m.jsx)(`p`,{className:`tree-status`,role:`status`,children:`正在加载…`}),(0,m.jsx)(a,{error:!0,children:S.error||D}),S.error&&(0,m.jsx)(`button`,{className:`tree-action`,onClick:()=>void S.reload(),children:`重试`}),F.map(t=>t.kind===`directory`?(0,m.jsx)(y,{owner:t.owner,path:t.path,level:c,context:f},g(t.owner,t.path)):(0,m.jsxs)(s,{type:`button`,role:`treeitem`,className:`tree-item`,style:_(c),"aria-label":t.path,"aria-level":c,"aria-selected":f.selected?.kind===`file`&&f.selected.owner===e&&f.selected.path===t.path,tabIndex:f.focused===`file:${g(e,t.path)}`?0:-1,"data-testid":`file-row`,"data-owner-id":e,"data-file-path":t.path,onFocus:()=>f.onFocus(`file:${g(e,t.path)}`),onClick:()=>f.onSelect(e,t.path),leading:(0,m.jsx)(`span`,{className:`tree-chevron`}),children:[(0,m.jsx)(u,{name:`file`}),(0,m.jsx)(`span`,{className:`tree-name`,children:t.path.split(`/`).at(-1)})]},t.path)),j&&(0,m.jsx)(`button`,{className:`tree-action`,"data-testid":`files-load-more`,disabled:T,onClick:()=>void M(),children:T?`正在加载…`:`加载更多`})]})}export{p as i,g as n,h as r,v as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{L as e}from"./index-DQsx-e5d.js";function t(t,n){if(!n||/^(?:[a-z][a-z0-9+.-]*:|\/)/i.test(n))return null;try{let r=n.split(/[?#]/,1)[0],i=r?t.split(`/`).slice(0,-1):t.split(`/`);for(let e of r.split(`/`)){let t=decodeURIComponent(e);if(t&&t!==`.`){if(t===`..`){if(!i.length)return null;i.pop()}else{if(t.includes(`/`)||t.includes(`\\`))return null;i.push(t)}}}return{path:i.length?e.parse(i.join(`/`)):``,directory:r.endsWith(`/`),anchor:n.includes(`#`)?decodeURIComponent(n.slice(n.indexOf(`#`)+1)):``}}catch{return null}}export{t};
|