@heybox/hb-sdk API Reference - v0.9.5
    正在准备搜索索引...

    接口 CompanionStdio

    Companion 的标准输入输出能力。

    仅当 Manifest 声明 stdio 且当前 Host 返回该能力时存在。传输的是原始字节, 不保证一次 write 对应一次 stdout/stderr 回调;业务协议必须自行处理 framing、拆包和重复。

    interface CompanionStdio {
        closeStdin(): Promise<void>;
        onStderr(handler: CompanionOutputHandler): () => void;
        onStdout(handler: CompanionOutputHandler): () => void;
        write(data: Uint8Array): Promise<void>;
    }
    索引

    方法

    • 不可逆地关闭当前 Companion Session 的 stdin 写入端。

      返回 Promise<void>

      当前 controller 对应的 Host 确认 stdin close 请求完成后以 undefined resolve。该时点只 表示输入半关闭已由 Host 接受,不返回退出码,不等待 Companion 消费完先前输入、stdout/stderr 排空或进程退出;使用 waitForExit() 等待进程终态。

      HbMiniProgramSDKError 当前 proxy 已知 Session 已退出时返回 COMPANION_SESSION_EXITED;controller 已转移给其他 Runtime generation 时返回 COMPANION_SESSION_OWNERSHIP_LOST。本地检查与 Host 执行之间仍存在竞态,Host 会用私有 controller generation 再次拒绝过期调用。

      HbMiniProgramSDKError stdin 已关闭、Session 不再提供 stdio 或通信管道不可用时 可返回 COMPANION_PIPE_CLOSED;进程异常退出或因输出上限结束时还可能返回 COMPANION_PROCESS_CRASHED / COMPANION_OUTPUT_LIMIT。

      HbMiniProgramSDKError 当前运行快照缺少或未启用 companion 权限时返回 PERMISSION_NOT_IN_SNAPSHOT / PERMISSION_DENIED;Host 未开放 companion.session.closeStdin 时返回 METHOD_FORBIDDEN,旧 Runtime 可返回 METHOD_NOT_FOUND。 未识别的 Host 失败会脱敏为 COMPANION_HOST_FAILED;SDK / Runtime 终止、不可用或请求超时还 可能返回 SDK_DESTROYED、RUNTIME_UNAVAILABLE、REQUEST_TIMEOUT。

      closeStdin() 是一次性的输入半关闭,不是 flush、取消、terminate() 或“请求进程退出”的别名。成功后不能重新打开 stdin,后续 write() 会失败;但 Companion 仍可继续运行、处理已经收到的字节并产生 stdout/stderr,Session 的 state 也会保持 'running',直到 Host 发送独立退出事件。

      SDK 不维护公开的 stdinClosed 状态,也不会合并或短路重复调用;每次调用都会携带当前私有 controller generation 发往 Host。重复关闭不属于公共幂等保证:不同 Host 可能重复确认,也可能 返回 COMPANION_PIPE_CLOSED。业务应只关闭一次;若请求失败或超时,Host 是否已经完成关闭可能 无法从该错误判断,不要无条件自动重试。

      SDK 不会在 write() 与 closeStdin() 之间建立队列。要发送最后一帧, 应先逐次 await 所有 write,再调用一次 close;并发调用会产生由实际请求到达顺序决定的竞态, 最后的 write 可能因管道已关闭而失败。空 Uint8Array 写入也不是 EOF,只有本方法表达 stdin EOF。

      该调用要求 Session 快照包含 'stdio'(否则 session.stdio 为 undefined)、进程尚未退出,且当前 Runtime generation 仍持有 controller。session.state === 'running' 本身不能证明仍有控制权;应监听 onOwnershipLost() 并立即停止新的 write/close 操作。失去 controller 或关闭 stdin 都不会让 waitForExit() 提前完成; 后者仍绑定同一个进程的真实退出事件。

      该方法属于已声明并经平台批准的 companion 高风险能力,不要求新的可信用户手势。V1 真实 Companion stdio 仅支持新 PC Host 的 Windows x64 与 macOS arm64;Browser Dev Host 提供确定性 Fake,其他平台、旧 Host 或 operation 缺失时 fail closed,不提供 WebSocket、worker 或 shell fallback。

      import hbSDK from '@heybox/hb-sdk'

      const session = await hbSDK.companion.getActiveSession('runner')
      const stdio = session?.stdio
      if (session && stdio) {
      const stopStdout = stdio.onStdout(chunk => consumeBusinessFrames(chunk))
      const stopStderr = stdio.onStderr(chunk => appendDiagnosticBytes(chunk))

      try {
      await stdio.write(encodeBusinessFrame({ type: 'finish' }))
      await stdio.closeStdin() // 只调用一次,并且在最后一次 write 完成之后。

      // stdin 已关闭后输出仍可能继续;进程终态以 waitForExit() 为准。
      const exit = await session.waitForExit()
      console.log(exit)
      } finally {
      stopStdout()
      stopStderr()
      }
      }
    • 订阅当前 Companion Session 的 stderr 原始字节流。

      参数

      • handler: CompanionOutputHandler

        每个新 stderr chunk 到达时同步调用的处理函数。参数是 SDK 为当前 handler 单独复制的 Uint8Array;修改它不会改变 Host payload,也不会影响同一事件的其他 handler。

      返回 () => void

      取消当前 handler 的同步函数。可调用一次或多次;取消后不再接收未来 chunk,不会关闭 stderr、stdin 或 Session,也不会取消其他 handler。相同函数引用重复订阅按 Set 语义只保留一项, 任一对应取消函数都会移除该项。

      HbMiniProgramSDKError handler 不是函数时同步抛出 INVALID_PARAMS。订阅本身不发送 bridge 请求,因此不会因权限、Host operation、Session 退出或 controller ownership 状态异步拒绝。

      session.stdio 只在 Session capability 集合包含 'stdio' 时存在;调用前必须先判空。取得 Session 仍受已声明并经平台批准的 companion 权限、当前版本产物和 Host 支持约束,但本地注册 handler 不要求新的可信用户手势,也不重新校验权限。Host 没有 Session event source 的兼容集成 即使返回了 stdio,订阅也只是成功注册本地 handler,之后不会收到输出事件;它不会轮询、报错或 从 write() 响应中推导 stderr。

      stderr 与 onStdout() 使用相同的原始字节与去重合同, 但两条流的订阅和去重相互独立。字节不会自动按 UTF-8、换行、JSON 或消息边界解码;一个逻辑 诊断可能被拆到多个 chunk,一个 chunk 也可能含多条诊断。stderr 是 Companion 进程的第二输出流, 收到数据不等于进程失败,退出结果应通过 CompanionSession.waitForExit 或 CompanionSession.onExit 判断。

      SDK 会在当前 controller 内抑制本流已见或倒退的输出,但 Host 输出仍是 at-least-once。 业务跨 controller 转移、页面 reload 或重连后,应按自己的 framing / 消息 ID 处理重放和去重。

      handler 按注册集合顺序同步执行,返回值会被忽略,Promise 不会被等待。每个 handler 的同步异常 都被 SDK 单独捕获,不会阻断同一 chunk 的其他 handler;异步 handler 的 rejected Promise 不会被 SDK 捕获,应在 handler 内显式处理。订阅不会重放注册前的 stderr,也不能读取历史缓冲区。

      Session 退出后,SDK 会清空 stdout/stderr handler;已有取消函数仍可安全调用。controller ownership 丢失后,旧 generation 的输出被忽略且不会确认,已有订阅不会因此收到错误或自动取消;调用方应同时 监听 CompanionSession.onOwnershipLost 并停止依赖旧 controller。之后通过 companion.getActiveSession 取得同一 Session 的 新 controller generation 时,SDK 会重置两条流的 sequence 水位,当前 proxy 上尚未取消的 handler 可以继续接收新 generation 输出。其他 Session ID、非法字节、非法 sequence、generation 不匹配以及 已退出 Session 的事件都会被丢弃。

      write() 只向 stdin 写入原始字节,不保证产生 stderr,也不保证一次 write 对应一次回调。需要捕获启动后的早期诊断时,应在 write 前订阅,并在 Session 退出或页面销毁 时调用取消函数。V1 真实 Companion stdio 仅支持新 PC Host 的 Windows x64 与 macOS arm64; Browser Dev Host 的确定性 Fake 只用于联调,不能替代真实进程验收。

      import hbSDK from '@heybox/hb-sdk'

      const session = await hbSDK.companion.getActiveSession('runner')
      if (session?.stdio) {
      const decoder = new TextDecoder()
      const stopStderr = session.stdio.onStderr(bytes => {
      // stream: true 保留跨 chunk 的 UTF-8 解码状态;协议 framing 仍需业务自行处理。
      appendDiagnosticText(decoder.decode(bytes, { stream: true }))
      })
      const stopOwnership = session.onOwnershipLost(() => {
      disableCompanionControls()
      })

      try {
      await session.stdio.write(encodeBusinessFrame({ type: 'status' }))
      await session.waitForExit()
      appendDiagnosticText(decoder.decode())
      } finally {
      stopStderr()
      stopOwnership()
      }
      }
    • 订阅当前 Companion Session 的 stdout 原始字节 chunk。

      参数

      返回 () => void

      同步返回取消订阅函数。调用后只移除当前 SDK proxy 上的本地 handler,不关闭 stdout、 不发送 Host unsubscribe、不关闭 stdin,也不终止 Session。重复调用取消函数安全且不会抛错。

      HbMiniProgramSDKError handler 不是函数时同步抛出 INVALID_PARAMS。订阅本身 不发 bridge 请求,因此不会因权限、ownership、Session 已退出或 Host event source 缺失而拒绝。

      该方法只在 session.stdio 存在时可调用;stdio 是否存在由 Session 快照的 capabilities 是否包含 'stdio' 决定。没有该 capability 时整个 session.stdio 为 undefined,调用方必须先分支。注册不要求新的可信用户手势,也不额外请求权限;Session 后续 仍可能因权限撤销、进程退出或 controller 转移而停止投递。

      stdout 是原始 byte stream,不是一次 write() 对应一次回调的消息 通道。SDK 不定义字符编码,也不保证 chunk 与换行、JSON、RPC frame 或业务消息对齐;业务必须 自行处理拆包、粘包和 framing。handler 每次收到独立的新 Uint8Array 副本,同一事件的其他 handler 也收到各自副本,因此一个 handler 修改 bytes 不会污染另一个 handler。

      Host 输出按 at-least-once 语义投递。SDK 会在当前 controller 内抑制同一流已见或倒退的输出, 但重新取得控制、页面 reload 或业务重连后仍可能收到重放。业务 frame 应携带自己的幂等 ID, 不能把 SDK 的局部去重当作端到端 exactly-once 保证。

      handler 的同步异常会被隔离:其他 stdout handler 仍会收到同一 chunk。 SDK 忽略 handler 返回值且不会 await Promise;若传入 async 函数,需在函数内部处理 rejected Promise。取消函数仅影响未来本地分发,已经开始执行的回调不会被中断。

      订阅没有历史回放或本地缓冲。事件到达时即使没有 handler,SDK 仍可确认并丢弃该 chunk,之后 注册不会补发;应在调用 write() 或触发 Companion 输出之前订阅。Session exit 会清除当前已 注册的 stdout/stderr handlers,退出后不会再投递。调用取消函数后 Host 仍可继续产生输出并由 SDK 内部确认,取消订阅不能用于流控或阻止 Companion 达到输出上限。

      ownership 丢失时,旧 proxy 不再分发旧 controller generation 的 output。调用 companion.getActiveSession 取得同一 Session 的更新 controller 后,SDK 会复用同一 proxy,保留已注册 handler,并为新 generation 重置 stdout/stderr sequence 去重状态;业务仍需处理 Host 重放。若不希望恢复后继续接收,应在 onOwnershipLost() 中调用本方法返回的取消函数。

      自定义 Host 若未提供 Session 事件源,本方法仍可注册,但不会收到输出、退出或 ownership 事件,也没有轮询 fallback。Mini-program 不能把注册成功当作事件源可用的保证。

      V1 真实 Companion stdio 仅支持新 PC Host 的 Windows x64 与 macOS arm64;Browser Dev Host 提供确定性 Fake 以验证字节流、framing 和错误 UI,不执行真实程序。其他平台、旧 Host 或 未开放 Companion 的环境不会提供可用 Session stdio。

      import hbSDK from '@heybox/hb-sdk'

      const session = await hbSDK.companion.getActiveSession('runner')
      const stdio = session?.stdio

      if (session && stdio) {
      // 仅当 Companion 业务协议规定 stdout 是 UTF-8 行文本时这样解码。
      const decoder = new TextDecoder()
      let pending = ''

      const stopStdout = stdio.onStdout(bytes => {
      pending += decoder.decode(bytes, { stream: true })
      const lines = pending.split('\n')
      pending = lines.pop() ?? ''
      for (const line of lines) console.log(line)
      })
      const stopOwnership = session.onOwnershipLost(stopStdout)

      session.onExit(() => {
      pending += decoder.decode()
      if (pending) console.log(pending)
      stopStdout()
      stopOwnership()
      })
      }

      0.8.1

      windows

      macos

      windows none

      macos none

    • 向当前 Companion Session 的 stdin 写入原始字节。

      参数

      • data: Uint8Array

        要写入的 Uint8Array。SDK 只复制当前 view 覆盖的字节区间;byteOffset 之外的 backing buffer 内容不会发送。空 Uint8Array 合法并会交给 Host,但不应把空写入当作 flush、 EOF 或消息分隔符。

      返回 Promise<void>

      Host 确认本次 stdin 写入请求完成后以 undefined resolve。该时点不返回写入字节数, 也不表示 Companion 已读取、解析或处理数据,更不保证会产生 stdout/stderr。

      HbMiniProgramSDKError data 不是当前 realm 的 ArrayBuffer-backed Uint8Array, 或使用 SharedArrayBuffer backing 时,在发送 bridge 请求前返回 INVALID_PARAMS。普通数组、 ArrayBuffer、DataView、其他 typed array 也不会被隐式转换。

      HbMiniProgramSDKError 当前 proxy 已知 Session 已退出时返回 COMPANION_SESSION_EXITED;controller 已转移给其他 Runtime generation 时返回 COMPANION_SESSION_OWNERSHIP_LOST。检查与 Host 写入之间仍存在竞态,Host 会用私有 controller generation 再次拒绝过期调用。

      HbMiniProgramSDKError stdin 已由 closeStdin() 关闭、Session 不再提供 stdio 或通信管道不可用时返回 COMPANION_PIPE_CLOSED;进程异常退出 或因输出上限结束时还可能返回 COMPANION_PROCESS_CRASHED / COMPANION_OUTPUT_LIMIT。

      HbMiniProgramSDKError 当前运行快照缺少或未启用 companion 权限时返回 PERMISSION_NOT_IN_SNAPSHOT / PERMISSION_DENIED;Host 未开放 companion.session.write 时返回 METHOD_FORBIDDEN,旧 Runtime 可返回 METHOD_NOT_FOUND。未知 Host 失败会脱敏并返回 COMPANION_HOST_FAILED;SDK/Runtime 终止或请求超时还可能返回 SDK_DESTROYED、 RUNTIME_UNAVAILABLE、REQUEST_TIMEOUT。

      stdio 只在 Session 快照的 capability 集合包含 'stdio' 时存在;调用前必须按 session.stdio 是否存在分支。它是已声明并经平台批准的 companion 高风险能力的一部分, 不要求新的可信用户手势;但持有 CompanionStdio 对象不代表 controller、进程或管道之后一直有效。 session.state === 'running' 也不能证明当前 Runtime 仍持有 controller,因为 ownership 转移不会 结束进程。

      SDK 在调用时同步复制 data 的可见字节,Runtime 在调用 Host 前再制作一份副本;调用返回后修改 原数组或 backing buffer 不会改变本次 payload。两层都只接受普通 ArrayBuffer backing,拒绝 SharedArrayBuffer,因此该 API 不建立跨 bridge 共享内存。SDK 没有公开 stdin 单次写入大小上限, 也不会自动分块;实际可接受大小仍受 Host、IPC 和操作系统管道限制,不能据此假定无限写入。

      字节不会经过 UTF-8 解码、换行处理、JSON 序列化或其他内容转换。stdin 是 byte stream,不保留 JavaScript write() 调用边界:一次写入可被 Companion 分段读取,多次写入也可被合并。业务必须 自己定义长度前缀、转义或其他 framing,并在需要确定顺序时逐次 await,不要并发写入后依赖完成顺序。

      onStdout() 和 onStderr() 是独立的 异步输出流;单次写入可能对应零个、一个或多个输出 chunk,输出也可能在本 Promise settle 前后到达。 应在写入前订阅,并让业务 framing 自带关联 ID。Host 输出采用 at-least-once 投递;SDK 会在同一 controller generation 内按 stream sequence 抑制已见 replay 并确认它,但 controller 转移、页面 reload 或业务重连后仍应自行处理重放和去重。

      closeStdin() 是不可逆的输入半关闭,不等于终止 Session;关闭后 stdout/stderr 和退出事件仍可继续。 应先依次 await 所有业务帧写入,再关闭 stdin;不要让 write() 与 closeStdin() 并发竞态。失去 controller 后不要自动重试不确定是否已提交的写入,否则可能向进程重复发送业务命令。需要明确恢复控制时, 由业务调用 companion.getActiveSession,再按自己的 幂等协议决定是否重发。

      V1 真实 Companion stdio 仅支持新 PC Host 的 Windows x64 与 macOS arm64;Browser Dev Host 提供确定性 Fake 用于验证 framing、输出和错误 UI,不执行真实程序。其他平台、旧 Host 或缺少 companion.session.write operation 时 fail closed,不提供 WebSocket、worker 或 shell fallback。

      import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'

      const session = await hbSDK.companion.getActiveSession('runner')
      const stdio = session?.stdio
      if (session && stdio) {
      const stopStdout = stdio.onStdout(chunk => consumeBusinessFrames(chunk))
      const stopStderr = stdio.onStderr(chunk => appendDiagnosticBytes(chunk))
      const stopOwnership = session.onOwnershipLost(() => disableCompanionControls())

      try {
      // encodeBusinessFrame 自行添加长度、消息 ID 等业务 framing。
      await stdio.write(encodeBusinessFrame({ id: 'status-1', type: 'status' }))
      await stdio.closeStdin()
      await session.waitForExit() // 保留输出订阅,直到进程结束。
      } catch (error) {
      if (
      error instanceof HbMiniProgramSDKError &&
      (error.code === 'COMPANION_PIPE_CLOSED' || error.code === 'COMPANION_SESSION_OWNERSHIP_LOST')
      ) {
      disableCompanionControls()
      } else {
      throw error
      }
      } finally {
      stopStdout()
      stopStderr()
      stopOwnership()
      }
      }

      0.8.1

      windows

      macos

      windows none

      macos none