The server sibling is running, but not yet replaceable
@smolpaws/openhands-agent-server is the missing server-side companion to @smolpaws/openhands-agent. The merged slice proves the core REST, WebSocket, bash, git, file, persistence, and sibling-SDK paths. Replaceability now depends on fixing package integrity, CI, background run semantics, and contract fidelity.
@smolpaws/openhands-agent1Replaceability is a two-package boundary
@smolpaws/openhands-agentAgent, tools, workspace, event schemas, RemoteConversation and RemoteWorkspace. See the counterpart page above.
@smolpaws/openhands-agent-serverFastify REST and sockets on top of the SDK. Pinned against OpenHands commit 9663409.
/run.Evidence: README status and route-family scope at README.md:7-52; app route registration at src/app.ts:30-64.
2The first slice does real work end-to-end
The merged package is not just a scaffold. Live testing exercised a real TCP Fastify server, WebSocket replay, bash execution, git/file endpoints, persistence, and the sibling SDK clients.
| Surface | Status | Grounding |
|---|---|---|
| Conversations and events | working start, search, get, update, delete, fork, append, search, count, batch, final response. | conversationRouter.ts · eventRouter.ts |
| SDK agent execution | working injected @smolpaws/openhands-agent agents run and publish events. | eventService.ts:206-229 |
| Bash, git, file | working with gaps live smoke passed for canonical paths and root-contained files. | bashRouter.ts · gitService.ts:13-66 |
| WebSockets | working with auth gap event and bash replay work; first-frame auth is missing. | sockets.ts:18-96 |
| OpenAPI | generated deterministic Zod-backed schema at /openapi.json, but parameter fidelity needs work. | openapi.ts:75-155 |
RemoteConversation and RemoteWorkspace can already talk to this server in a live smoke. The remaining work is not a rewrite; it is hardening the replacement boundary.3The defects are inside the claimed slice
These are the problems that block the implemented slice from being safely replaceable. Separately, skills/settings/profiles/agent-profiles are now required route-family work, while ACP, confirmation, security analyzers, and deferred init are not wanted.
| Priority | Defect | Why it matters | Bead |
|---|---|---|---|
| P0 | Published declarations point at missing dist/index.d.ts. | Consumers get TS7016 and lose typed imports after npm pack. | smolpaws-b1r.1 |
| P0 | SDK dependency is file:../../../openhands-agent. | Fresh standalone installs and tarball consumers break without a sibling checkout. | smolpaws-b1r.2 |
| P0 | CI does not run this package. | The PR can be green while the package cannot build, test, pack, or import. | smolpaws-b1r.3 |
| P0 | POST /run is synchronous from the caller perspective. | Upstream schedules background work; this route awaits the full agent run, so long LLM/tool runs hold HTTP open. | smolpaws-b1r.4 |
| P1 | First-message WebSocket auth is absent. | Upstream accepts an auth frame after open; TypeScript closes with code 1008 unless query/header auth is present. | smolpaws-b1r.5 |
| P1 | OpenAPI omits real params and multipart details. | Generated clients would miss query filters, upload bodies, and correct optional defaults. | smolpaws-b1r.6 |
| P1 | Bash batch path mismatch. | Spec says /api/bash/bash_events; runtime route is trailing-slash only. | smolpaws-b1r.7 |
| P1 | Git path aliases fail on macOS. | /var vs /private/var can make a repo look outside itself. | smolpaws-b1r.8 |
/run issue is a semantic mismatch, not just a performance nit. eventService.ts:125-134 stores runPromise and then awaits it before the route can return.4OpenAPI is the contract gate
The page count is not the goal by itself. The goal is a contract that generated clients and SmolPaws ingress code can trust.
9663409.routeSpecs.| OpenAPI concern | Current shape | Fix direction |
|---|---|---|
| Request schemas | Defaulted Zod fields appear required because schemas are emitted in output mode. | Use input-mode JSON schema for request bodies. |
| Query parameters | Route specs only infer path params; search/count/git/file query params are not listed. | Add explicit query/header/multipart parameter metadata to RouteSpec. |
| Upload body | /api/file/upload exists at runtime but no multipart body is documented. | Emit multipart/form-data schema and keep text/raw compatibility if intended. |
| Status fidelity | Several upstream validation and error statuses are absent or intentionally changed. | Normalize and allowlist deviations in CI instead of eyeballing. |
| Generated artifact | openapi.json is generated locally but not CI-checked against pinned upstream. | Add reproducible generation and diff check for the implemented slice. |
Evidence: route specs at openapi.ts:75-128; schema assembly at openapi.ts:158-188.
5Beads created from the audit
The audit findings are now concrete Beads under one epic. Required route-family work is tracked separately from useful-later deferrals and not-wanted deviations.
| Bead | Priority | Title |
|---|---|---|
smolpaws-b1r | P0 | Reach replaceable TypeScript OpenHands agent-server parity |
smolpaws-b1r.1 | P0 | Fix openhands-agent-server published declaration entrypoint |
smolpaws-b1r.2 | P0 | Make openhands-agent-server SDK dependency reproducible |
smolpaws-b1r.3 | P0 | Add CI coverage for packages/openhands-agent-server |
smolpaws-b1r.4 | P0 | Make POST /api/conversations/:id/run non-blocking like upstream |
smolpaws-b1r.5 | P1 | Restore first-message WebSocket auth parity |
smolpaws-b1r.6 | P1 | Make OpenAPI faithful for the implemented agent-server slice |
smolpaws-b1r.7 | P1 | Fix bash batch route and OpenAPI trailing-slash mismatch |
smolpaws-b1r.8 | P1 | Canonicalize Git paths for macOS /var vs /private/var aliases |
smolpaws-b1r.9 | P1 | Persist live end-to-end tests for the TypeScript agent-server slice |
smolpaws-b1r.10 | P2 | Define deferred upstream route-family roadmap for replaceable server parity |
smolpaws-b1r.11 | P2 | Add conversation lease and multi-instance ownership safeguards |
smolpaws-b1r.12 | P2 | Implement conversation secrets with keychain-backed SecretStore only |
smolpaws-b1r.13 | P1 | Port skills router and service parity |
smolpaws-b1r.14 | P1 | Port settings routes with LLM-profile-first semantics |
smolpaws-b1r.15 | P1 | Port profiles and agent-profiles route families |
smolpaws-b1r.16 | P1 | Add manual LLM examples workflow for agent-server parity |
smolpaws-b1r.17 | P1 | Port remote agent-server example parity tests |
smolpaws-b1r.18 | P1 | Add root script to generate all OpenAPI artifacts |
6Next order toward a replaceable server
- Make the package consumable. Fix declaration output and SDK dependency strategy, then add a pack-consumer test.
- Gate it in CI. The package should not depend on manual local validation.
- Restore upstream run semantics.
/runshould acknowledge scheduling, while progress flows through polling or sockets. - Make the contract machine-checkable. Fix OpenAPI parameters, request mode, multipart, status sets, and add pinned comparison.
- Automate live smokes. Promote the REST, WebSocket, and sibling SDK tests from audit scripts into Vitest or a dedicated integration harness.
- Port required breadth red-green. Skills, settings, profiles, and agent-profiles are required. ACP, confirmation mode, security analyzers, and deferred init stay non-goals; trajectory download, OpenAI gateway, VS Code/desktop, auth cookies, MCP test, and workspace routers are useful later.