@teammy/server 0.0.8 → 0.0.9

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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="theme-color" content="#161615" />
7
7
  <title>Teammy · 团队工作台</title>
8
- <script type="module" crossorigin src="/assets/index-f4fiI3WA.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CETlKRD0.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-hjEc8Pme.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teammy/server",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "The centralized Teammy collaboration hub server.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,6 +27,7 @@
27
27
  "@earendil-works/pi-ai": "1.4.0",
28
28
  "@earendil-works/pi-coding-agent": "1.4.0",
29
29
  "@fastify/static": "^10.1.7",
30
+ "diff": "8.0.4",
30
31
  "fastify": "5.12.7",
31
32
  "zod": "4.6.7"
32
33
  }
@@ -1 +0,0 @@
1
- import{B as e,C as t,D as n,E as r,H as i,I as a,R as o,S as s,T as c,_ as l,a as u,b as d,c as f,d as p,f as m,g as h,h as g,i as _,l as v,o as y,p as b,s as x,u as S,v as C,w,x as T,y as E,z as D}from"./index-f4fiI3WA.js";var O=i(),k=t();function A({members:e,me:t,seed:i,initialProfile:a,initialQuestion:o,onCreated:s}){let{ai:l,request:u}=_(),d=c(l.profiles),p=w(),[m,h]=(0,O.useState)(i??{owner:t,kind:`directory`,path:``}),[v,y]=(0,O.useState)(a??``),[b,S]=(0,O.useState)(o??``),[C,T]=(0,O.useState)(!1),[D,A]=(0,O.useState)(``),j=(0,O.useRef)({fingerprint:``,id:n()}),M=d.data?.profiles.filter(e=>e.enabled)??[],N=d.data?.defaults,P=v,F=P?M.some(e=>e.id===P):N?.available;async function I(){if(!C){T(!0),A(``);try{let e={...P?{profileId:P}:{},workflow:m.kind===`file`?`file-summary`:`directory-analysis`,selection:m,question:b},t=JSON.stringify(e);j.current.fingerprint!==t&&(j.current={fingerprint:t,id:n()});let r=await u(`ai/jobs`,f,{method:`POST`,body:x.parse({...e,operationId:j.current.id}),signal:p});j.current={fingerprint:``,id:n()},s(r.job)}catch(e){p.aborted||A(r(e))}finally{T(!1)}}}return(0,k.jsxs)(`form`,{className:`panel stack`,"data-testid":`ai-job-form`,onSubmit:e=>{e.preventDefault(),I()},children:[(0,k.jsx)(`h2`,{children:`新建分析`}),(0,k.jsxs)(`fieldset`,{className:`stack`,disabled:C,children:[(0,k.jsxs)(`div`,{className:`form-grid`,children:[(0,k.jsx)(g,{id:`ai-job-profile`,label:`使用模型`,children:(0,k.jsxs)(`select`,{value:P,onChange:e=>y(e.target.value),children:[(0,k.jsx)(`option`,{value:``,disabled:!N?.available,children:N?.available?`默认 · ${M.find(e=>e.id===N.effectiveProfileId)?.name??``}`:`请选择模型`}),M.map(e=>(0,k.jsx)(`option`,{value:e.id,children:e.name},e.id))]})}),(0,k.jsx)(g,{id:`ai-job-owner`,label:`资料所属成员`,children:(0,k.jsx)(`select`,{value:m.owner,onChange:e=>h({owner:e.target.value,kind:m.kind,path:``}),children:e.map(e=>(0,k.jsxs)(`option`,{value:e.id,children:[e.displayName,` · `,e.id]},e.id))})}),(0,k.jsx)(g,{id:`ai-job-kind`,label:`分析范围`,children:(0,k.jsxs)(`select`,{value:m.kind,onChange:e=>h({...m,kind:e.target.value,path:``}),children:[(0,k.jsx)(`option`,{value:`directory`,children:`目录分析`}),(0,k.jsx)(`option`,{value:`file`,children:`单文件摘要`})]})}),(0,k.jsx)(g,{id:`ai-job-path`,label:`成员目录内的路径`,hint:m.kind===`directory`?`留空表示该成员的整个目录。`:`例如 review/notes.md`,children:(0,k.jsx)(`input`,{required:m.kind===`file`,maxLength:1024,value:m.path,onChange:e=>h({...m,path:e.target.value})})})]}),(0,k.jsx)(g,{id:`ai-job-question`,label:`关注的问题(可选)`,children:(0,k.jsx)(`textarea`,{rows:2,maxLength:2e3,value:b,onChange:e=>S(e.target.value)})}),m.revision!==void 0&&(0,k.jsxs)(E,{children:[`已选择目录版本 v`,m.revision,`。`,` `,(0,k.jsx)(`button`,{type:`button`,"data-testid":`ai-use-latest`,onClick:()=>{let{revision:e,...t}=m;h(t)},children:`改用最新版本`})]})]}),(0,k.jsx)(`p`,{className:`muted`,children:`使用提交时的资料版本,结果向团队共享。`}),!d.loading&&!M.length&&(0,k.jsx)(E,{children:`请管理员先在“设置 → 模型接入”中添加并启用模型。`}),(0,k.jsx)(E,{error:!0,children:d.error||D}),(0,k.jsx)(`button`,{className:`primary`,"data-testid":`ai-job-submit`,disabled:C||!F,children:C?`正在提交…`:`开始分析`})]})}var j=D({path:e(),startLine:o(),endLine:o(),totalLines:o(),content:e(),hasMore:a()});function M({id:e,session:t,onChanged:i,onUpdated:a,onLatest:o}){let{ai:l,request:d}=_(),p=(0,O.useRef)(0),m=w(),[h,g]=(0,O.useState)([]),v=(0,O.useCallback)(async t=>{let[n,r]=await Promise.all([l.detail(e,t),l.events(e,p.current,t)]);return t.aborted||(p.current=r.nextCursor,g(e=>[...e,...r.events].slice(-200))),n},[e]),[b,x]=(0,O.useState)(3e3),S=c(v,b),C=S.data?.job;(0,O.useEffect)(()=>{C&&a(C)},[C,a]),(0,O.useEffect)(()=>{C&&x([`queued`,`running`].includes(C.status)?3e3:3e4)},[C?.status]);let[T,D]=(0,O.useState)(!1),[A,j]=(0,O.useState)(``),[M,P]=(0,O.useState)(),F=(0,O.useRef)(n()),I=C&&(t.siteRole===`admin`||C.requester===t.memberId);async function L(t){if(!T){D(!0),j(``);try{await d(`ai/jobs/${e}/${t}`,f,{method:`POST`,...t===`retry`?{body:{operationId:F.current}}:{},signal:m}),F.current=n(),await S.reload(),i()}catch(e){m.aborted||j(r(e))}finally{D(!1)}}}return(0,k.jsxs)(`section`,{className:`panel stack`,"data-testid":`ai-job-detail`,"data-job-id":e,"data-status":C?.status,children:[(0,k.jsxs)(`div`,{className:`section-heading`,children:[(0,k.jsx)(`h2`,{children:`分析详情`}),(0,k.jsx)(`button`,{"data-testid":`ai-detail-refresh`,disabled:S.loading,onClick:()=>void S.reload(),children:`刷新进度`})]}),(0,k.jsx)(E,{error:!0,children:S.error||A}),C&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsxs)(`div`,{children:[(0,k.jsx)(`span`,{className:`badge`,children:u[C.status]}),` `,(0,k.jsx)(`strong`,{children:y[C.workflow]})]}),(0,k.jsxs)(`p`,{className:`ai-break`,children:[C.input.owner,`/`,C.input.path||`(全部文件)`,` · v`,C.input.revision,` ·`,` `,C.input.fileCount,` 个文件`,(0,k.jsx)(`br`,{}),C.model,` · 由 `,C.requester,` 发起 · `,(0,k.jsx)(s,{value:C.createdAt})]}),C.question&&(0,k.jsx)(`p`,{children:C.question}),C.status===`queued`&&(0,k.jsx)(`small`,{children:`等待独立 AI Worker 领取任务;若长时间未开始,请管理员检查 Worker 是否运行。`}),C.error&&(0,k.jsxs)(E,{error:!0,children:[`本次分析未完成:`,C.error]}),C.sourceChanged&&(0,k.jsx)(E,{children:`来源已有新版本,本结果仍对应提交时的资料。`}),(0,k.jsxs)(`div`,{className:`row wrap`,children:[I&&[`queued`,`running`].includes(C.status)&&(0,k.jsx)(`button`,{"data-testid":`ai-job-cancel`,disabled:T,onClick:()=>void L(`cancel`),children:`取消任务`}),I&&[`failed`,`cancelled`].includes(C.status)&&(0,k.jsx)(`button`,{"data-testid":`ai-job-retry`,disabled:T,onClick:()=>void L(`retry`),children:`重试原版本`}),(0,k.jsx)(`button`,{"data-testid":`ai-job-latest`,disabled:T,onClick:()=>o(C),children:`分析最新版本…`})]}),C.result&&`summary`in C.result&&(0,k.jsxs)(`article`,{className:`stack ai-result`,"data-testid":`ai-result`,children:[(0,k.jsx)(`h3`,{children:`摘要`}),(0,k.jsx)(`p`,{children:C.result.summary}),C.result.findings.length>0&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`h3`,{children:`主要发现`}),(0,k.jsx)(`ul`,{children:C.result.findings.map((e,t)=>(0,k.jsx)(`li`,{children:e},t))})]}),C.result.uncertainties.length>0&&(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(`h3`,{children:`待确认事项`}),(0,k.jsx)(`ul`,{children:C.result.uncertainties.map((e,t)=>(0,k.jsx)(`li`,{children:e},t))})]}),(0,k.jsxs)(E,{children:[`已读 `,C.result.coverage.readFiles.length,` / `,C.result.coverage.totalFiles,` `,`个文件 · `,C.result.coverage.partial?`未完整覆盖全部内容`:`已完整读取所选内容`]}),C.result.coverage.limitations.map((e,t)=>(0,k.jsx)(`p`,{children:e},t)),(0,k.jsx)(`h3`,{children:`引用来源`}),(0,k.jsx)(`div`,{className:`stack`,children:C.result.citations.map((e,t)=>(0,k.jsxs)(`button`,{className:`ai-citation`,"data-testid":`ai-citation`,onClick:()=>P(e),children:[e.path,`:`,e.startLine,`–`,e.endLine]},t))}),M&&(0,k.jsx)(N,{id:e,citation:M},`${M.path}:${M.startLine}`)]}),(0,k.jsxs)(`details`,{open:C.status===`running`,children:[(0,k.jsx)(`summary`,{children:`执行进度(最近 200 条)`}),(0,k.jsx)(`ol`,{className:`ai-events`,"data-testid":`ai-events`,children:h.map(e=>(0,k.jsxs)(`li`,{children:[`第 `,e.attempt,` 次 · `,e.message]},e.seq))})]}),(0,k.jsxs)(`details`,{children:[(0,k.jsxs)(`summary`,{children:[`执行记录 · `,S.data.attempts.length,` 次`]}),S.data.attempts.map(e=>(0,k.jsxs)(`p`,{children:[`第 `,e.number,` 次 · `,e.status,` · `,(0,k.jsx)(s,{value:e.startedAt}),e.error&&` · ${e.error}`,e.usage&&` · 输入 ${e.usage.inputTokens} / 输出 ${e.usage.outputTokens} token`]},e.number))]})]})]})}function N({id:e,citation:t}){let{request:n}=_(),r=(0,O.useCallback)(r=>n(`ai/jobs/${e}/source?${new URLSearchParams({path:t.path,startLine:String(t.startLine)})}`,j,{signal:r}),[e,t.path,t.startLine]),i=c(r);return(0,k.jsxs)(`div`,{"data-testid":`ai-source`,children:[(0,k.jsx)(`small`,{children:`提交时的原文 · 最多 100 行`}),(0,k.jsx)(E,{error:!0,children:i.error}),i.data&&(0,k.jsx)(`pre`,{className:`raw`,children:i.data.content})]})}function P({session:e,members:t,seed:n}){let{ai:r}=_(),[i,a]=(0,O.useState)(!!n),[o,s]=(0,O.useState)(``),l=(0,O.useCallback)(e=>r.jobs(o,e),[o]),d=c(l,!0),[f,p]=(0,O.useState)(``),[h,g]=(0,O.useState)(),[v,b]=(0,O.useState)(),[x,S]=(0,O.useState)(),[C,w]=(0,O.useState)(n),[T,D]=(0,O.useState)(0),j=()=>{s(``),d.reload()};return(0,k.jsxs)(`section`,{className:`board-analysis`,"data-testid":`board-analysis`,children:[(0,k.jsxs)(`div`,{className:`section-heading`,children:[(0,k.jsx)(`h2`,{children:`手动分析`}),(0,k.jsx)(`button`,{"data-testid":`board-analyze`,onClick:()=>a(e=>!e),children:i?`收起`:`新建分析`})]}),(0,k.jsxs)(`div`,{className:`ai-grid ${!f&&!i?`ai-grid-idle`:``}`,children:[(0,k.jsxs)(`div`,{className:`stack`,children:[i&&(0,k.jsx)(A,{members:t,me:e.memberId,seed:C,initialProfile:v,initialQuestion:x,onCreated:e=>{p(e.id),j()}},T),(0,k.jsxs)(`section`,{className:`panel stack`,children:[(0,k.jsxs)(`div`,{className:`section-heading`,children:[(0,k.jsx)(`h3`,{children:`分析记录`}),(0,k.jsx)(`button`,{"data-testid":`ai-list-refresh`,onClick:j,children:`刷新`})]}),(0,k.jsx)(E,{error:!0,children:d.error}),d.data?.jobs.length===0&&(0,k.jsx)(`p`,{children:`暂无分析记录`}),d.data?.jobs.map(e=>{let t=h?.id===e.id?h:e;return(0,k.jsxs)(m,{className:`ai-job-row`,"data-testid":`ai-job-row`,"data-job-id":t.id,"data-status":t.status,"aria-pressed":f===t.id,onClick:()=>p(t.id),children:[(0,k.jsxs)(`strong`,{children:[t.input.owner,`/`,t.input.path||`全部文件`]}),(0,k.jsxs)(`small`,{children:[y[t.workflow],` · `,u[t.status],` · v`,t.input.revision]})]},t.id)}),d.data?.nextCursor&&(0,k.jsx)(`button`,{"data-testid":`ai-jobs-next`,onClick:()=>s(d.data.nextCursor),children:`下一页`})]})]}),f?(0,k.jsx)(M,{id:f,session:e,onChanged:j,onUpdated:g,onLatest:e=>{a(!0),b(e.profileId),S(e.question),w({owner:e.input.owner,kind:e.input.kind,path:e.input.path}),D(e=>e+1),document.querySelector(`[data-testid="ai-job-form"]`)?.scrollIntoView({behavior:`smooth`})}},f):i?(0,k.jsx)(`section`,{className:`panel empty`,children:(0,k.jsx)(`p`,{children:`分析完成后,在这里查看结果与来源。`})}):null]})]})}var F=[{status:`planned`,label:`计划`},{status:`in_progress`,label:`进行中`},{status:`in_review`,label:`待验收`},{status:`completed`,label:`已完成`},{status:null,label:`未明确`}];function I({members:e}){let{request:t}=_(),i=w(),a=(0,O.useCallback)(e=>t(`tasks`,v,{signal:e}),[t]),o=c(a,3e3),[s,u]=(0,O.useState)(!1),[f,p]=(0,O.useState)(``),[m,g]=(0,O.useState)(),[y,x]=(0,O.useState)(),C=(0,O.useRef)(new Map),D=o.data,A=D?.members.some(e=>[`queued`,`running`].includes(e.status)),j=new Map(e.map(e=>[e.id,e.displayName||e.id]));async function M(e){if(!s){u(!0),p(``);try{for(let r of e){let e=C.current.get(r)??n();C.current.set(r,e),await t(`tasks/bootstrap`,S,{method:`POST`,body:{owner:r,operationId:e},signal:i}),C.current.delete(r)}}catch(e){i.aborted||p(r(e))}finally{u(!1),i.aborted||o.reload()}}}let N=D?.members.filter(e=>e.sourceChanged||e.partial||e.uncertainties.length||[`failed`,`cancelled`].includes(e.status))??[];return(0,k.jsxs)(`div`,{className:`task-board`,"aria-busy":s,children:[(0,k.jsx)(d,{title:`工作看板`,children:(0,k.jsxs)(T,{label:`看板操作`,children:[(0,k.jsx)(l,{icon:`sparkles`,label:A?`正在整理工作区`:`整理工作区`,"data-testid":`task-bootstrap`,"aria-busy":s||A,disabled:s||A||!D?.modelAvailable||!D.members.some(e=>e.status!==`empty`),onClick:()=>void M(D.members.filter(e=>e.status!==`empty`).map(e=>e.owner))}),(0,k.jsx)(l,{icon:`refresh`,label:`刷新任务`,"data-testid":`task-board-refresh`,disabled:o.loading,onClick:()=>void o.reload()})]})}),(0,k.jsx)(`span`,{className:`sr-only`,role:`status`,children:A?`正在整理工作区`:o.loading&&!D?`正在读取任务`:``}),(0,k.jsx)(`section`,{className:`task-board-lanes`,"aria-label":`任务进度`,"data-testid":`progress-board`,children:F.filter(e=>e.status!==null||D?.tasks.some(e=>e.status===null)).map(e=>{let t=D?.tasks.filter(t=>t.status===e.status)??[];return(0,k.jsxs)(`section`,{className:`task-lane`,"aria-label":e.label,"data-stage":e.status??`unknown`,children:[(0,k.jsxs)(`h2`,{children:[(0,k.jsx)(`span`,{className:`lane-dot`}),e.label,(0,k.jsx)(b,{children:D?t.length:`—`})]}),(0,k.jsx)(`div`,{className:`task-lane-content`,children:t.length?t.map(e=>(0,k.jsx)(L,{task:e,names:j,onEdit:()=>g(e),onSource:t=>x({jobId:e.jobId,path:t})},e.id)):(0,k.jsx)(`p`,{className:`task-lane-empty`,children:D?`暂无任务`:`读取中…`})})]},e.label)})}),(0,k.jsxs)(`details`,{className:`board-activity`,"data-testid":`task-activity`,open:o.error||f?!0:void 0,children:[(0,k.jsxs)(`summary`,{children:[(0,k.jsx)(h,{name:`notifications`}),(0,k.jsx)(`span`,{children:`活动与提醒`}),(N.length>0||D&&!D.modelAvailable)&&(0,k.jsx)(b,{children:N.length+(D&&!D.modelAvailable?1:0)}),(0,k.jsx)(h,{name:`chevronDown`,size:`small`})]}),(0,k.jsxs)(`div`,{className:`board-activity-content`,children:[(0,k.jsx)(E,{error:!0,children:o.error||f}),D&&!D.modelAvailable&&(0,k.jsxs)(`p`,{children:[`配置模型后即可整理工作区。`,(0,k.jsx)(`a`,{href:`/site-settings`,children:`配置模型`})]}),N.map(e=>(0,k.jsxs)(`div`,{className:`task-board-member-note`,children:[(0,k.jsxs)(`div`,{children:[(0,k.jsx)(`strong`,{children:j.get(e.owner)??e.owner}),(0,k.jsx)(`p`,{children:e.status===`failed`?`整理未完成`:e.status===`cancelled`?`整理已取消`:e.sourceChanged?`资料已有更新`:`部分资料尚待确认`})]}),(0,k.jsx)(l,{icon:`refresh`,label:`重新整理 ${j.get(e.owner)??e.owner}`,disabled:s||!D?.modelAvailable||[`queued`,`running`].includes(e.status),onClick:()=>void M([e.owner])}),e.uncertainties.map((e,t)=>(0,k.jsx)(`p`,{className:`task-board-note-detail`,children:e},t))]},e.owner)),D?.modelAvailable&&!N.length&&!o.error&&!f&&(0,k.jsx)(`p`,{children:`暂无提醒`})]})]}),m&&(0,k.jsx)(z,{task:m,onClose:()=>g(void 0),onSaved:()=>{g(void 0),o.reload()}},m.id),y&&(0,k.jsx)(V,{source:y,onClose:()=>x(void 0)},`${y.jobId}:${y.path}`)]})}function L({task:e,names:t,onEdit:n,onSource:r}){return(0,k.jsxs)(`article`,{className:`task-card`,"data-testid":`task-card`,"data-task-id":e.id,"data-owner":e.owner,"data-status":e.status??`unknown`,children:[(0,k.jsxs)(`div`,{className:`task-card-heading`,children:[(0,k.jsx)(`h3`,{children:e.title}),(0,k.jsx)(l,{icon:`edit`,className:`task-card-edit`,label:`纠正任务:${e.title}`,"data-testid":`task-correct`,onClick:n})]}),(0,k.jsxs)(`small`,{children:[t.get(e.owner)??e.owner,e.corrected?` · 已纠正`:``]}),(0,k.jsx)(`p`,{className:`task-progress`,children:(0,k.jsx)(R,{value:e.progress,names:t})}),(0,k.jsxs)(`details`,{className:`task-card-details`,children:[(0,k.jsxs)(`summary`,{children:[`查看详情`,(0,k.jsx)(h,{name:`chevronDown`,size:`small`})]}),e.needsReview&&(0,k.jsx)(`p`,{children:`本次整理未能明确对应,请核对来源。`}),(0,k.jsx)(`p`,{children:e.goal?(0,k.jsx)(R,{value:e.goal,names:t}):`目标未明确`}),(0,k.jsx)(`div`,{className:`task-card-sources`,children:e.sources.map(e=>(0,k.jsxs)(`button`,{"data-testid":`task-source`,onClick:()=>r(e.path),children:[(0,k.jsx)(h,{name:`file`,size:`small`}),e.path]},e.path))}),(0,k.jsxs)(`small`,{children:[`资料同步于 `,(0,k.jsx)(s,{value:e.syncedAt})]})]})]})}function R({value:e,names:t}){return e.split(/(@[a-z][a-z0-9_-]*)/gi).map((e,n)=>e.startsWith(`@`)&&t.has(e.slice(1))?(0,k.jsx)(`mark`,{className:`task-mention`,children:e},n):e)}function z({task:e,onClose:t,onSaved:n}){let{request:i}=_(),a=w(),[o,s]=(0,O.useState)(e.title),[c,l]=(0,O.useState)(e.status??``),[u,d]=(0,O.useState)(!1),[f,m]=(0,O.useState)(``),h={...o===e.title?{}:{title:o},...c===(e.status??``)?{}:{status:c||null}};async function v(t=!1){if(!(u||!t&&!Object.keys(h).length)){d(!0),m(``);try{await i(`tasks/${e.id}/correction`,p,{method:t?`DELETE`:`PATCH`,signal:a,...t?{}:{body:h}}),a.aborted||n()}catch(e){a.aborted||m(r(e))}finally{d(!1)}}}return(0,k.jsx)(C,{id:`task-correction`,title:`纠正任务`,onClose:t,children:(0,k.jsxs)(`form`,{className:`stack`,"aria-busy":u,onSubmit:e=>{e.preventDefault(),v()},children:[(0,k.jsx)(g,{id:`task-title`,label:`标题`,children:(0,k.jsx)(`input`,{value:o,required:!0,maxLength:200,onChange:e=>s(e.target.value)})}),(0,k.jsx)(g,{id:`task-status`,label:`状态`,children:(0,k.jsx)(`select`,{value:c,onChange:e=>l(e.target.value),children:F.map(e=>(0,k.jsx)(`option`,{value:e.status??``,children:e.label},e.label))})}),(0,k.jsx)(`small`,{children:`仅调整看板,不修改原始文件。`}),(0,k.jsx)(E,{error:!0,children:f}),(0,k.jsxs)(`div`,{className:`row wrap`,children:[(0,k.jsx)(`button`,{type:`submit`,disabled:u||!Object.keys(h).length,"data-testid":`task-correction-save`,children:`保存`}),e.corrected&&(0,k.jsx)(`button`,{type:`button`,disabled:u,"data-testid":`task-correction-reset`,onClick:()=>void v(!0),children:`恢复自动结果`})]})]})})}var B=D({content:e(),endLine:o(),hasMore:a()});function V({source:e,onClose:t}){let{request:n}=_(),[r,i]=(0,O.useState)(1),[a,o]=(0,O.useState)([]),s=(0,O.useCallback)(t=>n(`ai/jobs/${e.jobId}/source?${new URLSearchParams({path:e.path,startLine:String(r)})}`,B,{signal:t}),[n,e.jobId,e.path,r]),l=c(s);return(0,k.jsxs)(C,{id:`task-source-dialog`,title:e.path,onClose:t,children:[(0,k.jsx)(`small`,{children:`整理时的资料版本`}),(0,k.jsx)(E,{error:!0,children:l.error}),(0,k.jsx)(`pre`,{className:`raw task-source-content`,"data-testid":`task-source-content`,children:l.loading?`加载中…`:l.data?.content}),(0,k.jsxs)(`div`,{className:`row`,children:[(0,k.jsx)(`button`,{disabled:l.loading||!a.length,onClick:()=>{i(a.at(-1)),o(e=>e.slice(0,-1))},children:`上一段`}),(0,k.jsx)(`button`,{disabled:l.loading||!!l.error||!l.data?.hasMore,onClick:()=>{o(e=>[...e,r]),i(l.data.endLine+1)},children:`下一段`})]})]})}function H({session:e,members:t,seed:n}){let[r,i]=(0,O.useState)(!!n);return(0,k.jsxs)(k.Fragment,{children:[(0,k.jsx)(I,{members:t}),(0,k.jsxs)(`details`,{className:`analysis-tools`,"data-testid":`analysis-tools`,open:r,onToggle:e=>i(e.currentTarget.open),children:[(0,k.jsxs)(`summary`,{children:[(0,k.jsx)(h,{name:`sparkles`}),(0,k.jsx)(`span`,{children:`资料分析`}),(0,k.jsx)(h,{name:`chevronDown`})]}),r&&(0,k.jsx)(P,{session:e,members:t,seed:n})]})]})}export{H as Dashboard};