/save failed with 502 every time unless you passed --force, and the cause was one missing clause. The precondition that makes a save refuse to clobber a newer revision was expressed as a HAVING on an implicit single-group aggregate — no GROUP BY. SQLite treats the whole result as one group and runs that happily; Turso's parser rejects it outright, near HAVING, "None": syntax error. The route threw, the platform returned 502, and the CLI reported exactly what it saw. The retries added in #380 could never help: an unparseable statement fails the same way on every attempt.
What kept it alive is that the tests could not see it. They run against file: — a different engine from the deployment — and the precondition is genuinely covered there, a stale revision refused as 409 and a current one accepted. That suite passed throughout, because on SQLite the statement is valid. GROUP BY user_id makes it parse on both engines and cannot change the answer, since the caller passes a null precondition when the account has no current revision, so there is always a row to group. It was verified against the real database rather than only locally. The new guard is static rather than behavioural for the same reason the bug survived: only reading the SQL can catch this, so sql-portability.test.mjs now fails on any uppercase HAVING in src/ with no GROUP BY, comments stripped, because "having" is also an English word and four files that contain no SQL say it in prose.
The other half of this release is a new engine, and it is the first entry in that registry that is not a coding agent. moshcode install openagents runs the vendor's own installer, and OpenAgents launches and supervises the engines around it rather than answering prompts itself. That shapes every field: there are no approvals to bypass and no yolo flag, so its autonomous-mode arguments are empty, and a bare launch opens the dashboard — which is its agent list, so agents openagents and start openagents land in the same place instead of one of them pretending to be an agent view. It stays out of the ai() headless map for the same reason; asking it to answer a prompt names it in the error rather than silently picking it as your engine.
The installer unpacks to ~/.openagents/nodejs and only appends that directory to a shell rc, so PATH will not see the binary until your next shell — including in the moshcode session that just ran the install. It declares that directory the same way kimi and opencode already do, so the engine reads as installed immediately. One thing worth knowing before you run it: the installer ends by offering to pair the machine with a workspace and waits for a real answer. It only asks when stderr is a terminal, and Enter skips it — but moshcode install hands the child the terminal, so that prompt is yours to answer. Run it somewhere you can reach a keyboard.
Full changelog: v0.49.0...v0.50.0
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.