zigrix 0.1.0-alpha.8 → 0.1.0

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.
Files changed (86) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +159 -120
  3. package/dist/agents/registry.js +19 -2
  4. package/dist/agents/roles.d.ts +10 -0
  5. package/dist/agents/roles.js +83 -0
  6. package/dist/config/defaults.d.ts +88 -6
  7. package/dist/config/defaults.js +82 -50
  8. package/dist/config/load.d.ts +5 -3
  9. package/dist/config/load.js +69 -30
  10. package/dist/config/schema.d.ts +46 -4
  11. package/dist/config/schema.js +49 -3
  12. package/dist/configure.d.ts +2 -0
  13. package/dist/configure.js +37 -14
  14. package/dist/dashboard/.next/BUILD_ID +1 -1
  15. package/dist/dashboard/.next/app-build-manifest.json +13 -13
  16. package/dist/dashboard/.next/app-path-routes-manifest.json +3 -3
  17. package/dist/dashboard/.next/build-manifest.json +2 -2
  18. package/dist/dashboard/.next/prerender-manifest.json +6 -6
  19. package/dist/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/dist/dashboard/.next/server/app/_not-found.html +1 -1
  21. package/dist/dashboard/.next/server/app/_not-found.rsc +1 -1
  22. package/dist/dashboard/.next/server/app/api/auth/login/route.js +1 -1
  23. package/dist/dashboard/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  24. package/dist/dashboard/.next/server/app/api/auth/logout/route.js +1 -1
  25. package/dist/dashboard/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  26. package/dist/dashboard/.next/server/app/api/auth/session/route.js +1 -1
  27. package/dist/dashboard/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
  28. package/dist/dashboard/.next/server/app/api/auth/setup/route.js +1 -1
  29. package/dist/dashboard/.next/server/app/api/auth/setup/route_client-reference-manifest.js +1 -1
  30. package/dist/dashboard/.next/server/app/api/overview/route_client-reference-manifest.js +1 -1
  31. package/dist/dashboard/.next/server/app/api/stream/route_client-reference-manifest.js +1 -1
  32. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  33. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/conversation/route_client-reference-manifest.js +1 -1
  34. package/dist/dashboard/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  35. package/dist/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
  36. package/dist/dashboard/.next/server/app/login.html +1 -1
  37. package/dist/dashboard/.next/server/app/login.rsc +1 -1
  38. package/dist/dashboard/.next/server/app/page.js +2 -2
  39. package/dist/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  40. package/dist/dashboard/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  41. package/dist/dashboard/.next/server/app/setup.html +1 -1
  42. package/dist/dashboard/.next/server/app/setup.rsc +1 -1
  43. package/dist/dashboard/.next/server/app-paths-manifest.json +3 -3
  44. package/dist/dashboard/.next/server/chunks/972.js +1 -1
  45. package/dist/dashboard/.next/server/functions-config-manifest.json +3 -3
  46. package/dist/dashboard/.next/server/middleware.js +1 -1
  47. package/dist/dashboard/.next/server/pages/404.html +1 -1
  48. package/dist/dashboard/.next/server/pages/500.html +1 -1
  49. package/dist/dashboard/.next/static/chunks/app/page-0314989c31e18b4b.js +1 -0
  50. package/dist/dashboard/.next/static/css/{94d75aff24d0c077.css → c3a7306cb2ba3f6c.css} +1 -1
  51. package/dist/dashboard.js +47 -0
  52. package/dist/doctor.js +28 -5
  53. package/dist/index.js +175 -171
  54. package/dist/onboard.d.ts +76 -2
  55. package/dist/onboard.js +529 -25
  56. package/dist/orchestration/dispatch.d.ts +3 -1
  57. package/dist/orchestration/dispatch.js +173 -45
  58. package/dist/orchestration/evidence.js +31 -4
  59. package/dist/orchestration/finalize.d.ts +1 -0
  60. package/dist/orchestration/finalize.js +5 -3
  61. package/dist/orchestration/report.js +9 -1
  62. package/dist/orchestration/worker.d.ts +1 -1
  63. package/dist/orchestration/worker.js +58 -8
  64. package/dist/rules/templates.js +3 -6
  65. package/dist/state/tasks.d.ts +12 -0
  66. package/dist/state/tasks.js +7 -0
  67. package/package.json +23 -2
  68. package/rules/defaults/README.md +9 -9
  69. package/rules/defaults/{back-zig.md → backend-agent.md} +4 -4
  70. package/rules/defaults/{front-zig.md → frontend-agent.md} +4 -4
  71. package/rules/defaults/orchestrator-agent.md +261 -0
  72. package/rules/defaults/{qa-zig.md → qa-agent.md} +11 -11
  73. package/rules/defaults/{sec-zig.md → security-agent.md} +4 -4
  74. package/rules/defaults/{sys-zig.md → system-agent.md} +8 -9
  75. package/rules/defaults/worker-common.md +25 -19
  76. package/skills/zigrix-doctor/SKILL.md +4 -2
  77. package/skills/zigrix-evidence/SKILL.md +7 -3
  78. package/skills/zigrix-main-agent-guide/SKILL.md +128 -0
  79. package/skills/zigrix-shared/SKILL.md +27 -3
  80. package/skills/zigrix-task-create/SKILL.md +8 -2
  81. package/skills/zigrix-task-status/SKILL.md +5 -2
  82. package/skills/zigrix-worker/SKILL.md +12 -4
  83. package/dist/dashboard/.next/static/chunks/app/page-25f54e54e74fb3af.js +0 -1
  84. package/rules/defaults/pro-zig.md +0 -238
  85. /package/dist/dashboard/.next/static/{2a4glWei05xr4Jg0Ly6cp → PT4hYxzrqxj-Zq4ZjtKNg}/_buildManifest.js +0 -0
  86. /package/dist/dashboard/.next/static/{2a4glWei05xr4Jg0Ly6cp → PT4hYxzrqxj-Zq4ZjtKNg}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[974],{109:e=>{e.exports={badge:"StatusBadge_badge__M4ZLM",status_OPEN:"StatusBadge_status_OPEN__0Pm_x",status_IN_PROGRESS:"StatusBadge_status_IN_PROGRESS__JhYac",status_BLOCKED:"StatusBadge_status_BLOCKED__8FFag",status_DONE_PENDING_REPORT:"StatusBadge_status_DONE_PENDING_REPORT__yVdnt",status_REPORTED:"StatusBadge_status_REPORTED__0p67U",status_UNKNOWN:"StatusBadge_status_UNKNOWN__VkyXw"}},594:e=>{e.exports={wrap:"ConversationTab_wrap__1QSeD",toggle:"ConversationTab_toggle__3CZ5X",list:"ConversationTab_list__3x9W9",message:"ConversationTab_message__ATEZY",header:"ConversationTab_header__JCM4X",agent:"ConversationTab_agent__y3KdF",meta:"ConversationTab_meta__dMgwn",body:"ConversationTab_body__uCFH9",markdown:"ConversationTab_markdown__A8qFO",thinking:"ConversationTab_thinking__9ksh2",toolBox:"ConversationTab_toolBox__z6pL2",toolName:"ConversationTab_toolName__SLqEU",notice:"ConversationTab_notice__wCw5J",empty:"ConversationTab_empty__aB__j"}},2357:e=>{e.exports={wrap:"EventLogTab_wrap__x2X_J",empty:"EventLogTab_empty__LRJDo",list:"EventLogTab_list__nm_mD",item:"EventLogTab_item__VL0dt",ts:"EventLogTab_ts__vQ9nA",name:"EventLogTab_name__4A39l"}},6143:e=>{e.exports={main:"DashboardClient_main__eZK1S",header:"DashboardClient_header__21U6H",brand:"DashboardClient_brand__1Ljqy",headerRight:"DashboardClient_headerRight__EinuX",sseWrap:"DashboardClient_sseWrap__dCBYi",dot:"DashboardClient_dot__NxKpZ",dot_connected:"DashboardClient_dot_connected__3UnYe",dot_disconnected:"DashboardClient_dot_disconnected__0IqOj",dot_connecting:"DashboardClient_dot_connecting__NNLev",statusBar:"DashboardClient_statusBar__eP3FN",statusItem:"DashboardClient_statusItem__Yi9TP",error:"DashboardClient_error__Tv__n",layout:"DashboardClient_layout__s4BTz",left:"DashboardClient_left__WqNyg",right:"DashboardClient_right__EWclx",tabs:"DashboardClient_tabs__tx3BS",tabActive:"DashboardClient_tabActive__5oF9r",panel:"DashboardClient_panel__bWB7I"}},6297:(e,t,a)=>{Promise.resolve().then(a.bind(a,9843))},6583:e=>{e.exports={wrap:"TaskDetailTab_wrap__dFSwq",empty:"TaskDetailTab_empty__wxQD4",header:"TaskDetailTab_header___564C",badges:"TaskDetailTab_badges__xm9EG",metaRow:"TaskDetailTab_metaRow__OSbDu",cancelButton:"TaskDetailTab_cancelButton__ReU0K",section:"TaskDetailTab_section__4dUxv",muted:"TaskDetailTab_muted__VWQMQ",units:"TaskDetailTab_units__XIBtG",unitCard:"TaskDetailTab_unitCard__jY43J",unitTop:"TaskDetailTab_unitTop__yZ5FK",unitMeta:"TaskDetailTab_unitMeta__LnHSZ",progressTrack:"TaskDetailTab_progressTrack__VlE22",progressFill:"TaskDetailTab_progressFill__JVS7w",evidenceList:"TaskDetailTab_evidenceList__xGfBZ",toggle:"TaskDetailTab_toggle__ujWwI",markdown:"TaskDetailTab_markdown__eoDyT"}},8157:e=>{e.exports={badge:"ScaleBadge_badge__Ufu_B",scale_simple:"ScaleBadge_scale_simple__MbInQ",scale_normal:"ScaleBadge_scale_normal__vPQOk",scale_risky:"ScaleBadge_scale_risky__pWko0",scale_large:"ScaleBadge_scale_large__aXng2",scale_unknown:"ScaleBadge_scale_unknown__gCQWs"}},9221:e=>{e.exports={wrap:"TaskList_wrap__JJmVD",filters:"TaskList_filters__P_eut",tabs:"TaskList_tabs__MrUoG",tab:"TaskList_tab__PJ3u6",tabActive:"TaskList_tabActive__hqEIw",input:"TaskList_input__069mt",select:"TaskList_select__07ygx",list:"TaskList_list__zaHPI",card:"TaskList_card__UWMn4",cardSelected:"TaskList_cardSelected__e4ZHd",cardTop:"TaskList_cardTop__ogfsJ",taskId:"TaskList_taskId__RiYub",title:"TaskList_title__BjaLg",metaRow:"TaskList_metaRow__zxzxl",dot:"TaskList_dot__zkHSK",pagination:"TaskList_pagination__3aWZh"}},9843:(e,t,a)=>{"use strict";a.d(t,{DashboardClient:()=>R});var s=a(5155),n=a(2115),l=a(109),i=a.n(l);let r={OPEN:{label:"대기",icon:"\uD83D\uDD35"},IN_PROGRESS:{label:"진행 중",icon:"\uD83D\uDFE0"},BLOCKED:{label:"차단",icon:"\uD83D\uDD34"},DONE_PENDING_REPORT:{label:"보고 대기",icon:"\uD83D\uDFE3"},REPORTED:{label:"보고 완료",icon:"\uD83D\uDFE2"}};function c(e){let{status:t}=e,a=(t||"UNKNOWN").toUpperCase(),n=r[a]||{label:t||"알 수 없음",icon:"⚪"};return(0,s.jsxs)("span",{className:"".concat(i().badge," ").concat(i()["status_".concat(a)]||i().status_UNKNOWN),children:[(0,s.jsx)("span",{"aria-hidden":!0,children:n.icon}),(0,s.jsx)("span",{children:n.label})]})}var o=a(8157),d=a.n(o);let u={simple:"simple",normal:"normal",risky:"risky",large:"large"};function _(e){let{scale:t}=e,a=(t||"unknown").toLowerCase(),n=u[a]||a;return(0,s.jsx)("span",{className:"".concat(d().badge," ").concat(d()["scale_".concat(a)]||d().scale_unknown),children:n})}function h(e){let{value:t}=e,[,a]=(0,n.useReducer)(e=>e+1,0);return(0,n.useEffect)(()=>{let e=setInterval(a,6e4);return()=>clearInterval(e)},[]),(0,s.jsx)("span",{title:t||"",children:function(e){if(!e)return"-";let t=new Date(e).getTime();if(!Number.isFinite(t))return e;let a=Math.floor((Date.now()-t)/1e3);if(a<5)return"방금 전";if(a<60)return"".concat(a,"초 전");let s=Math.floor(a/60);if(s<60)return"".concat(s,"분 전");let n=Math.floor(s/60);if(n<24)return"".concat(n,"시간 전");let l=Math.floor(n/24);return l<30?"".concat(l,"일 전"):new Date(e).toLocaleString("ko-KR")}(t)})}var m=a(9221),p=a.n(m);let x=["ALL","OPEN","IN_PROGRESS","BLOCKED","DONE_PENDING_REPORT","REPORTED"];function v(e){let{tasks:t,selectedTaskId:a,onSelectTask:l}=e,[i,r]=(0,n.useState)("ALL"),[o,d]=(0,n.useState)(""),[u,m]=(0,n.useState)("newest"),[v,g]=(0,n.useState)(1),k=(0,n.useMemo)(()=>{let e=o.trim().toLowerCase();return[...t.filter(t=>("ALL"===i||(t.status||"")===i)&&(!e||[t.taskId,t.title||"",t.actor||""].some(t=>t.toLowerCase().includes(e))))].sort((e,t)=>{if("taskId"===u)return e.taskId.localeCompare(t.taskId);let a=Date.parse(e.updatedAt||"")||0,s=Date.parse(t.updatedAt||"")||0;return"newest"===u?s-a:a-s})},[t,o,u,i]),N=Math.max(1,Math.ceil(k.length/12)),b=Math.min(v,N),j=k.slice((b-1)*12,12*b);return(0,s.jsxs)("section",{className:p().wrap,children:[(0,s.jsxs)("div",{className:p().filters,children:[(0,s.jsx)("div",{className:p().tabs,children:x.map(e=>(0,s.jsx)("button",{type:"button",className:"".concat(p().tab," ").concat(i===e?p().tabActive:""),onClick:()=>{r(e),g(1)},children:e},e))}),(0,s.jsx)("input",{className:p().input,placeholder:"taskId / title / actor 검색",value:o,onChange:e=>{d(e.target.value),g(1)}}),(0,s.jsxs)("select",{className:p().select,value:u,onChange:e=>{m(e.target.value),g(1)},children:[(0,s.jsx)("option",{value:"newest",children:"최신순"}),(0,s.jsx)("option",{value:"oldest",children:"오래된순"}),(0,s.jsx)("option",{value:"taskId",children:"taskId순"})]})]}),(0,s.jsx)("ul",{className:p().list,children:j.map(e=>(0,s.jsx)("li",{children:(0,s.jsxs)("button",{type:"button",className:"".concat(p().card," ").concat(a===e.taskId?p().cardSelected:""),onClick:()=>l(e.taskId),children:[(0,s.jsxs)("div",{className:p().cardTop,children:[(0,s.jsx)("code",{className:p().taskId,children:e.taskId}),(0,s.jsx)(c,{status:e.status})]}),(0,s.jsx)("p",{className:p().title,children:e.title||"(제목 없음)"}),(0,s.jsxs)("div",{className:p().metaRow,children:[(0,s.jsx)(_,{scale:e.scale}),(0,s.jsx)("span",{children:e.actor||"-"}),(0,s.jsx)("span",{className:p().dot,children:"•"}),(0,s.jsx)(h,{value:e.updatedAt})]})]})},e.taskId))}),(0,s.jsxs)("div",{className:p().pagination,children:[(0,s.jsx)("button",{type:"button",disabled:b<=1,onClick:()=>g(e=>Math.max(1,e-1)),children:"이전"}),(0,s.jsxs)("span",{children:[b," / ",N]}),(0,s.jsx)("button",{type:"button",disabled:b>=N,onClick:()=>g(e=>Math.min(N,e+1)),children:"다음"})]})]})}var g=a(856),k=a(6583),N=a.n(k);function b(e){var t,a;let{detail:l,onCancelTask:i,cancelling:r}=e,[o,d]=(0,n.useState)(!1),u=(0,n.useMemo)(()=>{var e,t;let a=null==l||null==(t=l.meta)||null==(e=t.data)?void 0:e.executionUnits;return Array.isArray(a)?a:[]},[l]);if(!l)return(0,s.jsx)("div",{className:N().empty,children:"태스크를 선택해 주세요."});let m=l.task.status,p=(l.spec.preview||"").split(/\r?\n/),x=o?p:p.slice(0,20),v=new Set(l.evidence.agents.map(e=>e.agentId)),k=Array.isArray(null==(t=l.evidence.merged)?void 0:t.requiredAgents)?null==(a=l.evidence.merged)?void 0:a.requiredAgents:Array.from(v);return(0,s.jsxs)("div",{className:N().wrap,children:[(0,s.jsxs)("div",{className:N().header,children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{children:l.task.title||"(제목 없음)"}),(0,s.jsx)("code",{children:l.task.taskId})]}),(0,s.jsxs)("div",{className:N().badges,children:[(0,s.jsx)(c,{status:m}),(0,s.jsx)(_,{scale:l.task.scale})]})]}),(0,s.jsxs)("div",{className:N().metaRow,children:[(0,s.jsxs)("span",{children:["생성: ",(0,s.jsx)(h,{value:l.spec.metadata.createdAt||null})]}),(0,s.jsxs)("span",{children:["업데이트: ",(0,s.jsx)(h,{value:l.task.updatedAt})]})]}),("OPEN"===m||"IN_PROGRESS"===m)&&(0,s.jsx)("button",{type:"button",className:N().cancelButton,onClick:()=>i(l.task.taskId),disabled:r,children:r?"취소 중...":"태스크 취소"}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Execution Units"}),0===u.length?(0,s.jsx)("p",{className:N().muted,children:"Execution Units 정보가 없습니다."}):(0,s.jsx)("div",{className:N().units,children:u.map((e,t)=>{let a=Array.isArray(e.workPackages)?e.workPackages:[],n=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return e.filter(e=>["DONE","REPORTED","DONE_PENDING_REPORT","COMPLETED"].includes((e.status||"").toUpperCase())).length}(a),l=a.length,i=l>0?Math.round(n/l*100):0;return(0,s.jsxs)("article",{className:N().unitCard,children:[(0,s.jsxs)("div",{className:N().unitTop,children:[(0,s.jsx)("strong",{children:e.title||e.unitId||"Unit ".concat(t+1)}),(0,s.jsx)("span",{children:e.status||"-"})]}),(0,s.jsxs)("div",{className:N().unitMeta,children:[(0,s.jsxs)("span",{children:["unitId: ",e.unitId||"-"]}),(0,s.jsxs)("span",{children:["owner: ",e.owner||e.workerAgent||"-"]}),(0,s.jsxs)("span",{children:[n,"/",l]})]}),(0,s.jsx)("div",{className:N().progressTrack,children:(0,s.jsx)("div",{className:N().progressFill,style:{width:"".concat(i,"%")}})})]},e.unitId||"".concat(e.title||"unit","-").concat(t))})})]}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Evidence"}),0===k.length?(0,s.jsx)("p",{className:N().muted,children:"증적 제출 정보가 없습니다."}):(0,s.jsx)("ul",{className:N().evidenceList,children:k.map(e=>(0,s.jsxs)("li",{children:[(0,s.jsx)("span",{children:e}),(0,s.jsx)("span",{children:v.has(e)?"제출됨":"미제출"})]},e))})]}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Spec Preview"}),0===p.length?(0,s.jsx)("p",{className:N().muted,children:"스펙 파일이 없습니다."}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("button",{type:"button",className:N().toggle,onClick:()=>d(e=>!e),children:o?"접기":"펼치기"}),(0,s.jsx)("div",{className:N().markdown,children:(0,s.jsx)(g.oz,{children:x.join("\n")})})]})]})]})}var j=a(2357),T=a.n(j);function y(e){let{events:t}=e,a=(0,n.useRef)(null);return(0,n.useEffect)(()=>{a.current&&(a.current.scrollTop=0)},[t.length]),(0,s.jsx)("div",{ref:a,className:T().wrap,children:0===t.length?(0,s.jsx)("p",{className:T().empty,children:"이벤트가 없습니다."}):(0,s.jsx)("ul",{className:T().list,children:t.map((e,t)=>{let a=e.event||"unknown";return(0,s.jsxs)("li",{className:T().item,children:[(0,s.jsxs)("span",{className:T().ts,children:["[",function(e){if(!e)return"-";let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleTimeString("ko-KR")}(e.ts),"]"]})," ",(0,s.jsx)("span",{className:T().name,children:a})," | ",(0,s.jsxs)("span",{children:["task=",e.taskId||"-"]})," | ",(0,s.jsxs)("span",{children:["status=",e.status||"-"]})," | ","worker_dispatched"===a?(0,s.jsxs)("strong",{children:[e.actor||e.agentId||"-"," → ",e.targetAgent||"-"]}):(0,s.jsxs)("span",{children:["actor=",e.actor||e.agentId||"-"]})]},"".concat(e.ts||"no-ts","-").concat(a,"-").concat(t))})})})}var w=a(594),E=a.n(w);function C(e){let{conversation:t}=e,[a,l]=(0,n.useState)(!1),i=(0,n.useRef)(null);(0,n.useEffect)(()=>{let e=i.current;e&&e.scrollHeight-e.scrollTop-e.clientHeight<200&&(e.scrollTop=e.scrollHeight)},[null==t?void 0:t.stream.length]);let r=(0,n.useMemo)(()=>(null==t?void 0:t.stream)||[],[t]);return t?t.openclawAvailable?(0,s.jsxs)("div",{className:E().wrap,children:[(0,s.jsxs)("label",{className:E().toggle,children:[(0,s.jsx)("input",{type:"checkbox",checked:a,onChange:e=>l(e.target.checked)}),(0,s.jsx)("span",{children:"Debug"})]}),(0,s.jsx)("div",{ref:i,className:E().list,children:r.map((e,t)=>{var n,l;let i=(n=e.content,l=e.toolName,"string"==typeof n?[{type:"text",text:n}]:Array.isArray(n)?n.flatMap(e=>{var t,a,s;if(!e||"object"!=typeof e)return[];let n=String(e.type||"text");return("text"===n||"markdown"===n)&&"string"==typeof e.text?[{type:"text",text:e.text}]:"thinking"===n&&"string"==typeof e.thinking?[{type:"thinking",text:e.thinking}]:("tool_use"===n||"toolCall"===n)&&("string"==typeof e.name||"string"==typeof e.toolName)?[{type:"toolCall",toolName:e.name||e.toolName||l||"tool",text:JSON.stringify(null!=(a=null!=(t=e.input)?t:e.arguments)?a:{},null,2)}]:"tool_result"===n||"toolResult"===n?[{type:"toolResult",toolName:l||"tool",text:"string"==typeof e.content?e.content:JSON.stringify(null!=(s=e.content)?s:e,null,2)}]:"string"==typeof e.text?[{type:"text",text:e.text}]:[{type:"text",text:JSON.stringify(e,null,2)}]}):[{type:"text",text:null==n?"":JSON.stringify(n,null,2)}]),r=function(e){let t=0;for(let a=0;a<e.length;a+=1)t=(t<<5)-t+e.charCodeAt(a);let a=Math.abs(t)%360;return"hsl(".concat(a," 65% 45%)")}(e.agentId||e.agentName||"agent");return(0,s.jsxs)("article",{className:E().message,children:[(0,s.jsxs)("header",{className:E().header,children:[(0,s.jsx)("span",{className:E().agent,style:{backgroundColor:r},children:e.agentName||e.agentId}),(0,s.jsx)("span",{className:E().meta,children:e.role||"unknown"}),(0,s.jsx)("span",{className:E().meta,children:e.ts?new Date(e.ts).toLocaleTimeString("ko-KR"):"-"})]}),(0,s.jsx)("div",{className:E().body,children:i.filter(t=>{var s;return s=e.role,"text"===t.type?"assistant"===s||"user"===s:a}).map((e,t)=>"thinking"===e.type?(0,s.jsxs)("details",{className:E().thinking,children:[(0,s.jsx)("summary",{children:"thinking"}),(0,s.jsx)("pre",{children:e.text})]},t):"toolCall"===e.type||"toolResult"===e.type?(0,s.jsxs)("div",{className:E().toolBox,children:[(0,s.jsxs)("span",{className:E().toolName,children:[e.type,": ",e.toolName]}),(0,s.jsx)("pre",{children:e.text})]},t):(0,s.jsx)("div",{className:E().markdown,children:(0,s.jsx)(g.oz,{children:e.text||""})},t))})]},"".concat(e.sessionKey,"-").concat(e.timestamp||t))})})]}):(0,s.jsx)("div",{className:E().notice,children:"OpenClaw 연동 필요"}):(0,s.jsx)("div",{className:E().empty,children:"태스크를 선택해 주세요."})}var f=a(6143),D=a.n(f);let S=["OPEN","IN_PROGRESS","BLOCKED","DONE_PENDING_REPORT","REPORTED"];async function I(e,t){let a=await fetch(e,{...t,cache:"no-store"});if(!a.ok){let e=await a.json().catch(()=>({}));throw Error("string"==typeof(null==e?void 0:e.error)?e.error:"HTTP ".concat(a.status))}return await a.json()}function R(e){var t;let{initialOverview:a,initialTaskDetail:l,initialConversation:i,initialSelectedTaskId:r}=e,[c,o]=(0,n.useState)(a),[d,u]=(0,n.useState)(r),[_,h]=(0,n.useState)(l),[m,p]=(0,n.useState)(i),[x,g]=(0,n.useState)("detail"),[k,N]=(0,n.useState)("connecting"),[j,T]=(0,n.useState)(!1),[w,E]=(0,n.useState)(null),[f,R]=(0,n.useState)(!1),O=(0,n.useRef)((null==(t=a.recentEvents[0])?void 0:t.ts)||null),L=(0,n.useRef)(null),P=(0,n.useRef)(null),A=(0,n.useMemo)(()=>null===d?[]:c.recentEvents.filter(e=>e.taskId===d),[c.recentEvents,d]),B=(0,n.useMemo)(()=>(function(e){let t=new Map(e.activeTasks.map(e=>[e.taskId,e])),a=new Map(e.taskHistory.map(e=>[e.taskId,e]));return Array.from(new Set([...e.taskHistory.map(e=>e.taskId),...e.activeTasks.map(e=>e.taskId)])).map(e=>{let s=a.get(e),n=t.get(e);return{taskId:e,status:(null==s?void 0:s.status)||(null==n?void 0:n.status)||null,title:(null==s?void 0:s.title)||(null==n?void 0:n.title)||null,scale:(null==s?void 0:s.scale)||(null==n?void 0:n.scale)||null,actor:(null==s?void 0:s.actor)||null,updatedAt:(null==s?void 0:s.ts)||(null==n?void 0:n.updatedAt)||null}})})(c),[c]),M=(0,n.useCallback)(async e=>{let[t,a]=await Promise.all([I("/api/tasks/".concat(encodeURIComponent(e))),I("/api/tasks/".concat(encodeURIComponent(e),"/conversation"))]);h(t),p(a)},[]),U=(0,n.useCallback)(async()=>{T(!0),E(null);try{var e,t;let a=await I("/api/overview");o(a);let s=(null==(e=a.recentEvents[0])?void 0:e.ts)||null;s&&(O.current=s);let n=d||(null==(t=a.taskHistory[0])?void 0:t.taskId)||null;n&&(u(n),await M(n))}catch(e){E(e.message||"새로고침 실패")}finally{T(!1)}},[M,d]),K=(0,n.useCallback)(async()=>{await fetch("/api/auth/logout",{method:"POST"}),window.location.href="/login"},[]),J=(0,n.useCallback)(async e=>{try{R(!0),E(null),await I("/api/tasks/".concat(encodeURIComponent(e),"/cancel"),{method:"POST"}),await U()}catch(e){E(e.message||"태스크 취소 실패")}finally{R(!1)}},[U]);return(0,n.useEffect)(()=>{d&&M(d).catch(e=>{E(e.message||"태스크 로딩 실패")})},[M,d]),(0,n.useEffect)(()=>{let e=!1,t=()=>{if(e)return;N("connecting");let a=new URLSearchParams;d&&a.set("taskId",d),O.current&&a.set("lastEventTs",O.current);let s=new EventSource("/api/stream".concat(a.toString()?"?".concat(a.toString()):""));P.current=s,s.onopen=()=>N("connected"),s.addEventListener("update",e=>{let t=JSON.parse(e.data);if(t.ts&&(O.current=t.ts),t.overview){var a,s;o(t.overview),!d&&(null==(a=t.overview.taskHistory[0])?void 0:a.taskId)&&u(t.overview.taskHistory[0].taskId);let e=null==(s=t.overview.recentEvents[0])?void 0:s.ts;e&&(O.current=e)}}),s.addEventListener("event_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),o(e=>({...e,recentEvents:t.recentEvents||e.recentEvents,taskHistory:t.taskHistory||e.taskHistory,bucketCounts:t.bucketCounts||e.bucketCounts}))}),s.addEventListener("task_detail_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),t.taskId&&t.taskId===d&&t.detail&&h(t.detail)}),s.addEventListener("conversation_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),t.taskId&&t.taskId===d&&p(e=>{var a,s;return{generatedAt:new Date().toISOString(),taskId:t.taskId||d,sessionKeys:t.sessionKeys||(null==e?void 0:e.sessionKeys)||[],stream:t.stream||(null==e?void 0:e.stream)||[],recentEvents:t.recentEvents||(null==e?void 0:e.recentEvents)||[],sessions:(null==e?void 0:e.sessions)||[],openclawAvailable:null!=(s=null!=(a=t.openclawAvailable)?a:null==e?void 0:e.openclawAvailable)&&s}})}),s.onerror=()=>{N("disconnected"),s.close(),L.current&&clearTimeout(L.current),L.current=setTimeout(t,1500)}};return t(),()=>{e=!0,L.current&&clearTimeout(L.current),P.current&&P.current.close()}},[d]),(0,s.jsxs)("main",{className:D().main,children:[(0,s.jsxs)("header",{className:D().header,children:[(0,s.jsx)("div",{className:D().brand,children:"Zigrix"}),(0,s.jsxs)("div",{className:D().headerRight,children:[(0,s.jsxs)("div",{className:D().sseWrap,children:[(0,s.jsx)("span",{className:"".concat(D().dot," ").concat(D()["dot_".concat(k)])}),(0,s.jsx)("span",{children:k})]}),(0,s.jsx)("button",{type:"button",onClick:()=>void U(),disabled:j,children:"새로고침"}),(0,s.jsx)("button",{type:"button",onClick:()=>void K(),children:"로그아웃"})]})]}),(0,s.jsx)("div",{className:D().statusBar,children:S.map(e=>(0,s.jsxs)("span",{className:D().statusItem,children:[e," (",c.bucketCounts[e]||0,")"]},e))}),w?(0,s.jsx)("p",{className:D().error,children:w}):null,(0,s.jsxs)("section",{className:D().layout,children:[(0,s.jsx)("aside",{className:D().left,children:(0,s.jsx)(v,{tasks:B,selectedTaskId:d,onSelectTask:u})}),(0,s.jsxs)("section",{className:D().right,children:[(0,s.jsxs)("nav",{className:D().tabs,children:[(0,s.jsx)("button",{type:"button",className:"detail"===x?D().tabActive:"",onClick:()=>g("detail"),children:"태스크 상세"}),(0,s.jsx)("button",{type:"button",className:"events"===x?D().tabActive:"",onClick:()=>g("events"),children:"이벤트 로그"}),(0,s.jsx)("button",{type:"button",className:"conversation"===x?D().tabActive:"",onClick:()=>g("conversation"),children:"대화 내역"})]}),(0,s.jsxs)("div",{className:D().panel,children:["detail"===x&&(0,s.jsx)(b,{detail:_,onCancelTask:J,cancelling:f}),"events"===x&&(0,s.jsx)(y,{events:A}),"conversation"===x&&(0,s.jsx)(C,{conversation:m})]})]})]})]})}}},e=>{e.O(0,[963,856,441,255,358],()=>e(e.s=6297)),_N_E=e.O()}]);
