@splinterzzz/ouro 0.1.4 → 0.1.5
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.
|
@@ -53,7 +53,7 @@ Error generating stack: `+s.message+`
|
|
|
53
53
|
*
|
|
54
54
|
* This source code is licensed under the MIT license found in the
|
|
55
55
|
* LICENSE file in the root directory of this source tree.
|
|
56
|
-
*/var Tl=z,Sp=kp;function jp(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Np=typeof Object.is=="function"?Object.is:jp,Ep=Sp.useSyncExternalStore,Cp=Tl.useRef,_p=Tl.useEffect,Tp=Tl.useMemo,zp=Tl.useDebugValue;Tc.useSyncExternalStoreWithSelector=function(e,t,n,r,l){var s=Cp(null);if(s.current===null){var i={hasValue:!1,value:null};s.current=i}else i=s.current;s=Tp(function(){function u(x){if(!c){if(c=!0,v=x,x=r(x),l!==void 0&&i.hasValue){var y=i.value;if(l(y,x))return h=y}return h=x}if(y=h,Np(v,x))return y;var w=r(x);return l!==void 0&&l(y,w)?(v=x,y):(v=x,h=w)}var c=!1,v,h,m=n===void 0?null:n;return[function(){return u(t())},m===null?void 0:function(){return u(m())}]},[t,n,r,l]);var a=Ep(e,s[0],s[1]);return _p(function(){i.hasValue=!0,i.value=a},[a]),zp(a),a};_c.exports=Tc;var Pp=_c.exports;const Lp=pa(Pp),Lc={},{useDebugValue:Mp}=Na,{useSyncExternalStoreWithSelector:Rp}=Lp;let sa=!1;const Ip=e=>e;function Op(e,t=Ip,n){(Lc?"production":void 0)!=="production"&&n&&!sa&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),sa=!0);const r=Rp(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return Mp(r),r}const ia=e=>{(Lc?"production":void 0)!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?dp(e):e,n=(r,l)=>Op(t,r,l);return Object.assign(n,t),n},zl=e=>e?ia(e):ia,Qe=zl((e,t)=>({agents:[],toolUniverse:[],defaultAgentId:null,loading:!0,error:null,selectedId:null,async hydrate(){try{const n=await fetch("/api/agents");if(!n.ok)throw new Error(`GET /api/agents → ${n.status}`);const{agents:r,toolUniverse:l,defaultAgentId:s}=await n.json();e(i=>{var a;return{agents:r,toolUniverse:l,defaultAgentId:s,loading:!1,error:null,selectedId:r.some(u=>u.id===i.selectedId)?i.selectedId:((a=r[0])==null?void 0:a.id)??null}})}catch(n){e({loading:!1,error:String(n.message||n)})}},select(n){e({selectedId:n})},async create(n){const r=await fetch("/api/agents",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n})});if(!r.ok)throw new Error((await r.json().catch(()=>({}))).error??`HTTP ${r.status}`);const l=await r.json();return await t().hydrate(),e({selectedId:l.id}),l},async save(n,r){const l=await fetch(`/api/agents/${n}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok)throw new Error((await l.json().catch(()=>({}))).error??`HTTP ${l.status}`);const s=await l.json();return await t().hydrate(),s},async remove(n){const r=await fetch(`/api/agents/${n}`,{method:"DELETE"});if(!r.ok)throw new Error(`HTTP ${r.status}`);e({selectedId:null}),await t().hydrate()},async fetchRaw(n){const r=await fetch(`/api/agents/${n}`);if(!r.ok)throw new Error(`HTTP ${r.status}`);return(await r.json()).raw??""}}));let Ue=null,oa=null,zr=500;function Dp(e){if(e.type==="error")return"bad";if(e.type==="cancelled"||e.type==="warn")return"warn";if(e.type==="ship-done")return"good";if(e.type==="ship")return"run";const t=e.event??{};return t.type==="stderr"?"warn":t.type==="result"?t.is_error?"bad":"good":t.type==="raw"||t.type==="rate_limit_event"||t.type==="system"&&t.subtype!=="init"?"dim":"run"}function $p(e){var r,l,s;if(e.type==="error")return`error: ${e.text}`;if(e.type==="cancelled")return e.text||"cancelled";if(e.type==="ship"||e.type==="ship-done"||e.type==="warn")return e.text;const t=e.event;if(!t)return JSON.stringify(e).slice(0,200);if(t.type==="raw"||t.type==="stderr")return(t.text??"").trim();if(t.type==="system")return t.subtype==="init"?`session started · ${t.model??"ready"}`:`· ${t.subtype??"system"}`;if(t.type==="rate_limit_event")return"· rate limit notice";if(t.type==="result"){const i=[t.is_error?"failed":"done"];return t.num_turns&&i.push(`${t.num_turns} turns`),t.duration_ms&&i.push(`${(t.duration_ms/1e3).toFixed(1)}s`),`${t.is_error?"✗":"✓"} ${i.join(" · ")}`}const n=(r=t.message)==null?void 0:r.content;if(Array.isArray(n)){const i=[];for(const a of n)if(a.type==="tool_use"){const u=a.input??{},c=u.file_path??u.path??u.command??u.pattern??u.prompt??"";i.push(`▶ ${a.name}${c?` ${String(c).slice(0,90)}`:""}`)}else a.type==="text"&&((l=a.text)!=null&&l.trim())?i.push(a.text.trim().slice(0,160)):a.type==="thinking"?i.push("· thinking"):a.type==="tool_result"&&i.push("◂ result");if(i.length)return i.join(" ")}return(s=t.item)!=null&&s.text?`${t.type}: ${t.item.text.slice(0,140)}`:`· ${t.type??"event"}`}let aa=0;const B=zl((e,t)=>({tickets:[],connected:!1,backend:null,defaultMode:"human",feed:[],selectedId:null,select(n){e(r=>({selectedId:r.selectedId===n?null:n}))},async hydrate(){const r=await(await fetch("/api/tickets")).json(),l=r.flatMap(s=>(s.log??[]).map(i=>({...ua(s.id,i),id:++aa}))).sort((s,i)=>s.ts.localeCompare(i.ts)).slice(-600);e({tickets:r,feed:l})},async hydrateConfig(){const n=await fetch("/api/config"),{backend:r,defaultMode:l}=await n.json();e({backend:r,defaultMode:l??"human"})},async setBackend(n){const r=t().backend;e({backend:n});try{const l=await fetch("/api/config/backend",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({backend:n})});if(!l.ok)throw new Error(await l.text());const s=await l.json();e({backend:s.backend??n})}catch{e({backend:r})}},async setDefaultMode(n){const r=t().defaultMode;e({defaultMode:n});try{const l=await fetch("/api/config/mode",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mode:n})});if(!l.ok)throw new Error(await l.text())}catch{e({defaultMode:r})}},connectSocket(){if(Ue&&Ue.readyState<=1)return;const n=location.protocol==="https:"?"wss":"ws";Ue=new WebSocket(`${n}://${location.host}/ws`),Ue.onopen=()=>{zr=500,e({connected:!0}),t().hydrate(),t().hydrateConfig()},Ue.onclose=()=>{e({connected:!1}),clearTimeout(oa),oa=setTimeout(()=>t().connectSocket(),zr),zr=Math.min(zr*2,8e3)},Ue.onerror=()=>Ue==null?void 0:Ue.close(),Ue.onmessage=r=>{let l;try{l=JSON.parse(r.data)}catch{return}t().applyEvent(l)}},applyEvent(n){if(n.type==="log"){const l={...ua(n.ticketId,n.entry),id:++aa};e(s=>({feed:[...s.feed,l].slice(-600),tickets:s.tickets.map(i=>i.id===n.ticketId?{...i,log:[...i.log??[],n.entry].slice(-400)}:i)}));return}if(n.type==="deleted"){e(l=>({tickets:l.tickets.filter(s=>s.id!==n.ticketId),selectedId:l.selectedId===n.ticketId?null:l.selectedId}));return}if(n.type==="config"){e({defaultMode:n.defaultMode});return}if(n.type==="agent"||n.type==="agent-deleted"){Qe.getState().hydrate();return}const r=n.ticket;r&&e(l=>({tickets:l.tickets.some(i=>i.id===r.id)?l.tickets.map(i=>i.id===r.id?r:i):[r,...l.tickets]}))},clearFeed(){e({feed:[]})},async setMode(n,r){await Me(`/api/tickets/${n}/mode`,{mode:r})},async setAgent(n,r){await Me(`/api/tickets/${n}/agent`,{agentId:r})},async analyzeTicket(n){await Me(`/api/tickets/${n}/analyze`)},async runTicket(n){await Me(`/api/tickets/${n}/run`)},async approveTicket(n){await Me(`/api/tickets/${n}/approve`)},async cancelTicket(n){await Me(`/api/tickets/${n}/cancel`)},async reopenTicket(n){await Me(`/api/tickets/${n}/reopen`)},async qaApprove(n){await Me(`/api/tickets/${n}/qa/approve`)},async qaReject(n){await Me(`/api/tickets/${n}/qa/reject`)},async shipTicket(n){const r=await Me(`/api/tickets/${n}/ship`);return r.json().catch(()=>({ok:!1,error:`HTTP ${r.status}`}))},async deleteTicket(n){await fetch(`/api/tickets/${n}`,{method:"DELETE"})},async createTicket(n){const r=await Me("/api/tickets",{source:"manual",...n});return r==null?void 0:r.json()}}));function ua(e,t){return{ticketId:e,ts:t.ts??new Date().toISOString(),tone:Dp(t),text:$p(t)}}function Me(e,t){return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},...t?{body:JSON.stringify(t)}:{}})}const Mc="ouro.ui.v1",ca={view:"board",railCollapsed:!1,ticketsOpen:!0,agentsOpen:!0,terminalOpen:!0,terminalHeight:200,autoscroll:!0},Rc=90,Ic=560;function Fp(){try{return{...ca,...JSON.parse(localStorage.getItem(Mc)??"{}")}}catch{return{...ca}}}const Xe=zl((e,t)=>({...Fp(),set(n){e(n);const{view:r,railCollapsed:l,ticketsOpen:s,agentsOpen:i,terminalOpen:a,terminalHeight:u,autoscroll:c}=t();try{localStorage.setItem(Mc,JSON.stringify({view:r,railCollapsed:l,ticketsOpen:s,agentsOpen:i,terminalOpen:a,terminalHeight:u,autoscroll:c}))}catch{}},toggle(n){t().set({[n]:!t()[n]})},setTerminalHeight(n){t().set({terminalHeight:Math.min(Ic,Math.max(Rc,n))})}})),Ap={inbox:"M22 12h-6l-2 3h-4l-2-3H2 M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",agents:"M12 8V4H8 M4 8h16v12H4z M2 14h2 M20 14h2 M15 13v2 M9 13v2",play:"m6 3 14 9-14 9V3z",stop:"M5 5h14v14H5z",check:"M20 6 9 17l-5-5",x:"M18 6 6 18 M6 6l12 12",chevronRight:"m9 18 6-6-6-6",chevronDown:"m6 9 6 6 6-6",chevronsLeft:"m11 17-5-5 5-5 M18 17l-5-5 5-5",chevronsRight:"m6 17 5-5-5-5 M13 17l5-5-5-5",plus:"M5 12h14 M12 5v14",terminal:"m4 17 6-6-6-6 M12 19h8",trash:"M3 6h18 M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",rotate:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8 M3 3v5h5",save:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z M17 21v-8H7v8 M7 3v5h8",file:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z M14 2v4a2 2 0 0 0 2 2h4",alert:"M12 9v4 M12 17h.01 M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z",search:"m21 21-4.34-4.34 M17 11a6 6 0 1 1-12 0 6 6 0 0 1 12 0z",gitBranch:"M6 3v12 M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M15 9a9 9 0 0 1-9 9",settings:"M20 7h-9 M14 17H5 M17 14a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M7 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6z",send:"m22 2-7 20-4-9-9-4Z M22 2 11 13"};function T({name:e,size:t=16,className:n="",...r}){const l=Ap[e];return l?o.jsx("svg",{className:`icon ${n}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",...r,children:l.split(" M").map((s,i)=>o.jsx("path",{d:i===0?s:`M${s}`},i))}):null}const Up=[[100,4],[135,2.5],[170,4],[205,3],[240,4.5],[275,2.5],[310,4],[340,3]];function Vp({size:e=20,title:t,className:n=""}){return o.jsxs("svg",{className:`logo ${n}`,width:e,height:e,viewBox:"0 0 64 64",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",role:t?"img":void 0,"aria-hidden":t?void 0:"true","aria-label":t,children:[t&&o.jsx("title",{children:t}),o.jsx("path",{d:"M43 12.95A22 22 0 1 1 28.18 10.33",strokeWidth:"4"}),o.jsx("path",{d:"M28.18 10.33A22 22 0 0 1 32 10",strokeWidth:"2.6"}),o.jsx("path",{d:"M32 10A22 22 0 0 1 33.92 10.08",strokeWidth:"1.5"}),o.jsx("path",{d:"M43 12.95A22 22 0 1 1 28.18 10.33",strokeWidth:"1.3",opacity:"0.7"}),o.jsxs("g",{opacity:"0.4",strokeWidth:"0.8",children:[Up.map(([r,l])=>o.jsxs("g",{transform:`rotate(${r} 32 32)`,children:[o.jsx("path",{d:`M32 13v${l}`}),o.jsx("circle",{cx:"32",cy:13+l,r:"0.85",fill:"currentColor",stroke:"none"})]},r)),o.jsx("path",{d:"M15.26 34.95A17 17 0 0 0 23.5 46.72"}),o.jsx("path",{d:"M43.4 43.4A17 17 0 0 0 48.4 36.1"})]}),o.jsx("path",{d:`M42.8 14.8
|
|
56
|
+
*/var Tl=z,Sp=kp;function jp(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Np=typeof Object.is=="function"?Object.is:jp,Ep=Sp.useSyncExternalStore,Cp=Tl.useRef,_p=Tl.useEffect,Tp=Tl.useMemo,zp=Tl.useDebugValue;Tc.useSyncExternalStoreWithSelector=function(e,t,n,r,l){var s=Cp(null);if(s.current===null){var i={hasValue:!1,value:null};s.current=i}else i=s.current;s=Tp(function(){function u(x){if(!c){if(c=!0,v=x,x=r(x),l!==void 0&&i.hasValue){var y=i.value;if(l(y,x))return h=y}return h=x}if(y=h,Np(v,x))return y;var w=r(x);return l!==void 0&&l(y,w)?(v=x,y):(v=x,h=w)}var c=!1,v,h,m=n===void 0?null:n;return[function(){return u(t())},m===null?void 0:function(){return u(m())}]},[t,n,r,l]);var a=Ep(e,s[0],s[1]);return _p(function(){i.hasValue=!0,i.value=a},[a]),zp(a),a};_c.exports=Tc;var Pp=_c.exports;const Lp=pa(Pp),Lc={},{useDebugValue:Mp}=Na,{useSyncExternalStoreWithSelector:Rp}=Lp;let sa=!1;const Ip=e=>e;function Op(e,t=Ip,n){(Lc?"production":void 0)!=="production"&&n&&!sa&&(console.warn("[DEPRECATED] Use `createWithEqualityFn` instead of `create` or use `useStoreWithEqualityFn` instead of `useStore`. They can be imported from 'zustand/traditional'. https://github.com/pmndrs/zustand/discussions/1937"),sa=!0);const r=Rp(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return Mp(r),r}const ia=e=>{(Lc?"production":void 0)!=="production"&&typeof e!="function"&&console.warn("[DEPRECATED] Passing a vanilla store will be unsupported in a future version. Instead use `import { useStore } from 'zustand'`.");const t=typeof e=="function"?dp(e):e,n=(r,l)=>Op(t,r,l);return Object.assign(n,t),n},zl=e=>e?ia(e):ia,Qe=zl((e,t)=>({agents:[],toolUniverse:[],defaultAgentId:null,loading:!0,error:null,selectedId:null,async hydrate(){try{const n=await fetch("/api/agents");if(!n.ok)throw new Error(`GET /api/agents → ${n.status}`);const{agents:r,toolUniverse:l,defaultAgentId:s}=await n.json();e(i=>{var a;return{agents:r,toolUniverse:l,defaultAgentId:s,loading:!1,error:null,selectedId:r.some(u=>u.id===i.selectedId)?i.selectedId:((a=r[0])==null?void 0:a.id)??null}})}catch(n){e({loading:!1,error:String(n.message||n)})}},select(n){e({selectedId:n})},async create(n){const r=await fetch("/api/agents",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:n})});if(!r.ok)throw new Error((await r.json().catch(()=>({}))).error??`HTTP ${r.status}`);const l=await r.json();return await t().hydrate(),e({selectedId:l.id}),l},async save(n,r){const l=await fetch(`/api/agents/${n}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok)throw new Error((await l.json().catch(()=>({}))).error??`HTTP ${l.status}`);const s=await l.json();return await t().hydrate(),s},async remove(n){const r=await fetch(`/api/agents/${n}`,{method:"DELETE"});if(!r.ok)throw new Error(`HTTP ${r.status}`);e({selectedId:null}),await t().hydrate()},async fetchRaw(n){const r=await fetch(`/api/agents/${n}`);if(!r.ok)throw new Error(`HTTP ${r.status}`);return(await r.json()).raw??""}}));let Ue=null,oa=null,zr=500;function Dp(e){if(e.type==="error")return"bad";if(e.type==="cancelled"||e.type==="warn")return"warn";if(e.type==="ship-done")return"good";if(e.type==="ship")return"run";const t=e.event??{};return t.type==="stderr"?"warn":t.type==="result"?t.is_error?"bad":"good":t.type==="raw"||t.type==="rate_limit_event"||t.type==="system"&&t.subtype!=="init"?"dim":"run"}function $p(e){var r,l,s;if(e.type==="error")return`error: ${e.text}`;if(e.type==="cancelled")return e.text||"cancelled";if(e.type==="ship"||e.type==="ship-done"||e.type==="warn")return e.text;const t=e.event;if(!t)return JSON.stringify(e).slice(0,200);if(t.type==="raw"||t.type==="stderr")return(t.text??"").trim();if(t.type==="system")return t.subtype==="init"?`session started · ${t.model??"ready"}`:`· ${t.subtype??"system"}`;if(t.type==="rate_limit_event")return"· rate limit notice";if(t.type==="result"){const i=[t.is_error?"failed":"done"];return t.num_turns&&i.push(`${t.num_turns} turns`),t.duration_ms&&i.push(`${(t.duration_ms/1e3).toFixed(1)}s`),`${t.is_error?"✗":"✓"} ${i.join(" · ")}`}const n=(r=t.message)==null?void 0:r.content;if(Array.isArray(n)){const i=[];for(const a of n)if(a.type==="tool_use"){const u=a.input??{},c=u.file_path??u.path??u.command??u.pattern??u.prompt??"";i.push(`▶ ${a.name}${c?` ${String(c).slice(0,90)}`:""}`)}else a.type==="text"&&((l=a.text)!=null&&l.trim())?i.push(a.text.trim().slice(0,160)):a.type==="tool_result"&&i.push("◂ result");return i.length?i.join(" "):null}return(s=t.item)!=null&&s.text?`${t.type}: ${t.item.text.slice(0,140)}`:`· ${t.type??"event"}`}let aa=0;const B=zl((e,t)=>({tickets:[],connected:!1,backend:null,defaultMode:"human",feed:[],selectedId:null,select(n){e(r=>({selectedId:r.selectedId===n?null:n}))},async hydrate(){const r=await(await fetch("/api/tickets")).json(),l=r.flatMap(s=>(s.log??[]).map(i=>({...ua(s.id,i),id:++aa}))).filter(s=>s.text!=null).sort((s,i)=>s.ts.localeCompare(i.ts)).slice(-600);e({tickets:r,feed:l})},async hydrateConfig(){const n=await fetch("/api/config"),{backend:r,defaultMode:l}=await n.json();e({backend:r,defaultMode:l??"human"})},async setBackend(n){const r=t().backend;e({backend:n});try{const l=await fetch("/api/config/backend",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({backend:n})});if(!l.ok)throw new Error(await l.text());const s=await l.json();e({backend:s.backend??n})}catch{e({backend:r})}},async setDefaultMode(n){const r=t().defaultMode;e({defaultMode:n});try{const l=await fetch("/api/config/mode",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mode:n})});if(!l.ok)throw new Error(await l.text())}catch{e({defaultMode:r})}},connectSocket(){if(Ue&&Ue.readyState<=1)return;const n=location.protocol==="https:"?"wss":"ws";Ue=new WebSocket(`${n}://${location.host}/ws`),Ue.onopen=()=>{zr=500,e({connected:!0}),t().hydrate(),t().hydrateConfig()},Ue.onclose=()=>{e({connected:!1}),clearTimeout(oa),oa=setTimeout(()=>t().connectSocket(),zr),zr=Math.min(zr*2,8e3)},Ue.onerror=()=>Ue==null?void 0:Ue.close(),Ue.onmessage=r=>{let l;try{l=JSON.parse(r.data)}catch{return}t().applyEvent(l)}},applyEvent(n){if(n.type==="log"){const l={...ua(n.ticketId,n.entry),id:++aa};e(s=>({feed:l.text==null?s.feed:[...s.feed,l].slice(-600),tickets:s.tickets.map(i=>i.id===n.ticketId?{...i,log:[...i.log??[],n.entry].slice(-400)}:i)}));return}if(n.type==="deleted"){e(l=>({tickets:l.tickets.filter(s=>s.id!==n.ticketId),selectedId:l.selectedId===n.ticketId?null:l.selectedId}));return}if(n.type==="config"){e({defaultMode:n.defaultMode});return}if(n.type==="agent"||n.type==="agent-deleted"){Qe.getState().hydrate();return}const r=n.ticket;r&&e(l=>({tickets:l.tickets.some(i=>i.id===r.id)?l.tickets.map(i=>i.id===r.id?r:i):[r,...l.tickets]}))},clearFeed(){e({feed:[]})},async setMode(n,r){await Me(`/api/tickets/${n}/mode`,{mode:r})},async setAgent(n,r){await Me(`/api/tickets/${n}/agent`,{agentId:r})},async analyzeTicket(n){await Me(`/api/tickets/${n}/analyze`)},async runTicket(n){await Me(`/api/tickets/${n}/run`)},async approveTicket(n){await Me(`/api/tickets/${n}/approve`)},async cancelTicket(n){await Me(`/api/tickets/${n}/cancel`)},async reopenTicket(n){await Me(`/api/tickets/${n}/reopen`)},async qaApprove(n){await Me(`/api/tickets/${n}/qa/approve`)},async qaReject(n){await Me(`/api/tickets/${n}/qa/reject`)},async shipTicket(n){const r=await Me(`/api/tickets/${n}/ship`);return r.json().catch(()=>({ok:!1,error:`HTTP ${r.status}`}))},async deleteTicket(n){await fetch(`/api/tickets/${n}`,{method:"DELETE"})},async createTicket(n){const r=await Me("/api/tickets",{source:"manual",...n});return r==null?void 0:r.json()}}));function ua(e,t){return{ticketId:e,ts:t.ts??new Date().toISOString(),tone:Dp(t),text:$p(t)}}function Me(e,t){return fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},...t?{body:JSON.stringify(t)}:{}})}const Mc="ouro.ui.v1",ca={view:"board",railCollapsed:!1,ticketsOpen:!0,agentsOpen:!0,terminalOpen:!0,terminalHeight:200,autoscroll:!0},Rc=90,Ic=560;function Fp(){try{return{...ca,...JSON.parse(localStorage.getItem(Mc)??"{}")}}catch{return{...ca}}}const Xe=zl((e,t)=>({...Fp(),set(n){e(n);const{view:r,railCollapsed:l,ticketsOpen:s,agentsOpen:i,terminalOpen:a,terminalHeight:u,autoscroll:c}=t();try{localStorage.setItem(Mc,JSON.stringify({view:r,railCollapsed:l,ticketsOpen:s,agentsOpen:i,terminalOpen:a,terminalHeight:u,autoscroll:c}))}catch{}},toggle(n){t().set({[n]:!t()[n]})},setTerminalHeight(n){t().set({terminalHeight:Math.min(Ic,Math.max(Rc,n))})}})),Ap={inbox:"M22 12h-6l-2 3h-4l-2-3H2 M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",agents:"M12 8V4H8 M4 8h16v12H4z M2 14h2 M20 14h2 M15 13v2 M9 13v2",play:"m6 3 14 9-14 9V3z",stop:"M5 5h14v14H5z",check:"M20 6 9 17l-5-5",x:"M18 6 6 18 M6 6l12 12",chevronRight:"m9 18 6-6-6-6",chevronDown:"m6 9 6 6 6-6",chevronsLeft:"m11 17-5-5 5-5 M18 17l-5-5 5-5",chevronsRight:"m6 17 5-5-5-5 M13 17l5-5-5-5",plus:"M5 12h14 M12 5v14",terminal:"m4 17 6-6-6-6 M12 19h8",trash:"M3 6h18 M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",rotate:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8 M3 3v5h5",save:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z M17 21v-8H7v8 M7 3v5h8",file:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z M14 2v4a2 2 0 0 0 2 2h4",alert:"M12 9v4 M12 17h.01 M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z",search:"m21 21-4.34-4.34 M17 11a6 6 0 1 1-12 0 6 6 0 0 1 12 0z",gitBranch:"M6 3v12 M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M15 9a9 9 0 0 1-9 9",settings:"M20 7h-9 M14 17H5 M17 14a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M7 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6z",send:"m22 2-7 20-4-9-9-4Z M22 2 11 13"};function T({name:e,size:t=16,className:n="",...r}){const l=Ap[e];return l?o.jsx("svg",{className:`icon ${n}`,width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",...r,children:l.split(" M").map((s,i)=>o.jsx("path",{d:i===0?s:`M${s}`},i))}):null}const Up=[[100,4],[135,2.5],[170,4],[205,3],[240,4.5],[275,2.5],[310,4],[340,3]];function Vp({size:e=20,title:t,className:n=""}){return o.jsxs("svg",{className:`logo ${n}`,width:e,height:e,viewBox:"0 0 64 64",fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",role:t?"img":void 0,"aria-hidden":t?void 0:"true","aria-label":t,children:[t&&o.jsx("title",{children:t}),o.jsx("path",{d:"M43 12.95A22 22 0 1 1 28.18 10.33",strokeWidth:"4"}),o.jsx("path",{d:"M28.18 10.33A22 22 0 0 1 32 10",strokeWidth:"2.6"}),o.jsx("path",{d:"M32 10A22 22 0 0 1 33.92 10.08",strokeWidth:"1.5"}),o.jsx("path",{d:"M43 12.95A22 22 0 1 1 28.18 10.33",strokeWidth:"1.3",opacity:"0.7"}),o.jsxs("g",{opacity:"0.4",strokeWidth:"0.8",children:[Up.map(([r,l])=>o.jsxs("g",{transform:`rotate(${r} 32 32)`,children:[o.jsx("path",{d:`M32 13v${l}`}),o.jsx("circle",{cx:"32",cy:13+l,r:"0.85",fill:"currentColor",stroke:"none"})]},r)),o.jsx("path",{d:"M15.26 34.95A17 17 0 0 0 23.5 46.72"}),o.jsx("path",{d:"M43.4 43.4A17 17 0 0 0 48.4 36.1"})]}),o.jsx("path",{d:`M42.8 14.8
|
|
57
57
|
C46.6 14.6 49.6 12.3 49.4 8.8
|
|
58
58
|
C49.2 6.0 46.8 4.5 43.6 5.0
|
|
59
59
|
L33.6 7.7
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
flash white around a near-black app on load. -->
|
|
10
10
|
<meta name="theme-color" content="#0b0a12" />
|
|
11
11
|
<title>ouro</title>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-
|
|
12
|
+
<script type="module" crossorigin src="/assets/index-D-niaPon.js"></script>
|
|
13
13
|
<link rel="stylesheet" crossorigin href="/assets/index-C21ZXjPS.css">
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
package/package.json
CHANGED
|
@@ -55,7 +55,10 @@ function runClaude(args, { cwd, onEvent, signal } = {}) {
|
|
|
55
55
|
return new Promise((resolve, reject) => {
|
|
56
56
|
// `signal` wires cancellation straight to the child: aborting SIGTERMs the
|
|
57
57
|
// CLI rather than leaving it running detached. See lib/runs.js.
|
|
58
|
-
|
|
58
|
+
// windowsHide: the dashboard daemon spawns this per run — without it, each
|
|
59
|
+
// run flashes an empty `claude` console window on Windows. Output is piped
|
|
60
|
+
// and parsed here, so the child never needs a visible console of its own.
|
|
61
|
+
const proc = spawn(CLAUDE_BIN, args, { cwd, env: process.env, signal, windowsHide: true });
|
|
59
62
|
|
|
60
63
|
const rl = readline.createInterface({ input: proc.stdout });
|
|
61
64
|
let sessionId = null;
|
package/src/lib/codexExec.js
CHANGED
|
@@ -63,7 +63,9 @@ function agentFlags(agent) {
|
|
|
63
63
|
function runCodexExec(args, { cwd, onEvent, signal } = {}) {
|
|
64
64
|
return new Promise((resolve, reject) => {
|
|
65
65
|
// `signal` makes cancellation kill the child process. See lib/runs.js.
|
|
66
|
-
|
|
66
|
+
// windowsHide: keep the per-run child from flashing an empty console window
|
|
67
|
+
// on Windows — output is piped and parsed here, not shown in a console.
|
|
68
|
+
const proc = spawn(CODEX_BIN, args, { cwd, env: process.env, signal, windowsHide: true });
|
|
67
69
|
|
|
68
70
|
const rl = readline.createInterface({ input: proc.stdout });
|
|
69
71
|
let sessionId = null;
|
package/src/server/index.js
CHANGED
|
@@ -103,7 +103,7 @@ export function qaPrompt(ticket, testResult, preview) {
|
|
|
103
103
|
"3. If it is not a UI change, tests-only is fine.",
|
|
104
104
|
"",
|
|
105
105
|
"Judge the running result against the acceptance criteria and the test results. Never call something ready just because it was asked for.",
|
|
106
|
-
'Respond with ONLY a JSON object, no prose and no fences: {"ready": boolean, "summary": string, "reasons": string[], "ui_change": boolean, "visual_method": "screenshot"|"html"|"none", "questions": string[]}. When not ready, `reasons` must be concrete and actionable. `questions` are
|
|
106
|
+
'Respond with ONLY a JSON object, no prose and no fences: {"ready": boolean, "summary": string, "reasons": string[], "ui_change": boolean, "visual_method": "screenshot"|"html"|"none", "questions": string[]}. When not ready, `reasons` must be concrete and actionable. `questions` are open items to resolve before shipping — in an agent loop the engineer answers them itself, in human-in-loop the person does.'
|
|
107
107
|
);
|
|
108
108
|
return parts.join("\n");
|
|
109
109
|
}
|
|
@@ -139,10 +139,25 @@ export function qaSummaryLine(v) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
export function qaFeedbackBlock(v) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
.
|
|
145
|
-
|
|
142
|
+
const blocks = [];
|
|
143
|
+
if (v?.reasons?.length) {
|
|
144
|
+
blocks.push(
|
|
145
|
+
`The QA gate sent this back. Address every point before it can ship:\n${v.reasons
|
|
146
|
+
.map((r, i) => `${i + 1}. ${r}`)
|
|
147
|
+
.join("\n")}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
// Agent loop: no human will answer QA's questions, so the engineer resolves
|
|
151
|
+
// them itself. Only reached on the agent-loop loop-back path (enterStaging),
|
|
152
|
+
// so framing them as "yours to answer" is always accurate here.
|
|
153
|
+
if (v?.questions?.length) {
|
|
154
|
+
blocks.push(
|
|
155
|
+
`QA raised these open questions. This is an agent loop — no human will answer them, so resolve each one yourself: investigate the code, decide, act on it, and state the answer in your final message:\n${v.questions
|
|
156
|
+
.map((q, i) => `${i + 1}. ${q}`)
|
|
157
|
+
.join("\n")}`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return blocks.length ? `\n\n${blocks.join("\n\n")}` : "";
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
/**
|