v0.5.0: Type-safe state tracking, lazy startup, and non-destructive cleanup - #1
Merged
Conversation
It serialized only event.text, silently dropping tool calls, permission requests, and status events for anyone proxying the stream to a frontend. No replacement — callers should serialize event.raw directly.
close() only cleared the local session_id and did no server-side cleanup, so the name implied more than it did. reset() matches actual behavior: the next ask()/stream() call starts a new conversation.
Prevents race conditions when multiple callers request the same server. Exactly one succeeds in claiming the startup slot; others wait for it to finish. Automatic cleanup of stale entries after 90s.
Store server lifecycle states (starting, running, stopping, failed) in registry instead of just starting/ready. Display status is derived separately from state + observed health, so the registry only tracks what we intentionally did.
Add three new functions to compute server status from state + health observation: - _is_process_alive(pid): check if PID is running - _is_health_ok(client): call /health endpoint with timeout - _compute_display_status(state, alive, health): derive user-facing status These will be used by CLI and tests. No behavior changes yet.
Populate registry fields on server startup: - runtime_version: set to current opencode-runtime version - last_used_at: set when server reaches running state Add ServerManager.touch(key) to update last_used_at when a session accesses the server. Called from OpenCodeRuntime.session() after get_or_start().
New 'opencode-runtime inspect <id>' shows full server details: - ID, Status (computed), Project, Workspace, User - PID, Port, Uptime, Last used, Runtime version, Log file Status display uses icons and colors (● running, ◐ starting, ▲ unhealthy, ○ stale). Uptime/idle computed from timestamps in the registry.
- Update RegistryEntry.state type hint from str to ServerState - Replace all state comparisons (state == "running") with enum values - Replace all state assignments (state="starting") with enum values - Update tests to use ServerState enum in fixtures and assertions - Import ServerState in cli.py, server.py, and test files - Update registry.claim_starting() to use ServerState.STARTING.value in SQL Type-safe state tracking throughout the codebase. No functional changes.
Do not start a default server on context entry. Servers start only when
the user explicitly requests a session via runtime.session().
Changes:
- Remove start() method (was just calling session())
- __aenter__ now returns self without starting a server
- Prevents wasting resources on unused runtimes
- Better for multi-workspace apps that may never use default workspace
Example:
async with OpenCodeRuntime() as runtime:
session = await runtime.session(workspace="acme") # starts here
This aligns with the "started on first use" design principle and prevents
creating unnecessary servers in applications that create a runtime at
startup but don't immediately use it.
ashish16052
force-pushed
the
asm/0.5
branch
2 times, most recently
from
July 10, 2026 11:36
8927cdb to
e32b663
Compare
ashish16052
force-pushed
the
asm/0.5
branch
2 times, most recently
from
July 10, 2026 16:02
653fd0a to
dd944da
Compare
close() now stops only servers this OpenCodeRuntime instance spawned itself, tracked via ServerManager._owned. Servers it merely attached to — already running, started by another process or the CLI — are left alone. - __aexit__ calls close() - get_or_start() records ownership only when it actually spawns a process, not when attaching to an existing one - close() calls the new stop_owned(), which stops and clears owned keys - Remove stop() (was calling stop_all()) To stop servers this runtime didn't start, use the CLI: opencode-runtime stop <key> / stop-all
- Remove calls to removed start() method; use close() instead - Lazy startup: tests call session() to trigger server creation - test_context_manager_with_server now asserts close() stops the server this runtime started - Add test_close_leaves_attached_server_running: a second runtime attached to the same server must not stop it via its own close() - Remove test_stop_all_terminates_all_tenant_servers (old behavior)
ashish16052
force-pushed
the
asm/0.5
branch
2 times, most recently
from
July 10, 2026 17:24
6703390 to
6181986
Compare
cmd_ps, cmd_health, and cmd_inspect each duplicated the same process-alive check, health probe, and display-status computation (plus, for cmd_ps/cmd_inspect, the same icon/color lookup tables). Move it all into ServerManager as status()/list_statuses(), backed by a new DisplayStatus enum, so the CLI only renders what ServerManager computes instead of re-deriving it three times.
Stamp the registry database with a schema version (via SQLite's PRAGMA user_version, no extra table needed) and add a migration runner that walks a database up to the current version on open. Unversioned (pre-existing) databases are treated as version 0 and migrated in place; a database newer than this code understands fails loudly (RegistrySchemaError) instead of being silently misread. No column changes yet — this just lands the mechanism now, while the schema is new and there's no real migration debt to carry forward.
status_coloured's own reset code cancelled the outer dim wrapper early, so every column after STATUS lost its dim styling.
manager.find() filters to RUNNING only, so a STARTING entry (e.g. an orphaned claim) couldn't be stopped by key; read the registry entry directly instead.
Password is sent as HTTP Basic auth, not Bearer, per _headers().
- SQLite registry with atomic claims - ServerState enum for type safety - Health probes and detailed status - Inspect command for server details - Lazy startup (no auto-create default server) - Non-destructive runtime cleanup (safe multi-process)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ServerStateenum for type safetysession()call, not on context entryruntime.close()— safe for multi-process deploymentsChanges
start()removed; servers start lazily on firstsession()stop()replaced withclose()(non-destructive)ServerStateenumFixes