beeos-claw 0.6.88 → 0.6.92

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 (48) hide show
  1. package/README.md +66 -6
  2. package/dist/acp-gateway/gateway-events.js +1 -1
  3. package/dist/acp-gateway/history-artifact-hydrator.js +1 -1
  4. package/dist/acp-gateway/history-replay.js +1 -1
  5. package/dist/acp-gateway/local-session-history.js +1 -1
  6. package/dist/canvas/html-delivery.js +1 -1
  7. package/dist/canvas/runtime-lease-token.js +1 -0
  8. package/dist/canvas/tools.js +1 -1
  9. package/dist/canvas-orchestrator.js +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/message-sanitization/transport-metadata-sanitizer.js +1 -1
  12. package/dist/runtime/agent-runtime-failure-classifier.js +1 -1
  13. package/dist/runtime/central-native-composition.js +1 -0
  14. package/dist/runtime/central-native-context-engine.js +1 -0
  15. package/dist/runtime/central-native-credentials.js +1 -0
  16. package/dist/runtime/central-native-delta.js +1 -0
  17. package/dist/runtime/central-native-host.js +1 -0
  18. package/dist/runtime/central-native-interactions.js +1 -0
  19. package/dist/runtime/central-native-memory.js +1 -0
  20. package/dist/runtime/central-native-pending-journal.js +1 -0
  21. package/dist/runtime/central-native-production.js +1 -0
  22. package/dist/runtime/central-native-response.js +1 -0
  23. package/dist/runtime/central-native-runtime.js +1 -0
  24. package/dist/runtime/central-native-titles.js +1 -0
  25. package/dist/runtime/central-session-key.js +1 -0
  26. package/dist/runtime/conversation-title.js +1 -1
  27. package/dist/runtime/identity-lane-lease.js +1 -0
  28. package/dist/runtime/im-reply-sink.js +1 -1
  29. package/dist/runtime/ms-runtime-message-channel-adapter.js +1 -1
  30. package/dist/runtime/ms-runtime-message-channel-consumer-factory.js +1 -1
  31. package/dist/runtime/native-cloud-prompt-bridge.js +1 -1
  32. package/dist/runtime/openclaw-session-write-quiescence.js +1 -1
  33. package/dist/runtime/reply-router.js +1 -1
  34. package/dist/runtime/runtime-command-journal.js +1 -1
  35. package/dist/runtime/runtime-production-authority.js +1 -1
  36. package/dist/runtime/runtime-service-contract-compatibility.js +1 -1
  37. package/dist/runtime/runtime-service-production-candidate.js +1 -1
  38. package/dist/runtime/sandbox-native-activation.js +1 -0
  39. package/dist/runtime/sandbox-native-credentials.js +1 -0
  40. package/dist/runtime/sandbox-native-execution-resolver.js +1 -0
  41. package/dist/runtime/session-mutation-coordinator.js +1 -1
  42. package/dist/terminal/runtime-terminal-outbound-registration.js +1 -1
  43. package/dist/terminal/session-manager.js +1 -1
  44. package/dist/terminal/standalone-runtime-terminal.js +1 -0
  45. package/dist/upload/native-output-tool-hook.js +1 -1
  46. package/openclaw.plugin.json +1 -1
  47. package/package.json +4 -4
  48. package/runtime-service-wire-identity.v1.json +1 -1
