chainlesschain 0.46.0 → 0.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -5
- package/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{Analytics-C1AnPdMx.js → Analytics-DgypYeUB.js} +2 -2
- package/src/assets/web-panel/assets/AppLayout-DQyDwGut.css +1 -0
- package/src/assets/web-panel/assets/AppLayout-ZHpCFO_p.js +1 -0
- package/src/assets/web-panel/assets/{Backup-D31iZX3l.js → Backup-Ba9UybpT.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DiXJ3TuK.js → Chat-BwXskT21.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-B8ZDdRm4.js → Cowork-UmOe7qvE.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-DBt1ueXh.js → Cron-JHS-rc-4.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +1 -0
- package/src/assets/web-panel/assets/{Dashboard-jt6XPIjB.js → Dashboard-CpWz2g0n.js} +2 -2
- package/src/assets/web-panel/assets/{Git-hwQ1oZHj.js → Git-CSYO0_zk.js} +2 -2
- package/src/assets/web-panel/assets/{Logs-4D9p6PRM.js → Logs-Hxw_K0km.js} +2 -2
- package/src/assets/web-panel/assets/{McpTools-CyAUjbbs.js → McpTools-DIE75TrB.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-BMqOR7S-.js → Memory-C4KVnLlp.js} +2 -2
- package/src/assets/web-panel/assets/{Notes-Cmas8i4E.js → Notes-DuzrHMAk.js} +2 -2
- package/src/assets/web-panel/assets/{Organization-DnSa58Tl.js → Organization-DTq6uF82.js} +4 -4
- package/src/assets/web-panel/assets/{P2P-BxksIBWs.js → P2P-C0hjlhsR.js} +2 -2
- package/src/assets/web-panel/assets/{Permissions-Bq5Qn2s3.js → Permissions-Ec0NH-xC.js} +4 -4
- package/src/assets/web-panel/assets/{Projects-B7EM0uPg.js → Projects-U8D0asCS.js} +2 -2
- package/src/assets/web-panel/assets/{Providers-DAwgG5KV.js → Providers-BngtTLvJ.js} +2 -2
- package/src/assets/web-panel/assets/{RssFeed-HSZoRXvS.js → RssFeed-B9NbwCKM.js} +3 -3
- package/src/assets/web-panel/assets/{Security-Cz17qBny.js → Security-BL5Rkr1T.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D2EsLq-v.js → Services-D4MJzLld.js} +2 -2
- package/src/assets/web-panel/assets/{Skills-C9v-f3vZ.js → Skills-CQTOMDwF.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-yMEcU0n7.js → Tasks-DepbJMnL.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-l7SvlKuB.js → Templates-C24PVZPu.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BHWhLWn9.js → Wallet-PQoSpN_P.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-kWhFYaUK.js → WebAuthn-BcuyQ4Lr.js} +4 -4
- package/src/assets/web-panel/assets/WorkflowEditor-C-SvXbHW.js +1 -0
- package/src/assets/web-panel/assets/WorkflowEditor-D5bX6woe.css +1 -0
- package/src/assets/web-panel/assets/{antd-D6h4fDFf.js → antd-DEjZPGMj.js} +82 -82
- package/src/assets/web-panel/assets/index-CLmYSvow.js +2 -0
- package/src/assets/web-panel/assets/{markdown-BZsB-Dsv.js → markdown-CusdXFxb.js} +1 -1
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/cowork.js +213 -41
- package/src/gateways/ws/action-protocol.js +140 -0
- package/src/gateways/ws/message-dispatcher.js +5 -0
- package/src/gateways/ws/ws-server.js +21 -0
- package/src/lib/cowork-evomap-adapter.js +121 -0
- package/src/lib/cowork-observe-html.js +108 -0
- package/src/lib/cowork-observe.js +160 -0
- package/src/lib/cowork-share.js +114 -10
- package/src/lib/provider-options.js +133 -0
- package/src/lib/skill-loader.js +65 -0
- package/src/lib/sub-agent-context.js +16 -4
- package/src/lib/sub-agent-profiles.js +164 -0
- package/src/lib/todo-manager.js +108 -0
- package/src/lib/turn-context.js +95 -0
- package/src/lib/web-fetch.js +224 -0
- package/src/repl/agent-repl.js +4 -0
- package/src/runtime/agent-core.js +135 -3
- package/src/runtime/coding-agent-contract-shared.cjs +131 -0
- package/src/runtime/coding-agent-policy.cjs +30 -0
- package/src/assets/web-panel/assets/AppLayout-BnvARObz.js +0 -1
- package/src/assets/web-panel/assets/AppLayout-cxfKLu-m.css +0 -1
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +0 -1
- package/src/assets/web-panel/assets/index-C1SPm_5l.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./AppLayout-ZHpCFO_p.js","./vendor-CN0Iv_qZ.js","./ws-Dma34ig_.js","./_plugin-vue_export-helper-DlAUqK2U.js","./antd-DEjZPGMj.js","./AppLayout-DQyDwGut.css","./Dashboard-CpWz2g0n.js","./chat-BYmuDvol.js","./Dashboard-BS-tzGNj.css","./Chat-BwXskT21.js","./markdown-CusdXFxb.js","./Chat-DfR76jyX.css","./github-dark-Dfs9RUU9.css","./Cowork-UmOe7qvE.js","./Cowork-CXuhlHew.css","./Services-D4MJzLld.js","./Services-C8Qs6KXv.css","./Logs-Hxw_K0km.js","./Logs-Gf_Mv9Nx.css","./Skills-CQTOMDwF.js","./parsers-DftYMnlk.js","./Skills-BdjRyorN.css","./Providers-BngtTLvJ.js","./Providers-BEakqcO5.css","./McpTools-DIE75TrB.js","./McpTools-CyhSLDwf.css","./Notes-DuzrHMAk.js","./Notes-BG69sJKi.css","./Memory-C4KVnLlp.js","./Memory-DRghrGJr.css","./Cron-JHS-rc-4.js","./WorkflowEditor-C-SvXbHW.js","./WorkflowEditor-D5bX6woe.css","./Tasks-DepbJMnL.js","./Tasks-BJjN_YEm.css","./Security-BL5Rkr1T.js","./Security-Dwxw7rfP.css","./Permissions-Ec0NH-xC.js","./Permissions-C9WlkGl-.css","./P2P-C0hjlhsR.js","./P2P-OEzOeMZX.css","./Git-CSYO0_zk.js","./Git-DGcuBXST.css","./Projects-U8D0asCS.js","./Projects-DxKelI5h.css","./Wallet-PQoSpN_P.js","./Wallet-DnIumafl.css","./Organization-DTq6uF82.js","./Organization-DdOOM4ic.css","./Analytics-DgypYeUB.js","./Analytics-B4OM8S8X.css","./Templates-C24PVZPu.js","./Templates-DOY_oZnm.css","./Backup-Ba9UybpT.js","./Backup-fZqtfC1m.css","./RssFeed-B9NbwCKM.js","./RssFeed-BlFC20eg.css","./WebAuthn-BcuyQ4Lr.js","./WebAuthn-CNPl2VQR.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{S as L,U as B,V as I,f as T,c as E,o as R,W as O,u as k,X as y,Y as V,Z as D,k as x,R as S,_ as w}from"./vendor-CN0Iv_qZ.js";import{a as g,A as M}from"./antd-DEjZPGMj.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 o of t)if(o.type==="childList")for(const n of o.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&m(n)}).observe(document,{childList:!0,subtree:!0});function c(t){const o={};return t.integrity&&(o.integrity=t.integrity),t.referrerPolicy&&(o.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?o.credentials="include":t.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function m(t){if(t.ep)return;t.ep=!0;const o=c(t);fetch(t.href,o)}})();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(u=>({status:"fulfilled",value:u}),u=>({status:"rejected",reason:u}))))};const n=document.getElementsByTagName("link"),r=document.querySelector("meta[property=csp-nonce]"),p=r?.nonce||r?.getAttribute("nonce");t=b(c.map(i=>{if(i=N(i,m),i in P)return;P[i]=!0;const d=i.endsWith(".css"),u=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}"]${u}`))return;const l=document.createElement("link");if(l.rel=d?"stylesheet":C,d||(l.as="script"),l.crossOrigin="",l.href=i,p&&l.setAttribute("nonce",p),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 o(n){const r=new Event("vite:preloadError",{cancelable:!0});if(r.payload=n,window.dispatchEvent(r),!r.defaultPrevented)throw n}return t.then(n=>{for(const r of n||[])r.status==="rejected"&&o(r.reason);return a().catch(o)})},U=[{path:"/",component:()=>e(()=>import("./AppLayout-ZHpCFO_p.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url),children:[{path:"",redirect:"/dashboard"},{path:"dashboard",name:"Dashboard",component:()=>e(()=>import("./Dashboard-CpWz2g0n.js"),__vite__mapDeps([6,1,2,7,3,4,8]),import.meta.url)},{path:"chat",name:"Chat",component:()=>e(()=>import("./Chat-BwXskT21.js"),__vite__mapDeps([9,1,10,4,7,2,3,11,12]),import.meta.url)},{path:"cowork",name:"Cowork",component:()=>e(()=>import("./Cowork-UmOe7qvE.js"),__vite__mapDeps([13,1,10,4,2,7,3,14,12]),import.meta.url)},{path:"services",name:"Services",component:()=>e(()=>import("./Services-D4MJzLld.js"),__vite__mapDeps([15,2,1,3,4,16]),import.meta.url)},{path:"logs",name:"Logs",component:()=>e(()=>import("./Logs-Hxw_K0km.js"),__vite__mapDeps([17,2,1,3,4,18]),import.meta.url)},{path:"skills",name:"Skills",component:()=>e(()=>import("./Skills-CQTOMDwF.js"),__vite__mapDeps([19,1,2,20,7,3,4,21]),import.meta.url)},{path:"providers",name:"Providers",component:()=>e(()=>import("./Providers-BngtTLvJ.js"),__vite__mapDeps([22,1,2,20,3,4,23]),import.meta.url)},{path:"mcp",name:"McpTools",component:()=>e(()=>import("./McpTools-DIE75TrB.js"),__vite__mapDeps([24,2,1,3,4,25]),import.meta.url)},{path:"notes",name:"Notes",component:()=>e(()=>import("./Notes-DuzrHMAk.js"),__vite__mapDeps([26,2,1,3,4,27]),import.meta.url)},{path:"memory",name:"Memory",component:()=>e(()=>import("./Memory-C4KVnLlp.js"),__vite__mapDeps([28,2,1,3,4,29]),import.meta.url)},{path:"cron",name:"Cron",component:()=>e(()=>import("./Cron-JHS-rc-4.js"),__vite__mapDeps([30,2,1,4]),import.meta.url)},{path:"workflow",name:"Workflow",component:()=>e(()=>import("./WorkflowEditor-C-SvXbHW.js"),__vite__mapDeps([31,1,2,3,4,32]),import.meta.url)},{path:"tasks",name:"Tasks",component:()=>e(()=>import("./Tasks-DepbJMnL.js"),__vite__mapDeps([33,1,2,3,4,34]),import.meta.url)},{path:"security",name:"Security",component:()=>e(()=>import("./Security-BL5Rkr1T.js"),__vite__mapDeps([35,2,1,3,4,36]),import.meta.url)},{path:"permissions",name:"Permissions",component:()=>e(()=>import("./Permissions-Ec0NH-xC.js"),__vite__mapDeps([37,2,1,3,4,38]),import.meta.url)},{path:"p2p",name:"P2P",component:()=>e(()=>import("./P2P-C0hjlhsR.js"),__vite__mapDeps([39,2,1,3,4,40]),import.meta.url)},{path:"git",name:"Git",component:()=>e(()=>import("./Git-CSYO0_zk.js"),__vite__mapDeps([41,2,1,3,4,42]),import.meta.url)},{path:"projects",name:"Projects",component:()=>e(()=>import("./Projects-U8D0asCS.js"),__vite__mapDeps([43,2,1,3,4,44]),import.meta.url)},{path:"wallet",name:"Wallet",component:()=>e(()=>import("./Wallet-PQoSpN_P.js"),__vite__mapDeps([45,2,1,3,4,46]),import.meta.url)},{path:"organization",name:"Organization",component:()=>e(()=>import("./Organization-DTq6uF82.js"),__vite__mapDeps([47,1,2,3,4,48]),import.meta.url)},{path:"analytics",name:"Analytics",component:()=>e(()=>import("./Analytics-DgypYeUB.js"),__vite__mapDeps([49,2,1,3,4,50]),import.meta.url)},{path:"templates",name:"Templates",component:()=>e(()=>import("./Templates-C24PVZPu.js"),__vite__mapDeps([51,1,2,3,4,52]),import.meta.url)},{path:"backup",name:"Backup",component:()=>e(()=>import("./Backup-Ba9UybpT.js"),__vite__mapDeps([53,2,1,3,4,54]),import.meta.url)},{path:"rssfeed",name:"RssFeed",component:()=>e(()=>import("./RssFeed-B9NbwCKM.js"),__vite__mapDeps([55,1,2,3,4,56]),import.meta.url)},{path:"webauthn",name:"WebAuthn",component:()=>e(()=>import("./WebAuthn-BcuyQ4Lr.js"),__vite__mapDeps([57,2,1,3,4,58]),import.meta.url)}]}],F=L({history:B(),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"}}},W=I("theme",()=>{const s=T(localStorage.getItem(A)||"light"),a=E(()=>v[s.value]||v.dark),c=E(()=>a.value.antd),m=E(()=>s.value!=="light");function t(){const r=a.value.vars,p=document.documentElement;for(const[b,i]of Object.entries(r))p.style.setProperty(b,i);p.setAttribute("data-theme",s.value)}function o(r){v[r]&&(s.value=r,localStorage.setItem(A,r),t())}function n(){t()}return{current:s,config:a,antdTheme:c,isDark:m,setTheme:o,init:n}}),j={__name:"App",setup(s){const a=W();return R(()=>a.init()),(c,m)=>{const t=y("router-view"),o=y("a-config-provider");return V(),O(o,{theme:k(a).antdTheme},{default:D(()=>[x(t)]),_:1},8,["theme"])}}},h=S(j);h.use(w());h.use(F);h.use(M);h.mount("#app");export{v as T,W as u};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as Yc}from"./antd-
|
|
1
|
+
import{g as Yc}from"./antd-DEjZPGMj.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,`
|
|
@@ -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-CLmYSvow.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-DEjZPGMj.js">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="./assets/index-CyGyEIVX.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
package/src/commands/cowork.js
CHANGED
|
@@ -300,17 +300,15 @@ export function registerCoworkCommand(program) {
|
|
|
300
300
|
tpl
|
|
301
301
|
.command("search [query]")
|
|
302
302
|
.description("Search for Cowork templates on the EvoMap hub")
|
|
303
|
+
.option("--hub <url>", "EvoMap hub URL")
|
|
303
304
|
.option("--limit <n>", "Max results", "20")
|
|
304
305
|
.option("--json", "Output as JSON")
|
|
305
306
|
.action(async (query, options) => {
|
|
306
|
-
const
|
|
307
|
-
await
|
|
308
|
-
import("../lib/cowork-template-marketplace.js"),
|
|
309
|
-
import("../lib/evomap-client.js"),
|
|
310
|
-
]);
|
|
311
|
-
mpDeps.evomapClient = new EvoMapClient();
|
|
307
|
+
const { searchTemplatesInHub } =
|
|
308
|
+
await import("../lib/cowork-evomap-adapter.js");
|
|
312
309
|
try {
|
|
313
|
-
const results = await
|
|
310
|
+
const results = await searchTemplatesInHub(query || "", {
|
|
311
|
+
hubUrl: options.hub,
|
|
314
312
|
limit: parseInt(options.limit, 10) || 20,
|
|
315
313
|
});
|
|
316
314
|
if (options.json) {
|
|
@@ -345,15 +343,22 @@ export function registerCoworkCommand(program) {
|
|
|
345
343
|
tpl
|
|
346
344
|
.command("install <geneId>")
|
|
347
345
|
.description("Install a Cowork template from the EvoMap hub")
|
|
348
|
-
.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
346
|
+
.option("--hub <url>", "EvoMap hub URL")
|
|
347
|
+
.option("--require-signed", "Reject genes without an Ed25519 signature")
|
|
348
|
+
.option(
|
|
349
|
+
"--trust <did>",
|
|
350
|
+
"Only accept genes signed by this DID (repeatable)",
|
|
351
|
+
(value, prev) => (prev ? [...prev, value] : [value]),
|
|
352
|
+
)
|
|
353
|
+
.action(async (geneId, options) => {
|
|
354
|
+
const { installTemplateFromHub } =
|
|
355
|
+
await import("../lib/cowork-evomap-adapter.js");
|
|
355
356
|
try {
|
|
356
|
-
const template = await
|
|
357
|
+
const template = await installTemplateFromHub(process.cwd(), geneId, {
|
|
358
|
+
hubUrl: options.hub,
|
|
359
|
+
requireSigned: !!options.requireSigned,
|
|
360
|
+
trustedDids: options.trust || null,
|
|
361
|
+
});
|
|
357
362
|
logger.log(
|
|
358
363
|
chalk.green(
|
|
359
364
|
`✓ Installed template '${template.id}' (${template.name})`,
|
|
@@ -407,38 +412,39 @@ export function registerCoworkCommand(program) {
|
|
|
407
412
|
tpl
|
|
408
413
|
.command("publish <templateId>")
|
|
409
414
|
.description("Publish a built-in or installed Cowork template to EvoMap")
|
|
410
|
-
.
|
|
411
|
-
.option("--
|
|
412
|
-
.option(
|
|
413
|
-
|
|
415
|
+
.option("--hub <url>", "EvoMap hub URL")
|
|
416
|
+
.option("--api-key <key>", "EvoMap API key (or set EVOMAP_API_KEY)")
|
|
417
|
+
.option(
|
|
418
|
+
"--sign <did>",
|
|
419
|
+
"Sign the gene with this DID from the local identity store",
|
|
420
|
+
)
|
|
414
421
|
.action(async (templateId, options) => {
|
|
415
|
-
const [
|
|
416
|
-
|
|
417
|
-
{ getTemplate },
|
|
418
|
-
{ EvoMapClient },
|
|
419
|
-
] = await Promise.all([
|
|
420
|
-
import("../lib/cowork-template-marketplace.js"),
|
|
422
|
+
const [{ publishTemplateToHub }, { getTemplate }] = await Promise.all([
|
|
423
|
+
import("../lib/cowork-evomap-adapter.js"),
|
|
421
424
|
import("../lib/cowork-task-templates.js"),
|
|
422
|
-
import("../lib/evomap-client.js"),
|
|
423
425
|
]);
|
|
424
|
-
mpDeps.evomapClient = new EvoMapClient();
|
|
425
426
|
|
|
426
427
|
const template = getTemplate(templateId);
|
|
427
|
-
if (template.id === "free") {
|
|
428
|
+
if (template.id === "free" && templateId !== "free") {
|
|
428
429
|
logger.error(`Unknown template: ${templateId}`);
|
|
429
430
|
process.exit(1);
|
|
430
431
|
}
|
|
431
|
-
|
|
432
|
+
|
|
433
|
+
let signer;
|
|
434
|
+
if (options.sign) {
|
|
435
|
+
signer = await _resolveSigner(options.sign);
|
|
436
|
+
}
|
|
437
|
+
|
|
432
438
|
try {
|
|
433
|
-
const result = await
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
tags: options.tags
|
|
438
|
-
? options.tags.split(",").map((t) => t.trim())
|
|
439
|
-
: [],
|
|
439
|
+
const result = await publishTemplateToHub(template, {
|
|
440
|
+
hubUrl: options.hub,
|
|
441
|
+
apiKey: options.apiKey,
|
|
442
|
+
signer,
|
|
440
443
|
});
|
|
441
|
-
logger.log(
|
|
444
|
+
logger.log(
|
|
445
|
+
chalk.green(`✓ Published ${result?.id || template.id}`) +
|
|
446
|
+
(signer ? chalk.gray(` (signed by ${signer.did})`) : ""),
|
|
447
|
+
);
|
|
442
448
|
} catch (err) {
|
|
443
449
|
logger.error(`Publish failed: ${err.message}`);
|
|
444
450
|
process.exit(1);
|
|
@@ -594,11 +600,28 @@ export function registerCoworkCommand(program) {
|
|
|
594
600
|
"Export/import signed Cowork packets (templates or task results)",
|
|
595
601
|
);
|
|
596
602
|
|
|
603
|
+
async function _resolveSigner(didQuery) {
|
|
604
|
+
if (!didQuery) return null;
|
|
605
|
+
const { getConnection } = await import("../lib/db-connection.js");
|
|
606
|
+
const { getIdentity } = await import("../lib/did-manager.js");
|
|
607
|
+
const db = await getConnection();
|
|
608
|
+
const identity = getIdentity(db, didQuery);
|
|
609
|
+
if (!identity) {
|
|
610
|
+
throw new Error(`DID identity not found: ${didQuery}`);
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
did: identity.did,
|
|
614
|
+
publicKey: identity.public_key,
|
|
615
|
+
privateKey: identity.secret_key,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
|
|
597
619
|
share
|
|
598
620
|
.command("export-template <id>")
|
|
599
621
|
.description("Export an installed template as a signed packet")
|
|
600
622
|
.requiredOption("--out <file>", "Output packet file (.json)")
|
|
601
623
|
.option("--author <name>", "Author name", "anonymous")
|
|
624
|
+
.option("--sign <did>", "Sign packet with a local DID identity")
|
|
602
625
|
.action(async (id, options) => {
|
|
603
626
|
const [{ listUserTemplates }, { exportTemplatePacket, writePacket }] =
|
|
604
627
|
await Promise.all([
|
|
@@ -611,9 +634,20 @@ export function registerCoworkCommand(program) {
|
|
|
611
634
|
logger.error(`Template not installed: ${id}`);
|
|
612
635
|
process.exit(1);
|
|
613
636
|
}
|
|
614
|
-
|
|
637
|
+
let signer = null;
|
|
638
|
+
try {
|
|
639
|
+
signer = await _resolveSigner(options.sign);
|
|
640
|
+
} catch (err) {
|
|
641
|
+
logger.error(err.message);
|
|
642
|
+
process.exit(1);
|
|
643
|
+
}
|
|
644
|
+
const packet = exportTemplatePacket(tpl, {
|
|
645
|
+
author: options.author,
|
|
646
|
+
signer,
|
|
647
|
+
});
|
|
615
648
|
writePacket(options.out, packet);
|
|
616
649
|
logger.log(chalk.green(`✓ Wrote template packet to ${options.out}`));
|
|
650
|
+
if (signer) logger.log(chalk.gray(` signed by: ${signer.did}`));
|
|
617
651
|
});
|
|
618
652
|
|
|
619
653
|
share
|
|
@@ -621,6 +655,7 @@ export function registerCoworkCommand(program) {
|
|
|
621
655
|
.description("Export a historical Cowork task result as a signed packet")
|
|
622
656
|
.requiredOption("--out <file>", "Output packet file (.json)")
|
|
623
657
|
.option("--author <name>", "Author name", "anonymous")
|
|
658
|
+
.option("--sign <did>", "Sign packet with a local DID identity")
|
|
624
659
|
.action(async (taskId, options) => {
|
|
625
660
|
const { findHistoryRecord, exportResultPacket, writePacket } =
|
|
626
661
|
await import("../lib/cowork-share.js");
|
|
@@ -629,9 +664,20 @@ export function registerCoworkCommand(program) {
|
|
|
629
664
|
logger.error(`Task not found in history: ${taskId}`);
|
|
630
665
|
process.exit(1);
|
|
631
666
|
}
|
|
632
|
-
|
|
667
|
+
let signer = null;
|
|
668
|
+
try {
|
|
669
|
+
signer = await _resolveSigner(options.sign);
|
|
670
|
+
} catch (err) {
|
|
671
|
+
logger.error(err.message);
|
|
672
|
+
process.exit(1);
|
|
673
|
+
}
|
|
674
|
+
const packet = exportResultPacket(rec, {
|
|
675
|
+
author: options.author,
|
|
676
|
+
signer,
|
|
677
|
+
});
|
|
633
678
|
writePacket(options.out, packet);
|
|
634
679
|
logger.log(chalk.green(`✓ Wrote result packet to ${options.out}`));
|
|
680
|
+
if (signer) logger.log(chalk.gray(` signed by: ${signer.did}`));
|
|
635
681
|
});
|
|
636
682
|
|
|
637
683
|
share
|
|
@@ -639,11 +685,20 @@ export function registerCoworkCommand(program) {
|
|
|
639
685
|
.description(
|
|
640
686
|
"Import a signed packet (auto-detects template vs result by kind)",
|
|
641
687
|
)
|
|
642
|
-
.
|
|
688
|
+
.option("--require-signed", "Reject unsigned packets")
|
|
689
|
+
.option(
|
|
690
|
+
"--trust <did>",
|
|
691
|
+
"Accept only packets signed by one of these DIDs (repeatable)",
|
|
692
|
+
(value, prev) => (prev ? [...prev, value] : [value]),
|
|
693
|
+
)
|
|
694
|
+
.action(async (file, options) => {
|
|
643
695
|
const { readPacket, importTemplatePacket, importResultPacket } =
|
|
644
696
|
await import("../lib/cowork-share.js");
|
|
645
697
|
try {
|
|
646
|
-
const packet = readPacket(file
|
|
698
|
+
const packet = readPacket(file, {
|
|
699
|
+
requireSigned: !!options.requireSigned,
|
|
700
|
+
trustedDids: options.trust || null,
|
|
701
|
+
});
|
|
647
702
|
if (packet.kind === "template") {
|
|
648
703
|
const tpl = importTemplatePacket(process.cwd(), packet);
|
|
649
704
|
logger.log(chalk.green(`✓ Imported template '${tpl.id}'`));
|
|
@@ -674,6 +729,11 @@ export function registerCoworkCommand(program) {
|
|
|
674
729
|
logger.log(chalk.gray(` author: ${pkt.meta.author}`));
|
|
675
730
|
logger.log(chalk.gray(` createdAt: ${pkt.meta.createdAt}`));
|
|
676
731
|
logger.log(chalk.gray(` checksum: ${pkt.checksum.slice(0, 16)}…`));
|
|
732
|
+
if (pkt.signature) {
|
|
733
|
+
logger.log(chalk.gray(` signed by: ${pkt.signature.did}`));
|
|
734
|
+
} else {
|
|
735
|
+
logger.log(chalk.gray(` signed: no`));
|
|
736
|
+
}
|
|
677
737
|
} catch (err) {
|
|
678
738
|
logger.error(err.message);
|
|
679
739
|
process.exit(1);
|
|
@@ -808,6 +868,118 @@ export function registerCoworkCommand(program) {
|
|
|
808
868
|
}
|
|
809
869
|
});
|
|
810
870
|
|
|
871
|
+
// cowork observe — unified dashboard over tasks/workflows/schedules
|
|
872
|
+
const observe = cowork
|
|
873
|
+
.command("observe")
|
|
874
|
+
.description(
|
|
875
|
+
"Aggregate view over Cowork history, workflows, and schedules",
|
|
876
|
+
);
|
|
877
|
+
|
|
878
|
+
observe
|
|
879
|
+
.command("report", { isDefault: true })
|
|
880
|
+
.description("Print the aggregate report (default)")
|
|
881
|
+
.option("--days <n>", "Window size in days", "7")
|
|
882
|
+
.option("--json", "Output as JSON")
|
|
883
|
+
.action(async (options) => {
|
|
884
|
+
const { aggregate } = await import("../lib/cowork-observe.js");
|
|
885
|
+
const windowDays = parseInt(options.days, 10) || 7;
|
|
886
|
+
const data = aggregate(process.cwd(), { windowDays });
|
|
887
|
+
if (options.json) {
|
|
888
|
+
console.log(JSON.stringify(data, null, 2));
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
const pct = (x) => `${Math.round((x || 0) * 100)}%`;
|
|
892
|
+
logger.log(chalk.bold(`Cowork Observe — last ${data.window.days}d`));
|
|
893
|
+
logger.log(chalk.gray(` ${data.window.from} → ${data.window.to}`));
|
|
894
|
+
logger.log("");
|
|
895
|
+
logger.log(chalk.cyan("Tasks"));
|
|
896
|
+
logger.log(` total: ${data.tasks.total}`);
|
|
897
|
+
logger.log(` completed: ${data.tasks.completed}`);
|
|
898
|
+
logger.log(` failed: ${data.tasks.failed}`);
|
|
899
|
+
logger.log(` success rate: ${pct(data.tasks.successRate)}`);
|
|
900
|
+
logger.log(` avg tokens: ${data.tasks.avgTokens}`);
|
|
901
|
+
logger.log("");
|
|
902
|
+
logger.log(chalk.cyan(`Templates (${data.templates.length})`));
|
|
903
|
+
for (const t of data.templates.slice(0, 5)) {
|
|
904
|
+
logger.log(
|
|
905
|
+
` ${t.templateName || t.templateId} runs=${t.runs} success=${pct(t.successRate)}`,
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
logger.log("");
|
|
909
|
+
logger.log(chalk.cyan("Schedules"));
|
|
910
|
+
logger.log(` active: ${data.schedules.active}`);
|
|
911
|
+
for (const n of data.schedules.nextTriggers) {
|
|
912
|
+
logger.log(
|
|
913
|
+
chalk.gray(` next: ${n.at} ${n.cron} (${n.scheduleId || "-"})`),
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
if (data.failures.length > 0) {
|
|
917
|
+
logger.log("");
|
|
918
|
+
logger.log(chalk.yellow(`Failures (${data.failures.length})`));
|
|
919
|
+
for (const f of data.failures.slice(0, 3)) {
|
|
920
|
+
const top = f.commonSummaries?.[0]?.summary || "—";
|
|
921
|
+
logger.log(
|
|
922
|
+
` ${f.templateName || f.templateId} ×${f.failureCount} ${top.slice(0, 60)}`,
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
observe
|
|
929
|
+
.command("serve")
|
|
930
|
+
.description("Start a read-only HTTP dashboard")
|
|
931
|
+
.option("--port <n>", "HTTP port (0 for random)", "18820")
|
|
932
|
+
.option("--host <addr>", "Bind address", "127.0.0.1")
|
|
933
|
+
.option("--days <n>", "Window size in days", "7")
|
|
934
|
+
.action(async (options) => {
|
|
935
|
+
const http = await import("node:http");
|
|
936
|
+
const { aggregate } = await import("../lib/cowork-observe.js");
|
|
937
|
+
const { buildHtml } = await import("../lib/cowork-observe-html.js");
|
|
938
|
+
const windowDays = parseInt(options.days, 10) || 7;
|
|
939
|
+
|
|
940
|
+
const server = http.createServer((req, res) => {
|
|
941
|
+
const urlPath = (req.url || "/").split("?")[0];
|
|
942
|
+
try {
|
|
943
|
+
if (urlPath === "/" || urlPath === "/index.html") {
|
|
944
|
+
const data = aggregate(process.cwd(), { windowDays });
|
|
945
|
+
const html = buildHtml(data);
|
|
946
|
+
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
947
|
+
res.end(html);
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
if (urlPath === "/api/observe") {
|
|
951
|
+
const data = aggregate(process.cwd(), { windowDays });
|
|
952
|
+
res.writeHead(200, {
|
|
953
|
+
"content-type": "application/json; charset=utf-8",
|
|
954
|
+
});
|
|
955
|
+
res.end(JSON.stringify(data));
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
959
|
+
res.end("Not found");
|
|
960
|
+
} catch (err) {
|
|
961
|
+
res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
|
|
962
|
+
res.end(`Error: ${err.message}`);
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
const port = parseInt(options.port, 10);
|
|
967
|
+
server.listen(Number.isFinite(port) ? port : 18820, options.host, () => {
|
|
968
|
+
const addr = server.address();
|
|
969
|
+
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
970
|
+
logger.log(
|
|
971
|
+
chalk.green(
|
|
972
|
+
`✓ Cowork Observe dashboard at http://${options.host}:${actualPort}/`,
|
|
973
|
+
),
|
|
974
|
+
);
|
|
975
|
+
logger.log(chalk.gray(" Press Ctrl+C to stop."));
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
process.on("SIGINT", () => {
|
|
979
|
+
server.close(() => process.exit(0));
|
|
980
|
+
});
|
|
981
|
+
});
|
|
982
|
+
|
|
811
983
|
// cowork learning — analyze historical runs
|
|
812
984
|
const learning = cowork
|
|
813
985
|
.command("learning")
|
|
@@ -275,3 +275,143 @@ export async function handleOrchestrate(server, id, ws, message) {
|
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
|
+
|
|
279
|
+
// ─── Workflow (N1) ───────────────────────────────────────────────────────────
|
|
280
|
+
|
|
281
|
+
function _cwd(server) {
|
|
282
|
+
return server.projectRoot || process.cwd();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function _sendError(server, ws, id, code, message) {
|
|
286
|
+
server._send(ws, { id, type: "error", code, message });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export async function handleWorkflowList(server, id, ws) {
|
|
290
|
+
try {
|
|
291
|
+
const { listWorkflows } = await import("../../lib/cowork-workflow.js");
|
|
292
|
+
const workflows = listWorkflows(_cwd(server));
|
|
293
|
+
server._send(ws, { id, type: "workflow:list", workflows });
|
|
294
|
+
} catch (err) {
|
|
295
|
+
_sendError(server, ws, id, "WORKFLOW_LIST_FAILED", err.message);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export async function handleWorkflowGet(server, id, ws, message) {
|
|
300
|
+
const { id: wfId } = message || {};
|
|
301
|
+
if (!wfId) return _sendError(server, ws, id, "MISSING_ID", "id required");
|
|
302
|
+
try {
|
|
303
|
+
const { getWorkflow } = await import("../../lib/cowork-workflow.js");
|
|
304
|
+
const workflow = getWorkflow(_cwd(server), wfId);
|
|
305
|
+
server._send(ws, { id, type: "workflow:get", workflow: workflow || null });
|
|
306
|
+
} catch (err) {
|
|
307
|
+
_sendError(server, ws, id, "WORKFLOW_GET_FAILED", err.message);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export async function handleWorkflowSave(server, id, ws, message) {
|
|
312
|
+
const { workflow } = message || {};
|
|
313
|
+
if (!workflow || typeof workflow !== "object") {
|
|
314
|
+
return _sendError(
|
|
315
|
+
server,
|
|
316
|
+
ws,
|
|
317
|
+
id,
|
|
318
|
+
"INVALID_WORKFLOW",
|
|
319
|
+
"workflow object required",
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
const { validateWorkflow, saveWorkflow } =
|
|
324
|
+
await import("../../lib/cowork-workflow.js");
|
|
325
|
+
const result = validateWorkflow(workflow);
|
|
326
|
+
if (!result.valid) {
|
|
327
|
+
return _sendError(
|
|
328
|
+
server,
|
|
329
|
+
ws,
|
|
330
|
+
id,
|
|
331
|
+
"WORKFLOW_INVALID",
|
|
332
|
+
result.errors.join("; "),
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
saveWorkflow(_cwd(server), workflow);
|
|
336
|
+
server._send(ws, {
|
|
337
|
+
id,
|
|
338
|
+
type: "workflow:save",
|
|
339
|
+
saved: true,
|
|
340
|
+
workflowId: workflow.id,
|
|
341
|
+
});
|
|
342
|
+
} catch (err) {
|
|
343
|
+
_sendError(server, ws, id, "WORKFLOW_SAVE_FAILED", err.message);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export async function handleWorkflowRemove(server, id, ws, message) {
|
|
348
|
+
const { id: wfId } = message || {};
|
|
349
|
+
if (!wfId) return _sendError(server, ws, id, "MISSING_ID", "id required");
|
|
350
|
+
try {
|
|
351
|
+
const { removeWorkflow } = await import("../../lib/cowork-workflow.js");
|
|
352
|
+
const removed = removeWorkflow(_cwd(server), wfId);
|
|
353
|
+
server._send(ws, { id, type: "workflow:remove", removed });
|
|
354
|
+
} catch (err) {
|
|
355
|
+
_sendError(server, ws, id, "WORKFLOW_REMOVE_FAILED", err.message);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export async function handleWorkflowRun(server, id, ws, message) {
|
|
360
|
+
const { id: wfId } = message || {};
|
|
361
|
+
if (!wfId) return _sendError(server, ws, id, "MISSING_ID", "id required");
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
const { getWorkflow, executeWorkflow } =
|
|
365
|
+
await import("../../lib/cowork-workflow.js");
|
|
366
|
+
const workflow = getWorkflow(_cwd(server), wfId);
|
|
367
|
+
if (!workflow) {
|
|
368
|
+
return _sendError(
|
|
369
|
+
server,
|
|
370
|
+
ws,
|
|
371
|
+
id,
|
|
372
|
+
"WORKFLOW_NOT_FOUND",
|
|
373
|
+
`No workflow: ${wfId}`,
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const runId = `wf-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
378
|
+
server._send(ws, { id, type: "workflow:started", runId, workflowId: wfId });
|
|
379
|
+
|
|
380
|
+
const onStepStart = ({ stepId, message: stepMessage }) => {
|
|
381
|
+
server._send(ws, {
|
|
382
|
+
id,
|
|
383
|
+
type: "workflow:step-start",
|
|
384
|
+
runId,
|
|
385
|
+
stepId,
|
|
386
|
+
message: stepMessage,
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
const onStepComplete = (outcome) => {
|
|
390
|
+
server._send(ws, {
|
|
391
|
+
id,
|
|
392
|
+
type: "workflow:step-complete",
|
|
393
|
+
runId,
|
|
394
|
+
stepId: outcome?.id,
|
|
395
|
+
status: outcome?.status,
|
|
396
|
+
summary: outcome?.result?.summary,
|
|
397
|
+
});
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
const record = await executeWorkflow({
|
|
401
|
+
workflow,
|
|
402
|
+
cwd: _cwd(server),
|
|
403
|
+
onStepStart,
|
|
404
|
+
onStepComplete,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
server._send(ws, {
|
|
408
|
+
id,
|
|
409
|
+
type: "workflow:done",
|
|
410
|
+
runId,
|
|
411
|
+
status: record?.status || "completed",
|
|
412
|
+
steps: record?.steps || [],
|
|
413
|
+
});
|
|
414
|
+
} catch (err) {
|
|
415
|
+
_sendError(server, ws, id, "WORKFLOW_RUN_FAILED", err.message);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
@@ -47,6 +47,11 @@ export function createWsMessageDispatcher(server) {
|
|
|
47
47
|
"cowork-cancel": () => server._handleCoworkCancel(id, ws, message),
|
|
48
48
|
"cowork-templates": () => server._handleCoworkTemplates(id, ws),
|
|
49
49
|
"cowork-history": () => server._handleCoworkHistory(id, ws, message),
|
|
50
|
+
"workflow-list": () => server._handleWorkflowList(id, ws),
|
|
51
|
+
"workflow-get": () => server._handleWorkflowGet(id, ws, message),
|
|
52
|
+
"workflow-save": () => server._handleWorkflowSave(id, ws, message),
|
|
53
|
+
"workflow-remove": () => server._handleWorkflowRemove(id, ws, message),
|
|
54
|
+
"workflow-run": () => server._handleWorkflowRun(id, ws, message),
|
|
50
55
|
"tasks-list": () => server._handleTasksList(id, ws),
|
|
51
56
|
"tasks-stop": () => server._handleTasksStop(id, ws, message),
|
|
52
57
|
"tasks-detail": () => server._handleTaskDetail(id, ws, message),
|
|
@@ -55,6 +55,11 @@ import {
|
|
|
55
55
|
handleCoworkCancel,
|
|
56
56
|
handleCoworkTemplates,
|
|
57
57
|
handleCoworkHistory,
|
|
58
|
+
handleWorkflowList,
|
|
59
|
+
handleWorkflowGet,
|
|
60
|
+
handleWorkflowSave,
|
|
61
|
+
handleWorkflowRemove,
|
|
62
|
+
handleWorkflowRun,
|
|
58
63
|
} from "./action-protocol.js";
|
|
59
64
|
import {
|
|
60
65
|
handleWorktreeDiff,
|
|
@@ -321,6 +326,22 @@ export class ChainlessChainWSServer extends EventEmitter {
|
|
|
321
326
|
return handleCoworkHistory(this, id, ws, message);
|
|
322
327
|
}
|
|
323
328
|
|
|
329
|
+
_handleWorkflowList(id, ws) {
|
|
330
|
+
return handleWorkflowList(this, id, ws);
|
|
331
|
+
}
|
|
332
|
+
_handleWorkflowGet(id, ws, message) {
|
|
333
|
+
return handleWorkflowGet(this, id, ws, message);
|
|
334
|
+
}
|
|
335
|
+
_handleWorkflowSave(id, ws, message) {
|
|
336
|
+
return handleWorkflowSave(this, id, ws, message);
|
|
337
|
+
}
|
|
338
|
+
_handleWorkflowRemove(id, ws, message) {
|
|
339
|
+
return handleWorkflowRemove(this, id, ws, message);
|
|
340
|
+
}
|
|
341
|
+
_handleWorkflowRun(id, ws, message) {
|
|
342
|
+
return handleWorkflowRun(this, id, ws, message);
|
|
343
|
+
}
|
|
344
|
+
|
|
324
345
|
/** @private – list background tasks */
|
|
325
346
|
async _handleTasksList(id, ws) {
|
|
326
347
|
try {
|