@teammy/server 0.1.18 → 0.1.20
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/dist/main.js +395 -271
- package/dist/web/assets/Assistant-K7R3l1Y9.js +1 -0
- package/dist/web/assets/Dashboard-CrasjWgz.js +1 -0
- package/dist/web/assets/Files-DuQt5JVa.js +1 -0
- package/dist/web/assets/{HtmlPreview-C4jbdvbl.js → HtmlPreview-mlq3f457.js} +1 -1
- package/dist/web/assets/{Markdown-2LnVpzw0.js → Markdown-s6-IMB4A.js} +4 -4
- package/dist/web/assets/Materials-a3rXNw0F.js +6 -0
- package/dist/web/assets/Memory-Ciq2tU2X.js +1 -0
- package/dist/web/assets/Sessions-BlLNPG-_.js +1 -0
- package/dist/web/assets/WorkspaceTree-tH2uUcnp.js +1 -0
- package/dist/web/assets/{file-links-DhXbS2mn.js → file-links-BArHrikX.js} +1 -1
- package/dist/web/assets/{index-BRdnk3k3.js → index-CfWIg76q.js} +6 -6
- 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-C1zIXX0T.js +0 -1
- package/dist/web/assets/Dashboard-CFXVQzsu.js +0 -1
- package/dist/web/assets/Files-ZsI66NX_.js +0 -1
- package/dist/web/assets/Materials-IT4hsXHL.js +0 -6
- package/dist/web/assets/Sessions-B_9xi3yE.js +0 -1
- package/dist/web/assets/WorkspaceTree-CU784GTC.js +0 -1
- /package/dist/web/assets/{Files-C-z-5rpe.css → Memory-C-z-5rpe.css} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{$ as e,A as t,B as n,C as r,F as i,G as a,J as o,M as s,P as c,Q as l,U as u,V as d,W as f,X as p,Y as m,b as h,d as g,et as _,f as v,k as y,nt as b,p as x,tt as S,v as C,w,x as T,y as E}from"./index-CfWIg76q.js";import{n as D,r as O,t as k}from"./Markdown-s6-IMB4A.js";import{i as ee,r as te}from"./WorkspaceTree-tH2uUcnp.js";import{t as A}from"./HtmlPreview-mlq3f457.js";function j(e){return _(u,e)}var M=S(),N=p().regex(/^R\d{6,}$/),P=m({name:p().min(1),sha256:n,size:o().int().nonnegative()}),F=l().refine(e=>/^https?:\/\//i.test(e),`Use an HTTP or HTTPS URL.`);m({operationId:e(),title:p().trim().default(``),text:p().optional(),url:F.optional(),originals:a(P).default([])}).strict().refine(e=>!!e.text?.trim()||!!e.url||e.originals.length>0,`Provide text, a link or a file.`),m({expectedRevision:d,title:p().trim().min(1).optional(),url:F.nullable().optional(),content:p().optional(),summary:p().optional(),sourceVersion:p().optional(),contentDate:p().optional(),originals:a(P).optional()}).strict();var I=m({id:N,projectId:p(),title:p(),submittedBy:p(),createdAt:p(),revision:d,source:m({kind:f([`web`,`chat`,`group`]),url:p().nullable(),groupId:p().optional(),messageId:p().optional(),sourceVersion:p().optional(),contentDate:p().optional()}),originals:a(P),content:p().nullable(),summary:p().nullable(),state:f([`waiting`,`running`,`ready`,`failed`]),error:p().nullable(),url:p()}),L=m({materials:a(I),nextCursor:o().nullable()});m({query:p().trim().min(1),scope:f([`all`,`workspace`,`materials`]).default(`all`),materialId:N.optional(),originalHash:n.optional(),after:p().default(``),limit:j().int().min(1).max(200).default(30)}).strict();var R=m({items:a(m({key:p(),kind:f([`workspace`,`materials`]),title:p(),snippet:p(),url:p(),path:p()})),nextCursor:p().nullable()}),z=s();function B(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 V(){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 H(){let{request:e,projectId:n}=v(),[r,i]=(0,M.useState)(V),[a,o]=(0,M.useState)(r),[s,l]=(0,M.useState)(()=>new Set(r?[r.id]:[])),[u,d]=(0,M.useState)(!1),[f,p]=(0,M.useState)(``),[m,_]=(0,M.useState)(``),[S,E]=(0,M.useState)(``),[D,O]=(0,M.useState)([]),[A,j]=(0,M.useState)(),[N,P]=(0,M.useState)(!1),[F,R]=(0,M.useState)(``),H=(0,M.useRef)(null),U=(0,M.useCallback)(t=>e(`materials`,L,{signal:t}),[e]),W=y(U,5e3,t(n,`materials`)),G=(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=y(G,5e3),q=K.data?.id===r?.id?K.data:null,J=[...new Map([...D,...W.data?.materials??[],...q?[q]:[]].map(e=>[e.id,e])).values()].sort((e,t)=>t.createdAt.localeCompare(e.createdAt)||t.id.localeCompare(e.id)),Y=A===void 0?W.data?.nextCursor:A;function X(e,t=``){i(e),o(e),_(``),E(t),d(!1),l(t=>new Set([...t,e.id])),history.replaceState(null,``,b(`/projects/${n}/materials?${new URLSearchParams({...e})}`))}(0,M.useEffect)(()=>{let e=()=>{let e=V();i(e),o(e),_(``),p(``),E(``),d(!1),e&&l(t=>new Set([...t,e.id]))};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);async function ae(){if(Y&&!N){P(!0),R(``);try{let t=await e(`materials?before=${Y}`,L);O(e=>[...e,...t.materials]),j(t.nextCursor)}catch(e){R(c(e))}finally{P(!1)}}}let Z=J.find(e=>e.id===a?.id),Q=Z?.originals.find(e=>e.sha256===a?.original)?.name??Z?.title??`当前资料`;function $(){o(void 0),E(``),H.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)(g,{title:`资料`,icon:`materials`,children:(0,z.jsx)(T,{icon:`plus`,label:`新增资料`,onClick:()=>{d(!0),R(``)}})}),(0,z.jsx)(w,{error:!0,children:W.error||F}),W.data?J.length===0?(0,z.jsx)(`p`,{className:`tree-status`,children:`暂无资料`}):(0,z.jsx)(`div`,{role:`tree`,"aria-label":`项目资料`,onKeyDown:te,children:J.map(e=>(0,z.jsxs)(`div`,{role:`none`,children:[(0,z.jsxs)(x,{role:`treeitem`,"aria-level":1,"aria-expanded":s.has(e.id),"aria-selected":!u&&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=s.has(e.id);X({id:e.id}),t&&l(t=>{let n=new Set(t);return n.delete(e.id),n})},leading:(0,z.jsx)(`span`,{className:`tree-chevron ${s.has(e.id)?`expanded`:``}`,children:(0,z.jsx)(h,{name:`chevron`,size:`small`})}),children:[(0,z.jsx)(h,{name:`files`}),(0,z.jsx)(`span`,{className:`tree-name`,children:e.title})]}),s.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)(x,{role:`treeitem`,"aria-level":2,"aria-selected":!u&&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)(h,{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:N,onClick:()=>void ae(),children:N?`加载中…`:`加载更多`})]}),(0,z.jsxs)(`section`,{className:`session-reader`,"aria-label":`资料内容与搜索`,children:[(0,z.jsx)(`div`,{className:`session-reader-content`,children:u?(0,z.jsx)(ie,{onCancel:()=>d(!1),onSaved:e=>{X({id:e}),W.reload()}}):m?(0,z.jsx)(ne,{query:m,scope:a,onSelect:e=>X(e,m)},`${m}/${a?.id}/${a?.original}`):r?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(w,{error:!0,children:K.error}),q?r.original?(0,z.jsx)(re,{material:q,hash:r.original,highlight:S},`${q.id}:${r.original}`):(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)(w,{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=>R(c(e))),children:`重试整理`}),q.content?(0,z.jsx)(`div`,{className:`markdown`,children:(0,z.jsx)(k,{highlight:S,children:B(q)})}):(0,z.jsx)(`p`,{className:`muted`,children:`正文尚未整理,可以先查看左侧原件。`})]}):(0,z.jsx)(`p`,{role:`status`,children:`加载中…`})]}):(0,z.jsx)(C,{mascot:!0,title:`选择资料开始阅读`,description:`也可以在下方搜索资料内容。`})}),!u&&(0,z.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`material-search-form`,onSubmit:e=>{e.preventDefault(),_(f.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:H,"aria-label":`搜索资料`,placeholder:`搜索资料内容`,value:f,onChange:e=>p(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!f&&a&&(e.preventDefault(),$())}}),(m||f||S)&&(0,z.jsx)(T,{icon:`close`,label:`清空搜索`,onClick:()=>{p(``),_(``),E(``),H.current?.focus()}}),(0,z.jsx)(T,{icon:`search`,type:`submit`,label:`搜索`,disabled:!f.trim()})]})]})]})]})}function ne({query:e,scope:t,onSelect:n}){let{request:r}=v(),[i,a]=(0,M.useState)(``),o=(0,M.useCallback)(n=>r(`resources/search?${new URLSearchParams({query:e,scope:`materials`,after:i,...t?{materialId:t.id}:{},...t?.original?{originalHash:t.original}:{}})}`,R,{signal:n}),[r,e,t?.id,t?.original,i]),s=y(o);return(0,z.jsxs)(`section`,{className:`session-results stack`,"aria-label":`搜索结果`,children:[(0,z.jsx)(w,{error:!0,children:s.error}),s.loading?(0,z.jsx)(`p`,{role:`status`,children:`正在搜索…`}):s.data?.items.length===0?(0,z.jsx)(`p`,{className:`empty`,children:`没有找到匹配的资料`}):s.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;n({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)),s.data?.nextCursor&&(0,z.jsx)(`button`,{disabled:s.loading,onClick:()=>a(s.data.nextCursor),children:`下一页`})]})}function re({material:e,hash:n,highlight:r}){let{projectId:i}=v(),a=e.originals.find(e=>e.sha256===n),o=b(`/api/v1/projects/${i}/materials/${e.id}/originals/${n}?revision=${e.revision}`),[s,c]=(0,M.useState)(!1),l=(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]),u=y(l,!1,t(i,`material-original`,n));if(!a)return(0,z.jsx)(w,{error:!0,children:`找不到此原件。`});let d=/\.(md|markdown)$/i.test(a.name),f=/\.html?$/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:[(d||f)&&(0,z.jsx)(T,{icon:s?`preview`:`code`,label:s?`切换为预览`:`切换为原文`,"aria-pressed":s,onClick:()=>c(!s)}),(0,z.jsx)(`a`,{className:`icon-button`,"aria-label":`下载原件`,title:`下载原件`,href:o,download:a.name,children:(0,z.jsx)(h,{name:`download`})})]})]}),(0,z.jsx)(w,{error:!0,children:u.error}),u.loading?(0,z.jsx)(`p`,{role:`status`,children:`加载中…`}):u.data===null?(0,z.jsx)(`p`,{className:`muted`,children:`此格式请下载后查看。`}):u.data!==void 0&&(0,z.jsx)(`div`,{className:`preview-body${f&&!s?` preview-body-html`:``}`,"data-testid":`material-original-content`,children:f&&!s?(0,z.jsx)(A,{url:o,name:a.name}):d&&!s?(0,z.jsx)(`article`,{className:`markdown`,children:(0,z.jsx)(k,{highlight:r,children:u.data})}):(0,z.jsx)(`pre`,{className:`raw`,children:(0,z.jsx)(D,{value:u.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 ie({onSaved:e,onCancel:t}){let{request:n,projectId:a}=v(),[o,s]=(0,M.useState)([]),[l,u]=(0,M.useState)(),[d,f]=(0,M.useState)(!1),[p,m]=(0,M.useState)(``),g=(0,M.useRef)(null),_=(0,M.useRef)(i()),y=(0,M.useRef)(new Map);function x(e){s(e),_.current=i(),m(``)}async function S(){f(!0),m(``);try{let t=[];for(let[e,n]of o.entries()){let r=y.current.get(n.id);if(!r){let t=n.kind===`file`?n.file.name:`${W(n.text)}.txt`,i=await fetch(b(`/api/v1/projects/${a}/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 i.json();if(!i.ok)throw Error(o.error?.message??`第 ${e+1} 项上传失败。`);r={name:t,sha256:o.sha256,size:o.size},y.current.set(n.id,r)}t.push(r)}let r=o.length===1&&o[0]?.kind===`text`?o[0].text.trim():``,i;try{let e=new URL(r);[`http:`,`https:`].includes(e.protocol)&&(i=e.href)}catch{}e((await n(`materials`,I,{method:`POST`,body:{operationId:_.current,originals:t,...i?{url:i}:{}}})).id)}catch(e){m(c(e))}finally{f(!1)}}return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`form`,{className:`material-form`,onSubmit:e=>{e.preventDefault(),S()},children:[(0,z.jsx)(`h1`,{children:`新增资料`}),(0,z.jsx)(`p`,{className:`muted`,children:`上传附件到项目,以便于Tim进行理解`}),(0,z.jsx)(w,{error:!0,children:p}),(0,z.jsxs)(`fieldset`,{disabled:d,children:[(0,z.jsxs)(`div`,{className:`attachment-grid`,children:[o.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:()=>u({id:e.id,text:e.text}),children:[(0,z.jsx)(h,{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)(h,{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),x(o.filter(t=>t.id!==e.id))}})]},e.id)),(0,z.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>u({text:``}),children:[(0,z.jsx)(h,{name:`addText`}),(0,z.jsx)(`span`,{children:`添加文本/链接`})]}),(0,z.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>g.current?.click(),children:[(0,z.jsx)(h,{name:`addFile`}),(0,z.jsx)(`span`,{children:`添加文件`})]})]}),(0,z.jsx)(`input`,{ref:g,type:`file`,multiple:!0,hidden:!0,"aria-label":`原始文件`,onChange:e=>{x([...o,...[...e.target.files??[]].map(e=>({id:i(),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:!o.length,children:d?`上传中…`:`提交资料`})]})]})]}),l&&(0,z.jsx)(r,{id:`material-text-editor`,title:`添加文本/链接`,onClose:()=>u(void 0),children:(0,z.jsxs)(`form`,{className:`stack`,onSubmit:e=>{if(e.preventDefault(),!l.text.trim())return;let t={id:l.id??i(),kind:`text`,text:l.text};y.current.delete(t.id),x(l.id?o.map(e=>e.id===l.id?t:e):[...o,t]),u(void 0)},children:[(0,z.jsx)(E,{id:`material-attachment-text`,label:`文本或链接`,children:(0,z.jsx)(`textarea`,{autoFocus:!0,rows:8,value:l.text,onChange:e=>u({...l,text:e.target.value}),placeholder:`粘贴文本或网页链接`})}),(0,z.jsx)(`div`,{className:`actions`,children:(0,z.jsx)(`button`,{type:`submit`,className:`primary`,disabled:!l.text.trim(),children:l.id?`保存`:`添加`})})]})})]})}export{H as Materials};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$ as e,A as t,F as n,G as r,J as i,K as a,M as o,P as s,T as c,W as l,X as u,Y as d,b as f,f as p,k as m,tt as h,w as g,x as _}from"./index-CfWIg76q.js";var v=h(),y=u().trim().min(1).max(120).refine(e=>!/[\r\n]/.test(e),`请使用一句简短的项目记忆。`),b=d({id:e(),text:y,state:l([`draft`,`kept`]),revision:i().int().positive(),createdAt:u(),updatedAt:u()}),x=d({cards:r(b)});d({id:e(),text:y}).strict(),d({expectedRevision:i().int().positive(),text:y.optional(),action:l([`keep`,`discard`,`delete`]).optional()}).strict().refine(e=>e.text!==void 0||e.action!==void 0,`没有需要保存的修改。`),d({text:y}).strict();var S=o();function C(){let{request:e,projectId:r}=p(),i=(0,v.useCallback)(t=>e(`memory`,x,{signal:t}),[e]),a=m(i,5e3,t(r,`memory`)),[o,s]=(0,v.useState)(null),[l,u]=(0,v.useState)({}),d=(0,v.useRef)(null),f=[...a.data?.cards??[]];for(let e of Object.values(l))f.some(t=>t.id===e.id)||f.push(e);if(a.data&&!d.current&&(d.current=[...f].sort((e,t)=>Number(t.state===`kept`)-Number(e.state===`kept`)).map(e=>e.id)),d.current){let e=new Map(d.current.map((e,t)=>[e,t]));for(let t of f)e.has(t.id)||(e.set(t.id,d.current.length),d.current.push(t.id));f.sort((t,n)=>e.get(t.id)-e.get(n.id))}return(0,S.jsxs)(`section`,{className:`memory-page`,children:[(0,S.jsx)(c,{title:`记忆`,children:(0,S.jsx)(_,{icon:`plus`,label:`新增记忆`,disabled:!!o,onClick:()=>s(n())})}),(0,S.jsx)(g,{error:!0,children:a.error}),!a.data&&a.loading&&(0,S.jsx)(`p`,{role:`status`,children:`加载中…`}),(0,S.jsxs)(`div`,{className:`memory-cards`,children:[o&&(0,S.jsx)(w,{id:o,onDone:()=>s(null),reload:a.reload},o),f.map(e=>(0,S.jsx)(w,{id:e.id,card:e,reload:a.reload,onEditing:t=>u(n=>{let r={...n};return t?r[e.id]=e:delete r[e.id],r})},e.id))]}),a.data&&f.length===0&&!o&&(0,S.jsx)(`p`,{className:`memory-empty`,children:`暂无记忆`})]})}function w({id:e,card:t,reload:n,onDone:r,onEditing:i}){let{request:o}=p(),[c,l]=(0,v.useState)(!t),[u,m]=(0,v.useState)(t?.text??``),[h,x]=(0,v.useState)(t?.revision),[C,w]=(0,v.useState)(!1),[T,E]=(0,v.useState)(``),D=(0,v.useRef)(!1),O=(0,v.useRef)(!1);function k(){O.current=!1,i?.(!0),m(t?.text??``),x(t?.revision),E(``),l(!0)}function A(){O.current=!0,l(!1),E(``),i?.(!1),r?.()}async function j(f){if(!D.current){if(!f&&t&&u===t.text)l(!1),i?.(!1);else if((!f||f===`keep`)&&!y.safeParse(c?u:t?.text).success)E(`请填写一句记忆,最多 120 个字符。`);else{D.current=!0,w(!0),E(``);try{t?await o(`memory/${e}`,d({saved:a()}),{method:`PATCH`,body:{expectedRevision:c?h:t.revision,...f?{action:f}:{},...c&&f!==`discard`&&f!==`delete`?{text:u}:{}}}):await o(`memory`,b,{method:`POST`,body:{id:e,text:u}}),l(!1),await n(),i?.(!1),r?.()}catch(e){E(s(e)),await n()}finally{D.current=!1,w(!1)}}}}return(0,S.jsxs)(`article`,{className:`memory-card`,"data-testid":`memory-card`,"data-memory-id":e,children:[(0,S.jsx)(`span`,{className:`memory-status ${t?.state===`kept`?`is-kept`:``}`,role:`img`,"aria-label":t?.state===`kept`?`已保留`:`待确认`,children:(0,S.jsx)(f,{name:t?.state===`kept`?`check`:`question`})}),(0,S.jsxs)(`div`,{className:`memory-content`,children:[c?(0,S.jsx)(`textarea`,{autoFocus:!0,"aria-label":`记忆内容`,value:u,maxLength:120,rows:2,disabled:C,onChange:e=>m(e.target.value.replace(/[\r\n]+/g,` `)),onBlur:e=>{O.current?O.current=!1:e.relatedTarget instanceof Element&&e.relatedTarget.closest(`.memory-actions`)||T||j()},onKeyDown:e=>{e.nativeEvent.isComposing||(e.key===`Escape`&&(e.preventDefault(),A()),e.key===`Enter`&&(e.preventDefault(),j()))}}):(0,S.jsx)(`button`,{type:`button`,className:`memory-text`,"aria-label":`编辑记忆:${t?.text??``}`,onClick:k,children:t?.text}),(0,S.jsx)(g,{error:!0,children:T})]}),(0,S.jsxs)(`div`,{className:`memory-actions`,onMouseDown:e=>{c&&e.preventDefault()},children:[(!t||t.state===`draft`)&&(0,S.jsx)(_,{icon:`check`,label:t?`保留记忆`:`保存记忆`,disabled:C,onClick:()=>void j(t?`keep`:void 0)}),c&&t?.state===`kept`&&(0,S.jsx)(_,{icon:`check`,label:`保存记忆`,disabled:C,onClick:()=>void j()}),(0,S.jsx)(_,{icon:`close`,label:t?t.state===`draft`?`舍弃记忆`:`删除记忆`:`取消新增`,disabled:C,onClick:()=>{t?j(t.state===`draft`?`discard`:`delete`):A()}})]})]})}export{C as Memory};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{$ as e,A as t,B as n,D as r,G as i,H as a,I as o,J as s,K as c,L as l,M as u,N as d,O as f,P as p,R as m,V as h,W as g,X as _,Y as v,Z as y,b,d as x,f as S,k as C,nt as w,p as T,q as E,tt as D,v as O,w as k,x as A}from"./index-CfWIg76q.js";import{n as j,r as M,t as N}from"./Markdown-s6-IMB4A.js";import{n as P}from"./project-links-Dy6-B89_.js";import{i as F,r as I}from"./WorkspaceTree-tH2uUcnp.js";var L=D(),R=g([`overview`,`handoff`]),z=v({title:_().trim().min(1),summary:_().trim().min(1)}).strict(),B=v({markdown:_().trim().min(1)}).strict(),V=z.extend({sourceRevision:h,sourceHash:n,generatedAt:_(),stale:c()}),H=v({kind:R,status:g([`absent`,`queued`,`running`,`succeeded`,`failed`]),available:c(),currentRevision:h,sourceRevision:h.nullable(),stale:c(),result:y([z,B]).nullable(),generatedAt:_().nullable(),error:_().nullable()}),U=g([`claude-code`,`codex`,`cursor`,`pi`,`dsh`]),W=v({formatVersion:E(1),adapterVersion:E(1),agent:U,nativeId:_().min(1).max(512),cwd:_().min(1).max(4096),messages:i(v({id:_().min(1).max(1024),role:g([`user`,`assistant`]),text:_().min(1),source:_().min(1).max(1024)}).strict())}).strict().refine(e=>new Set(e.messages.map(e=>e.id)).size===e.messages.length,`Duplicate message IDs.`);v({operationId:e(),sessionKey:n,parentRevision:h,blob:m}).strict(),v({revision:h,hash:n.nullable(),cleared:c()});var G=v({owner:a,sessionKey:n,agent:U,nativeId:_(),cwd:_(),title:_(),revision:h,updatedAt:_(),messageCount:s().int().nonnegative(),blob:m,overview:V.optional()}),K=v({sessions:i(G),nextCursor:h.nullable()}),q=v({totalSessions:s().int().nonnegative(),totalMessages:s().int().nonnegative(),memberCount:s().int().nonnegative(),updatedAt:_().nullable()});v({owner:a.optional(),sessionKey:n.optional()}).strict().refine(e=>!e.sessionKey||!!e.owner,`A session scope requires an owner.`);var J=v({matches:i(v({owner:a,sessionKey:n,revision:h,messageId:_(),source:g([`message`,`handoff`]).default(`message`),role:g([`user`,`assistant`]),snippet:_(),title:_()})),nextCursor:h.nullable()}),Y=v({owner:a,key:n,revision:h.refine(e=>e>0).optional(),messageId:_().min(1).optional(),source:g([`message`,`handoff`]).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`)}:{},...t.has(`source`)?{source:t.get(`source`)}:{}});return n.success?{target:n.data}:{error:`对话链接不完整或已损坏。`}}var Z=u();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)(T,{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)(b,{name:`chevron`,size:`small`})}),children:[(0,Z.jsx)(b,{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:n,onSession:r,focused:i,onFocus:a}){let{request:s,projectId:c}=S(),l=(0,L.useCallback)(t=>s(`sessions?${new URLSearchParams({owner:e,limit:`50`,order:`updated`})}`,K,{signal:t}),[e,s]),u=C(l,15e3,t(c,`session-tree`,e)),[d,f]=(0,L.useState)(),[m,h]=(0,L.useState)(!1),[g,_]=(0,L.useState)(``),v=(0,L.useRef)(null);(0,L.useEffect)(()=>()=>v.current?.abort(),[]);let y=d?d.nextCursor:u.data?.nextCursor;return(0,Z.jsxs)(`div`,{role:`group`,"aria-busy":u.loading||m,children:[(0,Z.jsx)(k,{error:!0,children:u.error||g}),u.error&&(0,Z.jsx)(`button`,{onClick:()=>void u.reload(),children:`重试`}),u.loading&&!u.data&&(0,Z.jsx)(`span`,{className:`tree-status`,role:`status`,children:`正在加载…`}),[...new Map([...d?.sessions??[],...u.data?.sessions??[]].map(e=>[e.sessionKey,e])).values()].sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt)||e.sessionKey.localeCompare(t.sessionKey)).map(t=>(0,Z.jsxs)(T,{type:`button`,role:`treeitem`,"aria-level":2,"aria-selected":n?.owner===e&&n.key===t.sessionKey,className:`tree-item`,style:{"--tree-level":2},tabIndex:i===`${e}/${t.sessionKey}`?0:-1,"data-testid":`session-row`,"data-owner-id":e,"data-session-key":t.sessionKey,title:o(t.title||t.nativeId),onFocus:()=>a(`${e}/${t.sessionKey}`),onClick:()=>r({owner:e,key:t.sessionKey,title:t.title||t.nativeId}),leading:(0,Z.jsx)(`span`,{className:`tree-chevron`}),children:[(0,Z.jsx)(b,{name:`sessions`}),(0,Z.jsx)(`span`,{className:`tree-name`,children:o(t.title||t.nativeId)})]},t.sessionKey)),y!=null&&(0,Z.jsx)(`button`,{className:`tree-action`,"data-testid":`session-tree-more`,disabled:m,onClick:async()=>{h(!0),_(``);let t=new AbortController;v.current=t;try{let n=await s(`sessions?${new URLSearchParams({owner:e,after:String(y),limit:`50`,order:`updated`})}`,K,{signal:t.signal});f(e=>({sessions:[...e?.sessions??[],...n.sessions],nextCursor:n.nextCursor}))}catch(e){t.signal.aborted||_(p(e))}finally{t.signal.aborted||h(!1)}},children:`加载更多`})]})}function ee({info:e,targeted:t=!1,highlight:n=``}){let[r,i]=(0,L.useState)(t),a=(0,L.useRef)(null);return(0,L.useEffect)(()=>{t&&a.current?.scrollIntoView({block:`center`})},[t]),(0,Z.jsxs)(`details`,{ref:a,open:r,className:`session-handoff`,onToggle:e=>i(e.currentTarget.open),children:[(0,Z.jsx)(`summary`,{children:`交接说明`}),r&&(0,Z.jsx)(te,{info:e,revision:t?e.revision:void 0,highlight:n})]})}function te({info:e,revision:t,highlight:n}){let{request:i}=S(),a=`sessions/${encodeURIComponent(e.owner)}/${e.sessionKey}`,o=(0,L.useCallback)(e=>i(`${a}/analysis/handoff${t===void 0?``:`?revision=${t}`}`,H,{signal:e}),[i,a,t]),s=C(o,5e3),c=f(),[l,u]=(0,L.useState)(!1),[d,m]=(0,L.useState)(``),h=s.data,g=l||h?.status===`queued`||h?.status===`running`,_=h?.result&&`markdown`in h.result?h.result.markdown:void 0;return(0,Z.jsxs)(`div`,{className:`stack`,"data-testid":`session-handoff`,children:[(0,Z.jsx)(k,{error:!0,children:d||s.error}),s.loading&&!h&&(0,Z.jsx)(`small`,{role:`status`,children:`正在加载…`}),h&&(0,Z.jsxs)(`div`,{className:`inline-actions`,children:[h.status===`failed`&&t===void 0&&(0,Z.jsx)(`button`,{"data-testid":`session-handoff-generate`,disabled:g||!h.available,onClick:async()=>{u(!0),m(``);try{await i(`${a}/handoff`,H,{method:`POST`,signal:c}),await s.reload()}catch(e){c.aborted||m(p(e))}finally{c.aborted||u(!1)}},children:g?`正在整理…`:`重试`}),!h.available&&(0,Z.jsx)(`small`,{children:`请先配置项目模型接入点`}),h.status===`failed`&&(0,Z.jsx)(`small`,{children:`整理未完成,可重试`}),h.available&&h.status!==`failed`&&(!_||h.stale||g)&&(0,Z.jsx)(`small`,{role:`status`,children:h.status===`running`||l?`正在整理…`:_?`对话已有新内容,等待自动更新…`:`等待自动整理…`}),h.currentRevision!==e.revision&&(0,Z.jsx)(`small`,{children:`交接说明使用最新对话;当前阅读的是历史原文`})]}),_&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`small`,{children:[`基于版本 `,h.sourceRevision,` · `,(0,Z.jsx)(r,{value:h.generatedAt})]}),(0,Z.jsx)(`div`,{className:`markdown`,"data-testid":`session-handoff-body`,children:(0,Z.jsx)(N,{highlight:n,children:_})})]})]})}function ne({members:e}){let{request:n,projectId:r,api:i}=S(),a=(0,L.useCallback)(async e=>{let[t,r]=await Promise.all([n(`sessions/stats`,q,{signal:e}),i.members(e)]);return{...t,members:r.members}},[n,i]),s=C(a,!0,t(r,`session-stats`)),[c,u]=(0,L.useState)(``),[d,f]=(0,L.useState)(``),[p,m]=(0,L.useState)(0),[h]=(0,L.useState)(()=>X(location.search)),[g,_]=(0,L.useState)(h.target),[v,y]=(0,L.useState)(h.target),[b,T]=(0,L.useState)(h.error??``),[E,D]=(0,L.useState)(``),j=(0,L.useRef)(null),M=g?.key?g.title?`搜索对话:${o(g.title)}`:`搜索当前对话`:g?`搜索:${g.owner} 的对话内容`:``,N=()=>{_(void 0),D(``),F(),j.current?.focus()};function F(){if(!v?.messageId)return;let{messageId:e,...t}=v;y(t),history.replaceState(null,``,w(P(r,t.owner,t.key,t)))}let I=(0,L.useCallback)(e=>{_(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);y(e.target),_(e.target),T(e.error??``),f(``),u(``),D(``)};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);let R=(e,t=``)=>{y(e),_(e),f(``),D(t),T(``),history.replaceState(null,``,w(P(r,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":`${l.sessions}目录`,children:[(0,Z.jsx)(x,{title:l.sessions,icon:`sessions`,count:(0,Z.jsx)(`span`,{"data-testid":`session-total`,children:s.data?.totalSessions??`—`}),children:(0,Z.jsx)(A,{icon:`refresh`,label:`刷新${l.sessions}`,"data-testid":`sessions-refresh`,disabled:s.loading,onClick:()=>{s.reload(),m(e=>e+1)}})}),(0,Z.jsx)(k,{error:!0,children:s.error}),(0,Z.jsx)(Q,{members:(s.data?.members??e).filter(e=>e.hasSessions),refresh:p,selected:g,onOwner:e=>{_({owner:e}),y(void 0),f(``),D(``),T(``),history.replaceState(null,``,w(`/projects/${encodeURIComponent(r)}/sessions`))},onSession:R})]}),(0,Z.jsxs)(`section`,{className:`session-reader`,"aria-label":`对话内容与搜索`,children:[(0,Z.jsx)(`div`,{className:`session-reader-content`,children:b?(0,Z.jsx)(k,{error:!0,children:b}):d?(0,Z.jsx)(re,{query:d,refresh:p,scope:{...g?{owner:g.owner}:{},...g?.key?{sessionKey:g.key}:{}},onSelect:e=>R(e,d)},`${d}/${g?.owner??``}/${g?.key??``}`):v?(0,Z.jsx)(ie,{selection:v,highlight:E,onLoaded:I,onLatest:()=>R({owner:v.owner,key:v.key})},`${v.owner}/${v.key}/${v.revision}/${v.source}/${p}`):(0,Z.jsx)(O,{mascot:!0,title:`选择对话开始阅读`,description:`也可以在下方搜索会话库内容。`})}),(0,Z.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`session-search-form`,onSubmit:e=>{e.preventDefault(),f(c.trim()),D(``),T(``),m(e=>e+1)},children:[g&&(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=>u(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!c&&g&&(e.preventDefault(),N())}}),(d||c||E)&&(0,Z.jsx)(A,{icon:`close`,label:`清空搜索`,"data-testid":`session-search-clear`,onClick:()=>{u(``),f(``),D(``),F(),j.current?.focus()}}),(0,Z.jsx)(A,{icon:`search`,type:`submit`,label:`搜索`,"data-testid":`session-search`,disabled:!c.trim()})]})]})]})]})}function re({query:e,refresh:t,scope:n,onSelect:r}){let{request:i}=S(),[a,s]=(0,L.useState)(0),c=(0,L.useCallback)(t=>i(`sessions/search?${new URLSearchParams({q:e,after:String(a),limit:`30`,order:`updated`,...n.owner?{owner:n.owner}:{},...n.sessionKey?{sessionKey:n.sessionKey}:{}})}`,J,{signal:t}),[i,e,a,t,n.owner,n.sessionKey]),l=C(c);return(0,Z.jsxs)(`section`,{className:`session-results stack`,"aria-label":`搜索结果`,"aria-busy":l.loading,children:[(0,Z.jsx)(k,{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:()=>r({owner:t.owner,key:t.sessionKey,revision:t.revision,messageId:t.messageId||void 0,source:t.source,title:t.title}),children:[(0,Z.jsx)(`strong`,{children:o(t.title)}),(0,Z.jsxs)(`small`,{children:[t.owner,` ·`,` `,t.source===`handoff`?`交接说明`: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.source}:${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:`下一页`}),a>0&&(0,Z.jsx)(`button`,{disabled:l.loading,onClick:()=>s(0),children:`返回第一页`})]})}function ie({selection:e,highlight:t,onLoaded:n,onLatest:r}){let{request:i}=S(),a=(0,L.useCallback)(async t=>{try{return await i(`sessions/${encodeURIComponent(e.owner)}/${e.key}${e.revision===void 0?``:`?revision=${e.revision}`}`,G,{signal:t})}catch(e){throw e instanceof d&&e.code===`SESSION_NOT_FOUND`?Error(`找不到这条对话或引用的版本,原链接可能已失效。`):e}},[i,e.owner,e.key,e.revision]),o=C(a,5e3);return(0,L.useEffect)(()=>{o.data&&n(o.data)},[o.data,n]),(0,Z.jsxs)(`section`,{className:`session-conversation stack`,"data-testid":`session-detail`,children:[(0,Z.jsx)(k,{error:!0,children:o.error}),o.error&&(0,Z.jsx)(`button`,{onClick:()=>void o.reload(),children:`重试`}),o.loading&&!o.data&&(0,Z.jsx)(`p`,{role:`status`,children:`正在读取对话…`}),o.data&&(0,Z.jsx)(ae,{info:o.data,messageId:e.messageId,handoff:e.source===`handoff`,highlight:t,pinned:e.revision!==void 0,onLatest:r},o.data.blob.sha256)]})}function ae({info:e,messageId:t,handoff:n,highlight:i,pinned:a,onLatest:s}){let{readTextBlob:c,projectId:l}=S(),u=(0,L.useCallback)(async t=>W.parse(JSON.parse(await c(e.blob,t))),[e.blob.sha256,e.blob.size]),d=C(u),f=(0,L.useRef)(null);return(0,L.useEffect)(()=>{d.data&&t&&f.current?.scrollIntoView({block:`center`})},[d.data,t]),(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`header`,{className:`conversation-header`,children:[(0,Z.jsx)(`h2`,{className:`session-title`,children:o(e.title||e.nativeId)}),(0,Z.jsxs)(`p`,{children:[e.owner,` · `,e.agent,` · `,e.messageCount,` 条消息`]}),(0,Z.jsxs)(`small`,{children:[(0,Z.jsx)(r,{value:e.updatedAt}),a&&(0,Z.jsxs)(Z.Fragment,{children:[` `,`· 引用版本 `,e.revision,` ·`,` `,(0,Z.jsx)(`a`,{href:w(P(l,e.owner,e.sessionKey)),onClick:e=>{e.preventDefault(),s()},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,targeted:n,highlight:n?i:``}),(0,Z.jsx)(k,{error:!0,children:d.error}),d.error&&(0,Z.jsx)(`button`,{onClick:()=>void d.reload(),children:`重新读取`}),d.loading&&(0,Z.jsx)(`p`,{role:`status`,children:`正在读取对话…`}),d.data&&(0,Z.jsxs)(Z.Fragment,{children:[t&&!d.data.messages.some(e=>e.id===t)&&(0,Z.jsx)(k,{children:`该版本中找不到引用的消息,已打开对话原文。`}),(0,Z.jsx)(`div`,{className:`session-messages`,children:d.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?f: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:i,children:e.text})})]},e.id))})]})]})}export{ne as Sessions};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,M as t,P as n,b as r,c as i,f as a,k as o,l as s,p as c,s as l,tt as u,u as d,w as f}from"./index-CfWIg76q.js";var p=u(),m=new Intl.Collator(`zh-CN`,{numeric:!0,sensitivity:`base`});function h(e,t){return m.compare(e,t)||(e<t?-1:+(e>t))}var g=t();function _(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 v=(e,t)=>`${e}/${t}`,y=e=>({"--tree-level":e});function b({members:e,...t}){let[n,r]=(0,p.useState)(()=>`folder:${v(e.find(e=>e.hasFiles)?.id??`_project`,``)}`);return(0,g.jsx)(`div`,{role:`tree`,"aria-label":`工作区文件`,"data-testid":`workspace-tree`,onKeyDown:_,children:(0,g.jsx)(S,{owner:l,path:``,level:1,members:e.filter(e=>e.hasFiles),context:{...t,focused:n,onFocus:r}})})}function x({owner:e,path:t,level:n,context:i}){let a=i.expanded.has(v(e,t)),o=`folder:${v(e,t)}`;return(0,g.jsxs)(`div`,{role:`none`,children:[(0,g.jsxs)(c,{type:`button`,role:`treeitem`,className:`tree-item tree-folder`,style:y(n),"aria-label":t||e,"aria-level":n,"aria-expanded":a,"aria-selected":i.selected?.kind===`directory`&&i.selected.owner===e&&i.selected.path===t,tabIndex:i.focused===o?0:-1,"data-testid":`directory-row`,"data-owner-id":e,"data-directory-path":t,onFocus:()=>i.onFocus(o),onClick:()=>i.onToggle(e,t),leading:(0,g.jsx)(`span`,{className:`tree-chevron ${a?`expanded`:``}`,children:(0,g.jsx)(r,{name:`chevron`,size:`small`})}),children:[(0,g.jsx)(r,{name:`files`}),(0,g.jsx)(`span`,{className:`tree-name`,children:t.split(`/`).at(-1)||e})]}),a&&(0,g.jsx)(S,{owner:e,path:t,level:n+1,context:i})]})}function S({owner:t,path:l,level:u,context:m,members:_=[]}){let{api:b,projectId:S}=a(),C=(0,p.useCallback)(e=>b.tree(t,l,void 0,``,e),[t,l]),w=o(C,!1,e(S,`file-tree`,t,l)),[T,E]=(0,p.useState)(),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(``),j=(0,p.useRef)(null);(0,p.useEffect)(()=>()=>j.current?.abort(),[]);let M=T?.revision===w.data?.revision?T:void 0,N=M?M.nextCursor:w.data?.nextCursor;async function P(){if(!N||!w.data||D)return;O(!0),A(``);let e=new AbortController;j.current=e;try{let n=await b.tree(t,l,w.data.revision,N,e.signal);e.signal.aborted||E({...n,entries:[...M?.entries??[],...n.entries]})}catch(t){e.signal.aborted||A(n(t))}finally{e.signal.aborted||O(!1)}}let F=[...(w.data?.entries??[]).filter(e=>!s(e.path)),...(M?.entries??[]).filter(e=>!s(e.path))],I=m.revealed;if(I?.owner===t&&!s(I.path)&&(!l||I.path.startsWith(l+`/`))){let e=l?I.path.slice(l.length+1):I.path,t=e.indexOf(`/`),n=t<0?I.path:[l,e.slice(0,t)].filter(Boolean).join(`/`);F.some(e=>e.path===n)||F.push(t<0?{...I.file,kind:`file`}:{kind:`directory`,path:n})}let L=[...F.filter(e=>t!==`_project`||!i(e.path)).map(e=>({...e,owner:t})),..._.map(e=>({kind:`directory`,path:``,owner:e.id}))].sort((e,t)=>e.kind===t.kind?h(e.path.split(`/`).at(-1)||e.owner,t.path.split(`/`).at(-1)||t.owner):e.kind===`directory`?-1:1);return(0,g.jsxs)(`div`,{role:`group`,"aria-label":v(d(t)?`workspaces`:t,l),"aria-busy":w.loading||D,children:[w.loading&&(0,g.jsx)(`p`,{className:`tree-status`,role:`status`,children:`正在加载…`}),(0,g.jsx)(f,{error:!0,children:w.error||k}),w.error&&(0,g.jsx)(`button`,{className:`tree-action`,onClick:()=>void w.reload(),children:`重试`}),L.map(e=>e.kind===`directory`?(0,g.jsx)(x,{owner:e.owner,path:e.path,level:u,context:m},v(e.owner,e.path)):(0,g.jsxs)(c,{type:`button`,role:`treeitem`,className:`tree-item`,style:y(u),"aria-label":e.path,"aria-level":u,"aria-selected":m.selected?.kind===`file`&&m.selected.owner===t&&m.selected.path===e.path,tabIndex:m.focused===`file:${v(t,e.path)}`?0:-1,"data-testid":`file-row`,"data-owner-id":t,"data-file-path":e.path,onFocus:()=>m.onFocus(`file:${v(t,e.path)}`),onClick:()=>m.onSelect(t,e.path),leading:(0,g.jsx)(`span`,{className:`tree-chevron`}),children:[(0,g.jsx)(r,{name:`file`}),(0,g.jsx)(`span`,{className:`tree-name`,children:e.path.split(`/`).at(-1)})]},e.path)),N&&(0,g.jsx)(`button`,{className:`tree-action`,"data-testid":`files-load-more`,disabled:D,onClick:()=>void P(),children:D?`正在加载…`:`加载更多`})]})}export{h as i,v as n,_ as r,b as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{z as e}from"./index-CfWIg76q.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};
|