@@ -1 +1 @@
1
- import{spawn}from"node:child_process";import{createRequire}from"node:module";import{randomUUID}from"node:crypto";import{realpathSync}from"node:fs";import{dirname,resolve}from"node:path";export const TERMINAL_TIMEOUT_REASONS={idle:"idle_timeout",maxDuration:"max_duration_timeout"};const ALLOWED_STATE_TRANSITIONS={opening:["running","closing","closed"],running:["closing","closed"],closing:["closed"],closed:[]},require=createRequire(import.meta.url);let cachedNodePty;function resolveOpenclawNodeModulesDir(){const e=process.argv[1];if(e)try{const t=realpathSync(e);if(/openclaw/i.test(t))return dirname(t)}catch{}const t=["/opt/homebrew/lib/node_modules/openclaw","/usr/local/lib/node_modules/openclaw","/usr/lib/node_modules/openclaw"];for(const e of t)try{return realpathSync(resolve(e,"package.json")),e}catch{}return null}function getNodePty(){if(void 0!==cachedNodePty)return cachedNodePty;const e=["node-pty","@lydell/node-pty"];for(const t of e)try{return cachedNodePty=require(t),cachedNodePty}catch{}const t=resolveOpenclawNodeModulesDir();if(t){const s=createRequire(resolve(t,"package.json"));for(const t of e)try{return cachedNodePty=s(t),cachedNodePty}catch{}}return cachedNodePty=null,null}function createPtyProcess(e){const t=getNodePty();if(!t)throw new Error("node-pty not available");const s={...process.env,...e.env,TERM:e.env?.TERM||"xterm-256color",LANG:e.env?.LANG||process.env.LANG||"C.UTF-8",LC_ALL:e.env?.LC_ALL||process.env.LC_ALL||"C.UTF-8"},i=t.spawn(e.shell,[...e.args],{name:"xterm-256color",cwd:e.cwd,env:s,cols:e.cols,rows:e.rows});let n=!1;return i.onData(t=>{e.onData(Buffer.from(t,"utf8"),"stdout")}),i.onExit(t=>{var s;s={code:Number.isFinite(t.exitCode)?t.exitCode:null,signal:null!=t.signal?String(t.signal):null},n||(n=!0,e.onExit(s))}),{write(e){const t=e.toString("utf8");t&&i.write(t)},resize(e,t){i.resize(e,t)},close(){try{i.kill()}catch{}}}}function createPipeProcess(e){const t=spawn(e.shell,[...e.args],{shell:!1,cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,...e.env,TERM:e.env?.TERM||"xterm-256color",LANG:e.env?.LANG||process.env.LANG||"C.UTF-8",LC_ALL:e.env?.LC_ALL||process.env.LC_ALL||"C.UTF-8"}});let s=!1;const i=t=>{s||(s=!0,e.onExit(t))};return t.stdout?.on("data",t=>e.onData(Buffer.isBuffer(t)?t:Buffer.from(t),"stdout")),t.stderr?.on("data",t=>e.onData(Buffer.isBuffer(t)?t:Buffer.from(t),"stderr")),t.once("error",e=>i({code:null,signal:null})),t.once("exit",(e,t)=>i({code:e??null,signal:t??null})),{write(e){t.stdin?.destroyed||t.stdin?.write(e)},resize(e,t){},close(){t.killed||t.kill()}}}function createDefaultProcess(e){try{return createPtyProcess(e)}catch{return createPipeProcess(e)}}const DEFAULT_MAX_CONCURRENT=10,DEFAULT_IDLE_TIMEOUT_MS=432e5,DEFAULT_MAX_DURATION_MS=432e5;export class TerminalNotFoundError extends Error{terminalId;constructor(e){super(`terminal not found: ${e}`),this.name="TerminalNotFoundError",this.terminalId=e}}export class TerminalClosedError extends Error{terminalId;state;constructor(e,t){super(`terminal is not writable in state=${t}: ${e}`),this.name="TerminalClosedError",this.terminalId=e,this.state=t}}function chainHandler(e,t){return t?e?s=>{e(s),t(s)}:t:e}export class TerminalManager{sessions=new Map;maxConcurrent;idleTimeoutMs;maxDurationMs;onOutput;onExit;onStateChange;constructor(e){this.maxConcurrent=e?.maxConcurrent??10,this.idleTimeoutMs=e?.idleTimeoutMs??432e5,this.maxDurationMs=e?.maxDurationMs??432e5}addListeners(e){this.onOutput=chainHandler(this.onOutput,e.onOutput),this.onExit=chainHandler(this.onExit,e.onExit),this.onStateChange=chainHandler(this.onStateChange,e.onStateChange)}openSession(e){if(void 0!==e.outputLimitBytes&&(!Number.isInteger(e.outputLimitBytes)||e.outputLimitBytes<1||e.outputLimitBytes>16777216))throw new Error("terminal output limit is outside the contract range");if(this.sessions.size>=this.maxConcurrent&&this.evictOldest(),this.sessions.size>=this.maxConcurrent)throw new Error("terminal quota exceeded");if(e.incarnation&&e.terminalId!==e.incarnation.terminalId)throw new Error("terminal incarnation does not match terminalId");if(e.incarnation&&e.terminalId&&this.sessions.has(e.terminalId))throw new Error(`terminal already exists: ${e.terminalId}`);const t=e.terminalId&&!this.sessions.has(e.terminalId)?e.terminalId:`term_${randomUUID().slice(0,12)}`,s=e.sessionId??t,i=e.command||process.env.SHELL||"/bin/bash",n=e.cwd||process.cwd(),r=Date.now(),o={terminalId:t,sessionId:s,shell:i,cwd:n,startedAt:r,lastActiveAt:r,cols:e.cols,rows:e.rows,state:"opening",nextServerSeq:Math.max(1,e.initialServerSequence??1),output:[],outputBytes:0,outputLimitBytes:Math.max(1,e.outputLimitBytes??1048576),clientExitWaiters:new Set,drainExitWaiters:new Set,process:null,incarnation:e.incarnation??this.createSessionIncarnation(t)};this.sessions.set(t,o);try{o.process=createDefaultProcess({shell:i,args:e.args??[],env:e.env,cwd:n,cols:e.cols,rows:e.rows,onData:(e,t)=>this.handleProcessData(o,e,t),onExit:e=>this.handleProcessExit(o,e)}),this.transitionState(o,"running"),this.scheduleIdleTimeout(o),this.scheduleMaxDuration(o)}catch(e){throw this.clearTimers(o),this.transitionState(o,"closed"),this.sessions.delete(t),e}return this.snapshot(o)}writeToSession(e,t){const s=this.requireSession(e);this.assertRunning(s),s.process?.write(t),this.markActivity(s)}writeToSessionIfCurrent(e,t,s){this.requireCurrentSession(e,t),this.writeToSession(e,s)}resizeSession(e,t,s){const i=this.requireSession(e);this.assertRunning(i),i.cols=t,i.rows=s,i.process?.resize(t,s),this.markActivity(i)}resizeSessionIfCurrent(e,t,s,i){this.requireCurrentSession(e,t),this.resizeSession(e,s,i)}closeSession(e,t){const s=this.sessions.get(e);s&&(t&&!s.timeoutReason&&(s.timeoutReason=t),"closed"!==s.state?(this.clearTimers(s),"closing"!==s.state&&(this.transitionState(s,"closing"),s.process?.close())):this.clearTimers(s))}touchSession(e){const t=this.requireSession(e);this.assertRunning(t),this.markActivity(t)}touchSessionIfCurrent(e,t){this.requireCurrentSession(e,t),this.touchSession(e)}nextServerSequence(e,t){const s=this.requireSession(e);if(t&&s.incarnation!==t)throw new TerminalNotFoundError(e);return s.nextServerSeq++}createSessionIncarnation(e){return Object.freeze({terminalId:e,token:Symbol(e)})}getSessionIncarnation(e){const t=this.sessions.get(e);return t&&!t.detached?t.incarnation:void 0}isCurrentSession(e,t){return this.sessions.get(e)?.incarnation===t}rebindSessionId(e,t,s){const i=this.sessions.get(e);return!(!i||i.detached||i.incarnation!==t)&&("string"==typeof s&&0!==s.length&&(i.sessionId=s,!0))}closeSessionIfCurrent(e,t,s){return!!this.isCurrentSession(e,t)&&(this.closeSession(e,s),!0)}releaseSessionIfCurrent(e,t){return!!this.isCurrentSession(e,t)&&(this.release(e),!0)}detachSessionIfCurrent(e,t){return!!this.isCurrentSession(e,t)&&(this.detach(e),!0)}killSessionIfCurrent(e,t,s="SIGTERM"){return!!this.isCurrentSession(e,t)&&(this.kill(e,s),!0)}getSession(e){const t=this.sessions.get(e);return t&&!t.detached?this.snapshot(t):void 0}async waitForExit(e,t=3e4){const s=this.requireSession(e);return"closed"!==s.state&&await new Promise(e=>{let i=!1;const n=()=>{i||(i=!0,clearTimeout(r),s.clientExitWaiters.delete(n),e())},r=setTimeout(n,Math.max(0,t));r.unref?.(),s.clientExitWaiters.add(n)}),{terminalId:e,exitCode:s.exitCode??null,output:s.output.join(""),state:s.state}}async waitForExitIfCurrent(e,t,s=3e4){this.requireCurrentSession(e,t);const i=await this.waitForExit(e,s);return this.requireCurrentSession(e,t),i}create(e){const t=this.openSession({command:e,cols:80,rows:24}),s=this.sessions.get(t.terminalId);return{id:s.terminalId,command:s.shell,state:s.state,output:s.output,exitCode:s.exitCode,seq:s.nextServerSeq-1}}get(e){const t=this.sessions.get(e);if(t&&!t.detached)return{id:t.terminalId,state:t.state,output:t.output,exitCode:t.exitCode,seq:t.nextServerSeq-1}}write(e,t){try{return this.writeToSession(e,Buffer.from(t,"utf8")),!0}catch{return!1}}resize(e,t,s){try{return this.resizeSession(e,t,s),!0}catch{return!1}}kill(e,t="SIGTERM"){const s=this.sessions.get(e);s&&s.process&&("closing"!==s.state&&this.transitionState(s,"closing"),s.process.close())}release(e){const t=this.sessions.get(e);if(t){!t.process||"running"!==t.state&&"opening"!==t.state||this.kill(e),this.clearTimers(t),this.sessions.delete(e);for(const e of[...t.clientExitWaiters])e()}}detach(e){const t=this.requireSession(e);t.detached=!0,t.output=[],t.outputBytes=0;for(const e of[...t.clientExitWaiters])e();"closed"===t.state&&this.sessions.delete(e)}listSessions(){return[...this.sessions.values()].map(e=>this.snapshot(e))}async drain(e,t){const s=[...this.sessions.values()].filter(e=>"closed"!==e.state);if(0===s.length)return"drained";let i;const n=[],r=Promise.all(s.map(e=>new Promise(t=>{const s=()=>{e.drainExitWaiters.delete(s),t()};n.push({session:e,finish:s}),e.drainExitWaiters.add(s)}))).then(()=>!0),o=await Promise.race([r,new Promise(t=>{i=setTimeout(()=>t(!1),Math.max(0,e))})]);if(i&&clearTimeout(i),o)return"drained";for(const e of n)e.session.drainExitWaiters.delete(e.finish);if(t)for(const e of s)this.closeOwnedSession(e,"worker_drain_timeout");return"terminated"}get sessionCount(){return this.sessions.size}get maxConcurrentLimit(){return this.maxConcurrent}destroy(){for(const e of[...this.sessions.keys()])this.release(e)}snapshot(e){return{terminalId:e.terminalId,sessionId:e.sessionId,shell:e.shell,cwd:e.cwd,startedAt:e.startedAt,lastActiveAt:e.lastActiveAt,cols:e.cols,rows:e.rows,state:e.state}}requireSession(e){const t=this.sessions.get(e);if(!t||t.detached)throw new TerminalNotFoundError(e);return t}requireCurrentSession(e,t){const s=this.requireSession(e);if(s.incarnation!==t)throw new TerminalNotFoundError(e);return s}assertRunning(e){if("running"!==e.state)throw new TerminalClosedError(e.terminalId,e.state)}transitionState(e,t){const s=e.state;s!==t&&ALLOWED_STATE_TRANSITIONS[s].includes(t)&&(e.state=t,this.onStateChange?.({terminalId:e.terminalId,sessionId:e.sessionId,from:s,to:t,incarnation:e.incarnation}))}handleProcessData(e,t,s){if(this.sessions.get(e.terminalId)!==e||"closed"===e.state)return;this.markActivity(e);const i=e.nextServerSeq++;appendOutput(e,t),this.onOutput?.({terminalId:e.terminalId,sessionId:e.sessionId,data:t,seq:i,stream:s,incarnation:e.incarnation})}handleProcessExit(e,t){if(this.sessions.get(e.terminalId)===e){this.clearTimers(e),e.exitCode=t.code??void 0;try{if("closing"!==e.state&&this.transitionState(e,"closing"),this.sessions.get(e.terminalId)!==e)return;if(this.transitionState(e,"closed"),this.sessions.get(e.terminalId)!==e)return;this.onExit?.({terminalId:e.terminalId,sessionId:e.sessionId,code:t.code,signal:t.signal,...e.timeoutReason?{reason:e.timeoutReason}:{},seq:e.nextServerSeq++,incarnation:e.incarnation})}finally{for(const t of[...e.clientExitWaiters])t();for(const t of[...e.drainExitWaiters])t();e.detached&&this.sessions.get(e.terminalId)===e&&this.sessions.delete(e.terminalId)}}}closeOwnedSession(e,t){this.sessions.get(e.terminalId)===e&&this.closeSession(e.terminalId,t)}markActivity(e){e.lastActiveAt=Date.now(),"running"===e.state&&this.refreshIdleTimer(e)}evictOldest(){let e=null;for(const t of this.sessions.values()){if("closed"===t.state){e=t;break}(!e||t.lastActiveAt<e.lastActiveAt||t.lastActiveAt===e.lastActiveAt&&t.startedAt<e.startedAt)&&(e=t)}e&&this.release(e.terminalId)}refreshIdleTimer(e){e.idleTimer&&clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{"running"===e.state&&this.closeSessionIfCurrent(e.terminalId,e.incarnation,TERMINAL_TIMEOUT_REASONS.idle)},this.idleTimeoutMs),"object"==typeof e.idleTimer&&"unref"in e.idleTimer&&e.idleTimer.unref()}scheduleIdleTimeout(e){this.refreshIdleTimer(e)}scheduleMaxDuration(e){e.maxDurationTimer=setTimeout(()=>{"running"===e.state&&this.closeSessionIfCurrent(e.terminalId,e.incarnation,TERMINAL_TIMEOUT_REASONS.maxDuration)},this.maxDurationMs),"object"==typeof e.maxDurationTimer&&"unref"in e.maxDurationTimer&&e.maxDurationTimer.unref()}clearTimers(e){e.idleTimer&&(clearTimeout(e.idleTimer),e.idleTimer=void 0),e.maxDurationTimer&&(clearTimeout(e.maxDurationTimer),e.maxDurationTimer=void 0)}}function appendOutput(e,t){const s=t.toString("utf8");for(e.output.push(s),e.outputBytes+=Buffer.byteLength(s);e.outputBytes>e.outputLimitBytes&&e.output.length>0;){const t=e.outputBytes-e.outputLimitBytes,s=e.output[0],i=Buffer.from(s);if(i.length<=t){e.output.shift(),e.outputBytes-=i.length;continue}let n=t;for(;n<i.length&&128==(192&i[n]);)n++;e.output[0]=i.subarray(n).toString("utf8"),e.outputBytes-=n}}
1
+ import{spawn}from"node:child_process";import{createRequire}from"node:module";import{randomUUID}from"node:crypto";import{realpathSync}from"node:fs";import{dirname,resolve}from"node:path";export const TERMINAL_TIMEOUT_REASONS={idle:"idle_timeout",maxDuration:"max_duration_timeout"};const ALLOWED_STATE_TRANSITIONS={opening:["running","closing","closed"],running:["closing","closed"],closing:["closed"],closed:[]},require=createRequire(import.meta.url);let cachedNodePty;function resolveOpenclawNodeModulesDir(){const e=process.argv[1];if(e)try{const t=realpathSync(e);if(/openclaw/i.test(t))return dirname(t)}catch{}const t=["/opt/homebrew/lib/node_modules/openclaw","/usr/local/lib/node_modules/openclaw","/usr/lib/node_modules/openclaw"];for(const e of t)try{return realpathSync(resolve(e,"package.json")),e}catch{}return null}function getNodePty(){if(void 0!==cachedNodePty)return cachedNodePty;const e=["node-pty","@lydell/node-pty"];for(const t of e)try{return cachedNodePty=require(t),cachedNodePty}catch{}const t=resolveOpenclawNodeModulesDir();if(t){const s=createRequire(resolve(t,"package.json"));for(const t of e)try{return cachedNodePty=s(t),cachedNodePty}catch{}}return cachedNodePty=null,null}function createPtyProcess(e){const t=getNodePty();if(!t)throw new Error("node-pty not available");const s={...process.env,...e.env,TERM:e.env?.TERM||"xterm-256color",LANG:e.env?.LANG||process.env.LANG||"C.UTF-8",LC_ALL:e.env?.LC_ALL||process.env.LC_ALL||"C.UTF-8"},i=t.spawn(e.shell,[...e.args],{name:"xterm-256color",cwd:e.cwd,env:s,cols:e.cols,rows:e.rows});let n=!1;return i.onData(t=>{e.onData(Buffer.from(t,"utf8"),"stdout")}),i.onExit(t=>{var s;s={code:Number.isFinite(t.exitCode)?t.exitCode:null,signal:null!=t.signal?String(t.signal):null},n||(n=!0,e.onExit(s))}),{write(e){const t=e.toString("utf8");t&&i.write(t)},resize(e,t){i.resize(e,t)},close(){try{i.kill()}catch{}}}}function createPipeProcess(e){const t=spawn(e.shell,[...e.args],{shell:!1,cwd:e.cwd,stdio:["pipe","pipe","pipe"],env:{...process.env,...e.env,TERM:e.env?.TERM||"xterm-256color",LANG:e.env?.LANG||process.env.LANG||"C.UTF-8",LC_ALL:e.env?.LC_ALL||process.env.LC_ALL||"C.UTF-8"}});let s=!1;const i=t=>{s||(s=!0,e.onExit(t))};return t.stdout?.on("data",t=>e.onData(Buffer.isBuffer(t)?t:Buffer.from(t),"stdout")),t.stderr?.on("data",t=>e.onData(Buffer.isBuffer(t)?t:Buffer.from(t),"stderr")),t.once("error",e=>i({code:null,signal:null})),t.once("exit",(e,t)=>i({code:e??null,signal:t??null})),{write(e){t.stdin?.destroyed||t.stdin?.write(e)},resize(e,t){},close(){t.killed||t.kill()}}}function createDefaultProcess(e){try{return createPtyProcess(e)}catch{return createPipeProcess(e)}}const DEFAULT_MAX_CONCURRENT=10,DEFAULT_IDLE_TIMEOUT_MS=432e5,DEFAULT_MAX_DURATION_MS=432e5;export class TerminalNotFoundError extends Error{terminalId;constructor(e){super(`terminal not found: ${e}`),this.name="TerminalNotFoundError",this.terminalId=e}}export class TerminalClosedError extends Error{terminalId;state;constructor(e,t){super(`terminal is not writable in state=${t}: ${e}`),this.name="TerminalClosedError",this.terminalId=e,this.state=t}}function chainHandler(e,t){return t?e?s=>{e(s),t(s)}:t:e}export class TerminalManager{sessions=new Map;admissions=new Map;maxConcurrent;idleTimeoutMs;maxDurationMs;requirePty;onOutput;onExit;onStateChange;constructor(e){this.maxConcurrent=e?.maxConcurrent??10,this.idleTimeoutMs=e?.idleTimeoutMs??432e5,this.maxDurationMs=e?.maxDurationMs??432e5,this.requirePty=!0===e?.requirePty}addListeners(e){this.onOutput=chainHandler(this.onOutput,e.onOutput),this.onExit=chainHandler(this.onExit,e.onExit),this.onStateChange=chainHandler(this.onStateChange,e.onStateChange)}openSession(e){if(void 0!==e.outputLimitBytes&&(!Number.isInteger(e.outputLimitBytes)||e.outputLimitBytes<1||e.outputLimitBytes>16777216))throw new Error("terminal output limit is outside the contract range");if(this.sessions.size>=this.maxConcurrent&&this.evictOldest(),this.sessions.size>=this.maxConcurrent)throw new Error("terminal quota exceeded");if(e.incarnation&&e.terminalId!==e.incarnation.terminalId)throw new Error("terminal incarnation does not match terminalId");if(e.incarnation&&e.terminalId&&this.sessions.has(e.terminalId))throw new Error(`terminal already exists: ${e.terminalId}`);const t=e.terminalId&&!this.sessions.has(e.terminalId)?e.terminalId:`term_${randomUUID().slice(0,12)}`,s=e.sessionId??t,i=e.command||process.env.SHELL||"/bin/bash",n=e.cwd||process.cwd(),r=Date.now(),o={terminalId:t,sessionId:s,shell:i,cwd:n,startedAt:r,lastActiveAt:r,cols:e.cols,rows:e.rows,state:"opening",nextServerSeq:Math.max(1,e.initialServerSequence??1),output:[],outputBytes:0,outputLimitBytes:Math.max(1,e.outputLimitBytes??1048576),clientExitWaiters:new Set,drainExitWaiters:new Set,process:null,incarnation:e.incarnation??this.createSessionIncarnation(t)};this.sessions.set(t,o),this.admissions.set(t,{incarnation:o.incarnation,clients:new Set([s]),started:!1,exited:!1,exitCode:null,lastSequence:0});try{o.process=(this.requirePty?createPtyProcess:createDefaultProcess)({shell:i,args:e.args??[],env:e.env,cwd:n,cols:e.cols,rows:e.rows,onData:(e,t)=>this.handleProcessData(o,e,t),onExit:e=>this.handleProcessExit(o,e)}),this.admissions.get(t).started=!0,this.transitionState(o,"running"),this.scheduleIdleTimeout(o),this.scheduleMaxDuration(o)}catch(e){throw this.clearTimers(o),this.transitionState(o,"closed"),this.sessions.delete(t),e}return this.snapshot(o)}writeToSession(e,t){const s=this.requireSession(e);this.assertRunning(s),s.process?.write(t),this.markActivity(s)}writeToSessionIfCurrent(e,t,s){this.requireCurrentSession(e,t),this.writeToSession(e,s)}resizeSession(e,t,s){const i=this.requireSession(e);this.assertRunning(i),i.cols=t,i.rows=s,i.process?.resize(t,s),this.markActivity(i)}resizeSessionIfCurrent(e,t,s,i){this.requireCurrentSession(e,t),this.resizeSession(e,s,i)}closeSession(e,t){const s=this.sessions.get(e);s&&(t&&!s.timeoutReason&&(s.timeoutReason=t),"closed"!==s.state?(this.clearTimers(s),"closing"!==s.state&&(this.transitionState(s,"closing"),s.process?.close())):this.clearTimers(s))}touchSession(e){const t=this.requireSession(e);this.assertRunning(t),this.markActivity(t)}touchSessionIfCurrent(e,t){this.requireCurrentSession(e,t),this.touchSession(e)}nextServerSequence(e,t){const s=this.requireSession(e);if(t&&s.incarnation!==t)throw new TerminalNotFoundError(e);const i=s.nextServerSeq++,n=this.admissions.get(e);return n?.incarnation===s.incarnation&&(n.lastSequence=i),i}createSessionIncarnation(e){return Object.freeze({terminalId:e,token:Symbol(e)})}getSessionIncarnation(e){const t=this.sessions.get(e);return t&&!t.detached?t.incarnation:void 0}isCurrentSession(e,t){return this.sessions.get(e)?.incarnation===t}rebindSessionId(e,t,s){const i=this.sessions.get(e);return!(!i||i.detached||i.incarnation!==t)&&("string"==typeof s&&0!==s.length&&(i.sessionId=s,this.admissions.get(e)?.clients.add(s),!0))}hasSessionAdmission(e){return this.admissions.has(e)}observeRetention(e,t){const s=this.admissions.get(e);if(!s?.clients.has(t))return;const i=this.sessions.get(e),n=s.started&&!s.exited;return{exists:Boolean(i)||n,active:n,exited:s.exited,exitCode:s.exitCode,retentionConverged:s.exited,lastServerSequence:String(Math.max(s.lastSequence,(i?.nextServerSeq??1)-1))}}closeSessionIfCurrent(e,t,s){return!!this.isCurrentSession(e,t)&&(this.closeSession(e,s),!0)}releaseSessionIfCurrent(e,t){return!!this.isCurrentSession(e,t)&&(this.release(e),!0)}detachSessionIfCurrent(e,t){return!!this.isCurrentSession(e,t)&&(this.detach(e),!0)}killSessionIfCurrent(e,t,s="SIGTERM"){return!!this.isCurrentSession(e,t)&&(this.kill(e,s),!0)}getSession(e){const t=this.sessions.get(e);return t&&!t.detached?this.snapshot(t):void 0}async waitForExit(e,t=3e4){const s=this.requireSession(e);return"closed"!==s.state&&await new Promise(e=>{let i=!1;const n=()=>{i||(i=!0,clearTimeout(r),s.clientExitWaiters.delete(n),e())},r=setTimeout(n,Math.max(0,t));r.unref?.(),s.clientExitWaiters.add(n)}),{terminalId:e,exitCode:s.exitCode??null,output:s.output.join(""),state:s.state}}async waitForExitIfCurrent(e,t,s=3e4){this.requireCurrentSession(e,t);const i=await this.waitForExit(e,s);return this.requireCurrentSession(e,t),i}create(e){const t=this.openSession({command:e,cols:80,rows:24}),s=this.sessions.get(t.terminalId);return{id:s.terminalId,command:s.shell,state:s.state,output:s.output,exitCode:s.exitCode,seq:s.nextServerSeq-1}}get(e){const t=this.sessions.get(e);if(t&&!t.detached)return{id:t.terminalId,state:t.state,output:t.output,exitCode:t.exitCode,seq:t.nextServerSeq-1}}write(e,t){try{return this.writeToSession(e,Buffer.from(t,"utf8")),!0}catch{return!1}}resize(e,t,s){try{return this.resizeSession(e,t,s),!0}catch{return!1}}kill(e,t="SIGTERM"){const s=this.sessions.get(e);s&&s.process&&("closing"!==s.state&&this.transitionState(s,"closing"),s.process.close())}release(e){const t=this.sessions.get(e);if(t){!t.process||"running"!==t.state&&"opening"!==t.state||this.kill(e),this.clearTimers(t),this.sessions.delete(e);for(const e of[...t.clientExitWaiters])e()}}detach(e){const t=this.requireSession(e);t.detached=!0,t.output=[],t.outputBytes=0;for(const e of[...t.clientExitWaiters])e();"closed"===t.state&&this.sessions.delete(e)}listSessions(){return[...this.sessions.values()].map(e=>this.snapshot(e))}async drain(e,t){const s=[...this.sessions.values()].filter(e=>"closed"!==e.state);if(0===s.length)return"drained";let i;const n=[],r=Promise.all(s.map(e=>new Promise(t=>{const s=()=>{e.drainExitWaiters.delete(s),t()};n.push({session:e,finish:s}),e.drainExitWaiters.add(s)}))).then(()=>!0),o=await Promise.race([r,new Promise(t=>{i=setTimeout(()=>t(!1),Math.max(0,e))})]);if(i&&clearTimeout(i),o)return"drained";for(const e of n)e.session.drainExitWaiters.delete(e.finish);if(t)for(const e of s)this.closeOwnedSession(e,"worker_drain_timeout");return"terminated"}get sessionCount(){return this.sessions.size}get maxConcurrentLimit(){return this.maxConcurrent}destroy(){for(const e of[...this.sessions.keys()])this.release(e)}snapshot(e){return{terminalId:e.terminalId,sessionId:e.sessionId,shell:e.shell,cwd:e.cwd,startedAt:e.startedAt,lastActiveAt:e.lastActiveAt,cols:e.cols,rows:e.rows,state:e.state}}requireSession(e){const t=this.sessions.get(e);if(!t||t.detached)throw new TerminalNotFoundError(e);return t}requireCurrentSession(e,t){const s=this.requireSession(e);if(s.incarnation!==t)throw new TerminalNotFoundError(e);return s}assertRunning(e){if("running"!==e.state)throw new TerminalClosedError(e.terminalId,e.state)}transitionState(e,t){const s=e.state;s!==t&&ALLOWED_STATE_TRANSITIONS[s].includes(t)&&(e.state=t,this.onStateChange?.({terminalId:e.terminalId,sessionId:e.sessionId,from:s,to:t,incarnation:e.incarnation}))}handleProcessData(e,t,s){if(this.sessions.get(e.terminalId)!==e||"closed"===e.state)return;this.markActivity(e);const i=e.nextServerSeq++,n=this.admissions.get(e.terminalId);n?.incarnation===e.incarnation&&(n.lastSequence=i),appendOutput(e,t),this.onOutput?.({terminalId:e.terminalId,sessionId:e.sessionId,data:t,seq:i,stream:s,incarnation:e.incarnation})}handleProcessExit(e,t){const s=this.admissions.get(e.terminalId);if(s?.incarnation===e.incarnation&&(s.exited=!0,s.exitCode=t.code,s.lastSequence=e.nextServerSeq),this.sessions.get(e.terminalId)===e){this.clearTimers(e),e.exitCode=t.code??void 0;try{if("closing"!==e.state&&this.transitionState(e,"closing"),this.sessions.get(e.terminalId)!==e)return;if(this.transitionState(e,"closed"),this.sessions.get(e.terminalId)!==e)return;this.onExit?.({terminalId:e.terminalId,sessionId:e.sessionId,code:t.code,signal:t.signal,...e.timeoutReason?{reason:e.timeoutReason}:{},seq:e.nextServerSeq++,incarnation:e.incarnation})}finally{for(const t of[...e.clientExitWaiters])t();for(const t of[...e.drainExitWaiters])t();e.detached&&this.sessions.get(e.terminalId)===e&&this.sessions.delete(e.terminalId)}}}closeOwnedSession(e,t){this.sessions.get(e.terminalId)===e&&this.closeSession(e.terminalId,t)}markActivity(e){e.lastActiveAt=Date.now(),"running"===e.state&&this.refreshIdleTimer(e)}evictOldest(){let e=null;for(const t of this.sessions.values()){if("closed"===t.state){e=t;break}(!e||t.lastActiveAt<e.lastActiveAt||t.lastActiveAt===e.lastActiveAt&&t.startedAt<e.startedAt)&&(e=t)}e&&this.release(e.terminalId)}refreshIdleTimer(e){e.idleTimer&&clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{"running"===e.state&&this.closeSessionIfCurrent(e.terminalId,e.incarnation,TERMINAL_TIMEOUT_REASONS.idle)},this.idleTimeoutMs),"object"==typeof e.idleTimer&&"unref"in e.idleTimer&&e.idleTimer.unref()}scheduleIdleTimeout(e){this.refreshIdleTimer(e)}scheduleMaxDuration(e){e.maxDurationTimer=setTimeout(()=>{"running"===e.state&&this.closeSessionIfCurrent(e.terminalId,e.incarnation,TERMINAL_TIMEOUT_REASONS.maxDuration)},this.maxDurationMs),"object"==typeof e.maxDurationTimer&&"unref"in e.maxDurationTimer&&e.maxDurationTimer.unref()}clearTimers(e){e.idleTimer&&(clearTimeout(e.idleTimer),e.idleTimer=void 0),e.maxDurationTimer&&(clearTimeout(e.maxDurationTimer),e.maxDurationTimer=void 0)}}function appendOutput(e,t){const s=t.toString("utf8");for(e.output.push(s),e.outputBytes+=Buffer.byteLength(s);e.outputBytes>e.outputLimitBytes&&e.output.length>0;){const t=e.outputBytes-e.outputLimitBytes,s=e.output[0],i=Buffer.from(s);if(i.length<=t){e.output.shift(),e.outputBytes-=i.length;continue}let n=t;for(;n<i.length&&128==(192&i[n]);)n++;e.output[0]=i.subarray(n).toString("utf8"),e.outputBytes-=n}}
@@ -0,0 +1 @@
1
+ import{EventEmitter}from"node:events";import{timingSafeEqual}from"node:crypto";import{readFileSync,statSync}from"node:fs";import{createServer}from"node:http";import{StringDecoder}from"node:string_decoder";import{pathToFileURL}from"node:url";import{TERMINAL_MAX_FRAME_BYTES}from"@beeos-ai/beeos-types/runtime";import{TerminalManager}from"./session-manager.js";import{assertTerminalClientFrame}from"./runtime-terminal-service.js";import{RuntimeTerminalOutboundRegistration}from"./runtime-terminal-outbound-registration.js";export const TERMINAL_UID=1001;export const WORKSPACE_GID=1002;export class TerminalJSONStream{accept;decoder=new StringDecoder("utf8");value="";depth=0;bytes=0;quoted=!1;escaped=!1;constructor(e){this.accept=e}push(e){for(const t of this.decoder.write(e)){if(!this.value){if(/\s/.test(t))continue;if("{"!==t)throw new Error("terminal frame must be a JSON object")}if(this.value+=t,this.bytes+=Buffer.byteLength(t),this.bytes>TERMINAL_MAX_FRAME_BYTES)throw new Error("terminal frame exceeds limit");if(this.quoted?this.escaped?this.escaped=!1:"\\"===t?this.escaped=!0:'"'===t&&(this.quoted=!1):'"'===t?this.quoted=!0:"{"===t||"["===t?this.depth++:"}"!==t&&"]"!==t||this.depth--,0===this.depth){const e=this.value;this.value="",this.bytes=0,this.accept(e)}}}}class LoopbackTerminalTransport extends EventEmitter{state="idle";routes=new Map;async connect(){this.state="connected",this.emit("connected")}async send(e){const t=JSON.parse(e.toString()),r=this.routes.get(t.clientId);r&&!r.socket.destroyed&&await new Promise(t=>{r.socket.write(e,e=>{e&&r.socket.destroy(),t()})})}async close(){this.state="closed";for(const e of this.routes.values())e.socket.destroy();this.routes.clear()}}export class StandaloneRuntimeTerminal{token;manager=new TerminalManager({requirePty:!0});transport=new LoopbackTerminalTransport;registration;server;sockets=new Set;ready=!1;stopping;constructor(e,t){if(this.token=e,!e)throw new Error("empty terminal transport token");this.registration=new RuntimeTerminalOutboundRegistration({client:this.transport,manager:this.manager,...t,frameAdmission:{admit:async e=>{const t=e;assertTerminalClientFrame(t);const r=this.transport.routes.get(t.clientId);if(!r||!r.established||t.terminalId!==r.identity.terminal_id)throw new Error("terminal transport ownership mismatch");return{frame:t,admission:{recovered:"terminal.resume"===t.type||this.manager.hasSessionAdmission(t.terminalId)}}}}}),this.server=createServer((e,t)=>{if("POST"===e.method&&"/terminal/status"===e.url)return void this.status(e,t);const r=this.authorized(e),s=r&&"/ready"===e.url&&this.ready;t.writeHead(r?s?200:503:401,{"Content-Type":"application/json"}),t.end(JSON.stringify(s?this.readiness():{ready:!1}))}),this.server.on("connection",e=>{this.sockets.add(e),e.on("error",()=>e.destroy()),e.once("end",()=>e.destroy()),e.once("close",()=>this.sockets.delete(e))}),this.server.on("upgrade",(e,t,r)=>{this.upgrade(e,t,r)})}readiness(){return{protocol_version:1,pty:!0,reconnect_window_seconds:this.registration.replayWindowSeconds}}async checkPty(){const e=this.manager.openSession({command:"/bin/sh",args:["-c","test -t 0 && test -t 1"],cols:80,rows:24});try{const t=await this.manager.waitForExit(e.terminalId,5e3);if("closed"!==t.state||0!==t.exitCode)throw new Error("native PTY probe failed")}finally{this.manager.release(e.terminalId)}}async listen(e=18802){return await this.checkPty(),await this.registration.start(),await new Promise((t,r)=>{this.server.once("error",r),this.server.listen(e,"127.0.0.1",()=>{this.server.off("error",r),t()})}),this.ready=!0,this.server.address().port}stop(){return this.stopping??=this.stopOnce()}async stopOnce(){this.ready=!1;const e=new Promise(e=>this.server.close(()=>e()));await this.registration.drain({timeoutMs:1e3,terminateAfterTimeout:!0});for(const e of this.sockets)e.destroy();await e,this.manager.destroy()}authorized(e){const t=Buffer.from(e.headers.authorization??""),r=Buffer.from("Bearer "+this.token);return t.length===r.length&&timingSafeEqual(t,r)}async status(e,t){const r=(e,r)=>{t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(r))};if(this.authorized(e))try{const t=[];let s=0;for await(const r of e){const e=Buffer.from(r);if(s+=e.length,s>16384)throw new Error("invalid identity");t.push(e)}const i=JSON.parse(Buffer.concat(t).toString());if("string"!=typeof i?.terminal_id||!i.terminal_id||"string"!=typeof i.client_id||!i.client_id)throw new Error("invalid identity");const n=this.manager.observeRetention(i.terminal_id,i.client_id),o=this.registration.replayObservation(i.terminal_id);r(200,{terminal_id:i.terminal_id,client_id:i.client_id,exists:n?.exists??!1,active:n?.active??!1,exited:n?.exited??!1,exit_code:n?.exitCode??null,retention_converged:n?.retentionConverged??!1,last_server_sequence:n?.lastServerSequence??"0",reconnect_deadline:n&&null!==o.deadline?new Date(o.deadline).toISOString():null,reconnect_window_seconds:o.windowSeconds})}catch{r(400,{error_code:"invalid"})}else r(401,{error_code:"authority_denied"})}upgrade(e,t,r){const s=Number(e.headers["content-length"]);if(!this.ready||!this.authorized(e)||"POST"!==e.method||"/terminal/protocol"!==e.url||"beeos-sandbox-stream"!==e.headers.upgrade||!Number.isInteger(s)||s<2||s>16384||e.headers["transfer-encoding"])return void t.end("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");let i,n=Buffer.alloc(0);const o=e=>{if(i)try{i.push(e)}catch{t.destroy()}else if(n=Buffer.concat([n,e]),!(n.length<s)){t.off("data",o),t.setTimeout(0);try{const e=JSON.parse(n.subarray(0,s).toString());if(!e||"string"!=typeof e.ticket_id||!e.ticket_id||"string"!=typeof e.client_id||"string"!=typeof e.terminal_id||"boolean"!=typeof e.resume||this.transport.routes.has(e.client_id))throw new Error("invalid or duplicate Runtime terminal route");if(!e.resume&&[...this.transport.routes.values()].some(t=>t.identity.terminal_id===e.terminal_id))throw new Error("terminal route already active");const r={identity:e,socket:t,established:!1};this.transport.routes.set(e.client_id,r),t.once("close",()=>{this.transport.routes.get(e.client_id)===r&&this.transport.routes.delete(e.client_id)});const o=new TerminalJSONStream(t=>{const s=JSON.parse(t);if(assertTerminalClientFrame(s),this.transport.routes.get(e.client_id)!==r||s.clientId!==e.client_id||s.terminalId!==e.terminal_id)throw new Error("terminal transport ownership changed");if(r.established){if(["terminal.open","terminal.resume","terminal.create"].includes(s.type))throw new Error("terminal transport already established")}else{if(e.resume?"terminal.resume"!==s.type||s.lastServerSequence!==e.last_server_sequence:"terminal.open"!==s.type||s.columns!==e.cols||s.rows!==e.rows)throw new Error("first terminal frame differs from Runtime identity");if(e.resume)for(const t of this.transport.routes.values())t!==r&&t.identity.terminal_id===e.terminal_id&&t.socket.destroy();r.established=!0}this.transport.emit("message",t)});i=o,t.on("data",e=>{try{o.push(e)}catch{t.destroy()}}),t.write("HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: beeos-sandbox-stream\r\n\r\n"),o.push(n.subarray(s))}catch{t.destroy()}}};t.setTimeout(5e3,()=>t.destroy()),t.on("data",o);const a=e.read();a&&o(a),o(r),e.on("data",o),t.resume()}}async function main(){const e=process.argv.includes("--check-pty");let t="probe-only";if(!e){const e=process.env.BEEOS_SANDBOX_TERMINAL_TOKEN_FILE;if(!e)throw new Error("terminal token file is required");const r=statSync(e);if(!r.isFile()||0!==r.uid||63&r.mode)throw new Error("terminal token must be root-private");t=readFileSync(e,"utf8").trim()}if(0===process.getuid?.()&&(process.setgroups([1002]),process.setgid(1001),process.setuid(1001)),1001!==process.getuid?.())throw new Error("standalone Terminal requires terminal UID 1001");process.umask(2),process.chdir("/workspace");const r=new StandaloneRuntimeTerminal(t);if(e)return await r.checkPty(),r.manager.destroy(),process.stdout.write(JSON.stringify(r.readiness())+"\n"),process.stdin.resume(),await new Promise(e=>process.stdin.once("end",e)),void process.stdin.pause();await r.listen();const s=()=>{r.stop().then(()=>{process.exitCode=0})};process.once("SIGTERM",s),process.once("SIGINT",s)}process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href&&main().catch(()=>{process.exitCode=1});
@@ -1 +1 @@
1
- import{prepareNativeOutputTool,nativeHtmlDeliveryForRun}from"../runtime/native-output-file-attempt.js";import{RENDER_UI_TOOL_NAME}from"../canvas/tools.js";import{BEEOS_FETCH_FILE_TOOL_NAME}from"../files/fetch-tool.js";import{BEEOS_UPLOAD_TOOL_NAME}from"./tool.js";export function needsNativeOutputCapability(t,o){return t===BEEOS_UPLOAD_TOOL_NAME||t===BEEOS_FETCH_FILE_TOOL_NAME||t===RENDER_UI_TOOL_NAME&&Object.prototype.hasOwnProperty.call(o,"html")}export function nativeOutputToolCallGate(t,o){if(needsNativeOutputCapability(t.toolName,t.params)){if(t.runId&&o.runId&&t.runId!==o.runId||t.toolCallId&&o.toolCallId&&t.toolCallId!==o.toolCallId)return{block:!0,blockReason:"native output file Host correlation conflict"};try{const e=t.runId??o.runId;if(t.toolName===RENDER_UI_TOOL_NAME&&nativeHtmlDeliveryForRun(e)?.publishedFileId)return{block:!0,blockReason:"The HTML file for this reply is already published. Use that result; do not generate or upload another copy."};prepareNativeOutputTool(e,t.toolCallId??o.toolCallId)}catch{return{block:!0,blockReason:"native output file trusted capability unavailable"}}}}
1
+ import{prepareNativeOutputTool,nativeHtmlDeliveryForRun}from"../runtime/native-output-file-attempt.js";import{RENDER_UI_TOOL_NAME}from"../canvas/tools.js";import{BEEOS_FETCH_FILE_TOOL_NAME}from"../files/fetch-tool.js";import{BEEOS_UPLOAD_TOOL_NAME}from"./tool.js";export function needsNativeOutputCapability(t,o){return t===BEEOS_UPLOAD_TOOL_NAME||t===BEEOS_FETCH_FILE_TOOL_NAME||t===RENDER_UI_TOOL_NAME&&Object.prototype.hasOwnProperty.call(o,"html")}export function nativeOutputToolCallGate(t,o){if(needsNativeOutputCapability(t.toolName,t.params)){if(t.runId&&o.runId&&t.runId!==o.runId||t.toolCallId&&o.toolCallId&&t.toolCallId!==o.toolCallId)return{block:!0,blockReason:"native output file Host correlation conflict"};try{const e=t.runId??o.runId;if(nativeHtmlDeliveryForRun(e)?.observeAttempt(t.toolName,t.params),t.toolName===RENDER_UI_TOOL_NAME&&nativeHtmlDeliveryForRun(e)?.publishedFileId)return{block:!0,blockReason:"The HTML file for this reply is already published. Use that result; do not generate or upload another copy."};prepareNativeOutputTool(e,t.toolCallId??o.toolCallId)}catch{return{block:!0,blockReason:"native output file trusted capability unavailable"}}}}
@@ -2,7 +2,7 @@
2
2
  "id": "beeos-claw",
