@chrysb/alphaclaw 0.9.11 → 0.9.13
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/lib/public/dist/app.bundle.js +1 -1
- package/lib/public/js/components/nodes-tab/connected-nodes/user-connected-nodes.js +1 -1
- package/lib/server/commands.js +5 -0
- package/lib/server/model-catalog-bootstrap.json +1431 -181
- package/lib/server/routes/nodes.js +54 -10
- package/package.json +3 -7
- package/patches/openclaw+2026.4.23.patch +0 -63
- package/scripts/apply-openclaw-patches.js +0 -99
|
@@ -8107,7 +8107,7 @@ ${O?.grantPublisher||""}`.trim()))}
|
|
|
8107
8107
|
</${Zn}>
|
|
8108
8108
|
`};var kL=R.bind(M),qf=({onRestartRequired:t=()=>{}})=>kL`
|
|
8109
8109
|
<${V1} onRestartRequired=${t} />
|
|
8110
|
-
`;var CL=1e4,j1=({enabled:t=!0}={})=>{let e=Le(async()=>{let n=await ag(),s=Array.isArray(n?.nodes)?n.nodes:[],o=Array.isArray(n?.pending)?n.pending:[];return{nodes:s,pending:o}},CL,{enabled:t,cacheKey:"/api/nodes"});return{nodes:Array.isArray(e.data?.nodes)?e.data.nodes:[],pending:Array.isArray(e.data?.pending)?e.data.pending:[],loading:e.data===null&&!e.error,error:e.error?String(e.error.message||"Could not load nodes"):"",refresh:e.refresh}};var U1=()=>{let t=j1({enabled:!0}),[e,n]=x(!1),[s,o]=x(!1),{data:r,error:i}=it("/api/nodes/connect-info",za,{maxAgeMs:6e4}),a=Array.isArray(t.nodes)?t.nodes.filter(c=>c?.paired!==!1):[];P(()=>{i&&E(i.message||"Could not load node connect command","error")},[i]);let l=G(async()=>{if(!s){o(!0);try{await t.refresh()}finally{o(!1)}}},[t.refresh,s]);return{state:{wizardVisible:e,nodes:a,pending:t.pending,loadingNodes:t.loading,refreshingNodes:s,nodesError:t.error,connectInfo:r},actions:{openWizard:()=>n(!0),closeWizard:()=>n(!1),refreshNodes:l}}};var _L=35e3,AL=1e4,G1="nodesBrowserAttachStateByNode",ML=/selected page has been closed/i,TL=async(t,e=_L)=>{let n=null;try{return await Promise.race([t,new Promise((s,o)=>{n=setTimeout(()=>{o(new Error("Browser check timed out"))},e)})])}finally{n&&clearTimeout(n)}},K1=t=>{let e=Array.isArray(t?.caps)?t.caps:[],n=Array.isArray(t?.commands)?t.commands:[];return e.includes("browser")||n.includes("browser.proxy")},PL=t=>{let e=String(t?.message||"Could not check node browser status").trim();return ML.test(e)?"Selected Chrome page was closed. Click Attach to reconnect.":e},RL=()=>{let e=ze()?.[G1];return!e||typeof e!="object"||Array.isArray(e)?{}:e},LL=(t={})=>{Ml(e=>({...e&&typeof e=="object"?e:{},[G1]:t&&typeof t=="object"?t:{}}))},q1=({nodes:t=[],onRefreshNodes:e=async()=>{}}={})=>{let[n,s]=x({}),[o,r]=x({}),[i,a]=x(""),[l,c]=x(()=>RL()),[d,u]=x(""),[p,f]=x(null),[g,m]=x(""),h=oe(0),b=oe(""),y=async(S,{successMessage:_="Connection command copied",errorMessage:D="Could not copy connection command"}={})=>{if(await Dn(S)){E(_,"success");return}E(D,"error")},v=G(async(S,{silent:_=!1}={})=>{let D=String(S||"").trim();if(!(!D||b.current)){b.current=D,_||a(D),r(I=>({...I,[D]:""}));try{let I=await TL(dg(D,"user")),H=I?.status&&typeof I.status=="object"?I.status:null;s(B=>({...B,[D]:H}))}catch(I){let H=PL(I);s(B=>({...B,[D]:null})),r(B=>({...B,[D]:H})),_||E(H,"error")}finally{b.current="",_||a("")}}},[]),$=G((S,_)=>{let D=String(S||"").trim();D&&c(I=>{let H={...I&&typeof I=="object"?I:{},[D]:_===!0};return LL(H),H})},[]),w=G(async S=>{let _=String(S||"").trim();_&&($(_,!0),await v(_))},[v,$]),k=G(S=>{let _=String(S||"").trim();_&&($(_,!1),s(D=>{let I={...D||{}};return delete I[_],I}),r(D=>{let I={...D||{}};return delete I[_],I}))},[$]),A=G(S=>{let _=String(S||"").trim();_&&u(D=>D===_?"":_)},[]),C=G(async()=>{let S=String(p?.nodeId||"").trim();if(!(!S||g)){m(S);try{await lg(S),k(S),E("Device removed","success"),f(null),u(""),await e()}catch(_){E(_.message||"Could not remove node","error")}finally{m("")}}},[k,e,p,g]);return P(()=>{if(i)return;let S=t.map(_=>({nodeId:String(_?.nodeId||"").trim(),connected:_?.connected===!0,browserCapable:K1(_)})).find(_=>!(!_.nodeId||!_.connected||!_.browserCapable||l?.[_.nodeId]!==!0||n?.[_.nodeId]||o?.[_.nodeId]))?.nodeId;S&&v(S,{silent:!0})},[l,o,n,i,v,t]),P(()=>{if(i)return;let S=t.map(H=>({nodeId:String(H?.nodeId||"").trim(),connected:H?.connected===!0,browserCapable:K1(H),browserRunning:n?.[String(H?.nodeId||"").trim()]?.running===!0})).filter(H=>H.nodeId&&H.connected&&H.browserCapable&&l?.[H.nodeId]===!0&&H.browserRunning).map(H=>H.nodeId);if(!S.length)return;let _=!0,I=setInterval(async()=>{if(!_||b.current)return;let H=h.current%S.length;h.current+=1;let B=S[H];await v(B,{silent:!0})},AL);return()=>{_=!1,clearInterval(I)}},[l,n,i,v,t]),{browserStatusByNodeId:n,browserErrorByNodeId:o,checkingBrowserNodeId:i,browserAttachStateByNodeId:l,menuOpenNodeId:d,removeDialogNode:p,removingNodeId:g,handleCopyText:y,handleCheckNodeBrowser:v,handleAttachNodeBrowser:w,handleDetachNodeBrowser:k,handleOpenNodeMenu:A,handleRemoveNode:C,setMenuOpenNodeId:u,setRemoveDialogNode:f}};var at=R.bind(M),IL=t=>String(t||"").replace(/"/g,'\\"'),J1=({node:t,connectInfo:e,maskToken:n=!1})=>{let s=String(e?.gatewayHost||"").trim()||"localhost",o=Number(e?.gatewayPort)||3e3,r=String(e?.gatewayToken||"").trim(),i=e?.tls===!0?"--tls":"",a=String(t?.displayName||t?.nodeId||"My Node").trim(),l=n?"****":r;return[l?`OPENCLAW_GATEWAY_TOKEN=${l}`:"","openclaw node run",`--host ${s}`,`--port ${o}`,i,`--display-name "${IL(a)}"`].filter(Boolean).join(" ")},EL=t=>t?.connected?at`<${ge} tone="success">Connected</${ge}>`:t?.paired?at`<${ge} tone="warning">Disconnected</${ge}>`:at`<${ge} tone="danger">Pending approval</${ge}>`,DL=t=>{let e=Array.isArray(t?.caps)?t.caps:[],n=Array.isArray(t?.commands)?t.commands:[];return e.includes("browser")||n.includes("browser.proxy")},NL=t=>t.running?"success":"warning",OL=t=>t.running?"Attached":"Not connected",Z1=({nodes:t=[],pending:e=[],loading:n=!1,error:s="",connectInfo:o=null,onRefreshNodes:r=async()=>{}})=>{let i=q1({nodes:t,onRefreshNodes:r}),{browserStatusByNodeId:a,browserErrorByNodeId:l,checkingBrowserNodeId:c,browserAttachStateByNodeId:d,menuOpenNodeId:u,removeDialogNode:p,removingNodeId:f,handleCopyText:g,handleCheckNodeBrowser:m,handleAttachNodeBrowser:h,handleDetachNodeBrowser:b,handleOpenNodeMenu:y,handleRemoveNode:v,setMenuOpenNodeId:$,setRemoveDialogNode:w}=i;return at`
|
|
8110
|
+
`;var CL=1e4,j1=({enabled:t=!0}={})=>{let e=Le(async()=>{let n=await ag(),s=Array.isArray(n?.nodes)?n.nodes:[],o=Array.isArray(n?.pending)?n.pending:[];return{nodes:s,pending:o}},CL,{enabled:t,cacheKey:"/api/nodes",dedupeInFlight:!0});return{nodes:Array.isArray(e.data?.nodes)?e.data.nodes:[],pending:Array.isArray(e.data?.pending)?e.data.pending:[],loading:e.data===null&&!e.error,error:e.error?String(e.error.message||"Could not load nodes"):"",refresh:e.refresh}};var U1=()=>{let t=j1({enabled:!0}),[e,n]=x(!1),[s,o]=x(!1),{data:r,error:i}=it("/api/nodes/connect-info",za,{maxAgeMs:6e4}),a=Array.isArray(t.nodes)?t.nodes.filter(c=>c?.paired!==!1):[];P(()=>{i&&E(i.message||"Could not load node connect command","error")},[i]);let l=G(async()=>{if(!s){o(!0);try{await t.refresh()}finally{o(!1)}}},[t.refresh,s]);return{state:{wizardVisible:e,nodes:a,pending:t.pending,loadingNodes:t.loading,refreshingNodes:s,nodesError:t.error,connectInfo:r},actions:{openWizard:()=>n(!0),closeWizard:()=>n(!1),refreshNodes:l}}};var _L=35e3,AL=1e4,G1="nodesBrowserAttachStateByNode",ML=/selected page has been closed/i,TL=async(t,e=_L)=>{let n=null;try{return await Promise.race([t,new Promise((s,o)=>{n=setTimeout(()=>{o(new Error("Browser check timed out"))},e)})])}finally{n&&clearTimeout(n)}},K1=t=>{let e=Array.isArray(t?.caps)?t.caps:[],n=Array.isArray(t?.commands)?t.commands:[];return e.includes("browser")||n.includes("browser.proxy")},PL=t=>{let e=String(t?.message||"Could not check node browser status").trim();return ML.test(e)?"Selected Chrome page was closed. Click Attach to reconnect.":e},RL=()=>{let e=ze()?.[G1];return!e||typeof e!="object"||Array.isArray(e)?{}:e},LL=(t={})=>{Ml(e=>({...e&&typeof e=="object"?e:{},[G1]:t&&typeof t=="object"?t:{}}))},q1=({nodes:t=[],onRefreshNodes:e=async()=>{}}={})=>{let[n,s]=x({}),[o,r]=x({}),[i,a]=x(""),[l,c]=x(()=>RL()),[d,u]=x(""),[p,f]=x(null),[g,m]=x(""),h=oe(0),b=oe(""),y=async(S,{successMessage:_="Connection command copied",errorMessage:D="Could not copy connection command"}={})=>{if(await Dn(S)){E(_,"success");return}E(D,"error")},v=G(async(S,{silent:_=!1}={})=>{let D=String(S||"").trim();if(!(!D||b.current)){b.current=D,_||a(D),r(I=>({...I,[D]:""}));try{let I=await TL(dg(D,"user")),H=I?.status&&typeof I.status=="object"?I.status:null;s(B=>({...B,[D]:H}))}catch(I){let H=PL(I);s(B=>({...B,[D]:null})),r(B=>({...B,[D]:H})),_||E(H,"error")}finally{b.current="",_||a("")}}},[]),$=G((S,_)=>{let D=String(S||"").trim();D&&c(I=>{let H={...I&&typeof I=="object"?I:{},[D]:_===!0};return LL(H),H})},[]),w=G(async S=>{let _=String(S||"").trim();_&&($(_,!0),await v(_))},[v,$]),k=G(S=>{let _=String(S||"").trim();_&&($(_,!1),s(D=>{let I={...D||{}};return delete I[_],I}),r(D=>{let I={...D||{}};return delete I[_],I}))},[$]),A=G(S=>{let _=String(S||"").trim();_&&u(D=>D===_?"":_)},[]),C=G(async()=>{let S=String(p?.nodeId||"").trim();if(!(!S||g)){m(S);try{await lg(S),k(S),E("Device removed","success"),f(null),u(""),await e()}catch(_){E(_.message||"Could not remove node","error")}finally{m("")}}},[k,e,p,g]);return P(()=>{if(i)return;let S=t.map(_=>({nodeId:String(_?.nodeId||"").trim(),connected:_?.connected===!0,browserCapable:K1(_)})).find(_=>!(!_.nodeId||!_.connected||!_.browserCapable||l?.[_.nodeId]!==!0||n?.[_.nodeId]||o?.[_.nodeId]))?.nodeId;S&&v(S,{silent:!0})},[l,o,n,i,v,t]),P(()=>{if(i)return;let S=t.map(H=>({nodeId:String(H?.nodeId||"").trim(),connected:H?.connected===!0,browserCapable:K1(H),browserRunning:n?.[String(H?.nodeId||"").trim()]?.running===!0})).filter(H=>H.nodeId&&H.connected&&H.browserCapable&&l?.[H.nodeId]===!0&&H.browserRunning).map(H=>H.nodeId);if(!S.length)return;let _=!0,I=setInterval(async()=>{if(!_||b.current)return;let H=h.current%S.length;h.current+=1;let B=S[H];await v(B,{silent:!0})},AL);return()=>{_=!1,clearInterval(I)}},[l,n,i,v,t]),{browserStatusByNodeId:n,browserErrorByNodeId:o,checkingBrowserNodeId:i,browserAttachStateByNodeId:l,menuOpenNodeId:d,removeDialogNode:p,removingNodeId:g,handleCopyText:y,handleCheckNodeBrowser:v,handleAttachNodeBrowser:w,handleDetachNodeBrowser:k,handleOpenNodeMenu:A,handleRemoveNode:C,setMenuOpenNodeId:u,setRemoveDialogNode:f}};var at=R.bind(M),IL=t=>String(t||"").replace(/"/g,'\\"'),J1=({node:t,connectInfo:e,maskToken:n=!1})=>{let s=String(e?.gatewayHost||"").trim()||"localhost",o=Number(e?.gatewayPort)||3e3,r=String(e?.gatewayToken||"").trim(),i=e?.tls===!0?"--tls":"",a=String(t?.displayName||t?.nodeId||"My Node").trim(),l=n?"****":r;return[l?`OPENCLAW_GATEWAY_TOKEN=${l}`:"","openclaw node run",`--host ${s}`,`--port ${o}`,i,`--display-name "${IL(a)}"`].filter(Boolean).join(" ")},EL=t=>t?.connected?at`<${ge} tone="success">Connected</${ge}>`:t?.paired?at`<${ge} tone="warning">Disconnected</${ge}>`:at`<${ge} tone="danger">Pending approval</${ge}>`,DL=t=>{let e=Array.isArray(t?.caps)?t.caps:[],n=Array.isArray(t?.commands)?t.commands:[];return e.includes("browser")||n.includes("browser.proxy")},NL=t=>t.running?"success":"warning",OL=t=>t.running?"Attached":"Not connected",Z1=({nodes:t=[],pending:e=[],loading:n=!1,error:s="",connectInfo:o=null,onRefreshNodes:r=async()=>{}})=>{let i=q1({nodes:t,onRefreshNodes:r}),{browserStatusByNodeId:a,browserErrorByNodeId:l,checkingBrowserNodeId:c,browserAttachStateByNodeId:d,menuOpenNodeId:u,removeDialogNode:p,removingNodeId:f,handleCopyText:g,handleCheckNodeBrowser:m,handleAttachNodeBrowser:h,handleDetachNodeBrowser:b,handleOpenNodeMenu:y,handleRemoveNode:v,setMenuOpenNodeId:$,setRemoveDialogNode:w}=i;return at`
|
|
8111
8111
|
<div class="space-y-3">
|
|
8112
8112
|
${e.length?at`
|
|
8113
8113
|
<div
|
package/lib/server/commands.js
CHANGED
|
@@ -55,6 +55,11 @@ const createCommands = ({ gatewayEnv }) => {
|
|
|
55
55
|
stderr: stderr.trim(),
|
|
56
56
|
code: err?.code,
|
|
57
57
|
};
|
|
58
|
+
if (err) {
|
|
59
|
+
result.killed = Boolean(err.killed);
|
|
60
|
+
result.signal = err.signal || null;
|
|
61
|
+
result.timedOut = Boolean(err.killed && err.signal === killSignal);
|
|
62
|
+
}
|
|
58
63
|
if (!quiet && !result.ok) {
|
|
59
64
|
console.log(`[alphaclaw] Error: ${result.stderr.slice(0, 200)}`);
|
|
60
65
|
}
|