@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.
Binary file
@@ -6,7 +6,7 @@
6
6
  <meta name="theme-color" content="#161615" />
7
7
  <title>Teammy 工作台</title>
8
8
  <link rel="icon" type="image/png" href="./assets/teammy-favicon-BiDvlPj2.png" />
9
- <script type="module" crossorigin src="./assets/index-BwEl1PIa.js"></script>
9
+ <script type="module" crossorigin src="./assets/index-DQsx-e5d.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="./assets/index-CTIAGUGG.css">
11
11
  </head>
12
12
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teammy/server",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "The centralized Teammy collaboration hub server.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- main#main[data-page=assistant]{height:100dvh;padding:0}.assistant-layout{grid-template-columns:var(--pane-width) minmax(0, 1fr);height:100%;min-height:0}.assistant-list{border-right:1px solid var(--color-line);background:var(--color-surface);flex-direction:column;min-height:0;display:flex}.assistant-list-heading,.assistant-thread-heading{border-bottom:1px solid var(--color-line);flex:0 0 76px;justify-content:space-between;align-items:center;padding:0 24px;display:flex}.assistant-list-heading h1{margin:0;font-size:20px}.assistant-thread-heading h2{text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:17px;overflow:hidden}.assistant-message-scroll{flex:1;min-height:0;overflow-y:auto}.assistant-list-status{color:var(--color-muted);font-size:var(--text-sm);margin:20px 24px}.assistant-message-item{border:0;border-bottom:1px solid var(--color-line);text-align:left;width:100%;color:var(--color-text);background:0 0;border-radius:0;align-items:center;gap:12px;padding:20px 24px;display:flex}.assistant-message-item:hover{background:var(--color-hover)}.assistant-message-item.selected{background:var(--color-soft)}.assistant-message-item.archived{color:var(--color-muted)}.assistant-message-item.archived strong{font-weight:400}.assistant-new-chat{width:32px;height:32px;min-height:32px;color:var(--brand-orange);background:var(--color-accent-soft);padding:6px}.assistant-new-chat .icon{width:20px;height:20px}.assistant-new-chat:after{top:calc(100% + 6px);bottom:auto}.assistant-message-copy{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.assistant-message-copy>.selection-content{width:fit-content;max-width:100%;color:var(--color-text);margin:-5px -8px;padding:5px 8px;display:block;overflow:visible}.assistant-message-item.archived .selection-content{color:inherit}.assistant-message-copy .selection-inner{min-width:0;display:block}.assistant-message-copy .selection-inner strong{display:block}.assistant-message-copy strong,.assistant-message-copy>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.assistant-message-copy strong{font-size:var(--text-base);font-weight:600}.assistant-message-copy>span,.assistant-message-copy time{font-size:var(--text-xs);color:var(--color-muted)}.assistant-message-dot{border-radius:50%;flex:0 0 7px;width:7px;height:7px}.assistant-message-dot.unread{background:var(--brand-orange)}.assistant-thread{background:var(--color-canvas);flex-direction:column;min-width:0;min-height:0;display:flex}.assistant-transcript{flex:1;min-height:0;padding:28px clamp(20px,4vw,64px);overflow-y:auto}.assistant-bubble-row{margin:0 0 24px;display:flex}.assistant-bubble-row.mine{justify-content:flex-end}.assistant-bubble{border-radius:4px var(--radius-lg) var(--radius-lg);background:var(--color-soft);overflow-wrap:anywhere;min-width:100px;max-width:min(88%,800px);padding:14px 18px}.assistant-bubble-row.mine .assistant-bubble{background:var(--color-accent-soft);border-radius:var(--radius-lg) 4px var(--radius-lg) var(--radius-lg)}.assistant-bubble-meta{font-size:var(--text-xs);color:var(--color-muted);align-items:baseline;gap:16px;margin-bottom:8px;display:flex}.assistant-debug-reply{font-size:var(--text-xs);background:var(--color-surface);margin-top:12px;padding:4px 10px}.assistant-bubble .markdown>:first-child{margin-top:0}.assistant-bubble .markdown>:last-child{margin-bottom:0}.assistant-bubble .markdown{font-size:var(--text-base);line-height:1.75}.assistant-bubble .markdown h1,.assistant-bubble .markdown h2{font-size:18px}.assistant-bubble .markdown h3,.assistant-bubble .markdown h4,.assistant-bubble .markdown h5,.assistant-bubble .markdown h6{font-size:var(--text-base)}.assistant-bubble .markdown :is(h1,h2,h3,h4,h5,h6){margin:18px 0 8px;line-height:1.5}.assistant-bubble .markdown :is(p,ul,ol){margin:10px 0}.assistant-bubble .markdown :is(ul,ol){padding-left:1.5em}.assistant-bubble .markdown li+li{margin-top:4px}.assistant-bubble .markdown li>:is(ul,ol){margin:4px 0}.assistant-bubble pre{max-width:100%;overflow-x:auto}.assistant-composer{background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--radius-lg);align-items:flex-end;gap:12px;margin:0 28px 28px;padding:12px;display:flex}.assistant-reply-hint{font-size:var(--text-xs);color:var(--color-muted);margin:0 28px 10px;line-height:1.7}.assistant-composer:focus-within{border-color:var(--color-muted)}.assistant-composer textarea{box-shadow:none;resize:vertical;background:0 0;border:0;flex:1;min-height:56px;max-height:220px;padding:8px}.assistant-composer textarea:focus{box-shadow:none;outline:none}.assistant-send{flex:0 0 40px;place-items:center;width:40px;height:40px;padding:0;display:grid}.assistant-empty{height:100%;min-height:240px;color:var(--color-muted);flex-direction:column;justify-content:center;align-items:center;gap:20px;display:flex}.assistant-empty .mascot{width:96px;height:144px}.assistant-empty p{margin:0}.assistant-archived{color:var(--color-muted);font-size:var(--text-sm);justify-content:center;align-items:center;gap:8px;padding:24px;display:flex}.assistant-thread>.notice{margin:0 28px 12px}.assistant-typing{gap:5px;padding:8px 0;display:inline-flex}.assistant-typing i{background:var(--color-muted);border-radius:50%;width:5px;height:5px;animation:1.4s infinite assistant-pulse}.assistant-typing i:nth-child(2){animation-delay:.15s}.assistant-typing i:nth-child(3){animation-delay:.3s}@keyframes assistant-pulse{0%,70%,to{opacity:.35}35%{opacity:1}}@media (prefers-reduced-motion:reduce){.assistant-typing i{animation:none}}@media (width<=900px){.assistant-layout{grid-template-columns:240px minmax(0,1fr)}.assistant-message-item{padding:16px}.assistant-composer{margin:0 16px 16px}.assistant-reply-hint{margin:0 16px 10px}.assistant-bubble{max-width:96%}}@media (width<=600px){.assistant-layout{grid-template-columns:150px minmax(0,1fr)}.assistant-list-heading,.assistant-thread-heading{padding:0 12px}.assistant-transcript{padding:16px 10px}.assistant-composer{gap:4px;margin:0 8px 12px;padding:6px}.assistant-reply-hint{margin:0 8px 10px}}.assistant-participants{text-overflow:ellipsis;white-space:nowrap;min-width:0;max-width:45%;color:var(--color-muted);font-size:var(--text-sm);margin-left:16px;overflow:hidden}
@@ -1 +0,0 @@
1
- import{$ as e,D as t,E as n,G as r,K as i,O as ee,Q as a,U as te,_ as o,a as s,d as c,i as ne,j as l,k as u,l as re,n as d,r as f,t as ie,v as ae,x as p,y as m}from"./index-BwEl1PIa.js";import{t as h}from"./Markdown-D3cU0ani.js";var g=a(),_=u(),v=e=>new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),y=e=>e.replace(/[#*_`>]/g,``).replace(/\s+/g,` `).trim();function b({mine:e=!1,author:t,time:n,children:r}){return(0,_.jsx)(`div`,{className:`assistant-bubble-row ${e?`mine`:``}`,children:(0,_.jsxs)(`div`,{className:`assistant-bubble`,children:[(0,_.jsxs)(`div`,{className:`assistant-bubble-meta`,children:[(0,_.jsx)(`span`,{children:t}),(0,_.jsx)(`time`,{dateTime:n,children:v(n)})]}),r]})})}function x({me:a}){let{projectId:u,request:x}=re(),C=ee(),w=t(u,a,`assistant-selection`),T=t(u,a,`assistant-drafts`),oe=(0,g.useCallback)(e=>x(`agents/outbox`,ne,{signal:e}),[x]),E=n(oe,3e3,t(u,a,`outbox`)),se=(0,g.useCallback)(e=>x(`agents/chats`,ie,{signal:e}),[x]),D=n(se,3e3,t(u,a,`chats`)),[O,ce]=(0,g.useState)(()=>{let e=new URLSearchParams(location.search),t=e.get(`chat`);return t?`chat:${t}`:e.get(`message`)??C?.get(w)??``}),k=O.startsWith(`chat:`)?O.slice(5):``,A=!O||!!k,[j,M]=(0,g.useState)(()=>C?.get(t(u,a,`chat`,k))),N=j?.id===k?j:C?.get(t(u,a,`chat`,k)),le=D.data?.chats.find(e=>e.id===k),[ue,P]=(0,g.useState)(),[F,de]=(0,g.useState)(()=>C?.get(T)??{}),I=F[O]??``,L=e=>de(t=>({...t,[O]:e})),[R,z]=(0,g.useState)(!1),[B,V]=(0,g.useState)(!1),[fe,H]=(0,g.useState)(``),[U,W]=(0,g.useState)(``),G=(0,g.useRef)(null),K=(0,g.useRef)(!0),q=(0,g.useRef)(O);q.current=O,(0,g.useEffect)(()=>{j&&C?.set(t(u,a,`chat`,j.id),j)},[C,u,a,j]),(0,g.useEffect)(()=>{C?.set(T,F)},[C,T,F]);function J(e){q.current=e,ce(e),C?.set(w,e);let t=new URL(location.href);e.startsWith(`chat:`)?t.searchParams.set(`chat`,e.slice(5)):t.searchParams.delete(`chat`),e&&!e.startsWith(`chat:`)&&e!==`debug`?t.searchParams.set(`message`,e):t.searchParams.delete(`message`),history.replaceState(history.state,``,t)}(0,g.useEffect)(()=>{!O&&D.data?.chats.length&&J(`chat:${D.data.chats[0].id}`)},[O,D.data]);let Y=(E.data?.messages??[]).filter(e=>e.box===`debug`).reverse(),X=E.data?.messages.find(e=>e.id===(O===`debug`?ue:O)),Z=Y.filter(e=>!e.readAt).map(e=>e.id).join(`,`);(0,g.useEffect)(()=>{X&&!X.readAt&&O!==`debug`&&x(`agents/outbox/${X.id}/read`,s,{method:`POST`}).then(()=>{window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}).catch(e=>H(l(e)))},[X?.id,X?.readAt,O,x,E.reload]),(0,g.useEffect)(()=>{O===`debug`&&Z&&Promise.all(Z.split(`,`).map(e=>x(`agents/outbox/${e}/read`,s,{method:`POST`}))).then(()=>{window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}).catch(e=>H(l(e)))},[O,Z,x,E.reload]),(0,g.useEffect)(()=>{if(W(``),!k)return;let t=!0,n=new EventSource(e(`/api/v1/projects/${encodeURIComponent(u)}/agents/chats/${encodeURIComponent(k)}/events`));n.addEventListener(`snapshot`,e=>{if(t)try{M(d.parse(JSON.parse(e.data))),W(``)}catch(e){W(l(e))}}),n.onerror=()=>{t&&W(`对话连接中断,正在重新连接…`)},n.addEventListener(`run`,e=>{if(!t)return;let n=f.parse(JSON.parse(e.data));M(t=>t&&{...t,cursor:Math.max(t.cursor,Number(e.lastEventId)||0),runs:t.runs.some(e=>e.id===n.id)?t.runs:[...t.runs,n]})});for(let e of[`delta`,`reset`,`state`])n.addEventListener(e,n=>{if(!t)return;let r=JSON.parse(n.data);M(t=>t&&{...t,cursor:Math.max(t.cursor,Number(n.lastEventId)||0),runs:t.runs.map(t=>t.id===r.id?{...t,answer:e===`delta`?t.answer+(r.text??``):e===`reset`?``:r.answer??t.answer,state:r.state??t.state,error:r.error===void 0?t.error:r.error}:t)})});return()=>{t=!1,n.close()}},[u,k]),(0,g.useEffect)(()=>{if(N?.kind!==`matter`||N.id!==k)return;let e=()=>{document.visibilityState===`visible`&&x(`agents/chats/${k}/read`,i({ok:te()}),{method:`POST`,body:{cursor:N.cursor}}).then(()=>{D.reload(),window.dispatchEvent(new Event(`teammy:outbox`))}).catch(e=>H(l(e)))},t=setTimeout(e,300);return document.addEventListener(`visibilitychange`,e),()=>{clearTimeout(t),document.removeEventListener(`visibilitychange`,e)}},[k,N?.cursor,N?.kind,x]),(0,g.useEffect)(()=>{K.current&&G.current?.scrollIntoView({block:`end`})},[O,j?.runs,X?.recipients,Y.length]);function Q(){window.dispatchEvent(new Event(`teammy:outbox`)),E.reload()}async function $(e){if(K.current=!0,J(e),H(``),P(void 0),!(e.startsWith(`chat:`)||e===`debug`))try{await x(`agents/outbox/${e}/read`,s,{method:`POST`}),Q()}catch(e){H(l(e))}}async function pe(){if(!B){V(!0),H(``);try{let e=await x(`agents/chats`,d,{method:`POST`});M(e),await $(`chat:${e.id}`),D.reload()}catch(e){H(l(e))}finally{V(!1)}}}async function me(e){e.preventDefault();let t=I.trim();if(t&&!R){z(!0),H(``);try{if(A){let e=k;if(!e){let t=await x(`agents/chats`,d,{method:`POST`});e=t.id,q.current===O&&(M(t),J(`chat:${e}`))}let n=await x(`agents/chats/${e}`,f,{method:`POST`,body:{text:t}});M(t=>t?.id===e?{...t,runs:t.runs.some(e=>e.id===n.id)?t.runs:[...t.runs,n]}:t),D.reload()}else await x(`agents/outbox/${X.id}/reply`,i({taskId:r()}),{method:`POST`,body:{body:t}}),Q(),P(void 0);L(``)}catch(e){H(l(e))}finally{z(!1)}}}let he=A||!!X&&!X.archivedAt&&!X.recipients.find(e=>e.userId===a)?.reply,ge=A&&!N&&(!!k||!D.data);return(0,_.jsxs)(`div`,{className:`split-layout assistant-layout`,"data-testid":`assistant-page`,children:[(0,_.jsxs)(`aside`,{className:`assistant-list`,"aria-label":`消息列表`,children:[(0,_.jsxs)(`header`,{className:`assistant-list-heading`,children:[(0,_.jsx)(`h1`,{children:`消息`}),(0,_.jsx)(ae,{className:`assistant-new-chat`,icon:`plus`,label:`新建对话`,disabled:B,onClick:()=>void pe(),"data-testid":`assistant-launcher`})]}),(0,_.jsxs)(`div`,{className:`assistant-message-scroll`,children:[D.loading&&!D.data&&(0,_.jsx)(`p`,{className:`assistant-list-status`,role:`status`,children:`加载中…`}),D.data?.chats.map(e=>(0,_.jsxs)(`button`,{type:`button`,"data-testid":`assistant-chat-${e.id}`,className:`assistant-message-item assistant-chat-item ${k===e.id?`selected`:``}`,"aria-pressed":k===e.id,onClick:()=>void $(`chat:${e.id}`),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${e.unread||e.state===`running`||e.state===`queued`?`unread`:``}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:k===e.id,children:(0,_.jsx)(`strong`,{children:e.title})}),(0,_.jsxs)(`time`,{dateTime:e.updatedAt,children:[new Date(e.updatedAt).toLocaleDateString([],{month:`numeric`,day:`numeric`}),` `,v(e.updatedAt)]})]})]},e.id)),!!Y.length&&(0,_.jsxs)(`button`,{type:`button`,"data-testid":`debug-outbox`,className:`assistant-message-item ${O===`debug`?`selected`:``}`,onClick:()=>void $(`debug`),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${Z?`unread`:``}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:O===`debug`,children:(0,_.jsx)(`strong`,{children:`运行提醒`})}),(0,_.jsx)(`span`,{children:y(Y.at(-1).body)})]})]}),E.data?.messages.filter(e=>e.box!==`debug`).sort((e,t)=>Number(!!e.archivedAt)-Number(!!t.archivedAt)).map(e=>(0,_.jsxs)(`button`,{type:`button`,"data-testid":`outbox-${e.id}`,className:`assistant-message-item ${e.archivedAt?`archived`:``} ${O===e.id?`selected`:``}`,onClick:()=>void $(e.id),children:[(0,_.jsx)(`span`,{className:`assistant-message-dot ${e.readAt?``:`unread`}`}),(0,_.jsxs)(`span`,{className:`assistant-message-copy`,children:[(0,_.jsx)(c,{selected:O===e.id,children:(0,_.jsx)(`strong`,{children:y(e.body)})}),(0,_.jsxs)(`time`,{dateTime:e.createdAt,children:[new Date(e.createdAt).toLocaleDateString([],{month:`numeric`,day:`numeric`}),` `,v(e.createdAt)]})]})]},e.id))]}),(0,_.jsx)(p,{error:!0,children:E.error||D.error})]}),(0,_.jsxs)(`section`,{className:`assistant-thread`,"aria-label":A?`提百事对话`:`消息内容`,children:[(0,_.jsxs)(`header`,{className:`assistant-thread-heading`,children:[(0,_.jsx)(`h2`,{children:A?le?.title??N?.title??(k?`无标题`:`提百事`):O===`debug`?`运行提醒`:`项目消息`}),N?.kind===`matter`&&(0,_.jsxs)(`span`,{className:`assistant-participants`,title:N.participants?.join(`、`),children:[N.visibility===`project`?`项目共享 · `:``,N.participants?.join(`、`)]})]}),(0,_.jsxs)(`div`,{className:`assistant-transcript`,role:`log`,"aria-live":`polite`,"data-testid":`assistant-transcript`,onScroll:e=>{let t=e.currentTarget;K.current=t.scrollHeight-t.scrollTop-t.clientHeight<100},children:[A?ge?(0,_.jsxs)(`div`,{className:`assistant-empty`,"data-testid":`assistant-loading`,children:[(0,_.jsx)(m,{}),(0,_.jsx)(`p`,{role:`status`,children:U||D.error?`暂时无法加载对话`:`加载中…`})]}):N?.runs.length?N.runs.map(e=>(0,_.jsxs)(`div`,{className:`assistant-turn`,children:[(0,_.jsx)(b,{mine:e.author===void 0||e.author===a,author:`${e.author===void 0?a:e.author||`提百事`}${e.source===`wecom`?` · 企业微信`:``}`,time:e.createdAt,children:(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.text})})}),(0,_.jsxs)(b,{author:`提百事`,time:e.createdAt,children:[e.answer&&(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.answer})}),[`queued`,`running`].includes(e.state)&&(0,_.jsxs)(`span`,{className:`assistant-typing`,"aria-label":`正在回答`,children:[(0,_.jsx)(`i`,{}),(0,_.jsx)(`i`,{}),(0,_.jsx)(`i`,{})]}),e.state===`failed`&&(0,_.jsx)(p,{error:!0,children:e.error||`本次回答未完成。`})]})]},e.id)):(0,_.jsxs)(`div`,{className:`assistant-empty`,children:[(0,_.jsx)(m,{}),(0,_.jsx)(`p`,{children:`有什么项目问题想聊聊?`})]}):!E.data&&E.loading?(0,_.jsx)(`div`,{className:`assistant-empty`,children:(0,_.jsx)(`p`,{role:`status`,children:`加载中…`})}):O===`debug`?Y.map(e=>(0,_.jsx)(S,{item:e,me:a,onReply:!e.archivedAt&&!e.recipients.find(e=>e.userId===a)?.reply?()=>{P(e.id),L(``),H(``)}:void 0},e.id)):X&&(0,_.jsx)(S,{item:X,me:a}),(0,_.jsx)(`div`,{ref:G})]}),(0,_.jsx)(p,{error:!0,children:fe||(A?U:``)}),he&&!A&&(0,_.jsx)(`p`,{className:`assistant-reply-hint`,id:`assistant-reply-hint`,children:O===`debug`?`回复运行提醒:${y(X.body).split(`诊断码`)[0]}。发送后将作为新的后台输入。`:`回应「提百事」的问题。注意:只能发送一条消息,「提百事」收到后会继续工作。如果有新的问题,「提百事」会继续发消息来问你。`}),he?(0,_.jsxs)(`form`,{className:`assistant-composer`,onSubmit:e=>void me(e),children:[(0,_.jsx)(`textarea`,{value:I,onChange:e=>L(e.target.value),"aria-label":A?`向提百事提问`:`回复消息`,"aria-describedby":A?void 0:`assistant-reply-hint`,placeholder:A?`问问提百事…`:`回复…`,rows:2,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.nativeEvent.isComposing&&(e.preventDefault(),e.currentTarget.form?.requestSubmit())}}),(0,_.jsx)(`button`,{className:`primary assistant-send`,type:`submit`,disabled:R||ge||!I.trim(),"aria-label":`发送`,children:(0,_.jsx)(o,{name:`send`})})]}):O!==`debug`&&X&&(0,_.jsxs)(`div`,{className:`assistant-archived`,children:[(0,_.jsx)(o,{name:`archive`}),`已归档`]})]})]})}function S({item:e,me:t,onReply:n}){return(0,_.jsxs)(`div`,{"data-testid":`outbox-thread-${e.id}`,children:[(0,_.jsxs)(b,{author:e.box===`debug`?`运行提醒`:`提百事`,time:e.createdAt,children:[(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.body})}),n&&(0,_.jsx)(`button`,{type:`button`,className:`assistant-debug-reply`,onClick:n,children:`回复`})]}),[...e.recipients].filter(e=>e.reply).sort((e,t)=>e.reply.createdAt.localeCompare(t.reply.createdAt)).map(e=>(0,_.jsx)(b,{mine:e.userId===t,author:e.userId,time:e.reply.createdAt,children:(0,_.jsx)(`div`,{className:`markdown`,children:(0,_.jsx)(h,{children:e.reply.body})})},e.userId))]})}export{x as Assistant};
@@ -1 +0,0 @@
1
- import{$ as e,D as t,E as n,Q as r,S as i,T as a,_ as o,b as s,f as c,g as l,j as u,k as d,l as f,m as p,p as m,v as h,w as g,x as _}from"./index-BwEl1PIa.js";import{t as v}from"./project-links-XbF78Bal.js";import"./file-links-GfCXWkEh.js";var y=r(),b=d(),x=[{status:`planned`,label:`计划`},{status:`in_progress`,label:`进行中`},{status:`in_review`,label:`待验收`},{status:`completed`,label:`已完成`},{status:null,label:`未明确`}];function S({members:e,project:r}){let{request:a,projectId:o}=f(),s=(0,y.useCallback)(e=>a(`tasks`,c,{signal:e}),[a]),l=n(s,3e3,t(o,`tasks`)),[u,d]=(0,y.useState)(),m=l.data,h=new Map(e.map(e=>[e.id,e.displayName||e.id]));return(0,b.jsxs)(`div`,{className:`task-board`,children:[(0,b.jsx)(i,{title:r?.projectName.trim()?`${r.projectName.trim()}|工作看板`:`工作看板`,description:r?.description.trim()||``}),(0,b.jsx)(_,{error:!0,children:l.error}),(0,b.jsx)(`section`,{className:`task-board-lanes`,"aria-label":`任务进度`,"data-testid":`progress-board`,children:x.filter(e=>e.status!==null||m?.tasks.some(e=>e.status===null)).map(e=>{let t=m?.tasks.filter(t=>t.status===e.status)??[];return(0,b.jsxs)(`section`,{className:`task-lane`,"aria-label":e.label,"data-stage":e.status??`unknown`,children:[(0,b.jsxs)(`h2`,{children:[(0,b.jsx)(`span`,{className:`lane-dot`}),e.label,(0,b.jsx)(p,{children:m?t.length:`—`})]}),(0,b.jsx)(`div`,{className:`task-lane-content`,children:t.length?t.map(e=>(0,b.jsx)(C,{task:e,names:h,onEdit:()=>d(e),onSaved:()=>void l.reload()},e.id)):(0,b.jsx)(`p`,{className:`task-lane-empty`,children:l.error&&!m?`读取失败`:m?`暂无任务`:`读取中…`})})]},e.label)})}),u&&(0,b.jsx)(T,{task:u,onClose:()=>d(void 0),onSaved:()=>{d(void 0),l.reload()}},u.id)]})}function C({task:t,names:n,onEdit:r,onSaved:i}){let{projectId:s,request:c}=f(),l=a(),[d,p]=(0,y.useState)(!1),[x,S]=(0,y.useState)(``);async function C(){if(!d){p(!0),S(``);try{await c(`tasks/${t.id}/correction`,m,{method:`PATCH`,signal:l,body:{needsConfirmation:!1,expectedRevision:t.revision}}),l.aborted||i()}catch(e){l.aborted||S(u(e))}finally{p(!1)}}}return(0,b.jsxs)(`details`,{className:`task-card`,"data-testid":`task-card`,"data-task-id":t.id,"data-owner":t.owner,"data-status":t.status??`unknown`,children:[(0,b.jsxs)(`summary`,{className:`task-card-heading`,"data-testid":`task-toggle`,children:[(0,b.jsx)(`h3`,{children:t.title}),(0,b.jsxs)(`span`,{className:`task-card-meta`,children:[(0,b.jsx)(`small`,{children:n.get(t.owner)??t.owner}),t.needsConfirmation&&(0,b.jsxs)(`span`,{className:`task-confirmation`,"data-testid":`task-confirmation`,children:[(0,b.jsx)(o,{name:`attention`,size:`small`}),`需要确认`]})]})]}),(0,b.jsx)(h,{icon:`edit`,className:`task-card-edit`,label:`纠正任务:${t.title}`,"data-testid":`task-correct`,disabled:d,onClick:r}),(0,b.jsxs)(`div`,{className:`task-card-details`,children:[t.corrected&&!t.needsConfirmation&&(0,b.jsx)(`small`,{children:`已确认`}),t.needsReview&&(0,b.jsx)(`p`,{children:`本次整理未能明确对应,请核对来源。`}),(0,b.jsx)(`h4`,{children:`目标`}),(0,b.jsx)(`p`,{children:t.goal?(0,b.jsx)(w,{value:t.goal,names:n}):`目标未明确`}),(0,b.jsx)(`h4`,{children:`当前进展`}),(0,b.jsx)(`p`,{className:`task-progress`,children:(0,b.jsx)(w,{value:t.progress,names:n})}),(0,b.jsx)(`div`,{className:`task-card-sources`,children:t.sources.map(n=>(0,b.jsxs)(`a`,{"data-testid":`task-source`,href:e(n.kind===`material`?`/projects/${s}/materials?id=${n.materialId}&revision=${n.revision}`:v(s,t.owner,n.path)),children:[(0,b.jsx)(o,{name:`file`,size:`small`}),(0,b.jsx)(`span`,{children:n.path})]},n.path))}),t.syncedAt&&(0,b.jsxs)(`small`,{children:[`资料同步于 `,(0,b.jsx)(g,{value:t.syncedAt})]}),t.needsConfirmation&&(0,b.jsxs)(`div`,{className:`task-card-confirm`,children:[(0,b.jsx)(_,{error:!0,children:x}),(0,b.jsx)(`button`,{className:`primary`,"data-testid":`task-confirm-save`,disabled:d,onClick:()=>void C(),children:d?`正在保存…`:`保存`})]})]})]})}function w({value:e,names:t}){return e.split(/(@[a-z][a-z0-9_-]*)/gi).map((e,n)=>e.startsWith(`@`)&&t.has(e.slice(1))?(0,b.jsx)(`mark`,{className:`task-mention`,children:e},n):e)}function T({task:e,onClose:t,onSaved:n}){let{request:r}=f(),i=a(),[o,c]=(0,y.useState)(e.title),[d,p]=(0,y.useState)(e.status??``),[h,g]=(0,y.useState)(e.goal??``),[v,S]=(0,y.useState)(e.progress),[C,w]=(0,y.useState)(!1),[T,E]=(0,y.useState)(``),D={...o===e.title?{}:{title:o},...d===(e.status??``)?{}:{status:d||null},...h===(e.goal??``)?{}:{goal:h||null},...v===e.progress?{}:{progress:v},...e.needsConfirmation?{needsConfirmation:!1}:{}};async function O(t=!1){if(!(C||!t&&!Object.keys(D).length)){w(!0),E(``);try{await r(`tasks/${e.id}/correction`,m,{method:t?`DELETE`:`PATCH`,signal:i,...t?{}:{body:{...D,expectedRevision:e.revision}}}),i.aborted||n()}catch(e){i.aborted||E(u(e))}finally{w(!1)}}}return(0,b.jsx)(s,{id:`task-correction`,title:`纠正任务`,onClose:t,children:(0,b.jsxs)(`form`,{className:`stack`,"aria-busy":C,onSubmit:e=>{e.preventDefault(),O()},children:[(0,b.jsx)(l,{id:`task-title`,label:`标题`,children:(0,b.jsx)(`input`,{value:o,required:!0,onChange:e=>c(e.target.value)})}),(0,b.jsxs)(`fieldset`,{className:`task-status-field`,disabled:C,children:[(0,b.jsx)(`legend`,{children:`状态`}),(0,b.jsx)(`div`,{className:`task-status-options`,"data-testid":`task-status`,children:x.filter(e=>e.status!==null).map(e=>(0,b.jsxs)(`label`,{className:`task-status-choice`,children:[(0,b.jsx)(`input`,{type:`radio`,name:`task-status`,value:e.status,checked:d===e.status,onChange:()=>p(e.status)}),(0,b.jsx)(`span`,{children:e.label})]},e.status))})]}),(0,b.jsx)(l,{id:`task-goal`,label:`目标`,children:(0,b.jsx)(`textarea`,{value:h,onChange:e=>g(e.target.value)})}),(0,b.jsx)(l,{id:`task-progress`,label:`当前进展`,children:(0,b.jsx)(`textarea`,{value:v,onChange:e=>S(e.target.value)})}),(0,b.jsx)(_,{error:!0,children:T}),(0,b.jsxs)(`div`,{className:`row wrap`,children:[(0,b.jsx)(`button`,{type:`submit`,className:`primary`,disabled:C||!Object.keys(D).length,"data-testid":`task-correction-save`,children:`保存`}),e.corrected&&e.jobId&&(0,b.jsx)(`button`,{type:`button`,disabled:C,"data-testid":`task-correction-reset`,onClick:()=>void O(!0),children:`恢复自动结果`})]})]})})}function E({members:e,config:t}){return(0,b.jsx)(S,{members:e,project:t})}export{E as Dashboard};
@@ -1 +0,0 @@
1
- import{$ as e,A as t,C as n,D as r,E as i,I as a,P as o,Q as s,_ as c,c as l,h as u,k as d,l as f,o as p,s as m,v as h,x as g}from"./index-BwEl1PIa.js";import{t as _}from"./Markdown-D3cU0ani.js";import{t as v}from"./project-links-XbF78Bal.js";import{t as y}from"./file-links-GfCXWkEh.js";import{n as b,t as x}from"./WorkspaceTree-DeAA1QtV.js";var S=s(),C=d();function w(e,t){let n=t.split(`/`).slice(0,-1);return n.map((t,r)=>b(e,n.slice(0,r+1).join(`/`))).concat(b(e,``))}function T({members:n,me:r,onRefresh:s}){let{api:c,projectId:d}=f(),[_,T]=(0,S.useState)(()=>{let e=new URLSearchParams(location.search),t=e.get(`owner`),r=a.safeParse(e.get(`path`));return t&&(t===`_project`||n.some(e=>e.id===t))&&r.success&&!m(r.data)?{owner:t,path:r.data}:void 0}),[D,O]=(0,S.useState)(()=>new Set(_?w(_.owner,_.path):[b(r,``)])),[k,A]=(0,S.useState)(()=>_?{..._,kind:`file`}:void 0),[j,M]=(0,S.useState)(0),[N,P]=(0,S.useState)(()=>{let e=new URLSearchParams(location.search);return!_&&(e.has(`owner`)||e.has(`path`))?`文件链接不完整或目标已不可用。`:``}),F=(0,S.useCallback)(async e=>{if(_)try{return{owner:_.owner,...await c.file(_.owner,_.path,void 0,e)}}catch(e){throw e instanceof t&&e.code===`FILE_NOT_FOUND`?Error(`找不到这个文件,可能已被删除或移动。`):e}},[_?.owner,_?.path,j]),I=i(F),L=I.data?.owner===_?.owner&&I.data?.file.path===_?.path?I.data:void 0;function R(e,t){let n=t.split(`/`).filter(Boolean);O(t=>{let r=new Set(t);for(let t=0;t<=n.length;t++)r.add(b(e,n.slice(0,t).join(`/`)));return r})}function z(t,n){P(``),R(t,n.split(`/`).slice(0,-1).join(`/`)),T({owner:t,path:n}),A({owner:t,path:n,kind:`file`}),history.replaceState(null,``,e(v(d,t,n)))}function B(e){if(!_)return!1;let t=y(_.owner===`_project`?_.path:`${_.owner}/${_.path}`,e);if(!t)return!/^[a-z][a-z0-9+.-]*:/i.test(e)&&!e.startsWith(`//`)&&(P(`该链接超出工作区,请在原仓库查看。`),!0);if(m(t.path))return P(`配置文件不在文件浏览中显示。`),!0;let[r,...i]=t.path.split(`/`),a=n.some(e=>e.id===r),o=a?r:p,s=a?i.join(`/`):t.path;return P(``),t.directory?(R(o,s),A({owner:o,path:s,kind:`directory`})):o===_.owner&&s===_.path?t.anchor&&[...document.querySelectorAll(`.markdown h1,.markdown h2,.markdown h3,.markdown h4`)].find(e=>e.textContent?.trim().toLowerCase().replace(/\s+/g,`-`)===t.anchor.toLowerCase())?.scrollIntoView({block:`center`}):z(o,s),!0}return(0,C.jsxs)(`div`,{className:`split-layout file-explorer`,"data-testid":`file-browser`,children:[(0,C.jsxs)(`aside`,{className:`file-tree-pane`,"aria-label":`文件资源管理器`,children:[(0,C.jsx)(l,{title:`工作区`,icon:`files`,children:(0,C.jsx)(h,{icon:`refresh`,label:`刷新文件`,"data-testid":`files-refresh`,onClick:()=>{P(``),M(e=>e+1),s()}})}),(0,C.jsx)(x,{members:n,expanded:D,selected:k,revealed:!I.loading&&!I.error&&L?{owner:L.owner,path:L.file.path,file:L.file}:void 0,onSelect:z,onToggle:(e,t)=>{A({owner:e,path:t,kind:`directory`}),O(n=>{let r=new Set(n),i=b(e,t);return r.has(i)?r.delete(i):r.add(i),r})}},j)]}),(0,C.jsx)(`section`,{className:`file-detail`,"data-testid":`file-preview`,"data-owner-id":_?.owner,"data-file-path":_?.path,"aria-label":o.filePreview,children:_?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(g,{error:!0,children:N||!I.loading&&I.error}),I.error&&(0,C.jsx)(`button`,{className:`file-entry-retry`,"data-testid":`files-retry`,onClick:()=>void I.reload(),children:o.retry}),I.loading?(0,C.jsx)(`p`,{className:`preview-body`,role:`status`,children:o.loading}):!I.error&&L&&(0,C.jsx)(E,{owner:L.owner,file:L.file,onLink:B},`${L.owner}:${L.file.path}:${L.file.sha256}`)]}):N?(0,C.jsx)(g,{error:!0,children:N}):(0,C.jsx)(u,{mascot:!0,title:`从一份资料开始`,description:o.pickFile})})]})}function E({owner:e,file:t,onLink:a}){let{readTextBlob:s,blobUrl:l,projectId:u}=f(),[d,p]=(0,S.useState)(!1),m=t.size>524288,v=/\.(md|markdown)$/i.test(t.path),y=(0,S.useCallback)(e=>m?Promise.resolve(void 0):s(t,e),[t.sha256,t.size,m]),b=i(y,!1,r(u,`file-body`,t.sha256));return(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`header`,{className:`file-detail-header`,children:[(0,C.jsxs)(`span`,{className:`file-detail-path`,title:`${e===`_project`?`workspaces`:e}/${t.path}`,children:[(0,C.jsxs)(`span`,{children:[e===`_project`?`workspaces`:e,` / `]}),t.path]}),(0,C.jsxs)(n,{label:`文件操作`,children:[v&&(0,C.jsx)(h,{icon:d?`preview`:`code`,label:d?`切换为预览`:`切换为原文`,"data-testid":`file-toggle-raw`,"aria-pressed":d,onClick:()=>p(!d)}),(0,C.jsx)(`a`,{className:`icon-button`,"data-testid":`file-download`,"aria-label":o.download,title:o.download,href:l(t.sha256),download:t.path.split(`/`).at(-1),children:(0,C.jsx)(c,{name:`download`})})]})]}),m?(0,C.jsx)(`div`,{className:`empty`,children:(0,C.jsx)(`p`,{children:o.previewLarge})}):b.error?(0,C.jsxs)(`div`,{className:`preview-body`,children:[(0,C.jsx)(g,{error:!0,children:b.error}),(0,C.jsx)(`button`,{"data-testid":`file-preview-retry`,onClick:()=>void b.reload(),children:o.retry})]}):b.loading?(0,C.jsx)(`p`,{className:`preview-body`,role:`status`,children:o.loading}):(0,C.jsx)(`div`,{className:`preview-body`,children:v&&!d?(0,C.jsx)(`article`,{className:`markdown`,"data-testid":`file-content`,"data-format":`markdown`,children:(0,C.jsx)(_,{onLink:a,children:b.data??``})}):(0,C.jsx)(`pre`,{className:`raw`,"data-testid":`file-content`,"data-format":`text`,children:b.data})})]})}export{T as Files};
@@ -1,6 +0,0 @@
1
- import{$ as e,B as t,D as n,E as r,G as i,H as a,K as o,L as s,M as c,Q as l,R as u,V as d,X as f,Y as p,Z as m,_ as h,b as g,c as _,g as v,h as y,j as b,k as x,l as S,q as C,u as w,v as T,x as E}from"./index-BwEl1PIa.js";import{n as D,r as O,t as k}from"./Markdown-D3cU0ani.js";import{i as ee,r as te}from"./WorkspaceTree-DeAA1QtV.js";function A(e){return m(t,e)}var j=l(),M=C().regex(/^R\d{6,}$/),N=o({name:C().min(1),sha256:s,size:i().int().nonnegative()}),P=p().refine(e=>/^https?:\/\//i.test(e),`Use an HTTP or HTTPS URL.`);o({operationId:f(),title:C().trim().default(``),text:C().optional(),url:P.optional(),originals:a(N).default([])}).strict().refine(e=>!!e.text?.trim()||!!e.url||e.originals.length>0,`Provide text, a link or a file.`),o({expectedRevision:u,title:C().trim().min(1).optional(),content:C().optional(),summary:C().optional(),sourceVersion:C().optional(),contentDate:C().optional(),originals:a(N).optional()}).strict();var F=o({id:M,projectId:C(),title:C(),submittedBy:C(),createdAt:C(),revision:u,source:o({kind:d([`web`,`chat`,`group`]),url:C().nullable(),groupId:C().optional(),messageId:C().optional(),sourceVersion:C().optional(),contentDate:C().optional()}),originals:a(N),content:C().nullable(),summary:C().nullable(),state:d([`waiting`,`running`,`ready`,`failed`]),error:C().nullable(),url:C()}),I=o({materials:a(F),nextCursor:i().nullable()});o({query:C().trim().min(1),scope:d([`all`,`workspace`,`materials`]).default(`all`),materialId:M.optional(),originalHash:s.optional(),after:C().default(``),limit:A().int().min(1).max(200).default(30)}).strict();var L=o({items:a(o({key:C(),kind:d([`workspace`,`materials`]),title:C(),snippet:C(),url:C(),path:C()})),nextCursor:C().nullable()}),R=x();function ne(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 z(){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 B(){let{request:t,projectId:i}=S(),[a,o]=(0,j.useState)(z),[s,c]=(0,j.useState)(a),[l,u]=(0,j.useState)(()=>new Set(a?[a.id]:[])),[d,f]=(0,j.useState)(!1),[p,m]=(0,j.useState)(``),[g,v]=(0,j.useState)(``),[x,C]=(0,j.useState)(``),[D,O]=(0,j.useState)([]),[A,M]=(0,j.useState)(),[N,P]=(0,j.useState)(!1),[L,B]=(0,j.useState)(``),U=(0,j.useRef)(null),W=(0,j.useCallback)(e=>t(`materials`,I,{signal:e}),[t]),G=r(W,5e3,n(i,`materials`)),ie=(0,j.useCallback)(e=>a?t(`materials/${encodeURIComponent(a.id)}${a.revision?`?revision=${encodeURIComponent(a.revision)}`:``}`,F,{signal:e}):Promise.resolve(null),[t,a?.id,a?.revision]),K=r(ie,5e3),q=K.data?.id===a?.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=A===void 0?G.data?.nextCursor:A;function X(t,n=``){o(t),c(t),v(``),C(n),f(!1),u(e=>new Set([...e,t.id])),history.replaceState(null,``,e(`/projects/${i}/materials?${new URLSearchParams({...t})}`))}(0,j.useEffect)(()=>{let e=()=>{let e=z();o(e),c(e),v(``),m(``),C(``),f(!1),e&&u(t=>new Set([...t,e.id]))};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);async function ae(){if(Y&&!N){P(!0),B(``);try{let e=await t(`materials?before=${Y}`,I);O(t=>[...t,...e.materials]),M(e.nextCursor)}catch(e){B(b(e))}finally{P(!1)}}}let Z=J.find(e=>e.id===s?.id),Q=Z?.originals.find(e=>e.sha256===s?.original)?.name??Z?.title??`当前资料`;function $(){c(void 0),C(``),U.current?.focus()}return(0,R.jsxs)(`div`,{className:`split-layout file-explorer session-explorer`,"data-testid":`materials-page`,children:[(0,R.jsxs)(`aside`,{className:`file-tree-pane`,"aria-label":`资料目录`,children:[(0,R.jsx)(_,{title:`资料`,icon:`materials`,children:(0,R.jsx)(T,{icon:`plus`,label:`新增资料`,onClick:()=>{f(!0),B(``)}})}),(0,R.jsx)(E,{error:!0,children:G.error||L}),G.data?J.length===0?(0,R.jsx)(`p`,{className:`tree-status`,children:`暂无资料`}):(0,R.jsx)(`div`,{role:`tree`,"aria-label":`项目资料`,onKeyDown:te,children:J.map(e=>(0,R.jsxs)(`div`,{role:`none`,children:[(0,R.jsxs)(w,{role:`treeitem`,"aria-level":1,"aria-expanded":l.has(e.id),"aria-selected":!d&&a?.id===e.id&&!a.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,R.jsx)(`span`,{className:`tree-chevron ${l.has(e.id)?`expanded`:``}`,children:(0,R.jsx)(h,{name:`chevron`,size:`small`})}),children:[(0,R.jsx)(h,{name:`files`}),(0,R.jsx)(`span`,{className:`tree-name`,children:e.title})]}),l.has(e.id)&&(0,R.jsx)(`div`,{role:`group`,children:[...e.originals].sort((e,t)=>ee(e.name,t.name)).map((t,n)=>(0,R.jsxs)(w,{role:`treeitem`,"aria-level":2,"aria-selected":!d&&a?.id===e.id&&a.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===a?.id&&a.revision?{revision:a.revision}:{}}),leading:(0,R.jsx)(`span`,{className:`tree-chevron`}),children:[(0,R.jsx)(h,{name:`file`}),(0,R.jsx)(`span`,{className:`tree-name`,children:t.name})]},`${t.sha256}:${n}`))})]},e.id))}):(0,R.jsx)(`p`,{className:`tree-status`,children:`加载中…`}),Y&&(0,R.jsx)(`button`,{className:`tree-action`,disabled:N,onClick:()=>void ae(),children:N?`加载中…`:`加载更多`})]}),(0,R.jsxs)(`section`,{className:`session-reader`,"aria-label":`资料内容与搜索`,children:[(0,R.jsx)(`div`,{className:`session-reader-content`,children:d?(0,R.jsx)(re,{onCancel:()=>f(!1),onSaved:e=>{X({id:e}),G.reload()}}):g?(0,R.jsx)(V,{query:g,scope:s,onSelect:e=>X(e,g)},`${g}/${s?.id}/${s?.original}`):a?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(E,{error:!0,children:K.error}),q?a.original?(0,R.jsx)(H,{material:q,hash:a.original,highlight:x}):(0,R.jsxs)(`article`,{className:`material-body`,children:[(0,R.jsx)(`h1`,{children:q.title}),a.revision&&(0,R.jsx)(`button`,{className:`material-link`,onClick:()=>X({id:a.id}),children:`查看最新内容`}),!a.revision&&(q.state===`waiting`||q.state===`running`)?(0,R.jsx)(`p`,{className:`muted`,role:`status`,children:`正在整理…`}):null,(0,R.jsx)(E,{error:!0,children:q.error??``}),!a.revision&&q.state===`failed`&&(0,R.jsx)(`button`,{onClick:()=>void t(`materials/${a.id}/retry`,F,{method:`POST`}).then(()=>K.reload()).catch(e=>B(b(e))),children:`重试整理`}),q.content?(0,R.jsx)(`div`,{className:`markdown`,children:(0,R.jsx)(k,{highlight:x,children:ne(q)})}):(0,R.jsx)(`p`,{className:`muted`,children:`正文尚未整理,可以先查看左侧原件。`})]}):(0,R.jsx)(`p`,{role:`status`,children:`加载中…`})]}):(0,R.jsx)(y,{mascot:!0,title:`选择资料开始阅读`,description:`也可以在下方搜索资料内容。`})}),!d&&(0,R.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`material-search-form`,onSubmit:e=>{e.preventDefault(),v(p.trim()),C(``)},children:[s&&(0,R.jsxs)(`button`,{type:`button`,className:`search-scope-chip`,title:`清除搜索范围`,"aria-label":`清除范围:${Q}`,onClick:$,children:[(0,R.jsxs)(`span`,{className:`scope-label`,children:[`搜索:`,Q]}),(0,R.jsx)(`span`,{"aria-hidden":`true`,children:`×`})]}),(0,R.jsxs)(`div`,{className:`session-search-input-row`,children:[(0,R.jsx)(`input`,{ref:U,"aria-label":`搜索资料`,placeholder:`搜索资料内容`,value:p,onChange:e=>m(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!p&&s&&(e.preventDefault(),$())}}),(g||p||x)&&(0,R.jsx)(T,{icon:`close`,label:`清空搜索`,onClick:()=>{m(``),v(``),C(``),U.current?.focus()}}),(0,R.jsx)(T,{icon:`search`,type:`submit`,label:`搜索`,disabled:!p.trim()})]})]})]})]})}function V({query:e,scope:t,onSelect:n}){let{request:i}=S(),[a,o]=(0,j.useState)(``),s=(0,j.useCallback)(n=>i(`resources/search?${new URLSearchParams({query:e,scope:`materials`,after:a,...t?{materialId:t.id}:{},...t?.original?{originalHash:t.original}:{}})}`,L,{signal:n}),[i,e,t?.id,t?.original,a]),c=r(s);return(0,R.jsxs)(`section`,{className:`session-results stack`,"aria-label":`搜索结果`,children:[(0,R.jsx)(E,{error:!0,children:c.error}),c.loading?(0,R.jsx)(`p`,{role:`status`,children:`正在搜索…`}):c.data?.items.length===0?(0,R.jsx)(`p`,{className:`empty`,children:`没有找到匹配的资料`}):c.data?.items.map(t=>(0,R.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,R.jsx)(`strong`,{children:t.title.replace(/^R\d+ · /,``)}),(0,R.jsx)(`span`,{className:`session-excerpt`,children:(0,R.jsx)(D,{value:O(t.snippet,e),query:e})})]},t.key)),c.data?.nextCursor&&(0,R.jsx)(`button`,{disabled:c.loading,onClick:()=>o(c.data.nextCursor),children:`下一页`})]})}function H({material:t,hash:i,highlight:a}){let{projectId:o}=S(),s=t.originals.find(e=>e.sha256===i),c=e(`/api/v1/projects/${o}/materials/${t.id}/originals/${i}?revision=${t.revision}`),[l,u]=(0,j.useState)(!1),d=(0,j.useCallback)(async e=>{let t=await fetch(c,{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}},[c]),f=r(d,!1,n(o,`material-original`,i));if(!s)return(0,R.jsx)(E,{error:!0,children:`找不到此原件。`});let p=/\.(md|markdown)$/i.test(s.name);return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`header`,{className:`file-detail-header`,children:[(0,R.jsx)(`span`,{className:`file-detail-path`,children:s.name}),(0,R.jsxs)(`div`,{className:`toolbar-actions`,children:[p&&(0,R.jsx)(T,{icon:l?`preview`:`code`,label:l?`切换为预览`:`切换为原文`,onClick:()=>u(!l)}),(0,R.jsx)(`a`,{className:`icon-button`,"aria-label":`下载原件`,title:`下载原件`,href:c,download:s.name,children:(0,R.jsx)(h,{name:`download`})})]})]}),(0,R.jsx)(E,{error:!0,children:f.error}),f.loading?(0,R.jsx)(`p`,{role:`status`,children:`加载中…`}):f.data===null?(0,R.jsx)(`p`,{className:`muted`,children:`此格式请下载后查看。`}):f.data!==void 0&&(0,R.jsx)(`div`,{className:`preview-body`,"data-testid":`material-original-content`,children:p&&!l?(0,R.jsx)(`article`,{className:`markdown`,children:(0,R.jsx)(k,{highlight:a,children:f.data})}):(0,R.jsx)(`pre`,{className:`raw`,children:(0,R.jsx)(D,{value:f.data,query:a})})})]})}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:t,onCancel:n}){let{request:r,projectId:i}=S(),[a,o]=(0,j.useState)([]),[s,l]=(0,j.useState)(),[u,d]=(0,j.useState)(!1),[f,p]=(0,j.useState)(``),m=(0,j.useRef)(null),_=(0,j.useRef)(c()),y=(0,j.useRef)(new Map);function x(e){o(e),_.current=c(),p(``)}async function C(){d(!0),p(``);try{let n=[];for(let[t,r]of a.entries()){let a=y.current.get(r.id);if(!a){let n=r.kind===`file`?r.file.name:`${W(r.text)}.txt`,o=await fetch(e(`/api/v1/projects/${i}/materials/uploads`),{method:`POST`,headers:{"content-type":`application/octet-stream`,"x-teammy-web":`1`},body:r.kind===`file`?r.file:new Blob([r.text],{type:`text/plain`})}),s=await o.json();if(!o.ok)throw Error(s.error?.message??`第 ${t+1} 项上传失败。`);a={name:n,sha256:s.sha256,size:s.size},y.current.set(r.id,a)}n.push(a)}let o=a.length===1&&a[0]?.kind===`text`?a[0].text.trim():``,s;try{let e=new URL(o);[`http:`,`https:`].includes(e.protocol)&&(s=e.href)}catch{}t((await r(`materials`,F,{method:`POST`,body:{operationId:_.current,originals:n,...s?{url:s}:{}}})).id)}catch(e){p(b(e))}finally{d(!1)}}return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`form`,{className:`material-form`,onSubmit:e=>{e.preventDefault(),C()},children:[(0,R.jsx)(`h1`,{children:`新增资料`}),(0,R.jsx)(`p`,{className:`muted`,children:`上传附件到项目,以便于提百事进行理解`}),(0,R.jsx)(E,{error:!0,children:f}),(0,R.jsxs)(`fieldset`,{disabled:u,children:[(0,R.jsxs)(`div`,{className:`attachment-grid`,children:[a.map(e=>(0,R.jsxs)(`article`,{className:`attachment-card`,"data-testid":`attachment-card`,children:[e.kind===`text`?(0,R.jsxs)(`button`,{type:`button`,className:`attachment-content`,"aria-label":`编辑:${W(e.text)}`,onClick:()=>l({id:e.id,text:e.text}),children:[(0,R.jsx)(h,{name:U(e)}),(0,R.jsx)(`span`,{className:`attachment-name`,children:W(e.text)}),G(e.text)&&(0,R.jsx)(`span`,{className:`attachment-excerpt`,children:G(e.text)})]}):(0,R.jsxs)(`div`,{className:`attachment-content`,children:[(0,R.jsx)(h,{name:U(e)}),(0,R.jsx)(`span`,{className:`attachment-name`,children:e.file.name})]}),(0,R.jsx)(T,{className:`attachment-remove`,icon:`close`,label:`移除:${e.kind===`file`?e.file.name:W(e.text)}`,onClick:()=>{y.current.delete(e.id),x(a.filter(t=>t.id!==e.id))}})]},e.id)),(0,R.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>l({text:``}),children:[(0,R.jsx)(h,{name:`addText`}),(0,R.jsx)(`span`,{children:`添加文本/链接`})]}),(0,R.jsxs)(`button`,{type:`button`,className:`attachment-add`,onClick:()=>m.current?.click(),children:[(0,R.jsx)(h,{name:`addFile`}),(0,R.jsx)(`span`,{children:`添加文件`})]})]}),(0,R.jsx)(`input`,{ref:m,type:`file`,multiple:!0,hidden:!0,"aria-label":`原始文件`,onChange:e=>{x([...a,...[...e.target.files??[]].map(e=>({id:c(),kind:`file`,file:e}))]),e.target.value=``}}),(0,R.jsxs)(`div`,{className:`actions attachment-actions`,children:[(0,R.jsx)(`button`,{type:`button`,onClick:n,children:`取消`}),(0,R.jsx)(`button`,{type:`submit`,className:`primary`,disabled:!a.length,children:u?`上传中…`:`提交资料`})]})]})]}),s&&(0,R.jsx)(g,{id:`material-text-editor`,title:`添加文本/链接`,onClose:()=>l(void 0),children:(0,R.jsxs)(`form`,{className:`stack`,onSubmit:e=>{if(e.preventDefault(),!s.text.trim())return;let t={id:s.id??c(),kind:`text`,text:s.text};y.current.delete(t.id),x(s.id?a.map(e=>e.id===s.id?t:e):[...a,t]),l(void 0)},children:[(0,R.jsx)(v,{id:`material-attachment-text`,label:`文本或链接`,children:(0,R.jsx)(`textarea`,{autoFocus:!0,rows:8,value:s.text,onChange:e=>l({...s,text:e.target.value}),placeholder:`粘贴文本或网页链接`})}),(0,R.jsx)(`div`,{className:`actions`,children:(0,R.jsx)(`button`,{type:`submit`,className:`primary`,disabled:!s.text.trim(),children:s.id?`保存`:`添加`})})]})})]})}export{B as Materials};
@@ -1 +0,0 @@
1
- import{$ as e,A as t,D as n,E as r,F as i,G as a,H as o,J as s,K as c,L as l,N as u,P as d,Q as f,R as p,T as m,U as h,V as g,W as _,X as v,_ as y,c as b,h as x,j as S,k as C,l as w,q as T,u as E,v as D,w as O,x as k,z as A}from"./index-BwEl1PIa.js";import{n as j,r as M,t as N}from"./Markdown-D3cU0ani.js";import{n as P}from"./project-links-XbF78Bal.js";import{i as F,r as I}from"./WorkspaceTree-DeAA1QtV.js";var L=f(),R=g([`overview`,`handoff`]),z=c({title:T().trim().min(1),summary:T().trim().min(1)}).strict(),B=c({markdown:T().trim().min(1)}).strict(),V=z.extend({sourceRevision:p,sourceHash:l,generatedAt:T(),stale:h()}),H=c({kind:R,status:g([`absent`,`queued`,`running`,`succeeded`,`failed`]),available:h(),currentRevision:p,sourceRevision:p.nullable(),stale:h(),result:s([z,B]).nullable(),generatedAt:T().nullable(),error:T().nullable()}),U=g([`claude-code`,`codex`,`cursor`,`pi`,`dsh`]),W=c({formatVersion:_(1),adapterVersion:_(1),agent:U,nativeId:T().min(1).max(512),cwd:T().min(1).max(4096),messages:o(c({id:T().min(1).max(1024),role:g([`user`,`assistant`]),text:T().min(1),source:T().min(1).max(1024)}).strict())}).strict().refine(e=>new Set(e.messages.map(e=>e.id)).size===e.messages.length,`Duplicate message IDs.`);c({operationId:v(),sessionKey:l,parentRevision:p,blob:i}).strict();var G=c({owner:A,sessionKey:l,agent:U,nativeId:T(),cwd:T(),title:T(),revision:p,updatedAt:T(),messageCount:a().int().nonnegative(),blob:i,overview:V.optional()}),K=c({sessions:o(G),nextCursor:p.nullable()}),q=c({totalSessions:a().int().nonnegative(),totalMessages:a().int().nonnegative(),memberCount:a().int().nonnegative(),updatedAt:T().nullable()});c({owner:A.optional(),sessionKey:l.optional()}).strict().refine(e=>!e.sessionKey||!!e.owner,`A session scope requires an owner.`);var J=c({matches:o(c({owner:A,sessionKey:l,revision:p,messageId:T(),role:g([`user`,`assistant`]),snippet:T(),title:T()})),nextCursor:p.nullable()}),Y=c({owner:A,key:l,revision:p.refine(e=>e>0).optional(),messageId:T().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=C();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)(E,{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)(y,{name:`chevron`,size:`small`})}),children:[(0,Z.jsx)(y,{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:i,focused:a,onFocus:o}){let{request:s,projectId:c}=w(),l=(0,L.useCallback)(t=>s(`sessions?${new URLSearchParams({owner:e,limit:`50`,order:`updated`})}`,K,{signal:t}),[e,s]),d=r(l,15e3,n(c,`session-tree`,e)),[f,p]=(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 b=f?f.nextCursor:d.data?.nextCursor;return(0,Z.jsxs)(`div`,{role:`group`,"aria-busy":d.loading||m,children:[(0,Z.jsx)(k,{error:!0,children:d.error||g}),d.error&&(0,Z.jsx)(`button`,{onClick:()=>void d.reload(),children:`重试`}),d.loading&&!d.data&&(0,Z.jsx)(`span`,{className:`tree-status`,role:`status`,children:`正在加载…`}),[...new Map([...f?.sessions??[],...d.data?.sessions??[]].map(e=>[e.sessionKey,e])).values()].sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt)||e.sessionKey.localeCompare(t.sessionKey)).map(n=>(0,Z.jsxs)(E,{type:`button`,role:`treeitem`,"aria-level":2,"aria-selected":t?.owner===e&&t.key===n.sessionKey,className:`tree-item`,style:{"--tree-level":2},tabIndex:a===`${e}/${n.sessionKey}`?0:-1,"data-testid":`session-row`,"data-owner-id":e,"data-session-key":n.sessionKey,title:u(n.title||n.nativeId),onFocus:()=>o(`${e}/${n.sessionKey}`),onClick:()=>i({owner:e,key:n.sessionKey,title:n.title||n.nativeId}),leading:(0,Z.jsx)(`span`,{className:`tree-chevron`}),children:[(0,Z.jsx)(y,{name:`sessions`}),(0,Z.jsx)(`span`,{className:`tree-name`,children:u(n.title||n.nativeId)})]},n.sessionKey)),b!=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(b),limit:`50`,order:`updated`})}`,K,{signal:t.signal});p(e=>({sessions:[...e?.sessions??[],...n.sessions],nextCursor:n.nextCursor}))}catch(e){t.signal.aborted||_(S(e))}finally{t.signal.aborted||h(!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}=w(),n=`sessions/${encodeURIComponent(e.owner)}/${e.sessionKey}`,i=(0,L.useCallback)(e=>t(`${n}/analysis/handoff`,H,{signal:e}),[t,n]),a=r(i,5e3),o=m(),[s,c]=(0,L.useState)(!1),[l,u]=(0,L.useState)(``),d=a.data,f=s||d?.status===`queued`||d?.status===`running`,p=d?.result&&`markdown`in d.result?d.result.markdown:void 0;return(0,Z.jsxs)(`div`,{className:`stack`,"data-testid":`session-handoff`,children:[(0,Z.jsx)(k,{error:!0,children:l||a.error}),d&&(0,Z.jsxs)(`div`,{className:`inline-actions`,children:[(!p||d.stale)&&(0,Z.jsx)(`button`,{"data-testid":`session-handoff-generate`,disabled:f||!d.available,onClick:async()=>{c(!0),u(``);try{await t(`${n}/handoff`,H,{method:`POST`,signal:o}),await a.reload()}catch(e){o.aborted||u(S(e))}finally{o.aborted||c(!1)}},children:f?`正在整理…`:d.status===`failed`?`重新生成`:p?`更新交接说明`:`生成交接说明`}),!d.available&&(0,Z.jsx)(`small`,{children:`请先配置项目模型接入点`}),d.status===`failed`&&(0,Z.jsx)(`small`,{children:`整理未完成,可重试`}),d.stale&&(0,Z.jsx)(`small`,{children:`对话已有新内容`}),d.currentRevision!==e.revision&&(0,Z.jsx)(`small`,{children:`交接说明使用最新对话;当前阅读的是历史原文`})]}),p&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`small`,{children:[`基于版本 `,d.sourceRevision,` · `,(0,Z.jsx)(O,{value:d.generatedAt})]}),(0,Z.jsx)(`div`,{className:`markdown`,"data-testid":`session-handoff-body`,children:(0,Z.jsx)(N,{children:p})})]})]})}function ne({members:t}){let{request:i,projectId:a,api:o}=w(),s=(0,L.useCallback)(async e=>{let[t,n]=await Promise.all([i(`sessions/stats`,q,{signal:e}),o.members(e)]);return{...t,members:n.members}},[i,o]),c=r(s,!0,n(a,`session-stats`)),[l,f]=(0,L.useState)(``),[p,m]=(0,L.useState)(``),[h,g]=(0,L.useState)(0),[_]=(0,L.useState)(()=>X(location.search)),[v,y]=(0,L.useState)(_.target),[S,C]=(0,L.useState)(_.target),[T,E]=(0,L.useState)(_.error??``),[O,A]=(0,L.useState)(``),j=(0,L.useRef)(null),M=v?.key?v.title?`搜索对话:${u(v.title)}`:`搜索当前对话`:v?`搜索:${v.owner} 的对话内容`:``,N=()=>{y(void 0),A(``),F(),j.current?.focus()};function F(){if(!S?.messageId)return;let{messageId:t,...n}=S;C(n),history.replaceState(null,``,e(P(a,n.owner,n.key,n)))}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);C(e.target),y(e.target),E(e.error??``),m(``),f(``),A(``)};return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[]);let R=(t,n=``)=>{C(t),y(t),m(``),A(n),E(``),history.replaceState(null,``,e(P(a,t.owner,t.key,t)))};return(0,Z.jsxs)(`div`,{className:`split-layout file-explorer session-explorer`,children:[(0,Z.jsxs)(`section`,{className:`file-tree-pane`,"aria-label":`${d.sessions}目录`,children:[(0,Z.jsx)(b,{title:d.sessions,icon:`sessions`,count:(0,Z.jsx)(`span`,{"data-testid":`session-total`,children:c.data?.totalSessions??`—`}),children:(0,Z.jsx)(D,{icon:`refresh`,label:`刷新${d.sessions}`,"data-testid":`sessions-refresh`,disabled:c.loading,onClick:()=>{c.reload(),g(e=>e+1)}})}),(0,Z.jsx)(k,{error:!0,children:c.error}),(0,Z.jsx)(Q,{members:(c.data?.members??t).filter(e=>e.hasSessions),refresh:h,selected:v,onOwner:t=>{y({owner:t}),C(void 0),m(``),A(``),E(``),history.replaceState(null,``,e(`/projects/${encodeURIComponent(a)}/sessions`))},onSession:R})]}),(0,Z.jsxs)(`section`,{className:`session-reader`,"aria-label":`对话内容与搜索`,children:[(0,Z.jsx)(`div`,{className:`session-reader-content`,children:T?(0,Z.jsx)(k,{error:!0,children:T}):p?(0,Z.jsx)(re,{query:p,refresh:h,scope:{...v?{owner:v.owner}:{},...v?.key?{sessionKey:v.key}:{}},onSelect:e=>R(e,p)},`${p}/${v?.owner??``}/${v?.key??``}`):S?(0,Z.jsx)(ie,{selection:S,highlight:O,onLoaded:I,onLatest:()=>R({owner:S.owner,key:S.key})},`${S.owner}/${S.key}/${S.revision}/${h}`):(0,Z.jsx)(x,{mascot:!0,title:`选择对话开始阅读`,description:`也可以在下方搜索会话库内容。`})}),(0,Z.jsxs)(`form`,{className:`session-search-dock`,"data-testid":`session-search-form`,onSubmit:e=>{e.preventDefault(),m(l.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:l,maxLength:500,placeholder:`搜索会话库内容`,onChange:e=>f(e.target.value),onKeyDown:e=>{e.key===`Backspace`&&!l&&v&&(e.preventDefault(),N())}}),(p||l||O)&&(0,Z.jsx)(D,{icon:`close`,label:`清空搜索`,"data-testid":`session-search-clear`,onClick:()=>{f(``),m(``),A(``),F(),j.current?.focus()}}),(0,Z.jsx)(D,{icon:`search`,type:`submit`,label:`搜索`,"data-testid":`session-search`,disabled:!l.trim()})]})]})]})]})}function re({query:e,refresh:t,scope:n,onSelect:i}){let{request:a}=w(),[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)(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:()=>i({owner:t.owner,key:t.sessionKey,revision:t.revision,messageId:t.messageId,title:t.title}),children:[(0,Z.jsx)(`strong`,{children:u(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:n,onLoaded:i,onLatest:a}){let{request:o}=w(),s=(0,L.useCallback)(async n=>{try{return await o(`sessions/${encodeURIComponent(e.owner)}/${e.key}${e.revision===void 0?``:`?revision=${e.revision}`}`,G,{signal:n})}catch(e){throw e instanceof t&&e.code===`SESSION_NOT_FOUND`?Error(`找不到这条对话或引用的版本,原链接可能已失效。`):e}},[o,e.owner,e.key,e.revision]),c=r(s,5e3);return(0,L.useEffect)(()=>{c.data&&i(c.data)},[c.data,i]),(0,Z.jsxs)(`section`,{className:`session-conversation stack`,"data-testid":`session-detail`,children:[(0,Z.jsx)(k,{error:!0,children:c.error}),c.error&&(0,Z.jsx)(`button`,{onClick:()=>void c.reload(),children:`重试`}),c.loading&&!c.data&&(0,Z.jsx)(`p`,{role:`status`,children:`正在读取对话…`}),c.data&&(0,Z.jsx)(ae,{info:c.data,messageId:e.messageId,highlight:n,pinned:e.revision!==void 0,onLatest:a},c.data.blob.sha256)]})}function ae({info:t,messageId:n,highlight:i,pinned:a,onLatest:o}){let{readTextBlob:s,projectId:c}=w(),l=(0,L.useCallback)(async e=>W.parse(JSON.parse(await s(t.blob,e))),[t.blob.sha256,t.blob.size]),d=r(l),f=(0,L.useRef)(null);return(0,L.useEffect)(()=>{d.data&&n&&f.current?.scrollIntoView({block:`center`})},[d.data,n]),(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsxs)(`header`,{className:`conversation-header`,children:[(0,Z.jsx)(`h2`,{className:`session-title`,children:u(t.title||t.nativeId)}),(0,Z.jsxs)(`p`,{children:[t.owner,` · `,t.agent,` · `,t.messageCount,` 条消息`]}),(0,Z.jsxs)(`small`,{children:[(0,Z.jsx)(O,{value:t.updatedAt}),a&&(0,Z.jsxs)(Z.Fragment,{children:[` `,`· 引用版本 `,t.revision,` ·`,` `,(0,Z.jsx)(`a`,{href:e(P(c,t.owner,t.sessionKey)),onClick:e=>{e.preventDefault(),o()},children:`查看最新`})]})]}),t.overview&&(0,Z.jsx)(`p`,{"data-testid":`session-summary`,children:t.overview.summary}),t.overview?.stale&&(0,Z.jsx)(`small`,{children:`摘要待更新`})]}),(0,Z.jsx)(ee,{info:t}),(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:[n&&!d.data.messages.some(e=>e.id===n)&&(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===n?`matched`:``}`,"data-testid":`session-message`,"data-message-id":e.id,ref:e.id===n?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};
@@ -1 +0,0 @@
1
- import{D as e,E as t,Q as n,_ as r,j as i,k as a,l as o,o as s,s as c,u as l,x as u}from"./index-BwEl1PIa.js";var d=n(),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=a();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:s,path:``,level:1,members:e.filter(e=>e.hasFiles),context:{...t,focused:n,onFocus:r}})})}function y({owner:e,path:t,level:n,context:i}){let a=i.expanded.has(g(e,t)),o=`folder:${g(e,t)}`;return(0,m.jsxs)(`div`,{role:`none`,children:[(0,m.jsxs)(l,{type:`button`,role:`treeitem`,className:`tree-item tree-folder`,style:_(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,m.jsx)(`span`,{className:`tree-chevron ${a?`expanded`:``}`,children:(0,m.jsx)(r,{name:`chevron`,size:`small`})}),children:[(0,m.jsx)(r,{name:`files`}),(0,m.jsx)(`span`,{className:`tree-name`,children:t.split(`/`).at(-1)||e})]}),a&&(0,m.jsx)(b,{owner:e,path:t,level:n+1,context:i})]})}function b({owner:n,path:a,level:s,context:f,members:h=[]}){let{api:v,projectId:b}=o(),x=(0,d.useCallback)(e=>v.tree(n,a,void 0,``,e),[n,a]),S=t(x,!1,e(b,`file-tree`,n,a)),[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 e=new AbortController;k.current=e;try{let t=await v.tree(n,a,S.data.revision,j,e.signal);e.signal.aborted||w({...t,entries:[...A?.entries??[],...t.entries]})}catch(t){e.signal.aborted||O(i(t))}finally{e.signal.aborted||E(!1)}}let N=[...(S.data?.entries??[]).filter(e=>!c(e.path)),...(A?.entries??[]).filter(e=>!c(e.path))],P=f.revealed;if(P?.owner===n&&!c(P.path)&&(!a||P.path.startsWith(a+`/`))){let e=a?P.path.slice(a.length+1):P.path,t=e.indexOf(`/`),n=t<0?P.path:[a,e.slice(0,t)].filter(Boolean).join(`/`);N.some(e=>e.path===n)||N.push(t<0?{...P.file,kind:`file`}:{kind:`directory`,path:n})}let F=[...N.map(e=>({...e,owner:n})),...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(n===`_project`?`workspaces`:n,a),"aria-busy":S.loading||T,children:[S.loading&&(0,m.jsx)(`p`,{className:`tree-status`,role:`status`,children:`正在加载…`}),(0,m.jsx)(u,{error:!0,children:S.error||D}),S.error&&(0,m.jsx)(`button`,{className:`tree-action`,onClick:()=>void S.reload(),children:`重试`}),F.map(e=>e.kind===`directory`?(0,m.jsx)(y,{owner:e.owner,path:e.path,level:s,context:f},g(e.owner,e.path)):(0,m.jsxs)(l,{type:`button`,role:`treeitem`,className:`tree-item`,style:_(s),"aria-label":e.path,"aria-level":s,"aria-selected":f.selected?.kind===`file`&&f.selected.owner===n&&f.selected.path===e.path,tabIndex:f.focused===`file:${g(n,e.path)}`?0:-1,"data-testid":`file-row`,"data-owner-id":n,"data-file-path":e.path,onFocus:()=>f.onFocus(`file:${g(n,e.path)}`),onClick:()=>f.onSelect(n,e.path),leading:(0,m.jsx)(`span`,{className:`tree-chevron`}),children:[(0,m.jsx)(r,{name:`file`}),(0,m.jsx)(`span`,{className:`tree-name`,children:e.path.split(`/`).at(-1)})]},e.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};