3
3
  "name": "beeos-claw",
4
4
  "description": "BeeOS platform bridge plugin for OpenClaw. Provides file upload/download, ACP bridge, and observability.",
5
- "version": "0.6.48-staging.1",
5
+ "version": "0.6.91",
6
6
  "activation": {
7
7
  "onStartup": true
8
8
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beeos-claw",
3
- "version": "0.6.88",
3
+ "version": "0.6.92",
4
4
  "description": "OpenClaw plugin that bridges the BeeOS platform with the local OpenClaw Gateway, providing file transfer, ACP bridge, and observability.",
5
5
  "license": "MIT",
6
6
  "author": "BeeOS <dev@beeos.ai>",
@@ -66,9 +66,9 @@
66
66
  "test:watch": "vitest"
67
67
  },
68
68
  "dependencies": {
69
- "@beeos-ai/beeos-types": "4.5.2-cloud.1",
69
+ "@beeos-ai/beeos-types": "4.5.2-cloud.2",
70
70
  "@beeos-ai/bridge-client": "^0.1.0",
71
- "@beeos-ai/cloud-harness-sdk": "1.0.0-cloud.7",
71
+ "@beeos-ai/cloud-harness-sdk": "1.0.1-cloud.1",
72
72
  "@beeos-ai/message-sdk": "2.0.16",
73
73
  "@modelcontextprotocol/sdk": "^1.29.0",
74
74
  "adm-zip": "0.6.1",
@@ -90,5 +90,5 @@
90
90
  "brace-expansion": ">=5.0.9",
91
91
  "@beeos-ai/beeos-types": "$@beeos-ai/beeos-types"
92
92
  },
93
- "gitHead": "9633df17d996bb9ae185f3c181f1273043395104"
93
+ "gitHead": "11274ec6ff443e3ce83e46865be0daee310e546a"
94
94
  }
@@ -4,7 +4,7 @@
4
4
  "hashAlgorithm": "SHA-256",
5
5
  "canonicalTypes": {
6
6
  "package": "@beeos-ai/beeos-types",
7
- "version": "4.4.2-cloud.7",
7
+ "version": "4.5.2-cloud.2",
8
8
  "runtimeRpcContractRevision": "2026-07-14.3",
9
9
  "runtimeMethodManifestRawSHA256": "9e33be754abb221cba4e4cd03eb760a170865248952346afd461427abd2cfaad",
10
10
  "runtimeMethodManifestJcsSHA256": "48f1a86987e1035e5f748f5f2e74fb6a56a8eb85257a808b478c0827a8509731"