Phase 10: nodes connect to the hub #18
Loading…
Reference in a new issue
No description provided.
Delete branch "refactor/phase-10-nodes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 10: nodes connect to the hub
A second machine runs
kanbot-node, connects to the hub, and runs agents on its own projects. The hub decides everything as before; the node runs the model and does the git and folder work where the files are.How it works
/api/nodes/wsand servesNodeRpcs(packages/contracts/src/nodes) on it:Node.hello,NodeSessions.*,NodeWorkspace.*. The hub is the RPC client.ToolCall/GateRequest/AskRequestmessages the hub answers withNodeSessions.reply.unreachableand keeps its slot. After a 10-minute lease it islost, and resumes by its external id once the node is back.MachineRuntimes.for(machineId, type)gives the local plugins on the hub and aRemoteRuntimeon a node.MachineWorkspaces.for(node)is a remote adapter.node, device id, last seen),onlinewhile linked, and shown with a dot on the machine badge.Projects.createtakes an optionalmachineId.npm run build:node→.output/node/index.mjs), with no Kanbot database.kanbot-node pair <hub> <code>stores its token innode.json(0600, written atomically).Security
Two adversarial review rounds; 17 findings, all fixed with a test each:
/api/nodes/ws(dot-segment bypasses closed), 8 MiB frames.O_NOFOLLOWand an inode re-check.kanbot-nodeas a dedicated user).Also in this branch
@in the catalogues, with a compile test. Component tests read the catalogue's text.surface, so it no longer reaches the database by itself.0021_node_machines(machines.device_id).Checks
npm run lint,npm run typecheck,npx vitest run: 1254 passed, 1 skipped, twice.kill -9makes it unavailable, and a restart brings it back.Not done / next
nuxt devcan crash when a client resets a proxied WebSocket. This predates these changes.Base:
refactor/phase-9-auth(PR #17).🤖 Generated with Claude Code
Any code from Settings › Devices could pair a node, so a code offered for someone's phone could become a node the hub sends prompts to. An offer is now for a node or, by default, for a browser or a script (Devices.offerPairing takes an optional { kind }; no payload still works), and redeeming it as the other kind fails like a wrong code (it counts towards burning it; every failure is the same PairingRefused / 401). Settings › Devices' pairing card has a "For a node" switch: it asks for a node's code and shows the kanbot-node pair command to run there instead of the address and QR code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>A code offered for a desktop (Devices.offerPairing({ kind: 'desktop' })) pairs two devices in one transaction: the window's browser device (its token is the kanbot_device cookie, Secure over HTTPS) and the node it runs (its token in the answer: { deviceId, nodeDeviceId, nodeToken }). devices.companion_id (migration 0022) points each at the other. Revoking either revokes both and cuts both off. A code for another kind fails like a wrong one. Settings › Devices offers the three kinds and shows a desktop as one entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>Over the utility process's parent port ({ type: 'kanbot-shell', action: 'open-connect' }), only from the desktop app's own window (a Local caller) and only when the shell started the server to talk over that port; anything else is ShellUnavailable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>