chainlesschain 0.45.67 → 0.45.74
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/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/Analytics-B4OM8S8X.css +1 -0
- package/src/assets/web-panel/assets/Analytics-sBrYoc3A.js +3 -0
- package/src/assets/web-panel/assets/AppLayout-BhJ3YFWt.js +1 -0
- package/src/assets/web-panel/assets/AppLayout-Cr2lWhF-.css +1 -0
- package/src/assets/web-panel/assets/Backup-D68fenbD.js +1 -0
- package/src/assets/web-panel/assets/Backup-fZqtfC1m.css +1 -0
- package/src/assets/web-panel/assets/{Chat-DXtvKoM0.js → Chat-DaxTP3x8.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-BJ4ODHOy.js → Cron-CNs03iHJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BZd4wDPQ.js → Dashboard-CjlX4CrX.js} +2 -2
- package/src/assets/web-panel/assets/Git-CCMVr3Y8.js +2 -0
- package/src/assets/web-panel/assets/Git-DGcuBXST.css +1 -0
- package/src/assets/web-panel/assets/{Logs-CSeKZEG_.js → Logs-BY6A0UNG.js} +2 -2
- package/src/assets/web-panel/assets/{McpTools-BYQAK11r.js → McpTools-CrBVYlg6.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-gkUAPyuZ.js → Memory-CWx3SpUt.js} +2 -2
- package/src/assets/web-panel/assets/{Notes-bjNrQgAo.js → Notes-1LcGD49x.js} +2 -2
- package/src/assets/web-panel/assets/Organization-DdOOM4ic.css +1 -0
- package/src/assets/web-panel/assets/Organization-Dx2DhbkM.js +4 -0
- package/src/assets/web-panel/assets/P2P-B16fjqfJ.js +2 -0
- package/src/assets/web-panel/assets/P2P-OEzOeMZX.css +1 -0
- package/src/assets/web-panel/assets/Permissions-BQbC9FzG.js +4 -0
- package/src/assets/web-panel/assets/Permissions-C9WlkGl-.css +1 -0
- package/src/assets/web-panel/assets/Projects-CjhZbNYm.js +2 -0
- package/src/assets/web-panel/assets/Projects-DxKelI5h.css +1 -0
- package/src/assets/web-panel/assets/Providers-BEakqcO5.css +1 -0
- package/src/assets/web-panel/assets/Providers-ivOAQtHM.js +2 -0
- package/src/assets/web-panel/assets/RssFeed-BlFC20eg.css +1 -0
- package/src/assets/web-panel/assets/RssFeed-BrsErdrU.js +3 -0
- package/src/assets/web-panel/assets/Security-DnEvJU5h.js +4 -0
- package/src/assets/web-panel/assets/Security-Dwxw7rfP.css +1 -0
- package/src/assets/web-panel/assets/{Services-CS0oMdxh.js → Services-7jQywNbl.js} +2 -2
- package/src/assets/web-panel/assets/Skills-BCvgBkD3.js +1 -0
- package/src/assets/web-panel/assets/{Tasks-qULws8pc.js → Tasks-CmJBC1cf.js} +1 -1
- package/src/assets/web-panel/assets/Templates-DOY_oZnm.css +1 -0
- package/src/assets/web-panel/assets/Templates-RXT8-DNk.js +1 -0
- package/src/assets/web-panel/assets/Wallet-3iYASEx_.js +4 -0
- package/src/assets/web-panel/assets/Wallet-DnIumafl.css +1 -0
- package/src/assets/web-panel/assets/WebAuthn-CNPl2VQR.css +1 -0
- package/src/assets/web-panel/assets/WebAuthn-s3Hzd9db.js +5 -0
- package/src/assets/web-panel/assets/{antd-CJSBocer.js → antd-gZyc63Qr.js} +114 -114
- package/src/assets/web-panel/assets/chat-BmwHBi9M.js +1 -0
- package/src/assets/web-panel/assets/index-DrmEk9S3.js +2 -0
- package/src/assets/web-panel/assets/{markdown-Bo5cVN4u.js → markdown-Bv7nG63L.js} +1 -1
- package/src/assets/web-panel/assets/ws-CU7Gvoom.js +1 -0
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/doctor.js +33 -151
- package/src/commands/mcp.js +1 -1
- package/src/commands/plugin.js +1 -1
- package/src/commands/session.js +106 -7
- package/src/commands/status.js +39 -69
- package/src/gateways/ws/message-dispatcher.js +9 -0
- package/src/gateways/ws/session-protocol.js +368 -1
- package/src/gateways/ws/ws-agent-handler.js +484 -0
- package/src/gateways/ws/ws-server.js +758 -4
- package/src/gateways/ws/ws-session-gateway.js +1432 -1
- package/src/harness/mcp-client.js +417 -0
- package/src/harness/mock-llm-provider.js +167 -0
- package/src/harness/plugin-manager.js +434 -0
- package/src/lib/agent-core.js +25 -1902
- package/src/lib/hashline.js +208 -0
- package/src/lib/jsonl-session-store.js +11 -0
- package/src/lib/mcp-client.js +14 -412
- package/src/lib/plugin-manager.js +29 -428
- package/src/lib/prompt-compressor.js +11 -0
- package/src/lib/session-hooks.js +61 -0
- package/src/lib/skill-loader.js +4 -0
- package/src/lib/skill-mcp.js +190 -0
- package/src/lib/workflow-state-reader.js +94 -0
- package/src/lib/ws-agent-handler.js +8 -472
- package/src/lib/ws-server.js +12 -726
- package/src/lib/ws-session-manager.js +8 -1178
- package/src/repl/agent-repl.js +27 -3
- package/src/runtime/agent-core.js +1760 -0
- package/src/runtime/agent-runtime.js +3 -1
- package/src/runtime/coding-agent-contract-shared.cjs +496 -0
- package/src/runtime/coding-agent-contract.js +49 -229
- package/src/runtime/coding-agent-events.cjs +14 -0
- package/src/runtime/coding-agent-policy.cjs +54 -5
- package/src/runtime/diagnostics.js +317 -0
- package/src/runtime/index.js +3 -0
- package/src/tools/index.js +3 -0
- package/src/tools/legacy-agent-tools.js +5 -0
- package/src/assets/web-panel/assets/AppLayout-B_tkw3Pn.js +0 -1
- package/src/assets/web-panel/assets/AppLayout-CFP4dGIJ.css +0 -1
- package/src/assets/web-panel/assets/Providers-Brm-S_hS.css +0 -1
- package/src/assets/web-panel/assets/Providers-Dbf57Tbv.js +0 -1
- package/src/assets/web-panel/assets/Skills-B2fgruv8.js +0 -1
- package/src/assets/web-panel/assets/chat-DnH09sSR.js +0 -1
- package/src/assets/web-panel/assets/index-IK-oro0g.js +0 -2
- package/src/assets/web-panel/assets/ws-DjelKkD6.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{V as j,f as g,r as w}from"./vendor-CN0Iv_qZ.js";import{u as f}from"./ws-CU7Gvoom.js";const S="新对话",T="新 Agent",M={"assistant.delta":"response-token","assistant.final":"response-complete","assistant.message":"response-complete","tool.call.started":"tool-executing","tool.call.completed":"tool-result","tool.call.failed":"tool-result","slot.filling":"question","approval.requested":"question",error:"error"},N=j("chat",()=>{const c=g([]),p=g(null),i=w({}),a=w({}),m=w({}),d=g(!1);let q=null;function y(t){return i[t]||(i[t]=[]),i[t]}function h(t){if(!t?.id)return;const e=c.value.find(o=>o.id===t.id);if(e){Object.assign(e,t);return}c.value.unshift(t)}function A(t,e=f()){i[t]||(i[t]=[]),a[t]||(a[t]={content:"",active:!1}),e.onSession(t,o=>E(t,o))}function v(t=f()){q||(q=t.onRuntimeEvent(e=>{const o=e.payload||{},s=o.record||{};if(e.type==="session:start"){const n=o.sessionType||s.type||"chat";h({id:o.sessionId,type:n,provider:s.provider||null,model:s.model||null,projectRoot:s.projectRoot||null,status:s.status||"created",title:n==="chat"?S:T,createdAt:Date.now(),messageCount:s.messageCount??0})}else if(e.type==="session:resume"){const n=o.sessionId;if(!n)return;Array.isArray(o.history)&&(i[n]=o.history.map(r=>({role:r.role,content:r.content,timestamp:r.timestamp||Date.now()}))),a[n]||(a[n]={content:"",active:!1}),h({id:n,type:s.type||null,provider:s.provider||null,model:s.model||null,projectRoot:s.projectRoot||null,status:s.status||"resumed",messageCount:s.messageCount??(Array.isArray(o.history)?o.history.length:0)})}else if(e.type==="session:end"){const n=o.sessionId;c.value=c.value.filter(r=>r.id!==n),p.value===n&&(p.value=c.value[0]?.id||null)}}))}async function C(){const t=f();v(t),c.value=await t.listSessions()}async function D(t="chat"){const e=f();v(e);const o=await e.createSession(t);return h({id:o,type:t,title:t==="chat"?S:T,createdAt:Date.now(),messageCount:0}),A(o,e),p.value=o,o}function E(t,e){const o=y(t),s=M[e.type]||e.type,n=e.payload||{};if(s==="response-token"){a[t]||(a[t]={content:"",active:!0});const r=e.token||n.token||n.delta||n.content||"";a[t].content+=r,a[t].active=!0}else if(s==="response-complete"){const r=e.content||n.content||a[t]?.content||"";o.push({role:"assistant",content:r,timestamp:Date.now()}),a[t]&&(a[t].content="",a[t].active=!1);const l=c.value.find(u=>u.id===t);if(l&&(l.title===S||l.title===T)){const u=o.find(L=>L.role==="user");u&&(l.title=u.content.slice(0,30))}l&&(l.messageCount=o.filter(u=>u.role!=="tool").length),d.value=!1}else if(s==="tool-executing")o.push({role:"tool",tool:e.tool||n.tool||n.toolName||"unknown",input:e.input||n.input||n.args||null,status:"running",timestamp:Date.now()});else if(s==="tool-result"){const r=e.tool||n.tool||n.toolName||"unknown",l=[...o].reverse().find(u=>u.role==="tool"&&u.tool===r);l&&(l.result=e.result||n.result||n.output||null,l.status="done")}else if(s==="question")m[t]={requestId:e.requestId||n.requestId||e.id,question:e.question||n.question||n.message||"",choices:e.choices||n.choices||n.options||[]};else if(s==="error"){const r=e.message||n.message||"Unknown error";o.push({role:"assistant",content:`Error: ${r}`,timestamp:Date.now()}),d.value=!1,a[t]&&(a[t].active=!1)}}async function k(t,e){const o=f();v(o),y(t).push({role:"user",content:e,timestamp:Date.now()}),a[t]||(a[t]={content:"",active:!1}),a[t].active=!0,d.value=!0,o.sendSessionMessage(t,e)}function _(t,e){const o=f(),s=m[t];s&&(o.answerQuestion(t,s.requestId,e),delete m[t])}async function R(t){const e=f();if(v(e),p.value=t,A(t,e),!i[t]||i[t].length===0)try{await e.resumeSession(t)}catch{}}return{sessions:c,currentSessionId:p,messages:i,streaming:a,pendingQuestion:m,isLoading:d,loadSessions:C,createSession:D,sendMessage:k,answerQuestion:_,switchSession:R,getMessages:y}});export{N as u};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./AppLayout-BhJ3YFWt.js","./vendor-CN0Iv_qZ.js","./ws-CU7Gvoom.js","./_plugin-vue_export-helper-DlAUqK2U.js","./antd-gZyc63Qr.js","./AppLayout-Cr2lWhF-.css","./Dashboard-CjlX4CrX.js","./chat-BmwHBi9M.js","./Dashboard-CKeMmCoT.css","./Chat-DaxTP3x8.js","./markdown-Bv7nG63L.js","./Chat-DB46afPg.css","./Services-7jQywNbl.js","./Services-C8Qs6KXv.css","./Logs-BY6A0UNG.js","./Logs-Gf_Mv9Nx.css","./Skills-BCvgBkD3.js","./parsers-DftYMnlk.js","./Skills-BdjRyorN.css","./Providers-ivOAQtHM.js","./Providers-BEakqcO5.css","./McpTools-CrBVYlg6.js","./McpTools-CyhSLDwf.css","./Notes-1LcGD49x.js","./Notes-BG69sJKi.css","./Memory-CWx3SpUt.js","./Memory-DRghrGJr.css","./Cron-CNs03iHJ.js","./Tasks-CmJBC1cf.js","./Tasks-BJjN_YEm.css","./Security-DnEvJU5h.js","./Security-Dwxw7rfP.css","./Permissions-BQbC9FzG.js","./Permissions-C9WlkGl-.css","./P2P-B16fjqfJ.js","./P2P-OEzOeMZX.css","./Git-CCMVr3Y8.js","./Git-DGcuBXST.css","./Projects-CjhZbNYm.js","./Projects-DxKelI5h.css","./Wallet-3iYASEx_.js","./Wallet-DnIumafl.css","./Organization-Dx2DhbkM.js","./Organization-DdOOM4ic.css","./Analytics-sBrYoc3A.js","./Analytics-B4OM8S8X.css","./Templates-RXT8-DNk.js","./Templates-DOY_oZnm.css","./Backup-D68fenbD.js","./Backup-fZqtfC1m.css","./RssFeed-BrsErdrU.js","./RssFeed-BlFC20eg.css","./WebAuthn-s3Hzd9db.js","./WebAuthn-CNPl2VQR.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{S as B,U as L,V as I,f as T,c as E,o as R,W as O,u as k,X as y,Y as x,Z as V,k as D,R as S,_ as w}from"./vendor-CN0Iv_qZ.js";import{a as g,A as M}from"./antd-gZyc63Qr.js";(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))m(t);new MutationObserver(t=>{for(const r of t)if(r.type==="childList")for(const n of r.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&m(n)}).observe(document,{childList:!0,subtree:!0});function c(t){const r={};return t.integrity&&(r.integrity=t.integrity),t.referrerPolicy&&(r.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?r.credentials="include":t.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function m(t){if(t.ep)return;t.ep=!0;const r=c(t);fetch(t.href,r)}})();const C="modulepreload",N=function(s,a){return new URL(s,a).href},P={},e=function(a,c,m){let t=Promise.resolve();if(c&&c.length>0){let b=function(i){return Promise.all(i.map(d=>Promise.resolve(d).then(p=>({status:"fulfilled",value:p}),p=>({status:"rejected",reason:p}))))};const n=document.getElementsByTagName("link"),o=document.querySelector("meta[property=csp-nonce]"),u=o?.nonce||o?.getAttribute("nonce");t=b(c.map(i=>{if(i=N(i,m),i in P)return;P[i]=!0;const d=i.endsWith(".css"),p=d?'[rel="stylesheet"]':"";if(m)for(let f=n.length-1;f>=0;f--){const _=n[f];if(_.href===i&&(!d||_.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${p}`))return;const l=document.createElement("link");if(l.rel=d?"stylesheet":C,d||(l.as="script"),l.crossOrigin="",l.href=i,u&&l.setAttribute("nonce",u),document.head.appendChild(l),d)return new Promise((f,_)=>{l.addEventListener("load",f),l.addEventListener("error",()=>_(new Error(`Unable to preload CSS for ${i}`)))})}))}function r(n){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=n,window.dispatchEvent(o),!o.defaultPrevented)throw n}return t.then(n=>{for(const o of n||[])o.status==="rejected"&&r(o.reason);return a().catch(r)})},U=[{path:"/",component:()=>e(()=>import("./AppLayout-BhJ3YFWt.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url),children:[{path:"",redirect:"/dashboard"},{path:"dashboard",name:"Dashboard",component:()=>e(()=>import("./Dashboard-CjlX4CrX.js"),__vite__mapDeps([6,1,2,7,3,4,8]),import.meta.url)},{path:"chat",name:"Chat",component:()=>e(()=>import("./Chat-DaxTP3x8.js"),__vite__mapDeps([9,1,10,4,7,2,3,11]),import.meta.url)},{path:"services",name:"Services",component:()=>e(()=>import("./Services-7jQywNbl.js"),__vite__mapDeps([12,2,1,3,4,13]),import.meta.url)},{path:"logs",name:"Logs",component:()=>e(()=>import("./Logs-BY6A0UNG.js"),__vite__mapDeps([14,2,1,3,4,15]),import.meta.url)},{path:"skills",name:"Skills",component:()=>e(()=>import("./Skills-BCvgBkD3.js"),__vite__mapDeps([16,1,2,17,7,3,4,18]),import.meta.url)},{path:"providers",name:"Providers",component:()=>e(()=>import("./Providers-ivOAQtHM.js"),__vite__mapDeps([19,1,2,17,3,4,20]),import.meta.url)},{path:"mcp",name:"McpTools",component:()=>e(()=>import("./McpTools-CrBVYlg6.js"),__vite__mapDeps([21,2,1,3,4,22]),import.meta.url)},{path:"notes",name:"Notes",component:()=>e(()=>import("./Notes-1LcGD49x.js"),__vite__mapDeps([23,2,1,3,4,24]),import.meta.url)},{path:"memory",name:"Memory",component:()=>e(()=>import("./Memory-CWx3SpUt.js"),__vite__mapDeps([25,2,1,3,4,26]),import.meta.url)},{path:"cron",name:"Cron",component:()=>e(()=>import("./Cron-CNs03iHJ.js"),__vite__mapDeps([27,2,1,4]),import.meta.url)},{path:"tasks",name:"Tasks",component:()=>e(()=>import("./Tasks-CmJBC1cf.js"),__vite__mapDeps([28,1,2,3,4,29]),import.meta.url)},{path:"security",name:"Security",component:()=>e(()=>import("./Security-DnEvJU5h.js"),__vite__mapDeps([30,2,1,3,4,31]),import.meta.url)},{path:"permissions",name:"Permissions",component:()=>e(()=>import("./Permissions-BQbC9FzG.js"),__vite__mapDeps([32,2,1,3,4,33]),import.meta.url)},{path:"p2p",name:"P2P",component:()=>e(()=>import("./P2P-B16fjqfJ.js"),__vite__mapDeps([34,2,1,3,4,35]),import.meta.url)},{path:"git",name:"Git",component:()=>e(()=>import("./Git-CCMVr3Y8.js"),__vite__mapDeps([36,2,1,3,4,37]),import.meta.url)},{path:"projects",name:"Projects",component:()=>e(()=>import("./Projects-CjhZbNYm.js"),__vite__mapDeps([38,2,1,3,4,39]),import.meta.url)},{path:"wallet",name:"Wallet",component:()=>e(()=>import("./Wallet-3iYASEx_.js"),__vite__mapDeps([40,2,1,3,4,41]),import.meta.url)},{path:"organization",name:"Organization",component:()=>e(()=>import("./Organization-Dx2DhbkM.js"),__vite__mapDeps([42,1,2,3,4,43]),import.meta.url)},{path:"analytics",name:"Analytics",component:()=>e(()=>import("./Analytics-sBrYoc3A.js"),__vite__mapDeps([44,2,1,3,4,45]),import.meta.url)},{path:"templates",name:"Templates",component:()=>e(()=>import("./Templates-RXT8-DNk.js"),__vite__mapDeps([46,1,2,3,4,47]),import.meta.url)},{path:"backup",name:"Backup",component:()=>e(()=>import("./Backup-D68fenbD.js"),__vite__mapDeps([48,2,1,3,4,49]),import.meta.url)},{path:"rssfeed",name:"RssFeed",component:()=>e(()=>import("./RssFeed-BrsErdrU.js"),__vite__mapDeps([50,1,2,3,4,51]),import.meta.url)},{path:"webauthn",name:"WebAuthn",component:()=>e(()=>import("./WebAuthn-s3Hzd9db.js"),__vite__mapDeps([52,2,1,3,4,53]),import.meta.url)}]}],F=B({history:L(),routes:U}),A="cc_theme",v={dark:{label:"暗黑",icon:"🌑",antd:{algorithm:g.darkAlgorithm,token:{colorPrimary:"#1677ff",colorBgBase:"#141414",colorBgContainer:"#1f1f1f",colorBgElevated:"#2a2a2a",borderRadius:8,fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'},components:{Layout:{siderBg:"#1c1c1c",headerBg:"#1c1c1c",bodyBg:"#141414"},Menu:{darkItemBg:"#1c1c1c",darkSubMenuItemBg:"#171717"}}},vars:{"--bg-base":"#141414","--bg-sidebar":"#1c1c1c","--bg-header":"#1c1c1c","--bg-card":"#1f1f1f","--bg-card-hover":"#262626","--border-color":"#252525","--border-subtle":"#1e1e1e","--text-primary":"#e0e0e0","--text-secondary":"#888","--text-muted":"#444","--logo-text":"#ffffff","--menu-mode":"dark","--shadow-card":"0 2px 8px rgba(0,0,0,.45)","--group-title":"#3a3a3a"}},light:{label:"亮白",icon:"☀️",antd:{algorithm:g.defaultAlgorithm,token:{colorPrimary:"#1677ff",colorBgBase:"#ffffff",colorBgContainer:"#ffffff",colorBgElevated:"#ffffff",borderRadius:8,fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'},components:{Layout:{siderBg:"#ffffff",headerBg:"#ffffff",bodyBg:"#f4f6fb"},Menu:{itemBg:"#ffffff"}}},vars:{"--bg-base":"#f4f6fb","--bg-sidebar":"#ffffff","--bg-header":"#ffffff","--bg-card":"#ffffff","--bg-card-hover":"#f0f4ff","--border-color":"#e8edf5","--border-subtle":"#f0f0f0","--text-primary":"#1a1a2e","--text-secondary":"#5a6474","--text-muted":"#b0b8c8","--logo-text":"#1a1a2e","--menu-mode":"light","--shadow-card":"0 2px 12px rgba(0,0,0,.07)","--group-title":"#aab0bc"}},blue:{label:"深蓝",icon:"🌊",antd:{algorithm:g.darkAlgorithm,token:{colorPrimary:"#2f80ed",colorBgBase:"#0d1117",colorBgContainer:"#161b22",colorBgElevated:"#1c2230",borderRadius:8,fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'},components:{Layout:{siderBg:"#0f1923",headerBg:"#0f1923",bodyBg:"#0d1117"},Menu:{darkItemBg:"#0f1923",darkSubMenuItemBg:"#0b1520"}}},vars:{"--bg-base":"#0d1117","--bg-sidebar":"#0f1923","--bg-header":"#0f1923","--bg-card":"#161b22","--bg-card-hover":"#1c2230","--border-color":"#21303f","--border-subtle":"#182030","--text-primary":"#c9d8ef","--text-secondary":"#6e8caa","--text-muted":"#2d4060","--logo-text":"#e0eeff","--menu-mode":"dark","--shadow-card":"0 2px 8px rgba(0,40,80,.5)","--group-title":"#2d4060"}},green:{label:"翠绿",icon:"🌿",antd:{algorithm:g.darkAlgorithm,token:{colorPrimary:"#29a270",colorBgBase:"#0a1a12",colorBgContainer:"#0f2318",colorBgElevated:"#152e20",borderRadius:8,fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'},components:{Layout:{siderBg:"#0c1e14",headerBg:"#0c1e14",bodyBg:"#0a1a12"},Menu:{darkItemBg:"#0c1e14",darkSubMenuItemBg:"#091810"}}},vars:{"--bg-base":"#0a1a12","--bg-sidebar":"#0c1e14","--bg-header":"#0c1e14","--bg-card":"#0f2318","--bg-card-hover":"#152e20","--border-color":"#1a3828","--border-subtle":"#122a1c","--text-primary":"#c0e8c8","--text-secondary":"#5a9a6a","--text-muted":"#1e4028","--logo-text":"#d8f0e0","--menu-mode":"dark","--shadow-card":"0 2px 8px rgba(0,40,20,.5)","--group-title":"#1e4028"}}},j=I("theme",()=>{const s=T(localStorage.getItem(A)||"dark"),a=E(()=>v[s.value]||v.dark),c=E(()=>a.value.antd),m=E(()=>s.value!=="light");function t(){const o=a.value.vars,u=document.documentElement;for(const[b,i]of Object.entries(o))u.style.setProperty(b,i);u.setAttribute("data-theme",s.value)}function r(o){v[o]&&(s.value=o,localStorage.setItem(A,o),t())}function n(){t()}return{current:s,config:a,antdTheme:c,isDark:m,setTheme:r,init:n}}),W={__name:"App",setup(s){const a=j();return R(()=>a.init()),(c,m)=>{const t=y("router-view"),r=y("a-config-provider");return x(),O(r,{theme:k(a).antdTheme},{default:V(()=>[D(t)]),_:1},8,["theme"])}}},h=S(W);h.use(w());h.use(F);h.use(M);h.mount("#app");export{v as T,j as u};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as Yc}from"./antd-
|
|
1
|
+
import{g as Yc}from"./antd-gZyc63Qr.js";function Ni(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}let He=Ni();function Mc(a){He=a}const Lc=/[&<>"']/,qc=new RegExp(Lc.source,"g"),xc=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,Hc=new RegExp(xc.source,"g"),Vc={"&":"&","<":"<",">":">",'"':""","'":"'"},$i=a=>Vc[a];function Ne(a,e){if(e){if(Lc.test(a))return a.replace(qc,$i)}else if(xc.test(a))return a.replace(Hc,$i);return a}const zc=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;function Wc(a){return a.replace(zc,(e,t)=>(t=t.toLowerCase(),t==="colon"?":":t.charAt(0)==="#"?t.charAt(1)==="x"?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""))}const $c=/(^|[^\[])\^/g;function Z(a,e){let t=typeof a=="string"?a:a.source;e=e||"";const n={replace:(r,i)=>{let o=typeof i=="string"?i:i.source;return o=o.replace($c,"$1"),t=t.replace(r,o),n},getRegex:()=>new RegExp(t,e)};return n}function Ki(a){try{a=encodeURI(a).replace(/%25/g,"%")}catch{return null}return a}const pt={exec:()=>null};function Qi(a,e){const t=a.replace(/\|/g,(i,o,s)=>{let l=!1,_=o;for(;--_>=0&&s[_]==="\\";)l=!l;return l?"|":" |"}),n=t.split(/ \|/);let r=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push("");for(;r<n.length;r++)n[r]=n[r].trim().replace(/\\\|/g,"|");return n}function yt(a,e,t){const n=a.length;if(n===0)return"";let r=0;for(;r<n&&a.charAt(n-r-1)===e;)r++;return a.slice(0,n-r)}function Kc(a,e){if(a.indexOf(e[1])===-1)return-1;let t=0;for(let n=0;n<a.length;n++)if(a[n]==="\\")n++;else if(a[n]===e[0])t++;else if(a[n]===e[1]&&(t--,t<0))return n;return-1}function Xi(a,e,t,n){const r=e.href,i=e.title?Ne(e.title):null,o=a[1].replace(/\\([\[\]])/g,"$1");if(a[0].charAt(0)!=="!"){n.state.inLink=!0;const s={type:"link",raw:t,href:r,title:i,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=!1,s}return{type:"image",raw:t,href:r,title:i,text:Ne(o)}}function Qc(a,e){const t=a.match(/^(\s+)(?:```)/);if(t===null)return e;const n=t[1];return e.split(`
|
|
2
2
|
`).map(r=>{const i=r.match(/^\s+/);if(i===null)return r;const[o]=i;return o.length>=n.length?r.slice(n.length):r}).join(`
|
|
3
3
|
`)}class Lt{options;rules;lexer;constructor(e){this.options=e||He}space(e){const t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){const t=this.rules.block.code.exec(e);if(t){const n=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?n:yt(n,`
|
|
4
4
|
`)}}}fences(e){const t=this.rules.block.fences.exec(e);if(t){const n=t[0],r=Qc(n,t[3]||"");return{type:"code",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:r}}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(/#$/.test(n)){const r=yt(n,"#");(this.options.pedantic||!r||/ $/.test(r))&&(n=r.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){const t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}}blockquote(e){const t=this.rules.block.blockquote.exec(e);if(t){let n=t[0].replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{V as U,f as E,c as B}from"./vendor-CN0Iv_qZ.js";let F=0;const w=()=>`wp-${++F}`,b=new Set;function d(e,r={},n={}){return{type:e,kind:n.kind||"server",sessionId:n.sessionId||r.sessionId||null,timestamp:n.timestamp||Date.now(),payload:r}}function G(e){const r=e?.type,n=e?.payload||{};switch(r){case"task:notification":return d("task:notification",{task:e.task||n.task},{kind:"server"});case"session-created":case"session.started":return d("session:start",{sessionId:e.sessionId||n.sessionId,sessionType:e.sessionType||n.sessionType||null,record:e.record||n.record||{id:e.sessionId||n.sessionId,type:e.sessionType||n.sessionType||null,status:"created",history:[],messageCount:0}},{kind:"server",sessionId:e.sessionId||n.sessionId});case"session-resumed":case"session.resumed":{const i=e.sessionId||n.sessionId,a=e.history||n.history||[];return d("session:resume",{sessionId:i,history:a,historyCount:Array.isArray(a)?a.length:0,record:e.record||n.record||{id:i,type:null,status:"resumed",history:a,messageCount:Array.isArray(a)?a.length:0}},{kind:"server",sessionId:i})}case"worktree-diff":case"worktree.diff":return d("worktree:diff:ready",{requestId:e.requestId||e.id||null,record:e.record||n.record||{branch:e.branch||n.branch||null,summary:e.summary||n.summary||null,previewEntrypoints:[{type:"worktree-diff",branch:e.branch||n.branch||null}]}},{kind:"server"});case"worktree-merged":case"worktree.merged":return d("worktree:merge:completed",{requestId:e.requestId||e.id||null,record:e.record||n.record||{branch:e.branch||n.branch||null,summary:e.summary||n.summary||null,conflicts:e.conflicts||n.conflicts||[],previewEntrypoints:e.previewEntrypoints||n.previewEntrypoints||[]}},{kind:"server"});case"compression-stats":case"context.compaction.completed":return d("compression:summary",{requestId:e.requestId||e.id||null,summary:e.summary||n.summary||{}},{kind:"server"});default:return null}}function W(e,r=null){b.forEach(n=>n(e,r||e))}function Q(e){if(!e)return null;const r=e.record||{id:e.id||null,type:e.type||null,provider:e.provider||null,model:e.model||null,projectRoot:e.projectRoot||null,messageCount:e.messageCount??0,history:e.history||[],status:e.status||null};return{...e,id:e.id||r.id,type:e.type||r.type,provider:e.provider||r.provider,model:e.model||r.model,projectRoot:e.projectRoot||r.projectRoot,messageCount:e.messageCount??r.messageCount??0,status:e.status||r.status||null,record:r}}const K=U("ws",()=>{const e=E(null),r=E("disconnected"),n=E(null),i=new Map,a=new Map;let C=null,v=1e3;const y=window.__CC_CONFIG__||{},R=B(()=>`ws://${y.wsHost||"127.0.0.1"}:${y.wsPort||18800}`);function h(){if(e.value?.readyState!==WebSocket.OPEN){r.value="connecting",n.value=null;try{const t=new WebSocket(R.value);e.value=t,t.onopen=()=>{v=1e3,y.wsToken?l({type:"auth",id:w(),token:y.wsToken}).then(()=>{r.value="connected"}).catch(()=>{r.value="connected"}):r.value="connected"},t.onmessage=o=>{let s;try{s=JSON.parse(o.data)}catch{return}q(s)},t.onerror=()=>{n.value="WebSocket error",r.value="error"},t.onclose=()=>{r.value="disconnected",e.value=null,i.forEach(({reject:o})=>o(new Error("WebSocket closed"))),i.clear(),C=setTimeout(()=>{v=Math.min(v*2,3e4),h()},v)}}catch(t){r.value="error",n.value=t.message}}}function P(){clearTimeout(C),e.value?.close(),e.value=null,r.value="disconnected"}function T(t){if(!t.version&&!t.payload)return t;const o=t.payload||{};return{...t,...o,type:t.type,sessionId:t.sessionId||o.sessionId||null}}function q(t){const{type:o}=t,s=t.requestId||t.id;let u=!1;if(s&&i.has(s)){const{resolve:f,reject:O,timeout:S}=i.get(s);clearTimeout(S),i.delete(s),u=!0;const I=T(t);I.id=s,o==="error"?O(new Error(I.message||"Unknown error")):f(I)}const c=t.sessionId||t.payload&&t.payload.sessionId||null;if(c&&a.has(c)){const f=T(t);a.get(c).forEach(S=>S(f))}k.forEach(f=>f(t));const m=G(t);return m&&W(m,t),u}const k=new Set;function J(t){return k.add(t),()=>k.delete(t)}function j(t){return b.add(t),()=>b.delete(t)}function x(t,o){return a.has(t)||a.set(t,new Set),a.get(t).add(o),()=>{a.get(t)?.delete(o),a.get(t)?.size===0&&a.delete(t)}}function l(t,o=15e3){return new Promise((s,u)=>{if(e.value?.readyState!==WebSocket.OPEN){u(new Error("WebSocket not connected"));return}const c=t.id||w(),m=setTimeout(()=>{i.delete(c),u(new Error("Request timeout"))},o);i.set(c,{resolve:s,reject:u,timeout:m}),e.value.send(JSON.stringify({...t,id:c}))})}function p(t=8e3){return r.value==="connected"?Promise.resolve():new Promise((o,s)=>{const u=Date.now()+t,c=()=>{if(r.value==="connected")return o();if(r.value==="error"||Date.now()>=u)return s(new Error(`WS not ready: ${r.value}`));setTimeout(c,150)};r.value==="disconnected"&&h(),c()})}async function N(t,o=3e4){await p(8e3);const s=await l({type:"execute",command:t},o),u=s.output??s.stdout??"",c=s.stderr??"";return{output:u||c,exitCode:s.exitCode??0}}async function M(t,o=3e4){const{output:s,exitCode:u}=await N(t,o);if(u!==0)throw new Error(`Command failed: ${s}`);try{return JSON.parse(s.trim())}catch{const c=s.match(/\{[\s\S]*\}|\[[\s\S]*\]/);if(c)return JSON.parse(c[0]);throw new Error(`Invalid JSON output: ${s.slice(0,200)}`)}}async function _(t="chat",o=null){await p(8e3);const s=w();return(await l({type:"session-create",id:s,sessionType:t,projectRoot:o||y.projectRoot||null})).sessionId}function $(t,o){e.value?.readyState===WebSocket.OPEN&&e.value.send(JSON.stringify({type:"session-message",id:w(),sessionId:t,content:o}))}function A(t,o,s){e.value?.readyState===WebSocket.OPEN&&e.value.send(JSON.stringify({type:"session-answer",id:w(),sessionId:t,requestId:o,answer:s}))}async function D(){return await p(8e3),((await l({type:"session-list"},1e4)).sessions||[]).map(Q).filter(Boolean)}async function H(t){try{await l({type:"session-close",sessionId:t},5e3),W(d("session:end",{sessionId:t},{kind:"server",sessionId:t}),{type:"result",sessionId:t,success:!0})}catch{}}async function z(t){return await p(8e3),await l({type:"session-resume",sessionId:t},1e4)}return{status:r,error:n,wsUrl:R,connect:h,disconnect:P,waitConnected:p,onMessage:J,onRuntimeEvent:j,onSession:x,sendRaw:l,execute:N,executeJson:M,createSession:_,resumeSession:z,sendSessionMessage:$,answerQuestion:A,listSessions:D,closeSession:H}});export{K as u};
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
// Injected by web-ui-server.js at serve time
|
|
9
9
|
window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
|
|
10
10
|
</script>
|
|
11
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
+
<script type="module" crossorigin src="./assets/index-DrmEk9S3.js"></script>
|
|
12
12
|
<link rel="modulepreload" crossorigin href="./assets/vendor-CN0Iv_qZ.js">
|
|
13
|
-
<link rel="modulepreload" crossorigin href="./assets/antd-
|
|
13
|
+
<link rel="modulepreload" crossorigin href="./assets/antd-gZyc63Qr.js">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="./assets/index-CyGyEIVX.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
package/src/commands/doctor.js
CHANGED
|
@@ -1,178 +1,60 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import { execSync } from "node:child_process";
|
|
3
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
4
|
-
import { createConnection } from "node:net";
|
|
5
|
-
import semver from "semver";
|
|
6
|
-
import { MIN_NODE_VERSION, DEFAULT_PORTS, VERSION } from "../constants.js";
|
|
7
|
-
import { getHomeDir, getConfigPath, getBinDir } from "../lib/paths.js";
|
|
8
|
-
import {
|
|
9
|
-
isDockerAvailable,
|
|
10
|
-
isDockerComposeAvailable,
|
|
11
|
-
} from "../lib/service-manager.js";
|
|
12
|
-
import { loadConfig } from "../lib/config-manager.js";
|
|
13
2
|
import logger from "../lib/logger.js";
|
|
3
|
+
import { collectDoctorReport } from "../runtime/diagnostics.js";
|
|
14
4
|
|
|
15
5
|
export function registerDoctorCommand(program) {
|
|
16
6
|
program
|
|
17
7
|
.command("doctor")
|
|
18
8
|
.description("Diagnose your ChainlessChain environment")
|
|
19
|
-
.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ok: nodeOk,
|
|
30
|
-
detail: nodeOk ? "" : `Requires >=${MIN_NODE_VERSION}`,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// npm
|
|
34
|
-
try {
|
|
35
|
-
const npmVersion = execSync("npm --version", {
|
|
36
|
-
encoding: "utf-8",
|
|
37
|
-
}).trim();
|
|
38
|
-
checks.push({ name: `npm ${npmVersion}`, ok: true });
|
|
39
|
-
} catch {
|
|
40
|
-
checks.push({ name: "npm", ok: false, detail: "Not found" });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Docker
|
|
44
|
-
checks.push({
|
|
45
|
-
name: "Docker",
|
|
46
|
-
ok: isDockerAvailable(),
|
|
47
|
-
detail: isDockerAvailable() ? "" : "Not installed (optional)",
|
|
48
|
-
});
|
|
49
|
-
checks.push({
|
|
50
|
-
name: "Docker Compose",
|
|
51
|
-
ok: isDockerComposeAvailable(),
|
|
52
|
-
detail: isDockerComposeAvailable() ? "" : "Not installed (optional)",
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Git
|
|
56
|
-
try {
|
|
57
|
-
const gitVersion = execSync("git --version", {
|
|
58
|
-
encoding: "utf-8",
|
|
59
|
-
}).trim();
|
|
60
|
-
checks.push({ name: gitVersion, ok: true });
|
|
61
|
-
} catch {
|
|
62
|
-
checks.push({ name: "Git", ok: false, detail: "Not found" });
|
|
9
|
+
.option("--json", "Output as machine-readable JSON")
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
const report = await collectDoctorReport();
|
|
12
|
+
|
|
13
|
+
if (options.json) {
|
|
14
|
+
console.log(JSON.stringify(report, null, 2));
|
|
15
|
+
if (report.summary.criticalFailed > 0) {
|
|
16
|
+
process.exitCode = 1;
|
|
17
|
+
}
|
|
18
|
+
return;
|
|
63
19
|
}
|
|
64
20
|
|
|
65
|
-
|
|
66
|
-
const homeDir = getHomeDir();
|
|
67
|
-
checks.push({
|
|
68
|
-
name: `Config dir: ${homeDir}`,
|
|
69
|
-
ok: existsSync(homeDir),
|
|
70
|
-
detail: existsSync(homeDir) ? "" : 'Run "chainlesschain setup"',
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Config file
|
|
74
|
-
const configPath = getConfigPath();
|
|
75
|
-
checks.push({
|
|
76
|
-
name: "Config file",
|
|
77
|
-
ok: existsSync(configPath),
|
|
78
|
-
detail: existsSync(configPath) ? "" : 'Run "chainlesschain setup"',
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Binary
|
|
82
|
-
const binDir = getBinDir();
|
|
83
|
-
const hasBin = existsSync(binDir) && readdirSafe(binDir).length > 0;
|
|
84
|
-
checks.push({
|
|
85
|
-
name: "Desktop binary",
|
|
86
|
-
ok: hasBin,
|
|
87
|
-
detail: hasBin
|
|
88
|
-
? ""
|
|
89
|
-
: 'Run "chainlesschain setup" or "chainlesschain update"',
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Setup completed
|
|
93
|
-
const config = loadConfig();
|
|
94
|
-
checks.push({
|
|
95
|
-
name: "Setup completed",
|
|
96
|
-
ok: config.setupCompleted,
|
|
97
|
-
detail: config.setupCompleted ? "" : 'Run "chainlesschain setup"',
|
|
98
|
-
});
|
|
21
|
+
logger.log(chalk.bold("\n ChainlessChain Doctor\n"));
|
|
99
22
|
|
|
100
|
-
|
|
101
|
-
for (const check of checks) {
|
|
23
|
+
for (const check of report.checks) {
|
|
102
24
|
const icon = check.ok ? chalk.green("✔") : chalk.red("✖");
|
|
103
25
|
const detail = check.detail ? chalk.gray(` (${check.detail})`) : "";
|
|
104
26
|
logger.log(` ${icon} ${check.name}${detail}`);
|
|
105
27
|
}
|
|
106
28
|
|
|
107
|
-
// Port scan
|
|
108
29
|
logger.log(chalk.bold("\n Port Status\n"));
|
|
109
|
-
for (const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
logger.log(` ${icon} ${name}: ${port}`);
|
|
30
|
+
for (const p of report.ports) {
|
|
31
|
+
const icon = p.open ? chalk.green("●") : chalk.gray("○");
|
|
32
|
+
logger.log(` ${icon} ${p.name}: ${p.port}`);
|
|
113
33
|
}
|
|
114
34
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const stats = statfsSync(homeDir);
|
|
121
|
-
const freeGB = (stats.bavail * stats.bsize) / (1024 * 1024 * 1024);
|
|
122
|
-
const ok = freeGB > 2;
|
|
123
|
-
logger.log(chalk.bold("\n Disk\n"));
|
|
124
|
-
const icon = ok ? chalk.green("✔") : chalk.yellow("⚠");
|
|
125
|
-
logger.log(` ${icon} Free space: ${freeGB.toFixed(1)} GB`);
|
|
126
|
-
}
|
|
127
|
-
} catch {
|
|
128
|
-
// statfsSync not available on all platforms
|
|
35
|
+
if (report.disk) {
|
|
36
|
+
const ok = report.disk.freeGB > 2;
|
|
37
|
+
logger.log(chalk.bold("\n Disk\n"));
|
|
38
|
+
const icon = ok ? chalk.green("✔") : chalk.yellow("⚠");
|
|
39
|
+
logger.log(` ${icon} Free space: ${report.disk.freeGB.toFixed(1)} GB`);
|
|
129
40
|
}
|
|
130
41
|
|
|
131
|
-
// Summary
|
|
132
|
-
const failures = checks.filter((c) => !c.ok);
|
|
133
42
|
logger.newline();
|
|
134
|
-
if (
|
|
43
|
+
if (report.summary.failed === 0) {
|
|
135
44
|
logger.log(chalk.bold.green(" All checks passed!\n"));
|
|
45
|
+
} else if (report.summary.criticalFailed > 0) {
|
|
46
|
+
logger.log(
|
|
47
|
+
chalk.bold.red(
|
|
48
|
+
` ${report.summary.criticalFailed} issue(s) found. See details above.\n`,
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
process.exitCode = 1;
|
|
136
52
|
} else {
|
|
137
|
-
|
|
138
|
-
|
|
53
|
+
logger.log(
|
|
54
|
+
chalk.bold.yellow(
|
|
55
|
+
` ${report.summary.failed} optional component(s) missing.\n`,
|
|
56
|
+
),
|
|
139
57
|
);
|
|
140
|
-
if (critical.length > 0) {
|
|
141
|
-
logger.log(
|
|
142
|
-
chalk.bold.red(
|
|
143
|
-
` ${critical.length} issue(s) found. See details above.\n`,
|
|
144
|
-
),
|
|
145
|
-
);
|
|
146
|
-
} else {
|
|
147
|
-
logger.log(
|
|
148
|
-
chalk.bold.yellow(
|
|
149
|
-
` ${failures.length} optional component(s) missing.\n`,
|
|
150
|
-
),
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
58
|
}
|
|
154
59
|
});
|
|
155
60
|
}
|
|
156
|
-
|
|
157
|
-
function checkPort(port, host = "127.0.0.1") {
|
|
158
|
-
return new Promise((resolve) => {
|
|
159
|
-
const socket = createConnection({ port, host, timeout: 1000 });
|
|
160
|
-
socket.on("connect", () => {
|
|
161
|
-
socket.destroy();
|
|
162
|
-
resolve(true);
|
|
163
|
-
});
|
|
164
|
-
socket.on("error", () => resolve(false));
|
|
165
|
-
socket.on("timeout", () => {
|
|
166
|
-
socket.destroy();
|
|
167
|
-
resolve(false);
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function readdirSafe(dir) {
|
|
173
|
-
try {
|
|
174
|
-
return readdirSync(dir);
|
|
175
|
-
} catch {
|
|
176
|
-
return [];
|
|
177
|
-
}
|
|
178
|
-
}
|
package/src/commands/mcp.js
CHANGED
|
@@ -7,7 +7,7 @@ import chalk from "chalk";
|
|
|
7
7
|
import ora from "ora";
|
|
8
8
|
import { logger } from "../lib/logger.js";
|
|
9
9
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
|
-
import { MCPClient, MCPServerConfig } from "../
|
|
10
|
+
import { MCPClient, MCPServerConfig } from "../harness/mcp-client.js";
|
|
11
11
|
|
|
12
12
|
// Singleton MCP client for session reuse
|
|
13
13
|
let mcpClient = null;
|
package/src/commands/plugin.js
CHANGED
package/src/commands/session.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
7
8
|
import chalk from "chalk";
|
|
8
9
|
import { logger } from "../lib/logger.js";
|
|
9
10
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
@@ -22,8 +23,12 @@ import {
|
|
|
22
23
|
migrateLegacySessionsBatch,
|
|
23
24
|
validateJsonlSession,
|
|
24
25
|
validateAllJsonlSessions,
|
|
25
|
-
} from "../
|
|
26
|
+
} from "../harness/jsonl-session-store.js";
|
|
26
27
|
import { feature } from "../lib/feature-flags.js";
|
|
28
|
+
import {
|
|
29
|
+
listWorkflowSessions,
|
|
30
|
+
readWorkflowSession,
|
|
31
|
+
} from "../lib/workflow-state-reader.js";
|
|
27
32
|
|
|
28
33
|
export function registerSessionCommand(program) {
|
|
29
34
|
const session = program
|
|
@@ -313,7 +318,11 @@ export function registerSessionCommand(program) {
|
|
|
313
318
|
.option("--dry-run", "Show what would migrate without writing files")
|
|
314
319
|
.option("--force", "Overwrite existing JSONL sessions")
|
|
315
320
|
.option("--no-archive", "Do not keep .migrated.json backups")
|
|
316
|
-
.option(
|
|
321
|
+
.option(
|
|
322
|
+
"--sample-size <n>",
|
|
323
|
+
"Validate N migrated sessions after migration",
|
|
324
|
+
"3",
|
|
325
|
+
)
|
|
317
326
|
.option("--retry-failures", "Retry failed migrations once")
|
|
318
327
|
.option("--json", "Output as JSON")
|
|
319
328
|
.action(async (source, options) => {
|
|
@@ -325,7 +334,8 @@ export function registerSessionCommand(program) {
|
|
|
325
334
|
sampleSize: parseInt(options.sampleSize, 10) || 3,
|
|
326
335
|
retryFailures: options.retryFailures,
|
|
327
336
|
});
|
|
328
|
-
const results =
|
|
337
|
+
const results =
|
|
338
|
+
report.results || migrateLegacySessions(source, options);
|
|
329
339
|
|
|
330
340
|
if (options.json) {
|
|
331
341
|
console.log(JSON.stringify(report, null, 2));
|
|
@@ -357,9 +367,10 @@ export function registerSessionCommand(program) {
|
|
|
357
367
|
|
|
358
368
|
if (report.sampledValidation?.length) {
|
|
359
369
|
for (const item of report.sampledValidation) {
|
|
360
|
-
const label =
|
|
361
|
-
|
|
362
|
-
|
|
370
|
+
const label =
|
|
371
|
+
item.valid && item.matchesExpectedMessages
|
|
372
|
+
? chalk.green("sample-ok")
|
|
373
|
+
: chalk.red("sample-fail");
|
|
363
374
|
logger.log(
|
|
364
375
|
`${label} ${item.sessionId} (${item.messageCount}/${item.expectedMessageCount} messages)`,
|
|
365
376
|
);
|
|
@@ -389,7 +400,9 @@ export function registerSessionCommand(program) {
|
|
|
389
400
|
|
|
390
401
|
const results = Array.isArray(result) ? result : [result];
|
|
391
402
|
for (const item of results) {
|
|
392
|
-
const label = item.valid
|
|
403
|
+
const label = item.valid
|
|
404
|
+
? chalk.green("valid")
|
|
405
|
+
: chalk.red("invalid");
|
|
393
406
|
logger.log(
|
|
394
407
|
`${label} ${item.sessionId} (${item.eventCount} events, ${item.messageCount || 0} messages, malformed: ${item.malformedLines})`,
|
|
395
408
|
);
|
|
@@ -402,4 +415,90 @@ export function registerSessionCommand(program) {
|
|
|
402
415
|
process.exit(1);
|
|
403
416
|
}
|
|
404
417
|
});
|
|
418
|
+
|
|
419
|
+
// session workflow — inspect canonical coding workflow state
|
|
420
|
+
// Reads .chainlesschain/sessions/<id>/{intent.md,plan.md,progress.log,mode.json}
|
|
421
|
+
// written by the 4 workflow skills ($deep-interview/$ralplan/$ralph/$team).
|
|
422
|
+
session
|
|
423
|
+
.command("workflow")
|
|
424
|
+
.description("Inspect coding workflow state (.chainlesschain/sessions/)")
|
|
425
|
+
.argument("[id]", "Workflow session ID (omit to list all)")
|
|
426
|
+
.option("--json", "Output as JSON")
|
|
427
|
+
.option("--cwd <path>", "Project root (defaults to process.cwd())")
|
|
428
|
+
.action((id, options) => {
|
|
429
|
+
try {
|
|
430
|
+
const projectRoot = path.resolve(options.cwd || process.cwd());
|
|
431
|
+
|
|
432
|
+
if (!id) {
|
|
433
|
+
const items = listWorkflowSessions(projectRoot);
|
|
434
|
+
if (options.json) {
|
|
435
|
+
console.log(JSON.stringify(items, null, 2));
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (items.length === 0) {
|
|
439
|
+
logger.info("No workflow sessions under .chainlesschain/sessions/");
|
|
440
|
+
logger.info(
|
|
441
|
+
'Start one with: $deep-interview "<your goal>" in the coding agent',
|
|
442
|
+
);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
logger.log(chalk.bold(`Workflow sessions (${items.length}):\n`));
|
|
446
|
+
for (const s of items) {
|
|
447
|
+
const approvedTag = s.approved
|
|
448
|
+
? chalk.green("approved")
|
|
449
|
+
: s.hasPlan
|
|
450
|
+
? chalk.yellow("unapproved")
|
|
451
|
+
: chalk.gray("no-plan");
|
|
452
|
+
logger.log(
|
|
453
|
+
` ${chalk.cyan(s.sessionId)} ${chalk.white(s.stage || "?")} ${approvedTag} ${chalk.gray(s.updatedAt || "")}`,
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const data = readWorkflowSession(projectRoot, id);
|
|
460
|
+
if (!data) {
|
|
461
|
+
logger.error(`Workflow session "${id}" not found`);
|
|
462
|
+
process.exit(1);
|
|
463
|
+
}
|
|
464
|
+
if (options.json) {
|
|
465
|
+
console.log(JSON.stringify(data, null, 2));
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
logger.log(chalk.bold(`\nSession: ${data.sessionId}`));
|
|
469
|
+
logger.log(
|
|
470
|
+
`Stage: ${data.mode?.stage || chalk.gray("(unset)")} Approved: ${
|
|
471
|
+
data.planApproved ? chalk.green("yes") : chalk.yellow("no")
|
|
472
|
+
}`,
|
|
473
|
+
);
|
|
474
|
+
logger.log(chalk.gray(`Dir: ${data.dir}\n`));
|
|
475
|
+
|
|
476
|
+
if (data.intent) {
|
|
477
|
+
logger.log(chalk.bold("── intent.md ──"));
|
|
478
|
+
logger.log(data.intent.trim());
|
|
479
|
+
logger.log("");
|
|
480
|
+
} else {
|
|
481
|
+
logger.log(chalk.gray("(no intent.md — run $deep-interview first)"));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (data.plan) {
|
|
485
|
+
logger.log(chalk.bold("── plan.md ──"));
|
|
486
|
+
logger.log(data.plan.trim());
|
|
487
|
+
logger.log("");
|
|
488
|
+
} else {
|
|
489
|
+
logger.log(chalk.gray("(no plan.md — run $ralplan)"));
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (data.progress) {
|
|
493
|
+
logger.log(chalk.bold("── progress.log (tail) ──"));
|
|
494
|
+
const lines = data.progress.trim().split("\n");
|
|
495
|
+
for (const line of lines.slice(-20)) {
|
|
496
|
+
logger.log(` ${line}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
} catch (err) {
|
|
500
|
+
logger.error(`Failed: ${err.message}`);
|
|
501
|
+
process.exit(1);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
405
504
|
}
|
package/src/commands/status.js
CHANGED
|
@@ -1,84 +1,69 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import { createConnection } from "node:net";
|
|
3
|
-
import { isAppRunning, getAppPid } from "../lib/process-manager.js";
|
|
4
|
-
import {
|
|
5
|
-
isDockerAvailable,
|
|
6
|
-
getServiceStatus,
|
|
7
|
-
findComposeFile,
|
|
8
|
-
} from "../lib/service-manager.js";
|
|
9
|
-
import { loadConfig } from "../lib/config-manager.js";
|
|
10
|
-
import { DEFAULT_PORTS } from "../constants.js";
|
|
11
2
|
import logger from "../lib/logger.js";
|
|
3
|
+
import { collectStatusReport } from "../runtime/diagnostics.js";
|
|
12
4
|
|
|
13
5
|
export function registerStatusCommand(program) {
|
|
14
6
|
program
|
|
15
7
|
.command("status")
|
|
16
8
|
.description("Show status of ChainlessChain app and services")
|
|
17
|
-
.
|
|
9
|
+
.option("--json", "Output as machine-readable JSON")
|
|
10
|
+
.action(async (options) => {
|
|
18
11
|
try {
|
|
19
|
-
const
|
|
12
|
+
const report = await collectStatusReport();
|
|
13
|
+
|
|
14
|
+
if (options.json) {
|
|
15
|
+
console.log(JSON.stringify(report, null, 2));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
20
18
|
|
|
21
19
|
// App status
|
|
22
20
|
logger.log(chalk.bold("\n App Status\n"));
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
if (report.app.running) {
|
|
22
|
+
logger.log(
|
|
23
|
+
` ${chalk.green("●")} Desktop app running (PID: ${report.app.pid})`,
|
|
24
|
+
);
|
|
26
25
|
} else {
|
|
27
26
|
logger.log(` ${chalk.gray("○")} Desktop app not running`);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
if (config.setupCompleted) {
|
|
29
|
+
if (report.setup.completed) {
|
|
32
30
|
logger.log(
|
|
33
|
-
` ${chalk.green("●")} Setup completed (${
|
|
31
|
+
` ${chalk.green("●")} Setup completed (${report.setup.completedAt || "unknown"})`,
|
|
34
32
|
);
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
if (report.setup.edition) {
|
|
34
|
+
logger.log(` Edition: ${report.setup.edition}`);
|
|
35
|
+
}
|
|
36
|
+
if (report.setup.llm) {
|
|
37
|
+
logger.log(
|
|
38
|
+
` LLM: ${report.setup.llm.provider} (${report.setup.llm.model})`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
37
41
|
} else {
|
|
38
42
|
logger.log(` ${chalk.yellow("●")} Setup not completed`);
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
// Docker services
|
|
42
46
|
logger.log(chalk.bold("\n Docker Services\n"));
|
|
43
|
-
if (
|
|
44
|
-
const composePath = findComposeFile([
|
|
45
|
-
process.cwd(),
|
|
46
|
-
"backend/docker",
|
|
47
|
-
]);
|
|
48
|
-
if (composePath) {
|
|
49
|
-
const status = getServiceStatus(composePath);
|
|
50
|
-
if (status && Array.isArray(status)) {
|
|
51
|
-
for (const svc of status) {
|
|
52
|
-
const running = svc.State === "running";
|
|
53
|
-
const icon = running ? chalk.green("●") : chalk.red("●");
|
|
54
|
-
logger.log(
|
|
55
|
-
` ${icon} ${svc.Service || svc.Name}: ${svc.State}`,
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
} else if (status) {
|
|
59
|
-
logger.log(` ${status}`);
|
|
60
|
-
} else {
|
|
61
|
-
logger.log(` ${chalk.gray("○")} No services running`);
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
logger.log(` ${chalk.gray("○")} docker-compose.yml not found`);
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
47
|
+
if (!report.docker.available) {
|
|
67
48
|
logger.log(` ${chalk.gray("○")} Docker not available`);
|
|
49
|
+
} else if (report.docker.services) {
|
|
50
|
+
for (const svc of report.docker.services) {
|
|
51
|
+
const running = svc.state === "running";
|
|
52
|
+
const icon = running ? chalk.green("●") : chalk.red("●");
|
|
53
|
+
logger.log(` ${icon} ${svc.name}: ${svc.state}`);
|
|
54
|
+
}
|
|
55
|
+
} else if (report.docker.note) {
|
|
56
|
+
const icon = report.docker.note.includes("not found")
|
|
57
|
+
? chalk.gray("○")
|
|
58
|
+
: chalk.gray("○");
|
|
59
|
+
logger.log(` ${icon} ${report.docker.note}`);
|
|
68
60
|
}
|
|
69
61
|
|
|
70
|
-
//
|
|
62
|
+
// Ports
|
|
71
63
|
logger.log(chalk.bold("\n Ports\n"));
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const icon = open ? chalk.green("●") : chalk.gray("○");
|
|
76
|
-
return ` ${icon} ${name}: ${port}`;
|
|
77
|
-
},
|
|
78
|
-
);
|
|
79
|
-
const results = await Promise.all(portChecks);
|
|
80
|
-
for (const line of results) {
|
|
81
|
-
logger.log(line);
|
|
64
|
+
for (const p of report.ports) {
|
|
65
|
+
const icon = p.open ? chalk.green("●") : chalk.gray("○");
|
|
66
|
+
logger.log(` ${icon} ${p.name}: ${p.port}`);
|
|
82
67
|
}
|
|
83
68
|
|
|
84
69
|
logger.newline();
|
|
@@ -88,18 +73,3 @@ export function registerStatusCommand(program) {
|
|
|
88
73
|
}
|
|
89
74
|
});
|
|
90
75
|
}
|
|
91
|
-
|
|
92
|
-
function checkPort(port, host = "127.0.0.1") {
|
|
93
|
-
return new Promise((resolve) => {
|
|
94
|
-
const socket = createConnection({ port, host, timeout: 1000 });
|
|
95
|
-
socket.on("connect", () => {
|
|
96
|
-
socket.destroy();
|
|
97
|
-
resolve(true);
|
|
98
|
-
});
|
|
99
|
-
socket.on("error", () => resolve(false));
|
|
100
|
-
socket.on("timeout", () => {
|
|
101
|
-
socket.destroy();
|
|
102
|
-
resolve(false);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
}
|
|
@@ -66,6 +66,15 @@ export function createWsMessageDispatcher(server) {
|
|
|
66
66
|
"patch-apply": () => server._handlePatchApply(id, ws, message),
|
|
67
67
|
"patch-reject": () => server._handlePatchReject(id, ws, message),
|
|
68
68
|
"patch-summary": () => server._handlePatchSummary(id, ws, message),
|
|
69
|
+
"task-graph-create": () =>
|
|
70
|
+
server._handleTaskGraphCreate(id, ws, message),
|
|
71
|
+
"task-graph-add-node": () =>
|
|
72
|
+
server._handleTaskGraphAddNode(id, ws, message),
|
|
73
|
+
"task-graph-update-node": () =>
|
|
74
|
+
server._handleTaskGraphUpdateNode(id, ws, message),
|
|
75
|
+
"task-graph-advance": () =>
|
|
76
|
+
server._handleTaskGraphAdvance(id, ws, message),
|
|
77
|
+
"task-graph-state": () => server._handleTaskGraphState(id, ws, message),
|
|
69
78
|
};
|
|
70
79
|
|
|
71
80
|
const handler = routes[type];
|