@@ -1 +1 @@
1
- .StatusBadge_badge__M4ZLM{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:3px 10px;font-size:12px;font-weight:700;border:1px solid var(--color-border)}.StatusBadge_status_OPEN__0Pm_x{color:var(--status-open);border-color:color-mix(in srgb,var(--status-open) 45%,var(--color-border));background:color-mix(in srgb,var(--status-open) 16%,transparent)}.StatusBadge_status_IN_PROGRESS__JhYac{color:var(--status-in-progress);border-color:color-mix(in srgb,var(--status-in-progress) 45%,var(--color-border));background:color-mix(in srgb,var(--status-in-progress) 16%,transparent)}.StatusBadge_status_BLOCKED__8FFag{color:var(--status-blocked);border-color:color-mix(in srgb,var(--status-blocked) 45%,var(--color-border));background:color-mix(in srgb,var(--status-blocked) 16%,transparent)}.StatusBadge_status_DONE_PENDING_REPORT__yVdnt{color:var(--status-done-pending-report);border-color:color-mix(in srgb,var(--status-done-pending-report) 45%,var(--color-border));background:color-mix(in srgb,var(--status-done-pending-report) 16%,transparent)}.StatusBadge_status_REPORTED__0p67U{color:var(--status-reported);border-color:color-mix(in srgb,var(--status-reported) 45%,var(--color-border));background:color-mix(in srgb,var(--status-reported) 16%,transparent)}.StatusBadge_status_UNKNOWN__VkyXw{color:var(--color-text-muted);background:var(--color-bg-card)}.ScaleBadge_badge__Ufu_B{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--color-border);padding:2px 8px;font-size:11px;text-transform:uppercase;letter-spacing:.04em}.ScaleBadge_scale_simple__MbInQ{color:#9ca3af}.ScaleBadge_scale_normal__vPQOk{color:#60a5fa}.ScaleBadge_scale_risky__pWko0{color:#f59e0b}.ScaleBadge_scale_large__aXng2{color:#ef4444}.ScaleBadge_scale_unknown__gCQWs{color:var(--color-text-muted)}.TaskList_wrap__JJmVD{display:flex;flex-direction:column;gap:12px;min-height:0}.TaskList_filters__P_eut{display:flex;flex-direction:column;gap:8px}.TaskList_tabs__MrUoG{display:flex;flex-wrap:wrap;gap:6px}.TaskList_tab__PJ3u6{border:1px solid var(--color-border);background:var(--color-bg-card);color:var(--color-text-muted);border-radius:999px;padding:4px 10px;font-size:11px;cursor:pointer}.TaskList_tabActive__hqEIw{color:var(--color-text);border-color:var(--color-accent);background:color-mix(in srgb,var(--color-accent) 18%,transparent)}.TaskList_input__069mt,.TaskList_select__07ygx{border:1px solid var(--color-border);background:var(--color-bg-card);color:var(--color-text);border-radius:8px;padding:8px 10px;font-size:13px}.TaskList_list__zaHPI{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;overflow-y:auto;min-height:0}.TaskList_card__UWMn4{width:100%;text-align:left;border:1px solid var(--color-border);background:var(--color-bg-card);border-radius:10px;padding:10px;color:var(--color-text);cursor:pointer}.TaskList_cardSelected__e4ZHd{border-color:var(--color-accent);background:color-mix(in srgb,var(--color-accent) 14%,transparent)}.TaskList_cardTop__ogfsJ{display:flex;justify-content:space-between;align-items:center;gap:8px}.TaskList_taskId__RiYub{font-size:12px;color:var(--color-text-muted)}.TaskList_title__BjaLg{margin:8px 0;font-weight:600;line-height:1.4}.TaskList_metaRow__zxzxl{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--color-text-muted)}.TaskList_dot__zkHSK{opacity:.7}.TaskList_pagination__3aWZh{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px}.TaskList_pagination__3aWZh button{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);color:var(--color-text);padding:4px 10px}.TaskDetailTab_wrap__dFSwq{display:flex;flex-direction:column;gap:14px}.TaskDetailTab_empty__wxQD4{color:var(--color-text-muted)}.TaskDetailTab_header___564C{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}.TaskDetailTab_header___564C h3{margin:0 0 6px}.TaskDetailTab_badges__xm9EG{display:flex;gap:8px;flex-wrap:wrap}.TaskDetailTab_metaRow__OSbDu{display:flex;gap:12px;font-size:13px;color:var(--color-text-muted);flex-wrap:wrap}.TaskDetailTab_cancelButton__ReU0K{align-self:flex-start;border:1px solid color-mix(in srgb,var(--status-blocked) 45%,var(--color-border));color:#fff;background:color-mix(in srgb,var(--status-blocked) 35%,#111);border-radius:8px;padding:6px 12px;cursor:pointer}.TaskDetailTab_cancelButton__ReU0K:disabled{opacity:.6;cursor:not-allowed}.TaskDetailTab_section__4dUxv{border:1px solid var(--color-border);border-radius:10px;background:var(--color-bg-card);padding:12px}.TaskDetailTab_section__4dUxv h4{margin:0 0 10px}.TaskDetailTab_muted__VWQMQ{color:var(--color-text-muted);font-size:13px}.TaskDetailTab_units__XIBtG{display:flex;flex-direction:column;gap:10px}.TaskDetailTab_unitCard__jY43J{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d;padding:10px}.TaskDetailTab_unitMeta__LnHSZ,.TaskDetailTab_unitTop__yZ5FK{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}.TaskDetailTab_unitMeta__LnHSZ{font-size:12px;color:var(--color-text-muted);margin-top:6px}.TaskDetailTab_progressTrack__VlE22{margin-top:8px;width:100%;height:8px;border-radius:999px;background:#1f1f1f;overflow:hidden}.TaskDetailTab_progressFill__JVS7w{height:100%;background:linear-gradient(90deg,var(--status-open),var(--status-reported))}.TaskDetailTab_evidenceList__xGfBZ{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}.TaskDetailTab_evidenceList__xGfBZ li{display:flex;justify-content:space-between;padding:6px 10px;font-size:13px}.TaskDetailTab_evidenceList__xGfBZ li,.TaskDetailTab_toggle__ujWwI{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d}.TaskDetailTab_toggle__ujWwI{color:var(--color-text);padding:5px 10px;margin-bottom:8px}.TaskDetailTab_markdown__eoDyT{font-size:14px;line-height:1.6}.EventLogTab_wrap__x2X_J{height:100%;overflow-y:auto}.EventLogTab_empty__LRJDo{color:var(--color-text-muted)}.EventLogTab_list__nm_mD{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}.EventLogTab_item__VL0dt{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);padding:8px 10px;font-size:13px;line-height:1.45;word-break:break-word}.EventLogTab_ts__vQ9nA{color:var(--color-text-muted)}.EventLogTab_name__4A39l{color:var(--color-accent)}.ConversationTab_wrap__1QSeD{height:100%;display:flex;flex-direction:column;gap:10px}.ConversationTab_toggle__3CZ5X{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--color-text-muted)}.ConversationTab_list__3x9W9{overflow-y:auto;display:flex;flex-direction:column;gap:10px;min-height:0}.ConversationTab_message__ATEZY{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);padding:8px}.ConversationTab_header__JCM4X{display:flex;align-items:center;gap:8px;margin-bottom:6px}.ConversationTab_agent__y3KdF{display:inline-flex;align-items:center;border-radius:999px;padding:2px 8px;font-size:11px;color:#fff;font-weight:700}.ConversationTab_meta__dMgwn{font-size:12px;color:var(--color-text-muted)}.ConversationTab_body__uCFH9{display:flex;flex-direction:column;gap:8px}.ConversationTab_markdown__A8qFO{font-size:14px;line-height:1.6}.ConversationTab_markdown__A8qFO p{margin:.4em 0}.ConversationTab_thinking__9ksh2,.ConversationTab_toolBox__z6pL2{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d;padding:8px}.ConversationTab_thinking__9ksh2 pre,.ConversationTab_toolBox__z6pL2 pre{margin:8px 0 0;white-space:pre-wrap;word-break:break-word;font-size:12px}.ConversationTab_toolName__SLqEU{font-size:12px;color:var(--color-accent)}.ConversationTab_empty__aB__j,.ConversationTab_notice__wCw5J{color:var(--color-text-muted)}.DashboardClient_main__eZK1S{max-width:1440px;margin:0 auto;padding:16px;display:flex;flex-direction:column;gap:12px}.DashboardClient_header__21U6H{display:flex;justify-content:space-between;align-items:center;border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg-card);padding:10px 14px}.DashboardClient_brand__1Ljqy{font-size:20px;font-weight:800}.DashboardClient_headerRight__EinuX{display:flex;align-items:center;gap:8px}.DashboardClient_headerRight__EinuX button{border:1px solid var(--color-border);background:#0d0d0d;color:var(--color-text);border-radius:8px;padding:6px 10px;cursor:pointer}.DashboardClient_sseWrap__dCBYi{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--color-text-muted);margin-right:4px}.DashboardClient_dot__NxKpZ{width:10px;height:10px;border-radius:999px}.DashboardClient_dot_connected__3UnYe{background:var(--status-reported)}.DashboardClient_dot_disconnected__0IqOj{background:var(--status-blocked)}.DashboardClient_dot_connecting__NNLev{background:var(--status-in-progress)}.DashboardClient_statusBar__eP3FN{display:flex;flex-wrap:wrap;gap:8px}.DashboardClient_statusItem__Yi9TP{border:1px solid var(--color-border);border-radius:999px;padding:3px 10px;font-size:12px;background:var(--color-bg-card)}.DashboardClient_error__Tv__n{margin:0;color:var(--status-blocked)}.DashboardClient_layout__s4BTz{display:grid;grid-template-columns:360px 1fr;grid-gap:12px;gap:12px;min-height:calc(100vh - 180px)}.DashboardClient_left__WqNyg,.DashboardClient_right__EWclx{border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg-card);min-height:0}.DashboardClient_left__WqNyg{padding:10px;overflow:hidden}.DashboardClient_right__EWclx{display:flex;flex-direction:column;overflow:hidden}.DashboardClient_tabs__tx3BS{display:flex;border-bottom:1px solid var(--color-border)}.DashboardClient_tabs__tx3BS button{border:0;border-right:1px solid var(--color-border);background:transparent;color:var(--color-text-muted);padding:10px 14px;cursor:pointer}.DashboardClient_tabActive__5oF9r{color:var(--color-text);background:color-mix(in srgb,var(--color-accent) 16%,transparent)!important}.DashboardClient_panel__bWB7I{flex:1 1;min-height:0;overflow:auto;padding:12px}@media (max-width:980px){.DashboardClient_layout__s4BTz{grid-template-columns:1fr;min-height:auto}.DashboardClient_left__WqNyg{max-height:420px}}
1
+ .StatusBadge_badge__M4ZLM{display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:3px 10px;font-size:12px;font-weight:700;border:1px solid var(--color-border)}.StatusBadge_status_OPEN__0Pm_x{color:var(--status-open);border-color:color-mix(in srgb,var(--status-open) 45%,var(--color-border));background:color-mix(in srgb,var(--status-open) 16%,transparent)}.StatusBadge_status_IN_PROGRESS__JhYac{color:var(--status-in-progress);border-color:color-mix(in srgb,var(--status-in-progress) 45%,var(--color-border));background:color-mix(in srgb,var(--status-in-progress) 16%,transparent)}.StatusBadge_status_BLOCKED__8FFag{color:var(--status-blocked);border-color:color-mix(in srgb,var(--status-blocked) 45%,var(--color-border));background:color-mix(in srgb,var(--status-blocked) 16%,transparent)}.StatusBadge_status_DONE_PENDING_REPORT__yVdnt{color:var(--status-done-pending-report);border-color:color-mix(in srgb,var(--status-done-pending-report) 45%,var(--color-border));background:color-mix(in srgb,var(--status-done-pending-report) 16%,transparent)}.StatusBadge_status_REPORTED__0p67U{color:var(--status-reported);border-color:color-mix(in srgb,var(--status-reported) 45%,var(--color-border));background:color-mix(in srgb,var(--status-reported) 16%,transparent)}.StatusBadge_status_UNKNOWN__VkyXw{color:var(--color-text-muted);background:var(--color-bg-card)}.ScaleBadge_badge__Ufu_B{display:inline-flex;align-items:center;border-radius:999px;border:1px solid var(--color-border);padding:2px 8px;font-size:11px;text-transform:uppercase;letter-spacing:.04em}.ScaleBadge_scale_simple__MbInQ{color:#9ca3af}.ScaleBadge_scale_normal__vPQOk{color:#60a5fa}.ScaleBadge_scale_risky__pWko0{color:#f59e0b}.ScaleBadge_scale_large__aXng2{color:#ef4444}.ScaleBadge_scale_unknown__gCQWs{color:var(--color-text-muted)}.TaskList_wrap__JJmVD{display:flex;flex-direction:column;gap:12px;min-height:0}.TaskList_filters__P_eut{display:flex;flex-direction:column;gap:8px}.TaskList_tabs__MrUoG{display:flex;flex-wrap:wrap;gap:6px}.TaskList_tab__PJ3u6{border:1px solid var(--color-border);background:var(--color-bg-card);color:var(--color-text-muted);border-radius:999px;padding:4px 10px;font-size:11px;cursor:pointer}.TaskList_tabActive__hqEIw{color:var(--color-text);border-color:var(--color-accent);background:color-mix(in srgb,var(--color-accent) 18%,transparent)}.TaskList_input__069mt,.TaskList_select__07ygx{border:1px solid var(--color-border);background:var(--color-bg-card);color:var(--color-text);border-radius:8px;padding:8px 10px;font-size:13px}.TaskList_list__zaHPI{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;overflow-y:auto;min-height:0}.TaskList_card__UWMn4{width:100%;text-align:left;border:1px solid var(--color-border);background:var(--color-bg-card);border-radius:10px;padding:10px;color:var(--color-text);cursor:pointer}.TaskList_cardSelected__e4ZHd{border-color:var(--color-accent);background:color-mix(in srgb,var(--color-accent) 14%,transparent)}.TaskList_cardTop__ogfsJ{display:flex;justify-content:space-between;align-items:center;gap:8px}.TaskList_taskId__RiYub{font-size:12px;color:var(--color-text-muted)}.TaskList_title__BjaLg{margin:8px 0;font-weight:600;line-height:1.4}.TaskList_metaRow__zxzxl{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--color-text-muted)}.TaskList_dot__zkHSK{opacity:.7}.TaskList_pagination__3aWZh{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px}.TaskList_pagination__3aWZh button{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);color:var(--color-text);padding:4px 10px}.TaskDetailTab_wrap__dFSwq{display:flex;flex-direction:column;gap:14px}.TaskDetailTab_empty__wxQD4{color:var(--color-text-muted)}.TaskDetailTab_header___564C{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}.TaskDetailTab_header___564C h3{margin:0 0 6px}.TaskDetailTab_badges__xm9EG{display:flex;gap:8px;flex-wrap:wrap}.TaskDetailTab_metaRow__OSbDu{display:flex;gap:12px;font-size:13px;color:var(--color-text-muted);flex-wrap:wrap}.TaskDetailTab_cancelButton__ReU0K{align-self:flex-start;border:1px solid color-mix(in srgb,var(--status-blocked) 45%,var(--color-border));color:#fff;background:color-mix(in srgb,var(--status-blocked) 35%,#111);border-radius:8px;padding:6px 12px;cursor:pointer}.TaskDetailTab_cancelButton__ReU0K:disabled{opacity:.6;cursor:not-allowed}.TaskDetailTab_section__4dUxv{border:1px solid var(--color-border);border-radius:10px;background:var(--color-bg-card);padding:12px}.TaskDetailTab_section__4dUxv h4{margin:0 0 10px}.TaskDetailTab_muted__VWQMQ{color:var(--color-text-muted);font-size:13px}.TaskDetailTab_units__XIBtG{display:flex;flex-direction:column;gap:10px}.TaskDetailTab_unitCard__jY43J{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d;padding:10px}.TaskDetailTab_unitMeta__LnHSZ,.TaskDetailTab_unitTop__yZ5FK{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}.TaskDetailTab_unitMeta__LnHSZ{font-size:12px;color:var(--color-text-muted);margin-top:6px}.TaskDetailTab_progressTrack__VlE22{margin-top:8px;width:100%;height:8px;border-radius:999px;background:#1f1f1f;overflow:hidden}.TaskDetailTab_progressFill__JVS7w{height:100%;background:linear-gradient(90deg,var(--status-open),var(--status-reported))}.TaskDetailTab_evidenceList__xGfBZ{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}.TaskDetailTab_evidenceList__xGfBZ li{display:flex;justify-content:space-between;padding:6px 10px;font-size:13px}.TaskDetailTab_evidenceList__xGfBZ li,.TaskDetailTab_toggle__ujWwI{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d}.TaskDetailTab_toggle__ujWwI{color:var(--color-text);padding:5px 10px;margin-bottom:8px}.TaskDetailTab_markdown__eoDyT{font-size:14px;line-height:1.6}.EventLogTab_wrap__x2X_J{height:100%;overflow-y:auto}.EventLogTab_empty__LRJDo{color:var(--color-text-muted)}.EventLogTab_list__nm_mD{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}.EventLogTab_item__VL0dt{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);padding:8px 10px;font-size:13px;line-height:1.45;word-break:break-word}.EventLogTab_ts__vQ9nA{color:var(--color-text-muted)}.EventLogTab_name__4A39l{color:var(--color-accent)}.ConversationTab_wrap__1QSeD{height:100%;display:flex;flex-direction:column;gap:10px}.ConversationTab_toggle__3CZ5X{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--color-text-muted)}.ConversationTab_list__3x9W9{overflow-y:auto;display:flex;flex-direction:column;gap:10px;min-height:0}.ConversationTab_message__ATEZY{border:1px solid var(--color-border);border-radius:8px;background:var(--color-bg-card);padding:8px}.ConversationTab_header__JCM4X{display:flex;align-items:center;gap:8px;margin-bottom:6px}.ConversationTab_agent__y3KdF{display:inline-flex;align-items:center;border-radius:999px;padding:2px 8px;font-size:11px;color:#fff;font-weight:700}.ConversationTab_meta__dMgwn{font-size:12px;color:var(--color-text-muted)}.ConversationTab_body__uCFH9{display:flex;flex-direction:column;gap:8px}.ConversationTab_markdown__A8qFO{font-size:14px;line-height:1.6}.ConversationTab_markdown__A8qFO p{margin:.4em 0}.ConversationTab_thinking__9ksh2,.ConversationTab_toolBox__z6pL2{border:1px solid var(--color-border);border-radius:8px;background:#0d0d0d;padding:8px}.ConversationTab_thinking__9ksh2 pre,.ConversationTab_toolBox__z6pL2 pre{margin:8px 0 0;white-space:pre-wrap;word-break:break-word;font-size:12px}.ConversationTab_toolName__SLqEU{font-size:12px;color:var(--color-accent)}.ConversationTab_empty__aB__j,.ConversationTab_notice__wCw5J{color:var(--color-text-muted)}.DashboardClient_main__eZK1S{max-width:1440px;margin:0 auto;padding:16px;display:flex;flex-direction:column;gap:12px}.DashboardClient_header__21U6H{display:flex;justify-content:space-between;align-items:center;border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg-card);padding:10px 14px}.DashboardClient_brand__1Ljqy{font-size:20px;font-weight:800}.DashboardClient_headerRight__EinuX{display:flex;align-items:center;gap:8px}.DashboardClient_headerRight__EinuX button{border:1px solid var(--color-border);background:#0d0d0d;color:var(--color-text);border-radius:8px;padding:6px 10px;cursor:pointer}.DashboardClient_sseWrap__dCBYi{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--color-text-muted);margin-right:4px}.DashboardClient_dot__NxKpZ{width:10px;height:10px;border-radius:999px}.DashboardClient_dot_connected__3UnYe{background:var(--status-reported)}.DashboardClient_dot_disconnected__0IqOj{background:var(--status-blocked)}.DashboardClient_dot_connecting__NNLev{background:var(--status-in-progress)}.DashboardClient_statusBar__eP3FN{display:flex;flex-wrap:wrap;gap:8px}.DashboardClient_statusItem__Yi9TP{border:1px solid var(--color-border);border-radius:999px;padding:3px 10px;font-size:12px;background:var(--color-bg-card)}.DashboardClient_error__Tv__n{margin:0;color:var(--status-blocked)}.DashboardClient_layout__s4BTz{display:grid;grid-template-columns:360px 1fr;grid-gap:12px;gap:12px;height:calc(100vh - 180px)}.DashboardClient_left__WqNyg,.DashboardClient_right__EWclx{border:1px solid var(--color-border);border-radius:12px;background:var(--color-bg-card);min-height:0}.DashboardClient_left__WqNyg{padding:10px;overflow-y:auto}.DashboardClient_right__EWclx{display:flex;flex-direction:column;overflow:hidden}.DashboardClient_tabs__tx3BS{display:flex;border-bottom:1px solid var(--color-border)}.DashboardClient_tabs__tx3BS button{border:0;border-right:1px solid var(--color-border);background:transparent;color:var(--color-text-muted);padding:10px 14px;cursor:pointer}.DashboardClient_tabActive__5oF9r{color:var(--color-text);background:color-mix(in srgb,var(--color-accent) 16%,transparent)!important}.DashboardClient_panel__bWB7I{flex:1 1;min-height:0;overflow:auto;padding:12px}@media (max-width:980px){.DashboardClient_layout__s4BTz{grid-template-columns:1fr;height:auto;max-height:none}.DashboardClient_left__WqNyg{max-height:420px}}
package/dist/dashboard.js CHANGED
@@ -3,6 +3,7 @@ import * as fs from 'node:fs';
3
3
  import * as net from 'node:net';
4
4
  import * as path from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
+ import { detectOpenClawHome } from './onboard.js';
6
7
  /** Default port for zigrix dashboard */
7
8
  export const DASHBOARD_DEFAULT_PORT = 3838;
8
9
  /**
@@ -38,6 +39,49 @@ export function isPortBusy(port) {
38
39
  server.listen(port, '127.0.0.1');
39
40
  });
40
41
  }
42
+ /**
43
+ * Read openclaw.json and extract gateway connection env vars.
44
+ * Only sets vars that are not already present in process.env,
45
+ * so explicit user overrides are always respected.
46
+ */
47
+ function resolveGatewayEnv() {
48
+ const env = {};
49
+ try {
50
+ const openclawHome = detectOpenClawHome();
51
+ const configPath = path.join(openclawHome, 'openclaw.json');
52
+ if (!fs.existsSync(configPath))
53
+ return env;
54
+ const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
55
+ const gateway = raw?.gateway;
56
+ if (!gateway)
57
+ return env;
58
+ // OPENCLAW_GATEWAY_URL — derive from gateway.port (loopback assumed)
59
+ if (!process.env.OPENCLAW_GATEWAY_URL && !process.env.ORCH_GATEWAY_URL) {
60
+ const port = Number(gateway.port);
61
+ if (port > 0) {
62
+ env.OPENCLAW_GATEWAY_URL = `http://localhost:${port}`;
63
+ }
64
+ }
65
+ // OPENCLAW_GATEWAY_TOKEN — from gateway.auth.token
66
+ if (!process.env.OPENCLAW_GATEWAY_TOKEN && !process.env.ORCH_GATEWAY_TOKEN) {
67
+ const token = gateway.auth?.token;
68
+ if (typeof token === 'string' && token.length > 0) {
69
+ env.OPENCLAW_GATEWAY_TOKEN = token;
70
+ }
71
+ }
72
+ // OPENCLAW_AGENTS_DIR — agents runtime directory
73
+ if (!process.env.OPENCLAW_AGENTS_DIR) {
74
+ const agentsDir = path.join(openclawHome, 'agents');
75
+ if (fs.existsSync(agentsDir)) {
76
+ env.OPENCLAW_AGENTS_DIR = agentsDir;
77
+ }
78
+ }
79
+ }
80
+ catch {
81
+ // Non-fatal: dashboard will work without gateway features
82
+ }
83
+ return env;
84
+ }
41
85
  /**
42
86
  * Main entry point for `zigrix dashboard`.
43
87
  *
@@ -65,6 +109,8 @@ export async function runDashboard(options = {}) {
65
109
  throw new Error(`Port ${port} is already in use. ` +
66
110
  `Stop the conflicting process or specify a different port with --port.`);
67
111
  }
112
+ // --- Resolve OpenClaw gateway env from openclaw.json ---
113
+ const gatewayEnv = resolveGatewayEnv();
68
114
  // --- Launch pre-built Next.js standalone server ---
69
115
  console.log(`🚀 Starting zigrix dashboard on http://localhost:${port}`);
70
116
  const child = spawn(process.execPath, [serverScript], {
@@ -72,6 +118,7 @@ export async function runDashboard(options = {}) {
72
118
  stdio: 'inherit',
73
119
  env: {
74
120
  ...process.env,
121
+ ...gatewayEnv,
75
122
  PORT: String(port),
76
123
  HOSTNAME: '0.0.0.0',
77
124
  },
package/dist/doctor.js CHANGED
@@ -37,6 +37,22 @@ export function gatherDoctor(loaded, paths) {
37
37
  return false;
38
38
  }
39
39
  }) ?? null;
40
+ const openclawInNonLoginPath = nonLoginShellPaths.some((dir) => {
41
+ try {
42
+ return fs.existsSync(path.join(dir, 'openclaw'));
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ });
48
+ const openclawNonLoginLocation = nonLoginShellPaths.find((dir) => {
49
+ try {
50
+ return fs.existsSync(path.join(dir, 'openclaw'));
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }) ?? null;
40
56
  const payload = {
41
57
  node: {
42
58
  executable: process.execPath,
@@ -71,7 +87,7 @@ export function gatherDoctor(loaded, paths) {
71
87
  binaries: {
72
88
  node: process.execPath,
73
89
  npm: process.env.npm_execpath ?? null,
74
- openclaw: null,
90
+ openclaw: loaded.config.openclaw?.binPath ?? null,
75
91
  },
76
92
  openclaw: {
77
93
  home: openclawHome,
@@ -83,6 +99,8 @@ export function gatherDoctor(loaded, paths) {
83
99
  nonLoginShellPaths,
84
100
  zigrixInNonLoginPath,
85
101
  zigrixNonLoginLocation,
102
+ openclawInNonLoginPath,
103
+ openclawNonLoginLocation,
86
104
  },
87
105
  };
88
106
  if (!payload.node.ok)
@@ -90,17 +108,21 @@ export function gatherDoctor(loaded, paths) {
90
108
  if (!payload.files.configExists)
91
109
  warnings.push('zigrix.config.json not found. Run `zigrix onboard`.');
92
110
  if (!payload.files.baseDirExists)
93
- warnings.push('~/.zigrix not found. Run `zigrix onboard`.');
111
+ warnings.push(`${paths.baseDir} not found. Run \`zigrix onboard\`.`);
94
112
  if (!payload.writeAccess.baseDir)
95
113
  warnings.push('Base directory is not writable.');
96
114
  if (!payload.openclaw.exists)
97
- warnings.push('~/.openclaw not found. OpenClaw integration remains optional.');
115
+ warnings.push(`${openclawHome} not found. OpenClaw integration remains optional.`);
98
116
  if (payload.rules.count === 0)
99
- warnings.push('No rule files found in rules directory. Seed from orchestration/rules/.');
117
+ warnings.push('No rule files found in rules directory. Seed bundled defaults with `zigrix onboard` or `zigrix configure --section rules`.');
100
118
  if (!payload.pathReach.zigrixInNonLoginPath) {
101
119
  warnings.push('zigrix is not reachable from non-login shell PATH (checked: /usr/local/bin, /usr/bin). ' +
102
120
  'Run `zigrix onboard` or manually: sudo ln -sfn $(which zigrix) /usr/local/bin/zigrix');
103
121
  }
122
+ if (!payload.pathReach.openclawInNonLoginPath) {
123
+ warnings.push('openclaw is not reachable from non-login shell PATH (checked: /usr/local/bin, /usr/bin). ' +
124
+ 'Run `zigrix onboard` or manually: sudo ln -sfn $(which openclaw) /usr/local/bin/openclaw');
125
+ }
104
126
  return {
105
127
  ...payload,
106
128
  summary: {
@@ -117,7 +139,8 @@ export function renderDoctorText(payload) {
117
139
  `- Config: ${payload.paths.configPath ?? 'missing'}`,
118
140
  `- Rules dir: ${payload.rules.dir} (${payload.rules.count} files)`,
119
141
  `- OpenClaw home: ${payload.openclaw.home} (${payload.openclaw.exists ? 'present' : 'missing'})`,
120
- `- Non-login PATH reach: ${payload.pathReach.zigrixInNonLoginPath ? `yes (${payload.pathReach.zigrixNonLoginLocation})` : 'no'}`,
142
+ `- Non-login PATH reach (zigrix): ${payload.pathReach.zigrixInNonLoginPath ? `yes (${payload.pathReach.zigrixNonLoginLocation})` : 'no'}`,
143
+ `- Non-login PATH reach (openclaw): ${payload.pathReach.openclawInNonLoginPath ? `yes (${payload.pathReach.openclawNonLoginLocation})` : 'no'}`,
121
144
  `- Ready: ${payload.summary.ready ? 'yes' : 'no'}`,
122
145
  ];
123
146
  for (const warning of payload.summary.warnings) {