61 lines
3.9 KiB
Markdown
61 lines
3.9 KiB
Markdown
# 02 — Lua client (`trapos-sandbox`)
|
|
|
|
> Sub-plan of [trap-sandbox-gateway-spec](./trap-sandbox-gateway-spec.md). Implements the
|
|
> **Protocol**, **Handshake**, and **os-event contract** from the spec — reference them, don't
|
|
> redefine. M2; depends on the protocol contract (not on M1 code existing).
|
|
|
|
## Scope
|
|
The Lua side: `apis/libsandbox.lua`, `servers/sandbox.lua`, `programs/sandbox.lua`, and Lua **unit**
|
|
tests. Package/meta changes are [03-packages](./03-packages.md); integration/e2e is
|
|
[04-integration-tooling](./04-integration-tooling.md).
|
|
|
|
## Task checklist
|
|
- [ ] `apis/libsandbox.lua` (template: `apis/libmcpcomputer.lua`).
|
|
- [ ] `servers/sandbox.lua` (template: `servers/mcp-computer-server.lua`).
|
|
- [ ] `programs/sandbox.lua` (template: `programs/ai.lua`).
|
|
- [ ] Lua unit tests (`tests/sandbox.lua`).
|
|
- [ ] Gate: `just _craftos-test` runs `tests/sandbox.lua` green.
|
|
|
|
## `apis/libsandbox.lua` — template: `apis/libmcpcomputer.lua`
|
|
`createSandbox()` returns:
|
|
- `traposId(osLike)` → `id .. ":" .. (label or "")`.
|
|
- Envelope builders for the 4 events + hello. **Every `computer_request` (including `hello`) must
|
|
carry a non-empty `traposSenderId` = the computer's `traposId`** — the TS gateway's zod schema
|
|
requires it (decided in the 01-ts-gateway grill). The `hello` identity used for registration is
|
|
still `payload.traposId`, but the envelope `traposSenderId` must also be present.
|
|
- `onMessage(content, …)`: decode (pcall); `gateway_request`→ built-in `ping` (else
|
|
`ok:false unknown_type`) replied as `computer_response` via pcall-send; `gateway_response`→ if
|
|
`type=="hello"` drive the handshake state, else `queueEvent('trapos_sandbox_reply', messageId, ok,
|
|
payload, error)`.
|
|
- `startSession(opts)` (daemon; injectable `http`/`eventloop`/`encode`/`decode`/`os`): builds the
|
|
connect URL from base `opts.url`, computes `traposId`; `websocketAsync`; on `websocket_success`
|
|
send hello; on hello `ok:true` set state=ready + `queueEvent('trapos_sandbox_connected', traposId)`;
|
|
on hello `ok:false` set state=unauthorized (**terminal**, store `lastError`, close, no reconnect);
|
|
on `websocket_failure`/`_closed` reconnect via `el.setTimeout(connect, 5)` (unless unauthorized);
|
|
hello with no ack in ~10s → close + reconnect; `trapos_sandbox_send` handler builds
|
|
`computer_request`, **pcall-send** only when ready, else fast `trapos_sandbox_reply(messageId,
|
|
false, nil, {code:"not_connected"})`. Returns `{ isReady, lastError }`.
|
|
- `request(type, payload, opts)` (injectable `queueEvent`/`pullEvent`/`startTimer`): mint messageId,
|
|
queue `trapos_sandbox_send`, wait for matching `trapos_sandbox_reply` vs a timer (**default 10s**,
|
|
overridable). Returns `(ok, payloadOrError)`.
|
|
|
|
## `servers/sandbox.lua` — template: `servers/mcp-computer-server.lua`
|
|
Read `sandbox.url` (unset/`http.websocket` missing → "daemon inactive", return) and `sandbox.password`;
|
|
`startSession{ eventloop=_G.bootEventLoop, url, password(secret), os }`; print version.
|
|
|
|
## `programs/sandbox.lua` — template: `programs/ai.lua`
|
|
- Reads `sandbox.url` first; unset → immediate `set sandbox.url first` (no 10s wait).
|
|
- `health` command → `request('probe_gateway')` (wire `type` renamed from `health` during the
|
|
01-ts-gateway grill; the in-game command name stays `health`); print `sandboxOk`/`opencodeOk`
|
|
(+ `opencode: <detail>` when false); on `not ok` print `sandbox health failed: <code> <message>`
|
|
(e.g. `unauthorized`, `not_connected`, `timeout`).
|
|
- `--version` / `--help`.
|
|
|
|
## Lua unit tests (`tests/sandbox.lua`, libtest + fakes)
|
|
Envelope builders, `traposId`, `onMessage` dispatch (ping ok / unknown_type / hello), empty-payload
|
|
coercion, `startSession` wiring (fake eventloop+http: hello sent on open, ready on ack, terminal on
|
|
unauthorized, reconnect on drop), `request()` resolve + timeout via injected event primitives.
|
|
|
|
## Verification gate
|
|
`just _craftos-test` runs the new `tests/sandbox.lua` green.
|